@tinycloud/replica 0.4.0-beta.1 → 0.4.0-beta.3
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/index.cjs +27 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +27 -2
- package/dist/index.js.map +1 -1
- package/dist/kv-storage.js +3 -2
- package/dist/kv-storage.js.map +1 -1
- package/dist/{kv-storage.worker.f2ee4476484924b91a94e0f97d77023eca43ed50cb532a0488bafbe68ae591bd.js → kv-storage.worker.71bb85eb4c4d49cbcf82e84da665129c8fcd8585768360ebba434003f650dd20.js} +28 -2
- package/dist/kv-storage.worker.js +28 -2
- package/dist/kv-storage.worker.js.map +1 -1
- package/dist/replica.worker.js +27 -2
- package/dist/replica.worker.js.map +1 -1
- package/package.json +2 -2
package/dist/replica.worker.js
CHANGED
|
@@ -6362,6 +6362,8 @@ var DEFAULT_PAGE_LIMIT = 500;
|
|
|
6362
6362
|
var DEFAULT_LEASE_TTL_MS = 12e4;
|
|
6363
6363
|
var FETCH_CHUNK = 100;
|
|
6364
6364
|
var REPAIR_BATCH = 100;
|
|
6365
|
+
var REPAIR_MAX_TRIES = 5;
|
|
6366
|
+
var REPAIR_BACKOFF_BASE_MS = 6e4;
|
|
6365
6367
|
var RETENTION_REVOKED = /* @__PURE__ */ new Set(["retention-grant-revoked", "retention-grant-ancestor-revoked"]);
|
|
6366
6368
|
var PENDING_REFUSALS = /* @__PURE__ */ new Set([
|
|
6367
6369
|
ReplicaErrorCode.GRANT_UNAUTHORIZED,
|
|
@@ -6371,6 +6373,9 @@ var PENDING_REFUSALS = /* @__PURE__ */ new Set([
|
|
|
6371
6373
|
function contentHash(bytes) {
|
|
6372
6374
|
return bytesToHex(blake3(bytes));
|
|
6373
6375
|
}
|
|
6376
|
+
function repairId(entry) {
|
|
6377
|
+
return `${entry.hash}\0${entry.key}`;
|
|
6378
|
+
}
|
|
6374
6379
|
function sameEtag(a, b) {
|
|
6375
6380
|
return a.replace(/^"|"$/g, "") === b.replace(/^"|"$/g, "");
|
|
6376
6381
|
}
|
|
@@ -6387,6 +6392,9 @@ var Replica = class {
|
|
|
6387
6392
|
#now;
|
|
6388
6393
|
#leaseTtlMs;
|
|
6389
6394
|
#onCommit;
|
|
6395
|
+
#contentFetch;
|
|
6396
|
+
/** Failed repair fetches of this session, by key and ETag hash. Never persisted: a new `Replica` retries afresh. */
|
|
6397
|
+
#repairTries = /* @__PURE__ */ new Map();
|
|
6390
6398
|
constructor(options) {
|
|
6391
6399
|
this.#store = options.store;
|
|
6392
6400
|
const transport = options.transport;
|
|
@@ -6394,6 +6402,7 @@ var Replica = class {
|
|
|
6394
6402
|
this.#now = options.now ?? Date.now;
|
|
6395
6403
|
this.#leaseTtlMs = options.leaseTtlMs ?? DEFAULT_LEASE_TTL_MS;
|
|
6396
6404
|
this.#onCommit = options.onCommit;
|
|
6405
|
+
this.#contentFetch = options.contentFetch ?? "eager";
|
|
6397
6406
|
}
|
|
6398
6407
|
async #state() {
|
|
6399
6408
|
const state = await this.#store.open();
|
|
@@ -6722,6 +6731,7 @@ var Replica = class {
|
|
|
6722
6731
|
changes[candidate.index].content = true;
|
|
6723
6732
|
return false;
|
|
6724
6733
|
});
|
|
6734
|
+
if (this.#contentFetch === "lazy") return { changes, blobs, fetched: 0 };
|
|
6725
6735
|
let fetched2 = 0;
|
|
6726
6736
|
for (let start = 0; start < needed.length; start += FETCH_CHUNK) {
|
|
6727
6737
|
const chunk = needed.slice(start, start + FETCH_CHUNK);
|
|
@@ -6741,7 +6751,15 @@ var Replica = class {
|
|
|
6741
6751
|
return { changes, blobs, fetched: fetched2 };
|
|
6742
6752
|
}
|
|
6743
6753
|
async #repair(attempt, cursor, nodeDid, coverage, retentionGrantCid) {
|
|
6744
|
-
|
|
6754
|
+
if (this.#contentFetch === "lazy") return 0;
|
|
6755
|
+
const all = await this.#store.pendingRepairs(Number.MAX_SAFE_INTEGER);
|
|
6756
|
+
const now = this.#now();
|
|
6757
|
+
const pendingIds = new Set(all.map((entry) => repairId(entry)));
|
|
6758
|
+
for (const id of this.#repairTries.keys()) if (!pendingIds.has(id)) this.#repairTries.delete(id);
|
|
6759
|
+
const pending = all.filter((entry) => {
|
|
6760
|
+
const state = this.#repairTries.get(repairId(entry));
|
|
6761
|
+
return state === void 0 || state.tries < REPAIR_MAX_TRIES && now >= state.nextAttemptAt;
|
|
6762
|
+
});
|
|
6745
6763
|
let repaired = 0;
|
|
6746
6764
|
for (let start = 0; start < pending.length; start += REPAIR_BATCH) {
|
|
6747
6765
|
const chunk = pending.slice(start, start + REPAIR_BATCH);
|
|
@@ -6753,7 +6771,14 @@ var Replica = class {
|
|
|
6753
6771
|
const changes = [];
|
|
6754
6772
|
for (const entry of chunk) {
|
|
6755
6773
|
const bytes = acceptContent(entry, contents.get(entry.key));
|
|
6756
|
-
|
|
6774
|
+
const id = repairId(entry);
|
|
6775
|
+
if (bytes === void 0) {
|
|
6776
|
+
const tries = (this.#repairTries.get(id)?.tries ?? 0) + 1;
|
|
6777
|
+
const wait = tries === 1 ? 0 : REPAIR_BACKOFF_BASE_MS * 2 ** (tries - 2);
|
|
6778
|
+
this.#repairTries.set(id, { tries, nextAttemptAt: this.#now() + wait });
|
|
6779
|
+
continue;
|
|
6780
|
+
}
|
|
6781
|
+
this.#repairTries.delete(id);
|
|
6757
6782
|
blobs.set(entry.hash, bytes);
|
|
6758
6783
|
changes.push({ ...entry, content: true });
|
|
6759
6784
|
}
|