@opendatalabs/personal-server-ts-core 1.35.1 → 1.35.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.
Files changed (45) hide show
  1. package/dist/additions/budget.d.ts +6 -0
  2. package/dist/additions/budget.d.ts.map +1 -1
  3. package/dist/additions/budget.js +25 -0
  4. package/dist/additions/budget.js.map +1 -1
  5. package/dist/additions/durable.d.ts +1 -1
  6. package/dist/additions/durable.d.ts.map +1 -1
  7. package/dist/additions/durable.js +102 -19
  8. package/dist/additions/durable.js.map +1 -1
  9. package/dist/additions/version-inventory.d.ts +2 -0
  10. package/dist/additions/version-inventory.d.ts.map +1 -1
  11. package/dist/additions/version-inventory.js +2 -0
  12. package/dist/additions/version-inventory.js.map +1 -1
  13. package/dist/ports/index.d.ts +79 -1
  14. package/dist/ports/index.d.ts.map +1 -1
  15. package/dist/ports/index.js.map +1 -1
  16. package/dist/sync/delete-data-port.d.ts +2 -0
  17. package/dist/sync/delete-data-port.d.ts.map +1 -1
  18. package/dist/sync/delete-data-port.js +22 -1
  19. package/dist/sync/delete-data-port.js.map +1 -1
  20. package/dist/sync/engine/sync-manager.d.ts +6 -1
  21. package/dist/sync/engine/sync-manager.d.ts.map +1 -1
  22. package/dist/sync/engine/sync-manager.js +62 -9
  23. package/dist/sync/engine/sync-manager.js.map +1 -1
  24. package/dist/sync/index.d.ts +1 -0
  25. package/dist/sync/index.d.ts.map +1 -1
  26. package/dist/sync/index.js +1 -0
  27. package/dist/sync/index.js.map +1 -1
  28. package/dist/sync/pending-blob-deletions.d.ts.map +1 -1
  29. package/dist/sync/pending-blob-deletions.js +28 -0
  30. package/dist/sync/pending-blob-deletions.js.map +1 -1
  31. package/dist/sync/tombstone-finality.d.ts +36 -0
  32. package/dist/sync/tombstone-finality.d.ts.map +1 -0
  33. package/dist/sync/tombstone-finality.js +142 -0
  34. package/dist/sync/tombstone-finality.js.map +1 -0
  35. package/dist/sync/tombstone-resubmits.d.ts +61 -0
  36. package/dist/sync/tombstone-resubmits.d.ts.map +1 -0
  37. package/dist/sync/tombstone-resubmits.js +85 -0
  38. package/dist/sync/tombstone-resubmits.js.map +1 -0
  39. package/dist/sync/types.d.ts +8 -0
  40. package/dist/sync/types.d.ts.map +1 -1
  41. package/dist/sync/workers/delete.d.ts +54 -5
  42. package/dist/sync/workers/delete.d.ts.map +1 -1
  43. package/dist/sync/workers/delete.js +278 -44
  44. package/dist/sync/workers/delete.js.map +1 -1
  45. package/package.json +1 -1
