@abraca/dabra 1.0.17 → 1.0.18
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/abracadabra-provider.cjs +42 -4
- package/dist/abracadabra-provider.cjs.map +1 -1
- package/dist/abracadabra-provider.esm.js +42 -4
- package/dist/abracadabra-provider.esm.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/package.json +1 -1
- package/src/AbracadabraProvider.ts +14 -0
- package/src/BackgroundSyncManager.ts +59 -9
|
@@ -3100,8 +3100,11 @@ var AbracadabraProvider = class AbracadabraProvider extends AbracadabraBaseProvi
|
|
|
3100
3100
|
}
|
|
3101
3101
|
destroy() {
|
|
3102
3102
|
this.document.off("subdocs", this.boundHandleYSubdocsChange);
|
|
3103
|
+
const childIds = [...this.childProviders.keys()];
|
|
3103
3104
|
for (const provider of this.childProviders.values()) provider.destroy();
|
|
3104
3105
|
this.childProviders.clear();
|
|
3106
|
+
const wsProviderMap = this.configuration.websocketProvider?.configuration?.providerMap;
|
|
3107
|
+
if (wsProviderMap) for (const childId of childIds) wsProviderMap.delete(childId);
|
|
3105
3108
|
this.offlineStore?.destroy();
|
|
3106
3109
|
this.offlineStore = null;
|
|
3107
3110
|
super.destroy();
|
|
@@ -8419,7 +8422,9 @@ var BackgroundSyncManager = class extends EventEmitter {
|
|
|
8419
8422
|
this.opts = {
|
|
8420
8423
|
concurrency: opts?.concurrency ?? 2,
|
|
8421
8424
|
syncTimeout: opts?.syncTimeout ?? 15e3,
|
|
8422
|
-
prefetchFiles: opts?.prefetchFiles ?? true
|
|
8425
|
+
prefetchFiles: opts?.prefetchFiles ?? true,
|
|
8426
|
+
throttleMs: opts?.throttleMs ?? 50,
|
|
8427
|
+
maxRetries: opts?.maxRetries ?? 2
|
|
8423
8428
|
};
|
|
8424
8429
|
let serverOrigin = "default";
|
|
8425
8430
|
try {
|
|
@@ -8453,7 +8458,38 @@ var BackgroundSyncManager = class extends EventEmitter {
|
|
|
8453
8458
|
for (const [docId, v] of entries) updatedAtMap.set(docId, v?.updatedAt ?? v?.createdAt ?? 0);
|
|
8454
8459
|
this._prefetchCovers(entries).catch(() => null);
|
|
8455
8460
|
const queue = this._buildQueue(entries);
|
|
8456
|
-
|
|
8461
|
+
const failed = [];
|
|
8462
|
+
let idx = 0;
|
|
8463
|
+
const next = async () => {
|
|
8464
|
+
while (idx < queue.length) {
|
|
8465
|
+
if (this._destroyed) return;
|
|
8466
|
+
const docId = queue[idx++];
|
|
8467
|
+
const updatedAt = updatedAtMap.get(docId) ?? 0;
|
|
8468
|
+
if (!await this._syncWithSemaphore(docId, updatedAt)) failed.push(docId);
|
|
8469
|
+
if (this.opts.throttleMs > 0 && idx < queue.length) await new Promise((r) => setTimeout(r, this.opts.throttleMs));
|
|
8470
|
+
}
|
|
8471
|
+
};
|
|
8472
|
+
const workers = Array.from({ length: this.opts.concurrency }, () => next());
|
|
8473
|
+
await Promise.all(workers);
|
|
8474
|
+
for (let retry = 0; retry < this.opts.maxRetries && failed.length > 0; retry++) {
|
|
8475
|
+
if (this._destroyed) return;
|
|
8476
|
+
const batch = failed.splice(0, failed.length);
|
|
8477
|
+
const backoff = 2e3 * 2 ** retry;
|
|
8478
|
+
await new Promise((r) => setTimeout(r, backoff));
|
|
8479
|
+
idx = 0;
|
|
8480
|
+
const retryQueue = batch;
|
|
8481
|
+
const retryNext = async () => {
|
|
8482
|
+
while (idx < retryQueue.length) {
|
|
8483
|
+
if (this._destroyed) return;
|
|
8484
|
+
const docId = retryQueue[idx++];
|
|
8485
|
+
const updatedAt = updatedAtMap.get(docId) ?? 0;
|
|
8486
|
+
if (!await this._syncWithSemaphore(docId, updatedAt)) failed.push(docId);
|
|
8487
|
+
if (this.opts.throttleMs > 0 && idx < retryQueue.length) await new Promise((r) => setTimeout(r, this.opts.throttleMs));
|
|
8488
|
+
}
|
|
8489
|
+
};
|
|
8490
|
+
const retryWorkers = Array.from({ length: this.opts.concurrency }, () => retryNext());
|
|
8491
|
+
await Promise.all(retryWorkers);
|
|
8492
|
+
}
|
|
8457
8493
|
}
|
|
8458
8494
|
/** Sync a single document by ID. */
|
|
8459
8495
|
async syncDoc(docId) {
|
|
@@ -8534,15 +8570,16 @@ var BackgroundSyncManager = class extends EventEmitter {
|
|
|
8534
8570
|
items.sort((a, b) => b.priority - a.priority);
|
|
8535
8571
|
return items.map((i) => i.docId);
|
|
8536
8572
|
}
|
|
8573
|
+
/** Returns true on success (or skip), false on error. */
|
|
8537
8574
|
async _syncWithSemaphore(docId, updatedAt) {
|
|
8538
|
-
if (this._destroyed) return;
|
|
8575
|
+
if (this._destroyed) return true;
|
|
8539
8576
|
const existing = this.syncStates.get(docId);
|
|
8540
8577
|
if (existing && existing.status === "synced" && existing.lastSynced !== null && existing.lastSynced >= updatedAt) {
|
|
8541
8578
|
this.emit("stateChanged", {
|
|
8542
8579
|
docId,
|
|
8543
8580
|
state: existing
|
|
8544
8581
|
});
|
|
8545
|
-
return;
|
|
8582
|
+
return true;
|
|
8546
8583
|
}
|
|
8547
8584
|
await this.semaphore.acquire();
|
|
8548
8585
|
try {
|
|
@@ -8553,6 +8590,7 @@ var BackgroundSyncManager = class extends EventEmitter {
|
|
|
8553
8590
|
docId,
|
|
8554
8591
|
state
|
|
8555
8592
|
});
|
|
8593
|
+
return state.status !== "error";
|
|
8556
8594
|
} finally {
|
|
8557
8595
|
this.semaphore.release();
|
|
8558
8596
|
}
|