@powersync/web 1.3.0 → 1.5.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 +1 -25
- package/lib/src/db/PowerSyncDatabase.d.ts +2 -2
- package/lib/src/db/PowerSyncDatabase.js +35 -28
- package/lib/src/db/adapters/AbstractWebPowerSyncDatabaseOpenFactory.js +7 -1
- package/lib/src/db/adapters/AbstractWebSQLOpenFactory.js +2 -0
- package/lib/src/db/adapters/SSRDBAdapter.js +28 -48
- package/lib/src/db/adapters/wa-sqlite/WASQLiteDBAdapter.js +105 -124
- package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.js +4 -1
- package/lib/src/db/adapters/web-sql-flags.js +6 -3
- package/lib/src/db/sync/SSRWebStreamingSyncImplementation.js +2 -0
- package/lib/src/db/sync/SharedWebStreamingSyncImplementation.js +66 -95
- package/lib/src/db/sync/WebRemote.d.ts +5 -1
- package/lib/src/db/sync/WebRemote.js +29 -21
- package/lib/src/shared/open-db.js +153 -184
- package/lib/src/worker/db/SharedWASQLiteDB.worker.js +15 -23
- package/lib/src/worker/db/WASQLiteDB.worker.js +1 -10
- package/lib/src/worker/sync/BroadcastLogger.js +16 -19
- package/lib/src/worker/sync/SharedSyncImplementation.js +96 -115
- package/lib/src/worker/sync/SharedSyncImplementation.worker.js +1 -5
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +13 -7
|
@@ -16,11 +16,14 @@ export const DEFAULT_WEB_SQL_FLAGS = {
|
|
|
16
16
|
useWebWorker: true
|
|
17
17
|
};
|
|
18
18
|
export function resolveWebSQLFlags(flags) {
|
|
19
|
-
const resolvedFlags =
|
|
20
|
-
|
|
19
|
+
const resolvedFlags = {
|
|
20
|
+
...DEFAULT_WEB_SQL_FLAGS,
|
|
21
|
+
...(flags ?? {})
|
|
22
|
+
};
|
|
23
|
+
if (typeof flags?.enableMultiTabs != 'undefined') {
|
|
21
24
|
resolvedFlags.enableMultiTabs = flags.enableMultiTabs;
|
|
22
25
|
}
|
|
23
|
-
if (
|
|
26
|
+
if (flags?.useWebWorker === false) {
|
|
24
27
|
resolvedFlags.enableMultiTabs = false;
|
|
25
28
|
}
|
|
26
29
|
return resolvedFlags;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { AbstractStreamingSyncImplementation, LockType } from '@powersync/common';
|
|
2
2
|
import { Mutex } from 'async-mutex';
|
|
3
3
|
export class SSRStreamingSyncImplementation extends AbstractStreamingSyncImplementation {
|
|
4
|
+
syncMutex;
|
|
5
|
+
crudMutex;
|
|
4
6
|
constructor(options) {
|
|
5
7
|
super(options);
|
|
6
8
|
this.syncMutex = new Mutex();
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import * as Comlink from 'comlink';
|
|
11
2
|
import { WebStreamingSyncImplementation } from './WebStreamingSyncImplementation';
|
|
12
3
|
import { SharedSyncClientEvent } from '../../worker/sync/SharedSyncImplementation';
|
|
@@ -17,76 +8,70 @@ import { openWorkerDatabasePort } from '../../worker/db/open-worker-database';
|
|
|
17
8
|
* via this client provider.
|
|
18
9
|
*/
|
|
19
10
|
class SharedSyncClientProvider extends AbstractSharedSyncClientProvider {
|
|
11
|
+
options;
|
|
12
|
+
statusChanged;
|
|
20
13
|
constructor(options, statusChanged) {
|
|
21
14
|
super();
|
|
22
15
|
this.options = options;
|
|
23
16
|
this.statusChanged = statusChanged;
|
|
24
17
|
}
|
|
25
|
-
fetchCredentials() {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
};
|
|
42
|
-
});
|
|
18
|
+
async fetchCredentials() {
|
|
19
|
+
const credentials = await this.options.remote.getCredentials();
|
|
20
|
+
if (credentials == null) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The credentials need to be serializable.
|
|
25
|
+
* Users might extend [PowerSyncCredentials] to contain
|
|
26
|
+
* items which are not serializable.
|
|
27
|
+
* This returns only the essential fields.
|
|
28
|
+
*/
|
|
29
|
+
return {
|
|
30
|
+
endpoint: credentials.endpoint,
|
|
31
|
+
token: credentials.token,
|
|
32
|
+
expiresAt: credentials.expiresAt
|
|
33
|
+
};
|
|
43
34
|
}
|
|
44
|
-
uploadCrud() {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
yield this.options.uploadCrud();
|
|
51
|
-
});
|
|
35
|
+
async uploadCrud() {
|
|
36
|
+
/**
|
|
37
|
+
* Don't return anything here, just incase something which is not
|
|
38
|
+
* serializable is returned from the `uploadCrud` function.
|
|
39
|
+
*/
|
|
40
|
+
await this.options.uploadCrud();
|
|
52
41
|
}
|
|
53
42
|
get logger() {
|
|
54
43
|
return this.options.logger;
|
|
55
44
|
}
|
|
56
45
|
trace(...x) {
|
|
57
|
-
|
|
58
|
-
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(...x);
|
|
46
|
+
this.logger?.trace(...x);
|
|
59
47
|
}
|
|
60
48
|
debug(...x) {
|
|
61
|
-
|
|
62
|
-
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.debug(...x);
|
|
49
|
+
this.logger?.debug(...x);
|
|
63
50
|
}
|
|
64
51
|
info(...x) {
|
|
65
|
-
|
|
66
|
-
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.info(...x);
|
|
52
|
+
this.logger?.info(...x);
|
|
67
53
|
}
|
|
68
54
|
log(...x) {
|
|
69
|
-
|
|
70
|
-
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.log(...x);
|
|
55
|
+
this.logger?.log(...x);
|
|
71
56
|
}
|
|
72
57
|
warn(...x) {
|
|
73
|
-
|
|
74
|
-
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.warn(...x);
|
|
58
|
+
this.logger?.warn(...x);
|
|
75
59
|
}
|
|
76
60
|
error(...x) {
|
|
77
|
-
|
|
78
|
-
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.error(...x);
|
|
61
|
+
this.logger?.error(...x);
|
|
79
62
|
}
|
|
80
63
|
time(label) {
|
|
81
|
-
|
|
82
|
-
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.time(label);
|
|
64
|
+
this.logger?.time(label);
|
|
83
65
|
}
|
|
84
66
|
timeEnd(label) {
|
|
85
|
-
|
|
86
|
-
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.timeEnd(label);
|
|
67
|
+
this.logger?.timeEnd(label);
|
|
87
68
|
}
|
|
88
69
|
}
|
|
89
70
|
export class SharedWebStreamingSyncImplementation extends WebStreamingSyncImplementation {
|
|
71
|
+
syncManager;
|
|
72
|
+
clientProvider;
|
|
73
|
+
messagePort;
|
|
74
|
+
isInitialized;
|
|
90
75
|
constructor(options) {
|
|
91
76
|
super(options);
|
|
92
77
|
/**
|
|
@@ -135,53 +120,39 @@ export class SharedWebStreamingSyncImplementation extends WebStreamingSyncImplem
|
|
|
135
120
|
* Starts the sync process, this effectively acts as a call to
|
|
136
121
|
* `connect` if not yet connected.
|
|
137
122
|
*/
|
|
138
|
-
connect(options) {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
return
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
event: SharedSyncClientEvent.CLOSE_CLIENT,
|
|
167
|
-
data: {}
|
|
168
|
-
};
|
|
169
|
-
this.messagePort.postMessage(closeMessagePayload);
|
|
170
|
-
// Release the proxy
|
|
171
|
-
this.syncManager[Comlink.releaseProxy]();
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
waitForReady() {
|
|
175
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
176
|
-
return this.isInitialized;
|
|
177
|
-
});
|
|
123
|
+
async connect(options) {
|
|
124
|
+
await this.waitForReady();
|
|
125
|
+
return this.syncManager.connect(options);
|
|
126
|
+
}
|
|
127
|
+
async disconnect() {
|
|
128
|
+
await this.waitForReady();
|
|
129
|
+
return this.syncManager.disconnect();
|
|
130
|
+
}
|
|
131
|
+
async getWriteCheckpoint() {
|
|
132
|
+
await this.waitForReady();
|
|
133
|
+
return this.syncManager.getWriteCheckpoint();
|
|
134
|
+
}
|
|
135
|
+
async hasCompletedSync() {
|
|
136
|
+
return this.syncManager.hasCompletedSync();
|
|
137
|
+
}
|
|
138
|
+
async dispose() {
|
|
139
|
+
await this.waitForReady();
|
|
140
|
+
// Signal the shared worker that this client is closing its connection to the worker
|
|
141
|
+
const closeMessagePayload = {
|
|
142
|
+
event: SharedSyncClientEvent.CLOSE_CLIENT,
|
|
143
|
+
data: {}
|
|
144
|
+
};
|
|
145
|
+
this.messagePort.postMessage(closeMessagePayload);
|
|
146
|
+
// Release the proxy
|
|
147
|
+
this.syncManager[Comlink.releaseProxy]();
|
|
148
|
+
}
|
|
149
|
+
async waitForReady() {
|
|
150
|
+
return this.isInitialized;
|
|
178
151
|
}
|
|
179
152
|
/**
|
|
180
153
|
* Used in tests to force a connection states
|
|
181
154
|
*/
|
|
182
|
-
_testUpdateStatus(status) {
|
|
183
|
-
return
|
|
184
|
-
return this.syncManager['_testUpdateAllStatuses'](status.toJSON());
|
|
185
|
-
});
|
|
155
|
+
async _testUpdateStatus(status) {
|
|
156
|
+
return this.syncManager['_testUpdateAllStatuses'](status.toJSON());
|
|
186
157
|
}
|
|
187
158
|
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type ILogger } from 'js-logger';
|
|
2
|
+
import { AbstractRemote, AbstractRemoteOptions, BSONImplementation, RemoteConnector } from '@powersync/common';
|
|
2
3
|
export declare class WebRemote extends AbstractRemote {
|
|
4
|
+
protected connector: RemoteConnector;
|
|
5
|
+
protected logger: ILogger;
|
|
3
6
|
private _bson;
|
|
7
|
+
constructor(connector: RemoteConnector, logger?: ILogger, options?: Partial<AbstractRemoteOptions>);
|
|
4
8
|
getBSON(): Promise<BSONImplementation>;
|
|
5
9
|
}
|
|
@@ -1,25 +1,33 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
import { AbstractRemote } from '@powersync/common';
|
|
1
|
+
import { AbstractRemote, DEFAULT_REMOTE_LOGGER, FetchImplementationProvider } from '@powersync/common';
|
|
2
|
+
/*
|
|
3
|
+
* Depends on browser's implementation of global fetch.
|
|
4
|
+
*/
|
|
5
|
+
class WebFetchProvider extends FetchImplementationProvider {
|
|
6
|
+
getFetch() {
|
|
7
|
+
return fetch.bind(globalThis);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
11
10
|
export class WebRemote extends AbstractRemote {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
*/
|
|
20
|
-
const { BSON } = yield import('bson');
|
|
21
|
-
this._bson = BSON;
|
|
22
|
-
return this._bson;
|
|
11
|
+
connector;
|
|
12
|
+
logger;
|
|
13
|
+
_bson;
|
|
14
|
+
constructor(connector, logger = DEFAULT_REMOTE_LOGGER, options) {
|
|
15
|
+
super(connector, logger, {
|
|
16
|
+
...(options ?? {}),
|
|
17
|
+
fetchImplementation: options?.fetchImplementation ?? new WebFetchProvider()
|
|
23
18
|
});
|
|
19
|
+
this.connector = connector;
|
|
20
|
+
this.logger = logger;
|
|
21
|
+
}
|
|
22
|
+
async getBSON() {
|
|
23
|
+
if (this._bson) {
|
|
24
|
+
return this._bson;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Dynamic import to be used only when needed.
|
|
28
|
+
*/
|
|
29
|
+
const { BSON } = await import('bson');
|
|
30
|
+
this._bson = BSON;
|
|
31
|
+
return this._bson;
|
|
24
32
|
}
|
|
25
33
|
}
|