@powersync/web 1.12.2 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -0
- package/dist/3cb48be086dd9edd02ff.wasm +0 -0
- package/dist/{_journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js-async-mutex-c-3cff7d0.index.umd.js → _journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js-_powersync_co-780aa20.index.umd.js} +18 -8
- package/dist/_journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js-_powersync_co-780aa20.index.umd.js.map +1 -0
- package/dist/{_journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js-async-mutex-c-3cff7d1.index.umd.js → _journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js-_powersync_co-780aa21.index.umd.js} +18 -8
- package/dist/_journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js-_powersync_co-780aa21.index.umd.js.map +1 -0
- package/dist/df958358cadf945bd0fe.wasm +0 -0
- package/dist/f9c8ada26c59f5bf4339.wasm +0 -0
- package/dist/fe5693c7678cf12e05ac.wasm +0 -0
- package/dist/index.umd.js +3709 -499
- package/dist/index.umd.js.map +1 -1
- package/dist/worker/SharedSyncImplementation.umd.js +247 -2172
- package/dist/worker/SharedSyncImplementation.umd.js.map +1 -1
- package/dist/worker/WASQLiteDB.umd.js +767 -196
- package/dist/worker/WASQLiteDB.umd.js.map +1 -1
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_mc-wa-sqlite-async_mjs.umd.js +45 -0
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_mc-wa-sqlite-async_mjs.umd.js.map +1 -0
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_mc-wa-sqlite_mjs.umd.js +45 -0
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_mc-wa-sqlite_mjs.umd.js.map +1 -0
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_wa-sqlite-async_mjs.umd.js +2 -2
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_wa-sqlite-async_mjs.umd.js.map +1 -1
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_wa-sqlite_mjs.umd.js +45 -0
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_wa-sqlite_mjs.umd.js.map +1 -0
- package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_AccessHandlePoolVFS_js.umd.js +1509 -0
- package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_AccessHandlePoolVFS_js.umd.js.map +1 -0
- package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js.umd.js +39 -0
- package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js.umd.js.map +1 -1
- package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_OPFSCoopSyncVFS_js.umd.js +1641 -0
- package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_OPFSCoopSyncVFS_js.umd.js.map +1 -0
- package/lib/package.json +6 -6
- package/lib/src/db/PowerSyncDatabase.d.ts +10 -2
- package/lib/src/db/PowerSyncDatabase.js +20 -4
- package/lib/src/db/adapters/AbstractWebSQLOpenFactory.d.ts +2 -0
- package/lib/src/db/adapters/AbstractWebSQLOpenFactory.js +3 -0
- package/lib/src/db/adapters/AsyncDatabaseConnection.d.ts +26 -0
- package/lib/src/db/adapters/LockedAsyncDatabaseAdapter.d.ts +82 -0
- package/lib/src/db/adapters/LockedAsyncDatabaseAdapter.js +239 -0
- package/lib/src/db/adapters/WebDBAdapter.d.ts +17 -0
- package/lib/src/db/adapters/WebDBAdapter.js +1 -0
- package/lib/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.d.ts +39 -0
- package/lib/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.js +46 -0
- package/lib/src/db/adapters/wa-sqlite/WASQLiteConnection.d.ts +127 -0
- package/lib/src/db/adapters/wa-sqlite/WASQLiteConnection.js +343 -0
- package/lib/src/db/adapters/wa-sqlite/WASQLiteDBAdapter.d.ts +10 -42
- package/lib/src/db/adapters/wa-sqlite/WASQLiteDBAdapter.js +36 -212
- package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.d.ts +12 -0
- package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.js +81 -4
- package/lib/src/db/adapters/web-sql-flags.d.ts +17 -0
- package/lib/src/db/sync/SharedWebStreamingSyncImplementation.d.ts +9 -2
- package/lib/src/db/sync/SharedWebStreamingSyncImplementation.js +16 -10
- package/lib/src/db/sync/WebStreamingSyncImplementation.d.ts +0 -5
- package/lib/src/index.d.ts +8 -7
- package/lib/src/index.js +8 -7
- package/lib/src/worker/db/WASQLiteDB.worker.js +38 -20
- package/lib/src/worker/db/open-worker-database.d.ts +5 -4
- package/lib/src/worker/db/open-worker-database.js +5 -3
- package/lib/src/worker/sync/AbstractSharedSyncClientProvider.d.ts +1 -0
- package/lib/src/worker/sync/SharedSyncImplementation.d.ts +20 -3
- package/lib/src/worker/sync/SharedSyncImplementation.js +40 -11
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -7
- package/dist/24cd027f23123a1360de.wasm +0 -0
- package/dist/_journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js-async-mutex-c-3cff7d0.index.umd.js.map +0 -1
- package/dist/_journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js-async-mutex-c-3cff7d1.index.umd.js.map +0 -1
- package/lib/src/shared/open-db.d.ts +0 -5
- package/lib/src/shared/open-db.js +0 -193
- package/lib/src/shared/types.d.ts +0 -22
- /package/lib/src/{shared/types.js → db/adapters/AsyncDatabaseConnection.js} +0 -0
|
@@ -1,222 +1,46 @@
|
|
|
1
|
-
import { BaseObserver } from '@powersync/common';
|
|
2
1
|
import * as Comlink from 'comlink';
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
2
|
+
import { resolveWebPowerSyncFlags } from '../../PowerSyncDatabase';
|
|
3
|
+
import { LockedAsyncDatabaseAdapter } from '../LockedAsyncDatabaseAdapter';
|
|
4
|
+
import { TemporaryStorageOption } from '../web-sql-flags';
|
|
5
|
+
import { WorkerWrappedAsyncDatabaseConnection } from '../WorkerWrappedAsyncDatabaseConnection';
|
|
6
|
+
import { WASQLiteOpenFactory } from './WASQLiteOpenFactory';
|
|
8
7
|
/**
|
|
9
8
|
* Adapter for WA-SQLite SQLite connections.
|
|
10
9
|
*/
|
|
11
|
-
export class WASQLiteDBAdapter extends
|
|
12
|
-
options;
|
|
13
|
-
initialized;
|
|
14
|
-
logger;
|
|
15
|
-
dbGetHelpers;
|
|
16
|
-
methods;
|
|
17
|
-
debugMode;
|
|
10
|
+
export class WASQLiteDBAdapter extends LockedAsyncDatabaseAdapter {
|
|
18
11
|
constructor(options) {
|
|
19
|
-
super(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
12
|
+
super({
|
|
13
|
+
name: options.dbFilename,
|
|
14
|
+
openConnection: async () => {
|
|
15
|
+
const { workerPort, temporaryStorage } = options;
|
|
16
|
+
if (workerPort) {
|
|
17
|
+
const remote = Comlink.wrap(workerPort);
|
|
18
|
+
return new WorkerWrappedAsyncDatabaseConnection({
|
|
19
|
+
remote,
|
|
20
|
+
identifier: options.dbFilename,
|
|
21
|
+
baseConnection: await remote({
|
|
22
|
+
...options,
|
|
23
|
+
temporaryStorage: temporaryStorage ?? TemporaryStorageOption.MEMORY,
|
|
24
|
+
flags: resolveWebPowerSyncFlags(options.flags),
|
|
25
|
+
encryptionKey: options.encryptionKey
|
|
26
|
+
})
|
|
27
|
+
});
|
|
33
28
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
get name() {
|
|
46
|
-
return this.options.dbFilename;
|
|
47
|
-
}
|
|
48
|
-
get flags() {
|
|
49
|
-
return resolveWebSQLFlags(this.options.flags ?? {});
|
|
50
|
-
}
|
|
51
|
-
getWorker() { }
|
|
52
|
-
async init() {
|
|
53
|
-
const { enableMultiTabs, useWebWorker } = this.flags;
|
|
54
|
-
if (!enableMultiTabs) {
|
|
55
|
-
this.logger.warn('Multiple tabs are not enabled in this browser');
|
|
56
|
-
}
|
|
57
|
-
const tempStoreQuery = `PRAGMA temp_store = ${this.options.temporaryStorage ?? TemporaryStorageOption.MEMORY};`;
|
|
58
|
-
if (useWebWorker) {
|
|
59
|
-
const optionsDbWorker = this.options.worker;
|
|
60
|
-
const dbOpener = this.options.workerPort
|
|
61
|
-
? Comlink.wrap(this.options.workerPort)
|
|
62
|
-
: typeof optionsDbWorker === 'function'
|
|
63
|
-
? Comlink.wrap(resolveWorkerDatabasePortFactory(() => optionsDbWorker({
|
|
64
|
-
...this.options,
|
|
65
|
-
flags: this.flags
|
|
66
|
-
})))
|
|
67
|
-
: getWorkerDatabaseOpener(this.options.dbFilename, enableMultiTabs, optionsDbWorker);
|
|
68
|
-
this.methods = await dbOpener(this.options.dbFilename);
|
|
69
|
-
await this.methods.execute(tempStoreQuery);
|
|
70
|
-
this.methods.registerOnTableChange(Comlink.proxy((event) => {
|
|
71
|
-
this.iterateListeners((cb) => cb.tablesUpdated?.(event));
|
|
72
|
-
}));
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
this.methods = await _openDB(this.options.dbFilename, { useWebWorker: false });
|
|
76
|
-
await this.methods.execute(tempStoreQuery);
|
|
77
|
-
this.methods.registerOnTableChange((event) => {
|
|
78
|
-
this.iterateListeners((cb) => cb.tablesUpdated?.(event));
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
async execute(query, params) {
|
|
82
|
-
return this.writeLock((ctx) => ctx.execute(query, params));
|
|
83
|
-
}
|
|
84
|
-
async executeBatch(query, params) {
|
|
85
|
-
return this.writeLock((ctx) => this._executeBatch(query, params));
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Wraps the worker execute function, awaiting for it to be available
|
|
89
|
-
*/
|
|
90
|
-
_execute = async (sql, bindings) => {
|
|
91
|
-
await this.initialized;
|
|
92
|
-
const result = await this.methods.execute(sql, bindings);
|
|
93
|
-
return {
|
|
94
|
-
...result,
|
|
95
|
-
rows: {
|
|
96
|
-
...result.rows,
|
|
97
|
-
item: (idx) => result.rows._array[idx]
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
};
|
|
101
|
-
/**
|
|
102
|
-
* Wraps the worker executeBatch function, awaiting for it to be available
|
|
103
|
-
*/
|
|
104
|
-
_executeBatch = async (query, params) => {
|
|
105
|
-
await this.initialized;
|
|
106
|
-
const result = await this.methods.executeBatch(query, params);
|
|
107
|
-
return {
|
|
108
|
-
...result,
|
|
109
|
-
rows: undefined
|
|
110
|
-
};
|
|
111
|
-
};
|
|
112
|
-
/**
|
|
113
|
-
* Attempts to close the connection.
|
|
114
|
-
* Shared workers might not actually close the connection if other
|
|
115
|
-
* tabs are still using it.
|
|
116
|
-
*/
|
|
117
|
-
close() {
|
|
118
|
-
this.methods?.close?.();
|
|
119
|
-
}
|
|
120
|
-
async getAll(sql, parameters) {
|
|
121
|
-
await this.initialized;
|
|
122
|
-
return this.dbGetHelpers.getAll(sql, parameters);
|
|
123
|
-
}
|
|
124
|
-
async getOptional(sql, parameters) {
|
|
125
|
-
await this.initialized;
|
|
126
|
-
return this.dbGetHelpers.getOptional(sql, parameters);
|
|
127
|
-
}
|
|
128
|
-
async get(sql, parameters) {
|
|
129
|
-
await this.initialized;
|
|
130
|
-
return this.dbGetHelpers.get(sql, parameters);
|
|
131
|
-
}
|
|
132
|
-
async readLock(fn, options) {
|
|
133
|
-
await this.initialized;
|
|
134
|
-
return this.acquireLock(async () => fn(this.generateDBHelpers({ execute: this._execute })));
|
|
135
|
-
}
|
|
136
|
-
async writeLock(fn, options) {
|
|
137
|
-
await this.initialized;
|
|
138
|
-
return this.acquireLock(async () => fn(this.generateDBHelpers({ execute: this._execute })));
|
|
139
|
-
}
|
|
140
|
-
acquireLock(callback) {
|
|
141
|
-
return getNavigatorLocks().request(`db-lock-${this.options.dbFilename}`, callback);
|
|
142
|
-
}
|
|
143
|
-
async readTransaction(fn, options) {
|
|
144
|
-
return this.readLock(this.wrapTransaction(fn));
|
|
145
|
-
}
|
|
146
|
-
writeTransaction(fn, options) {
|
|
147
|
-
return this.writeLock(this.wrapTransaction(fn));
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Wraps a lock context into a transaction context
|
|
151
|
-
*/
|
|
152
|
-
wrapTransaction(cb) {
|
|
153
|
-
return async (tx) => {
|
|
154
|
-
await this._execute('BEGIN TRANSACTION');
|
|
155
|
-
let finalized = false;
|
|
156
|
-
const commit = async () => {
|
|
157
|
-
if (finalized) {
|
|
158
|
-
return { rowsAffected: 0 };
|
|
159
|
-
}
|
|
160
|
-
finalized = true;
|
|
161
|
-
return this._execute('COMMIT');
|
|
162
|
-
};
|
|
163
|
-
const rollback = () => {
|
|
164
|
-
finalized = true;
|
|
165
|
-
return this._execute('ROLLBACK');
|
|
166
|
-
};
|
|
167
|
-
try {
|
|
168
|
-
const result = await cb({
|
|
169
|
-
...tx,
|
|
170
|
-
commit,
|
|
171
|
-
rollback
|
|
29
|
+
const openFactory = new WASQLiteOpenFactory({
|
|
30
|
+
dbFilename: options.dbFilename,
|
|
31
|
+
dbLocation: options.dbLocation,
|
|
32
|
+
debugMode: options.debugMode,
|
|
33
|
+
flags: options.flags,
|
|
34
|
+
temporaryStorage,
|
|
35
|
+
logger: options.logger,
|
|
36
|
+
vfs: options.vfs,
|
|
37
|
+
encryptionKey: options.encryptionKey,
|
|
38
|
+
worker: options.worker
|
|
172
39
|
});
|
|
173
|
-
|
|
174
|
-
await commit();
|
|
175
|
-
}
|
|
176
|
-
return result;
|
|
177
|
-
}
|
|
178
|
-
catch (ex) {
|
|
179
|
-
this.logger.debug('Caught ex in transaction', ex);
|
|
180
|
-
try {
|
|
181
|
-
await rollback();
|
|
182
|
-
}
|
|
183
|
-
catch (ex2) {
|
|
184
|
-
// In rare cases, a rollback may fail.
|
|
185
|
-
// Safe to ignore.
|
|
186
|
-
}
|
|
187
|
-
throw ex;
|
|
188
|
-
}
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
generateDBHelpers(tx) {
|
|
192
|
-
return {
|
|
193
|
-
...tx,
|
|
194
|
-
/**
|
|
195
|
-
* Execute a read-only query and return results
|
|
196
|
-
*/
|
|
197
|
-
async getAll(sql, parameters) {
|
|
198
|
-
const res = await tx.execute(sql, parameters);
|
|
199
|
-
return res.rows?._array ?? [];
|
|
40
|
+
return openFactory.openConnection();
|
|
200
41
|
},
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
async getOptional(sql, parameters) {
|
|
205
|
-
const res = await tx.execute(sql, parameters);
|
|
206
|
-
return res.rows?.item(0) ?? null;
|
|
207
|
-
},
|
|
208
|
-
/**
|
|
209
|
-
* Execute a read-only query and return the first result, error if the ResultSet is empty.
|
|
210
|
-
*/
|
|
211
|
-
async get(sql, parameters) {
|
|
212
|
-
const res = await tx.execute(sql, parameters);
|
|
213
|
-
const first = res.rows?.item(0);
|
|
214
|
-
if (!first) {
|
|
215
|
-
throw new Error('Result set is empty');
|
|
216
|
-
}
|
|
217
|
-
return first;
|
|
218
|
-
}
|
|
219
|
-
};
|
|
42
|
+
debugMode: options.debugMode,
|
|
43
|
+
logger: options.logger
|
|
44
|
+
});
|
|
220
45
|
}
|
|
221
|
-
async refreshSchema() { }
|
|
222
46
|
}
|
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
import { DBAdapter } from '@powersync/common';
|
|
2
2
|
import { AbstractWebSQLOpenFactory } from '../AbstractWebSQLOpenFactory';
|
|
3
|
+
import { AsyncDatabaseConnection } from '../AsyncDatabaseConnection';
|
|
4
|
+
import { ResolvedWebSQLOpenOptions, WebSQLOpenFactoryOptions } from '../web-sql-flags';
|
|
5
|
+
import { WASQLiteVFS } from './WASQLiteConnection';
|
|
6
|
+
export interface WASQLiteOpenFactoryOptions extends WebSQLOpenFactoryOptions {
|
|
7
|
+
vfs?: WASQLiteVFS;
|
|
8
|
+
}
|
|
9
|
+
export interface ResolvedWASQLiteOpenFactoryOptions extends ResolvedWebSQLOpenOptions {
|
|
10
|
+
vfs: WASQLiteVFS;
|
|
11
|
+
}
|
|
3
12
|
/**
|
|
4
13
|
* Opens a SQLite connection using WA-SQLite.
|
|
5
14
|
*/
|
|
6
15
|
export declare class WASQLiteOpenFactory extends AbstractWebSQLOpenFactory {
|
|
16
|
+
constructor(options: WASQLiteOpenFactoryOptions);
|
|
17
|
+
get waOptions(): WASQLiteOpenFactoryOptions;
|
|
7
18
|
protected openAdapter(): DBAdapter;
|
|
19
|
+
openConnection(): Promise<AsyncDatabaseConnection>;
|
|
8
20
|
}
|
|
@@ -1,13 +1,90 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as Comlink from 'comlink';
|
|
2
|
+
import { openWorkerDatabasePort, resolveWorkerDatabasePortFactory } from '../../../worker/db/open-worker-database';
|
|
2
3
|
import { AbstractWebSQLOpenFactory } from '../AbstractWebSQLOpenFactory';
|
|
4
|
+
import { LockedAsyncDatabaseAdapter } from '../LockedAsyncDatabaseAdapter';
|
|
5
|
+
import { TemporaryStorageOption } from '../web-sql-flags';
|
|
6
|
+
import { WorkerWrappedAsyncDatabaseConnection } from '../WorkerWrappedAsyncDatabaseConnection';
|
|
7
|
+
import { WASqliteConnection, WASQLiteVFS } from './WASQLiteConnection';
|
|
3
8
|
/**
|
|
4
9
|
* Opens a SQLite connection using WA-SQLite.
|
|
5
10
|
*/
|
|
6
11
|
export class WASQLiteOpenFactory extends AbstractWebSQLOpenFactory {
|
|
12
|
+
constructor(options) {
|
|
13
|
+
super(options);
|
|
14
|
+
assertValidWASQLiteOpenFactoryOptions(options);
|
|
15
|
+
}
|
|
16
|
+
get waOptions() {
|
|
17
|
+
// Cast to extended type
|
|
18
|
+
return this.options;
|
|
19
|
+
}
|
|
7
20
|
openAdapter() {
|
|
8
|
-
return new
|
|
9
|
-
|
|
10
|
-
|
|
21
|
+
return new LockedAsyncDatabaseAdapter({
|
|
22
|
+
name: this.options.dbFilename,
|
|
23
|
+
openConnection: () => this.openConnection(),
|
|
24
|
+
debugMode: this.options.debugMode,
|
|
25
|
+
logger: this.logger
|
|
11
26
|
});
|
|
12
27
|
}
|
|
28
|
+
async openConnection() {
|
|
29
|
+
const { enableMultiTabs, useWebWorker } = this.resolvedFlags;
|
|
30
|
+
const { vfs = WASQLiteVFS.IDBBatchAtomicVFS, temporaryStorage = TemporaryStorageOption.MEMORY, encryptionKey } = this.waOptions;
|
|
31
|
+
if (!enableMultiTabs) {
|
|
32
|
+
this.logger.warn('Multiple tabs are not enabled in this browser');
|
|
33
|
+
}
|
|
34
|
+
if (useWebWorker) {
|
|
35
|
+
const optionsDbWorker = this.options.worker;
|
|
36
|
+
const workerPort = typeof optionsDbWorker == 'function'
|
|
37
|
+
? resolveWorkerDatabasePortFactory(() => optionsDbWorker({
|
|
38
|
+
...this.options,
|
|
39
|
+
temporaryStorage,
|
|
40
|
+
flags: this.resolvedFlags,
|
|
41
|
+
encryptionKey
|
|
42
|
+
}))
|
|
43
|
+
: openWorkerDatabasePort(this.options.dbFilename, enableMultiTabs, optionsDbWorker, this.waOptions.vfs);
|
|
44
|
+
const workerDBOpener = Comlink.wrap(workerPort);
|
|
45
|
+
return new WorkerWrappedAsyncDatabaseConnection({
|
|
46
|
+
remote: workerDBOpener,
|
|
47
|
+
baseConnection: await workerDBOpener({
|
|
48
|
+
dbFilename: this.options.dbFilename,
|
|
49
|
+
vfs,
|
|
50
|
+
temporaryStorage,
|
|
51
|
+
flags: this.resolvedFlags,
|
|
52
|
+
encryptionKey: encryptionKey
|
|
53
|
+
}),
|
|
54
|
+
identifier: this.options.dbFilename,
|
|
55
|
+
onClose: () => {
|
|
56
|
+
if (workerPort instanceof Worker) {
|
|
57
|
+
workerPort.terminate();
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
workerPort.close();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
// Don't use a web worker
|
|
67
|
+
return new WASqliteConnection({
|
|
68
|
+
dbFilename: this.options.dbFilename,
|
|
69
|
+
dbLocation: this.options.dbLocation,
|
|
70
|
+
debugMode: this.options.debugMode,
|
|
71
|
+
vfs,
|
|
72
|
+
temporaryStorage,
|
|
73
|
+
flags: this.resolvedFlags,
|
|
74
|
+
encryptionKey: encryptionKey
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Asserts that the factory options are valid.
|
|
81
|
+
*/
|
|
82
|
+
function assertValidWASQLiteOpenFactoryOptions(options) {
|
|
83
|
+
// The OPFS VFS only works in dedicated web workers.
|
|
84
|
+
if ('vfs' in options && 'flags' in options) {
|
|
85
|
+
const { vfs, flags = {} } = options;
|
|
86
|
+
if (vfs !== WASQLiteVFS.IDBBatchAtomicVFS && 'useWebWorker' in flags && !flags.useWebWorker) {
|
|
87
|
+
throw new Error(`Invalid configuration: The 'useWebWorker' flag must be true when using an OPFS-based VFS (${vfs}).`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
13
90
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SQLOpenOptions } from '@powersync/common';
|
|
2
|
+
import { ILogger } from 'js-logger';
|
|
2
3
|
/**
|
|
3
4
|
* Common settings used when creating SQL connections on web.
|
|
4
5
|
*/
|
|
@@ -33,6 +34,16 @@ export interface WebSQLFlags {
|
|
|
33
34
|
export type ResolvedWebSQLFlags = Required<WebSQLFlags>;
|
|
34
35
|
export interface ResolvedWebSQLOpenOptions extends SQLOpenOptions {
|
|
35
36
|
flags: ResolvedWebSQLFlags;
|
|
37
|
+
/**
|
|
38
|
+
* Where to store SQLite temporary files. Defaults to 'MEMORY'.
|
|
39
|
+
* Setting this to `FILESYSTEM` can cause issues with larger queries or datasets.
|
|
40
|
+
*/
|
|
41
|
+
temporaryStorage: TemporaryStorageOption;
|
|
42
|
+
/**
|
|
43
|
+
* Encryption key for the database.
|
|
44
|
+
* If set, the database will be encrypted using ChaCha20.
|
|
45
|
+
*/
|
|
46
|
+
encryptionKey?: string;
|
|
36
47
|
}
|
|
37
48
|
export declare enum TemporaryStorageOption {
|
|
38
49
|
MEMORY = "memory",
|
|
@@ -50,11 +61,17 @@ export interface WebSQLOpenFactoryOptions extends SQLOpenOptions {
|
|
|
50
61
|
* or a factory method that returns a worker.
|
|
51
62
|
*/
|
|
52
63
|
worker?: string | URL | ((options: ResolvedWebSQLOpenOptions) => Worker | SharedWorker);
|
|
64
|
+
logger?: ILogger;
|
|
53
65
|
/**
|
|
54
66
|
* Where to store SQLite temporary files. Defaults to 'MEMORY'.
|
|
55
67
|
* Setting this to `FILESYSTEM` can cause issues with larger queries or datasets.
|
|
56
68
|
*/
|
|
57
69
|
temporaryStorage?: TemporaryStorageOption;
|
|
70
|
+
/**
|
|
71
|
+
* Encryption key for the database.
|
|
72
|
+
* If set, the database will be encrypted using ChaCha20.
|
|
73
|
+
*/
|
|
74
|
+
encryptionKey?: string;
|
|
58
75
|
}
|
|
59
76
|
export declare function isServerSide(): boolean;
|
|
60
77
|
export declare const DEFAULT_WEB_SQL_FLAGS: ResolvedWebSQLFlags;
|
|
@@ -2,6 +2,7 @@ import { PowerSyncConnectionOptions, PowerSyncCredentials, SyncStatusOptions } f
|
|
|
2
2
|
import * as Comlink from 'comlink';
|
|
3
3
|
import { AbstractSharedSyncClientProvider } from '../../worker/sync/AbstractSharedSyncClientProvider';
|
|
4
4
|
import { SharedSyncImplementation } from '../../worker/sync/SharedSyncImplementation';
|
|
5
|
+
import { WebDBAdapter } from '../adapters/WebDBAdapter';
|
|
5
6
|
import { WebStreamingSyncImplementation, WebStreamingSyncImplementationOptions } from './WebStreamingSyncImplementation';
|
|
6
7
|
/**
|
|
7
8
|
* The shared worker will trigger methods on this side of the message port
|
|
@@ -10,7 +11,9 @@ import { WebStreamingSyncImplementation, WebStreamingSyncImplementationOptions }
|
|
|
10
11
|
declare class SharedSyncClientProvider extends AbstractSharedSyncClientProvider {
|
|
11
12
|
protected options: WebStreamingSyncImplementationOptions;
|
|
12
13
|
statusChanged: (status: SyncStatusOptions) => void;
|
|
13
|
-
|
|
14
|
+
protected webDB: WebDBAdapter;
|
|
15
|
+
constructor(options: WebStreamingSyncImplementationOptions, statusChanged: (status: SyncStatusOptions) => void, webDB: WebDBAdapter);
|
|
16
|
+
getDBWorkerPort(): Promise<MessagePort>;
|
|
14
17
|
fetchCredentials(): Promise<PowerSyncCredentials | null>;
|
|
15
18
|
uploadCrud(): Promise<void>;
|
|
16
19
|
get logger(): import("js-logger").ILogger | undefined;
|
|
@@ -23,12 +26,16 @@ declare class SharedSyncClientProvider extends AbstractSharedSyncClientProvider
|
|
|
23
26
|
time(label: string): void;
|
|
24
27
|
timeEnd(label: string): void;
|
|
25
28
|
}
|
|
29
|
+
export interface SharedWebStreamingSyncImplementationOptions extends WebStreamingSyncImplementationOptions {
|
|
30
|
+
db: WebDBAdapter;
|
|
31
|
+
}
|
|
26
32
|
export declare class SharedWebStreamingSyncImplementation extends WebStreamingSyncImplementation {
|
|
27
33
|
protected syncManager: Comlink.Remote<SharedSyncImplementation>;
|
|
28
34
|
protected clientProvider: SharedSyncClientProvider;
|
|
29
35
|
protected messagePort: MessagePort;
|
|
30
36
|
protected isInitialized: Promise<void>;
|
|
31
|
-
|
|
37
|
+
protected dbAdapter: WebDBAdapter;
|
|
38
|
+
constructor(options: SharedWebStreamingSyncImplementationOptions);
|
|
32
39
|
/**
|
|
33
40
|
* Starts the sync process, this effectively acts as a call to
|
|
34
41
|
* `connect` if not yet connected.
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import * as Comlink from 'comlink';
|
|
2
|
-
import { openWorkerDatabasePort, resolveWorkerDatabasePortFactory } from '../../worker/db/open-worker-database';
|
|
3
2
|
import { AbstractSharedSyncClientProvider } from '../../worker/sync/AbstractSharedSyncClientProvider';
|
|
4
3
|
import { SharedSyncClientEvent } from '../../worker/sync/SharedSyncImplementation';
|
|
4
|
+
import { resolveWebSQLFlags, TemporaryStorageOption } from '../adapters/web-sql-flags';
|
|
5
5
|
import { WebStreamingSyncImplementation } from './WebStreamingSyncImplementation';
|
|
6
|
-
import { resolveWebSQLFlags } from '../adapters/web-sql-flags';
|
|
7
6
|
/**
|
|
8
7
|
* The shared worker will trigger methods on this side of the message port
|
|
9
8
|
* via this client provider.
|
|
@@ -11,10 +10,16 @@ import { resolveWebSQLFlags } from '../adapters/web-sql-flags';
|
|
|
11
10
|
class SharedSyncClientProvider extends AbstractSharedSyncClientProvider {
|
|
12
11
|
options;
|
|
13
12
|
statusChanged;
|
|
14
|
-
|
|
13
|
+
webDB;
|
|
14
|
+
constructor(options, statusChanged, webDB) {
|
|
15
15
|
super();
|
|
16
16
|
this.options = options;
|
|
17
17
|
this.statusChanged = statusChanged;
|
|
18
|
+
this.webDB = webDB;
|
|
19
|
+
}
|
|
20
|
+
async getDBWorkerPort() {
|
|
21
|
+
const { port } = await this.webDB.shareConnection();
|
|
22
|
+
return Comlink.transfer(port, [port]);
|
|
18
23
|
}
|
|
19
24
|
async fetchCredentials() {
|
|
20
25
|
const credentials = await this.options.remote.getCredentials();
|
|
@@ -72,8 +77,10 @@ export class SharedWebStreamingSyncImplementation extends WebStreamingSyncImplem
|
|
|
72
77
|
clientProvider;
|
|
73
78
|
messagePort;
|
|
74
79
|
isInitialized;
|
|
80
|
+
dbAdapter;
|
|
75
81
|
constructor(options) {
|
|
76
82
|
super(options);
|
|
83
|
+
this.dbAdapter = options.db;
|
|
77
84
|
/**
|
|
78
85
|
* Configure or connect to the shared sync worker.
|
|
79
86
|
* This worker will manage all syncing operations remotely.
|
|
@@ -81,6 +88,8 @@ export class SharedWebStreamingSyncImplementation extends WebStreamingSyncImplem
|
|
|
81
88
|
const resolvedWorkerOptions = {
|
|
82
89
|
...options,
|
|
83
90
|
dbFilename: this.options.identifier,
|
|
91
|
+
// TODO
|
|
92
|
+
temporaryStorage: TemporaryStorageOption.MEMORY,
|
|
84
93
|
flags: resolveWebSQLFlags(options.flags)
|
|
85
94
|
};
|
|
86
95
|
const syncWorker = options.sync?.worker;
|
|
@@ -111,13 +120,9 @@ export class SharedWebStreamingSyncImplementation extends WebStreamingSyncImplem
|
|
|
111
120
|
* sync worker.
|
|
112
121
|
*/
|
|
113
122
|
const { crudUploadThrottleMs, identifier, retryDelayMs } = this.options;
|
|
114
|
-
const dbWorker = options.database?.options?.worker;
|
|
115
|
-
const dbOpenerPort = typeof dbWorker === 'function'
|
|
116
|
-
? resolveWorkerDatabasePortFactory(() => dbWorker(resolvedWorkerOptions))
|
|
117
|
-
: openWorkerDatabasePort(this.options.identifier, true, dbWorker);
|
|
118
123
|
const flags = { ...this.webOptions.flags, workers: undefined };
|
|
119
|
-
this.isInitialized = this.syncManager.
|
|
120
|
-
|
|
124
|
+
this.isInitialized = this.syncManager.setParams({
|
|
125
|
+
dbParams: this.dbAdapter.getConfiguration(),
|
|
121
126
|
streamOptions: {
|
|
122
127
|
crudUploadThrottleMs,
|
|
123
128
|
identifier,
|
|
@@ -130,7 +135,7 @@ export class SharedWebStreamingSyncImplementation extends WebStreamingSyncImplem
|
|
|
130
135
|
*/
|
|
131
136
|
this.clientProvider = new SharedSyncClientProvider(this.webOptions, (status) => {
|
|
132
137
|
this.iterateListeners((l) => this.updateSyncStatus(status));
|
|
133
|
-
});
|
|
138
|
+
}, options.db);
|
|
134
139
|
/**
|
|
135
140
|
* The sync worker will call this client provider when it needs
|
|
136
141
|
* to fetch credentials or upload data.
|
|
@@ -179,6 +184,7 @@ export class SharedWebStreamingSyncImplementation extends WebStreamingSyncImplem
|
|
|
179
184
|
* Used in tests to force a connection states
|
|
180
185
|
*/
|
|
181
186
|
async _testUpdateStatus(status) {
|
|
187
|
+
await this.isInitialized;
|
|
182
188
|
return this.syncManager['_testUpdateAllStatuses'](status.toJSON());
|
|
183
189
|
}
|
|
184
190
|
}
|
|
@@ -2,11 +2,6 @@ import { AbstractStreamingSyncImplementation, AbstractStreamingSyncImplementatio
|
|
|
2
2
|
import { ResolvedWebSQLOpenOptions, WebSQLFlags } from '../adapters/web-sql-flags';
|
|
3
3
|
export interface WebStreamingSyncImplementationOptions extends AbstractStreamingSyncImplementationOptions {
|
|
4
4
|
flags?: WebSQLFlags;
|
|
5
|
-
database?: {
|
|
6
|
-
options: {
|
|
7
|
-
worker?: string | URL | ((options: ResolvedWebSQLOpenOptions) => Worker | SharedWorker);
|
|
8
|
-
};
|
|
9
|
-
};
|
|
10
5
|
sync?: {
|
|
11
6
|
worker?: string | URL | ((options: ResolvedWebSQLOpenOptions) => SharedWorker);
|
|
12
7
|
};
|
package/lib/src/index.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
export * from '@powersync/common';
|
|
2
|
-
export * from './db/PowerSyncDatabase';
|
|
3
|
-
export * from './db/sync/WebRemote';
|
|
4
|
-
export * from './db/sync/WebStreamingSyncImplementation';
|
|
5
|
-
export * from './db/sync/SharedWebStreamingSyncImplementation';
|
|
6
|
-
export * from './db/adapters/wa-sqlite/WASQLiteDBAdapter';
|
|
7
|
-
export * from './db/adapters/wa-sqlite/WASQLitePowerSyncDatabaseOpenFactory';
|
|
8
2
|
export * from './db/adapters/AbstractWebPowerSyncDatabaseOpenFactory';
|
|
9
|
-
export * from './db/adapters/web-sql-flags';
|
|
10
3
|
export * from './db/adapters/AbstractWebSQLOpenFactory';
|
|
4
|
+
export * from './db/adapters/wa-sqlite/WASQLiteConnection';
|
|
5
|
+
export * from './db/adapters/wa-sqlite/WASQLiteDBAdapter';
|
|
11
6
|
export * from './db/adapters/wa-sqlite/WASQLiteOpenFactory';
|
|
7
|
+
export * from './db/adapters/wa-sqlite/WASQLitePowerSyncDatabaseOpenFactory';
|
|
8
|
+
export * from './db/adapters/web-sql-flags';
|
|
9
|
+
export * from './db/PowerSyncDatabase';
|
|
10
|
+
export * from './db/sync/SharedWebStreamingSyncImplementation';
|
|
11
|
+
export * from './db/sync/WebRemote';
|
|
12
|
+
export * from './db/sync/WebStreamingSyncImplementation';
|
package/lib/src/index.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
export * from '@powersync/common';
|
|
2
|
-
export * from './db/PowerSyncDatabase';
|
|
3
|
-
export * from './db/sync/WebRemote';
|
|
4
|
-
export * from './db/sync/WebStreamingSyncImplementation';
|
|
5
|
-
export * from './db/sync/SharedWebStreamingSyncImplementation';
|
|
6
|
-
export * from './db/adapters/wa-sqlite/WASQLiteDBAdapter';
|
|
7
|
-
export * from './db/adapters/wa-sqlite/WASQLitePowerSyncDatabaseOpenFactory';
|
|
8
2
|
export * from './db/adapters/AbstractWebPowerSyncDatabaseOpenFactory';
|
|
9
|
-
export * from './db/adapters/web-sql-flags';
|
|
10
3
|
export * from './db/adapters/AbstractWebSQLOpenFactory';
|
|
4
|
+
export * from './db/adapters/wa-sqlite/WASQLiteConnection';
|
|
5
|
+
export * from './db/adapters/wa-sqlite/WASQLiteDBAdapter';
|
|
11
6
|
export * from './db/adapters/wa-sqlite/WASQLiteOpenFactory';
|
|
7
|
+
export * from './db/adapters/wa-sqlite/WASQLitePowerSyncDatabaseOpenFactory';
|
|
8
|
+
export * from './db/adapters/web-sql-flags';
|
|
9
|
+
export * from './db/PowerSyncDatabase';
|
|
10
|
+
export * from './db/sync/SharedWebStreamingSyncImplementation';
|
|
11
|
+
export * from './db/sync/WebRemote';
|
|
12
|
+
export * from './db/sync/WebStreamingSyncImplementation';
|