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