Skip to content

Commit babeefc

Browse files
committed
Dropped sql.js temp package. Using dev release from standalone project.
1 parent 3679fda commit babeefc

File tree

11 files changed

+227
-438
lines changed

11 files changed

+227
-438
lines changed

packages/dev-adapter/README.md

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,89 @@
11
# PowerSync SDK Dev Adapter
22

3-
A very small development DB Adapter for PowerSync which uses [SQL.js](https://sql.js.org/#/)
3+
A development DB Adapter for PowerSync which uses [SQL.js](https://sql.js.org/#/)
4+
5+
## Usage
6+
7+
By default the SQLJS adapter will be in-memory. Read further for persistor examples.
8+
9+
```tsx
10+
import { SQLJSOpenFactory } from '@powersync/dev-adapter';
11+
12+
powersync = new PowerSyncDatabase({
13+
schema: AppSchema,
14+
database: new SQLJSOpenFactory({
15+
dbFilename: 'powersync.db'
16+
})
17+
});
18+
```
19+
20+
````
21+
22+
## Persister examples
23+
24+
### Expo
25+
26+
We can use the [Expo File System](https://docs.expo.dev/versions/latest/sdk/filesystem/) to persist the database in an Expo app.
27+
28+
```tsx
29+
import { SQLJSPersister } from '@powersync/dev-adapter';
30+
import * as FileSystem from 'expo-file-system';
31+
32+
const createSQLJSPersister = (dbFilename: string): SQLJSPersister => {
33+
const dbPath = `${FileSystem.documentDirectory}${dbFilename}`;
34+
35+
return {
36+
readFile: async (): Promise<ArrayLike<number> | Buffer | null> => {
37+
try {
38+
const fileInfo = await FileSystem.getInfoAsync(dbPath);
39+
if (!fileInfo.exists) {
40+
return null;
41+
}
42+
43+
const result = await FileSystem.readAsStringAsync(dbPath, {
44+
encoding: FileSystem.EncodingType.Base64
45+
});
46+
47+
const binary = atob(result);
48+
const bytes = new Uint8Array(binary.length);
49+
for (let i = 0; i < binary.length; i++) {
50+
bytes[i] = binary.charCodeAt(i);
51+
}
52+
return bytes;
53+
} catch (error) {
54+
console.error('Error reading database file:', error);
55+
return null;
56+
}
57+
},
58+
59+
writeFile: async (data: ArrayLike<number> | Buffer): Promise<void> => {
60+
try {
61+
const uint8Array = new Uint8Array(data);
62+
const binary = Array.from(uint8Array, (byte) => String.fromCharCode(byte)).join('');
63+
const base64 = btoa(binary);
64+
65+
await FileSystem.writeAsStringAsync(dbPath, base64, {
66+
encoding: FileSystem.EncodingType.Base64
67+
});
68+
} catch (error) {
69+
console.error('Error writing database file:', error);
70+
throw error;
71+
}
72+
}
73+
};
74+
};
75+
````
76+
77+
Which can then be used here
78+
79+
```tsx
80+
import { SQLJSOpenFactory, SQLJSPersister } from '@powersync/dev-adapter';
81+
82+
powersync = new PowerSyncDatabase({
83+
schema: AppSchema,
84+
database: new SQLJSOpenFactory({
85+
dbFilename: 'powersync.db',
86+
persister: createSQLJSPersister('powersync.db')
87+
})
88+
});
89+
```

packages/dev-adapter/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,12 @@
3232
"async-mutex": "^0.4.0"
3333
},
3434
"devDependencies": {
35+
"@powersync/sql-js": "0.0.0-dev-20250711104904",
36+
"@powersync/web": "workspace:*",
3537
"@rollup/plugin-alias": "^5.1.0",
3638
"@types/sql.js": "^1.4.9",
39+
"chance": "^1.1.9",
3740
"rollup": "4.14.3",
38-
"sql.js": "workspace:*"
41+
"uuid": "^11.1.0"
3942
}
4043
}

packages/dev-adapter/src/SQLJSAdapter.ts

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,18 @@ import {
1414
} from '@powersync/common';
1515
import { Mutex } from 'async-mutex';
1616
// This uses a pure JS version which avoids the need for WebAssembly, which is not supported in React Native.
17-
import SQLJs from 'sql.js/dist/sql-asm.js';
17+
import SQLJs from '@powersync/sql-js/dist/sql-asm.js';
1818

1919
export interface SQLJSPersister {
2020
readFile: () => Promise<ArrayLike<number> | Buffer | null>;
2121
writeFile: (data: ArrayLike<number> | Buffer) => Promise<void>;
2222
}
23+
2324
export interface SQLJSOpenOptions extends SQLOpenOptions {
25+
persister?: SQLJSPersister;
26+
}
27+
28+
export interface ResolvedSQLJSOpenOptions extends SQLJSOpenOptions {
2429
persister: SQLJSPersister;
2530
}
2631

@@ -53,6 +58,7 @@ export class SQLJSDBAdapter extends BaseObserver<DBAdapterListener> implements D
5358
protected tableUpdateCache: Set<string>;
5459
protected dbP: number | null;
5560
protected writeScheduler: ControlledExecutor<SQLJs.Database>;
61+
protected options: ResolvedSQLJSOpenOptions;
5662

5763
static sharedObserver = new TableObserver();
5864
protected disposeListener: () => void;
@@ -67,8 +73,9 @@ export class SQLJSDBAdapter extends BaseObserver<DBAdapterListener> implements D
6773
return this.options.dbFilename;
6874
}
6975

70-
constructor(protected options: SQLJSOpenOptions) {
76+
constructor(options: SQLJSOpenOptions) {
7177
super();
78+
this.options = this.resolveOptions(options);
7279
this.initPromise = this.init();
7380
this._db = null;
7481
this.tableUpdateCache = new Set<string>();
@@ -89,18 +96,27 @@ export class SQLJSDBAdapter extends BaseObserver<DBAdapterListener> implements D
8996
});
9097
}
9198

99+
protected resolveOptions(options: SQLJSOpenOptions): ResolvedSQLJSOpenOptions {
100+
const persister = options.persister ?? {
101+
readFile: async () => null,
102+
writeFile: async () => {}
103+
};
104+
return {
105+
...options,
106+
persister
107+
};
108+
}
109+
92110
protected async init(): Promise<SQLJs.Database> {
93-
console.log('Initializing SQL.js database with options');
94111
const SQL = await SQLJs({
95112
locateFile: (filename: any) => `../dist/${filename}`,
96113
print: (text) => {
97114
console.log('[stdout]', text);
98115
},
99116
printErr: (text) => {
100-
console.warn('[stderr]', text);
117+
console.error('[stderr]', text);
101118
}
102119
});
103-
console.log('SQL.js loaded:');
104120
const existing = await this.options.persister.readFile();
105121
const db = new SQL.Database(existing);
106122
this.dbP = db['db'];
@@ -205,9 +221,26 @@ export class SQLJSDBAdapter extends BaseObserver<DBAdapterListener> implements D
205221
return this.writeLock((tx) => tx.executeRaw(query, params));
206222
}
207223

208-
executeBatch(query: string, params?: any[][]): Promise<QueryResult> {
209-
// TODO
210-
throw new Error('Method not implemented.');
224+
async executeBatch(query: string, params: any[][] = []): Promise<QueryResult> {
225+
let totalRowsAffected = 0;
226+
const db = await this.getDB();
227+
228+
try {
229+
const stmt = db.prepare(query);
230+
231+
for (const paramSet of params) {
232+
stmt.run(paramSet);
233+
totalRowsAffected += db.getRowsModified();
234+
}
235+
236+
stmt.free();
237+
238+
return {
239+
rowsAffected: totalRowsAffected
240+
};
241+
} catch (error) {
242+
throw error;
243+
}
211244
}
212245

213246
readLock<T>(fn: (tx: LockContext) => Promise<T>, options?: DBLockOptions): Promise<T> {
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
declare module '@powersync/sql-js/dist/sql-asm.js' {
2+
import sqljs from 'sql.js/dist/sql-asm.js';
3+
export default sqljs;
4+
}

packages/sqljs/.gitignore

Lines changed: 0 additions & 1 deletion
This file was deleted.

packages/sqljs/README.md

Lines changed: 0 additions & 7 deletions
This file was deleted.

packages/sqljs/build.sh

Lines changed: 0 additions & 24 deletions
This file was deleted.

packages/sqljs/package.json

Lines changed: 0 additions & 31 deletions
This file was deleted.

packages/sqljs/patches/powersync-update.patch

Lines changed: 0 additions & 34 deletions
This file was deleted.

0 commit comments

Comments
 (0)