@powersync/web 0.0.0-dev-20260708104358 → 0.0.0-dev-20260917074240
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -11
- package/bin/powersync.cjs +1 -1
- package/dist/index.react_native_web.js +2095 -0
- package/dist/index.react_native_web.js.map +1 -0
- package/dist/worker/AccessHandlePoolVFS-BPUHfZME.js +2 -0
- package/dist/worker/AccessHandlePoolVFS-BPUHfZME.js.map +1 -0
- package/dist/worker/FacadeVFS-d1ZDvud7.js +2 -0
- package/dist/worker/FacadeVFS-d1ZDvud7.js.map +1 -0
- package/dist/worker/IDBBatchAtomicVFS-DbkDb777.js +2 -0
- package/dist/worker/IDBBatchAtomicVFS-DbkDb777.js.map +1 -0
- package/dist/worker/MemoryVFS-DVJL5F8j.js +2 -0
- package/dist/worker/MemoryVFS-DVJL5F8j.js.map +1 -0
- package/dist/worker/OPFSCoopSyncVFS-BgTiWPfa.js +2 -0
- package/dist/worker/OPFSCoopSyncVFS-BgTiWPfa.js.map +1 -0
- package/dist/worker/OPFSWriteAheadVFS-Rt5CGCZP.js +2 -0
- package/dist/worker/OPFSWriteAheadVFS-Rt5CGCZP.js.map +1 -0
- package/dist/worker/assets/mc-wa-sqlite-BHScYYZw.wasm +0 -0
- package/dist/worker/assets/mc-wa-sqlite-async-DdlQmAUV.wasm +0 -0
- package/dist/worker/assets/wa-sqlite-CIxTmRHQ.wasm +0 -0
- package/dist/worker/assets/wa-sqlite-async-zc68fxQq.wasm +0 -0
- package/dist/worker/mc-wa-sqlite-PubB6u8c.js +2 -0
- package/dist/worker/mc-wa-sqlite-PubB6u8c.js.map +1 -0
- package/dist/worker/mc-wa-sqlite-async-DJG_ANKO.js +2 -0
- package/dist/worker/mc-wa-sqlite-async-DJG_ANKO.js.map +1 -0
- package/dist/worker/wa-sqlite-D1_4mGs8.js +2 -0
- package/dist/worker/wa-sqlite-D1_4mGs8.js.map +1 -0
- package/dist/worker/wa-sqlite-async-BxkwNY-2.js +2 -0
- package/dist/worker/wa-sqlite-async-BxkwNY-2.js.map +1 -0
- package/dist/worker/websockets-Q8W_lerF.js +9 -0
- package/dist/worker/websockets-Q8W_lerF.js.map +1 -0
- package/dist/worker/worker.js +7 -0
- package/dist/worker/worker.js.map +1 -0
- package/lib/attachments/IndexDBFileSystemAdapter.js.map +1 -0
- package/lib/{src/db → db}/NavigatorTriggerClaimManager.d.ts +1 -1
- package/lib/db/NavigatorTriggerClaimManager.js.map +1 -0
- package/lib/db/PowerSyncDatabase.d.ts +66 -0
- package/lib/{src/db → db}/PowerSyncDatabase.js +60 -79
- package/lib/db/PowerSyncDatabase.js.map +1 -0
- package/lib/db/adapters/AsyncWebAdapter.d.ts +32 -0
- package/lib/{src/db → db}/adapters/AsyncWebAdapter.js +18 -69
- package/lib/db/adapters/AsyncWebAdapter.js.map +1 -0
- package/lib/db/adapters/SSRDBAdapter.d.ts +17 -0
- package/lib/db/adapters/SSRDBAdapter.js +37 -0
- package/lib/db/adapters/SSRDBAdapter.js.map +1 -0
- package/lib/{src/db → db}/adapters/WebDBAdapter.d.ts +1 -1
- package/lib/db/adapters/WebDBAdapter.js.map +1 -0
- package/lib/db/adapters/acquireFromPool.d.ts +7 -0
- package/lib/db/adapters/acquireFromPool.js +60 -0
- package/lib/db/adapters/acquireFromPool.js.map +1 -0
- package/lib/db/adapters/memory-pool/client.d.ts +70 -0
- package/lib/db/adapters/memory-pool/client.js +269 -0
- package/lib/db/adapters/memory-pool/client.js.map +1 -0
- package/lib/db/adapters/memory-pool/shared.d.ts +51 -0
- package/lib/db/adapters/memory-pool/shared.js +16 -0
- package/lib/db/adapters/memory-pool/shared.js.map +1 -0
- package/lib/db/adapters/memory-pool/vfs.d.ts +19 -0
- package/lib/db/adapters/memory-pool/vfs.js +247 -0
- package/lib/db/adapters/memory-pool/vfs.js.map +1 -0
- package/lib/db/adapters/memory-pool/worker.js +45 -0
- package/lib/db/adapters/memory-pool/worker.js.map +1 -0
- package/lib/db/adapters/options.d.ts +94 -0
- package/lib/db/adapters/options.js +6 -0
- package/lib/db/adapters/options.js.map +1 -0
- package/lib/db/adapters/resolveAndValidateOptions.d.ts +13 -0
- package/lib/db/adapters/resolveAndValidateOptions.js +41 -0
- package/lib/db/adapters/resolveAndValidateOptions.js.map +1 -0
- package/lib/{src/db → db}/adapters/wa-sqlite/ConcurrentConnection.d.ts +3 -4
- package/lib/{src/db → db}/adapters/wa-sqlite/ConcurrentConnection.js +2 -2
- package/lib/db/adapters/wa-sqlite/ConcurrentConnection.js.map +1 -0
- package/lib/{src/db → db}/adapters/wa-sqlite/DatabaseClient.d.ts +4 -4
- package/lib/{src/db → db}/adapters/wa-sqlite/DatabaseClient.js +11 -37
- package/lib/db/adapters/wa-sqlite/DatabaseClient.js.map +1 -0
- package/lib/{src/db → db}/adapters/wa-sqlite/DatabaseServer.d.ts +5 -5
- package/lib/{src/db → db}/adapters/wa-sqlite/DatabaseServer.js +14 -7
- package/lib/db/adapters/wa-sqlite/DatabaseServer.js.map +1 -0
- package/lib/{src/db → db}/adapters/wa-sqlite/RawSqliteConnection.d.ts +30 -12
- package/lib/{src/db → db}/adapters/wa-sqlite/RawSqliteConnection.js +70 -16
- package/lib/db/adapters/wa-sqlite/RawSqliteConnection.js.map +1 -0
- package/lib/db/adapters/wa-sqlite/StatementCache.d.ts +16 -0
- package/lib/db/adapters/wa-sqlite/StatementCache.js +44 -0
- package/lib/db/adapters/wa-sqlite/StatementCache.js.map +1 -0
- package/lib/db/adapters/wa-sqlite/WASQLiteOpenFactory.d.ts +18 -0
- package/lib/db/adapters/wa-sqlite/WASQLiteOpenFactory.js +140 -0
- package/lib/db/adapters/wa-sqlite/WASQLiteOpenFactory.js.map +1 -0
- package/lib/{src/db → db}/adapters/wa-sqlite/vfs.d.ts +9 -2
- package/lib/{src/db → db}/adapters/wa-sqlite/vfs.js +6 -6
- package/lib/db/adapters/wa-sqlite/vfs.js.map +1 -0
- package/lib/{src/db → db}/sync/SSRWebStreamingSyncImplementation.d.ts +5 -16
- package/lib/{src/db → db}/sync/SSRWebStreamingSyncImplementation.js +7 -23
- package/lib/db/sync/SSRWebStreamingSyncImplementation.js.map +1 -0
- package/lib/{src/db → db}/sync/SharedWebStreamingSyncImplementation.d.ts +15 -15
- package/lib/{src/db → db}/sync/SharedWebStreamingSyncImplementation.js +38 -70
- package/lib/db/sync/SharedWebStreamingSyncImplementation.js.map +1 -0
- package/lib/db/sync/TabLocalStreamingSyncImplementation.d.ts +19 -0
- package/lib/db/sync/TabLocalStreamingSyncImplementation.js +70 -0
- package/lib/db/sync/TabLocalStreamingSyncImplementation.js.map +1 -0
- package/lib/db/sync/WebRemote.d.ts +10 -0
- package/lib/db/sync/WebRemote.js +33 -0
- package/lib/db/sync/WebRemote.js.map +1 -0
- package/lib/{src/db → db}/sync/WebStreamingSyncImplementation.d.ts +2 -4
- package/lib/{src/db → db}/sync/WebStreamingSyncImplementation.js +3 -2
- package/lib/db/sync/WebStreamingSyncImplementation.js.map +1 -0
- package/lib/db/sync/userAgent.js.map +1 -0
- package/lib/{src/index.d.ts → index.d.ts} +1 -3
- package/lib/{src/index.js → index.js} +1 -3
- package/lib/index.js.map +1 -0
- package/lib/shared/navigator.js.map +1 -0
- package/lib/shared/tab_close_signal.js.map +1 -0
- package/lib/worker/SharedWorkerConnectionRequest.d.ts +5 -0
- package/lib/worker/SharedWorkerConnectionRequest.js +2 -0
- package/lib/worker/SharedWorkerConnectionRequest.js.map +1 -0
- package/lib/worker/client.d.ts +17 -0
- package/lib/worker/client.js +90 -0
- package/lib/worker/client.js.map +1 -0
- package/lib/worker/db/MultiDatabaseServer.d.ts +21 -0
- package/lib/{src/worker → worker}/db/MultiDatabaseServer.js +45 -24
- package/lib/worker/db/MultiDatabaseServer.js.map +1 -0
- package/lib/worker/sync/AbstractSharedSyncClientProvider.d.ts +14 -0
- package/lib/worker/sync/AbstractSharedSyncClientProvider.js.map +1 -0
- package/lib/worker/sync/BroadcastLogger.d.ts +27 -0
- package/lib/worker/sync/BroadcastLogger.js +65 -0
- package/lib/worker/sync/BroadcastLogger.js.map +1 -0
- package/lib/{src/worker → worker}/sync/SharedSyncImplementation.d.ts +14 -25
- package/lib/{src/worker → worker}/sync/SharedSyncImplementation.js +140 -107
- package/lib/worker/sync/SharedSyncImplementation.js.map +1 -0
- package/lib/{src/worker → worker}/sync/WorkerClient.d.ts +4 -4
- package/lib/{src/worker → worker}/sync/WorkerClient.js +5 -5
- package/lib/worker/sync/WorkerClient.js.map +1 -0
- package/lib/worker/worker.d.ts +1 -0
- package/lib/worker/worker.js +34 -0
- package/lib/worker/worker.js.map +1 -0
- package/package.json +31 -32
- package/src/db/NavigatorTriggerClaimManager.ts +1 -1
- package/src/db/PowerSyncDatabase.ts +96 -144
- package/src/db/adapters/AsyncWebAdapter.ts +29 -86
- package/src/db/adapters/SSRDBAdapter.ts +14 -64
- package/src/db/adapters/WebDBAdapter.ts +1 -1
- package/src/db/adapters/acquireFromPool.ts +73 -0
- package/src/db/adapters/memory-pool/client.ts +367 -0
- package/src/db/adapters/memory-pool/shared.ts +79 -0
- package/src/db/adapters/memory-pool/vfs.ts +293 -0
- package/src/db/adapters/memory-pool/worker.ts +53 -0
- package/src/db/adapters/options.ts +108 -0
- package/src/db/adapters/resolveAndValidateOptions.ts +49 -0
- package/src/db/adapters/wa-sqlite/ConcurrentConnection.ts +4 -5
- package/src/db/adapters/wa-sqlite/DatabaseClient.ts +20 -56
- package/src/db/adapters/wa-sqlite/DatabaseServer.ts +18 -12
- package/src/db/adapters/wa-sqlite/RawSqliteConnection.ts +108 -30
- package/src/db/adapters/wa-sqlite/StatementCache.ts +50 -0
- package/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.ts +82 -125
- package/src/db/adapters/wa-sqlite/vfs.ts +13 -8
- package/src/db/sync/SSRWebStreamingSyncImplementation.ts +8 -36
- package/src/db/sync/SharedWebStreamingSyncImplementation.ts +47 -82
- package/src/db/sync/TabLocalStreamingSyncImplementation.ts +90 -0
- package/src/db/sync/WebRemote.ts +23 -26
- package/src/db/sync/WebStreamingSyncImplementation.ts +4 -5
- package/src/index.ts +1 -3
- package/src/worker/SharedWorkerConnectionRequest.ts +6 -0
- package/src/worker/client.ts +121 -0
- package/src/worker/db/MultiDatabaseServer.ts +59 -33
- package/src/worker/sync/AbstractSharedSyncClientProvider.ts +5 -10
- package/src/worker/sync/BroadcastLogger.ts +35 -103
- package/src/worker/sync/SharedSyncImplementation.ts +197 -138
- package/src/worker/sync/WorkerClient.ts +8 -8
- package/src/worker/worker.ts +38 -0
- package/dist/2075a31bb151adbb9767.wasm +0 -0
- package/dist/3322bc84de986b63c2cd.wasm +0 -0
- package/dist/8e97452e297be23b5e50.wasm +0 -0
- package/dist/fbc178b70d530e8ce02b.wasm +0 -0
- package/dist/index.umd.js +0 -7821
- package/dist/index.umd.js.map +0 -1
- package/dist/worker/SharedSyncImplementation.umd.js +0 -16139
- package/dist/worker/SharedSyncImplementation.umd.js.map +0 -1
- package/dist/worker/WASQLiteDB.umd.js +0 -17434
- package/dist/worker/WASQLiteDB.umd.js.map +0 -1
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_dist_mc-wa-s-9af0a7.umd.js +0 -31
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_dist_mc-wa-s-9af0a7.umd.js.map +0 -1
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_dist_mc-wa-s-bbf5a9.umd.js +0 -31
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_dist_mc-wa-s-bbf5a9.umd.js.map +0 -1
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_dist_wa-sqli-c26e0f.umd.js +0 -31
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_dist_wa-sqli-c26e0f.umd.js.map +0 -1
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_dist_wa-sqlite_mjs.umd.js +0 -31
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_dist_wa-sqlite_mjs.umd.js.map +0 -1
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-2fb422.umd.js +0 -3562
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-2fb422.umd.js.map +0 -1
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-833585.umd.js +0 -1400
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-833585.umd.js.map +0 -1
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-96fb23.umd.js +0 -2478
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-96fb23.umd.js.map +0 -1
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-c89911.umd.js +0 -1681
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-c89911.umd.js.map +0 -1
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-ec4eb1.umd.js +0 -1820
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-ec4eb1.umd.js.map +0 -1
- package/lib/package.json +0 -91
- package/lib/src/attachments/IndexDBFileSystemAdapter.js.map +0 -1
- package/lib/src/db/NavigatorTriggerClaimManager.js.map +0 -1
- package/lib/src/db/PowerSyncDatabase.d.ts +0 -78
- package/lib/src/db/PowerSyncDatabase.js.map +0 -1
- package/lib/src/db/adapters/AbstractWebPowerSyncDatabaseOpenFactory.d.ts +0 -23
- package/lib/src/db/adapters/AbstractWebPowerSyncDatabaseOpenFactory.js +0 -27
- package/lib/src/db/adapters/AbstractWebPowerSyncDatabaseOpenFactory.js.map +0 -1
- package/lib/src/db/adapters/AsyncWebAdapter.d.ts +0 -50
- package/lib/src/db/adapters/AsyncWebAdapter.js.map +0 -1
- package/lib/src/db/adapters/SSRDBAdapter.d.ts +0 -30
- package/lib/src/db/adapters/SSRDBAdapter.js +0 -69
- package/lib/src/db/adapters/SSRDBAdapter.js.map +0 -1
- package/lib/src/db/adapters/WebDBAdapter.js.map +0 -1
- package/lib/src/db/adapters/wa-sqlite/ConcurrentConnection.js.map +0 -1
- package/lib/src/db/adapters/wa-sqlite/DatabaseClient.js.map +0 -1
- package/lib/src/db/adapters/wa-sqlite/DatabaseServer.js.map +0 -1
- package/lib/src/db/adapters/wa-sqlite/RawSqliteConnection.js.map +0 -1
- package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.d.ts +0 -45
- package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.js +0 -146
- package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.js.map +0 -1
- package/lib/src/db/adapters/wa-sqlite/WASQLitePowerSyncDatabaseOpenFactory.d.ts +0 -15
- package/lib/src/db/adapters/wa-sqlite/WASQLitePowerSyncDatabaseOpenFactory.js +0 -22
- package/lib/src/db/adapters/wa-sqlite/WASQLitePowerSyncDatabaseOpenFactory.js.map +0 -1
- package/lib/src/db/adapters/wa-sqlite/vfs.js.map +0 -1
- package/lib/src/db/adapters/web-sql-flags.d.ts +0 -92
- package/lib/src/db/adapters/web-sql-flags.js +0 -37
- package/lib/src/db/adapters/web-sql-flags.js.map +0 -1
- package/lib/src/db/sync/SSRWebStreamingSyncImplementation.js.map +0 -1
- package/lib/src/db/sync/SharedWebStreamingSyncImplementation.js.map +0 -1
- package/lib/src/db/sync/WebRemote.d.ts +0 -7
- package/lib/src/db/sync/WebRemote.js +0 -33
- package/lib/src/db/sync/WebRemote.js.map +0 -1
- package/lib/src/db/sync/WebStreamingSyncImplementation.js.map +0 -1
- package/lib/src/db/sync/userAgent.js.map +0 -1
- package/lib/src/index.js.map +0 -1
- package/lib/src/shared/navigator.js.map +0 -1
- package/lib/src/shared/tab_close_signal.js.map +0 -1
- package/lib/src/worker/db/MultiDatabaseServer.d.ts +0 -17
- package/lib/src/worker/db/MultiDatabaseServer.js.map +0 -1
- package/lib/src/worker/db/WASQLiteDB.worker.d.ts +0 -4
- package/lib/src/worker/db/WASQLiteDB.worker.js +0 -31
- package/lib/src/worker/db/WASQLiteDB.worker.js.map +0 -1
- package/lib/src/worker/db/open-worker-database.d.ts +0 -14
- package/lib/src/worker/db/open-worker-database.js +0 -53
- package/lib/src/worker/db/open-worker-database.js.map +0 -1
- package/lib/src/worker/sync/AbstractSharedSyncClientProvider.d.ts +0 -19
- package/lib/src/worker/sync/AbstractSharedSyncClientProvider.js.map +0 -1
- package/lib/src/worker/sync/BroadcastLogger.d.ts +0 -47
- package/lib/src/worker/sync/BroadcastLogger.js +0 -129
- package/lib/src/worker/sync/BroadcastLogger.js.map +0 -1
- package/lib/src/worker/sync/SharedSyncImplementation.js.map +0 -1
- package/lib/src/worker/sync/SharedSyncImplementation.worker.js +0 -12
- package/lib/src/worker/sync/SharedSyncImplementation.worker.js.map +0 -1
- package/lib/src/worker/sync/WorkerClient.js.map +0 -1
- package/lib/tsconfig.tsbuildinfo +0 -1
- package/src/db/adapters/AbstractWebPowerSyncDatabaseOpenFactory.ts +0 -47
- package/src/db/adapters/wa-sqlite/WASQLitePowerSyncDatabaseOpenFactory.ts +0 -24
- package/src/db/adapters/web-sql-flags.ts +0 -141
- package/src/worker/db/WASQLiteDB.worker.ts +0 -35
- package/src/worker/db/open-worker-database.ts +0 -62
- package/src/worker/sync/SharedSyncImplementation.worker.ts +0 -14
- /package/lib/{src/attachments → attachments}/IndexDBFileSystemAdapter.d.ts +0 -0
- /package/lib/{src/attachments → attachments}/IndexDBFileSystemAdapter.js +0 -0
- /package/lib/{src/db → db}/NavigatorTriggerClaimManager.js +0 -0
- /package/lib/{src/db → db}/adapters/WebDBAdapter.js +0 -0
- /package/lib/{src/worker/sync/SharedSyncImplementation.worker.d.ts → db/adapters/memory-pool/worker.d.ts} +0 -0
- /package/lib/{src/db → db}/sync/userAgent.d.ts +0 -0
- /package/lib/{src/db → db}/sync/userAgent.js +0 -0
- /package/lib/{src/shared → shared}/navigator.d.ts +0 -0
- /package/lib/{src/shared → shared}/navigator.js +0 -0
- /package/lib/{src/shared → shared}/tab_close_signal.d.ts +0 -0
- /package/lib/{src/shared → shared}/tab_close_signal.js +0 -0
- /package/lib/{src/worker → worker}/sync/AbstractSharedSyncClientProvider.js +0 -0
|
@@ -1,26 +1,24 @@
|
|
|
1
1
|
import {
|
|
2
|
-
AbortOperation,
|
|
3
2
|
BaseObserver,
|
|
4
|
-
ConnectionManager,
|
|
5
|
-
ConnectionPool,
|
|
6
3
|
DBAdapter,
|
|
7
|
-
DBAdapterDefaultMixin,
|
|
8
|
-
DBAdapterListener,
|
|
9
4
|
DBLockOptions,
|
|
10
5
|
LockContext,
|
|
11
6
|
PowerSyncBackendConnector,
|
|
7
|
+
SyncStatus,
|
|
8
|
+
LogLevels,
|
|
9
|
+
SyncStreamConnectionMethod
|
|
10
|
+
} from '@powersync/common';
|
|
11
|
+
import {
|
|
12
|
+
AbortOperation,
|
|
13
|
+
ConnectionManager,
|
|
12
14
|
SqliteBucketStorage,
|
|
13
15
|
SubscribedStream,
|
|
14
|
-
SyncStatus,
|
|
15
|
-
createLogger,
|
|
16
|
-
Mutex,
|
|
17
|
-
type ILogLevel,
|
|
18
|
-
type ILogger,
|
|
19
|
-
type PowerSyncConnectionOptions,
|
|
20
16
|
type StreamingSyncImplementation,
|
|
21
17
|
type StreamingSyncImplementationListener,
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
Mutex,
|
|
19
|
+
ResolvedSyncOptions,
|
|
20
|
+
SyncStatusSnapshot
|
|
21
|
+
} from '@powersync/shared-internals';
|
|
24
22
|
import * as Comlink from 'comlink';
|
|
25
23
|
import { WebRemote } from '../../db/sync/WebRemote.js';
|
|
26
24
|
import {
|
|
@@ -28,11 +26,11 @@ import {
|
|
|
28
26
|
WebStreamingSyncImplementationOptions
|
|
29
27
|
} from '../../db/sync/WebStreamingSyncImplementation.js';
|
|
30
28
|
|
|
31
|
-
import { ResolvedWebSQLOpenOptions } from '../../db/adapters/web-sql-flags.js';
|
|
32
29
|
import { AbstractSharedSyncClientProvider } from './AbstractSharedSyncClientProvider.js';
|
|
33
30
|
import { BroadcastLogger } from './BroadcastLogger.js';
|
|
34
31
|
import { DatabaseClient, OpenWorkerConnection } from '../../db/adapters/wa-sqlite/DatabaseClient.js';
|
|
35
32
|
import { generateTabCloseSignal } from '../../shared/tab_close_signal.js';
|
|
33
|
+
import { ResolvedWebSQLOpenOptions } from '../../db/adapters/options.js';
|
|
36
34
|
|
|
37
35
|
/**
|
|
38
36
|
* @internal
|
|
@@ -60,8 +58,12 @@ export type ManualSharedSyncPayload = {
|
|
|
60
58
|
* @internal
|
|
61
59
|
*/
|
|
62
60
|
export type SharedSyncInitOptions = {
|
|
63
|
-
streamOptions: Omit<
|
|
61
|
+
streamOptions: Omit<
|
|
62
|
+
WebStreamingSyncImplementationOptions,
|
|
63
|
+
'adapter' | 'uploadCrud' | 'postCheckpointRequest' | 'remote' | 'subscriptions' | 'logger'
|
|
64
|
+
>;
|
|
64
65
|
dbParams: ResolvedWebSQLOpenOptions;
|
|
66
|
+
enableBroadcastLogs: boolean;
|
|
65
67
|
};
|
|
66
68
|
|
|
67
69
|
/**
|
|
@@ -83,14 +85,6 @@ export type WrappedSyncPort = {
|
|
|
83
85
|
isClosing: boolean;
|
|
84
86
|
};
|
|
85
87
|
|
|
86
|
-
/**
|
|
87
|
-
* @internal
|
|
88
|
-
*/
|
|
89
|
-
export type RemoteOperationAbortController = {
|
|
90
|
-
controller: AbortController;
|
|
91
|
-
activePort: WrappedSyncPort;
|
|
92
|
-
};
|
|
93
|
-
|
|
94
88
|
/**
|
|
95
89
|
* HACK: The shared implementation wraps and provides its own
|
|
96
90
|
* PowerSyncBackendConnector when generating the streaming sync implementation.
|
|
@@ -98,6 +92,23 @@ export type RemoteOperationAbortController = {
|
|
|
98
92
|
*/
|
|
99
93
|
const CONNECTOR_PLACEHOLDER = {} as PowerSyncBackendConnector;
|
|
100
94
|
|
|
95
|
+
/**
|
|
96
|
+
* How long to wait for a client tab to answer a call before giving up on it.
|
|
97
|
+
*/
|
|
98
|
+
const CONNECTOR_CALL_TIMEOUT_MS = 30_000;
|
|
99
|
+
|
|
100
|
+
type UseConnectorOptions = {
|
|
101
|
+
/**
|
|
102
|
+
* Aborted when the sync client disconnects.
|
|
103
|
+
*/
|
|
104
|
+
signal?: AbortSignal;
|
|
105
|
+
/**
|
|
106
|
+
* Fail the call if the tab has not responded within this many milliseconds. `null` waits indefinitely, which is only
|
|
107
|
+
* appropriate for calls that are unbounded by nature and already covered by {@link UseConnectorOptions.signal}.
|
|
108
|
+
*/
|
|
109
|
+
timeoutMs?: number | null;
|
|
110
|
+
};
|
|
111
|
+
|
|
101
112
|
/**
|
|
102
113
|
* @internal
|
|
103
114
|
* Shared sync implementation which runs inside a shared webworker
|
|
@@ -108,25 +119,22 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
|
|
|
108
119
|
protected isInitialized: Promise<void>;
|
|
109
120
|
protected statusListener?: () => void;
|
|
110
121
|
|
|
111
|
-
protected fetchCredentialsController?: RemoteOperationAbortController;
|
|
112
|
-
protected uploadDataController?: RemoteOperationAbortController;
|
|
113
|
-
|
|
114
122
|
protected syncParams: SharedSyncInitOptions | null;
|
|
115
|
-
protected
|
|
116
|
-
protected lastConnectOptions: PowerSyncConnectionOptions | undefined;
|
|
123
|
+
protected lastConnectOptions: ResolvedSyncOptions | undefined;
|
|
117
124
|
protected portMutex: Mutex;
|
|
118
125
|
private subscriptions: SubscribedStream[] = [];
|
|
119
126
|
|
|
120
127
|
protected connectionManager: ConnectionManager;
|
|
121
|
-
syncStatus
|
|
122
|
-
|
|
128
|
+
private syncStatus?: SyncStatusSnapshot;
|
|
129
|
+
logger: BroadcastLogger;
|
|
123
130
|
protected readonly database = this.generateReconnectableDatabase();
|
|
124
131
|
|
|
132
|
+
private sharedCloseSignal = generateTabCloseSignal();
|
|
133
|
+
|
|
125
134
|
constructor() {
|
|
126
135
|
super();
|
|
127
136
|
this.ports = [];
|
|
128
137
|
this.syncParams = null;
|
|
129
|
-
this.logger = createLogger('shared-sync');
|
|
130
138
|
this.lastConnectOptions = undefined;
|
|
131
139
|
this.portMutex = new Mutex();
|
|
132
140
|
|
|
@@ -139,26 +147,37 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
|
|
|
139
147
|
});
|
|
140
148
|
});
|
|
141
149
|
|
|
142
|
-
this.
|
|
143
|
-
this.broadCastLogger = new BroadcastLogger(this.ports);
|
|
150
|
+
this.logger = new BroadcastLogger('shared-sync', this.ports);
|
|
144
151
|
|
|
145
152
|
this.connectionManager = new ConnectionManager({
|
|
146
153
|
createSyncImplementation: async () => {
|
|
147
154
|
await this.waitForReady();
|
|
148
155
|
|
|
149
156
|
const sync = this.generateStreamingImplementation();
|
|
150
|
-
const
|
|
151
|
-
statusChanged: (
|
|
152
|
-
this.
|
|
157
|
+
const removeStatusListener = sync.registerListener({
|
|
158
|
+
statusChanged: (snapshot) => {
|
|
159
|
+
this.syncStatus = snapshot;
|
|
160
|
+
const json = snapshot.toJSON();
|
|
161
|
+
this.ports.forEach((p) => p.clientProvider.statusChanged(json));
|
|
153
162
|
}
|
|
154
163
|
});
|
|
155
164
|
|
|
156
165
|
return {
|
|
157
166
|
sync,
|
|
158
|
-
onDispose
|
|
167
|
+
onDispose: () => {
|
|
168
|
+
removeStatusListener();
|
|
169
|
+
|
|
170
|
+
// Drop the JavaScript state along with the implementation that produced it: it describes in-flight work of
|
|
171
|
+
// a sync client that no longer exists. `addPort` hands this status to every tab that connects afterwards,
|
|
172
|
+
// so a `downloadError` left here is shown by tabs that never saw the failure, and nothing can clear it
|
|
173
|
+
// because only a completed sync does. The core status is kept - `hasSynced` and `lastSyncedAt` are
|
|
174
|
+
// persisted facts that remain true while disconnected.
|
|
175
|
+
this.syncStatus &&= new SyncStatusSnapshot(this.syncStatus.core, {});
|
|
176
|
+
}
|
|
159
177
|
};
|
|
160
178
|
},
|
|
161
|
-
logger: this.logger
|
|
179
|
+
logger: this.logger,
|
|
180
|
+
defaultConnectionMethod: SyncStreamConnectionMethod.HTTP
|
|
162
181
|
});
|
|
163
182
|
}
|
|
164
183
|
|
|
@@ -192,12 +211,6 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
|
|
|
192
211
|
});
|
|
193
212
|
}
|
|
194
213
|
|
|
195
|
-
async waitForStatus(status: SyncStatusOptions): Promise<void> {
|
|
196
|
-
return this.withSyncImplementation(async (sync) => {
|
|
197
|
-
return sync.waitForStatus(status);
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
|
|
201
214
|
async waitUntilStatusMatches(predicate: (status: SyncStatus) => boolean): Promise<void> {
|
|
202
215
|
return this.withSyncImplementation(async (sync) => {
|
|
203
216
|
return sync.waitUntilStatusMatches(predicate);
|
|
@@ -209,7 +222,7 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
|
|
|
209
222
|
}
|
|
210
223
|
|
|
211
224
|
private collectActiveSubscriptions() {
|
|
212
|
-
this.logger.debug
|
|
225
|
+
this.logger.log({ level: LogLevels.debug, message: 'Collecting active stream subscriptions across tabs' });
|
|
213
226
|
const active = new Map<string, SubscribedStream>();
|
|
214
227
|
for (const port of this.ports) {
|
|
215
228
|
for (const stream of port.currentSubscriptions) {
|
|
@@ -218,7 +231,10 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
|
|
|
218
231
|
}
|
|
219
232
|
}
|
|
220
233
|
this.subscriptions = [...active.values()];
|
|
221
|
-
this.logger.
|
|
234
|
+
this.logger.log({
|
|
235
|
+
level: LogLevels.debug,
|
|
236
|
+
message: `Collected stream subscriptions, ${JSON.stringify(this.subscriptions)}`
|
|
237
|
+
});
|
|
222
238
|
this.connectionManager.syncStreamImplementation?.updateSubscriptions(this.subscriptions);
|
|
223
239
|
}
|
|
224
240
|
|
|
@@ -227,9 +243,8 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
|
|
|
227
243
|
this.collectActiveSubscriptions();
|
|
228
244
|
}
|
|
229
245
|
|
|
230
|
-
setLogLevel(level:
|
|
246
|
+
setLogLevel(level: number) {
|
|
231
247
|
this.logger.setLevel(level);
|
|
232
|
-
this.broadCastLogger.setLevel(level);
|
|
233
248
|
}
|
|
234
249
|
|
|
235
250
|
/**
|
|
@@ -247,16 +262,18 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
|
|
|
247
262
|
|
|
248
263
|
// First time setting params
|
|
249
264
|
this.syncParams = params;
|
|
250
|
-
|
|
251
|
-
this.logger = this.broadCastLogger;
|
|
252
|
-
}
|
|
265
|
+
this.logger.sendBroadcasts = params.enableBroadcastLogs;
|
|
253
266
|
|
|
254
267
|
// Ensure we have a usable database connection, the reconnectable database will connect lazily on first use.
|
|
255
268
|
await this.database.readLock(async () => {});
|
|
256
269
|
|
|
257
270
|
self.onerror = (event) => {
|
|
258
271
|
// Share any uncaught events on the broadcast logger
|
|
259
|
-
this.logger.
|
|
272
|
+
this.logger.log({
|
|
273
|
+
level: LogLevels.error,
|
|
274
|
+
message: 'Uncaught exception in PowerSync shared sync worker',
|
|
275
|
+
error: event
|
|
276
|
+
});
|
|
260
277
|
};
|
|
261
278
|
|
|
262
279
|
this.iterateListeners((l) => l.initialized?.());
|
|
@@ -274,9 +291,9 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
|
|
|
274
291
|
* The connection will simply be reconnected whenever a new tab
|
|
275
292
|
* connects.
|
|
276
293
|
*/
|
|
277
|
-
async connect(options
|
|
294
|
+
async connect(options: ResolvedSyncOptions, serializedSchema: any) {
|
|
278
295
|
this.lastConnectOptions = options;
|
|
279
|
-
return this.connectionManager.connect(CONNECTOR_PLACEHOLDER, options ?? {});
|
|
296
|
+
return this.connectionManager.connect(CONNECTOR_PLACEHOLDER, options ?? {}, serializedSchema);
|
|
280
297
|
}
|
|
281
298
|
|
|
282
299
|
async disconnect() {
|
|
@@ -298,7 +315,7 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
|
|
|
298
315
|
this.ports.push(portProvider);
|
|
299
316
|
|
|
300
317
|
// Give the newly connected client the latest status
|
|
301
|
-
const status = this.
|
|
318
|
+
const status = this.syncStatus;
|
|
302
319
|
if (status) {
|
|
303
320
|
portProvider.clientProvider.statusChanged(status.toJSON());
|
|
304
321
|
}
|
|
@@ -321,7 +338,10 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
|
|
|
321
338
|
return await this.portMutex.runExclusive(async () => {
|
|
322
339
|
const index = this.ports.findIndex((p) => p == port);
|
|
323
340
|
if (index < 0) {
|
|
324
|
-
this.logger.
|
|
341
|
+
this.logger.log({
|
|
342
|
+
level: LogLevels.warn,
|
|
343
|
+
message: `Could not remove port ${port} since it is not present in active ports.`
|
|
344
|
+
});
|
|
325
345
|
return () => {};
|
|
326
346
|
}
|
|
327
347
|
|
|
@@ -329,18 +349,6 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
|
|
|
329
349
|
// Remove from the list of active ports
|
|
330
350
|
this.ports.splice(index, 1);
|
|
331
351
|
|
|
332
|
-
/**
|
|
333
|
-
* The port might currently be in use. Any active functions might
|
|
334
|
-
* not resolve. Abort them here.
|
|
335
|
-
*/
|
|
336
|
-
[this.fetchCredentialsController, this.uploadDataController].forEach((abortController) => {
|
|
337
|
-
if (abortController?.activePort == port) {
|
|
338
|
-
abortController!.controller.abort(
|
|
339
|
-
new AbortOperation('Closing pending requests after client port is removed')
|
|
340
|
-
);
|
|
341
|
-
}
|
|
342
|
-
});
|
|
343
|
-
|
|
344
352
|
// Close the worker wrapped database connection, we can't accurately rely on this connection
|
|
345
353
|
for (const closeListener of trackedPort.closeListeners) {
|
|
346
354
|
await closeListener();
|
|
@@ -358,10 +366,8 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
|
|
|
358
366
|
});
|
|
359
367
|
}
|
|
360
368
|
|
|
361
|
-
|
|
362
|
-
return this.withSyncImplementation(
|
|
363
|
-
return sync.getWriteCheckpoint();
|
|
364
|
-
});
|
|
369
|
+
requestCheckpoint() {
|
|
370
|
+
return this.withSyncImplementation((sync) => sync.requestCheckpoint());
|
|
365
371
|
}
|
|
366
372
|
|
|
367
373
|
protected async withSyncImplementation<T>(callback: (sync: StreamingSyncImplementation) => Promise<T>): Promise<T> {
|
|
@@ -397,62 +403,48 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
|
|
|
397
403
|
throw new Error('No client port found to invalidate credentials');
|
|
398
404
|
}
|
|
399
405
|
try {
|
|
400
|
-
this.logger.log(
|
|
406
|
+
this.logger.log({
|
|
407
|
+
level: LogLevels.info,
|
|
408
|
+
message: 'calling the last port client provider to invalidate credentials'
|
|
409
|
+
});
|
|
401
410
|
lastPort.clientProvider.invalidateCredentials();
|
|
402
|
-
} catch (
|
|
403
|
-
this.logger.error
|
|
411
|
+
} catch (error) {
|
|
412
|
+
this.logger.log({ level: LogLevels.error, message: 'error invalidating credentials', error });
|
|
404
413
|
}
|
|
405
414
|
},
|
|
406
|
-
fetchCredentials:
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
this.logger.log('calling the last port client provider for credentials');
|
|
421
|
-
resolve(await lastPort.clientProvider.fetchCredentials());
|
|
422
|
-
} catch (ex) {
|
|
423
|
-
reject(ex);
|
|
424
|
-
} finally {
|
|
425
|
-
this.fetchCredentialsController = undefined;
|
|
426
|
-
}
|
|
427
|
-
});
|
|
415
|
+
fetchCredentials: () => {
|
|
416
|
+
return this.#useConnector(
|
|
417
|
+
(port) => {
|
|
418
|
+
this.logger.log({
|
|
419
|
+
level: LogLevels.info,
|
|
420
|
+
message: 'calling the last port client provider for credentials'
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
return port.clientProvider.fetchCredentials();
|
|
424
|
+
},
|
|
425
|
+
'fetchCredentials',
|
|
426
|
+
// No sync abort signal reaches the remote, so this relies on the timeout alone.
|
|
427
|
+
{ timeoutMs: CONNECTOR_CALL_TIMEOUT_MS }
|
|
428
|
+
);
|
|
428
429
|
}
|
|
429
430
|
},
|
|
430
431
|
this.logger
|
|
431
432
|
),
|
|
432
|
-
uploadCrud:
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
return new Promise(async (resolve, reject) => {
|
|
439
|
-
const abortController = new AbortController();
|
|
440
|
-
this.uploadDataController = {
|
|
441
|
-
controller: abortController,
|
|
442
|
-
activePort: lastPort
|
|
443
|
-
};
|
|
444
|
-
|
|
445
|
-
// Resolving will make it retry
|
|
446
|
-
abortController.signal.onabort = () => resolve();
|
|
447
|
-
try {
|
|
448
|
-
resolve(await lastPort.clientProvider.uploadCrud());
|
|
449
|
-
} catch (ex) {
|
|
450
|
-
reject(ex);
|
|
451
|
-
} finally {
|
|
452
|
-
this.uploadDataController = undefined;
|
|
453
|
-
}
|
|
433
|
+
uploadCrud: (signal) => {
|
|
434
|
+
return this.#useConnector((port) => port.clientProvider.uploadCrud(), 'uploadCrud', {
|
|
435
|
+
signal,
|
|
436
|
+
// Uploads are user-defined and legitimately unbounded (large batches over slow connections), so a timeout
|
|
437
|
+
// would cut valid work short. Disconnecting aborts the signal, which is what releases this.
|
|
438
|
+
timeoutMs: null
|
|
454
439
|
});
|
|
455
440
|
},
|
|
441
|
+
postCheckpointRequest: (clientId, requestId, signal) => {
|
|
442
|
+
return this.#useConnector(
|
|
443
|
+
(port) => port.clientProvider.postCheckpointRequest(clientId, requestId),
|
|
444
|
+
'postCheckpointRequest',
|
|
445
|
+
{ signal, timeoutMs: CONNECTOR_CALL_TIMEOUT_MS }
|
|
446
|
+
);
|
|
447
|
+
},
|
|
456
448
|
...syncParams.streamOptions,
|
|
457
449
|
subscriptions: this.subscriptions,
|
|
458
450
|
// Logger cannot be transferred just yet
|
|
@@ -460,6 +452,79 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
|
|
|
460
452
|
});
|
|
461
453
|
}
|
|
462
454
|
|
|
455
|
+
/**
|
|
456
|
+
* Calls into a client tab.
|
|
457
|
+
*
|
|
458
|
+
* A tab can stop servicing its message port without ever closing it: it may be frozen or in the back/forward cache,
|
|
459
|
+
* or its sync implementation may have been abandoned without being disposed. Comlink has no timeout of its own, so a
|
|
460
|
+
* call to such a port settles neither way, and the `closeListeners` below only fire for ports we know have closed.
|
|
461
|
+
*
|
|
462
|
+
* That is not a local problem. `disconnect()` awaits the sync loops, so a single call that can never settle wedges
|
|
463
|
+
* the disconnect, and with it every `connect()` queued behind it. Every call is therefore bounded by the caller's
|
|
464
|
+
* abort signal, a timeout, or both.
|
|
465
|
+
*/
|
|
466
|
+
async #useConnector<T>(
|
|
467
|
+
inner: (port: WrappedSyncPort) => Promise<T>,
|
|
468
|
+
debugContext: string,
|
|
469
|
+
options: UseConnectorOptions = {}
|
|
470
|
+
): Promise<T> {
|
|
471
|
+
const { signal, timeoutMs = CONNECTOR_CALL_TIMEOUT_MS } = options;
|
|
472
|
+
|
|
473
|
+
const controller = new AbortController();
|
|
474
|
+
const abortWith = (reason: string) => {
|
|
475
|
+
if (controller.signal.aborted) {
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
this.logger.log({ level: LogLevels.warn, message: `Aborting ${debugContext}: ${reason}` });
|
|
479
|
+
controller.abort(new AbortOperation(`Aborted ${debugContext}: ${reason}`));
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
const timeout =
|
|
483
|
+
timeoutMs == null
|
|
484
|
+
? undefined
|
|
485
|
+
: setTimeout(() => abortWith(`the client tab did not respond within ${timeoutMs}ms`), timeoutMs);
|
|
486
|
+
|
|
487
|
+
const onRequestedAbort = () => abortWith('the sync client disconnected');
|
|
488
|
+
signal?.addEventListener('abort', onRequestedAbort, { once: true });
|
|
489
|
+
if (signal?.aborted) {
|
|
490
|
+
onRequestedAbort();
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
try {
|
|
494
|
+
return await withAbort({
|
|
495
|
+
signal: controller.signal,
|
|
496
|
+
// Resolving the port takes the portMutex, which is held while other ports are being removed, so it has to be
|
|
497
|
+
// inside the guard as well.
|
|
498
|
+
action: async () => {
|
|
499
|
+
const lastPort = await this.getLastWrappedPort();
|
|
500
|
+
if (!lastPort) {
|
|
501
|
+
throw new Error(`No client port found for ${debugContext}`);
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
return await new Promise<T>((resolve, reject) => {
|
|
505
|
+
const portClosed = () => {
|
|
506
|
+
reject(new Error(`Tab closed while handling ${debugContext}`));
|
|
507
|
+
};
|
|
508
|
+
|
|
509
|
+
lastPort.closeListeners.push(portClosed);
|
|
510
|
+
|
|
511
|
+
inner(lastPort)
|
|
512
|
+
.then(resolve, reject)
|
|
513
|
+
.finally(() => {
|
|
514
|
+
const index = lastPort.closeListeners.indexOf(portClosed);
|
|
515
|
+
if (index >= 0) {
|
|
516
|
+
lastPort.closeListeners.splice(index, 1);
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
} finally {
|
|
523
|
+
clearTimeout(timeout);
|
|
524
|
+
signal?.removeEventListener('abort', onRequestedAbort);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
|
|
463
528
|
/**
|
|
464
529
|
* Requests a random client to share its database connection with us.
|
|
465
530
|
*/
|
|
@@ -508,7 +573,7 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
|
|
|
508
573
|
const remote = Comlink.wrap<OpenWorkerConnection>(workerPort);
|
|
509
574
|
const identifier = this.syncParams!.dbParams.dbFilename;
|
|
510
575
|
|
|
511
|
-
const clientLockName = await
|
|
576
|
+
const clientLockName = await this.sharedCloseSignal;
|
|
512
577
|
|
|
513
578
|
/**
|
|
514
579
|
* The open could fail if the tab is closed while we're busy opening the database.
|
|
@@ -542,7 +607,7 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
|
|
|
542
607
|
clearTimeout(timeout);
|
|
543
608
|
|
|
544
609
|
client.closeListeners.push(async () => {
|
|
545
|
-
this.logger.info
|
|
610
|
+
this.logger.log({ level: LogLevels.info, message: 'Aborting open connection because associated tab closed.' });
|
|
546
611
|
handleClosed(db);
|
|
547
612
|
/**
|
|
548
613
|
* Don't await this close operation. It might never resolve if the tab is closed.
|
|
@@ -550,7 +615,9 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
|
|
|
550
615
|
* We then call close. The close operation is configured to fire-and-forget, the main promise will reject immediately.
|
|
551
616
|
*/
|
|
552
617
|
db.markRemoteClosed();
|
|
553
|
-
db.close().catch((
|
|
618
|
+
db.close().catch((error) =>
|
|
619
|
+
this.logger.log({ level: LogLevels.warn, message: 'error closing database connection', error })
|
|
620
|
+
);
|
|
554
621
|
});
|
|
555
622
|
return db;
|
|
556
623
|
}
|
|
@@ -559,7 +626,7 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
|
|
|
559
626
|
const syncParams = this.syncParams;
|
|
560
627
|
const sharedSync = this;
|
|
561
628
|
|
|
562
|
-
class
|
|
629
|
+
return new (class extends DBAdapter {
|
|
563
630
|
private connectionState:
|
|
564
631
|
| null
|
|
565
632
|
| DatabaseClient<ResolvedWebSQLOpenOptions>
|
|
@@ -628,19 +695,7 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
|
|
|
628
695
|
async refreshSchema(): Promise<void> {
|
|
629
696
|
// Not used by sync client.
|
|
630
697
|
}
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
const Adapter = DBAdapterDefaultMixin(ReconnectPool);
|
|
634
|
-
return new Adapter();
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
/**
|
|
638
|
-
* A method to update the all shared statuses for each
|
|
639
|
-
* client.
|
|
640
|
-
*/
|
|
641
|
-
private updateAllStatuses(status: SyncStatusOptions) {
|
|
642
|
-
this.syncStatus = new SyncStatus(status);
|
|
643
|
-
this.ports.forEach((p) => p.clientProvider.statusChanged(status));
|
|
698
|
+
})();
|
|
644
699
|
}
|
|
645
700
|
}
|
|
646
701
|
|
|
@@ -653,15 +708,19 @@ function withAbort<T>(options: {
|
|
|
653
708
|
cleanupOnAbort?: (result: T) => void;
|
|
654
709
|
}): Promise<T> {
|
|
655
710
|
const { action, signal, cleanupOnAbort } = options;
|
|
711
|
+
// Callers that abort with an `Error` reason get it propagated, so the failure says what actually went wrong.
|
|
712
|
+
const abortError = () =>
|
|
713
|
+
signal.reason instanceof Error ? signal.reason : new AbortOperation('Operation aborted by abort controller');
|
|
714
|
+
|
|
656
715
|
return new Promise((resolve, reject) => {
|
|
657
716
|
if (signal.aborted) {
|
|
658
|
-
reject(
|
|
717
|
+
reject(abortError());
|
|
659
718
|
return;
|
|
660
719
|
}
|
|
661
720
|
|
|
662
721
|
function handleAbort() {
|
|
663
722
|
signal.removeEventListener('abort', handleAbort);
|
|
664
|
-
reject(
|
|
723
|
+
reject(abortError());
|
|
665
724
|
}
|
|
666
725
|
|
|
667
726
|
signal.addEventListener('abort', handleAbort, { once: true });
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { ILogLevel, PowerSyncConnectionOptions, SubscribedStream } from '@powersync/common';
|
|
2
1
|
import * as Comlink from 'comlink';
|
|
3
2
|
import { getNavigatorLocks } from '../../shared/navigator.js';
|
|
4
3
|
import {
|
|
@@ -8,6 +7,7 @@ import {
|
|
|
8
7
|
SharedSyncInitOptions,
|
|
9
8
|
WrappedSyncPort
|
|
10
9
|
} from './SharedSyncImplementation.js';
|
|
10
|
+
import { SubscribedStream, ResolvedSyncOptions } from '@powersync/shared-internals';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* A client to the shared sync worker.
|
|
@@ -65,7 +65,7 @@ export class WorkerClient {
|
|
|
65
65
|
});
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
setLogLevel(level:
|
|
68
|
+
setLogLevel(level: number) {
|
|
69
69
|
this.sync.setLogLevel(level);
|
|
70
70
|
}
|
|
71
71
|
|
|
@@ -78,12 +78,8 @@ export class WorkerClient {
|
|
|
78
78
|
return this.sync.setParams(params);
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
return this.sync.
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
connect(options?: PowerSyncConnectionOptions) {
|
|
86
|
-
return this.sync.connect(options);
|
|
81
|
+
connect(options: ResolvedSyncOptions, schema: any) {
|
|
82
|
+
return this.sync.connect(options, schema);
|
|
87
83
|
}
|
|
88
84
|
|
|
89
85
|
updateSubscriptions(subscriptions: SubscribedStream[]) {
|
|
@@ -92,6 +88,10 @@ export class WorkerClient {
|
|
|
92
88
|
}
|
|
93
89
|
}
|
|
94
90
|
|
|
91
|
+
requestCheckpoint(): Promise<bigint> {
|
|
92
|
+
return this.sync.requestCheckpoint();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
95
|
disconnect() {
|
|
96
96
|
return this.sync.disconnect();
|
|
97
97
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as Comlink from 'comlink';
|
|
2
|
+
|
|
3
|
+
import { createConsoleLogger, LogLevels } from '@powersync/common';
|
|
4
|
+
import { isSharedWorker, MultiDatabaseServer } from './db/MultiDatabaseServer.js';
|
|
5
|
+
import { SharedSyncImplementation } from './sync/SharedSyncImplementation.js';
|
|
6
|
+
import { OpenWorkerConnection } from '../db/adapters/wa-sqlite/DatabaseClient.js';
|
|
7
|
+
import { SharedWorkerConnectionRequest } from './SharedWorkerConnectionRequest.js';
|
|
8
|
+
import { WorkerClient } from './sync/WorkerClient.js';
|
|
9
|
+
|
|
10
|
+
const server = new MultiDatabaseServer(createConsoleLogger({ prefix: 'db-worker', minLevel: LogLevels.trace }));
|
|
11
|
+
|
|
12
|
+
const exposedDatabaseFunctions: OpenWorkerConnection = {
|
|
13
|
+
connect: (config) => server.handleConnection(config),
|
|
14
|
+
connectToExisting: ({ identifier, lockName }) => server.connectToExisting(identifier, lockName)
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
if (isSharedWorker) {
|
|
18
|
+
const sharedSyncImplementation = new SharedSyncImplementation();
|
|
19
|
+
|
|
20
|
+
// A shared worker can either be an IndexedDB-VFS database server or a shared sync coordinator.
|
|
21
|
+
// To be able to know what service a client is connecting to, we let clients send an inner MessagePort through the
|
|
22
|
+
// top-level port along with a tag describing what they need.
|
|
23
|
+
const _self = self as unknown as SharedWorkerGlobalScope;
|
|
24
|
+
_self.onconnect = (outerEvent: MessageEvent) => {
|
|
25
|
+
const port = outerEvent.ports[0];
|
|
26
|
+
port.onmessage = (event: MessageEvent<SharedWorkerConnectionRequest>) => {
|
|
27
|
+
const { service, port } = event.data;
|
|
28
|
+
if (service === 'database') {
|
|
29
|
+
Comlink.expose(exposedDatabaseFunctions, port);
|
|
30
|
+
} else if (service === 'sync') {
|
|
31
|
+
new WorkerClient(sharedSyncImplementation, port);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
} else {
|
|
36
|
+
// Dedicated workers are only used for databases, so we don't need an intermediate layer.
|
|
37
|
+
Comlink.expose(exposedDatabaseFunctions);
|
|
38
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|