@@ -0,0 +1,142 @@
1
+ import { isTombstoneRecord } from "./tombstone.js";
2
+ const PAGE_LIMIT = 1000;
3
+ const MAX_PAGES = 20;
4
+ const SETTLED = new Set(["finalized", "failed"]);
5
+ /**
6
+ * Tombstone finality read from the gateway's version inventory
7
+ * (`GET /v1/data/:id/versions`, owner or registered-server signed).
8
+ *
9
+ * Only `finalized` counts. The gateway moves a data version
10
+ * pending → submitting → confirmed → finalized, and can still push a
11
+ * `confirmed` version back to `pending` on a reorg
12
+ * (data-gateway `reconcileConfirmedDataPoints`); until a tombstone is
13
+ * finalized its settlement can fail, the gateway rolls the head back, and
14
+ * a writer may recover the failed slot.
15
+ *
16
+ * While a tombstone at or above the asked version is settling, every call
17
+ * reads the inventory, so a sync cycle sees finality on its next pass. The
18
+ * route has no rate limit; a call costs one signed read of at most
19
+ * `MAX_PAGES` pages.
20
+ *
21
+ * When nothing is settling and nothing is finalized (a scope that was never
22
+ * registered, a rolled-back tombstone, a newer write above it), the scope is
23
+ * not read again until its recheck time, which doubles from `minRecheckMs`
24
+ * up to `maxRecheckMs`. Such keys may never become free, so they cost a few
25
+ * reads an hour, not one per sync cycle. `recheckNow` drops the wait when a
26
+ * new tombstone is queued. The backoff only delays a deletion, never brings
27
+ * one forward.
28
+ */
29
+ export function createInventoryTombstoneFinality(inventory, options = {}) {
30
+ const now = options.now ?? Date.now;
31
+ const minRecheck = options.minRecheckMs ?? 60_000;
32
+ const maxRecheck = options.maxRecheckMs ?? 15 * 60_000;
33
+ const recheck = new Map();
34
+ const idle = {
35
+ finalized: null,
36
+ settling: false,
37
+ rolledBack: null,
38
+ };
39
+ async function read(scope, from) {
40
+ let after = (from > 0n ? from - 1n : 0n).toString();
41
+ let finalized = null;
42
+ let settling = false;
43
+ // The highest listed row at or above `from`, and the head as of the last
44
+ // page (each page is its own snapshot; the last one is the newest).
45
+ let top = null;
46
+ let head = null;
47
+ let complete = false;
48
+ for (let count = 0; count < MAX_PAGES; count++) {
49
+ const result = await inventory.page(scope, { after, limit: PAGE_LIMIT });
50
+ head = result.data.head ?? null;
51
+ for (const version of result.data.versions) {
52
+ const value = BigInt(version.expectedVersion);
53
+ if (value < from)
54
+ continue;
55
+ if (top === null || value > top.version) {
56
+ top = {
57
+ version: value,
58
+ failedTombstone: version.isTombstone && version.status === "failed",
59
+ };
60
+ }
61
+ if (!version.isTombstone)
62
+ continue;
63
+ if (version.status === "finalized") {
64
+ if (finalized === null || value > finalized)
65
+ finalized = value;
66
+ }
67
+ else if (!SETTLED.has(version.status)) {
68
+ settling = true;
69
+ }
70
+ }
71
+ if (!result.pagination.hasMore) {
72
+ complete = true;
73
+ break;
74
+ }
75
+ const next = result.pagination.nextAfter;
76
+ if (next === null)
77
+ break;
78
+ after = next;
79
+ }
80
+ // The head counts as a tombstone row too: a re-submitted delete can take
81
+ // a slot below the asked version (the gateway rolls back to the latest
82
+ // non-failed row, which may sit below a failed data row), and its
83
+ // finality frees the keys at or below it.
84
+ if (head !== null && (head.deletedAt !== null || isTombstoneRecord(head))) {
85
+ const value = BigInt(head.expectedVersion);
86
+ if (head.status === "finalized") {
87
+ if (finalized === null || value > finalized)
88
+ finalized = value;
89
+ }
90
+ else if (!SETTLED.has(head.status)) {
91
+ settling = true;
92
+ }
93
+ }
94
+ // An unfinished traversal can only under-report: keys wait longer, and
95
+ // it never reports a rollback it did not see to the end.
96
+ let rolledBack = null;
97
+ if (complete && !settling && top?.failedTombstone) {
98
+ const restored = head !== null &&
99
+ head.deletedAt === null &&
100
+ !isTombstoneRecord(head) &&
101
+ BigInt(head.expectedVersion) < top.version
102
+ ? head
103
+ : null;
104
+ if (restored) {
105
+ rolledBack = {
106
+ tombstoneVersion: top.version.toString(),
107
+ head: {
108
+ expectedVersion: restored.expectedVersion,
109
+ dataHash: restored.dataHash,
110
+ metadataHash: restored.metadataHash,
111
+ },
112
+ };
113
+ }
114
+ }
115
+ return {
116
+ finalized: finalized === null ? null : finalized.toString(),
117
+ settling,
118
+ rolledBack,
119
+ };
120
+ }
121
+ return {
122
+ async tombstoneState(scope, atOrAbove) {
123
+ const waiting = recheck.get(scope);
124
+ if (waiting && now() < waiting.at)
125
+ return idle;
126
+ const state = await read(scope, BigInt(atOrAbove));
127
+ if (state.finalized !== null || state.settling) {
128
+ recheck.delete(scope);
129
+ return state;
130
+ }
131
+ const interval = waiting
132
+ ? Math.min(waiting.interval * 2, maxRecheck)
133
+ : minRecheck;
134
+ recheck.set(scope, { at: now() + interval, interval });
135
+ return state;
136
+ },
137
+ recheckNow(scope) {
138
+ recheck.delete(scope);
139
+ },
140
+ };
141
+ }
142
+ //# sourceMappingURL=tombstone-finality.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tombstone-finality.js","sourceRoot":"","sources":["../../src/sync/tombstone-finality.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Bounded re-submission of a user's delete whose gateway tombstone failed.
3
+ *
4
+ * A tombstone the gateway queued can fail to settle. The gateway then rolls
5
+ * the head back and reports the scope live again, though the user asked to
6
+ * delete it. The retry pass re-submits the delete through the ordinary delete
7
+ * path; this tracker bounds how often. Attempt n waits
8
+ * `baseDelayMs * 2^(n-2)` after attempt n-1 (the first runs at once), and
9
+ * after `maxAttempts` failed re-submissions the scope is reported as failed
10
+ * and left alone until the user deletes it again.
11
+ *
12
+ * In memory per sync manager: a restart starts the count again, so the bound
13
+ * is per boot.
14
+ */
15
+ export interface TombstoneResubmitState {
16
+ scope: string;
17
+ /** Re-submissions made so far (the user's own delete is not counted). */
18
+ attempts: number;
19
+ /** The failed tombstone version last seen for the scope. */
20
+ tombstoneVersion: string;
21
+ /** ISO time of the last re-submission. */
22
+ lastAttemptAt: string;
23
+ /**
24
+ * Why the delete stopped (failed entries only): every attempt failed, or
25
+ * the gateway restored a head other than the one the delete replaced, so
26
+ * it is not re-submitted automatically.
27
+ */
28
+ reason?: TombstoneResubmitFailure;
29
+ }
30
+ export type TombstoneResubmitFailure = "attempts-exhausted" | "head-changed";
31
+ export interface TombstoneResubmitSnapshot {
32
+ /** Scopes with a re-submission in progress or due. */
33
+ retrying: TombstoneResubmitState[];
34
+ /** Scopes whose delete did not complete after the last allowed attempt. */
35
+ failed: Array<TombstoneResubmitState & {
36
+ failedAt: string;
37
+ }>;
38
+ }
39
+ export interface TombstoneResubmitTracker {
40
+ /** Whether another re-submission is allowed now. */
41
+ due(scope: string): boolean;
42
+ /** True once the scope has used every attempt and been reported. */
43
+ exhausted(scope: string): boolean;
44
+ /** True when the scope has used every attempt but is not reported yet. */
45
+ outOfAttempts(scope: string): boolean;
46
+ /** Count one re-submission; returns the attempt number. */
47
+ recordAttempt(scope: string, tombstoneVersion: string): number;
48
+ /** Report the scope as failed (the default reason: attempts exhausted). */
49
+ giveUp(scope: string, tombstoneVersion: string, reason?: TombstoneResubmitFailure): TombstoneResubmitState;
50
+ /** Forget the scope: the delete converged, or the user deleted it again. */
51
+ reset(scope: string): void;
52
+ snapshot(): TombstoneResubmitSnapshot;
53
+ }
54
+ export declare const DEFAULT_TOMBSTONE_RESUBMIT_MAX_ATTEMPTS = 5;
55
+ export declare const DEFAULT_TOMBSTONE_RESUBMIT_BASE_DELAY_MS = 60000;
56
+ export declare function createTombstoneResubmitTracker(options?: {
57
+ maxAttempts?: number;
58
+ baseDelayMs?: number;
59
+ now?: () => number;
60
+ }): TombstoneResubmitTracker;
61
+ //# sourceMappingURL=tombstone-resubmits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tombstone-resubmits.d.ts","sourceRoot":"","sources":["../../src/sync/tombstone-resubmits.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,QAAQ,EAAE,MAAM,CAAC;IACjB,4DAA4D;IAC5D,gBAAgB,EAAE,MAAM,CAAC;IACzB,0CAA0C;IAC1C,aAAa,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,MAAM,CAAC,EAAE,wBAAwB,CAAC;CACnC;AAED,MAAM,MAAM,wBAAwB,GAAG,oBAAoB,GAAG,cAAc,CAAC;AAE7E,MAAM,WAAW,yBAAyB;IACxC,sDAAsD;IACtD,QAAQ,EAAE,sBAAsB,EAAE,CAAC;IACnC,2EAA2E;IAC3E,MAAM,EAAE,KAAK,CAAC,sBAAsB,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC9D;AAED,MAAM,WAAW,wBAAwB;IACvC,oDAAoD;IACpD,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5B,oEAAoE;IACpE,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC,0EAA0E;IAC1E,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IACtC,2DAA2D;IAC3D,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/D,2EAA2E;IAC3E,MAAM,CACJ,KAAK,EAAE,MAAM,EACb,gBAAgB,EAAE,MAAM,EACxB,MAAM,CAAC,EAAE,wBAAwB,GAChC,sBAAsB,CAAC;IAC1B,4EAA4E;IAC5E,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,IAAI,yBAAyB,CAAC;CACvC;AAED,eAAO,MAAM,uCAAuC,IAAI,CAAC;AACzD,eAAO,MAAM,wCAAwC,QAAS,CAAC;AAE/D,wBAAgB,8BAA8B,CAC5C,OAAO,GAAE;IACP,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACf,GACL,wBAAwB,CA8F1B"}
@@ -0,0 +1,85 @@
1
+ export const DEFAULT_TOMBSTONE_RESUBMIT_MAX_ATTEMPTS = 5;
2
+ export const DEFAULT_TOMBSTONE_RESUBMIT_BASE_DELAY_MS = 60_000;
3
+ export function createTombstoneResubmitTracker(options = {}) {
4
+ const maxAttempts = options.maxAttempts ?? DEFAULT_TOMBSTONE_RESUBMIT_MAX_ATTEMPTS;
5
+ const baseDelayMs = options.baseDelayMs ?? DEFAULT_TOMBSTONE_RESUBMIT_BASE_DELAY_MS;
6
+ const now = options.now ?? Date.now;
7
+ const states = new Map();
8
+ const view = (scope) => {
9
+ const state = states.get(scope);
10
+ return state
11
+ ? {
12
+ scope,
13
+ attempts: state.attempts,
14
+ tombstoneVersion: state.tombstoneVersion,
15
+ lastAttemptAt: new Date(state.lastAttemptMs).toISOString(),
16
+ ...(state.reason ? { reason: state.reason } : {}),
17
+ }
18
+ : null;
19
+ };
20
+ return {
21
+ due(scope) {
22
+ const state = states.get(scope);
23
+ if (!state)
24
+ return true;
25
+ if (state.failedAtMs !== null || state.attempts >= maxAttempts)
26
+ return false;
27
+ const wait = baseDelayMs * 2 ** (state.attempts - 1);
28
+ return now() - state.lastAttemptMs >= wait;
29
+ },
30
+ exhausted(scope) {
31
+ return states.get(scope)?.failedAtMs != null;
32
+ },
33
+ outOfAttempts(scope) {
34
+ const state = states.get(scope);
35
+ return (state !== undefined &&
36
+ state.failedAtMs === null &&
37
+ state.attempts >= maxAttempts);
38
+ },
39
+ recordAttempt(scope, tombstoneVersion) {
40
+ const state = states.get(scope);
41
+ const attempts = (state?.attempts ?? 0) + 1;
42
+ states.set(scope, {
43
+ attempts,
44
+ tombstoneVersion,
45
+ lastAttemptMs: now(),
46
+ failedAtMs: null,
47
+ });
48
+ return attempts;
49
+ },
50
+ giveUp(scope, tombstoneVersion, reason = "attempts-exhausted") {
51
+ const state = states.get(scope) ?? {
52
+ attempts: 0,
53
+ tombstoneVersion,
54
+ lastAttemptMs: now(),
55
+ failedAtMs: null,
56
+ };
57
+ states.set(scope, {
58
+ ...state,
59
+ tombstoneVersion,
60
+ failedAtMs: now(),
61
+ reason,
62
+ });
63
+ return view(scope);
64
+ },
65
+ reset(scope) {
66
+ states.delete(scope);
67
+ },
68
+ snapshot() {
69
+ const retrying = [];
70
+ const failed = [];
71
+ for (const [scope, state] of states) {
72
+ const entry = view(scope);
73
+ if (state.failedAtMs === null)
74
+ retrying.push(entry);
75
+ else
76
+ failed.push({
77
+ ...entry,
78
+ failedAt: new Date(state.failedAtMs).toISOString(),
79
+ });
80
+ }
81
+ return { retrying, failed };
82
+ },
83
+ };
84
+ }
85
+ //# sourceMappingURL=tombstone-resubmits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tombstone-resubmits.js","sourceRoot":"","sources":["../../src/sync/tombstone-resubmits.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import type { TombstoneResubmitSnapshot } from "./tombstone-resubmits.js";
1
2
  /** Sync engine status for GET /v1/sync/status */
