@powersync/web 2.5.0 → 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 +80 -21
- 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 +3 -0
- 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 +1 -0
- package/lib/db/sync/SharedWebStreamingSyncImplementation.js +28 -11
- 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/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 +6 -6
- package/src/db/PowerSyncDatabase.ts +6 -3
- 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 +34 -15
- package/src/db/sync/WebRemote.ts +2 -5
- package/src/worker/sync/SharedSyncImplementation.ts +89 -48
- package/src/worker/sync/WorkerClient.ts +4 -3
- package/dist/worker/AccessHandlePoolVFS-B9CKqcQ3.js +0 -2
- package/dist/worker/AccessHandlePoolVFS-B9CKqcQ3.js.map +0 -1
- package/dist/worker/IDBBatchAtomicVFS-BfRzbRoV.js +0 -2
- package/dist/worker/IDBBatchAtomicVFS-BfRzbRoV.js.map +0 -1
- package/dist/worker/OPFSCoopSyncVFS-BxXAVpVQ.js +0 -2
- package/dist/worker/OPFSCoopSyncVFS-BxXAVpVQ.js.map +0 -1
- package/dist/worker/OPFSWriteAheadVFS-DuqXaOct.js +0 -2
- package/dist/worker/OPFSWriteAheadVFS-DuqXaOct.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
|
@@ -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);
|
|
@@ -1782,10 +1821,10 @@ class SharedSyncClientProvider extends AbstractSharedSyncClientProvider {
|
|
|
1782
1821
|
* Don't return anything here, just incase something which is not
|
|
1783
1822
|
* serializable is returned from the `uploadCrud` function.
|
|
1784
1823
|
*/
|
|
1785
|
-
await this.#relay(() => this.options.uploadCrud());
|
|
1824
|
+
await this.#relay(() => this.options.connector.uploadCrud());
|
|
1786
1825
|
}
|
|
1787
1826
|
async postCheckpointRequest(clientId, requestId) {
|
|
1788
|
-
return await this.#relay(async () => (await this.options.postCheckpointRequest(clientId, requestId)) ?? null);
|
|
1827
|
+
return await this.#relay(async () => (await this.options.connector.postCheckpointRequest(clientId, requestId)) ?? null);
|
|
1789
1828
|
}
|
|
1790
1829
|
get logger() {
|
|
1791
1830
|
return this.options.logger;
|
|
@@ -1862,9 +1901,13 @@ class SharedWebStreamingSyncImplementation extends WebStreamingSyncImplementatio
|
|
|
1862
1901
|
* - The client sends the params to the shared worker after locks have been registered.
|
|
1863
1902
|
*/
|
|
1864
1903
|
const closeSignal = await generateTabCloseSignal(this.abortOnClose.signal);
|
|
1904
|
+
const { identifier, connector } = this.options;
|
|
1865
1905
|
// Awaiting here ensures the worker is waiting for the lock
|
|
1866
|
-
await this.syncManager.
|
|
1867
|
-
|
|
1906
|
+
await this.syncManager.initialize(closeSignal, {
|
|
1907
|
+
hasFetchCredentials: !!connector.fetchCredentials,
|
|
1908
|
+
hasPostCheckpointRequest: !!connector.postCheckpointRequest,
|
|
1909
|
+
hasUploadCrud: !!connector.uploadCrud
|
|
1910
|
+
});
|
|
1868
1911
|
await this.syncManager.setParams({
|
|
1869
1912
|
dbParams: this.dbAdapter.getConfiguration(),
|
|
1870
1913
|
streamOptions: {
|
|
@@ -1887,8 +1930,26 @@ class SharedWebStreamingSyncImplementation extends WebStreamingSyncImplementatio
|
|
|
1887
1930
|
return this.syncManager.disconnect();
|
|
1888
1931
|
}
|
|
1889
1932
|
async dispose() {
|
|
1890
|
-
|
|
1891
|
-
|
|
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) => {
|
|
1892
1953
|
// This will always be a message port since we use shared workers.
|
|
1893
1954
|
const messagePort = this.worker.endpoint;
|
|
1894
1955
|
// Listen for the close acknowledgment from the worker
|
|
@@ -1905,11 +1966,6 @@ class SharedWebStreamingSyncImplementation extends WebStreamingSyncImplementatio
|
|
|
1905
1966
|
};
|
|
1906
1967
|
messagePort.postMessage(closeMessagePayload);
|
|
1907
1968
|
});
|
|
1908
|
-
await super.dispose();
|
|
1909
|
-
this.abortOnClose.abort();
|
|
1910
|
-
// Release the proxy
|
|
1911
|
-
this.syncManager[Comlink.releaseProxy]();
|
|
1912
|
-
this.worker.close();
|
|
1913
1969
|
}
|
|
1914
1970
|
async waitForReady() {
|
|
1915
1971
|
return this.isInitialized;
|
|
@@ -2033,6 +2089,9 @@ class WebPowerSyncDatabase extends BasePowerSyncDatabase {
|
|
|
2033
2089
|
// Lets development tooling in this page find the live databases.
|
|
2034
2090
|
registerDatabase(this);
|
|
2035
2091
|
}
|
|
2092
|
+
get sdkName() {
|
|
2093
|
+
return '@powersync/web';
|
|
2094
|
+
}
|
|
2036
2095
|
async _initialize() {
|
|
2037
2096
|
if (this.database instanceof AsyncDbAdapter) {
|
|
2038
2097
|
/**
|