@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.
Files changed (62) hide show
  1. package/dist/1807036ae51c10ee4d23.wasm +0 -0
  2. package/dist/{10072fe45f0a8fab0a0e.wasm → 307d8ce2280e3bae09d5.wasm} +0 -0
  3. package/dist/{6e435e51534839845554.wasm → cd8b9e8f4c87bf81c169.wasm} +0 -0
  4. package/dist/e797080f5ed0b5324166.wasm +0 -0
  5. package/dist/index.umd.js +2551 -161
  6. package/dist/index.umd.js.map +1 -1
  7. package/dist/worker/SharedSyncImplementation.umd.js +2020 -148
  8. package/dist/worker/SharedSyncImplementation.umd.js.map +1 -1
  9. package/dist/worker/WASQLiteDB.umd.js +1824 -9
  10. package/dist/worker/WASQLiteDB.umd.js.map +1 -1
  11. package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_mc-wa-sqlite-async_mjs.umd.js +2 -2
  12. package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_mc-wa-sqlite-async_mjs.umd.js.map +1 -1
  13. package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_mc-wa-sqlite_mjs.umd.js +2 -2
  14. package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_mc-wa-sqlite_mjs.umd.js.map +1 -1
  15. package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_wa-sqlite-async_mjs.umd.js +2 -2
  16. package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_wa-sqlite-async_mjs.umd.js.map +1 -1
  17. package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_wa-sqlite_mjs.umd.js +2 -2
  18. package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_wa-sqlite_mjs.umd.js.map +1 -1
  19. package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_AccessHandlePoolVFS_js.umd.js +0 -1203
  20. package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_AccessHandlePoolVFS_js.umd.js.map +1 -1
  21. package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js.umd.js +20 -1226
  22. package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js.umd.js.map +1 -1
  23. package/lib/package.json +2 -2
  24. package/lib/src/db/PowerSyncDatabase.d.ts +1 -1
  25. package/lib/src/db/PowerSyncDatabase.js +4 -4
  26. package/lib/src/db/adapters/AsyncDatabaseConnection.d.ts +5 -0
  27. package/lib/src/db/adapters/AsyncDatabaseConnection.js +5 -0
  28. package/lib/src/db/adapters/LockedAsyncDatabaseAdapter.d.ts +10 -2
  29. package/lib/src/db/adapters/LockedAsyncDatabaseAdapter.js +72 -33
  30. package/lib/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.d.ts +5 -1
  31. package/lib/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.js +12 -5
  32. package/lib/src/db/adapters/wa-sqlite/WASQLiteConnection.js +3 -3
  33. package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.d.ts +1 -1
  34. package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.js +2 -2
  35. package/lib/src/db/sync/SharedWebStreamingSyncImplementation.d.ts +0 -4
  36. package/lib/src/db/sync/SharedWebStreamingSyncImplementation.js +3 -8
  37. package/lib/src/worker/db/WASQLiteDB.worker.js +0 -1
  38. package/lib/src/worker/db/opfs.d.ts +96 -0
  39. package/lib/src/worker/db/opfs.js +582 -0
  40. package/lib/src/worker/sync/SharedSyncImplementation.d.ts +6 -11
  41. package/lib/src/worker/sync/SharedSyncImplementation.js +95 -67
  42. package/lib/src/worker/sync/SharedSyncImplementation.worker.js +1 -1
  43. package/lib/src/worker/sync/WorkerClient.d.ts +1 -3
  44. package/lib/src/worker/sync/WorkerClient.js +3 -27
  45. package/lib/tsconfig.tsbuildinfo +1 -1
  46. package/package.json +5 -5
  47. package/src/db/PowerSyncDatabase.ts +13 -15
  48. package/src/db/adapters/AsyncDatabaseConnection.ts +5 -0
  49. package/src/db/adapters/LockedAsyncDatabaseAdapter.ts +91 -51
  50. package/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.ts +16 -4
  51. package/src/db/adapters/wa-sqlite/WASQLiteConnection.ts +3 -4
  52. package/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.ts +3 -3
  53. package/src/db/sync/SharedWebStreamingSyncImplementation.ts +5 -11
  54. package/src/worker/db/WASQLiteDB.worker.ts +0 -2
  55. package/src/worker/db/opfs.ts +623 -0
  56. package/src/worker/sync/SharedSyncImplementation.ts +106 -78
  57. package/src/worker/sync/SharedSyncImplementation.worker.ts +1 -1
  58. package/src/worker/sync/WorkerClient.ts +4 -30
  59. package/dist/a730f7ca717b02234beb.wasm +0 -0
  60. package/dist/aa2f408d64445fed090e.wasm +0 -0
  61. package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_OPFSCoopSyncVFS_js.umd.js +0 -1813
  62. 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
- // Don't run the operation if we're going to reject
51
- return;
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
- await this.withRemote(() => this.baseConnection.close());
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
- // @ts-expect-error The types for this static method are missing upstream
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: await OPFSCoopSyncVFS.create(options.dbFileName, module)
87
+ vfs: vfs
88
88
  };
89
89
  }
90
90
  };
@@ -1,4 +1,4 @@
1
- import { type ILogLevel, DBAdapter } from '@powersync/common';
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 { WASqliteConnection, WASQLiteVFS } from './WASQLiteConnection';
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
+ }