2
3
  export interface SyncStatus {
3
4
  enabled: boolean;
@@ -13,6 +14,13 @@ export interface SyncStatus {
13
14
  /** Exact scopes hydrated independently of the registry cursor. */
14
15
  hydratedScopes: string[];
15
16
  errors: SyncError[];
17
+ /**
18
+ * Deletes whose gateway tombstone failed and rolled back (the data is live
19
+ * again). `retrying`: re-submitted automatically, a new tombstone is due or
20
+ * settling. `failed`: every allowed re-submission failed; the user must
21
+ * delete the scope again. Both lists are empty when nothing is owed.
22
+ */
23
+ deletions?: TombstoneResubmitSnapshot;
16
24
  }
17
25
  export interface SyncBlockedReason {
18
26
  reason: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sync/types.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,+CAA+C;IAC/C,OAAO,EAAE,OAAO,CAAC;IACjB,mEAAmE;IACnE,OAAO,EAAE,OAAO,CAAC;IACjB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACnC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,SAAS,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sync/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAC1E,iDAAiD;AACjD,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,+CAA+C;IAC/C,OAAO,EAAE,OAAO,CAAC;IACjB,mEAAmE;IACnE,OAAO,EAAE,OAAO,CAAC;IACjB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACnC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,yBAAyB,CAAC;CACvC;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB"}
@@ -1,5 +1,6 @@
1
1
  import type { Logger } from "../../logger/index.js";
2
- import type { DataPointFeedPort, DataStoragePort, DeleteDataPort, PendingBlobDeletion, PendingBlobDeletionStore } from "../../ports/index.js";
2
+ import type { DataPointFeedPort, DataStoragePort, DeleteDataPort, PendingBlobDeletion, PendingBlobDeletionStore, TombstoneFence, TombstoneFinalityPort } from "../../ports/index.js";
3
+ import { type TombstoneResubmitState, type TombstoneResubmitTracker } from "../tombstone-resubmits.js";
3
4
  import { type ScopeDeletionTracker } from "../scope-deletions.js";
4
5
  /**
5
6
  * Exact blob deletes sent per pass. vana-storage allows 30 DELETE requests
@@ -32,6 +33,15 @@ export interface DeleteScopeDeps {
32
33
  * expand a marker whose tombstone version was not known.
33
34
  */
34
35
  dataPointFeed?: DataPointFeedPort;
36
+ /**
37
+ * When set, a covered storage key is deleted only once a tombstone at or
38
+ * above the one that covers it is finalized at the gateway, never on the
39
+ * tombstone's queue acknowledgement. Until then settlement can fail, the
40
+ * gateway rolls the head back, and a writer may recover the failed slot: a
41
+ * key freed earlier could take another writer's bytes under that slot.
42
+ * Without it keys are deleted as soon as the tombstone is acknowledged.
43
+ */
44
+ tombstoneFinality?: TombstoneFinalityPort;
35
45
  logger: Logger;
36
46
  now?: () => Date;
37
47
  }
@@ -125,13 +135,37 @@ export declare function planBlobDeletions(storage: Pick<DataStoragePort, "listVe
125
135
  * markers; step 3 does not wait for them because the tombstone already makes
126
136
  * the deletion stick.
127
137
  *
138
+ * With `tombstoneFinality` wired, step 2 queues every covered key and sends
139
+ * only keys whose covering tombstone the gateway reports as finalized. The
140
+ * gateway acknowledges a tombstone when it queues it; settlement can still
141
+ * fail, roll the head back and let a writer recover the failed slot with the
142
+ * ciphertext it uploaded there. A key freed before finality could take a
143
+ * second writer's bytes, and the recovered registration would then commit to
144
+ * bytes that are not stored. Reads refuse the scope from step 1 on, so the
145
+ * wait only keeps owner-encrypted ciphertext in storage until finality.
146
+ *
128
147
  * Not serialised here: the sync manager runs this under the same lock as its
129
148
  * upload/download cycles so a delete cannot interleave with an upload of the
130
149
  * same scope on this replica (see engine/sync-manager.ts). Uploads racing on
131
150
  * another replica are handled by the upload worker's deletion guard and the
132
151
  * download worker's reconcile.
133
152
  */
134
- export declare function deleteScope(deps: DeleteScopeDeps, scope: string): Promise<DeleteScopeResult>;
153
+ export interface DeleteScopeOptions {
154
+ /**
155
+ * Automatic re-submission of a rolled-back delete: the tombstone is queued
156
+ * only over exactly this head (the one the failed tombstone replaced), so a
157
+ * write that landed after the rollback is never deleted.
158
+ */
159
+ fence?: {
160
+ head: TombstoneFence;
161
+ };
162
+ /**
163
+ * False records the storage work but sends no batch in this call; the
164
+ * caller's own pass already used this cycle's storage budget.
165
+ */
166
+ storagePass?: boolean;
167
+ }
168
+ export declare function deleteScope(deps: DeleteScopeDeps, scope: string, options?: DeleteScopeOptions): Promise<DeleteScopeResult>;
135
169
  export interface RetryPendingBlobDeletionsResult {
136
170
  /** Exact keys finished this pass (deleted, or already absent). */
137
171
  completed: PendingBlobDeletion[];
@@ -154,10 +188,25 @@ export interface RetryPendingBlobDeletionsResult {
154
188
  * are expanded from the registry first; if the registry shows the scope live
155
189
  * again the old tombstone's version is unknowable, so the marker is dropped
156
190
  * and the pre-tombstone ciphertext stays (owner-decryptable only) until the
157
- * next delete of that scope.
191
+ * next delete of that scope. With `tombstoneFinality` wired, a key is sent
192
+ * only once a tombstone at or above its gate is finalized; a failed
193
+ * tombstone's keys stay queued (the deletion did not happen) until a later
194
+ * deletion of the scope is finalized.
158
195
  */
159
- export declare function retryPendingBlobDeletions(deps: Pick<DeleteScopeDeps, "deleteData" | "pendingBlobDeletions" | "dataPointFeed" | "serverOwner" | "logger"> & {
196
+ export declare const TOMBSTONE_RESUBMIT_MAX_ATTEMPTS = 5;
197
+ export type RetryPendingBlobDeletionsDeps = Pick<DeleteScopeDeps, "deleteData" | "pendingBlobDeletions" | "dataPointFeed" | "serverOwner" | "tombstoneFinality" | "logger"> & {
160
198
  /** Local index, for expanding unexpanded markers into exact keys. */
161
199
  storage?: Pick<DataStoragePort, "listVersions">;
162
- }): Promise<RetryPendingBlobDeletionsResult>;
200
+ /**
201
+ * Re-submits the user's delete of a scope whose tombstone failed, through
202
+ * the ordinary delete path. The caller runs it inside the same mutation
203
+ * queue as this pass.
204
+ */
205
+ resubmitDeletion?: (scope: string, options: DeleteScopeOptions) => Promise<DeleteScopeResult>;
206
+ /** Bounds the re-submissions; required with `resubmitDeletion`. */
207
+ tombstoneResubmits?: TombstoneResubmitTracker;
208
+ /** Called once when a scope's re-submissions are used up. */
209
+ onDeletionAbandoned?: (state: TombstoneResubmitState) => void;
210
+ };
211
+ export declare function retryPendingBlobDeletions(deps: RetryPendingBlobDeletionsDeps): Promise<RetryPendingBlobDeletionsResult>;
163
212
  //# sourceMappingURL=delete.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/sync/workers/delete.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/sync/workers/delete.ts"],"names":[],"mappings":"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"}