@powersync/web 0.0.0-dev-20251127205344 → 0.0.0-dev-20251201150812
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/1807036ae51c10ee4d23.wasm +0 -0
- package/dist/{10072fe45f0a8fab0a0e.wasm → 307d8ce2280e3bae09d5.wasm} +0 -0
- package/dist/{6e435e51534839845554.wasm → cd8b9e8f4c87bf81c169.wasm} +0 -0
- package/dist/e797080f5ed0b5324166.wasm +0 -0
- package/dist/index.umd.js +336 -177
- package/dist/index.umd.js.map +1 -1
- package/dist/worker/SharedSyncImplementation.umd.js +310 -143
- package/dist/worker/SharedSyncImplementation.umd.js.map +1 -1
- package/dist/worker/WASQLiteDB.umd.js +19 -5
- 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 +2 -2
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_mc-wa-sqlite-async_mjs.umd.js.map +1 -1
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_mc-wa-sqlite_mjs.umd.js +2 -2
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_mc-wa-sqlite_mjs.umd.js.map +1 -1
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_wa-sqlite-async_mjs.umd.js +2 -2
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_wa-sqlite-async_mjs.umd.js.map +1 -1
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_wa-sqlite_mjs.umd.js +2 -2
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_wa-sqlite_mjs.umd.js.map +1 -1
- package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js.umd.js +20 -23
- package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js.umd.js.map +1 -1
- package/lib/src/db/PowerSyncDatabase.d.ts +1 -1
- package/lib/src/db/PowerSyncDatabase.js +4 -4
- package/lib/src/db/adapters/AsyncDatabaseConnection.d.ts +8 -0
- package/lib/src/db/adapters/AsyncDatabaseConnection.js +11 -1
- package/lib/src/db/adapters/LockedAsyncDatabaseAdapter.d.ts +14 -0
- package/lib/src/db/adapters/LockedAsyncDatabaseAdapter.js +61 -8
- package/lib/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.d.ts +5 -1
- package/lib/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.js +15 -7
- package/lib/src/db/sync/SharedWebStreamingSyncImplementation.d.ts +1 -4
- package/lib/src/db/sync/SharedWebStreamingSyncImplementation.js +45 -31
- package/lib/src/worker/sync/MockSyncService.d.ts +2 -0
- package/lib/src/worker/sync/MockSyncService.js +3 -0
- package/lib/src/worker/sync/MockSyncServiceTypes.d.ts +101 -0
- package/lib/src/worker/sync/MockSyncServiceTypes.js +1 -0
- package/lib/src/worker/sync/MockSyncServiceWorker.d.ts +56 -0
- package/lib/src/worker/sync/MockSyncServiceWorker.js +369 -0
- package/lib/src/worker/sync/SharedSyncImplementation.d.ts +18 -8
- package/lib/src/worker/sync/SharedSyncImplementation.js +174 -108
- package/lib/src/worker/sync/SharedSyncImplementation.worker.js +1 -1
- package/lib/src/worker/sync/WorkerClient.d.ts +4 -5
- package/lib/src/worker/sync/WorkerClient.js +5 -7
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/db/PowerSyncDatabase.ts +13 -15
- package/src/db/adapters/AsyncDatabaseConnection.ts +12 -0
- package/src/db/adapters/LockedAsyncDatabaseAdapter.ts +71 -9
- package/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.ts +19 -6
- package/src/db/sync/SharedWebStreamingSyncImplementation.ts +56 -40
- package/src/worker/sync/MockSyncService.ts +3 -0
- package/src/worker/sync/MockSyncServiceTypes.ts +71 -0
- package/src/worker/sync/MockSyncServiceWorker.ts +406 -0
- package/src/worker/sync/SharedSyncImplementation.ts +201 -120
- package/src/worker/sync/SharedSyncImplementation.worker.ts +1 -1
- package/src/worker/sync/WorkerClient.ts +6 -11
- package/dist/a730f7ca717b02234beb.wasm +0 -0
- package/dist/aa2f408d64445fed090e.wasm +0 -0
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mock sync service implementation for shared worker environments.
|
|
3
|
+
* This allows tests to mock sync responses when using enableMultipleTabs: true.
|
|
4
|
+
* Requests are kept pending until a client explicitly creates a response.
|
|
5
|
+
*/
|
|
6
|
+
export class MockSyncService {
|
|
7
|
+
pendingRequests = new Map();
|
|
8
|
+
activeResponses = new Map();
|
|
9
|
+
nextId = 0;
|
|
10
|
+
automaticResponse = null;
|
|
11
|
+
/**
|
|
12
|
+
* A Static instance of the mock sync service.
|
|
13
|
+
* This can be used directly for non-worker environments.
|
|
14
|
+
* A proxy is required for worker environments.
|
|
15
|
+
*/
|
|
16
|
+
static GLOBAL_INSTANCE = new MockSyncService();
|
|
17
|
+
/**
|
|
18
|
+
* Register a new pending request (called by WebRemote when a sync stream is requested).
|
|
19
|
+
* Returns a promise that resolves when a client creates a response for this request.
|
|
20
|
+
*/
|
|
21
|
+
registerPendingRequest(url, method, headers, body, signal) {
|
|
22
|
+
const id = `pending-${++this.nextId}`;
|
|
23
|
+
let resolveResponse;
|
|
24
|
+
let rejectResponse;
|
|
25
|
+
const responsePromise = new Promise((resolve, reject) => {
|
|
26
|
+
resolveResponse = resolve;
|
|
27
|
+
rejectResponse = reject;
|
|
28
|
+
});
|
|
29
|
+
const pendingRequest = {
|
|
30
|
+
id,
|
|
31
|
+
url,
|
|
32
|
+
method,
|
|
33
|
+
headers,
|
|
34
|
+
body,
|
|
35
|
+
responsePromise: {
|
|
36
|
+
resolve: resolveResponse,
|
|
37
|
+
reject: rejectResponse
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
this.pendingRequests.set(id, pendingRequest);
|
|
41
|
+
signal?.addEventListener('abort', () => {
|
|
42
|
+
this.pendingRequests.delete(id);
|
|
43
|
+
rejectResponse(new Error('Request aborted'));
|
|
44
|
+
// if already in active responses, remove it
|
|
45
|
+
if (this.activeResponses.has(id)) {
|
|
46
|
+
const response = this.activeResponses.get(id);
|
|
47
|
+
if (response) {
|
|
48
|
+
response.stream.close();
|
|
49
|
+
}
|
|
50
|
+
this.activeResponses.delete(id);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
// If automatic response is configured, apply it immediately
|
|
54
|
+
if (this.automaticResponse) {
|
|
55
|
+
// Use setTimeout to ensure the response is created asynchronously
|
|
56
|
+
// This prevents issues if the response creation happens synchronously
|
|
57
|
+
setTimeout(() => {
|
|
58
|
+
try {
|
|
59
|
+
// Create response with automatic config
|
|
60
|
+
this.createResponse(id, this.automaticResponse.status, this.automaticResponse.headers);
|
|
61
|
+
// Push body lines if provided
|
|
62
|
+
if (this.automaticResponse.bodyLines) {
|
|
63
|
+
for (const line of this.automaticResponse.bodyLines) {
|
|
64
|
+
const lineStr = `${JSON.stringify(line)}\n`;
|
|
65
|
+
const encoder = new TextEncoder();
|
|
66
|
+
this.pushBodyData(id, encoder.encode(lineStr));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Complete the response
|
|
70
|
+
this.completeResponse(id);
|
|
71
|
+
}
|
|
72
|
+
catch (e) {
|
|
73
|
+
// If automatic response fails, reject the promise
|
|
74
|
+
rejectResponse(e instanceof Error ? e : new Error(String(e)));
|
|
75
|
+
}
|
|
76
|
+
}, 0);
|
|
77
|
+
}
|
|
78
|
+
// Return the promise - it will resolve when createResponse is called (or immediately if auto-response is set)
|
|
79
|
+
return responsePromise;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Get all pending requests
|
|
83
|
+
*/
|
|
84
|
+
getPendingRequestsSync() {
|
|
85
|
+
return Array.from(this.pendingRequests.values()).map((pr) => ({
|
|
86
|
+
id: pr.id,
|
|
87
|
+
url: pr.url,
|
|
88
|
+
method: pr.method,
|
|
89
|
+
headers: pr.headers,
|
|
90
|
+
body: pr.body
|
|
91
|
+
}));
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Create a response for a pending request.
|
|
95
|
+
* This resolves the response promise and allows pushing body lines.
|
|
96
|
+
*/
|
|
97
|
+
createResponse(pendingRequestId, status, headers) {
|
|
98
|
+
const pendingRequest = this.pendingRequests.get(pendingRequestId);
|
|
99
|
+
if (!pendingRequest) {
|
|
100
|
+
throw new Error(`Pending request ${pendingRequestId} not found`);
|
|
101
|
+
}
|
|
102
|
+
// Create a readable stream that the mock service can control
|
|
103
|
+
// Response.body is always ReadableStream<Uint8Array>, so we use Uint8Array
|
|
104
|
+
const stream = new ReadableStream({
|
|
105
|
+
start: (controller) => {
|
|
106
|
+
// Store the active response once the controller is available
|
|
107
|
+
// The start callback is called synchronously, so this is safe
|
|
108
|
+
const activeResponse = {
|
|
109
|
+
id: pendingRequestId,
|
|
110
|
+
status,
|
|
111
|
+
headers,
|
|
112
|
+
stream: controller
|
|
113
|
+
};
|
|
114
|
+
this.activeResponses.set(pendingRequestId, activeResponse);
|
|
115
|
+
},
|
|
116
|
+
cancel: () => {
|
|
117
|
+
// Remove response when stream is cancelled
|
|
118
|
+
this.activeResponses.delete(pendingRequestId);
|
|
119
|
+
this.pendingRequests.delete(pendingRequestId);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
// Create the Response object
|
|
123
|
+
const response = new Response(stream, {
|
|
124
|
+
status,
|
|
125
|
+
headers
|
|
126
|
+
});
|
|
127
|
+
// Resolve the pending request's promise
|
|
128
|
+
pendingRequest.responsePromise.resolve(response);
|
|
129
|
+
// Remove from pending (it's now active)
|
|
130
|
+
this.pendingRequests.delete(pendingRequestId);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Push body data to an active response.
|
|
134
|
+
* Accepts either text (string) or binary data (ArrayBuffer or Uint8Array).
|
|
135
|
+
* All data is encoded to Uint8Array before enqueueing (required by ReadableStream<Uint8Array>).
|
|
136
|
+
*/
|
|
137
|
+
pushBodyData(pendingRequestId, data) {
|
|
138
|
+
const activeResponse = this.activeResponses.get(pendingRequestId);
|
|
139
|
+
if (!activeResponse) {
|
|
140
|
+
throw new Error(`Active response ${pendingRequestId} not found`);
|
|
141
|
+
}
|
|
142
|
+
try {
|
|
143
|
+
let encoded;
|
|
144
|
+
if (typeof data === 'string') {
|
|
145
|
+
// Encode string to Uint8Array (required by ReadableStream<Uint8Array>)
|
|
146
|
+
const encoder = new TextEncoder();
|
|
147
|
+
encoded = encoder.encode(data);
|
|
148
|
+
}
|
|
149
|
+
else if (data instanceof ArrayBuffer) {
|
|
150
|
+
// Convert ArrayBuffer to Uint8Array
|
|
151
|
+
encoded = new Uint8Array(data);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
// Already Uint8Array, use directly
|
|
155
|
+
encoded = data;
|
|
156
|
+
}
|
|
157
|
+
activeResponse.stream.enqueue(encoded);
|
|
158
|
+
}
|
|
159
|
+
catch (e) {
|
|
160
|
+
// Stream might be closed, remove it
|
|
161
|
+
this.activeResponses.delete(pendingRequestId);
|
|
162
|
+
throw new Error(`Failed to push data to response ${pendingRequestId}: ${e}`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Complete an active response (close the stream)
|
|
167
|
+
*/
|
|
168
|
+
completeResponse(pendingRequestId) {
|
|
169
|
+
const activeResponse = this.activeResponses.get(pendingRequestId);
|
|
170
|
+
if (!activeResponse) {
|
|
171
|
+
throw new Error(`Active response ${pendingRequestId} not found`);
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
activeResponse.stream.close();
|
|
175
|
+
}
|
|
176
|
+
catch (e) {
|
|
177
|
+
// Stream might already be closed
|
|
178
|
+
}
|
|
179
|
+
finally {
|
|
180
|
+
this.activeResponses.delete(pendingRequestId);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Set the automatic response configuration.
|
|
185
|
+
* When set, this will be used to automatically reply to all pending requests.
|
|
186
|
+
*/
|
|
187
|
+
setAutomaticResponse(config) {
|
|
188
|
+
this.automaticResponse = config;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Automatically reply to all pending requests using the automatic response configuration.
|
|
192
|
+
* Returns the number of requests that were replied to.
|
|
193
|
+
*/
|
|
194
|
+
replyToAllPendingRequests() {
|
|
195
|
+
if (!this.automaticResponse) {
|
|
196
|
+
throw new Error('Automatic response not set. Call setAutomaticResponse first.');
|
|
197
|
+
}
|
|
198
|
+
const pendingRequestIds = Array.from(this.pendingRequests.keys());
|
|
199
|
+
let count = 0;
|
|
200
|
+
for (const requestId of pendingRequestIds) {
|
|
201
|
+
try {
|
|
202
|
+
// Create response with automatic config
|
|
203
|
+
this.createResponse(requestId, this.automaticResponse.status, this.automaticResponse.headers);
|
|
204
|
+
// Push body lines if provided
|
|
205
|
+
if (this.automaticResponse.bodyLines) {
|
|
206
|
+
for (const line of this.automaticResponse.bodyLines) {
|
|
207
|
+
const lineStr = `${JSON.stringify(line)}\n`;
|
|
208
|
+
const encoder = new TextEncoder();
|
|
209
|
+
this.pushBodyData(requestId, encoder.encode(lineStr));
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
// Complete the response
|
|
213
|
+
this.completeResponse(requestId);
|
|
214
|
+
count++;
|
|
215
|
+
}
|
|
216
|
+
catch (e) {
|
|
217
|
+
// Skip requests that fail (might already be handled)
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return count;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Set up message handler for the mock service on a MessagePort
|
|
226
|
+
*/
|
|
227
|
+
export function setupMockServiceMessageHandler(port) {
|
|
228
|
+
port.addEventListener('message', (event) => {
|
|
229
|
+
const message = event.data;
|
|
230
|
+
if (!message || typeof message !== 'object' || !('type' in message)) {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
const service = MockSyncService.GLOBAL_INSTANCE;
|
|
234
|
+
try {
|
|
235
|
+
switch (message.type) {
|
|
236
|
+
case 'getPendingRequests': {
|
|
237
|
+
try {
|
|
238
|
+
const requests = service.getPendingRequestsSync();
|
|
239
|
+
port.postMessage({
|
|
240
|
+
type: 'getPendingRequests',
|
|
241
|
+
requestId: message.requestId,
|
|
242
|
+
requests
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
port.postMessage({
|
|
247
|
+
type: 'error',
|
|
248
|
+
requestId: message.requestId,
|
|
249
|
+
error: error instanceof Error ? error.message : String(error)
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
case 'createResponse': {
|
|
255
|
+
try {
|
|
256
|
+
service.createResponse(message.pendingRequestId, message.status, message.headers);
|
|
257
|
+
port.postMessage({
|
|
258
|
+
type: 'createResponse',
|
|
259
|
+
requestId: message.requestId,
|
|
260
|
+
success: true
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
catch (error) {
|
|
264
|
+
port.postMessage({
|
|
265
|
+
type: 'error',
|
|
266
|
+
requestId: message.requestId,
|
|
267
|
+
error: error instanceof Error ? error.message : String(error)
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
break;
|
|
271
|
+
}
|
|
272
|
+
case 'pushBodyData': {
|
|
273
|
+
try {
|
|
274
|
+
service.pushBodyData(message.pendingRequestId, message.data);
|
|
275
|
+
port.postMessage({
|
|
276
|
+
type: 'pushBodyData',
|
|
277
|
+
requestId: message.requestId,
|
|
278
|
+
success: true
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
catch (error) {
|
|
282
|
+
port.postMessage({
|
|
283
|
+
type: 'error',
|
|
284
|
+
requestId: message.requestId,
|
|
285
|
+
error: error instanceof Error ? error.message : String(error)
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
case 'completeResponse': {
|
|
291
|
+
try {
|
|
292
|
+
service.completeResponse(message.pendingRequestId);
|
|
293
|
+
port.postMessage({
|
|
294
|
+
type: 'completeResponse',
|
|
295
|
+
requestId: message.requestId,
|
|
296
|
+
success: true
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
catch (error) {
|
|
300
|
+
port.postMessage({
|
|
301
|
+
type: 'error',
|
|
302
|
+
requestId: message.requestId,
|
|
303
|
+
error: error instanceof Error ? error.message : String(error)
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
break;
|
|
307
|
+
}
|
|
308
|
+
case 'setAutomaticResponse': {
|
|
309
|
+
try {
|
|
310
|
+
service.setAutomaticResponse(message.config);
|
|
311
|
+
port.postMessage({
|
|
312
|
+
type: 'setAutomaticResponse',
|
|
313
|
+
requestId: message.requestId,
|
|
314
|
+
success: true
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
catch (error) {
|
|
318
|
+
port.postMessage({
|
|
319
|
+
type: 'error',
|
|
320
|
+
requestId: message.requestId,
|
|
321
|
+
error: error instanceof Error ? error.message : String(error)
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
break;
|
|
325
|
+
}
|
|
326
|
+
case 'replyToAllPendingRequests': {
|
|
327
|
+
try {
|
|
328
|
+
const count = service.replyToAllPendingRequests();
|
|
329
|
+
port.postMessage({
|
|
330
|
+
type: 'replyToAllPendingRequests',
|
|
331
|
+
requestId: message.requestId,
|
|
332
|
+
success: true,
|
|
333
|
+
count
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
catch (error) {
|
|
337
|
+
port.postMessage({
|
|
338
|
+
type: 'error',
|
|
339
|
+
requestId: message.requestId,
|
|
340
|
+
error: error instanceof Error ? error.message : String(error)
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
break;
|
|
344
|
+
}
|
|
345
|
+
default: {
|
|
346
|
+
const requestId = 'requestId' in message && typeof message === 'object' && message !== null
|
|
347
|
+
? message.requestId
|
|
348
|
+
: undefined;
|
|
349
|
+
port.postMessage({
|
|
350
|
+
type: 'error',
|
|
351
|
+
requestId,
|
|
352
|
+
error: `Unknown message type: ${message.type}`
|
|
353
|
+
});
|
|
354
|
+
break;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
catch (error) {
|
|
359
|
+
// Fallback for any unexpected errors
|
|
360
|
+
const requestId = 'requestId' in message ? message.requestId : undefined;
|
|
361
|
+
port.postMessage({
|
|
362
|
+
type: 'error',
|
|
363
|
+
requestId,
|
|
364
|
+
error: error instanceof Error ? error.message : String(error)
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
port.start();
|
|
369
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { BaseObserver, ConnectionManager, DBAdapter, SubscribedStream, SyncStatus, type
|
|
1
|
+
import { BaseObserver, ConnectionManager, DBAdapter, SubscribedStream, SyncStatus, type ILogLevel, type ILogger, type PowerSyncConnectionOptions, type StreamingSyncImplementation, type StreamingSyncImplementationListener, type SyncStatusOptions } from '@powersync/common';
|
|
2
2
|
import { Mutex } from 'async-mutex';
|
|
3
3
|
import * as Comlink from 'comlink';
|
|
4
4
|
import { WebStreamingSyncImplementation, WebStreamingSyncImplementationOptions } from '../../db/sync/WebStreamingSyncImplementation';
|
|
5
|
+
import { WorkerWrappedAsyncDatabaseConnection } from '../../db/adapters/WorkerWrappedAsyncDatabaseConnection';
|
|
5
6
|
import { ResolvedWebSQLOpenOptions } from '../../db/adapters/web-sql-flags';
|
|
6
7
|
import { AbstractSharedSyncClientProvider } from './AbstractSharedSyncClientProvider';
|
|
7
8
|
/**
|
|
@@ -45,6 +46,7 @@ export type WrappedSyncPort = {
|
|
|
45
46
|
db?: DBAdapter;
|
|
46
47
|
currentSubscriptions: SubscribedStream[];
|
|
47
48
|
closeListeners: (() => void | Promise<void>)[];
|
|
49
|
+
isClosing: boolean;
|
|
48
50
|
};
|
|
49
51
|
/**
|
|
50
52
|
* @internal
|
|
@@ -63,7 +65,6 @@ export declare class SharedSyncImplementation extends BaseObserver<SharedSyncImp
|
|
|
63
65
|
protected statusListener?: () => void;
|
|
64
66
|
protected fetchCredentialsController?: RemoteOperationAbortController;
|
|
65
67
|
protected uploadDataController?: RemoteOperationAbortController;
|
|
66
|
-
protected dbAdapter: DBAdapter | null;
|
|
67
68
|
protected syncParams: SharedSyncInitOptions | null;
|
|
68
69
|
protected logger: ILogger;
|
|
69
70
|
protected lastConnectOptions: PowerSyncConnectionOptions | undefined;
|
|
@@ -72,9 +73,19 @@ export declare class SharedSyncImplementation extends BaseObserver<SharedSyncImp
|
|
|
72
73
|
protected connectionManager: ConnectionManager;
|
|
73
74
|
syncStatus: SyncStatus;
|
|
74
75
|
broadCastLogger: ILogger;
|
|
76
|
+
protected distributedDB: DBAdapter | null;
|
|
75
77
|
constructor();
|
|
76
78
|
get lastSyncedAt(): Date | undefined;
|
|
77
79
|
get isConnected(): boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Gets the last client port which we know is safe from unexpected closes.
|
|
82
|
+
*/
|
|
83
|
+
protected getLastWrappedPort(): Promise<WrappedSyncPort | undefined>;
|
|
84
|
+
/**
|
|
85
|
+
* In some very rare cases a specific tab might not respond to requests.
|
|
86
|
+
* This returns a random port which is not closing.
|
|
87
|
+
*/
|
|
88
|
+
protected getRandomWrappedPort(): Promise<WrappedSyncPort | undefined>;
|
|
78
89
|
waitForStatus(status: SyncStatusOptions): Promise<void>;
|
|
79
90
|
waitUntilStatusMatches(predicate: (status: SyncStatus) => boolean): Promise<void>;
|
|
80
91
|
waitForReady(): Promise<void>;
|
|
@@ -102,6 +113,7 @@ export declare class SharedSyncImplementation extends BaseObserver<SharedSyncImp
|
|
|
102
113
|
clientProvider: Comlink.Remote<AbstractSharedSyncClientProvider>;
|
|
103
114
|
currentSubscriptions: never[];
|
|
104
115
|
closeListeners: never[];
|
|
116
|
+
isClosing: false;
|
|
105
117
|
}>;
|
|
106
118
|
/**
|
|
107
119
|
* Removes a message port client from this manager's managed
|
|
@@ -113,15 +125,13 @@ export declare class SharedSyncImplementation extends BaseObserver<SharedSyncImp
|
|
|
113
125
|
getWriteCheckpoint(): Promise<string>;
|
|
114
126
|
protected withSyncImplementation<T>(callback: (sync: StreamingSyncImplementation) => Promise<T>): Promise<T>;
|
|
115
127
|
protected generateStreamingImplementation(): WebStreamingSyncImplementation;
|
|
116
|
-
|
|
128
|
+
/**
|
|
129
|
+
* Opens a worker wrapped database connection. Using the last connected client port.
|
|
130
|
+
*/
|
|
131
|
+
protected openInternalDB(): Promise<WorkerWrappedAsyncDatabaseConnection<ResolvedWebSQLOpenOptions>>;
|
|
117
132
|
/**
|
|
118
133
|
* A method to update the all shared statuses for each
|
|
119
134
|
* client.
|
|
120
135
|
*/
|
|
121
136
|
private updateAllStatuses;
|
|
122
|
-
/**
|
|
123
|
-
* A function only used for unit tests which updates the internal
|
|
124
|
-
* sync stream client and all tab client's sync status
|
|
125
|
-
*/
|
|
126
|
-
_testUpdateAllStatuses(status: SyncStatusOptions): Promise<void>;
|
|
127
137
|
}
|