@loomwork/event-runtime 0.0.0-stage → 0.1.0

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 (153) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +8 -0
  3. package/README.md +95 -2
  4. package/dist/BranchRegistry.d.ts +140 -0
  5. package/dist/BranchRegistry.d.ts.map +1 -0
  6. package/dist/BranchRegistry.js +66 -0
  7. package/dist/BranchRegistry.js.map +1 -0
  8. package/dist/CoalescingEventStore.d.ts +97 -0
  9. package/dist/CoalescingEventStore.d.ts.map +1 -0
  10. package/dist/CoalescingEventStore.js +180 -0
  11. package/dist/CoalescingEventStore.js.map +1 -0
  12. package/dist/InMemoryArchiveStore.d.ts +19 -0
  13. package/dist/InMemoryArchiveStore.d.ts.map +1 -0
  14. package/dist/InMemoryArchiveStore.js +49 -0
  15. package/dist/InMemoryArchiveStore.js.map +1 -0
  16. package/dist/InMemoryAsyncEventStore.d.ts +111 -0
  17. package/dist/InMemoryAsyncEventStore.d.ts.map +1 -0
  18. package/dist/InMemoryAsyncEventStore.js +374 -0
  19. package/dist/InMemoryAsyncEventStore.js.map +1 -0
  20. package/dist/InMemoryBranchRegistry.d.ts +31 -0
  21. package/dist/InMemoryBranchRegistry.d.ts.map +1 -0
  22. package/dist/InMemoryBranchRegistry.js +167 -0
  23. package/dist/InMemoryBranchRegistry.js.map +1 -0
  24. package/dist/ProfilingEventStore.d.ts +75 -0
  25. package/dist/ProfilingEventStore.d.ts.map +1 -0
  26. package/dist/ProfilingEventStore.js +133 -0
  27. package/dist/ProfilingEventStore.js.map +1 -0
  28. package/dist/ShardPlan.d.ts +87 -0
  29. package/dist/ShardPlan.d.ts.map +1 -0
  30. package/dist/ShardPlan.js +193 -0
  31. package/dist/ShardPlan.js.map +1 -0
  32. package/dist/ShardedEventStore.d.ts +149 -0
  33. package/dist/ShardedEventStore.d.ts.map +1 -0
  34. package/dist/ShardedEventStore.js +468 -0
  35. package/dist/ShardedEventStore.js.map +1 -0
  36. package/dist/SubscriberRegistry.d.ts +59 -0
  37. package/dist/SubscriberRegistry.d.ts.map +1 -0
  38. package/dist/SubscriberRegistry.js +113 -0
  39. package/dist/SubscriberRegistry.js.map +1 -0
  40. package/dist/TenantScopedArchiveStore.d.ts +36 -0
  41. package/dist/TenantScopedArchiveStore.d.ts.map +1 -0
  42. package/dist/TenantScopedArchiveStore.js +96 -0
  43. package/dist/TenantScopedArchiveStore.js.map +1 -0
  44. package/dist/TenantScopedEventStore.d.ts +59 -0
  45. package/dist/TenantScopedEventStore.d.ts.map +1 -0
  46. package/dist/TenantScopedEventStore.js +227 -0
  47. package/dist/TenantScopedEventStore.js.map +1 -0
  48. package/dist/archive.d.ts +68 -0
  49. package/dist/archive.d.ts.map +1 -0
  50. package/dist/archive.js +207 -0
  51. package/dist/archive.js.map +1 -0
  52. package/dist/archiveSpi.d.ts +165 -0
  53. package/dist/archiveSpi.d.ts.map +1 -0
  54. package/dist/archiveSpi.js +184 -0
  55. package/dist/archiveSpi.js.map +1 -0
  56. package/dist/creationMarker.d.ts +13 -0
  57. package/dist/creationMarker.d.ts.map +1 -0
  58. package/dist/creationMarker.js +17 -0
  59. package/dist/creationMarker.js.map +1 -0
  60. package/dist/decoratorPlan.typecheck.d.ts +2 -0
  61. package/dist/decoratorPlan.typecheck.d.ts.map +1 -0
  62. package/dist/decoratorPlan.typecheck.js +41 -0
  63. package/dist/decoratorPlan.typecheck.js.map +1 -0
  64. package/dist/eventKindClass.d.ts +40 -0
  65. package/dist/eventKindClass.d.ts.map +1 -0
  66. package/dist/eventKindClass.js +99 -0
  67. package/dist/eventKindClass.js.map +1 -0
  68. package/dist/executionIdOrder.d.ts +21 -0
  69. package/dist/executionIdOrder.d.ts.map +1 -0
  70. package/dist/executionIdOrder.js +43 -0
  71. package/dist/executionIdOrder.js.map +1 -0
  72. package/dist/fencing.d.ts +21 -0
  73. package/dist/fencing.d.ts.map +1 -0
  74. package/dist/fencing.js +36 -0
  75. package/dist/fencing.js.map +1 -0
  76. package/dist/index.d.ts +39 -0
  77. package/dist/index.d.ts.map +1 -0
  78. package/dist/index.js +126 -0
  79. package/dist/index.js.map +1 -0
  80. package/dist/installOptional.d.ts +52 -0
  81. package/dist/installOptional.d.ts.map +1 -0
  82. package/dist/installOptional.js +112 -0
  83. package/dist/installOptional.js.map +1 -0
  84. package/dist/keyUnavailable.d.ts +67 -0
  85. package/dist/keyUnavailable.d.ts.map +1 -0
  86. package/dist/keyUnavailable.js +87 -0
  87. package/dist/keyUnavailable.js.map +1 -0
  88. package/dist/leases.d.ts +177 -0
  89. package/dist/leases.d.ts.map +1 -0
  90. package/dist/leases.js +142 -0
  91. package/dist/leases.js.map +1 -0
  92. package/dist/payloadShredded.d.ts +30 -0
  93. package/dist/payloadShredded.d.ts.map +1 -0
  94. package/dist/payloadShredded.js +67 -0
  95. package/dist/payloadShredded.js.map +1 -0
  96. package/dist/scaleDecorators.bench.d.ts +2 -0
  97. package/dist/scaleDecorators.bench.d.ts.map +1 -0
  98. package/dist/scaleDecorators.bench.js +93 -0
  99. package/dist/scaleDecorators.bench.js.map +1 -0
  100. package/dist/sequenceRange.bench.d.ts +2 -0
  101. package/dist/sequenceRange.bench.d.ts.map +1 -0
  102. package/dist/sequenceRange.bench.js +46 -0
  103. package/dist/sequenceRange.bench.js.map +1 -0
  104. package/dist/sequenceRange.d.ts +10 -0
  105. package/dist/sequenceRange.d.ts.map +1 -0
  106. package/dist/sequenceRange.js +35 -0
  107. package/dist/sequenceRange.js.map +1 -0
  108. package/dist/timers.d.ts +87 -0
  109. package/dist/timers.d.ts.map +1 -0
  110. package/dist/timers.js +68 -0
  111. package/dist/timers.js.map +1 -0
  112. package/dist/types.d.ts +634 -0
  113. package/dist/types.d.ts.map +1 -0
  114. package/dist/types.js +429 -0
  115. package/dist/types.js.map +1 -0
  116. package/dist/writeConflicts.d.ts +46 -0
  117. package/dist/writeConflicts.d.ts.map +1 -0
  118. package/dist/writeConflicts.js +63 -0
  119. package/dist/writeConflicts.js.map +1 -0
  120. package/memory.d.ts +4 -0
  121. package/memory.js +13 -0
  122. package/package.json +67 -3
  123. package/sequence.d.ts +1 -0
  124. package/sequence.js +5 -0
  125. package/src/BranchRegistry.ts +161 -0
  126. package/src/CoalescingEventStore.ts +214 -0
  127. package/src/InMemoryArchiveStore.ts +69 -0
  128. package/src/InMemoryAsyncEventStore.ts +425 -0
  129. package/src/InMemoryBranchRegistry.ts +178 -0
  130. package/src/ProfilingEventStore.ts +153 -0
  131. package/src/ShardPlan.ts +235 -0
  132. package/src/ShardedEventStore.ts +557 -0
  133. package/src/SubscriberRegistry.ts +115 -0
  134. package/src/TenantScopedArchiveStore.ts +114 -0
  135. package/src/TenantScopedEventStore.ts +266 -0
  136. package/src/archive.ts +248 -0
  137. package/src/archiveSpi.ts +308 -0
  138. package/src/creationMarker.ts +15 -0
  139. package/src/decoratorPlan.typecheck.ts +52 -0
  140. package/src/eventKindClass.ts +127 -0
  141. package/src/executionIdOrder.ts +38 -0
  142. package/src/fencing.ts +31 -0
  143. package/src/index.ts +151 -0
  144. package/src/installOptional.ts +136 -0
  145. package/src/keyUnavailable.ts +98 -0
  146. package/src/leases.ts +319 -0
  147. package/src/payloadShredded.ts +63 -0
  148. package/src/scaleDecorators.bench.ts +107 -0
  149. package/src/sequenceRange.bench.ts +51 -0
  150. package/src/sequenceRange.ts +35 -0
  151. package/src/timers.ts +150 -0
  152. package/src/types.ts +857 -0
  153. package/src/writeConflicts.ts +56 -0
