@peerbit/shared-log 13.2.24 → 13.2.26

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 (81) hide show
  1. package/dist/src/checked-prune.d.ts +12 -0
  2. package/dist/src/checked-prune.d.ts.map +1 -1
  3. package/dist/src/checked-prune.js +33 -0
  4. package/dist/src/checked-prune.js.map +1 -1
  5. package/dist/src/coordinate-persistence.d.ts +211 -0
  6. package/dist/src/coordinate-persistence.d.ts.map +1 -0
  7. package/dist/src/coordinate-persistence.js +1133 -0
  8. package/dist/src/coordinate-persistence.js.map +1 -0
  9. package/dist/src/errors.d.ts +1 -0
  10. package/dist/src/errors.d.ts.map +1 -1
  11. package/dist/src/errors.js +19 -0
  12. package/dist/src/errors.js.map +1 -1
  13. package/dist/src/index.d.ts +127 -133
  14. package/dist/src/index.d.ts.map +1 -1
  15. package/dist/src/index.js +1400 -4269
  16. package/dist/src/index.js.map +1 -1
  17. package/dist/src/instance-lifecycle.d.ts +117 -0
  18. package/dist/src/instance-lifecycle.d.ts.map +1 -0
  19. package/dist/src/instance-lifecycle.js +254 -0
  20. package/dist/src/instance-lifecycle.js.map +1 -0
  21. package/dist/src/join-warmup.d.ts +86 -0
  22. package/dist/src/join-warmup.d.ts.map +1 -0
  23. package/dist/src/join-warmup.js +351 -0
  24. package/dist/src/join-warmup.js.map +1 -0
  25. package/dist/src/native-write-through-block-store.d.ts +123 -0
  26. package/dist/src/native-write-through-block-store.d.ts.map +1 -0
  27. package/dist/src/native-write-through-block-store.js +989 -0
  28. package/dist/src/native-write-through-block-store.js.map +1 -0
  29. package/dist/src/peer-session.d.ts +117 -0
  30. package/dist/src/peer-session.d.ts.map +1 -0
  31. package/dist/src/peer-session.js +259 -0
  32. package/dist/src/peer-session.js.map +1 -0
  33. package/dist/src/replication-announcement.d.ts +116 -0
  34. package/dist/src/replication-announcement.d.ts.map +1 -0
  35. package/dist/src/replication-announcement.js +515 -0
  36. package/dist/src/replication-announcement.js.map +1 -0
  37. package/dist/src/replicator-liveness.d.ts +59 -0
  38. package/dist/src/replicator-liveness.d.ts.map +1 -0
  39. package/dist/src/replicator-liveness.js +304 -0
  40. package/dist/src/replicator-liveness.js.map +1 -0
  41. package/dist/src/sync/dispatch-lifecycle.d.ts +48 -0
  42. package/dist/src/sync/dispatch-lifecycle.d.ts.map +1 -0
  43. package/dist/src/sync/dispatch-lifecycle.js +141 -0
  44. package/dist/src/sync/dispatch-lifecycle.js.map +1 -0
  45. package/dist/src/sync/factory.d.ts +29 -0
  46. package/dist/src/sync/factory.d.ts.map +1 -0
  47. package/dist/src/sync/factory.js +87 -0
  48. package/dist/src/sync/factory.js.map +1 -0
  49. package/dist/src/sync/pending-sync-store.d.ts +105 -0
  50. package/dist/src/sync/pending-sync-store.d.ts.map +1 -0
  51. package/dist/src/sync/pending-sync-store.js +877 -0
  52. package/dist/src/sync/pending-sync-store.js.map +1 -0
  53. package/dist/src/sync/rateless-iblt.d.ts +4 -1
  54. package/dist/src/sync/rateless-iblt.d.ts.map +1 -1
  55. package/dist/src/sync/rateless-iblt.js +102 -106
  56. package/dist/src/sync/rateless-iblt.js.map +1 -1
  57. package/dist/src/sync/simple.d.ts +10 -41
  58. package/dist/src/sync/simple.d.ts.map +1 -1
  59. package/dist/src/sync/simple.js +259 -952
  60. package/dist/src/sync/simple.js.map +1 -1
  61. package/dist/src/sync/sync-peer-state.d.ts +16 -0
  62. package/dist/src/sync/sync-peer-state.d.ts.map +1 -0
  63. package/dist/src/sync/sync-peer-state.js +82 -0
  64. package/dist/src/sync/sync-peer-state.js.map +1 -0
  65. package/package.json +12 -12
  66. package/src/checked-prune.ts +35 -0
  67. package/src/coordinate-persistence.ts +1796 -0
  68. package/src/errors.ts +21 -0
  69. package/src/index.ts +4014 -7858
  70. package/src/instance-lifecycle.ts +351 -0
  71. package/src/join-warmup.ts +507 -0
  72. package/src/native-write-through-block-store.ts +1170 -0
  73. package/src/peer-session.ts +336 -0
  74. package/src/replication-announcement.ts +744 -0
  75. package/src/replicator-liveness.ts +439 -0
  76. package/src/sync/dispatch-lifecycle.ts +230 -0
  77. package/src/sync/factory.ts +154 -0
  78. package/src/sync/pending-sync-store.ts +1085 -0
  79. package/src/sync/rateless-iblt.ts +122 -132
  80. package/src/sync/simple.ts +334 -1144
  81. package/src/sync/sync-peer-state.ts +107 -0
