@powersync/common 1.53.1 → 1.53.2
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/bundle.cjs +66 -62
- package/dist/bundle.cjs.map +1 -1
- package/dist/bundle.mjs +66 -62
- package/dist/bundle.mjs.map +1 -1
- package/dist/bundle.node.cjs +66 -62
- package/dist/bundle.node.cjs.map +1 -1
- package/dist/bundle.node.mjs +66 -62
- package/dist/bundle.node.mjs.map +1 -1
- package/dist/index.d.cts +6 -9
- package/lib/client/sync/stream/AbstractStreamingSyncImplementation.d.ts +6 -9
- package/lib/client/sync/stream/AbstractStreamingSyncImplementation.js +28 -43
- package/lib/client/sync/stream/AbstractStreamingSyncImplementation.js.map +1 -1
- package/lib/utils/async.d.ts +13 -7
- package/lib/utils/async.js +38 -24
- package/lib/utils/async.js.map +1 -1
- package/package.json +1 -1
- package/src/client/sync/stream/AbstractStreamingSyncImplementation.ts +31 -54
- package/src/utils/async.ts +51 -24
package/dist/bundle.mjs
CHANGED
|
@@ -2428,30 +2428,44 @@ function throttleTrailing(func, wait) {
|
|
|
2428
2428
|
}
|
|
2429
2429
|
};
|
|
2430
2430
|
}
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2431
|
+
function asyncNotifier() {
|
|
2432
|
+
let waitingConsumer = null;
|
|
2433
|
+
let hasPendingNotification = false;
|
|
2434
|
+
return {
|
|
2435
|
+
notify() {
|
|
2436
|
+
if (waitingConsumer != null) {
|
|
2437
|
+
waitingConsumer();
|
|
2438
|
+
waitingConsumer = null;
|
|
2439
|
+
}
|
|
2440
|
+
else {
|
|
2441
|
+
hasPendingNotification = true;
|
|
2442
|
+
}
|
|
2443
|
+
},
|
|
2444
|
+
waitForNotification(signal) {
|
|
2445
|
+
return new Promise((resolve) => {
|
|
2446
|
+
if (waitingConsumer != null) {
|
|
2447
|
+
throw new Error('Illegal call to waitForNotification, already has a waiter.');
|
|
2448
|
+
}
|
|
2449
|
+
if (signal.aborted) {
|
|
2450
|
+
resolve();
|
|
2451
|
+
}
|
|
2452
|
+
else if (hasPendingNotification) {
|
|
2453
|
+
resolve();
|
|
2454
|
+
hasPendingNotification = false;
|
|
2455
|
+
}
|
|
2456
|
+
else {
|
|
2457
|
+
function complete() {
|
|
2458
|
+
signal.removeEventListener('abort', onAbort);
|
|
2459
|
+
resolve();
|
|
2460
|
+
}
|
|
2461
|
+
function onAbort() {
|
|
2462
|
+
waitingConsumer = null;
|
|
2463
|
+
resolve();
|
|
2464
|
+
}
|
|
2465
|
+
waitingConsumer = complete;
|
|
2466
|
+
signal.addEventListener('abort', onAbort);
|
|
2467
|
+
}
|
|
2468
|
+
});
|
|
2455
2469
|
}
|
|
2456
2470
|
};
|
|
2457
2471
|
}
|
|
@@ -10653,7 +10667,7 @@ function requireDist () {
|
|
|
10653
10667
|
|
|
10654
10668
|
var distExports = requireDist();
|
|
10655
10669
|
|
|
10656
|
-
var version = "1.53.
|
|
10670
|
+
var version = "1.53.2";
|
|
10657
10671
|
var PACKAGE = {
|
|
10658
10672
|
version: version};
|
|
10659
10673
|
|
|
@@ -11561,19 +11575,15 @@ const DEFAULT_STREAM_CONNECTION_OPTIONS = {
|
|
|
11561
11575
|
class AbstractStreamingSyncImplementation extends BaseObserver {
|
|
11562
11576
|
options;
|
|
11563
11577
|
abortController;
|
|
11564
|
-
// In rare cases, mostly for tests, uploads can be triggered without being properly connected.
|
|
11565
|
-
// This allows ensuring that all upload processes can be aborted.
|
|
11566
|
-
uploadAbortController;
|
|
11567
11578
|
crudUpdateListener;
|
|
11568
11579
|
streamingSyncPromise;
|
|
11569
11580
|
logger;
|
|
11570
11581
|
activeStreams;
|
|
11571
11582
|
connectionMayHaveChanged = false;
|
|
11572
|
-
|
|
11583
|
+
crudUploadNotifier = asyncNotifier();
|
|
11573
11584
|
notifyCompletedUploads;
|
|
11574
11585
|
handleActiveStreamsChange;
|
|
11575
11586
|
syncStatus;
|
|
11576
|
-
triggerCrudUpload;
|
|
11577
11587
|
constructor(options) {
|
|
11578
11588
|
super();
|
|
11579
11589
|
this.options = options;
|
|
@@ -11589,16 +11599,9 @@ class AbstractStreamingSyncImplementation extends BaseObserver {
|
|
|
11589
11599
|
}
|
|
11590
11600
|
});
|
|
11591
11601
|
this.abortController = null;
|
|
11592
|
-
|
|
11593
|
-
|
|
11594
|
-
|
|
11595
|
-
}
|
|
11596
|
-
this.isUploadingCrud = true;
|
|
11597
|
-
this._uploadAllCrud().finally(() => {
|
|
11598
|
-
this.notifyCompletedUploads?.();
|
|
11599
|
-
this.isUploadingCrud = false;
|
|
11600
|
-
});
|
|
11601
|
-
}, this.options.crudUploadThrottleMs);
|
|
11602
|
+
}
|
|
11603
|
+
triggerCrudUpload() {
|
|
11604
|
+
this.crudUploadNotifier.notify();
|
|
11602
11605
|
}
|
|
11603
11606
|
async waitForReady() { }
|
|
11604
11607
|
waitForStatus(status) {
|
|
@@ -11646,7 +11649,6 @@ class AbstractStreamingSyncImplementation extends BaseObserver {
|
|
|
11646
11649
|
super.dispose();
|
|
11647
11650
|
this.crudUpdateListener?.();
|
|
11648
11651
|
this.crudUpdateListener = undefined;
|
|
11649
|
-
this.uploadAbortController?.abort();
|
|
11650
11652
|
}
|
|
11651
11653
|
async getWriteCheckpoint() {
|
|
11652
11654
|
const clientId = await this.options.adapter.getClientId();
|
|
@@ -11656,7 +11658,17 @@ class AbstractStreamingSyncImplementation extends BaseObserver {
|
|
|
11656
11658
|
this.logger.debug(`Created write checkpoint: ${checkpoint}`);
|
|
11657
11659
|
return checkpoint;
|
|
11658
11660
|
}
|
|
11659
|
-
async
|
|
11661
|
+
async crudUploadLoop(signal) {
|
|
11662
|
+
while (!signal.aborted) {
|
|
11663
|
+
await Promise.all([
|
|
11664
|
+
// Start the initial CRUD upload on connect. Then, keep polling until we're done.
|
|
11665
|
+
this._uploadAllCrud(signal),
|
|
11666
|
+
this.delayRetry(signal, this.options.crudUploadThrottleMs)
|
|
11667
|
+
]);
|
|
11668
|
+
await this.crudUploadNotifier.waitForNotification(signal);
|
|
11669
|
+
}
|
|
11670
|
+
}
|
|
11671
|
+
async _uploadAllCrud(signal) {
|
|
11660
11672
|
return this.obtainLock({
|
|
11661
11673
|
type: LockType.CRUD,
|
|
11662
11674
|
callback: async () => {
|
|
@@ -11664,12 +11676,7 @@ class AbstractStreamingSyncImplementation extends BaseObserver {
|
|
|
11664
11676
|
* Keep track of the first item in the CRUD queue for the last `uploadCrud` iteration.
|
|
11665
11677
|
*/
|
|
11666
11678
|
let checkedCrudItem;
|
|
11667
|
-
|
|
11668
|
-
this.uploadAbortController = controller;
|
|
11669
|
-
this.abortController?.signal.addEventListener('abort', () => {
|
|
11670
|
-
controller.abort();
|
|
11671
|
-
}, { once: true });
|
|
11672
|
-
while (!controller.signal.aborted) {
|
|
11679
|
+
while (!signal.aborted) {
|
|
11673
11680
|
try {
|
|
11674
11681
|
/**
|
|
11675
11682
|
* This is the first item in the FIFO CRUD queue.
|
|
@@ -11699,7 +11706,10 @@ The next upload iteration will be delayed.`);
|
|
|
11699
11706
|
else {
|
|
11700
11707
|
// Uploading is completed
|
|
11701
11708
|
const neededUpdate = await this.options.adapter.updateLocalTarget(() => this.getWriteCheckpoint());
|
|
11702
|
-
if (neededUpdate
|
|
11709
|
+
if (neededUpdate) {
|
|
11710
|
+
this.notifyCompletedUploads?.();
|
|
11711
|
+
}
|
|
11712
|
+
else if (checkedCrudItem != null) {
|
|
11703
11713
|
// Only log this if there was something to upload
|
|
11704
11714
|
this.logger.debug('Upload complete, no write checkpoint needed.');
|
|
11705
11715
|
}
|
|
@@ -11714,7 +11724,7 @@ The next upload iteration will be delayed.`);
|
|
|
11714
11724
|
uploadError: ex
|
|
11715
11725
|
}
|
|
11716
11726
|
});
|
|
11717
|
-
await this.delayRetry(
|
|
11727
|
+
await this.delayRetry(signal);
|
|
11718
11728
|
if (!this.isConnected) {
|
|
11719
11729
|
// Exit the upload loop if the sync stream is no longer connected
|
|
11720
11730
|
break;
|
|
@@ -11729,7 +11739,6 @@ The next upload iteration will be delayed.`);
|
|
|
11729
11739
|
});
|
|
11730
11740
|
}
|
|
11731
11741
|
}
|
|
11732
|
-
this.uploadAbortController = undefined;
|
|
11733
11742
|
}
|
|
11734
11743
|
});
|
|
11735
11744
|
}
|
|
@@ -11739,7 +11748,10 @@ The next upload iteration will be delayed.`);
|
|
|
11739
11748
|
}
|
|
11740
11749
|
const controller = new AbortController();
|
|
11741
11750
|
this.abortController = controller;
|
|
11742
|
-
this.streamingSyncPromise =
|
|
11751
|
+
this.streamingSyncPromise = Promise.all([
|
|
11752
|
+
this.crudUploadLoop(controller.signal).catch((ex) => this.logger.error('Error in crud upload loop', ex)),
|
|
11753
|
+
this.streamingSync(controller.signal, options)
|
|
11754
|
+
]);
|
|
11743
11755
|
// Return a promise that resolves when the connection status is updated to indicate that we're connected.
|
|
11744
11756
|
return new Promise((resolve) => {
|
|
11745
11757
|
const disposer = this.registerListener({
|
|
@@ -11777,14 +11789,7 @@ The next upload iteration will be delayed.`);
|
|
|
11777
11789
|
this.abortController = null;
|
|
11778
11790
|
this.updateSyncStatus({ connected: false, connecting: false });
|
|
11779
11791
|
}
|
|
11780
|
-
/**
|
|
11781
|
-
* @deprecated use [connect instead]
|
|
11782
|
-
*/
|
|
11783
11792
|
async streamingSync(signal, options) {
|
|
11784
|
-
if (!signal) {
|
|
11785
|
-
this.abortController = new AbortController();
|
|
11786
|
-
signal = this.abortController.signal;
|
|
11787
|
-
}
|
|
11788
11793
|
/**
|
|
11789
11794
|
* Listen for CRUD updates and trigger upstream uploads
|
|
11790
11795
|
*/
|
|
@@ -12158,14 +12163,13 @@ The next upload iteration will be delayed.`);
|
|
|
12158
12163
|
// trigger this for all updates
|
|
12159
12164
|
this.iterateListeners((cb) => cb.statusUpdated?.(options));
|
|
12160
12165
|
}
|
|
12161
|
-
async delayRetry(signal) {
|
|
12166
|
+
async delayRetry(signal, delay = this.options.retryDelayMs) {
|
|
12162
12167
|
return new Promise((resolve) => {
|
|
12163
12168
|
if (signal?.aborted) {
|
|
12164
12169
|
// If the signal is already aborted, resolve immediately
|
|
12165
12170
|
resolve();
|
|
12166
12171
|
return;
|
|
12167
12172
|
}
|
|
12168
|
-
const { retryDelayMs } = this.options;
|
|
12169
12173
|
let timeoutId;
|
|
12170
12174
|
const endDelay = () => {
|
|
12171
12175
|
resolve();
|
|
@@ -12176,7 +12180,7 @@ The next upload iteration will be delayed.`);
|
|
|
12176
12180
|
signal?.removeEventListener('abort', endDelay);
|
|
12177
12181
|
};
|
|
12178
12182
|
signal?.addEventListener('abort', endDelay, { once: true });
|
|
12179
|
-
timeoutId = setTimeout(endDelay,
|
|
12183
|
+
timeoutId = setTimeout(endDelay, delay);
|
|
12180
12184
|
});
|
|
12181
12185
|
}
|
|
12182
12186
|
updateSubscriptions(subscriptions) {
|