@powersync/web 0.0.0-dev-20251129133952 → 0.0.0-dev-20251203144301
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/dist/1807036ae51c10ee4d23.wasm +0 -0
- package/dist/{10072fe45f0a8fab0a0e.wasm → 307d8ce2280e3bae09d5.wasm} +0 -0
- package/dist/{6e435e51534839845554.wasm → cd8b9e8f4c87bf81c169.wasm} +0 -0
- package/dist/e797080f5ed0b5324166.wasm +0 -0
- package/dist/index.umd.js +2551 -161
- package/dist/index.umd.js.map +1 -1
- package/dist/worker/SharedSyncImplementation.umd.js +2020 -148
- package/dist/worker/SharedSyncImplementation.umd.js.map +1 -1
- package/dist/worker/WASQLiteDB.umd.js +1824 -9
- 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 +2 -2
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_mc-wa-sqlite-async_mjs.umd.js.map +1 -1
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_mc-wa-sqlite_mjs.umd.js +2 -2
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_mc-wa-sqlite_mjs.umd.js.map +1 -1
- 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 +2 -2
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_wa-sqlite_mjs.umd.js.map +1 -1
- package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_AccessHandlePoolVFS_js.umd.js +0 -1203
- package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_AccessHandlePoolVFS_js.umd.js.map +1 -1
- package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js.umd.js +20 -1226
- package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js.umd.js.map +1 -1
- package/lib/package.json +2 -2
- package/lib/src/db/PowerSyncDatabase.d.ts +1 -1
- package/lib/src/db/PowerSyncDatabase.js +4 -4
- package/lib/src/db/adapters/AsyncDatabaseConnection.d.ts +5 -0
- package/lib/src/db/adapters/AsyncDatabaseConnection.js +5 -0
- package/lib/src/db/adapters/LockedAsyncDatabaseAdapter.d.ts +10 -2
- package/lib/src/db/adapters/LockedAsyncDatabaseAdapter.js +72 -33
- package/lib/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.d.ts +5 -1
- package/lib/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.js +12 -5
- package/lib/src/db/adapters/wa-sqlite/WASQLiteConnection.js +3 -3
- package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.d.ts +1 -1
- package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.js +2 -2
- package/lib/src/db/sync/SharedWebStreamingSyncImplementation.d.ts +0 -4
- package/lib/src/db/sync/SharedWebStreamingSyncImplementation.js +3 -8
- package/lib/src/worker/db/WASQLiteDB.worker.js +0 -1
- package/lib/src/worker/db/opfs.d.ts +96 -0
- package/lib/src/worker/db/opfs.js +582 -0
- package/lib/src/worker/sync/SharedSyncImplementation.d.ts +6 -11
- package/lib/src/worker/sync/SharedSyncImplementation.js +95 -67
- package/lib/src/worker/sync/SharedSyncImplementation.worker.js +1 -1
- package/lib/src/worker/sync/WorkerClient.d.ts +1 -3
- package/lib/src/worker/sync/WorkerClient.js +3 -27
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/src/db/PowerSyncDatabase.ts +13 -15
- package/src/db/adapters/AsyncDatabaseConnection.ts +5 -0
- package/src/db/adapters/LockedAsyncDatabaseAdapter.ts +91 -51
- package/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.ts +16 -4
- package/src/db/adapters/wa-sqlite/WASQLiteConnection.ts +3 -4
- package/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.ts +3 -3
- package/src/db/sync/SharedWebStreamingSyncImplementation.ts +5 -11
- package/src/worker/db/WASQLiteDB.worker.ts +0 -2
- package/src/worker/db/opfs.ts +623 -0
- package/src/worker/sync/SharedSyncImplementation.ts +106 -78
- package/src/worker/sync/SharedSyncImplementation.worker.ts +1 -1
- package/src/worker/sync/WorkerClient.ts +4 -30
- package/dist/a730f7ca717b02234beb.wasm +0 -0
- package/dist/aa2f408d64445fed090e.wasm +0 -0
- package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_OPFSCoopSyncVFS_js.umd.js +0 -1813
- package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_OPFSCoopSyncVFS_js.umd.js.map +0 -1
|
@@ -1,14 +1,16 @@
|
|
|
1
|
+
import { BaseObserver } from '@powersync/common';
|
|
1
2
|
import * as Comlink from 'comlink';
|
|
2
3
|
import { ConnectionClosedError } from './AsyncDatabaseConnection';
|
|
3
4
|
/**
|
|
4
5
|
* Wraps a provided instance of {@link AsyncDatabaseConnection}, providing necessary proxy
|
|
5
6
|
* functions for worker listeners.
|
|
6
7
|
*/
|
|
7
|
-
export class WorkerWrappedAsyncDatabaseConnection {
|
|
8
|
+
export class WorkerWrappedAsyncDatabaseConnection extends BaseObserver {
|
|
8
9
|
options;
|
|
9
10
|
lockAbortController = new AbortController();
|
|
10
11
|
notifyRemoteClosed;
|
|
11
12
|
constructor(options) {
|
|
13
|
+
super();
|
|
12
14
|
this.options = options;
|
|
13
15
|
if (options.remoteCanCloseUnexpectedly) {
|
|
14
16
|
this.notifyRemoteClosed = new AbortController();
|
|
@@ -41,14 +43,17 @@ export class WorkerWrappedAsyncDatabaseConnection {
|
|
|
41
43
|
isAutoCommit() {
|
|
42
44
|
return this.withRemote(() => this.baseConnection.isAutoCommit());
|
|
43
45
|
}
|
|
44
|
-
withRemote(workerPromise) {
|
|
46
|
+
withRemote(workerPromise, fireActionOnAbort = false) {
|
|
45
47
|
const controller = this.notifyRemoteClosed;
|
|
46
48
|
if (controller) {
|
|
47
49
|
return new Promise((resolve, reject) => {
|
|
48
50
|
if (controller.signal.aborted) {
|
|
49
51
|
reject(new ConnectionClosedError('Called operation on closed remote'));
|
|
50
|
-
|
|
51
|
-
|
|
52
|
+
if (!fireActionOnAbort) {
|
|
53
|
+
// Don't run the operation if we're going to reject
|
|
54
|
+
// We might want to fire-and-forget the operation in some cases (like a close operation)
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
52
57
|
}
|
|
53
58
|
function handleAbort() {
|
|
54
59
|
reject(new ConnectionClosedError('Remote peer closed with request in flight'));
|
|
@@ -119,11 +124,13 @@ export class WorkerWrappedAsyncDatabaseConnection {
|
|
|
119
124
|
// Abort any pending lock requests.
|
|
120
125
|
this.lockAbortController.abort();
|
|
121
126
|
try {
|
|
122
|
-
|
|
127
|
+
// fire and forget the close operation
|
|
128
|
+
await this.withRemote(() => this.baseConnection.close(), true);
|
|
123
129
|
}
|
|
124
130
|
finally {
|
|
125
131
|
this.options.remote[Comlink.releaseProxy]();
|
|
126
132
|
this.options.onClose?.();
|
|
133
|
+
this.iterateListeners((l) => l.closing?.());
|
|
127
134
|
}
|
|
128
135
|
}
|
|
129
136
|
execute(sql, params) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as SQLite from '@journeyapps/wa-sqlite';
|
|
2
2
|
import { BaseObserver } from '@powersync/common';
|
|
3
3
|
import { Mutex } from 'async-mutex';
|
|
4
|
+
import { OPFSCoopSyncVFS } from '../../../worker/db/opfs';
|
|
4
5
|
/**
|
|
5
6
|
* List of currently tested virtual filesystems
|
|
6
7
|
*/
|
|
@@ -80,11 +81,10 @@ export const DEFAULT_MODULE_FACTORIES = {
|
|
|
80
81
|
else {
|
|
81
82
|
module = await SyncWASQLiteModuleFactory();
|
|
82
83
|
}
|
|
83
|
-
|
|
84
|
-
const { OPFSCoopSyncVFS } = await import('@journeyapps/wa-sqlite/src/examples/OPFSCoopSyncVFS.js');
|
|
84
|
+
const vfs = await OPFSCoopSyncVFS.create(options.dbFileName, module);
|
|
85
85
|
return {
|
|
86
86
|
module,
|
|
87
|
-
vfs:
|
|
87
|
+
vfs: vfs
|
|
88
88
|
};
|
|
89
89
|
}
|
|
90
90
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ILogLevel
|
|
1
|
+
import { DBAdapter, type ILogLevel } from '@powersync/common';
|
|
2
2
|
import { AbstractWebSQLOpenFactory } from '../AbstractWebSQLOpenFactory';
|
|
3
3
|
import { AsyncDatabaseConnection } from '../AsyncDatabaseConnection';
|
|
4
4
|
import { ResolvedWebSQLOpenOptions, WebSQLOpenFactoryOptions } from '../web-sql-flags';
|
|
@@ -2,9 +2,9 @@ import * as Comlink from 'comlink';
|
|
|
2
2
|
import { openWorkerDatabasePort, resolveWorkerDatabasePortFactory } from '../../../worker/db/open-worker-database';
|
|
3
3
|
import { AbstractWebSQLOpenFactory } from '../AbstractWebSQLOpenFactory';
|
|
4
4
|
import { LockedAsyncDatabaseAdapter } from '../LockedAsyncDatabaseAdapter';
|
|
5
|
-
import { DEFAULT_CACHE_SIZE_KB, TemporaryStorageOption } from '../web-sql-flags';
|
|
6
5
|
import { WorkerWrappedAsyncDatabaseConnection } from '../WorkerWrappedAsyncDatabaseConnection';
|
|
7
|
-
import {
|
|
6
|
+
import { DEFAULT_CACHE_SIZE_KB, TemporaryStorageOption } from '../web-sql-flags';
|
|
7
|
+
import { WASQLiteVFS, WASqliteConnection } from './WASQLiteConnection';
|
|
8
8
|
/**
|
|
9
9
|
* Opens a SQLite connection using WA-SQLite.
|
|
10
10
|
*/
|
|
@@ -53,9 +53,5 @@ export declare class SharedWebStreamingSyncImplementation extends WebStreamingSy
|
|
|
53
53
|
dispose(): Promise<void>;
|
|
54
54
|
waitForReady(): Promise<void>;
|
|
55
55
|
updateSubscriptions(subscriptions: SubscribedStream[]): void;
|
|
56
|
-
/**
|
|
57
|
-
* Used in tests to force a connection states
|
|
58
|
-
*/
|
|
59
|
-
private _testUpdateStatus;
|
|
60
56
|
}
|
|
61
57
|
export {};
|
|
@@ -150,6 +150,8 @@ export class SharedWebStreamingSyncImplementation extends WebStreamingSyncImplem
|
|
|
150
150
|
* - The shared worker can then request the same lock. The client has been closed if the shared worker can acquire the lock.
|
|
151
151
|
* - Once the shared worker knows the client's lock, we can guarentee that the shared worker will detect if the client has been closed.
|
|
152
152
|
* - This makes the client safe for the shared worker to use.
|
|
153
|
+
* - The client is only added to the SharedSyncImplementation once the lock has been registered.
|
|
154
|
+
* This ensures we don't ever keep track of dead clients (tabs that closed before the lock was registered).
|
|
153
155
|
* - The client side lock is held until the client is disposed.
|
|
154
156
|
* - We resolve the top-level promise after the lock has been registered with the shared worker.
|
|
155
157
|
* - The client sends the params to the shared worker after locks have been registered.
|
|
@@ -205,7 +207,6 @@ export class SharedWebStreamingSyncImplementation extends WebStreamingSyncImplem
|
|
|
205
207
|
}
|
|
206
208
|
async dispose() {
|
|
207
209
|
await this.waitForReady();
|
|
208
|
-
await super.dispose();
|
|
209
210
|
await new Promise((resolve) => {
|
|
210
211
|
// Listen for the close acknowledgment from the worker
|
|
211
212
|
this.messagePort.addEventListener('message', (event) => {
|
|
@@ -221,6 +222,7 @@ export class SharedWebStreamingSyncImplementation extends WebStreamingSyncImplem
|
|
|
221
222
|
};
|
|
222
223
|
this.messagePort.postMessage(closeMessagePayload);
|
|
223
224
|
});
|
|
225
|
+
await super.dispose();
|
|
224
226
|
this.abortOnClose.abort();
|
|
225
227
|
// Release the proxy
|
|
226
228
|
this.syncManager[Comlink.releaseProxy]();
|
|
@@ -232,11 +234,4 @@ export class SharedWebStreamingSyncImplementation extends WebStreamingSyncImplem
|
|
|
232
234
|
updateSubscriptions(subscriptions) {
|
|
233
235
|
this.syncManager.updateSubscriptions(subscriptions);
|
|
234
236
|
}
|
|
235
|
-
/**
|
|
236
|
-
* Used in tests to force a connection states
|
|
237
|
-
*/
|
|
238
|
-
async _testUpdateStatus(status) {
|
|
239
|
-
await this.isInitialized;
|
|
240
|
-
return this.syncManager._testUpdateAllStatuses(status.toJSON());
|
|
241
|
-
}
|
|
242
237
|
}
|
|
@@ -14,7 +14,6 @@ const DBMap = new Map();
|
|
|
14
14
|
const OPEN_DB_LOCK = 'open-wasqlite-db';
|
|
15
15
|
let nextClientId = 1;
|
|
16
16
|
const openDBShared = async (options) => {
|
|
17
|
-
// Prevent multiple simultaneous opens from causing race conditions
|
|
18
17
|
return getNavigatorLocks().request(OPEN_DB_LOCK, async () => {
|
|
19
18
|
const clientId = nextClientId++;
|
|
20
19
|
const { dbFilename, logLevel } = options;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { FacadeVFS } from '@journeyapps/wa-sqlite/src/FacadeVFS.js';
|
|
2
|
+
export declare class OPFSCoopSyncVFS extends FacadeVFS {
|
|
3
|
+
#private;
|
|
4
|
+
/** @type {Map<number, File>} */ mapIdToFile: Map<any, any>;
|
|
5
|
+
lastError: null;
|
|
6
|
+
log: null;
|
|
7
|
+
/** @type {Map<string, PersistentFile>} */ persistentFiles: Map<any, any>;
|
|
8
|
+
/** @type {Map<string, FileSystemSyncAccessHandle>} */ boundAccessHandles: Map<any, any>;
|
|
9
|
+
/** @type {Set<FileSystemSyncAccessHandle>} */ unboundAccessHandles: Set<unknown>;
|
|
10
|
+
/** @type {Set<string>} */ accessiblePaths: Set<unknown>;
|
|
11
|
+
releaser: null;
|
|
12
|
+
static create(name: any, module: any): Promise<OPFSCoopSyncVFS>;
|
|
13
|
+
constructor(name: any, module: any);
|
|
14
|
+
/**
|
|
15
|
+
* @param {string?} zName
|
|
16
|
+
* @param {number} fileId
|
|
17
|
+
* @param {number} flags
|
|
18
|
+
* @param {DataView} pOutFlags
|
|
19
|
+
* @returns {number}
|
|
20
|
+
*/
|
|
21
|
+
jOpen(zName: any, fileId: any, flags: any, pOutFlags: any): 0 | 5 | 14;
|
|
22
|
+
/**
|
|
23
|
+
* @param {string} zName
|
|
24
|
+
* @param {number} syncDir
|
|
25
|
+
* @returns {number}
|
|
26
|
+
*/
|
|
27
|
+
jDelete(zName: any, syncDir: any): 0 | 2570;
|
|
28
|
+
/**
|
|
29
|
+
* @param {string} zName
|
|
30
|
+
* @param {number} flags
|
|
31
|
+
* @param {DataView} pResOut
|
|
32
|
+
* @returns {number}
|
|
33
|
+
*/
|
|
34
|
+
jAccess(zName: any, flags: any, pResOut: any): 0 | 3338;
|
|
35
|
+
/**
|
|
36
|
+
* @param {number} fileId
|
|
37
|
+
* @returns {number}
|
|
38
|
+
*/
|
|
39
|
+
jClose(fileId: any): 0 | 4106;
|
|
40
|
+
/**
|
|
41
|
+
* @param {number} fileId
|
|
42
|
+
* @param {Uint8Array} pData
|
|
43
|
+
* @param {number} iOffset
|
|
44
|
+
* @returns {number}
|
|
45
|
+
*/
|
|
46
|
+
jRead(fileId: any, pData: any, iOffset: any): 0 | 522 | 266;
|
|
47
|
+
/**
|
|
48
|
+
* @param {number} fileId
|
|
49
|
+
* @param {Uint8Array} pData
|
|
50
|
+
* @param {number} iOffset
|
|
51
|
+
* @returns {number}
|
|
52
|
+
*/
|
|
53
|
+
jWrite(fileId: any, pData: any, iOffset: any): 0 | 778;
|
|
54
|
+
/**
|
|
55
|
+
* @param {number} fileId
|
|
56
|
+
* @param {number} iSize
|
|
57
|
+
* @returns {number}
|
|
58
|
+
*/
|
|
59
|
+
jTruncate(fileId: any, iSize: any): 0 | 1546;
|
|
60
|
+
/**
|
|
61
|
+
* @param {number} fileId
|
|
62
|
+
* @param {number} flags
|
|
63
|
+
* @returns {number}
|
|
64
|
+
*/
|
|
65
|
+
jSync(fileId: any, flags: any): 0 | 1034;
|
|
66
|
+
/**
|
|
67
|
+
* @param {number} fileId
|
|
68
|
+
* @param {DataView} pSize64
|
|
69
|
+
* @returns {number}
|
|
70
|
+
*/
|
|
71
|
+
jFileSize(fileId: any, pSize64: any): 0 | 1802;
|
|
72
|
+
/**
|
|
73
|
+
* @param {number} fileId
|
|
74
|
+
* @param {number} lockType
|
|
75
|
+
* @returns {number}
|
|
76
|
+
*/
|
|
77
|
+
jLock(fileId: any, lockType: any): 0 | 5;
|
|
78
|
+
/**
|
|
79
|
+
* @param {number} fileId
|
|
80
|
+
* @param {number} lockType
|
|
81
|
+
* @returns {number}
|
|
82
|
+
*/
|
|
83
|
+
jUnlock(fileId: any, lockType: any): 0;
|
|
84
|
+
/**
|
|
85
|
+
* @param {number} fileId
|
|
86
|
+
* @param {number} op
|
|
87
|
+
* @param {DataView} pArg
|
|
88
|
+
* @returns {number|Promise<number>}
|
|
89
|
+
*/
|
|
90
|
+
jFileControl(fileId: any, op: any, pArg: any): 10 | 12;
|
|
91
|
+
/**
|
|
92
|
+
* @param {Uint8Array} zBuf
|
|
93
|
+
* @returns
|
|
94
|
+
*/
|
|
95
|
+
jGetLastError(zBuf: any): 0;
|
|
96
|
+
}
|