@@ -0,0 +1,75 @@
1
+ import type { EventEnvelope } from "@loomwork/core";
2
+ import type { EventStore } from "./types";
3
+ /** Store-side timings, in milliseconds unless stated otherwise. */
4
+ export interface WriteProfile {
5
+ /** Envelopes durably appended (counting each envelope of a batch). */
6
+ envelopes: number;
7
+ /** Calls to `append` plus calls to `appendBatch` — i.e. round-trips. */
8
+ roundTrips: number;
9
+ /** Summed wall time inside the store's write calls. */
10
+ totalWriteMs: number;
11
+ /** Longest single write call. */
12
+ maxWriteMs: number;
13
+ /** Greatest number of write calls in flight at once — the queue the log is absorbing. */
14
+ peakConcurrentWrites: number;
15
+ /** Wall time from the first write starting to the last one finishing. */
16
+ spanMs: number;
17
+ /** Envelopes per second over `spanMs`. 0 before anything is written. */
18
+ envelopesPerSec: number;
19
+ }
20
+ /**
21
+ * Measures what the durable write path actually costs, so a workload can be *profiled*
22
+ * rather than reasoned about.
23
+ *
24
+ * This exists for [ADR 0065](../../../docs/adr/0065-group-commit-deferred-evidence-gate.md)
25
+ * gate 1, which asks for a real workload where **event-write throughput — not effect
26
+ * latency, not fold cost — is the measured bottleneck**, and is explicit that a profile is
27
+ * required rather than intuition. The gate is deliberately hard to satisfy: `ExecutionJournal`
28
+ * already decouples the interpreter from write latency by queueing appends on a serial
29
+ * tail, so a workload can write a great deal without writes ever being the constraint.
30
+ *
31
+ * Point this at your own application, alongside `effectTimingMiddleware` from
32
+ * `@loomwork/middleware`, and compare: if effect time dwarfs write time, batching cannot help
33
+ * you, whatever the raw event rate looks like.
34
+ *
35
+ * Zero-cost when unwired — it is a decorator, so a store that is not wrapped is unaffected.
36
+ */
37
+ export declare class ProfilingEventStore implements EventStore {
38
+ private readonly inner;
39
+ readonly head?: NonNullable<EventStore["head"]>;
40
+ readonly readRange?: NonNullable<EventStore["readRange"]>;
41
+ readonly acquireFence?: NonNullable<EventStore["acquireFence"]>;
42
+ readonly acquireFenceIf?: NonNullable<EventStore["acquireFenceIf"]>;
43
+ readonly appendIfUnchanged?: NonNullable<EventStore["appendIfUnchanged"]>;
44
+ readonly storeNow?: NonNullable<EventStore["storeNow"]>;
45
+ readonly sealingCapability?: NonNullable<EventStore["sealingCapability"]>;
46
+ readonly readAtRest?: NonNullable<EventStore["readAtRest"]>;
47
+ readonly copyPrefix?: NonNullable<EventStore["copyPrefix"]>;
48
+ readonly deleteExecution?: NonNullable<EventStore["deleteExecution"]>;
49
+ readonly deleteThrough?: NonNullable<EventStore["deleteThrough"]>;
50
+ readonly truncatePrefix?: NonNullable<EventStore["truncatePrefix"]>;
51
+ readonly truncatePrefixKeeping?: NonNullable<EventStore["truncatePrefixKeeping"]>;
52
+ readonly listExecutions?: NonNullable<EventStore["listExecutions"]>;
53
+ readonly listExecutionsPage?: NonNullable<EventStore["listExecutionsPage"]>;
54
+ readonly appendBatch?: NonNullable<EventStore["appendBatch"]>;
55
+ private envelopes;
56
+ private roundTrips;
57
+ private totalWriteMs;
58
+ private maxWriteMs;
59
+ private inFlight;
60
+ private peakConcurrentWrites;
61
+ private firstStart;
62
+ private lastEnd;
63
+ constructor(inner: EventStore);
64
+ private timed;
65
+ append(envelope: EventEnvelope): Promise<void>;
66
+ /** Snapshot of the write profile so far. */
67
+ writeProfile(): WriteProfile;
68
+ /** Discard measurements (e.g. after a warmup phase). */
69
+ resetProfile(): void;
70
+ read(executionId: string): Promise<EventEnvelope[]>;
71
+ readFrom(executionId: string, fromSequence: number): Promise<EventEnvelope[]>;
72
+ subscribe(executionId: string, handler: (event: EventEnvelope) => void): Promise<() => void>;
73
+ close(): Promise<void>;
74
+ }
75
+ //# sourceMappingURL=ProfilingEventStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProfilingEventStore.d.ts","sourceRoot":"","sources":["../src/ProfilingEventStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProfilingEventStore = void 0;
4
+ const installOptional_1 = require("./installOptional");
5
+ /**
6
+ * Measures what the durable write path actually costs, so a workload can be *profiled*
7
+ * rather than reasoned about.
8
+ *
9
+ * This exists for [ADR 0065](../../../docs/adr/0065-group-commit-deferred-evidence-gate.md)
10
+ * gate 1, which asks for a real workload where **event-write throughput — not effect
11
+ * latency, not fold cost — is the measured bottleneck**, and is explicit that a profile is
12
+ * required rather than intuition. The gate is deliberately hard to satisfy: `ExecutionJournal`
13
+ * already decouples the interpreter from write latency by queueing appends on a serial
14
+ * tail, so a workload can write a great deal without writes ever being the constraint.
15
+ *
16
+ * Point this at your own application, alongside `effectTimingMiddleware` from
17
+ * `@loomwork/middleware`, and compare: if effect time dwarfs write time, batching cannot help
18
+ * you, whatever the raw event rate looks like.
19
+ *
20
+ * Zero-cost when unwired — it is a decorator, so a store that is not wrapped is unaffected.
21
+ */
22
+ class ProfilingEventStore {
23
+ inner;
24
+ head;
25
+ readRange;
26
+ acquireFence;
27
+ acquireFenceIf;
28
+ appendIfUnchanged;
29
+ storeNow;
30
+ sealingCapability;
31
+ readAtRest;
32
+ copyPrefix;
33
+ deleteExecution;
34
+ deleteThrough;
35
+ truncatePrefix;
36
+ truncatePrefixKeeping;
37
+ listExecutions;
38
+ listExecutionsPage;
39
+ appendBatch;
40
+ envelopes = 0;
41
+ roundTrips = 0;
42
+ totalWriteMs = 0;
43
+ maxWriteMs = 0;
44
+ inFlight = 0;
45
+ peakConcurrentWrites = 0;
46
+ firstStart;
47
+ lastEnd = 0;
48
+ constructor(inner) {
49
+ this.inner = inner;
50
+ // Only advertise what the inner store has (installOptional's rule), so wrapping never
51
+ // changes which path a caller takes. Batches are timed like single appends.
52
+ const plan = {
53
+ appendBatch: (envelopes) => this.timed(envelopes.length, () => inner.appendBatch(envelopes)),
54
+ head: "forward",
55
+ readRange: "forward",
56
+ acquireFence: "forward",
57
+ acquireFenceIf: "forward",
58
+ appendIfUnchanged: "forward",
59
+ storeNow: "forward",
60
+ sealingCapability: "forward",
61
+ readAtRest: "forward",
62
+ copyPrefix: "forward",
63
+ deleteExecution: "forward",
64
+ deleteThrough: "forward",
65
+ truncatePrefix: "forward",
66
+ truncatePrefixKeeping: "forward",
67
+ listExecutions: "forward",
68
+ listExecutionsPage: "forward",
69
+ };
70
+ (0, installOptional_1.installOptional)(this, inner, plan);
71
+ }
72
+ async timed(envelopes, run) {
73
+ const started = performance.now();
74
+ if (this.firstStart === undefined)
75
+ this.firstStart = started;
76
+ this.inFlight++;
77
+ if (this.inFlight > this.peakConcurrentWrites)
78
+ this.peakConcurrentWrites = this.inFlight;
79
+ try {
80
+ await run();
81
+ }
82
+ finally {
83
+ const elapsed = performance.now() - started;
84
+ this.inFlight--;
85
+ this.roundTrips++;
86
+ this.envelopes += envelopes;
87
+ this.totalWriteMs += elapsed;
88
+ if (elapsed > this.maxWriteMs)
89
+ this.maxWriteMs = elapsed;
90
+ this.lastEnd = performance.now();
91
+ }
92
+ }
93
+ append(envelope) {
94
+ return this.timed(1, () => this.inner.append(envelope));
95
+ }
96
+ /** Snapshot of the write profile so far. */
97
+ writeProfile() {
98
+ const spanMs = this.firstStart === undefined ? 0 : this.lastEnd - this.firstStart;
99
+ return {
100
+ envelopes: this.envelopes,
101
+ roundTrips: this.roundTrips,
102
+ totalWriteMs: this.totalWriteMs,
103
+ maxWriteMs: this.maxWriteMs,
104
+ peakConcurrentWrites: this.peakConcurrentWrites,
105
+ spanMs,
106
+ envelopesPerSec: spanMs > 0 ? (this.envelopes / spanMs) * 1000 : 0,
107
+ };
108
+ }
109
+ /** Discard measurements (e.g. after a warmup phase). */
110
+ resetProfile() {
111
+ this.envelopes = 0;
112
+ this.roundTrips = 0;
113
+ this.totalWriteMs = 0;
114
+ this.maxWriteMs = 0;
115
+ this.peakConcurrentWrites = 0;
116
+ this.firstStart = undefined;
117
+ this.lastEnd = 0;
118
+ }
119
+ read(executionId) {
120
+ return this.inner.read(executionId);
121
+ }
122
+ readFrom(executionId, fromSequence) {
123
+ return this.inner.readFrom(executionId, fromSequence);
124
+ }
125
+ subscribe(executionId, handler) {
126
+ return this.inner.subscribe(executionId, handler);
127
+ }
128
+ close() {
129
+ return this.inner.close();
130
+ }
131
+ }
132
+ exports.ProfilingEventStore = ProfilingEventStore;
133
+ //# sourceMappingURL=ProfilingEventStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProfilingEventStore.js","sourceRoot":"","sources":["../src/ProfilingEventStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Where a bucket's executions live.
3
+ *
4
+ * `migrating` is the whole point of the plan: a bucket can be *in the process of* moving
5
+ * without anything being blocked or copied, because the store resolves per execution which
6
+ * side actually holds it.
7
+ */
8
+ export type ShardPlacement = {
9
+ readonly kind: "settled";
10
+ readonly shard: number;
11
+ } | {
12
+ readonly kind: "migrating";
13
+ readonly from: number;
14
+ readonly to: number;
15
+ };
16
+ /** Serialized form. Every node sharing a log MUST load the same plan. */
17
+ export interface ShardPlanJSON {
18
+ readonly version: 1;
19
+ readonly shardCount: number;
20
+ readonly placements: ReadonlyArray<{
21
+ shard: number;
22
+ } | {
23
+ from: number;
24
+ to: number;
25
+ }>;
26
+ }
27
+ /** Default virtual-bucket count. Power of two, comfortably above any realistic shard count. */
28
+ export declare const DEFAULT_BUCKETS = 4096;
29
+ /**
30
+ * An explicit, persistable map from virtual bucket to shard — the thing that makes a
31
+ * sharded log **rebalanceable** (ADR 0075).
32
+ *
33
+ * Without it, routing is `hash(executionId) % shardCount`, and changing the shard count
34
+ * re-routes almost every execution at once: reads land on a shard that has never seen the
35
+ * data. That is not a rebalance, it is data loss with extra steps.
36
+ *
37
+ * Two things fix that, and this class is both:
38
+ *
39
+ * 1. **Virtual buckets.** Executions hash to one of `buckets` (default 4096), and buckets
40
+ * are assigned to shards by an explicit table. Growing from N to N+1 shards moves
41
+ * roughly `1/(N+1)` of the buckets instead of nearly all of them.
42
+ * 2. **A `migrating` state per bucket.** A bucket being moved names both sides, so the
43
+ * store can keep serving reads and writes for executions that still live on the source
44
+ * while new ones start on the destination.
45
+ *
46
+ * The plan is **immutable** — every mutation returns a new plan. It is a value that
47
+ * multiple nodes must agree on, so it wants to be compared, persisted, and shipped around,
48
+ * not mutated in place.
49
+ */
50
+ export declare class ShardPlan {
51
+ readonly shardCount: number;
52
+ private readonly placements;
53
+ private constructor();
54
+ /** Buckets spread round-robin over `shardCount` shards, all settled. */
55
+ static uniform(shardCount: number, buckets?: number): ShardPlan;
56
+ static fromJSON(json: ShardPlanJSON): ShardPlan;
57
+ toJSON(): ShardPlanJSON;
58
+ get buckets(): number;
59
+ /** No bucket is mid-move. */
60
+ get isStable(): boolean;
61
+ bucketFor(executionId: string): number;
62
+ placementAt(bucket: number): ShardPlacement;
63
+ placementFor(executionId: string): ShardPlacement;
64
+ /** Buckets currently mid-move, in ascending order. */
65
+ migratingBuckets(): number[];
66
+ /**
67
+ * Re-spread buckets over `shardCount` shards, marking every bucket whose owner changes as
68
+ * `migrating(old → new)`. Nothing is copied — the returned plan is only a routing
69
+ * decision. Executions already on the source keep being served there; new ones start on
70
+ * the destination. See {@link ShardedEventStore.migrateExecution} to actually move data,
71
+ * and {@link settled} to finish a bucket.
72
+ *
73
+ * Refuses to re-plan while a migration is outstanding: layering a second move over an
74
+ * unfinished one would produce a bucket whose executions are spread over three shards,
75
+ * which nothing here can resolve. Settle first.
76
+ */
77
+ rebalanced(shardCount: number, options?: {
78
+ allowShrink?: boolean;
79
+ }): ShardPlan;
80
+ /** Mark a migrating bucket as finished, owned by its destination. */
81
+ settled(bucket: number): ShardPlan;
82
+ /** Mark every migrating bucket settled. Only safe once their data has actually moved. */
83
+ settledAll(): ShardPlan;
84
+ /** Every shard index the plan can route to — used to validate against a store's shards. */
85
+ private assertValid;
86
+ }
87
+ //# sourceMappingURL=ShardPlan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShardPlan.d.ts","sourceRoot":"","sources":["../src/ShardPlan.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GACtB;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACpD;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/E,yEAAyE;AACzE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACtF;AAED,+FAA+F;AAC/F,eAAO,MAAM,eAAe,OAAO,CAAC;AAEpC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,SAAS;IAElB,QAAQ,CAAC,UAAU,EAAE,MAAM;IAC3B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAF7B,OAAO;IAKP,wEAAwE;IACxE,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE,MAAwB,GAAG,SAAS;IAahF,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,aAAa,GAAG,SAAS;IAa/C,MAAM,IAAI,aAAa;IAUvB,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,6BAA6B;IAC7B,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAItC,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc;IAM3C,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,cAAc;IAIjD,sDAAsD;IACtD,gBAAgB,IAAI,MAAM,EAAE;IAQ5B;;;;;;;;;;OAUG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,WAAW,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,SAAS;IAwElF,qEAAqE;IACrE,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS;IAQlC,yFAAyF;IACzF,UAAU,IAAI,SAAS;IAQvB,2FAA2F;IAC3F,OAAO,CAAC,WAAW;CAapB"}
@@ -0,0 +1,193 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ShardPlan = exports.DEFAULT_BUCKETS = void 0;
4
+ const SubscriberRegistry_1 = require("./SubscriberRegistry");
5
+ /** Default virtual-bucket count. Power of two, comfortably above any realistic shard count. */
6
+ exports.DEFAULT_BUCKETS = 4096;
7
+ /**
8
+ * An explicit, persistable map from virtual bucket to shard — the thing that makes a
9
+ * sharded log **rebalanceable** (ADR 0075).
10
+ *
11
+ * Without it, routing is `hash(executionId) % shardCount`, and changing the shard count
12
+ * re-routes almost every execution at once: reads land on a shard that has never seen the
13
+ * data. That is not a rebalance, it is data loss with extra steps.
14
+ *
15
+ * Two things fix that, and this class is both:
16
+ *
17
+ * 1. **Virtual buckets.** Executions hash to one of `buckets` (default 4096), and buckets
18
+ * are assigned to shards by an explicit table. Growing from N to N+1 shards moves
19
+ * roughly `1/(N+1)` of the buckets instead of nearly all of them.
20
+ * 2. **A `migrating` state per bucket.** A bucket being moved names both sides, so the
21
+ * store can keep serving reads and writes for executions that still live on the source
22
+ * while new ones start on the destination.
23
+ *
24
+ * The plan is **immutable** — every mutation returns a new plan. It is a value that
25
+ * multiple nodes must agree on, so it wants to be compared, persisted, and shipped around,
26
+ * not mutated in place.
27
+ */
28
+ class ShardPlan {
29
+ shardCount;
30
+ placements;
31
+ constructor(shardCount, placements) {
32
+ this.shardCount = shardCount;
33
+ this.placements = placements;
34
+ }
35
+ /** Buckets spread round-robin over `shardCount` shards, all settled. */
36
+ static uniform(shardCount, buckets = exports.DEFAULT_BUCKETS) {
37
+ if (shardCount < 1)
38
+ throw new Error("ShardPlan requires at least one shard");
39
+ if (buckets < shardCount) {
40
+ throw new Error(`ShardPlan needs at least as many buckets as shards (buckets=${buckets}, shards=${shardCount})`);
41
+ }
42
+ return new ShardPlan(shardCount, Array.from({ length: buckets }, (_, b) => ({ kind: "settled", shard: b % shardCount })));
43
+ }
44
+ static fromJSON(json) {
45
+ if (json.version !== 1)
46
+ throw new Error(`unsupported ShardPlan version ${json.version}`);
47
+ const placements = json.placements.map((p) => "shard" in p
48
+ ? { kind: "settled", shard: p.shard }
49
+ : { kind: "migrating", from: p.from, to: p.to });
50
+ const plan = new ShardPlan(json.shardCount, placements);
51
+ plan.assertValid();
52
+ return plan;
53
+ }
54
+ toJSON() {
55
+ return {
56
+ version: 1,
57
+ shardCount: this.shardCount,
58
+ placements: this.placements.map((p) => p.kind === "settled" ? { shard: p.shard } : { from: p.from, to: p.to }),
59
+ };
60
+ }
61
+ get buckets() {
62
+ return this.placements.length;
63
+ }
64
+ /** No bucket is mid-move. */
65
+ get isStable() {
66
+ return this.placements.every((p) => p.kind === "settled");
67
+ }
68
+ bucketFor(executionId) {
69
+ return (0, SubscriberRegistry_1.bucketOf)(executionId, this.placements.length);
70
+ }
71
+ placementAt(bucket) {
72
+ const placement = this.placements[bucket];
73
+ if (placement === undefined)
74
+ throw new Error(`bucket ${bucket} is out of range`);
75
+ return placement;
76
+ }
77
+ placementFor(executionId) {
78
+ return this.placementAt(this.bucketFor(executionId));
79
+ }
80
+ /** Buckets currently mid-move, in ascending order. */
81
+ migratingBuckets() {
82
+ const out = [];
83
+ for (let b = 0; b < this.placements.length; b++) {
84
+ if (this.placements[b].kind === "migrating")
85
+ out.push(b);
86
+ }
87
+ return out;
88
+ }
89
+ /**
90
+ * Re-spread buckets over `shardCount` shards, marking every bucket whose owner changes as
91
+ * `migrating(old → new)`. Nothing is copied — the returned plan is only a routing
92
+ * decision. Executions already on the source keep being served there; new ones start on
93
+ * the destination. See {@link ShardedEventStore.migrateExecution} to actually move data,
94
+ * and {@link settled} to finish a bucket.
95
+ *
96
+ * Refuses to re-plan while a migration is outstanding: layering a second move over an
97
+ * unfinished one would produce a bucket whose executions are spread over three shards,
98
+ * which nothing here can resolve. Settle first.
99
+ */
100
+ rebalanced(shardCount, options = {}) {
101
+ if (shardCount < 1)
102
+ throw new Error("ShardPlan requires at least one shard");
103
+ if (!this.isStable) {
104
+ throw new Error(`cannot rebalance while ${this.migratingBuckets().length} bucket(s) are still migrating — settle them first`);
105
+ }
106
+ if (shardCount < this.shardCount && options.allowShrink !== true) {
107
+ throw new Error(`rebalancing ${this.shardCount} → ${shardCount} shards removes capacity; pass { allowShrink: true } if that is intended`);
108
+ }
109
+ if (this.placements.length < shardCount) {
110
+ throw new Error(`ShardPlan needs at least as many buckets as shards (buckets=${this.placements.length}, shards=${shardCount})`);
111
+ }
112
+ // MINIMAL MOVEMENT. The naive assignment — `bucket % shardCount` — throws away the
113
+ // existing layout and rehashes everything: measured, growing 4→5 shards moves 80% of
114
+ // buckets and 8→9 moves 89%, which is barely better than the `hash % shardCount`
115
+ // routing virtual buckets exist to escape.
116
+ //
117
+ // Instead: keep every bucket where it is, and move only the EXCESS from shards that now
118
+ // hold more than their fair share onto shards that hold less. That moves ~1/newCount of
119
+ // buckets, which is the theoretical minimum for a uniform target.
120
+ const total = this.placements.length;
121
+ const base = Math.floor(total / shardCount);
122
+ const remainder = total % shardCount;
123
+ // The first `remainder` shards carry one extra bucket, so the targets sum to `total`.
124
+ const targetFor = (shard) => base + (shard < remainder ? 1 : 0);
125
+ const heldBy = new Map();
126
+ for (const [bucket, placement] of this.placements.entries()) {
127
+ const shard = placement.shard;
128
+ const list = heldBy.get(shard);
129
+ if (list === undefined)
130
+ heldBy.set(shard, [bucket]);
131
+ else
132
+ list.push(bucket);
133
+ }
134
+ const owner = this.placements.map((p) => p.shard);
135
+ const orphans = [];
136
+ const kept = new Map();
137
+ for (const [shard, list] of heldBy) {
138
+ if (shard >= shardCount) {
139
+ // The shard is going away entirely (a shrink); everything it holds must move.
140
+ orphans.push(...list);
141
+ continue;
142
+ }
143
+ const target = targetFor(shard);
144
+ kept.set(shard, Math.min(list.length, target));
145
+ if (list.length > target)
146
+ orphans.push(...list.slice(target));
147
+ }
148
+ // Vacancies, in shard order, so the assignment is deterministic across nodes.
149
+ const vacancies = [];
150
+ for (let shard = 0; shard < shardCount; shard++) {
151
+ const have = kept.get(shard) ?? 0;
152
+ for (let i = have; i < targetFor(shard); i++)
153
+ vacancies.push(shard);
154
+ }
155
+ for (const [i, bucket] of orphans.entries()) {
156
+ owner[bucket] = vacancies[i];
157
+ }
158
+ const next = this.placements.map((current, bucket) => {
159
+ const from = current.shard;
160
+ const to = owner[bucket];
161
+ return from === to ? { kind: "settled", shard: to } : { kind: "migrating", from, to };
162
+ });
163
+ return new ShardPlan(shardCount, next);
164
+ }
165
+ /** Mark a migrating bucket as finished, owned by its destination. */
166
+ settled(bucket) {
167
+ const placement = this.placementAt(bucket);
168
+ if (placement.kind === "settled")
169
+ return this;
170
+ const next = [...this.placements];
171
+ next[bucket] = { kind: "settled", shard: placement.to };
172
+ return new ShardPlan(this.shardCount, next);
173
+ }
174
+ /** Mark every migrating bucket settled. Only safe once their data has actually moved. */
175
+ settledAll() {
176
+ if (this.isStable)
177
+ return this;
178
+ return new ShardPlan(this.shardCount, this.placements.map((p) => (p.kind === "settled" ? p : { kind: "settled", shard: p.to })));
179
+ }
180
+ /** Every shard index the plan can route to — used to validate against a store's shards. */
181
+ assertValid() {
182
+ for (const [bucket, placement] of this.placements.entries()) {
183
+ const refs = placement.kind === "settled" ? [placement.shard] : [placement.from, placement.to];
184
+ for (const shard of refs) {
185
+ if (!Number.isInteger(shard) || shard < 0 || shard >= this.shardCount) {
186
+ throw new Error(`ShardPlan bucket ${bucket} references shard ${shard}, outside 0..${this.shardCount - 1}`);
187
+ }
188
+ }
189
+ }
190
+ }
191
+ }
192
+ exports.ShardPlan = ShardPlan;
193
+ //# sourceMappingURL=ShardPlan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShardPlan.js","sourceRoot":"","sources":["../src/ShardPlan.ts"],"names":[],"mappings":"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"}