@powersync/web 2.4.2 → 2.6.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/index.react_native_web.js +142 -25
- package/dist/index.react_native_web.js.map +1 -1
- package/dist/worker/AccessHandlePoolVFS-Do8lc5Ck.js +2 -0
- package/dist/worker/AccessHandlePoolVFS-Do8lc5Ck.js.map +1 -0
- package/dist/worker/FacadeVFS-d1ZDvud7.js.map +1 -1
- package/dist/worker/IDBBatchAtomicVFS-CDb4d4wN.js +2 -0
- package/dist/worker/IDBBatchAtomicVFS-CDb4d4wN.js.map +1 -0
- package/dist/worker/MemoryVFS-DVJL5F8j.js.map +1 -1
- package/dist/worker/OPFSCoopSyncVFS-CDNBPKfy.js +2 -0
- package/dist/worker/OPFSCoopSyncVFS-CDNBPKfy.js.map +1 -0
- package/dist/worker/OPFSWriteAheadVFS-V9yBrLWl.js +2 -0
- package/dist/worker/OPFSWriteAheadVFS-V9yBrLWl.js.map +1 -0
- package/dist/worker/assets/mc-wa-sqlite-Cq3AePIW.wasm +0 -0
- package/dist/worker/assets/{mc-wa-sqlite-async-DdlQmAUV.wasm → mc-wa-sqlite-async-aRcIGeKj.wasm} +0 -0
- package/dist/worker/assets/wa-sqlite-CePoIZt_.wasm +0 -0
- package/dist/worker/assets/wa-sqlite-async-B3FiUnt1.wasm +0 -0
- package/dist/worker/{mc-wa-sqlite-PubB6u8c.js → mc-wa-sqlite-DRR2R_uj.js} +2 -2
- package/dist/worker/mc-wa-sqlite-DRR2R_uj.js.map +1 -0
- package/dist/worker/{mc-wa-sqlite-async-DJG_ANKO.js → mc-wa-sqlite-async-C40l6kIz.js} +2 -2
- package/dist/worker/mc-wa-sqlite-async-C40l6kIz.js.map +1 -0
- package/dist/worker/{wa-sqlite-D1_4mGs8.js → wa-sqlite-_a9CU4MM.js} +2 -2
- package/dist/worker/wa-sqlite-_a9CU4MM.js.map +1 -0
- package/dist/worker/wa-sqlite-async-Da0d0GJg.js +2 -0
- package/dist/worker/wa-sqlite-async-Da0d0GJg.js.map +1 -0
- package/dist/worker/{websockets-Q8W_lerF.js → websockets-Dx9ExO-W.js} +2 -2
- package/dist/worker/{websockets-Q8W_lerF.js.map → websockets-Dx9ExO-W.js.map} +1 -1
- package/dist/worker/worker.js +1 -1
- package/dist/worker/worker.js.map +1 -1
- package/lib/db/PowerSyncDatabase.d.ts +4 -3
- package/lib/db/PowerSyncDatabase.js +9 -2
- package/lib/db/PowerSyncDatabase.js.map +1 -1
- package/lib/db/adapters/options.d.ts +30 -0
- package/lib/db/adapters/options.js.map +1 -1
- package/lib/db/adapters/resolveAndValidateOptions.js +6 -1
- package/lib/db/adapters/resolveAndValidateOptions.js.map +1 -1
- package/lib/db/adapters/wa-sqlite/RawSqliteConnection.d.ts +5 -0
- package/lib/db/adapters/wa-sqlite/RawSqliteConnection.js +7 -2
- package/lib/db/adapters/wa-sqlite/RawSqliteConnection.js.map +1 -1
- package/lib/db/adapters/wa-sqlite/WASQLiteOpenFactory.js +4 -2
- package/lib/db/adapters/wa-sqlite/WASQLiteOpenFactory.js.map +1 -1
- package/lib/db/adapters/wa-sqlite/vfs.d.ts +24 -1
- package/lib/db/adapters/wa-sqlite/vfs.js +33 -4
- package/lib/db/adapters/wa-sqlite/vfs.js.map +1 -1
- package/lib/db/sync/SharedWebStreamingSyncImplementation.d.ts +2 -0
- package/lib/db/sync/SharedWebStreamingSyncImplementation.js +43 -12
- package/lib/db/sync/SharedWebStreamingSyncImplementation.js.map +1 -1
- package/lib/db/sync/WebRemote.d.ts +2 -3
- package/lib/db/sync/WebRemote.js +0 -2
- package/lib/db/sync/WebRemote.js.map +1 -1
- package/lib/db/sync/WebStreamingSyncImplementation.d.ts +8 -1
- package/lib/db/sync/WebStreamingSyncImplementation.js +14 -0
- package/lib/db/sync/WebStreamingSyncImplementation.js.map +1 -1
- package/lib/devtools/index.d.ts +7 -0
- package/lib/devtools/index.js +8 -0
- package/lib/devtools/index.js.map +1 -0
- package/lib/devtools/registry.d.ts +12 -0
- package/lib/devtools/registry.js +42 -0
- package/lib/devtools/registry.js.map +1 -0
- package/lib/worker/sync/BroadcastLogger.d.ts +1 -4
- package/lib/worker/sync/BroadcastLogger.js +14 -15
- package/lib/worker/sync/BroadcastLogger.js.map +1 -1
- package/lib/worker/sync/SharedSyncImplementation.d.ts +9 -2
- package/lib/worker/sync/SharedSyncImplementation.js +66 -37
- package/lib/worker/sync/SharedSyncImplementation.js.map +1 -1
- package/lib/worker/sync/WorkerClient.d.ts +3 -3
- package/lib/worker/sync/WorkerClient.js +3 -3
- package/lib/worker/sync/WorkerClient.js.map +1 -1
- package/package.json +12 -8
- package/src/db/PowerSyncDatabase.ts +12 -5
- package/src/db/adapters/options.ts +32 -0
- package/src/db/adapters/resolveAndValidateOptions.ts +9 -1
- package/src/db/adapters/wa-sqlite/RawSqliteConnection.ts +12 -2
- package/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.ts +6 -2
- package/src/db/adapters/wa-sqlite/vfs.ts +51 -4
- package/src/db/sync/SharedWebStreamingSyncImplementation.ts +54 -17
- package/src/db/sync/WebRemote.ts +2 -5
- package/src/db/sync/WebStreamingSyncImplementation.ts +18 -0
- package/src/devtools/index.ts +7 -0
- package/src/devtools/registry.ts +53 -0
- package/src/worker/sync/BroadcastLogger.ts +15 -15
- package/src/worker/sync/SharedSyncImplementation.ts +89 -48
- package/src/worker/sync/WorkerClient.ts +4 -3
- package/dist/worker/AccessHandlePoolVFS-BPUHfZME.js +0 -2
- package/dist/worker/AccessHandlePoolVFS-BPUHfZME.js.map +0 -1
- package/dist/worker/IDBBatchAtomicVFS-DbkDb777.js +0 -2
- package/dist/worker/IDBBatchAtomicVFS-DbkDb777.js.map +0 -1
- package/dist/worker/OPFSCoopSyncVFS-BgTiWPfa.js +0 -2
- package/dist/worker/OPFSCoopSyncVFS-BgTiWPfa.js.map +0 -1
- package/dist/worker/OPFSWriteAheadVFS-BW9pqSNn.js +0 -2
- package/dist/worker/OPFSWriteAheadVFS-BW9pqSNn.js.map +0 -1
- package/dist/worker/assets/mc-wa-sqlite-BHScYYZw.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.map +0 -1
- package/dist/worker/mc-wa-sqlite-async-DJG_ANKO.js.map +0 -1
- package/dist/worker/wa-sqlite-D1_4mGs8.js.map +0 -1
- package/dist/worker/wa-sqlite-async-BxkwNY-2.js +0 -2
- package/dist/worker/wa-sqlite-async-BxkwNY-2.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DBAdapter, LockContext, LogLevels, queryResultWithoutRows, BaseObserver } from '@powersync/common';
|
|
2
2
|
export * from '@powersync/common';
|
|
3
3
|
import * as Comlink from 'comlink';
|
|
4
|
-
import { Mutex, ConnectionClosedError, Semaphore, LockType, AbstractRemote, AbstractStreamingSyncImplementation, BasePowerSyncDatabase, openDatabase } from '@powersync/shared-internals';
|
|
4
|
+
import { Mutex, ConnectionClosedError, Semaphore, LockType, AbstractRemote, AbstractStreamingSyncImplementation, serializeErrorForRelay, BasePowerSyncDatabase, openDatabase } from '@powersync/shared-internals';
|
|
5
5
|
import { Factory, SQLITE_ROW } from '@journeyapps/wa-sqlite';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -139,6 +139,35 @@ var WASQLiteVFS;
|
|
|
139
139
|
function vfsRequiresDedicatedWorkers(vfs) {
|
|
140
140
|
return vfs != WASQLiteVFS.IDBBatchAtomicVFS && vfs != WASQLiteVFS.InMemoryVfs;
|
|
141
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* Whether the VFS can keep its files in a Storage Bucket, see {@link WebSpecificOpenOptions.storageBucket}.
|
|
144
|
+
*/
|
|
145
|
+
function vfsSupportsStorageBuckets(vfs) {
|
|
146
|
+
return (vfs == WASQLiteVFS.OPFSCoopSyncVFS || vfs == WASQLiteVFS.OPFSWriteAheadVFS || vfs == WASQLiteVFS.AccessHandlePoolVFS);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Options for an OPFS-based VFS that keep its files in the named Storage Bucket, see
|
|
150
|
+
* {@link WebSpecificOpenOptions.storageBucket}. Without a bucket name, no options: the VFS uses the root of the
|
|
151
|
+
* origin private file system.
|
|
152
|
+
*
|
|
153
|
+
* @internal
|
|
154
|
+
*/
|
|
155
|
+
function vfsOptionsForStorageBucket(storageBucket, storageBuckets = navigator.storageBuckets) {
|
|
156
|
+
if (storageBucket == null) {
|
|
157
|
+
return {};
|
|
158
|
+
}
|
|
159
|
+
if (storageBuckets == null) {
|
|
160
|
+
throw new Error(`The 'storageBucket' option needs the Storage Buckets API (navigator.storageBuckets), which this browser does not have. Check for it before setting the option.`);
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
// Called by the VFS each time it needs its root directory. Opening the bucket again creates it when the
|
|
164
|
+
// browser deleted it with the rest of the site's data.
|
|
165
|
+
getRoot: () => storageBuckets.open(storageBucket).then((bucket) => bucket.getDirectory()),
|
|
166
|
+
// Keeps the locks and channels of a file apart from those of a file of the same name in another bucket.
|
|
167
|
+
// Bucket names cannot contain ':', so the names of two buckets never overlap.
|
|
168
|
+
prefix: `${storageBucket}:`
|
|
169
|
+
};
|
|
170
|
+
}
|
|
142
171
|
async function asyncModuleFactory(encryptionKey) {
|
|
143
172
|
if (encryptionKey) {
|
|
144
173
|
const { default: factory } = await import('@journeyapps/wa-sqlite/dist/mc-wa-sqlite-async.mjs');
|
|
@@ -162,7 +191,7 @@ async function syncModuleFactory(encryptionKey) {
|
|
|
162
191
|
/**
|
|
163
192
|
* @internal
|
|
164
193
|
*/
|
|
165
|
-
async function loadModuleAndVfs({ vfs, filename, encryptionKey }) {
|
|
194
|
+
async function loadModuleAndVfs({ vfs, filename, encryptionKey, storageBucket }) {
|
|
166
195
|
let moduleFactory = syncModuleFactory;
|
|
167
196
|
let resolveVfs;
|
|
168
197
|
switch (vfs) {
|
|
@@ -178,19 +207,19 @@ async function loadModuleAndVfs({ vfs, filename, encryptionKey }) {
|
|
|
178
207
|
case WASQLiteVFS.AccessHandlePoolVFS: {
|
|
179
208
|
// @ts-expect-error The types for this import are missing upstream
|
|
180
209
|
const { AccessHandlePoolVFS } = await import('@journeyapps/wa-sqlite/src/examples/AccessHandlePoolVFS.js');
|
|
181
|
-
resolveVfs = (module) => AccessHandlePoolVFS.create(filename, module);
|
|
210
|
+
resolveVfs = (module) => AccessHandlePoolVFS.create(filename, module, vfsOptionsForStorageBucket(storageBucket));
|
|
182
211
|
break;
|
|
183
212
|
}
|
|
184
213
|
case WASQLiteVFS.OPFSCoopSyncVFS: {
|
|
185
214
|
// @ts-expect-error The types for this import are missing upstream
|
|
186
215
|
const { OPFSCoopSyncVFS } = await import('@journeyapps/wa-sqlite/src/examples/OPFSCoopSyncVFS.js');
|
|
187
|
-
resolveVfs = (module) => OPFSCoopSyncVFS.create(filename, module);
|
|
216
|
+
resolveVfs = (module) => OPFSCoopSyncVFS.create(filename, module, vfsOptionsForStorageBucket(storageBucket));
|
|
188
217
|
break;
|
|
189
218
|
}
|
|
190
219
|
case WASQLiteVFS.OPFSWriteAheadVFS: {
|
|
191
220
|
// @ts-expect-error The types for this import are missing upstream
|
|
192
221
|
const { OPFSWriteAheadVFS } = await import('@journeyapps/wa-sqlite/src/examples/OPFSWriteAheadVFS.js');
|
|
193
|
-
resolveVfs = (module) => OPFSWriteAheadVFS.create(filename, module,
|
|
222
|
+
resolveVfs = (module) => OPFSWriteAheadVFS.create(filename, module, vfsOptionsForStorageBucket(storageBucket));
|
|
194
223
|
break;
|
|
195
224
|
}
|
|
196
225
|
case WASQLiteVFS.InMemoryVfs: {
|
|
@@ -439,6 +468,11 @@ function resolveAndValidateOptions(options) {
|
|
|
439
468
|
if (vfsRequiresDedicatedWorkers(resolved.vfs) && !resolved.useWebWorker) {
|
|
440
469
|
throw new Error(`Invalid configuration: The 'useWebWorker' flag must be true when using an OPFS-based VFS (${resolved.vfs}).`);
|
|
441
470
|
}
|
|
471
|
+
if (resolved.storageBucket != null) {
|
|
472
|
+
if (!vfsSupportsStorageBuckets(resolved.vfs)) {
|
|
473
|
+
throw new Error(`Invalid configuration: The 'storageBucket' option needs an OPFS-based VFS, which ${resolved.vfs} is not.`);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
442
476
|
return resolved;
|
|
443
477
|
}
|
|
444
478
|
|
|
@@ -530,9 +564,14 @@ class RawSqliteConnection {
|
|
|
530
564
|
const sqlite3 = Factory(module);
|
|
531
565
|
sqlite3.vfs_register(vfs, true);
|
|
532
566
|
/**
|
|
533
|
-
* Register the PowerSync core
|
|
567
|
+
* Register the PowerSync core and additional statically linked extensions
|
|
534
568
|
*/
|
|
535
|
-
|
|
569
|
+
for (const name of ['powersync_init_static', ...(this.options.additionalInitializationFunctions ?? [])]) {
|
|
570
|
+
const result = module.ccall(name, 'int', []);
|
|
571
|
+
if (result !== 0) {
|
|
572
|
+
throw new Error(`SQLite extension initializer ${name} failed with code ${result}`);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
536
575
|
/**
|
|
537
576
|
* Create the multiple cipher vfs if an encryption key is provided
|
|
538
577
|
*/
|
|
@@ -1421,7 +1460,7 @@ class WASQLiteOpenFactory {
|
|
|
1421
1460
|
return this.openAdapter();
|
|
1422
1461
|
}
|
|
1423
1462
|
async openConnection() {
|
|
1424
|
-
const { enableMultiTabs, useWebWorker, vfs, dbFilename, encryptionKey, temporaryStorage, cacheSizeKb, preparedStatementsCache } = this.options;
|
|
1463
|
+
const { enableMultiTabs, useWebWorker, vfs, dbFilename, encryptionKey, temporaryStorage, cacheSizeKb, preparedStatementsCache, additionalInitializationFunctions, storageBucket } = this.options;
|
|
1425
1464
|
if (!enableMultiTabs) {
|
|
1426
1465
|
this.logger.log({ level: LogLevels.warn, message: 'Multiple tabs are not enabled in this browser' });
|
|
1427
1466
|
}
|
|
@@ -1437,7 +1476,9 @@ class WASQLiteOpenFactory {
|
|
|
1437
1476
|
temporaryStorage,
|
|
1438
1477
|
cacheSizeKb,
|
|
1439
1478
|
// TODO: Enable prepared statement cache by default?
|
|
1440
|
-
preparedStatementsCache: preparedStatementsCache ?? 0
|
|
1479
|
+
preparedStatementsCache: preparedStatementsCache ?? 0,
|
|
1480
|
+
additionalInitializationFunctions,
|
|
1481
|
+
storageBucket
|
|
1441
1482
|
};
|
|
1442
1483
|
}
|
|
1443
1484
|
if (useWebWorker) {
|
|
@@ -1653,10 +1694,8 @@ function getOsInfo(nav) {
|
|
|
1653
1694
|
}
|
|
1654
1695
|
|
|
1655
1696
|
class WebRemote extends AbstractRemote {
|
|
1656
|
-
connector;
|
|
1657
1697
|
constructor(connector, logger) {
|
|
1658
1698
|
super(connector, logger);
|
|
1659
|
-
this.connector = connector;
|
|
1660
1699
|
}
|
|
1661
1700
|
fetch({ resource, request }) {
|
|
1662
1701
|
return fetch(resource, request);
|
|
@@ -1683,10 +1722,24 @@ class WebRemote extends AbstractRemote {
|
|
|
1683
1722
|
let websockets;
|
|
1684
1723
|
|
|
1685
1724
|
class WebStreamingSyncImplementation extends AbstractStreamingSyncImplementation {
|
|
1725
|
+
diagnosticsChannel;
|
|
1686
1726
|
constructor(options) {
|
|
1687
1727
|
// Super will store and provide default values for options
|
|
1688
1728
|
super(options);
|
|
1689
1729
|
}
|
|
1730
|
+
/**
|
|
1731
|
+
* Broadcasts a core diagnostics event on a same-origin channel for diagnostics tooling to consume.
|
|
1732
|
+
* The channel reaches the page even when sync runs in a shared worker.
|
|
1733
|
+
*/
|
|
1734
|
+
emitDiagnostics(event) {
|
|
1735
|
+
this.diagnosticsChannel ??= new BroadcastChannel('powersync-diagnostics-events');
|
|
1736
|
+
this.diagnosticsChannel.postMessage(event);
|
|
1737
|
+
}
|
|
1738
|
+
async dispose() {
|
|
1739
|
+
await super.dispose();
|
|
1740
|
+
this.diagnosticsChannel?.close();
|
|
1741
|
+
this.diagnosticsChannel = undefined;
|
|
1742
|
+
}
|
|
1690
1743
|
get webOptions() {
|
|
1691
1744
|
return this.options;
|
|
1692
1745
|
}
|
|
@@ -1731,11 +1784,24 @@ class SharedSyncClientProvider extends AbstractSharedSyncClientProvider {
|
|
|
1731
1784
|
const { port } = await this.webDB.shareConnection();
|
|
1732
1785
|
return Comlink.transfer(port, [port]);
|
|
1733
1786
|
}
|
|
1787
|
+
async #relay(action) {
|
|
1788
|
+
try {
|
|
1789
|
+
return await action();
|
|
1790
|
+
}
|
|
1791
|
+
catch (ex) {
|
|
1792
|
+
/**
|
|
1793
|
+
* Connector callbacks run in this tab and their rejection crosses the
|
|
1794
|
+
* MessagePort to the sync worker, so serialize it here, where the error
|
|
1795
|
+
* originates, before Comlink's error transfer can drop custom fields.
|
|
1796
|
+
*/
|
|
1797
|
+
throw serializeErrorForRelay(ex);
|
|
1798
|
+
}
|
|
1799
|
+
}
|
|
1734
1800
|
invalidateCredentials() {
|
|
1735
1801
|
this.options.remote.invalidateCredentials();
|
|
1736
1802
|
}
|
|
1737
1803
|
async fetchCredentials() {
|
|
1738
|
-
const credentials = await this.options.remote.getCredentials();
|
|
1804
|
+
const credentials = await this.#relay(() => this.options.remote.getCredentials());
|
|
1739
1805
|
if (credentials == null) {
|
|
1740
1806
|
return null;
|
|
1741
1807
|
}
|
|
@@ -1755,10 +1821,10 @@ class SharedSyncClientProvider extends AbstractSharedSyncClientProvider {
|
|
|
1755
1821
|
* Don't return anything here, just incase something which is not
|
|
1756
1822
|
* serializable is returned from the `uploadCrud` function.
|
|
1757
1823
|
*/
|
|
1758
|
-
await this.options.uploadCrud();
|
|
1824
|
+
await this.#relay(() => this.options.connector.uploadCrud());
|
|
1759
1825
|
}
|
|
1760
1826
|
async postCheckpointRequest(clientId, requestId) {
|
|
1761
|
-
return await this.options.postCheckpointRequest(clientId, requestId);
|
|
1827
|
+
return await this.#relay(async () => (await this.options.connector.postCheckpointRequest(clientId, requestId)) ?? null);
|
|
1762
1828
|
}
|
|
1763
1829
|
get logger() {
|
|
1764
1830
|
return this.options.logger;
|
|
@@ -1835,9 +1901,13 @@ class SharedWebStreamingSyncImplementation extends WebStreamingSyncImplementatio
|
|
|
1835
1901
|
* - The client sends the params to the shared worker after locks have been registered.
|
|
1836
1902
|
*/
|
|
1837
1903
|
const closeSignal = await generateTabCloseSignal(this.abortOnClose.signal);
|
|
1904
|
+
const { identifier, connector } = this.options;
|
|
1838
1905
|
// Awaiting here ensures the worker is waiting for the lock
|
|
1839
|
-
await this.syncManager.
|
|
1840
|
-
|
|
1906
|
+
await this.syncManager.initialize(closeSignal, {
|
|
1907
|
+
hasFetchCredentials: !!connector.fetchCredentials,
|
|
1908
|
+
hasPostCheckpointRequest: !!connector.postCheckpointRequest,
|
|
1909
|
+
hasUploadCrud: !!connector.uploadCrud
|
|
1910
|
+
});
|
|
1841
1911
|
await this.syncManager.setParams({
|
|
1842
1912
|
dbParams: this.dbAdapter.getConfiguration(),
|
|
1843
1913
|
streamOptions: {
|
|
@@ -1860,8 +1930,26 @@ class SharedWebStreamingSyncImplementation extends WebStreamingSyncImplementatio
|
|
|
1860
1930
|
return this.syncManager.disconnect();
|
|
1861
1931
|
}
|
|
1862
1932
|
async dispose() {
|
|
1863
|
-
|
|
1864
|
-
|
|
1933
|
+
let registeredWithWorker = true;
|
|
1934
|
+
try {
|
|
1935
|
+
await this.waitForReady();
|
|
1936
|
+
}
|
|
1937
|
+
catch {
|
|
1938
|
+
// The worker rejected this client (e.g. because it connects in a mode incompatible with other tabs), so it won't
|
|
1939
|
+
// acknowledge a close request either.
|
|
1940
|
+
registeredWithWorker = false;
|
|
1941
|
+
}
|
|
1942
|
+
if (registeredWithWorker) {
|
|
1943
|
+
await this.#closeWorkerClient();
|
|
1944
|
+
}
|
|
1945
|
+
await super.dispose();
|
|
1946
|
+
this.abortOnClose.abort();
|
|
1947
|
+
// Release the proxy
|
|
1948
|
+
this.syncManager[Comlink.releaseProxy]();
|
|
1949
|
+
this.worker.close();
|
|
1950
|
+
}
|
|
1951
|
+
#closeWorkerClient() {
|
|
1952
|
+
return new Promise((resolve) => {
|
|
1865
1953
|
// This will always be a message port since we use shared workers.
|
|
1866
1954
|
const messagePort = this.worker.endpoint;
|
|
1867
1955
|
// Listen for the close acknowledgment from the worker
|
|
@@ -1878,11 +1966,6 @@ class SharedWebStreamingSyncImplementation extends WebStreamingSyncImplementatio
|
|
|
1878
1966
|
};
|
|
1879
1967
|
messagePort.postMessage(closeMessagePayload);
|
|
1880
1968
|
});
|
|
1881
|
-
await super.dispose();
|
|
1882
|
-
this.abortOnClose.abort();
|
|
1883
|
-
// Release the proxy
|
|
1884
|
-
this.syncManager[Comlink.releaseProxy]();
|
|
1885
|
-
this.worker.close();
|
|
1886
1969
|
}
|
|
1887
1970
|
async waitForReady() {
|
|
1888
1971
|
return this.isInitialized;
|
|
@@ -1963,6 +2046,34 @@ class TabLocalStreamingSyncImplementation extends WebStreamingSyncImplementation
|
|
|
1963
2046
|
}
|
|
1964
2047
|
}
|
|
1965
2048
|
|
|
2049
|
+
/**
|
|
2050
|
+
* Live database instances in this page, for development tooling.
|
|
2051
|
+
*
|
|
2052
|
+
* Every {@link WebPowerSyncDatabase} registers itself when constructed and leaves when closed, so a
|
|
2053
|
+
* tool that runs in the same page (for example the diagnostics Vite plugin's injected agent) can find
|
|
2054
|
+
* the app's databases without the app wiring anything up. The set holds only instances that already
|
|
2055
|
+
* exist, so it adds nothing to a production bundle beyond the references themselves.
|
|
2056
|
+
*/
|
|
2057
|
+
class DatabaseRegistry extends BaseObserver {
|
|
2058
|
+
databases = new Set();
|
|
2059
|
+
notify() {
|
|
2060
|
+
const snapshot = [...this.databases];
|
|
2061
|
+
this.iterateListeners((listener) => listener.databasesChanged?.(snapshot));
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2064
|
+
const registry = new DatabaseRegistry();
|
|
2065
|
+
/** @internal Called by the database constructor. */
|
|
2066
|
+
function registerDatabase(db) {
|
|
2067
|
+
registry.databases.add(db);
|
|
2068
|
+
registry.notify();
|
|
2069
|
+
}
|
|
2070
|
+
/** @internal Called when the database closes. */
|
|
2071
|
+
function unregisterDatabase(db) {
|
|
2072
|
+
if (registry.databases.delete(db)) {
|
|
2073
|
+
registry.notify();
|
|
2074
|
+
}
|
|
2075
|
+
}
|
|
2076
|
+
|
|
1966
2077
|
/**
|
|
1967
2078
|
* @internal Use {@link PowerSyncDatabase} instead, this class is only used by other SDKs also needing web support.
|
|
1968
2079
|
*/
|
|
@@ -1975,6 +2086,11 @@ class WebPowerSyncDatabase extends BasePowerSyncDatabase {
|
|
|
1975
2086
|
super(options);
|
|
1976
2087
|
this.resolvedOpenOptions = resolvedOpenOptions;
|
|
1977
2088
|
this.enableBroadcastLogs = options.broadcastLogs ?? true;
|
|
2089
|
+
// Lets development tooling in this page find the live databases.
|
|
2090
|
+
registerDatabase(this);
|
|
2091
|
+
}
|
|
2092
|
+
get sdkName() {
|
|
2093
|
+
return '@powersync/web';
|
|
1978
2094
|
}
|
|
1979
2095
|
async _initialize() {
|
|
1980
2096
|
if (this.database instanceof AsyncDbAdapter) {
|
|
@@ -2015,11 +2131,12 @@ class WebPowerSyncDatabase extends BasePowerSyncDatabase {
|
|
|
2015
2131
|
* By default the sync stream client is only disconnected if
|
|
2016
2132
|
* multiple tabs are not enabled.
|
|
2017
2133
|
*/
|
|
2018
|
-
close(options) {
|
|
2019
|
-
|
|
2134
|
+
async close(options) {
|
|
2135
|
+
await super.close({
|
|
2020
2136
|
// Don't disconnect by default if multiple tabs are enabled
|
|
2021
2137
|
disconnect: options?.disconnect ?? !this.resolvedOpenOptions.enableMultiTabs
|
|
2022
2138
|
});
|
|
2139
|
+
unregisterDatabase(this);
|
|
2023
2140
|
}
|
|
2024
2141
|
async loadVersion() {
|
|
2025
2142
|
if (this.resolvedOpenOptions.ssrMode) {
|