@powersync/web 1.38.6 → 1.39.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.umd.js +259 -51
- package/dist/index.umd.js.map +1 -1
- package/dist/worker/SharedSyncImplementation.umd.js +11 -3
- package/dist/worker/SharedSyncImplementation.umd.js.map +1 -1
- package/dist/worker/WASQLiteDB.umd.js +78 -54
- package/dist/worker/WASQLiteDB.umd.js.map +1 -1
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-833585.umd.js +1400 -0
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-833585.umd.js.map +1 -0
- package/lib/package.json +2 -2
- package/lib/src/db/adapters/wa-sqlite/RawSqliteConnection.d.ts +0 -1
- package/lib/src/db/adapters/wa-sqlite/RawSqliteConnection.js +4 -9
- package/lib/src/db/adapters/wa-sqlite/RawSqliteConnection.js.map +1 -1
- package/lib/src/db/adapters/wa-sqlite/vfs.d.ts +20 -30
- package/lib/src/db/adapters/wa-sqlite/vfs.js +57 -39
- package/lib/src/db/adapters/wa-sqlite/vfs.js.map +1 -1
- package/lib/src/worker/db/MultiDatabaseServer.js +5 -3
- package/lib/src/worker/db/MultiDatabaseServer.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/db/adapters/wa-sqlite/RawSqliteConnection.ts +5 -11
- package/src/db/adapters/wa-sqlite/vfs.ts +67 -54
- package/src/worker/db/MultiDatabaseServer.ts +5 -3
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type * as SQLite from '@journeyapps/wa-sqlite';
|
|
2
|
+
import { ResolvedWASQLiteOpenFactoryOptions } from './WASQLiteOpenFactory.js';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* List of currently tested virtual filesystems
|
|
@@ -7,31 +8,36 @@ export enum WASQLiteVFS {
|
|
|
7
8
|
IDBBatchAtomicVFS = 'IDBBatchAtomicVFS',
|
|
8
9
|
OPFSCoopSyncVFS = 'OPFSCoopSyncVFS',
|
|
9
10
|
AccessHandlePoolVFS = 'AccessHandlePoolVFS',
|
|
10
|
-
OPFSWriteAheadVFS = 'OPFSWriteAheadVFS'
|
|
11
|
+
OPFSWriteAheadVFS = 'OPFSWriteAheadVFS',
|
|
12
|
+
/**
|
|
13
|
+
* A virtual file system storing data in-memory only, without persistence.
|
|
14
|
+
*
|
|
15
|
+
* This file system can be used in three configurations:
|
|
16
|
+
*
|
|
17
|
+
* 1. In shared workers (the default when available): All tabs share the same in-memory database, which is cleared
|
|
18
|
+
* once the last tab is closed.
|
|
19
|
+
* 2. In dedicated workers (used when `enableMultiTabs` is disabled). Each tab has its own in-memory database cleared
|
|
20
|
+
* when the tab is closed. Queries are offloaded to a dedicated worker.
|
|
21
|
+
* 3. In the context of the tab itself (used when both `enableMultiTabs` and `useWebWorker` are disabled). The per-tab
|
|
22
|
+
* database is hosted in the tab itself, and queries run synchronously. This is _a lot_ faster than any other
|
|
23
|
+
* single-threadedVFS, but can block JavaScript for computationally-intensive queries.
|
|
24
|
+
*
|
|
25
|
+
* This VFS primarily intended for development, but it also useful for online-first deployments not syncing large
|
|
26
|
+
* amounts of data, as it is quicker to start up.
|
|
27
|
+
*/
|
|
28
|
+
InMemoryVfs = 'InMemoryVFS'
|
|
11
29
|
}
|
|
12
30
|
|
|
13
31
|
export function vfsRequiresDedicatedWorkers(vfs: WASQLiteVFS) {
|
|
14
|
-
return vfs != WASQLiteVFS.IDBBatchAtomicVFS;
|
|
32
|
+
return vfs != WASQLiteVFS.IDBBatchAtomicVFS && vfs != WASQLiteVFS.InMemoryVfs;
|
|
15
33
|
}
|
|
16
34
|
|
|
17
|
-
/**
|
|
18
|
-
* @internal
|
|
19
|
-
*/
|
|
20
|
-
export type WASQLiteModuleFactoryOptions = { dbFileName: string; encryptionKey?: string };
|
|
21
|
-
|
|
22
35
|
/**
|
|
23
36
|
* @internal
|
|
24
37
|
*/
|
|
25
38
|
export type SQLiteModule = Parameters<typeof SQLite.Factory>[0];
|
|
26
39
|
|
|
27
|
-
|
|
28
|
-
* @internal
|
|
29
|
-
*/
|
|
30
|
-
export type WASQLiteModuleFactory = (
|
|
31
|
-
options: WASQLiteModuleFactoryOptions
|
|
32
|
-
) => Promise<{ module: SQLiteModule; vfs: SQLiteVFS }>;
|
|
33
|
-
|
|
34
|
-
async function asyncModuleFactory(encryptionKey: unknown) {
|
|
40
|
+
async function asyncModuleFactory(encryptionKey: string | undefined): Promise<SQLiteModule> {
|
|
35
41
|
if (encryptionKey) {
|
|
36
42
|
const { default: factory } = await import('@journeyapps/wa-sqlite/dist/mc-wa-sqlite-async.mjs');
|
|
37
43
|
return factory();
|
|
@@ -41,7 +47,7 @@ async function asyncModuleFactory(encryptionKey: unknown) {
|
|
|
41
47
|
}
|
|
42
48
|
}
|
|
43
49
|
|
|
44
|
-
async function syncModuleFactory(encryptionKey:
|
|
50
|
+
async function syncModuleFactory(encryptionKey: string | undefined): Promise<SQLiteModule> {
|
|
45
51
|
if (encryptionKey) {
|
|
46
52
|
const { default: factory } = await import('@journeyapps/wa-sqlite/dist/mc-wa-sqlite.mjs');
|
|
47
53
|
return factory();
|
|
@@ -54,43 +60,50 @@ async function syncModuleFactory(encryptionKey: unknown) {
|
|
|
54
60
|
/**
|
|
55
61
|
* @internal
|
|
56
62
|
*/
|
|
57
|
-
export
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
export async function loadModuleAndVfs({
|
|
64
|
+
vfs,
|
|
65
|
+
dbFilename,
|
|
66
|
+
encryptionKey
|
|
67
|
+
}: ResolvedWASQLiteOpenFactoryOptions): Promise<{ module: SQLiteModule; vfs: SQLiteVFS }> {
|
|
68
|
+
let moduleFactory = syncModuleFactory;
|
|
69
|
+
let resolveVfs: (module: any) => Promise<SQLiteVFS>;
|
|
70
|
+
|
|
71
|
+
switch (vfs) {
|
|
72
|
+
case WASQLiteVFS.IDBBatchAtomicVFS: {
|
|
73
|
+
moduleFactory = asyncModuleFactory;
|
|
74
|
+
const { IDBBatchAtomicVFS } = await import('@journeyapps/wa-sqlite/src/examples/IDBBatchAtomicVFS.js');
|
|
75
|
+
resolveVfs = (module) => {
|
|
76
|
+
// @ts-expect-error The types for this static method are missing upstream
|
|
77
|
+
return IDBBatchAtomicVFS.create(dbFilename, module, { lockPolicy: 'exclusive' });
|
|
78
|
+
};
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
case WASQLiteVFS.AccessHandlePoolVFS: {
|
|
82
|
+
// @ts-expect-error The types for this import are missing upstream
|
|
83
|
+
const { AccessHandlePoolVFS } = await import('@journeyapps/wa-sqlite/src/examples/AccessHandlePoolVFS.js');
|
|
84
|
+
resolveVfs = (module) => AccessHandlePoolVFS.create(dbFilename, module);
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
case WASQLiteVFS.OPFSCoopSyncVFS: {
|
|
88
|
+
// @ts-expect-error The types for this import are missing upstream
|
|
89
|
+
const { OPFSCoopSyncVFS } = await import('@journeyapps/wa-sqlite/src/examples/OPFSCoopSyncVFS.js');
|
|
90
|
+
resolveVfs = (module) => OPFSCoopSyncVFS.create(dbFilename, module);
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
case WASQLiteVFS.OPFSWriteAheadVFS: {
|
|
94
|
+
// @ts-expect-error The types for this import are missing upstream
|
|
95
|
+
const { OPFSWriteAheadVFS } = await import('@journeyapps/wa-sqlite/src/examples/OPFSWriteAheadVFS.js');
|
|
96
|
+
resolveVfs = (module) => OPFSWriteAheadVFS.create(dbFilename, module, {});
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
case WASQLiteVFS.InMemoryVfs: {
|
|
100
|
+
const { MemoryVFS } = await import('@journeyapps/wa-sqlite/src/examples/MemoryVFS.js');
|
|
63
101
|
// @ts-expect-error The types for this static method are missing upstream
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
[WASQLiteVFS.AccessHandlePoolVFS]: async (options: WASQLiteModuleFactoryOptions) => {
|
|
68
|
-
const module = await syncModuleFactory(options.encryptionKey);
|
|
69
|
-
// @ts-expect-error The types for this static method are missing upstream
|
|
70
|
-
const { AccessHandlePoolVFS } = await import('@journeyapps/wa-sqlite/src/examples/AccessHandlePoolVFS.js');
|
|
71
|
-
return {
|
|
72
|
-
module,
|
|
73
|
-
vfs: await AccessHandlePoolVFS.create(options.dbFileName, module)
|
|
74
|
-
};
|
|
75
|
-
},
|
|
76
|
-
[WASQLiteVFS.OPFSCoopSyncVFS]: async (options: WASQLiteModuleFactoryOptions) => {
|
|
77
|
-
const module = await syncModuleFactory(options.encryptionKey);
|
|
78
|
-
// @ts-expect-error The types for this static method are missing upstream
|
|
79
|
-
const { OPFSCoopSyncVFS } = await import('@journeyapps/wa-sqlite/src/examples/OPFSCoopSyncVFS.js');
|
|
80
|
-
const vfs = await OPFSCoopSyncVFS.create(options.dbFileName, module);
|
|
81
|
-
return {
|
|
82
|
-
module,
|
|
83
|
-
vfs
|
|
84
|
-
};
|
|
85
|
-
},
|
|
86
|
-
[WASQLiteVFS.OPFSWriteAheadVFS]: async (options: WASQLiteModuleFactoryOptions) => {
|
|
87
|
-
const module = await syncModuleFactory(options.encryptionKey);
|
|
88
|
-
// @ts-expect-error The types for this static method are missing upstream
|
|
89
|
-
const { OPFSWriteAheadVFS } = await import('@journeyapps/wa-sqlite/src/examples/OPFSWriteAheadVFS.js');
|
|
90
|
-
const vfs = await OPFSWriteAheadVFS.create(options.dbFileName, module, {});
|
|
91
|
-
return {
|
|
92
|
-
module,
|
|
93
|
-
vfs
|
|
94
|
-
};
|
|
102
|
+
resolveVfs = (module) => MemoryVFS.create(dbFilename, module);
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
95
105
|
}
|
|
96
|
-
|
|
106
|
+
|
|
107
|
+
const module = await moduleFactory(encryptionKey);
|
|
108
|
+
return { module, vfs: await resolveVfs(module) };
|
|
109
|
+
}
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
import { getNavigatorLocks } from '../../shared/navigator.js';
|
|
9
9
|
import { RawSqliteConnection } from '../../db/adapters/wa-sqlite/RawSqliteConnection.js';
|
|
10
10
|
import { ConcurrentSqliteConnection } from '../../db/adapters/wa-sqlite/ConcurrentConnection.js';
|
|
11
|
+
import { WASQLiteVFS } from '../../db/adapters/wa-sqlite/vfs.js';
|
|
11
12
|
|
|
12
13
|
const OPEN_DB_LOCK = 'open-wasqlite-db';
|
|
13
14
|
|
|
@@ -57,14 +58,15 @@ export class MultiDatabaseServer {
|
|
|
57
58
|
|
|
58
59
|
private async databaseOpenAttempt(options: ResolvedWASQLiteOpenFactoryOptions): Promise<DatabaseServer> {
|
|
59
60
|
return getNavigatorLocks().request(OPEN_DB_LOCK, async () => {
|
|
60
|
-
const { dbFilename } = options;
|
|
61
|
+
const { dbFilename, isReadOnly, vfs } = options;
|
|
61
62
|
|
|
62
63
|
let server: DatabaseServer | undefined = this.activeDatabases.get(dbFilename);
|
|
63
64
|
if (server == null) {
|
|
64
65
|
// We don't need navigator locks for shared workers because all queries run in this shared worker exclusively.
|
|
65
66
|
// For read-only connections, we use a VFS that supports concurrent reads (so a single lock on the connection is
|
|
66
|
-
// fine).
|
|
67
|
-
|
|
67
|
+
// fine). In-memory databases either run in a shared worker or aren't shared across tabs at all, so the internal
|
|
68
|
+
// lock is enough.
|
|
69
|
+
const needsNavigatorLocks = !(isSharedWorker || isReadOnly || vfs == WASQLiteVFS.InMemoryVfs);
|
|
68
70
|
const connection = new RawSqliteConnection(options);
|
|
69
71
|
const withSafeConcurrency = new ConcurrentSqliteConnection(connection, needsNavigatorLocks);
|
|
70
72
|
|