@powersync/web 1.31.0 → 1.32.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/dist/_journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_AccessHandlePoolVFS_js-_journeyapp-89f0ba.index.umd.js +1867 -0
- package/dist/_journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_AccessHandlePoolVFS_js-_journeyapp-89f0ba.index.umd.js.map +1 -0
- package/dist/_journeyapps_wa-sqlite_src_examples_AccessHandlePoolVFS_js-_journeyapps_wa-sqlite_src_example-2530150.index.umd.js +555 -0
- package/dist/_journeyapps_wa-sqlite_src_examples_AccessHandlePoolVFS_js-_journeyapps_wa-sqlite_src_example-2530150.index.umd.js.map +1 -0
- package/dist/_journeyapps_wa-sqlite_src_examples_AccessHandlePoolVFS_js-_journeyapps_wa-sqlite_src_example-2530151.index.umd.js +555 -0
- package/dist/_journeyapps_wa-sqlite_src_examples_AccessHandlePoolVFS_js-_journeyapps_wa-sqlite_src_example-2530151.index.umd.js.map +1 -0
- package/dist/index.umd.js +4575 -43416
- package/dist/index.umd.js.map +1 -1
- package/dist/worker/SharedSyncImplementation.umd.js +402 -2053
- package/dist/worker/SharedSyncImplementation.umd.js.map +1 -1
- package/dist/worker/WASQLiteDB.umd.js +449 -2104
- package/dist/worker/WASQLiteDB.umd.js.map +1 -1
- package/dist/worker/{node_modules_bson_lib_bson_mjs.umd.js → node_modules_pnpm_bson_6_10_4_node_modules_bson_lib_bson_mjs.umd.js} +6 -6
- package/dist/worker/node_modules_pnpm_bson_6_10_4_node_modules_bson_lib_bson_mjs.umd.js.map +1 -0
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_4_1_node_modules_journeyapps_wa-sqlite_dist_mc-wa-s-3a94cf.umd.js +44 -0
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_4_1_node_modules_journeyapps_wa-sqlite_dist_mc-wa-s-3a94cf.umd.js.map +1 -0
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_4_1_node_modules_journeyapps_wa-sqlite_dist_mc-wa-s-868779.umd.js +44 -0
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_4_1_node_modules_journeyapps_wa-sqlite_dist_mc-wa-s-868779.umd.js.map +1 -0
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_4_1_node_modules_journeyapps_wa-sqlite_dist_wa-sqli-f60d0d.umd.js +44 -0
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_4_1_node_modules_journeyapps_wa-sqlite_dist_wa-sqli-f60d0d.umd.js.map +1 -0
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_4_1_node_modules_journeyapps_wa-sqlite_dist_wa-sqlite_mjs.umd.js +44 -0
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_4_1_node_modules_journeyapps_wa-sqlite_dist_wa-sqlite_mjs.umd.js.map +1 -0
- package/dist/worker/{node_modules_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js.umd.js → node_modules_pnpm_journeyapps_wa-sqlite_1_4_1_node_modules_journeyapps_wa-sqlite_src_examples-0d2437.umd.js} +24 -24
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_4_1_node_modules_journeyapps_wa-sqlite_src_examples-0d2437.umd.js.map +1 -0
- package/dist/worker/{node_modules_journeyapps_wa-sqlite_src_examples_OPFSCoopSyncVFS_js.umd.js → node_modules_pnpm_journeyapps_wa-sqlite_1_4_1_node_modules_journeyapps_wa-sqlite_src_examples-1d4e74.umd.js} +18 -18
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_4_1_node_modules_journeyapps_wa-sqlite_src_examples-1d4e74.umd.js.map +1 -0
- package/dist/worker/{node_modules_journeyapps_wa-sqlite_src_examples_AccessHandlePoolVFS_js.umd.js → node_modules_pnpm_journeyapps_wa-sqlite_1_4_1_node_modules_journeyapps_wa-sqlite_src_examples-3622cf.umd.js} +18 -18
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_4_1_node_modules_journeyapps_wa-sqlite_src_examples-3622cf.umd.js.map +1 -0
- package/lib/package.json +26 -22
- package/lib/src/db/NavigatorTriggerClaimManager.d.ts +6 -0
- package/lib/src/db/NavigatorTriggerClaimManager.js +20 -0
- package/lib/src/db/PowerSyncDatabase.d.ts +5 -2
- package/lib/src/db/PowerSyncDatabase.js +46 -8
- package/lib/src/db/adapters/AbstractWebPowerSyncDatabaseOpenFactory.d.ts +1 -1
- package/lib/src/db/adapters/AbstractWebPowerSyncDatabaseOpenFactory.js +1 -1
- package/lib/src/db/adapters/AbstractWebSQLOpenFactory.d.ts +2 -2
- package/lib/src/db/adapters/AbstractWebSQLOpenFactory.js +2 -2
- package/lib/src/db/adapters/AsyncDatabaseConnection.d.ts +1 -1
- package/lib/src/db/adapters/LockedAsyncDatabaseAdapter.d.ts +4 -4
- package/lib/src/db/adapters/LockedAsyncDatabaseAdapter.js +8 -4
- package/lib/src/db/adapters/WebDBAdapter.d.ts +5 -2
- package/lib/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.d.ts +2 -2
- package/lib/src/db/adapters/wa-sqlite/InternalWASQLiteDBAdapter.d.ts +12 -0
- package/lib/src/db/adapters/wa-sqlite/InternalWASQLiteDBAdapter.js +19 -0
- package/lib/src/db/adapters/wa-sqlite/WASQLiteConnection.d.ts +2 -2
- package/lib/src/db/adapters/wa-sqlite/WASQLiteDBAdapter.d.ts +4 -4
- package/lib/src/db/adapters/wa-sqlite/WASQLiteDBAdapter.js +6 -6
- package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.d.ts +4 -4
- package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.js +7 -7
- package/lib/src/db/adapters/wa-sqlite/WASQLitePowerSyncDatabaseOpenFactory.d.ts +1 -1
- package/lib/src/db/adapters/wa-sqlite/WASQLitePowerSyncDatabaseOpenFactory.js +3 -3
- package/lib/src/db/sync/SharedWebStreamingSyncImplementation.d.ts +5 -5
- package/lib/src/db/sync/SharedWebStreamingSyncImplementation.js +5 -5
- package/lib/src/db/sync/WebRemote.js +1 -1
- package/lib/src/db/sync/WebStreamingSyncImplementation.d.ts +1 -1
- package/lib/src/db/sync/WebStreamingSyncImplementation.js +1 -1
- package/lib/src/index.d.ts +12 -12
- package/lib/src/index.js +12 -12
- package/lib/src/worker/db/SharedWASQLiteConnection.d.ts +2 -2
- package/lib/src/worker/db/WASQLiteDB.worker.js +3 -3
- package/lib/src/worker/db/WorkerWASQLiteConnection.d.ts +2 -2
- package/lib/src/worker/db/WorkerWASQLiteConnection.js +1 -1
- package/lib/src/worker/db/open-worker-database.d.ts +2 -2
- package/lib/src/worker/db/open-worker-database.js +1 -1
- package/lib/src/worker/sync/BroadcastLogger.d.ts +1 -1
- package/lib/src/worker/sync/SharedSyncImplementation.d.ts +4 -4
- package/lib/src/worker/sync/SharedSyncImplementation.js +5 -5
- package/lib/src/worker/sync/SharedSyncImplementation.worker.js +2 -2
- package/lib/src/worker/sync/WorkerClient.d.ts +1 -1
- package/lib/src/worker/sync/WorkerClient.js +2 -2
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +21 -17
- package/src/db/NavigatorTriggerClaimManager.ts +23 -0
- package/src/db/PowerSyncDatabase.ts +53 -9
- package/src/db/adapters/AbstractWebPowerSyncDatabaseOpenFactory.ts +1 -1
- package/src/db/adapters/AbstractWebSQLOpenFactory.ts +3 -3
- package/src/db/adapters/AsyncDatabaseConnection.ts +1 -1
- package/src/db/adapters/LockedAsyncDatabaseAdapter.ts +13 -9
- package/src/db/adapters/WebDBAdapter.ts +6 -2
- package/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.ts +2 -2
- package/src/db/adapters/wa-sqlite/InternalWASQLiteDBAdapter.ts +23 -0
- package/src/db/adapters/wa-sqlite/WASQLiteConnection.ts +2 -2
- package/src/db/adapters/wa-sqlite/WASQLiteDBAdapter.ts +8 -8
- package/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.ts +8 -8
- package/src/db/adapters/wa-sqlite/WASQLitePowerSyncDatabaseOpenFactory.ts +3 -3
- package/src/db/sync/SharedWebStreamingSyncImplementation.ts +7 -7
- package/src/db/sync/WebRemote.ts +1 -1
- package/src/db/sync/WebStreamingSyncImplementation.ts +2 -2
- package/src/index.ts +12 -12
- package/src/worker/db/SharedWASQLiteConnection.ts +2 -2
- package/src/worker/db/WASQLiteDB.worker.ts +5 -5
- package/src/worker/db/WorkerWASQLiteConnection.ts +2 -2
- package/src/worker/db/open-worker-database.ts +2 -2
- package/src/worker/sync/BroadcastLogger.ts +1 -1
- package/src/worker/sync/SharedSyncImplementation.ts +9 -9
- package/src/worker/sync/SharedSyncImplementation.worker.ts +2 -2
- package/src/worker/sync/WorkerClient.ts +2 -2
- package/dist/worker/node_modules_bson_lib_bson_mjs.umd.js.map +0 -1
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_mc-wa-sqlite-async_mjs.umd.js +0 -44
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_mc-wa-sqlite-async_mjs.umd.js.map +0 -1
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_mc-wa-sqlite_mjs.umd.js +0 -44
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_mc-wa-sqlite_mjs.umd.js.map +0 -1
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_wa-sqlite-async_mjs.umd.js +0 -44
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_wa-sqlite-async_mjs.umd.js.map +0 -1
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_wa-sqlite_mjs.umd.js +0 -44
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_wa-sqlite_mjs.umd.js.map +0 -1
- package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_AccessHandlePoolVFS_js.umd.js.map +0 -1
- package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js.umd.js.map +0 -1
- package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_OPFSCoopSyncVFS_js.umd.js.map +0 -1
- /package/bin/{powersync.js → powersync.cjs} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_AccessHandlePoolVFS_js-_journeyapp-89f0ba.index.umd.js","mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACrYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;AClJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;AC3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AC/DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;AC/HA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;AC9eA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;ACnFA;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AC3BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACRA;AACA;AACA;AACA;AACA;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACPA;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACpCA;AACA;AACA;AACA;AACA;AACA;;;;;AELA;AACA","sources":["webpack://sdk_web/webpack/universalModuleDefinition","webpack://sdk_web/./lib/src/db/adapters/LockedAsyncDatabaseAdapter.js","webpack://sdk_web/./lib/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.js","webpack://sdk_web/./lib/src/db/sync/WebRemote.js","webpack://sdk_web/./lib/src/db/sync/WebStreamingSyncImplementation.js","webpack://sdk_web/./lib/src/db/sync/userAgent.js","webpack://sdk_web/./lib/src/worker/sync/BroadcastLogger.js","webpack://sdk_web/./lib/src/worker/sync/SharedSyncImplementation.js","webpack://sdk_web/./lib/src/worker/sync/SharedSyncImplementation.worker.js","webpack://sdk_web/./lib/src/worker/sync/WorkerClient.js","webpack://sdk_web/external umd \"@journeyapps/wa-sqlite\"","webpack://sdk_web/external umd \"@journeyapps/wa-sqlite/src/examples/AccessHandlePoolVFS.js\"","webpack://sdk_web/external umd \"@journeyapps/wa-sqlite/src/examples/IDBBatchAtomicVFS.js\"","webpack://sdk_web/external umd \"@journeyapps/wa-sqlite/src/examples/OPFSCoopSyncVFS.js\"","webpack://sdk_web/external umd \"@powersync/common\"","webpack://sdk_web/external umd \"async-mutex\"","webpack://sdk_web/external umd \"comlink\"","webpack://sdk_web/webpack/bootstrap","webpack://sdk_web/webpack/runtime/chunk loaded","webpack://sdk_web/webpack/runtime/create fake namespace object","webpack://sdk_web/webpack/runtime/define property getters","webpack://sdk_web/webpack/runtime/ensure chunk","webpack://sdk_web/webpack/runtime/get javascript chunk filename","webpack://sdk_web/webpack/runtime/global","webpack://sdk_web/webpack/runtime/hasOwnProperty shorthand","webpack://sdk_web/webpack/runtime/make namespace object","webpack://sdk_web/webpack/runtime/publicPath","webpack://sdk_web/webpack/runtime/importScripts chunk loading","webpack://sdk_web/webpack/runtime/startup chunk dependencies","webpack://sdk_web/webpack/before-startup","webpack://sdk_web/webpack/startup","webpack://sdk_web/webpack/after-startup"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"@powersync/common\"), require(\"async-mutex\"), require(\"comlink\"), require(\"@journeyapps/wa-sqlite\"), require(\"@journeyapps/wa-sqlite/src/examples/OPFSCoopSyncVFS.js\"), require(\"@journeyapps/wa-sqlite/src/examples/AccessHandlePoolVFS.js\"), require(\"@journeyapps/wa-sqlite/src/examples/IDBBatchAtomicVFS.js\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"@powersync/common\", \"async-mutex\", \"comlink\", \"@journeyapps/wa-sqlite\", \"@journeyapps/wa-sqlite/src/examples/OPFSCoopSyncVFS.js\", \"@journeyapps/wa-sqlite/src/examples/AccessHandlePoolVFS.js\", \"@journeyapps/wa-sqlite/src/examples/IDBBatchAtomicVFS.js\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"sdk_web\"] = factory(require(\"@powersync/common\"), require(\"async-mutex\"), require(\"comlink\"), require(\"@journeyapps/wa-sqlite\"), require(\"@journeyapps/wa-sqlite/src/examples/OPFSCoopSyncVFS.js\"), require(\"@journeyapps/wa-sqlite/src/examples/AccessHandlePoolVFS.js\"), require(\"@journeyapps/wa-sqlite/src/examples/IDBBatchAtomicVFS.js\"));\n\telse\n\t\troot[\"sdk_web\"] = factory(root[\"@powersync/common\"], root[\"async-mutex\"], root[\"comlink\"], root[\"@journeyapps/wa-sqlite\"], root[\"@journeyapps/wa-sqlite/src/examples/OPFSCoopSyncVFS.js\"], root[\"@journeyapps/wa-sqlite/src/examples/AccessHandlePoolVFS.js\"], root[\"@journeyapps/wa-sqlite/src/examples/IDBBatchAtomicVFS.js\"]);\n})(self, (__WEBPACK_EXTERNAL_MODULE__powersync_common__, __WEBPACK_EXTERNAL_MODULE_async_mutex__, __WEBPACK_EXTERNAL_MODULE_comlink__, __WEBPACK_EXTERNAL_MODULE__journeyapps_wa_sqlite__, __WEBPACK_EXTERNAL_MODULE__journeyapps_wa_sqlite_src_examples_OPFSCoopSyncVFS_js__, __WEBPACK_EXTERNAL_MODULE__journeyapps_wa_sqlite_src_examples_AccessHandlePoolVFS_js__, __WEBPACK_EXTERNAL_MODULE__journeyapps_wa_sqlite_src_examples_IDBBatchAtomicVFS_js__) => {\nreturn ","import { BaseObserver, ConnectionClosedError, createLogger } from '@powersync/common';\nimport { getNavigatorLocks } from '../../shared/navigator.js';\nimport { WorkerWrappedAsyncDatabaseConnection } from './WorkerWrappedAsyncDatabaseConnection.js';\nimport { WASQLiteVFS } from './wa-sqlite/WASQLiteConnection.js';\n/**\n * @internal\n * Wraps a {@link AsyncDatabaseConnection} and provides exclusive locking functions in\n * order to implement {@link DBAdapter}.\n */\nexport class LockedAsyncDatabaseAdapter extends BaseObserver {\n options;\n logger;\n dbGetHelpers;\n debugMode;\n _dbIdentifier;\n initPromise;\n _db = null;\n _disposeTableChangeListener = null;\n _config = null;\n pendingAbortControllers;\n requiresHolds;\n databaseOpenPromise = null;\n closing;\n closed;\n constructor(options) {\n super();\n this.options = options;\n this._dbIdentifier = options.name;\n this.logger = options.logger ?? createLogger(`LockedAsyncDatabaseAdapter - ${this._dbIdentifier}`);\n this.pendingAbortControllers = new Set();\n this.closed = false;\n this.closing = false;\n this.requiresHolds = null;\n // Set the name if provided. We can query for the name if not available yet\n this.debugMode = options.debugMode ?? false;\n if (this.debugMode) {\n const originalExecute = this._execute.bind(this);\n this._execute = async (sql, bindings) => {\n const start = performance.now();\n try {\n const r = await originalExecute(sql, bindings);\n performance.measure(`[SQL] ${sql}`, { start });\n return r;\n }\n catch (e) {\n performance.measure(`[SQL] [ERROR: ${e.message}] ${sql}`, { start });\n throw e;\n }\n };\n }\n this.dbGetHelpers = this.generateDBHelpers({\n execute: (query, params) => this.acquireLock(() => this._execute(query, params)),\n executeRaw: (query, params) => this.acquireLock(() => this._executeRaw(query, params))\n });\n this.initPromise = this._init();\n }\n get baseDB() {\n if (!this._db) {\n throw new Error(`Initialization has not completed yet. Cannot access base db`);\n }\n return this._db;\n }\n get name() {\n return this._dbIdentifier;\n }\n /**\n * Init is automatic, this helps catch errors or explicitly await initialization\n */\n async init() {\n return this.initPromise;\n }\n async openInternalDB() {\n /**\n * Execute opening of the db in a lock in order not to interfere with other operations.\n */\n return this._acquireLock(async () => {\n // Dispose any previous table change listener.\n this._disposeTableChangeListener?.();\n this._disposeTableChangeListener = null;\n this._db?.close().catch((ex) => this.logger.warn(`Error closing database before opening new instance`, ex));\n const isReOpen = !!this._db;\n this._db = null;\n this._db = await this.options.openConnection();\n await this._db.init();\n this._config = await this._db.getConfig();\n await this.registerOnChangeListener(this._db);\n if (isReOpen) {\n this.iterateListeners((cb) => cb.databaseReOpened?.());\n }\n /**\n * This is only required for the long-lived shared IndexedDB connections.\n */\n this.requiresHolds = this._config.vfs == WASQLiteVFS.IDBBatchAtomicVFS;\n });\n }\n _reOpen() {\n this.databaseOpenPromise = this.openInternalDB().finally(() => {\n this.databaseOpenPromise = null;\n });\n return this.databaseOpenPromise;\n }\n /**\n * Re-opens the underlying database.\n * Returns a pending operation if one is already in progress.\n */\n async reOpenInternalDB() {\n if (!this.options.reOpenOnConnectionClosed) {\n throw new Error(`Cannot re-open underlying database, reOpenOnConnectionClosed is not enabled`);\n }\n if (this.databaseOpenPromise) {\n return this.databaseOpenPromise;\n }\n return this._reOpen();\n }\n async _init() {\n /**\n * For OPFS, we can see this open call sometimes fail due to NoModificationAllowedError.\n * We should be able to recover from this by re-opening the database.\n */\n const maxAttempts = 3;\n for (let count = 0; count < maxAttempts; count++) {\n try {\n await this.openInternalDB();\n break;\n }\n catch (ex) {\n if (count == maxAttempts - 1) {\n throw ex;\n }\n this.logger.warn(`Attempt ${count + 1} of ${maxAttempts} to open database failed, retrying in 1 second...`, ex);\n await new Promise((resolve) => setTimeout(resolve, 1000));\n }\n }\n this.iterateListeners((cb) => cb.initialized?.());\n }\n getConfiguration() {\n if (!this._config) {\n throw new Error(`Cannot get config before initialization is completed`);\n }\n return {\n ...this._config,\n // This can be overridden by the adapter later\n requiresPersistentTriggers: false\n };\n }\n async waitForInitialized() {\n // Awaiting this will expose errors on function calls like .execute etc\n await this.initPromise;\n }\n async shareConnection() {\n if (false == this._db instanceof WorkerWrappedAsyncDatabaseConnection) {\n throw new Error(`Only worker connections can be shared`);\n }\n return this._db.shareConnection();\n }\n /**\n * Registers a table change notification callback with the base database.\n * This can be extended by custom implementations in order to handle proxy events.\n */\n async registerOnChangeListener(db) {\n this._disposeTableChangeListener = await db.registerOnTableChange((event) => {\n this.iterateListeners((cb) => cb.tablesUpdated?.(event));\n });\n }\n /**\n * This is currently a no-op on web\n */\n async refreshSchema() { }\n async execute(query, params) {\n return this.writeLock((ctx) => ctx.execute(query, params));\n }\n async executeRaw(query, params) {\n return this.writeLock((ctx) => ctx.executeRaw(query, params));\n }\n async executeBatch(query, params) {\n return this.writeLock((ctx) => this._executeBatch(query, params));\n }\n /**\n * Attempts to close the connection.\n * Shared workers might not actually close the connection if other\n * tabs are still using it.\n */\n async close() {\n this.closing = true;\n /**\n * Note that we obtain a reference to the callback to avoid calling the callback with `this` as the context.\n * This is to avoid Comlink attempting to clone `this` when calling the method.\n */\n const dispose = this._disposeTableChangeListener;\n if (dispose) {\n dispose();\n }\n this.pendingAbortControllers.forEach((controller) => controller.abort('Closed'));\n await this.baseDB?.close?.();\n this.closed = true;\n }\n async getAll(sql, parameters) {\n await this.waitForInitialized();\n return this.dbGetHelpers.getAll(sql, parameters);\n }\n async getOptional(sql, parameters) {\n await this.waitForInitialized();\n return this.dbGetHelpers.getOptional(sql, parameters);\n }\n async get(sql, parameters) {\n await this.waitForInitialized();\n return this.dbGetHelpers.get(sql, parameters);\n }\n async readLock(fn, options) {\n await this.waitForInitialized();\n return this.acquireLock(async () => fn(this.generateDBHelpers({ execute: this._execute, executeRaw: this._executeRaw })), {\n timeoutMs: options?.timeoutMs ?? this.options.defaultLockTimeoutMs\n });\n }\n async writeLock(fn, options) {\n await this.waitForInitialized();\n return this.acquireLock(async () => fn(this.generateDBHelpers({ execute: this._execute, executeRaw: this._executeRaw })), {\n timeoutMs: options?.timeoutMs ?? this.options.defaultLockTimeoutMs\n });\n }\n async _acquireLock(callback, options) {\n if (this.closing) {\n throw new Error(`Cannot acquire lock, the database is closing`);\n }\n const abortController = new AbortController();\n this.pendingAbortControllers.add(abortController);\n const { timeoutMs } = options ?? {};\n const timeoutId = timeoutMs\n ? setTimeout(() => {\n abortController.abort(`Timeout after ${timeoutMs}ms`);\n this.pendingAbortControllers.delete(abortController);\n }, timeoutMs)\n : null;\n return getNavigatorLocks().request(`db-lock-${this._dbIdentifier}`, { signal: abortController.signal }, async () => {\n this.pendingAbortControllers.delete(abortController);\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n return await callback();\n });\n }\n async acquireLock(callback, options) {\n await this.waitForInitialized();\n // The database is being opened in the background. Wait for it here.\n if (this.databaseOpenPromise) {\n await this.databaseOpenPromise;\n }\n return this._acquireLock(async () => {\n let holdId = null;\n try {\n /**\n * We can't await this since it uses the same lock as we're in now.\n * If there is a pending open, this call will throw.\n * If there is no pending open, but there is also no database - the open\n * might have failed. We need to re-open the database.\n */\n if (this.databaseOpenPromise || !this._db) {\n throw new ConnectionClosedError('Connection is busy re-opening');\n }\n holdId = this.requiresHolds ? await this.baseDB.markHold() : null;\n return await callback();\n }\n catch (ex) {\n if (ConnectionClosedError.MATCHES(ex)) {\n if (this.options.reOpenOnConnectionClosed && !this.databaseOpenPromise && !this.closing) {\n // Immediately re-open the database. We need to miss as little table updates as possible.\n // Note, don't await this since it uses the same lock as we're in now.\n this.reOpenInternalDB();\n }\n }\n throw ex;\n }\n finally {\n if (holdId) {\n await this.baseDB.releaseHold(holdId);\n }\n }\n }, options);\n }\n async readTransaction(fn, options) {\n return this.readLock(this.wrapTransaction(fn));\n }\n writeTransaction(fn, options) {\n return this.writeLock(this.wrapTransaction(fn, true));\n }\n generateDBHelpers(tx) {\n return {\n ...tx,\n /**\n * Execute a read-only query and return results\n */\n async getAll(sql, parameters) {\n const res = await tx.execute(sql, parameters);\n return res.rows?._array ?? [];\n },\n /**\n * Execute a read-only query and return the first result, or null if the ResultSet is empty.\n */\n async getOptional(sql, parameters) {\n const res = await tx.execute(sql, parameters);\n return res.rows?.item(0) ?? null;\n },\n /**\n * Execute a read-only query and return the first result, error if the ResultSet is empty.\n */\n async get(sql, parameters) {\n const res = await tx.execute(sql, parameters);\n const first = res.rows?.item(0);\n if (!first) {\n throw new Error('Result set is empty');\n }\n return first;\n }\n };\n }\n /**\n * Wraps a lock context into a transaction context\n */\n wrapTransaction(cb, write = false) {\n return async (tx) => {\n await this._execute(write ? 'BEGIN EXCLUSIVE' : 'BEGIN');\n let finalized = false;\n const commit = async () => {\n if (finalized) {\n return { rowsAffected: 0 };\n }\n finalized = true;\n return this._execute('COMMIT');\n };\n const rollback = () => {\n finalized = true;\n return this._execute('ROLLBACK');\n };\n try {\n const result = await cb({\n ...tx,\n commit,\n rollback\n });\n if (!finalized) {\n await commit();\n }\n return result;\n }\n catch (ex) {\n this.logger.debug('Caught ex in transaction', ex);\n try {\n await rollback();\n }\n catch (ex2) {\n // In rare cases, a rollback may fail.\n // Safe to ignore.\n }\n throw ex;\n }\n };\n }\n /**\n * Wraps the worker execute function, awaiting for it to be available\n */\n _execute = async (sql, bindings) => {\n await this.waitForInitialized();\n const result = await this.baseDB.execute(sql, bindings);\n return {\n ...result,\n rows: {\n ...result.rows,\n item: (idx) => result.rows._array[idx]\n }\n };\n };\n /**\n * Wraps the worker executeRaw function, awaiting for it to be available\n */\n _executeRaw = async (sql, bindings) => {\n await this.waitForInitialized();\n return await this.baseDB.executeRaw(sql, bindings);\n };\n /**\n * Wraps the worker executeBatch function, awaiting for it to be available\n */\n _executeBatch = async (query, params) => {\n await this.waitForInitialized();\n const result = await this.baseDB.executeBatch(query, params);\n return {\n ...result,\n rows: undefined\n };\n };\n}\n","import { BaseObserver, ConnectionClosedError } from '@powersync/common';\nimport * as Comlink from 'comlink';\n/**\n * Wraps a provided instance of {@link AsyncDatabaseConnection}, providing necessary proxy\n * functions for worker listeners.\n */\nexport class WorkerWrappedAsyncDatabaseConnection extends BaseObserver {\n options;\n lockAbortController = new AbortController();\n notifyRemoteClosed;\n constructor(options) {\n super();\n this.options = options;\n if (options.remoteCanCloseUnexpectedly) {\n this.notifyRemoteClosed = new AbortController();\n }\n }\n get baseConnection() {\n return this.options.baseConnection;\n }\n init() {\n return this.baseConnection.init();\n }\n /**\n * Marks the remote as closed.\n *\n * This can sometimes happen outside of our control, e.g. when a shared worker requests a connection from a tab. When\n * it happens, all methods on the {@link baseConnection} would never resolve. To avoid livelocks in this scenario, we\n * throw on all outstanding promises and forbid new calls.\n */\n markRemoteClosed() {\n // Can non-null assert here because this function is only supposed to be called when remoteCanCloseUnexpectedly was\n // set.\n this.notifyRemoteClosed.abort();\n }\n markHold() {\n return this.withRemote(() => this.baseConnection.markHold());\n }\n releaseHold(holdId) {\n return this.withRemote(() => this.baseConnection.releaseHold(holdId));\n }\n isAutoCommit() {\n return this.withRemote(() => this.baseConnection.isAutoCommit());\n }\n withRemote(workerPromise, fireActionOnAbort = false) {\n const controller = this.notifyRemoteClosed;\n if (controller) {\n return new Promise((resolve, reject) => {\n if (controller.signal.aborted) {\n reject(new ConnectionClosedError('Called operation on closed remote'));\n if (!fireActionOnAbort) {\n // Don't run the operation if we're going to reject\n // We might want to fire-and-forget the operation in some cases (like a close operation)\n return;\n }\n }\n function handleAbort() {\n reject(new ConnectionClosedError('Remote peer closed with request in flight'));\n }\n function completePromise(action) {\n controller.signal.removeEventListener('abort', handleAbort);\n action();\n }\n controller.signal.addEventListener('abort', handleAbort);\n workerPromise()\n .then((data) => completePromise(() => resolve(data)))\n .catch((e) => completePromise(() => reject(e)));\n });\n }\n else {\n // Can't close, so just return the inner worker promise unguarded.\n return workerPromise();\n }\n }\n /**\n * Get a MessagePort which can be used to share the internals of this connection.\n */\n async shareConnection() {\n const { identifier, remote } = this.options;\n /**\n * Hold a navigator lock in order to avoid features such as Chrome's frozen tabs,\n * or Edge's sleeping tabs from pausing the thread for this connection.\n * This promise resolves once a lock is obtained.\n * This lock will be held as long as this connection is open.\n * The `shareConnection` method should not be called on multiple tabs concurrently.\n */\n await new Promise((resolve, reject) => navigator.locks\n .request(`shared-connection-${this.options.identifier}-${Date.now()}-${Math.round(Math.random() * 10000)}`, {\n signal: this.lockAbortController.signal\n }, async () => {\n resolve();\n // Free the lock when the connection is already closed.\n if (this.lockAbortController.signal.aborted) {\n return;\n }\n // Hold the lock while the shared connection is in use.\n await new Promise((releaseLock) => {\n this.lockAbortController.signal.addEventListener('abort', () => {\n releaseLock();\n });\n });\n })\n // We aren't concerned with abort errors here\n .catch((ex) => {\n if (ex.name == 'AbortError') {\n resolve();\n }\n else {\n reject(ex);\n }\n }));\n const newPort = await remote[Comlink.createEndpoint]();\n return { port: newPort, identifier };\n }\n /**\n * Registers a table change notification callback with the base database.\n * This can be extended by custom implementations in order to handle proxy events.\n */\n async registerOnTableChange(callback) {\n return this.baseConnection.registerOnTableChange(Comlink.proxy(callback));\n }\n async close() {\n // Abort any pending lock requests.\n this.lockAbortController.abort();\n try {\n // fire and forget the close operation\n await this.withRemote(() => this.baseConnection.close(), true);\n }\n finally {\n this.options.remote[Comlink.releaseProxy]();\n this.options.onClose?.();\n this.iterateListeners((l) => l.closing?.());\n }\n }\n execute(sql, params) {\n return this.withRemote(() => this.baseConnection.execute(sql, params));\n }\n executeRaw(sql, params) {\n return this.withRemote(() => this.baseConnection.executeRaw(sql, params));\n }\n executeBatch(sql, params) {\n return this.withRemote(() => this.baseConnection.executeBatch(sql, params));\n }\n getConfig() {\n return this.withRemote(() => this.baseConnection.getConfig());\n }\n}\n","import { AbstractRemote, DEFAULT_REMOTE_LOGGER, FetchImplementationProvider } from '@powersync/common';\nimport { getUserAgentInfo } from './userAgent.js';\n/*\n * Depends on browser's implementation of global fetch.\n */\nclass WebFetchProvider extends FetchImplementationProvider {\n getFetch() {\n return fetch.bind(globalThis);\n }\n}\nexport class WebRemote extends AbstractRemote {\n connector;\n logger;\n _bson;\n constructor(connector, logger = DEFAULT_REMOTE_LOGGER, options) {\n super(connector, logger, {\n ...(options ?? {}),\n fetchImplementation: options?.fetchImplementation ?? new WebFetchProvider()\n });\n this.connector = connector;\n this.logger = logger;\n }\n getUserAgent() {\n let ua = [super.getUserAgent(), `powersync-web`];\n try {\n ua.push(...getUserAgentInfo());\n }\n catch (e) {\n this.logger.warn('Failed to get user agent info', e);\n }\n return ua.join(' ');\n }\n async getBSON() {\n if (this._bson) {\n return this._bson;\n }\n /**\n * Dynamic import to be used only when needed.\n */\n const { BSON } = await import('bson');\n this._bson = BSON;\n return this._bson;\n }\n}\n","import { AbstractStreamingSyncImplementation, LockType } from '@powersync/common';\nimport { getNavigatorLocks } from '../../shared/navigator.js';\nexport class WebStreamingSyncImplementation extends AbstractStreamingSyncImplementation {\n constructor(options) {\n // Super will store and provide default values for options\n super(options);\n }\n get webOptions() {\n return this.options;\n }\n async obtainLock(lockOptions) {\n const identifier = `streaming-sync-${lockOptions.type}-${this.webOptions.identifier}`;\n if (lockOptions.type == LockType.SYNC) {\n this.logger.debug('requesting lock for ', identifier);\n }\n return getNavigatorLocks().request(identifier, { signal: lockOptions.signal }, lockOptions.callback);\n }\n}\n","/**\n * Get a minimal representation of browser, version and operating system.\n *\n * The goal is to get enough environemnt info to reproduce issues, but no\n * more.\n */\nexport function getUserAgentInfo(nav) {\n nav ??= navigator;\n const browser = getBrowserInfo(nav);\n const os = getOsInfo(nav);\n // The cast below is to cater for TypeScript < 5.5.0\n return [browser, os].filter((v) => v != null);\n}\nfunction getBrowserInfo(nav) {\n const brands = nav.userAgentData?.brands;\n if (brands != null) {\n const tests = [\n { name: 'Google Chrome', value: 'Chrome' },\n { name: 'Opera', value: 'Opera' },\n { name: 'Edge', value: 'Edge' },\n { name: 'Chromium', value: 'Chromium' }\n ];\n for (let { name, value } of tests) {\n const brand = brands.find((b) => b.brand == name);\n if (brand != null) {\n return `${value}/${brand.version}`;\n }\n }\n }\n const ua = nav.userAgent;\n const regexps = [\n { re: /(?:firefox|fxios)\\/(\\d+)/i, value: 'Firefox' },\n { re: /(?:edg|edge|edga|edgios)\\/(\\d+)/i, value: 'Edge' },\n { re: /opr\\/(\\d+)/i, value: 'Opera' },\n { re: /(?:chrome|chromium|crios)\\/(\\d+)/i, value: 'Chrome' },\n { re: /version\\/(\\d+).*safari/i, value: 'Safari' }\n ];\n for (let { re, value } of regexps) {\n const match = re.exec(ua);\n if (match != null) {\n return `${value}/${match[1]}`;\n }\n }\n return null;\n}\nfunction getOsInfo(nav) {\n if (nav.userAgentData?.platform != null) {\n return nav.userAgentData.platform.toLowerCase();\n }\n const ua = nav.userAgent;\n const regexps = [\n { re: /windows/i, value: 'windows' },\n { re: /android/i, value: 'android' },\n { re: /linux/i, value: 'linux' },\n { re: /iphone|ipad|ipod/i, value: 'ios' },\n { re: /macintosh|mac os x/i, value: 'macos' }\n ];\n for (let { re, value } of regexps) {\n if (re.test(ua)) {\n return value;\n }\n }\n return null;\n}\n","import { LogLevel } from '@powersync/common';\n/**\n * Broadcasts logs to all clients\n */\nexport class BroadcastLogger {\n clients;\n TRACE;\n DEBUG;\n INFO;\n TIME;\n WARN;\n ERROR;\n OFF;\n currentLevel = LogLevel.INFO;\n constructor(clients) {\n this.clients = clients;\n this.TRACE = LogLevel.TRACE;\n this.DEBUG = LogLevel.DEBUG;\n this.INFO = LogLevel.INFO;\n this.TIME = LogLevel.TIME;\n this.WARN = LogLevel.WARN;\n this.ERROR = LogLevel.ERROR;\n this.OFF = LogLevel.OFF;\n }\n trace(...x) {\n if (!this.enabledFor(this.TRACE))\n return;\n console.trace(...x);\n const sanitized = this.sanitizeArgs(x);\n this.iterateClients((client) => client.clientProvider.trace(...sanitized));\n }\n debug(...x) {\n if (!this.enabledFor(this.DEBUG))\n return;\n console.debug(...x);\n const sanitized = this.sanitizeArgs(x);\n this.iterateClients((client) => client.clientProvider.debug(...sanitized));\n }\n info(...x) {\n if (!this.enabledFor(this.INFO))\n return;\n console.info(...x);\n const sanitized = this.sanitizeArgs(x);\n this.iterateClients((client) => client.clientProvider.info(...sanitized));\n }\n log(...x) {\n if (!this.enabledFor(this.INFO))\n return;\n console.log(...x);\n const sanitized = this.sanitizeArgs(x);\n this.iterateClients((client) => client.clientProvider.log(...sanitized));\n }\n warn(...x) {\n if (!this.enabledFor(this.WARN))\n return;\n console.warn(...x);\n const sanitized = this.sanitizeArgs(x);\n this.iterateClients((client) => client.clientProvider.warn(...sanitized));\n }\n error(...x) {\n if (!this.enabledFor(this.ERROR))\n return;\n console.error(...x);\n const sanitized = this.sanitizeArgs(x);\n this.iterateClients((client) => client.clientProvider.error(...sanitized));\n }\n time(label) {\n if (!this.enabledFor(this.TIME))\n return;\n console.time(label);\n this.iterateClients((client) => client.clientProvider.time(label));\n }\n timeEnd(label) {\n if (!this.enabledFor(this.TIME))\n return;\n console.timeEnd(label);\n this.iterateClients((client) => client.clientProvider.timeEnd(label));\n }\n /**\n * Set the global log level.\n */\n setLevel(level) {\n this.currentLevel = level;\n }\n /**\n * Get the current log level.\n */\n getLevel() {\n return this.currentLevel;\n }\n /**\n * Returns true if the given level is enabled.\n */\n enabledFor(level) {\n return level.value >= this.currentLevel.value;\n }\n /**\n * Iterates all clients, catches individual client exceptions\n * and proceeds to execute for all clients.\n */\n async iterateClients(callback) {\n for (const client of this.clients) {\n try {\n await callback(client);\n }\n catch (ex) {\n console.error('Caught exception when iterating client', ex);\n }\n }\n }\n /**\n * Guards against any logging errors.\n * We don't want a logging exception to cause further issues upstream\n */\n sanitizeArgs(x) {\n const sanitizedParams = x.map((param) => {\n try {\n // Try and clone here first. If it fails it won't be passable over a MessagePort\n return structuredClone(param);\n }\n catch (ex) {\n console.error(ex);\n return 'Could not serialize log params. Check shared worker logs for more details.';\n }\n });\n return sanitizedParams;\n }\n}\n","import { AbortOperation, BaseObserver, ConnectionManager, SqliteBucketStorage, SyncStatus, createLogger } from '@powersync/common';\nimport { Mutex } from 'async-mutex';\nimport * as Comlink from 'comlink';\nimport { WebRemote } from '../../db/sync/WebRemote.js';\nimport { WebStreamingSyncImplementation } from '../../db/sync/WebStreamingSyncImplementation.js';\nimport { LockedAsyncDatabaseAdapter } from '../../db/adapters/LockedAsyncDatabaseAdapter.js';\nimport { WorkerWrappedAsyncDatabaseConnection } from '../../db/adapters/WorkerWrappedAsyncDatabaseConnection.js';\nimport { BroadcastLogger } from './BroadcastLogger.js';\n/**\n * @internal\n * Manual message events for shared sync clients\n */\nexport var SharedSyncClientEvent;\n(function (SharedSyncClientEvent) {\n /**\n * This client requests the shared sync manager should\n * close it's connection to the client.\n */\n SharedSyncClientEvent[\"CLOSE_CLIENT\"] = \"close-client\";\n SharedSyncClientEvent[\"CLOSE_ACK\"] = \"close-ack\";\n})(SharedSyncClientEvent || (SharedSyncClientEvent = {}));\n/**\n * HACK: The shared implementation wraps and provides its own\n * PowerSyncBackendConnector when generating the streaming sync implementation.\n * We provide this unused placeholder when connecting with the ConnectionManager.\n */\nconst CONNECTOR_PLACEHOLDER = {};\n/**\n * @internal\n * Shared sync implementation which runs inside a shared webworker\n */\nexport class SharedSyncImplementation extends BaseObserver {\n ports;\n isInitialized;\n statusListener;\n fetchCredentialsController;\n uploadDataController;\n syncParams;\n logger;\n lastConnectOptions;\n portMutex;\n subscriptions = [];\n connectionManager;\n syncStatus;\n broadCastLogger;\n distributedDB;\n constructor() {\n super();\n this.ports = [];\n this.syncParams = null;\n this.logger = createLogger('shared-sync');\n this.lastConnectOptions = undefined;\n this.portMutex = new Mutex();\n this.isInitialized = new Promise((resolve) => {\n const callback = this.registerListener({\n initialized: () => {\n resolve();\n callback?.();\n }\n });\n });\n // Should be configured once we get params\n this.distributedDB = null;\n this.syncStatus = new SyncStatus({});\n this.broadCastLogger = new BroadcastLogger(this.ports);\n this.connectionManager = new ConnectionManager({\n createSyncImplementation: async () => {\n await this.waitForReady();\n const sync = this.generateStreamingImplementation();\n const onDispose = sync.registerListener({\n statusChanged: (status) => {\n this.updateAllStatuses(status.toJSON());\n }\n });\n return {\n sync,\n onDispose\n };\n },\n logger: this.logger\n });\n }\n get lastSyncedAt() {\n return this.connectionManager.syncStreamImplementation?.lastSyncedAt;\n }\n get isConnected() {\n return this.connectionManager.syncStreamImplementation?.isConnected ?? false;\n }\n /**\n * Gets the last client port which we know is safe from unexpected closes.\n */\n async getLastWrappedPort() {\n // Find the last port which is not closing\n return await this.portMutex.runExclusive(() => {\n for (let i = this.ports.length - 1; i >= 0; i--) {\n if (!this.ports[i].isClosing) {\n return this.ports[i];\n }\n }\n return;\n });\n }\n /**\n * In some very rare cases a specific tab might not respond to requests.\n * This returns a random port which is not closing.\n */\n async getRandomWrappedPort() {\n return await this.portMutex.runExclusive(() => {\n const nonClosingPorts = this.ports.filter((p) => !p.isClosing);\n return nonClosingPorts[Math.floor(Math.random() * nonClosingPorts.length)];\n });\n }\n async waitForStatus(status) {\n return this.withSyncImplementation(async (sync) => {\n return sync.waitForStatus(status);\n });\n }\n async waitUntilStatusMatches(predicate) {\n return this.withSyncImplementation(async (sync) => {\n return sync.waitUntilStatusMatches(predicate);\n });\n }\n async waitForReady() {\n return this.isInitialized;\n }\n collectActiveSubscriptions() {\n this.logger.debug('Collecting active stream subscriptions across tabs');\n const active = new Map();\n for (const port of this.ports) {\n for (const stream of port.currentSubscriptions) {\n const serializedKey = JSON.stringify(stream);\n active.set(serializedKey, stream);\n }\n }\n this.subscriptions = [...active.values()];\n this.logger.debug('Collected stream subscriptions', this.subscriptions);\n this.connectionManager.syncStreamImplementation?.updateSubscriptions(this.subscriptions);\n }\n updateSubscriptions(port, subscriptions) {\n port.currentSubscriptions = subscriptions;\n this.collectActiveSubscriptions();\n }\n setLogLevel(level) {\n this.logger.setLevel(level);\n this.broadCastLogger.setLevel(level);\n }\n /**\n * Configures the DBAdapter connection and a streaming sync client.\n */\n async setParams(params) {\n await this.portMutex.runExclusive(async () => {\n this.collectActiveSubscriptions();\n });\n if (this.syncParams) {\n // Cannot modify already existing sync implementation params\n return;\n }\n // First time setting params\n this.syncParams = params;\n if (params.streamOptions?.flags?.broadcastLogs) {\n this.logger = this.broadCastLogger;\n }\n const lockedAdapter = new LockedAsyncDatabaseAdapter({\n name: params.dbParams.dbFilename,\n openConnection: async () => {\n // Gets a connection from the clients when a new connection is requested.\n const db = await this.openInternalDB();\n db.registerListener({\n closing: () => {\n lockedAdapter.reOpenInternalDB();\n }\n });\n return db;\n },\n logger: this.logger,\n reOpenOnConnectionClosed: true\n });\n this.distributedDB = lockedAdapter;\n await lockedAdapter.init();\n lockedAdapter.registerListener({\n databaseReOpened: () => {\n // We may have missed some table updates while the database was closed.\n // We can poke the crud in case we missed any updates.\n this.connectionManager.syncStreamImplementation?.triggerCrudUpload();\n /**\n * FIXME or IMPROVE ME\n * The Rust client implementation stores sync state on the connection level.\n * Reopening the database causes a state machine error which should cause the\n * StreamingSyncImplementation to reconnect. It would be nicer if we could trigger\n * this reconnect earlier.\n * This reconnect is not required for IndexedDB.\n */\n }\n });\n self.onerror = (event) => {\n // Share any uncaught events on the broadcast logger\n this.logger.error('Uncaught exception in PowerSync shared sync worker', event);\n };\n this.iterateListeners((l) => l.initialized?.());\n }\n async dispose() {\n await this.waitForReady();\n this.statusListener?.();\n return this.connectionManager.close();\n }\n /**\n * Connects to the PowerSync backend instance.\n * Multiple tabs can safely call this in their initialization.\n * The connection will simply be reconnected whenever a new tab\n * connects.\n */\n async connect(options) {\n this.lastConnectOptions = options;\n return this.connectionManager.connect(CONNECTOR_PLACEHOLDER, options ?? {});\n }\n async disconnect() {\n return this.connectionManager.disconnect();\n }\n /**\n * Adds a new client tab's message port to the list of connected ports\n */\n async addPort(port) {\n return await this.portMutex.runExclusive(() => {\n const portProvider = {\n port,\n clientProvider: Comlink.wrap(port),\n currentSubscriptions: [],\n closeListeners: [],\n isClosing: false\n };\n this.ports.push(portProvider);\n // Give the newly connected client the latest status\n const status = this.connectionManager.syncStreamImplementation?.syncStatus;\n if (status) {\n portProvider.clientProvider.statusChanged(status.toJSON());\n }\n return portProvider;\n });\n }\n /**\n * Removes a message port client from this manager's managed\n * clients.\n */\n async removePort(port) {\n // Ports might be removed faster than we can process them.\n port.isClosing = true;\n // Remove the port within a mutex context.\n // Warns if the port is not found. This should not happen in practice.\n // We return early if the port is not found.\n return await this.portMutex.runExclusive(async () => {\n const index = this.ports.findIndex((p) => p == port);\n if (index < 0) {\n this.logger.warn(`Could not remove port ${port} since it is not present in active ports.`);\n return () => { };\n }\n const trackedPort = this.ports[index];\n // Remove from the list of active ports\n this.ports.splice(index, 1);\n /**\n * The port might currently be in use. Any active functions might\n * not resolve. Abort them here.\n */\n [this.fetchCredentialsController, this.uploadDataController].forEach((abortController) => {\n if (abortController?.activePort == port) {\n abortController.controller.abort(new AbortOperation('Closing pending requests after client port is removed'));\n }\n });\n // Close the worker wrapped database connection, we can't accurately rely on this connection\n for (const closeListener of trackedPort.closeListeners) {\n await closeListener();\n }\n this.collectActiveSubscriptions();\n return () => trackedPort.clientProvider[Comlink.releaseProxy]();\n });\n }\n triggerCrudUpload() {\n this.withSyncImplementation(async (sync) => {\n sync.triggerCrudUpload();\n });\n }\n async hasCompletedSync() {\n return this.withSyncImplementation(async (sync) => {\n return sync.hasCompletedSync();\n });\n }\n async getWriteCheckpoint() {\n return this.withSyncImplementation(async (sync) => {\n return sync.getWriteCheckpoint();\n });\n }\n async withSyncImplementation(callback) {\n await this.waitForReady();\n if (this.connectionManager.syncStreamImplementation) {\n return callback(this.connectionManager.syncStreamImplementation);\n }\n const sync = await new Promise((resolve) => {\n const dispose = this.connectionManager.registerListener({\n syncStreamCreated: (sync) => {\n resolve(sync);\n dispose?.();\n }\n });\n });\n return callback(sync);\n }\n generateStreamingImplementation() {\n // This should only be called after initialization has completed\n const syncParams = this.syncParams;\n // Create a new StreamingSyncImplementation for each connect call. This is usually done is all SDKs.\n return new WebStreamingSyncImplementation({\n adapter: new SqliteBucketStorage(this.distributedDB, this.logger),\n remote: new WebRemote({\n invalidateCredentials: async () => {\n const lastPort = await this.getLastWrappedPort();\n if (!lastPort) {\n throw new Error('No client port found to invalidate credentials');\n }\n try {\n this.logger.log('calling the last port client provider to invalidate credentials');\n lastPort.clientProvider.invalidateCredentials();\n }\n catch (ex) {\n this.logger.error('error invalidating credentials', ex);\n }\n },\n fetchCredentials: async () => {\n const lastPort = await this.getLastWrappedPort();\n if (!lastPort) {\n throw new Error('No client port found to fetch credentials');\n }\n return new Promise(async (resolve, reject) => {\n const abortController = new AbortController();\n this.fetchCredentialsController = {\n controller: abortController,\n activePort: lastPort\n };\n abortController.signal.onabort = reject;\n try {\n this.logger.log('calling the last port client provider for credentials');\n resolve(await lastPort.clientProvider.fetchCredentials());\n }\n catch (ex) {\n reject(ex);\n }\n finally {\n this.fetchCredentialsController = undefined;\n }\n });\n }\n }, this.logger),\n uploadCrud: async () => {\n const lastPort = await this.getLastWrappedPort();\n if (!lastPort) {\n throw new Error('No client port found to upload crud');\n }\n return new Promise(async (resolve, reject) => {\n const abortController = new AbortController();\n this.uploadDataController = {\n controller: abortController,\n activePort: lastPort\n };\n // Resolving will make it retry\n abortController.signal.onabort = () => resolve();\n try {\n resolve(await lastPort.clientProvider.uploadCrud());\n }\n catch (ex) {\n reject(ex);\n }\n finally {\n this.uploadDataController = undefined;\n }\n });\n },\n ...syncParams.streamOptions,\n subscriptions: this.subscriptions,\n // Logger cannot be transferred just yet\n logger: this.logger\n });\n }\n /**\n * Opens a worker wrapped database connection. Using the last connected client port.\n */\n async openInternalDB() {\n const client = await this.getRandomWrappedPort();\n if (!client) {\n // Should not really happen in practice\n throw new Error(`Could not open DB connection since no client is connected.`);\n }\n // Fail-safe timeout for opening a database connection.\n const timeout = setTimeout(() => {\n abortController.abort();\n }, 10_000);\n /**\n * Handle cases where the client might close while opening a connection.\n */\n const abortController = new AbortController();\n const closeListener = () => {\n abortController.abort();\n };\n const removeCloseListener = () => {\n const index = client.closeListeners.indexOf(closeListener);\n if (index >= 0) {\n client.closeListeners.splice(index, 1);\n }\n };\n client.closeListeners.push(closeListener);\n const workerPort = await withAbort({\n action: () => client.clientProvider.getDBWorkerPort(),\n signal: abortController.signal,\n cleanupOnAbort: (port) => {\n port.close();\n }\n }).catch((ex) => {\n removeCloseListener();\n throw ex;\n });\n const remote = Comlink.wrap(workerPort);\n const identifier = this.syncParams.dbParams.dbFilename;\n /**\n * The open could fail if the tab is closed while we're busy opening the database.\n * This operation is typically executed inside an exclusive portMutex lock.\n * We typically execute the closeListeners using the portMutex in a different context.\n * We can't rely on the closeListeners to abort the operation if the tab is closed.\n */\n const db = await withAbort({\n action: () => remote(this.syncParams.dbParams),\n signal: abortController.signal,\n cleanupOnAbort: (db) => {\n db.close();\n }\n }).finally(() => {\n // We can remove the close listener here since we no longer need it past this point.\n removeCloseListener();\n });\n clearTimeout(timeout);\n const wrapped = new WorkerWrappedAsyncDatabaseConnection({\n remote,\n baseConnection: db,\n identifier,\n // It's possible for this worker to outlive the client hosting the database for us. We need to be prepared for\n // that and ensure pending requests are aborted when the tab is closed.\n remoteCanCloseUnexpectedly: true\n });\n client.closeListeners.push(async () => {\n this.logger.info('Aborting open connection because associated tab closed.');\n /**\n * Don't await this close operation. It might never resolve if the tab is closed.\n * We mark the remote as closed first, this will reject any pending requests.\n * We then call close. The close operation is configured to fire-and-forget, the main promise will reject immediately.\n */\n wrapped.markRemoteClosed();\n wrapped.close().catch((ex) => this.logger.warn('error closing database connection', ex));\n });\n return wrapped;\n }\n /**\n * A method to update the all shared statuses for each\n * client.\n */\n updateAllStatuses(status) {\n this.syncStatus = new SyncStatus(status);\n this.ports.forEach((p) => p.clientProvider.statusChanged(status));\n }\n}\n/**\n * Runs the action with an abort controller.\n */\nfunction withAbort(options) {\n const { action, signal, cleanupOnAbort } = options;\n return new Promise((resolve, reject) => {\n if (signal.aborted) {\n reject(new AbortOperation('Operation aborted by abort controller'));\n return;\n }\n function handleAbort() {\n signal.removeEventListener('abort', handleAbort);\n reject(new AbortOperation('Operation aborted by abort controller'));\n }\n signal.addEventListener('abort', handleAbort, { once: true });\n function completePromise(action) {\n signal.removeEventListener('abort', handleAbort);\n action();\n }\n action()\n .then((data) => {\n // We already rejected due to the abort, allow for cleanup\n if (signal.aborted) {\n return completePromise(() => cleanupOnAbort?.(data));\n }\n completePromise(() => resolve(data));\n })\n .catch((e) => completePromise(() => reject(e)));\n });\n}\n","import { createBaseLogger } from '@powersync/common';\nimport { SharedSyncImplementation } from './SharedSyncImplementation.js';\nimport { WorkerClient } from './WorkerClient.js';\nconst _self = self;\nconst logger = createBaseLogger();\nlogger.useDefaults();\nconst sharedSyncImplementation = new SharedSyncImplementation();\n_self.onconnect = async function (event) {\n const port = event.ports[0];\n new WorkerClient(sharedSyncImplementation, port);\n};\n","import * as Comlink from 'comlink';\nimport { getNavigatorLocks } from '../../shared/navigator.js';\nimport { SharedSyncClientEvent } from './SharedSyncImplementation.js';\n/**\n * A client to the shared sync worker.\n *\n * The shared sync implementation needs a per-client view of subscriptions so that subscriptions of closed tabs can\n * automatically be evicted later.\n */\nexport class WorkerClient {\n sync;\n port;\n resolvedPort = null;\n resolvedPortPromise = null;\n constructor(sync, port) {\n this.sync = sync;\n this.port = port;\n Comlink.expose(this, this.port);\n /**\n * Adds an extra listener which can remove this port\n * from the list of monitored ports.\n */\n this.port.addEventListener('message', async (event) => {\n const payload = event.data;\n if (payload?.event == SharedSyncClientEvent.CLOSE_CLIENT) {\n await this.removePort();\n }\n });\n }\n async removePort() {\n if (this.resolvedPort) {\n const resolved = this.resolvedPort;\n this.resolvedPort = null;\n const release = await this.sync.removePort(resolved);\n this.resolvedPort = null;\n this.port.postMessage({\n event: SharedSyncClientEvent.CLOSE_ACK,\n data: {}\n });\n release?.();\n }\n }\n /**\n * Called by a client after obtaining a lock with a random name.\n *\n * When the client tab is closed, its lock will be returned. So when the shared worker attempts to acquire the lock,\n * it can consider the connection to be closed.\n */\n async addLockBasedCloseSignal(name) {\n // Only add the port once the lock has been obtained on the client.\n this.resolvedPort = await this.sync.addPort(this.port);\n // Don't await this lock request\n getNavigatorLocks().request(name, async () => {\n await this.removePort();\n });\n }\n setLogLevel(level) {\n this.sync.setLogLevel(level);\n }\n triggerCrudUpload() {\n return this.sync.triggerCrudUpload();\n }\n setParams(params, subscriptions) {\n this.resolvedPort.currentSubscriptions = subscriptions;\n return this.sync.setParams(params);\n }\n getWriteCheckpoint() {\n return this.sync.getWriteCheckpoint();\n }\n hasCompletedSync() {\n return this.sync.hasCompletedSync();\n }\n connect(options) {\n return this.sync.connect(options);\n }\n updateSubscriptions(subscriptions) {\n if (this.resolvedPort) {\n this.sync.updateSubscriptions(this.resolvedPort, subscriptions);\n }\n }\n disconnect() {\n return this.sync.disconnect();\n }\n}\n","module.exports = __WEBPACK_EXTERNAL_MODULE__journeyapps_wa_sqlite__;","module.exports = __WEBPACK_EXTERNAL_MODULE__journeyapps_wa_sqlite_src_examples_AccessHandlePoolVFS_js__;","module.exports = __WEBPACK_EXTERNAL_MODULE__journeyapps_wa_sqlite_src_examples_IDBBatchAtomicVFS_js__;","module.exports = __WEBPACK_EXTERNAL_MODULE__journeyapps_wa_sqlite_src_examples_OPFSCoopSyncVFS_js__;","module.exports = __WEBPACK_EXTERNAL_MODULE__powersync_common__;","module.exports = __WEBPACK_EXTERNAL_MODULE_async_mutex__;","module.exports = __WEBPACK_EXTERNAL_MODULE_comlink__;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Check if module exists (development only)\n\tif (__webpack_modules__[moduleId] === undefined) {\n\t\tvar e = new Error(\"Cannot find module '\" + moduleId + \"'\");\n\t\te.code = 'MODULE_NOT_FOUND';\n\t\tthrow e;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n// the startup function\n__webpack_require__.x = () => {\n\t// Load entry module and return exports\n\t// This entry module depends on other loaded chunks and execution need to be delayed\n\tvar __webpack_exports__ = __webpack_require__.O(undefined, [\"main\"], () => (__webpack_require__(\"./lib/src/worker/sync/SharedSyncImplementation.worker.js\")))\n\t__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n\treturn __webpack_exports__;\n};\n\n","var deferred = [];\n__webpack_require__.O = (result, chunkIds, fn, priority) => {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar [chunkIds, fn, priority] = deferred[i];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","var getProto = Object.getPrototypeOf ? (obj) => (Object.getPrototypeOf(obj)) : (obj) => (obj.__proto__);\nvar leafPrototypes;\n// create a fake namespace object\n// mode & 1: value is a module id, require it\n// mode & 2: merge all properties of value into the ns\n// mode & 4: return value when already ns object\n// mode & 16: return value when it's Promise-like\n// mode & 8|1: behave like require\n__webpack_require__.t = function(value, mode) {\n\tif(mode & 1) value = this(value);\n\tif(mode & 8) return value;\n\tif(typeof value === 'object' && value) {\n\t\tif((mode & 4) && value.__esModule) return value;\n\t\tif((mode & 16) && typeof value.then === 'function') return value;\n\t}\n\tvar ns = Object.create(null);\n\t__webpack_require__.r(ns);\n\tvar def = {};\n\tleafPrototypes = leafPrototypes || [null, getProto({}), getProto([]), getProto(getProto)];\n\tfor(var current = mode & 2 && value; (typeof current == 'object' || typeof current == 'function') && !~leafPrototypes.indexOf(current); current = getProto(current)) {\n\t\tObject.getOwnPropertyNames(current).forEach((key) => (def[key] = () => (value[key])));\n\t}\n\tdef['default'] = () => (value);\n\t__webpack_require__.d(ns, def);\n\treturn ns;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.f = {};\n// This file contains only the entry chunk.\n// The chunk loading function for additional chunks\n__webpack_require__.e = (chunkId) => {\n\treturn Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {\n\t\t__webpack_require__.f[key](chunkId, promises);\n\t\treturn promises;\n\t}, []));\n};","// This function allow to reference async chunks and chunks that the entrypoint depends on\n__webpack_require__.u = (chunkId) => {\n\t// return url for filenames based on template\n\treturn undefined;\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","var scriptUrl;\nif (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + \"\";\nvar document = __webpack_require__.g.document;\nif (!scriptUrl && document) {\n\tif (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT')\n\t\tscriptUrl = document.currentScript.src;\n\tif (!scriptUrl) {\n\t\tvar scripts = document.getElementsByTagName(\"script\");\n\t\tif(scripts.length) {\n\t\t\tvar i = scripts.length - 1;\n\t\t\twhile (i > -1 && (!scriptUrl || !/^http(s?):/.test(scriptUrl))) scriptUrl = scripts[i--].src;\n\t\t}\n\t}\n}\n// When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration\n// or pass an empty string (\"\") and set the __webpack_public_path__ variable from your code to use your own logic.\nif (!scriptUrl) throw new Error(\"Automatic publicPath is not supported in this browser\");\nscriptUrl = scriptUrl.replace(/^blob:/, \"\").replace(/#.*$/, \"\").replace(/\\?.*$/, \"\").replace(/\\/[^\\/]+$/, \"/\");\n__webpack_require__.p = scriptUrl;","__webpack_require__.b = self.location + \"\";\n\n// object to store loaded chunks\n// \"1\" means \"already loaded\"\nvar installedChunks = {\n\t\"_journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_AccessHandlePoolVFS_js-_journeyapp-89f0ba\": 1\n};\n\n// importScripts chunk loading\nvar installChunk = (data) => {\n\tvar [chunkIds, moreModules, runtime] = data;\n\tfor(var moduleId in moreModules) {\n\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t}\n\t}\n\tif(runtime) runtime(__webpack_require__);\n\twhile(chunkIds.length)\n\t\tinstalledChunks[chunkIds.pop()] = 1;\n\tparentChunkLoadingFunction(data);\n};\n__webpack_require__.f.i = (chunkId, promises) => {\n\t// \"1\" is the signal for \"already loaded\"\n\tif(!installedChunks[chunkId]) {\n\t\tif(true) { // all chunks have JS\n\t\t\timportScripts(__webpack_require__.p + __webpack_require__.u(chunkId));\n\t\t}\n\t}\n};\n\nvar chunkLoadingGlobal = self[\"webpackChunksdk_web\"] = self[\"webpackChunksdk_web\"] || [];\nvar parentChunkLoadingFunction = chunkLoadingGlobal.push.bind(chunkLoadingGlobal);\nchunkLoadingGlobal.push = installChunk;\n\n// no HMR\n\n// no HMR manifest","var next = __webpack_require__.x;\n__webpack_require__.x = () => {\n\treturn Promise.all([\n\n\t]).then(next);\n};","","// run startup\nvar __webpack_exports__ = __webpack_require__.x();\n",""],"names":[],"ignoreList":[],"sourceRoot":""}
|