@@ -0,0 +1,117 @@
1
+ export type InstanceLifecyclePhase = "opening" | "active" | "poisoned" | "terminating" | "closed";
2
+ export type InstanceLifecycleTerminalReason = "close" | "drop" | "internal-close";
3
+ export type InstanceLifecycleDeps = {
4
+ /** host._instanceLifecycle — identity anchor for isCurrent() */
5
+ getCurrentLifecycle: () => InstanceLifecycle | undefined;
6
+ /** host._closeController */
7
+ getCloseController: () => AbortController | undefined;
8
+ /** host._replicationRangeMutationFailure (poison latch, fence A2) */
9
+ getPoisonFailure: () => unknown;
10
+ /** host.closed */
11
+ isHostClosed: () => boolean;
12
+ /** host.isTerminating() — closed || parent-detach || closeController aborted */
13
+ isHostTerminating: () => boolean;
14
+ /** host._checkedPrune — identity only, never dereferenced (fence A3) */
15
+ getCheckedPruneCoordinator: () => object | undefined;
16
+ /** host._replicationRangeMutationsClosing (terminal lane fence, A4) */
17
+ areRangeMutationsClosing: () => boolean;
18
+ /** host._pruneRemovesClosing (terminal lane fence, A4) */
19
+ arePruneRemovesClosing: () => boolean;
20
+ /** host.pruneDebouncedFn — identity only */
21
+ getPruneDebouncer: () => object | undefined;
22
+ /** host.replicationChangeDebounceFn — identity only */
23
+ getReplicationChangeDebouncer: () => object | undefined;
24
+ /** host.rebalanceParticipationDebounced — identity only */
25
+ getRebalanceDebouncer: () => object | undefined;
26
+ };
27
+ export declare class InstanceLifecycle {
28
+ private readonly deps;
29
+ roleGeneration: number;
30
+ _receiveOwnershipRevision: number;
31
+ _receiveOwnershipMutationAdmissions: number;
32
+ readonly ownershipLifecycleController: AbortController;
33
+ membershipLifecycleController?: AbortController;
34
+ declaredPhase: InstanceLifecyclePhase;
35
+ terminalReason?: InstanceLifecycleTerminalReason;
36
+ poisonCause?: unknown;
37
+ constructor(deps: InstanceLifecycleDeps);
38
+ markOpenComplete(): void;
39
+ beginTerminal(reason: InstanceLifecycleTerminalReason): void;
40
+ markPoisoned(cause: unknown): void;
41
+ /** ≡ legacy SharedLog.stopRepairLifecycle body (`controller?.abort()`),
42
+ * and the abort half of legacy startRepairLifecycle. Abort-in-place: the
43
+ * lifecycle identity is untouched (the poison contract — poison never
44
+ * rotates the lifecycle, so captures keep passing the identity term and
45
+ * fail on `signal.aborted`/poison exactly as before). */
46
+ abortOwnership(): void;
47
+ /** ≡ the legacy guarded abort in stopSubscriptionChangeCallbackAdmission:
48
+ * `if (!c?.signal.aborted) c?.abort(reason)`. */
49
+ abortMembership(reason?: unknown): void;
50
+ /** ≡ legacy `this._replicationLifecycleController = new AbortController()`
51
+ * in resetSubscriptionChangeCallbackTracking. Called exactly once per
52
+ * lifecycle, from open(); plain assignment kept (KEEP-OLD overwrite: the
53
+ * predecessor either is undefined or was aborted at close/drop). A
54
+ * direct out-of-open rotation (test-only) leaves the NEW lifecycle's
55
+ * membership undefined until the next open — a deliberate divergence
56
+ * from legacy, where the host field survived direct rotations; the two
57
+ * observables that path uses are pinned in the spec. */
58
+ beginMembership(): AbortController;
59
+ bumpRoleGeneration(): number;
60
+ isRoleCurrent(capturedRoleGeneration: number): boolean;
61
+ isCurrent(): boolean;
62
+ phase(): InstanceLifecyclePhase;
63
+ /** ≡ SharedLog.isRepairLifecycleActive(controller). Stage 4 note: the
64
+ * identity term compares against the OWNED controller. For a stale
65
+ * captured lifecycle with its co-captured controller the term now
66
+ * passes where the legacy host-current compare failed; the predicate
67
+ * still returns false via `signal.aborted`, guaranteed by the rotation
68
+ * invariant (non-current ⇒ abortOwnership already ran — see the field
69
+ * comment above). */
70
+ isActiveFor(controller: AbortController | undefined): boolean;
71
+ /**
72
+ * Controller-free form for stage-3 seams. Because this object OWNS its
73
+ * ownership controller (stage 4), lifecycle and controller rotate
74
+ * together by construction, so `capturedLifecycle.isActive()` ⇔
75
+ * `isRepairLifecycleActive(capturedController)` for captures taken
76
+ * together — the equivalence the unit spec asserts.
77
+ */
78
+ isActive(): boolean;
79
+ /** ≡ SharedLog.throwIfReplicationOwnershipPoisoned — message and `cause`
80
+ * must stay byte-identical for stage-3 drop-in. */
81
+ throwIfPoisoned(): void;
82
+ /** ≡ SharedLog.throwIfReplicationOwnershipLifecycleInactive. */
83
+ throwIfInactive(controller?: AbortController | undefined): void;
84
+ /** ≡ SharedLog.captureReplicationOwnershipLifecycle, but returns the
85
+ * lifecycle; stage-3 sites capture this instead of the raw controller
86
+ * (which stays reachable via ownershipSignal()). */
87
+ capture(): InstanceLifecycle;
88
+ /** AbortControllers stay the signal carriers. */
89
+ ownershipSignal(): AbortSignal | undefined;
90
+ /** ≡ SharedLog.isReplicationLifecycleActive(controller).
91
+ * NOTE the asymmetry vs isActiveFor: this side uses isTerminating()
92
+ * (closeController + parent-detach), not `closed` — preserve exactly. */
93
+ isMembershipActiveFor(controller: AbortController | undefined): boolean;
94
+ membershipSignal(): AbortSignal | undefined;
95
+ closeSignal(): AbortSignal | undefined;
96
+ /** ≡ prune()'s isCheckedPruneLifecycleCurrent triple for captures taken
97
+ * at the same admission point. Stage 3 extension: an omitted
98
+ * `closeController` SKIPS that term (the non-prune() checked-prune seats
99
+ * never compared it — adding the compare would strengthen their
100
+ * predicates), and `controller` lets a seat honor an explicitly threaded
101
+ * (possibly stale) ownership capture instead of the current one. */
102
+ isCheckedPruneCurrent(coordinator: object | undefined, closeController?: AbortController, controller?: AbortController | undefined): boolean;
103
+ /** Exact fold of prune()'s throwIfCheckedPruneLifecycleInactive and of
104
+ * revalidateCheckedPruneOwnership's controller branch (there with the
105
+ * closeController term omitted). Error order MUST stay: poison Error →
106
+ * ownership TerminalOperationNotStartedError ("Replication ownership
107
+ * lifecycle is no longer active") → checked-prune
108
+ * TerminalOperationNotStartedError ("Checked prune lifecycle is no
109
+ * longer active"). */
110
+ throwIfCheckedPruneInactive(coordinator: object | undefined, closeController?: AbortController, controller?: AbortController | undefined): void;
111
+ areRangeMutationsClosing(): boolean;
112
+ arePruneRemovesClosing(): boolean;
113
+ isPruneDebouncerCurrent(fn: object | undefined): boolean;
114
+ isReplicationChangeDebouncerCurrent(fn: object | undefined): boolean;
115
+ isRebalanceDebouncerCurrent(fn: object | undefined): boolean;
116
+ }
117
+ //# sourceMappingURL=instance-lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instance-lifecycle.d.ts","sourceRoot":"","sources":["../../src/instance-lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,254 @@
1
+ // One InstanceLifecycle per SharedLog.open(). Stage 2 of the
2
+ // session/lifecycle refactor introduced the object as a WRAPPER over the
3
+ // existing fences via late-bound readers; stage 3 migrated the documented
4
+ // multi-fence seams onto this API; stage 4 makes it the physical owner of
5
+ // the per-open state: the role sub-generation, the receive-ownership
6
+ // counters, and the ownership/membership AbortControllers themselves (the
7
+ // index.ts ratchet entries moved file-to-file into this file's baseline in
8
+ // scripts/ci/check-fence-ratchet.mjs). The remaining deps are late-bound
9
+ // readers for host state that outlives any single lifecycle (poison latch,
10
+ // close controller, coordinator/debouncer identities).
11
+ import { TerminalOperationNotStartedError } from "@peerbit/program";
12
+ export class InstanceLifecycle {
13
+ deps;
14
+ // The ONLY state that physically moved in stage 2 (absorbed the former
15
+ // SharedLog._localReplicationRoleGeneration; the accessor shim was deleted
16
+ // in stage 3). Bumped by replicate()'s
17
+ // fixed-role replacement and by full unreplication WITHOUT rotating the
18
+ // lifecycle: unreplicate() deliberately keeps the store open, so admitted
19
+ // adaptive planners are invalidated by this sub-generation, not by
20
+ // retiring the instance identity.
21
+ roleGeneration = 0;
22
+ // Moved from SharedLog (fences C1/C2, same names — the sanctioned
23
+ // file-to-file ratchet move). Physically owned per-open counters read and
24
+ // written directly through the lifecycle owner; the fresh lifecycle object
25
+ // at open() IS the legacy reset-to-0 (same pattern as roleGeneration above).
26
+ //
27
+ // Receive-side ownership plans may span lower-log joins that invoke user
28
+ // code. Incremented synchronously with leader-cache invalidation so the
29
+ // handler can detect whether its pre-join plan needs one fresh
30
+ // post-persist audit.
31
+ _receiveOwnershipRevision = 0;
32
+ // Count of ownership-changing range mutations from queue admission
33
+ // through settlement, including mutations already pending when a receive
34
+ // starts.
35
+ _receiveOwnershipMutationAdmissions = 0;
36
+ // ---- stage 4: physically owned controllers (moved from SharedLog) ----
37
+ // Fences A1/A5; the index.ts ratchet entries _repairLifecycleController /
38
+ // _replicationLifecycleController moved file-to-file under these names.
39
+ // Rotate-with-the-lifecycle by construction: a fresh InstanceLifecycle IS
40
+ // the rotation of both controllers; within one lifecycle the ownership
41
+ // controller identity never changes (readonly) — poison and terminal
42
+ // paths abort it IN PLACE, exactly like the legacy un-reassigned host
43
+ // field. Background repair work can outlive the await that admitted it;
44
+ // the per-open replacement of this whole object keeps an older runner
45
+ // from dispatching into or mutating a freshly opened lifecycle.
46
+ //
47
+ // INVARIANT every rotation site must keep: whatever installs a new
48
+ // host._instanceLifecycle aborts the outgoing lifecycle's ownership
49
+ // controller in the same synchronous block (startRepairLifecycle does).
50
+ // The stale-capture predicates in isActiveFor lean on
51
+ // non-current ⇒ aborted now that the identity term compares against the
52
+ // owned field rather than the host-current controller.
53
+ ownershipLifecycleController = new AbortController();
54
+ // undefined until open() reaches resetSubscriptionChangeCallbackTracking
55
+ // (beginMembership) — preserves the legacy `?: AbortController` decl-site
56
+ // semantics for constructed-but-never-opened hosts.
57
+ membershipLifecycleController;
58
+ // Stage-2 bookkeeping. WRITE-ONLY in production paths: no query method
59
+ // consults these (phase() is derived from the wrapped fences), so a
60
+ // missed or doubled transition cannot change behavior. Stage 3 flips
61
+ // phase() onto declaredPhase once the transitions have soaked in CI.
62
+ declaredPhase = "opening";
63
+ terminalReason;
64
+ poisonCause;
65
+ constructor(deps) {
66
+ this.deps = deps;
67
+ }
68
+ // ---- rotation-point transitions (stage 2: diagnostics only) ----
69
+ markOpenComplete() {
70
+ if (this.declaredPhase === "opening")
71
+ this.declaredPhase = "active";
72
+ }
73
+ beginTerminal(reason) {
74
+ this.terminalReason ??= reason;
75
+ if (this.declaredPhase !== "poisoned")
76
+ this.declaredPhase = "terminating";
77
+ }
78
+ markPoisoned(cause) {
79
+ this.poisonCause ??= cause;
80
+ this.declaredPhase = "poisoned";
81
+ }
82
+ // ---- owned-controller transitions (stage 4) ----
83
+ /** ≡ legacy SharedLog.stopRepairLifecycle body (`controller?.abort()`),
84
+ * and the abort half of legacy startRepairLifecycle. Abort-in-place: the
85
+ * lifecycle identity is untouched (the poison contract — poison never
86
+ * rotates the lifecycle, so captures keep passing the identity term and
87
+ * fail on `signal.aborted`/poison exactly as before). */
88
+ abortOwnership() {
89
+ this.ownershipLifecycleController.abort();
90
+ }
91
+ /** ≡ the legacy guarded abort in stopSubscriptionChangeCallbackAdmission:
92
+ * `if (!c?.signal.aborted) c?.abort(reason)`. */
93
+ abortMembership(reason) {
94
+ if (!this.membershipLifecycleController?.signal.aborted) {
95
+ this.membershipLifecycleController?.abort(reason);
96
+ }
97
+ }
98
+ /** ≡ legacy `this._replicationLifecycleController = new AbortController()`
99
+ * in resetSubscriptionChangeCallbackTracking. Called exactly once per
100
+ * lifecycle, from open(); plain assignment kept (KEEP-OLD overwrite: the
101
+ * predecessor either is undefined or was aborted at close/drop). A
102
+ * direct out-of-open rotation (test-only) leaves the NEW lifecycle's
103
+ * membership undefined until the next open — a deliberate divergence
104
+ * from legacy, where the host field survived direct rotations; the two
105
+ * observables that path uses are pinned in the spec. */
106
+ beginMembership() {
107
+ return (this.membershipLifecycleController = new AbortController());
108
+ }
109
+ // ---- role sub-generation (absorbed fence A6) ----
110
+ bumpRoleGeneration() {
111
+ return ++this.roleGeneration;
112
+ }
113
+ isRoleCurrent(capturedRoleGeneration) {
114
+ return this.roleGeneration === capturedRoleGeneration;
115
+ }
116
+ // ---- identity ----
117
+ isCurrent() {
118
+ return this.deps.getCurrentLifecycle() === this;
119
+ }
120
+ // ---- derived phase (single source of truth = the wrapped fences) ----
121
+ phase() {
122
+ if (this.deps.getPoisonFailure() !== undefined)
123
+ return "poisoned";
124
+ if (this.deps.isHostClosed())
125
+ return "closed";
126
+ // The legacy `ownership == null` arm is gone: a lifecycle object owns
127
+ // its controller, so the absent-controller state is unrepresentable
128
+ // (clones have no lifecycle and cannot reach phase()).
129
+ if (!this.isCurrent() || this.ownershipLifecycleController.signal.aborted) {
130
+ return "terminating";
131
+ }
132
+ return this.declaredPhase === "opening" ? "opening" : "active";
133
+ }
134
+ // ---- ownership half: exact folds of the legacy predicates ----
135
+ /** ≡ SharedLog.isRepairLifecycleActive(controller). Stage 4 note: the
136
+ * identity term compares against the OWNED controller. For a stale
137
+ * captured lifecycle with its co-captured controller the term now
138
+ * passes where the legacy host-current compare failed; the predicate
139
+ * still returns false via `signal.aborted`, guaranteed by the rotation
140
+ * invariant (non-current ⇒ abortOwnership already ran — see the field
141
+ * comment above). */
142
+ isActiveFor(controller) {
143
+ return (controller != null &&
144
+ controller === this.ownershipLifecycleController &&
145
+ !controller.signal.aborted &&
146
+ this.deps.getPoisonFailure() === undefined &&
147
+ !this.deps.isHostClosed());
148
+ }
149
+ /**
150
+ * Controller-free form for stage-3 seams. Because this object OWNS its
151
+ * ownership controller (stage 4), lifecycle and controller rotate
152
+ * together by construction, so `capturedLifecycle.isActive()` ⇔
153
+ * `isRepairLifecycleActive(capturedController)` for captures taken
154
+ * together — the equivalence the unit spec asserts.
155
+ */
156
+ isActive() {
157
+ return (this.isCurrent() && this.isActiveFor(this.ownershipLifecycleController));
158
+ }
159
+ /** ≡ SharedLog.throwIfReplicationOwnershipPoisoned — message and `cause`
160
+ * must stay byte-identical for stage-3 drop-in. */
161
+ throwIfPoisoned() {
162
+ const failure = this.deps.getPoisonFailure();
163
+ if (failure !== undefined) {
164
+ throw new Error("Replication ownership recovery is required before further planning", { cause: failure });
165
+ }
166
+ }
167
+ /** ≡ SharedLog.throwIfReplicationOwnershipLifecycleInactive. */
168
+ throwIfInactive(controller = this.ownershipLifecycleController) {
169
+ this.throwIfPoisoned();
170
+ if (!(this.isCurrent() && this.isActiveFor(controller))) {
171
+ throw new TerminalOperationNotStartedError("Replication ownership lifecycle is no longer active");
172
+ }
173
+ }
174
+ /** ≡ SharedLog.captureReplicationOwnershipLifecycle, but returns the
175
+ * lifecycle; stage-3 sites capture this instead of the raw controller
176
+ * (which stays reachable via ownershipSignal()). */
177
+ capture() {
178
+ this.throwIfInactive();
179
+ return this;
180
+ }
181
+ /** AbortControllers stay the signal carriers. */
182
+ ownershipSignal() {
183
+ return this.ownershipLifecycleController.signal;
184
+ }
185
+ // ---- membership half (fence A5): exact fold ----
186
+ /** ≡ SharedLog.isReplicationLifecycleActive(controller).
187
+ * NOTE the asymmetry vs isActiveFor: this side uses isTerminating()
188
+ * (closeController + parent-detach), not `closed` — preserve exactly. */
189
+ isMembershipActiveFor(controller) {
190
+ return (controller != null &&
191
+ controller === this.membershipLifecycleController &&
192
+ !controller.signal.aborted &&
193
+ !this.deps.isHostTerminating());
194
+ }
195
+ membershipSignal() {
196
+ return this.membershipLifecycleController?.signal;
197
+ }
198
+ closeSignal() {
199
+ return this.deps.getCloseController()?.signal;
200
+ }
201
+ // ---- checked-prune identity (seams 4 and 7) ----
202
+ /** ≡ prune()'s isCheckedPruneLifecycleCurrent triple for captures taken
203
+ * at the same admission point. Stage 3 extension: an omitted
204
+ * `closeController` SKIPS that term (the non-prune() checked-prune seats
205
+ * never compared it — adding the compare would strengthen their
206
+ * predicates), and `controller` lets a seat honor an explicitly threaded
207
+ * (possibly stale) ownership capture instead of the current one. */
208
+ isCheckedPruneCurrent(coordinator, closeController, controller = this.ownershipLifecycleController) {
209
+ return (this.isCurrent() &&
210
+ this.isActiveFor(controller) &&
211
+ coordinator === this.deps.getCheckedPruneCoordinator() &&
212
+ (closeController === undefined ||
213
+ closeController === this.deps.getCloseController()));
214
+ }
215
+ /** Exact fold of prune()'s throwIfCheckedPruneLifecycleInactive and of
216
+ * revalidateCheckedPruneOwnership's controller branch (there with the
217
+ * closeController term omitted). Error order MUST stay: poison Error →
218
+ * ownership TerminalOperationNotStartedError ("Replication ownership
219
+ * lifecycle is no longer active") → checked-prune
220
+ * TerminalOperationNotStartedError ("Checked prune lifecycle is no
221
+ * longer active"). */
222
+ throwIfCheckedPruneInactive(coordinator, closeController, controller = this.ownershipLifecycleController) {
223
+ this.throwIfInactive(controller);
224
+ if (coordinator !== this.deps.getCheckedPruneCoordinator() ||
225
+ (closeController !== undefined &&
226
+ closeController !== this.deps.getCloseController())) {
227
+ throw new TerminalOperationNotStartedError("Checked prune lifecycle is no longer active");
228
+ }
229
+ }
230
+ // ---- terminal lane fences (A4): exposed, NOT folded into isActive ----
231
+ // Folding them would change which TerminalOperationNotStartedError message
232
+ // the admission sites throw ("Replication range mutations are closing",
233
+ // "Prune removals are closing") — a behavior change.
234
+ areRangeMutationsClosing() {
235
+ return this.deps.areRangeMutationsClosing();
236
+ }
237
+ arePruneRemovesClosing() {
238
+ return this.deps.arePruneRemovesClosing();
239
+ }
240
+ // ---- debouncer identities (seam 6 et al.) ----
241
+ // Bare === on purpose: at rebalanceParticipation the captured default
242
+ // parameter may be undefined and `undefined === undefined` legitimately
243
+ // passes today. A null-guard would break that.
244
+ isPruneDebouncerCurrent(fn) {
245
+ return fn === this.deps.getPruneDebouncer();
246
+ }
247
+ isReplicationChangeDebouncerCurrent(fn) {
248
+ return fn === this.deps.getReplicationChangeDebouncer();
249
+ }
250
+ isRebalanceDebouncerCurrent(fn) {
251
+ return fn === this.deps.getRebalanceDebouncer();
252
+ }
253
+ }
254
+ //# sourceMappingURL=instance-lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instance-lifecycle.js","sourceRoot":"","sources":["../../src/instance-lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * One WarmupSession per join-warmup attempt window for a target. The
3
+ * instance IS the legacy opaque generation token — always compared by
4
+ * identity, never inspected — now carrying diagnostics. Rotation points are
5
+ * unchanged: created on demand, dropped at cancelJoinWarmupTarget so the
6
+ * next touch mints a fresh identity. Deliberately NOT hosted on
7
+ * PeerSession: warmup windows rotate independently of subscription epochs
8
+ * (poison and committed removals leave the subscription session alone), and
9
+ * a warmup target may have no session at all — auto-creating one as a
10
+ * warmup side effect would flip `isCurrent(peer, null)` from true to false
11
+ * at every receive-admission seat.
12
+ */
13
+ export declare class WarmupSession {
14
+ readonly target: string;
15
+ readonly createdAt: number;
16
+ constructor(target: string);
17
+ }
18
+ export type JoinWarmupSendState<E> = {
19
+ bypassKnownPeerHints: boolean;
20
+ entries: Map<string, E>;
21
+ session: WarmupSession;
22
+ lastCompletedAt: number;
23
+ pending: boolean;
24
+ running: boolean;
25
+ };
26
+ export type JoinWarmupRetryTimer = {
27
+ handle: ReturnType<typeof setTimeout>;
28
+ resolve?: () => void;
29
+ };
30
+ export type JoinWarmupScheduledRetryBatch<E> = {
31
+ bypassKnownPeerHints: boolean;
32
+ entries: Map<string, E>;
33
+ remainingAttempts: number;
34
+ };
35
+ export type JoinWarmupScheduledRetryCohort<E> = {
36
+ batches: JoinWarmupScheduledRetryBatch<E>[];
37
+ dueAt: number;
38
+ };
39
+ export type JoinWarmupScheduledRetrySlot<E> = {
40
+ cohorts: JoinWarmupScheduledRetryCohort<E>[];
41
+ head: number;
42
+ timer?: JoinWarmupRetryTimer;
43
+ timerDueAt?: number;
44
+ };
45
+ export type JoinWarmupScheduledRetries<E> = {
46
+ session: WarmupSession;
47
+ slotsByDelay: Map<number, JoinWarmupScheduledRetrySlot<E>>;
48
+ };
49
+ export type JoinWarmupDeps<E> = {
50
+ isLifecycleActive: (controller: AbortController) => boolean;
51
+ getCurrentLifecycleController: () => AbortController;
52
+ getRepairRetryTimers: () => Set<ReturnType<typeof setTimeout>>;
53
+ isClosed: () => boolean;
54
+ onTargetCancelled: (target: string) => void;
55
+ bumpSimpleFallbackPasses: () => void;
56
+ sendEntriesSimple: (target: string, entries: ReadonlyMap<string, E>, options: {
57
+ bypassKnownPeers: boolean;
58
+ bypassRecentKnownPeers: boolean;
59
+ isStillCurrent: () => boolean;
60
+ signal: AbortSignal;
61
+ }) => Promise<void>;
62
+ logError: (error: any) => void;
63
+ };
64
+ export declare class JoinWarmupCoordinator<E> {
65
+ private readonly deps;
66
+ _warmupSessionsByTarget: Map<string, WarmupSession>;
67
+ _joinWarmupSendStateByTarget: Map<string, JoinWarmupSendState<E>>;
68
+ _joinWarmupRetryTimersByTarget: Map<string, Set<JoinWarmupRetryTimer>>;
69
+ _joinWarmupScheduledRetriesByTarget: Map<string, JoinWarmupScheduledRetries<E>>;
70
+ _repairSweepWarmupSessionByTarget: Map<string, WarmupSession>;
71
+ constructor(deps: JoinWarmupDeps<E>);
72
+ reset(): void;
73
+ ensureWarmupSession(target: string): WarmupSession;
74
+ clearRepairSweepWarmupSessions(): void;
75
+ trackJoinWarmupTimer(target: string, timer: JoinWarmupRetryTimer): void;
76
+ untrackJoinWarmupTimer(target: string, timer: JoinWarmupRetryTimer): void;
77
+ cancelJoinWarmupTimers(target: string): void;
78
+ cancelJoinWarmupTarget(target: string): void;
79
+ cancelAllJoinWarmupTargets(): void;
80
+ sleepJoinWarmupTracked(target: string, delayMs: number, repairLifecycleController: AbortController): Promise<void>;
81
+ scheduleJoinWarmupRetries(target: string, session: WarmupSession, delaysMs: Iterable<number>, entries: ReadonlyMap<string, E>, bypassKnownPeerHints: boolean, repairLifecycleController?: AbortController): void;
82
+ armJoinWarmupRetrySlot(target: string, scheduled: JoinWarmupScheduledRetries<E>, delayMs: number, slot: JoinWarmupScheduledRetrySlot<E>, repairLifecycleController: AbortController): void;
83
+ queueJoinWarmupSend(target: string, session: WarmupSession, entries: ReadonlyMap<string, E>, bypassKnownPeerHints: boolean, repairLifecycleController?: AbortController): void;
84
+ drainJoinWarmupSends(target: string, state: JoinWarmupSendState<E>, repairLifecycleController: AbortController): Promise<void>;
85
+ }
86
+ //# sourceMappingURL=join-warmup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"join-warmup.d.ts","sourceRoot":"","sources":["../../src/join-warmup.ts"],"names":[],"mappings":"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"}