@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,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { LogLevels, PowerSyncLogger } from '@powersync/common';
|
|
2
2
|
import { ConcurrentSqliteConnection, ConnectionLeaseToken } from './ConcurrentConnection.js';
|
|
3
|
-
import {
|
|
3
|
+
import { RawWebResult } from './RawSqliteConnection.js';
|
|
4
4
|
|
|
5
5
|
export interface DatabaseServerOptions {
|
|
6
6
|
inner: ConcurrentSqliteConnection;
|
|
7
7
|
onClose: () => void;
|
|
8
|
-
logger:
|
|
8
|
+
logger: PowerSyncLogger;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -24,7 +24,7 @@ export class DatabaseServer {
|
|
|
24
24
|
constructor(options: DatabaseServerOptions) {
|
|
25
25
|
this.#options = options;
|
|
26
26
|
const inner = options.inner;
|
|
27
|
-
this.#updateBroadcastChannel = new BroadcastChannel(`${inner.options.
|
|
27
|
+
this.#updateBroadcastChannel = new BroadcastChannel(`${inner.options.filename}-table-updates`);
|
|
28
28
|
|
|
29
29
|
this.#updateBroadcastChannel.onmessage = ({ data }) => {
|
|
30
30
|
this.#pushTableUpdateToClients(data as string[]);
|
|
@@ -85,7 +85,7 @@ export class DatabaseServer {
|
|
|
85
85
|
|
|
86
86
|
// If the client holds a connection lease it hasn't returned, return that now.
|
|
87
87
|
for (const { lease } of connectionLeases.values()) {
|
|
88
|
-
this.#logger.debug
|
|
88
|
+
this.#logger.log({ level: LogLevels.debug, message: `Closing connection lease that hasn't been returned.` });
|
|
89
89
|
await lease.returnLease();
|
|
90
90
|
}
|
|
91
91
|
|
|
@@ -94,7 +94,10 @@ export class DatabaseServer {
|
|
|
94
94
|
if (this.#activeClients.size == 0) {
|
|
95
95
|
await this.forceClose();
|
|
96
96
|
} else {
|
|
97
|
-
this.#logger.
|
|
97
|
+
this.#logger.log({
|
|
98
|
+
level: LogLevels.debug,
|
|
99
|
+
message: 'Keeping underlying connection active since its used by other clients.'
|
|
100
|
+
});
|
|
98
101
|
}
|
|
99
102
|
}
|
|
100
103
|
};
|
|
@@ -133,9 +136,9 @@ export class DatabaseServer {
|
|
|
133
136
|
try {
|
|
134
137
|
if (lease.write) {
|
|
135
138
|
// Collect update hooks invoked while the client had the write connection.
|
|
136
|
-
const {
|
|
137
|
-
if (
|
|
138
|
-
const updatedTables: string[] = JSON.parse(
|
|
139
|
+
const { rawRows } = await lease.lease.use((conn) => conn.execute(`SELECT powersync_update_hooks('get')`));
|
|
140
|
+
if (rawRows.length) {
|
|
141
|
+
const updatedTables: string[] = JSON.parse(rawRows[0][0] as string);
|
|
139
142
|
if (updatedTables.length) {
|
|
140
143
|
this.#updateBroadcastChannel.postMessage(updatedTables);
|
|
141
144
|
this.#pushTableUpdateToClients(updatedTables);
|
|
@@ -169,7 +172,10 @@ export class DatabaseServer {
|
|
|
169
172
|
}
|
|
170
173
|
|
|
171
174
|
async forceClose() {
|
|
172
|
-
this.#logger.
|
|
175
|
+
this.#logger.log({
|
|
176
|
+
level: LogLevels.debug,
|
|
177
|
+
message: `Closing connection to ${JSON.stringify(this.#inner.options)}.`
|
|
178
|
+
});
|
|
173
179
|
const connection = this.#inner;
|
|
174
180
|
this.#options.onClose();
|
|
175
181
|
this.#updateBroadcastChannel.close();
|
|
@@ -190,8 +196,8 @@ export interface ClientConnectionView {
|
|
|
190
196
|
* give other clients access to the database afterwards.
|
|
191
197
|
*/
|
|
192
198
|
requestAccess(write: boolean, timeoutMs?: number): Promise<string>;
|
|
193
|
-
execute(token: string, sql: string, params: any[] | undefined): Promise<
|
|
194
|
-
executeBatch(token: string, sql: string, params: any[][]): Promise<
|
|
199
|
+
execute(token: string, sql: string, params: any[] | undefined): Promise<RawWebResult>;
|
|
200
|
+
executeBatch(token: string, sql: string, params: any[][]): Promise<RawWebResult[]>;
|
|
195
201
|
completeAccess(token: string): Promise<void>;
|
|
196
202
|
|
|
197
203
|
/**
|
|
@@ -1,18 +1,34 @@
|
|
|
1
1
|
import { Factory as WaSqliteFactory, SQLITE_ROW } from '@journeyapps/wa-sqlite';
|
|
2
2
|
|
|
3
|
-
import { loadModuleAndVfs } from './vfs.js';
|
|
4
|
-
import {
|
|
3
|
+
import { loadModuleAndVfs, WASQLiteVFS } from './vfs.js';
|
|
4
|
+
import { TemporaryStorageOption } from '../options.js';
|
|
5
|
+
import { RawQueryResult, SqliteValue } from '@powersync/common';
|
|
6
|
+
import { maxPathNameLength } from '../resolveAndValidateOptions.js';
|
|
7
|
+
import { PreparedStatementCache } from './StatementCache.js';
|
|
8
|
+
|
|
9
|
+
export interface RawWebResult extends Required<RawQueryResult> {
|
|
10
|
+
autocommit: boolean;
|
|
11
|
+
}
|
|
5
12
|
|
|
6
13
|
export interface RawResultSet {
|
|
7
|
-
|
|
8
|
-
|
|
14
|
+
columnNames: string[];
|
|
15
|
+
rawRows: SqliteValue[][];
|
|
9
16
|
}
|
|
10
17
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
/**
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
21
|
+
export interface RawWaSqliteDatabaseOptions {
|
|
22
|
+
filename: string;
|
|
23
|
+
readonly: boolean;
|
|
24
|
+
vfs: WASQLiteVFS;
|
|
25
|
+
encryptionKey: string | undefined;
|
|
26
|
+
temporaryStorage: TemporaryStorageOption;
|
|
27
|
+
cacheSizeKb: number;
|
|
28
|
+
/**
|
|
29
|
+
* The amount of prepared statements to cache, or 0 to disable caching.
|
|
30
|
+
*/
|
|
31
|
+
preparedStatementsCache: number;
|
|
16
32
|
}
|
|
17
33
|
|
|
18
34
|
/**
|
|
@@ -23,35 +39,48 @@ export interface RawQueryResult {
|
|
|
23
39
|
*/
|
|
24
40
|
export class RawSqliteConnection {
|
|
25
41
|
private _sqliteAPI: SQLiteAPI | null = null;
|
|
42
|
+
private sqlite3_stmt_isexplain!: (stmt: number) => 0 | 1 | 2;
|
|
43
|
+
|
|
26
44
|
/**
|
|
27
45
|
* The `sqlite3*` connection pointer.
|
|
28
46
|
*/
|
|
29
47
|
private db: number = 0;
|
|
48
|
+
private statementCache: PreparedStatementCache | null;
|
|
30
49
|
|
|
31
|
-
constructor(readonly options:
|
|
50
|
+
constructor(readonly options: RawWaSqliteDatabaseOptions) {
|
|
51
|
+
this.statementCache =
|
|
52
|
+
options.preparedStatementsCache > 0 ? new PreparedStatementCache(options.preparedStatementsCache) : null;
|
|
53
|
+
}
|
|
32
54
|
|
|
33
55
|
get isOpen(): boolean {
|
|
34
56
|
return this.db != 0;
|
|
35
57
|
}
|
|
36
58
|
|
|
37
59
|
async init() {
|
|
38
|
-
const
|
|
60
|
+
const { module, vfs } = await loadModuleAndVfs(this.options);
|
|
61
|
+
await this.initWithModule(module, vfs);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async initWithModule(module: any, vfs: any) {
|
|
65
|
+
const api = (this._sqliteAPI = await this.openSQLiteAPI(module, vfs));
|
|
39
66
|
this.db = await api.open_v2(
|
|
40
|
-
this.options.
|
|
41
|
-
this.options.
|
|
67
|
+
this.options.filename,
|
|
68
|
+
this.options.readonly ? 1 /* SQLITE_OPEN_READONLY */ : 6 /* SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE */
|
|
42
69
|
);
|
|
43
70
|
await this.executeRaw(`PRAGMA temp_store = ${this.options.temporaryStorage};`);
|
|
44
71
|
if (this.options.encryptionKey) {
|
|
45
|
-
const escapedKey = this.options.encryptionKey.
|
|
46
|
-
await this.executeRaw(`PRAGMA key = '${escapedKey}'
|
|
72
|
+
const escapedKey = this.options.encryptionKey.replaceAll("'", "''");
|
|
73
|
+
await this.executeRaw(`PRAGMA key = '${escapedKey}';`);
|
|
47
74
|
}
|
|
48
75
|
await this.executeRaw(`PRAGMA cache_size = -${this.options.cacheSizeKb};`);
|
|
49
76
|
|
|
50
77
|
await this.executeRaw(`SELECT powersync_update_hooks('install');`);
|
|
51
78
|
}
|
|
52
79
|
|
|
53
|
-
private async openSQLiteAPI(): Promise<SQLiteAPI> {
|
|
54
|
-
|
|
80
|
+
private async openSQLiteAPI(module: any, vfs: SQLiteVFS): Promise<SQLiteAPI> {
|
|
81
|
+
vfs.mxPathname = maxPathNameLength;
|
|
82
|
+
|
|
83
|
+
this.sqlite3_stmt_isexplain = module.cwrap('sqlite3_stmt_isexplain', 'int', ['int']);
|
|
55
84
|
const sqlite3 = WaSqliteFactory(module);
|
|
56
85
|
sqlite3.vfs_register(vfs, true);
|
|
57
86
|
/**
|
|
@@ -63,7 +92,7 @@ export class RawSqliteConnection {
|
|
|
63
92
|
* Create the multiple cipher vfs if an encryption key is provided
|
|
64
93
|
*/
|
|
65
94
|
if (this.options.encryptionKey) {
|
|
66
|
-
const createResult = module.ccall('sqlite3mc_vfs_create', 'int', ['string', 'int'], [this.options.
|
|
95
|
+
const createResult = module.ccall('sqlite3mc_vfs_create', 'int', ['string', 'int'], [this.options.filename, 1]);
|
|
67
96
|
if (createResult !== 0) {
|
|
68
97
|
throw new Error('Failed to create multiple cipher vfs, Database encryption will not work');
|
|
69
98
|
}
|
|
@@ -87,12 +116,12 @@ export class RawSqliteConnection {
|
|
|
87
116
|
return this.requireSqlite().get_autocommit(this.db) != 0;
|
|
88
117
|
}
|
|
89
118
|
|
|
90
|
-
async execute(sql: string, bindings?: any[]): Promise<
|
|
119
|
+
async execute(sql: string, bindings?: any[]): Promise<RawWebResult> {
|
|
91
120
|
const resultSet = await this.executeSingleStatementRaw(sql, bindings);
|
|
92
121
|
return this.wrapQueryResults(this.requireSqlite(), resultSet);
|
|
93
122
|
}
|
|
94
123
|
|
|
95
|
-
async executeBatch(sql: string, bindings: any[][]): Promise<
|
|
124
|
+
async executeBatch(sql: string, bindings: any[][]): Promise<RawWebResult[]> {
|
|
96
125
|
const results = [];
|
|
97
126
|
const api = this.requireSqlite();
|
|
98
127
|
for await (const stmt of api.statements(this.db, sql)) {
|
|
@@ -110,31 +139,32 @@ export class RawSqliteConnection {
|
|
|
110
139
|
return results;
|
|
111
140
|
}
|
|
112
141
|
|
|
113
|
-
private wrapQueryResults(api: SQLiteAPI,
|
|
142
|
+
private wrapQueryResults(api: SQLiteAPI, { rawRows, columnNames }: RawResultSet): RawWebResult {
|
|
114
143
|
return {
|
|
115
|
-
|
|
116
|
-
|
|
144
|
+
rowsAffected: api.changes(this.db),
|
|
145
|
+
insertId: api.last_insert_id(this.db),
|
|
117
146
|
autocommit: api.get_autocommit(this.db) != 0,
|
|
118
|
-
|
|
147
|
+
rawRows,
|
|
148
|
+
columnNames
|
|
119
149
|
};
|
|
120
150
|
}
|
|
121
151
|
|
|
122
152
|
/**
|
|
123
153
|
* This executes a single statement using SQLite3 and returns the results as a {@link RawResultSet}.
|
|
124
154
|
*/
|
|
125
|
-
private async executeSingleStatementRaw(sql: string, bindings?: any[]): Promise<RawResultSet
|
|
155
|
+
private async executeSingleStatementRaw(sql: string, bindings?: any[]): Promise<RawResultSet> {
|
|
126
156
|
const results = await this.executeRaw(sql, bindings);
|
|
127
|
-
return results.length ? results[0] :
|
|
157
|
+
return results.length ? results[0] : { columnNames: [], rawRows: [] };
|
|
128
158
|
}
|
|
129
159
|
|
|
130
160
|
async executeRaw(sql: string, bindings?: any[]): Promise<RawResultSet[]> {
|
|
131
161
|
const results = [];
|
|
132
162
|
const api = this.requireSqlite();
|
|
133
|
-
for await (const stmt of
|
|
163
|
+
for await (const stmt of this.cachedStatements(api, sql)) {
|
|
134
164
|
let columns;
|
|
135
165
|
|
|
136
166
|
const rs = await this.stepThroughStatement(api, stmt, bindings ?? [], columns);
|
|
137
|
-
columns = rs.
|
|
167
|
+
columns = rs.columnNames;
|
|
138
168
|
if (columns.length) {
|
|
139
169
|
results.push(rs);
|
|
140
170
|
}
|
|
@@ -176,13 +206,61 @@ export class RawSqliteConnection {
|
|
|
176
206
|
}
|
|
177
207
|
|
|
178
208
|
knownColumns ??= api.column_names(stmt);
|
|
179
|
-
return {
|
|
209
|
+
return { columnNames: knownColumns, rawRows: rows };
|
|
180
210
|
}
|
|
181
211
|
|
|
182
212
|
async close() {
|
|
183
213
|
if (this.isOpen) {
|
|
184
|
-
|
|
214
|
+
const api = this.requireSqlite();
|
|
215
|
+
|
|
216
|
+
if (this.statementCache) {
|
|
217
|
+
for (const stmt of this.statementCache.drain()) {
|
|
218
|
+
await api.finalize(stmt);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
await api.close(this.db);
|
|
185
223
|
this.db = 0;
|
|
186
224
|
}
|
|
187
225
|
}
|
|
226
|
+
|
|
227
|
+
private async *cachedStatements(api: SQLiteAPI, sql: string): AsyncIterable<number> {
|
|
228
|
+
{
|
|
229
|
+
const existing = this.statementCache?.lookup(sql);
|
|
230
|
+
if (existing != null) {
|
|
231
|
+
yield existing;
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const inner = api.statements(this.db, sql, { unscoped: true });
|
|
237
|
+
const preparedStatements: number[] = [];
|
|
238
|
+
|
|
239
|
+
try {
|
|
240
|
+
for await (const stmt of inner) {
|
|
241
|
+
preparedStatements.push(stmt);
|
|
242
|
+
yield stmt;
|
|
243
|
+
}
|
|
244
|
+
} finally {
|
|
245
|
+
// We can only cache statements if the sql text corresponds to a single statement, otherwise it's not clear what
|
|
246
|
+
// portion of the original sql text to use as a key.
|
|
247
|
+
if (preparedStatements.length === 1 && this.statementCache) {
|
|
248
|
+
const stmt = preparedStatements[0];
|
|
249
|
+
// Don't cache EXPLAIN statements, their result becomes invalid after schema changes.
|
|
250
|
+
if (this.sqlite3_stmt_isexplain(stmt) == 0) {
|
|
251
|
+
const evicted = this.statementCache.addStatement(sql, stmt);
|
|
252
|
+
if (evicted != null) {
|
|
253
|
+
await api.finalize(evicted);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// We're not caching statements, so finalize them.
|
|
261
|
+
for (const stmt of preparedStatements) {
|
|
262
|
+
await api.finalize(stmt);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
188
266
|
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export class PreparedStatementCache {
|
|
2
|
+
readonly #size: number;
|
|
3
|
+
// Note that Map preserves insertion order, which allows using it as an LRU
|
|
4
|
+
// cache (with the first element being the first element to evict).
|
|
5
|
+
readonly #statements = new Map<string, number>();
|
|
6
|
+
|
|
7
|
+
constructor(size: number) {
|
|
8
|
+
this.#size = size;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Attempts to look up the cached sql statement, if it's currently cached.
|
|
13
|
+
*/
|
|
14
|
+
lookup(sql: string): number | null {
|
|
15
|
+
const foundStatement = this.#statements.get(sql);
|
|
16
|
+
if (foundStatement != null) {
|
|
17
|
+
// Delete and re-insert to move to the end (most-recently-used position).
|
|
18
|
+
this.#statements.delete(sql);
|
|
19
|
+
this.#statements.set(sql, foundStatement);
|
|
20
|
+
return foundStatement;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Adds a new statement into the cache.
|
|
28
|
+
*
|
|
29
|
+
* If that exceeds the target size of the statement cache, returns an old statement to evict.
|
|
30
|
+
* The caller is responsible for freeing that statement.
|
|
31
|
+
*/
|
|
32
|
+
addStatement(sql: string, statement: number): number | null {
|
|
33
|
+
this.#statements.set(sql, statement);
|
|
34
|
+
|
|
35
|
+
if (this.#statements.size > this.#size) {
|
|
36
|
+
for (const [k, v] of this.#statements.entries()) {
|
|
37
|
+
this.#statements.delete(k);
|
|
38
|
+
return v;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
drain(): number[] {
|
|
46
|
+
const values = [...this.#statements.values()];
|
|
47
|
+
this.#statements.clear();
|
|
48
|
+
return values;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -1,70 +1,38 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DBAdapter, LogLevels, PowerSyncLogger, SQLOpenFactory } from '@powersync/common';
|
|
2
2
|
import * as Comlink from 'comlink';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
DEFAULT_CACHE_SIZE_KB,
|
|
6
|
-
isServerSide,
|
|
7
|
-
ResolvedWebSQLFlags,
|
|
8
|
-
ResolvedWebSQLOpenOptions,
|
|
9
|
-
resolveWebSQLFlags,
|
|
10
|
-
TemporaryStorageOption,
|
|
11
|
-
WebSQLOpenFactoryOptions
|
|
12
|
-
} from '../web-sql-flags.js';
|
|
3
|
+
import { ResolvedWebSQLOpenOptions, WebSQLOpenOptions } from '../options.js';
|
|
13
4
|
import { SSRDBAdapter } from '../SSRDBAdapter.js';
|
|
14
5
|
import { vfsRequiresDedicatedWorkers, WASQLiteVFS } from './vfs.js';
|
|
15
6
|
import { MultiDatabaseServer } from '../../../worker/db/MultiDatabaseServer.js';
|
|
16
7
|
import { DatabaseClient, OpenWorkerConnection } from './DatabaseClient.js';
|
|
17
8
|
import { generateTabCloseSignal } from '../../../shared/tab_close_signal.js';
|
|
18
9
|
import { AsyncDbAdapter, PoolConnection } from '../AsyncWebAdapter.js';
|
|
10
|
+
import { RawWaSqliteDatabaseOptions } from './RawSqliteConnection.js';
|
|
11
|
+
import { maxPathNameLength, resolveAndValidateOptions } from '../resolveAndValidateOptions.js';
|
|
12
|
+
import { connectToExistingWorker, connectToWorker, WorkerConnection } from '../../../worker/client.js';
|
|
19
13
|
|
|
20
|
-
export interface WASQLiteOpenFactoryOptions
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
* If the {@link vfs} supports it, an additional amount of read-only connections to open. Using additional read
|
|
24
|
-
* connections can speed up queries by dispatching them to multiple workers running them concurrently.
|
|
25
|
-
*
|
|
26
|
-
* {@link WASQLiteVFS.OPFSWriteAheadVFS} is the only VFS with support for multiple connections, so this option is
|
|
27
|
-
* ignored for other VFS implementations.
|
|
28
|
-
*
|
|
29
|
-
* Defaults to 1.
|
|
30
|
-
*/
|
|
31
|
-
additionalReaders?: number;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export interface ResolvedWASQLiteOpenFactoryOptions extends ResolvedWebSQLOpenOptions {
|
|
35
|
-
vfs: WASQLiteVFS;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Whether this is a read-only connection opened for the `OPFSWriteAheadVFS` file system.
|
|
39
|
-
*/
|
|
40
|
-
isReadOnly: boolean;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface WorkerDBOpenerOptions extends ResolvedWASQLiteOpenFactoryOptions {
|
|
44
|
-
logLevel: ILogLevel;
|
|
45
|
-
/**
|
|
46
|
-
* A lock that is currently held by the client. When the lock is returned, we know the client is gone and that we need
|
|
47
|
-
* to clean up resources.
|
|
48
|
-
*/
|
|
49
|
-
lockName: string;
|
|
14
|
+
export interface WASQLiteOpenFactoryOptions {
|
|
15
|
+
open: WebSQLOpenOptions;
|
|
16
|
+
logger: PowerSyncLogger;
|
|
50
17
|
}
|
|
51
18
|
|
|
52
19
|
/**
|
|
53
20
|
* Opens a SQLite connection using WA-SQLite.
|
|
54
21
|
*/
|
|
55
22
|
export class WASQLiteOpenFactory implements SQLOpenFactory {
|
|
56
|
-
private
|
|
57
|
-
private logger:
|
|
23
|
+
private options: ResolvedWebSQLOpenOptions;
|
|
24
|
+
private logger: PowerSyncLogger;
|
|
58
25
|
|
|
59
|
-
constructor(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
26
|
+
constructor(options: WASQLiteOpenFactoryOptions) {
|
|
27
|
+
this.options = resolveAndValidateOptions(options.open);
|
|
28
|
+
|
|
29
|
+
// Account for the fact that SQLite might append -journal suffixes
|
|
30
|
+
const maxLength = maxPathNameLength - 16;
|
|
31
|
+
if (this.options.dbFilename.length > maxLength) {
|
|
32
|
+
throw new Error(`dbFilename too long (max length is ${maxLength})`);
|
|
33
|
+
}
|
|
64
34
|
|
|
65
|
-
|
|
66
|
-
// Cast to extended type
|
|
67
|
-
return this.options;
|
|
35
|
+
this.logger = options.logger;
|
|
68
36
|
}
|
|
69
37
|
|
|
70
38
|
protected openAdapter(): DBAdapter {
|
|
@@ -72,84 +40,91 @@ export class WASQLiteOpenFactory implements SQLOpenFactory {
|
|
|
72
40
|
}
|
|
73
41
|
|
|
74
42
|
openDB(): DBAdapter {
|
|
75
|
-
const {
|
|
76
|
-
|
|
77
|
-
} = this;
|
|
43
|
+
const { disableSSRWarning, enableMultiTabs, ssrMode } = this.options;
|
|
44
|
+
|
|
78
45
|
if (ssrMode) {
|
|
79
46
|
if (!disableSSRWarning) {
|
|
80
|
-
this.logger.
|
|
81
|
-
|
|
47
|
+
this.logger.log({
|
|
48
|
+
level: LogLevels.warn,
|
|
49
|
+
message: `
|
|
82
50
|
Running PowerSync in SSR mode.
|
|
83
51
|
Only empty query results will be returned.
|
|
84
52
|
Disable this warning by setting 'disableSSRWarning: true' in options.`
|
|
85
|
-
);
|
|
53
|
+
});
|
|
86
54
|
}
|
|
87
55
|
|
|
88
56
|
return new SSRDBAdapter();
|
|
89
57
|
}
|
|
90
58
|
|
|
91
59
|
if (!enableMultiTabs) {
|
|
92
|
-
this.logger.
|
|
93
|
-
|
|
94
|
-
|
|
60
|
+
this.logger.log({
|
|
61
|
+
level: LogLevels.warn,
|
|
62
|
+
message: 'Multiple tab support is not enabled. Using this site across multiple tabs may not function correctly.'
|
|
63
|
+
});
|
|
95
64
|
}
|
|
96
65
|
|
|
97
66
|
return this.openAdapter();
|
|
98
67
|
}
|
|
99
68
|
|
|
100
69
|
async openConnection(): Promise<PoolConnection> {
|
|
101
|
-
const { enableMultiTabs, useWebWorker } = this.resolvedFlags;
|
|
102
70
|
const {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
cacheSizeKb = DEFAULT_CACHE_SIZE_KB,
|
|
106
|
-
encryptionKey
|
|
107
|
-
} = this.waOptions;
|
|
108
|
-
|
|
109
|
-
if (!enableMultiTabs) {
|
|
110
|
-
this.logger.warn('Multiple tabs are not enabled in this browser');
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
const resolveOptions = (isReadOnly: boolean): ResolvedWASQLiteOpenFactoryOptions => ({
|
|
114
|
-
dbFilename: this.options.dbFilename,
|
|
115
|
-
dbLocation: this.options.dbLocation,
|
|
116
|
-
debugMode: this.options.debugMode,
|
|
71
|
+
enableMultiTabs,
|
|
72
|
+
useWebWorker,
|
|
117
73
|
vfs,
|
|
74
|
+
dbFilename,
|
|
75
|
+
encryptionKey,
|
|
118
76
|
temporaryStorage,
|
|
119
77
|
cacheSizeKb,
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
78
|
+
preparedStatementsCache
|
|
79
|
+
} = this.options;
|
|
80
|
+
|
|
81
|
+
if (!enableMultiTabs) {
|
|
82
|
+
this.logger.log({ level: LogLevels.warn, message: 'Multiple tabs are not enabled in this browser' });
|
|
83
|
+
}
|
|
124
84
|
|
|
125
85
|
let client: DatabaseClient;
|
|
126
86
|
let additionalReaders: DatabaseClient[] = [];
|
|
127
87
|
let requiresPersistentTriggers = vfsRequiresDedicatedWorkers(vfs);
|
|
128
88
|
|
|
89
|
+
function resolveRawWaSqliteDatabaseOptions(readonly: boolean): RawWaSqliteDatabaseOptions {
|
|
90
|
+
return {
|
|
91
|
+
filename: dbFilename,
|
|
92
|
+
readonly,
|
|
93
|
+
vfs,
|
|
94
|
+
encryptionKey,
|
|
95
|
+
temporaryStorage,
|
|
96
|
+
cacheSizeKb,
|
|
97
|
+
// TODO: Enable prepared statement cache by default?
|
|
98
|
+
preparedStatementsCache: preparedStatementsCache ?? 0
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
129
102
|
if (useWebWorker) {
|
|
130
103
|
const optionsDbWorker = this.options.worker;
|
|
131
104
|
|
|
132
|
-
const openDatabaseWorker = async (
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
:
|
|
147
|
-
|
|
148
|
-
|
|
105
|
+
const openDatabaseWorker = async (readonly: boolean): Promise<DatabaseClient> => {
|
|
106
|
+
let workerConnection: WorkerConnection;
|
|
107
|
+
if (typeof optionsDbWorker == 'function') {
|
|
108
|
+
const worker = optionsDbWorker(this.options);
|
|
109
|
+
workerConnection = connectToExistingWorker(worker, this.logger, 'database');
|
|
110
|
+
} else {
|
|
111
|
+
const needsDedicated = vfsRequiresDedicatedWorkers(vfs);
|
|
112
|
+
const useShared = !needsDedicated && enableMultiTabs;
|
|
113
|
+
|
|
114
|
+
workerConnection = connectToWorker({
|
|
115
|
+
service: 'database',
|
|
116
|
+
databaseIdentifier: this.options.dbFilename,
|
|
117
|
+
shared: useShared,
|
|
118
|
+
customWorker: optionsDbWorker,
|
|
119
|
+
loggerForErrors: this.logger
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const source = Comlink.wrap<OpenWorkerConnection>(workerConnection.endpoint);
|
|
149
124
|
const closeSignal = new AbortController();
|
|
150
125
|
const connection = await source.connect({
|
|
151
|
-
|
|
152
|
-
logLevel: this.
|
|
126
|
+
database: resolveRawWaSqliteDatabaseOptions(readonly),
|
|
127
|
+
logLevel: this.options.databaseWorkerLogLevel,
|
|
153
128
|
lockName: await generateTabCloseSignal(closeSignal.signal)
|
|
154
129
|
});
|
|
155
130
|
const clientOptions = {
|
|
@@ -159,42 +134,39 @@ export class WASQLiteOpenFactory implements SQLOpenFactory {
|
|
|
159
134
|
remoteCanCloseUnexpectedly: false,
|
|
160
135
|
onClose: () => {
|
|
161
136
|
closeSignal.abort();
|
|
162
|
-
|
|
163
|
-
workerPort.terminate();
|
|
164
|
-
} else {
|
|
165
|
-
workerPort.close();
|
|
166
|
-
}
|
|
137
|
+
workerConnection.close();
|
|
167
138
|
}
|
|
168
139
|
};
|
|
169
140
|
|
|
170
141
|
return new DatabaseClient(clientOptions, {
|
|
171
|
-
...
|
|
142
|
+
...this.options,
|
|
172
143
|
requiresPersistentTriggers
|
|
173
144
|
});
|
|
174
145
|
};
|
|
175
146
|
|
|
176
|
-
client = await openDatabaseWorker(
|
|
147
|
+
client = await openDatabaseWorker(false);
|
|
177
148
|
|
|
178
149
|
if (vfs == WASQLiteVFS.OPFSWriteAheadVFS) {
|
|
179
150
|
// This VFS supports concurrent reads, so we can open additional workers to host read-only connections for
|
|
180
151
|
// concurrent reads / writes.
|
|
181
152
|
const additionalReadersCount = this.options.additionalReaders ?? 1;
|
|
153
|
+
|
|
154
|
+
const additionalReaderPromises: Promise<DatabaseClient>[] = [];
|
|
182
155
|
for (let i = 0; i < additionalReadersCount; i++) {
|
|
183
|
-
|
|
184
|
-
additionalReaders.push(reader);
|
|
156
|
+
additionalReaderPromises.push(openDatabaseWorker(true));
|
|
185
157
|
}
|
|
158
|
+
additionalReaders.push(...(await Promise.all(additionalReaderPromises)));
|
|
186
159
|
}
|
|
187
160
|
} else {
|
|
188
161
|
// Don't use a web worker. Instead, open the MultiDatabaseServer a worker would use locally.
|
|
189
162
|
const localServer = new MultiDatabaseServer(this.logger);
|
|
190
163
|
requiresPersistentTriggers = true;
|
|
191
164
|
|
|
192
|
-
const
|
|
193
|
-
const connection = await localServer.openConnectionLocally(resolvedOptions);
|
|
165
|
+
const connection = await localServer.openConnectionLocally(this.logger, resolveRawWaSqliteDatabaseOptions(false));
|
|
194
166
|
client = new DatabaseClient(
|
|
195
167
|
{ connection, source: null, remoteCanCloseUnexpectedly: false },
|
|
196
168
|
{
|
|
197
|
-
...
|
|
169
|
+
...this.options,
|
|
198
170
|
requiresPersistentTriggers
|
|
199
171
|
}
|
|
200
172
|
);
|
|
@@ -206,18 +178,3 @@ export class WASQLiteOpenFactory implements SQLOpenFactory {
|
|
|
206
178
|
};
|
|
207
179
|
}
|
|
208
180
|
}
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* Asserts that the factory options are valid.
|
|
212
|
-
*/
|
|
213
|
-
function assertValidWASQLiteOpenFactoryOptions(options: WASQLiteOpenFactoryOptions): void {
|
|
214
|
-
// The OPFS VFS only works in dedicated web workers.
|
|
215
|
-
if ('vfs' in options && 'flags' in options) {
|
|
216
|
-
const { vfs, flags = {} } = options;
|
|
217
|
-
if (vfs && vfsRequiresDedicatedWorkers(vfs) && 'useWebWorker' in flags && !flags.useWebWorker) {
|
|
218
|
-
throw new Error(
|
|
219
|
-
`Invalid configuration: The 'useWebWorker' flag must be true when using an OPFS-based VFS (${vfs}).`
|
|
220
|
-
);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
}
|