@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
|
@@ -3070,8 +3070,11 @@ var AbracadabraProvider = class AbracadabraProvider extends AbracadabraBaseProvi
|
|
|
3070
3070
|
}
|
|
3071
3071
|
destroy() {
|
|
3072
3072
|
this.document.off("subdocs", this.boundHandleYSubdocsChange);
|
|
3073
|
+
const childIds = [...this.childProviders.keys()];
|
|
3073
3074
|
for (const provider of this.childProviders.values()) provider.destroy();
|
|
3074
3075
|
this.childProviders.clear();
|
|
3076
|
+
const wsProviderMap = this.configuration.websocketProvider?.configuration?.providerMap;
|
|
3077
|
+
if (wsProviderMap) for (const childId of childIds) wsProviderMap.delete(childId);
|
|
3075
3078
|
this.offlineStore?.destroy();
|
|
3076
3079
|
this.offlineStore = null;
|
|
3077
3080
|
super.destroy();
|
|
@@ -8367,7 +8370,9 @@ var BackgroundSyncManager = class extends EventEmitter {
|
|
|
8367
8370
|
this.opts = {
|
|
8368
8371
|
concurrency: opts?.concurrency ?? 2,
|
|
8369
8372
|
syncTimeout: opts?.syncTimeout ?? 15e3,
|
|
8370
|
-
prefetchFiles: opts?.prefetchFiles ?? true
|
|
8373
|
+
prefetchFiles: opts?.prefetchFiles ?? true,
|
|
8374
|
+
throttleMs: opts?.throttleMs ?? 50,
|
|
8375
|
+
maxRetries: opts?.maxRetries ?? 2
|
|
8371
8376
|
};
|
|
8372
8377
|
let serverOrigin = "default";
|
|
8373
8378
|
try {
|
|
@@ -8401,7 +8406,38 @@ var BackgroundSyncManager = class extends EventEmitter {
|
|
|
8401
8406
|
for (const [docId, v] of entries) updatedAtMap.set(docId, v?.updatedAt ?? v?.createdAt ?? 0);
|
|
8402
8407
|
this._prefetchCovers(entries).catch(() => null);
|
|
8403
8408
|
const queue = this._buildQueue(entries);
|
|
8404
|
-
|
|
8409
|
+
const failed = [];
|
|
8410
|
+
let idx = 0;
|
|
8411
|
+
const next = async () => {
|
|
8412
|
+
while (idx < queue.length) {
|
|
8413
|
+
if (this._destroyed) return;
|
|
8414
|
+
const docId = queue[idx++];
|
|
8415
|
+
const updatedAt = updatedAtMap.get(docId) ?? 0;
|
|
8416
|
+
if (!await this._syncWithSemaphore(docId, updatedAt)) failed.push(docId);
|
|
8417
|
+
if (this.opts.throttleMs > 0 && idx < queue.length) await new Promise((r) => setTimeout(r, this.opts.throttleMs));
|
|
8418
|
+
}
|
|
8419
|
+
};
|
|
8420
|
+
const workers = Array.from({ length: this.opts.concurrency }, () => next());
|
|
8421
|
+
await Promise.all(workers);
|
|
8422
|
+
for (let retry = 0; retry < this.opts.maxRetries && failed.length > 0; retry++) {
|
|
8423
|
+
if (this._destroyed) return;
|
|
8424
|
+
const batch = failed.splice(0, failed.length);
|
|
8425
|
+
const backoff = 2e3 * 2 ** retry;
|
|
8426
|
+
await new Promise((r) => setTimeout(r, backoff));
|
|
8427
|
+
idx = 0;
|
|
8428
|
+
const retryQueue = batch;
|
|
8429
|
+
const retryNext = async () => {
|
|
8430
|
+
while (idx < retryQueue.length) {
|
|
8431
|
+
if (this._destroyed) return;
|
|
8432
|
+
const docId = retryQueue[idx++];
|
|
8433
|
+
const updatedAt = updatedAtMap.get(docId) ?? 0;
|
|
8434
|
+
if (!await this._syncWithSemaphore(docId, updatedAt)) failed.push(docId);
|
|
8435
|
+
if (this.opts.throttleMs > 0 && idx < retryQueue.length) await new Promise((r) => setTimeout(r, this.opts.throttleMs));
|
|
8436
|
+
}
|
|
8437
|
+
};
|
|
8438
|
+
const retryWorkers = Array.from({ length: this.opts.concurrency }, () => retryNext());
|
|
8439
|
+
await Promise.all(retryWorkers);
|
|
8440
|
+
}
|
|
8405
8441
|
}
|
|
8406
8442
|
/** Sync a single document by ID. */
|
|
8407
8443
|
async syncDoc(docId) {
|
|
@@ -8482,15 +8518,16 @@ var BackgroundSyncManager = class extends EventEmitter {
|
|
|
8482
8518
|
items.sort((a, b) => b.priority - a.priority);
|
|
8483
8519
|
return items.map((i) => i.docId);
|
|
8484
8520
|
}
|
|
8521
|
+
/** Returns true on success (or skip), false on error. */
|
|
8485
8522
|
async _syncWithSemaphore(docId, updatedAt) {
|
|
8486
|
-
if (this._destroyed) return;
|
|
8523
|
+
if (this._destroyed) return true;
|
|
8487
8524
|
const existing = this.syncStates.get(docId);
|
|
8488
8525
|
if (existing && existing.status === "synced" && existing.lastSynced !== null && existing.lastSynced >= updatedAt) {
|
|
8489
8526
|
this.emit("stateChanged", {
|
|
8490
8527
|
docId,
|
|
8491
8528
|
state: existing
|
|
8492
8529
|
});
|
|
8493
|
-
return;
|
|
8530
|
+
return true;
|
|
8494
8531
|
}
|
|
8495
8532
|
await this.semaphore.acquire();
|
|
8496
8533
|
try {
|
|
@@ -8501,6 +8538,7 @@ var BackgroundSyncManager = class extends EventEmitter {
|
|
|
8501
8538
|
docId,
|
|
8502
8539
|
state
|
|
8503
8540
|
});
|
|
8541
|
+
return state.status !== "error";
|
|
8504
8542
|
} finally {
|
|
8505
8543
|
this.semaphore.release();
|
|
8506
8544
|
}
|