@powersync/web 1.12.3 → 1.13.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/README.md +33 -0
- package/dist/3cb48be086dd9edd02ff.wasm +0 -0
- package/dist/{_journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js-async-mutex-c-3cff7d0.index.umd.js → _journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js-_powersync_co-780aa20.index.umd.js} +18 -8
- package/dist/_journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js-_powersync_co-780aa20.index.umd.js.map +1 -0
- package/dist/{_journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js-async-mutex-c-3cff7d1.index.umd.js → _journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js-_powersync_co-780aa21.index.umd.js} +18 -8
- package/dist/_journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js-_powersync_co-780aa21.index.umd.js.map +1 -0
- package/dist/df958358cadf945bd0fe.wasm +0 -0
- package/dist/f9c8ada26c59f5bf4339.wasm +0 -0
- package/dist/index.umd.js +3707 -497
- package/dist/index.umd.js.map +1 -1
- package/dist/worker/SharedSyncImplementation.umd.js +246 -2171
- package/dist/worker/SharedSyncImplementation.umd.js.map +1 -1
- package/dist/worker/WASQLiteDB.umd.js +767 -196
- package/dist/worker/WASQLiteDB.umd.js.map +1 -1
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_mc-wa-sqlite-async_mjs.umd.js +45 -0
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_mc-wa-sqlite-async_mjs.umd.js.map +1 -0
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_mc-wa-sqlite_mjs.umd.js +45 -0
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_mc-wa-sqlite_mjs.umd.js.map +1 -0
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_wa-sqlite_mjs.umd.js +45 -0
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_wa-sqlite_mjs.umd.js.map +1 -0
- package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_AccessHandlePoolVFS_js.umd.js +1509 -0
- package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_AccessHandlePoolVFS_js.umd.js.map +1 -0
- package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_OPFSCoopSyncVFS_js.umd.js +1641 -0
- package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_OPFSCoopSyncVFS_js.umd.js.map +1 -0
- package/lib/package.json +2 -2
- package/lib/src/db/PowerSyncDatabase.d.ts +10 -2
- package/lib/src/db/PowerSyncDatabase.js +20 -4
- package/lib/src/db/adapters/AbstractWebSQLOpenFactory.d.ts +2 -0
- package/lib/src/db/adapters/AbstractWebSQLOpenFactory.js +3 -0
- package/lib/src/db/adapters/AsyncDatabaseConnection.d.ts +26 -0
- package/lib/src/db/adapters/LockedAsyncDatabaseAdapter.d.ts +82 -0
- package/lib/src/db/adapters/LockedAsyncDatabaseAdapter.js +239 -0
- package/lib/src/db/adapters/WebDBAdapter.d.ts +17 -0
- package/lib/src/db/adapters/WebDBAdapter.js +1 -0
- package/lib/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.d.ts +39 -0
- package/lib/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.js +46 -0
- package/lib/src/db/adapters/wa-sqlite/WASQLiteConnection.d.ts +127 -0
- package/lib/src/db/adapters/wa-sqlite/WASQLiteConnection.js +343 -0
- package/lib/src/db/adapters/wa-sqlite/WASQLiteDBAdapter.d.ts +10 -42
- package/lib/src/db/adapters/wa-sqlite/WASQLiteDBAdapter.js +36 -212
- package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.d.ts +12 -0
- package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.js +81 -4
- package/lib/src/db/adapters/web-sql-flags.d.ts +17 -0
- package/lib/src/db/sync/SharedWebStreamingSyncImplementation.d.ts +9 -2
- package/lib/src/db/sync/SharedWebStreamingSyncImplementation.js +16 -10
- package/lib/src/db/sync/WebStreamingSyncImplementation.d.ts +0 -5
- package/lib/src/index.d.ts +8 -7
- package/lib/src/index.js +8 -7
- package/lib/src/worker/db/WASQLiteDB.worker.js +38 -20
- package/lib/src/worker/db/open-worker-database.d.ts +5 -4
- package/lib/src/worker/db/open-worker-database.js +5 -3
- package/lib/src/worker/sync/AbstractSharedSyncClientProvider.d.ts +1 -0
- package/lib/src/worker/sync/SharedSyncImplementation.d.ts +20 -3
- package/lib/src/worker/sync/SharedSyncImplementation.js +40 -11
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/dist/_journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js-async-mutex-c-3cff7d0.index.umd.js.map +0 -1
- package/dist/_journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js-async-mutex-c-3cff7d1.index.umd.js.map +0 -1
- package/lib/src/shared/open-db.d.ts +0 -5
- package/lib/src/shared/open-db.js +0 -193
- package/lib/src/shared/types.d.ts +0 -22
- /package/lib/src/{shared/types.js → db/adapters/AsyncDatabaseConnection.js} +0 -0
|
@@ -3,46 +3,63 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import '@journeyapps/wa-sqlite';
|
|
5
5
|
import * as Comlink from 'comlink';
|
|
6
|
-
import {
|
|
6
|
+
import { WASqliteConnection } from '../../db/adapters/wa-sqlite/WASQLiteConnection';
|
|
7
7
|
import { getNavigatorLocks } from '../../shared/navigator';
|
|
8
8
|
const DBMap = new Map();
|
|
9
9
|
const OPEN_DB_LOCK = 'open-wasqlite-db';
|
|
10
10
|
let nextClientId = 1;
|
|
11
|
-
const
|
|
11
|
+
const openWorkerConnection = async (options) => {
|
|
12
|
+
const connection = new WASqliteConnection(options);
|
|
13
|
+
return {
|
|
14
|
+
init: Comlink.proxy(() => connection.init()),
|
|
15
|
+
getConfig: Comlink.proxy(() => connection.getConfig()),
|
|
16
|
+
close: Comlink.proxy(() => connection.close()),
|
|
17
|
+
execute: Comlink.proxy(async (sql, params) => connection.execute(sql, params)),
|
|
18
|
+
executeBatch: Comlink.proxy(async (sql, params) => connection.executeBatch(sql, params)),
|
|
19
|
+
registerOnTableChange: Comlink.proxy(async (callback) => {
|
|
20
|
+
// Proxy the callback remove function
|
|
21
|
+
return Comlink.proxy(await connection.registerOnTableChange(callback));
|
|
22
|
+
})
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
const openDBShared = async (options) => {
|
|
12
26
|
// Prevent multiple simultaneous opens from causing race conditions
|
|
13
27
|
return getNavigatorLocks().request(OPEN_DB_LOCK, async () => {
|
|
14
28
|
const clientId = nextClientId++;
|
|
15
|
-
|
|
29
|
+
const { dbFilename } = options;
|
|
30
|
+
if (!DBMap.has(dbFilename)) {
|
|
16
31
|
const clientIds = new Set();
|
|
17
|
-
const connection = await
|
|
18
|
-
|
|
32
|
+
const connection = await openWorkerConnection(options);
|
|
33
|
+
await connection.init();
|
|
34
|
+
DBMap.set(dbFilename, {
|
|
19
35
|
clientIds,
|
|
20
36
|
db: connection
|
|
21
37
|
});
|
|
22
38
|
}
|
|
23
|
-
const dbEntry = DBMap.get(
|
|
39
|
+
const dbEntry = DBMap.get(dbFilename);
|
|
24
40
|
dbEntry.clientIds.add(clientId);
|
|
25
41
|
const { db } = dbEntry;
|
|
26
42
|
const wrappedConnection = {
|
|
27
43
|
...db,
|
|
44
|
+
init: Comlink.proxy(() => {
|
|
45
|
+
// the init has been done automatically
|
|
46
|
+
}),
|
|
28
47
|
close: Comlink.proxy(() => {
|
|
29
48
|
const { clientIds } = dbEntry;
|
|
49
|
+
console.debug(`Close requested from client ${clientId} of ${[...clientIds]}`);
|
|
30
50
|
clientIds.delete(clientId);
|
|
31
51
|
if (clientIds.size == 0) {
|
|
32
|
-
console.debug(`Closing connection to ${
|
|
33
|
-
DBMap.delete(
|
|
52
|
+
console.debug(`Closing connection to ${dbFilename}.`);
|
|
53
|
+
DBMap.delete(dbFilename);
|
|
34
54
|
return db.close?.();
|
|
35
55
|
}
|
|
36
|
-
console.debug(`Connection to ${
|
|
56
|
+
console.debug(`Connection to ${dbFilename} not closed yet due to active clients.`);
|
|
57
|
+
return;
|
|
37
58
|
})
|
|
38
59
|
};
|
|
39
60
|
return Comlink.proxy(wrappedConnection);
|
|
40
61
|
});
|
|
41
62
|
};
|
|
42
|
-
const openDBDedicated = async (dbFileName) => {
|
|
43
|
-
const connection = await _openDB(dbFileName);
|
|
44
|
-
return Comlink.proxy(connection);
|
|
45
|
-
};
|
|
46
63
|
// Check if we're in a SharedWorker context
|
|
47
64
|
if (typeof SharedWorkerGlobalScope !== 'undefined') {
|
|
48
65
|
const _self = self;
|
|
@@ -51,13 +68,14 @@ if (typeof SharedWorkerGlobalScope !== 'undefined') {
|
|
|
51
68
|
console.debug('Exposing shared db on port', port);
|
|
52
69
|
Comlink.expose(openDBShared, port);
|
|
53
70
|
};
|
|
54
|
-
addEventListener('unload', () => {
|
|
55
|
-
Array.from(DBMap.values()).forEach(async (dbConnection) => {
|
|
56
|
-
const db = await dbConnection.db;
|
|
57
|
-
db.close?.();
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
71
|
}
|
|
61
72
|
else {
|
|
62
|
-
|
|
73
|
+
// A dedicated worker can be shared externally
|
|
74
|
+
Comlink.expose(openDBShared);
|
|
63
75
|
}
|
|
76
|
+
addEventListener('unload', () => {
|
|
77
|
+
Array.from(DBMap.values()).forEach(async (dbConnection) => {
|
|
78
|
+
const { db } = dbConnection;
|
|
79
|
+
db.close?.();
|
|
80
|
+
});
|
|
81
|
+
});
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import * as Comlink from 'comlink';
|
|
2
|
-
import
|
|
2
|
+
import { OpenAsyncDatabaseConnection } from '../..//db/adapters/AsyncDatabaseConnection';
|
|
3
|
+
import { WASQLiteVFS } from '../../db/adapters/wa-sqlite/WASQLiteConnection';
|
|
3
4
|
/**
|
|
4
5
|
* Opens a shared or dedicated worker which exposes opening of database connections
|
|
5
6
|
*/
|
|
6
|
-
export declare function openWorkerDatabasePort(workerIdentifier: string, multipleTabs?: boolean, worker?: string | URL):
|
|
7
|
+
export declare function openWorkerDatabasePort(workerIdentifier: string, multipleTabs?: boolean, worker?: string | URL, vfs?: WASQLiteVFS): Worker | MessagePort;
|
|
7
8
|
/**
|
|
8
9
|
* @returns A function which allows for opening database connections inside
|
|
9
10
|
* a worker.
|
|
10
11
|
*/
|
|
11
|
-
export declare function getWorkerDatabaseOpener(workerIdentifier: string, multipleTabs?: boolean, worker?: string | URL): Comlink.Remote<
|
|
12
|
-
export declare function resolveWorkerDatabasePortFactory(worker: () => Worker | SharedWorker):
|
|
12
|
+
export declare function getWorkerDatabaseOpener(workerIdentifier: string, multipleTabs?: boolean, worker?: string | URL): Comlink.Remote<OpenAsyncDatabaseConnection>;
|
|
13
|
+
export declare function resolveWorkerDatabasePortFactory(worker: () => Worker | SharedWorker): Worker | MessagePort;
|
|
13
14
|
export declare function isSharedWorker(worker: Worker | SharedWorker): worker is SharedWorker;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import * as Comlink from 'comlink';
|
|
2
|
+
import { WASQLiteVFS } from '../../db/adapters/wa-sqlite/WASQLiteConnection';
|
|
2
3
|
/**
|
|
3
4
|
* Opens a shared or dedicated worker which exposes opening of database connections
|
|
4
5
|
*/
|
|
5
|
-
export function openWorkerDatabasePort(workerIdentifier, multipleTabs = true, worker = '') {
|
|
6
|
+
export function openWorkerDatabasePort(workerIdentifier, multipleTabs = true, worker = '', vfs) {
|
|
7
|
+
const needsDedicated = vfs == WASQLiteVFS.AccessHandlePoolVFS || vfs == WASQLiteVFS.OPFSCoopSyncVFS;
|
|
6
8
|
if (worker) {
|
|
7
|
-
return multipleTabs
|
|
9
|
+
return !needsDedicated && multipleTabs
|
|
8
10
|
? new SharedWorker(`${worker}`, {
|
|
9
11
|
/* @vite-ignore */
|
|
10
12
|
name: `shared-DB-worker-${workerIdentifier}`
|
|
@@ -21,7 +23,7 @@ export function openWorkerDatabasePort(workerIdentifier, multipleTabs = true, wo
|
|
|
21
23
|
* This enables multi tab support by default, but falls back if SharedWorker is not available
|
|
22
24
|
* (in the case of Android)
|
|
23
25
|
*/
|
|
24
|
-
return multipleTabs
|
|
26
|
+
return !needsDedicated && multipleTabs
|
|
25
27
|
? new SharedWorker(new URL('./WASQLiteDB.worker.js', import.meta.url), {
|
|
26
28
|
/* @vite-ignore */
|
|
27
29
|
name: `shared-DB-worker-${workerIdentifier}`,
|
|
@@ -6,6 +6,7 @@ export declare abstract class AbstractSharedSyncClientProvider {
|
|
|
6
6
|
abstract fetchCredentials(): Promise<PowerSyncCredentials | null>;
|
|
7
7
|
abstract uploadCrud(): Promise<void>;
|
|
8
8
|
abstract statusChanged(status: SyncStatusOptions): void;
|
|
9
|
+
abstract getDBWorkerPort(): Promise<MessagePort>;
|
|
9
10
|
abstract trace(...x: any[]): void;
|
|
10
11
|
abstract debug(...x: any[]): void;
|
|
11
12
|
abstract info(...x: any[]): void;
|
|
@@ -2,6 +2,7 @@ import { type AbstractStreamingSyncImplementation, type LockOptions, type PowerS
|
|
|
2
2
|
import * as Comlink from 'comlink';
|
|
3
3
|
import { type ILogger } from 'js-logger';
|
|
4
4
|
import { WebStreamingSyncImplementation, WebStreamingSyncImplementationOptions } from '../../db/sync/WebStreamingSyncImplementation';
|
|
5
|
+
import { ResolvedWebSQLOpenOptions } from '../../db/adapters/web-sql-flags';
|
|
5
6
|
import { AbstractSharedSyncClientProvider } from './AbstractSharedSyncClientProvider';
|
|
6
7
|
/**
|
|
7
8
|
* Manual message events for shared sync clients
|
|
@@ -17,22 +18,36 @@ export type ManualSharedSyncPayload = {
|
|
|
17
18
|
event: SharedSyncClientEvent;
|
|
18
19
|
data: any;
|
|
19
20
|
};
|
|
21
|
+
/**
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
20
24
|
export type SharedSyncInitOptions = {
|
|
21
|
-
dbName: string;
|
|
22
25
|
streamOptions: Omit<WebStreamingSyncImplementationOptions, 'adapter' | 'uploadCrud' | 'remote'>;
|
|
26
|
+
dbParams: ResolvedWebSQLOpenOptions;
|
|
23
27
|
};
|
|
28
|
+
/**
|
|
29
|
+
* @internal
|
|
30
|
+
*/
|
|
24
31
|
export interface SharedSyncImplementationListener extends StreamingSyncImplementationListener {
|
|
25
32
|
initialized: () => void;
|
|
26
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* @internal
|
|
36
|
+
*/
|
|
27
37
|
export type WrappedSyncPort = {
|
|
28
38
|
port: MessagePort;
|
|
29
39
|
clientProvider: Comlink.Remote<AbstractSharedSyncClientProvider>;
|
|
40
|
+
db?: DBAdapter;
|
|
30
41
|
};
|
|
42
|
+
/**
|
|
43
|
+
* @internal
|
|
44
|
+
*/
|
|
31
45
|
export type RemoteOperationAbortController = {
|
|
32
46
|
controller: AbortController;
|
|
33
47
|
activePort: WrappedSyncPort;
|
|
34
48
|
};
|
|
35
49
|
/**
|
|
50
|
+
* @internal
|
|
36
51
|
* Shared sync implementation which runs inside a shared webworker
|
|
37
52
|
*/
|
|
38
53
|
export declare class SharedSyncImplementation extends BaseObserver<SharedSyncImplementationListener> implements StreamingSyncImplementation {
|
|
@@ -45,6 +60,7 @@ export declare class SharedSyncImplementation extends BaseObserver<SharedSyncImp
|
|
|
45
60
|
protected dbAdapter: DBAdapter | null;
|
|
46
61
|
protected syncParams: SharedSyncInitOptions | null;
|
|
47
62
|
protected logger: ILogger;
|
|
63
|
+
protected lastConnectOptions: PowerSyncConnectionOptions | undefined;
|
|
48
64
|
syncStatus: SyncStatus;
|
|
49
65
|
broadCastLogger: ILogger;
|
|
50
66
|
constructor();
|
|
@@ -55,7 +71,7 @@ export declare class SharedSyncImplementation extends BaseObserver<SharedSyncImp
|
|
|
55
71
|
/**
|
|
56
72
|
* Configures the DBAdapter connection and a streaming sync client.
|
|
57
73
|
*/
|
|
58
|
-
|
|
74
|
+
setParams(params: SharedSyncInitOptions): Promise<void>;
|
|
59
75
|
dispose(): Promise<void | undefined>;
|
|
60
76
|
/**
|
|
61
77
|
* Connects to the PowerSync backend instance.
|
|
@@ -73,12 +89,13 @@ export declare class SharedSyncImplementation extends BaseObserver<SharedSyncImp
|
|
|
73
89
|
* Removes a message port client from this manager's managed
|
|
74
90
|
* clients.
|
|
75
91
|
*/
|
|
76
|
-
removePort(port: MessagePort): void
|
|
92
|
+
removePort(port: MessagePort): Promise<void>;
|
|
77
93
|
triggerCrudUpload(): void;
|
|
78
94
|
obtainLock<T>(lockOptions: LockOptions<T>): Promise<T>;
|
|
79
95
|
hasCompletedSync(): Promise<boolean>;
|
|
80
96
|
getWriteCheckpoint(): Promise<string>;
|
|
81
97
|
protected generateStreamingImplementation(): WebStreamingSyncImplementation;
|
|
98
|
+
protected openInternalDB(): Promise<void>;
|
|
82
99
|
/**
|
|
83
100
|
* A method to update the all shared statuses for each
|
|
84
101
|
* client.
|
|
@@ -4,9 +4,10 @@ import * as Comlink from 'comlink';
|
|
|
4
4
|
import Logger from 'js-logger';
|
|
5
5
|
import { WebRemote } from '../../db/sync/WebRemote';
|
|
6
6
|
import { WebStreamingSyncImplementation } from '../../db/sync/WebStreamingSyncImplementation';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { LockedAsyncDatabaseAdapter } from '../../db/adapters/LockedAsyncDatabaseAdapter';
|
|
8
|
+
import { WorkerWrappedAsyncDatabaseConnection } from '../../db/adapters/WorkerWrappedAsyncDatabaseConnection';
|
|
9
9
|
import { getNavigatorLocks } from '../../shared/navigator';
|
|
10
|
+
import { BroadcastLogger } from './BroadcastLogger';
|
|
10
11
|
/**
|
|
11
12
|
* Manual message events for shared sync clients
|
|
12
13
|
*/
|
|
@@ -19,6 +20,7 @@ export var SharedSyncClientEvent;
|
|
|
19
20
|
SharedSyncClientEvent["CLOSE_CLIENT"] = "close-client";
|
|
20
21
|
})(SharedSyncClientEvent || (SharedSyncClientEvent = {}));
|
|
21
22
|
/**
|
|
23
|
+
* @internal
|
|
22
24
|
* Shared sync implementation which runs inside a shared webworker
|
|
23
25
|
*/
|
|
24
26
|
export class SharedSyncImplementation extends BaseObserver {
|
|
@@ -31,6 +33,7 @@ export class SharedSyncImplementation extends BaseObserver {
|
|
|
31
33
|
dbAdapter;
|
|
32
34
|
syncParams;
|
|
33
35
|
logger;
|
|
36
|
+
lastConnectOptions;
|
|
34
37
|
syncStatus;
|
|
35
38
|
broadCastLogger;
|
|
36
39
|
constructor() {
|
|
@@ -40,6 +43,7 @@ export class SharedSyncImplementation extends BaseObserver {
|
|
|
40
43
|
this.syncParams = null;
|
|
41
44
|
this.syncStreamClient = null;
|
|
42
45
|
this.logger = Logger.get('shared-sync');
|
|
46
|
+
this.lastConnectOptions = undefined;
|
|
43
47
|
this.isInitialized = new Promise((resolve) => {
|
|
44
48
|
const callback = this.registerListener({
|
|
45
49
|
initialized: () => {
|
|
@@ -67,17 +71,11 @@ export class SharedSyncImplementation extends BaseObserver {
|
|
|
67
71
|
/**
|
|
68
72
|
* Configures the DBAdapter connection and a streaming sync client.
|
|
69
73
|
*/
|
|
70
|
-
async
|
|
71
|
-
if (this.
|
|
74
|
+
async setParams(params) {
|
|
75
|
+
if (this.syncParams) {
|
|
72
76
|
// Cannot modify already existing sync implementation
|
|
73
77
|
return;
|
|
74
78
|
}
|
|
75
|
-
this.dbAdapter = new WASQLiteDBAdapter({
|
|
76
|
-
dbFilename: params.dbName,
|
|
77
|
-
workerPort: dbWorkerPort,
|
|
78
|
-
flags: { enableMultiTabs: true, useWebWorker: true },
|
|
79
|
-
logger: this.logger
|
|
80
|
-
});
|
|
81
79
|
this.syncParams = params;
|
|
82
80
|
if (params.streamOptions?.flags?.broadcastLogs) {
|
|
83
81
|
this.logger = this.broadCastLogger;
|
|
@@ -86,6 +84,7 @@ export class SharedSyncImplementation extends BaseObserver {
|
|
|
86
84
|
// Share any uncaught events on the broadcast logger
|
|
87
85
|
this.logger.error('Uncaught exception in PowerSync shared sync worker', event);
|
|
88
86
|
};
|
|
87
|
+
await this.openInternalDB();
|
|
89
88
|
this.iterateListeners((l) => l.initialized?.());
|
|
90
89
|
}
|
|
91
90
|
async dispose() {
|
|
@@ -104,6 +103,7 @@ export class SharedSyncImplementation extends BaseObserver {
|
|
|
104
103
|
// This effectively queues connect and disconnect calls. Ensuring multiple tabs' requests are synchronized
|
|
105
104
|
return getNavigatorLocks().request('shared-sync-connect', async () => {
|
|
106
105
|
this.syncStreamClient = this.generateStreamingImplementation();
|
|
106
|
+
this.lastConnectOptions = options;
|
|
107
107
|
this.syncStreamClient.registerListener({
|
|
108
108
|
statusChanged: (status) => {
|
|
109
109
|
this.updateAllStatuses(status.toJSON());
|
|
@@ -140,13 +140,16 @@ export class SharedSyncImplementation extends BaseObserver {
|
|
|
140
140
|
* Removes a message port client from this manager's managed
|
|
141
141
|
* clients.
|
|
142
142
|
*/
|
|
143
|
-
removePort(port) {
|
|
143
|
+
async removePort(port) {
|
|
144
144
|
const index = this.ports.findIndex((p) => p.port == port);
|
|
145
145
|
if (index < 0) {
|
|
146
146
|
console.warn(`Could not remove port ${port} since it is not present in active ports.`);
|
|
147
147
|
return;
|
|
148
148
|
}
|
|
149
149
|
const trackedPort = this.ports[index];
|
|
150
|
+
if (trackedPort.db) {
|
|
151
|
+
trackedPort.db.close();
|
|
152
|
+
}
|
|
150
153
|
// Release proxy
|
|
151
154
|
trackedPort.clientProvider[Comlink.releaseProxy]();
|
|
152
155
|
this.ports.splice(index, 1);
|
|
@@ -159,6 +162,12 @@ export class SharedSyncImplementation extends BaseObserver {
|
|
|
159
162
|
abortController.controller.abort(new AbortOperation('Closing pending requests after client port is removed'));
|
|
160
163
|
}
|
|
161
164
|
});
|
|
165
|
+
if (this.dbAdapter == trackedPort.db && this.syncStreamClient) {
|
|
166
|
+
await this.disconnect();
|
|
167
|
+
// Ask for a new DB worker port handler
|
|
168
|
+
await this.openInternalDB();
|
|
169
|
+
await this.connect(this.lastConnectOptions);
|
|
170
|
+
}
|
|
162
171
|
}
|
|
163
172
|
triggerCrudUpload() {
|
|
164
173
|
this.waitForReady().then(() => this.syncStreamClient?.triggerCrudUpload());
|
|
@@ -230,6 +239,26 @@ export class SharedSyncImplementation extends BaseObserver {
|
|
|
230
239
|
logger: this.logger
|
|
231
240
|
});
|
|
232
241
|
}
|
|
242
|
+
async openInternalDB() {
|
|
243
|
+
const lastClient = this.ports[this.ports.length - 1];
|
|
244
|
+
const workerPort = await lastClient.clientProvider.getDBWorkerPort();
|
|
245
|
+
const remote = Comlink.wrap(workerPort);
|
|
246
|
+
const identifier = this.syncParams.dbParams.dbFilename;
|
|
247
|
+
const db = await remote(this.syncParams.dbParams);
|
|
248
|
+
const locked = new LockedAsyncDatabaseAdapter({
|
|
249
|
+
name: identifier,
|
|
250
|
+
openConnection: async () => {
|
|
251
|
+
return new WorkerWrappedAsyncDatabaseConnection({
|
|
252
|
+
remote,
|
|
253
|
+
baseConnection: db,
|
|
254
|
+
identifier
|
|
255
|
+
});
|
|
256
|
+
},
|
|
257
|
+
logger: this.logger
|
|
258
|
+
});
|
|
259
|
+
await locked.init();
|
|
260
|
+
this.dbAdapter = lastClient.db = locked;
|
|
261
|
+
}
|
|
233
262
|
/**
|
|
234
263
|
* A method to update the all shared statuses for each
|
|
235
264
|
* client.
|