@shirudo/ddd-kit 2.2.0 → 3.0.0-rc.4

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.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/array/is-built-in.ts","../src/utils/array/deep-equal.ts","../src/utils/array/deep-omit.ts","../src/utils/array/deep-equal-except.ts","../src/value-object/value-object.ts","../src/aggregate/clock.ts","../src/aggregate/domain-event.ts","../src/aggregate/aggregate.ts","../src/core/errors.ts","../src/entity/entity.ts","../src/aggregate/base-aggregate.ts","../src/aggregate/aggregate-root.ts","../src/aggregate/event-sourced-aggregate.ts","../src/app/describe-thrown.ts","../src/app/command-bus.ts","../src/utils/abort.ts","../src/utils/observer.ts","../src/app/handler.ts","../src/app/query-bus.ts","../src/repo/identity-map.ts","../src/app/unit-of-work.ts","../src/domain-state-machine/errors.ts","../src/domain-state-machine/machine-data.ts","../src/domain-state-machine/definition.ts","../src/domain-state-machine/snapshot.ts","../src/domain-state-machine/transition.ts","../src/domain-state-machine/analyzer.ts","../src/domain-state-machine/domain-state-machine.ts","../src/events/event-bus.ts","../src/events/outbox.ts","../src/repo/in-memory-event-store.ts","../src/repo/retrying-scope.ts","../src/validation/vo-validated.ts"],"names":["ownKeys","tagA","tagB","len","clone","ok","err","BaseError","cloned"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Set of `Object.prototype.toString.call(x)` tags that the library treats\n * as built-in atomic types. Members of this set are compared/cloned by\n * reference (or with type-specific logic) rather than walked structurally.\n *\n * Detection is tag-based, since `Object.prototype.toString` gives the same\n * answer across realms (an iframe's `Date` has the same tag as the main\n * window's `Date`), and then brand-verified via internal-slot probes,\n * because `Symbol.toStringTag` lets any plain object claim a built-in tag.\n * The previous strategy also checked `globalThis[name] === constructor`\n * and a `proto !== Object.prototype` heuristic; both broke for cross-realm\n * objects and the latter additionally misclassified ordinary user classes\n * as built-ins.\n */\nconst BUILT_IN_TAGS: ReadonlySet<string> = new Set([\n\t\"[object Date]\",\n\t\"[object RegExp]\",\n\t\"[object Map]\",\n\t\"[object Set]\",\n\t\"[object WeakMap]\",\n\t\"[object WeakSet]\",\n\t\"[object Promise]\",\n\t\"[object Error]\",\n\t\"[object Boolean]\",\n\t\"[object Number]\",\n\t\"[object String]\",\n\t\"[object BigInt]\",\n\t\"[object ArrayBuffer]\",\n\t\"[object SharedArrayBuffer]\",\n\t\"[object DataView]\",\n]);\n\n// Intrinsic probes for brand verification. Each one reads an internal slot\n// and throws a TypeError when `this` is not a genuine instance, the only\n// check a plain object cannot spoof via `Symbol.toStringTag`. Captured once\n// so a tampered prototype cannot redirect the probe later.\nfunction intrinsicGetter(\n\tproto: object,\n\tprop: string,\n): (this: unknown) => unknown {\n\tconst get = Object.getOwnPropertyDescriptor(proto, prop)?.get;\n\t// Spec-guaranteed accessors on intrinsic prototypes: unreachable\n\t// unless the environment itself is broken.\n\tif (!get) throw new Error(`missing intrinsic getter for ${prop}`);\n\treturn get;\n}\n\nconst dateGetTime = Date.prototype.getTime;\nconst mapSizeGet = intrinsicGetter(Map.prototype, \"size\");\nconst setSizeGet = intrinsicGetter(Set.prototype, \"size\");\nconst weakMapHas = WeakMap.prototype.has;\nconst weakSetHas = WeakSet.prototype.has;\nconst dataViewByteLengthGet = intrinsicGetter(DataView.prototype, \"byteLength\");\nconst arrayBufferByteLengthGet = intrinsicGetter(\n\tArrayBuffer.prototype,\n\t\"byteLength\",\n);\nconst sharedArrayBufferByteLengthGet =\n\ttypeof SharedArrayBuffer === \"undefined\"\n\t\t? undefined\n\t\t: intrinsicGetter(SharedArrayBuffer.prototype, \"byteLength\");\nconst regExpSourceGet = intrinsicGetter(RegExp.prototype, \"source\");\nconst booleanValueOf = Boolean.prototype.valueOf;\nconst numberValueOf = Number.prototype.valueOf;\nconst stringValueOf = String.prototype.valueOf;\nconst bigIntValueOf = BigInt.prototype.valueOf;\nconst functionToString = Function.prototype.toString;\nconst PROBE_KEY = {};\n\nconst INTRINSIC_CONSTRUCTOR_NAMES = [\n\t\"Object\",\n\t\"Array\",\n\t\"Date\",\n\t\"RegExp\",\n\t\"Map\",\n\t\"Set\",\n\t\"WeakMap\",\n\t\"WeakSet\",\n\t\"Promise\",\n\t\"Error\",\n\t\"EvalError\",\n\t\"RangeError\",\n\t\"ReferenceError\",\n\t\"SyntaxError\",\n\t\"TypeError\",\n\t\"URIError\",\n\t\"AggregateError\",\n\t\"Boolean\",\n\t\"Number\",\n\t\"String\",\n\t\"BigInt\",\n\t\"ArrayBuffer\",\n\t\"SharedArrayBuffer\",\n\t\"DataView\",\n\t\"Int8Array\",\n\t\"Uint8Array\",\n\t\"Uint8ClampedArray\",\n\t\"Int16Array\",\n\t\"Uint16Array\",\n\t\"Int32Array\",\n\t\"Uint32Array\",\n\t\"Float32Array\",\n\t\"Float64Array\",\n\t\"BigInt64Array\",\n\t\"BigUint64Array\",\n] as const;\n\nconst intrinsicConstructorSources: ReadonlyMap<string, string> = new Map(\n\tINTRINSIC_CONSTRUCTOR_NAMES.flatMap((name) => {\n\t\tconst descriptor = Object.getOwnPropertyDescriptor(globalThis, name);\n\t\tconst intrinsic = descriptor?.value;\n\t\treturn typeof intrinsic === \"function\"\n\t\t\t? [[name, functionToString.call(intrinsic)] as const]\n\t\t\t: [];\n\t}),\n);\nconst intrinsicConstructorSourceSet: ReadonlySet<string> = new Set(\n\tintrinsicConstructorSources.values(),\n);\nconst ERROR_INTRINSIC_NAMES = [\n\t\"Error\",\n\t\"EvalError\",\n\t\"RangeError\",\n\t\"ReferenceError\",\n\t\"SyntaxError\",\n\t\"TypeError\",\n\t\"URIError\",\n\t\"AggregateError\",\n] as const;\n\nexport function isIntrinsicConstructorPrototype(\n\tprototype: object,\n\texpectedName?: string,\n): boolean {\n\tconst constructorDescriptor = Object.getOwnPropertyDescriptor(\n\t\tprototype,\n\t\t\"constructor\",\n\t);\n\tconst candidateConstructor = constructorDescriptor?.value;\n\tif (\n\t\tconstructorDescriptor === undefined ||\n\t\t!(\"value\" in constructorDescriptor) ||\n\t\ttypeof candidateConstructor !== \"function\"\n\t) {\n\t\treturn false;\n\t}\n\n\tlet candidateSource: string;\n\ttry {\n\t\tcandidateSource = functionToString.call(candidateConstructor);\n\t} catch {\n\t\treturn false;\n\t}\n\tconst expectedSource =\n\t\texpectedName === undefined\n\t\t\t? undefined\n\t\t\t: intrinsicConstructorSources.get(expectedName);\n\tif (\n\t\t(expectedSource !== undefined && candidateSource !== expectedSource) ||\n\t\t(expectedSource === undefined &&\n\t\t\t!intrinsicConstructorSourceSet.has(candidateSource))\n\t) {\n\t\treturn false;\n\t}\n\n\tconst nameDescriptor = Object.getOwnPropertyDescriptor(\n\t\tcandidateConstructor,\n\t\t\"name\",\n\t);\n\tconst candidateName =\n\t\tnameDescriptor !== undefined &&\n\t\t\"value\" in nameDescriptor &&\n\t\ttypeof nameDescriptor.value === \"string\"\n\t\t\t? nameDescriptor.value\n\t\t\t: undefined;\n\tconst intrinsicName = expectedName ?? candidateName;\n\tconst intrinsicSource =\n\t\tintrinsicName === undefined\n\t\t\t? undefined\n\t\t\t: intrinsicConstructorSources.get(intrinsicName);\n\treturn (\n\t\tcandidateName === intrinsicName &&\n\t\tintrinsicSource !== undefined &&\n\t\tcandidateSource === intrinsicSource &&\n\t\tObject.getOwnPropertyDescriptor(candidateConstructor, \"prototype\")\n\t\t\t?.value === prototype\n\t);\n}\n\n/**\n * Accepts an intrinsic prototype, optionally behind transparent\n * `Symbol.toStringTag` override layers. A user-defined subclass has its own\n * non-native constructor and is therefore rejected before reaching the\n * intrinsic prototype.\n */\nexport function hasIntrinsicPrototypeChain(\n\tvalue: object,\n\texpectedName?: string,\n): boolean {\n\tconst visited = new WeakSet<object>();\n\tlet prototype = Object.getPrototypeOf(value);\n\n\twhile (prototype !== null && !visited.has(prototype)) {\n\t\tvisited.add(prototype);\n\t\tif (Object.hasOwn(prototype, \"constructor\")) {\n\t\t\treturn isIntrinsicConstructorPrototype(prototype, expectedName);\n\t\t}\n\t\tconst ownKeys = Reflect.ownKeys(prototype);\n\t\tif (ownKeys.length !== 1 || ownKeys[0] !== Symbol.toStringTag) {\n\t\t\treturn false;\n\t\t}\n\t\tprototype = Object.getPrototypeOf(prototype);\n\t}\n\n\treturn false;\n}\n\n/**\n * Tags that `deepEqual` compares BY REFERENCE (its unhandled-built-in\n * fallback) and that `deepOmit` must therefore ALIAS rather than clone:\n * a clone would break `deepEqualExcept(x, x)` reflexivity. Single source\n * of truth so the two modules cannot drift: if `deepEqual` ever learns a\n * by-value comparison for one of these, remove it here and add a clone\n * case in `deepOmit`'s `cloneBuiltIn` in the same change.\n */\nexport const REFERENCE_COMPARED_TAGS: ReadonlySet<string> = new Set([\n\t\"[object Error]\",\n\t\"[object ArrayBuffer]\",\n\t\"[object SharedArrayBuffer]\",\n\t\"[object Promise]\",\n\t\"[object WeakMap]\",\n\t\"[object WeakSet]\",\n]);\n\nexport function findPropertyDescriptor(\n\tvalue: object,\n\tkey: PropertyKey,\n): PropertyDescriptor | undefined {\n\tconst visited = new WeakSet<object>();\n\tlet current: object | null = value;\n\n\twhile (current !== null && !visited.has(current)) {\n\t\tvisited.add(current);\n\t\tconst descriptor = Object.getOwnPropertyDescriptor(current, key);\n\t\tif (descriptor !== undefined) return descriptor;\n\t\tcurrent = Object.getPrototypeOf(current);\n\t}\n\n\treturn undefined;\n}\n\nexport function objectTagWithoutInvokingAccessors(value: object): string {\n\tconst descriptor = findPropertyDescriptor(value, Symbol.toStringTag);\n\treturn descriptor !== undefined && !(\"value\" in descriptor)\n\t\t? \"[object Object]\"\n\t\t: Object.prototype.toString.call(value);\n}\n\nexport type MutableBuiltInTag =\n\t| \"[object Date]\"\n\t| \"[object Map]\"\n\t| \"[object Set]\";\n\nexport function builtInTagWithoutInvokingAccessors(\n\tvalue: object,\n): string | undefined {\n\tif (ArrayBuffer.isView(value)) {\n\t\treturn hasBrand(value, \"[object DataView]\")\n\t\t\t? \"[object DataView]\"\n\t\t\t: \"[object TypedArray]\";\n\t}\n\n\tconst descriptor = findPropertyDescriptor(value, Symbol.toStringTag);\n\tif (descriptor !== undefined && !(\"value\" in descriptor)) {\n\t\treturn builtInTagFromBrand(value);\n\t}\n\n\tconst tag = Object.prototype.toString.call(value);\n\tif (BUILT_IN_TAGS.has(tag) && hasBrand(value, tag)) {\n\t\treturn tag;\n\t}\n\treturn descriptor === undefined ? undefined : builtInTagFromBrand(value);\n}\n\nexport function mutableBuiltInTagWithoutInvokingAccessors(\n\tvalue: object,\n): MutableBuiltInTag | undefined {\n\tconst tag = builtInTagWithoutInvokingAccessors(value);\n\treturn tag === \"[object Date]\" ||\n\t\ttag === \"[object Map]\" ||\n\t\ttag === \"[object Set]\"\n\t\t? tag\n\t\t: undefined;\n}\n\nfunction builtInTagFromBrand(value: object): string | undefined {\n\tif (hasBrand(value, \"[object Date]\")) return \"[object Date]\";\n\tif (hasBrand(value, \"[object RegExp]\")) return \"[object RegExp]\";\n\tif (hasBrand(value, \"[object Map]\")) return \"[object Map]\";\n\tif (hasBrand(value, \"[object Set]\")) return \"[object Set]\";\n\tif (hasBrand(value, \"[object WeakMap]\")) return \"[object WeakMap]\";\n\tif (hasBrand(value, \"[object WeakSet]\")) return \"[object WeakSet]\";\n\tif (hasBrand(value, \"[object DataView]\")) return \"[object DataView]\";\n\tif (hasBrand(value, \"[object ArrayBuffer]\")) return \"[object ArrayBuffer]\";\n\tif (hasBrand(value, \"[object SharedArrayBuffer]\")) {\n\t\treturn \"[object SharedArrayBuffer]\";\n\t}\n\tif (hasBrand(value, \"[object Boolean]\")) return \"[object Boolean]\";\n\tif (hasBrand(value, \"[object Number]\")) return \"[object Number]\";\n\tif (hasBrand(value, \"[object String]\")) return \"[object String]\";\n\tif (hasBrand(value, \"[object BigInt]\")) return \"[object BigInt]\";\n\tif (hasNativePrototype(value, \"Promise\")) return \"[object Promise]\";\n\tif (hasNativePrototype(value, \"Error\")) return \"[object Error]\";\n\treturn undefined;\n}\n\nfunction hasNativePrototype(value: object, expectedName: string): boolean {\n\tconst visited = new WeakSet<object>();\n\tlet prototype = Object.getPrototypeOf(value);\n\n\twhile (prototype !== null && !visited.has(prototype)) {\n\t\tvisited.add(prototype);\n\t\tif (isIntrinsicConstructorPrototype(prototype, expectedName)) {\n\t\t\treturn true;\n\t\t}\n\t\tprototype = Object.getPrototypeOf(prototype);\n\t}\n\treturn false;\n}\n\n/**\n * Verifies that `obj` genuinely is the type its tag claims, via an\n * internal-slot probe. Promise and Error have no side-effect-free standard\n * probe, so their visible tags remain conservative; masked instances are\n * identified separately through their native prototype chain.\n */\nfunction hasBrand(obj: object, tag: string): boolean {\n\ttry {\n\t\tswitch (tag) {\n\t\t\tcase \"[object Date]\":\n\t\t\t\tdateGetTime.call(obj);\n\t\t\t\treturn true;\n\t\t\tcase \"[object RegExp]\":\n\t\t\t\tregExpSourceGet.call(obj);\n\t\t\t\treturn true;\n\t\t\tcase \"[object Map]\":\n\t\t\t\tmapSizeGet.call(obj);\n\t\t\t\treturn true;\n\t\t\tcase \"[object Set]\":\n\t\t\t\tsetSizeGet.call(obj);\n\t\t\t\treturn true;\n\t\t\tcase \"[object WeakMap]\":\n\t\t\t\tweakMapHas.call(obj, PROBE_KEY);\n\t\t\t\treturn true;\n\t\t\tcase \"[object WeakSet]\":\n\t\t\t\tweakSetHas.call(obj, PROBE_KEY);\n\t\t\t\treturn true;\n\t\t\tcase \"[object DataView]\":\n\t\t\t\tdataViewByteLengthGet.call(obj);\n\t\t\t\treturn true;\n\t\t\tcase \"[object ArrayBuffer]\":\n\t\t\t\tarrayBufferByteLengthGet.call(obj);\n\t\t\t\treturn true;\n\t\t\tcase \"[object SharedArrayBuffer]\":\n\t\t\t\tif (!sharedArrayBufferByteLengthGet) return false;\n\t\t\t\tsharedArrayBufferByteLengthGet.call(obj);\n\t\t\t\treturn true;\n\t\t\tcase \"[object Boolean]\":\n\t\t\t\tbooleanValueOf.call(obj);\n\t\t\t\treturn true;\n\t\t\tcase \"[object Number]\":\n\t\t\t\tnumberValueOf.call(obj);\n\t\t\t\treturn true;\n\t\t\tcase \"[object String]\":\n\t\t\t\tstringValueOf.call(obj);\n\t\t\t\treturn true;\n\t\t\tcase \"[object BigInt]\":\n\t\t\t\tbigIntValueOf.call(obj);\n\t\t\t\treturn true;\n\t\t\tcase \"[object Promise]\":\n\t\t\t\treturn hasNativePrototype(obj, \"Promise\");\n\t\t\tcase \"[object Error]\":\n\t\t\t\treturn ERROR_INTRINSIC_NAMES.some((name) =>\n\t\t\t\t\thasNativePrototype(obj, name),\n\t\t\t\t);\n\t\t\tdefault:\n\t\t\t\treturn false;\n\t\t}\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Returns `true` when `obj` is a built-in JavaScript type that should be\n * treated atomically (compared/cloned as a unit, not walked structurally).\n * Cross-realm safe, and brand-verified: a plain object spoofing a built-in\n * tag via `Symbol.toStringTag` returns `false` and is walked structurally\n * like any other plain object instead of crashing type-specific code.\n *\n * @param obj - The object to classify\n * @param tag - The result of `Object.prototype.toString.call(obj)`, passed\n * in so callers that already computed it don't pay twice\n */\nexport function isBuiltInObject(obj: object, tag: string): boolean {\n\t// ArrayBuffer views (DataView + all TypedArrays, present and future)\n\t// carry an unforgeable internal slot, the strongest brand check.\n\tif (ArrayBuffer.isView(obj)) return true;\n\t// A built-in-looking TypedArray tag WITHOUT the view brand is spoofed.\n\tif (tag.endsWith(\"Array]\")) return false;\n\treturn BUILT_IN_TAGS.has(tag) && hasBrand(obj, tag);\n}\n","import { isBuiltInObject } from \"./is-built-in\";\n\nconst objProto = Object.prototype;\nconst objToString = objProto.toString;\nconst objHasOwn = objProto.hasOwnProperty;\n\n/**\n * SameValueZero: `===` plus NaN-equals-NaN (and `+0 === -0`, unlike\n * `Object.is`). The numeric semantics `deepEqual` documents for primitives,\n * applied consistently inside TypedArrays, Dates and Number wrappers.\n */\nfunction sameValueZero(a: unknown, b: unknown): boolean {\n\treturn (\n\t\ta === b || (Number.isNaN(a as number) && Number.isNaN(b as number))\n\t);\n}\n\n/**\n * Performs a deep equality check between two values.\n *\n * This function compares values recursively, handling:\n * - Primitives (with special handling for NaN)\n * - Arrays (nested arrays supported)\n * - Objects (plain objects and class instances)\n * - TypedArrays (Uint8Array, Int32Array, etc.)\n * - DataView\n * - Maps and Sets\n * - Dates and RegExp\n * - Wrapper objects (Boolean, Number, String)\n * - Circular references (detected and handled)\n *\n * @param a - The first value to compare\n * @param b - The second value to compare\n * @returns `true` if the values are deeply equal, `false` otherwise\n *\n * @example\n * ```ts\n * deepEqual([1, 2, 3], [1, 2, 3]); // true\n * deepEqual({ a: 1, b: [2, 3] }, { a: 1, b: [2, 3] }); // true\n * deepEqual(NaN, NaN); // true\n * deepEqual([1, 2], [1, 2, 3]); // false\n * ```\n */\nexport function deepEqual(a: unknown, b: unknown): boolean {\n\treturn deepEqualInner(a, b, new WeakMap<object, WeakSet<object>>());\n}\n\n/**\n * Visited pair tracker for cycle detection. The cache is a pair-set:\n * for every left-hand object we keep the set of right-hand objects we\n * have already paired it with. Encountering an already-known pair returns\n * the cycle hypothesis (assume equal); a new (a, b') pair with b' ≠ any\n * previously cached b for that a is walked normally. The previous shape\n * (`WeakMap<object, object>`) could only remember one B per A, which\n * could short-circuit unrelated comparisons that happened to revisit the\n * same A with a different B.\n */\ntype VisitedPairs = WeakMap<object, WeakSet<object>>;\n\n/**\n * Internal recursive function for deep equality comparison.\n *\n * @internal\n */\nfunction deepEqualInner(\n\ta: unknown,\n\tb: unknown,\n\tvisited: VisitedPairs,\n): boolean {\n\t// 1. Fast path: reference equality\n\tif (a === b) return true;\n\n\tconst typeA = typeof a;\n\tconst typeB = typeof b;\n\n\t// 2. If one is not an object → primitive / function\n\tif (typeA !== \"object\" || a === null || typeB !== \"object\" || b === null) {\n\t\t// Special case: NaN should be equal\n\t\tif (typeA === \"number\" && typeB === \"number\") {\n\t\t\treturn Number.isNaN(a as number) && Number.isNaN(b as number);\n\t\t}\n\t\t// Everything else is directly unequal with !== (including functions)\n\t\treturn false;\n\t}\n\n\t// From here on: both are non-null objects\n\n\tconst objA = a as object;\n\tconst objB = b as object;\n\n\t// 3. Cycles: already seen this exact (a, b) pair?\n\tlet cachedBs = visited.get(objA);\n\tif (cachedBs?.has(objB)) {\n\t\t// Cycle hypothesis: pretend equal so the walk can terminate. If the\n\t\t// structure is actually unequal elsewhere, a different recursive\n\t\t// branch will surface the mismatch.\n\t\treturn true;\n\t}\n\tif (!cachedBs) {\n\t\tcachedBs = new WeakSet();\n\t\tvisited.set(objA, cachedBs);\n\t}\n\tcachedBs.add(objB);\n\n\t// 4. Handle Typed Arrays / DataView first\n\tif (ArrayBuffer.isView(objA) || ArrayBuffer.isView(objB)) {\n\t\tif (!ArrayBuffer.isView(objA) || !ArrayBuffer.isView(objB)) return false;\n\n\t\tconst tagA = objToString.call(objA);\n\t\tconst tagB = objToString.call(objB);\n\t\tif (tagA !== tagB) return false;\n\n\t\t// DataView: compare byte by byte\n\t\tif (tagA === \"[object DataView]\") {\n\t\t\tconst viewA = objA as DataView;\n\t\t\tconst viewB = objB as DataView;\n\t\t\tif (viewA.byteLength !== viewB.byteLength) return false;\n\n\t\t\tconst len = viewA.byteLength;\n\t\t\tfor (let i = 0; i < len; i++) {\n\t\t\t\tif (viewA.getUint8(i) !== viewB.getUint8(i)) return false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\t// Typed Arrays: element by element (length + numeric index access are\n\t\t// part of the TypedArray contract; the indexed read is sound).\n\t\tconst arrA = objA as unknown as Record<number, unknown> & { length: number };\n\t\tconst arrB = objB as unknown as Record<number, unknown> & { length: number };\n\n\t\tconst len = arrA.length;\n\t\tif (len !== arrB.length) return false;\n\n\t\tfor (let i = 0; i < len; i++) {\n\t\t\tif (!sameValueZero(arrA[i], arrB[i])) return false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t// 5. Arrays: `Array.isArray` is brand-based and immune to\n\t// `Symbol.toStringTag` spoofing (a spoofed tag would otherwise route a\n\t// real array away from element comparison, or a plain object into it).\n\tif (Array.isArray(objA) || Array.isArray(objB)) {\n\t\tif (!Array.isArray(objA) || !Array.isArray(objB)) return false;\n\t\tif (objA.length !== objB.length) return false;\n\n\t\tconst keysA = Reflect.ownKeys(objA).filter((key) => key !== \"length\");\n\t\tconst keysB = Reflect.ownKeys(objB).filter((key) => key !== \"length\");\n\t\tif (keysA.length !== keysB.length) return false;\n\n\t\tconst arrA = objA as unknown as Record<PropertyKey, unknown>;\n\t\tconst arrB = objB as unknown as Record<PropertyKey, unknown>;\n\t\tfor (const key of keysA) {\n\t\t\tif (!objHasOwn.call(objB, key)) return false;\n\t\t\t// Read the element by access (invoking any getter) rather than\n\t\t\t// comparing accessor descriptors by function identity, so an array\n\t\t\t// index defined as a getter is compared by the value it yields,\n\t\t\t// matching how comparePlainObjects treats accessor properties.\n\t\t\t// Sparse holes stay observable through the key-set comparison above:\n\t\t\t// a hole leaves no own key, so two arrays that differ by a hole vs\n\t\t\t// an explicit undefined have different key sets.\n\t\t\tif (!deepEqualInner(arrA[key], arrB[key], visited)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t// 6. Tag-based type detection (robust across realms), brand-verified:\n\t// a plain object spoofing a built-in tag is compared as a plain object\n\t// instead of crashing type-specific code below.\n\tconst tagA = objToString.call(objA);\n\tconst tagB = objToString.call(objB);\n\tif (tagA !== tagB) return false;\n\n\tconst builtInA = isBuiltInObject(objA, tagA);\n\tconst builtInB = isBuiltInObject(objB, tagB);\n\t// A genuine built-in never equals a spoofed lookalike.\n\tif (builtInA !== builtInB) return false;\n\n\tif (!builtInA) {\n\t\treturn comparePlainObjects(objA, objB, visited);\n\t}\n\n\tswitch (tagA) {\n\t\tcase \"[object Map]\": {\n\t\t\tconst mapA = objA as Map<unknown, unknown>;\n\t\t\tconst mapB = objB as Map<unknown, unknown>;\n\n\t\t\tif (mapA.size !== mapB.size) return false;\n\n\t\t\tfor (const [key, valA] of mapA) {\n\t\t\t\t// Map keys according to JS semantics: reference / SameValueZero\n\t\t\t\tif (!mapB.has(key)) return false;\n\t\t\t\tconst valB = mapB.get(key);\n\t\t\t\tif (!deepEqualInner(valA, valB, visited)) return false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tcase \"[object Set]\": {\n\t\t\tconst setA = objA as Set<unknown>;\n\t\t\tconst setB = objB as Set<unknown>;\n\n\t\t\tif (setA.size !== setB.size) return false;\n\n\t\t\t// Set elements: same reference (JS semantics)\n\t\t\tfor (const value of setA) {\n\t\t\t\tif (!setB.has(value)) return false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tcase \"[object Date]\": {\n\t\t\t// SameValueZero so two invalid Dates (getTime() === NaN) compare\n\t\t\t// equal, matching the primitive NaN semantics.\n\t\t\treturn sameValueZero((objA as Date).getTime(), (objB as Date).getTime());\n\t\t}\n\n\t\tcase \"[object RegExp]\": {\n\t\t\tconst regA = objA as RegExp;\n\t\t\tconst regB = objB as RegExp;\n\t\t\treturn regA.source === regB.source && regA.flags === regB.flags;\n\t\t}\n\n\t\tcase \"[object Boolean]\":\n\t\tcase \"[object Number]\":\n\t\tcase \"[object String]\":\n\t\tcase \"[object BigInt]\": {\n\t\t\t// Wrapper objects (Boolean/Number/String/BigInt); SameValueZero so\n\t\t\t// two NaN Number wrappers compare equal.\n\t\t\treturn sameValueZero(\n\t\t\t\t(objA as { valueOf(): unknown }).valueOf(),\n\t\t\t\t(objB as { valueOf(): unknown }).valueOf(),\n\t\t\t);\n\t\t}\n\n\t\tdefault: {\n\t\t\t// Unhandled but brand-trusted built-ins: compared by reference.\n\t\t\t// Their internal structure is unknown, and this keeps new\n\t\t\t// built-ins from falling through to plain-object comparison.\n\t\t\t// This branch IS the REFERENCE_COMPARED_TAGS contract exported\n\t\t\t// from is-built-in.ts (and consumed by deepOmit's cloneBuiltIn):\n\t\t\t// adding a by-value case above means removing the tag there.\n\t\t\treturn objA === objB;\n\t\t}\n\t}\n}\n\n/**\n * Plain / custom objects: compare own enumerable string keys + own symbol\n * keys and their values. Used both as the final fallback and for objects\n * whose built-in-looking tag failed brand verification.\n */\nfunction comparePlainObjects(\n\tobjA: object,\n\tobjB: object,\n\tvisited: VisitedPairs,\n): boolean {\n\tconst recA = objA as Record<string | symbol, unknown>;\n\tconst recB = objB as Record<string | symbol, unknown>;\n\n\t// Own string keys including non-enumerable ones: symbols are already\n\t// counted through Object.getOwnPropertySymbols (which ignores\n\t// enumerability), so using Object.keys here would let two objects that\n\t// differ only by a non-enumerable string property compare equal.\n\tconst stringKeysA = Object.getOwnPropertyNames(objA);\n\tconst stringKeysB = Object.getOwnPropertyNames(objB);\n\tif (stringKeysA.length !== stringKeysB.length) return false;\n\n\tconst symbolKeysA = Object.getOwnPropertySymbols(objA);\n\tconst symbolKeysB = Object.getOwnPropertySymbols(objB);\n\tif (symbolKeysA.length !== symbolKeysB.length) return false;\n\n\t// Build the B-side symbol set once; the previous impl rebuilt the\n\t// array and ran .includes per key, which was quadratic.\n\tconst symbolKeysBSet = new Set<symbol>(symbolKeysB);\n\n\tfor (const key of stringKeysA) {\n\t\tif (!objHasOwn.call(objB, key)) return false;\n\t}\n\tfor (const key of symbolKeysA) {\n\t\tif (!symbolKeysBSet.has(key)) return false;\n\t}\n\n\tfor (const key of stringKeysA) {\n\t\tif (!deepEqualInner(recA[key], recB[key], visited)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\tfor (const key of symbolKeysA) {\n\t\tif (!deepEqualInner(recA[key], recB[key], visited)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n","import { isBuiltInObject, REFERENCE_COMPARED_TAGS } from \"./is-built-in\";\n\nexport type Key = string | symbol;\nexport type PathSegment = string | number | symbol;\n\nexport interface DeepOmitOptions {\n\t/**\n\t * Keys to ignore everywhere in the object tree.\n\t * Only applies to object properties, not Map/Set/TypedArray contents.\n\t */\n\treadonly ignoreKeys?: readonly Key[];\n\n\t/**\n\t * Fine-grained control: Key + path (without current key).\n\t * Example path: [\"user\", \"meta\", 0, \"data\"]\n\t */\n\treadonly ignoreKeyPredicate?: (\n\t\tkey: Key,\n\t\tpath: readonly PathSegment[],\n\t) => boolean;\n}\n\n/**\n * Creates a deep copy of `value` with certain keys removed according to the\n * provided rules.\n *\n * Walks the object tree and skips keys that match `ignoreKeys` /\n * `ignoreKeyPredicate`. Built-in atomic types that `deepEqual` compares by\n * value (Date, RegExp, Map, Set, TypedArrays, DataView) are cloned by type\n * rather than walked, since their internal structure has no key filtering to\n * apply. Types that `deepEqual` compares by reference (Error, ArrayBuffer,\n * SharedArrayBuffer, Promise, WeakMap, WeakSet) are passed through by\n * reference, so `deepEqualExcept(x, x)` stays reflexive. Cycles are\n * preserved: a cycle `a → a` clones to `a' → a'`. Arrays retain sparse\n * holes and all non-ignored own properties, including symbol keys.\n *\n * **Shared references.** Without `ignoreKeyPredicate`, an object reached\n * via several paths dedupes to a single clone. With a predicate, each\n * path gets its own clone, because the predicate may decide differently per\n * path, so memoising the first path's result would be wrong. This is\n * inherently exponential for diamond-shaped sharing (a node reachable\n * via 2^n paths is cloned 2^n times); the walk aborts with a descriptive\n * error after {@link PATH_SENSITIVE_VISIT_BUDGET} node visits instead of\n * hanging the process.\n *\n * **Prototype-pollution safety.** `__proto__` and `constructor` keys\n * encountered as *own* properties of the input (typical of `JSON.parse`\n * output) are copied as inert data properties via `Object.defineProperty`\n * so the clone graph cannot bleed into `Object.prototype`.\n *\n * **Class instances.** When the input is a class instance, the clone is\n * built via `Object.create(proto)` so the prototype is preserved, but the\n * constructor is NOT re-invoked, so class invariants enforced by the\n * constructor are not re-checked. `deepOmit` is therefore best used for\n * comparison/serialisation (`voEqualsExcept`, `deepEqualExcept`), not as\n * a general-purpose clone for behaviour-carrying objects.\n *\n * @param value - The value to create a deep copy from\n * @param options - Options specifying which keys to ignore\n * @returns A deep copy of `value` with specified keys removed\n */\nexport function deepOmit<T>(value: T, options: DeepOmitOptions): T {\n\tconst visited = new WeakMap<object, unknown>();\n\t// Materialise ignoreKeys as a Set once so the inner loop probes O(1).\n\tconst ignoreKeys = options.ignoreKeys\n\t\t? new Set<Key>(options.ignoreKeys)\n\t\t: undefined;\n\t// With a path-sensitive predicate, a clone computed under one path must\n\t// NOT be reused for the same object reached via another path (the\n\t// predicate may decide differently there). The cache then only tracks\n\t// in-progress ancestors (pure cycle detection) instead of memoising\n\t// completed subtrees. Without a predicate, results are path-independent\n\t// and shared references keep deduplicating to one clone. The budget\n\t// bounds the per-path expansion (exponential on diamond sharing).\n\tconst budget = options.ignoreKeyPredicate ? { visits: 0 } : undefined;\n\treturn omitInternal(value, options, ignoreKeys, [], visited, budget) as T;\n}\n\n/**\n * Maximum object-node visits for a single path-sensitive `deepOmit` walk.\n * Per-path cloning expands exponentially on diamond-shaped sharing; past\n * this bound the walk throws instead of hanging the process. One million\n * visits covers any realistically tree-shaped input.\n */\nconst PATH_SENSITIVE_VISIT_BUDGET = 1_000_000;\n\nfunction omitInternal(\n\tvalue: unknown,\n\toptions: DeepOmitOptions,\n\tignoreKeys: ReadonlySet<Key> | undefined,\n\tpath: PathSegment[],\n\tvisited: WeakMap<object, unknown>,\n\tbudget: { visits: number } | undefined,\n): unknown {\n\tif (value === null) return value;\n\tif (typeof value !== \"object\") return value;\n\n\tconst obj = value as object;\n\n\t// Cycles (and, in the path-independent case, shared references): return\n\t// the cached clone. Use `has` (not `cached !== undefined`) so a\n\t// legitimately-undefined cached clone would not be misclassified as\n\t// \"never seen\".\n\tif (visited.has(obj)) {\n\t\treturn visited.get(obj);\n\t}\n\n\tif (budget && ++budget.visits > PATH_SENSITIVE_VISIT_BUDGET) {\n\t\tthrow new Error(\n\t\t\t`deepOmit: exceeded ${PATH_SENSITIVE_VISIT_BUDGET} node visits. ` +\n\t\t\t\t`With ignoreKeyPredicate, objects reached via shared references ` +\n\t\t\t\t`are cloned once per path (the predicate may decide differently ` +\n\t\t\t\t`per path), which expands exponentially on diamond-shaped ` +\n\t\t\t\t`sharing. Restructure the input to a tree, or use ignoreKeys ` +\n\t\t\t\t`for path-independent filtering.`,\n\t\t);\n\t}\n\n\t// Arrays: recursively process every own property so sparse holes, custom\n\t// properties, symbols, and descriptors remain observable to deepEqual.\n\t// `Array.isArray` is brand-based and immune to `Symbol.toStringTag` spoofing.\n\tif (Array.isArray(obj)) {\n\t\tconst arr = obj as unknown[];\n\t\tconst clone: unknown[] = new Array(arr.length);\n\t\tconst lengthDescriptor = Object.getOwnPropertyDescriptor(arr, \"length\");\n\t\tvisited.set(obj, clone);\n\t\tfor (const key of Reflect.ownKeys(arr)) {\n\t\t\tif (key === \"length\") continue;\n\t\t\tconst segment = arrayPathSegment(key);\n\t\t\t// Key filtering never applies to array elements (numeric indices):\n\t\t\t// dropping an element would leave a hole and make structurally\n\t\t\t// different arrays compare equal through deepEqualExcept. It still\n\t\t\t// applies to custom (non-index) own properties on the array.\n\t\t\tif (\n\t\t\t\ttypeof segment !== \"number\" &&\n\t\t\t\tshouldIgnoreKey(key, path, ignoreKeys, options)\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(arr, key);\n\t\t\tif (descriptor === undefined) continue;\n\n\t\t\tpath.push(segment);\n\t\t\tif (\"value\" in descriptor) {\n\t\t\t\tdescriptor.value = omitInternal(\n\t\t\t\t\tdescriptor.value,\n\t\t\t\t\toptions,\n\t\t\t\t\tignoreKeys,\n\t\t\t\t\tpath,\n\t\t\t\t\tvisited,\n\t\t\t\t\tbudget,\n\t\t\t\t);\n\t\t\t}\n\t\t\tObject.defineProperty(clone, key, descriptor);\n\t\t\tpath.pop();\n\t\t}\n\t\tif (lengthDescriptor !== undefined) {\n\t\t\tObject.defineProperty(clone, \"length\", lengthDescriptor);\n\t\t}\n\t\tif (budget) visited.delete(obj);\n\t\treturn clone;\n\t}\n\n\tconst tag = Object.prototype.toString.call(obj);\n\n\t// Built-in atomic types: clone by type rather than walk. The detection\n\t// is brand-verified: a plain object spoofing a built-in tag falls\n\t// through to the plain-object walk below.\n\tif (isBuiltInObject(obj, tag)) {\n\t\tconst builtInClone = cloneBuiltIn(obj, tag);\n\t\tvisited.set(obj, builtInClone);\n\t\treturn builtInClone;\n\t}\n\n\t// Plain / Custom Objects: filter keys, recursively process values.\n\tconst clone = Object.create(Object.getPrototypeOf(obj));\n\tvisited.set(obj, clone);\n\n\tconst stringKeys = Object.keys(obj);\n\tconst symbolKeys = Object.getOwnPropertySymbols(obj);\n\n\tfor (const key of stringKeys) {\n\t\tif (shouldIgnoreKey(key, path, ignoreKeys, options)) continue;\n\t\tpath.push(key);\n\t\tassignOwn(\n\t\t\tclone,\n\t\t\tkey,\n\t\t\tomitInternal(\n\t\t\t\t(obj as Record<PropertyKey, unknown>)[key],\n\t\t\t\toptions,\n\t\t\t\tignoreKeys,\n\t\t\t\tpath,\n\t\t\t\tvisited,\n\t\t\t\tbudget,\n\t\t\t),\n\t\t);\n\t\tpath.pop();\n\t}\n\tfor (const key of symbolKeys) {\n\t\tif (shouldIgnoreKey(key, path, ignoreKeys, options)) continue;\n\t\tpath.push(key);\n\t\tassignOwn(\n\t\t\tclone,\n\t\t\tkey,\n\t\t\tomitInternal(\n\t\t\t\t(obj as Record<PropertyKey, unknown>)[key],\n\t\t\t\toptions,\n\t\t\t\tignoreKeys,\n\t\t\t\tpath,\n\t\t\t\tvisited,\n\t\t\t\tbudget,\n\t\t\t),\n\t\t);\n\t\tpath.pop();\n\t}\n\n\tif (budget) visited.delete(obj);\n\treturn clone;\n}\n\nfunction arrayPathSegment(key: string | symbol): PathSegment {\n\tif (typeof key === \"symbol\") return key;\n\tconst index = Number(key);\n\treturn Number.isInteger(index) &&\n\t\tindex >= 0 &&\n\t\tindex < 4_294_967_295 &&\n\t\tString(index) === key\n\t\t? index\n\t\t: key;\n}\n\n/**\n * Assigns `value` as an OWN data property on `target` without going through\n * any inherited setter; critically, it never invokes the `__proto__` setter\n * even when `key === \"__proto__\"`. Required to defeat prototype-pollution\n * payloads that ship `__proto__` as a parsed-JSON own key.\n */\nfunction assignOwn(target: object, key: PropertyKey, value: unknown): void {\n\tObject.defineProperty(target, key, {\n\t\tvalue,\n\t\twritable: true,\n\t\tenumerable: true,\n\t\tconfigurable: true,\n\t});\n}\n\n/**\n * Clones a built-in atomic type by case. Falls back to `structuredClone`\n * for anything not explicitly enumerated (e.g. DataView, TypedArrays,\n * Boolean/Number/String wrappers, all of which `deepEqual` compares by\n * value). Types that `deepEqual` compares BY REFERENCE (the shared\n * {@link REFERENCE_COMPARED_TAGS} set) are passed through by reference\n * instead; cloning them would make `deepEqualExcept(x, x)` false.\n * Promise/WeakMap/WeakSet additionally cannot be cloned at all\n * (`structuredClone` rejects them).\n */\nfunction cloneBuiltIn(obj: object, tag: string): unknown {\n\tif (REFERENCE_COMPARED_TAGS.has(tag)) return obj;\n\tswitch (tag) {\n\t\tcase \"[object Date]\":\n\t\t\treturn new Date((obj as Date).getTime());\n\t\tcase \"[object RegExp]\": {\n\t\t\tconst re = obj as RegExp;\n\t\t\tconst copy = new RegExp(re.source, re.flags);\n\t\t\tcopy.lastIndex = re.lastIndex;\n\t\t\treturn copy;\n\t\t}\n\t\tcase \"[object Map]\": {\n\t\t\tconst m = obj as Map<unknown, unknown>;\n\t\t\treturn new Map(m);\n\t\t}\n\t\tcase \"[object Set]\": {\n\t\t\tconst s = obj as Set<unknown>;\n\t\t\treturn new Set(s);\n\t\t}\n\t\tdefault:\n\t\t\treturn structuredClone(obj);\n\t}\n}\n\nfunction shouldIgnoreKey(\n\tkey: Key,\n\tpath: readonly PathSegment[],\n\tignoreKeys: ReadonlySet<Key> | undefined,\n\toptions: DeepOmitOptions,\n): boolean {\n\tif (ignoreKeys?.has(key)) return true;\n\tif (options.ignoreKeyPredicate?.(key, path)) return true;\n\treturn false;\n}\n","import { deepEqual } from \"./deep-equal\";\nimport { type DeepOmitOptions, deepOmit } from \"./deep-omit\";\n\nexport type DeepEqualExceptOptions = DeepOmitOptions;\n\n/**\n * Performs a deep equality comparison between two values after omitting specified keys.\n * \n * This function first removes the specified keys from both values using `deepOmit`,\n * then performs a deep equality check using `deepEqual`.\n * \n * @param a - The first value to compare\n * @param b - The second value to compare\n * @param options - Options specifying which keys to omit before comparison\n * @returns `true` if the values are deeply equal after omitting specified keys, `false` otherwise\n * \n * @example\n * ```ts\n * const obj1 = { id: 1, name: \"Alice\", updatedAt: \"2024-01-01\" };\n * const obj2 = { id: 2, name: \"Alice\", updatedAt: \"2024-01-02\" };\n * \n * deepEqualExcept(obj1, obj2, { ignoreKeys: [\"id\", \"updatedAt\"] }); // true\n * ```\n */\nexport function deepEqualExcept(\n\ta: unknown,\n\tb: unknown,\n\toptions: DeepEqualExceptOptions,\n): boolean {\n\tconst prunedA = deepOmit(a, options);\n\tconst prunedB = deepOmit(b, options);\n\treturn deepEqual(prunedA, prunedB);\n}\n","import { deepEqual } from \"../utils/array/deep-equal\";\nimport {\n deepEqualExcept,\n type DeepEqualExceptOptions,\n} from \"../utils/array/deep-equal-except\";\nimport {\n builtInTagWithoutInvokingAccessors,\n hasIntrinsicPrototypeChain,\n isIntrinsicConstructorPrototype,\n mutableBuiltInTagWithoutInvokingAccessors,\n} from \"../utils/array/is-built-in\";\nimport { err, ok, type Result } from \"@shirudo/result\";\n\n// ============================================================================\n// Functional Value Object API\n// ============================================================================\n\nexport type VO<T> = Readonly<T>;\n\n/**\n * `Object.freeze` does not protect internal slots: a frozen Date still\n * accepts `setTime`, a frozen Map still accepts `set`. To make the\n * \"deeply immutable\" guarantee real, the mutator methods are shadowed\n * with own throwing functions BEFORE the freeze. The shadows are\n * non-enumerable, so they are invisible to `Object.keys`/spread (deep\n * equality is unaffected) and `structuredClone` drops them (a `vo()`\n * round-trip never sees them).\n */\nconst DATE_MUTATORS: readonly string[] = [\n \"setTime\",\n \"setMilliseconds\",\n \"setUTCMilliseconds\",\n \"setSeconds\",\n \"setUTCSeconds\",\n \"setMinutes\",\n \"setUTCMinutes\",\n \"setHours\",\n \"setUTCHours\",\n \"setDate\",\n \"setUTCDate\",\n \"setMonth\",\n \"setUTCMonth\",\n \"setFullYear\",\n \"setUTCFullYear\",\n \"setYear\",\n];\n\n// One thrower function per (typeName, method) for the lifetime of the\n// module: createDomainEvent deep-freezes a Date per event, so fresh\n// per-instance closures would be pure allocation churn on a hot path.\nconst mutationThrowers = new Map<string, () => never>();\nconst mapEntries = Map.prototype.entries;\nconst setValues = Set.prototype.values;\n\nfunction mutationThrower(typeName: string, method: string): () => never {\n const key = `${typeName}.${method}`;\n let thrower = mutationThrowers.get(key);\n if (!thrower) {\n thrower = function throwFrozenMutation(): never {\n throw new TypeError(\n `Cannot call ${method}() on a ${typeName} inside a deeply frozen value`,\n );\n };\n mutationThrowers.set(key, thrower);\n }\n return thrower;\n}\n\n// Reused descriptor: Object.defineProperty reads it synchronously, so a\n// single mutable module-level object avoids one allocation per method.\nconst shadowDescriptor = {\n value: undefined as unknown,\n writable: false,\n enumerable: false,\n configurable: false,\n};\n\nfunction shadowMutators(\n obj: object,\n typeName: string,\n methods: readonly string[],\n): void {\n // A non-extensible built-in (frozen, sealed, or preventExtensions'd)\n // cannot receive shadow properties, so skip it (best effort; the caller\n // chose to lock it themselves).\n if (!Object.isExtensible(obj)) return;\n for (const method of methods) {\n shadowDescriptor.value = mutationThrower(typeName, method);\n Object.defineProperty(obj, method, shadowDescriptor);\n }\n}\n\n/**\n * Deep freezes an object and all its nested properties recursively, then\n * returns it. Iterates both string-keyed and symbol-keyed own properties\n * so the freeze symmetry matches `deepEqual` (which also considers symbol\n * keys). Handles circular references by tracking visited objects.\n *\n * Note: `deepFreeze` mutates its argument in place; it sets `[[Frozen]]`\n * on the object you pass in. Callers that need to avoid touching the\n * input (e.g. `vo()`) should deep-clone first.\n *\n * Date/Map/Set keep internal-slot mutability under `Object.freeze`\n * (`setTime`, `set`, `add`, … still work on frozen instances), so their\n * mutator methods are shadowed with throwing own properties and Map/Set\n * contents are frozen recursively. The shadows are non-enumerable:\n * invisible to `Object.keys`, spread, `deepEqual`, and `structuredClone`.\n *\n * The shadowing is deny-by-enumeration: only the mutators known at\n * release time are blocked. If the runtime grows a NEW mutator (e.g. the\n * stage-3 `Map.prototype.getOrInsert` upsert proposal), it is not blocked\n * until the list is updated. Treat the mutator blocking as a guard rail,\n * not a security boundary.\n *\n * Limitation: ArrayBuffer views (TypedArrays, DataView) are passed through\n * unfrozen, because the spec forbids freezing a view with elements, and\n * freezing cannot protect the underlying buffer. Their contents remain mutable.\n */\nexport function deepFreeze<T>(obj: T, visited = new WeakSet<object>()): Readonly<T> {\n if (obj === null || typeof obj !== \"object\") {\n return obj as Readonly<T>;\n }\n // ArrayBuffer views are atomic: Object.freeze on a typed array with\n // elements throws per spec, and freezing cannot protect the underlying\n // buffer anyway, so views are returned as-is (their contents stay\n // mutable). Mirrors deepEqual, which also treats views atomically.\n if (ArrayBuffer.isView(obj)) {\n return obj as Readonly<T>;\n }\n if (visited.has(obj as object)) {\n return obj as Readonly<T>;\n }\n visited.add(obj as object);\n\n // Date/Map/Set keep internal-slot mutability under Object.freeze:\n // shadow their mutators and freeze Map/Set contents (entries are not\n // own keys, so the key walk below would miss them). Internal-slot brand\n // probes distinguish genuine built-ins without invoking toStringTag\n // accessors; spoofed plain objects are frozen structurally.\n const mutableBuiltInTag = mutableBuiltInTagWithoutInvokingAccessors(\n obj as object,\n );\n if (mutableBuiltInTag !== undefined) {\n if (mutableBuiltInTag === \"[object Date]\") {\n shadowMutators(obj as object, \"Date\", DATE_MUTATORS);\n } else if (mutableBuiltInTag === \"[object Map]\") {\n for (const [key, value] of obj as unknown as Map<\n unknown,\n unknown\n >) {\n deepFreeze(key, visited);\n deepFreeze(value, visited);\n }\n shadowMutators(obj as object, \"Map\", [\"set\", \"delete\", \"clear\"]);\n } else if (mutableBuiltInTag === \"[object Set]\") {\n for (const member of obj as unknown as Set<unknown>) {\n deepFreeze(member, visited);\n }\n shadowMutators(obj as object, \"Set\", [\"add\", \"delete\", \"clear\"]);\n }\n }\n\n // Reflect.ownKeys returns both string and symbol own keys.\n const keys = Reflect.ownKeys(obj);\n for (const key of keys) {\n const value = (obj as Record<string | symbol, unknown>)[key];\n if (value !== null && typeof value === \"object\") {\n deepFreeze(value, visited);\n }\n }\n\n return Object.freeze(obj) as Readonly<T>;\n}\n\n/**\n * Deep clone used by `vo()` and the `ValueObject` constructor.\n *\n * Plain objects, arrays, and Map values are walked manually so\n * that symbol-keyed properties survive (which `structuredClone` silently\n * drops; they would otherwise be invisible to `voEquals`, whose\n * `deepEqual` DOES consider symbol keys) and shared references / cycles\n * keep their identity across Map boundaries. Function values throw,\n * preserving `vo()`'s documented data-not-behaviour gate. Built-ins without\n * immutable value semantics throw a descriptive `TypeError`. Custom class\n * instances and subclasses of built-ins are rejected because cloning them\n * without invoking their\n * constructor can silently lose private or non-enumerable state. Map keys\n * and Set members must be primitive because their equality is\n * identity-based and object identity cannot survive defensive cloning.\n * Accessor properties are rejected without invoking them. Admitted atomic\n * built-ins (Date, RegExp and primitive wrappers) delegate to\n * `structuredClone`, brand-verified so a `Symbol.toStringTag` spoofer is\n * walked as the plain object it is. `__proto__` own keys are copied as\n * inert data properties.\n */\nfunction cloneForVo(value: unknown, visited: WeakMap<object, unknown>): unknown {\n if (typeof value === \"function\") {\n throw new TypeError(\n \"vo() does not accept function values: Value Objects are data, not behaviour\",\n );\n }\n if (value === null || typeof value !== \"object\") {\n return value;\n }\n const obj = value as object;\n if (ArrayBuffer.isView(obj)) {\n throwUnsupportedValueSemantics(\n builtInTagWithoutInvokingAccessors(obj) ??\n \"[object ArrayBuffer view]\",\n );\n }\n if (visited.has(obj)) {\n return visited.get(obj);\n }\n\n if (Array.isArray(obj)) {\n if (!hasIntrinsicPrototypeChain(obj, \"Array\")) {\n throwUnsupportedClassInstance();\n }\n const clone: unknown[] = new Array(obj.length);\n visited.set(obj, clone);\n for (const key of Reflect.ownKeys(obj)) {\n if (key === \"length\") continue;\n const descriptor = Object.getOwnPropertyDescriptor(obj, key);\n if (descriptor === undefined) continue;\n if (!(\"value\" in descriptor)) {\n throwUnsupportedAccessorProperty();\n }\n // Drop non-enumerable string keys just like the plain-object branch\n // below, so an array and an object carrying the same hidden property\n // clone to the same value surface. Array indices are enumerable and\n // therefore preserved.\n if (typeof key === \"string\" && !descriptor.enumerable) continue;\n descriptor.value = cloneForVo(descriptor.value, visited);\n Object.defineProperty(clone, key, descriptor);\n }\n return clone;\n }\n\n const tag = builtInTagWithoutInvokingAccessors(obj);\n if (tag !== undefined) {\n if (!hasIntrinsicPrototypeChain(obj)) {\n throwUnsupportedClassInstance();\n }\n if (tag === \"[object Map]\") {\n const clone = new Map<unknown, unknown>();\n visited.set(obj, clone);\n for (const [key, entry] of mapEntries.call(\n obj as Map<unknown, unknown>,\n )) {\n if (!isPrimitiveValue(key)) {\n throw new TypeError(\n \"vo() Map keys must be primitive values to preserve value equality\",\n );\n }\n clone.set(key, cloneForVo(entry, visited));\n }\n return clone;\n }\n if (tag === \"[object Set]\") {\n const clone = new Set<unknown>();\n visited.set(obj, clone);\n for (const member of setValues.call(obj as Set<unknown>)) {\n if (!isPrimitiveValue(member)) {\n throw new TypeError(\n \"vo() Set members must be primitive values to preserve value equality\",\n );\n }\n clone.add(member);\n }\n return clone;\n }\n if (\n tag === \"[object Promise]\" ||\n tag === \"[object WeakMap]\" ||\n tag === \"[object WeakSet]\"\n ) {\n throw new TypeError(\n `vo() cannot clone a ${tag.slice(8, -1)}: Value Objects are plain data`,\n );\n }\n if (\n tag === \"[object Error]\" ||\n tag === \"[object ArrayBuffer]\" ||\n tag === \"[object SharedArrayBuffer]\"\n ) {\n throwUnsupportedValueSemantics(tag);\n }\n if (tag === \"[object RegExp]\") {\n // A global or sticky RegExp carries observable mutable scan state:\n // every test()/exec() writes lastIndex, so it is a stateful object,\n // not a value. Deep-freezing it makes lastIndex non-writable and\n // crashes matching, so reject it instead of admitting a half-frozen\n // value. A plain (non-global, non-sticky) RegExp never touches\n // lastIndex and stays a genuine immutable value.\n const regExp = obj as RegExp;\n if (regExp.global || regExp.sticky) {\n throw new TypeError(\n \"vo() cannot accept a global or sticky RegExp: its lastIndex is mutable scan state, not an immutable value\",\n );\n }\n }\n // Atomic built-ins admitted by the VO contract: Date, RegExp and\n // primitive wrappers all have stable value semantics in deepEqual.\n const builtInClone = structuredClone(obj);\n visited.set(obj, builtInClone);\n return builtInClone;\n }\n\n const prototype = Object.getPrototypeOf(obj);\n if (\n prototype !== null &&\n (!isIntrinsicConstructorPrototype(prototype, \"Object\") ||\n Object.getPrototypeOf(prototype) !== null)\n ) {\n throwUnsupportedClassInstance();\n }\n\n // Normalize cross-realm records to the local Object prototype.\n const clone = Object.create(prototype === null ? null : Object.prototype);\n visited.set(obj, clone);\n for (const key of Reflect.ownKeys(obj)) {\n const descriptor = Object.getOwnPropertyDescriptor(obj, key);\n if (descriptor === undefined) continue;\n if (!(\"value\" in descriptor)) {\n throwUnsupportedAccessorProperty();\n }\n if (typeof key === \"string\" && !descriptor.enumerable) continue;\n // defineProperty (not assignment) so an own \"__proto__\" key can\n // never invoke the prototype setter.\n Object.defineProperty(clone, key, {\n value: cloneForVo(descriptor.value, visited),\n writable: true,\n enumerable: descriptor.enumerable,\n configurable: true,\n });\n }\n return clone;\n}\n\nfunction throwUnsupportedClassInstance(): never {\n throw new TypeError(\n \"vo() cannot clone custom class instances: Value Objects are plain data\",\n );\n}\n\nfunction throwUnsupportedAccessorProperty(): never {\n throw new TypeError(\n \"vo() cannot clone accessor properties: Value Objects are plain data\",\n );\n}\n\nfunction throwUnsupportedValueSemantics(tag: string): never {\n const name = tag.startsWith(\"[object \") ? tag.slice(8, -1) : tag;\n throw new TypeError(\n `vo() cannot accept ${name} values: Value Objects require immutable value semantics`,\n );\n}\n\nfunction isPrimitiveValue(value: unknown): boolean {\n return (\n value === null ||\n (typeof value !== \"object\" && typeof value !== \"function\")\n );\n}\n\n/**\n * Creates a deeply immutable value object from the given data.\n *\n * The input is first deep-cloned, then the clone is frozen, so calling\n * `vo(input)` never freezes the caller's own object graph as a\n * side-effect. Mutating the input afterwards does not bleed into the VO.\n * Symbol-keyed properties are preserved (matching `voEquals`); function\n * values and custom class instances are rejected (Value Objects are plain\n * data, not behaviour-bearing object graphs). Inputs must be trusted and\n * Proxy-free: ECMAScript provides no portable way to identify a transparent\n * Proxy without potentially executing its traps, so `vo()` is not a sandbox\n * for hostile in-process objects. Built-ins that cannot provide immutable,\n * value-based semantics are rejected instead of weakening the VO contract.\n *\n * @example\n * ```typescript\n * const nested = { lat: 52.5, lng: 13.4 };\n * const address = vo({ street: \"Main St\", coordinates: nested });\n * address.coordinates.lat = 99; // ❌ Cannot assign to read-only property\n * nested.lat = 0; // ✅ caller's input still mutable\n * ```\n */\nexport function vo<T>(t: T): VO<T> {\n return deepFreeze(cloneForVo(t, new WeakMap()) as T);\n}\n\n/**\n * Compares two value objects for equality based on their values.\n * Uses deep equality comparison that handles:\n * - Nested objects and arrays\n * - Primitives (including NaN)\n * - Dates, Maps, Sets, RegExp\n * - Symbol keys\n * - Circular references\n *\n * @param a - First value object\n * @param b - Second value object\n * @returns true if both objects have the same values, false otherwise\n *\n * @example\n * ```typescript\n * const money1 = vo({ amount: 100, currency: \"USD\" });\n * const money2 = vo({ amount: 100, currency: \"USD\" });\n * voEquals(money1, money2); // true\n *\n * const address1 = vo({\n * street: \"Main St\",\n * coordinates: { lat: 52.5, lng: 13.4 }\n * });\n * const address2 = vo({\n * street: \"Main St\",\n * coordinates: { lat: 52.5, lng: 13.4 }\n * });\n * voEquals(address1, address2); // true\n * ```\n */\nexport function voEquals<T>(a: VO<T>, b: VO<T>): boolean {\n return deepEqual(a, b);\n}\n\n/**\n * Compares two value objects for equality while ignoring specified keys.\n * Useful for comparing value objects that contain metadata or optional fields\n * that should not affect equality comparison.\n *\n * @param a - First value object\n * @param b - Second value object\n * @param options - Options specifying which keys to ignore during comparison\n * @returns true if both objects have the same values (after ignoring specified keys), false otherwise\n *\n * @example\n * ```typescript\n * // Value object with metadata\n * const address1 = vo({\n * street: \"Main St\",\n * city: \"Berlin\",\n * metadata: { createdAt: \"2024-01-01\", updatedAt: \"2024-01-02\" }\n * });\n *\n * const address2 = vo({\n * street: \"Main St\",\n * city: \"Berlin\",\n * metadata: { createdAt: \"2024-01-01\", updatedAt: \"2024-01-03\" }\n * });\n *\n * // Compare ignoring metadata timestamps\n * voEqualsExcept(address1, address2, {\n * ignoreKeys: [\"updatedAt\"],\n * ignoreKeyPredicate: (key, path) => path.includes(\"metadata\")\n * }); // true\n *\n * // Compare ignoring all metadata\n * voEqualsExcept(address1, address2, {\n * ignoreKeyPredicate: (key, path) => path.includes(\"metadata\")\n * }); // true\n * ```\n */\nexport function voEqualsExcept<T>(\n a: VO<T>,\n b: VO<T>,\n options: DeepEqualExceptOptions,\n): boolean {\n return deepEqualExcept(a, b, options);\n}\n\n/**\n * Creates a value object with optional validation.\n * Returns a Result type instead of throwing an error.\n *\n * Note: the Result covers VALIDATION failures only. Non-data values and\n * built-ins without immutable value semantics still throw a\n * `TypeError` from `vo()`; they cannot occur in parsed JSON and signal\n * a programming error, not a validation failure.\n *\n * @param t - The data to convert into a value object\n * @param validate - Validation function that returns true if valid\n * @param errorMessage - Optional custom error message if validation fails\n * @returns Result containing the value object if valid, or an error message if validation fails\n *\n * @example\n * ```typescript\n * const result = voWithValidation(\n * { amount: 100, currency: \"USD\" },\n * (m) => m.amount >= 0 && m.currency.length === 3,\n * \"Invalid money: amount must be non-negative and currency must be 3 characters\"\n * );\n *\n * if (result.ok) {\n * console.log(result.value); // Use the value object\n * } else {\n * console.error(result.error); // Handle validation error\n * }\n * ```\n */\nexport function voWithValidation<T>(\n t: T,\n validate: (value: T) => boolean,\n errorMessage?: string,\n): Result<VO<T>, string> {\n if (!validate(t)) {\n return err(\n errorMessage ?? `Validation failed for value object: ${describeValue(t)}`,\n );\n }\n return ok(vo(t));\n}\n\n/**\n * Best-effort rendering of a value for the default validation-failure\n * message. `JSON.stringify` throws for cyclic and BigInt-bearing values, and\n * the error path of a Result-returning function must never throw itself.\n */\nfunction describeValue(value: unknown): string {\n try {\n const json = JSON.stringify(value);\n if (json !== undefined) return json;\n } catch {\n // Cyclic or BigInt-bearing values cannot be JSON-serialised.\n }\n return String(value);\n}\n\n// ============================================================================\n// Class-based Value Object API\n// ============================================================================\n\n/**\n * Interface for Value Objects.\n * Value Objects are immutable and defined by their properties.\n *\n * @template T - The shape of the value object's properties\n */\nexport interface IValueObject<T extends object> {\n /**\n * The immutable properties of the value object.\n */\n readonly props: Readonly<T>;\n\n /**\n * Checks if this value object is equal to another.\n * Uses deep equality comparison on the properties.\n *\n * @param other - The other value object to compare\n * @returns true if the properties are deeply equal\n */\n equals(other: IValueObject<T>): boolean;\n\n /**\n * Creates a clone of the value object with optional property overrides.\n *\n * @param props - Optional properties to override\n * @returns A new instance of the value object\n */\n clone(props?: Partial<T>): IValueObject<T>;\n\n /**\n * Serializes the value object to its raw properties for JSON operations.\n *\n * @returns The raw properties object\n */\n toJSON(): Readonly<T>;\n}\n\n/**\n * Abstract base class for creating Value Objects.\n * Value Objects are immutable and defined by their properties.\n *\n * @template T - The shape of the value object's properties\n */\nexport abstract class ValueObject<T extends object> implements IValueObject<T> {\n public readonly props: Readonly<T>;\n\n /**\n * Creates a new ValueObject.\n * The plain-data properties are deep-cloned and then deeply\n * frozen, so the caller's own object graph is never frozen or mutated,\n * and later mutation of the input does not bleed into the value object.\n *\n * @param props - The properties of the value object\n * @example\n * ```ts\n * class Money extends ValueObject<{ amount: number; currency: string }> {\n * constructor(props: { amount: number; currency: string }) {\n * super(props);\n * }\n *\n * protected validate(props: { amount: number; currency: string }): void {\n * if (props.amount < 0) throw new Error(\"Amount cannot be negative\");\n * }\n * }\n * ```\n */\n constructor(props: T) {\n this.validate(props);\n // Same clone as vo(): Map/Set contents are walked (so the caller's\n // entries are never frozen or shadowed in place), and functions and\n // custom class instances are rejected. A shallow `{ ...props }` or\n // deepOmit (which aliases reference-compared built-ins by design)\n // would let deepFreeze reach caller-owned objects.\n this.props = deepFreeze(cloneForVo(props, new WeakMap()) as T);\n }\n\n /**\n * Optional validation hook that can be overridden by subclasses.\n * Should throw an error if validation fails.\n *\n * @param props - The properties to validate\n * @throws Error if validation fails\n */\n protected validate(props: T): void {\n // Default implementation does nothing\n }\n\n /**\n * Checks if this value object is equal to another.\n * Uses deep equality comparison on the properties and checks for constructor equality.\n *\n * @param other - The other value object to compare\n * @returns true if the properties are deeply equal and constructors match\n */\n public equals(other: ValueObject<T>): boolean {\n if (other === null || other === undefined) {\n return false;\n }\n\n if (this.constructor !== other.constructor) {\n return false;\n }\n\n return deepEqual(this.props, other.props);\n }\n\n /**\n * Creates a clone of the value object with optional property overrides.\n *\n * @param props - Optional properties to override\n * @returns A new instance of the value object\n */\n public clone(props?: Partial<T>): this {\n const Constructor = this.constructor as new (props: T) => this;\n const merged = { ...this.props, ...(props || {}) } as T;\n // A `{ ...spread }` copies only enumerable own keys, so any\n // non-enumerable own property that cloneForVo preserved on this.props\n // (e.g. a non-enumerable symbol) would be dropped, making\n // `x.equals(x.clone())` false because deepEqual counts all own symbols.\n // Re-attach every non-enumerable own key the caller did not override.\n for (const key of Reflect.ownKeys(this.props)) {\n const descriptor = Object.getOwnPropertyDescriptor(this.props, key);\n if (descriptor === undefined || descriptor.enumerable) continue;\n if (props && Object.hasOwn(props, key)) continue;\n Object.defineProperty(merged, key, {\n value: (this.props as Record<PropertyKey, unknown>)[\n key as PropertyKey\n ],\n writable: true,\n enumerable: false,\n configurable: true,\n });\n }\n return new Constructor(merged);\n }\n\n /**\n * Serializes the value object to its raw properties for JSON operations.\n *\n * @returns The raw properties object\n */\n public toJSON(): Readonly<T> {\n return this.props;\n }\n\n\n}\n","/**\n * Module-internal home of the kit's swappable clock. The public surface\n * (`ClockFactory`, `setClockFactory`, `withClockFactory`,\n * `resetClockFactory`) is re-exported through `domain-event.ts`; the\n * `now()` accessor stays internal so the barrel files never ship it.\n * Living in its own module lets `createDomainEvent` (occurredAt) and\n * `BaseAggregate.createSnapshot` (snapshotAt) read the same clock\n * without an import cycle between those files.\n */\n\n/**\n * Clock function producing a fresh `Date` for each call. The library\n * defaults to `() => new Date()`; override globally via `setClockFactory`\n * for deterministic event-sourcing tests, time-travel debugging, or any\n * scenario where `occurredAt` / `snapshotAt` must be reproducible.\n */\nexport type ClockFactory = () => Date;\n\nconst defaultClockFactory: ClockFactory = () => new Date();\nlet currentClockFactory: ClockFactory = defaultClockFactory;\n\n/**\n * Internal: the current clock reading. Consumers of the kit control it\n * via `setClockFactory` / `withClockFactory`; kit code that needs a\n * timestamp (event `occurredAt`, snapshot `snapshotAt`) reads through\n * this accessor instead of a hard `new Date()`, so a swapped clock\n * covers every timestamp the kit stamps.\n */\nexport function now(): Date {\n\treturn currentClockFactory();\n}\n\n/**\n * Replaces the global clock factory used by `createDomainEvent` and\n * `createSnapshot`. Call once during application bootstrap (or per-test\n * in deterministic test suites):\n *\n * ```ts\n * import { setClockFactory } from \"@shirudo/ddd-kit\";\n *\n * setClockFactory(() => new Date(\"2026-01-01T00:00:00Z\"));\n * ```\n *\n * The per-call `options.occurredAt` override always wins over this\n * factory. Symmetric to `setEventIdFactory`.\n *\n * Module-scoped: see `setEventIdFactory` for the global-state\n * caveats. For test isolation prefer {@link withClockFactory}; for\n * multi-tenant request isolation prefer the per-call\n * `options.occurredAt`.\n */\nexport function setClockFactory(factory: ClockFactory): void {\n\tcurrentClockFactory = factory;\n}\n\n/**\n * Scoped variant of {@link setClockFactory}: installs `factory`, runs\n * `fn`, then restores the previous factory in a `finally` block.\n * Synchronous-only, with the same constraints (and same runtime thenable\n * guard) as `withEventIdFactory`.\n *\n * **When to prefer the per-call `options.occurredAt` instead.** Same\n * trade-off as `withEventIdFactory`: passing `{ occurredAt }`\n * to `createDomainEvent` is the strongest isolation for single-event\n * cases. The scoped helper is for events constructed deep inside\n * domain methods where threading an explicit timestamp is awkward.\n *\n * @example\n * ```ts\n * it(\"stamps events with a fixed clock\", () => {\n * const fixed = new Date(\"2026-01-01T00:00:00Z\");\n * withClockFactory(() => fixed, () => {\n * const e = createDomainEvent(\"X\", { v: 1 });\n * expect(e.occurredAt).toEqual(fixed);\n * });\n * });\n * ```\n */\nexport function withClockFactory<T>(factory: ClockFactory, fn: () => T): T {\n\tconst previous = currentClockFactory;\n\tcurrentClockFactory = factory;\n\ttry {\n\t\tconst result = fn();\n\t\tassertNotThenable(result, \"withClockFactory\");\n\t\treturn result;\n\t} finally {\n\t\tcurrentClockFactory = previous;\n\t}\n}\n\n/**\n * Restores the default clock factory (`() => new Date()`).\n * Intended for use in test `afterEach` hooks.\n */\nexport function resetClockFactory(): void {\n\tcurrentClockFactory = defaultClockFactory;\n}\n\n/**\n * Internal guard for the scoped factory helpers (`withClockFactory`,\n * `withEventIdFactory`). Throws a clear error when the user-supplied\n * `fn` returns a thenable: the helpers are synchronous-only, and a\n * silent async-misuse would restore the factory before the awaited body\n * of `fn` runs, leaving the awaited code reading the previous factory.\n */\nexport function assertNotThenable(result: unknown, helperName: string): void {\n\tif (\n\t\tresult !== null &&\n\t\t(typeof result === \"object\" || typeof result === \"function\") &&\n\t\ttypeof (result as { then?: unknown }).then === \"function\"\n\t) {\n\t\tthrow new Error(\n\t\t\t`${helperName}: fn returned a thenable. ` +\n\t\t\t\t`The factory is only installed for the synchronous portion of fn; ` +\n\t\t\t\t`awaited continuations would see the previous factory. ` +\n\t\t\t\t`For async-scoped factories use AsyncLocalStorage.`,\n\t\t);\n\t}\n}\n","import { deepFreeze } from \"../value-object/value-object\";\nimport { assertNotThenable, now } from \"./clock\";\n\n// The swappable clock lives in ./clock (so BaseAggregate.createSnapshot\n// can read it without an import cycle); its public API ships from here,\n// unchanged.\nexport {\n\ttype ClockFactory,\n\tresetClockFactory,\n\tsetClockFactory,\n\twithClockFactory,\n} from \"./clock\";\n\n/**\n * Factory function producing a fresh, unique event identifier for each call.\n *\n * The library ships a default that uses Web Crypto `crypto.randomUUID()`\n * (works on Node 19+, modern browsers in secure contexts, Deno, Bun,\n * Cloudflare Workers, Vercel Edge, and any runtime that implements Web\n * Crypto). Note that `crypto.randomUUID()` returns **UUID v4** (purely\n * random); for production event stores prefer a **time-ordered** id\n * format (UUID v7 / ULID / KSUID) so B-tree indexes on the eventId\n * column stay clustered and `ORDER BY eventId` matches creation order.\n * Swap one in via `setEventIdFactory(() => uuidv7())` or `() => ulid()`.\n */\nexport type EventIdFactory = () => string;\n\nconst defaultEventIdFactory: EventIdFactory = () => crypto.randomUUID();\nlet currentEventIdFactory: EventIdFactory = defaultEventIdFactory;\n\n/**\n * Replaces the global event-id factory used by `createDomainEvent`. Call\n * once during application bootstrap, for example:\n *\n * ```ts\n * import { ulid } from \"ulid\";\n * import { setEventIdFactory } from \"@shirudo/ddd-kit\";\n *\n * setEventIdFactory(() => ulid());\n * ```\n *\n * The per-call `options.eventId` override always wins over this factory.\n *\n * **Module-scoped: last setter wins.** The factory lives as a single\n * module variable; importing two libraries that both call this races on\n * load order, and parallel test workers will see each other's factory.\n * For test isolation and short-lived contexts prefer\n * {@link withEventIdFactory}; for multi-tenant request isolation\n * (e.g. one factory per tenant in a single Worker invocation) **prefer\n * the per-call `options.eventId`** instead of mutating the global. Same\n * caveat applies to `setClockFactory`.\n */\nexport function setEventIdFactory(factory: EventIdFactory): void {\n\tcurrentEventIdFactory = factory;\n}\n\n/**\n * Scoped variant of {@link setEventIdFactory}: installs `factory`,\n * runs `fn`, then restores the previous factory in a `finally` block,\n * so the restoration happens even if `fn` throws. Safe for parallel\n * tests and for synchronous request handlers that need a tenant-\n * specific factory without polluting the global.\n *\n * **Synchronous-only, enforced at runtime.** If `fn` returns a\n * thenable (a `Promise` or any object with a `then` method), the\n * helper throws *before* returning the value to the caller. This\n * catches the async-misuse footgun where the factory would be\n * restored before the awaited body of `fn` runs, leaving the awaited\n * code reading the previous factory. For async scoping across `await`\n * boundaries, use `AsyncLocalStorage`, which is out of scope for this\n * helper; build it on top if you need it.\n *\n * Composes by nesting: an inner `withEventIdFactory` restores back to\n * the outer's factory; the outer restores to the original.\n *\n * **When to prefer the per-call `options.eventId` instead.** If you're\n * constructing a single event and want full control over its id,\n * passing `{ eventId: \"...\" }` to `createDomainEvent` is the strongest\n * isolation: it bypasses the factory mechanism entirely, no global\n * mutation, no scope to manage. Reach for `withEventIdFactory` when\n * the events are constructed deep inside domain methods you can't\n * thread an explicit id through (typical test scenario), or when many\n * events in a scope should share the same factory.\n *\n * @example\n * ```ts\n * // In a vitest test:\n * it(\"emits deterministic ids\", () => {\n * withEventIdFactory(() => \"evt-fixed\", () => {\n * const e = createDomainEvent(\"X\", { v: 1 });\n * expect(e.eventId).toBe(\"evt-fixed\");\n * });\n * // Outside the callback the default crypto.randomUUID is restored,\n * // even if the body had thrown.\n * });\n * ```\n */\nexport function withEventIdFactory<T>(\n\tfactory: EventIdFactory,\n\tfn: () => T,\n): T {\n\tconst previous = currentEventIdFactory;\n\tcurrentEventIdFactory = factory;\n\ttry {\n\t\tconst result = fn();\n\t\tassertNotThenable(result, \"withEventIdFactory\");\n\t\treturn result;\n\t} finally {\n\t\tcurrentEventIdFactory = previous;\n\t}\n}\n\n/**\n * Restores the default event-id factory (`crypto.randomUUID()`).\n * Intended for use in test `afterEach` hooks.\n */\nexport function resetEventIdFactory(): void {\n\tcurrentEventIdFactory = defaultEventIdFactory;\n}\n\n/**\n * Metadata associated with a domain event for traceability and correlation.\n * Used in event-driven architectures to track event flow across services.\n */\nexport interface EventMetadata {\n\t/**\n\t * Correlation ID for tracing events across multiple services/components.\n\t * Typically used to group related events in a distributed system.\n\t */\n\tcorrelationId?: string;\n\n\t/**\n\t * Causation ID referencing the event or command that caused this event.\n\t * Used to build event chains and understand causality.\n\t */\n\tcausationId?: string;\n\n\t/**\n\t * User ID of the person or system that triggered the event.\n\t */\n\tuserId?: string;\n\n\t/**\n\t * Source service or component that produced the event.\n\t */\n\tsource?: string;\n\n\t/**\n\t * Additional custom metadata fields.\n\t * Allows extensibility for domain-specific metadata.\n\t */\n\t[key: string]: unknown;\n}\n\n/**\n * Domain Event represents something meaningful that happened in the domain.\n * Events are immutable and carry information about what occurred.\n *\n * **Events are PLAIN DATA objects**, constructed via `createDomainEvent`\n * (or the aggregate's `recordEvent` helper) and deeply frozen. Class-based\n * event objects that satisfy this shape structurally via prototype\n * members are unsupported: the `withCommit` harvest copies events with a\n * shallow spread (to stamp `aggregateVersion`), which only carries own\n * enumerable properties.\n *\n * **Field-accretion boundary.** This type already carries the write-side\n * transport concerns the outbox needs (`aggregateId`, `aggregateType`,\n * `aggregateVersion`, `metadata`). That is the line: further transport\n * fields (partition keys, tenancy, schema URNs, …) belong in an outbox\n * envelope / `metadata`, not on the domain event: the next first-class\n * transport field forces an `OutboxMessage` envelope port instead.\n *\n * @template T - The event type name (e.g., \"OrderCreated\")\n * @template P - The event payload type\n */\nexport interface DomainEvent<T extends string, P = void> {\n\t/**\n\t * Unique identifier for this specific event instance. Used by idempotent\n\t * consumers, outbox dispatch tracking, and as the target of\n\t * `metadata.causationId`. Defaults to `crypto.randomUUID()` if not\n\t * supplied.\n\t */\n\teventId: string;\n\n\t/**\n\t * The type of the event, used for routing and handling.\n\t */\n\ttype: T;\n\n\t/**\n\t * Identifier of the aggregate that produced the event. Optional at the\n\t * library level; set it whenever the producing aggregate is known so\n\t * downstream subscribers, outboxes, and projections can scope by entity.\n\t */\n\taggregateId?: string;\n\n\t/**\n\t * Name of the aggregate type that produced the event (e.g. \"Order\").\n\t * Pairs with `aggregateId` to fully qualify the source aggregate.\n\t */\n\taggregateType?: string;\n\n\t/**\n\t * The event payload containing the domain data. The field is always\n\t * present; its value is `undefined` when `P` is `void`.\n\t */\n\tpayload: P;\n\n\t/**\n\t * Timestamp when the event occurred.\n\t */\n\toccurredAt: Date;\n\n\t/**\n\t * Event schema version for handling schema evolution.\n\t * Required for safe schema migration in event-sourced systems.\n\t * Use 1 for the initial schema version.\n\t *\n\t * **NOT the aggregate's version**: that is\n\t * {@link aggregateVersion}. The two are deliberately distinct\n\t * fields: this one says \"which shape does the payload have\"\n\t * (upcasting), the other says \"which state revision of the\n\t * aggregate emitted this\".\n\t */\n\tversion: number;\n\n\t/**\n\t * The version of the producing aggregate at COMMIT time: the same\n\t * value the OCC row write carries. Stamped automatically by\n\t * `withCommit` at the harvest boundary (all events of one aggregate\n\t * in one commit share it; their relative order within the commit is\n\t * the harvest order), or set manually via\n\t * `CreateDomainEventOptions.aggregateVersion`; a pre-set value is\n\t * never overwritten.\n\t *\n\t * Consumers use it for cross-commit ordering and debugging. It is NOT\n\t * a per-event idempotency key: all events of one commit share the\n\t * stamp, so a position cursor keyed on it alone would silently skip\n\t * every event after the first within a commit (e.g. after a crash\n\t * between two same-version events). Dedup keys belong on `eventId`;\n\t * as a watermark this value is per-commit only (advance it after\n\t * processing ALL events of that version; see the outbox guide).\n\t * Optional at the type level: events created outside an aggregate\n\t * (system/integration events) and events from older kit versions\n\t * don't carry it.\n\t */\n\taggregateVersion?: number;\n\n\t/**\n\t * Optional metadata for traceability, correlation, and auditing.\n\t * Includes correlationId, causationId, userId, source, and custom fields.\n\t */\n\tmetadata?: EventMetadata;\n}\n\n/**\n * Upper-bound alias for \"any `DomainEvent` shape\". Use as a generic\n * constraint when a type parameter should accept any concrete event\n * union. The `unknown` payload is the upper bound; concrete unions\n * still narrow via `Extract<Evt, { type: K }>` at the use-site.\n */\nexport type AnyDomainEvent = DomainEvent<string, unknown>;\n\n/**\n * Shared option bag for the `createDomainEvent*` factories.\n */\nexport interface CreateDomainEventOptions {\n\t/**\n\t * Override for the auto-generated `eventId`. Pass an existing id (for\n\t * replay, tests, or deterministic event sourcing) instead of letting the\n\t * factory call `crypto.randomUUID()`.\n\t */\n\teventId?: string;\n\n\t/**\n\t * Identifier of the aggregate that produced the event.\n\t */\n\taggregateId?: string;\n\n\t/**\n\t * Name of the aggregate type that produced the event.\n\t */\n\taggregateType?: string;\n\n\t/**\n\t * Override for the auto-generated `occurredAt` timestamp.\n\t */\n\toccurredAt?: Date;\n\n\t/**\n\t * Override for the default schema version (1).\n\t */\n\tversion?: number;\n\n\t/**\n\t * Pre-set the producing aggregate's version (see\n\t * `DomainEvent.aggregateVersion`). Normally left unset (`withCommit`\n\t * stamps it at the harvest boundary with the commit version), but\n\t * useful for replay fixtures and events constructed outside an\n\t * aggregate. A pre-set value is never overwritten by the harvest.\n\t */\n\taggregateVersion?: number;\n\n\t/**\n\t * Event metadata: correlation, causation, user, source, custom fields.\n\t */\n\tmetadata?: EventMetadata;\n}\n\n/**\n * Creates a domain event with default values.\n * Sets occurredAt to current date and version to 1 if not provided.\n *\n * **Input ownership.** The event is deeply frozen, and `payload` and\n * `metadata` are deep-cloned first, so the caller's own objects are never\n * frozen in place and later mutation of them does not bleed into the\n * event (same contract as `vo()`). The clone follows the plain-data event\n * contract via `structuredClone`: functions, Promise, and WeakMap/WeakSet\n * values throw a `TypeError`; symbol-keyed properties are not carried\n * over.\n *\n * **For aggregate-internal events, prefer `this.recordEvent(...)` on\n * `AggregateRoot` / `EventSourcedAggregate`.** That helper auto-injects\n * `aggregateId` (from `this.id`) and `aggregateType` (from the\n * aggregate's declared `aggregateType` property), which downstream\n * consumers (outbox dispatchers, projection handlers, audit logs)\n * route by. The `withCommit` harvest boundary now validates both fields\n * are present and throws if they're missing, so a direct\n * `createDomainEvent(...)` call inside an aggregate that forgets the\n * options is caught at runtime.\n *\n * Use `createDomainEvent(...)` directly for events that don't belong to\n * an aggregate: system events, integration events, configuration events,\n * test fixtures. For those, set `aggregateId` / `aggregateType` in\n * `options` if downstream consumers expect routing metadata.\n *\n * @param type - The event type\n * @param payload - The event payload\n * @param options - Optional event configuration (including `aggregateId`\n * and `aggregateType` for routing)\n * @returns A domain event\n *\n * @example\n * ```typescript\n * const event = createDomainEvent(\"OrderCreated\", { orderId: \"123\" });\n * ```\n */\nexport function createDomainEvent<T extends string>(\n\ttype: T,\n\tpayload?: undefined,\n\toptions?: CreateDomainEventOptions,\n): DomainEvent<T, void>;\nexport function createDomainEvent<T extends string, P>(\n\ttype: T,\n\tpayload: P,\n\toptions?: CreateDomainEventOptions,\n): DomainEvent<T, P>;\nexport function createDomainEvent<T extends string, P>(\n\ttype: T,\n\tpayload?: P,\n\toptions?: CreateDomainEventOptions,\n): DomainEvent<T, P> {\n\tconst event: DomainEvent<T, P> = {\n\t\teventId: options?.eventId ?? currentEventIdFactory(),\n\t\ttype,\n\t\taggregateId: options?.aggregateId,\n\t\taggregateType: options?.aggregateType,\n\t\t// Defensive copies throughout: the deep-freeze below must never\n\t\t// reach the caller's own object graph. Without the clone, passing\n\t\t// (parts of) live aggregate state as payload, or reusing a metadata\n\t\t// object across events, would freeze the caller's objects in place;\n\t\t// the next mutation then throws far away from the cause. Same\n\t\t// ownership contract as `vo()` and the occurredAt copy.\n\t\tpayload: cloneOwnedEventData(payload as P, \"payload\"),\n\t\toccurredAt: options?.occurredAt\n\t\t\t? new Date(options.occurredAt.getTime())\n\t\t\t: now(),\n\t\tversion: options?.version ?? 1,\n\t\taggregateVersion: options?.aggregateVersion,\n\t\tmetadata: cloneOwnedEventData(options?.metadata, \"metadata\"),\n\t};\n\t// Deep-freeze so a mutating subscriber cannot poison subsequent\n\t// handlers: events are facts of the past and must be immutable\n\t// (Vernon, IDDD §8).\n\treturn deepFreeze(event) as DomainEvent<T, P>;\n}\n\n/**\n * Deep-clones caller-supplied event data (payload, metadata) before the\n * event is frozen, so `createDomainEvent` never freezes or aliases the\n * caller's own object graph. Primitives pass through unchanged.\n *\n * Uses `structuredClone`, which matches the documented plain-data event\n * contract: functions, Promise, and WeakMap/WeakSet values throw a\n * descriptive `TypeError` (they are not data); symbol-keyed properties\n * are not carried over; a class instance would silently lose its\n * prototype, which the plain-data contract already rules out.\n */\nfunction cloneOwnedEventData<T>(value: T, field: \"payload\" | \"metadata\"): T {\n\tif (typeof value === \"function\") {\n\t\tthrow new TypeError(\n\t\t\t`createDomainEvent: ${field} must not be a function: domain events are plain data`,\n\t\t);\n\t}\n\tif (value === null || typeof value !== \"object\") {\n\t\treturn value;\n\t}\n\ttry {\n\t\treturn structuredClone(value);\n\t} catch (cause) {\n\t\tthrow new TypeError(\n\t\t\t`createDomainEvent: ${field} must be plain, structured-cloneable data ` +\n\t\t\t\t`(no functions, Promises, or WeakMap/WeakSet values): domain events ` +\n\t\t\t\t`are plain data`,\n\t\t\t{ cause },\n\t\t);\n\t}\n}\n\n/**\n * Copies metadata from a source event to a new event.\n * Useful for maintaining correlation chains in event-driven architectures.\n *\n * @example\n * ```typescript\n * const newEvent = createDomainEvent(\n * \"OrderShipped\",\n * { orderId: \"123\" },\n * { metadata: copyMetadata(previousEvent, { causationId: previousEvent.type }) }\n * );\n * ```\n */\nexport function copyMetadata(\n\tsourceEvent: AnyDomainEvent,\n\tadditionalMetadata?: Partial<EventMetadata>,\n): EventMetadata {\n\treturn {\n\t\t...(sourceEvent.metadata ?? {}),\n\t\t...(additionalMetadata ?? {}),\n\t};\n}\n\n/**\n * Merges multiple metadata objects into one.\n * Later metadata objects override earlier ones for the same keys.\n *\n * @example\n * ```typescript\n * const metadata = mergeMetadata(\n * { correlationId: \"corr-123\" },\n * { userId: \"user-456\" },\n * { source: \"order-service\" }\n * );\n * ```\n */\nexport function mergeMetadata(\n\t...metadataObjects: Array<EventMetadata | undefined>\n): EventMetadata {\n\t// Copy via defineProperty, not Object.assign: assign uses [[Set]],\n\t// which invokes the `__proto__` setter for an own \"__proto__\" key\n\t// (typical of JSON.parse'd metadata from outbox rows or message\n\t// envelopes) and would install an attacker-controlled prototype.\n\tconst merged: Record<PropertyKey, unknown> = {};\n\tfor (const metadata of metadataObjects) {\n\t\tif (!metadata) continue;\n\t\tfor (const key of Reflect.ownKeys(metadata)) {\n\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(metadata, key);\n\t\t\tif (!descriptor?.enumerable) continue;\n\t\t\tObject.defineProperty(merged, key, {\n\t\t\t\tvalue: (metadata as Record<PropertyKey, unknown>)[key],\n\t\t\t\twritable: true,\n\t\t\t\tenumerable: true,\n\t\t\t\tconfigurable: true,\n\t\t\t});\n\t\t}\n\t}\n\treturn merged as EventMetadata;\n}\n","import type { Result } from \"@shirudo/result\";\nimport type { Id } from \"../core/id\";\nimport type { DomainError } from \"../core/errors\";\nimport type { AnyDomainEvent } from \"./domain-event\";\n\n// Re-export domain event types for convenience\nexport * from \"./domain-event\";\n\n// --- Aggregate types ---\n\nexport type Version = number & { readonly __v: true };\n\n/**\n * Snapshot of an aggregate state at a specific point in time.\n * Used for optimizing event replay by starting from a snapshot\n * instead of replaying all events from the beginning.\n *\n * @template TState - The type of the aggregate state\n */\nexport interface AggregateSnapshot<TState> {\n\t/**\n\t * The state of the aggregate at the time of the snapshot.\n\t */\n\treadonly state: TState;\n\n\t/**\n\t * The version of the aggregate when the snapshot was taken.\n\t */\n\treadonly version: Version;\n\n\t/**\n\t * Timestamp when the snapshot was created.\n\t */\n\treadonly snapshotAt: Date;\n\n\t/**\n\t * Schema version of the SHAPE of `state` (the aggregate's declared\n\t * `snapshotSchemaVersion`), stamped by `createSnapshot`. Distinct from\n\t * {@link version}, which counts mutations: this field says \"which\n\t * shape does the stored state have\", so a restore can detect a\n\t * snapshot written against an older `TSnapshotState` and migrate or\n\t * discard it instead of crashing later. Optional: absent on snapshots\n\t * written by older kit versions, which restore treats as schema `1`.\n\t */\n\treadonly schemaVersion?: number;\n}\n\n/**\n * Public contract every Aggregate Root satisfies. Implemented by\n * `BaseAggregate` and inherited by both `AggregateRoot` and\n * `EventSourcedAggregate`. Repository implementations type their\n * `save(aggregate)` parameter against this interface rather than the\n * concrete classes, so the repo layer does not take a compile-time\n * dependency on the aggregate hierarchy.\n *\n * Full per-member documentation lives on the concrete `BaseAggregate`\n * class; the interface is intentionally terse to avoid drift.\n *\n * @template TId - The aggregate root identifier (branded via `Id<Tag>`)\n * @template TEvent - The domain-event union, defaults to `never`\n */\nexport interface IAggregateRoot<TId extends Id<string>, TEvent = never> {\n\treadonly id: TId;\n\treadonly version: Version;\n\treadonly persistedVersion: Version | undefined;\n\treadonly pendingEvents: ReadonlyArray<TEvent>;\n\tclearPendingEvents(): void;\n\tmarkPersisted(version: Version): void;\n}\n\n/**\n * Public contract for Event-Sourced Aggregate Roots. Extends\n * `IAggregateRoot` with the replay-from-history boundary.\n *\n * @template TId - The aggregate root identifier\n * @template TEvent - The union type of all domain events\n */\nexport interface IEventSourcedAggregate<\n\tTId extends Id<string>,\n\tTEvent extends AnyDomainEvent,\n> extends IAggregateRoot<TId, TEvent> {\n\t/**\n\t * Reconstitutes the aggregate from an event history. Returns\n\t * `Result` because event-stream corruption is an expected\n\t * recoverable failure at the infrastructure boundary.\n\t */\n\tloadFromHistory(history: ReadonlyArray<TEvent>): Result<void, DomainError>;\n}\n\n/**\n * Checks if two aggregates are at the same version (same ID and version).\n * Useful for optimistic concurrency control checks.\n *\n * Note: Two aggregates with the same ID ARE the same aggregate (identity).\n * This function checks if they are at the same version: i.e., no concurrent modification.\n *\n * @example\n * ```typescript\n * const before = await repository.getById(id);\n * // ... some operations ...\n * const after = await repository.getById(id);\n *\n * if (!sameVersion(before, after)) {\n * throw new Error(\"Aggregate was modified by another process\");\n * }\n * ```\n */\nexport function sameVersion<TId extends Id<string>>(\n\ta: { id: TId; version: Version },\n\tb: { id: TId; version: Version },\n): boolean {\n\treturn a.id === b.id && a.version === b.version;\n}\n","import { BaseError } from \"@shirudo/base-error\";\n\n/**\n * Abstract base for **domain-invariant violations**. Domain methods\n * (aggregates, entity validation hooks, value-object constructors)\n * throw `DomainError`-derived exceptions when a business rule is\n * violated. Consumers derive their own concrete errors (e.g.\n * `class OrderAlreadyShippedError extends DomainError<\"OrderAlreadyShippedError\"> {}`)\n * for `instanceof`-style catching at the App-Service boundary, where\n * they typically map to HTTP 400 / business-rule responses.\n *\n * The library itself does **not** ship any concrete `DomainError`\n * subclass: the kit can't know your invariants.\n *\n * Extends `BaseError<Name>`; see `@shirudo/base-error` for the inherited\n * surface (timestamps, cause chains, `toJSON()`, `isRetryable`, …). For\n * client-safe / localized messages, project errors through the opt-in\n * `@shirudo/base-error/presentation` subpath at the boundary; the technical\n * core deliberately carries no user-facing message.\n */\nexport abstract class DomainError<\n\tName extends string = string,\n> extends BaseError<Name> {}\n\n/**\n * Abstract base for **infrastructure / persistence failures** that the\n * App-Service can recover from: typically by retrying, by returning\n * HTTP 404 / 409, or by surfacing a \"please try again\" UX. These are\n * not domain-invariant violations (the business rules were not\n * broken); they describe race conditions and missing rows at the\n * storage boundary.\n *\n * Library-internal concrete subclasses: {@link AggregateNotFoundError},\n * {@link ConcurrencyConflictError}, {@link DuplicateAggregateError},\n * plus the unit-of-work lifecycle wrappers `CommitError` and\n * `RollbackError` (in `src/app/unit-of-work.ts`).\n */\nexport abstract class InfrastructureError<\n\tName extends string = string,\n> extends BaseError<Name> {}\n\n/**\n * Thrown by `EventSourcedAggregate.apply()` when no handler is\n * registered for the event's type. This means the aggregate's subclass\n * forgot to add an entry to its `handlers` map: a programming /\n * configuration bug, not a domain or infrastructure failure.\n *\n * Deliberately **not** on `DomainError` or `InfrastructureError`:\n * a generic `catch (e instanceof DomainError)` handler at the App\n * layer must not mask a forgotten handler; this should crash loud and\n * fail the calling Use Case so the bug surfaces in development. The\n * replay methods (`loadFromHistory`, `restoreFromSnapshotWithEvents`)\n * also let it propagate uncaught instead of wrapping it in `Result.Err`.\n *\n * Use `isBaseError(e)` from `@shirudo/base-error` to detect\n * \"any structured error from the kit or any other BaseError-using\n * library\" at the App boundary.\n */\nexport class MissingHandlerError extends BaseError<\"MissingHandlerError\"> {\n\tconstructor(\n\t\tpublic readonly eventType: string,\n\t\tcause?: unknown,\n\t) {\n\t\tsuper(`Missing handler for event type: ${eventType}`, cause, {\n\t\t\tname: \"MissingHandlerError\",\n\t\t});\n\t}\n}\n\n/**\n * Thrown by `EventSourcedAggregate.loadFromHistory` and\n * `restoreFromSnapshotWithEvents` when the replay target is not fresh:\n * the aggregate carries unflushed `pendingEvents`, or (for\n * `loadFromHistory`) an in-memory version that was never persisted.\n * Replaying onto such an instance would `markRestored` a\n * `persistedVersion` that counts unpersisted history: repository routing\n * flips from INSERT to UPDATE (or appends with a wrong expected version)\n * and harvested events would claim a version baseline the stream does\n * not carry.\n *\n * Deliberately **not** a `DomainError` or `InfrastructureError` (same\n * posture as {@link MissingHandlerError}): a deterministic programming\n * bug in how the aggregate was constructed before replay. It propagates\n * as a throw instead of riding the replay methods' `Result` channel, so\n * a generic corrupted-stream handler cannot absorb it. Reconstitution\n * belongs on a bare instance: construct the aggregate without\n * factory-recorded events or prior mutations, then replay.\n */\nexport class UnreplayableAggregateError extends BaseError<\"UnreplayableAggregateError\"> {\n\tconstructor(\n\t\tpublic readonly aggregateId: string,\n\t\treason: string,\n\t) {\n\t\tsuper(\n\t\t\t`Cannot replay history onto aggregate ${aggregateId}: ${reason}. ` +\n\t\t\t\t\"Reconstitute on a fresh instance (no factory-recorded events, \" +\n\t\t\t\t\"no unpersisted mutations), or markPersisted the aggregate \" +\n\t\t\t\t\"before a catch-up replay.\",\n\t\t\tundefined,\n\t\t\t{ name: \"UnreplayableAggregateError\" },\n\t\t);\n\t}\n}\n\n/**\n * Thrown by `withCommit` when an event harvested from an aggregate cannot\n * be safely committed: it is missing `aggregateId` / `aggregateType`\n * (downstream routing would break), or it carries a pre-set\n * `aggregateVersion` AHEAD of the aggregate's commit version (a leaked or\n * copied fixture that would advance consumer idempotency watermarks past\n * real history). Both are programming bugs in how the aggregate recorded\n * the event, deterministic, and fail identically on every retry.\n *\n * Deliberately **not** an {@link InfrastructureError} (same reasoning as\n * {@link MissingHandlerError}): the failure happens after the work\n * callback completed, but it is NOT transient. A `catch (e instanceof\n * InfrastructureError)` retry handler, or a retrying `TransactionScope`,\n * must NOT mask it or loop on it forever; it should crash loud so the\n * recordEvent / createDomainEvent misuse surfaces in development. This is\n * why `withCommit` throws it directly and `UnitOfWork.run` passes it\n * through unchanged instead of wrapping it in `CommitError`.\n */\nexport class EventHarvestError extends BaseError<\"EventHarvestError\"> {\n\tconstructor(\n\t\tmessage: string,\n\t\t/** The `type` of the offending event, for programmatic routing. */\n\t\tpublic readonly eventType?: string,\n\t) {\n\t\tsuper(message, undefined, { name: \"EventHarvestError\" });\n\t}\n}\n\n/** Constructor options for {@link UnregisteredHandlerError}. */\nexport interface UnregisteredHandlerErrorOptions {\n\t/** Which bus rejected the dispatch. */\n\treadonly busKind: \"command\" | \"query\";\n\t/** The message type no handler was registered for. */\n\treadonly messageType: string;\n}\n\n/**\n * Produced by the in-memory `CommandBus` / `QueryBus` when a message is\n * dispatched for a type no handler was registered under: a wiring bug\n * (typo in the type string, missing `register` call at bootstrap), not\n * a domain or infrastructure failure.\n *\n * Extends `BaseError` directly (same crash-loud family as\n * {@link MissingHandlerError}): a generic `catch (e instanceof\n * DomainError)` handler must not absorb it. For 2.x compatibility the\n * buses still deliver it through their error CHANNEL (`err(...)` via the\n * `errorMapper`, so the default string channel keeps its exact message)\n * rather than throwing; the named type exists so a typed error channel\n * can route it explicitly instead of pattern-matching message strings.\n * `QueryBus.executeUnsafe` throws it directly. v3 makes `execute` throw\n * it too.\n */\nexport class UnregisteredHandlerError extends BaseError<\"UnregisteredHandlerError\"> {\n\treadonly busKind: \"command\" | \"query\";\n\treadonly messageType: string;\n\n\tconstructor(options: UnregisteredHandlerErrorOptions) {\n\t\tsuper(\n\t\t\t`No handler registered for ${options.busKind} type: ${options.messageType}`,\n\t\t\tundefined,\n\t\t\t{ name: \"UnregisteredHandlerError\" },\n\t\t);\n\t\tthis.busKind = options.busKind;\n\t\tthis.messageType = options.messageType;\n\t}\n}\n\n/**\n * Thrown at the end of a `UnitOfWork.run` when an aggregate that was\n * loaded into the identity map during the operation carries unflushed\n * `pendingEvents` but was never enrolled (no `session.enrollSaved`, and\n * not deleted). The almost-certain cause is a repository `save()` that\n * forgot to call `enrollSaved`, or a use case that recorded events on a\n * loaded aggregate and never saved it. Without this guard those events\n * would be silently dropped: never harvested into the outbox, never\n * published.\n *\n * Deliberately **not** an `InfrastructureError` (same posture as\n * {@link MissingHandlerError}): a programming bug that must crash loud,\n * not be absorbed by a generic infrastructure-error handler. The throw\n * happens inside the transaction, so the unit of work rolls back and\n * leaves no partial state.\n *\n * **Scope of the guard.** A best-effort runtime safety net, not a proof.\n * It only sees aggregates the identity map knows about (those loaded via\n * `getById`), and detects new events by comparing the pending-event COUNT\n * at load against commit, which assumes the kit's append-only event model\n * (so it cannot see events that were recorded and then cleared within the\n * same run). A freshly *created* aggregate that was never enrolled is\n * invisible to the kit. The repository contract test suite remains the\n * full mitigation. See the Unit of Work guide.\n */\nexport class UnenrolledChangesError extends BaseError<\"UnenrolledChangesError\"> {\n\tconstructor(public readonly aggregateId: string) {\n\t\tsuper(\n\t\t\t`Aggregate ${aggregateId} was loaded in this unit of work and has ` +\n\t\t\t\t\"pending events, but was never enrolled (no save), so its events \" +\n\t\t\t\t\"would be silently dropped. Call repository.save(aggregate), and \" +\n\t\t\t\t\"ensure save() calls session.enrollSaved before the row write.\",\n\t\t\tundefined,\n\t\t\t{ name: \"UnenrolledChangesError\" },\n\t\t);\n\t}\n}\n\n/**\n * Thrown when an aggregate that was deleted within the current unit of\n * work is saved or re-registered again in the same operation: by\n * `UnitOfWorkSession.enrollSaved` after `enrollDeleted` of the same\n * instance, and by `IdentityMap.set` for a type+id that was deleted.\n * Deletion is final within an operation; saving afterwards would write\n * a row the delete just removed (or resurrect it), which is always a\n * use-case bug.\n *\n * Extends `BaseError` directly (same reasoning as\n * {@link MissingHandlerError}): a programming bug that should crash\n * loud, not be absorbed by a generic infrastructure-error handler.\n */\nexport class AggregateDeletedError extends BaseError<\"AggregateDeletedError\"> {\n\tconstructor(public readonly aggregateId: string) {\n\t\tsuper(\n\t\t\t`Aggregate ${aggregateId} was deleted in this unit of work and ` +\n\t\t\t\t\"cannot be saved or registered again. Deletion is final within an \" +\n\t\t\t\t\"operation; if the aggregate must live, do not delete it.\",\n\t\t\tundefined,\n\t\t\t{ name: \"AggregateDeletedError\" },\n\t\t);\n\t}\n}\n\n/**\n * Thrown by `IRepository.getByIdOrFail()` when an aggregate with the\n * given id does not exist. `InfrastructureError` because the storage\n * boundary, not a business rule, decided the row is absent. Use the\n * nullable variant `getById()` if \"not found\" is a valid outcome.\n *\n * Accepts an optional `cause` so a `Repository.save()` implementation\n * can wrap a lower-level \"row not found\" / driver-level error without\n * losing context. Cause-chain helpers (`getRootCause`,\n * `findInCauseChain`) from `@shirudo/base-error` traverse the chain.\n *\n * Not retryable: retrying won't make the row appear.\n */\nexport interface AggregateNotFoundErrorOptions {\n\treadonly aggregateType: string;\n\treadonly id: string;\n\t/** Optional lower-level error to preserve in the cause chain. */\n\treadonly cause?: unknown;\n}\n\nexport class AggregateNotFoundError extends InfrastructureError<\"AggregateNotFoundError\"> {\n\treadonly aggregateType: string;\n\treadonly id: string;\n\n\tconstructor(options: AggregateNotFoundErrorOptions) {\n\t\tsuper(\n\t\t\t`Aggregate not found: ${options.aggregateType}(${options.id})`,\n\t\t\toptions.cause,\n\t\t\t{ name: \"AggregateNotFoundError\" },\n\t\t);\n\t\tthis.aggregateType = options.aggregateType;\n\t\tthis.id = options.id;\n\t}\n}\n\n/**\n * Thrown by a repository's `save()` INSERT path when a row with the\n * aggregate's id already exists (unique-constraint violation): two\n * concurrent creators raced on the same business-derived id, or the\n * id generator collided. Same delegation model as\n * {@link ConcurrencyConflictError}: the kit ships the class, the\n * consumer repository maps its driver's unique-violation signal to it\n * instead of letting a raw driver error escape -\n *\n * - Postgres: SQLSTATE `23505` (`unique_violation`)\n * - MySQL/MariaDB: errno `1062` (`ER_DUP_ENTRY`)\n * - SQLite: `SQLITE_CONSTRAINT_UNIQUE` (extended code 2067)\n *\n * `InfrastructureError` because the storage boundary detects the\n * collision. NOT retryable: re-running the same INSERT cannot succeed.\n * The right reactions are domain decisions - map to HTTP 409, or for\n * idempotency-key flows load the existing aggregate and treat the\n * request as already-applied.\n */\nexport interface DuplicateAggregateErrorOptions {\n\treadonly aggregateType: string;\n\treadonly aggregateId: string;\n\t/** Optional driver-level error to preserve in the cause chain. */\n\treadonly cause?: unknown;\n}\n\nexport class DuplicateAggregateError extends InfrastructureError<\"DuplicateAggregateError\"> {\n\treadonly aggregateType: string;\n\treadonly aggregateId: string;\n\n\tconstructor(options: DuplicateAggregateErrorOptions) {\n\t\tsuper(\n\t\t\t`Duplicate aggregate: ${options.aggregateType}(${options.aggregateId}) already exists`,\n\t\t\toptions.cause,\n\t\t\t{ name: \"DuplicateAggregateError\" },\n\t\t);\n\t\tthis.aggregateType = options.aggregateType;\n\t\tthis.aggregateId = options.aggregateId;\n\t}\n}\n\n/**\n * Thrown on snapshot restore (`restoreFromSnapshot`,\n * `restoreFromSnapshotWithEvents`) when the stored snapshot carries a\n * different schema version than the aggregate's declared\n * `snapshotSchemaVersion` and no `migrateSnapshotState` override handles\n * the upgrade. Without the check, a snapshot written against an older\n * `TSnapshotState` shape would surface as an undefined-field crash on\n * the first method call after a much later restore.\n *\n * `InfrastructureError` because the storage boundary served outdated\n * data; the schema evolving past stored snapshots is an expected\n * lifecycle event, not a programming bug. NOT retryable: the recovery\n * is a code path, not a repeat. Either override `migrateSnapshotState`\n * on the aggregate (upgrade old shapes in place), or catch this error\n * in the repository, discard the snapshot, and refold from the full\n * event stream / reload from the source of truth.\n */\nexport interface SnapshotSchemaMismatchErrorOptions {\n\treadonly aggregateType: string;\n\treadonly aggregateId: string;\n\treadonly expectedSchemaVersion: number;\n\treadonly actualSchemaVersion: number;\n}\n\nexport class SnapshotSchemaMismatchError extends InfrastructureError<\"SnapshotSchemaMismatchError\"> {\n\treadonly aggregateType: string;\n\treadonly aggregateId: string;\n\treadonly expectedSchemaVersion: number;\n\treadonly actualSchemaVersion: number;\n\n\tconstructor(options: SnapshotSchemaMismatchErrorOptions) {\n\t\tsuper(\n\t\t\t`Snapshot schema mismatch on ${options.aggregateType}(${options.aggregateId}): ` +\n\t\t\t\t`the aggregate expects snapshot schema ${options.expectedSchemaVersion}, ` +\n\t\t\t\t`the stored snapshot carries ${options.actualSchemaVersion}. Override ` +\n\t\t\t\t`migrateSnapshotState to upgrade old snapshots, or discard the snapshot ` +\n\t\t\t\t`and refold from the full event stream.`,\n\t\t\tundefined,\n\t\t\t{ name: \"SnapshotSchemaMismatchError\" },\n\t\t);\n\t\tthis.aggregateType = options.aggregateType;\n\t\tthis.aggregateId = options.aggregateId;\n\t\tthis.expectedSchemaVersion = options.expectedSchemaVersion;\n\t\tthis.actualSchemaVersion = options.actualSchemaVersion;\n\t}\n}\n\n/**\n * Thrown by `IRepository.save()` when the aggregate's expected version\n * does not match the version currently persisted: i.e. another writer\n * updated the aggregate concurrently. The canonical optimistic-\n * concurrency signal; the App-Service typically reloads, re-applies\n * the use case, and retries, or surfaces HTTP 409 to the caller.\n *\n * **Retry means a FRESH unit of work** (a new `UnitOfWork.run()` /\n * `withCommit` invocation): reload, re-apply, save. Do NOT catch this\n * inside the same `run()` callback and continue: the failed aggregate\n * is already enrolled (its events would be committed for a write that\n * never happened) and the identity map still serves the same stale\n * instance to any in-place \"reload\".\n *\n * `InfrastructureError` because the persistence layer (not a domain\n * rule) detects the race. Marks itself as `retryable: true` so the\n * `isRetryable` predicate from `@shirudo/base-error` picks it up.\n */\nexport interface ConcurrencyConflictErrorOptions {\n\treadonly aggregateType: string;\n\treadonly aggregateId: string;\n\treadonly expectedVersion: number;\n\treadonly actualVersion: number;\n\t/** Optional driver-level error to preserve in the cause chain. */\n\treadonly cause?: unknown;\n}\n\nexport class ConcurrencyConflictError extends InfrastructureError<\"ConcurrencyConflictError\"> {\n\t/**\n\t * Marks this error as retryable so `isRetryable(err)` returns\n\t * true. The canonical OCC pattern is to reload the aggregate, re-apply\n\t * the use case, and retry on this exception.\n\t */\n\treadonly retryable = true as const;\n\n\treadonly aggregateType: string;\n\treadonly aggregateId: string;\n\treadonly expectedVersion: number;\n\treadonly actualVersion: number;\n\n\tconstructor(options: ConcurrencyConflictErrorOptions) {\n\t\tsuper(\n\t\t\t`Concurrency conflict on ${options.aggregateType}(${options.aggregateId}): expected version ${options.expectedVersion}, actual ${options.actualVersion}`,\n\t\t\toptions.cause,\n\t\t\t{ name: \"ConcurrencyConflictError\" },\n\t\t);\n\t\tthis.aggregateType = options.aggregateType;\n\t\tthis.aggregateId = options.aggregateId;\n\t\tthis.expectedVersion = options.expectedVersion;\n\t\tthis.actualVersion = options.actualVersion;\n\t}\n}\n","/**\n * Entity utilities and interfaces for Domain-Driven Design.\n *\n * In Domain-Driven Design, there are two types of entities:\n *\n * 1. **Aggregate Root Entity**: The parent Entity of an aggregate.\n * - Has identity (id), state, and version\n * - Implemented by classes extending `AggregateRoot` or `EventSourcedAggregate`\n * - Represents the aggregate externally\n * - Loaded/saved through repositories\n *\n * 2. **Child Entities**: Entities within an aggregate.\n * - Have identity (id) and state, but no own version\n * - Can extend `Entity<TState, TId>` for class-based entities\n * - Or use functional style with `Identifiable<TId> & TProps`\n * - Exist only within the aggregate boundary\n * - Versioned through the Aggregate Root\n * - Cannot be referenced directly from outside the aggregate\n *\n * This module provides:\n * - `Entity<TState, TId>` - Base class for entities with state\n * - `EntityConfig` - Construction options (opt-in deep freeze)\n * - `Identifiable<TId>` - Minimal interface for objects with id\n * - Helper functions for working with collections of entities\n *\n * @example\n * ```typescript\n * // Class-based child entity with logic\n * class OrderItem extends Entity<OrderItemState, ItemId> {\n * constructor(id: ItemId, initialState: OrderItemState) {\n * super(id, initialState);\n * }\n *\n * updateQuantity(quantity: number): void {\n * // setState runs validateState and re-freezes; a direct\n * // `this._state = ...` assignment would skip both.\n * this.setState({ ...this.state, quantity });\n * }\n *\n * calculateSubtotal(): number {\n * return this.state.price * this.state.quantity;\n * }\n * }\n *\n * // Functional-style child entity (simpler, no logic)\n * type OrderItem = Identifiable<ItemId> & {\n * productId: string;\n * quantity: number;\n * price: number;\n * };\n *\n * // Aggregate Root (Entity with version)\n * class Order extends AggregateRoot<OrderState, OrderId> {\n * // Order is an Aggregate Root Entity\n * // OrderState contains OrderItem child entities\n * }\n * ```\n */\nimport type { Id } from \"../core/id\";\nimport { deepFreeze } from \"../value-object/value-object\";\n\n/**\n * Construction options shared by `Entity` and (via `AggregateConfig`) the\n * aggregate base classes.\n */\nexport interface EntityConfig {\n\t/**\n\t * Opt-in: freeze the WHOLE state graph (via `deepFreeze`) instead of\n\t * the default shallow freeze, so nested outside writes\n\t * (`entity.state.items.push(x)`) throw instead of silently bypassing\n\t * `validateState`, the version bump, and the `changedKeys` dirty diff.\n\t *\n\t * Defaults to `false` (the documented shallow contract): deep freezing\n\t * costs a full state-graph walk on every state write, which is why it\n\t * is not the default on hot paths.\n\t *\n\t * **Only for plain-data states.** The deep freeze walks the entire\n\t * graph: a class-based child entity inside the state would be frozen\n\t * too, and its own mutation methods would start throwing. States\n\t * carrying class-based children must keep the default shallow freeze.\n\t * Note that the ownership transfer widens accordingly: nested objects\n\t * passed into the constructor or `setState` are frozen IN PLACE (the\n\t * shallow copy protects only the top-level input object).\n\t */\n\tdeepFreezeState?: boolean;\n}\n\n/**\n * Functional definition of an Entity via its capability: an object is\n * identifiable if it has an `id`.\n *\n * `TId` is constrained to `Id<string>` so the brand discipline that\n * `Id<Tag>` enforces is preserved end-to-end: an `Identifiable<UserId>`\n * cannot accidentally be paired with an `Identifiable<OrderId>` or with\n * a plain `string`.\n */\nexport type Identifiable<TId extends Id<string>> = {\n\treadonly id: TId;\n};\n\n/**\n * Interface for Entities with state.\n *\n * In Domain-Driven Design, Entities have:\n * - Identity (id): Distinguishes one entity from another\n * - State: The attributes/properties of the entity\n *\n * Unlike Value Objects (which are immutable and compared by value),\n * Entities are compared by identity and can have mutable state.\n *\n * @template TId - The type of the entity identifier\n * @template TState - The type of the entity state\n */\nexport interface IEntity<TId extends Id<string>, TState> extends Identifiable<TId> {\n\t/**\n\t * Unique identifier of the entity.\n\t */\n\treadonly id: TId;\n\n\t/**\n\t * The current state of the entity.\n\t */\n\treadonly state: TState;\n}\n\n/**\n * Abstract base class for Entities with state.\n *\n * Provides:\n * - Identity management (id)\n * - State management\n * - State validation hook\n * - Immutable state access through getter\n *\n * This is the foundation for all Entities in DDD:\n * - Child Entities within aggregates can extend this\n * - Aggregate Roots extend this and add version + events\n *\n * @template TState - The type of the entity state\n * @template TId - The type of the entity identifier\n *\n * @example\n * ```typescript\n * // Child Entity within an aggregate\n * class OrderItem extends Entity<OrderItemState, ItemId> {\n * constructor(id: ItemId, initialState: OrderItemState) {\n * super(id, initialState);\n * }\n *\n * updateQuantity(quantity: number): void {\n * // setState runs validateState and re-freezes; a direct\n * // `this._state = ...` assignment would skip both.\n * this.setState({ ...this.state, quantity });\n * }\n * }\n * ```\n */\nexport abstract class Entity<TState, TId extends Id<string>>\n\timplements IEntity<TId, TState> {\n\tpublic readonly id: TId;\n\n\t/**\n\t * Returns the current state of the entity.\n\t *\n\t * By default the state object is **shallowly frozen**: direct property\n\t * writes (`entity.state.foo = …`) throw in strict mode, but writes to\n\t * nested objects (`entity.state.address.zip = …`) bypass the freeze.\n\t * For deep immutability either enable the opt-in\n\t * {@link EntityConfig.deepFreezeState} (plain-data states only), model\n\t * nested data with `vo()` (which freezes deeply), or reach for a\n\t * structural-sharing library like Immer at the App layer. The shallow\n\t * default is intentional: deep freezing on every state write is too\n\t * expensive for hot paths, and DDD aggregates normally treat their own\n\t * state as private (`Tell, Don't Ask`).\n\t */\n\tpublic get state(): TState {\n\t\treturn this._state;\n\t}\n\n\t/**\n\t * The state is 'protected' so that only the subclass can modify it.\n\t * Subclasses can mutate this directly or use helper methods; direct\n\t * assignments should freeze through {@link freezeState} so the\n\t * configured freeze mode is honored.\n\t */\n\tprotected _state: TState;\n\n\tprivate readonly _deepFreezeState: boolean;\n\n\t/**\n\t * **State ownership.** Plain-object and array states are shallow-copied\n\t * before the freeze, so the caller's own object stays mutable. A CLASS\n\t * INSTANCE passed as state is an ownership transfer: it is frozen\n\t * in place (a copy would strip its prototype). Do not keep mutating\n\t * the instance after handing it to the entity. The same contract\n\t * applies to {@link setState}. With\n\t * {@link EntityConfig.deepFreezeState} enabled, the ownership transfer\n\t * widens to the whole graph: NESTED objects are frozen in place too.\n\t */\n\tprotected constructor(id: TId, initialState: TState, config?: EntityConfig) {\n\t\tif (id === null || id === undefined) {\n\t\t\tthrow new Error(\"Entity ID cannot be null or undefined\");\n\t\t}\n\t\tthis.id = id;\n\t\tthis._deepFreezeState = config?.deepFreezeState ?? false;\n\t\tthis._state = this.freezeState(shallowCopyOwned(initialState));\n\t\tthis.validateState(this._state);\n\t}\n\n\t/**\n\t * Freezes a state value according to this entity's configured freeze\n\t * mode: the default shallow freeze, or `deepFreeze` when\n\t * {@link EntityConfig.deepFreezeState} was enabled at construction.\n\t * Subclass code that assigns `this._state` directly (bypassing\n\t * `setState`) must freeze through this method, not `freezeShallow`,\n\t * or the opt-in silently degrades to shallow for that path.\n\t */\n\tprotected freezeState(value: TState): TState {\n\t\treturn this._deepFreezeState\n\t\t\t? (deepFreeze(value) as TState)\n\t\t\t: freezeShallow(value);\n\t}\n\n\t/**\n\t * Optional validation hook to ensure state invariants. Called during\n\t * construction (from `Entity`'s constructor) and again on every\n\t * `setState()` call. Throw to reject invalid state.\n\t *\n\t * **⚠️ Must not read subclass instance fields via `this`.** The\n\t * constructor calls `validateState(initialState)` BEFORE the subclass's\n\t * field initializers run, so `this.someField` is `undefined` at that\n\t * point, a classic TypeScript/JavaScript constructor-ordering footgun.\n\t * The `state` argument is the single source of truth; treat the method\n\t * as pure with respect to `this`.\n\t *\n\t * If your invariants genuinely depend on per-instance configuration\n\t * that isn't part of the state, pass that configuration into the state\n\t * itself (DDD-canonical: the aggregate's state contains everything it\n\t * needs) or perform the additional check after construction in a\n\t * dedicated factory method.\n\t *\n\t * @param state - The state to validate\n\t * @throws Error (or `DomainError` subclass) if validation fails\n\t */\n\tprotected validateState(_state: TState): void {\n\t\t// Default implementation does nothing\n\t}\n\n\t/**\n\t * Sets the state of the entity.\n\t * This is a convenience method for state mutations.\n\t * Automatically validates the newState using `validateState()`.\n\t *\n\t * Plain-object and array states are shallow-copied before the freeze\n\t * (the caller's object stays mutable); a class-instance state is an\n\t * ownership transfer and is frozen in place; see the constructor.\n\t *\n\t * @param newState - The new state\n\t */\n\tprotected setState(newState: TState): void {\n\t\tthis.validateState(newState);\n\t\tthis._state = this.freezeState(shallowCopyOwned(newState));\n\t}\n}\n\n/**\n * Shallow-freezes `value` when it's a non-null object or array, so that\n * direct property writes throw in strict mode. Returns the value as-is for\n * primitives. Used internally by `Entity` (via `freezeState`, which picks\n * shallow or deep per the `deepFreezeState` config) to prevent outside\n * mutation of state read through the `state` getter without paying the\n * cost of a deep clone on every read.\n *\n * Subclass code that assigns `this._state` directly should freeze through\n * the protected `freezeState(value)` method rather than calling this\n * helper, so the configured freeze mode is honored. The export remains\n * for consumers using it as a standalone utility.\n */\nexport function freezeShallow<T>(value: T): T {\n\tif (value !== null && typeof value === \"object\") {\n\t\treturn Object.freeze(value);\n\t}\n\treturn value;\n}\n\n/**\n * Returns a shallow copy for plain objects and arrays so the subsequent\n * `freezeShallow` never locks the caller's own object in place (their later\n * writes to it would throw in strict mode). Class instances and primitives\n * pass through unchanged: a spread would strip an instance's prototype,\n * and handing a class instance as state is an ownership transfer. Nested\n * objects stay shared by design (shallow-freeze, no deep clone).\n */\nfunction shallowCopyOwned<T>(value: T): T {\n\tif (value === null || typeof value !== \"object\") return value;\n\tif (Array.isArray(value)) return [...value] as T;\n\tconst proto = Object.getPrototypeOf(value);\n\tif (proto !== Object.prototype && proto !== null) return value;\n\treturn Object.assign(Object.create(proto), value) as T;\n}\n\n\n/**\n * Checks if two entities have the same ID.\n * Works with any object that has an 'id' property.\n *\n * @param a - First entity\n * @param b - Second entity\n * @returns true if both entities have the same ID, false otherwise\n *\n * @example\n * ```typescript\n * const item1: OrderItem = { id: itemId1, productId: \"prod-1\", quantity: 2 };\n * const item2: OrderItem = { id: itemId2, productId: \"prod-2\", quantity: 1 };\n *\n * sameEntity(item1, item2); // false\n * sameEntity(item1, item1); // true\n * ```\n */\nexport function sameEntity<TId extends Id<string>>(a: Identifiable<TId>, b: Identifiable<TId>): boolean {\n\treturn a.id === b.id;\n}\n\n/**\n * Finds an entity by ID in a collection.\n * Returns undefined if not found.\n *\n * @param entities - Array of entities to search\n * @param id - The ID to search for\n * @returns The entity if found, undefined otherwise\n *\n * @example\n * ```typescript\n * const items: OrderItem[] = [\n * { id: itemId1, productId: \"prod-1\", quantity: 2 },\n * { id: itemId2, productId: \"prod-2\", quantity: 1 }\n * ];\n *\n * const item = findEntityById(items, itemId1);\n * // item is { id: itemId1, productId: \"prod-1\", quantity: 2 }\n * ```\n */\nexport function findEntityById<TId extends Id<string>, T extends Identifiable<TId>>(\n\tentities: ReadonlyArray<T>,\n\tid: TId,\n): T | undefined {\n\treturn entities.find((entity) => entity.id === id);\n}\n\n/**\n * Checks if an entity with the given ID exists in the collection.\n *\n * @param entities - Array of entities to search\n * @param id - The ID to check for\n * @returns true if an entity with the ID exists, false otherwise\n *\n * @example\n * ```typescript\n * const items: OrderItem[] = [\n * { id: itemId1, productId: \"prod-1\", quantity: 2 }\n * ];\n *\n * hasEntityId(items, itemId1); // true\n * hasEntityId(items, itemId2); // false\n * ```\n */\nexport function hasEntityId<TId extends Id<string>, T extends Identifiable<TId>>(\n\tentities: ReadonlyArray<T>,\n\tid: TId,\n): boolean {\n\treturn entities.some((entity) => entity.id === id);\n}\n\n/**\n * Removes an entity with the given ID from the collection.\n * Returns a new array without the entity.\n *\n * @param entities - Array of entities\n * @param id - The ID of the entity to remove\n * @returns A new array without the entity with the given ID\n *\n * @example\n * ```typescript\n * const items: OrderItem[] = [\n * { id: itemId1, productId: \"prod-1\", quantity: 2 },\n * { id: itemId2, productId: \"prod-2\", quantity: 1 }\n * ];\n *\n * const updated = removeEntityById(items, itemId1);\n * // updated is [{ id: itemId2, productId: \"prod-2\", quantity: 1 }]\n * ```\n */\nexport function removeEntityById<TId extends Id<string>, T extends Identifiable<TId>>(\n\tentities: ReadonlyArray<T>,\n\tid: TId,\n): T[] {\n\treturn entities.filter((entity) => entity.id !== id);\n}\n\n/**\n * Updates an entity with the given ID in the collection.\n * Returns a new array with the updated entity.\n * If the entity is not found, returns the original array unchanged.\n *\n * @param entities - Array of entities\n * @param id - The ID of the entity to update\n * @param updater - Function that takes the entity and returns the updated entity\n * @returns A new array with the updated entity\n *\n * @example\n * ```typescript\n * const items: OrderItem[] = [\n * { id: itemId1, productId: \"prod-1\", quantity: 2 }\n * ];\n *\n * const updated = updateEntityById(items, itemId1, (item) => ({\n * ...item,\n * quantity: item.quantity + 1\n * }));\n * // updated is [{ id: itemId1, productId: \"prod-1\", quantity: 3 }]\n * ```\n */\nexport function updateEntityById<TId extends Id<string>, T extends Identifiable<TId>>(\n\tentities: ReadonlyArray<T>,\n\tid: TId,\n\tupdater: (entity: T) => T,\n): T[] {\n\treturn entities.map((entity) => (entity.id === id ? updater(entity) : entity));\n}\n\n/**\n * Replaces an entity with the given ID in the collection.\n * Returns a new array with the replaced entity.\n * If the entity is not found, returns the original array unchanged.\n *\n * @param entities - Array of entities\n * @param id - The ID of the entity to replace\n * @param replacement - The replacement entity\n * @returns A new array with the replaced entity\n *\n * @example\n * ```typescript\n * const items: OrderItem[] = [\n * { id: itemId1, productId: \"prod-1\", quantity: 2 }\n * ];\n *\n * const updated = replaceEntityById(items, itemId1, {\n * id: itemId1,\n * productId: \"prod-1\",\n * quantity: 5\n * });\n * ```\n */\nexport function replaceEntityById<TId extends Id<string>, T extends Identifiable<TId>>(\n\tentities: ReadonlyArray<T>,\n\tid: TId,\n\treplacement: T,\n): T[] {\n\treturn entities.map((entity) => (entity.id === id ? replacement : entity));\n}\n\n/**\n * Extracts all IDs from a collection of entities.\n *\n * @param entities - Array of entities\n * @returns Array of entity IDs\n *\n * @example\n * ```typescript\n * const items: OrderItem[] = [\n * { id: itemId1, productId: \"prod-1\", quantity: 2 },\n * { id: itemId2, productId: \"prod-2\", quantity: 1 }\n * ];\n *\n * const ids = entityIds(items);\n * // ids is [itemId1, itemId2]\n * ```\n */\nexport function entityIds<TId extends Id<string>, T extends Identifiable<TId>>(entities: ReadonlyArray<T>): TId[] {\n\treturn entities.map((entity) => entity.id);\n}\n\n","import { SnapshotSchemaMismatchError } from \"../core/errors\";\nimport type { Id } from \"../core/id\";\nimport { Entity } from \"../entity/entity\";\nimport { isBuiltInObject } from \"../utils/array/is-built-in\";\nimport type { AggregateSnapshot, IAggregateRoot, Version } from \"./aggregate\";\nimport { now } from \"./clock\";\nimport {\n\ttype AnyDomainEvent,\n\ttype CreateDomainEventOptions,\n\tcreateDomainEvent,\n\ttype DomainEvent,\n} from \"./domain-event\";\n\n/**\n * Shared base for both `AggregateRoot` (state-stored) and\n * `EventSourcedAggregate`. Carries the lifecycle machinery that's\n * identical across the two flavours: version + persistedVersion\n * tracking, pending events buffer, the `markRestored` (Post-Load) /\n * `markPersisted` (Post-Save) lifecycle markers, and the\n * `recordEvent` helper that auto-injects `aggregateId` +\n * `aggregateType` on every event the aggregate emits.\n *\n * Consumers do NOT extend this class directly; extend\n * `AggregateRoot` for state-stored aggregates or\n * `EventSourcedAggregate` for event-sourced ones. The split between\n * those two reflects the canonical Vernon §8 (state-stored) /\n * Vernon §11 + Greg Young (event-sourced) distinction in how state\n * is represented; the lifecycle machinery is the same for both.\n *\n * @template TState - The type of the aggregate state\n * @template TId - The aggregate root identifier\n * @template TEvent - The domain-event union. Defaults to `never` so\n * aggregates without a declared event type cannot emit events\n * (emitting any event becomes a compile error).\n * @template TSnapshotState - The plain-data shape stored in snapshots.\n * Defaults to `TState` for plain-data states. Aggregates whose state\n * carries class-based child entities declare a plain DTO shape here\n * and override {@link toSnapshotState} / {@link fromSnapshotState}.\n */\nexport abstract class BaseAggregate<\n\t\tTState,\n\t\tTId extends Id<string>,\n\t\tTEvent extends AnyDomainEvent = never,\n\t\tTSnapshotState = TState,\n\t>\n\textends Entity<TState, TId>\n\timplements IAggregateRoot<TId, TEvent>\n{\n\t/**\n\t * The aggregate's domain type as a string, used to populate\n\t * `aggregateType` on events recorded via {@link recordEvent}.\n\t *\n\t * Subclasses MUST declare this as a string literal:\n\t *\n\t * ```ts\n\t * class Order extends AggregateRoot<OrderState, OrderId, OrderEvent> {\n\t * protected readonly aggregateType = \"Order\";\n\t * }\n\t * ```\n\t *\n\t * The string is *the* identifier downstream consumers (outbox\n\t * dispatchers, projection handlers, audit logs) use to route by\n\t * aggregate kind. Use the same canonical name across your system;\n\t * matching the class name is the obvious choice, but the value\n\t * comes from this explicit declaration, not `constructor.name`\n\t * (which is fragile under minification, bundler transforms, and\n\t * subclass renaming).\n\t */\n\tprotected abstract readonly aggregateType: string;\n\n\tprivate _version: Version = 0 as Version;\n\n\t/**\n\t * DB-baseline version. `undefined` until the aggregate has been\n\t * persisted or restored at least once. Repository implementations\n\t * route INSERT vs UPDATE on this field and use it as the OCC\n\t * baseline. See `IRepository.save` JSDoc.\n\t *\n\t * Distinct from {@link version}, which is the in-memory\n\t * post-mutation value. Mutations bump `_version` but never touch\n\t * `_persistedVersion`; that field only moves on {@link markRestored}\n\t * (Post-Load) and {@link markPersisted} (Post-Save).\n\t */\n\tprivate _persistedVersion: Version | undefined = undefined;\n\n\tprivate _pendingEvents: TEvent[] = [];\n\n\tpublic get version(): Version {\n\t\treturn this._version;\n\t}\n\n\tpublic get persistedVersion(): Version | undefined {\n\t\treturn this._persistedVersion;\n\t}\n\n\t/**\n\t * Read-only list of domain events recorded on this aggregate that\n\t * have not yet been flushed to the outbox / persistence layer.\n\t */\n\tpublic get pendingEvents(): ReadonlyArray<TEvent> {\n\t\treturn Object.freeze(this._pendingEvents.slice());\n\t}\n\n\t/**\n\t * Clears the pending-event list. Called by `markPersisted` after a\n\t * successful write: the events have been handed off to the outbox\n\t * / event store and are no longer the aggregate's responsibility.\n\t */\n\tpublic clearPendingEvents(): void {\n\t\tthis._pendingEvents = [];\n\t}\n\n\tprotected setVersion(version: Version): void {\n\t\tthis._version = version;\n\t}\n\n\t/**\n\t * Manually bumps the aggregate version. Used by state-stored\n\t * aggregates' `setState(_, true)` / `commit()` paths and by the\n\t * event-sourced replay path after each applied event.\n\t */\n\tprotected bumpVersion(): void {\n\t\tthis.setVersion((this._version + 1) as Version);\n\t}\n\n\t/**\n\t * **Lifecycle marker, Post-Load.** Syncs both `_version` and\n\t * `_persistedVersion` to the DB-stored version. Used by\n\t * `reconstitute(...)` factories to assemble an in-memory aggregate\n\t * from a persisted row.\n\t *\n\t * Does NOT fire {@link onPersisted}; that hook has post-save\n\t * semantics (metrics, audit, cache eviction), not post-load. The\n\t * Factory-vs-Reconstitution distinction (Vernon §11) is honoured\n\t * structurally: two separate markers, one for each transition.\n\t *\n\t * **If you override this, call `super.markRestored(version)` FIRST**,\n\t * same discipline as {@link markPersisted}. The marker is load-bearing\n\t * twice over: it syncs `version`/`persistedVersion`, and on\n\t * `AggregateRoot` it also captures the dirty-tracking baseline for\n\t * `changedKeys`/`hasChanges`. An override that skips `super` leaves\n\t * that baseline uncaptured: `changedKeys` permanently reports ALL\n\t * keys and `hasChanges` never returns `false`, so a partial-write\n\t * repository silently degrades to full writes on every save, on top\n\t * of the broken version sync.\n\t *\n\t * @param version - The version the row currently holds in the DB\n\t *\n\t * @example\n\t * ```ts\n\t * static reconstitute(id: OrderId, state: OrderState, version: Version): Order {\n\t * const order = new Order(id, state);\n\t * order.markRestored(version);\n\t * return order;\n\t * }\n\t * ```\n\t */\n\tprotected markRestored(version: Version): void {\n\t\tthis.setVersion(version);\n\t\tthis._persistedVersion = version;\n\t}\n\n\t/**\n\t * **Framework lifecycle method (`@sealed`).** Called by `withCommit`\n\t * (or by your own orchestration code, after harvesting `pendingEvents`)\n\t * to push the persisted version back into the in-memory aggregate and\n\t * clear `pendingEvents`. TypeScript has no `final` keyword, but\n\t * subclasses **should not** override this method directly.\n\t *\n\t * Overriding without calling `super.markPersisted(version)` silently\n\t * leaks `pendingEvents`: the next `withCommit` will re-dispatch them\n\t * through the outbox, double-emitting events. This bug has been hit\n\t * in production by consumers; the {@link onPersisted} hook below is\n\t * the safer extension point.\n\t *\n\t * If you must override (legitimate cases are very rare), call\n\t * `super.markPersisted(version)` FIRST so the framework's cleanup\n\t * runs, then add your logic afterwards.\n\t *\n\t * @param version - The version assigned by the persistence layer\n\t * @see onPersisted, the safe extension point for subclasses\n\t */\n\tpublic markPersisted(version: Version): void {\n\t\tthis.markRestored(version);\n\t\tthis._pendingEvents = [];\n\t\tthis.onPersisted(version);\n\t}\n\n\t/**\n\t * Subclass extension point: fires AFTER {@link markPersisted} has\n\t * updated the version and cleared `pendingEvents`. Override this for\n\t * post-persist logging, metrics, or cache-eviction without risk of\n\t * breaking the framework's pendingEvents cleanup.\n\t *\n\t * The default implementation is a no-op. Subclasses do NOT need to\n\t * call `super.onPersisted(version)`: there is nothing in the parent\n\t * implementation to preserve.\n\t *\n\t * **Observer contract: errors are swallowed.** `withCommit` invokes\n\t * `markPersisted` after the transaction has committed; a throwing hook\n\t * must neither abort the loop for peer aggregates nor make the\n\t * committed write look failed, so `withCommit` catches and discards\n\t * hook errors. Handle failures inside the hook if you need them.\n\t *\n\t * **`onPersisted` deliberately receives only the version, not the\n\t * drained events.** Event-driven post-persist logic (aggregate-level\n\t * audit logging, per-event-type side effects) belongs in `EventBus`\n\t * subscribers or the outbox dispatcher; that is the proper\n\t * Aggregate-Boundary separation. Building event-aware logic into\n\t * `onPersisted` couples aggregate lifecycle to event processing and\n\t * recreates the boundary problems Vernon's aggregate discipline is\n\t * meant to prevent.\n\t *\n\t * **The hook must return synchronously.** `markPersisted` is `void`-\n\t * typed and calls `onPersisted` without `await`. TypeScript's\n\t * permissive `void` will accept an `async`-override returning\n\t * `Promise<void>`, but the returned promise is fire-and-forget:\n\t * any rejection becomes an unhandled rejection and `withCommit`\n\t * proceeds without waiting. For asynchronous work, subscribe to the\n\t * relevant domain event on the `EventBus` instead; that is the\n\t * properly awaited extension point.\n\t *\n\t * @param version - The version that was just persisted\n\t */\n\tprotected onPersisted(_version: Version): void {}\n\n\t/**\n\t * Appends a domain event to the pending list. Prefer the higher-level\n\t * `AggregateRoot.commit()` (state-stored) or `EventSourcedAggregate.apply()`\n\t * (event-sourced) call sites, both of which wrap `addDomainEvent` in the\n\t * canonical record-AFTER-mutation order (Vernon §8). Calling\n\t * `addDomainEvent` directly is appropriate only when state and event\n\t * recording have already been decoupled deliberately (e.g. a\n\t * deletion event before a hard-delete; see `docs/guide/repository.md`).\n\t */\n\tprotected addDomainEvent(event: TEvent): void {\n\t\tthis._pendingEvents.push(event);\n\t}\n\n\t/**\n\t * Creates a snapshot of the current aggregate state: the state at\n\t * this moment plus the version. Useful for ES snapshot policies and\n\t * for state-stored backup / restore.\n\t *\n\t * The state is converted via {@link toSnapshotState}; the default\n\t * requires plain, serialisable data and fails fast otherwise.\n\t *\n\t * `snapshotAt` is read from the kit's swappable clock, the same one\n\t * `createDomainEvent` stamps `occurredAt` from, so\n\t * `setClockFactory` / `withClockFactory` pin snapshot timestamps in\n\t * deterministic tests too. `schemaVersion` is stamped from\n\t * {@link snapshotSchemaVersion} so a later restore can detect\n\t * snapshots written against an older `TSnapshotState` shape.\n\t */\n\tpublic createSnapshot(): AggregateSnapshot<TSnapshotState> {\n\t\treturn {\n\t\t\tstate: this.toSnapshotState(this._state),\n\t\t\tversion: this.version,\n\t\t\tsnapshotAt: now(),\n\t\t\tschemaVersion: this.snapshotSchemaVersion,\n\t\t};\n\t}\n\n\t/**\n\t * Schema version of the shape {@link toSnapshotState} produces.\n\t * Defaults to `1`. Bump it whenever `TSnapshotState` changes\n\t * incompatibly (renamed or removed fields, changed representations):\n\t * `createSnapshot` stamps it onto every snapshot, and the restore\n\t * paths compare it, so an outdated stored snapshot surfaces as a\n\t * `SnapshotSchemaMismatchError` at restore time (or is upgraded via\n\t * {@link migrateSnapshotState}) instead of crashing on the first\n\t * method call much later.\n\t */\n\tprotected readonly snapshotSchemaVersion: number = 1;\n\n\t/**\n\t * Resolves a stored snapshot's state against the aggregate's current\n\t * snapshot schema: pass-through when the versions match (a missing\n\t * `schemaVersion` counts as `1`, the pre-versioning era), otherwise\n\t * routed through {@link migrateSnapshotState}. Called by both restore\n\t * paths BEFORE anything is assigned, so a rejected snapshot leaves\n\t * the aggregate untouched.\n\t */\n\tprotected resolveSnapshotState(\n\t\tsnapshot: AggregateSnapshot<TSnapshotState>,\n\t): TSnapshotState {\n\t\tconst storedSchemaVersion = snapshot.schemaVersion ?? 1;\n\t\tif (storedSchemaVersion === this.snapshotSchemaVersion) {\n\t\t\treturn snapshot.state;\n\t\t}\n\t\treturn this.migrateSnapshotState(snapshot.state, storedSchemaVersion);\n\t}\n\n\t/**\n\t * Upgrade hook for snapshots written against an older\n\t * `TSnapshotState` shape. Receives the stored state as `unknown`\n\t * (its shape is, by definition, not the current `TSnapshotState`)\n\t * plus the schema version it was written with, and returns the\n\t * current shape. The default rejects with\n\t * `SnapshotSchemaMismatchError`: discard-and-refold from the full\n\t * event stream is the safe default strategy; override this only when\n\t * upgrading in place is cheaper than refolding.\n\t */\n\tprotected migrateSnapshotState(\n\t\t_stored: unknown,\n\t\tstoredSchemaVersion: number,\n\t): TSnapshotState {\n\t\tthrow new SnapshotSchemaMismatchError({\n\t\t\taggregateType: this.aggregateType,\n\t\t\taggregateId: String(this.id),\n\t\t\texpectedSchemaVersion: this.snapshotSchemaVersion,\n\t\t\tactualSchemaVersion: storedSchemaVersion,\n\t\t});\n\t}\n\n\t/**\n\t * Converts live aggregate state into the plain-data shape stored in a\n\t * snapshot. The default validates that the state graph is plain,\n\t * serialisable data (no class instances, functions, Promise/WeakMap/\n\t * WeakSet) and then `structuredClone`s it: class instances would\n\t * silently lose their prototype here AND on every snapshot-store\n\t * round-trip, so the default fails fast with the offending path\n\t * instead of producing a snapshot that breaks on first method call\n\t * after restore.\n\t *\n\t * Override this together with {@link fromSnapshotState} (and the\n\t * `TSnapshotState` generic) when the state carries class-based child\n\t * entities. The override owns isolation: return fresh objects, not\n\t * references into live state.\n\t */\n\tprotected toSnapshotState(state: TState): TSnapshotState {\n\t\tassertSnapshotSafe(state, \"\", new WeakSet());\n\t\treturn structuredClone(state) as unknown as TSnapshotState;\n\t}\n\n\t/**\n\t * Converts the plain-data snapshot shape back into live aggregate\n\t * state. The default `structuredClone`s the stored state so the\n\t * restored aggregate never aliases the snapshot object. Override\n\t * together with {@link toSnapshotState} to reconstruct class-based\n\t * child entities.\n\t */\n\tprotected fromSnapshotState(stored: TSnapshotState): TState {\n\t\treturn structuredClone(stored) as unknown as TState;\n\t}\n\n\t/**\n\t * Sugar for `createDomainEvent` that auto-injects `aggregateId`\n\t * (from `this.id`) and `aggregateType` (from {@link aggregateType})\n\t * into the event's metadata fields. This is the canonical path for\n\t * recording events from inside aggregate domain methods.\n\t *\n\t * Downstream consumers (outbox dispatchers, projection handlers,\n\t * audit logs) route by these two fields. Calling\n\t * `createDomainEvent(...)` directly inside an aggregate method\n\t * leaves them unset and is caught at the `withCommit` harvest\n\t * boundary, but `this.recordEvent(...)` makes the right thing\n\t * impossible to forget.\n\t *\n\t * @example\n\t * ```ts\n\t * class Order extends AggregateRoot<OrderState, OrderId, OrderEvent> {\n\t * protected readonly aggregateType = \"Order\";\n\t *\n\t * confirm(): void {\n\t * this.commit(\n\t * { ...this.state, status: \"confirmed\" },\n\t * this.recordEvent(\"OrderConfirmed\", { orderId: this.id }),\n\t * );\n\t * }\n\t * }\n\t * ```\n\t *\n\t * @param type - event type discriminator (must be one of `TEvent`'s tags)\n\t * @param payload - payload for that event subtype\n\t * @param options - any remaining `createDomainEvent` options\n\t * (`eventId`, `occurredAt`, `metadata`, `version`); `aggregateId`\n\t * and `aggregateType` are deliberately omitted, because the helper\n\t * sets them.\n\t */\n\tprotected recordEvent<E extends TEvent>(\n\t\ttype: E[\"type\"],\n\t\tpayload: E[\"payload\"],\n\t\toptions?: Omit<CreateDomainEventOptions, \"aggregateId\" | \"aggregateType\">,\n\t): E {\n\t\treturn createDomainEvent(type, payload, {\n\t\t\t...options,\n\t\t\taggregateId: this.id,\n\t\t\taggregateType: this.aggregateType,\n\t\t}) as DomainEvent<E[\"type\"], E[\"payload\"]> as E;\n\t}\n}\n\n/**\n/**\n * Walks a state graph and throws a descriptive error (with the offending\n * path) when it contains anything `structuredClone` would either reject\n * (functions, Promise/WeakMap/WeakSet) or silently degrade (class\n * instances lose their prototype and methods; Errors lose subclass\n * prototypes and custom fields; symbol-keyed properties are dropped).\n * Used by the default `toSnapshotState` so snapshot corruption surfaces\n * at snapshot time, not on the first method call after a much later\n * restore.\n *\n * Built-in detection is brand-verified via {@link isBuiltInObject}: a\n * plain object spoofing a built-in tag through `Symbol.toStringTag` is\n * walked like any other plain object, so nothing can smuggle unsafe\n * members past the guard. The plain-object walk mirrors what\n * `structuredClone` serialises: own ENUMERABLE string-keyed values\n * (non-enumerable members are deliberately excluded from serialisation\n * and are ignored here too).\n */\nfunction assertSnapshotSafe(\n\tvalue: unknown,\n\tpath: string,\n\tseen: WeakSet<object>,\n): void {\n\tif (typeof value === \"function\") {\n\t\tthrow new Error(\n\t\t\t`createSnapshot: state${path} is a function: snapshot state must be ` +\n\t\t\t\t`plain, serialisable data. Override toSnapshotState()/` +\n\t\t\t\t`fromSnapshotState() to map it.`,\n\t\t);\n\t}\n\tif (value === null || typeof value !== \"object\") return;\n\tconst obj = value as object;\n\tif (seen.has(obj)) return;\n\tseen.add(obj);\n\n\tif (Array.isArray(obj)) {\n\t\tfor (let i = 0; i < obj.length; i++) {\n\t\t\tassertSnapshotSafe(obj[i], `${path}[${i}]`, seen);\n\t\t}\n\t\treturn;\n\t}\n\n\tconst tag = Object.prototype.toString.call(obj);\n\tif (isBuiltInObject(obj, tag)) {\n\t\tif (tag === \"[object Map]\") {\n\t\t\tlet i = 0;\n\t\t\tfor (const [key, entryValue] of obj as Map<unknown, unknown>) {\n\t\t\t\tassertSnapshotSafe(key, `${path}<map key #${i}>`, seen);\n\t\t\t\tassertSnapshotSafe(entryValue, `${path}<map value #${i}>`, seen);\n\t\t\t\ti++;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (tag === \"[object Set]\") {\n\t\t\tlet i = 0;\n\t\t\tfor (const member of obj as Set<unknown>) {\n\t\t\t\tassertSnapshotSafe(member, `${path}<set member #${i}>`, seen);\n\t\t\t\ti++;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (\n\t\t\ttag === \"[object Promise]\" ||\n\t\t\ttag === \"[object WeakMap]\" ||\n\t\t\ttag === \"[object WeakSet]\"\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t`createSnapshot: state${path} is a ${tag.slice(8, -1)}: it cannot ` +\n\t\t\t\t\t`be cloned or persisted. Override toSnapshotState()/` +\n\t\t\t\t\t`fromSnapshotState() to map it.`,\n\t\t\t);\n\t\t}\n\t\tif (tag === \"[object Error]\") {\n\t\t\tthrow new Error(\n\t\t\t\t`createSnapshot: state${path} is an Error: structuredClone ` +\n\t\t\t\t\t`downgrades Error subclasses to plain Error and silently drops ` +\n\t\t\t\t\t`custom fields, so the restored value would not round-trip. ` +\n\t\t\t\t\t`Override toSnapshotState()/fromSnapshotState() to map it to ` +\n\t\t\t\t\t`plain data.`,\n\t\t\t);\n\t\t}\n\t\t// Remaining brand-verified built-ins are snapshot-safe atomics:\n\t\t// Date, RegExp, TypedArrays/DataView, ArrayBuffer(+Shared), and\n\t\t// Boolean/Number/String wrappers. Never walked for own keys (a\n\t\t// deep-frozen Date carries non-enumerable shadow methods that must\n\t\t// not trip the function check).\n\t\treturn;\n\t}\n\n\tconst proto = Object.getPrototypeOf(obj);\n\tif (proto === Object.prototype || proto === null) {\n\t\tfor (const key of Reflect.ownKeys(obj)) {\n\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(obj, key);\n\t\t\tif (!descriptor?.enumerable) continue;\n\t\t\tif (typeof key === \"symbol\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`createSnapshot: state${path} has a symbol-keyed property ` +\n\t\t\t\t\t\t`(${String(key)}): structuredClone silently drops symbol ` +\n\t\t\t\t\t\t`keys, so the snapshot would lose state. Override ` +\n\t\t\t\t\t\t`toSnapshotState()/fromSnapshotState() to map it.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tassertSnapshotSafe(\n\t\t\t\t(obj as Record<PropertyKey, unknown>)[key],\n\t\t\t\t`${path}.${key}`,\n\t\t\t\tseen,\n\t\t\t);\n\t\t}\n\t\treturn;\n\t}\n\n\t// Class instances and unknown exotic objects (including anything whose\n\t// built-in-looking tag failed brand verification): structuredClone\n\t// would strip or reject them: fail fast with the path.\n\tconst name: string = proto.constructor?.name || \"anonymous class\";\n\tthrow new Error(\n\t\t`createSnapshot: state${path} is a class instance (${name}): ` +\n\t\t\t`structuredClone would strip its prototype and methods, producing ` +\n\t\t\t`a snapshot that breaks on the first method call after restore. ` +\n\t\t\t`Override toSnapshotState()/fromSnapshotState() to map child ` +\n\t\t\t`entities to plain data.`,\n\t);\n}\n","import type { Id } from \"../core/id\";\nimport type { EntityConfig } from \"../entity/entity\";\nimport { BaseAggregate } from \"./base-aggregate\";\nimport type { AggregateSnapshot, Version } from \"./aggregate\";\nimport type { AnyDomainEvent } from \"./domain-event\";\n\n// Re-export for backwards compatibility: `IAggregateRoot` lives in\n// `aggregate.ts` (the type hub) but consumers historically imported it\n// from `@shirudo/ddd-kit` / `./aggregate-root`. Keep both paths working.\nexport type { IAggregateRoot } from \"./aggregate\";\n\n/**\n * Configuration options for AggregateRoot behavior. Inherits\n * `deepFreezeState` from {@link EntityConfig} (opt-in deep freeze for\n * plain-data states).\n */\nexport interface AggregateConfig extends EntityConfig {\n\t/**\n\t * Whether `setState()` should bump the version automatically when the\n\t * caller omits the per-call `bumpVersion` argument.\n\t *\n\t * Defaults to **`false`**: `setState()` already takes an explicit\n\t * `bumpVersion` argument per call, so the config is just the default\n\t * the per-call argument falls back to.\n\t *\n\t * **OCC warning: an un-bumped mutation can be silently overwritten.**\n\t * A save whose version did not move writes `WHERE version = v SET\n\t * version = v`; a concurrent writer that loaded the same `v` then\n\t * commits `WHERE version = v` successfully and replaces the state\n\t * without any `ConcurrencyConflictError`. Skip the bump only for data\n\t * whose loss under a concurrent write is acceptable (cosmetic caches,\n\t * denormalized display fields), never for domain state.\n\t *\n\t * **Deprecation notice.** Relying on the implicit default (calling\n\t * `setState(newState)` without a per-call `bumpVersion` and without\n\t * setting this config) is deprecated. v3 makes the per-call argument\n\t * required, so every mutation states its OCC intent explicitly at the\n\t * call site; code that already passes `bumpVersion` or uses `commit()`\n\t * is unaffected.\n\t */\n\tautoVersionBump?: boolean;\n}\n\n/**\n * Base class for Aggregate Roots without Event Sourcing.\n *\n * In DDD (Evans), an Aggregate is a cluster of objects (root entity, child entities,\n * and value objects) treated as a unit for consistency. The **Aggregate Root** is the\n * root entity that represents the aggregate externally and is the only entry point\n * for external code. This class serves as both: it IS the root entity and it contains\n * the aggregate state (`TState`) which holds child entities and value objects.\n *\n * Provides:\n * - Identity (id) and state management (via `Entity`)\n * - Version + persistedVersion + pending-event tracking (via `BaseAggregate`)\n * - `setState`-based mutation with optional version bumping\n * - `commit()` record-after-mutation helper\n * - Snapshot support for performance optimization\n *\n * All changes to child entities within `TState` are versioned through this root.\n * Use `setState()` for state mutations to ensure invariant validation.\n *\n * For event sourcing, use `EventSourcedAggregate` instead.\n *\n * @template TState - The type of the aggregate state (contains child entities and value objects)\n * @template TId - The type of the aggregate root identifier\n * @template TEvent - The type of domain events recorded by this aggregate. Defaults to `never`: aggregates without a declared event type cannot emit events (emitting any event becomes a compile error). Supply a concrete event union to opt in.\n *\n * @example\n * ```typescript\n * // Order is an Aggregate Root (an Entity with version)\n * class Order extends AggregateRoot<OrderState, OrderId> {\n * protected readonly aggregateType = \"Order\";\n *\n * constructor(id: OrderId, initialState: OrderState) {\n * super(id, initialState);\n * }\n *\n * confirm(): void {\n * this.commit(\n * { ...this.state, status: \"confirmed\" },\n * this.recordEvent(\"OrderConfirmed\", { orderId: this.id }),\n * );\n * }\n * }\n * ```\n */\nexport abstract class AggregateRoot<\n\tTState,\n\tTId extends Id<string>,\n\tTEvent extends AnyDomainEvent = never,\n\tTSnapshotState = TState,\n> extends BaseAggregate<TState, TId, TEvent, TSnapshotState> {\n\tprivate readonly _autoVersionBump: boolean;\n\n\t/**\n\t * The state reference as of the last {@link markRestored} /\n\t * `markPersisted` (the persistence-lifecycle markers). Only\n\t * meaningful while {@link _hasBaseline} is `true`; tracked by a\n\t * separate flag rather than an `undefined` sentinel so a `TState`\n\t * that itself admits `undefined` cannot be confused with the\n\t * never-persisted insert path.\n\t *\n\t * Held by reference, never copied: `_state` is shallow-frozen and only\n\t * ever *replaced* (via `setState` / restore), so the captured reference\n\t * stays an exact image of the state at baseline time.\n\t */\n\tprivate _baselineState: TState | undefined = undefined;\n\n\t/**\n\t * `false` until the aggregate has been persisted or restored at least\n\t * once: the insert path, where every key counts as changed.\n\t */\n\tprivate _hasBaseline = false;\n\n\tprotected constructor(\n\t\tid: TId,\n\t\tinitialState: TState,\n\t\tconfig?: AggregateConfig,\n\t) {\n\t\tsuper(id, initialState, config);\n\t\tthis._autoVersionBump = config?.autoVersionBump ?? false;\n\t}\n\n\t/**\n\t * **Lifecycle marker, Post-Load (see `BaseAggregate.markRestored`).**\n\t * Additionally captures the current state reference as the dirty-\n\t * tracking baseline for {@link changedKeys} / {@link hasChanges}.\n\t *\n\t * Covers all three baseline-capture paths through a single override:\n\t * `reconstitute(...)` factories, {@link restoreFromSnapshot} (which\n\t * assigns the restored state *before* calling this), and\n\t * `markPersisted` (which delegates here, so a successful save\n\t * re-baselines the diff).\n\t *\n\t * If you override this, call `super.markRestored(version)` FIRST:\n\t * skipping it leaves the baseline uncaptured, so `changedKeys`\n\t * permanently reports ALL keys and `hasChanges` never returns `false`\n\t * (partial-write repositories silently degrade to full writes), on\n\t * top of breaking version sync.\n\t */\n\tprotected override markRestored(version: Version): void {\n\t\tsuper.markRestored(version);\n\t\tthis._baselineState = this._state;\n\t\tthis._hasBaseline = true;\n\t}\n\n\t/**\n\t * Top-level state keys whose value (or presence) changed since the\n\t * last {@link markRestored} / `markPersisted`. Never-persisted\n\t * aggregates report ALL current keys (the insert path).\n\t *\n\t * This is the write-scoping signal for **partial writes in multi-table\n\t * repositories**: a `save()` for an aggregate whose state spans a root\n\t * row plus N child-collection tables can write only the collections\n\t * whose key is dirty, while the root-row OCC version write rides every\n\t * save. See `docs/guide/repository.md` → \"Partial writes for\n\t * multi-table aggregates\".\n\t *\n\t * **How it works.** `setState()` replaces state immutably and the\n\t * state object is shallow-frozen, so unchanged top-level sub-objects\n\t * keep reference identity across mutations. The diff is therefore a\n\t * shallow per-key `!==` against the baseline reference: O(top-level\n\t * keys), no proxies, no deep diff. A key also counts as dirty when its\n\t * *presence* differs (added or removed, even with an `undefined`\n\t * value). Computed fresh on every access (a new `Set` each time), so\n\t * callers cannot poison later reads.\n\t *\n\t * **Soundness contract (same one `freezeShallow` already makes):**\n\t * the per-key diff is exact only for plain-record `TState` mutated via\n\t * `setState` / `commit` (whole-state replacement). In-place mutation\n\t * of NESTED objects bypasses the shallow freeze AND this diff; a\n\t * class-instance `TState` mutated through its own methods defeats\n\t * tracking entirely (the reference never changes). A keyless `TState`\n\t * (primitive, bare `Date`) has no keys to report, so `changedKeys`\n\t * stays empty for it; use {@link hasChanges}, whose reference\n\t * fallback covers keyless states. A deep-equal but newly-referenced\n\t * value reports a false POSITIVE (harmless extra write); under the\n\t * contract above there are no false negatives.\n\t *\n\t * Granularity is per top-level key, table-granular, not row-granular:\n\t * a dirty collection key means \"this child table changed\", not which\n\t * rows. `EventSourcedAggregate` deliberately has no `changedKeys`;\n\t * its `pendingEvents` are the change record.\n\t */\n\tpublic get changedKeys(): ReadonlySet<Extract<keyof TState, string>> {\n\t\tif (!this._hasBaseline) {\n\t\t\treturn new Set(ownKeys(this._state)) as unknown as ReadonlySet<\n\t\t\t\tExtract<keyof TState, string>\n\t\t\t>;\n\t\t}\n\t\treturn computeChangedKeys(this._baselineState as TState, this._state);\n\t}\n\n\t/**\n\t * Safe skip signal: `false` only when there is genuinely nothing to\n\t * persist or flush. `true` when the aggregate has never been\n\t * persisted, the version moved past `persistedVersion`, there are\n\t * unflushed {@link pendingEvents}, any state key is dirty, or, for\n\t * keyless states the per-key diff cannot see (primitive `TState`,\n\t * zero-own-key objects like a bare `Date`), the state reference\n\t * changed since the baseline.\n\t *\n\t * The version clause is deliberate: `setState({...state}, true)` with\n\t * identical per-key values yields empty {@link changedKeys} but a\n\t * bumped version. If a repository skipped `save()` on a state-only\n\t * check, `withCommit` would still call `markPersisted(version)` after\n\t * commit, desyncing `persistedVersion` from the DB row; and the next\n\t * uncontended save would throw a false `ConcurrencyConflictError`.\n\t *\n\t * The pending-events clause covers the sanctioned decoupled\n\t * `addDomainEvent` path (an event recorded without a state change,\n\t * e.g. a deletion event before a hard delete): the aggregate still\n\t * needs its trip through `withCommit` so the event reaches the\n\t * outbox. With all clauses included, `hasChanges === false` genuinely\n\t * means \"skipping save is safe\".\n\t */\n\tpublic get hasChanges(): boolean {\n\t\tif (!this._hasBaseline) return true;\n\t\tif (this.version !== this.persistedVersion) return true;\n\t\tif (this.pendingEvents.length > 0) return true;\n\t\tif (this.changedKeys.size > 0) return true;\n\t\t// Keyless states are invisible to the per-key diff; fall back to\n\t\t// the state reference itself; setState always replaces it.\n\t\tconst baseline = this._baselineState;\n\t\treturn (\n\t\t\tbaseline !== this._state &&\n\t\t\townKeys(baseline).length === 0 &&\n\t\t\townKeys(this._state).length === 0\n\t\t);\n\t}\n\n\t/**\n\t * Mutates state and records the resulting domain events in the\n\t * **canonical record-after-mutation order**. Use this instead of calling\n\t * `setState` + `addDomainEvent` separately and you cannot trip the\n\t * \"event for a fact that never happened\" footgun.\n\t *\n\t * Order of operations:\n\t * 1. `setState(newState, true)`: runs `validateState` first.\n\t * If it throws, the method propagates and **no event is recorded\n\t * and no version is bumped**.\n\t * 2. Each event in `events` is appended via `addDomainEvent`.\n\t *\n\t * `commit()` **always bumps the version**, regardless of the aggregate's\n\t * `autoVersionBump` config. Recording a domain event implies \"something\n\t * happened that the outside world cares about\", and optimistic-\n\t * concurrency callers must see a fresh version every time. The config\n\t * still governs the un-coupled `setState` path. If you need to mutate\n\t * state without bumping (e.g. cosmetic caches), call `setState(newState,\n\t * false)` and skip `commit` entirely.\n\t *\n\t * `events` accepts a single event or an array. Omit it (or pass `[]`)\n\t * for state-only mutations.\n\t *\n\t * @example\n\t * ```ts\n\t * confirm(): void {\n\t * if (this.state.status === \"confirmed\") {\n\t * throw new OrderAlreadyConfirmedError(this.id);\n\t * }\n\t * this.commit(\n\t * { ...this.state, status: \"confirmed\" },\n\t * this.recordEvent(\"OrderConfirmed\", { orderId: this.id }),\n\t * );\n\t * }\n\t * ```\n\t *\n\t * `EventSourcedAggregate.apply()` enforces the same ordering\n\t * structurally; `commit()` is the opt-in equivalent on `AggregateRoot`,\n\t * where `setState` and `addDomainEvent` are otherwise decoupled and the\n\t * ordering is convention-only.\n\t *\n\t * @param newState - The new state (validated by `validateState`)\n\t * @param events - One event, an array of events, or none (default)\n\t */\n\tprotected commit(\n\t\tnewState: TState,\n\t\tevents: TEvent | readonly TEvent[] = [],\n\t): void {\n\t\tthis.setState(newState, true);\n\t\tconst list: readonly TEvent[] = Array.isArray(events)\n\t\t\t? events\n\t\t\t: [events as TEvent];\n\t\tfor (const ev of list) {\n\t\t\tthis.addDomainEvent(ev);\n\t\t}\n\t}\n\n\t/**\n\t * Sets the state and optionally bumps the version automatically.\n\t * Validates `newState` via `validateState()`.\n\t *\n\t * **State the OCC intent explicitly.** With neither the per-call\n\t * `bumpVersion` argument nor an `autoVersionBump` config, the version\n\t * does not move, and an un-bumped mutation can be silently overwritten\n\t * by a concurrent writer (see the {@link AggregateConfig.autoVersionBump}\n\t * warning for the mechanics). Prefer `commit()` for domain mutations,\n\t * or pass `bumpVersion` explicitly; relying on the implicit default is\n\t * deprecated and v3 makes the argument required.\n\t *\n\t * @param newState - The new state\n\t * @param bumpVersion - Whether to bump the version (defaults to autoVersionBump config)\n\t */\n\tprotected setState(newState: TState, bumpVersion?: boolean): void {\n\t\tsuper.setState(newState);\n\t\tconst shouldBump = bumpVersion ?? this._autoVersionBump;\n\t\tif (shouldBump) {\n\t\t\tthis.bumpVersion();\n\t\t}\n\t}\n\n\t/**\n\t * Restores the aggregate from a snapshot: loads state and aligns\n\t * `version` + `persistedVersion` to the snapshot version. Validates\n\t * the restored state.\n\t *\n\t * @param snapshot - The snapshot to restore from\n\t */\n\tpublic restoreFromSnapshot(snapshot: AggregateSnapshot<TSnapshotState>): void {\n\t\tconst restored = this.fromSnapshotState(this.resolveSnapshotState(snapshot));\n\t\tthis.validateState(restored);\n\t\tthis._state = this.freezeState(restored);\n\t\tthis.markRestored(snapshot.version);\n\t}\n}\n\n/**\n * Own enumerable string keys of a state value; empty for primitives.\n * Mirrors what `shallowCopyOwned` copies and what the snapshot walk\n * serialises (own ENUMERABLE string-keyed values). Symbol-keyed\n * properties are invisible to the diff, exactly as they are invisible\n * to `Object.keys`-based persistence mapping.\n */\nfunction ownKeys(value: unknown): readonly string[] {\n\treturn value !== null && typeof value === \"object\" ? Object.keys(value) : [];\n}\n\n/**\n * Shallow per-key diff between the baseline state and the current state:\n * a key is dirty when its PRESENCE differs (added/removed key, including\n * one whose value was `undefined`) or its value reference differs\n * (`!==`). The never-persisted insert path is handled by the caller\n * (`changedKeys` reports all current keys), not here.\n *\n * Presence is compared via own-enumerable-key membership, never via the\n * prototype chain, so state keys named `constructor` or `__proto__`\n * cannot resolve through `Object.prototype` and compare wrong (same\n * own-key discipline as `EventSourcedAggregate`'s handler dispatch).\n */\nfunction computeChangedKeys<TState>(\n\tbaseline: TState,\n\tcurrent: TState,\n): ReadonlySet<Extract<keyof TState, string>> {\n\tconst baselineKeys = new Set(ownKeys(baseline));\n\tconst currentKeys = new Set(ownKeys(current));\n\tconst dirty = new Set<string>();\n\tfor (const key of currentKeys) {\n\t\tif (!baselineKeys.has(key)) {\n\t\t\t// Added key.\n\t\t\tdirty.add(key);\n\t\t\tcontinue;\n\t\t}\n\t\t// Key is an own enumerable property on BOTH sides; the indexed\n\t\t// reads below can never fall through to the prototype chain.\n\t\tconst before = (baseline as Record<string, unknown>)[key];\n\t\tconst after = (current as Record<string, unknown>)[key];\n\t\tif (before !== after) {\n\t\t\tdirty.add(key);\n\t\t}\n\t}\n\tfor (const key of baselineKeys) {\n\t\tif (!currentKeys.has(key)) {\n\t\t\t// Removed key.\n\t\t\tdirty.add(key);\n\t\t}\n\t}\n\treturn dirty as unknown as ReadonlySet<Extract<keyof TState, string>>;\n}\n","import { err, ok, type Result } from \"@shirudo/result\";\nimport type { Id } from \"../core/id\";\nimport {\n\tDomainError,\n\tMissingHandlerError,\n\tUnreplayableAggregateError,\n} from \"../core/errors\";\nimport { BaseAggregate } from \"./base-aggregate\";\nimport type { AnyDomainEvent } from \"./domain-event\";\nimport type { AggregateSnapshot, IEventSourcedAggregate, Version } from \"./aggregate\";\n\n// Re-export for backwards compatibility: `IEventSourcedAggregate` lives\n// in `aggregate.ts` (the type hub).\nexport type { IEventSourcedAggregate } from \"./aggregate\";\n\ntype Handler<TState, TEvent extends AnyDomainEvent> = (\n\tstate: TState,\n\tevent: TEvent,\n) => TState;\n\n/**\n * Base class for Event-Sourced Aggregate Roots (Vernon, IDDD Chapter 8).\n *\n * Like `AggregateRoot`, this is both the root entity and the aggregate\n * boundary. The difference is persistence: state is derived from events,\n * not stored directly. Events are the single source of truth: all state\n * changes go through `apply()` → handler.\n *\n * Extends `BaseAggregate` (the shared lifecycle machinery) but does NOT\n * expose `setState()` or `commit()` from `AggregateRoot`. This enforces\n * the event sourcing pattern at the type level: there is no way to\n * mutate state without going through an event handler.\n *\n * `apply()` and `validateEvent()` throw `DomainError`-derived exceptions\n * on invariant violations. Subclasses override `validateEvent()` to\n * throw their own concrete subclasses (e.g. `OrderAlreadyConfirmedError`).\n * Only the infrastructure-boundary methods (`loadFromHistory`,\n * `restoreFromSnapshotWithEvents`) return `Result`: they catch\n * `DomainError` during replay so callers can react to corrupted event\n * streams without try/catch.\n *\n * @template TState - The aggregate state (contains child entities and value objects)\n * @template TEvent - The union type of all domain events\n * @template TId - The aggregate root identifier\n *\n * @example\n * ```typescript\n * class OrderAlreadyConfirmedError extends DomainError {\n * constructor(id: OrderId) { super(`Order ${id} is already confirmed`); }\n * }\n *\n * class Order extends EventSourcedAggregate<OrderState, OrderEvent, OrderId> {\n * protected readonly aggregateType = \"Order\";\n *\n * confirm(): void {\n * this.apply(this.recordEvent(\"OrderConfirmed\", { orderId: this.id }));\n * }\n *\n * protected validateEvent(event: OrderEvent): void {\n * if (event.type === \"OrderConfirmed\" && this.state.status === \"confirmed\") {\n * throw new OrderAlreadyConfirmedError(this.id);\n * }\n * }\n *\n * protected readonly handlers = {\n * OrderConfirmed: (state: OrderState): OrderState => ({\n * ...state,\n * status: \"confirmed\",\n * }),\n * };\n * }\n * ```\n */\nexport abstract class EventSourcedAggregate<\n\t\tTState,\n\t\tTEvent extends AnyDomainEvent,\n\t\tTId extends Id<string>,\n\t\tTSnapshotState = TState,\n\t>\n\textends BaseAggregate<TState, TId, TEvent, TSnapshotState>\n\timplements IEventSourcedAggregate<TId, TEvent>\n{\n\t/**\n\t * Validates an event before it is applied. Default is no-op.\n\t * Subclasses override to throw a concrete `DomainError` subclass when\n\t * the event violates an invariant in the current state.\n\t */\n\tprotected validateEvent(_event: TEvent): void {}\n\n\t/**\n\t * Applies an event: validates, locates the handler, computes the next\n\t * state, then commits state + pending event + version bump atomically.\n\t *\n\t * Throws `DomainError` (or a subclass) on validation failure.\n\t * Throws `MissingHandlerError` if no handler is registered for `event.type`.\n\t *\n\t * State is not mutated if any step throws: the handler is invoked into\n\t * a local and only assigned to `_state` once all checks pass.\n\t *\n\t * The method is generic in the event tag `K`, so concrete callers\n\t * (`this.apply(orderCreated)`) narrow to the literal tag and the\n\t * dispatched handler is typed as `Handler<TState, Extract<TEvent, { type: K }>>`,\n\t * with no `as` cast required at the call site.\n\t *\n\t * @param event - The domain event to apply\n\t * @param isNew - Whether the event is new (needs persisting) or replayed from history\n\t */\n\tprotected apply<K extends TEvent[\"type\"]>(\n\t\tevent: Extract<TEvent, { type: K }>,\n\t\tisNew = true,\n\t): void {\n\t\tthis.dispatchAndCommit(event, isNew);\n\t}\n\n\t/**\n\t * Internal dispatch path used by `apply()` and the replay methods\n\t * (`loadFromHistory`, `restoreFromSnapshotWithEvents`). The replay loop\n\t * iterates over `TEvent[]` and therefore cannot supply a narrowed `K`\n\t * generic, so this helper accepts `TEvent` and the discriminator is\n\t * resolved via the (statically-sound) `handlers` map.\n\t */\n\tprivate dispatchAndCommit(event: TEvent, isNew: boolean): void {\n\t\tthis.validateEvent(event);\n\n\t\t// Own-key guard: the handlers map is an object literal, so a plain\n\t\t// property get for event.type === \"toString\" / \"constructor\" /\n\t\t// \"__proto__\" (a corrupt or adversarial stream row) would resolve\n\t\t// through Object.prototype and invoke a non-handler.\n\t\tconst handler = Object.hasOwn(this.handlers, event.type)\n\t\t\t? (this.handlers[event.type as keyof typeof this.handlers] as Handler<\n\t\t\t\t\tTState,\n\t\t\t\t\tTEvent\n\t\t\t\t>)\n\t\t\t: undefined;\n\t\tif (!handler) {\n\t\t\tthrow new MissingHandlerError(event.type);\n\t\t}\n\n\t\tconst nextState = handler(this._state, event);\n\n\t\t// Atomic commit: nothing above this line mutated aggregate state.\n\t\tthis._state = this.freezeState(nextState);\n\t\tif (isNew) {\n\t\t\tthis.addDomainEvent(event);\n\t\t\tthis.bumpVersion();\n\t\t}\n\t}\n\n\t/**\n\t * Reconstitutes the aggregate from an event history. Catches `DomainError`\n\t * thrown during replay and returns it as an `Err`: this is the\n\t * infrastructure boundary, where event-stream corruption is an expected\n\t * recoverable failure. Unexpected (non-DomainError) throws propagate.\n\t *\n\t * All-or-nothing: if any event mid-stream throws, the aggregate's state\n\t * is rolled back to its pre-call value, the same contract as\n\t * `restoreFromSnapshotWithEvents`. Partial replay is never observable.\n\t * (Version needs no rollback: replay dispatches with `isNew = false`,\n\t * which never bumps it; only the final `markRestored` advances it.)\n\t *\n\t * Version advances additively: the aggregate's pre-existing version plus\n\t * `history.length`. A fresh aggregate (v=0) loading 3 events ends at\n\t * v=3; a PERSISTED aggregate at v=P (`persistedVersion === P`) catching\n\t * up on M newer events ends at v=P+M.\n\t *\n\t * **The replay target must be fresh or persisted.** An aggregate with\n\t * unflushed `pendingEvents`, or with an in-memory version that was\n\t * never persisted (a factory-created instance), throws\n\t * {@link UnreplayableAggregateError} BEFORE anything moves: replaying\n\t * onto it would `markRestored` a `persistedVersion` that counts\n\t * unpersisted history, flipping repository routing from INSERT to\n\t * UPDATE (or appending with a wrong expected version). The throw is\n\t * deliberate (crash-loud programming bug), never a `Result` `Err`, and\n\t * runs before the empty-history fast path so the misuse is caught\n\t * deterministically rather than only when the stream happens to be\n\t * non-empty.\n\t */\n\tpublic loadFromHistory(\n\t\thistory: ReadonlyArray<TEvent>,\n\t): Result<void, DomainError> {\n\t\tthis.assertReplayTargetFresh(true);\n\t\t// Empty stream: nothing was loaded, so leave the lifecycle markers\n\t\t// alone. markRestored(version) here would replace the\n\t\t// never-persisted sentinel (persistedVersion === undefined) on a\n\t\t// fresh aggregate, flipping repository routing from INSERT to\n\t\t// UPDATE against a row that does not exist.\n\t\tif (history.length === 0) return ok();\n\n\t\tconst previousState = this._state;\n\t\tconst startVersion = this.version;\n\t\tfor (const event of history) {\n\t\t\ttry {\n\t\t\t\tthis.dispatchAndCommit(event, false);\n\t\t\t} catch (e) {\n\t\t\t\tthis._state = previousState;\n\t\t\t\tif (e instanceof DomainError) return err(e);\n\t\t\t\tthrow e;\n\t\t\t}\n\t\t}\n\t\tthis.markRestored((startVersion + history.length) as Version);\n\t\treturn ok();\n\t}\n\n\t/**\n\t * Restores the aggregate from a snapshot and applies events that occurred\n\t * after. Same infrastructure-boundary semantics as `loadFromHistory`:\n\t * catches `DomainError` and returns it as an `Err`; non-domain throws\n\t * propagate.\n\t *\n\t * All-or-nothing: if any event mid-stream throws a `DomainError`, the\n\t * aggregate is rolled back to its pre-call state + version. Partial\n\t * restoration is never observable to the caller.\n\t *\n\t * **The restore target must not carry pending events.** Events recorded\n\t * before the restore are unrelated to the restored stream; harvesting\n\t * them after `markRestored` would emit them with a version baseline\n\t * they were never part of. Such a target throws\n\t * {@link UnreplayableAggregateError} before anything moves (crash-loud\n\t * programming bug, never a `Result` `Err`). Unlike `loadFromHistory`,\n\t * a never-persisted in-memory version is fine here: the snapshot\n\t * overwrites state and version entirely instead of adding to them.\n\t */\n\tpublic restoreFromSnapshotWithEvents(\n\t\tsnapshot: AggregateSnapshot<TSnapshotState>,\n\t\teventsAfterSnapshot: ReadonlyArray<TEvent>,\n\t): Result<void, DomainError> {\n\t\tthis.assertReplayTargetFresh(false);\n\t\tconst previousState = this._state;\n\t\tconst previousVersion = this.version;\n\t\t// `persistedVersion` is invariant during the loop; no rollback needed.\n\n\t\t// Same guard AggregateRoot.restoreFromSnapshot applies: a corrupt\n\t\t// snapshot store must not reconstitute an invalid aggregate. Runs\n\t\t// BEFORE anything is assigned, so there is nothing to roll back;\n\t\t// a DomainError maps to Err (infrastructure boundary, same contract\n\t\t// as the replay loop below), everything else propagates.\n\t\t// Resolve, convert, and validate BEFORE anything is assigned, all\n\t\t// under the method's documented Result contract: a DomainError from\n\t\t// a migrateSnapshotState override, fromSnapshotState, or\n\t\t// validateState maps to Err (the repository's discard-and-refold\n\t\t// branch must see it), while SnapshotSchemaMismatchError (an\n\t\t// InfrastructureError) and other non-domain throws propagate.\n\t\tlet restored: TState;\n\t\ttry {\n\t\t\trestored = this.fromSnapshotState(this.resolveSnapshotState(snapshot));\n\t\t\tthis.validateState(restored);\n\t\t} catch (e) {\n\t\t\tif (e instanceof DomainError) return err(e);\n\t\t\tthrow e;\n\t\t}\n\n\t\tthis._state = this.freezeState(restored);\n\t\tthis.setVersion(snapshot.version);\n\n\t\tfor (const event of eventsAfterSnapshot) {\n\t\t\ttry {\n\t\t\t\tthis.dispatchAndCommit(event, false);\n\t\t\t} catch (e) {\n\t\t\t\tthis._state = previousState;\n\t\t\t\tthis.setVersion(previousVersion);\n\t\t\t\tif (e instanceof DomainError) return err(e);\n\t\t\t\tthrow e;\n\t\t\t}\n\t\t}\n\n\t\tthis.markRestored(\n\t\t\t(snapshot.version + eventsAfterSnapshot.length) as Version,\n\t\t);\n\t\treturn ok();\n\t}\n\n\t/**\n\t * Replay-target freshness guard shared by `loadFromHistory` and\n\t * `restoreFromSnapshotWithEvents`. See {@link UnreplayableAggregateError}\n\t * for the desync both conditions prevent. `checkUnpersistedVersion` is\n\t * `true` for the additive `loadFromHistory` path only: the snapshot\n\t * restore overwrites version wholesale, so a never-persisted in-memory\n\t * version is harmless there.\n\t */\n\tprivate assertReplayTargetFresh(checkUnpersistedVersion: boolean): void {\n\t\tconst pending = this.pendingEvents.length;\n\t\tif (pending > 0) {\n\t\t\tthrow new UnreplayableAggregateError(\n\t\t\t\tString(this.id),\n\t\t\t\t`it carries ${pending} unflushed pending event(s) that are not ` +\n\t\t\t\t\t\"part of the persisted stream\",\n\t\t\t);\n\t\t}\n\t\tif (\n\t\t\tcheckUnpersistedVersion &&\n\t\t\tthis.version > 0 &&\n\t\t\tthis.persistedVersion === undefined\n\t\t) {\n\t\t\tthrow new UnreplayableAggregateError(\n\t\t\t\tString(this.id),\n\t\t\t\t`its in-memory version (${this.version}) was never persisted ` +\n\t\t\t\t\t\"(persistedVersion is undefined), so additive replay would \" +\n\t\t\t\t\t\"mark unpersisted history as persisted\",\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * A map of event types to their corresponding handlers.\n\t * Subclasses MUST implement this property.\n\t */\n\tprotected abstract readonly handlers: {\n\t\t[K in TEvent[\"type\"]]: Handler<TState, Extract<TEvent, { type: K }>>;\n\t};\n}\n","/**\n * Renders a thrown value into the buses' string error channel without\n * destroying diagnostics: an `Error` contributes its message; anything\n * else (driver SDKs commonly throw structured objects like\n * `{ code: \"DB_CONN\" }`) is JSON-serialised so the fields stay readable;\n * `String(error)` would collapse it to `\"[object Object]\"`.\n */\nexport function describeThrown(error: unknown): string {\n\tif (error instanceof Error) return error.message;\n\ttry {\n\t\tconst json = JSON.stringify(error);\n\t\t// JSON.stringify yields undefined for undefined/functions/symbols.\n\t\tif (json !== undefined) return json;\n\t} catch {\n\t\t// Cyclic or BigInt-bearing values cannot be JSON-serialised.\n\t}\n\treturn String(error);\n}\n","import { err, type Result } from \"@shirudo/result\";\nimport { UnregisteredHandlerError } from \"../core/errors\";\nimport type { Command, CommandHandler } from \"./command\";\nimport { describeThrown } from \"./describe-thrown\";\n\n/**\n * Internal adapter shape for handlers stored in the map.\n *\n * Registered handlers are typed as `CommandHandler<C, TMap[K]>` (narrower\n * input, specific return) and cannot be stored directly in a heterogeneous\n * map (function-parameter contravariance). The closure in `register`\n * downcasts `Command` to the handler's expected `C` based on the\n * dispatch-key invariant (we only call this entry when `cmd.type` matches\n * the key it was registered under). Result is widened to `unknown` here\n * and narrowed back via the public overloads on `execute`.\n */\ntype StoredCommandHandler<E> = (cmd: Command) => Promise<Result<unknown, E>>;\n\n/**\n * Type map for command types to their return types.\n * Used to improve type inference in CommandBus.\n *\n * @example\n * ```typescript\n * type MyCommandMap = {\n * CreateOrder: OrderId;\n * CancelOrder: void;\n * };\n *\n * const bus = new CommandBus<MyCommandMap>();\n * const result = await bus.execute({ type: \"CreateOrder\", ... });\n * // result: Result<OrderId, string> ← automatically inferred\n * ```\n */\ntype CommandTypeMap = Record<string, unknown>;\n\n/**\n * Construction options for {@link CommandBus}.\n *\n * @template E - The error channel type of the bus.\n */\nexport interface CommandBusOptions<E = string> {\n\t/**\n\t * Maps a thrown value (a handler that throws, or dispatch to an\n\t * unregistered command type) into the bus's error channel `E`. Defaults to\n\t * {@link describeThrown}, which renders any thrown value as a `string`.\n\t * base-error's `toStructuredError` fits this slot directly when `E` is a\n\t * `StructuredError`.\n\t */\n\terrorMapper?: (thrown: unknown) => E;\n}\n\n/**\n * Constructor arguments for {@link CommandBus}. When `E` is the default\n * `string`, options are optional (the built-in {@link describeThrown} mapper\n * applies). When `E` is widened, an `errorMapper` is required, so a typed\n * channel can never silently fall back to string values.\n */\ntype CommandBusArgs<E> = [E] extends [string]\n\t? [options?: CommandBusOptions<E>]\n\t: [options: CommandBusOptions<E> & { errorMapper: (thrown: unknown) => E }];\n\n/**\n * Command Bus interface for dispatching commands to their handlers.\n * Provides a centralized way to execute commands with handler registration.\n *\n * Supports an optional type map (`TMap`) for automatic return type inference.\n * Without a type map, the return type must be specified manually or defaults to `unknown`.\n *\n * @template TMap - Optional mapping from command type strings to return types\n *\n * @example\n * ```typescript\n * // With type map (recommended) – return type is inferred\n * type MyCommands = { CreateOrder: OrderId; CancelOrder: void };\n * const bus = new CommandBus<MyCommands>();\n * const result = await bus.execute({ type: \"CreateOrder\", ... });\n * // result: Result<OrderId, string>\n *\n * // Without type map – works like before\n * const bus = new CommandBus();\n * bus.register(\"CreateOrder\", createOrderHandler);\n * const result = await bus.execute({ type: \"CreateOrder\", ... });\n * // result: Result<unknown, string>\n * ```\n */\nexport interface ICommandBus<\n\tTMap extends CommandTypeMap = CommandTypeMap,\n\tE = string,\n> {\n\t/**\n\t * Executes a command by dispatching it to the registered handler.\n\t * When a type map is provided, the return type is inferred from the command type.\n\t *\n\t * @param command - The command to execute\n\t * @returns Result containing the success value or an error of type `E`\n\t */\n\texecute<C extends Command & { type: keyof TMap & string }>(\n\t\tcommand: C,\n\t): Promise<Result<TMap[C[\"type\"]], E>>;\n\texecute<C extends Command, R>(command: C): Promise<Result<R, E>>;\n\n\t/**\n\t * Registers a handler for a specific command type.\n\t *\n\t * When `TMap` is supplied, the `commandType` argument is restricted to\n\t * its keys and the handler signature is forced to match `TMap[K]` for the\n\t * return value: typos and wrong-typed handlers are compile errors.\n\t * Without `TMap` the registration is loose (any string key, any return\n\t * type) so the no-config path keeps working.\n\t *\n\t * @param commandType - The command type to register the handler for\n\t * @param handler - The handler function for this command type\n\t */\n\tregister<\n\t\tK extends keyof TMap & string,\n\t\tC extends Command & { type: K } = Command & { type: K },\n\t>(commandType: K, handler: CommandHandler<C, TMap[K], E>): void;\n}\n\n/**\n * Simple in-memory command bus implementation.\n * Handlers are stored in a Map and dispatched based on command type.\n *\n * Supports an optional type map (`TMap`) for automatic return type inference.\n * When `TMap` is provided, `execute()` infers the result type from the command type.\n * Without `TMap`, it works like before (return type defaults to `unknown` or can be specified manually).\n *\n * **Note:** This is a basic implementation suitable for development and simple use cases.\n * For production environments, consider implementing or using a more feature-rich bus that includes:\n * - Middleware/Pipeline support (logging, validation, authorization)\n * - Error handling and retry logic\n * - Timeout handling\n * - Metrics and observability\n * - Transaction management\n * - Dead letter queue support\n *\n * The `CommandHandler` type can still be used with external production-grade buses\n * (e.g., RabbitMQ, AWS SQS) while maintaining type safety.\n *\n * @template TMap - Optional mapping from command type strings to return types\n *\n * @example\n * ```typescript\n * // With type map – full inference\n * type Commands = { CreateOrder: OrderId; CancelOrder: void };\n * const bus = new CommandBus<Commands>();\n * const result = await bus.execute({ type: \"CreateOrder\", ... });\n * // result: Result<OrderId, string>\n *\n * // Without type map – same as before\n * const bus = new CommandBus();\n * bus.register(\"CreateOrder\", async (cmd) => ok(orderId));\n * const result = await bus.execute({ type: \"CreateOrder\", ... });\n * ```\n */\nexport class CommandBus<\n\tTMap extends CommandTypeMap = CommandTypeMap,\n\tE = string,\n> implements ICommandBus<TMap, E>\n{\n\tprivate readonly handlers = new Map<string, StoredCommandHandler<E>>();\n\tprivate readonly errorMapper: (thrown: unknown) => E;\n\n\tconstructor(...args: CommandBusArgs<E>) {\n\t\t// describeThrown produces a string; that is the correct mapper only for\n\t\t// the default E = string. CommandBusArgs makes errorMapper mandatory once\n\t\t// E is widened, so this fallback is never reached with a non-string E.\n\t\tthis.errorMapper =\n\t\t\targs[0]?.errorMapper ?? (describeThrown as (thrown: unknown) => E);\n\t}\n\n\tregister<\n\t\tK extends keyof TMap & string,\n\t\tC extends Command & { type: K } = Command & { type: K },\n\t>(commandType: K, handler: CommandHandler<C, TMap[K], E>): void {\n\t\t// Silent replacement would turn the first handler into dead code\n\t\t// with no signal; wiring bugs must surface at registration time.\n\t\tif (this.handlers.has(commandType)) {\n\t\t\tthrow new Error(\n\t\t\t\t`CommandBus: a handler for command type \"${commandType}\" is already registered`,\n\t\t\t);\n\t\t}\n\t\tthis.handlers.set(commandType, (cmd) => handler(cmd as C));\n\t}\n\n\tasync execute<C extends Command & { type: keyof TMap & string }>(\n\t\tcommand: C,\n\t): Promise<Result<TMap[C[\"type\"]], E>>;\n\tasync execute<C extends Command, R>(command: C): Promise<Result<R, E>>;\n\tasync execute<C extends Command, R>(command: C): Promise<Result<R, E>> {\n\t\tconst handler = this.handlers.get(command.type);\n\t\tif (!handler) {\n\t\t\t// A wiring bug, not a domain failure: the NAMED error type lets a\n\t\t\t// typed error channel route it explicitly. Delivered through the\n\t\t\t// channel (not thrown) for 2.x compatibility; the message is\n\t\t\t// byte-identical to what the default string channel always carried.\n\t\t\treturn err(\n\t\t\t\tthis.errorMapper(\n\t\t\t\t\tnew UnregisteredHandlerError({\n\t\t\t\t\t\tbusKind: \"command\",\n\t\t\t\t\t\tmessageType: command.type,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\ttry {\n\t\t\treturn (await handler(command)) as Result<R, E>;\n\t\t} catch (error) {\n\t\t\treturn err(this.errorMapper(error));\n\t\t}\n\t}\n}\n","/**\n * The value to reject with when an `AbortSignal` has fired.\n *\n * Returns the signal's `reason` (a `DOMException` `AbortError` for\n * `controller.abort()`, `TimeoutError` for `AbortSignal.timeout`), falling\n * back to a plain `Error` with `fallbackMessage` when `reason` is nullish.\n * A spec-compliant signal always populates `reason` when aborted, so the\n * fallback only fires for a non-spec polyfill; without it, a bare\n * `throw undefined` would surface, breaking `instanceof Error` handling.\n *\n * Centralizes the `signal.reason ?? new Error(...)` idiom used at every\n * abort site (event bus, `withCommit`, `UnitOfWork.run`, the retrying\n * scope) so a single fix covers all of them.\n */\nexport function abortReason(\n\tsignal: AbortSignal,\n\tfallbackMessage: string,\n): unknown {\n\treturn signal.reason ?? new Error(fallbackMessage);\n}\n","/**\n * Invokes a fire-and-forget observer hook (`onPersistError`,\n * `onPublishError`, `onRetry`) and neutralises BOTH failure shapes it can\n * produce. The observers are typed `(...) => void`, but a `void` return\n * type still admits an `async` function, so an observer can fail in two\n * ways: a synchronous throw, or a rejected promise. Either would replace\n * or mask the operation's real outcome (a committed write made to look\n * failed, a retryable error swapped for the observer's own), and the\n * async rejection additionally becomes an `unhandledRejection` that can\n * crash the process under Node's default policy. Both are swallowed\n * here: observers report, they never affect the operation they observe.\n *\n * Internal utility (not exported from the package barrels).\n */\nexport function reportToObserver(invoke: () => void): void {\n\tlet result: unknown;\n\ttry {\n\t\tresult = invoke() as unknown;\n\t} catch {\n\t\treturn;\n\t}\n\tif (\n\t\tresult !== null &&\n\t\ttypeof result === \"object\" &&\n\t\ttypeof (result as { then?: unknown }).then === \"function\"\n\t) {\n\t\t(result as Promise<unknown>).then(undefined, () => {});\n\t}\n}\n","import type { IAggregateRoot } from \"../aggregate/aggregate-root\";\nimport type { AnyDomainEvent } from \"../aggregate/domain-event\";\nimport { EventHarvestError } from \"../core/errors\";\nimport type { Id } from \"../core/id\";\nimport type { EventBus, Outbox } from \"../events/ports\";\nimport type { TransactionScope } from \"../repo/scope\";\nimport { abortReason } from \"../utils/abort\";\nimport { reportToObserver } from \"../utils/observer\";\n\n/**\n * Helper for executing a write Use Case inside a transaction scope.\n *\n * The use-case callback returns the aggregates it touched; `withCommit`\n * owns the post-save lifecycle (harvest, outbox, mark-persisted, publish).\n * This matches the Vernon / Axon / EventFlow unit-of-work pattern:\n * `Repository.save` is pure persistence; \"this aggregate has been\n * committed\" is the orchestrator's call to make, not the repo's.\n *\n * Order of operations:\n * 1. `fn(ctx)` runs inside `scope.transactional(...)`; domain mutations\n * + repo writes happen here. `ctx` is whatever transaction handle the\n * `scope` exposes (Drizzle `tx`, Prisma `tx`, Mongo session, or\n * `undefined` for context-free scopes).\n * 2. **Still inside the transaction**, `withCommit` harvests every\n * aggregate's `pendingEvents` and writes them via `outbox.add` (so\n * events persist atomically with the state change). Skipped when no\n * events were recorded. Each harvested event is stamped with\n * `aggregateVersion` = the aggregate's commit version (onto a frozen\n * copy; a pre-set value wins) - consumers get the OCC version the\n * row was written with, for cross-commit ordering and debugging.\n * All events of one commit share the stamp, so per-event dedup\n * belongs on `eventId`, not on this value (see the outbox guide).\n *\n * **Harvest order.** Events are concatenated in the order\n * aggregates appear in the returned `aggregates` array, then in\n * each aggregate's `pendingEvents` order (insertion order via\n * `apply` / `commit` / `addDomainEvent`). So `aggregates: [a, b]`\n * with `a` emitting `[e1, e2]` and `b` emitting `[e3]` produces\n * `outbox.add([e1, e2, e3])` and `bus.publish([e1, e2, e3])` in\n * that exact order.\n *\n * **Two ordering guarantees, not one.** Within a single aggregate\n * the order is *causal*: events are recorded in the order the\n * domain methods ran, and subscribers (handlers, projections,\n * replay) MUST process them in that order. Across aggregates the\n * order in this batch is deterministic but *not* a domain\n * guarantee. Greg Young / Vernon IDDD §10: aggregates are\n * independent consistency boundaries; events across them are\n * eventually consistent. Subscribers should NOT engineer\n * dependencies on cross-aggregate ordering; use\n * `EventMetadata.causationId` to express true causation, or a\n * process manager to coordinate. The in-process EventBus delivers\n * this batch in order, sequential outbox-dispatchers preserve it\n * too, but parallel dispatchers or message brokers may reorder\n * across aggregates at delivery time.\n * 3. The transaction commits.\n * 4. **After** the commit, `aggregate.markPersisted(aggregate.version)`\n * fires on each returned aggregate; only now are pending events\n * considered flushed. Aggregates listed in the optional `deleted`\n * marker array are the exception: their pending events are cleared\n * directly WITHOUT `markPersisted`, so the post-save `onPersisted`\n * hook never fires for a row that was just deleted.\n * 5. `bus.publish(events)` fires for the in-process fast path (skipped\n * when no events or no `bus` is wired).\n *\n * Publishing AFTER commit prevents the classic \"publish before commit\"\n * footgun: in-process subscribers can never react to events from a\n * transaction that later rolled back. If `bus.publish` itself throws, the\n * outbox still holds the events and an outbox-dispatcher will deliver\n * them (eventual consistency).\n *\n * **A `bus.publish` failure never rejects `withCommit`.** Once the\n * transaction has committed, the write succeeded; surfacing a subscriber\n * failure as a rejection would hand the caller a use-case failure for a\n * committed write (a typical caller retries, double-executing it). The\n * in-process fast path is best-effort by design; the error is reported to\n * the optional `onPublishError(error, events)` hook (wire it to your\n * logger/metrics) and otherwise dropped; delivery is still guaranteed via\n * the outbox. The hook is an observer: if it throws, its error is\n * swallowed so the post-commit invariant holds.\n *\n * If the transaction rolls back, `markPersisted` is **not** called: the\n * aggregate keeps its pending events, so the caller can retry or discard.\n *\n * **Do not mutate an aggregate after `repository.save(...)` inside `fn`.**\n * `withCommit` cannot see what `save` wrote; the post-commit\n * `markPersisted` syncs `persistedVersion` to the CURRENT in-memory\n * version and (on `AggregateRoot`) re-baselines dirty tracking against\n * the CURRENT state. A mutation between `save` and the callback's return\n * therefore desyncs OCC (next save throws a false\n * `ConcurrencyConflictError`); and under a partial-write repository\n * using `changedKeys`, an un-bumped mutation is silently marked clean\n * and never written. The `aggregateVersion` stamp widens the blast\n * radius further: harvested events would publicly claim a version the\n * committed row does not carry, poisoning every consumer's ordering\n * and idempotency watermarks: a cross-service inconsistency, not just\n * a local one. Mutate first, save last.\n *\n * **Duplicate aggregates are deduped by reference.** If the returned\n * `aggregates` array contains the same instance twice (e.g. a use\n * case touches an order via two repository references that happen to\n * resolve to the same identity-map entry), `withCommit` dedupes by\n * JavaScript object identity before harvesting. Each event lands in\n * the outbox exactly once and `markPersisted` fires exactly once. Two\n * *different* instances with the same logical id cannot be detected\n * at this layer; that is a Repository contract violation (failure to\n * maintain Fowler's Identity Map per Unit of Work). See\n * `docs/guide/repository.md` → \"Identity Map: one instance per\n * aggregate per Unit of Work\" for the requirement on `IRepository`\n * implementations that makes this dedupe sound.\n *\n * @example Tx-bound repos (Drizzle, Prisma, Mongo, …)\n * ```typescript\n * const result = await withCommit({ outbox, bus, scope }, async (tx) => {\n * const orderRepository = makeOrderRepository(tx); // your factory binds tx to the repo\n * const order = await orderRepository.getByIdOrFail(orderId);\n * order.confirm();\n * await orderRepository.save(order); // pure persistence; does NOT call markPersisted\n * return { result: order.id, aggregates: [order] };\n * });\n * ```\n */\nexport async function withCommit<Evt extends AnyDomainEvent, R, TCtx>(\n\tdeps: {\n\t\toutbox: Outbox<Evt>;\n\t\tbus?: EventBus<Evt>;\n\t\tscope: TransactionScope<TCtx>;\n\t\t/**\n\t\t * Observer for post-commit `bus.publish` failures. Called with the\n\t\t * error and the events that were published. Must not be relied on\n\t\t * for delivery: the outbox dispatcher is the reliable path.\n\t\t */\n\t\tonPublishError?: (\n\t\t\terror: unknown,\n\t\t\tevents: ReadonlyArray<Evt>,\n\t\t) => void;\n\t\t/**\n\t\t * Observer for post-commit persistence-cleanup failures: a throw from\n\t\t * `markPersisted`, the user-overridable `onPersisted` hook, or\n\t\t * `clearPendingEvents`. Called once per failing aggregate with the\n\t\t * error and that aggregate. Symmetric with {@link onPublishError}: the\n\t\t * transaction has already committed, so the failure must NOT reject the\n\t\t * write; without this observer it would otherwise vanish silently. The\n\t\t * hook is an observer only: if it throws, its error is swallowed so the\n\t\t * post-commit invariant holds, and the loop continues marking the\n\t\t * remaining aggregates.\n\t\t */\n\t\tonPersistError?: (\n\t\t\terror: unknown,\n\t\t\taggregate: IAggregateRoot<Id<string>, Evt>,\n\t\t) => void;\n\t\t/**\n\t\t * Cooperative-cancellation signal. If already aborted, `withCommit`\n\t\t * rejects with the signal's `reason` BEFORE opening the transaction.\n\t\t * Otherwise the signal is forwarded to `scope.transactional`, where a\n\t\t * cancellation-aware scope can abort an in-flight query. The kit does\n\t\t * not race the work promise: aborting does not kill a running query\n\t\t * unless the scope honors the signal.\n\t\t */\n\t\tsignal?: AbortSignal;\n\t},\n\tfn: (ctx: TCtx) => Promise<{\n\t\tresult: R;\n\t\taggregates: ReadonlyArray<IAggregateRoot<Id<string>, Evt>>;\n\t\t/**\n\t\t * Optional marker: which of `aggregates` were DELETED in this unit\n\t\t * of work. Their pending events are harvested like any other\n\t\t * (deletion events must reach the outbox), but the post-commit\n\t\t * lifecycle differs: `markPersisted` is NOT called on them. It\n\t\t * would fire the user-overridable `onPersisted` hook, whose\n\t\t * post-save semantics (cache fill, read-model warm-up) are a lie\n\t\t * for a row that was just deleted. Their pending events are\n\t\t * cleared directly instead, so a later commit cannot re-emit them.\n\t\t */\n\t\tdeleted?: ReadonlyArray<IAggregateRoot<Id<string>, Evt>>;\n\t}>,\n): Promise<R> {\n\t// Pre-flight: an already-aborted caller never opens a transaction.\n\t// Throwing the signal's reason matches the web AbortSignal convention;\n\t// the `??` fallback mirrors event-bus.ts and guards a non-spec polyfill\n\t// whose `reason` is undefined (a bare `throw undefined` is unusable).\n\tif (deps.signal?.aborted) {\n\t\tthrow abortReason(deps.signal, \"withCommit aborted before opening a transaction\");\n\t}\n\n\tconst { result, aggregates, deleted, events } = await deps.scope.transactional(\n\t\tasync (ctx) => {\n\t\t\tconst fnResult = await fn(ctx);\n\t\t\t// Dedupe by object identity. A use case that touches the same\n\t\t\t// aggregate via two repository references (same identity-map\n\t\t\t// entry) would otherwise double-harvest its events and call\n\t\t\t// markPersisted twice. Distinct instances with the same logical\n\t\t\t// id are NOT detected here; that's a different misuse class.\n\t\t\tconst uniqueAggregates = Array.from(new Set(fnResult.aggregates));\n\t\t\t// Stamp each harvested event with its aggregate's COMMIT version\n\t\t\t// (the value the OCC row write carries for saved aggregates).\n\t\t\t// Events are deeply frozen at creation, so the stamp goes onto a\n\t\t\t// frozen shallow copy - the aggregate's own pendingEvents stay\n\t\t\t// untouched, and a manually pre-set aggregateVersion is never\n\t\t\t// overwritten. The outbox and the bus receive the stamped copies.\n\t\t\t// NOTE: the shallow copy assumes events are PLAIN DATA objects\n\t\t\t// (the createDomainEvent / recordEvent contract); class-based\n\t\t\t// event objects with prototype members are unsupported.\n\t\t\tconst harvested = uniqueAggregates.flatMap((agg) =>\n\t\t\t\tagg.pendingEvents.map((event) => {\n\t\t\t\t\tif (event.aggregateVersion === undefined) {\n\t\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\t\t...event,\n\t\t\t\t\t\t\taggregateVersion: agg.version as number,\n\t\t\t\t\t\t}) as Evt;\n\t\t\t\t\t}\n\t\t\t\t\t// Pre-set values win (replay fixtures, backfills) - but a\n\t\t\t\t\t// pre-set AHEAD of the commit version is always a leaked\n\t\t\t\t\t// fixture or copied options object, and consumers key\n\t\t\t\t\t// idempotency watermarks on this number: fail fast, same\n\t\t\t\t\t// posture as the aggregateId/aggregateType guard below.\n\t\t\t\t\tif (event.aggregateVersion > (agg.version as number)) {\n\t\t\t\t\t\tthrow new EventHarvestError(\n\t\t\t\t\t\t\t`withCommit: event \"${event.type}\" carries a pre-set ` +\n\t\t\t\t\t\t\t\t`aggregateVersion (${event.aggregateVersion}) AHEAD of its ` +\n\t\t\t\t\t\t\t\t`aggregate's commit version (${agg.version}). A stale-or-` +\n\t\t\t\t\t\t\t\t`copied pre-set would advance consumer idempotency ` +\n\t\t\t\t\t\t\t\t`watermarks past real history; remove the manual ` +\n\t\t\t\t\t\t\t\t`aggregateVersion or correct it.`,\n\t\t\t\t\t\t\t\tevent.type,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn event;\n\t\t\t\t}),\n\t\t\t);\n\t\t\t// Guard: every event harvested from an aggregate MUST carry\n\t\t\t// aggregateId + aggregateType. Downstream consumers (outbox\n\t\t\t// dispatchers, projection handlers, audit logs) route by these\n\t\t\t// fields; missing them silently breaks routing. The\n\t\t\t// `this.recordEvent(...)` helper on AggregateRoot /\n\t\t\t// EventSourcedAggregate injects them automatically; this guard\n\t\t\t// catches the case where someone called `createDomainEvent(...)`\n\t\t\t// directly inside an aggregate method and forgot the options.\n\t\t\tfor (const event of harvested) {\n\t\t\t\tconst missing: string[] = [];\n\t\t\t\tif (!event.aggregateId) missing.push(\"aggregateId\");\n\t\t\t\tif (!event.aggregateType) missing.push(\"aggregateType\");\n\t\t\t\tif (missing.length > 0) {\n\t\t\t\t\tthrow new EventHarvestError(\n\t\t\t\t\t\t`withCommit: event \"${event.type}\" is missing ${missing.join(\n\t\t\t\t\t\t\t\" and \",\n\t\t\t\t\t\t)}. ` +\n\t\t\t\t\t\t\t`Use this.recordEvent(type, payload) inside aggregate methods ` +\n\t\t\t\t\t\t\t`instead of createDomainEvent(...); recordEvent auto-injects ` +\n\t\t\t\t\t\t\t`aggregateId and aggregateType. Outbox dispatchers and ` +\n\t\t\t\t\t\t\t`projection handlers rely on these fields for routing.`,\n\t\t\t\t\t\t\tevent.type,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (harvested.length > 0) {\n\t\t\t\tawait deps.outbox.add(harvested);\n\t\t\t}\n\t\t\treturn {\n\t\t\t\t...fnResult,\n\t\t\t\taggregates: uniqueAggregates,\n\t\t\t\tdeleted: new Set(fnResult.deleted ?? []),\n\t\t\t\tevents: harvested,\n\t\t\t};\n\t\t},\n\t\t{ signal: deps.signal },\n\t);\n\n\t// Post-commit: mark each aggregate as persisted (clears pendingEvents).\n\t// Done AFTER the tx commits so a rolled-back transaction never silently\n\t// \"consumes\" the in-memory pending events. DELETED aggregates get their\n\t// pending events cleared without markPersisted: the row is gone, and\n\t// firing the post-save onPersisted hook for a deletion would hand the\n\t// hook a semantic lie (see the `deleted` field JSDoc above).\n\tfor (const agg of aggregates) {\n\t\ttry {\n\t\t\tif (deleted.has(agg)) {\n\t\t\t\tagg.clearPendingEvents();\n\t\t\t} else {\n\t\t\t\tagg.markPersisted(agg.version);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// Only the user-overridable onPersisted hook can throw here, and\n\t\t\t// it runs AFTER the framework cleanup (events already flushed for\n\t\t\t// THIS aggregate). Aborting the loop would leave the remaining\n\t\t\t// aggregates un-marked (double-emitting their events on the next\n\t\t\t// commit) and reject a committed write. Hook failures are\n\t\t\t// observer failures: the post-commit invariant wins. Report the\n\t\t\t// failure to onPersistError instead of dropping it silently\n\t\t\t// (symmetric with the onPublishError path below); a throwing OR\n\t\t\t// async-rejecting observer is neutralised so it cannot break the\n\t\t\t// invariant either.\n\t\t\treportToObserver(() => deps.onPersistError?.(error, agg));\n\t\t}\n\t}\n\n\tif (deps.bus && events.length > 0) {\n\t\ttry {\n\t\t\tawait deps.bus.publish(events);\n\t\t} catch (error) {\n\t\t\t// The tx has committed and the outbox holds the events; an\n\t\t\t// outbox dispatcher will deliver them. Rejecting here would turn\n\t\t\t// a committed write into an apparent use-case failure (callers\n\t\t\t// would retry and double-execute). A throwing OR async-rejecting\n\t\t\t// observer is neutralised so it cannot break the invariant either.\n\t\t\treportToObserver(() => deps.onPublishError?.(error, events));\n\t\t}\n\t}\n\n\treturn result;\n}\n","import { err, ok, type Result } from \"@shirudo/result\";\nimport { UnregisteredHandlerError } from \"../core/errors\";\nimport { describeThrown } from \"./describe-thrown\";\nimport type { Query, QueryHandler } from \"./query\";\n\n/**\n * Internal adapter shape for handlers stored in the map.\n *\n * Registered handlers are typed as `QueryHandler<Q, TMap[K]>` (narrower\n * input, specific return) and cannot be stored directly in a heterogeneous\n * map (function-parameter contravariance). The closure in `register`\n * downcasts `Query` to the handler's expected `Q` based on the\n * dispatch-key invariant (we only call this entry when `query.type` matches\n * the key it was registered under). Result is widened to `unknown` here\n * and narrowed back via the public overloads on `execute` / `executeUnsafe`.\n */\ntype StoredQueryHandler = (query: Query) => Promise<unknown>;\n\n/**\n * Type map for query types to their return types.\n * Used to improve type inference in QueryBus.\n *\n * @example\n * ```typescript\n * type MyQueryMap = {\n * GetOrder: Order | null;\n * ListOrders: Order[];\n * };\n *\n * const bus = new QueryBus<MyQueryMap>();\n * const result = await bus.execute({ type: \"GetOrder\", orderId: \"123\" });\n * // result: Result<Order | null, string> ← automatically inferred\n * ```\n */\ntype QueryTypeMap = Record<string, unknown>;\n\n/**\n * Construction options for {@link QueryBus}.\n *\n * @template E - The error channel type of the bus.\n */\nexport interface QueryBusOptions<E = string> {\n\t/**\n\t * Maps a thrown value (a handler that throws, or dispatch to an\n\t * unregistered query type) into the bus's error channel `E`. Defaults to\n\t * {@link describeThrown}, which renders any thrown value as a `string`.\n\t * base-error's `toStructuredError` fits this slot directly when `E` is a\n\t * `StructuredError`.\n\t */\n\terrorMapper?: (thrown: unknown) => E;\n}\n\n/**\n * Constructor arguments for {@link QueryBus}. When `E` is the default `string`,\n * options are optional (the built-in {@link describeThrown} mapper applies).\n * When `E` is widened, an `errorMapper` is required, so a typed channel can\n * never silently fall back to string values.\n */\ntype QueryBusArgs<E> = [E] extends [string]\n\t? [options?: QueryBusOptions<E>]\n\t: [options: QueryBusOptions<E> & { errorMapper: (thrown: unknown) => E }];\n\n/**\n * Query Bus interface for dispatching queries to their handlers.\n * Provides a centralized way to execute queries with handler registration.\n *\n * Supports an optional type map (`TMap`) for automatic return type inference.\n * Without a type map, the return type must be specified manually or defaults to `unknown`.\n *\n * @template TMap - Optional mapping from query type strings to return types\n *\n * @example\n * ```typescript\n * // With type map (recommended) – return type is inferred\n * type MyQueries = { GetOrder: Order | null; ListOrders: Order[] };\n * const bus = new QueryBus<MyQueries>();\n * const result = await bus.execute({ type: \"GetOrder\", orderId: \"123\" });\n * // result: Result<Order | null, string>\n *\n * // Without type map – works like before\n * const bus = new QueryBus();\n * const result = await bus.execute({ type: \"GetOrder\", orderId: \"123\" });\n * // result: Result<unknown, string>\n * ```\n */\nexport interface IQueryBus<\n\tTMap extends QueryTypeMap = QueryTypeMap,\n\tE = string,\n> {\n\t/**\n\t * Executes a query by dispatching it to the registered handler.\n\t * When a type map is provided, the return type is inferred from the query type.\n\t *\n\t * @param query - The query to execute\n\t * @returns Result containing the query result if successful, or an error message\n\t */\n\texecute<Q extends Query & { type: keyof TMap & string }>(\n\t\tquery: Q,\n\t): Promise<Result<TMap[Q[\"type\"]], E>>;\n\texecute<Q extends Query, R>(query: Q): Promise<Result<R, E>>;\n\n\t/**\n\t * Executes a query by dispatching it to the registered handler.\n\t * Throws an error if no handler is registered.\n\t *\n\t * @param query - The query to execute\n\t * @returns The query result\n\t * @throws Error if no handler is registered for the query type\n\t */\n\texecuteUnsafe<Q extends Query & { type: keyof TMap & string }>(\n\t\tquery: Q,\n\t): Promise<TMap[Q[\"type\"]]>;\n\texecuteUnsafe<Q extends Query, R>(query: Q): Promise<R>;\n\n\t/**\n\t * Registers a handler for a specific query type.\n\t *\n\t * When `TMap` is supplied, the `queryType` argument is restricted to its\n\t * keys and the handler signature is forced to match `TMap[K]` for the\n\t * return value: typos and wrong-typed handlers are compile errors.\n\t * Without `TMap` the registration is loose (any string key, any return\n\t * type) so the no-config path keeps working.\n\t *\n\t * @param queryType - The query type to register the handler for\n\t * @param handler - The handler function for this query type\n\t */\n\tregister<\n\t\tK extends keyof TMap & string,\n\t\tQ extends Query & { type: K } = Query & { type: K },\n\t>(queryType: K, handler: QueryHandler<Q, TMap[K]>): void;\n}\n\n/**\n * Simple in-memory query bus implementation.\n * Handlers are stored in a Map and dispatched based on query type.\n *\n * Supports an optional type map (`TMap`) for automatic return type inference.\n * When `TMap` is provided, `execute()` and `executeUnsafe()` infer the result type from the query type.\n * Without `TMap`, it works like before (return type defaults to `unknown` or can be specified manually).\n *\n * **Note:** This is a basic implementation suitable for development and simple use cases.\n * For production environments, consider implementing or using a more feature-rich bus that includes:\n * - Middleware/Pipeline support (logging, caching, rate limiting)\n * - Error handling\n * - Timeout handling\n * - Metrics and observability\n * - Query result caching\n * - Rate limiting\n *\n * The `QueryHandler` type can still be used with external production-grade buses\n * (e.g., RabbitMQ, AWS SQS) while maintaining type safety.\n *\n * @template TMap - Optional mapping from query type strings to return types\n *\n * @example\n * ```typescript\n * // With type map – full inference\n * type Queries = { GetOrder: Order | null; ListOrders: Order[] };\n * const bus = new QueryBus<Queries>();\n * const result = await bus.execute({ type: \"GetOrder\", orderId: \"123\" });\n * // result: Result<Order | null, string>\n *\n * // Without type map – same as before\n * const bus = new QueryBus();\n * bus.register(\"GetOrder\", async (query) => repository.getById(query.orderId));\n * const result = await bus.execute({ type: \"GetOrder\", orderId: \"123\" });\n * ```\n */\nexport class QueryBus<TMap extends QueryTypeMap = QueryTypeMap, E = string>\n\timplements IQueryBus<TMap, E>\n{\n\tprivate readonly handlers = new Map<string, StoredQueryHandler>();\n\tprivate readonly errorMapper: (thrown: unknown) => E;\n\n\tconstructor(...args: QueryBusArgs<E>) {\n\t\t// describeThrown produces a string; that is the correct mapper only for\n\t\t// the default E = string. QueryBusArgs makes errorMapper mandatory once\n\t\t// E is widened, so this fallback is never reached with a non-string E.\n\t\tthis.errorMapper =\n\t\t\targs[0]?.errorMapper ?? (describeThrown as (thrown: unknown) => E);\n\t}\n\n\tregister<\n\t\tK extends keyof TMap & string,\n\t\tQ extends Query & { type: K } = Query & { type: K },\n\t>(queryType: K, handler: QueryHandler<Q, TMap[K]>): void {\n\t\t// Silent replacement would turn the first handler into dead code\n\t\t// with no signal; wiring bugs must surface at registration time.\n\t\tif (this.handlers.has(queryType)) {\n\t\t\tthrow new Error(\n\t\t\t\t`QueryBus: a handler for query type \"${queryType}\" is already registered`,\n\t\t\t);\n\t\t}\n\t\tthis.handlers.set(queryType, (query) => handler(query as Q));\n\t}\n\n\tasync execute<Q extends Query & { type: keyof TMap & string }>(\n\t\tquery: Q,\n\t): Promise<Result<TMap[Q[\"type\"]], E>>;\n\tasync execute<Q extends Query, R>(query: Q): Promise<Result<R, E>>;\n\tasync execute<Q extends Query, R>(query: Q): Promise<Result<R, E>> {\n\t\tconst handler = this.handlers.get(query.type);\n\t\tif (!handler) {\n\t\t\t// Same posture as CommandBus: a named wiring-bug error through\n\t\t\t// the channel (2.x compatibility; the wire message is unchanged).\n\t\t\treturn err(\n\t\t\t\tthis.errorMapper(\n\t\t\t\t\tnew UnregisteredHandlerError({\n\t\t\t\t\t\tbusKind: \"query\",\n\t\t\t\t\t\tmessageType: query.type,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\ttry {\n\t\t\tconst result = (await handler(query)) as R;\n\t\t\treturn ok(result);\n\t\t} catch (error) {\n\t\t\treturn err(this.errorMapper(error));\n\t\t}\n\t}\n\n\tasync executeUnsafe<Q extends Query & { type: keyof TMap & string }>(\n\t\tquery: Q,\n\t): Promise<TMap[Q[\"type\"]]>;\n\tasync executeUnsafe<Q extends Query, R>(query: Q): Promise<R>;\n\tasync executeUnsafe<Q extends Query, R>(query: Q): Promise<R> {\n\t\tconst handler = this.handlers.get(query.type);\n\t\tif (!handler) {\n\t\t\tthrow new UnregisteredHandlerError({\n\t\t\t\tbusKind: \"query\",\n\t\t\t\tmessageType: query.type,\n\t\t\t});\n\t\t}\n\t\treturn (await handler(query)) as R;\n\t}\n}\n","import { AggregateDeletedError } from \"../core/errors\";\nimport type { Id } from \"../core/id\";\n\n/**\n * A class reference used as the type key of the identity map. Keying\n * on the CLASS (not a name string) makes collisions impossible by\n * construction: `Restaurant` and `Booking` are different keys even if\n * someone names two aggregates identically across modules, and there\n * is no string-discipline to maintain.\n *\n * The `Function & { prototype: TAgg }` branch is load-bearing: the\n * kit's aggregate convention is a **protected constructor** plus\n * static factories, and TypeScript rejects assigning a class with a\n * protected constructor to a construct-signature type. The prototype\n * witness accepts those classes while still inferring `TAgg`.\n */\nexport type AggregateClass<TAgg> =\n\t// biome-ignore lint/suspicious/noExplicitAny: variance; a class reference is only used as a map key and instance witness here.\n\t| (abstract new (...args: any[]) => TAgg)\n\t// biome-ignore lint/complexity/noBannedTypes: Function is deliberate; a construct signature cannot accept protected-constructor classes (the kit's aggregate convention); the prototype witness keeps TAgg inference.\n\t| (Function & { prototype: TAgg });\n\n/**\n * Per-unit-of-work Identity Map (Fowler, PoEAA): within one operation,\n * one aggregate type+id maps to exactly ONE in-memory instance.\n *\n * This is the shipped implementation of the contract the\n * [Repository guide](../../docs/guide/repository.md) places on\n * `IRepository` implementations: two `getById(id)` calls in the same\n * unit of work MUST return the same instance, because `withCommit`'s\n * aggregate dedupe (and therefore exactly-once event harvest and\n * `markPersisted`) is keyed on JavaScript object identity.\n *\n * Storage is two-level (per-type stores created lazily), so\n * `Restaurant:123` and `Booking:123` can never collide: the type key\n * is the aggregate CLASS, not the id alone and not a name string.\n *\n * Repository read-path contract:\n *\n * ```ts\n * async getById(id: OrderId): Promise<Order | null> {\n * const cached = this.session.identityMap.get(Order, id);\n * if (cached) return cached;\n * // Deleted in this unit of work = gone, even if the physical\n * // delete is deferred and the row is still visible in the tx.\n * if (this.session.identityMap.isDeleted(Order, id)) return null;\n *\n * const row = await this.loadRow(id);\n * if (!row) return null;\n * const order = Order.reconstitute(row.id, row.state, row.version);\n * this.session.identityMap.set(Order, id, order);\n * return order;\n * }\n * ```\n *\n * Deletion is final within an operation: {@link delete} removes the\n * entry AND records a tombstone, so a later {@link set} of the same\n * type+id throws `AggregateDeletedError`: a second instance of a\n * deleted aggregate can never sneak back into the unit of work, even\n * through a repository whose row delete is deferred.\n *\n * Lifetime is ONE unit of work: the `UnitOfWork` creates a fresh map\n * per `run()` and clears it on close. Never cache across operations;\n * that would silently bypass optimistic concurrency control.\n */\nexport class IdentityMap {\n\tprivate readonly _stores = new Map<\n\t\tAggregateClass<unknown>,\n\t\tMap<string, unknown>\n\t>();\n\tprivate readonly _deleted = new Map<AggregateClass<unknown>, Set<string>>();\n\t// pendingEvents length captured when an instance was first registered\n\t// (load time), so the unit of work can tell events RECORDED AFTER load\n\t// apart from a \"dirty\" reconstitution that already carried events.\n\tprivate readonly _pendingAtRegistration = new WeakMap<object, number>();\n\n\t/** The cached instance for type+id, or `undefined` (also after {@link delete}). */\n\tpublic get<TAgg>(\n\t\ttype: AggregateClass<TAgg>,\n\t\tid: Id<string>,\n\t): TAgg | undefined {\n\t\treturn this._stores.get(type)?.get(id) as TAgg | undefined;\n\t}\n\n\t/** Whether an instance is registered for type+id (false after {@link delete}). */\n\tpublic has<TAgg>(type: AggregateClass<TAgg>, id: Id<string>): boolean {\n\t\treturn this._stores.get(type)?.has(id) ?? false;\n\t}\n\n\t/**\n\t * Whether type+id was {@link delete}d in this unit of work. The\n\t * read path checks this BEFORE hydrating and returns `null`, so\n\t * \"deleted in this operation\" reads uniformly as not-found,\n\t * regardless of whether the repository's physical delete already\n\t * removed the row or is deferred within the transaction. Without\n\t * the check, a read-only probe of a deleted aggregate would crash\n\t * in {@link set} for deferred-write repositories and return `null`\n\t * for immediate-write ones.\n\t */\n\tpublic isDeleted<TAgg>(type: AggregateClass<TAgg>, id: Id<string>): boolean {\n\t\treturn this._deleted.get(type)?.has(id) ?? false;\n\t}\n\n\t/**\n\t * Registers the hydrated instance for type+id.\n\t *\n\t * - Re-registering the SAME instance is a no-op (idempotent).\n\t * - Registering a DIFFERENT instance for an occupied type+id throws:\n\t * that is precisely the identity-map violation this class exists\n\t * to prevent (the repository hydrated twice instead of checking\n\t * {@link get} first), and letting it pass would double-harvest\n\t * events downstream.\n\t * - Registering a type+id that was {@link delete}d in this unit of\n\t * work throws `AggregateDeletedError`: deletion is final within\n\t * the operation.\n\t */\n\tpublic set<TAgg>(\n\t\ttype: AggregateClass<TAgg>,\n\t\tid: Id<string>,\n\t\taggregate: TAgg,\n\t): void {\n\t\tif (this._deleted.get(type)?.has(id)) {\n\t\t\tthrow new AggregateDeletedError(String(id));\n\t\t}\n\t\tlet store = this._stores.get(type);\n\t\tif (store === undefined) {\n\t\t\tstore = new Map<string, unknown>();\n\t\t\tthis._stores.set(type, store);\n\t\t}\n\t\tconst existing = store.get(id);\n\t\tif (existing !== undefined && existing !== aggregate) {\n\t\t\tthrow new Error(\n\t\t\t\t`IdentityMap: a different instance is already registered for ` +\n\t\t\t\t\t`${type.name}(${String(id)}). Check get() before hydrating - ` +\n\t\t\t\t\t`two live instances of one aggregate break the one-instance-per-` +\n\t\t\t\t\t`unit-of-work contract that exactly-once event harvest relies on.`,\n\t\t\t);\n\t\t}\n\t\tstore.set(id, aggregate);\n\t\t// Capture the load-time pending count once (idempotent re-set keeps\n\t\t// the first value), so the unit of work can later tell events\n\t\t// RECORDED AFTER load apart from a reconstitution that already\n\t\t// carried events. Assumes pendingEvents is append-only between load\n\t\t// and commit (the kit's recordEvent model); only markPersisted /\n\t\t// clearPendingEvents shrink it, and those run post-commit.\n\t\tif (\n\t\t\taggregate !== null &&\n\t\t\ttypeof aggregate === \"object\" &&\n\t\t\t!this._pendingAtRegistration.has(aggregate as object)\n\t\t) {\n\t\t\tconst pending = pendingEventsOf(aggregate);\n\t\t\tif (pending) {\n\t\t\t\tthis._pendingAtRegistration.set(aggregate as object, pending.length);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Registered instances that have recorded MORE pending events than they\n\t * carried when first registered (loaded). Used by the unit of work's\n\t * end-of-run guard: an aggregate that gained events after load but was\n\t * never enrolled would silently drop them. A read-only load, or a\n\t * reconstitution that already carried events, shows no increase and is\n\t * not reported.\n\t */\n\tpublic instancesWithNewPendingEvents(): unknown[] {\n\t\tconst result: unknown[] = [];\n\t\tfor (const store of this._stores.values()) {\n\t\t\tfor (const instance of store.values()) {\n\t\t\t\tconst pending = pendingEventsOf(instance);\n\t\t\t\tif (!pending) continue;\n\t\t\t\tconst atRegistration =\n\t\t\t\t\tthis._pendingAtRegistration.get(instance as object) ?? 0;\n\t\t\t\tif (pending.length > atRegistration) {\n\t\t\t\t\tresult.push(instance);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\t/**\n\t * Removes the entry for type+id and records a tombstone: subsequent\n\t * {@link get} / {@link has} report absence, and a subsequent\n\t * {@link set} of the same type+id throws `AggregateDeletedError`.\n\t * Called by a repository's `delete(aggregate)` alongside\n\t * `session.enrollDeleted(aggregate)`.\n\t */\n\tpublic delete<TAgg>(type: AggregateClass<TAgg>, id: Id<string>): void {\n\t\tthis._stores.get(type)?.delete(id);\n\t\tlet tombstones = this._deleted.get(type);\n\t\tif (tombstones === undefined) {\n\t\t\ttombstones = new Set<string>();\n\t\t\tthis._deleted.set(type, tombstones);\n\t\t}\n\t\ttombstones.add(id);\n\t}\n\n\t/** Empties all stores and tombstones. Called by the unit of work on close. */\n\tpublic clear(): void {\n\t\tthis._stores.clear();\n\t\tthis._deleted.clear();\n\t}\n}\n\n/**\n * Duck-types a stored value as an aggregate and returns its `pendingEvents`\n * array, or `undefined` for anything that is not aggregate-shaped. Single\n * source of truth so the load-time capture in {@link IdentityMap.set} and\n * the end-of-run scan in {@link IdentityMap.instancesWithNewPendingEvents}\n * cannot drift apart.\n */\nfunction pendingEventsOf(value: unknown): readonly unknown[] | undefined {\n\tif (value === null || typeof value !== \"object\") return undefined;\n\tconst pending = (value as { pendingEvents?: unknown }).pendingEvents;\n\treturn Array.isArray(pending) ? pending : undefined;\n}\n","import { BaseError } from \"@shirudo/base-error\";\nimport type { IAggregateRoot } from \"../aggregate/aggregate\";\nimport type { AnyDomainEvent } from \"../aggregate/domain-event\";\nimport {\n\tAggregateDeletedError,\n\tEventHarvestError,\n\tInfrastructureError,\n\tUnenrolledChangesError,\n} from \"../core/errors\";\nimport type { Id } from \"../core/id\";\nimport type { EventBus, Outbox } from \"../events/ports\";\nimport { type AggregateClass, IdentityMap } from \"../repo/identity-map\";\nimport type { TransactionScope } from \"../repo/scope\";\nimport { abortReason } from \"../utils/abort\";\nimport { withCommit } from \"./handler\";\n\n/**\n * Thrown when `UnitOfWork.run()` is called while the same instance is\n * already executing a unit of work: either a genuinely nested `run()`\n * inside the work callback, or two concurrent operations sharing one\n * instance.\n *\n * Both are contract violations, not recoverable infrastructure\n * failures, so this extends `BaseError` directly (same reasoning as\n * `MissingHandlerError`): a generic `catch (e instanceof\n * InfrastructureError)` handler must not mask it.\n *\n * A nested `run()` would NOT join the outer transaction; it would open\n * an independent one, silently breaking the all-or-nothing guarantee.\n * If two operations must commit together, they are ONE unit of work:\n * merge them into a single `run()` callback. For concurrent requests,\n * construct one `UnitOfWork` per operation (construction is trivially\n * cheap; the dependency object is the thing you share).\n */\nexport class NestedUnitOfWorkError extends BaseError<\"NestedUnitOfWorkError\"> {\n\tconstructor() {\n\t\tsuper(\n\t\t\t\"UnitOfWork.run() was called while this instance is already running. \" +\n\t\t\t\t\"A nested run() would open an independent transaction, not join the \" +\n\t\t\t\t\"outer one - merge the work into a single run() callback. For \" +\n\t\t\t\t\"concurrent operations, construct one UnitOfWork per operation.\",\n\t\t\tundefined,\n\t\t\t{ name: \"NestedUnitOfWorkError\" },\n\t\t);\n\t}\n}\n\n/**\n * Thrown when the unit-of-work context is used after `run()` has\n * settled: reading `context.repositories` / `context.transaction`, or\n * calling `session.enrollSaved` / `session.enrollDeleted`, once the\n * transaction has committed or rolled back.\n *\n * Use-after-close is a programming bug (typically a leaked context\n * reference or a fire-and-forget promise outliving the callback), so\n * this extends `BaseError` directly and should crash loud.\n *\n * **Honest scope of this guard:** the kit can only invalidate what it\n * controls - the context getters and the session. A repository or raw\n * transaction handle captured into a variable BEFORE close keeps\n * working as far as the kit can see; whether the underlying tx handle\n * rejects is ORM-specific. Do not let references escape the callback.\n */\nexport class TransactionClosedError extends BaseError<\"TransactionClosedError\"> {\n\tconstructor(public readonly operation: string) {\n\t\tsuper(\n\t\t\t`Unit of work is closed: ${operation} was called after the ` +\n\t\t\t\t\"transaction committed or rolled back. Do not use the context or \" +\n\t\t\t\t\"session outside the run() callback.\",\n\t\t\tundefined,\n\t\t\t{ name: \"TransactionClosedError\" },\n\t\t);\n\t}\n}\n\n/**\n * The unit of work failed AFTER the work callback completed\n * successfully, at the persistence boundary: the outbox write or the\n * transaction commit itself rejected. The kit cannot see inside\n * `TransactionScope.transactional`, so these are deliberately one error\n * class; the underlying failure is attached as `cause`.\n *\n * `InfrastructureError`: the business logic ran to completion; the\n * persistence boundary failed. The transaction rolled back (or never\n * committed), no aggregate was marked persisted, and pending events\n * survive on the aggregates; the operation left no partial state behind.\n * A `CommitError` is the **potentially transient** post-completion\n * failure (a commit-time serialization failure is the classic case), so\n * it is the one a retrying caller should consider re-running. The\n * deterministic post-completion failure, a harvest-guard violation (an\n * event missing `aggregateId` / `aggregateType`, or an `aggregateVersion`\n * ahead of the commit version), is a programming bug and surfaces as\n * {@link EventHarvestError} instead, which does NOT extend\n * `InfrastructureError`, so it stays out of retry paths by construction.\n */\nexport class CommitError extends InfrastructureError<\"CommitError\"> {\n\tconstructor(cause: unknown) {\n\t\tsuper(\n\t\t\t\"Unit of work failed after the work callback completed: the outbox \" +\n\t\t\t\t\"write or the transaction commit rejected. The transaction did \" +\n\t\t\t\t\"not commit; this failure may be transient, inspect the cause \" +\n\t\t\t\t\"(e.g. someChainRetryable) before retrying.\",\n\t\t\tcause,\n\t\t\t{ name: \"CommitError\" },\n\t\t);\n\t}\n}\n\n/**\n * The work callback threw AND the transaction scope rejected with a\n * DIFFERENT error that does not wrap the callback's error in its cause\n * chain - the strongest available signal that the rollback itself\n * failed. The callback's (primary) error is preserved as `cause`, so\n * cause-chain helpers (`someChainRetryable`, `findInCauseChain`) still\n * see a wrapped `ConcurrencyConflictError` & co.; the scope's error is\n * carried in {@link rollbackCause}.\n *\n * Scopes that rethrow the original error (Drizzle, Prisma do) never\n * produce this; scopes that WRAP the original are detected via the\n * cause chain and passed through unchanged instead.\n */\nexport class RollbackError extends InfrastructureError<\"RollbackError\"> {\n\tconstructor(\n\t\tcause: unknown,\n\t\tpublic readonly rollbackCause: unknown,\n\t) {\n\t\tsuper(\n\t\t\t\"The work callback failed and the transaction scope rejected with a \" +\n\t\t\t\t\"different error (possible rollback failure). The callback's error \" +\n\t\t\t\t\"is the cause; the scope's error is in rollbackCause.\",\n\t\t\tcause,\n\t\t\t{ name: \"RollbackError\" },\n\t\t);\n\t}\n}\n\n/**\n * The enrollment handle a unit of work hands to its repositories.\n *\n * Repositories enroll every aggregate they write so the unit of work\n * can harvest pending events into the outbox (inside the transaction)\n * and call `markPersisted` after the commit - the same lifecycle\n * `withCommit` runs for its returned `aggregates` array, minus the\n * footgun: with enrollment, \"forgot to list the aggregate\" cannot\n * happen per call site; each repository implements it once and its\n * tests pin it once.\n *\n * Contract for repository implementations:\n * - `getById(id)` checks `identityMap.get` BEFORE hydrating, treats\n * `identityMap.isDeleted` as not-found (`null`), and registers the\n * hydrated instance after - two loads of the same aggregate in one\n * unit of work must return the same instance.\n * - `save(aggregate)` calls {@link enrollSaved} BEFORE the row write:\n * the deleted-gate then throws `AggregateDeletedError` before any SQL\n * runs (instead of the write surfacing as a confusing\n * `ConcurrencyConflictError` against the deleted row). Enrollment is\n * idempotent per instance, mirroring `withCommit`'s reference dedupe,\n * and a failed write rolls the whole unit of work back anyway.\n * - `delete(aggregate)` calls {@link enrollDeleted} - ONE call does all\n * the deletion bookkeeping: the identity-map entry is removed and\n * tombstoned automatically (keyed on the instance's concrete class),\n * the recorded deletion events are still harvested into the outbox,\n * and saving or re-registering the aggregate (same instance OR a\n * re-created one with the same type+id) later in this unit of work\n * throws `AggregateDeletedError`.\n *\n * The use case can also enroll manually via `context.session` for the\n * rare write that bypasses a repository.\n */\nexport interface UnitOfWorkSession<\n\tEvt extends AnyDomainEvent = AnyDomainEvent,\n> {\n\t/**\n\t * The per-operation Identity Map (Fowler): one aggregate type+id,\n\t * one in-memory instance. Created fresh per `run()`, cleared on\n\t * close; accessing it after close throws\n\t * {@link TransactionClosedError}.\n\t */\n\treadonly identityMap: IdentityMap;\n\n\t/** Enroll an aggregate that was (or will be) written in this unit of work. */\n\tenrollSaved(aggregate: IAggregateRoot<Id<string>, Evt>): void;\n\n\t/**\n\t * Enroll an aggregate whose row was (or will be) deleted in this\n\t * unit of work. Its pending events (e.g. a recorded deletion event)\n\t * are harvested like any other; re-saving the instance afterwards\n\t * throws `AggregateDeletedError`.\n\t */\n\tenrollDeleted(aggregate: IAggregateRoot<Id<string>, Evt>): void;\n}\n\n/**\n * What the work callback receives: repositories already bound to the\n * live transaction, the enrollment session, and, deliberately named to\n * look like the escape hatch it is, the raw transaction handle.\n *\n * All members throw {@link TransactionClosedError} once `run()` has\n * settled; do not let the context escape the callback.\n */\nexport interface UnitOfWorkContext<\n\tTCtx,\n\tTRepos,\n\tEvt extends AnyDomainEvent = AnyDomainEvent,\n> {\n\treadonly repositories: TRepos;\n\n\t/**\n\t * **Escape hatch: you are leaving the unit of work's guarantees.**\n\t * A write issued on the raw handle bypasses the repository contract,\n\t * enrollment (its aggregate's events are NOT harvested unless you\n\t * also call `session.enrollSaved`), and the identity map (a later\n\t * `getById` of the same aggregate hydrates a SECOND instance:\n\t * double harvest, double `markPersisted`). Use it only for writes no\n\t * repository covers, pair it with manual enrollment, and prefer\n\t * adding a repository method whenever one could exist.\n\t */\n\treadonly rawTransaction: TCtx;\n\n\treadonly session: UnitOfWorkSession<Evt>;\n\n\t/**\n\t * The cooperative-cancellation signal passed to {@link UnitOfWork.run},\n\t * or `undefined` if none was given. Poll `signal?.aborted` between\n\t * steps of a long operation and throw `signal.reason` to bail out; the\n\t * throw rolls the unit of work back like any other callback error. The\n\t * kit does not interrupt an in-flight query for you: actual query\n\t * cancellation depends on the `TransactionScope` honoring the signal.\n\t */\n\treadonly signal?: AbortSignal;\n}\n\n/** Options for a single {@link UnitOfWork.run} call. */\nexport interface RunOptions {\n\t/**\n\t * Cooperative-cancellation signal. If already aborted, `run()` rejects\n\t * with the signal's `reason` before opening a transaction. Otherwise it\n\t * is exposed on the context (poll `context.signal`) and forwarded to the\n\t * `TransactionScope`. Use `AbortSignal.timeout(ms)` for a deadline.\n\t */\n\treadonly signal?: AbortSignal;\n}\n\n/**\n * Per-repository factory map: for each key of `TRepos`, a function\n * that constructs the repository bound to the live transaction handle\n * and the enrollment session. Called once per `run()`, so every\n * repository of one unit of work shares the same transaction.\n *\n * ```ts\n * const factories = {\n * orders: (tx, session) => new DrizzleOrderRepository(tx, session),\n * invoices: (tx, session) => new DrizzleInvoiceRepository(tx, session),\n * };\n * ```\n */\nexport type RepositoryFactories<\n\tTCtx,\n\tTRepos,\n\tEvt extends AnyDomainEvent = AnyDomainEvent,\n> = {\n\t[K in keyof TRepos]: (\n\t\ttx: TCtx,\n\t\tsession: UnitOfWorkSession<Evt>,\n\t) => TRepos[K];\n};\n\n/** Dependencies for {@link UnitOfWork}; the app-level singleton part. */\nexport interface UnitOfWorkDeps<\n\tEvt extends AnyDomainEvent,\n\tTCtx,\n\tTRepos,\n> {\n\tscope: TransactionScope<TCtx>;\n\toutbox: Outbox<Evt>;\n\tbus?: EventBus<Evt>;\n\t/** See `withCommit`: observer for post-commit `bus.publish` failures. */\n\tonPublishError?: (error: unknown, events: ReadonlyArray<Evt>) => void;\n\t/**\n\t * See `withCommit`: observer for post-commit persistence-cleanup failures\n\t * (a throw from `markPersisted`, the `onPersisted` hook, or\n\t * `clearPendingEvents`). Called once per failing aggregate; observer only,\n\t * never rejects the committed write.\n\t */\n\tonPersistError?: (\n\t\terror: unknown,\n\t\taggregate: IAggregateRoot<Id<string>, Evt>,\n\t) => void;\n\trepositories: RepositoryFactories<TCtx, TRepos, Evt>;\n}\n\n/**\n * Explicit-save Unit of Work: one `run()` call is one application-level\n * write operation. All repository writes inside the callback share one\n * transaction and either persist completely or not at all.\n *\n * Built ON TOP of `withCommit` - the commit orchestration (event\n * harvest into the outbox inside the transaction, `markPersisted`\n * after the commit, best-effort in-process publish last) is inherited,\n * not reimplemented. What this layer adds:\n *\n * - **Tx-bound repositories via a registry.** The callback receives\n * ready-made repositories instead of a raw transaction handle; the\n * factory map is wired once at construction.\n * - **Enrollment instead of a returned aggregates array.** Repositories\n * enroll what they write via {@link UnitOfWorkSession}; the use case\n * cannot forget to list an aggregate (the `withCommit` footgun).\n * - **Lifecycle errors.** {@link NestedUnitOfWorkError},\n * {@link TransactionClosedError}, {@link CommitError},\n * {@link RollbackError}, {@link AggregateDeletedError}.\n *\n * - **A per-operation Identity Map** on the session: repositories\n * check it before hydrating and register after, so one type+id maps\n * to one in-memory instance per unit of work (the contract\n * `withCommit`'s reference-dedupe relies on, now shipped instead of\n * merely documented).\n *\n * What it deliberately does NOT do (v1): no auto-flush (explicit\n * `save()` only - `hasChanges` makes a redundant save a cheap no-op),\n * no savepoints, no nested-transaction joining. `withCommit` with\n * hand-rolled repos remains fully supported; this facade is opt-in.\n *\n * **Instance discipline:** one instance owns one logical operation at\n * a time. `run()` while a run is active throws\n * {@link NestedUnitOfWorkError} - that covers genuine nesting AND two\n * concurrent requests sharing one instance, which is the same bug in\n * different clothes. Construct one `UnitOfWork` per operation\n * (construction stores one reference; the shareable singleton is the\n * deps object). Sequential reuse of an instance is fine.\n *\n * **Error pass-through:** an error thrown by the work callback (a\n * repository's `ConcurrencyConflictError`, a `DomainError`, anything)\n * is rethrown UNCHANGED - the unit of work never converts a concurrency\n * conflict into a generic error. Only the two failure modes the\n * callback cannot observe are wrapped: see {@link CommitError} and\n * {@link RollbackError}.\n *\n * @example\n * ```ts\n * const deps = {\n * scope: drizzleScope,\n * outbox: drizzleOutbox,\n * bus: eventBus,\n * repositories: {\n * restaurants: (tx, session) => new DrizzleRestaurantRepository(tx, session),\n * },\n * };\n *\n * const uow = new UnitOfWork(deps);\n * const result = await uow.run(async ({ repositories }) => {\n * const restaurant = await repositories.restaurants.getByIdOrFail(id);\n * restaurant.changeOpeningHours(openingHours);\n * await repositories.restaurants.save(restaurant); // save() enrolls\n * return restaurant.id;\n * });\n * ```\n */\nexport class UnitOfWork<\n\tEvt extends AnyDomainEvent,\n\tTCtx,\n\tTRepos extends Record<string, unknown>,\n> {\n\tprivate _active = false;\n\n\tconstructor(private readonly deps: UnitOfWorkDeps<Evt, TCtx, TRepos>) {}\n\n\t/**\n\t * Execute one unit of work: open the transaction, hand the callback\n\t * tx-bound repositories, commit on resolve, roll back on throw,\n\t * run the post-commit lifecycle (markPersisted, publish) for every\n\t * enrolled aggregate. Returns the callback's result.\n\t */\n\tpublic async run<R>(\n\t\twork: (context: UnitOfWorkContext<TCtx, TRepos, Evt>) => Promise<R>,\n\t\toptions?: RunOptions,\n\t): Promise<R> {\n\t\t// Pre-flight: an already-aborted caller rejects with the signal's\n\t\t// reason before opening a transaction (no callback runs). Placed\n\t\t// before the active-guard so a doubly-bad call (aborted signal on an\n\t\t// already-running instance) is reported as aborted rather than as a\n\t\t// nesting error. The `??` fallback mirrors event-bus.ts and guards a\n\t\t// non-spec polyfill whose `reason` is undefined.\n\t\tif (options?.signal?.aborted) {\n\t\t\tthrow abortReason(options.signal, \"UnitOfWork.run aborted before opening a transaction\");\n\t\t}\n\t\tif (this._active) {\n\t\t\tthrow new NestedUnitOfWorkError();\n\t\t}\n\t\tthis._active = true;\n\n\t\tlet session: Session<Evt> | undefined;\n\t\tlet workCompleted = false;\n\t\tlet workThrew = false;\n\t\tlet workError: unknown;\n\n\t\ttry {\n\t\t\treturn await withCommit<Evt, R, TCtx>(\n\t\t\t\t{\n\t\t\t\t\toutbox: this.deps.outbox,\n\t\t\t\t\tbus: this.deps.bus,\n\t\t\t\t\tscope: this.deps.scope,\n\t\t\t\t\tonPublishError: this.deps.onPublishError,\n\t\t\t\t\tonPersistError: this.deps.onPersistError,\n\t\t\t\t\tsignal: options?.signal,\n\t\t\t\t},\n\t\t\t\tasync (tx) => {\n\t\t\t\t\t// Fresh state per scope invocation: a TransactionScope that\n\t\t\t\t\t// retries its callback (serialization-failure retry wrappers)\n\t\t\t\t\t// re-runs this fn, and state from the rolled-back attempt\n\t\t\t\t\t// (enrollments, identity-map entries, error flags) must not\n\t\t\t\t\t// leak into the retry. The previous attempt's session is\n\t\t\t\t\t// closed so its leaked contexts turn loud.\n\t\t\t\t\tsession?.close();\n\t\t\t\t\tconst s = new Session<Evt>();\n\t\t\t\t\tsession = s;\n\t\t\t\t\tworkCompleted = false;\n\t\t\t\t\tworkThrew = false;\n\t\t\t\t\tworkError = undefined;\n\n\t\t\t\t\tconst repositories = this.buildRepositories(tx, s);\n\t\t\t\t\tconst context = makeContext(repositories, tx, s, options?.signal);\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await work(context);\n\t\t\t\t\t\t// Catch a forgotten enrollment before sealing: a loaded\n\t\t\t\t\t\t// aggregate with pending events that was never enrolled\n\t\t\t\t\t\t// would otherwise drop its events silently. Throws inside\n\t\t\t\t\t\t// the transaction, so the unit of work rolls back.\n\t\t\t\t\t\ts.assertAllChangesEnrolled();\n\t\t\t\t\t\tworkCompleted = true;\n\t\t\t\t\t\t// Seal immediately: the aggregates snapshot below is what\n\t\t\t\t\t\t// gets harvested. A late enrollment (an un-awaited\n\t\t\t\t\t\t// repo.save() promise still in flight) must throw\n\t\t\t\t\t\t// TransactionClosedError instead of being silently\n\t\t\t\t\t\t// accepted-but-never-harvested.\n\t\t\t\t\t\tconst aggregates = s.enrolledAggregates;\n\t\t\t\t\t\tconst deleted = s.deletedAggregates;\n\t\t\t\t\t\ts.close();\n\t\t\t\t\t\treturn { result, aggregates, deleted };\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tworkThrew = true;\n\t\t\t\t\t\tworkError = error;\n\t\t\t\t\t\tthrow error;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthrow classifyRunError(error, {\n\t\t\t\tworkThrew,\n\t\t\t\tworkCompleted,\n\t\t\t\tworkError,\n\t\t\t});\n\t\t} finally {\n\t\t\tsession?.close();\n\t\t\tthis._active = false;\n\t\t}\n\t}\n\n\tprivate buildRepositories(\n\t\ttx: TCtx,\n\t\tsession: UnitOfWorkSession<Evt>,\n\t): TRepos {\n\t\tconst repositories = {} as TRepos;\n\t\tfor (const key of Object.keys(this.deps.repositories) as Array<\n\t\t\tkeyof TRepos\n\t\t>) {\n\t\t\trepositories[key] = this.deps.repositories[key](tx, session);\n\t\t}\n\t\treturn repositories;\n\t}\n}\n\n/** Internal session implementation; closed by `run()`'s finally. */\nclass Session<Evt extends AnyDomainEvent> implements UnitOfWorkSession<Evt> {\n\t// Insertion-ordered: harvest order = enrollment order (withCommit\n\t// then preserves per-aggregate emission order).\n\tprivate readonly _enrolled = new Set<IAggregateRoot<Id<string>, Evt>>();\n\tprivate readonly _deleted = new Set<IAggregateRoot<Id<string>, Evt>>();\n\tprivate readonly _identityMap = new IdentityMap();\n\tprivate _closed = false;\n\n\tpublic get identityMap(): IdentityMap {\n\t\tthis.assertOpen(\"session.identityMap\");\n\t\treturn this._identityMap;\n\t}\n\n\tpublic enrollSaved(aggregate: IAggregateRoot<Id<string>, Evt>): void {\n\t\tthis.assertOpen(\"session.enrollSaved\");\n\t\t// Two gates, one invariant: the instance set catches the same\n\t\t// reference; the identity-map tombstone (keyed on the instance's\n\t\t// concrete class) catches a DIFFERENT instance with the same\n\t\t// type+id: e.g. one re-created via the static factory after the\n\t\t// delete. Both mean \"deleted is final within this operation\".\n\t\tif (\n\t\t\tthis._deleted.has(aggregate) ||\n\t\t\tthis._identityMap.isDeleted(\n\t\t\t\taggregate.constructor as AggregateClass<unknown>,\n\t\t\t\taggregate.id,\n\t\t\t)\n\t\t) {\n\t\t\tthrow new AggregateDeletedError(String(aggregate.id));\n\t\t}\n\t\tthis._enrolled.add(aggregate);\n\t}\n\n\tpublic enrollDeleted(aggregate: IAggregateRoot<Id<string>, Evt>): void {\n\t\tthis.assertOpen(\"session.enrollDeleted\");\n\t\tthis._deleted.add(aggregate);\n\t\t// One call does ALL the deletion bookkeeping: the identity-map\n\t\t// entry is removed and tombstoned automatically (keyed on the\n\t\t// instance's concrete class), so repositories do not need a\n\t\t// second manual identityMap.delete() call; a forgotten leg of a\n\t\t// two-call protocol would silently weaken the deletion gate.\n\t\t// Assumption (documented on IdentityMap): repositories key the\n\t\t// map with the same concrete class their factories produce.\n\t\tthis._identityMap.delete(\n\t\t\taggregate.constructor as AggregateClass<unknown>,\n\t\t\taggregate.id,\n\t\t);\n\t\t// Deleted aggregates stay in the harvest set: their recorded\n\t\t// deletion events must reach the outbox (repository.md, hard-\n\t\t// delete with event harvest). withCommit receives them in the\n\t\t// `deleted` marker set and skips markPersisted for them, so the\n\t\t// post-save onPersisted hook never fires for a deletion.\n\t\tthis._enrolled.add(aggregate);\n\t}\n\n\t/**\n\t * End-of-run safety net: a loaded aggregate (registered in the identity\n\t * map via `getById`) that carries pending events but was never enrolled\n\t * is almost certainly a forgotten `save()` / `enrollSaved`, whose events\n\t * would otherwise be silently dropped. Convert that silent loss into a\n\t * loud, rolling-back {@link UnenrolledChangesError}. Only sees loaded\n\t * aggregates; a freshly created one that was never enrolled is invisible\n\t * to the kit (the contract test suite remains the full mitigation).\n\t */\n\tpublic assertAllChangesEnrolled(): void {\n\t\tfor (const instance of this._identityMap.instancesWithNewPendingEvents()) {\n\t\t\tif (\n\t\t\t\tthis._enrolled.has(instance as IAggregateRoot<Id<string>, Evt>) ||\n\t\t\t\tthis._deleted.has(instance as IAggregateRoot<Id<string>, Evt>)\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// Events were recorded on a loaded aggregate after it was\n\t\t\t// registered, yet it was never enrolled: a forgotten save whose\n\t\t\t// events would be silently dropped.\n\t\t\tconst id = (instance as { id?: unknown }).id;\n\t\t\tthrow new UnenrolledChangesError(String(id));\n\t\t}\n\t}\n\n\tpublic get enrolledAggregates(): ReadonlyArray<\n\t\tIAggregateRoot<Id<string>, Evt>\n\t> {\n\t\treturn [...this._enrolled];\n\t}\n\n\tpublic get deletedAggregates(): ReadonlyArray<\n\t\tIAggregateRoot<Id<string>, Evt>\n\t> {\n\t\treturn [...this._deleted];\n\t}\n\n\tpublic close(): void {\n\t\tthis._closed = true;\n\t\t// Defensive: a leaked direct IdentityMap reference must not serve\n\t\t// stale instances into a later operation (that would silently\n\t\t// bypass OCC). The session getter already throws after close;\n\t\t// clearing covers refs captured before.\n\t\tthis._identityMap.clear();\n\t}\n\n\tpublic assertOpen(operation: string): void {\n\t\tif (this._closed) {\n\t\t\tthrow new TransactionClosedError(operation);\n\t\t}\n\t}\n}\n\nfunction makeContext<TCtx, TRepos, Evt extends AnyDomainEvent>(\n\trepositories: TRepos,\n\ttransaction: TCtx,\n\tsession: Session<Evt>,\n\tsignal: AbortSignal | undefined,\n): UnitOfWorkContext<TCtx, TRepos, Evt> {\n\treturn {\n\t\tget repositories(): TRepos {\n\t\t\tsession.assertOpen(\"context.repositories\");\n\t\t\treturn repositories;\n\t\t},\n\t\tget rawTransaction(): TCtx {\n\t\t\tsession.assertOpen(\"context.rawTransaction\");\n\t\t\treturn transaction;\n\t\t},\n\t\tsession,\n\t\t// The caller's own signal: exposed directly, not gated by\n\t\t// assertOpen, so polling `aborted` after close stays harmless.\n\t\tsignal,\n\t};\n}\n\n/**\n * Classifies a `withCommit` rejection into the error `run()` should throw,\n * using the flags captured inside the work wrapper. Pure and total: it\n * returns the error to throw rather than throwing itself, so `run()` reads\n * as orchestration and this decision is unit-testable in isolation.\n *\n * - `workThrew`: the work callback (or `assertAllChangesEnrolled`) threw.\n * The scope normally rethrows that error unchanged (rolled back, pass\n * through so a `ConcurrencyConflictError` & co. stay catchable as-is); a\n * scope that WRAPS the original is detected via the cause chain and also\n * passed through. Only a rejection that neither IS nor wraps the\n * callback's error indicates the rollback itself failed, which becomes a\n * {@link RollbackError}.\n * - `workCompleted`: the callback finished; the failure is post-completion.\n * A harvest-guard violation (an event missing aggregateId / aggregateType,\n * or an aggregateVersion ahead of the commit version) is a deterministic\n * programming bug, surfaced as its {@link EventHarvestError} (which does\n * NOT extend `InfrastructureError`, so a retry-on-Infrastructure handler\n * skips it). It is thrown inside `scope.transactional()`, so a wrapping\n * scope can nest it: walk the chain rather than a bare `instanceof`. Only\n * genuinely unforeseeable post-completion failures (outbox write, the\n * commit itself) become {@link CommitError}.\n * - Neither flag set: `withCommit` rejected before the callback ran (the\n * scope failed to even open a transaction); pass the error through.\n */\nfunction classifyRunError(\n\terror: unknown,\n\tstate: {\n\t\treadonly workThrew: boolean;\n\t\treadonly workCompleted: boolean;\n\t\treadonly workError: unknown;\n\t},\n): unknown {\n\tif (state.workThrew) {\n\t\tif (\n\t\t\terror === state.workError ||\n\t\t\tcauseChainContains(error, state.workError)\n\t\t) {\n\t\t\treturn error;\n\t\t}\n\t\treturn new RollbackError(state.workError, error);\n\t}\n\tif (state.workCompleted) {\n\t\tconst harvestError = findHarvestErrorInChain(error);\n\t\tif (harvestError) {\n\t\t\treturn harvestError;\n\t\t}\n\t\treturn new CommitError(error);\n\t}\n\treturn error;\n}\n\n/**\n * Walks `error`'s standard `cause` chain looking for `target` by\n * reference. Bounded and cycle-safe, and hardened for arbitrary driver\n * errors: a `target` of `undefined`/`null` never matches (every error\n * without a `cause` property would otherwise \"contain\" a thrown\n * `undefined`), and a throwing `cause` getter (lazy deserialization,\n * revoked Proxy) is treated as no-match instead of replacing the real\n * failure with the getter's exception.\n */\n/**\n * Walks `error`'s `cause` chain and returns the first `EventHarvestError`,\n * or `undefined`. Cycle-safe and getter-throw-safe, like\n * {@link causeChainContains}. `withCommit` throws the harvest-guard error\n * INSIDE `scope.transactional`, so a wrapping scope can nest it; matching\n * only the top-level error would let the wrapper mask the non-retryable\n * type. `withCommit` and `run()` share this module, so the local\n * `instanceof` is reliable for the un-wrapped link.\n */\nfunction findHarvestErrorInChain(\n\terror: unknown,\n): EventHarvestError | undefined {\n\tconst seen = new Set<unknown>();\n\tlet current: unknown = error;\n\twhile (\n\t\tcurrent !== null &&\n\t\ttypeof current === \"object\" &&\n\t\t!seen.has(current)\n\t) {\n\t\tseen.add(current);\n\t\tif (current instanceof EventHarvestError) {\n\t\t\treturn current;\n\t\t}\n\t\tlet next: unknown;\n\t\ttry {\n\t\t\tnext = (current as { cause?: unknown }).cause;\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t\tcurrent = next;\n\t}\n\treturn undefined;\n}\n\nfunction causeChainContains(error: unknown, target: unknown): boolean {\n\tif (target === undefined || target === null) {\n\t\treturn false;\n\t}\n\tconst seen = new Set<unknown>();\n\tlet current: unknown = error;\n\twhile (\n\t\tcurrent !== null &&\n\t\ttypeof current === \"object\" &&\n\t\t!seen.has(current)\n\t) {\n\t\tseen.add(current);\n\t\tlet next: unknown;\n\t\ttry {\n\t\t\tnext = (current as { cause?: unknown }).cause;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t\tif (next === target) {\n\t\t\treturn true;\n\t\t}\n\t\tcurrent = next;\n\t}\n\treturn false;\n}\n","import { BaseError } from \"@shirudo/base-error\";\nimport { DomainError } from \"../core/errors\";\n\n/** No transition is defined for the input in the current state. */\nexport class InvalidDomainTransitionError extends DomainError<\"InvalidDomainTransitionError\"> {\n\tconstructor(\n\t\tpublic readonly state: string,\n\t\tpublic readonly inputType: string,\n\t) {\n\t\tsuper(`No domain transition from \"${state}\" on \"${inputType}\".`);\n\t}\n}\n\n/** A defined transition was rejected by its domain guard. */\nexport class DomainTransitionGuardRejectedError extends DomainError<\"DomainTransitionGuardRejectedError\"> {\n\tconstructor(\n\t\tpublic readonly state: string,\n\t\tpublic readonly inputType: string,\n\t) {\n\t\tsuper(`Domain transition guard rejected \"${inputType}\" from \"${state}\".`);\n\t}\n}\n\n/** The machine definition violates its runtime contract. */\nexport class InvalidDomainMachineDefinitionError extends BaseError<\"InvalidDomainMachineDefinitionError\"> {\n\tconstructor(message: string, cause?: unknown) {\n\t\tsuper(message, cause, { name: \"InvalidDomainMachineDefinitionError\" });\n\t}\n}\n\n/** Context contains unsupported or unsafe runtime data. */\nexport class InvalidDomainMachineContextError extends BaseError<\"InvalidDomainMachineContextError\"> {\n\tconstructor(message: string, cause?: unknown) {\n\t\tsuper(message, cause, { name: \"InvalidDomainMachineContextError\" });\n\t}\n}\n\n/** A supplied or produced snapshot is malformed or violates invariants. */\nexport class InvalidDomainMachineSnapshotError extends BaseError<\"InvalidDomainMachineSnapshotError\"> {\n\tconstructor(message: string, cause?: unknown) {\n\t\tsuper(message, cause, { name: \"InvalidDomainMachineSnapshotError\" });\n\t}\n}\n\n/** An input is malformed or contains unsupported runtime data. */\nexport class InvalidDomainMachineInputError extends BaseError<\"InvalidDomainMachineInputError\"> {\n\tconstructor(message: string, cause?: unknown) {\n\t\tsuper(message, cause, { name: \"InvalidDomainMachineInputError\" });\n\t}\n}\n\n/** A guard returned a value other than `boolean` or `DomainError`. */\nexport class InvalidDomainTransitionGuardResultError extends BaseError<\"InvalidDomainTransitionGuardResultError\"> {\n\tconstructor(message: string, cause?: unknown) {\n\t\tsuper(message, cause, { name: \"InvalidDomainTransitionGuardResultError\" });\n\t}\n}\n\n/** A reducer returned a malformed result or unsupported output data. */\nexport class InvalidDomainTransitionResultError extends BaseError<\"InvalidDomainTransitionResultError\"> {\n\tconstructor(message: string, cause?: unknown) {\n\t\tsuper(message, cause, { name: \"InvalidDomainTransitionResultError\" });\n\t}\n}\n\n/** A callback attempted to evaluate the same stateful machine recursively. */\nexport class ReentrantDomainStateMachineEvaluationError extends BaseError<\"ReentrantDomainStateMachineEvaluationError\"> {\n\tconstructor() {\n\t\tsuper(\n\t\t\t\"Domain state machine callbacks cannot evaluate the same machine.\",\n\t\t\tundefined,\n\t\t\t{ name: \"ReentrantDomainStateMachineEvaluationError\" },\n\t\t);\n\t}\n}\n","import {\n\tfindPropertyDescriptor,\n\tisBuiltInObject,\n\tisIntrinsicConstructorPrototype,\n} from \"../utils/array/is-built-in\";\nimport { deepFreeze } from \"../value-object/value-object\";\nimport type { DomainMachineInput, DomainMachineReadonly } from \"./contracts\";\nimport {\n\tInvalidDomainMachineContextError,\n\tInvalidDomainMachineInputError,\n\tInvalidDomainTransitionResultError,\n} from \"./errors\";\n\ntype DomainMachineDataErrorFactory = (\n\tmessage: string,\n\tcause?: unknown,\n) =>\n\t| InvalidDomainMachineContextError\n\t| InvalidDomainMachineInputError\n\t| InvalidDomainTransitionResultError;\n\nconst DOMAIN_MACHINE_DATA_MAX_DEPTH = 256;\nconst DOMAIN_MACHINE_DATA_MAX_NODES = 10_000;\nconst DOMAIN_MACHINE_DATA_MAX_PROPERTIES = 100_000;\n\ntype DomainMachineDataTraversal = {\n\tnodes: number;\n\tproperties: number;\n};\n\nexport function copyDomainMachineOutputs<TOutput>(\n\toutputs: readonly (TOutput | DomainMachineReadonly<TOutput>)[] | undefined,\n): readonly DomainMachineReadonly<TOutput>[] {\n\ttry {\n\t\tconst copiedOutputs = cloneDomainMachineDataValue(\n\t\t\toutputs ?? [],\n\t\t\tcreateDomainTransitionOutputError,\n\t\t);\n\t\treturn deepFreeze(\n\t\t\tcopiedOutputs,\n\t\t) as readonly DomainMachineReadonly<TOutput>[];\n\t} catch (cause) {\n\t\tif (cause instanceof InvalidDomainTransitionResultError) {\n\t\t\tthrow cause;\n\t\t}\n\t\tthrow new InvalidDomainTransitionResultError(\n\t\t\t\"Domain transition result outputs must contain cloneable, deeply immutable data.\",\n\t\t\tcause,\n\t\t);\n\t}\n}\n\nexport function copyDomainMachineInput<TInput extends DomainMachineInput>(\n\tinput: TInput,\n): DomainMachineReadonly<TInput> {\n\ttry {\n\t\treturn deepFreeze(\n\t\t\tcloneDomainMachineDataValue(input, createDomainMachineInputError),\n\t\t) as DomainMachineReadonly<TInput>;\n\t} catch (cause) {\n\t\tif (cause instanceof InvalidDomainMachineInputError) {\n\t\t\tthrow cause;\n\t\t}\n\t\tthrow new InvalidDomainMachineInputError(\n\t\t\t\"Domain machine input must contain cloneable, deeply immutable data.\",\n\t\t\tcause,\n\t\t);\n\t}\n}\n\nexport function copyDomainMachineContext<TContext>(\n\tcontext: TContext | DomainMachineReadonly<TContext>,\n): DomainMachineReadonly<TContext> {\n\ttry {\n\t\treturn deepFreeze(\n\t\t\tcloneDomainMachineDataValue(context, createDomainMachineContextError),\n\t\t) as DomainMachineReadonly<TContext>;\n\t} catch (cause) {\n\t\tif (cause instanceof InvalidDomainMachineContextError) {\n\t\t\tthrow cause;\n\t\t}\n\t\tthrow new InvalidDomainMachineContextError(\n\t\t\t\"Domain machine context must contain cloneable, deeply immutable data.\",\n\t\t\tcause,\n\t\t);\n\t}\n}\n\nfunction createDomainMachineContextError(\n\tmessage: string,\n\tcause?: unknown,\n): InvalidDomainMachineContextError {\n\treturn new InvalidDomainMachineContextError(message, cause);\n}\n\nfunction createDomainMachineInputError(\n\tmessage: string,\n\tcause?: unknown,\n): InvalidDomainMachineInputError {\n\treturn new InvalidDomainMachineInputError(message, cause);\n}\n\nfunction createDomainTransitionOutputError(\n\tmessage: string,\n\tcause?: unknown,\n): InvalidDomainTransitionResultError {\n\treturn new InvalidDomainTransitionResultError(message, cause);\n}\n\nfunction cloneDomainMachineDataValue<TValue>(\n\tvalue: TValue,\n\terrorFactory: DomainMachineDataErrorFactory,\n\tseen = new WeakMap<object, unknown>(),\n\ttraversal: DomainMachineDataTraversal = { nodes: 0, properties: 0 },\n\tdepth = 0,\n): TValue {\n\tif (typeof value === \"function\") {\n\t\tthrow errorFactory(\"Domain machine data cannot contain function values.\");\n\t}\n\tif (value === null || typeof value !== \"object\") return value;\n\n\tconst source = value as object;\n\tif (depth > DOMAIN_MACHINE_DATA_MAX_DEPTH) {\n\t\tthrow errorFactory(\n\t\t\t`Domain machine data exceeds the maximum depth of ${DOMAIN_MACHINE_DATA_MAX_DEPTH}.`,\n\t\t);\n\t}\n\tconst existing = seen.get(source);\n\tif (existing !== undefined) return existing as TValue;\n\ttraversal.nodes += 1;\n\tif (traversal.nodes > DOMAIN_MACHINE_DATA_MAX_NODES) {\n\t\tthrow errorFactory(\n\t\t\t`Domain machine data contains more than ${DOMAIN_MACHINE_DATA_MAX_NODES.toLocaleString(\"en-US\")} object nodes.`,\n\t\t);\n\t}\n\tconst toStringTagDescriptor = findPropertyDescriptor(\n\t\tsource,\n\t\tSymbol.toStringTag,\n\t);\n\tif (\n\t\ttoStringTagDescriptor !== undefined &&\n\t\t!(\"value\" in toStringTagDescriptor)\n\t) {\n\t\tthrow errorFactory(\n\t\t\t\"Domain machine data cannot contain accessor properties.\",\n\t\t);\n\t}\n\n\tif (Array.isArray(value)) {\n\t\tif (!isIntrinsicArrayPrototype(Object.getPrototypeOf(value))) {\n\t\t\tthrow errorFactory(\n\t\t\t\t\"Domain machine data cannot contain custom Array instances.\",\n\t\t\t);\n\t\t}\n\t\tconst cloned: unknown[] = new Array(value.length);\n\t\tseen.set(source, cloned);\n\n\t\tfor (const key of readDomainMachineDataKeys(\n\t\t\tsource,\n\t\t\terrorFactory,\n\t\t\ttraversal,\n\t\t)) {\n\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(source, key);\n\t\t\tif (!descriptor) continue;\n\n\t\t\tif (!(\"value\" in descriptor)) {\n\t\t\t\tthrow errorFactory(\n\t\t\t\t\t\"Domain machine data cannot contain accessor properties.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (key === \"length\") continue;\n\n\t\t\tdescriptor.value = cloneDomainMachineDataValue(\n\t\t\t\tdescriptor.value,\n\t\t\t\terrorFactory,\n\t\t\t\tseen,\n\t\t\t\ttraversal,\n\t\t\t\tdepth + 1,\n\t\t\t);\n\t\t\tObject.defineProperty(cloned, key, descriptor);\n\t\t}\n\t\treturn cloned as TValue;\n\t}\n\n\tconst prototype = Object.getPrototypeOf(source);\n\tif (prototype !== null && !isIntrinsicObjectPrototype(prototype)) {\n\t\tthrow errorFactory(\n\t\t\t\"Domain machine data cannot contain custom class instances.\",\n\t\t);\n\t}\n\n\tconst tag = Object.prototype.toString.call(source);\n\tif (isBuiltInObject(source, tag) || ArrayBuffer.isView(source)) {\n\t\tthrow errorFactory(\n\t\t\t`Domain machine data cannot contain ${tag.slice(8, -1)} object values.`,\n\t\t);\n\t}\n\n\tconst cloned = Object.create(prototype === null ? null : Object.prototype);\n\tseen.set(source, cloned);\n\n\tfor (const key of readDomainMachineDataKeys(\n\t\tsource,\n\t\terrorFactory,\n\t\ttraversal,\n\t)) {\n\t\tconst descriptor = Object.getOwnPropertyDescriptor(source, key);\n\t\tif (!descriptor) continue;\n\n\t\tif (!(\"value\" in descriptor)) {\n\t\t\tthrow errorFactory(\n\t\t\t\t\"Domain machine data cannot contain accessor properties.\",\n\t\t\t);\n\t\t}\n\n\t\tdescriptor.value = cloneDomainMachineDataValue(\n\t\t\tdescriptor.value,\n\t\t\terrorFactory,\n\t\t\tseen,\n\t\t\ttraversal,\n\t\t\tdepth + 1,\n\t\t);\n\t\tObject.defineProperty(cloned, key, descriptor);\n\t}\n\n\treturn cloned as TValue;\n}\n\nfunction readDomainMachineDataKeys(\n\tvalue: object,\n\terrorFactory: DomainMachineDataErrorFactory,\n\ttraversal: DomainMachineDataTraversal,\n): readonly PropertyKey[] {\n\tconst keys = Reflect.ownKeys(value);\n\ttraversal.properties += keys.length;\n\tif (traversal.properties > DOMAIN_MACHINE_DATA_MAX_PROPERTIES) {\n\t\tthrow errorFactory(\n\t\t\t`Domain machine data contains more than ${DOMAIN_MACHINE_DATA_MAX_PROPERTIES.toLocaleString(\"en-US\")} own properties.`,\n\t\t);\n\t}\n\treturn keys;\n}\n\nexport function isRecord(\n\tvalue: unknown,\n): value is Record<PropertyKey, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport function isPlainRecord(\n\tvalue: unknown,\n): value is Record<PropertyKey, unknown> {\n\tif (!isRecord(value)) return false;\n\n\tconst prototype = Object.getPrototypeOf(value);\n\treturn prototype === null || isIntrinsicObjectPrototype(prototype);\n}\n\nfunction isIntrinsicArrayPrototype(prototype: object | null): boolean {\n\tif (prototype === null || !Array.isArray(prototype)) return false;\n\tif (!isIntrinsicConstructorPrototype(prototype, \"Array\")) return false;\n\n\tconst parentPrototype = Object.getPrototypeOf(prototype);\n\treturn (\n\t\tparentPrototype !== null && isIntrinsicObjectPrototype(parentPrototype)\n\t);\n}\n\nfunction isIntrinsicObjectPrototype(prototype: object): boolean {\n\treturn (\n\t\tObject.getPrototypeOf(prototype) === null &&\n\t\tisIntrinsicConstructorPrototype(prototype, \"Object\")\n\t);\n}\n\nexport function hasOwn<T extends object>(\n\tvalue: T,\n\tkey: PropertyKey,\n): key is keyof T {\n\treturn Object.hasOwn(value, key);\n}\n","import type {\n\tDomainMachineDefinition,\n\tDomainMachineInput,\n\tDomainMachineSnapshot,\n\tDomainStateNode,\n\tDomainTransition,\n} from \"./contracts\";\nimport { InvalidDomainMachineDefinitionError } from \"./errors\";\nimport { hasOwn, isPlainRecord } from \"./machine-data\";\n\nconst DOMAIN_MACHINE_DEFINITION_KEYS: ReadonlySet<PropertyKey> = new Set([\n\t\"initial\",\n\t\"initialContext\",\n\t\"validateSnapshot\",\n\t\"states\",\n]);\nconst DOMAIN_MACHINE_STATE_NODE_KEYS: ReadonlySet<PropertyKey> = new Set([\n\t\"terminal\",\n\t\"validateContext\",\n\t\"on\",\n]);\nconst DOMAIN_MACHINE_TRANSITION_KEYS: ReadonlySet<PropertyKey> = new Set([\n\t\"target\",\n\t\"guard\",\n\t\"reduce\",\n]);\n\nexport function copyDomainMachineDefinition<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n): DomainMachineDefinition<TState, TContext, TInput, TOutput> {\n\tconst states = readDomainMachineDefinitionProperty(\n\t\tdefinition,\n\t\t\"states\",\n\t) as DomainMachineDefinition<TState, TContext, TInput, TOutput>[\"states\"];\n\tconst copiedStates = Object.create(null) as {\n\t\t[TName in TState]: DomainStateNode<TState, TContext, TInput, TOutput>;\n\t};\n\n\tfor (const state of Object.keys(states) as TState[]) {\n\t\tconst node = readDomainMachineDefinitionProperty(\n\t\t\tstates,\n\t\t\tstate,\n\t\t) as DomainStateNode<TState, TContext, TInput, TOutput>;\n\t\tconst transitions = readOptionalDomainMachineDefinitionProperty(\n\t\t\tnode,\n\t\t\t\"on\",\n\t\t) as DomainStateNode<TState, TContext, TInput, TOutput>[\"on\"] | undefined;\n\t\tconst copiedTransitions = Object.create(null) as {\n\t\t\t[TType in TInput[\"type\"]]?: DomainTransition<\n\t\t\t\tTState,\n\t\t\t\tTContext,\n\t\t\t\tExtract<TInput, { readonly type: TType }>,\n\t\t\t\tTOutput\n\t\t\t>;\n\t\t};\n\n\t\tfor (const inputType of Object.keys(\n\t\t\ttransitions ?? {},\n\t\t) as TInput[\"type\"][]) {\n\t\t\tconst transition = readDomainMachineDefinitionProperty(\n\t\t\t\ttransitions as object,\n\t\t\t\tinputType,\n\t\t\t) as\n\t\t\t\t| DomainTransition<\n\t\t\t\t\t\tTState,\n\t\t\t\t\t\tTContext,\n\t\t\t\t\t\tExtract<TInput, { readonly type: typeof inputType }>,\n\t\t\t\t\t\tTOutput\n\t\t\t\t >\n\t\t\t\t| undefined;\n\t\t\tif (transition) {\n\t\t\t\tconst copiedTransition = Object.freeze({\n\t\t\t\t\ttarget: readDomainMachineDefinitionProperty(transition, \"target\"),\n\t\t\t\t\tguard: readOptionalDomainMachineDefinitionProperty(\n\t\t\t\t\t\ttransition,\n\t\t\t\t\t\t\"guard\",\n\t\t\t\t\t),\n\t\t\t\t\treduce: readOptionalDomainMachineDefinitionProperty(\n\t\t\t\t\t\ttransition,\n\t\t\t\t\t\t\"reduce\",\n\t\t\t\t\t),\n\t\t\t\t}) as DomainTransition<\n\t\t\t\t\tTState,\n\t\t\t\t\tTContext,\n\t\t\t\t\tExtract<TInput, { readonly type: typeof inputType }>,\n\t\t\t\t\tTOutput\n\t\t\t\t>;\n\t\t\t\tObject.defineProperty(copiedTransitions, inputType, {\n\t\t\t\t\tvalue: copiedTransition,\n\t\t\t\t\tenumerable: true,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tObject.defineProperty(copiedStates, state, {\n\t\t\tvalue: Object.freeze({\n\t\t\t\tterminal: readOptionalDomainMachineDefinitionProperty(node, \"terminal\"),\n\t\t\t\tvalidateContext: readOptionalDomainMachineDefinitionProperty(\n\t\t\t\t\tnode,\n\t\t\t\t\t\"validateContext\",\n\t\t\t\t),\n\t\t\t\ton: Object.freeze(copiedTransitions),\n\t\t\t}),\n\t\t\tenumerable: true,\n\t\t});\n\t}\n\n\treturn Object.freeze({\n\t\tinitial: readDomainMachineDefinitionProperty(\n\t\t\tdefinition,\n\t\t\t\"initial\",\n\t\t) as TState,\n\t\tinitialContext: readDomainMachineDefinitionProperty(\n\t\t\tdefinition,\n\t\t\t\"initialContext\",\n\t\t) as () => TContext,\n\t\tvalidateSnapshot: readOptionalDomainMachineDefinitionProperty(\n\t\t\tdefinition,\n\t\t\t\"validateSnapshot\",\n\t\t) as\n\t\t\t| ((snapshot: DomainMachineSnapshot<TState, TContext>) => boolean)\n\t\t\t| undefined,\n\t\tstates: Object.freeze(copiedStates),\n\t});\n}\n\n/**\n * Registry of definitions produced by `prepareDomainMachineDefinition`:\n * validated, defensively copied, deeply frozen. The runtime membership\n * proof lives in this module-private WeakSet (the stable copies are\n * frozen and must stay pure data, so no runtime brand property); the\n * compile-time proof is the required type brand on\n * {@link PreparedDomainMachineDefinition}. Only\n * `prepareDomainMachineDefinition` below adds to the set, so membership\n * always implies validated + copied + frozen.\n */\nconst preparedDefinitions = new WeakSet<object>();\n\ndeclare const preparedDefinitionBrand: unique symbol;\n\n/**\n * A machine definition that `prepareDomainMachineDefinition` has\n * validated, defensively copied, and deeply frozen. Assignable wherever\n * a plain `DomainMachineDefinition` is accepted; the reverse does NOT\n * hold (the brand is required), so an API that demands a prepared\n * definition rejects raw ones at compile time. The pure functions and\n * the `DomainStateMachine` constructor recognize prepared definitions\n * at runtime and skip their per-call validate-and-copy.\n */\nexport type PreparedDomainMachineDefinition<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput = never,\n> = DomainMachineDefinition<TState, TContext, TInput, TOutput> & {\n\treadonly [preparedDefinitionBrand]: true;\n};\n\n/**\n * The entry-point normalization every pure function and the\n * `DomainStateMachine` constructor share: a prepared definition passes\n * through untouched (already validated, copied, frozen); anything else\n * pays the documented per-call validate-and-copy.\n */\nexport function ensureStableDomainMachineDefinition<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n): DomainMachineDefinition<TState, TContext, TInput, TOutput> {\n\tif (preparedDefinitions.has(definition)) return definition;\n\tvalidateDomainMachineDefinition(definition);\n\treturn copyDomainMachineDefinition(definition);\n}\n\n/**\n * Validates and stabilizes a machine definition ONCE, for repeated use\n * with the pure functions. Without it, `transitionDomainState` and\n * `canTransitionDomainState` re-validate and defensively re-copy the\n * WHOLE definition on every call (the documented safety of the raw\n * path); on a hot dispatch path that is avoidable O(definition) work.\n * The `DomainStateMachine` class does the equivalent once in its\n * constructor; this export brings the same amortization to pure-API\n * users:\n *\n * ```ts\n * const prepared = prepareDomainMachineDefinition(orderLifecycle);\n * // per dispatch: no re-validation, no definition copy\n * const outcome = transitionDomainState(prepared, snapshot, input);\n * ```\n *\n * The returned definition is a deeply frozen copy, isolated from later\n * mutation of the input object. Preparing an already-prepared\n * definition returns it unchanged.\n */\nexport function prepareDomainMachineDefinition<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n): PreparedDomainMachineDefinition<TState, TContext, TInput, TOutput> {\n\tconst stable = ensureStableDomainMachineDefinition(definition);\n\tpreparedDefinitions.add(stable);\n\treturn stable as PreparedDomainMachineDefinition<\n\t\tTState,\n\t\tTContext,\n\t\tTInput,\n\t\tTOutput\n\t>;\n}\n\nexport function getTransition<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n\tstate: TState,\n\tinput: TInput,\n): DomainTransition<TState, TContext, TInput, TOutput> | undefined {\n\tconst transitions = definition.states[state].on;\n\tif (!transitions || !hasOwn(transitions, input.type)) return undefined;\n\n\treturn transitions[input.type as TInput[\"type\"]] as\n\t\t| DomainTransition<TState, TContext, TInput, TOutput>\n\t\t| undefined;\n}\n\nexport function validateDomainMachineDefinition<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n): void {\n\tconst candidate = definition as unknown;\n\tif (!isPlainRecord(candidate)) {\n\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\"Domain machine definition must be a plain object.\",\n\t\t);\n\t}\n\tassertDomainMachineDefinitionDataProperties(\n\t\tcandidate,\n\t\tDOMAIN_MACHINE_DEFINITION_KEYS,\n\t);\n\n\tconst initial = readDomainMachineDefinitionProperty(candidate, \"initial\");\n\tif (typeof initial !== \"string\") {\n\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\"Domain machine initial state must be a string data property.\",\n\t\t);\n\t}\n\n\tif (\n\t\ttypeof readDomainMachineDefinitionProperty(candidate, \"initialContext\") !==\n\t\t\"function\"\n\t) {\n\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\"Domain machine initialContext must be a function data property.\",\n\t\t);\n\t}\n\n\tconst validateSnapshot = readOptionalDomainMachineDefinitionProperty(\n\t\tcandidate,\n\t\t\"validateSnapshot\",\n\t);\n\tif (\n\t\tvalidateSnapshot !== undefined &&\n\t\ttypeof validateSnapshot !== \"function\"\n\t) {\n\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\"Domain machine validateSnapshot must be a function data property.\",\n\t\t);\n\t}\n\n\tconst statesCandidate = readDomainMachineDefinitionProperty(\n\t\tcandidate,\n\t\t\"states\",\n\t);\n\tif (!isPlainRecord(statesCandidate)) {\n\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\"Domain machine states must be a plain object data property.\",\n\t\t);\n\t}\n\tconst states: Record<PropertyKey, unknown> = statesCandidate;\n\tassertDomainMachineDefinitionEntryMap(states, \"state\");\n\n\tif (!hasOwn(states, initial)) {\n\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t`Initial domain machine state \"${initial}\" is not defined.`,\n\t\t);\n\t}\n\n\tfor (const state of Object.keys(states)) {\n\t\tconst node: unknown = readDomainMachineDefinitionProperty(states, state);\n\t\tif (!isPlainRecord(node)) {\n\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t`Domain machine state \"${state}\" must be a plain object data property.`,\n\t\t\t);\n\t\t}\n\t\tassertDomainMachineDefinitionDataProperties(\n\t\t\tnode,\n\t\t\tDOMAIN_MACHINE_STATE_NODE_KEYS,\n\t\t);\n\n\t\tconst terminal: unknown = readOptionalDomainMachineDefinitionProperty(\n\t\t\tnode,\n\t\t\t\"terminal\",\n\t\t);\n\t\tif (terminal !== undefined && typeof terminal !== \"boolean\") {\n\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t`Domain machine state \"${state}\" terminal flag must be a boolean.`,\n\t\t\t);\n\t\t}\n\n\t\tconst validateContext: unknown =\n\t\t\treadOptionalDomainMachineDefinitionProperty(node, \"validateContext\");\n\t\tif (\n\t\t\tvalidateContext !== undefined &&\n\t\t\ttypeof validateContext !== \"function\"\n\t\t) {\n\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t`Domain machine state \"${state}\" validateContext must be a function.`,\n\t\t\t);\n\t\t}\n\n\t\tconst transitions: unknown = readOptionalDomainMachineDefinitionProperty(\n\t\t\tnode,\n\t\t\t\"on\",\n\t\t);\n\t\tif (transitions !== undefined && !isPlainRecord(transitions)) {\n\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t`Domain machine state \"${state}\" transitions must be a plain object.`,\n\t\t\t);\n\t\t}\n\t\tif (isPlainRecord(transitions)) {\n\t\t\tassertDomainMachineDefinitionEntryMap(transitions, \"input\");\n\t\t}\n\n\t\tconst inputTypes = Object.keys(transitions ?? {});\n\t\tif (terminal === true && inputTypes.length > 0) {\n\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t`Terminal domain machine state \"${state}\" cannot declare transitions.`,\n\t\t\t);\n\t\t}\n\n\t\tfor (const inputType of inputTypes) {\n\t\t\tconst transition: unknown = readDomainMachineDefinitionProperty(\n\t\t\t\ttransitions as object,\n\t\t\t\tinputType,\n\t\t\t);\n\t\t\tif (!isPlainRecord(transition)) {\n\t\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t\t`Domain transition from \"${state}\" on \"${inputType}\" must be a plain object.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tassertDomainMachineDefinitionDataProperties(\n\t\t\t\ttransition,\n\t\t\t\tDOMAIN_MACHINE_TRANSITION_KEYS,\n\t\t\t);\n\n\t\t\tconst target: unknown = readDomainMachineDefinitionProperty(\n\t\t\t\ttransition,\n\t\t\t\t\"target\",\n\t\t\t);\n\t\t\tif (typeof target !== \"string\") {\n\t\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t\t`Domain transition from \"${state}\" on \"${inputType}\" must target a string state.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (!hasOwn(states, target)) {\n\t\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t\t`Domain transition from \"${state}\" on \"${inputType}\" targets unknown state \"${target}\".`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst guard: unknown = readOptionalDomainMachineDefinitionProperty(\n\t\t\t\ttransition,\n\t\t\t\t\"guard\",\n\t\t\t);\n\t\t\tif (guard !== undefined && typeof guard !== \"function\") {\n\t\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t\t`Domain transition from \"${state}\" on \"${inputType}\" guard must be a function.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst reduce: unknown = readOptionalDomainMachineDefinitionProperty(\n\t\t\t\ttransition,\n\t\t\t\t\"reduce\",\n\t\t\t);\n\t\t\tif (reduce !== undefined && typeof reduce !== \"function\") {\n\t\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t\t`Domain transition from \"${state}\" on \"${inputType}\" reduce must be a function.`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction assertDomainMachineDefinitionDataProperties(\n\tvalue: object,\n\tallowedKeys?: ReadonlySet<PropertyKey>,\n): void {\n\tfor (const key of Reflect.ownKeys(value)) {\n\t\tconst descriptor = Object.getOwnPropertyDescriptor(value, key);\n\t\tif (descriptor !== undefined && !(\"value\" in descriptor)) {\n\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t\"Domain machine definition must contain data properties only.\",\n\t\t\t);\n\t\t}\n\t\tif (allowedKeys !== undefined && !allowedKeys.has(key)) {\n\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t`Domain machine definition contains unknown property \"${String(key)}\".`,\n\t\t\t);\n\t\t}\n\t}\n}\n\nfunction assertDomainMachineDefinitionEntryMap(\n\tvalue: object,\n\tentryName: \"state\" | \"input\",\n): void {\n\tassertDomainMachineDefinitionDataProperties(value);\n\n\tfor (const key of Reflect.ownKeys(value)) {\n\t\tconst descriptor = Object.getOwnPropertyDescriptor(value, key);\n\t\tif (typeof key !== \"string\" || descriptor?.enumerable !== true) {\n\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t`Domain machine ${entryName} names must be enumerable string properties.`,\n\t\t\t);\n\t\t}\n\t}\n}\n\nfunction readDomainMachineDefinitionProperty(\n\tvalue: object,\n\tkey: PropertyKey,\n): unknown {\n\tconst descriptor = Object.getOwnPropertyDescriptor(value, key);\n\tif (descriptor === undefined || !(\"value\" in descriptor)) {\n\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\"Domain machine definition must contain data properties only.\",\n\t\t);\n\t}\n\n\treturn descriptor.value;\n}\n\nfunction readOptionalDomainMachineDefinitionProperty(\n\tvalue: object,\n\tkey: PropertyKey,\n): unknown {\n\tconst descriptor = Object.getOwnPropertyDescriptor(value, key);\n\tif (descriptor === undefined) return undefined;\n\tif (!(\"value\" in descriptor)) {\n\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\"Domain machine definition must contain data properties only.\",\n\t\t);\n\t}\n\n\treturn descriptor.value;\n}\n","import { DomainError } from \"../core/errors\";\nimport type {\n\tDomainMachineDefinition,\n\tDomainMachineInput,\n\tDomainMachineReadonly,\n\tDomainMachineSnapshot,\n\tDomainTransitionResult,\n} from \"./contracts\";\nimport {\n\tInvalidDomainMachineDefinitionError,\n\tInvalidDomainMachineInputError,\n\tInvalidDomainMachineSnapshotError,\n\tInvalidDomainTransitionGuardResultError,\n\tInvalidDomainTransitionResultError,\n} from \"./errors\";\nimport {\n\tcopyDomainMachineContext,\n\thasOwn,\n\tisPlainRecord,\n\tisRecord,\n} from \"./machine-data\";\n\nconst DOMAIN_TRANSITION_RESULT_KEYS: ReadonlySet<PropertyKey> = new Set([\n\t\"context\",\n\t\"outputs\",\n]);\n\nexport function prepareDomainMachineSnapshot<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n\tsnapshot: DomainMachineSnapshot<TState, TContext>,\n): DomainMachineSnapshot<TState, TContext> {\n\tvalidateDomainMachineSnapshot(definition, snapshot);\n\tconst preparedSnapshot = createDomainMachineSnapshot<TState, TContext>(\n\t\tsnapshot,\n\t);\n\tvalidateDomainMachineSnapshotInvariant(definition, preparedSnapshot);\n\treturn preparedSnapshot;\n}\n\nexport function createDomainMachineSnapshotFromPreparedContext<\n\tTState extends string,\n\tTContext,\n>(\n\tstate: TState,\n\tcontext: DomainMachineReadonly<TContext>,\n): DomainMachineSnapshot<TState, TContext> {\n\treturn Object.freeze({ state, context });\n}\n\nexport function createDomainMachineSnapshot<\n\tTState extends string,\n\tTContext,\n>(snapshot: {\n\treadonly state: TState;\n\treadonly context: TContext | DomainMachineReadonly<TContext>;\n}): DomainMachineSnapshot<TState, TContext> {\n\treturn Object.freeze({\n\t\tstate: readDomainMachineSnapshotState(snapshot),\n\t\tcontext: copyDomainMachineContext<TContext>(\n\t\t\treadDomainMachineSnapshotContext(snapshot),\n\t\t),\n\t}) as DomainMachineSnapshot<TState, TContext>;\n}\n\nexport function validateDomainMachineSnapshot<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n\tsnapshot: DomainMachineSnapshot<TState, TContext>,\n): void {\n\tif (!isRecord(snapshot)) {\n\t\tthrow new InvalidDomainMachineSnapshotError(\n\t\t\t\"Domain machine snapshot must be an object.\",\n\t\t);\n\t}\n\n\tconst state = readDomainMachineSnapshotState(snapshot);\n\treadDomainMachineSnapshotContext(snapshot);\n\n\tif (!hasOwn(definition.states, state)) {\n\t\tthrow new InvalidDomainMachineSnapshotError(\n\t\t\t`Domain machine snapshot state \"${state}\" is not defined.`,\n\t\t);\n\t}\n}\n\nexport function validateDomainMachineSnapshotInvariant<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n\tsnapshot: DomainMachineSnapshot<TState, TContext>,\n): void {\n\tconst stateNode = definition.states[snapshot.state];\n\tif (stateNode.validateContext !== undefined) {\n\t\tconst validContext = stateNode.validateContext({\n\t\t\tstate: snapshot.state,\n\t\t\tcontext: snapshot.context,\n\t\t});\n\t\tif (typeof validContext !== \"boolean\") {\n\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t`Domain machine state \"${snapshot.state}\" validateContext must return a boolean.`,\n\t\t\t);\n\t\t}\n\t\tif (!validContext) {\n\t\t\tthrow new InvalidDomainMachineSnapshotError(\n\t\t\t\t`Domain machine snapshot violates the context invariant for state \"${snapshot.state}\".`,\n\t\t\t);\n\t\t}\n\t}\n\n\tif (definition.validateSnapshot === undefined) return;\n\n\tconst valid = definition.validateSnapshot(snapshot);\n\tif (typeof valid !== \"boolean\") {\n\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\"Domain machine validateSnapshot must return a boolean.\",\n\t\t);\n\t}\n\n\tif (!valid) {\n\t\tthrow new InvalidDomainMachineSnapshotError(\n\t\t\t`Domain machine snapshot violates invariants for state \"${snapshot.state}\".`,\n\t\t);\n\t}\n}\n\nfunction readDomainMachineSnapshotState<TState extends string>(snapshot: {\n\treadonly state: TState;\n}): TState {\n\tconst stateDescriptor = Object.getOwnPropertyDescriptor(snapshot, \"state\");\n\tif (\n\t\tstateDescriptor === undefined ||\n\t\t!(\"value\" in stateDescriptor) ||\n\t\ttypeof stateDescriptor.value !== \"string\"\n\t) {\n\t\tthrow new InvalidDomainMachineSnapshotError(\n\t\t\t\"Domain machine snapshot state must be a string data property.\",\n\t\t);\n\t}\n\n\treturn stateDescriptor.value as TState;\n}\n\nfunction readDomainMachineSnapshotContext<TContext>(snapshot: {\n\treadonly context: TContext;\n}): TContext {\n\tconst contextDescriptor = Object.getOwnPropertyDescriptor(\n\t\tsnapshot,\n\t\t\"context\",\n\t);\n\tif (contextDescriptor === undefined || !(\"value\" in contextDescriptor)) {\n\t\tthrow new InvalidDomainMachineSnapshotError(\n\t\t\t\"Domain machine snapshot context must be present as a data property.\",\n\t\t);\n\t}\n\n\treturn contextDescriptor.value as TContext;\n}\n\nexport function validateDomainMachineInput(\n\tinput: unknown,\n): asserts input is DomainMachineInput {\n\tif (!isDomainMachineInput(input)) {\n\t\tthrow new InvalidDomainMachineInputError(\n\t\t\t\"Domain machine input must be an object with a string type.\",\n\t\t);\n\t}\n}\n\nexport function isDomainMachineInput(\n\tinput: unknown,\n): input is DomainMachineInput {\n\tif (!isRecord(input)) return false;\n\n\tconst typeDescriptor = Object.getOwnPropertyDescriptor(input, \"type\");\n\treturn (\n\t\ttypeDescriptor !== undefined &&\n\t\t\"value\" in typeDescriptor &&\n\t\ttypeof typeDescriptor.value === \"string\"\n\t);\n}\n\nexport function resolveDomainTransitionGuardResult(\n\tresult: unknown,\n):\n\t| { readonly allowed: true }\n\t| { readonly allowed: false; readonly rejection?: DomainError } {\n\tif (typeof result === \"boolean\") return { allowed: result };\n\tif (result instanceof DomainError) {\n\t\treturn { allowed: false, rejection: result };\n\t}\n\n\tthrow new InvalidDomainTransitionGuardResultError(\n\t\t\"Domain transition guard must return a boolean or DomainError.\",\n\t);\n}\n\nexport function validateDomainTransitionResult<TContext, TOutput>(\n\tresult: DomainTransitionResult<TContext, TOutput> | undefined,\n): void {\n\tif (result === undefined) return;\n\n\tif (!isPlainRecord(result)) {\n\t\tthrow new InvalidDomainTransitionResultError(\n\t\t\t\"Domain transition result must be a plain object when returned.\",\n\t\t);\n\t}\n\n\tfor (const key of Reflect.ownKeys(result)) {\n\t\tif (!DOMAIN_TRANSITION_RESULT_KEYS.has(key)) {\n\t\t\tthrow new InvalidDomainTransitionResultError(\n\t\t\t\t`Domain transition result contains unknown property \"${String(key)}\".`,\n\t\t\t);\n\t\t}\n\t\tconst descriptor = Object.getOwnPropertyDescriptor(result, key);\n\t\tif (descriptor !== undefined && !(\"value\" in descriptor)) {\n\t\t\tthrow new InvalidDomainTransitionResultError(\n\t\t\t\t\"Domain transition result must contain data properties only.\",\n\t\t\t);\n\t\t}\n\t}\n\n\tconst outputs = readDomainTransitionResultOutputs(result);\n\tif (outputs !== undefined && !Array.isArray(outputs)) {\n\t\tthrow new InvalidDomainTransitionResultError(\n\t\t\t\"Domain transition result outputs must be an array when provided.\",\n\t\t);\n\t}\n}\n\nexport function readDomainTransitionResultContext<TContext, TOutput>(\n\tresult: DomainTransitionResult<TContext, TOutput> | undefined,\n):\n\t| { readonly hasContext: false }\n\t| { readonly hasContext: true; readonly context: TContext } {\n\tif (result === undefined) return { hasContext: false };\n\n\tconst contextDescriptor = Object.getOwnPropertyDescriptor(result, \"context\");\n\tif (contextDescriptor === undefined) return { hasContext: false };\n\tif (!(\"value\" in contextDescriptor)) {\n\t\tthrow new InvalidDomainTransitionResultError(\n\t\t\t\"Domain transition result context must be a data property when provided.\",\n\t\t);\n\t}\n\n\treturn { hasContext: true, context: contextDescriptor.value as TContext };\n}\n\nexport function readDomainTransitionResultOutputs<TContext, TOutput>(\n\tresult: DomainTransitionResult<TContext, TOutput> | undefined,\n): readonly TOutput[] | undefined {\n\tif (result === undefined) return undefined;\n\n\tconst outputsDescriptor = Object.getOwnPropertyDescriptor(result, \"outputs\");\n\tif (outputsDescriptor === undefined) return undefined;\n\tif (!(\"value\" in outputsDescriptor)) {\n\t\tthrow new InvalidDomainTransitionResultError(\n\t\t\t\"Domain transition result outputs must be a data property when provided.\",\n\t\t);\n\t}\n\n\treturn outputsDescriptor.value as readonly TOutput[] | undefined;\n}\n","import type {\n\tDomainMachineDefinition,\n\tDomainMachineInput,\n\tDomainMachineSnapshot,\n\tDomainTransitionOutcome,\n} from \"./contracts\";\nimport {\n\tensureStableDomainMachineDefinition,\n\tgetTransition,\n} from \"./definition\";\nimport {\n\tDomainTransitionGuardRejectedError,\n\tInvalidDomainTransitionError,\n} from \"./errors\";\nimport {\n\tcopyDomainMachineInput,\n\tcopyDomainMachineOutputs,\n} from \"./machine-data\";\nimport {\n\tcreateDomainMachineSnapshot,\n\tcreateDomainMachineSnapshotFromPreparedContext,\n\tisDomainMachineInput,\n\tprepareDomainMachineSnapshot,\n\treadDomainTransitionResultContext,\n\treadDomainTransitionResultOutputs,\n\tresolveDomainTransitionGuardResult,\n\tvalidateDomainMachineInput,\n\tvalidateDomainMachineSnapshotInvariant,\n\tvalidateDomainTransitionResult,\n} from \"./snapshot\";\n\n/** Creates and validates a fresh initial snapshot from a machine definition. */\nexport function createInitialDomainMachineSnapshot<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n): DomainMachineSnapshot<TState, TContext> {\n\tconst stableDefinition = ensureStableDomainMachineDefinition(definition);\n\treturn createInitialDomainMachineSnapshotFromPrepared(stableDefinition);\n}\n\nexport function createInitialDomainMachineSnapshotFromPrepared<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n): DomainMachineSnapshot<TState, TContext> {\n\tconst snapshot = createDomainMachineSnapshot<TState, TContext>({\n\t\tstate: definition.initial,\n\t\tcontext: definition.initialContext(),\n\t});\n\tvalidateDomainMachineSnapshotInvariant(definition, snapshot);\n\treturn snapshot;\n}\n\n/**\n * Checks whether an input currently has an allowed transition.\n *\n * Returns `false` for missing transitions, terminal states, rejected guards,\n * and inputs without an own string `type` property. Invalid payload data for a\n * matching transition and broken guard code still throw structured errors.\n */\nexport function canTransitionDomainState<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n\tsnapshot: DomainMachineSnapshot<TState, TContext>,\n\tinput: TInput,\n): boolean {\n\tconst stableDefinition = ensureStableDomainMachineDefinition(definition);\n\tconst currentSnapshot = prepareDomainMachineSnapshot(\n\t\tstableDefinition,\n\t\tsnapshot,\n\t);\n\treturn canTransitionPreparedDomainState(\n\t\tstableDefinition,\n\t\tcurrentSnapshot,\n\t\tinput,\n\t);\n}\n\nexport function canTransitionPreparedDomainState<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n\tsnapshot: DomainMachineSnapshot<TState, TContext>,\n\tinput: TInput,\n): boolean {\n\tif (!isDomainMachineInput(input)) return false;\n\n\tconst stateNode = definition.states[snapshot.state];\n\tif (stateNode.terminal === true) return false;\n\n\tconst transition = getTransition(definition, snapshot.state, input);\n\tif (!transition) return false;\n\n\tconst currentInput = copyDomainMachineInput(input);\n\tif (!transition.guard) return true;\n\n\tconst guardResult = transition.guard({\n\t\tstate: snapshot.state,\n\t\tcontext: snapshot.context,\n\t\tinput: currentInput,\n\t});\n\n\treturn resolveDomainTransitionGuardResult(guardResult).allowed;\n}\n\n/**\n * Applies one input without mutating the input definition or snapshot.\n *\n * @throws {@link InvalidDomainTransitionError} when no transition is defined.\n * @throws {@link DomainTransitionGuardRejectedError} when its guard rejects.\n * @throws A concrete `DomainError` returned by a rejecting guard.\n */\nexport function transitionDomainState<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n\tsnapshot: DomainMachineSnapshot<TState, TContext>,\n\tinput: TInput,\n): DomainTransitionOutcome<TState, TContext, TOutput> {\n\tconst stableDefinition = ensureStableDomainMachineDefinition(definition);\n\tconst currentSnapshot = prepareDomainMachineSnapshot(\n\t\tstableDefinition,\n\t\tsnapshot,\n\t);\n\treturn transitionPreparedDomainState(\n\t\tstableDefinition,\n\t\tcurrentSnapshot,\n\t\tinput,\n\t);\n}\n\nexport function transitionPreparedDomainState<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n\tsnapshot: DomainMachineSnapshot<TState, TContext>,\n\tinput: TInput,\n): DomainTransitionOutcome<TState, TContext, TOutput> {\n\tvalidateDomainMachineInput(input);\n\n\tconst from = snapshot.state;\n\tconst stateNode = definition.states[from];\n\tconst transition =\n\t\tstateNode.terminal === true\n\t\t\t? undefined\n\t\t\t: getTransition(definition, from, input);\n\n\tif (!transition) {\n\t\tthrow new InvalidDomainTransitionError(from, input.type);\n\t}\n\n\tconst currentInput = copyDomainMachineInput(input);\n\tconst guardResult =\n\t\ttransition.guard === undefined\n\t\t\t? true\n\t\t\t: transition.guard({\n\t\t\t\t\tstate: from,\n\t\t\t\t\tcontext: snapshot.context,\n\t\t\t\t\tinput: currentInput,\n\t\t\t\t});\n\tconst guardDecision = resolveDomainTransitionGuardResult(guardResult);\n\n\tif (!guardDecision.allowed) {\n\t\tif (guardDecision.rejection !== undefined) {\n\t\t\tthrow guardDecision.rejection;\n\t\t}\n\t\tthrow new DomainTransitionGuardRejectedError(from, currentInput.type);\n\t}\n\n\tconst result = transition.reduce?.({\n\t\tstate: from,\n\t\tcontext: snapshot.context,\n\t\tinput: currentInput,\n\t});\n\tvalidateDomainTransitionResult(result);\n\tconst contextResult = readDomainTransitionResultContext(result);\n\tconst nextContext = contextResult.hasContext\n\t\t? contextResult.context\n\t\t: snapshot.context;\n\tconst nextSnapshot =\n\t\tnextContext === snapshot.context\n\t\t\t? createDomainMachineSnapshotFromPreparedContext<TState, TContext>(\n\t\t\t\t\ttransition.target,\n\t\t\t\t\tsnapshot.context,\n\t\t\t\t)\n\t\t\t: createDomainMachineSnapshot<TState, TContext>({\n\t\t\t\t\tstate: transition.target,\n\t\t\t\t\tcontext: nextContext,\n\t\t\t\t});\n\tvalidateDomainMachineSnapshotInvariant(definition, nextSnapshot);\n\n\treturn {\n\t\tfrom,\n\t\tto: transition.target,\n\t\tsnapshot: nextSnapshot,\n\t\toutputs: copyDomainMachineOutputs(\n\t\t\treadDomainTransitionResultOutputs(result),\n\t\t),\n\t};\n}\n","import type { DomainMachineDefinition, DomainMachineInput } from \"./contracts\";\nimport {\n\tcopyDomainMachineDefinition,\n\tvalidateDomainMachineDefinition,\n} from \"./definition\";\n\nexport type DomainMachineDefinitionDiagnostic<TState extends string> =\n\t| {\n\t\t\treadonly code: \"unreachable-state\";\n\t\t\treadonly state: TState;\n\t }\n\t| {\n\t\t\treadonly code: \"structural-dead-end\";\n\t\t\treadonly state: TState;\n\t }\n\t| {\n\t\t\treadonly code: \"no-terminal-path\";\n\t\t\treadonly state: TState;\n\t };\n\nexport type DomainMachineTransitionDescription<\n\tTState extends string,\n\tTInputType extends string,\n> = {\n\treadonly state: TState;\n\treadonly inputType: TInputType;\n\treadonly target: TState;\n\treadonly guarded: boolean;\n};\n\nexport type DomainMachineDefinitionAnalysis<\n\tTState extends string,\n\tTInputType extends string,\n> = {\n\treadonly diagnostics: readonly DomainMachineDefinitionDiagnostic<TState>[];\n\treadonly transitions: readonly DomainMachineTransitionDescription<\n\t\tTState,\n\t\tTInputType\n\t>[];\n\t/** States reachable when every guard is assumed to allow its transition. */\n\treadonly structurallyReachableStates: readonly TState[];\n\t/** States with a graph path to a terminal state when every guard is assumed to allow it. */\n\treadonly statesWithTerminalPath: readonly TState[];\n};\n\n/**\n * Inspects the declarative transition graph without executing definition callbacks.\n * Guarded edges are treated as possible edges, so diagnostics never claim more\n * runtime reachability than the static graph can prove.\n */\nexport function analyzeDomainMachineDefinition<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n): DomainMachineDefinitionAnalysis<TState, TInput[\"type\"]> {\n\tvalidateDomainMachineDefinition(definition);\n\tconst stableDefinition = copyDomainMachineDefinition(definition);\n\tconst states = (Object.keys(stableDefinition.states) as TState[]).sort(\n\t\tcompareStrings,\n\t);\n\tconst outgoing = new Map<TState, TState[]>();\n\tconst incoming = new Map<TState, TState[]>();\n\tconst transitions: DomainMachineTransitionDescription<\n\t\tTState,\n\t\tTInput[\"type\"]\n\t>[] = [];\n\n\tfor (const state of states) {\n\t\toutgoing.set(state, []);\n\t\tincoming.set(state, []);\n\t}\n\n\tfor (const state of states) {\n\t\tconst stateTransitions = stableDefinition.states[state].on;\n\t\tconst inputTypes = (\n\t\t\tObject.keys(stateTransitions ?? {}) as TInput[\"type\"][]\n\t\t).sort(compareStrings);\n\n\t\tfor (const inputType of inputTypes) {\n\t\t\tconst transition = stateTransitions?.[inputType];\n\t\t\tif (transition === undefined) continue;\n\n\t\t\toutgoing.get(state)?.push(transition.target);\n\t\t\tincoming.get(transition.target)?.push(state);\n\t\t\ttransitions.push(\n\t\t\t\tObject.freeze({\n\t\t\t\t\tstate,\n\t\t\t\t\tinputType,\n\t\t\t\t\ttarget: transition.target,\n\t\t\t\t\tguarded: transition.guard !== undefined,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t}\n\n\tconst structurallyReachable = visitGraph(\n\t\t[stableDefinition.initial],\n\t\toutgoing,\n\t);\n\tconst terminalStates = states.filter(\n\t\t(state) => stableDefinition.states[state].terminal === true,\n\t);\n\tconst statesWithTerminalPath = visitGraph(terminalStates, incoming);\n\tconst diagnostics: DomainMachineDefinitionDiagnostic<TState>[] = [];\n\n\tfor (const state of states) {\n\t\tif (!structurallyReachable.has(state)) {\n\t\t\tdiagnostics.push(Object.freeze({ code: \"unreachable-state\", state }));\n\t\t}\n\t}\n\tfor (const state of states) {\n\t\tif (\n\t\t\tstableDefinition.states[state].terminal !== true &&\n\t\t\toutgoing.get(state)?.length === 0\n\t\t) {\n\t\t\tdiagnostics.push(Object.freeze({ code: \"structural-dead-end\", state }));\n\t\t}\n\t}\n\tfor (const state of states) {\n\t\tif (!statesWithTerminalPath.has(state)) {\n\t\t\tdiagnostics.push(Object.freeze({ code: \"no-terminal-path\", state }));\n\t\t}\n\t}\n\n\treturn Object.freeze({\n\t\tdiagnostics: Object.freeze(diagnostics),\n\t\ttransitions: Object.freeze(transitions),\n\t\tstructurallyReachableStates: Object.freeze(\n\t\t\tstates.filter((state) => structurallyReachable.has(state)),\n\t\t),\n\t\tstatesWithTerminalPath: Object.freeze(\n\t\t\tstates.filter((state) => statesWithTerminalPath.has(state)),\n\t\t),\n\t});\n}\n\nfunction visitGraph<TState extends string>(\n\tstartStates: readonly TState[],\n\tedges: ReadonlyMap<TState, readonly TState[]>,\n): ReadonlySet<TState> {\n\tconst visited = new Set<TState>();\n\tconst pending = [...startStates];\n\n\twhile (pending.length > 0) {\n\t\tconst state = pending.pop();\n\t\tif (state === undefined || visited.has(state)) continue;\n\n\t\tvisited.add(state);\n\t\tfor (const next of edges.get(state) ?? []) {\n\t\t\tif (!visited.has(next)) pending.push(next);\n\t\t}\n\t}\n\n\treturn visited;\n}\n\nfunction compareStrings(left: string, right: string): number {\n\treturn left < right ? -1 : left > right ? 1 : 0;\n}\n","import type {\n\tDomainMachineDefinition,\n\tDomainMachineInput,\n\tDomainMachineReadonly,\n\tDomainMachineSnapshot,\n\tDomainTransitionOutcome,\n} from \"./contracts\";\nimport { ensureStableDomainMachineDefinition } from \"./definition\";\nimport { ReentrantDomainStateMachineEvaluationError } from \"./errors\";\nimport {\n\tcreateDomainMachineSnapshot,\n\tvalidateDomainMachineSnapshot,\n\tvalidateDomainMachineSnapshotInvariant,\n} from \"./snapshot\";\nimport {\n\tcanTransitionPreparedDomainState,\n\tcreateInitialDomainMachineSnapshotFromPrepared,\n\ttransitionPreparedDomainState,\n} from \"./transition\";\n\nexport type {\n\tDomainMachineDefinitionAnalysis,\n\tDomainMachineDefinitionDiagnostic,\n\tDomainMachineTransitionDescription,\n} from \"./analyzer\";\nexport { analyzeDomainMachineDefinition } from \"./analyzer\";\nexport type {\n\tDomainMachineDefinition,\n\tDomainMachineInput,\n\tDomainMachineReadonly,\n\tDomainMachineSnapshot,\n\tDomainStateNode,\n\tDomainTransition,\n\tDomainTransitionGuardResult,\n\tDomainTransitionOutcome,\n\tDomainTransitionResult,\n} from \"./contracts\";\nexport {\n\ttype PreparedDomainMachineDefinition,\n\tprepareDomainMachineDefinition,\n} from \"./definition\";\nexport {\n\tDomainTransitionGuardRejectedError,\n\tInvalidDomainMachineContextError,\n\tInvalidDomainMachineDefinitionError,\n\tInvalidDomainMachineInputError,\n\tInvalidDomainMachineSnapshotError,\n\tInvalidDomainTransitionError,\n\tInvalidDomainTransitionGuardResultError,\n\tInvalidDomainTransitionResultError,\n\tReentrantDomainStateMachineEvaluationError,\n} from \"./errors\";\nexport {\n\tcanTransitionDomainState,\n\tcreateInitialDomainMachineSnapshot,\n\ttransitionDomainState,\n} from \"./transition\";\n\n/**\n * Stateful convenience wrapper around the pure domain transition functions.\n *\n * Persist {@link snapshot}, not the machine instance. Pass a restored snapshot\n * to the second constructor overload to validate and reconstitute a machine.\n */\nexport class DomainStateMachine<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput = never,\n> {\n\tprivate readonly definition: DomainMachineDefinition<\n\t\tTState,\n\t\tTContext,\n\t\tTInput,\n\t\tTOutput\n\t>;\n\n\t#snapshot: DomainMachineSnapshot<TState, TContext>;\n\t#evaluating = false;\n\n\tconstructor(\n\t\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n\t);\n\tconstructor(\n\t\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n\t\tsnapshot: DomainMachineSnapshot<TState, TContext> | undefined,\n\t);\n\tconstructor(\n\t\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n\t\t...snapshotInput: [] | [DomainMachineSnapshot<TState, TContext> | undefined]\n\t) {\n\t\t// A prepared definition (prepareDomainMachineDefinition) passes\n\t\t// through; a raw one pays the one-time validate-and-copy here.\n\t\tthis.definition = ensureStableDomainMachineDefinition(definition);\n\t\t// Resolve the overload by the argument value, not the rest-parameter\n\t\t// arity: an explicit `undefined` snapshot (a natural result of a\n\t\t// nullable `repo.loadSnapshot(id)` or `map.get(id)` passed straight\n\t\t// through) means \"no snapshot\", so it must fall back to the initial\n\t\t// snapshot instead of failing validation.\n\t\tconst [suppliedSnapshot] = snapshotInput;\n\t\tif (suppliedSnapshot !== undefined) {\n\t\t\tvalidateDomainMachineSnapshot(this.definition, suppliedSnapshot);\n\t\t\tthis.#snapshot = createDomainMachineSnapshot<TState, TContext>(\n\t\t\t\tsuppliedSnapshot,\n\t\t\t);\n\t\t\tvalidateDomainMachineSnapshotInvariant(this.definition, this.#snapshot);\n\t\t} else {\n\t\t\tthis.#snapshot = createInitialDomainMachineSnapshotFromPrepared(\n\t\t\t\tthis.definition,\n\t\t\t);\n\t\t}\n\t}\n\n\t/** Returns a defensive, deeply frozen copy of the current snapshot. */\n\tget snapshot(): DomainMachineSnapshot<TState, TContext> {\n\t\treturn createDomainMachineSnapshot<TState, TContext>(this.#snapshot);\n\t}\n\n\t/** Current named control state. */\n\tget state(): TState {\n\t\treturn this.#snapshot.state;\n\t}\n\n\t/** Current deeply readonly context. */\n\tget context(): DomainMachineReadonly<TContext> {\n\t\treturn this.#snapshot.context;\n\t}\n\n\t/** Whether the current state permanently forbids outgoing transitions. */\n\tisTerminal(): boolean {\n\t\treturn this.definition.states[this.state].terminal === true;\n\t}\n\n\t/** Checks a transition without changing the current snapshot. */\n\tcan(input: TInput): boolean {\n\t\treturn this.evaluate(() =>\n\t\t\tcanTransitionPreparedDomainState(this.definition, this.#snapshot, input),\n\t\t);\n\t}\n\n\t/** Applies an input and advances the current snapshot on success. */\n\tdispatch(input: TInput): DomainTransitionOutcome<TState, TContext, TOutput> {\n\t\treturn this.evaluate(() => {\n\t\t\tconst result = transitionPreparedDomainState(\n\t\t\t\tthis.definition,\n\t\t\t\tthis.#snapshot,\n\t\t\t\tinput,\n\t\t\t);\n\t\t\tthis.#snapshot = result.snapshot;\n\t\t\treturn result;\n\t\t});\n\t}\n\n\tprivate evaluate<TResult>(operation: () => TResult): TResult {\n\t\tif (this.#evaluating) {\n\t\t\tthrow new ReentrantDomainStateMachineEvaluationError();\n\t\t}\n\n\t\tthis.#evaluating = true;\n\t\ttry {\n\t\t\treturn operation();\n\t\t} finally {\n\t\t\tthis.#evaluating = false;\n\t\t}\n\t}\n}\n","import type { AnyDomainEvent } from \"../aggregate/domain-event\";\nimport { abortReason } from \"../utils/abort\";\nimport type { EventBus, EventHandler, OnceOptions } from \"./ports\";\n\n/**\n * Simple in-memory event bus implementation.\n * Supports multiple subscribers per event type (pub/sub pattern).\n *\n * @template Evt - The type of domain events (must extend DomainEvent)\n *\n * @example\n * ```typescript\n * const bus = new EventBusImpl<OrderEvent>();\n *\n * bus.subscribe(\"OrderCreated\", async (event) => {\n * await sendEmail(event.payload.customerId);\n * });\n *\n * bus.subscribe(\"OrderCreated\", async (event) => {\n * await logEvent(event);\n * });\n *\n * await bus.publish([orderCreatedEvent]);\n * // Both handlers will be called\n * ```\n */\nexport class EventBusImpl<Evt extends AnyDomainEvent>\n\timplements EventBus<Evt>\n{\n\tprivate readonly handlers = new Map<string, EventHandler<Evt>[]>();\n\n\tsubscribe<K extends Evt[\"type\"]>(\n\t\teventType: K,\n\t\thandler: EventHandler<Extract<Evt, { type: K }>>,\n\t): () => void {\n\t\tconst type = eventType;\n\t\tif (!this.handlers.has(type)) {\n\t\t\tthis.handlers.set(type, []);\n\t\t}\n\t\tconst handlersForType = this.handlers.get(type)!;\n\t\tconst casted = handler as EventHandler<Evt>;\n\t\thandlersForType.push(casted);\n\n\t\t// Return unsubscribe: removes exactly this subscription, even if the\n\t\t// same handler reference was subscribed multiple times (each call to\n\t\t// subscribe gets its own unsubscribe).\n\t\tlet removed = false;\n\t\treturn () => {\n\t\t\tif (removed) return;\n\t\t\tconst idx = handlersForType.indexOf(casted);\n\t\t\tif (idx !== -1) {\n\t\t\t\thandlersForType.splice(idx, 1);\n\t\t\t\tremoved = true;\n\t\t\t}\n\t\t\tif (handlersForType.length === 0) {\n\t\t\t\tthis.handlers.delete(type);\n\t\t\t}\n\t\t};\n\t}\n\n\tonce<K extends Evt[\"type\"]>(\n\t\teventType: K,\n\t\toptions?: OnceOptions,\n\t): Promise<Extract<Evt, { type: K }>> {\n\t\treturn new Promise<Extract<Evt, { type: K }>>((resolve, reject) => {\n\t\t\t// Reject synchronously if the signal is already aborted; don't\n\t\t\t// even subscribe.\n\t\t\tif (options?.signal?.aborted) {\n\t\t\t\treject(abortReason(options.signal, \"EventBus.once aborted\"));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\t\t\tlet settled = false;\n\t\t\tlet abortListener: (() => void) | undefined;\n\n\t\t\tconst cleanup = () => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tunsubscribe();\n\t\t\t\tif (timer !== undefined) clearTimeout(timer);\n\t\t\t\tif (abortListener && options?.signal) {\n\t\t\t\t\toptions.signal.removeEventListener(\"abort\", abortListener);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst unsubscribe = this.subscribe(eventType, (event) => {\n\t\t\t\tcleanup();\n\t\t\t\tresolve(event);\n\t\t\t});\n\n\t\t\tif (options?.signal) {\n\t\t\t\tabortListener = () => {\n\t\t\t\t\tcleanup();\n\t\t\t\t\treject(abortReason(options.signal!, \"EventBus.once aborted\"));\n\t\t\t\t};\n\t\t\t\toptions.signal.addEventListener(\"abort\", abortListener);\n\t\t\t}\n\n\t\t\tif (typeof options?.timeoutMs === \"number\") {\n\t\t\t\ttimer = setTimeout(() => {\n\t\t\t\t\tcleanup();\n\t\t\t\t\treject(\n\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t`EventBus.once timed out after ${options.timeoutMs}ms waiting for \"${eventType}\"`,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}, options.timeoutMs);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * See {@link EventBus.publish} for the full ordering / parallelism /\n\t * error-aggregation contract this implementation realises:\n\t * - events in input order, sequentially;\n\t * - handlers within one event in parallel via `Promise.allSettled`;\n\t * - errors collected and thrown after the batch (single Error, or\n\t * `AggregateError` for multiple failures).\n\t */\n\tasync publish(events: ReadonlyArray<Evt>): Promise<void> {\n\t\tconst errors: Error[] = [];\n\n\t\tfor (const event of events) {\n\t\t\tconst handlersForType = this.handlers.get(event.type);\n\t\t\tif (handlersForType) {\n\t\t\t\t// Snapshot so a handler unsubscribing during dispatch doesn't\n\t\t\t\t// shift indices while we iterate. The async wrapper converts a\n\t\t\t\t// synchronous throw (EventHandler may return void) into a\n\t\t\t\t// rejection; otherwise it would escape before allSettled sees\n\t\t\t\t// the array, skipping peers and orphaning their promises.\n\t\t\t\tconst results = await Promise.allSettled(\n\t\t\t\t\thandlersForType.slice().map(async (handler) => handler(event)),\n\t\t\t\t);\n\t\t\t\tfor (const result of results) {\n\t\t\t\t\tif (result.status === \"rejected\") {\n\t\t\t\t\t\terrors.push(\n\t\t\t\t\t\t\tresult.reason instanceof Error\n\t\t\t\t\t\t\t\t? result.reason\n\t\t\t\t\t\t\t\t: // Attach the raw reason as cause: a handler\n\t\t\t\t\t\t\t\t\t// rejecting with a structured payload must stay\n\t\t\t\t\t\t\t\t\t// diagnosable, not collapse to '[object Object]'.\n\t\t\t\t\t\t\t\t\tnew Error(String(result.reason), {\n\t\t\t\t\t\t\t\t\t\tcause: result.reason,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (errors.length === 1) {\n\t\t\tthrow errors[0];\n\t\t}\n\t\tif (errors.length > 1) {\n\t\t\tthrow new AggregateError(errors, \"Multiple event handlers failed\");\n\t\t}\n\t}\n}\n\n","import type { AnyDomainEvent } from \"../aggregate/domain-event\";\nimport type {\n\tDeadLetterRecord,\n\tDispatchTrackingOutbox,\n\tOutboxRecord,\n} from \"./ports\";\n\n/** Construction options for {@link InMemoryOutbox}. */\nexport interface InMemoryOutboxOptions {\n\t/**\n\t * Failed-delivery ceiling: once `markFailed` has been reported this\n\t * many times for a record, it moves to {@link InMemoryOutbox.deadLetters}\n\t * and stops coming back from `getPending`. Default `5`.\n\t */\n\tmaxDeliveryAttempts?: number;\n}\n\ntype TrackedRecord<Evt extends AnyDomainEvent> = {\n\tdispatchId: string;\n\tevent: Evt;\n\tattempts: number;\n\tlastError?: string;\n};\n\n/**\n * In-memory reference implementation of `DispatchTrackingOutbox<Evt>`\n * (and therefore of the plain `Outbox<Evt>` port).\n *\n * Intended for tests, single-process workers, and quick-start demos.\n * Uses the event's own `eventId` as the dispatch id: the common, clean\n * choice. Storage is a `Map` keyed by `eventId`, so re-adding the same\n * event is naturally idempotent (`getPending` returns each event at\n * most once; a re-add refreshes the stored copy, e.g. a retried\n * commit's freshly stamped `aggregateVersion`, while the delivery\n * attempt count survives), and insertion order is preserved:\n * `getPending` returns records in commit order, as the port contract\n * requires.\n *\n * Dispatch tracking: `markFailed` increments the record's attempt count\n * and, at `maxDeliveryAttempts`, moves it to the dead-letter set\n * exposed by `deadLetters()`. Re-`add`ing a dead-lettered event\n * requeues it with a fresh attempts budget (the operator-facing\n * inverse of `deadLetters()`); `markDispatched` acks pending AND\n * dead-lettered records (manual redelivery then ack).\n *\n * For production, back the outbox with a transactional store so the\n * outbox row participates in the same transaction as the aggregate\n * write (see `TransactionScope` + `withCommit`). This class lives in\n * memory only: events are lost on process restart. Sharper still:\n * events `add()`ed inside a transaction that later rolls back are NOT\n * removed (the Map knows nothing about your scope's rollback). Tests\n * that assert rollback purity need an outbox that participates in the\n * test store's transactional semantics; see the reference adapter at\n * https://github.com/shi-rudo/ddd-kit-ts/blob/main/src/testing/repository-contract.test.ts\n * (repo-only, not shipped to npm).\n *\n * @example\n * ```ts\n * import { InMemoryOutbox, EventBusImpl, withCommit } from \"@shirudo/ddd-kit\";\n *\n * const outbox = new InMemoryOutbox<OrderEvent>();\n * const bus = new EventBusImpl<OrderEvent>();\n *\n * await withCommit({ scope, outbox, bus }, async (tx) => {\n * const orderRepository = makeOrderRepository(tx);\n * const order = await orderRepository.getByIdOrFail(id);\n * order.confirm();\n * await orderRepository.save(order);\n * return { result: order.id, aggregates: [order] };\n * });\n * ```\n */\nexport class InMemoryOutbox<Evt extends AnyDomainEvent>\n\timplements DispatchTrackingOutbox<Evt>\n{\n\tprivate readonly pending = new Map<string, TrackedRecord<Evt>>();\n\tprivate readonly dead = new Map<string, DeadLetterRecord<Evt>>();\n\tprivate readonly maxDeliveryAttempts: number;\n\n\tconstructor(options?: InMemoryOutboxOptions) {\n\t\tconst max = options?.maxDeliveryAttempts ?? 5;\n\t\tif (!Number.isInteger(max) || max < 1) {\n\t\t\tthrow new Error(\n\t\t\t\t`InMemoryOutbox: maxDeliveryAttempts must be an integer >= 1, got ${max}`,\n\t\t\t);\n\t\t}\n\t\tthis.maxDeliveryAttempts = max;\n\t}\n\n\tasync add(events: ReadonlyArray<Evt>): Promise<void> {\n\t\tfor (const event of events) {\n\t\t\t// Requeue path: re-adding a dead-lettered event is the natural\n\t\t\t// inverse of deadLetters() (an operator fixed the poison cause).\n\t\t\t// It moves back into automatic dispatch with a fresh attempts\n\t\t\t// budget, at the tail of the pending order; silently succeeding\n\t\t\t// while the event stays dead would be a lie.\n\t\t\tif (this.dead.has(event.eventId)) {\n\t\t\t\tthis.dead.delete(event.eventId);\n\t\t\t\tthis.pending.set(event.eventId, {\n\t\t\t\t\tdispatchId: event.eventId,\n\t\t\t\t\tevent,\n\t\t\t\t\tattempts: 0,\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst existing = this.pending.get(event.eventId);\n\t\t\tif (existing) {\n\t\t\t\t// Re-add refreshes the stored COPY but keeps the delivery\n\t\t\t\t// bookkeeping: a failed-commit-then-retry re-adds the same\n\t\t\t\t// eventId with a newly stamped aggregateVersion (withCommit\n\t\t\t\t// stamps at harvest), and dispatching the stale copy would\n\t\t\t\t// hand consumers a version from a commit that never\n\t\t\t\t// happened. The attempts count belongs to delivery, not to\n\t\t\t\t// the payload, so it survives the refresh.\n\t\t\t\texisting.event = event;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthis.pending.set(event.eventId, {\n\t\t\t\tdispatchId: event.eventId,\n\t\t\t\tevent,\n\t\t\t\tattempts: 0,\n\t\t\t});\n\t\t}\n\t}\n\n\tasync getPending(\n\t\tlimit?: number,\n\t): Promise<ReadonlyArray<OutboxRecord<Evt>>> {\n\t\t// Copies, not the tracked internals: a caller mutating a returned\n\t\t// record must not corrupt the attempt bookkeeping. Map iteration\n\t\t// preserves insertion order, satisfying the port's ordering contract.\n\t\tconst all = [...this.pending.values()].map((record) => ({\n\t\t\tdispatchId: record.dispatchId,\n\t\t\tevent: record.event,\n\t\t\tattempts: record.attempts,\n\t\t}));\n\t\tif (typeof limit !== \"number\") return all;\n\t\t// Clamp: slice's end-relative indexing would turn a negative limit\n\t\t// (e.g. a dispatcher's batchSize - inFlight going negative) into\n\t\t// \"everything but the last records\".\n\t\treturn all.slice(0, Math.max(0, limit));\n\t}\n\n\tasync markDispatched(dispatchIds: ReadonlyArray<string>): Promise<void> {\n\t\tfor (const id of dispatchIds) {\n\t\t\tthis.pending.delete(id);\n\t\t\t// Manual redelivery then ack: dispatching a dead-lettered record\n\t\t\t// clears it too.\n\t\t\tthis.dead.delete(id);\n\t\t}\n\t}\n\n\tasync markFailed(dispatchId: string, error?: unknown): Promise<void> {\n\t\tconst record = this.pending.get(dispatchId);\n\t\t// Unknown or already-dispatched (or already dead-lettered) id: a\n\t\t// late failure report must not resurrect anything.\n\t\tif (!record) return;\n\t\trecord.attempts += 1;\n\t\trecord.lastError =\n\t\t\terror instanceof Error ? error.message : String(error ?? \"unknown\");\n\t\tif (record.attempts >= this.maxDeliveryAttempts) {\n\t\t\tthis.pending.delete(dispatchId);\n\t\t\tthis.dead.set(dispatchId, {\n\t\t\t\tdispatchId: record.dispatchId,\n\t\t\t\tevent: record.event,\n\t\t\t\tattempts: record.attempts,\n\t\t\t\tlastError: record.lastError,\n\t\t\t});\n\t\t}\n\t}\n\n\tasync deadLetters(): Promise<ReadonlyArray<DeadLetterRecord<Evt>>> {\n\t\treturn [...this.dead.values()].map((record) => ({ ...record }));\n\t}\n}\n","import type { AnyDomainEvent } from \"../aggregate/domain-event\";\nimport { ConcurrencyConflictError } from \"../core/errors\";\nimport type { Id } from \"../core/id\";\nimport type {\n\tEventStore,\n\tEventStoreAppendOptions,\n\tReadStreamOptions,\n} from \"./event-store\";\n\n/**\n * In-memory reference implementation of `EventStore<Evt>`.\n *\n * Intended for tests, single-process workers, and quick-start demos.\n * Implements the full port contract: expectedVersion-guarded appends\n * (throwing `ConcurrencyConflictError` on mismatch), atomic rejected\n * appends, append-order reads, and `fromVersion` slicing.\n *\n * For production, back the port with a durable store whose append and\n * the aggregate transaction share atomicity (a table with a\n * `(stream_id, position)` unique key inside the same transaction, or a\n * dedicated event store). Same caveat as `InMemoryOutbox`: this class\n * lives in memory only and knows nothing about your `TransactionScope`\n * rollbacks; events appended inside a transaction that later rolls back\n * are NOT removed. The event-sourced repository contract suite's\n * reference environment shows the snapshot/restore pattern for\n * rollback-pure in-memory testing.\n */\nexport class InMemoryEventStore<Evt extends AnyDomainEvent>\n\timplements EventStore<Evt>\n{\n\tprivate readonly streams = new Map<string, Evt[]>();\n\n\tasync append(\n\t\tstreamId: Id<string>,\n\t\tevents: ReadonlyArray<Evt>,\n\t\toptions: EventStoreAppendOptions,\n\t): Promise<void> {\n\t\tif (events.length === 0) return;\n\t\tconst stream = this.streams.get(streamId) ?? [];\n\t\tif (stream.length !== options.expectedVersion) {\n\t\t\tthrow new ConcurrencyConflictError({\n\t\t\t\taggregateType: events[0]?.aggregateType ?? \"stream\",\n\t\t\t\taggregateId: streamId,\n\t\t\t\texpectedVersion: options.expectedVersion,\n\t\t\t\tactualVersion: stream.length,\n\t\t\t});\n\t\t}\n\t\t// Atomic by construction: the conflict check above throws before\n\t\t// anything is written, and the batch lands in one push.\n\t\tthis.streams.set(streamId, [...stream, ...events]);\n\t}\n\n\tasync readStream(\n\t\tstreamId: Id<string>,\n\t\toptions?: ReadStreamOptions,\n\t): Promise<ReadonlyArray<Evt>> {\n\t\tconst stream = this.streams.get(streamId) ?? [];\n\t\tconst fromVersion = options?.fromVersion ?? 0;\n\t\t// slice() always copies: callers never see the internal array.\n\t\treturn stream.slice(Math.max(0, fromVersion));\n\t}\n}\n","import { someChainRetryable } from \"@shirudo/base-error\";\nimport { abortReason } from \"../utils/abort\";\nimport { reportToObserver } from \"../utils/observer\";\nimport type { TransactionScope, TransactionalOptions } from \"./scope\";\n\n/**\n * Tuning for {@link RetryingTransactionScope}. All fields are optional;\n * the defaults suit optimistic-concurrency retries (a handful of writers\n * racing one aggregate), not high-fan-out hot-row contention.\n */\nexport interface RetryPolicy {\n\t/** Total tries, including the first. Default `3` (1 initial + 2 retries). */\n\tmaxAttempts?: number;\n\t/** First backoff delay; doubles each retry. Default `50`ms. */\n\tbaseDelayMs?: number;\n\t/** Ceiling for the backoff delay. Default `1000`ms. */\n\tmaxDelayMs?: number;\n\t/**\n\t * Classifier deciding whether an error is worth retrying. Default\n\t * {@link someChainRetryable} (walks the cause chain for the loose\n\t * `retryable === true` marker, so `ConcurrencyConflictError` matches\n\t * even when an adapter wraps it). Override to add driver-specific\n\t * serialization codes (Postgres 40001, MySQL 1213, SQLite SQLITE_BUSY)\n\t * that your adapter has not mapped to a retryable kit error.\n\t */\n\tisRetryable?: (error: unknown) => boolean;\n\t/**\n\t * Observer fired before each backoff wait (logging / metrics).\n\t * Neutralised like the `withCommit` observers: a synchronous throw or\n\t * an async rejection is swallowed, so a buggy observer can neither\n\t * abort the retry loop nor mask the original retryable error.\n\t */\n\tonRetry?: (info: {\n\t\tattempt: number;\n\t\terror: unknown;\n\t\tdelayMs: number;\n\t}) => void;\n\t/** Backoff wait. Default an abortable `setTimeout`. Injectable for tests. */\n\tsleep?: (ms: number, signal?: AbortSignal) => Promise<void>;\n\t/** Jitter source in `[0, 1)`. Default `Math.random`. Injectable for tests. */\n\trandom?: () => number;\n}\n\nconst DEFAULT_MAX_ATTEMPTS = 3;\nconst DEFAULT_BASE_DELAY_MS = 50;\nconst DEFAULT_MAX_DELAY_MS = 1000;\n\n/**\n * Backoff delay for the attempt that just failed (1-based): exponential\n * (`baseDelayMs * 2^(attempt-1)`), capped at `maxDelayMs`, then a +/-20%\n * jitter band (`* random(0.8, 1.2)`) applied and re-clamped to the cap.\n * Pure and deterministic given `random`. Result is never negative.\n *\n * @internal Exported only so it can be unit-tested directly; not part of\n * the supported public API and may change without a major version.\n */\nexport function computeBackoffDelay(\n\tattempt: number,\n\topts: { baseDelayMs: number; maxDelayMs: number; random: () => number },\n): number {\n\tconst exponential = opts.baseDelayMs * 2 ** (attempt - 1);\n\tconst capped = Math.min(opts.maxDelayMs, exponential);\n\tconst jitter = 0.8 + opts.random() * 0.4; // [0.8, 1.2)\n\treturn Math.max(0, Math.min(opts.maxDelayMs, Math.round(capped * jitter)));\n}\n\nfunction assertNonNegativeFinite(field: string, value: number): void {\n\tif (!Number.isFinite(value) || value < 0) {\n\t\tthrow new Error(\n\t\t\t`RetryingTransactionScope: ${field} must be a non-negative finite number, got ${value}`,\n\t\t);\n\t}\n}\n\nconst ABORT_MESSAGE = \"RetryingTransactionScope aborted\";\n\n/** Abortable `setTimeout`; rejects with the signal reason if aborted. */\nfunction defaultSleep(ms: number, signal?: AbortSignal): Promise<void> {\n\treturn new Promise<void>((resolve, reject) => {\n\t\tif (signal?.aborted) {\n\t\t\treject(abortReason(signal, ABORT_MESSAGE));\n\t\t\treturn;\n\t\t}\n\t\tlet onAbort: (() => void) | undefined;\n\t\tconst timer = setTimeout(() => {\n\t\t\tif (onAbort && signal) signal.removeEventListener(\"abort\", onAbort);\n\t\t\tresolve();\n\t\t}, ms);\n\t\tif (signal) {\n\t\t\tonAbort = () => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\treject(abortReason(signal, ABORT_MESSAGE));\n\t\t\t};\n\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t}\n\t});\n}\n\n/**\n * A {@link TransactionScope} that retries its inner scope on transient\n * failures with exponential backoff and jitter. Compose it transparently:\n *\n * ```ts\n * const scope = new RetryingTransactionScope(drizzleScope, { maxAttempts: 5 });\n * const uow = new UnitOfWork({ scope, outbox, repositories });\n * ```\n *\n * **Retries the transaction only.** Each attempt re-invokes the inner\n * `transactional` with a fresh transaction, so the work callback must be\n * reload-safe (load aggregates via `getById` inside it, never capture an\n * aggregate from a previous attempt) and free of non-transactional side\n * effects before commit. `withCommit` publishes AFTER the commit, so the\n * in-process publish is outside the retried region and never duplicated;\n * publish failures are handled by `onPublishError`, not retried here.\n *\n * **Classification is by error, not by guesswork.** Only errors the\n * `isRetryable` predicate accepts are retried; everything else (a\n * `DomainError`, `EventHarvestError`, `UnenrolledChangesError`,\n * `DuplicateAggregateError`, a non-Error throw) surfaces immediately.\n * After `maxAttempts` the last error is rethrown unchanged, so a caller\n * can still match `ConcurrencyConflictError` and map it to HTTP 409.\n *\n * **Cancellation.** The `AbortSignal` from `transactional` options is\n * checked before each attempt and aborts the backoff wait, so an\n * `AbortSignal.timeout(ms)` bounds total elapsed time (there is\n * deliberately no separate max-elapsed knob).\n */\nexport class RetryingTransactionScope<TCtx> implements TransactionScope<TCtx> {\n\t// Policy resolved and validated once at construction (a misconfigured\n\t// policy is a wiring bug and fails fast, never at run time).\n\tprivate readonly maxAttempts: number;\n\tprivate readonly baseDelayMs: number;\n\tprivate readonly maxDelayMs: number;\n\tprivate readonly isRetryable: (error: unknown) => boolean;\n\tprivate readonly sleep: (ms: number, signal?: AbortSignal) => Promise<void>;\n\tprivate readonly random: () => number;\n\tprivate readonly onRetry?: RetryPolicy[\"onRetry\"];\n\n\tconstructor(\n\t\tprivate readonly inner: TransactionScope<TCtx>,\n\t\tpolicy: RetryPolicy = {},\n\t) {\n\t\tthis.maxAttempts = policy.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;\n\t\tthis.baseDelayMs = policy.baseDelayMs ?? DEFAULT_BASE_DELAY_MS;\n\t\tthis.maxDelayMs = policy.maxDelayMs ?? DEFAULT_MAX_DELAY_MS;\n\t\tif (!Number.isInteger(this.maxAttempts) || this.maxAttempts < 1) {\n\t\t\tthrow new Error(\n\t\t\t\t`RetryingTransactionScope: maxAttempts must be an integer >= 1, got ${this.maxAttempts}`,\n\t\t\t);\n\t\t}\n\t\tassertNonNegativeFinite(\"baseDelayMs\", this.baseDelayMs);\n\t\tassertNonNegativeFinite(\"maxDelayMs\", this.maxDelayMs);\n\t\tthis.isRetryable = policy.isRetryable ?? someChainRetryable;\n\t\tthis.sleep = policy.sleep ?? defaultSleep;\n\t\tthis.random = policy.random ?? Math.random;\n\t\tthis.onRetry = policy.onRetry;\n\t}\n\n\tasync transactional<T>(\n\t\tfn: (ctx: TCtx) => Promise<T>,\n\t\toptions?: TransactionalOptions,\n\t): Promise<T> {\n\t\tconst { maxAttempts, isRetryable, sleep } = this;\n\t\tconst signal = options?.signal;\n\n\t\tfor (let attempt = 1; attempt <= maxAttempts; attempt++) {\n\t\t\tif (signal?.aborted) {\n\t\t\t\tthrow abortReason(signal, ABORT_MESSAGE);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn await this.inner.transactional(fn, options);\n\t\t\t} catch (error) {\n\t\t\t\t// Exhausted, or a failure retrying cannot fix: surface it\n\t\t\t\t// unchanged so the caller keeps the original error type.\n\t\t\t\tif (attempt === maxAttempts || !isRetryable(error)) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tconst delayMs = computeBackoffDelay(attempt, {\n\t\t\t\t\tbaseDelayMs: this.baseDelayMs,\n\t\t\t\t\tmaxDelayMs: this.maxDelayMs,\n\t\t\t\t\trandom: this.random,\n\t\t\t\t});\n\t\t\t\t// Observer only: a throwing or async-rejecting onRetry must\n\t\t\t\t// neither abort the retry loop nor mask the original error.\n\t\t\t\treportToObserver(() => this.onRetry?.({ attempt, error, delayMs }));\n\t\t\t\t// An abort during the wait rejects out of the loop with the\n\t\t\t\t// signal reason: cancellation wins over another attempt.\n\t\t\t\tawait sleep(delayMs, signal);\n\t\t\t}\n\t\t}\n\t\t// Unreachable: the loop either returns or throws on the last attempt.\n\t\tthrow new Error(\"RetryingTransactionScope: exhausted without result\");\n\t}\n}\n","import { ValidationError } from \"@shirudo/base-error\";\nimport { err, ok, type Result } from \"@shirudo/result\";\nimport { type VO, vo } from \"../value-object/value-object\";\n\n/**\n * Builds an immutable value object while collecting **all** validation\n * violations into a single {@link ValidationError}, instead of failing on the\n * first one. This is the Result-first, multi-error counterpart to\n * `voWithValidation` (which returns a single string message).\n *\n * The `validate` callback receives a fresh `ValidationError` to push field\n * issues onto (via `addIssue` / `addIssues`) and the raw input. When no issue\n * was recorded the input is frozen into a `VO<T>` and returned as `Ok`;\n * otherwise the populated `ValidationError` is returned as `Err`.\n *\n * `ValidationError` comes from `@shirudo/base-error`; import it from there to\n * narrow the `Err` branch, exactly as `Result` is imported from\n * `@shirudo/result`. It serializes to RFC 9457 Problem Details; use\n * {@link validationProblemDetails} at the HTTP boundary to surface the issues.\n *\n * @example\n * ```ts\n * const result = voValidated(\n * { email, age },\n * (issues, m) => {\n * if (!isEmail(m.email))\n * issues.addIssue({ message: \"must be a valid email\", path: [\"email\"] });\n * if (m.age < 0)\n * issues.addIssue({ message: \"must not be negative\", path: [\"age\"] });\n * },\n * \"Registration is invalid\",\n * );\n * // result.isErr() → result.error.publicIssues() has both violations\n * ```\n */\nexport function voValidated<T>(\n\tt: T,\n\tvalidate: (issues: ValidationError, value: T) => void,\n\tmessage = \"Validation failed\",\n): Result<VO<T>, ValidationError> {\n\tconst issues = new ValidationError(message);\n\tvalidate(issues, t);\n\treturn issues.hasIssues() ? err(issues) : ok(vo(t));\n}\n"]}
1
+ {"version":3,"file":"index.js","names":["capabilities","capabilities","invalid","#snapshot","#evaluating"],"sources":["../src/aggregate/aggregate.ts","../src/entity/entity.ts","../src/aggregate/global-capability-registry.ts","../src/aggregate/pending-event-lifecycle.ts","../src/aggregate/pending-event-recording.ts","../src/aggregate/base-aggregate.ts","../src/aggregate/aggregate-root.ts","../src/aggregate/event-sourced-aggregate.ts","../src/app/bus-internals.ts","../src/app/command-bus.ts","../src/events/json-value.ts","../src/app/command-outbox.ts","../src/app/domain-error-result.ts","../src/utils/abort.ts","../src/utils/validate.ts","../src/utils/execution.ts","../src/utils/observer.ts","../src/app/handler.ts","../src/app/idempotency.ts","../src/app/in-memory-idempotency-store.ts","../src/app/query-bus.ts","../src/app/record-pending-events.ts","../src/repo/identity-map.ts","../src/repo/persistence-model.ts","../src/app/unit-of-work.ts","../src/utils/delivery-failure.ts","../src/utils/backoff.ts","../src/utils/in-flight.ts","../src/utils/sleep.ts","../src/utils/poll-loop.ts","../src/deadlines/deadline-processor.ts","../src/deadlines/in-memory-deadline-store.ts","../src/domain-state-machine/errors.ts","../src/domain-state-machine/machine-data.ts","../src/domain-state-machine/definition.ts","../src/domain-state-machine/snapshot.ts","../src/domain-state-machine/transition.ts","../src/domain-state-machine/analyzer.ts","../src/domain-state-machine/domain-state-machine.ts","../src/events/event-bus.ts","../src/events/integration-message.ts","../src/aggregate/aggregate-address.ts","../src/events/outbox.ts","../src/events/outbox-dispatcher.ts","../src/projections/ports.ts","../src/projections/in-memory-checkpoint-store.ts","../src/projections/projection-from-handlers.ts","../src/projections/projector.ts","../src/repo/in-memory-event-store.ts","../src/repo/in-memory-snapshot-store.ts","../src/repo/retrying-scope.ts","../src/repo/snapshot-model.ts","../src/specification/specification.ts","../src/validation/vo-validated.ts"],"sourcesContent":["import type { Result } from \"@shirudo/result\";\nimport type { DomainError } from \"../core/errors\";\nimport type { Id } from \"../core/id\";\nimport type { AnyDomainEvent, PendingDomainEvent } from \"./domain-event\";\n\n// Re-export domain event types for convenience\nexport * from \"./domain-event\";\n\n// --- Aggregate types ---\n\nexport type Version = number & { readonly __v: true };\n\n/**\n * Snapshot of an aggregate state at a specific point in time.\n * Used for optimizing event replay by starting from a snapshot\n * instead of replaying all events from the beginning.\n *\n * @template TState - The type of the aggregate state\n */\nexport interface AggregateSnapshot<TState> {\n\t/**\n\t * The state of the aggregate at the time of the snapshot.\n\t */\n\treadonly state: TState;\n\n\t/**\n\t * The version of the aggregate when the snapshot was taken.\n\t */\n\treadonly version: Version;\n\n\t/**\n\t * Timestamp when the snapshot was created.\n\t */\n\treadonly snapshotAt: Date;\n\n\t/**\n\t * Schema version of the stored `state` shape, declared by its adapter-owned\n\t * `SnapshotModel` and stamped by `captureAggregateSnapshot`. Distinct from\n\t * {@link version}, which counts mutations: this field says \"which\n\t * shape does the stored state have\", so a restore can detect a\n\t * snapshot written against an older DTO shape and migrate or\n\t * discard it instead of crashing later. Optional: absent on snapshots\n\t * written by older kit versions, which restore treats as schema `1`.\n\t */\n\treadonly schemaVersion?: number;\n}\n\n/**\n * Public contract every Aggregate Root satisfies. Implemented by\n * `BaseAggregate` and inherited by both `AggregateRoot` and\n * `EventSourcedAggregate`. Repository ports use this interface as their\n * aggregate type rather than depending on concrete base classes, so persistence\n * orchestration does not take a compile-time\n * dependency on the aggregate hierarchy.\n *\n * Full per-member documentation lives on the concrete `BaseAggregate`\n * class; the interface is intentionally terse to avoid drift. Persistence\n * facts are readable, but acknowledgement and pending-event disposal are not\n * part of this surface. `withCommit` and `UnitOfWork` hold that authority.\n *\n * @template TId - The aggregate root identifier (branded via `Id<Tag>`)\n * @template TEvent - The domain-event union, defaults to `never`\n */\nexport interface IAggregateRoot<\n\tTId extends Id<string>,\n\tTEvent extends AnyDomainEvent = never,\n> {\n\treadonly id: TId;\n\treadonly version: Version;\n\treadonly pendingEvents: ReadonlyArray<PendingDomainEvent<TEvent>>;\n}\n\n/**\n * Public contract for Event-Sourced Aggregate Roots. Extends\n * `IAggregateRoot` with the replay-from-history boundary.\n *\n * @template TId - The aggregate root identifier\n * @template TEvent - The union type of all domain events\n */\nexport interface IEventSourcedAggregate<\n\tTId extends Id<string>,\n\tTEvent extends AnyDomainEvent,\n> extends IAggregateRoot<TId, TEvent> {\n\t/**\n\t * Reconstitutes the aggregate from an event history. Returns\n\t * `Result` because event-stream corruption is an expected\n\t * recoverable failure at the infrastructure boundary.\n\t */\n\tloadFromHistory(history: ReadonlyArray<TEvent>): Result<void, DomainError>;\n}\n\n/**\n * Checks if two aggregates are at the same version (same ID and version).\n * Useful for optimistic concurrency control checks.\n *\n * Note: Two aggregates with the same ID ARE the same aggregate (identity).\n * This function checks if they are at the same version: i.e., no concurrent modification.\n *\n * @example\n * ```typescript\n * const before = await repository.findById(id);\n * // ... some operations ...\n * const after = await repository.findById(id);\n *\n * if (!sameVersion(before, after)) {\n * throw new Error(\"Aggregate was modified by another process\");\n * }\n * ```\n */\nexport function sameVersion<TId extends Id<string>>(\n\ta: { id: TId; version: Version },\n\tb: { id: TId; version: Version },\n): boolean {\n\treturn a.id === b.id && a.version === b.version;\n}\n","/**\n * Entity utilities and interfaces for Domain-Driven Design.\n *\n * In Domain-Driven Design, there are two types of entities:\n *\n * 1. **Aggregate Root Entity**: The parent Entity of an aggregate.\n * - Has identity (id), state, and version\n * - Implemented by classes extending `AggregateRoot` or `EventSourcedAggregate`\n * - Represents the aggregate externally\n * - Loaded/saved through repositories\n *\n * 2. **Child Entities**: Entities within an aggregate.\n * - Have identity (id) and state, but no own version\n * - Can extend `Entity<TState, TId>` for class-based entities\n * - Or use functional style with `Identifiable<TId> & TProps`\n * - Exist only within the aggregate boundary\n * - Versioned through the Aggregate Root\n * - Cannot be referenced directly from outside the aggregate\n *\n * This module provides:\n * - `Entity<TState, TId>` - Base class for entities with state\n * - `EntityConfig` - Construction options (validation and opt-in deep freeze)\n * - `Identifiable<TId>` - Minimal interface for objects with id\n * - Helper functions for working with collections of entities\n *\n * @example\n * ```typescript\n * // Class-based child entity with logic\n * const validateOrderItemState = (state: OrderItemState): void => {\n * if (state.quantity < 1) throw new Error(\"quantity must be positive\");\n * };\n *\n * class OrderItem extends Entity<OrderItemState, ItemId> {\n * constructor(id: ItemId, initialState: OrderItemState) {\n * super(id, initialState, { validateState: validateOrderItemState });\n * }\n *\n * updateQuantity(quantity: number): void {\n * // setState runs validateState and re-freezes; a direct\n * // `this._state = ...` assignment would skip both.\n * this.setState({ ...this.state, quantity });\n * }\n *\n * calculateSubtotal(): number {\n * return this.state.price * this.state.quantity;\n * }\n * }\n *\n * // Functional-style child entity (simpler, no logic)\n * type OrderItem = Identifiable<ItemId> & {\n * productId: string;\n * quantity: number;\n * price: number;\n * };\n *\n * // Aggregate Root (Entity with version)\n * class Order extends AggregateRoot<OrderState, OrderId> {\n * // Order is an Aggregate Root Entity\n * // OrderState contains OrderItem child entities\n * }\n * ```\n */\nimport { assertNoHostileOwnProtoKey } from \"../core/errors\";\nimport type { Id } from \"../core/id\";\nimport { deepFreeze } from \"../value-object/value-object\";\n\n/** A pure invariant check that throws when a candidate state is invalid. */\nexport type StateValidator<TState> = (state: TState) => void;\n\n/**\n * Construction options shared by `Entity` and (via `AggregateConfig`) the\n * aggregate base classes.\n */\nexport interface EntityConfig<TState = unknown> {\n\t/**\n\t * Pure state-invariant validator captured by the entity instance. It runs\n\t * against the exact frozen state stored during construction and every\n\t * {@link Entity.setState} call. Throw to reject the candidate state.\n\t *\n\t * Passing validation as data avoids virtual dispatch from the base\n\t * constructor: the function cannot observe partly initialised subclass\n\t * fields through `this`. Close over immutable policy supplied to the\n\t * concrete constructor when validation needs instance-specific inputs.\n\t */\n\treadonly validateState?: StateValidator<TState>;\n\n\t/**\n\t * Opt-in: freeze the WHOLE state graph (via `deepFreeze`) instead of\n\t * the default shallow freeze. This protects against nested aliases\n\t * retained by constructor callers and against accidental in-place\n\t * writes inside the entity; live state itself is never public.\n\t *\n\t * Defaults to `false` (the documented shallow contract): deep freezing\n\t * costs a full state-graph walk on every state write, which is why it\n\t * is not the default on hot paths.\n\t *\n\t * **Only for plain-data states.** The deep freeze walks the entire\n\t * graph: a class-based child entity inside the state would be frozen\n\t * too, and its own mutation methods would start throwing. States\n\t * carrying class-based children must keep the default shallow freeze.\n\t * Note that the ownership transfer widens accordingly: nested objects\n\t * passed into the constructor or `setState` are frozen IN PLACE (the\n\t * shallow copy protects only the top-level input object).\n\t */\n\tdeepFreezeState?: boolean;\n}\n\n/**\n * Functional definition of an Entity via its capability: an object is\n * identifiable if it has an `id`.\n *\n * `TId` is constrained to `Id<string>` so the brand discipline that\n * `Id<Tag>` enforces is preserved end-to-end: an `Identifiable<UserId>`\n * cannot accidentally be paired with an `Identifiable<OrderId>` or with\n * a plain `string`.\n */\nexport type Identifiable<TId extends Id<string>> = {\n\treadonly id: TId;\n};\n\n/**\n * Interface for Entities with state.\n *\n * In Domain-Driven Design, Entities have:\n * - Identity (id): Distinguishes one entity from another\n * - State: The attributes/properties of the entity\n *\n * Unlike Value Objects (which are immutable and compared by value),\n * Entities are compared by identity and can have mutable state.\n *\n * @template TId - The type of the entity identifier\n */\nexport interface IEntity<TId extends Id<string>> extends Identifiable<TId> {\n\t/**\n\t * Unique identifier of the entity.\n\t */\n\treadonly id: TId;\n}\n\n/**\n * Abstract base class for Entities with state.\n *\n * Provides:\n * - Identity management (id)\n * - State management\n * - Instance-bound pure state validation\n * - Protected state access for domain behavior\n *\n * This is the foundation for all Entities in DDD:\n * - Child Entities within aggregates can extend this\n * - Aggregate Roots extend this and add version + events\n *\n * @template TState - The type of the entity state\n * @template TId - The type of the entity identifier\n *\n * @example\n * ```typescript\n * // Child Entity within an aggregate\n * const validateOrderItemState = (state: OrderItemState): void => {\n * if (state.quantity < 1) throw new Error(\"quantity must be positive\");\n * };\n *\n * class OrderItem extends Entity<OrderItemState, ItemId> {\n * constructor(id: ItemId, initialState: OrderItemState) {\n * super(id, initialState, { validateState: validateOrderItemState });\n * }\n *\n * updateQuantity(quantity: number): void {\n * // setState runs validateState and re-freezes; a direct\n * // `this._state = ...` assignment would skip both.\n * this.setState({ ...this.state, quantity });\n * }\n * }\n * ```\n */\nexport abstract class Entity<TState, TId extends Id<string>>\n\timplements IEntity<TId>\n{\n\tpublic readonly id: TId;\n\n\t/**\n\t * Returns the live state to subclass domain behavior.\n\t *\n\t * This accessor is deliberately protected: returning the generic\n\t * `TState` publicly would expose the aggregate's live object graph and\n\t * let nested mutation bypass behavior, validation, versioning, and\n\t * dirty tracking. Concrete entities should expose business-meaningful queries or\n\t * detached immutable DTOs. Snapshot projection belongs to an adapter-owned\n\t * `SnapshotModel`; persistence code captures an aggregate with\n\t * `captureAggregateSnapshot(model, aggregate, snapshotAt)` rather than\n\t * asking the entity to create its own persistence memento.\n\t */\n\tprotected get state(): TState {\n\t\treturn this._state;\n\t}\n\n\t/**\n\t * The state is `protected` so that only the subclass can modify it.\n\t * Ordinary entity behavior must use {@link setState}; direct assignment\n\t * skips instance-bound validation. Kit event-sourcing internals use direct\n\t * assignment deliberately because historical evolution must not run\n\t * today's decision validator.\n\t */\n\tprotected _state: TState;\n\n\tprivate readonly _stateFreezeMode: StateFreezeMode;\n\tprivate readonly validateState: StateValidator<TState>;\n\n\t/**\n\t * **State ownership.** Plain-object and array states are shallow-copied\n\t * before the freeze, so the caller's own object stays mutable. A CLASS\n\t * INSTANCE passed as state is an ownership transfer: it is frozen\n\t * in place (a copy would strip its prototype). Do not keep mutating\n\t * the instance after handing it to the entity. The same contract\n\t * applies to {@link setState}. With\n\t * {@link EntityConfig.deepFreezeState} enabled, the ownership transfer\n\t * widens to the whole graph: NESTED objects are frozen in place too.\n\t *\n\t * @throws HostileStateKeyError when a plain-object, null-prototype,\n\t * or array state carries an own `\"__proto__\"` data key; validate and\n\t * strip untrusted input at the boundary.\n\t */\n\tprotected constructor(\n\t\tid: TId,\n\t\tinitialState: TState,\n\t\tconfig?: EntityConfig<TState>,\n\t) {\n\t\tif (id === null || id === undefined) {\n\t\t\tthrow new Error(\"Entity ID cannot be null or undefined\");\n\t\t}\n\t\tthis.id = id;\n\t\tthis._stateFreezeMode = config?.deepFreezeState ?? false ? \"deep\" : \"shallow\";\n\t\tthis.validateState = config?.validateState ?? noStateValidation;\n\t\t// Both mutation paths validate the exact frozen object that is stored.\n\t\t// Assigning the validator as an own property before invoking it also\n\t\t// prevents same-named prototype methods in JavaScript consumers from\n\t\t// turning this constructor call back into virtual dispatch. The module\n\t\t// freeze helper similarly avoids the protected post-construction hook.\n\t\tthis._state = freezeStateByMode(\n\t\t\tshallowCopyOwned(initialState),\n\t\t\tthis._stateFreezeMode,\n\t\t);\n\t\tthis.validateState(this._state);\n\t}\n\n\t/**\n\t * Freezes a state value according to this entity's configured freeze\n\t * mode: the default shallow freeze, or `deepFreeze` when\n\t * {@link EntityConfig.deepFreezeState} was enabled at construction.\n\t * Infrastructure-style subclass code that deliberately assigns\n\t * `this._state` directly must freeze through this method, not\n\t * `freezeShallow`, or the opt-in silently degrades to shallow for that\n\t * path. Ordinary domain behavior should use {@link setState} instead.\n\t */\n\tprotected freezeState(value: TState): TState {\n\t\treturn freezeStateByMode(value, this._stateFreezeMode);\n\t}\n\n\t/**\n\t * Sets the state of the entity.\n\t * This is a convenience method for state mutations.\n\t * Automatically validates `newState` with the instance-bound\n\t * {@link EntityConfig.validateState} function.\n\t *\n\t * Plain-object and array states are shallow-copied before the freeze\n\t * (the caller's object stays mutable); a class-instance state is an\n\t * ownership transfer and is frozen in place; see the constructor.\n\t *\n\t * @param newState - The new state\n\t * @throws HostileStateKeyError when the state carries an own\n\t * `\"__proto__\"` data key; the previous state is kept.\n\t */\n\tprotected setState(newState: TState): void {\n\t\t// Same copy-freeze-validate-assign order as the constructor: the\n\t\t// object validated IS the object stored, and a validation throw\n\t\t// leaves the previous state untouched.\n\t\tconst next = this.freezeState(shallowCopyOwned(newState));\n\t\tthis.validateState(next);\n\t\tthis._state = next;\n\t}\n}\n\nconst noStateValidation: StateValidator<unknown> = () => {};\n\n/** The entity's configured freeze depth, fixed once at construction. */\ntype StateFreezeMode = \"shallow\" | \"deep\";\n\nfunction freezeStateByMode<TState>(\n\tvalue: TState,\n\tmode: StateFreezeMode,\n): TState {\n\treturn mode === \"deep\" ? (deepFreeze(value) as TState) : freezeShallow(value);\n}\n\n/**\n * Shallow-freezes `value` when it's a non-null object or array, so that\n * direct property writes throw in strict mode. Returns the value as-is for\n * primitives. Used internally by `Entity` (via `freezeState`, which picks\n * shallow or deep per the `deepFreezeState` config) to prevent outside\n * mutation of state read through the `state` getter without paying the\n * cost of a deep clone on every read.\n *\n * Subclass code that assigns `this._state` directly should freeze through\n * the protected `freezeState(value)` method rather than calling this\n * helper, so the configured freeze mode is honored. The export remains\n * for consumers using it as a standalone utility.\n */\nexport function freezeShallow<T>(value: T): T {\n\tif (value !== null && typeof value === \"object\") {\n\t\treturn Object.freeze(value);\n\t}\n\treturn value;\n}\n\n/**\n * Returns a shallow copy for plain objects and arrays so the subsequent\n * `freezeShallow` never locks the caller's own object in place (their later\n * writes to it would throw in strict mode). Class instances and primitives\n * pass through unchanged: a spread would strip an instance's prototype,\n * and handing a class instance as state is an ownership transfer. Nested\n * objects stay shared by design (shallow-freeze, no deep clone).\n */\nfunction shallowCopyOwned<T>(value: T): T {\n\tif (value === null || typeof value !== \"object\") return value;\n\tif (Array.isArray(value)) {\n\t\tassertNoHostileOwnProtoKey(value, \"Entity state\");\n\t\t// Spread copies only iterated index elements; transfer own\n\t\t// enumerable NON-INDEX keys (items.total = 5 style annotations) as\n\t\t// data properties too, mirroring the plain-object branch, so the\n\t\t// copy never silently loses caller state.\n\t\tconst copy = [...value];\n\t\tfor (const key of Reflect.ownKeys(value)) {\n\t\t\tif (key === \"length\" || Object.hasOwn(copy, key)) continue;\n\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(value, key);\n\t\t\tif (!descriptor?.enumerable) continue;\n\t\t\tObject.defineProperty(copy, key, {\n\t\t\t\tvalue: (value as Record<PropertyKey, unknown>)[key],\n\t\t\t\twritable: true,\n\t\t\t\tenumerable: true,\n\t\t\t\tconfigurable: true,\n\t\t\t});\n\t\t}\n\t\treturn copy as T;\n\t}\n\tconst proto = Object.getPrototypeOf(value);\n\tif (proto !== Object.prototype && proto !== null) return value;\n\tassertNoHostileOwnProtoKey(value, \"Entity state\");\n\t// Copy as data properties, never through [[Set]]: object spread uses\n\t// CreateDataProperty, so even without the guard above no key could\n\t// reach the `__proto__` setter the way Object.assign onto an\n\t// Object.prototype-based target would. On a null-prototype target no\n\t// setter exists in the chain, so Object.assign is safe there.\n\treturn (\n\t\tproto === null ? Object.assign(Object.create(null), value) : { ...value }\n\t) as T;\n}\n\n/**\n * Checks if two entities have the same ID.\n * Works with any object that has an 'id' property.\n *\n * @param a - First entity\n * @param b - Second entity\n * @returns true if both entities have the same ID, false otherwise\n *\n * @example\n * ```typescript\n * const item1: OrderItem = { id: itemId1, productId: \"prod-1\", quantity: 2 };\n * const item2: OrderItem = { id: itemId2, productId: \"prod-2\", quantity: 1 };\n *\n * sameEntity(item1, item2); // false\n * sameEntity(item1, item1); // true\n * ```\n */\nexport function sameEntity<TId extends Id<string>>(\n\ta: Identifiable<TId>,\n\tb: Identifiable<TId>,\n): boolean {\n\treturn a.id === b.id;\n}\n\n/**\n * Finds an entity by ID in a collection.\n * Returns undefined if not found.\n *\n * @param entities - Array of entities to search\n * @param id - The ID to search for\n * @returns The entity if found, undefined otherwise\n *\n * @example\n * ```typescript\n * const items: OrderItem[] = [\n * { id: itemId1, productId: \"prod-1\", quantity: 2 },\n * { id: itemId2, productId: \"prod-2\", quantity: 1 }\n * ];\n *\n * const item = findEntityById(items, itemId1);\n * // item is { id: itemId1, productId: \"prod-1\", quantity: 2 }\n * ```\n */\nexport function findEntityById<\n\tTId extends Id<string>,\n\tT extends Identifiable<TId>,\n>(entities: ReadonlyArray<T>, id: TId): T | undefined {\n\treturn entities.find((entity) => entity.id === id);\n}\n\n/**\n * Checks if an entity with the given ID exists in the collection.\n *\n * @param entities - Array of entities to search\n * @param id - The ID to check for\n * @returns true if an entity with the ID exists, false otherwise\n *\n * @example\n * ```typescript\n * const items: OrderItem[] = [\n * { id: itemId1, productId: \"prod-1\", quantity: 2 }\n * ];\n *\n * hasEntityId(items, itemId1); // true\n * hasEntityId(items, itemId2); // false\n * ```\n */\nexport function hasEntityId<\n\tTId extends Id<string>,\n\tT extends Identifiable<TId>,\n>(entities: ReadonlyArray<T>, id: TId): boolean {\n\treturn entities.some((entity) => entity.id === id);\n}\n\n/**\n * Removes an entity with the given ID from the collection. Returns the\n * ORIGINAL array when the id is absent (structural sharing for the\n * reference-based dirty tracking; see `updateEntityById`), otherwise a\n * new array without the entity.\n *\n * @param entities - Array of entities\n * @param id - The ID of the entity to remove\n * @returns A new array without the entity with the given ID\n *\n * @example\n * ```typescript\n * const items: OrderItem[] = [\n * { id: itemId1, productId: \"prod-1\", quantity: 2 },\n * { id: itemId2, productId: \"prod-2\", quantity: 1 }\n * ];\n *\n * const updated = removeEntityById(items, itemId1);\n * // updated is [{ id: itemId2, productId: \"prod-2\", quantity: 1 }]\n * ```\n */\nexport function removeEntityById<\n\tTId extends Id<string>,\n\tT extends Identifiable<TId>,\n>(entities: ReadonlyArray<T>, id: TId): ReadonlyArray<T> {\n\tconst filtered = entities.filter((entity) => entity.id !== id);\n\treturn filtered.length === entities.length ? entities : filtered;\n}\n\n/**\n * Updates an entity with the given ID in the collection.\n * Returns a new array with the updated entity.\n * Structural sharing for adapter-owned persistence projections: returns\n * the ORIGINAL array when nothing changed (no match, or the element kept\n * its reference), so a partial-write adapter can skip the untouched\n * collection; a new array only when an\n * element reference actually changed. The result is `ReadonlyArray<T>`:\n * it may BE the (possibly frozen) input; spread it if you need a mutable\n * copy.\n *\n * @param entities - Array of entities\n * @param id - The ID of the entity to update\n * @param updater - Function that takes the entity and returns the updated entity\n * @returns A new array with the updated entity\n *\n * @example\n * ```typescript\n * const items: OrderItem[] = [\n * { id: itemId1, productId: \"prod-1\", quantity: 2 }\n * ];\n *\n * const updated = updateEntityById(items, itemId1, (item) => ({\n * ...item,\n * quantity: item.quantity + 1\n * }));\n * // updated is [{ id: itemId1, productId: \"prod-1\", quantity: 3 }]\n * ```\n */\nexport function updateEntityById<\n\tTId extends Id<string>,\n\tT extends Identifiable<TId>,\n>(\n\tentities: ReadonlyArray<T>,\n\tid: TId,\n\tupdater: (entity: T) => T,\n): ReadonlyArray<T> {\n\tlet changed = false;\n\tconst mapped = entities.map((entity) => {\n\t\tif (entity.id !== id) return entity;\n\t\tconst next = updater(entity);\n\t\tif (next !== entity) changed = true;\n\t\treturn next;\n\t});\n\treturn changed ? mapped : entities;\n}\n\n/**\n * Replaces an entity with the given ID in the collection.\n * Returns a new array with the replaced entity.\n * Structural sharing for adapter-owned persistence projections: returns\n * the ORIGINAL array when nothing changed (no match, or the element kept\n * its reference), so a partial-write adapter can skip the untouched\n * collection; a new array only when an\n * element reference actually changed. The result is `ReadonlyArray<T>`:\n * it may BE the (possibly frozen) input; spread it if you need a mutable\n * copy.\n *\n * @param entities - Array of entities\n * @param id - The ID of the entity to replace\n * @param replacement - The replacement entity\n * @returns A new array with the replaced entity\n *\n * @example\n * ```typescript\n * const items: OrderItem[] = [\n * { id: itemId1, productId: \"prod-1\", quantity: 2 }\n * ];\n *\n * const updated = replaceEntityById(items, itemId1, {\n * id: itemId1,\n * productId: \"prod-1\",\n * quantity: 5\n * });\n * ```\n */\nexport function replaceEntityById<\n\tTId extends Id<string>,\n\tT extends Identifiable<TId>,\n>(entities: ReadonlyArray<T>, id: TId, replacement: T): ReadonlyArray<T> {\n\tlet changed = false;\n\tconst mapped = entities.map((entity) => {\n\t\tif (entity.id !== id) return entity;\n\t\tif (replacement !== entity) changed = true;\n\t\treturn replacement;\n\t});\n\treturn changed ? mapped : entities;\n}\n\n/**\n * Extracts all IDs from a collection of entities.\n *\n * @param entities - Array of entities\n * @returns Array of entity IDs\n *\n * @example\n * ```typescript\n * const items: OrderItem[] = [\n * { id: itemId1, productId: \"prod-1\", quantity: 2 },\n * { id: itemId2, productId: \"prod-2\", quantity: 1 }\n * ];\n *\n * const ids = entityIds(items);\n * // ids is [itemId1, itemId2]\n * ```\n */\nexport function entityIds<TId extends Id<string>, T extends Identifiable<TId>>(\n\tentities: ReadonlyArray<T>,\n): TId[] {\n\treturn entities.map((entity) => entity.id);\n}\n","/**\n * Shared bootstrap for the kit's cross-copy capability registries.\n *\n * A registry is a WeakMap installed once on `globalThis` under a versioned\n * `Symbol.for` key, so aggregates constructed by a bundled plugin copy of\n * the kit cooperate with the host package copy. The key version stamps the\n * capability SHAPE: registrations made under another key stay invisible, so\n * an incompatible copy fails the caller's generic capability check instead\n * of half-working.\n *\n * A registry is not a security boundary against code already running in the\n * same process; it is an architectural boundary kept out of package exports\n * and public aggregate types.\n */\nexport function createGlobalCapabilityRegistry<TCapability extends object>(\n\tkey: symbol,\n): WeakMap<object, TCapability> {\n\tconst existing = Object.getOwnPropertyDescriptor(globalThis, key)?.value;\n\tif (existing instanceof WeakMap) {\n\t\treturn existing as WeakMap<object, TCapability>;\n\t}\n\n\tconst registry = new WeakMap<object, TCapability>();\n\ttry {\n\t\tObject.defineProperty(globalThis, key, {\n\t\t\tvalue: registry,\n\t\t\tenumerable: false,\n\t\t\twritable: false,\n\t\t\tconfigurable: false,\n\t\t});\n\t} catch {\n\t\t// A hardened host may reject global registration. The local registry\n\t\t// still preserves the capability boundary; only duplicate-package\n\t\t// cooperation is unavailable in that host.\n\t}\n\treturn registry;\n}\n","import { createGlobalCapabilityRegistry } from \"./global-capability-registry\";\n\n/**\n * Kit-internal authority for acknowledging one exact pending-event batch.\n *\n * Kept out of every package entry point: repositories may inspect aggregate\n * state and pending events, but only application commit orchestration may\n * acknowledge or discard them after the surrounding transaction commits.\n */\nexport interface PendingEventLifecycleCapability {\n\t/**\n\t * Acknowledges the committed batch. `committedVersion` is the version the\n\t * commit actually persisted (captured at enrollment); the aggregate syncs\n\t * its persisted-version marker from it rather than from its live version,\n\t * so un-awaited concurrent work mutating the instance in the post-commit\n\t * window cannot desync the marker.\n\t */\n\tacknowledge(events: ReadonlyArray<unknown>, committedVersion?: number): void;\n\tdiscardPendingEvents(events: ReadonlyArray<unknown>): void;\n\t/**\n\t * Version the persistence layer last confirmed for the aggregate, or\n\t * `undefined` for a never-persisted instance. Grounds the `withCommit`\n\t * unique-cursor guard.\n\t */\n\tpersistedVersion(): number | undefined;\n\t/**\n\t * Count of unflushed pending events. The public `pendingEvents` getter\n\t * allocates and freezes a defensive copy per read, which count-only\n\t * consumers (the identity map's end-of-run scan) do not need.\n\t */\n\tpendingEventCount(): number;\n}\n\n// The key version stamps the capability SHAPE. Bump it whenever the\n// interface above changes: registrations made under another key stay\n// invisible, so an aggregate constructed by an incompatible package copy\n// fails the generic \"no kit-managed persistence lifecycle\" check instead of\n// half-working through a shape it does not fully implement.\nconst persistenceCapabilityRegistryKey = Symbol.for(\n\t\"@shirudo/ddd-kit/pending-event-lifecycle-registry/v4\",\n);\n\nconst capabilities = createGlobalCapabilityRegistry<PendingEventLifecycleCapability>(\n\tpersistenceCapabilityRegistryKey,\n);\n\nexport function registerPendingEventLifecycleCapability(\n\taggregate: object,\n\tcapability: PendingEventLifecycleCapability,\n): void {\n\tconst frozen = Object.freeze(capability);\n\tcapabilities.set(aggregate, frozen);\n}\n\nexport function pendingEventLifecycleCapabilityFor(\n\taggregate: object,\n): PendingEventLifecycleCapability | undefined {\n\treturn capabilities.get(aggregate);\n}\n","import { createGlobalCapabilityRegistry } from \"./global-capability-registry\";\nimport type {\n\tAnyDomainEvent,\n\tAnyUncommittedDomainEvent,\n\tDomainEventStamp,\n} from \"./domain-event\";\n\nexport type PendingEventStampFactory = (\n\tevent: AnyUncommittedDomainEvent,\n\tindex: number,\n) => DomainEventStamp;\n\nexport interface PendingEventRecordingCapability {\n\treadonly record: (\n\t\tcreateStamp: PendingEventStampFactory,\n\t) => ReadonlyArray<AnyDomainEvent>;\n}\n\n// The key version stamps the capability SHAPE, mirroring\n// pending-event-lifecycle.ts. Bump it whenever the interface above changes:\n// registrations made under another key stay invisible, so an aggregate\n// constructed by an incompatible package copy fails the caller's generic\n// \"created by this package\" check instead of half-working.\nconst recordingCapabilityRegistryKey = Symbol.for(\n\t\"@shirudo/ddd-kit/pending-event-recording-registry/v1\",\n);\n\nconst capabilities = createGlobalCapabilityRegistry<PendingEventRecordingCapability>(\n\trecordingCapabilityRegistryKey,\n);\n\nexport function registerPendingEventRecordingCapability(\n\taggregate: object,\n\tcapability: PendingEventRecordingCapability,\n): void {\n\tcapabilities.set(aggregate, Object.freeze(capability));\n}\n\nexport function pendingEventRecordingCapabilityFor(\n\taggregate: object,\n): PendingEventRecordingCapability | undefined {\n\treturn capabilities.get(aggregate);\n}\n","import {\n\tDuplicateEventIdError,\n\tReentrantEventRecordingError,\n\tUnmintedEventError,\n\tUnreplayableAggregateError,\n} from \"../core/errors\";\nimport type { Id } from \"../core/id\";\nimport { Entity, type EntityConfig } from \"../entity/entity\";\nimport type { IAggregateRoot, Version } from \"./aggregate\";\nimport {\n\ttype AnyDomainEvent,\n\ttype AnyUncommittedDomainEvent,\n\ttype CreateUncommittedDomainEventOptions,\n\tcreateUncommittedDomainEvent,\n\tisMintedEvent,\n\tisUncommittedDomainEvent,\n\ttype PendingDomainEvent,\n\trecordDomainEvent,\n\ttype UncommittedDomainEventOf,\n} from \"./domain-event\";\nimport { registerPendingEventLifecycleCapability } from \"./pending-event-lifecycle\";\nimport { registerPendingEventRecordingCapability } from \"./pending-event-recording\";\n\n/** Construction options shared by state-stored and event-sourced aggregates. */\nexport type AggregateConfig<TState = unknown> = EntityConfig<TState>;\n\n/**\n * Shared base for both `AggregateRoot` (state-stored) and\n * `EventSourcedAggregate`. Carries the lifecycle machinery that's\n * identical across the two flavours: current version, pending-event\n * tracking, the kit-internal post-commit acknowledgement capability,\n * the `markRestored` post-load marker, and the `createEvent` helper\n * that auto-injects `aggregateId` + `aggregateType` on every event the\n * aggregate emits. The application shell records the pending decisions\n * with `recordPendingEvents` before persistence.\n *\n * Consumers do NOT extend this class directly; extend\n * `AggregateRoot` for state-stored aggregates or\n * `EventSourcedAggregate` for event-sourced ones. The split between\n * those two reflects the canonical Vernon §8 (state-stored) /\n * Vernon §11 + Greg Young (event-sourced) distinction in how state\n * is represented; the lifecycle machinery is the same for both.\n *\n * @template TState - The type of the aggregate state\n * @template TId - The aggregate root identifier\n * @template TEvent - The domain-event union. Defaults to `never` so\n * aggregates without a declared event type cannot emit events\n * (emitting any event becomes a compile error).\n */\nexport abstract class BaseAggregate<\n\t\tTState,\n\t\tTId extends Id<string>,\n\t\tTEvent extends AnyDomainEvent = never,\n\t>\n\textends Entity<TState, TId>\n\timplements IAggregateRoot<TId, TEvent>\n{\n\t/**\n\t * The aggregate's domain type as a string, used to populate\n\t * `aggregateType` on events created via {@link createEvent}.\n\t *\n\t * Subclasses MUST declare this as a string literal:\n\t *\n\t * ```ts\n\t * class Order extends AggregateRoot<OrderState, OrderId, OrderEvent> {\n\t * protected readonly aggregateType = \"Order\";\n\t * }\n\t * ```\n\t *\n\t * The string is *the* identifier downstream consumers (outbox\n\t * dispatchers, projection handlers, audit logs) use to route by\n\t * aggregate kind. Use the same canonical name across your system;\n\t * matching the class name is the obvious choice, but the value\n\t * comes from this explicit declaration, not `constructor.name`\n\t * (which is fragile under minification, bundler transforms, and\n\t * subclass renaming).\n\t */\n\tprotected abstract readonly aggregateType: string;\n\n\tprivate _version: Version = 0 as Version;\n\n\t/**\n\t * Version the persistence layer last confirmed for this instance:\n\t * `undefined` until the aggregate is reconstituted (`markRestored`) or a\n\t * commit is acknowledged. Kit-internal via the lifecycle capability; it\n\t * grounds the `withCommit` unique-cursor guard so an eventful commit that\n\t * did not advance beyond the persisted row is rejected deterministically.\n\t */\n\tprivate _persistedVersion: Version | undefined;\n\n\tprivate _pendingEvents: PendingDomainEvent<TEvent>[] = [];\n\n\tprotected constructor(\n\t\tid: TId,\n\t\tinitialState: TState,\n\t\tconfig?: AggregateConfig<TState>,\n\t) {\n\t\tsuper(id, initialState, config);\n\t\tregisterPendingEventLifecycleCapability(this, {\n\t\t\tacknowledge: (events, committedVersion) => {\n\t\t\t\tthis.acknowledgePendingEvents(events, committedVersion);\n\t\t\t},\n\t\t\tdiscardPendingEvents: (events) => {\n\t\t\t\tthis.discardPendingEventsAfterDeletion(events);\n\t\t\t},\n\t\t\tpersistedVersion: () => this._persistedVersion,\n\t\t\tpendingEventCount: () => this._pendingEvents.length,\n\t\t});\n\t\tregisterPendingEventRecordingCapability(this, {\n\t\t\trecord: (createStamp) => {\n\t\t\t\tconst stamped = this._pendingEvents;\n\t\t\t\tconst stampedCount = stamped.length;\n\t\t\t\tconst recorded: TEvent[] = stamped.map((event, index) => {\n\t\t\t\t\tconst candidate = event as AnyDomainEvent | AnyUncommittedDomainEvent;\n\t\t\t\t\tif (isMintedEvent(candidate)) return candidate as TEvent;\n\t\t\t\t\tif (!isUncommittedDomainEvent(candidate)) {\n\t\t\t\t\t\tthrow new UnmintedEventError(\n\t\t\t\t\t\t\t(event as { readonly type: string }).type,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn recordDomainEvent(\n\t\t\t\t\t\tcandidate,\n\t\t\t\t\t\tcreateStamp(candidate, index),\n\t\t\t\t\t) as TEvent;\n\t\t\t\t});\n\t\t\t\t// A stamp provider that triggers a new decision on this aggregate\n\t\t\t\t// grows or replaces the pending list mid-map; assigning `recorded`\n\t\t\t\t// would silently discard that decision. Checked BEFORE the\n\t\t\t\t// assignment, so recording stays atomic when the guard fires.\n\t\t\t\tif (\n\t\t\t\t\tthis._pendingEvents !== stamped ||\n\t\t\t\t\tthis._pendingEvents.length !== stampedCount\n\t\t\t\t) {\n\t\t\t\t\tthrow new ReentrantEventRecordingError(String(this.id));\n\t\t\t\t}\n\t\t\t\t// One identity per decision: a reused stamp would mint two facts\n\t\t\t\t// sharing one eventId, and idempotent consumers keyed on it\n\t\t\t\t// would silently drop one. Also checked before the assignment.\n\t\t\t\tconst seenEventIds = new Set<string>();\n\t\t\t\tfor (const event of recorded) {\n\t\t\t\t\tconst eventId = (event as AnyDomainEvent).eventId;\n\t\t\t\t\tif (seenEventIds.has(eventId)) {\n\t\t\t\t\t\tthrow new DuplicateEventIdError(String(this.id), eventId);\n\t\t\t\t\t}\n\t\t\t\t\tseenEventIds.add(eventId);\n\t\t\t\t}\n\t\t\t\tthis._pendingEvents = recorded;\n\t\t\t\treturn Object.freeze(recorded.slice()) as ReadonlyArray<AnyDomainEvent>;\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate acknowledgePendingEvents(\n\t\tevents: ReadonlyArray<unknown>,\n\t\tcommittedVersion?: number,\n\t): void {\n\t\tthis.stripAcknowledgedPrefix(events);\n\t\t// The next eventful commit needs a cursor beyond the version this\n\t\t// commit persisted. The caller passes the enrollment-time version:\n\t\t// syncing from the live version instead would let un-awaited\n\t\t// concurrent work that mutates the instance in the post-commit window\n\t\t// desync the marker.\n\t\tthis._persistedVersion = (committedVersion ?? this._version) as Version;\n\t}\n\n\t/**\n\t * Post-commit cleanup for the deleted disposition. The row is gone, so\n\t * there is no persisted version to advance: stamping the marker from the\n\t * live instance would make a later legitimate re-enrollment of this\n\t * instance trip the unique-cursor guard for a row that does not exist.\n\t */\n\tprivate discardPendingEventsAfterDeletion(\n\t\tevents: ReadonlyArray<unknown>,\n\t): void {\n\t\tthis.stripAcknowledgedPrefix(events);\n\t}\n\n\tprivate stripAcknowledgedPrefix(events: ReadonlyArray<unknown>): void {\n\t\tif (\n\t\t\tevents.length > this._pendingEvents.length ||\n\t\t\tevents.some((event, index) => event !== this._pendingEvents[index])\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t\"The committed event batch is no longer the aggregate's pending prefix.\",\n\t\t\t);\n\t\t}\n\t\tthis._pendingEvents = this._pendingEvents.slice(events.length);\n\t}\n\n\tpublic get version(): Version {\n\t\treturn this._version;\n\t}\n\n\t/**\n\t * Read-only list of domain events recorded on this aggregate that\n\t * have not yet been flushed to the outbox / persistence layer.\n\t */\n\tpublic get pendingEvents(): ReadonlyArray<PendingDomainEvent<TEvent>> {\n\t\treturn Object.freeze(this._pendingEvents.slice());\n\t}\n\n\t/**\n\t * Count-only accessor for internal aggregate paths: the public\n\t * {@link pendingEvents} getter allocates and freezes\n\t * a defensive copy per read, which a length check does not need.\n\t */\n\tprotected get pendingEventCount(): number {\n\t\treturn this._pendingEvents.length;\n\t}\n\n\tprotected setVersion(version: Version): void {\n\t\tthis._version = version;\n\t}\n\n\t/**\n\t * Manually bumps the aggregate version. Used by state-stored\n\t * aggregates' `setState()` / `commit()` paths and by the\n\t * event-sourced replay path after each applied event.\n\t */\n\tprotected bumpVersion(): void {\n\t\tthis.setVersion((this._version + 1) as Version);\n\t}\n\n\t/**\n\t * **Lifecycle marker, Post-Load.** Syncs both `_version` and\n\t * the current version to the stored version. Used by\n\t * `reconstitute(...)` factories to assemble an in-memory aggregate\n\t * from a persisted row.\n\t *\n\t * The Factory-vs-Reconstitution distinction (Vernon §11) is honoured\n\t * structurally: reconstitution stays inside the aggregate factory while\n\t * post-commit acknowledgement belongs to application commit orchestration.\n\t *\n\t * If you override this, call `super.markRestored(version)` so the current\n\t * domain version remains aligned with the reconstituted facts.\n\t *\n\t * @param version - The version the row currently holds in the DB\n\t *\n\t * @example\n\t * ```ts\n\t * static reconstitute(id: OrderId, state: OrderState, version: Version): Order {\n\t * const order = new Order(id, state);\n\t * order.markRestored(version);\n\t * return order;\n\t * }\n\t * ```\n\t */\n\tprotected markRestored(version: Version): void {\n\t\tthis.setVersion(version);\n\t\tthis._persistedVersion = version;\n\t}\n\n\t/**\n\t * Appends a domain event to the pending list. Prefer the higher-level\n\t * `AggregateRoot.commit()` (state-stored) or `EventSourcedAggregate.apply()`\n\t * (event-sourced) call sites, both of which wrap `addDomainEvent` in the\n\t * canonical record-AFTER-mutation order (Vernon §8). Calling\n\t * `addDomainEvent` directly is appropriate only after a version-advancing\n\t * state mutation, or while constructing a never-persisted aggregate.\n\t * An event-only commit on an already-persisted aggregate has no unique\n\t * cursor and `withCommit` rejects it; use `commit(currentState, event)`.\n\t */\n\tprotected addDomainEvent(event: PendingDomainEvent<TEvent>): void {\n\t\tthis.assertMintedEvent(event);\n\t\tthis._pendingEvents.push(event);\n\t}\n\n\t/**\n\t * Immutability gate for every recording path: only events minted by\n\t * the kit's constructors (`createDomainEvent`,\n\t * `createDomainEventFromFacts`, `createEvent`) pass,\n\t * checked against the constructor's internal, unforgeable mint\n\t * marker. Minted implies deeply frozen with defensively copied\n\t * payload and metadata, a guarantee no frozen-ness probe can\n\t * establish (a shallow-frozen literal with mutable nested data\n\t * would fool it). O(1): one WeakSet lookup.\n\t */\n\tprotected assertMintedEvent(event: PendingDomainEvent<TEvent>): void {\n\t\tif (!isMintedEvent(event) && !isUncommittedDomainEvent(event)) {\n\t\t\tthrow new UnmintedEventError(\n\t\t\t\t(event as AnyDomainEvent | AnyUncommittedDomainEvent).type,\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Creates the immutable business fact accepted by this aggregate without\n\t * reading a clock, generating an id, or attaching tracing metadata.\n\t *\n\t * The application shell records pending events after the domain operation\n\t * and before persistence. Payload schema version stays here, next to the\n\t * concrete event producer, rather than in shell-owned recording data.\n\t */\n\tprotected createEvent<E extends TEvent>(\n\t\ttype: E[\"type\"],\n\t\tpayload: E[\"payload\"],\n\t\toptions?: Omit<\n\t\t\tCreateUncommittedDomainEventOptions,\n\t\t\t\"aggregateId\" | \"aggregateType\"\n\t\t>,\n\t): UncommittedDomainEventOf<E> {\n\t\treturn createUncommittedDomainEvent(type, payload, {\n\t\t\t...options,\n\t\t\taggregateId: this.id,\n\t\t\taggregateType: this.aggregateType,\n\t\t}) as UncommittedDomainEventOf<E>;\n\t}\n}\n\n/**\n * Replay-target guard used by `EventSourcedAggregate.loadFromHistory`: a\n * target carrying unflushed\n * `pendingEvents` throws {@link UnreplayableAggregateError} BEFORE anything\n * moves. Replay advances the aggregate's current version, so unflushed events\n * recorded against the old version would later be\n * harvested claiming a version baseline they were never part of. When the\n * discard is deliberate, discard this dirty instance and reconstitute a\n * fresh aggregate instead of mutating persistence lifecycle state publicly.\n *\n * Deliberately a module-level function, not a class method: it MUST not be\n * overridable by consumer subclasses (a no-op override would silently\n * disable the guard for all three call sites), and it checks the PUBLIC\n * `pendingEvents` getter, the same surface `withCommit` harvests.\n *\n * @internal Shared by the aggregate flavours in this package; not part of\n * the public API.\n */\nexport function assertReplayTargetHasNoPendingEvents(aggregate: {\n\treadonly id: unknown;\n\treadonly pendingEvents: ReadonlyArray<unknown>;\n}): void {\n\tconst pending = aggregate.pendingEvents.length;\n\tif (pending > 0) {\n\t\tthrow new UnreplayableAggregateError(\n\t\t\tString(aggregate.id),\n\t\t\t`it carries ${pending} unflushed pending event(s) that are not ` +\n\t\t\t\t\"part of the persisted stream; discard this dirty instance and \" +\n\t\t\t\t\"reconstitute a fresh aggregate before restoring persisted history\",\n\t\t);\n\t}\n}\n","import type { Id } from \"../core/id\";\nimport { BaseAggregate } from \"./base-aggregate\";\nimport type { AnyDomainEvent, PendingDomainEvent } from \"./domain-event\";\n\nexport type { IAggregateRoot } from \"./aggregate\";\nexport type { AggregateConfig } from \"./base-aggregate\";\n\n/**\n * OO-first Aggregate Root for state-stored domain models.\n *\n * The aggregate owns identity, valid domain state, behavior, its current\n * domain version, and pending domain events. It deliberately does not own a\n * database baseline or dirty-key bookkeeping. A repository adapter defines\n * its persistence projection through `PersistenceModel`; the Unit of Work\n * retains that opaque baseline and derives the adapter's change set at flush.\n */\nexport abstract class AggregateRoot<\n\tTState,\n\tTId extends Id<string>,\n\tTEvent extends AnyDomainEvent = never,\n> extends BaseAggregate<TState, TId, TEvent> {\n\t/**\n\t * Changes state and records the resulting facts in record-after-mutation\n\t * order. Validation and event mint checks run before the transition becomes\n\t * observable, so a rejected decision records nothing.\n\t */\n\tprotected commit(\n\t\tnewState: TState,\n\t\tevents:\n\t\t\t| PendingDomainEvent<TEvent>\n\t\t\t| readonly PendingDomainEvent<TEvent>[] = [],\n\t): void {\n\t\tconst eventBatch: readonly PendingDomainEvent<TEvent>[] = Array.isArray(\n\t\t\tevents,\n\t\t)\n\t\t\t? events\n\t\t\t: [events as PendingDomainEvent<TEvent>];\n\t\tfor (const event of eventBatch) this.assertMintedEvent(event);\n\n\t\tthis.setState(newState);\n\t\tfor (const event of eventBatch) this.addDomainEvent(event);\n\t}\n\n\t/** Every normal domain-state transition advances the OCC version. */\n\tprotected override setState(newState: TState): void {\n\t\tsuper.setState(newState);\n\t\tthis.bumpVersion();\n\t}\n\n\t/**\n\t * Replaces loss-tolerant derived state without advancing the domain version.\n\t *\n\t * This is intentionally loud: concurrent writers may overwrite such a\n\t * change. Keep business facts on the normal `setState`/`commit` path.\n\t */\n\tprotected setStateWithoutVersionBump(newState: TState): void {\n\t\tsuper.setState(newState);\n\t}\n}\n","import { err, ok, type Result } from \"@shirudo/result\";\nimport {\n\tDomainError,\n\tForeignEventError,\n\tMisaddressedEventError,\n\tMissingHandlerError,\n} from \"../core/errors\";\nimport type { Id } from \"../core/id\";\nimport type { IEventSourcedAggregate, Version } from \"./aggregate\";\nimport {\n\tassertReplayTargetHasNoPendingEvents,\n\tBaseAggregate,\n} from \"./base-aggregate\";\nimport {\n\ttype AnyDomainEvent,\n\ttype AnyUncommittedDomainEvent,\n\tadoptMintedEvent,\n\tadoptUncommittedDomainEvent,\n\tisMintedEvent,\n\ttype PendingDomainEvent,\n\ttype UncommittedDomainEventOf,\n} from \"./domain-event\";\n\n// Re-export for backwards compatibility: `IEventSourcedAggregate` lives\n// in `aggregate.ts` (the type hub).\nexport type { IEventSourcedAggregate } from \"./aggregate\";\n\ntype Handler<TState, TEvent> = (state: TState, event: TEvent) => TState;\n\n/**\n * Base class for Event-Sourced Aggregate Roots (Vernon, IDDD Chapter 8).\n *\n * Like `AggregateRoot`, this is both the root entity and the aggregate\n * boundary. The difference is persistence: state is derived from events,\n * not stored directly. Events are the single source of truth: all state\n * changes go through `apply()` → handler.\n *\n * Extends `BaseAggregate` (the shared lifecycle machinery) but does NOT\n * expose `setState()` or `commit()` from `AggregateRoot`. This enforces\n * the event sourcing pattern at the type level: there is no way to\n * mutate state without going through an event handler.\n *\n * `apply()` and `validateEvent()` throw `DomainError`-derived exceptions\n * on invariant violations. Subclasses override `validateEvent()` to\n * throw their own concrete subclasses (e.g. `OrderAlreadyConfirmedError`).\n * Validation guards NEW facts only. Replay through `loadFromHistory` never\n * runs `validateEvent`, because history is already accepted fact and decision\n * rules change over time;\n * a stream that was valid when written must stay loadable under\n * tomorrow's rules. The infrastructure-boundary method `loadFromHistory`\n * returns `Result`: it catches `DomainError` during replay so callers can\n * react to corrupted event streams without try/catch.\n *\n * @template TState - The aggregate state (contains child entities and value objects)\n * @template TEvent - The union type of all domain events\n * @template TId - The aggregate root identifier\n *\n * @example\n * ```typescript\n * class OrderAlreadyConfirmedError extends DomainError<\"ORDER_ALREADY_CONFIRMED\"> {\n * constructor(id: OrderId) {\n * super({ code: \"ORDER_ALREADY_CONFIRMED\", message: `Order ${id} is already confirmed` });\n * }\n * }\n *\n * class Order extends EventSourcedAggregate<OrderState, OrderEvent, OrderId> {\n * protected readonly aggregateType = \"Order\";\n *\n * confirm(): void {\n * this.apply(\n * this.createEvent(\"OrderConfirmed\", { orderId: this.id }),\n * );\n * }\n *\n * protected validateEvent(event: OrderEvent): void {\n * if (event.type === \"OrderConfirmed\" && this.state.status === \"confirmed\") {\n * throw new OrderAlreadyConfirmedError(this.id);\n * }\n * }\n *\n * protected readonly handlers = {\n * OrderConfirmed: (state: OrderState): OrderState => ({\n * ...state,\n * status: \"confirmed\",\n * }),\n * };\n * }\n * ```\n */\nexport abstract class EventSourcedAggregate<\n\t\tTState,\n\t\tTEvent extends AnyDomainEvent,\n\t\tTId extends Id<string>,\n\t>\n\textends BaseAggregate<TState, TId, TEvent>\n\timplements IEventSourcedAggregate<TId, TEvent>\n{\n\t/**\n\t * Validates a NEW event before `apply()` records it. Default is\n\t * no-op. Subclasses override to throw a concrete `DomainError`\n\t * subclass when the event violates an invariant in the current\n\t * state: the second net behind the command method's own guards.\n\t *\n\t * Replay never invokes this method. History is already accepted\n\t * fact, and decision rules evolve; re-checking yesterday's events\n\t * against today's rules would make legitimately persisted streams\n\t * unloadable after a rule change. Old storage shapes are not a\n\t * validation concern either: decode and upcast persisted events at\n\t * the read boundary (see the event-upcasting guide) so handlers\n\t * and replay always receive the current event shape.\n\t */\n\tprotected validateEvent(_event: UncommittedDomainEventOf<TEvent>): void {}\n\n\t/**\n\t * Applies an event: validates, locates the handler, computes the next\n\t * state, then commits state + pending event + version bump atomically.\n\t *\n\t * Throws `DomainError` (or a subclass) on validation failure.\n\t * Throws `MissingHandlerError` if no handler is registered for `event.type`.\n\t * Throws `MisaddressedEventError` (wiring) when the event carries an\n\t * `aggregateId` or `aggregateType` naming a different aggregate;\n\t * missing address fields are stamped from the aggregate instead.\n\t *\n\t * State is not mutated if any step throws: the handler is invoked into\n\t * a local and only assigned to `_state` once all checks pass.\n\t *\n\t * The method is generic in the event tag `K`, so concrete callers\n\t * (`this.apply(orderCreated)`) narrow to the literal tag and the\n\t * dispatched handler is typed as `Handler<TState, Extract<TEvent, { type: K }>>`,\n\t * with no `as` cast required at the call site.\n\t *\n\t * `apply()` is exclusively for NEW facts: it always records the event\n\t * and bumps the version (the former `isNew` flag argument is gone).\n\t * Replaying history is a different operation with its own entry\n\t * point, `loadFromHistory`.\n\t *\n\t * @param event - The domain event to apply\n\t */\n\tprotected apply<K extends TEvent[\"type\"]>(\n\t\tevent: PendingDomainEvent<Extract<TEvent, { type: K }>>,\n\t): void {\n\t\t// New facts get their address here, by construction: missing\n\t\t// fields are stamped from the aggregate (the createEvent\n\t\t// guarantee), a present-but-foreign address throws\n\t\t// MisaddressedEventError before anything is recorded. Without\n\t\t// this, a mis-addressed event would mutate state, version, and\n\t\t// pendingEvents and only fail later at harvest or on the next\n\t\t// load, poisoning the own stream.\n\t\tconst stamped = this.stampNewEventAddress(event);\n\t\t// Validation lives HERE, not in dispatch: only new facts are\n\t\t// checked against current rules; replay trusts history.\n\t\tthis.validateEvent(stamped as UncommittedDomainEventOf<TEvent>);\n\t\tthis.dispatch(stamped);\n\t\tthis.addDomainEvent(stamped);\n\t\tthis.bumpVersion();\n\t}\n\n\t/**\n\t * Address discipline for NEW facts: a present-but-foreign\n\t * `aggregateId` / `aggregateType` is a wiring bug and throws\n\t * {@link MisaddressedEventError}; missing fields are filled in from\n\t * the aggregate, so an applied event is always fully addressed and\n\t * can never fail the harvest or the replay guard later. The\n\t * stamped copy is frozen like the original (payload and metadata\n\t * are shared, already deep-frozen by `createDomainEvent`).\n\t */\n\tprivate stampNewEventAddress<K extends TEvent[\"type\"]>(\n\t\tevent: PendingDomainEvent<Extract<TEvent, { type: K }>>,\n\t): PendingDomainEvent<Extract<TEvent, { type: K }>> {\n\t\t// Immutability first: runs before validate/dispatch so a rejected\n\t\t// event cannot leave mutated state behind (addDomainEvent would\n\t\t// catch it too, but only after the handler already committed).\n\t\tthis.assertMintedEvent(event);\n\t\tconst { aggregateId, aggregateType } = event;\n\t\tconst idForeign = aggregateId !== undefined && aggregateId !== this.id;\n\t\tconst typeForeign =\n\t\t\taggregateType !== undefined && aggregateType !== this.aggregateType;\n\t\tif (idForeign || typeForeign) {\n\t\t\tthrow new MisaddressedEventError(\n\t\t\t\tthis.id,\n\t\t\t\tthis.aggregateType,\n\t\t\t\tevent.type,\n\t\t\t\taggregateId,\n\t\t\t\taggregateType,\n\t\t\t);\n\t\t}\n\t\tif (aggregateId !== undefined && aggregateType !== undefined) {\n\t\t\treturn event;\n\t\t}\n\t\t// The spread preserves the event's structural shape; TS cannot\n\t\t// prove it against the generic Extract, so the copy goes through\n\t\t// the event's own wider type. `aggregateId`/`aggregateType` are\n\t\t// `string | undefined` on DomainEvent; filling them in cannot\n\t\t// leave the declared shape.\n\t\tconst copy = {\n\t\t\t...event,\n\t\t\taggregateId: this.id,\n\t\t\taggregateType: this.aggregateType,\n\t\t};\n\t\tconst stamped: AnyDomainEvent | AnyUncommittedDomainEvent = isMintedEvent(\n\t\t\tevent,\n\t\t)\n\t\t\t? adoptMintedEvent(copy)\n\t\t\t: adoptUncommittedDomainEvent(copy);\n\t\treturn stamped as PendingDomainEvent<Extract<TEvent, { type: K }>>;\n\t}\n\n\t/**\n\t * Internal state-transition path shared by `apply()` and\n\t * `loadFromHistory`:\n\t * locate the handler, commit the next state. It deliberately does\n\t * NOT record the event, bump the version, or run `validateEvent`;\n\t * `apply()` layers all three on for new facts, while replay must not\n\t * (the history is already persisted, and validating it against\n\t * current rules would reject streams that were valid when written).\n\t * The replay loop iterates over `TEvent[]` and therefore cannot\n\t * supply a narrowed `K` generic, so this helper accepts `TEvent`\n\t * and the discriminator is resolved via the (statically-sound)\n\t * `handlers` map.\n\t *\n\t * Replay address check: a history event that names a DIFFERENT\n\t * aggregate id or type is a persisted row that belongs to someone\n\t * else (a miswired stream read, colliding ids across types, a\n\t * corrupted store). Throws `ForeignEventError`, an\n\t * `InfrastructureError`, which PROPAGATES through the replay\n\t * methods (their `Result` channel is reserved for `DomainError`\n\t * stream corruption) after the all-or-nothing rollback. History\n\t * events without the optional address fields pass unchecked (the\n\t * fields are optional on the event shape); NEW events are covered\n\t * by the stricter `stampNewEventAddress` on the apply path.\n\t */\n\tprivate assertReplayedEventBelongsHere(event: TEvent): void {\n\t\tconst idMismatch =\n\t\t\tevent.aggregateId !== undefined && event.aggregateId !== this.id;\n\t\tconst typeMismatch =\n\t\t\tevent.aggregateType !== undefined &&\n\t\t\tevent.aggregateType !== this.aggregateType;\n\t\tif (idMismatch || typeMismatch) {\n\t\t\tthrow new ForeignEventError(\n\t\t\t\tthis.id,\n\t\t\t\tthis.aggregateType,\n\t\t\t\tevent.type,\n\t\t\t\tevent.aggregateId,\n\t\t\t\tevent.aggregateType,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate dispatch(event: TEvent | UncommittedDomainEventOf<TEvent>): void {\n\t\t// Own-key guard: the handlers map is an object literal, so a plain\n\t\t// property get for event.type === \"toString\" / \"constructor\" /\n\t\t// \"__proto__\" (a corrupt or adversarial stream row) would resolve\n\t\t// through Object.prototype and invoke a non-handler.\n\t\tconst handler = Object.hasOwn(this.handlers, event.type)\n\t\t\t? (this.handlers[event.type as keyof typeof this.handlers] as Handler<\n\t\t\t\t\tTState,\n\t\t\t\t\tTEvent | UncommittedDomainEventOf<TEvent>\n\t\t\t\t>)\n\t\t\t: undefined;\n\t\tif (!handler) {\n\t\t\tthrow new MissingHandlerError(event.type);\n\t\t}\n\n\t\tconst nextState = handler(this._state, event);\n\n\t\t// Atomic commit: nothing above this line mutated aggregate state.\n\t\tthis._state = this.freezeState(nextState);\n\t}\n\n\t/**\n\t * Reconstitutes the aggregate from an event history. Catches `DomainError`\n\t * thrown during replay and returns it as an `Err`: this is the\n\t * infrastructure boundary, where event-stream corruption is an expected\n\t * recoverable failure. Unexpected (non-DomainError) throws propagate.\n\t *\n\t * All-or-nothing: if any event mid-stream throws, the aggregate's state\n\t * is rolled back to its pre-call value, the same contract as\n\t * every replay path. Partial replay is never observable.\n\t * (Version needs no rollback: replay goes through `dispatch`, which\n\t * never bumps it; only the final `markRestored` advances it.)\n\t *\n\t * Version advances additively: the aggregate's pre-existing version plus\n\t * `history.length`. A fresh aggregate (v=0) loading 3 events ends at v=3;\n\t * a reconstituted aggregate at v=P catching up on M newer events ends at\n\t * v=P+M.\n\t *\n\t * The replay target must not carry pending decisions. Factory-vs-load\n\t * lifecycle is owned by the Unit of Work rather than inferred from an\n\t * aggregate persistence flag.\n\t */\n\tpublic loadFromHistory(\n\t\thistory: ReadonlyArray<TEvent>,\n\t): Result<void, DomainError> {\n\t\tassertReplayTargetHasNoPendingEvents(this);\n\t\t// Empty stream: nothing was loaded, so preserve current state and version.\n\t\tif (history.length === 0) return ok();\n\n\t\tconst previousState = this._state;\n\t\tconst startVersion = this.version;\n\t\tfor (const event of history) {\n\t\t\ttry {\n\t\t\t\tthis.assertReplayedEventBelongsHere(event);\n\t\t\t\tthis.dispatch(event);\n\t\t\t} catch (e) {\n\t\t\t\tthis._state = previousState;\n\t\t\t\tif (e instanceof DomainError) return err(e);\n\t\t\t\tthrow e;\n\t\t\t}\n\t\t}\n\t\tthis.markRestored((startVersion + history.length) as Version);\n\t\treturn ok();\n\t}\n\n\t/**\n\t * A map of event types to their corresponding handlers.\n\t * Subclasses MUST implement this property.\n\t *\n\t * Handlers MUST fold state from `type` and `payload` only. The\n\t * parameter is typed as the uncommitted shape because a live `apply()`\n\t * dispatches the event BEFORE the shell records it: `eventId` and\n\t * `occurredAt` do not exist yet. Replay dispatches recorded events\n\t * through the same handlers, so those fields ARE present at runtime\n\t * there. A handler that reads them through an escape hatch (`as any`,\n\t * plain JavaScript) folds `undefined` live and a value on replay,\n\t * producing silently divergent state. When a time or identity changes a\n\t * business decision, pass it in the payload.\n\t */\n\tprotected abstract readonly handlers: {\n\t\t[K in TEvent[\"type\"]]: Handler<\n\t\t\tTState,\n\t\t\tUncommittedDomainEventOf<Extract<TEvent, { type: K }>>\n\t\t>;\n\t};\n}\n","import { err, type Result } from \"@shirudo/result\";\nimport {\n\tDuplicateHandlerRegistrationError,\n\tErrorMapperFailedError,\n\tUnregisteredHandlerError,\n} from \"../core/errors\";\n\n/**\n * INTERNAL shared pieces of `CommandBus` and `QueryBus`. The two buses are\n * deliberately separate public classes (distinct docs, distinct handler\n * types), but their wiring semantics must not drift: the expected-error\n * decision shape, register-once guard, no-handler gate, and handler-failure\n * classification live here exactly once. Not exported from any package entry.\n */\n\n/**\n * A positive classification decision from a bus's expected-error mapper.\n * The wrapper makes `undefined` a valid error-channel value without making\n * it ambiguous with the mapper declining to classify a thrown value.\n */\nexport interface ExpectedErrorDecision<E> {\n\treadonly error: E;\n}\n\n/**\n * Classifies and maps one handler throw. Returning `undefined` declines the\n * failure, which makes the bus rethrow the exact original value.\n */\nexport type ExpectedErrorMapper<E> = (\n\tthrown: unknown,\n) => ExpectedErrorDecision<E> | undefined;\n\n/**\n * Keeps manual result typing available only for the deliberately untyped\n * default map. Concrete maps, typed or refined index maps, and `any` keep their\n * mapped result contract authoritative.\n */\nexport type UntypedMapDispatch<\n\tTMap extends Record<string, unknown>,\n\tTMessage,\n> = 0 extends 1 & TMap\n\t? never\n\t: string extends keyof TMap\n\t\t? Record<string, unknown> extends TMap\n\t\t\t? TMessage\n\t\t\t: never\n\t\t: never;\n\n/**\n * Registers a handler exactly once. Silent replacement would turn the first\n * handler into dead code with no signal; wiring bugs must surface at\n * registration time.\n */\nexport function registerOnce<THandler>(\n\thandlers: Map<string, THandler>,\n\tbusKind: \"command\" | \"query\",\n\ttype: string,\n\thandler: THandler,\n): void {\n\tif (handlers.has(type)) {\n\t\tthrow new DuplicateHandlerRegistrationError({\n\t\t\tbusKind,\n\t\t\tmessageType: type,\n\t\t});\n\t}\n\thandlers.set(type, handler);\n}\n\n/**\n * Shared no-handler gate for dispatch: a wiring bug throws\n * `UnregisteredHandlerError` (crash-loud, same posture as\n * `MissingHandlerError`), it never rides the error channel. One\n * implementation so the buses and their unsafe paths cannot drift.\n */\nexport function handlerOrThrow<THandler>(\n\thandlers: Map<string, THandler>,\n\tbusKind: \"command\" | \"query\",\n\ttype: string,\n): THandler {\n\tconst handler = handlers.get(type);\n\tif (!handler) {\n\t\tthrow new UnregisteredHandlerError({ busKind, messageType: type });\n\t}\n\treturn handler;\n}\n\n/**\n * Classifies one registered handler failure. Absence of a mapper or an\n * `undefined` decision preserves and rethrows the exact failure: unknown\n * programmer, cancellation, and infrastructure errors cannot silently ride\n * a Result channel. A nested dispatch's wiring error always bypasses the\n * policy. A mapper that throws or returns a malformed decision is itself a\n * wiring bug and is wrapped without losing either cause.\n */\nexport function mapHandlerFailure<E>(\n\terror: unknown,\n\tmapExpectedError: ExpectedErrorMapper<E> | undefined,\n\tbusKind: \"command\" | \"query\",\n): Result<never, E> {\n\tif (\n\t\terror instanceof UnregisteredHandlerError ||\n\t\terror instanceof ErrorMapperFailedError\n\t) {\n\t\tthrow error;\n\t}\n\tif (!mapExpectedError) throw error;\n\n\tlet decision: ExpectedErrorDecision<E> | undefined;\n\ttry {\n\t\tdecision = mapExpectedError(error);\n\t} catch (mapperError) {\n\t\tthrow new ErrorMapperFailedError({\n\t\t\tbusKind,\n\t\t\thandlerError: error,\n\t\t\tmapperError,\n\t\t});\n\t}\n\tif (decision === undefined) throw error;\n\n\tlet mapped: E;\n\ttry {\n\t\tconst candidate: unknown = decision;\n\t\tif (\n\t\t\ttypeof candidate !== \"object\" ||\n\t\t\tcandidate === null ||\n\t\t\t!Object.hasOwn(candidate, \"error\")\n\t\t) {\n\t\t\tthrow new TypeError(\n\t\t\t\t\"mapExpectedError must return undefined or an own { error } decision\",\n\t\t\t);\n\t\t}\n\t\tmapped = (candidate as ExpectedErrorDecision<E>).error;\n\t} catch (mapperError) {\n\t\tthrow new ErrorMapperFailedError({\n\t\t\tbusKind,\n\t\t\thandlerError: error,\n\t\t\tmapperError,\n\t\t});\n\t}\n\treturn err(mapped);\n}\n","import type { Result } from \"@shirudo/result\";\nimport {\n\ttype ExpectedErrorMapper,\n\thandlerOrThrow,\n\tmapHandlerFailure,\n\tregisterOnce,\n\ttype UntypedMapDispatch,\n} from \"./bus-internals\";\nimport type { Command, CommandHandler } from \"./command\";\n\n/**\n * Internal adapter shape for handlers stored in the map.\n *\n * Registered handlers are typed as `CommandHandler<C, TMap[K]>` (narrower\n * input, specific return) and cannot be stored directly in a heterogeneous\n * map (function-parameter contravariance). The closure in `register`\n * downcasts `Command` to the handler's expected `C` based on the\n * dispatch-key invariant (we only call this entry when `cmd.type` matches\n * the key it was registered under). Result is widened to `unknown` here\n * and narrowed back via the public overloads on `execute`.\n */\ntype StoredCommandHandler<E> = (cmd: Command) => Promise<Result<unknown, E>>;\n\n/**\n * Type map for command types to their return types.\n * Used to improve type inference in CommandBus.\n *\n * @example\n * ```typescript\n * type MyCommandMap = {\n * CreateOrder: OrderId;\n * CancelOrder: void;\n * };\n *\n * const bus = new CommandBus<MyCommandMap>();\n * const result = await bus.execute({ type: \"CreateOrder\", ... });\n * // result: Result<OrderId, string> ← automatically inferred\n * ```\n */\ntype CommandTypeMap = Record<string, unknown>;\n\n/**\n * Construction options for {@link CommandBus}.\n *\n * @template E - The error channel type of the bus.\n */\nexport interface CommandBusOptions<E = string> {\n\t/**\n\t * Explicitly recognizes an expected handler failure and maps it into the\n\t * bus's error channel. Return `{ error }` only for failures this boundary\n\t * owns; return `undefined` to rethrow the exact original value. With no\n\t * mapper, every handler throw propagates. Unregistered-handler and nested\n\t * bus wiring errors always propagate.\n\t */\n\tmapExpectedError?: (thrown: unknown) => { readonly error: E } | undefined;\n}\n\n/**\n * Command Bus interface for dispatching commands to their handlers.\n * Provides a centralized way to execute commands with handler registration.\n *\n * Supports an optional type map (`TMap`) for automatic return type inference.\n * Without a type map, the return type must be specified manually or defaults to `unknown`.\n * With a concrete result map, its entry is the only result type for that\n * command; the loose explicit-result overload is unavailable.\n *\n * @template TMap - Optional mapping from command type strings to return types\n *\n * @example\n * ```typescript\n * // With a type map (recommended): the return type is inferred\n * type MyCommands = { CreateOrder: OrderId; CancelOrder: void };\n * const bus = new CommandBus<MyCommands>();\n * const result = await bus.execute({ type: \"CreateOrder\", ... });\n * // result: Result<OrderId, string>\n *\n * // Without a type map: the return type defaults to `unknown`\n * const bus = new CommandBus();\n * bus.register(\"CreateOrder\", createOrderHandler);\n * const result = await bus.execute({ type: \"CreateOrder\", ... });\n * // result: Result<unknown, string>\n * ```\n */\nexport interface ICommandBus<\n\tTMap extends CommandTypeMap = CommandTypeMap,\n\tE = string,\n> {\n\t/**\n\t * Executes a command by dispatching it to the registered handler.\n\t * When a type map is provided, the return type is inferred from the command type.\n\t *\n\t * @param command - The command to execute\n\t * @returns Result containing the success value or an error of type `E`\n\t * @throws UnregisteredHandlerError when no handler is registered for\n\t * `command.type` (a wiring bug; never delivered through the channel)\n\t * @throws The exact handler failure when `mapExpectedError` is absent or\n\t * returns `undefined`\n\t * @throws ErrorMapperFailedError when `mapExpectedError` fails\n\t */\n\texecute<C extends Command & { type: keyof TMap & string }>(\n\t\tcommand: C,\n\t): Promise<Result<TMap[C[\"type\"]], E>>;\n\t// Manual result typing belongs only to the default untyped map shape.\n\texecute<C extends Command, R>(\n\t\tcommand: UntypedMapDispatch<TMap, C>,\n\t): Promise<Result<R, E>>;\n\n\t/**\n\t * Registers a handler for a specific command type.\n\t *\n\t * When `TMap` is supplied, the `commandType` argument is restricted to\n\t * its keys and the handler signature is forced to match `TMap[K]` for the\n\t * return value: typos and wrong-typed handlers are compile errors.\n\t * Without `TMap` the registration is loose (any string key, any return\n\t * type) so the no-config path keeps working.\n\t *\n\t * @param commandType - The command type to register the handler for\n\t * @param handler - The handler function for this command type\n\t */\n\tregister<\n\t\tK extends keyof TMap & string,\n\t\tC extends Command & { type: K } = Command & { type: K },\n\t>(commandType: K, handler: CommandHandler<C, TMap[K], E>): void;\n}\n\n/**\n * Simple in-memory command bus implementation.\n * Handlers are stored in a Map and dispatched based on command type.\n *\n * Supports an optional type map (`TMap`) for automatic return type inference.\n * When `TMap` is concrete, `execute()` infers the result type from the command type.\n * An explicit competing result generic cannot override that map.\n * Without `TMap`, the return type defaults to `unknown` or is specified per call.\n *\n * **Note:** This is a basic implementation suitable for development and simple use cases.\n * For production environments, consider implementing or using a more feature-rich bus that includes:\n * - Middleware/Pipeline support (logging, validation, authorization)\n * - Error handling and retry logic\n * - Timeout handling\n * - Metrics and observability\n * - Transaction management\n * - Dead letter queue support\n *\n * The `CommandHandler` type can still be used with external production-grade buses\n * (e.g., RabbitMQ, AWS SQS) while maintaining type safety.\n *\n * @template TMap - Optional mapping from command type strings to return types\n *\n * @example\n * ```typescript\n * // With a type map: full inference\n * type Commands = { CreateOrder: OrderId; CancelOrder: void };\n * const bus = new CommandBus<Commands>();\n * const result = await bus.execute({ type: \"CreateOrder\", ... });\n * // result: Result<OrderId, string>\n *\n * // Without a type map: specify the return type per call\n * const bus = new CommandBus();\n * bus.register(\"CreateOrder\", async (cmd) => ok(orderId));\n * const result = await bus.execute({ type: \"CreateOrder\", ... });\n * ```\n */\nexport class CommandBus<\n\tTMap extends CommandTypeMap = CommandTypeMap,\n\tE = string,\n> implements ICommandBus<TMap, E>\n{\n\tprivate readonly handlers = new Map<string, StoredCommandHandler<E>>();\n\tprivate readonly mapExpectedError: ExpectedErrorMapper<E> | undefined;\n\n\tconstructor(options?: CommandBusOptions<E>) {\n\t\tthis.mapExpectedError = options?.mapExpectedError;\n\t}\n\n\tregister<\n\t\tK extends keyof TMap & string,\n\t\tC extends Command & { type: K } = Command & { type: K },\n\t>(commandType: K, handler: CommandHandler<C, TMap[K], E>): void {\n\t\tregisterOnce(this.handlers, \"command\", commandType, (cmd: Command) =>\n\t\t\thandler(cmd as C),\n\t\t);\n\t}\n\n\tasync execute<C extends Command & { type: keyof TMap & string }>(\n\t\tcommand: C,\n\t): Promise<Result<TMap[C[\"type\"]], E>>;\n\t// Keep the class surface identical to ICommandBus's untyped fallback.\n\tasync execute<C extends Command, R>(\n\t\tcommand: UntypedMapDispatch<TMap, C>,\n\t): Promise<Result<R, E>>;\n\tasync execute<C extends Command, R>(command: C): Promise<Result<R, E>> {\n\t\t// No-handler dispatch is a wiring bug, not a domain failure: thrown,\n\t\t// never delivered through the error channel (see handlerOrThrow).\n\t\tconst handler = handlerOrThrow(this.handlers, \"command\", command.type);\n\t\ttry {\n\t\t\treturn (await handler(command)) as Result<R, E>;\n\t\t} catch (error) {\n\t\t\treturn mapHandlerFailure(error, this.mapExpectedError, \"command\");\n\t\t}\n\t}\n}\n","/** A primitive value represented without loss by JSON. */\nexport type JsonPrimitive = boolean | null | number | string;\n\n/** A recursively JSON-safe value. Runtime validation rejects lossy shapes. */\nexport type JsonValue =\n\t| JsonPrimitive\n\t| ReadonlyArray<JsonValue>\n\t| { readonly [key: string]: JsonValue };\n\n/** A JSON-safe object. */\nexport type JsonObject = { readonly [key: string]: JsonValue };\n\n/** Non-null, non-array object shape check shared by the message boundaries. */\nexport function isJsonObject(value: unknown): value is JsonObject {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\ntype InvalidJsonValue = (path: string, reason: string) => never;\n\n/**\n * Proves that JSON serialization preserves a value exactly.\n *\n * The caller owns the boundary-specific error type through `invalid`.\n */\nexport function assertJsonValue(\n\tvalue: unknown,\n\tpath: string,\n\tinvalid: InvalidJsonValue,\n\tactive = new WeakSet<object>(),\n): asserts value is JsonValue {\n\tif (value === null) return;\n\tswitch (typeof value) {\n\t\tcase \"string\":\n\t\tcase \"boolean\":\n\t\t\treturn;\n\t\tcase \"number\":\n\t\t\tif (!Number.isFinite(value)) {\n\t\t\t\treturn invalid(path, \"numbers must be finite JSON numbers\");\n\t\t\t}\n\t\t\t// JSON.stringify(-0) produces \"0\", so negative zero does not\n\t\t\t// round-trip; rejecting it keeps the exactness contract honest.\n\t\t\tif (Object.is(value, -0)) {\n\t\t\t\treturn invalid(path, \"negative zero changes to 0 in JSON\");\n\t\t\t}\n\t\t\treturn;\n\t\tcase \"object\":\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tinvalid(path, `value of type ${typeof value} is not JSON-safe`);\n\t}\n\n\tif (active.has(value)) {\n\t\tinvalid(path, \"cyclic references are not JSON-safe\");\n\t}\n\tactive.add(value);\n\tif (Array.isArray(value)) {\n\t\tfor (const key of Reflect.ownKeys(value)) {\n\t\t\tif (key === \"length\") continue;\n\t\t\tif (typeof key === \"symbol\") {\n\t\t\t\tinvalid(path, \"symbol-keyed array properties would be dropped by JSON\");\n\t\t\t}\n\t\t\tconst index = Number(key);\n\t\t\tif (\n\t\t\t\t!Number.isInteger(index) ||\n\t\t\t\tindex < 0 ||\n\t\t\t\tindex >= value.length ||\n\t\t\t\tString(index) !== key\n\t\t\t) {\n\t\t\t\tinvalid(\n\t\t\t\t\t`${path}.${key}`,\n\t\t\t\t\t\"named array properties would be dropped by JSON\",\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tfor (let index = 0; index < value.length; index += 1) {\n\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(value, index);\n\t\t\tif (descriptor === undefined) {\n\t\t\t\tinvalid(\n\t\t\t\t\t`${path}[${index}]`,\n\t\t\t\t\t\"sparse array holes would change to null in JSON\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (!(\"value\" in descriptor) || !descriptor.enumerable) {\n\t\t\t\tinvalid(\n\t\t\t\t\t`${path}[${index}]`,\n\t\t\t\t\t\"accessor and non-enumerable array elements are not JSON-safe\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tassertJsonValue(descriptor.value, `${path}[${index}]`, invalid, active);\n\t\t}\n\t\tactive.delete(value);\n\t\treturn;\n\t}\n\n\tconst prototype = Object.getPrototypeOf(value);\n\tif (prototype !== Object.prototype && prototype !== null) {\n\t\tinvalid(\n\t\t\tpath,\n\t\t\t\"Date, Map, Set, and class instances are not JSON-safe here; map \" +\n\t\t\t\t\"them explicitly to strings, arrays, or plain objects\",\n\t\t);\n\t}\n\tfor (const key of Reflect.ownKeys(value)) {\n\t\tif (typeof key === \"symbol\") {\n\t\t\tinvalid(path, \"symbol-keyed properties would be dropped by JSON\");\n\t\t}\n\t\tconst descriptor = Object.getOwnPropertyDescriptor(value, key);\n\t\tif (descriptor === undefined) continue;\n\t\tconst childPath = `${path}.${key}`;\n\t\tif (key === \"__proto__\") {\n\t\t\tinvalid(\n\t\t\t\tchildPath,\n\t\t\t\t\"hostile __proto__ keys are not accepted at integration boundaries\",\n\t\t\t);\n\t\t}\n\t\tif (!(\"value\" in descriptor) || !descriptor.enumerable) {\n\t\t\tinvalid(\n\t\t\t\tchildPath,\n\t\t\t\t\"accessor and non-enumerable properties are not JSON-safe\",\n\t\t\t);\n\t\t}\n\t\tassertJsonValue(descriptor.value, childPath, invalid, active);\n\t}\n\tactive.delete(value);\n}\n","import type { AggregateAddress } from \"../aggregate/aggregate-address\";\nimport type { AnyDomainEvent } from \"../aggregate/domain-event\";\nimport { InvalidCommandMessageError } from \"../core/errors\";\nimport {\n\tassertJsonValue,\n\tisJsonObject,\n\ttype JsonObject,\n} from \"../events/json-value\";\nimport type {\n\tEventCommitCandidate,\n\tEventCommitCandidatePosition,\n\tOutboxWriter,\n} from \"../events/ports\";\nimport { deepFreeze } from \"../value-object/value-object\";\nimport type { PublishedCommand } from \"./command\";\n\n/**\n * Business relationships and technical trace context selected explicitly for\n * an outgoing command. Correlation/conversation explain the business flow;\n * W3C Trace Context connects technical spans.\n */\nexport interface CommandMessageRelationships {\n\t/** Groups messages that belong to one operation or trace. */\n\treadonly correlationId?: string;\n\t/** Groups every message in one long-running business interaction. */\n\treadonly conversationId?: string;\n\t/** W3C Trace Context parent for technical distributed tracing. */\n\treadonly traceparent?: string;\n\t/** Optional vendor trace state associated with `traceparent`. */\n\treadonly tracestate?: string;\n}\n\n/**\n * Application-owned Published Language produced from one private domain or\n * process event. `destination` names one receiver contract; it is deliberately\n * required because a command is an instruction, not a broadcast fact.\n *\n * The command carries a stable schema `version` and JSON-safe `payload`.\n * Domain value objects are translated to wire DTOs by the mapper before this\n * boundary.\n */\nexport interface CommandMessageContent<C extends PublishedCommand>\n\textends CommandMessageRelationships {\n\treadonly destination: string;\n\treadonly command: C;\n}\n\n/**\n * Immutable, JSON-safe command envelope stored for later at-least-once\n * delivery.\n *\n * `causationId` always identifies the private event whose accepted decision\n * requested this command. The mapper cannot replace it with a weaker\n * correlation. Consumer-produced events should in turn use `messageId` as\n * their causation id.\n */\nexport interface DurableCommandMessage<C extends PublishedCommand>\n\textends CommandMessageContent<C> {\n\treadonly messageId: string;\n\treadonly recordedAt: string;\n\treadonly causationId: string;\n}\n\n/**\n * Receipt for the private event that requested one command batch. It retains\n * commit identity and ordering without putting the private event or its\n * payload into the command outbox.\n */\nexport interface CommandCommitOriginCandidate {\n\treadonly eventId: string;\n\treadonly source: AggregateAddress;\n\treadonly position: EventCommitCandidatePosition;\n}\n\n/**\n * One private process-event commit and the exact commands it requested.\n * `messages` may be empty: the receipt still advances the originating source\n * and makes an exact retry distinguishable from a missing commit.\n */\nexport interface CommandOutboxCommitCandidate<C extends PublishedCommand> {\n\treadonly origin: CommandCommitOriginCandidate;\n\treadonly messages: ReadonlyArray<DurableCommandMessage<C>>;\n}\n\n/**\n * Write port for a dedicated transactional command outbox.\n *\n * The adapter is bound to the same ambient transaction as the aggregate or\n * event-stream repository. It must persist the complete input atomically,\n * retain input order, deduplicate exact retries by `origin.eventId`, and reject\n * a reused origin id whose source, position, or messages differ. It also owns\n * the durable source cursor represented by `origin.position`; an empty command\n * batch still advances that cursor.\n *\n * Delivery is out of band and at least once. A consumer therefore uses\n * `message.messageId` as its idempotency key and acknowledges only after the\n * command result has been stored.\n */\nexport interface CommandOutboxWriter<C extends PublishedCommand> {\n\tadd(commits: ReadonlyArray<CommandOutboxCommitCandidate<C>>): Promise<void>;\n}\n\n/** Maps one private accepted event to zero or more addressed commands. */\nexport type CommandOutboxMapper<\n\tEvt extends AnyDomainEvent,\n\tC extends PublishedCommand,\n> = (event: Evt) => ReadonlyArray<CommandMessageContent<C>>;\n\n/**\n * Adapts a dedicated command outbox to the event-candidate write port consumed\n * by `withCommit`.\n *\n * Mapping happens inside the transaction, before the command outbox write.\n * The private event is used only at this boundary and is reduced to an origin\n * receipt. The helper never publishes it or copies its payload implicitly; the\n * application mapper selects and translates the data that belongs in the\n * versioned Published Language. The route rejects values JSON would lose or\n * change before it calls the adapter.\n * Every command gets a stable id derived from the event id and its zero-based\n * order, so an exact transaction retry produces the same rows.\n *\n * Omit `withCommit`'s in-process `bus` for private process events. Participants\n * consume the durable command messages from their explicitly named\n * destinations, while event-stream replay only rebuilds process state.\n */\nexport function routeEventsToCommandOutbox<\n\tC extends PublishedCommand,\n\tEvt extends AnyDomainEvent = AnyDomainEvent,\n>(\n\toutbox: CommandOutboxWriter<C>,\n\tmapper: CommandOutboxMapper<Evt, C>,\n): OutboxWriter<Evt> {\n\treturn {\n\t\tadd: async (events) => {\n\t\t\tconst commits = events.map((candidate) =>\n\t\t\t\ttoCommandCommit(candidate, mapper),\n\t\t\t);\n\t\t\tawait outbox.add(commits);\n\t\t},\n\t};\n}\n\nfunction toCommandCommit<\n\tEvt extends AnyDomainEvent,\n\tC extends PublishedCommand,\n>(\n\tcandidate: EventCommitCandidate<Evt>,\n\tmapper: CommandOutboxMapper<Evt, C>,\n): CommandOutboxCommitCandidate<C> {\n\tconst mapped = mapper(candidate.event);\n\tif (!Array.isArray(mapped)) {\n\t\tthrow new TypeError(\n\t\t\t\"Command outbox mapper must return a readonly array of commands\",\n\t\t);\n\t}\n\tconst messages = Array.from(mapped, (content, index) =>\n\t\ttoDurableCommand<C>(candidate.event, content, index),\n\t);\n\treturn deepFreeze({\n\t\torigin: {\n\t\t\teventId: candidate.event.eventId,\n\t\t\tsource: { ...candidate.source },\n\t\t\tposition: { ...candidate.position },\n\t\t},\n\t\tmessages,\n\t}) as CommandOutboxCommitCandidate<C>;\n}\n\nfunction toDurableCommand<C extends PublishedCommand>(\n\tevent: AnyDomainEvent,\n\tcontent: CommandMessageContent<C>,\n\tindex: number,\n): DurableCommandMessage<C> {\n\tif (\n\t\tcontent === null ||\n\t\ttypeof content !== \"object\" ||\n\t\tArray.isArray(content)\n\t) {\n\t\tthrow new TypeError(\"Command outbox mapper entry must be an object\");\n\t}\n\tconst {\n\t\tdestination,\n\t\tcommand: sourceCommand,\n\t\tcorrelationId,\n\t\tconversationId,\n\t\ttraceparent,\n\t\ttracestate,\n\t} = content;\n\tassertNonBlank(\"destination\", destination);\n\tif (\n\t\tsourceCommand === null ||\n\t\ttypeof sourceCommand !== \"object\" ||\n\t\tArray.isArray(sourceCommand)\n\t) {\n\t\tthrow new TypeError(\"Command outbox command must be an object\");\n\t}\n\tassertPublishedCommand(sourceCommand);\n\tassertOptionalNonBlank(\"correlationId\", correlationId);\n\tassertOptionalNonBlank(\"conversationId\", conversationId);\n\tassertTraceContext(traceparent, tracestate);\n\n\tconst command = JSON.parse(JSON.stringify(sourceCommand)) as C;\n\treturn deepFreeze({\n\t\tmessageId: `${event.eventId}:command:${index}`,\n\t\trecordedAt: event.occurredAt.toISOString(),\n\t\tdestination,\n\t\tcommand,\n\t\t...(correlationId === undefined ? {} : { correlationId }),\n\t\t...(conversationId === undefined ? {} : { conversationId }),\n\t\t...(traceparent === undefined ? {} : { traceparent }),\n\t\t...(tracestate === undefined ? {} : { tracestate }),\n\t\tcausationId: event.eventId,\n\t}) as DurableCommandMessage<C>;\n}\n\nfunction assertNonBlank(\n\tfield: string,\n\tvalue: unknown,\n): asserts value is string {\n\tif (typeof value !== \"string\" || value.trim().length === 0) {\n\t\tinvalid(`$.${field}`, \"must be a non-blank string\");\n\t}\n}\n\nfunction assertOptionalNonBlank(field: string, value: unknown): void {\n\tif (value !== undefined) assertNonBlank(field, value);\n}\n\nfunction assertPublishedCommand(\n\tvalue: unknown,\n): asserts value is PublishedCommand {\n\tassertJsonValue(value, \"$.command\", invalid);\n\tif (!isJsonObject(value)) {\n\t\tinvalid(\"$.command\", \"must be a plain JSON object\");\n\t}\n\tfor (const key of Object.keys(value)) {\n\t\tif (key !== \"type\" && key !== \"version\" && key !== \"payload\") {\n\t\t\tinvalid(\n\t\t\t\t`$.command.${key}`,\n\t\t\t\t\"is not part of the published command schema\",\n\t\t\t);\n\t\t}\n\t}\n\tassertNonBlank(\"command.type\", value.type);\n\tif (\n\t\ttypeof value.version !== \"number\" ||\n\t\t!Number.isInteger(value.version) ||\n\t\tvalue.version < 1\n\t) {\n\t\tinvalid(\"$.command.version\", \"must be an integer >= 1\");\n\t}\n\tif (!Object.hasOwn(value, \"payload\")) {\n\t\tinvalid(\"$.command.payload\", \"is required (use null for an empty payload)\");\n\t}\n}\n\nconst TRACEPARENT =\n\t/^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})([\\x21-\\x7e]*)$/;\nconst TRACESTATE_MEMBER =\n\t/^([a-z0-9][a-z0-9_@*/-]{0,255})=[\\x20-\\x2b\\x2d-\\x3c\\x3e-\\x7e]{1,256}$/;\n\nfunction assertTraceContext(traceparent: unknown, tracestate: unknown): void {\n\tif (traceparent === undefined) {\n\t\tif (tracestate !== undefined) {\n\t\t\tinvalid(\"$.tracestate\", \"requires traceparent\");\n\t\t}\n\t\treturn;\n\t}\n\tif (typeof traceparent !== \"string\") {\n\t\tinvalid(\"$.traceparent\", \"must be a W3C traceparent string\");\n\t}\n\tconst match = TRACEPARENT.exec(traceparent);\n\tconst version = match?.[1];\n\tconst extension = match?.[5] ?? \"\";\n\tif (\n\t\tmatch === null ||\n\t\tversion === \"ff\" ||\n\t\t/^0+$/.test(match[2] ?? \"\") ||\n\t\t/^0+$/.test(match[3] ?? \"\") ||\n\t\t(version === \"00\" && extension.length > 0) ||\n\t\t(version !== \"00\" &&\n\t\t\textension.length > 0 &&\n\t\t\t(!extension.startsWith(\"-\") || extension.length === 1))\n\t) {\n\t\tinvalid(\n\t\t\t\"$.traceparent\",\n\t\t\t\"must be a structurally valid lowercase W3C traceparent\",\n\t\t);\n\t}\n\tif (tracestate === undefined) return;\n\tif (typeof tracestate !== \"string\" || tracestate.length > 512) {\n\t\tinvalid(\n\t\t\t\"$.tracestate\",\n\t\t\t\"must stay within the 512-character command limit\",\n\t\t);\n\t}\n\t// W3C Trace Context requires receivers to tolerate empty list-members\n\t// (\"vendor1=abc,,vendor2=def\"). They carry no data and are dropped\n\t// before validation; a header with only empty members counts as absent.\n\tconst members = tracestate\n\t\t.split(\",\")\n\t\t.map((member) => member.trim())\n\t\t.filter((member) => member.length > 0);\n\tif (members.length === 0) return;\n\tconst keys = new Set<string>();\n\tif (\n\t\tmembers.length > 32 ||\n\t\tmembers.some((member) => {\n\t\t\tconst memberMatch = TRACESTATE_MEMBER.exec(member);\n\t\t\tconst key = memberMatch?.[1];\n\t\t\tif (key === undefined || keys.has(key)) return true;\n\t\t\tkeys.add(key);\n\t\t\treturn false;\n\t\t})\n\t) {\n\t\tinvalid(\n\t\t\t\"$.tracestate\",\n\t\t\t\"must contain 1 to 32 unique, valid W3C tracestate list-members\",\n\t\t);\n\t}\n}\n\nfunction invalid(path: string, reason: string): never {\n\tthrow new InvalidCommandMessageError(path, reason);\n}\n","import { err, ok, type Result } from \"@shirudo/result\";\nimport { DomainError } from \"../core/errors\";\n\n/** A concrete consumer-defined DomainError subclass accepted at a boundary. */\nexport type DomainErrorClass<E extends DomainError = DomainError> = new (\n\t...args: never[]\n) => E;\n\ntype ListedDomainError<TClasses extends readonly DomainErrorClass[]> =\n\tInstanceType<TClasses[number]>;\n\n/**\n * Runs application-boundary work and turns only explicitly listed domain\n * rejections into a typed Result error. Every unlisted DomainError and every\n * non-domain failure is rethrown unchanged. The class list is copied and\n * validated before work starts.\n *\n * @throws TypeError when expectedErrors is empty or contains a non-DomainError\n * class\n * @throws The exact operation failure when it is not an instance of a listed\n * class\n */\nexport async function domainErrorToResult<\n\tT,\n\tconst TClasses extends readonly [DomainErrorClass, ...DomainErrorClass[]],\n>(\n\toperation: () => T | PromiseLike<T>,\n\texpectedErrors: TClasses,\n): Promise<Result<T, ListedDomainError<TClasses>>> {\n\tconst stableExpectedErrors = [...expectedErrors];\n\tassertExpectedErrorClasses(stableExpectedErrors);\n\n\ttry {\n\t\treturn ok(await operation());\n\t} catch (error) {\n\t\tfor (const errorClass of stableExpectedErrors) {\n\t\t\tif (\n\t\t\t\t((typeof error === \"object\" && error !== null) ||\n\t\t\t\t\ttypeof error === \"function\") &&\n\t\t\t\tObject.prototype.isPrototypeOf.call(errorClass.prototype, error)\n\t\t\t) {\n\t\t\t\treturn err(error as ListedDomainError<TClasses>);\n\t\t\t}\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nfunction assertExpectedErrorClasses(\n\terrorClasses: readonly unknown[],\n): asserts errorClasses is readonly [DomainErrorClass, ...DomainErrorClass[]] {\n\tif (errorClasses.length === 0) {\n\t\tthrow new TypeError(\n\t\t\t\"domainErrorToResult requires at least one expected DomainError class\",\n\t\t);\n\t}\n\tfor (const errorClass of errorClasses) {\n\t\tif (\n\t\t\ttypeof errorClass !== \"function\" ||\n\t\t\t!Object.prototype.isPrototypeOf.call(\n\t\t\t\tDomainError.prototype,\n\t\t\t\terrorClass.prototype,\n\t\t\t)\n\t\t) {\n\t\t\tthrow new TypeError(\n\t\t\t\t\"domainErrorToResult expected every entry to be a concrete DomainError subclass\",\n\t\t\t);\n\t\t}\n\t}\n}\n","/**\n * The value to reject with when an `AbortSignal` has fired.\n *\n * Returns the signal's `reason` (a `DOMException` `AbortError` for\n * `controller.abort()`, `TimeoutError` for `AbortSignal.timeout`), falling\n * back to a plain `Error` with `fallbackMessage` when `reason` is nullish.\n * A spec-compliant signal always populates `reason` when aborted, so the\n * fallback only fires for a non-spec polyfill; without it, a bare\n * `throw undefined` would surface, breaking `instanceof Error` handling.\n *\n * Centralizes the `signal.reason ?? new Error(...)` idiom used at every\n * abort site (event bus, `withCommit`, `UnitOfWork.run`, the retrying\n * scope) so a single fix covers all of them.\n */\nexport function abortReason(\n\tsignal: AbortSignal,\n\tfallbackMessage: string,\n): unknown {\n\treturn signal.reason ?? new Error(fallbackMessage);\n}\n","/**\n * Shared construction-time guards for numeric options. `context` names\n * the throwing component so the error reads like the component's own\n * validation (\"OutboxDispatcher: pollIntervalMs must be...\").\n */\n\n/** Guard for numeric options that must be a non-negative finite number. */\nexport function assertNonNegativeFinite(\n\tcontext: string,\n\tfield: string,\n\tvalue: number,\n): void {\n\tif (!Number.isFinite(value) || value < 0) {\n\t\tthrow new Error(\n\t\t\t`${context}: ${field} must be a non-negative finite number, got ${value}`,\n\t\t);\n\t}\n}\n\n/** Guard for count options that must be a whole number of at least 1. */\nexport function assertPositiveInteger(\n\tcontext: string,\n\tfield: string,\n\tvalue: number,\n): void {\n\tif (!Number.isInteger(value) || value < 1) {\n\t\tthrow new Error(\n\t\t\t`${context}: ${field} must be an integer >= 1, got ${value}`,\n\t\t);\n\t}\n}\n\n/** Guard for retained-record capacities that must fit exact JS integers. */\nexport function assertPositiveSafeInteger(\n\tcontext: string,\n\tfield: string,\n\tvalue: number,\n): void {\n\tif (!Number.isSafeInteger(value) || value < 1) {\n\t\tthrow new RangeError(\n\t\t\t`${context}: ${field} must be a positive safe integer, got ${value}`,\n\t\t);\n\t}\n}\n","import { abortReason } from \"./abort\";\nimport { assertNonNegativeFinite } from \"./validate\";\n\n/** Cancellation and deadline controls for one bounded shell operation. */\nexport interface ExecutionContext {\n\t/** Cooperative cancellation for the in-flight operation. */\n\treadonly signal: AbortSignal;\n\t/** Absolute Unix epoch millisecond at which the shell stops waiting. */\n\treadonly deadlineAt: number;\n}\n\n/** Caller controls for one bounded shell operation. */\ntype ExecutionOptions =\n\t| {\n\t\t\t/** Optional owner/request cancellation signal. */\n\t\t\treadonly signal?: AbortSignal;\n\t\t\t/** Maximum time the shell waits for the operation. */\n\t\t\treadonly timeoutMs: number;\n\t\t\treadonly deadlineAt?: never;\n\t }\n\t| {\n\t\t\t/** Optional owner/request cancellation signal. */\n\t\t\treadonly signal?: AbortSignal;\n\t\t\treadonly timeoutMs?: never;\n\t\t\t/** Shared absolute deadline for a multi-operation budget. */\n\t\t\treadonly deadlineAt: number;\n\t };\n\n/** Default bound for delivery and post-commit operations. */\nexport const DEFAULT_EXECUTION_TIMEOUT_MS = 30_000;\n\n/**\n * Runs one operation with a child signal that combines owner cancellation and a\n * shell-owned timeout. The returned promise settles on abort even when an\n * adapter ignores the signal; the adapter promise remains observed so a later\n * rejection cannot become an unhandled rejection.\n *\n * This bounds how long the shell waits; JavaScript cannot forcibly terminate\n * an arbitrary promise. An I/O adapter that must prevent zombie work and\n * overlapping retries has to pass `context.signal` to its native operation or\n * enforce a native timeout no later than `context.deadlineAt`.\n */\nexport function runBoundedExecution<T>(\n\tlabel: string,\n\toptions: ExecutionOptions,\n\toperation: (context: ExecutionContext) => Promise<T> | T,\n): Promise<T> {\n\tif (options.deadlineAt === undefined) {\n\t\tassertNonNegativeFinite(label, \"timeoutMs\", options.timeoutMs);\n\t} else {\n\t\tassertNonNegativeFinite(label, \"deadlineAt\", options.deadlineAt);\n\t}\n\tconst startedAt = Date.now();\n\tconst deadlineAt = options.deadlineAt ?? startedAt + options.timeoutMs;\n\tconst timeoutMs = Math.max(0, deadlineAt - startedAt);\n\tconst timeoutError = (): DOMException =>\n\t\tnew DOMException(`${label} timed out after ${timeoutMs}ms`, \"TimeoutError\");\n\tconst controller = new AbortController();\n\tconst context = Object.freeze({\n\t\tsignal: controller.signal,\n\t\tdeadlineAt,\n\t});\n\tconst ownerSignal = options.signal;\n\tconst abortFromOwner = (): void => {\n\t\tcontroller.abort(\n\t\t\townerSignal === undefined\n\t\t\t\t? new Error(`${label} aborted`)\n\t\t\t\t: abortReason(ownerSignal, `${label} aborted`),\n\t\t);\n\t};\n\n\tif (ownerSignal?.aborted) abortFromOwner();\n\telse ownerSignal?.addEventListener(\"abort\", abortFromOwner, { once: true });\n\tif (\n\t\t!controller.signal.aborted &&\n\t\toptions.deadlineAt !== undefined &&\n\t\tdeadlineAt <= startedAt\n\t) {\n\t\tcontroller.abort(timeoutError());\n\t}\n\n\tconst timer = setTimeout(() => {\n\t\tcontroller.abort(timeoutError());\n\t}, timeoutMs);\n\n\treturn new Promise<T>((resolve, reject) => {\n\t\tlet settled = false;\n\t\tconst finish = (complete: () => void): void => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tclearTimeout(timer);\n\t\t\townerSignal?.removeEventListener(\"abort\", abortFromOwner);\n\t\t\tcontroller.signal.removeEventListener(\"abort\", onAbort);\n\t\t\tcomplete();\n\t\t};\n\t\tconst onAbort = (): void => {\n\t\t\t// Defer one microtask so a promise that settled immediately before the\n\t\t\t// abort keeps its acknowledgement semantics. If abort happened first,\n\t\t\t// this microtask was queued first and still wins deterministically.\n\t\t\tqueueMicrotask(() =>\n\t\t\t\tfinish(() =>\n\t\t\t\t\treject(abortReason(controller.signal, `${label} aborted`)),\n\t\t\t\t),\n\t\t\t);\n\t\t};\n\n\t\tif (controller.signal.aborted) {\n\t\t\tonAbort();\n\t\t\treturn;\n\t\t}\n\t\tcontroller.signal.addEventListener(\"abort\", onAbort, { once: true });\n\t\tlet outcome: Promise<T>;\n\t\ttry {\n\t\t\toutcome = Promise.resolve(operation(context));\n\t\t} catch (error) {\n\t\t\tfinish(() => reject(error));\n\t\t\treturn;\n\t\t}\n\t\toutcome.then(\n\t\t\t(value) => finish(() => resolve(value)),\n\t\t\t(error) => finish(() => reject(error)),\n\t\t);\n\t});\n}\n","/**\n * Invokes a fire-and-forget observer hook (`onPersistError`,\n * `onPublishError`, `onRetry`) and neutralises BOTH failure shapes it can\n * produce. The observers are typed `(...) => void`, but a `void` return\n * type still admits an `async` function, so an observer can fail in two\n * ways: a synchronous throw, or a rejected promise. Either would replace\n * or mask the operation's real outcome (a committed write made to look\n * failed, a retryable error swapped for the observer's own), and the\n * async rejection additionally becomes an `unhandledRejection` that can\n * crash the process under Node's default policy. Both are swallowed\n * here: observers report, they never affect the operation they observe.\n *\n * Internal utility (not exported from the package barrels).\n */\nexport function reportToObserver(invoke: () => void): void {\n\tlet result: unknown;\n\ttry {\n\t\tresult = invoke() as unknown;\n\t} catch {\n\t\treturn;\n\t}\n\tif (\n\t\tresult !== null &&\n\t\ttypeof result === \"object\" &&\n\t\ttypeof (result as { then?: unknown }).then === \"function\"\n\t) {\n\t\t(result as Promise<unknown>).then(undefined, () => {});\n\t}\n}\n\n/** Runtime-validates and immutably captures a production-observer bundle. */\nexport function captureObserverFunctions<\n\tT extends object,\n\tK extends Extract<keyof T, string>,\n>(context: string, observers: T, required: readonly K[]): Readonly<Pick<T, K>> {\n\tif (observers === null || typeof observers !== \"object\") {\n\t\tthrow new TypeError(\n\t\t\t`${context}.observers must provide ${required.join(\", \")}`,\n\t\t);\n\t}\n\tconst captured: Partial<Record<K, T[K]>> = {};\n\tfor (const name of required) {\n\t\tconst observer = (observers as Record<string, unknown>)[name];\n\t\tif (typeof observer !== \"function\") {\n\t\t\tthrow new TypeError(`${context}.observers.${name} must be a function`);\n\t\t}\n\t\tcaptured[name] = observer as T[K];\n\t}\n\treturn Object.freeze(captured) as Readonly<Pick<T, K>>;\n}\n","import type { Version } from \"../aggregate/aggregate\";\nimport type { IAggregateRoot } from \"../aggregate/aggregate-root\";\nimport {\n\ttype AnyDomainEvent,\n\tisMintedEvent,\n\ttype PendingDomainEvent,\n} from \"../aggregate/domain-event\";\nimport {\n\ttype PendingEventLifecycleCapability,\n\tpendingEventLifecycleCapabilityFor,\n} from \"../aggregate/pending-event-lifecycle\";\nimport { EventHarvestError } from \"../core/errors\";\nimport type { Id } from \"../core/id\";\nimport type {\n\tEventBus,\n\tEventCommitCandidate,\n\tOutboxWriter,\n} from \"../events/ports\";\nimport type { TransactionScope } from \"../repo/scope\";\nimport { abortReason } from \"../utils/abort\";\nimport {\n\tDEFAULT_EXECUTION_TIMEOUT_MS,\n\ttype ExecutionContext,\n\trunBoundedExecution,\n} from \"../utils/execution\";\nimport { reportToObserver } from \"../utils/observer\";\nimport { assertNonNegativeFinite } from \"../utils/validate\";\n\n/** Dependencies for {@link withCommit}. */\nexport interface WithCommitDeps<Evt extends AnyDomainEvent, TCtx> {\n\t/**\n\t * The write half of the outbox: `withCommit` only ever calls `add()`.\n\t * Pass a full `Outbox` for the kit's poll-based dispatch, or a bare\n\t * `OutboxWriter` backed by an external delivery solution.\n\t *\n\t * Required on purpose, while `bus` is optional: the bus is the\n\t * best-effort in-process fast path, the outbox is the delivery\n\t * guarantee. Running without delivery reliability is a decision, not\n\t * a default; make it explicit with\n\t * `outboxWriterAcceptingEventLoss()`.\n\t */\n\toutbox: OutboxWriter<Evt>;\n\tbus?: EventBus<Evt>;\n\tscope: TransactionScope<TCtx>;\n\t/**\n\t * Observer for post-commit `bus.publish` failures. Called with the\n\t * error and the events that were published. Must not be relied on\n\t * for delivery: the outbox dispatcher is the reliable path.\n\t */\n\tonPublishError?: (error: unknown, events: ReadonlyArray<Evt>) => void;\n\t/**\n\t * Application-shell observer invoked for each successfully acknowledged\n\t * saved aggregate, after every commit record has completed its internal\n\t * acknowledgement attempt. Deleted aggregates do not trigger it. `version`\n\t * is the commit-time value captured before any observer runs. Observer\n\t * failures are reported through `onPersistError` and never turn an already\n\t * committed write into an apparent failure. The execution context carries\n\t * owner cancellation and the configured post-commit deadline.\n\t */\n\tonPersisted?: (\n\t\taggregate: IAggregateRoot<Id<string>, Evt>,\n\t\tversion: Version,\n\t\tcontext: ExecutionContext,\n\t) => void | Promise<void>;\n\t/**\n\t * Observer for post-commit persistence failures: either the internal\n\t * acknowledgement/disposal step or the application-shell `onPersisted`\n\t * observer. Called once per failure with the error and affected aggregate.\n\t * Symmetric with {@link onPublishError}: the\n\t * transaction has already committed, so the failure must NOT reject the\n\t * write; without this observer it would otherwise vanish silently. The\n\t * hook is an observer only: if it throws, its error is swallowed so the\n\t * post-commit invariant holds, and the loop continues the remaining\n\t * post-commit work.\n\t */\n\tonPersistError?: (\n\t\terror: unknown,\n\t\taggregate: IAggregateRoot<Id<string>, Evt>,\n\t) => void;\n\t/**\n\t * Total time allotted to the complete post-commit application phase:\n\t * every application observer followed by in-process bus publication shares\n\t * one absolute deadline. Callbacks that have not started when the deadline is\n\t * reached are skipped and reported as timeouts. Defaults to `30000`ms.\n\t * Timing out or aborting these best-effort operations is reported through the\n\t * matching error observer and never rejects an already committed write.\n\t */\n\tpostCommitTimeoutMs?: number;\n\t/**\n\t * Cooperative-cancellation signal. If already aborted, `withCommit`\n\t * rejects with the signal's `reason` BEFORE opening the transaction.\n\t * Otherwise the signal is forwarded to `scope.transactional`, where a\n\t * cancellation-aware scope can abort an in-flight query. The kit does\n\t * not race the work promise: aborting does not kill a running query\n\t * unless the scope honors the signal.\n\t */\n\tsignal?: AbortSignal;\n}\n\ndeclare const aggregateCommitTokenBrand: unique symbol;\n\n/**\n * Opaque receipt that one aggregate was explicitly enrolled in the current\n * {@link withCommit} invocation. Tokens are minted only by the invocation's\n * {@link CommitEnrollment} capability and are bound to that invocation at\n * runtime; a forged token or one retained from an earlier call is rejected\n * inside the transaction.\n */\nexport interface AggregateCommitToken<\n\tEvt extends AnyDomainEvent = AnyDomainEvent,\n> {\n\treadonly [aggregateCommitTokenBrand]: Evt;\n}\n\n/**\n * Invocation-scoped enrollment capability handed to a {@link withCommit}\n * callback. Call `enrollSaved` only for an aggregate participating in the\n * repository write, and return every resulting token in `commits`. Omitting\n * any token rejects the transaction: an enrolled write may not commit without\n * its event harvest and post-commit acknowledgement. Enrollable instances\n * must extend `AggregateRoot` or `EventSourcedAggregate`; structural\n * `IAggregateRoot` lookalikes have no internal lifecycle capability and fail\n * before commit.\n */\nexport interface CommitEnrollment<Evt extends AnyDomainEvent> {\n\tenrollSaved(\n\t\taggregate: IAggregateRoot<Id<string>, Evt>,\n\t\toptions?: CommitEnrollmentOptions,\n\t): AggregateCommitToken<Evt>;\n\t/**\n\t * Enroll an aggregate whose row is deleted by the current transaction.\n\t * Its events are harvested and discarded after commit, but the saved-only\n\t * application `onPersisted` observer is not called.\n\t */\n\tenrollDeleted(\n\t\taggregate: IAggregateRoot<Id<string>, Evt>,\n\t\toptions?: CommitEnrollmentOptions,\n\t): AggregateCommitToken<Evt>;\n}\n\n/** OCC baseline associated with one exact commit enrollment. */\nexport interface CommitEnrollmentOptions {\n\t/** Absent for a new aggregate; captured at load for update or removal. */\n\treadonly expectedVersion?: Version;\n}\n\n/** The resolved value of a {@link withCommit} work callback. */\nexport interface WithCommitWorkResult<Evt extends AnyDomainEvent, R> {\n\tresult: R;\n\t/**\n\t * Commit tokens returned by the invocation's enrollment capability.\n\t * Every token minted during the callback must appear at least once.\n\t * Naked aggregates are intentionally not accepted: touching an aggregate\n\t * does not prove that its repository write participated in the transaction.\n\t */\n\tcommits: ReadonlyArray<AggregateCommitToken<Evt>>;\n}\n\ntype CommitDisposition = \"saved\" | \"deleted\";\n\ninterface AggregateCommitRecord<Evt extends AnyDomainEvent> {\n\treadonly aggregate: IAggregateRoot<Id<string>, Evt>;\n\treadonly eventLifecycle: PendingEventLifecycleCapability;\n\treadonly version: Version;\n\treadonly expectedVersion: Version | undefined;\n\t/**\n\t * Version the persistence layer last confirmed for the aggregate at\n\t * enrollment time (kit-maintained). `undefined` means the aggregate was\n\t * never persisted, so any single eventful commit cursor is unique.\n\t */\n\treadonly persistedVersion: Version | undefined;\n\treadonly events: ReadonlyArray<PendingDomainEvent<Evt>>;\n\tdisposition: CommitDisposition;\n}\n\n/**\n * True when the aggregate's live version or pending-event batch no longer\n * matches its enrollment-time snapshot. Shared by the duplicate-enrollment\n * gate and the harvest-time recheck: both must reject the same divergence,\n * or events recorded after enrollment would be silently dropped.\n */\nfunction enrollmentDiverged<Evt extends AnyDomainEvent>(\n\trecord: AggregateCommitRecord<Evt>,\n): boolean {\n\tconst pending = record.aggregate.pendingEvents;\n\treturn (\n\t\trecord.aggregate.version !== record.version ||\n\t\tpending.length !== record.events.length ||\n\t\trecord.events.some((event, index) => event !== pending[index])\n\t);\n}\n\ninterface CommitTokenScope<Evt extends AnyDomainEvent> {\n\treadonly enrollment: CommitEnrollment<Evt>;\n\tclose(): void;\n\tresolve(tokens: unknown): ReadonlyArray<AggregateCommitRecord<Evt>>;\n}\n\n/** One token registry per transactional callback attempt. */\nfunction createCommitTokenScope<\n\tEvt extends AnyDomainEvent,\n>(): CommitTokenScope<Evt> {\n\tconst recordsByToken = new WeakMap<object, AggregateCommitRecord<Evt>>();\n\tconst tokensByAggregate = new WeakMap<\n\t\tIAggregateRoot<Id<string>, Evt>,\n\t\tAggregateCommitToken<Evt>\n\t>();\n\tlet mintedTokenCount = 0;\n\tlet open = true;\n\n\tconst enroll = (\n\t\taggregate: IAggregateRoot<Id<string>, Evt>,\n\t\tdisposition: CommitDisposition,\n\t\toptions?: CommitEnrollmentOptions,\n\t): AggregateCommitToken<Evt> => {\n\t\tif (!open) {\n\t\t\tthrow new EventHarvestError(\n\t\t\t\t\"withCommit: commit enrollment was used after its work callback \" +\n\t\t\t\t\t\"settled. Await every repository write and return its token before \" +\n\t\t\t\t\t\"leaving the callback.\",\n\t\t\t);\n\t\t}\n\n\t\tconst existing = tokensByAggregate.get(aggregate);\n\t\tif (existing) {\n\t\t\tconst record = recordsByToken.get(existing);\n\t\t\tif (!record) {\n\t\t\t\tthrow new EventHarvestError(\n\t\t\t\t\t\"withCommit: internal commit-token registry is inconsistent.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (record.disposition === \"deleted\" && disposition === \"saved\") {\n\t\t\t\tthrow new EventHarvestError(\n\t\t\t\t\t`withCommit: aggregate ${String(aggregate.id)} was enrolled as ` +\n\t\t\t\t\t\t\"saved after it was enrolled as deleted in the same transaction.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Duplicate enrollment is idempotent by reference. An omitted\n\t\t\t// expectedVersion is no assertion, not an assertion of \"absent\":\n\t\t\t// only a supplied value is compared against the recorded baseline.\n\t\t\tif (\n\t\t\t\toptions?.expectedVersion !== undefined &&\n\t\t\t\toptions.expectedVersion !== record.expectedVersion\n\t\t\t) {\n\t\t\t\tthrow new EventHarvestError(\n\t\t\t\t\t`withCommit: aggregate ${String(aggregate.id)} was re-enrolled ` +\n\t\t\t\t\t\t`with expectedVersion ${String(options.expectedVersion)}, but its ` +\n\t\t\t\t\t\t`enrollment recorded ${String(record.expectedVersion)}. Duplicate ` +\n\t\t\t\t\t\t\"enrollment must assert the same OCC baseline or none.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (enrollmentDiverged(record)) {\n\t\t\t\tthrow new EventHarvestError(\n\t\t\t\t\t`withCommit: aggregate ${String(aggregate.id)} changed after its ` +\n\t\t\t\t\t\t\"commit batch was enrolled. Register persistence intent last.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\t// The widened disposition is adopted only after every check passed:\n\t\t\t// a rejected enrollDeleted whose error the callback catches must\n\t\t\t// not leave a saved aggregate marked deleted, or the post-commit\n\t\t\t// loop would discard instead of acknowledge.\n\t\t\tif (disposition === \"deleted\") {\n\t\t\t\trecord.disposition = \"deleted\";\n\t\t\t}\n\t\t\treturn existing;\n\t\t}\n\n\t\tconst eventLifecycle = pendingEventLifecycleCapabilityFor(aggregate);\n\t\tif (!eventLifecycle) {\n\t\t\tthrow new EventHarvestError(\n\t\t\t\t`withCommit: aggregate ${String(aggregate.id)} has no kit-managed ` +\n\t\t\t\t\t\"persistence lifecycle. Extend AggregateRoot or \" +\n\t\t\t\t\t\"EventSourcedAggregate; repository DTOs and structural lookalikes \" +\n\t\t\t\t\t\"cannot be enrolled for commit acknowledgement.\",\n\t\t\t);\n\t\t}\n\n\t\tconst token = Object.freeze(\n\t\t\tObject.create(null),\n\t\t) as AggregateCommitToken<Evt>;\n\t\t// The pendingEvents getter already returns a frozen detached copy;\n\t\t// re-copying and re-freezing it here would only duplicate the work.\n\t\tconst events = aggregate.pendingEvents;\n\t\t// Recorded-before-persistence is checked HERE, not only at harvest:\n\t\t// the UnitOfWork enrolls at write registration, so this rejection\n\t\t// lands before any adapter flush. The harvest guard alone fires after\n\t\t// flush, and a non-transactional event store would already have\n\t\t// appended the unstamped batch durably.\n\t\tfor (const event of events) {\n\t\t\tif (!isMintedEvent(event)) {\n\t\t\t\tthrow new EventHarvestError(\n\t\t\t\t\t`withCommit: event \"${(event as { readonly type: string }).type}\" ` +\n\t\t\t\t\t\t\"has not been recorded. Call recordPendingEvents(aggregate, \" +\n\t\t\t\t\t\t\"createStamp) in the application shell before persistence or \" +\n\t\t\t\t\t\t\"outbox harvest.\",\n\t\t\t\t\t(event as { readonly type: string }).type,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\t// The kit-maintained marker, not the enrollment-supplied\n\t\t// expectedVersion, grounds the unique-cursor guard: it survives\n\t\t// callers who omit enrollment options (the documented\n\t\t// direct-withCommit style), and grounding the guard in data supplied\n\t\t// by the very caller it checks would be circular.\n\t\tconst persistedVersion = eventLifecycle.persistedVersion() as\n\t\t\t| Version\n\t\t\t| undefined;\n\t\ttokensByAggregate.set(aggregate, token);\n\t\trecordsByToken.set(token, {\n\t\t\taggregate,\n\t\t\teventLifecycle,\n\t\t\tdisposition,\n\t\t\tversion: aggregate.version,\n\t\t\texpectedVersion: options?.expectedVersion,\n\t\t\tpersistedVersion,\n\t\t\tevents,\n\t\t});\n\t\tmintedTokenCount += 1;\n\t\treturn token;\n\t};\n\n\treturn {\n\t\tenrollment: Object.freeze({\n\t\t\tenrollSaved: (\n\t\t\t\taggregate: IAggregateRoot<Id<string>, Evt>,\n\t\t\t\toptions?: CommitEnrollmentOptions,\n\t\t\t) => enroll(aggregate, \"saved\", options),\n\t\t\tenrollDeleted: (\n\t\t\t\taggregate: IAggregateRoot<Id<string>, Evt>,\n\t\t\t\toptions?: CommitEnrollmentOptions,\n\t\t\t) => enroll(aggregate, \"deleted\", options),\n\t\t}),\n\t\tclose: () => {\n\t\t\topen = false;\n\t\t},\n\t\tresolve: (tokens) => {\n\t\t\tif (!Array.isArray(tokens)) {\n\t\t\t\tthrow new EventHarvestError(\n\t\t\t\t\t\"withCommit: the work callback must return `commits` containing \" +\n\t\t\t\t\t\t\"tokens from the current enrollment capability. Naked aggregate \" +\n\t\t\t\t\t\t\"arrays are not commit evidence.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst seen = new Set<object>();\n\t\t\tconst records: AggregateCommitRecord<Evt>[] = [];\n\t\t\tfor (const token of tokens) {\n\t\t\t\tif (\n\t\t\t\t\ttoken === null ||\n\t\t\t\t\t(typeof token !== \"object\" && typeof token !== \"function\")\n\t\t\t\t) {\n\t\t\t\t\tthrow new EventHarvestError(\n\t\t\t\t\t\t\"withCommit: a commit token was not minted by this callback's \" +\n\t\t\t\t\t\t\t\"enrollment capability. Forged and stale tokens are rejected.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst tokenObject = token as object;\n\t\t\t\tconst record = recordsByToken.get(tokenObject);\n\t\t\t\tif (!record) {\n\t\t\t\t\tthrow new EventHarvestError(\n\t\t\t\t\t\t\"withCommit: a commit token was not minted by this callback's \" +\n\t\t\t\t\t\t\t\"enrollment capability. Forged and stale tokens are rejected.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (seen.has(tokenObject)) continue;\n\t\t\t\tseen.add(tokenObject);\n\t\t\t\t// Harvest-time recheck of the enrollment snapshot: an event\n\t\t\t\t// recorded after enrollSaved but before the callback returned\n\t\t\t\t// would be excluded from the harvest and silently lost by the\n\t\t\t\t// post-commit prefix acknowledgement. Divergence fails loudly\n\t\t\t\t// inside the transaction instead.\n\t\t\t\tif (enrollmentDiverged(record)) {\n\t\t\t\t\tthrow new EventHarvestError(\n\t\t\t\t\t\t`withCommit: aggregate ${String(record.aggregate.id)} changed ` +\n\t\t\t\t\t\t\t\"after its commit batch was enrolled; events recorded after \" +\n\t\t\t\t\t\t\t\"enrollment are not part of the attested write and would be \" +\n\t\t\t\t\t\t\t\"silently dropped. Make domain decisions first, write, and \" +\n\t\t\t\t\t\t\t\"enroll last.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\trecords.push(record);\n\t\t\t}\n\t\t\tif (seen.size !== mintedTokenCount) {\n\t\t\t\tthrow new EventHarvestError(\n\t\t\t\t\t\"withCommit: every token minted by the current enrollment \" +\n\t\t\t\t\t\t\"capability must be returned in `commits`. If an enrolled write \" +\n\t\t\t\t\t\t\"must not commit, throw so the transaction rolls back.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn records;\n\t\t},\n\t};\n}\n\n/**\n * Helper for executing a write Use Case inside a transaction scope.\n *\n * The use-case callback receives an invocation-scoped enrollment capability\n * and returns opaque commit tokens for the repository writes that completed\n * in the transaction. `withCommit` owns the post-commit lifecycle (harvest,\n * outbox, mark-persisted, publish). A naked aggregate is not commit evidence:\n * merely touching or constructing one must never make it look persisted.\n *\n * **Trust boundary.** A token proves invocation-local enrollment, not that the\n * kit inspected a database write; a generic transaction helper cannot observe\n * adapter internals. Repository code must enroll only writes participating in\n * this transaction. `UnitOfWork` centralizes that rule in repository methods.\n * The opaque, scoped token prevents accidental aggregate smuggling and stale\n * reuse; it is not a security boundary against code that deliberately lies to\n * its own persistence capability.\n *\n * Order of operations:\n * 1. `fn(ctx, enrollment)` runs inside `scope.transactional(...)`; domain\n * mutations + repo writes happen here. After a repository write has\n * enrolled an aggregate, the callback includes that opaque token in its\n * `commits` result. Tokens are invocation-bound: forged or stale tokens\n * fail before harvest. `ctx` is whatever transaction handle the `scope`\n * exposes (Drizzle `tx`, Prisma `tx`, Mongo session, or `undefined` for\n * context-free scopes).\n * 2. **Still inside the transaction**, `withCommit` harvests every\n * aggregate's `pendingEvents` and writes them via `outbox.add` (so\n * events persist atomically with the state change). Skipped when no\n * events were recorded. Each bare domain event is composed into an\n * `EventCommitCandidate` carrying its aggregate source and the commit\n * facts known by the application. The outbox source atomically links\n * that candidate to the preceding eventful commit and persists the\n * resulting `CommittedDomainEvent`. The domain event itself is never\n * stamped or copied.\n *\n * **Harvest order.** Events are concatenated in the order\n * tokens appear in the returned `commits` array, then in\n * each aggregate's `pendingEvents` order (insertion order via\n * `apply` / `commit` / `addDomainEvent`). So tokens for `[a, b]`\n * with `a` emitting `[e1, e2]` and `b` emitting `[e3]` produces\n * `outbox.add([envelope(e1), envelope(e2), envelope(e3)])` and\n * `bus.publish([e1, e2, e3])` in that exact order.\n *\n * **Two ordering guarantees, not one.** Within a single aggregate\n * the order is *causal*: events are recorded in the order the\n * domain methods ran, and subscribers (handlers, projections,\n * replay) MUST process them in that order. Across aggregates the\n * order in this batch is deterministic but *not* a domain\n * guarantee. Greg Young / Vernon IDDD §10: aggregates are\n * independent consistency boundaries; events across them are\n * eventually consistent. Subscribers should NOT engineer\n * dependencies on cross-aggregate ordering; use\n * `EventMetadata.causationId` to express true causation, or a\n * process manager to coordinate. The in-process EventBus delivers\n * this batch in order, sequential outbox-dispatchers preserve it\n * too, but parallel dispatchers or message brokers may reorder\n * across aggregates at delivery time.\n * 3. The transaction commits.\n * 4. **After** the commit, a non-exported capability acknowledges every\n * saved enrollment and discards pending events for deleted enrollments.\n * Only after the complete commit set is clean does the optional\n * application-shell `onPersisted(aggregate, version, context)` observer run for\n * saved aggregates. Deleted rows never trigger that observer.\n * 5. `bus.publish(events)` fires for the in-process fast path (skipped\n * when no events or no `bus` is wired).\n *\n * Publishing AFTER commit prevents the classic \"publish before commit\"\n * footgun: in-process subscribers can never react to events from a\n * transaction that later rolled back. If `bus.publish` itself throws, the\n * outbox still holds the events and an outbox-dispatcher will deliver\n * them (eventual consistency).\n *\n * **A `bus.publish` failure never rejects `withCommit`.** Once the\n * transaction has committed, the write succeeded; surfacing a subscriber\n * failure as a rejection would hand the caller a use-case failure for a\n * committed write (a typical caller retries, double-executing it). The\n * in-process fast path is best-effort by design; the error is reported to\n * the optional `onPublishError(error, events)` hook (wire it to your\n * logger/metrics) and otherwise dropped; delivery is still guaranteed via\n * the outbox. The hook is an observer: if it throws, its error is\n * swallowed so the post-commit invariant holds.\n * The complete application-observer and bus-publication phase shares one\n * absolute `postCommitTimeoutMs` budget (30 seconds by default); later callbacks\n * are not started once it expires. A timeout or owner abort is reported\n * through the same observer paths and never changes the committed result.\n *\n * If the transaction rolls back, no acknowledgement occurs: the aggregate\n * keeps its pending events, so the caller can retry or discard the instance.\n *\n * Enrollment captures an exact version and event batch. Re-enrolling the same\n * aggregate after it changes rejects. `UnitOfWork` additionally seals the\n * adapter persistence projection and rejects later mutation before flush. For\n * direct `withCommit` use, make domain decisions first, write, and enroll last.\n *\n * **Duplicate enrollment is idempotent by reference.** Enrolling the same\n * instance repeatedly returns the same token, and a repeated token in\n * `commits` is harvested once. A repeat call that omits `expectedVersion`\n * makes no OCC assertion; only a supplied value that contradicts the\n * enrollment-time baseline rejects. Each event lands in the outbox exactly once\n * and post-commit acknowledgement runs exactly once. Two\n * *different* instances with the same logical id cannot be detected\n * at this layer; that is a Repository contract violation (failure to\n * maintain Fowler's Identity Map per Unit of Work). See\n * `docs/guide/repository.md` → \"Identity Map: one instance per\n * aggregate per Unit of Work\" for the requirement on repository\n * implementations that makes this dedupe sound.\n *\n * @example Tx-bound repos (Drizzle, Prisma, Mongo, …)\n * ```typescript\n * const result = await withCommit({ outbox, bus, scope }, async (tx, enrollment) => {\n * const orderRepository = makeOrderRepository(tx); // your factory binds tx to the repo\n * const order = await orderRepository.getById(orderId);\n * order.confirm();\n * await persistOrder(tx, order); // low-level adapter write\n * const commit = enrollment.enrollSaved(order); // attest the repository write\n * return { result: order.id, commits: [commit] };\n * });\n * ```\n */\nexport async function withCommit<Evt extends AnyDomainEvent, R, TCtx>(\n\tdeps: WithCommitDeps<Evt, TCtx>,\n\tfn: (\n\t\tctx: TCtx,\n\t\tenrollment: CommitEnrollment<Evt>,\n\t) => Promise<WithCommitWorkResult<Evt, R>>,\n): Promise<R> {\n\tconst postCommitTimeoutMs =\n\t\tdeps.postCommitTimeoutMs ?? DEFAULT_EXECUTION_TIMEOUT_MS;\n\tassertNonNegativeFinite(\n\t\t\"withCommit\",\n\t\t\"postCommitTimeoutMs\",\n\t\tpostCommitTimeoutMs,\n\t);\n\n\t// Pre-flight: an already-aborted caller never opens a transaction.\n\t// Throwing the signal's reason matches the web AbortSignal convention;\n\t// the `??` fallback mirrors event-bus.ts and guards a non-spec polyfill\n\t// whose `reason` is undefined (a bare `throw undefined` is unusable).\n\tif (deps.signal?.aborted) {\n\t\tthrow abortReason(\n\t\t\tdeps.signal,\n\t\t\t\"withCommit aborted before opening a transaction\",\n\t\t);\n\t}\n\n\tconst { result, commitRecords, events } = await deps.scope.transactional(\n\t\tasync (ctx) => {\n\t\t\tconst tokenScope = createCommitTokenScope<Evt>();\n\t\t\tlet fnResult: WithCommitWorkResult<Evt, R>;\n\t\t\ttry {\n\t\t\t\tfnResult = await fn(ctx, tokenScope.enrollment);\n\t\t\t} finally {\n\t\t\t\t// A callback can leak the capability into delayed work. Seal it as\n\t\t\t\t// soon as the callback settles so a late enrollment fails loudly\n\t\t\t\t// instead of being accepted after the harvest snapshot.\n\t\t\t\ttokenScope.close();\n\t\t\t}\n\t\t\tconst commitRecords = tokenScope.resolve(fnResult.commits);\n\t\t\t// Prepare each bare domain event for source finalization in the outbox.\n\t\t\t// The aggregate's event remains untouched and is what the in-process\n\t\t\t// domain bus receives.\n\t\t\tconst candidates = commitRecords.flatMap((record) => {\n\t\t\t\tconst agg = record.aggregate;\n\t\t\t\tif (\n\t\t\t\t\trecord.events.length > 0 &&\n\t\t\t\t\trecord.persistedVersion !== undefined &&\n\t\t\t\t\t(record.version as number) <= (record.persistedVersion as number)\n\t\t\t\t) {\n\t\t\t\t\tthrow new EventHarvestError(\n\t\t\t\t\t\t`withCommit: aggregate ${String(agg.id)} recorded events but ` +\n\t\t\t\t\t\t\t`did not advance its version beyond the persisted version ` +\n\t\t\t\t\t\t\t`(${String(record.persistedVersion)}). An eventful commit needs a unique ` +\n\t\t\t\t\t\t\t`cursor; use AggregateRoot.commit(currentState, event) instead ` +\n\t\t\t\t\t\t\t`of addDomainEvent(event) alone.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn record.events.map((event, index) => {\n\t\t\t\t\tif (!isMintedEvent(event)) {\n\t\t\t\t\t\tthrow new EventHarvestError(\n\t\t\t\t\t\t\t`withCommit: event \"${event.type}\" has not been recorded. ` +\n\t\t\t\t\t\t\t\t\"Call recordPendingEvents(aggregate, createStamp) in the \" +\n\t\t\t\t\t\t\t\t\"application shell before persistence or outbox harvest.\",\n\t\t\t\t\t\t\tevent.type,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tconst recordedEvent = event as Evt;\n\t\t\t\t\tconst commitSize = record.events.length;\n\t\t\t\t\tconst aggregateId = recordedEvent.aggregateId;\n\t\t\t\t\tconst aggregateType = recordedEvent.aggregateType;\n\t\t\t\t\tconst missing: string[] = [];\n\t\t\t\t\tif (!aggregateId) missing.push(\"aggregateId\");\n\t\t\t\t\tif (!aggregateType) missing.push(\"aggregateType\");\n\t\t\t\t\tif (!aggregateId || !aggregateType) {\n\t\t\t\t\t\tthrow new EventHarvestError(\n\t\t\t\t\t\t\t`withCommit: event \"${recordedEvent.type}\" is missing ${missing.join(\n\t\t\t\t\t\t\t\t\" and \",\n\t\t\t\t\t\t\t)}. ` +\n\t\t\t\t\t\t\t\t`Use this.createEvent(type, payload) inside aggregate methods ` +\n\t\t\t\t\t\t\t\t`instead of createDomainEvent(...); createEvent auto-injects ` +\n\t\t\t\t\t\t\t\t`aggregateId and aggregateType. Outbox dispatchers and ` +\n\t\t\t\t\t\t\t\t`projection handlers rely on the envelope source.`,\n\t\t\t\t\t\t\trecordedEvent.type,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\tevent: recordedEvent,\n\t\t\t\t\t\tsource: Object.freeze({ aggregateId, aggregateType }),\n\t\t\t\t\t\tposition: Object.freeze({\n\t\t\t\t\t\t\taggregateVersion: record.version as number,\n\t\t\t\t\t\t\tcommitSequence: index,\n\t\t\t\t\t\t\tcommitSize,\n\t\t\t\t\t\t}),\n\t\t\t\t\t}) as EventCommitCandidate<Evt>;\n\t\t\t\t});\n\t\t\t});\n\t\t\tif (candidates.length > 0) {\n\t\t\t\tawait deps.outbox.add(candidates);\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tresult: fnResult.result,\n\t\t\t\tcommitRecords,\n\t\t\t\tevents: candidates.map(({ event }) => event),\n\t\t\t};\n\t\t},\n\t\t{ signal: deps.signal },\n\t);\n\n\t// Post-commit: capture the persisted versions, acknowledge every saved\n\t// aggregate, and discard pending events for deleted aggregates through the\n\t// non-exported capability.\n\t// Done AFTER the tx commits so a rolled-back transaction never silently\n\t// \"consumes\" the in-memory pending events. A deleted row does not trigger\n\t// the saved-only application observer.\n\tconst persistedObservations: Array<{\n\t\treadonly aggregate: IAggregateRoot<Id<string>, Evt>;\n\t\treadonly version: Version;\n\t}> = [];\n\tfor (const {\n\t\taggregate,\n\t\teventLifecycle,\n\t\tdisposition,\n\t\tversion,\n\t\tevents: committedEvents,\n\t} of commitRecords) {\n\t\ttry {\n\t\t\tif (disposition === \"deleted\") {\n\t\t\t\teventLifecycle.discardPendingEvents(committedEvents);\n\t\t\t} else {\n\t\t\t\teventLifecycle.acknowledge(committedEvents, version as number);\n\t\t\t\tpersistedObservations.push({ aggregate, version });\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// An aggregate can still be made hostile at runtime, for example by\n\t\t\t// freezing it after construction. The transaction has committed, so\n\t\t\t// continue cleaning peers and report the failed acknowledgement rather\n\t\t\t// than rejecting a successful write or double-emitting peer events.\n\t\t\treportToObserver(() => deps.onPersistError?.(error, aggregate));\n\t\t}\n\t}\n\n\t// Application observers run only after every commit record has completed\n\t// its acknowledgement attempt, and only for successful acknowledgements.\n\t// A slow or failing observer can therefore never prevent peer cleanup. Each\n\t// observer receives the version captured before any observer ran, so an\n\t// earlier callback cannot rewrite a later callback's commit receipt.\n\tconst postCommitDeadlineAt = Date.now() + postCommitTimeoutMs;\n\tconst onPersisted = deps.onPersisted;\n\tif (onPersisted) {\n\t\tfor (const { aggregate, version } of persistedObservations) {\n\t\t\ttry {\n\t\t\t\tawait runBoundedExecution(\n\t\t\t\t\t\"withCommit.onPersisted\",\n\t\t\t\t\t{ signal: deps.signal, deadlineAt: postCommitDeadlineAt },\n\t\t\t\t\t(context) => onPersisted(aggregate, version, context),\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\treportToObserver(() => deps.onPersistError?.(error, aggregate));\n\t\t\t}\n\t\t}\n\t}\n\n\tconst bus = deps.bus;\n\tif (bus && events.length > 0) {\n\t\ttry {\n\t\t\tawait runBoundedExecution(\n\t\t\t\t\"withCommit.bus.publish\",\n\t\t\t\t{ signal: deps.signal, deadlineAt: postCommitDeadlineAt },\n\t\t\t\t(context) =>\n\t\t\t\t\tbus.publish(events, {\n\t\t\t\t\t\tsignal: context.signal,\n\t\t\t\t\t\ttimeoutMs: Math.max(0, context.deadlineAt - Date.now()),\n\t\t\t\t\t}),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\t// The tx has committed and the outbox holds the events; an\n\t\t\t// outbox dispatcher will deliver them. Rejecting here would turn\n\t\t\t// a committed write into an apparent use-case failure (callers\n\t\t\t// would retry and double-execute). A throwing OR async-rejecting\n\t\t\t// observer is neutralised so it cannot break the invariant either.\n\t\t\treportToObserver(() => deps.onPublishError?.(error, events));\n\t\t}\n\t}\n\n\treturn result;\n}\n","import type { AnyDomainEvent } from \"../aggregate/domain-event\";\nimport {\n\tEventHarvestError,\n\tIdempotencyReconciliationRequiredError,\n} from \"../core/errors\";\nimport type { TransactionScope } from \"../repo/scope\";\nimport { reportToObserver } from \"../utils/observer\";\nimport {\n\ttype CommitEnrollment,\n\ttype WithCommitDeps,\n\ttype WithCommitWorkResult,\n\twithCommit,\n} from \"./handler\";\n\n/**\n * Result of `IdempotencyStore.claim()`: this execution owns the key and must\n * run the command (`claimed`), a previous execution completed and its outcome\n * is replayed (`completed`), or an expired staged outcome needs evidence from\n * the authoritative write model (`reconciliation-required`).\n *\n * The two FAILURE answers are thrown, not returned, following the kit's\n * error posture: a concurrent unfinished execution throws\n * `IdempotencyInFlightError` (retryable), and the same key arriving\n * with a different fingerprint throws `IdempotencyKeyReuseError`\n * (not retryable).\n */\nexport interface IdempotencyLease {\n\t/** Adapter-clock expiry as a canonical ISO-8601 timestamp. */\n\treadonly expiresAt: string;\n\t/** Delay after which the wrapper should renew this lease. */\n\treadonly renewAfterMs: number;\n}\n\n/** Store-minted ownership receipt for one successful claim. */\nexport interface IdempotencyClaimHandle {\n\treadonly key: string;\n\t/** Unique across ownership generations for this key; treat as opaque. */\n\treadonly token: string;\n\t/** Absent for a transactional store; required for a leased store. */\n\treadonly lease?: IdempotencyLease;\n}\n\n/** Receipt for an expired staged outcome that needs authoritative evidence. */\nexport interface IdempotencyReconciliation {\n\treadonly key: string;\n\treadonly fingerprint: string;\n\treadonly token: string;\n\treadonly expiredAt: string;\n}\n\nexport type IdempotencyReconciliationDecision =\n\t| \"committed\"\n\t| \"not-committed\"\n\t| \"unknown\";\n\nexport type IdempotencyClaim =\n\t| { readonly status: \"claimed\"; readonly claim: IdempotencyClaimHandle }\n\t| { readonly status: \"completed\"; readonly outcome: unknown }\n\t| {\n\t\t\treadonly status: \"reconciliation-required\";\n\t\t\treadonly reconciliation: IdempotencyReconciliation;\n\t };\n\n/**\n * Driven port for command idempotency and message-inbox deduplication.\n *\n * The store keeps one record per idempotency key: the key, a\n * fingerprint of the command that first claimed it, and, once the\n * execution completed, the stored outcome. The intended integration is\n * the SINGLE-TRANSACTION pattern via {@link withIdempotentCommit}: the\n * record is written in the same transaction as the aggregate and the\n * outbox, so a rollback releases the claim and there is no crash window\n * between claim and commit.\n *\n * Adapter contract (mirror of the repository/event-store delegation\n * model): the adapter maps its store's native signals onto the kit's\n * errors instead of leaking driver errors:\n *\n * - unique-constraint conflict from a CONCURRENT uncommitted claim ->\n * `IdempotencyInFlightError` (retryable; a retry replays the outcome\n * or claims fresh),\n * - existing COMPLETED record with the same fingerprint -> return\n * `{ status: \"completed\", outcome }`,\n * - existing record with a DIFFERENT fingerprint ->\n * `IdempotencyKeyReuseError`.\n *\n * **Transactional vs leased non-transactional stores.** A transactional\n * adapter (the record lives in the same database as the aggregate)\n * gets the commit boundary for free: `complete` is atomic with the\n * command's commit, a rollback releases everything, and `confirm` /\n * `abandon` / `renew` / `reconcile` are no-ops. This remains the recommended\n * production pattern and the only family that proves atomic command effect +\n * idempotency completion without reconciliation.\n *\n * A NON-transactional store (the in-memory reference, a separate durable\n * store) cannot see commits or rollbacks. Every fresh claim therefore returns\n * a store-minted token and bounded lease. The wrapper renews it while the\n * transaction runs; `complete`, `renew`, `confirm`, `abandon`, and `reconcile`\n * compare the token so a stale owner cannot mutate a successor claim. An\n * expired PENDING claim may be replaced. An expired STAGED outcome is never\n * replayed or released automatically: `claim` returns\n * `reconciliation-required`, and the application must consult the source of\n * truth. `unknown` keeps it blocked.\n *\n * A lease is coordination, not a security or exactly-once boundary. To return\n * `not-committed` safely, the source transaction must persist an idempotency\n * key or claim token (available as the callback's `execution` argument), or\n * offer equivalent durable fencing proving the old transaction cannot still\n * commit. Without that evidence, return `unknown`. A database row merely being\n * absent while an old transaction may still be in flight is not proof.\n * A takeover can overlap briefly with the stale worker, so `fn` must keep\n * irreversible external side effects out of the transaction. Persist an\n * outbox record and deliver after commit; token fencing can stop the stale\n * database commit, but it cannot undo an HTTP call already sent.\n *\n * The same store doubles as a message INBOX: use the message id as the\n * key and a constant fingerprint; a duplicate delivery replays the\n * stored (possibly `undefined`) outcome instead of re-running the\n * handler.\n *\n * The stored outcome must be PLAIN, serialisable data (the same\n * discipline as snapshots and event payloads): the record round-trips\n * through the adapter's storage, so class instances would silently lose\n * their prototype.\n *\n * @template TCtx - The transaction context the surrounding scope\n * exposes (Drizzle `tx`, Prisma `tx`, `undefined` for context-free\n * scopes). `claim` and `complete` run inside that transaction.\n */\nexport interface IdempotencyStore<TCtx = unknown> {\n\t/**\n\t * Claims the key for this execution, atomically with respect to\n\t * concurrent claimers (`INSERT ... ON CONFLICT` or equivalent).\n\t * Returns `claimed` when this execution owns the key, or\n\t * `completed` with the stored outcome when a previous execution\n\t * already finished under the same key and fingerprint. Throws\n\t * `IdempotencyInFlightError` / `IdempotencyKeyReuseError` for the\n\t * failure answers (see the port docs). A live staged outcome is in-flight;\n\t * after its lease expires it returns `reconciliation-required`, never a\n\t * replay or fresh claim.\n\t */\n\tclaim(ctx: TCtx, key: string, fingerprint: string): Promise<IdempotencyClaim>;\n\n\t/**\n\t * Stores the outcome for a key this execution claimed, in the same\n\t * transaction as the command's writes. On a transactional store the\n\t * commit makes it durable and replayable; on a non-transactional\n\t * store the outcome is only STAGED until {@link confirm} runs.\n\t * Throws `IdempotencyCompletionWithoutClaimError` when no claim exists, and\n\t * `IdempotencyClaimLostError` when the receipt is stale, already settled, or\n\t * expired. A stale completion must fail before the source transaction can\n\t * commit.\n\t */\n\tcomplete(\n\t\tctx: TCtx,\n\t\tclaim: IdempotencyClaimHandle,\n\t\toutcome: unknown,\n\t): Promise<void>;\n\n\t/**\n\t * Extends a non-transactional claim's lease and returns its new timing.\n\t * The update is compare-and-set on key + token. A transactional adapter\n\t * implements this as a no-op returning `undefined`; the wrapper never calls\n\t * it for a claim without a lease.\n\t */\n\trenew(claim: IdempotencyClaimHandle): Promise<IdempotencyLease | undefined>;\n\n\t/**\n\t * Finalizes a staged outcome AFTER the surrounding transaction\n\t * committed. Called by {@link withIdempotentCommit} post-commit on\n\t * every fresh execution. A transactional adapter implements this as\n\t * a no-op (the commit already finalized the record). Idempotent:\n\t * confirming an already-confirmed receipt is a no-op. A missing or stale\n\t * receipt is also a no-op and must never confirm its successor.\n\t */\n\tconfirm(claim: IdempotencyClaimHandle): Promise<void>;\n\n\t/**\n\t * Releases a claim whose attempt did not commit: a pending claim or\n\t * a staged, unconfirmed outcome. Called by\n\t * {@link withIdempotentCommit} once per failed attempt, best-effort.\n\t * A transactional adapter implements this as a no-op: the rollback\n\t * already removed the row, and the method must be SAFE to call when\n\t * the commit outcome is unknown; it never releases a confirmed\n\t * record. A stale receipt is a no-op and must never release its successor.\n\t */\n\tabandon(claim: IdempotencyClaimHandle): Promise<void>;\n\n\t/**\n\t * Resolves an EXPIRED staged outcome after the application consulted its\n\t * authoritative write model. `committed` makes the staged result replayable;\n\t * `not-committed` releases it for a fresh execution. `unknown` is\n\t * intentionally not accepted here: uncertainty must preserve the record.\n\t * The receipt is compare-and-set so a stale reconciler cannot settle a newer\n\t * owner. Transactional adapters implement this as a no-op because they never\n\t * return `reconciliation-required`.\n\t */\n\treconcile(\n\t\treconciliation: IdempotencyReconciliation,\n\t\tdecision: Exclude<IdempotencyReconciliationDecision, \"unknown\">,\n\t): Promise<void>;\n}\n\n/** Identifies one logical command execution for {@link withIdempotentCommit}. */\nexport interface IdempotentCommitRequest {\n\t/**\n\t * The idempotency key: client-supplied header, message id, or a key\n\t * derived from actor + intention. One key names one logical command.\n\t */\n\treadonly key: string;\n\t/**\n\t * Fingerprint of the command's content (a hash or canonical string\n\t * of the request payload). Detects the same key being reused for a\n\t * DIFFERENT command, which is rejected instead of replayed.\n\t */\n\treadonly fingerprint: string;\n}\n\n/**\n * Outcome of {@link withIdempotentCommit}: `replayed: false` carries the\n * fresh result of this execution; `replayed: true` carries the stored\n * outcome of the previous execution with the same key and fingerprint.\n * The replayed value is typed `R` on the strength of the fingerprint\n * match: the same command was executed, so the stored outcome has the\n * shape this command produces, provided the adapter round-trips plain\n * data faithfully.\n */\nexport interface IdempotentCommitResult<R> {\n\treadonly replayed: boolean;\n\treadonly result: R;\n}\n\n/** Claim identity visible to work that persists a source-of-truth marker. */\nexport interface IdempotentExecution extends IdempotentCommitRequest {\n\treadonly claimToken: string;\n}\n\nexport interface IdempotencyOperationErrorContext {\n\treadonly operation: \"abandon\" | \"confirm\" | \"renew\";\n\treadonly key: string;\n\treadonly token: string;\n}\n\nexport interface WithIdempotentCommitDeps<Evt extends AnyDomainEvent, TCtx>\n\textends WithCommitDeps<Evt, TCtx> {\n\tidempotency: IdempotencyStore<TCtx>;\n\t/**\n\t * Source-of-truth decision for an expired staged outcome. The callback must\n\t * return `committed` only when the command effect is durably visible, and\n\t * `not-committed` only when a durable marker proves the attempt cannot still\n\t * commit. `unknown` keeps the key blocked.\n\t */\n\treconcileIdempotency?: (\n\t\treconciliation: IdempotencyReconciliation,\n\t\tctx: TCtx,\n\t) => Promise<IdempotencyReconciliationDecision>;\n\t/**\n\t * Observer for best-effort post-commit confirm, rollback abandon, and a\n\t * secondary heartbeat failure masked by the primary work error.\n\t */\n\tonIdempotencyError?: (\n\t\terror: unknown,\n\t\tcontext: IdempotencyOperationErrorContext,\n\t) => void;\n}\n\ninterface LeaseHeartbeat {\n\tstop(): Promise<void>;\n\tfailure(): unknown | undefined;\n}\n\nfunction validRenewAfterMs(value: number): boolean {\n\treturn Number.isSafeInteger(value) && value > 0 && value <= 2_147_483_647;\n}\n\nfunction startLeaseHeartbeat<TCtx>(\n\tstore: IdempotencyStore<TCtx>,\n\tclaim: IdempotencyClaimHandle,\n): LeaseHeartbeat | undefined {\n\tif (!claim.lease) return undefined;\n\tlet stopped = false;\n\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\tlet inFlight: Promise<void> = Promise.resolve();\n\tlet heartbeatFailure: unknown | undefined;\n\n\tconst schedule = (delayMs: number): void => {\n\t\tif (!validRenewAfterMs(delayMs)) {\n\t\t\theartbeatFailure = new TypeError(\n\t\t\t\t\"IdempotencyStore returned an invalid lease renewAfterMs; expected a positive safe integer no greater than 2147483647\",\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\ttimer = setTimeout(() => {\n\t\t\tinFlight = store\n\t\t\t\t.renew(claim)\n\t\t\t\t.then((lease) => {\n\t\t\t\t\tif (!lease) {\n\t\t\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\t\t\"IdempotencyStore returned no lease while renewing a leased claim\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tif (stopped) return;\n\t\t\t\t\tschedule(lease.renewAfterMs);\n\t\t\t\t})\n\t\t\t\t.catch((error: unknown) => {\n\t\t\t\t\theartbeatFailure = error;\n\t\t\t\t});\n\t\t}, delayMs);\n\t};\n\n\tschedule(claim.lease.renewAfterMs);\n\treturn {\n\t\tstop: async () => {\n\t\t\tstopped = true;\n\t\t\tif (timer !== undefined) clearTimeout(timer);\n\t\t\tawait inFlight;\n\t\t},\n\t\tfailure: () => heartbeatFailure,\n\t};\n}\n\nfunction scopeWorkEnrollment<Evt extends AnyDomainEvent>(\n\tparent: CommitEnrollment<Evt>,\n): { readonly enrollment: CommitEnrollment<Evt>; close(): void } {\n\tlet open = true;\n\tconst assertOpen = (): void => {\n\t\tif (!open) {\n\t\t\tthrow new EventHarvestError(\n\t\t\t\t\"withIdempotentCommit: commit enrollment was used after the \" +\n\t\t\t\t\t\"user work callback settled. Await every repository write before \" +\n\t\t\t\t\t\"returning from the callback.\",\n\t\t\t);\n\t\t}\n\t};\n\n\treturn {\n\t\tenrollment: Object.freeze({\n\t\t\tenrollSaved: (\n\t\t\t\taggregate: Parameters<CommitEnrollment<Evt>[\"enrollSaved\"]>[0],\n\t\t\t) => {\n\t\t\t\tassertOpen();\n\t\t\t\treturn parent.enrollSaved(aggregate);\n\t\t\t},\n\t\t\tenrollDeleted: (\n\t\t\t\taggregate: Parameters<CommitEnrollment<Evt>[\"enrollDeleted\"]>[0],\n\t\t\t) => {\n\t\t\t\tassertOpen();\n\t\t\t\treturn parent.enrollDeleted(aggregate);\n\t\t\t},\n\t\t}),\n\t\tclose: () => {\n\t\t\topen = false;\n\t\t},\n\t};\n}\n\n/**\n * {@link withCommit} with command idempotency: the duplicate-safe write\n * path for retryable deliveries (client retries, at-least-once\n * messages, scheduler re-runs).\n *\n * Order of operations:\n * 1. Inside the transaction, `store.claim(ctx, key, fingerprint)` runs\n * FIRST. A completed execution short-circuits without touching the domain.\n * An expired staged outcome invokes `reconcileIdempotency`; `committed`\n * replays it, `not-committed` releases and claims fresh, and `unknown` (or\n * no callback) throws `IdempotencyReconciliationRequiredError` without\n * changing the store.\n * 2. A fresh claim carries an opaque ownership token. For a leased store the\n * wrapper renews it at `renewAfterMs` until the transaction callback is\n * ready to commit. A renewal failure rejects before commit and releases\n * the claim. `fn(ctx, enrollment, execution)` receives the same token so a\n * source-side marker can make later reconciliation conclusive.\n * 3. `store.complete(ctx, claim, fn's result)` stages or completes the outcome\n * in the same transaction as aggregate writes and outbox. The enrollment\n * capability is sealed and its token array copied before `complete` can\n * yield, so leaked callback state cannot change the harvest receipt.\n * 4. After commit, `store.confirm(claim)` finalizes a leased store's staged\n * outcome; it is a no-op for transactional stores. A failure cannot reject\n * an already committed write, so it is sent to `onIdempotencyError` and the\n * record later enters reconciliation after lease expiry.\n * 5. Any pre-commit failure releases that exact token through\n * `store.abandon(claim)` before leaving the transactional region. A stale\n * abandon cannot release a successor. Secondary abandon/renew failures are\n * observable but never mask the primary error.\n *\n * Composes with `RetryingTransactionScope`: a retryable failure inside\n * one attempt releases that attempt's claim, and the retry either\n * executes fresh or, when a concurrent execution completed meanwhile,\n * replays its confirmed outcome. A concurrent duplicate while the first\n * execution is still running surfaces as `IdempotencyInFlightError`\n * (retryable); unwrapped, map it to a conflict/retry-later application\n * outcome.\n *\n * The stored outcome is `fn`'s `result` value; it must be plain, serialisable\n * data (see {@link IdempotencyStore}). Transactional storage remains the\n * production default. Leases make the non-transactional family recoverable;\n * they do not manufacture an atomic exactly-once boundary across two stores.\n */\nexport async function withIdempotentCommit<Evt extends AnyDomainEvent, R, TCtx>(\n\tdeps: WithIdempotentCommitDeps<Evt, TCtx>,\n\trequest: IdempotentCommitRequest,\n\tfn: (\n\t\tctx: TCtx,\n\t\tenrollment: CommitEnrollment<Evt>,\n\t\texecution: IdempotentExecution,\n\t) => Promise<WithCommitWorkResult<Evt, R>>,\n): Promise<IdempotentCommitResult<R>> {\n\tconst store = deps.idempotency;\n\tconst attempt: {\n\t\tclaim: IdempotencyClaimHandle | undefined;\n\t\theartbeat: LeaseHeartbeat | undefined;\n\t} = { claim: undefined, heartbeat: undefined };\n\n\t// Decorator around the caller's scope: releases the current\n\t// attempt's claim before an error leaves the transactional region.\n\t// This is the only place that sees EVERY failure point of one\n\t// attempt (the work, withCommit's harvest guards, the outbox write),\n\t// including the ones outside this module's own callback, and it runs\n\t// INSIDE a retrying scope's loop, so the next attempt starts clean.\n\tconst scope: TransactionScope<TCtx> = {\n\t\ttransactional: async (work, options) => {\n\t\t\ttry {\n\t\t\t\treturn await deps.scope.transactional(async (ctx) => {\n\t\t\t\tattempt.claim = undefined;\n\t\t\t\tattempt.heartbeat = undefined;\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await work(ctx);\n\t\t\t\t\tconst currentHeartbeat = attempt.heartbeat as\n\t\t\t\t\t\t| LeaseHeartbeat\n\t\t\t\t\t\t| undefined;\n\t\t\t\t\tawait currentHeartbeat?.stop();\n\t\t\t\t\tconst heartbeatFailure = currentHeartbeat?.failure();\n\t\t\t\t\tif (heartbeatFailure !== undefined) throw heartbeatFailure;\n\t\t\t\t\treturn result;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst currentHeartbeat = attempt.heartbeat as\n\t\t\t\t\t\t| LeaseHeartbeat\n\t\t\t\t\t\t| undefined;\n\t\t\t\t\tawait currentHeartbeat?.stop();\n\t\t\t\t\tconst heartbeatFailure = currentHeartbeat?.failure();\n\t\t\t\t\tconst currentClaim = attempt.claim as\n\t\t\t\t\t\t| IdempotencyClaimHandle\n\t\t\t\t\t\t| undefined;\n\t\t\t\t\tif (\n\t\t\t\t\t\theartbeatFailure !== undefined &&\n\t\t\t\t\t\theartbeatFailure !== error &&\n\t\t\t\t\t\tcurrentClaim\n\t\t\t\t\t) {\n\t\t\t\t\t\treportToObserver(() =>\n\t\t\t\t\t\t\tdeps.onIdempotencyError?.(heartbeatFailure, {\n\t\t\t\t\t\t\t\toperation: \"renew\",\n\t\t\t\t\t\t\t\tkey: currentClaim.key,\n\t\t\t\t\t\t\t\ttoken: currentClaim.token,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tconst abandoned = attempt.claim as IdempotencyClaimHandle | undefined;\n\t\t\t\t\tif (abandoned) {\n\t\t\t\t\t\tattempt.claim = undefined;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait store.abandon(abandoned);\n\t\t\t\t\t\t} catch (abandonError) {\n\t\t\t\t\t\t\t// Best-effort release: the abandon failure must not\n\t\t\t\t\t\t\t// mask the attempt's error. Transactional stores\n\t\t\t\t\t\t\t// release via rollback anyway; a leased store can\n\t\t\t\t\t\t\t// recover after expiry. The observer keeps the\n\t\t\t\t\t\t\t// secondary operational failure visible.\n\t\t\t\t\t\t\treportToObserver(() =>\n\t\t\t\t\t\t\t\tdeps.onIdempotencyError?.(abandonError, {\n\t\t\t\t\t\t\t\t\toperation: \"abandon\",\n\t\t\t\t\t\t\t\t\tkey: abandoned.key,\n\t\t\t\t\t\t\t\t\ttoken: abandoned.token,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}, options);\n\t\t\t} catch (error) {\n\t\t\t\t// COMMIT-time failure: the driver rejected AFTER the callback\n\t\t\t\t// resolved, so the catch above never saw it and the staged\n\t\t\t\t// claim would stay wedged until lease expiry (and demand\n\t\t\t\t// reconciliation after). The store contract declares abandon\n\t\t\t\t// safe when the commit outcome is unknown: a transactional\n\t\t\t\t// store's claim died with the rollback anyway, and a leased\n\t\t\t\t// store releases the lease while the durable outcome record\n\t\t\t\t// still decides replay on the next attempt.\n\t\t\t\tconst staged = attempt.claim as IdempotencyClaimHandle | undefined;\n\t\t\t\tif (staged) {\n\t\t\t\t\tattempt.claim = undefined;\n\t\t\t\t\tattempt.heartbeat = undefined;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait store.abandon(staged);\n\t\t\t\t\t} catch (abandonError) {\n\t\t\t\t\t\treportToObserver(() =>\n\t\t\t\t\t\t\tdeps.onIdempotencyError?.(abandonError, {\n\t\t\t\t\t\t\t\toperation: \"abandon\",\n\t\t\t\t\t\t\t\tkey: staged.key,\n\t\t\t\t\t\t\t\ttoken: staged.token,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\t};\n\n\tconst outcome = await withCommit<Evt, IdempotentCommitResult<R>, TCtx>(\n\t\t{ ...deps, scope },\n\t\tasync (ctx, enrollment) => {\n\t\t\tlet claim = await store.claim(ctx, request.key, request.fingerprint);\n\t\t\tif (claim.status === \"reconciliation-required\") {\n\t\t\t\tconst decision = deps.reconcileIdempotency\n\t\t\t\t\t? await deps.reconcileIdempotency(claim.reconciliation, ctx)\n\t\t\t\t\t: \"unknown\";\n\t\t\t\tif (decision === \"unknown\") {\n\t\t\t\t\tthrow new IdempotencyReconciliationRequiredError(\n\t\t\t\t\t\tclaim.reconciliation,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (decision !== \"committed\" && decision !== \"not-committed\") {\n\t\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\t\"reconcileIdempotency must return committed, not-committed, or unknown\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tawait store.reconcile(claim.reconciliation, decision);\n\t\t\t\tclaim = await store.claim(ctx, request.key, request.fingerprint);\n\t\t\t\tif (claim.status === \"reconciliation-required\") {\n\t\t\t\t\tthrow new IdempotencyReconciliationRequiredError(\n\t\t\t\t\t\tclaim.reconciliation,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (claim.status === \"completed\") {\n\t\t\t\treturn {\n\t\t\t\t\tresult: { replayed: true, result: claim.outcome as R },\n\t\t\t\t\tcommits: [],\n\t\t\t\t};\n\t\t\t}\n\t\t\tattempt.claim = claim.claim;\n\t\t\tattempt.heartbeat = startLeaseHeartbeat(store, claim.claim);\n\t\t\tconst workEnrollment = scopeWorkEnrollment(enrollment);\n\t\t\tlet work: WithCommitWorkResult<Evt, R>;\n\t\t\ttry {\n\t\t\t\twork = await fn(ctx, workEnrollment.enrollment, {\n\t\t\t\t\tkey: request.key,\n\t\t\t\t\tfingerprint: request.fingerprint,\n\t\t\t\t\tclaimToken: claim.claim.token,\n\t\t\t\t});\n\t\t\t} finally {\n\t\t\t\tworkEnrollment.close();\n\t\t\t}\n\t\t\t// Snapshot the user-controlled receipt before complete() yields. A\n\t\t\t// leaked mutable array must not be able to add or remove aggregate\n\t\t\t// commits while the idempotency adapter is persisting the outcome.\n\t\t\tconst result = work.result;\n\t\t\tconst commits = Array.isArray(work.commits)\n\t\t\t\t? Object.freeze([...work.commits])\n\t\t\t\t: work.commits;\n\t\t\tawait store.complete(ctx, claim.claim, result);\n\t\t\treturn {\n\t\t\t\tresult: { replayed: false, result },\n\t\t\t\tcommits,\n\t\t\t};\n\t\t},\n\t);\n\n\tif (!outcome.replayed) {\n\t\t// Post-commit finalize: flips a leased store's staged\n\t\t// outcome to confirmed so only committed outcomes ever replay.\n\t\t// No-op for transactional stores. Runs after the commit, so a\n\t\t// throw here must not reject the committed write. The staged record\n\t\t// remains in-flight until lease expiry and then requires an\n\t\t// authoritative reconciliation decision.\n\t\tconst committedClaim = attempt.claim as IdempotencyClaimHandle | undefined;\n\t\tif (!committedClaim) {\n\t\t\tthrow new EventHarvestError(\n\t\t\t\t\"withIdempotentCommit: a fresh result committed without its claim receipt.\",\n\t\t\t);\n\t\t}\n\t\ttry {\n\t\t\tawait store.confirm(committedClaim);\n\t\t} catch (confirmError) {\n\t\t\t// Swallowed by the post-commit invariant: the write has committed.\n\t\t\t// Report it so the staged record enters the reconciliation path\n\t\t\t// visibly instead of becoming a silent permanent blockage.\n\t\t\treportToObserver(() =>\n\t\t\t\tdeps.onIdempotencyError?.(confirmError, {\n\t\t\t\t\toperation: \"confirm\",\n\t\t\t\t\tkey: committedClaim.key,\n\t\t\t\t\ttoken: committedClaim.token,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t}\n\treturn outcome;\n}\n","import {\n\tIdempotencyClaimLostError,\n\tIdempotencyCompletionWithoutClaimError,\n\tIdempotencyInFlightError,\n\tIdempotencyKeyReuseError,\n\tInMemoryCapacityExceededError,\n} from \"../core/errors\";\nimport { assertPositiveSafeInteger } from \"../utils/validate\";\nimport type {\n\tIdempotencyClaim,\n\tIdempotencyClaimHandle,\n\tIdempotencyLease,\n\tIdempotencyReconciliation,\n\tIdempotencyReconciliationDecision,\n\tIdempotencyStore,\n} from \"./idempotency\";\n\ninterface PendingEntry {\n\treadonly fingerprint: string;\n\treadonly status: \"pending\";\n\treadonly token: string;\n\treadonly expiresAtMs: number;\n}\n\ninterface StagedEntry {\n\treadonly fingerprint: string;\n\treadonly status: \"staged\";\n\treadonly token: string;\n\treadonly expiresAtMs: number;\n\treadonly outcome: unknown;\n}\n\ninterface ConfirmedEntry {\n\treadonly fingerprint: string;\n\treadonly status: \"confirmed\";\n\treadonly token: string;\n\treadonly outcome: unknown;\n}\n\ntype IdempotencyEntry = PendingEntry | StagedEntry | ConfirmedEntry;\n\nexport interface InMemoryIdempotencyStoreOptions {\n\t/** Store-local clock. Durable adapters should prefer server/database time. */\n\treadonly clock?: () => Date;\n\t/** Token component source; an internal generation keeps ownership unique. */\n\treadonly claimTokenFactory?: () => string;\n\t/** Lease lifetime for pending and staged records. Default: 30 seconds. */\n\treadonly leaseDurationMs?: number;\n\t/** Heartbeat delay advertised to the wrapper. Default: half the lease. */\n\treadonly renewAfterMs?: number;\n\t/** Maximum number of pending, staged, and confirmed records. */\n\treadonly maxEntries?: number;\n}\n\nconst DEFAULT_LEASE_DURATION_MS = 30_000;\n\nfunction positiveSafeInteger(value: number): boolean {\n\treturn Number.isSafeInteger(value) && value > 0;\n}\n\n/**\n * In-memory reference implementation of {@link IdempotencyStore} for\n * finite-lifetime tests and demos. Without `maxEntries`, every confirmed\n * receipt remains reachable for the lifetime of the instance. A long-lived\n * process must configure the limit or use a durable adapter; exhaustion\n * rejects new keys before mutation and never forgets an idempotency decision.\n *\n * It is deliberately not transaction-aware. Claims and staged outcomes carry\n * bounded leases, while every mutation compares the store-minted token. An\n * expired pending claim may be replaced; an expired staged outcome cannot be\n * guessed away and instead returns `reconciliation-required`. Only an\n * authoritative `committed` / `not-committed` decision can settle it.\n */\nexport class InMemoryIdempotencyStore<TCtx = unknown>\n\timplements IdempotencyStore<TCtx>\n{\n\tprivate readonly entries = new Map<string, IdempotencyEntry>();\n\tprivate readonly clock: () => Date;\n\tprivate readonly claimTokenFactory: () => string;\n\tprivate readonly leaseDurationMs: number;\n\tprivate readonly renewAfterMs: number;\n\tprivate readonly maxEntries: number | undefined;\n\tprivate tokenGeneration = 0;\n\n\tconstructor(options: InMemoryIdempotencyStoreOptions = {}) {\n\t\tthis.clock = options.clock ?? (() => new Date());\n\t\tthis.claimTokenFactory =\n\t\t\toptions.claimTokenFactory ?? (() => globalThis.crypto.randomUUID());\n\t\tthis.leaseDurationMs = options.leaseDurationMs ?? DEFAULT_LEASE_DURATION_MS;\n\t\tthis.renewAfterMs =\n\t\t\toptions.renewAfterMs ?? Math.floor(this.leaseDurationMs / 2);\n\t\tif (options.maxEntries !== undefined) {\n\t\t\tassertPositiveSafeInteger(\n\t\t\t\t\"InMemoryIdempotencyStore\",\n\t\t\t\t\"maxEntries\",\n\t\t\t\toptions.maxEntries,\n\t\t\t);\n\t\t}\n\t\tthis.maxEntries = options.maxEntries;\n\t\tif (\n\t\t\t!positiveSafeInteger(this.leaseDurationMs) ||\n\t\t\tthis.leaseDurationMs > 2_147_483_647\n\t\t) {\n\t\t\tthrow new RangeError(\n\t\t\t\t\"leaseDurationMs must be a positive safe integer no greater than 2147483647\",\n\t\t\t);\n\t\t}\n\t\tif (\n\t\t\t!positiveSafeInteger(this.renewAfterMs) ||\n\t\t\tthis.renewAfterMs >= this.leaseDurationMs ||\n\t\t\tthis.renewAfterMs > 2_147_483_647\n\t\t) {\n\t\t\tthrow new RangeError(\n\t\t\t\t\"renewAfterMs must be a positive safe integer below leaseDurationMs and no greater than 2147483647\",\n\t\t\t);\n\t\t}\n\t}\n\n\tasync claim(\n\t\t_ctx: TCtx,\n\t\tkey: string,\n\t\tfingerprint: string,\n\t): Promise<IdempotencyClaim> {\n\t\tconst now = this.nowMs();\n\t\tconst existing = this.entries.get(key);\n\t\tif (existing === undefined) {\n\t\t\tif (\n\t\t\t\tthis.maxEntries !== undefined &&\n\t\t\t\tthis.entries.size >= this.maxEntries\n\t\t\t) {\n\t\t\t\tthrow new InMemoryCapacityExceededError({\n\t\t\t\t\tstore: \"InMemoryIdempotencyStore\",\n\t\t\t\t\tresource: \"entries\",\n\t\t\t\t\tlimit: this.maxEntries,\n\t\t\t\t\tcurrent: this.entries.size,\n\t\t\t\t\tattempted: 1,\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn this.createPending(key, fingerprint, now);\n\t\t}\n\t\tif (existing.fingerprint !== fingerprint) {\n\t\t\tthrow new IdempotencyKeyReuseError({\n\t\t\t\tkey,\n\t\t\t\tstoredFingerprint: existing.fingerprint,\n\t\t\t\treceivedFingerprint: fingerprint,\n\t\t\t});\n\t\t}\n\t\tif (existing.status === \"confirmed\") {\n\t\t\treturn {\n\t\t\t\tstatus: \"completed\",\n\t\t\t\toutcome: structuredClone(existing.outcome),\n\t\t\t};\n\t\t}\n\t\tif (now < existing.expiresAtMs) {\n\t\t\tthrow new IdempotencyInFlightError({ key });\n\t\t}\n\t\tif (existing.status === \"staged\") {\n\t\t\treturn {\n\t\t\t\tstatus: \"reconciliation-required\",\n\t\t\t\treconciliation: Object.freeze({\n\t\t\t\t\tkey,\n\t\t\t\t\tfingerprint,\n\t\t\t\t\ttoken: existing.token,\n\t\t\t\t\texpiredAt: new Date(existing.expiresAtMs).toISOString(),\n\t\t\t\t}),\n\t\t\t};\n\t\t}\n\t\treturn this.createPending(key, fingerprint, now);\n\t}\n\n\tasync complete(\n\t\t_ctx: TCtx,\n\t\tclaim: IdempotencyClaimHandle,\n\t\toutcome: unknown,\n\t): Promise<void> {\n\t\tconst now = this.nowMs();\n\t\tconst existing = this.entries.get(claim.key);\n\t\tif (existing === undefined) {\n\t\t\tthrow new IdempotencyCompletionWithoutClaimError(claim.key);\n\t\t}\n\t\tif (\n\t\t\texisting.status !== \"pending\" ||\n\t\t\texisting.token !== claim.token ||\n\t\t\tnow >= existing.expiresAtMs\n\t\t) {\n\t\t\tthrow this.claimLost(claim);\n\t\t}\n\t\tconst expiresAtMs = now + this.leaseDurationMs;\n\t\tthis.lease(expiresAtMs);\n\t\tthis.entries.set(claim.key, {\n\t\t\tfingerprint: existing.fingerprint,\n\t\t\tstatus: \"staged\",\n\t\t\ttoken: existing.token,\n\t\t\texpiresAtMs,\n\t\t\toutcome: structuredClone(outcome),\n\t\t});\n\t}\n\n\tasync renew(\n\t\tclaim: IdempotencyClaimHandle,\n\t): Promise<IdempotencyLease | undefined> {\n\t\tconst now = this.nowMs();\n\t\tconst existing = this.entries.get(claim.key);\n\t\tif (\n\t\t\texisting === undefined ||\n\t\t\texisting.status === \"confirmed\" ||\n\t\t\texisting.token !== claim.token ||\n\t\t\tnow >= existing.expiresAtMs\n\t\t) {\n\t\t\tthrow this.claimLost(claim);\n\t\t}\n\t\tconst expiresAtMs = now + this.leaseDurationMs;\n\t\tconst lease = this.lease(expiresAtMs);\n\t\tthis.entries.set(claim.key, { ...existing, expiresAtMs });\n\t\treturn lease;\n\t}\n\n\tasync confirm(claim: IdempotencyClaimHandle): Promise<void> {\n\t\tconst existing = this.entries.get(claim.key);\n\t\tif (existing?.status === \"staged\" && existing.token === claim.token) {\n\t\t\tthis.entries.set(claim.key, {\n\t\t\t\tfingerprint: existing.fingerprint,\n\t\t\t\tstatus: \"confirmed\",\n\t\t\t\ttoken: existing.token,\n\t\t\t\toutcome: existing.outcome,\n\t\t\t});\n\t\t}\n\t}\n\n\tasync abandon(claim: IdempotencyClaimHandle): Promise<void> {\n\t\tconst existing = this.entries.get(claim.key);\n\t\tif (\n\t\t\texisting !== undefined &&\n\t\t\texisting.status !== \"confirmed\" &&\n\t\t\texisting.token === claim.token\n\t\t) {\n\t\t\tthis.entries.delete(claim.key);\n\t\t}\n\t}\n\n\tasync reconcile(\n\t\treconciliation: IdempotencyReconciliation,\n\t\tdecision: Exclude<IdempotencyReconciliationDecision, \"unknown\">,\n\t): Promise<void> {\n\t\tif (decision !== \"committed\" && decision !== \"not-committed\") {\n\t\t\tthrow new TypeError(\n\t\t\t\t\"reconcile decision must be committed or not-committed; uncertainty must leave the record untouched\",\n\t\t\t);\n\t\t}\n\t\tconst existing = this.entries.get(reconciliation.key);\n\t\tif (\n\t\t\texisting === undefined ||\n\t\t\texisting.status !== \"staged\" ||\n\t\t\texisting.token !== reconciliation.token ||\n\t\t\texisting.fingerprint !== reconciliation.fingerprint ||\n\t\t\tnew Date(existing.expiresAtMs).toISOString() !==\n\t\t\t\treconciliation.expiredAt ||\n\t\t\tthis.nowMs() < existing.expiresAtMs\n\t\t) {\n\t\t\tthrow new IdempotencyClaimLostError({\n\t\t\t\tkey: reconciliation.key,\n\t\t\t\ttoken: reconciliation.token,\n\t\t\t});\n\t\t}\n\t\tif (decision === \"committed\") {\n\t\t\tthis.entries.set(reconciliation.key, {\n\t\t\t\tfingerprint: existing.fingerprint,\n\t\t\t\tstatus: \"confirmed\",\n\t\t\t\ttoken: existing.token,\n\t\t\t\toutcome: existing.outcome,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tthis.entries.delete(reconciliation.key);\n\t}\n\n\t/** Test hook: number of stored records in any state. */\n\tget size(): number {\n\t\treturn this.entries.size;\n\t}\n\n\t/** Test hook: drops every record. */\n\tclear(): void {\n\t\tthis.entries.clear();\n\t}\n\n\tprivate createPending(\n\t\tkey: string,\n\t\tfingerprint: string,\n\t\tnow: number,\n\t): IdempotencyClaim {\n\t\tconst tokenPart = this.claimTokenFactory();\n\t\tif (typeof tokenPart !== \"string\" || tokenPart.length === 0) {\n\t\t\tthrow new TypeError(\"claimTokenFactory must return a non-empty string\");\n\t\t}\n\t\tthis.tokenGeneration += 1;\n\t\tif (!Number.isSafeInteger(this.tokenGeneration)) {\n\t\t\tthrow new RangeError(\"idempotency claim-token generation exhausted\");\n\t\t}\n\t\tconst token = `${this.tokenGeneration}:${tokenPart}`;\n\t\tconst expiresAtMs = now + this.leaseDurationMs;\n\t\tconst lease = this.lease(expiresAtMs);\n\t\tthis.entries.set(key, {\n\t\t\tfingerprint,\n\t\t\tstatus: \"pending\",\n\t\t\ttoken,\n\t\t\texpiresAtMs,\n\t\t});\n\t\treturn {\n\t\t\tstatus: \"claimed\",\n\t\t\tclaim: Object.freeze({ key, token, lease }),\n\t\t};\n\t}\n\n\tprivate lease(expiresAtMs: number): IdempotencyLease {\n\t\treturn Object.freeze({\n\t\t\texpiresAt: new Date(expiresAtMs).toISOString(),\n\t\t\trenewAfterMs: this.renewAfterMs,\n\t\t});\n\t}\n\n\tprivate nowMs(): number {\n\t\tconst now = this.clock();\n\t\tconst value = now instanceof Date ? now.getTime() : Number.NaN;\n\t\tif (!Number.isFinite(value)) {\n\t\t\tthrow new TypeError(\"idempotency clock must return a valid Date\");\n\t\t}\n\t\treturn value;\n\t}\n\n\tprivate claimLost(claim: IdempotencyClaimHandle): IdempotencyClaimLostError {\n\t\treturn new IdempotencyClaimLostError({\n\t\t\tkey: claim.key,\n\t\t\ttoken: claim.token,\n\t\t});\n\t}\n}\n","import { ok, type Result } from \"@shirudo/result\";\nimport {\n\ttype ExpectedErrorMapper,\n\thandlerOrThrow,\n\tmapHandlerFailure,\n\tregisterOnce,\n\ttype UntypedMapDispatch,\n} from \"./bus-internals\";\nimport type { Query, QueryHandler } from \"./query\";\n\n/**\n * Internal adapter shape for handlers stored in the map.\n *\n * Registered handlers are typed as `QueryHandler<Q, TMap[K]>` (narrower\n * input, specific return) and cannot be stored directly in a heterogeneous\n * map (function-parameter contravariance). The closure in `register`\n * downcasts `Query` to the handler's expected `Q` based on the\n * dispatch-key invariant (we only call this entry when `query.type` matches\n * the key it was registered under). Result is widened to `unknown` here\n * and narrowed back via the public overloads on `execute` / `executeUnsafe`.\n */\ntype StoredQueryHandler = (query: Query) => Promise<unknown>;\n\n/**\n * Type map for query types to their return types.\n * Used to improve type inference in QueryBus.\n *\n * @example\n * ```typescript\n * type MyQueryMap = {\n * GetOrder: Order | null;\n * ListOrders: Order[];\n * };\n *\n * const bus = new QueryBus<MyQueryMap>();\n * const result = await bus.execute({ type: \"GetOrder\", orderId: \"123\" });\n * // result: Result<Order | null, string> ← automatically inferred\n * ```\n */\ntype QueryTypeMap = Record<string, unknown>;\n\n/**\n * Construction options for {@link QueryBus}.\n *\n * @template E - The error channel type of the bus.\n */\nexport interface QueryBusOptions<E = string> {\n\t/**\n\t * Explicitly recognizes an expected handler failure and maps it into the\n\t * bus's error channel. Return `{ error }` only for failures this boundary\n\t * owns; return `undefined` to rethrow the exact original value. With no\n\t * mapper, every handler throw propagates. Unregistered-handler and nested\n\t * bus wiring errors always propagate.\n\t */\n\tmapExpectedError?: (thrown: unknown) => { readonly error: E } | undefined;\n}\n\n/**\n * Query Bus interface for dispatching queries to their handlers.\n * Provides a centralized way to execute queries with handler registration.\n *\n * Supports an optional type map (`TMap`) for automatic return type inference.\n * Without a type map, the return type must be specified manually or defaults to `unknown`.\n * With a concrete result map, its entry is the only result type for that\n * query; the loose explicit-result overloads are unavailable.\n *\n * @template TMap - Optional mapping from query type strings to return types\n *\n * @example\n * ```typescript\n * // With a type map (recommended): the return type is inferred\n * type MyQueries = { GetOrder: Order | null; ListOrders: Order[] };\n * const bus = new QueryBus<MyQueries>();\n * const result = await bus.execute({ type: \"GetOrder\", orderId: \"123\" });\n * // result: Result<Order | null, string>\n *\n * // Without a type map: the return type defaults to `unknown`\n * const bus = new QueryBus();\n * const result = await bus.execute({ type: \"GetOrder\", orderId: \"123\" });\n * // result: Result<unknown, string>\n * ```\n */\nexport interface IQueryBus<\n\tTMap extends QueryTypeMap = QueryTypeMap,\n\tE = string,\n> {\n\t/**\n\t * Executes a query by dispatching it to the registered handler.\n\t * When a type map is provided, the return type is inferred from the query type.\n\t *\n\t * @param query - The query to execute\n\t * @returns Result containing the query result if successful, or an error of type `E`\n\t * @throws UnregisteredHandlerError when no handler is registered for\n\t * `query.type` (a wiring bug; never delivered through the channel)\n\t * @throws The exact handler failure when `mapExpectedError` is absent or\n\t * returns `undefined`\n\t * @throws ErrorMapperFailedError when `mapExpectedError` fails\n\t */\n\texecute<Q extends Query & { type: keyof TMap & string }>(\n\t\tquery: Q,\n\t): Promise<Result<TMap[Q[\"type\"]], E>>;\n\t// Manual result typing belongs only to the default untyped map shape.\n\texecute<Q extends Query, R>(\n\t\tquery: UntypedMapDispatch<TMap, Q>,\n\t): Promise<Result<R, E>>;\n\n\t/**\n\t * Executes a query by dispatching it to the registered handler.\n\t * Throws an error if no handler is registered.\n\t *\n\t * @param query - The query to execute\n\t * @returns The query result\n\t * @throws The exact handler failure or UnregisteredHandlerError\n\t */\n\texecuteUnsafe<Q extends Query & { type: keyof TMap & string }>(\n\t\tquery: Q,\n\t): Promise<TMap[Q[\"type\"]]>;\n\texecuteUnsafe<Q extends Query, R>(\n\t\tquery: UntypedMapDispatch<TMap, Q>,\n\t): Promise<R>;\n\n\t/**\n\t * Registers a handler for a specific query type.\n\t *\n\t * When `TMap` is supplied, the `queryType` argument is restricted to its\n\t * keys and the handler signature is forced to match `TMap[K]` for the\n\t * return value: typos and wrong-typed handlers are compile errors.\n\t * Without `TMap` the registration is loose (any string key, any return\n\t * type) so the no-config path keeps working.\n\t *\n\t * @param queryType - The query type to register the handler for\n\t * @param handler - The handler function for this query type\n\t */\n\tregister<\n\t\tK extends keyof TMap & string,\n\t\tQ extends Query & { type: K } = Query & { type: K },\n\t>(queryType: K, handler: QueryHandler<Q, TMap[K]>): void;\n}\n\n/**\n * Simple in-memory query bus implementation.\n * Handlers are stored in a Map and dispatched based on query type.\n *\n * Supports an optional type map (`TMap`) for automatic return type inference.\n * When `TMap` is concrete, `execute()` and `executeUnsafe()` infer the result type from the query type.\n * Explicit competing result generics cannot override that map.\n * Without `TMap`, the return type defaults to `unknown` or is specified per call.\n *\n * **Note:** This is a basic implementation suitable for development and simple use cases.\n * For production environments, consider implementing or using a more feature-rich bus that includes:\n * - Middleware/Pipeline support (logging, caching, rate limiting)\n * - Error handling\n * - Timeout handling\n * - Metrics and observability\n * - Query result caching\n * - Rate limiting\n *\n * The `QueryHandler` type can still be used with external production-grade buses\n * (e.g., RabbitMQ, AWS SQS) while maintaining type safety.\n *\n * @template TMap - Optional mapping from query type strings to return types\n *\n * @example\n * ```typescript\n * // With a type map: full inference\n * type Queries = { GetOrder: Order | null; ListOrders: Order[] };\n * const bus = new QueryBus<Queries>();\n * const result = await bus.execute({ type: \"GetOrder\", orderId: \"123\" });\n * // result: Result<Order | null, string>\n *\n * // Without a type map: specify the return type per call\n * const bus = new QueryBus();\n * bus.register(\"GetOrder\", async (query) => repository.findById(query.orderId));\n * const result = await bus.execute({ type: \"GetOrder\", orderId: \"123\" });\n * ```\n */\nexport class QueryBus<TMap extends QueryTypeMap = QueryTypeMap, E = string>\n\timplements IQueryBus<TMap, E>\n{\n\tprivate readonly handlers = new Map<string, StoredQueryHandler>();\n\tprivate readonly mapExpectedError: ExpectedErrorMapper<E> | undefined;\n\n\tconstructor(options?: QueryBusOptions<E>) {\n\t\tthis.mapExpectedError = options?.mapExpectedError;\n\t}\n\n\tregister<\n\t\tK extends keyof TMap & string,\n\t\tQ extends Query & { type: K } = Query & { type: K },\n\t>(queryType: K, handler: QueryHandler<Q, TMap[K]>): void {\n\t\tregisterOnce(this.handlers, \"query\", queryType, (query: Query) =>\n\t\t\thandler(query as Q),\n\t\t);\n\t}\n\n\tasync execute<Q extends Query & { type: keyof TMap & string }>(\n\t\tquery: Q,\n\t): Promise<Result<TMap[Q[\"type\"]], E>>;\n\t// Keep the class surface identical to IQueryBus's untyped fallback.\n\tasync execute<Q extends Query, R>(\n\t\tquery: UntypedMapDispatch<TMap, Q>,\n\t): Promise<Result<R, E>>;\n\tasync execute<Q extends Query, R>(query: Q): Promise<Result<R, E>> {\n\t\tconst handler = handlerOrThrow(this.handlers, \"query\", query.type);\n\t\ttry {\n\t\t\tconst result = (await handler(query)) as R;\n\t\t\treturn ok(result);\n\t\t} catch (error) {\n\t\t\treturn mapHandlerFailure(error, this.mapExpectedError, \"query\");\n\t\t}\n\t}\n\n\tasync executeUnsafe<Q extends Query & { type: keyof TMap & string }>(\n\t\tquery: Q,\n\t): Promise<TMap[Q[\"type\"]]>;\n\tasync executeUnsafe<Q extends Query, R>(\n\t\tquery: UntypedMapDispatch<TMap, Q>,\n\t): Promise<R>;\n\tasync executeUnsafe<Q extends Query, R>(query: Q): Promise<R> {\n\t\t// Same no-handler gate as execute: one implementation so the two\n\t\t// paths cannot drift.\n\t\tconst handler = handlerOrThrow(this.handlers, \"query\", query.type);\n\t\treturn (await handler(query)) as R;\n\t}\n}\n","import type { IAggregateRoot } from \"../aggregate/aggregate\";\nimport type {\n\tAnyDomainEvent,\n\tDomainEventFactory,\n\tDomainEventStamp,\n\tUncommittedDomainEventOf,\n} from \"../aggregate/domain-event\";\nimport { pendingEventRecordingCapabilityFor } from \"../aggregate/pending-event-recording\";\nimport type { Id } from \"../core/id\";\n\n/** Minimal shell role accepted by {@link recordPendingEvents}. */\nexport type DomainEventStampFactory = Pick<DomainEventFactory, \"createStamp\">;\n\n/** Per-decision stamp provider for metadata that depends on the event. */\nexport type DomainEventStampProvider<TEvent extends AnyDomainEvent> = (\n\tevent: UncommittedDomainEventOf<TEvent>,\n\tindex: number,\n) => DomainEventStamp;\n\n/**\n * Records every still-unstamped event accepted by an aggregate.\n *\n * Recording is atomic with respect to the aggregate's pending list: if stamp\n * creation or validation fails, every decision remains unrecorded. A\n * successful second call returns the same event objects and does not read the\n * factory again, which keeps event identity stable across transaction retries.\n *\n * Pass a `DomainEventFactory` (only its `createStamp` role is required) for one\n * uniform recording policy, or a callback when metadata depends on the\n * concrete decision.\n */\nexport function recordPendingEvents<\n\tTId extends Id<string>,\n\tTEvent extends AnyDomainEvent,\n>(\n\taggregate: IAggregateRoot<TId, TEvent>,\n\tfactory: DomainEventStampFactory,\n): ReadonlyArray<TEvent>;\nexport function recordPendingEvents<\n\tTId extends Id<string>,\n\tTEvent extends AnyDomainEvent,\n>(\n\taggregate: IAggregateRoot<TId, TEvent>,\n\tcreateStamp: DomainEventStampProvider<TEvent>,\n): ReadonlyArray<TEvent>;\nexport function recordPendingEvents<\n\tTId extends Id<string>,\n\tTEvent extends AnyDomainEvent,\n>(\n\taggregate: IAggregateRoot<TId, TEvent>,\n\tsource: DomainEventStampFactory | DomainEventStampProvider<TEvent>,\n): ReadonlyArray<TEvent> {\n\tconst capability = pendingEventRecordingCapabilityFor(aggregate);\n\tif (!capability) {\n\t\tthrow new TypeError(\n\t\t\t\"recordPendingEvents requires an aggregate created by this package\",\n\t\t);\n\t}\n\tconst createStamp: DomainEventStampProvider<TEvent> =\n\t\ttypeof source === \"function\" ? source : () => source.createStamp();\n\treturn capability.record((event, index) =>\n\t\tcreateStamp(event as UncommittedDomainEventOf<TEvent>, index),\n\t) as ReadonlyArray<TEvent>;\n}\n","import { pendingEventLifecycleCapabilityFor } from \"../aggregate/pending-event-lifecycle\";\nimport { AggregateDeletedError } from \"../core/errors\";\nimport type { Id } from \"../core/id\";\n\n/**\n * A class reference used as the type key of the identity map. Keying\n * on the CLASS (not a name string) makes collisions impossible by\n * construction: `Restaurant` and `Booking` are different keys even if\n * someone names two aggregates identically across modules, and there\n * is no string-discipline to maintain.\n *\n * The `Function & { prototype: TAgg }` branch is load-bearing: the\n * kit's aggregate convention is a **protected constructor** plus\n * static factories, and TypeScript rejects assigning a class with a\n * protected constructor to a construct-signature type. The prototype\n * witness accepts those classes while still inferring `TAgg`.\n */\nexport type AggregateClass<TAgg> =\n\t| (abstract new (\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: variance; a class reference is only used as a map key and instance witness here.\n\t\t\t...args: any[]\n\t ) => TAgg)\n\t// biome-ignore lint/complexity/noBannedTypes: Function is deliberate; a construct signature cannot accept protected-constructor classes (the kit's aggregate convention); the prototype witness keeps TAgg inference.\n\t| (Function & { prototype: TAgg });\n\n/**\n * Per-unit-of-work Identity Map (Fowler, PoEAA): within one operation,\n * one aggregate type+id maps to exactly ONE in-memory instance.\n *\n * This is the shipped implementation of the contract the\n * [Repository guide](../../docs/guide/repository.md) places on\n * `AggregatePersistence` implementations: two `findById(id)` calls in the same\n * unit of work MUST return the same instance, because commit-token\n * write registration dedupes by JavaScript object identity. Two instances for\n * one logical aggregate can otherwise produce two tokens, two harvests,\n * and two post-commit lifecycle calls.\n *\n * Storage is two-level (per-type stores created lazily), so\n * `Restaurant:123` and `Booking:123` can never collide: the type key\n * is the aggregate CLASS, not the id alone and not a name string.\n *\n * Repository read-path contract:\n *\n * ```ts\n * async findById(id: OrderId): Promise<Order | undefined> {\n * const cached = this.tracking.identityMap.get(Order, id);\n * if (cached) return cached;\n * // Deleted in this unit of work = gone, even if the physical\n * // delete is deferred and the row is still visible in the tx.\n * if (this.tracking.identityMap.isDeleted(Order, id)) return undefined;\n *\n * const row = await this.loadRow(id);\n * if (!row) return undefined;\n * const order = Order.reconstitute(row.id, row.state, row.version);\n * return this.tracking.trackLoaded(order);\n * }\n * ```\n *\n * Deletion is final within an operation: {@link delete} removes the\n * entry AND records a tombstone, so a later {@link set} of the same\n * type+id throws `AggregateDeletedError`: a second instance of a\n * deleted aggregate can never sneak back into the unit of work, even\n * through a repository whose row delete is deferred.\n *\n * Lifetime is ONE unit of work: the `UnitOfWork` creates a fresh map\n * per `run()` and clears it on close. Never cache across operations;\n * that would silently bypass optimistic concurrency control.\n */\nexport class IdentityMap {\n\tprivate readonly _stores = new Map<\n\t\tAggregateClass<unknown>,\n\t\tMap<string, unknown>\n\t>();\n\tprivate readonly _deleted = new Map<AggregateClass<unknown>, Set<string>>();\n\t// pendingEvents length captured when an instance was first registered\n\t// (load time), so the unit of work can tell events RECORDED AFTER load\n\t// apart from a \"dirty\" reconstitution that already carried events.\n\tprivate _pendingAtRegistration = new WeakMap<object, number>();\n\n\t/** The cached instance for type+id, or `undefined` (also after {@link delete}). */\n\tpublic get<TAgg>(\n\t\ttype: AggregateClass<TAgg>,\n\t\tid: Id<string>,\n\t): TAgg | undefined {\n\t\treturn this._stores.get(type)?.get(id) as TAgg | undefined;\n\t}\n\n\t/** Whether an instance is registered for type+id (false after {@link delete}). */\n\tpublic has<TAgg>(type: AggregateClass<TAgg>, id: Id<string>): boolean {\n\t\treturn this._stores.get(type)?.has(id) ?? false;\n\t}\n\n\t/**\n\t * Whether type+id was {@link delete}d in this unit of work. The\n\t * read path checks this BEFORE hydrating and returns `null`, so\n\t * \"deleted in this operation\" reads uniformly as not-found,\n\t * regardless of whether the repository's physical delete already\n\t * removed the row or is deferred within the transaction. Without\n\t * the check, a read-only probe of a deleted aggregate would crash\n\t * in {@link set} for deferred-write repositories and return `null`\n\t * for immediate-write ones.\n\t */\n\tpublic isDeleted<TAgg>(type: AggregateClass<TAgg>, id: Id<string>): boolean {\n\t\treturn this._deleted.get(type)?.has(id) ?? false;\n\t}\n\n\t/**\n\t * Registers the hydrated instance for type+id.\n\t *\n\t * - Re-registering the SAME instance is a no-op (idempotent).\n\t * - Registering a DIFFERENT instance for an occupied type+id throws:\n\t * that is precisely the identity-map violation this class exists\n\t * to prevent (the repository hydrated twice instead of checking\n\t * {@link get} first), and letting it pass would double-harvest\n\t * events downstream.\n\t * - Registering a type+id that was {@link delete}d in this unit of\n\t * work throws `AggregateDeletedError`: deletion is final within\n\t * the operation.\n\t */\n\tpublic set<TAgg>(\n\t\ttype: AggregateClass<TAgg>,\n\t\tid: Id<string>,\n\t\taggregate: TAgg,\n\t): void {\n\t\tif (this._deleted.get(type)?.has(id)) {\n\t\t\tthrow new AggregateDeletedError(String(id));\n\t\t}\n\t\tlet store = this._stores.get(type);\n\t\tif (store === undefined) {\n\t\t\tstore = new Map<string, unknown>();\n\t\t\tthis._stores.set(type, store);\n\t\t}\n\t\tconst existing = store.get(id);\n\t\tif (existing !== undefined && existing !== aggregate) {\n\t\t\tthrow new Error(\n\t\t\t\t`IdentityMap: a different instance is already registered for ` +\n\t\t\t\t\t`${type.name}(${String(id)}). Check get() before hydrating - ` +\n\t\t\t\t\t`two live instances of one aggregate break the one-instance-per-` +\n\t\t\t\t\t`unit-of-work contract that exactly-once event harvest relies on.`,\n\t\t\t);\n\t\t}\n\t\tstore.set(id, aggregate);\n\t\t// Capture the load-time pending count once (idempotent re-set keeps\n\t\t// the first value), so the unit of work can later tell events\n\t\t// RECORDED AFTER load apart from a reconstitution that already\n\t\t// carried events. Assumes pendingEvents is append-only between load\n\t\t// and commit (the kit's recordEvent model); only the internal\n\t\t// post-commit capability shrinks it.\n\t\tif (\n\t\t\taggregate !== null &&\n\t\t\ttypeof aggregate === \"object\" &&\n\t\t\t!this._pendingAtRegistration.has(aggregate as object)\n\t\t) {\n\t\t\tconst pending = pendingEventCountOf(aggregate);\n\t\t\tif (pending !== undefined) {\n\t\t\t\tthis._pendingAtRegistration.set(aggregate as object, pending);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Registered instances that have recorded MORE pending events than they\n\t * carried when first registered (loaded). Used by the unit of work's\n\t * end-of-run guard: an aggregate that gained events after load but was\n\t * never enrolled would silently drop them. A read-only load, or a\n\t * reconstitution that already carried events, shows no increase and is\n\t * not reported.\n\t */\n\tpublic instancesWithNewPendingEvents(): unknown[] {\n\t\tconst result: unknown[] = [];\n\t\tfor (const store of this._stores.values()) {\n\t\t\tfor (const instance of store.values()) {\n\t\t\t\tconst pending = pendingEventCountOf(instance);\n\t\t\t\tif (pending === undefined) continue;\n\t\t\t\tconst atRegistration =\n\t\t\t\t\tthis._pendingAtRegistration.get(instance as object) ?? 0;\n\t\t\t\tif (pending > atRegistration) {\n\t\t\t\t\tresult.push(instance);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\t/**\n\t * Takes back a registration WITHOUT a tombstone: the entry is removed\n\t * only when the stored instance IS the given one, and a later\n\t * {@link set} of the same type+id stays legal. The Unit of Work calls\n\t * this when a registration step fails after {@link set} already ran, so\n\t * the failed instance cannot be served by `findById` as a phantom.\n\t * This is rollback, not deletion; deletion finality belongs to\n\t * {@link delete}.\n\t */\n\tpublic discard<TAgg>(\n\t\ttype: AggregateClass<TAgg>,\n\t\tid: Id<string>,\n\t\taggregate: TAgg,\n\t): void {\n\t\tconst store = this._stores.get(type);\n\t\tif (store?.get(id) === aggregate) {\n\t\t\tstore.delete(id);\n\t\t}\n\t}\n\n\t/**\n\t * Removes the entry for type+id and records a tombstone: subsequent\n\t * {@link get} / {@link has} report absence, and a subsequent\n\t * {@link set} of the same type+id throws `AggregateDeletedError`.\n\t * The Unit of Work calls this as part of `repository.remove(aggregate)`;\n\t * repository adapters receive only the read-only\n\t * identity-map view.\n\t */\n\tpublic delete<TAgg>(type: AggregateClass<TAgg>, id: Id<string>): void {\n\t\tthis._stores.get(type)?.delete(id);\n\t\tlet tombstones = this._deleted.get(type);\n\t\tif (tombstones === undefined) {\n\t\t\ttombstones = new Set<string>();\n\t\t\tthis._deleted.set(type, tombstones);\n\t\t}\n\t\ttombstones.add(id);\n\t}\n\n\t/** Empties all stores and tombstones. Called by the unit of work on close. */\n\tpublic clear(): void {\n\t\tthis._stores.clear();\n\t\tthis._deleted.clear();\n\t\t// A WeakMap cannot be emptied in place; replace it so a reused map\n\t\t// captures FRESH pending-event baselines. A stale (higher) baseline\n\t\t// would make instancesWithNewPendingEvents under-report and defeat\n\t\t// the UnenrolledChangesError safety net.\n\t\tthis._pendingAtRegistration = new WeakMap<object, number>();\n\t}\n}\n\n/**\n * Pending-event count of a stored value, or `undefined` for anything that is\n * not aggregate-shaped. Single source of truth so the load-time capture in\n * {@link IdentityMap.set} and the end-of-run scan in\n * {@link IdentityMap.instancesWithNewPendingEvents} cannot drift apart.\n * The kit-internal count capability avoids the public `pendingEvents`\n * getter, which allocates and freezes a defensive copy per read; the getter\n * stays as the fallback for structural lookalikes.\n */\nfunction pendingEventCountOf(value: unknown): number | undefined {\n\tif (value === null || typeof value !== \"object\") return undefined;\n\tconst capability = pendingEventLifecycleCapabilityFor(value);\n\tif (capability?.pendingEventCount) return capability.pendingEventCount();\n\tconst pending = (value as { pendingEvents?: unknown }).pendingEvents;\n\treturn Array.isArray(pending) ? pending.length : undefined;\n}\n","import { deepEqual } from \"../utils/array/deep-equal\";\n\n/** Whether a baseline represents an existing row or a pending insert. */\nexport type PersistenceLifecycle = \"loaded\" | \"new\";\n\n/**\n * Adapter-owned projection and change derivation for one aggregate type.\n *\n * The domain model does not implement this contract. A repository adapter\n * chooses what it persists, how that projection is captured at load, and\n * whether a change set is a partial diff or a full replacement.\n */\nexport interface PersistenceModel<TAggregate, TBaseline, TChangeSet> {\n\t/**\n\t * Captures the adapter's persistence projection at the current moment.\n\t * Return a detached value or an immutable value object: the Unit of Work\n\t * retains it as a baseline and cannot make an arbitrary adapter type safe.\n\t *\n\t * Capture must be deterministic for an unchanged aggregate: the Unit of\n\t * Work compares successive captures to detect mutation after write\n\t * registration. A capture that embeds ambient values (clock reads,\n\t * random ids) would make every commit look mutated. The default\n\t * comparison is the package's structural deep equality, which matches\n\t * `Set` members and `Map` keys by reference (JS `SameValueZero`\n\t * semantics): a capture that re-materializes object Set members or Map\n\t * keys on every call must supply {@link captureEquals}.\n\t */\n\tcapture(aggregate: TAggregate): TBaseline;\n\n\t/**\n\t * Adapter-owned equality for two captures of the persistence projection.\n\t * Optional: the default is the package's structural deep equality (Set\n\t * members and Map keys by reference). Supply it when the capture shape\n\t * needs domain-specific comparison, for example rebuilt value-object Set\n\t * members compared by value.\n\t */\n\treadonly captureEquals?: (a: TBaseline, b: TBaseline) => boolean;\n\n\t/**\n\t * Derives the adapter's write payload from its own baseline.\n\t *\n\t * `baseline` is absent for a new aggregate. `lifecycle` disambiguates that\n\t * case from an adapter whose loaded baseline type itself admits `undefined`.\n\t * The returned payload must not share mutable references with the aggregate;\n\t * it is the exact value later handed to `flush`.\n\t */\n\tchanges(\n\t\tbaseline: TBaseline | undefined,\n\t\taggregate: TAggregate,\n\t\tlifecycle: PersistenceLifecycle,\n\t): TChangeSet;\n\n\t/** Tells orchestration whether the derived state write is empty. */\n\tisEmpty(changes: TChangeSet): boolean;\n}\n\ndeclare const persistenceBaselineBrand: unique symbol;\n\n/**\n * Opaque, typed receipt for an adapter-owned persistence baseline.\n *\n * It intentionally exposes no data. The Unit of Work may retain the token and\n * ask the owning adapter capability to derive changes, but cannot branch on or\n * couple itself to the baseline's shape.\n */\nexport interface PersistenceBaseline<TAggregate, TChangeSet> {\n\treadonly [persistenceBaselineBrand]: (aggregate: TAggregate) => TChangeSet;\n}\n\n/** A derived adapter change set plus its adapter-defined emptiness result. */\nexport interface PersistenceChanges<TChangeSet> {\n\treadonly value: TChangeSet;\n\treadonly empty: boolean;\n}\n\ninterface BaselineCapability {\n\treadonly baseline: unknown;\n\treadonly lifecycle: PersistenceLifecycle;\n\tcapture(aggregate: unknown): unknown;\n\tcaptureEquals(a: unknown, b: unknown): boolean;\n\tchanges(\n\t\tbaseline: unknown,\n\t\taggregate: unknown,\n\t\tlifecycle: PersistenceLifecycle,\n\t): unknown;\n\tisEmpty(changes: unknown): boolean;\n}\n\nconst capabilities = new WeakMap<object, BaselineCapability>();\n\n/** Captures a baseline for an aggregate restored by a repository adapter. */\nexport function capturePersistenceBaseline<TAggregate, TBaseline, TChangeSet>(\n\tmodel: PersistenceModel<TAggregate, TBaseline, TChangeSet>,\n\taggregate: TAggregate,\n): PersistenceBaseline<TAggregate, TChangeSet> {\n\treturn createBaselineToken(model, model.capture(aggregate), \"loaded\");\n}\n\n/** Creates the explicit no-row baseline for a newly added aggregate. */\nexport function insertPersistenceBaseline<TAggregate, TBaseline, TChangeSet>(\n\tmodel: PersistenceModel<TAggregate, TBaseline, TChangeSet>,\n): PersistenceBaseline<TAggregate, TChangeSet> {\n\treturn createBaselineToken(model, undefined, \"new\");\n}\n\n/**\n * Captures the aggregate's current adapter projection using the capability\n * carried by an existing baseline. Used to seal persistence-last registration.\n */\nexport function recapturePersistenceBaseline<TAggregate, TChangeSet>(\n\tbaseline: PersistenceBaseline<TAggregate, TChangeSet>,\n\taggregate: TAggregate,\n): PersistenceBaseline<TAggregate, TChangeSet> {\n\tconst capability = capabilityFor(baseline);\n\treturn createErasedBaselineToken({\n\t\t...capability,\n\t\tbaseline: capability.capture(aggregate),\n\t\tlifecycle: \"loaded\",\n\t});\n}\n\n/**\n * Recaptures the adapter projection and reports whether it drifted from the\n * baseline's stored capture, using the model's `captureEquals` when supplied\n * and structural deep equality otherwise.\n *\n * This, not `changes()`/`isEmpty()`, is the mutation detector: the\n * `PersistenceModel` contract explicitly permits a full-replacement change\n * set whose `isEmpty` is never true, so a non-empty change set proves\n * nothing about mutation. Comparing capture to capture asks the honest\n * question independent of the model's diffing strategy. A `\"new\"` lifecycle\n * baseline has no stored capture and never reports drift.\n */\nexport function persistenceProjectionDrifted<TAggregate, TChangeSet>(\n\tbaseline: PersistenceBaseline<TAggregate, TChangeSet>,\n\taggregate: TAggregate,\n): boolean {\n\tconst capability = capabilityFor(baseline);\n\tif (capability.lifecycle === \"new\") return false;\n\treturn !capability.captureEquals(\n\t\tcapability.baseline,\n\t\tcapability.capture(aggregate),\n\t);\n}\n\n/** Derives a typed adapter change set without exposing the stored baseline. */\nexport function derivePersistenceChanges<TAggregate, TChangeSet>(\n\tbaseline: PersistenceBaseline<TAggregate, TChangeSet>,\n\taggregate: TAggregate,\n): PersistenceChanges<TChangeSet> {\n\tconst capability = capabilityFor(baseline);\n\tconst value = capability.changes(\n\t\tcapability.baseline,\n\t\taggregate,\n\t\tcapability.lifecycle,\n\t) as TChangeSet;\n\treturn Object.freeze({ value, empty: capability.isEmpty(value) });\n}\n\nfunction createBaselineToken<TAggregate, TBaseline, TChangeSet>(\n\tmodel: PersistenceModel<TAggregate, TBaseline, TChangeSet>,\n\tbaseline: TBaseline | undefined,\n\tlifecycle: PersistenceLifecycle,\n): PersistenceBaseline<TAggregate, TChangeSet> {\n\treturn createErasedBaselineToken({\n\t\tbaseline,\n\t\tlifecycle,\n\t\tcapture: (aggregate) => model.capture(aggregate as TAggregate),\n\t\tcaptureEquals: (a, b) =>\n\t\t\tmodel.captureEquals\n\t\t\t\t? model.captureEquals(a as TBaseline, b as TBaseline)\n\t\t\t\t: deepEqual(a, b),\n\t\tchanges: (stored, aggregate, currentLifecycle) =>\n\t\t\tmodel.changes(\n\t\t\t\tstored as TBaseline | undefined,\n\t\t\t\taggregate as TAggregate,\n\t\t\t\tcurrentLifecycle,\n\t\t\t),\n\t\tisEmpty: (changes) => model.isEmpty(changes as TChangeSet),\n\t});\n}\n\nfunction createErasedBaselineToken<TAggregate, TChangeSet>(\n\tcapability: BaselineCapability,\n): PersistenceBaseline<TAggregate, TChangeSet> {\n\tconst token = Object.freeze(Object.create(null)) as PersistenceBaseline<\n\t\tTAggregate,\n\t\tTChangeSet\n\t>;\n\tcapabilities.set(token as object, capability);\n\treturn token;\n}\n\nfunction capabilityFor<TAggregate, TChangeSet>(\n\tbaseline: PersistenceBaseline<TAggregate, TChangeSet>,\n): BaselineCapability {\n\tconst capability = capabilities.get(baseline as object);\n\tif (!capability) {\n\t\tthrow new TypeError(\n\t\t\t\"Persistence baseline was not created by this package instance.\",\n\t\t);\n\t}\n\treturn capability;\n}\n","import type { IAggregateRoot, Version } from \"../aggregate/aggregate\";\nimport type {\n\tAnyDomainEvent,\n\tPendingDomainEvent,\n} from \"../aggregate/domain-event\";\nimport {\n\tAggregateDeletedError,\n\tEventHarvestError,\n\tInfrastructureError,\n\tisInfrastructureErrorLike,\n\tKitWiringError,\n\tUnenrolledChangesError,\n} from \"../core/errors\";\nimport type { Id } from \"../core/id\";\nimport type { EventBus, OutboxWriter } from \"../events/ports\";\nimport { type AggregateClass, IdentityMap } from \"../repo/identity-map\";\nimport {\n\tcapturePersistenceBaseline,\n\tderivePersistenceChanges,\n\tinsertPersistenceBaseline,\n\ttype PersistenceBaseline,\n\ttype PersistenceChanges,\n\ttype PersistenceModel,\n\tpersistenceProjectionDrifted,\n\trecapturePersistenceBaseline,\n} from \"../repo/persistence-model\";\nimport type { TransactionScope } from \"../repo/scope\";\nimport { abortReason } from \"../utils/abort\";\nimport type { ExecutionContext } from \"../utils/execution\";\nimport {\n\ttype AggregateCommitToken,\n\ttype CommitEnrollment,\n\twithCommit,\n} from \"./handler\";\n\n/**\n * Thrown when `UnitOfWork.run()` is called while the same instance is\n * already executing a unit of work: either a genuinely nested `run()`\n * inside the work callback, or two concurrent operations sharing one\n * instance.\n *\n * Both are contract violations, not recoverable infrastructure\n * failures, so this carries the `WIRING` category (same reasoning as\n * `MissingHandlerError`): a generic `catch (e instanceof\n * InfrastructureError)` handler must not mask it.\n *\n * A nested `run()` would NOT join the outer transaction; it would open\n * an independent one, silently breaking the all-or-nothing guarantee.\n * If two operations must commit together, they are ONE unit of work:\n * merge them into a single `run()` callback. For concurrent requests,\n * construct one `UnitOfWork` per operation (construction is trivially\n * cheap; the dependency object is the thing you share).\n */\nexport class NestedUnitOfWorkError extends KitWiringError<\"NESTED_UNIT_OF_WORK\"> {\n\tconstructor() {\n\t\tsuper(\n\t\t\t\"NESTED_UNIT_OF_WORK\",\n\t\t\t\"UnitOfWork.run() was called while this instance is already running. \" +\n\t\t\t\t\"A nested run() would open an independent transaction, not join the \" +\n\t\t\t\t\"outer one - merge the work into a single run() callback. For \" +\n\t\t\t\t\"concurrent operations, construct one UnitOfWork per operation.\",\n\t\t);\n\t}\n}\n\ninterface RuntimePersistenceDefinition<Evt extends AnyDomainEvent> {\n\treadonly aggregate: AggregateClass<IAggregateRoot<Id<string>, Evt>>;\n\treadonly persistence: PersistenceModel<\n\t\tIAggregateRoot<Id<string>, Evt>,\n\t\tunknown,\n\t\tunknown\n\t>;\n\treadonly flush: (\n\t\ttransaction: unknown,\n\t\twrite: AggregatePersistenceWrite<IAggregateRoot<Id<string>, Evt>, unknown>,\n\t) => void | Promise<void>;\n\treadonly mapError: (\n\t\terror: unknown,\n\t\twrite: AggregatePersistenceWrite<IAggregateRoot<Id<string>, Evt>, unknown>,\n\t) => InfrastructureError;\n\treadonly physicalRemoval?: boolean;\n}\n\ninterface RuntimeRepositoryDefinition<Evt extends AnyDomainEvent, TCtx>\n\textends RuntimePersistenceDefinition<Evt> {\n\treadonly create: (\n\t\ttransaction: TCtx,\n\t\ttracking: RepositoryTracking<IAggregateRoot<Id<string>, Evt>>,\n\t) => unknown;\n}\n\n/**\n * Thrown when the unit-of-work context is used after `run()` has\n * settled: reading `context.repositories`, calling an adapter-held\n * `tracking.trackLoaded`, or using a repository facade after the transaction\n * has committed or rolled back.\n *\n * Use-after-close is a programming bug (typically a leaked context\n * reference or a fire-and-forget promise outliving the callback), so\n * this carries the `WIRING` category and should crash loud.\n *\n * **Honest scope of this guard:** the kit can only invalidate what it\n * controls: context getters, repository-facade operations, and the tracking\n * capability. An adapter that captures its raw transaction handle can still call\n * it as far as the kit can see;\n * whether the driver rejects after close is ORM-specific. Adapter factories\n * must not let that handle escape into application code.\n */\nexport class TransactionClosedError extends KitWiringError<\"TRANSACTION_CLOSED\"> {\n\tconstructor(public readonly operation: string) {\n\t\tsuper(\n\t\t\t\"TRANSACTION_CLOSED\",\n\t\t\t`Unit of work is closed: ${operation} was called after the ` +\n\t\t\t\t\"transaction committed or rolled back. Do not use the context or \" +\n\t\t\t\t\"repository facade or tracking capability outside the run() callback.\",\n\t\t);\n\t}\n}\n\n/** A repository factory returned a value that cannot be wrapped as a facade. */\nexport class InvalidRepositoryAdapterError extends KitWiringError<\"INVALID_REPOSITORY_ADAPTER\"> {\n\tconstructor(\n\t\tpublic readonly repository: string,\n\t\tpublic readonly receivedType: string,\n\t) {\n\t\tsuper(\n\t\t\t\"INVALID_REPOSITORY_ADAPTER\",\n\t\t\t`Repository factory \"${repository}\" returned ${receivedType}; ` +\n\t\t\t\t\"it must return an adapter object.\",\n\t\t);\n\t}\n}\n\n/** A Unit of Work received repository wiring that bypassed {@link defineRepository}. */\nexport class InvalidRepositoryDefinitionError extends KitWiringError<\"INVALID_REPOSITORY_DEFINITION\"> {\n\tconstructor(public readonly repository: string) {\n\t\tsuper(\n\t\t\t\"INVALID_REPOSITORY_DEFINITION\",\n\t\t\t`Repository \"${repository}\" was not created by defineRepository. ` +\n\t\t\t\t\"Declare the application port explicitly and pass the helper-created \" +\n\t\t\t\t\"definition to UnitOfWork.\",\n\t\t);\n\t}\n}\n\n/** A repository's persistence-error policy threw or returned a non-kit error. */\nexport class RepositoryErrorMappingFailedError extends KitWiringError<\"REPOSITORY_ERROR_MAPPING_FAILED\"> {\n\treadonly aggregateId: string;\n\treadonly intent: AggregateWriteIntent;\n\treadonly mapperCause: unknown;\n\n\tconstructor(options: {\n\t\treadonly aggregateId: string;\n\t\treadonly intent: AggregateWriteIntent;\n\t\treadonly persistenceError: unknown;\n\t\treadonly mapperError: unknown;\n\t}) {\n\t\tsuper(\n\t\t\t\"REPOSITORY_ERROR_MAPPING_FAILED\",\n\t\t\t`The repository error mapper failed for ${options.intent} of aggregate ` +\n\t\t\t\t`${options.aggregateId}. The original persistence failure is preserved ` +\n\t\t\t\t\"as cause; the mapper failure is available as mapperCause.\",\n\t\t\toptions.persistenceError,\n\t\t);\n\t\tthis.aggregateId = options.aggregateId;\n\t\tthis.intent = options.intent;\n\t\tthis.mapperCause = options.mapperError;\n\t}\n}\n\n/** The explicit persistence intent registered for one tracked aggregate. */\nexport type AggregateWriteIntent = \"add\" | \"update\" | \"remove\";\n\n/** Why an aggregate lifecycle registration was rejected. */\nexport type AggregateTrackingFailure =\n\t| \"not_loaded\"\n\t| \"loaded_as_new\"\n\t| \"different_repository\"\n\t| \"conflicting_intent\"\n\t| \"mutated_after_registration\";\n\n/**\n * A deterministic violation of the Unit of Work's aggregate lifecycle.\n *\n * This is a wiring error rather than a domain or infrastructure failure: the\n * application registered persistence intent in an order the Unit of Work\n * cannot execute truthfully. Retrying the same callback cannot repair it.\n */\nexport class AggregateTrackingError extends KitWiringError<\"AGGREGATE_TRACKING\"> {\n\tconstructor(\n\t\tpublic readonly aggregateId: string,\n\t\tpublic readonly operation: AggregateWriteIntent | \"load\" | \"commit\",\n\t\tpublic readonly reason: AggregateTrackingFailure,\n\t\tpublic readonly registeredIntent?: AggregateWriteIntent,\n\t) {\n\t\tsuper(\n\t\t\t\"AGGREGATE_TRACKING\",\n\t\t\ttrackingFailureMessage(aggregateId, operation, reason, registeredIntent),\n\t\t);\n\t}\n}\n\nfunction trackingFailureMessage(\n\taggregateId: string,\n\toperation: AggregateWriteIntent | \"load\" | \"commit\",\n\treason: AggregateTrackingFailure,\n\tregisteredIntent: AggregateWriteIntent | undefined,\n): string {\n\tswitch (reason) {\n\t\tcase \"not_loaded\":\n\t\t\treturn (\n\t\t\t\t`Aggregate ${aggregateId} cannot be registered for ${operation}: ` +\n\t\t\t\t\"it was not loaded into this unit of work. Load it through the \" +\n\t\t\t\t\"repository before updating or removing it.\"\n\t\t\t);\n\t\tcase \"loaded_as_new\":\n\t\t\treturn (\n\t\t\t\t`Aggregate ${aggregateId} cannot be added as new because it was ` +\n\t\t\t\t\"loaded by this unit of work. Use update for a loaded aggregate.\"\n\t\t\t);\n\t\tcase \"different_repository\":\n\t\t\treturn (\n\t\t\t\t`Aggregate ${aggregateId} cannot be registered for ${operation} through ` +\n\t\t\t\t\"a different repository in the same unit of work. One aggregate instance \" +\n\t\t\t\t\"must remain owned by the repository definition that first tracked it.\"\n\t\t\t);\n\t\tcase \"conflicting_intent\":\n\t\t\treturn (\n\t\t\t\t`Aggregate ${aggregateId} is already registered for ` +\n\t\t\t\t`${registeredIntent ?? \"another write\"}; ${operation} would create ` +\n\t\t\t\t\"conflicting persistence intent in one unit of work. Decide the final \" +\n\t\t\t\t\"lifecycle outcome before registering it.\"\n\t\t\t);\n\t\tcase \"mutated_after_registration\":\n\t\t\treturn (\n\t\t\t\t`Aggregate ${aggregateId} changed after ${registeredIntent ?? \"write\"} ` +\n\t\t\t\t\"was registered. Make domain decisions first and call add, update, or \" +\n\t\t\t\t\"remove last so persisted state and recorded events cannot diverge.\"\n\t\t\t);\n\t}\n}\n\n/**\n * The unit of work failed AFTER the work callback completed\n * successfully, at the persistence boundary: the outbox write or the\n * transaction commit itself rejected. The kit cannot see inside\n * `TransactionScope.transactional`, so these are deliberately one error\n * class; the underlying failure is attached as `cause`.\n *\n * `InfrastructureError`: the business logic ran to completion; the\n * persistence boundary failed. The transaction rolled back (or never\n * committed), no aggregate was marked persisted, and pending events\n * survive on the aggregates; the operation left no partial state behind.\n * A `CommitError` is the **potentially transient** post-completion\n * failure (a commit-time serialization failure is the classic case), so\n * it is the one a retrying caller should consider re-running. The\n * deterministic post-completion failure, a harvest-guard violation (an\n * event missing `aggregateId` / `aggregateType`, or an eventful persisted\n * aggregate that did not advance its version), is a programming bug and surfaces as\n * {@link EventHarvestError} instead, which does NOT extend\n * `InfrastructureError`, so it stays out of retry paths by construction.\n */\nexport class CommitError extends InfrastructureError<\"COMMIT_FAILED\"> {\n\tconstructor(cause: unknown) {\n\t\tsuper({\n\t\t\tcode: \"COMMIT_FAILED\",\n\t\t\tmessage:\n\t\t\t\t\"Unit of work failed after the work callback completed: the outbox \" +\n\t\t\t\t\"write or the transaction commit rejected. The transaction did \" +\n\t\t\t\t\"not commit; this failure may be transient, inspect the cause \" +\n\t\t\t\t\"(e.g. someChainRetryable) before retrying.\",\n\t\t\tcause,\n\t\t});\n\t}\n}\n\n/**\n * The work callback threw AND the transaction scope rejected with a\n * DIFFERENT error that does not wrap the callback's error in its cause\n * chain - the strongest available signal that the rollback itself\n * failed. The callback's (primary) error is preserved as `cause`, so\n * cause-chain helpers (`someChainRetryable`, `findInCauseChain`) still\n * see a wrapped `ConcurrencyConflictError` & co.; the scope's error is\n * carried in {@link rollbackCause}.\n *\n * Scopes that rethrow the original error (Drizzle, Prisma do) never\n * produce this; scopes that WRAP the original are detected via the\n * cause chain and passed through unchanged instead.\n */\nexport class RollbackError extends InfrastructureError<\"ROLLBACK_FAILED\"> {\n\tconstructor(\n\t\tcause: unknown,\n\t\tpublic readonly rollbackCause: unknown,\n\t) {\n\t\tsuper({\n\t\t\tcode: \"ROLLBACK_FAILED\",\n\t\t\tmessage:\n\t\t\t\t\"The work callback failed and the transaction scope rejected with a \" +\n\t\t\t\t\"different error (possible rollback failure). The callback's error \" +\n\t\t\t\t\"is the cause; the scope's error is in rollbackCause.\",\n\t\t\tcause,\n\t\t});\n\t}\n}\n\n/** Read-only Identity Map operations available to repository adapters. */\nexport type UnitOfWorkIdentityMap = Pick<\n\tIdentityMap,\n\t\"get\" | \"has\" | \"isDeleted\"\n>;\n\n/**\n * Repository-specific tracking capability handed only to its adapter.\n *\n * Read paths call {@link RepositoryTracking.trackLoaded} before returning a\n * restored aggregate.\n * Write methods exposed to application code are replaced by Unit-of-Work-owned\n * `add`, `update`, and `remove` registrations, so an adapter implementation of\n * those methods cannot perform durable I/O early or skip event harvesting.\n *\n * Contract for repository implementations:\n * - `findById(id)` checks `identityMap.get` BEFORE hydrating, treats\n * `identityMap.isDeleted` as not-found (`undefined`), and returns\n * `tracking.trackLoaded(aggregate)` after hydration. This captures the\n * expected version before application code can mutate the instance.\n * - Adapter objects do not need lifecycle methods; the facade installs the\n * Unit-of-Work-owned `add`, `update`, and optional `remove`. If a concrete\n * adapter has same-named methods anyway, the facade masks them.\n * - Other repository methods are reads. A custom method that performs a write\n * would bypass the Unit of Work and violates the adapter contract.\n */\nexport interface RepositoryTracking<\n\tTAggregate extends IAggregateRoot<Id<string>, AnyDomainEvent>,\n> {\n\t/**\n\t * Registers an aggregate restored by a repository before returning it to\n\t * application code. The Unit of Work identity-maps the instance and captures\n\t * its current version as the optimistic-concurrency expectation.\n\t */\n\ttrackLoaded(aggregate: TAggregate): TAggregate;\n\n\t/**\n\t * Read-only view of the per-operation Identity Map (Fowler): one aggregate type+id,\n\t * one in-memory instance. Created fresh per `run()`, cleared on\n\t * close; accessing it after close throws\n\t * {@link TransactionClosedError}.\n\t */\n\treadonly identityMap: UnitOfWorkIdentityMap;\n}\n\n/**\n * What the application work callback receives: repositories already bound to\n * the live Unit of Work plus cooperative cancellation.\n *\n * The adapter-only transaction and tracking capability are deliberately absent.\n * Exposing either would let application code bypass repository lifecycle\n * registration and would leak infrastructure types into the use case.\n */\nexport interface UnitOfWorkContext<TRepos> {\n\treadonly repositories: TRepos;\n\n\t/**\n\t * The cooperative-cancellation signal passed to {@link UnitOfWork.run},\n\t * or `undefined` if none was given. Poll `signal?.aborted` between\n\t * steps of a long operation and throw `signal.reason` to bail out; the\n\t * throw rolls the unit of work back like any other callback error. The\n\t * kit does not interrupt an in-flight query for you: actual query\n\t * cancellation depends on the `TransactionScope` honoring the signal.\n\t */\n\treadonly signal?: AbortSignal;\n}\n\n/** Options for a single {@link UnitOfWork.run} call. */\nexport interface RunOptions {\n\t/**\n\t * Cooperative-cancellation signal. If already aborted, `run()` rejects\n\t * with the signal's `reason` before opening a transaction. Otherwise it\n\t * is exposed on the context (poll `context.signal`) and forwarded to the\n\t * `TransactionScope`. Use `AbortSignal.timeout(ms)` for a deadline.\n\t */\n\treadonly signal?: AbortSignal;\n}\n\n// Shared across package copies like every other kit brand: a definition\n// built by a bundled plugin copy's defineRepository must be accepted by the\n// host copy's UnitOfWork. The key version stamps the definition SHAPE; bump\n// it when the definition contract changes so an incompatible copy fails the\n// generic not-a-definition check instead of half-working.\nconst repositoryDefinitionBrand: unique symbol = Symbol.for(\n\t\"@shirudo/ddd-kit/repository-definition/v1\",\n);\n\n/** Adapter wiring accepted by {@link defineRepository}. */\nexport interface RepositoryDefinitionOptions<\n\tTCtx,\n\tTRepositoryPort extends object,\n\tTAggregate extends IAggregateRoot<Id<string>, AnyDomainEvent>,\n\tTBaseline,\n\tTChangeSet,\n\tTRemoval extends boolean = false,\n> {\n\t/** Concrete aggregate class used as the Identity Map key. */\n\treadonly aggregate: AggregateClass<TAggregate>;\n\t/** Adapter-owned projection, baseline, and change-set policy. */\n\treadonly persistence: PersistenceModel<TAggregate, TBaseline, TChangeSet>;\n\t/**\n\t * Creates the transaction-bound adapter for the port's non-lifecycle\n\t * methods. The Unit of Work supplies `add`, `update`, and optional `remove`.\n\t */\n\treadonly create: (\n\t\ttransaction: TCtx,\n\t\ttracking: RepositoryTracking<TAggregate>,\n\t) => Omit<TRepositoryPort, \"add\" | \"update\" | \"remove\">;\n\t/**\n\t * Performs the registered write during the Unit of Work's commit phase.\n\t *\n\t * The receipt contains adapter-owned changes and immutable persistence\n\t * facts, never the mutable aggregate instance. The transaction remains open\n\t * while this function and the outbox write run.\n\t */\n\treadonly flush: (\n\t\ttransaction: NoInfer<TCtx>,\n\t\twrite: AggregatePersistenceWrite<TAggregate, TChangeSet>,\n\t) => void | Promise<void>;\n\t/**\n\t * Translates every adapter/driver failure from `flush` into an explicit\n\t * application-facing infrastructure error. Returning or throwing a raw\n\t * driver error is a wiring failure and is rejected by the Unit of Work.\n\t */\n\treadonly mapError: (\n\t\terror: unknown,\n\t\twrite: AggregatePersistenceWrite<TAggregate, TChangeSet>,\n\t) => InfrastructureError;\n\t/** Adds Unit-of-Work-owned `remove` to the application-facing repository. */\n\treadonly physicalRemoval?: TRemoval;\n}\n\n/** Complete, helper-created definition for one Unit-of-Work repository. */\nexport interface RepositoryDefinition<\n\tTCtx,\n\tTRepositoryPort extends object,\n\tTAggregate extends IAggregateRoot<Id<string>, AnyDomainEvent>,\n\tTBaseline,\n\tTChangeSet,\n\tTRemoval extends boolean = false,\n> extends RepositoryDefinitionOptions<\n\t\tTCtx,\n\t\tTRepositoryPort,\n\t\tTAggregate,\n\t\tTBaseline,\n\t\tTChangeSet,\n\t\tTRemoval\n\t> {\n\t/** Nominal marker installed by {@link defineRepository}. */\n\treadonly [repositoryDefinitionBrand]: true;\n}\n\n/**\n * Immutable adapter input for one registered aggregate write.\n *\n * `expectedVersion` is captured when a loaded aggregate joins the Unit of\n * Work and is absent for `add`. `version`, `changes`, and `events` describe\n * the exact moment at which the application registered its write intent.\n * Adapters must use the expected/current version pair for their OCC predicate\n * and must not read mutable write state back from an aggregate reference.\n */\nexport interface AggregatePersistenceWrite<\n\tTAggregate extends IAggregateRoot<Id<string>, AnyDomainEvent>,\n\tTChangeSet,\n> {\n\treadonly intent: AggregateWriteIntent;\n\treadonly aggregateId: TAggregate[\"id\"];\n\treadonly expectedVersion: Version | undefined;\n\treadonly version: Version;\n\treadonly changes: PersistenceChanges<TChangeSet>;\n\treadonly events: TAggregate[\"pendingEvents\"];\n}\n\n/** @inline */\ntype CallableValue = (...args: never[]) => unknown;\n\n/** @inline */\ntype RepositoryDefinitionBuilder<TRepositoryPort extends object> = <\n\tTAggregate extends IAggregateRoot<Id<string>, AnyDomainEvent>,\n\tTCreate extends (\n\t\ttransaction: never,\n\t\ttracking: RepositoryTracking<TAggregate>,\n\t) => Omit<TRepositoryPort, \"add\" | \"update\" | \"remove\">,\n\tTBaseline,\n\tTChangeSet,\n\tTRemoval extends boolean = false,\n>(\n\tdefinition: RepositoryDefinitionOptions<\n\t\tParameters<TCreate>[0],\n\t\tTRepositoryPort,\n\t\tTAggregate,\n\t\tTBaseline,\n\t\tTChangeSet,\n\t\tTRemoval\n\t> & {\n\t\treadonly create: TCreate;\n\t} & (TRepositoryPort extends AggregateWriteRegistration<TAggregate>\n\t\t\t? TRemoval extends true\n\t\t\t\t? TRepositoryPort extends PhysicalRemovalRegistration<TAggregate>\n\t\t\t\t\t? unknown\n\t\t\t\t\t: never\n\t\t\t\t: TRepositoryPort extends PhysicalRemovalRegistration<TAggregate>\n\t\t\t\t\t? never\n\t\t\t\t\t: unknown\n\t\t\t: never),\n) => RepositoryDefinition<\n\tParameters<TCreate>[0],\n\tTRepositoryPort,\n\tTAggregate,\n\tTBaseline,\n\tTChangeSet,\n\tTRemoval\n>;\n\n/**\n * Defines repository wiring for an application-owned driven port.\n *\n * The first call makes the port explicit; the second infers the transaction,\n * aggregate, persistence, event, and removal types from the adapter wiring.\n * The port must declare `add` and `update`; if it declares `remove`, the\n * definition must set `physicalRemoval: true`. The adapter created by the\n * definition implements only the remaining methods because lifecycle writes\n * are installed by the Unit of Work.\n * The returned definition is the only form accepted by {@link UnitOfWork}; a\n * raw adapter-shaped object cannot silently turn its concrete surface into the\n * application contract.\n */\nfunction assertRepositoryDefinitionMembers(\n\tdefinition: Record<PropertyKey, unknown>,\n): void {\n\tfor (const key of [\"create\", \"flush\", \"mapError\"] as const) {\n\t\tif (typeof definition[key] !== \"function\") {\n\t\t\tthrow new TypeError(\n\t\t\t\t`defineRepository: \"${key}\" is missing or not a function on the ` +\n\t\t\t\t\t\"definition. The builder copies own enumerable properties only; \" +\n\t\t\t\t\t\"prototype methods and non-enumerable members are not carried. \" +\n\t\t\t\t\t\"Pass a plain object literal.\",\n\t\t\t);\n\t\t}\n\t}\n\tif (typeof definition.aggregate !== \"function\") {\n\t\tthrow new TypeError(\n\t\t\t'defineRepository: \"aggregate\" is missing or not a class reference ' +\n\t\t\t\t\"on the definition. Pass a plain object literal with own \" +\n\t\t\t\t\"enumerable properties.\",\n\t\t);\n\t}\n\tif (\n\t\tdefinition.persistence === null ||\n\t\ttypeof definition.persistence !== \"object\"\n\t) {\n\t\tthrow new TypeError(\n\t\t\t'defineRepository: \"persistence\" is missing or not a ' +\n\t\t\t\t\"PersistenceModel on the definition. Pass a plain object literal \" +\n\t\t\t\t\"with own enumerable properties.\",\n\t\t);\n\t}\n}\n\nexport function defineRepository<TRepositoryPort extends object>(): Extract<\n\tTRepositoryPort,\n\tCallableValue\n> extends never\n\t? RepositoryDefinitionBuilder<TRepositoryPort>\n\t: never {\n\tconst builder = (definition: object): object => {\n\t\tconst branded = { ...definition };\n\t\t// Validated AFTER the spread, on what actually survives it: the\n\t\t// spread copies own enumerable properties only, so create/flush/\n\t\t// mapError carried on a prototype (class instance) or as\n\t\t// non-enumerable members vanish silently. Without this check, the\n\t\t// loss surfaces as a bare TypeError deep inside the first run().\n\t\tassertRepositoryDefinitionMembers(branded as Record<PropertyKey, unknown>);\n\t\tObject.defineProperty(branded, repositoryDefinitionBrand, {\n\t\t\tconfigurable: false,\n\t\t\tenumerable: false,\n\t\t\tvalue: true,\n\t\t\twritable: false,\n\t\t});\n\t\treturn Object.freeze(branded);\n\t};\n\treturn builder as unknown as Extract<\n\t\tTRepositoryPort,\n\t\tCallableValue\n\t> extends never\n\t\t? RepositoryDefinitionBuilder<TRepositoryPort>\n\t\t: never;\n}\n\n/** Application-facing repositories inferred from their adapter definitions. */\nexport type RepositoriesOf<TDefinitions> = {\n\t[K in keyof TDefinitions]: RepositoryFacadeOf<TDefinitions[K]>;\n};\n\n/**\n * Preserves each concrete repository definition while rejecting incomplete\n * entries, callable adapter results, and definitions whose transaction context\n * or aggregate event family does not belong to the Unit of Work that owns them.\n */\nexport type CompatibleRepositoryDefinitions<\n\tEvt extends AnyDomainEvent,\n\tTCtx,\n\tTDefinitions,\n> = {\n\t[K in keyof TDefinitions]: TDefinitions[K] extends RepositoryDefinition<\n\t\tinfer TDefinitionContext,\n\t\tinfer _TRepositoryPort,\n\t\tinfer TAggregate,\n\t\tinfer _TBaseline,\n\t\tinfer _TChangeSet,\n\t\tinfer _TRemoval\n\t>\n\t\t? TAggregate extends IAggregateRoot<Id<string>, infer TDefinitionEvent>\n\t\t\t? [TDefinitionEvent] extends [Evt]\n\t\t\t\t? TCtx extends TDefinitionContext\n\t\t\t\t\t? TDefinitions[K]\n\t\t\t\t\t: never\n\t\t\t\t: never\n\t\t\t: never\n\t\t: never;\n};\n\n/** @inline */\ntype RepositoryFacadeOf<TDefinition> = TDefinition extends RepositoryDefinition<\n\tinfer _TCtx,\n\tinfer TRepositoryPort,\n\tinfer _TAggregate,\n\tinfer _TBaseline,\n\tinfer _TChangeSet,\n\tinfer _TRemoval\n>\n\t? TRepositoryPort\n\t: never;\n\n/** Unit-of-Work-owned writes added to every application repository facade. */\nexport interface AggregateWriteRegistration<\n\tTAggregate extends IAggregateRoot<Id<string>, AnyDomainEvent>,\n> {\n\tadd(aggregate: TAggregate): void;\n\tupdate(aggregate: TAggregate): void;\n}\n\n/** Optional physical removal added only by an explicit repository definition. */\nexport interface PhysicalRemovalRegistration<\n\tTAggregate extends IAggregateRoot<Id<string>, AnyDomainEvent>,\n> {\n\tremove(aggregate: TAggregate): void;\n}\n\n/** Dependencies for {@link UnitOfWork}; the app-level singleton part. */\nexport interface UnitOfWorkDeps<\n\tEvt extends AnyDomainEvent,\n\tTCtx,\n\tTDefinitions extends Record<string, unknown>,\n> {\n\tscope: TransactionScope<TCtx>;\n\t/**\n\t * The write half of the outbox; see `WithCommitDeps.outbox` for the\n\t * required-vs-optional-bus asymmetry and the explicit opt-out\n\t * (`outboxWriterAcceptingEventLoss`).\n\t */\n\toutbox: OutboxWriter<Evt>;\n\tbus?: EventBus<Evt>;\n\t/** See `withCommit`: observer for post-commit `bus.publish` failures. */\n\tonPublishError?: (error: unknown, events: ReadonlyArray<Evt>) => void;\n\t/**\n\t * See `withCommit`: application-shell observer after acknowledgement.\n\t * The version argument is captured before any observer runs; the context\n\t * carries the bounded post-commit execution signal and deadline.\n\t */\n\tonPersisted?: (\n\t\taggregate: IAggregateRoot<Id<string>, Evt>,\n\t\tversion: Version,\n\t\tcontext: ExecutionContext,\n\t) => void | Promise<void>;\n\t/**\n\t * See `withCommit`: failure observer for internal post-commit\n\t * acknowledgement/disposal and the application-shell `onPersisted`\n\t * callback. Never rejects the committed write.\n\t */\n\tonPersistError?: (\n\t\terror: unknown,\n\t\taggregate: IAggregateRoot<Id<string>, Evt>,\n\t) => void;\n\t/**\n\t * See `withCommit`: one total budget shared by the complete post-commit\n\t * application phase. Default `30000`ms.\n\t */\n\tpostCommitTimeoutMs?: number;\n\trepositories: CompatibleRepositoryDefinitions<Evt, TCtx, TDefinitions>;\n}\n\n/**\n * Explicit-intent Unit of Work: one `run()` call is one application-level\n * write operation. All repository writes inside the callback share one\n * transaction and either persist completely or not at all.\n *\n * Built ON TOP of `withCommit` - the commit orchestration (event\n * harvest into the outbox inside the transaction, internal acknowledgement\n * after the commit, best-effort in-process publish last) is inherited,\n * not reimplemented. What this layer adds:\n *\n * - **Tx-bound repository adapters via a registry.** The callback receives\n * application-facing repository facades and never sees the raw transaction\n * or tracking capability.\n * - **Unit-of-Work-owned writes.** Standard `add`, `update`, and `remove`\n * methods register lifecycle intent. Adapter implementations with those\n * names are not invoked through the facade.\n * - **Lifecycle errors.** {@link NestedUnitOfWorkError},\n * {@link TransactionClosedError}, {@link CommitError},\n * {@link RollbackError}, {@link AggregateDeletedError}.\n *\n * - **A per-operation Identity Map and expected-version receipt.** Read paths\n * call `trackLoaded` before returning an aggregate. The Unit of Work then\n * owns the one-instance rule and the optimistic-concurrency expectation.\n * - **Persistence-last guard.** Once write intent is registered, a later\n * version or event-batch change rejects the operation before commit.\n *\n * Nested transactions, savepoints, and transaction joining remain outside\n * this boundary. One `run()` is one consistency transaction.\n *\n * **Instance discipline:** one instance owns one logical operation at\n * a time. `run()` while a run is active throws\n * {@link NestedUnitOfWorkError} - that covers genuine nesting AND two\n * concurrent requests sharing one instance, which is the same bug in\n * different clothes. Construct one `UnitOfWork` per operation\n * (construction stores one reference; the shareable singleton is the\n * deps object). Sequential reuse of an instance is fine.\n *\n * **Error pass-through:** an error thrown by the work callback (a\n * repository's `ConcurrencyConflictError`, a `DomainError`, anything)\n * is rethrown UNCHANGED - the unit of work never converts a concurrency\n * conflict into a generic error. Only the two failure modes the\n * callback cannot observe are wrapped: see {@link CommitError} and\n * {@link RollbackError}.\n *\n * @example\n * ```ts\n * const deps = {\n * scope: drizzleScope,\n * outbox: drizzleOutbox,\n * bus: eventBus,\n * repositories: {\n * restaurants: restaurantRepositoryDefinition,\n * },\n * };\n *\n * const uow = new UnitOfWork(deps);\n * const result = await uow.run(async ({ repositories }) => {\n * const restaurant = await repositories.restaurants.getById(id);\n * restaurant.changeOpeningHours(openingHours);\n * repositories.restaurants.update(restaurant);\n * return restaurant.id;\n * });\n * ```\n */\nexport class UnitOfWork<\n\tEvt extends AnyDomainEvent,\n\tTCtx,\n\tTDefinitions extends Record<string, unknown>,\n> {\n\tprivate _active = false;\n\n\tconstructor(private readonly deps: UnitOfWorkDeps<Evt, TCtx, TDefinitions>) {}\n\n\t/**\n\t * Execute one unit of work: open the transaction, hand the callback\n\t * tx-bound repositories, commit on resolve, roll back on throw,\n\t * run the post-commit lifecycle (acknowledge, observe, publish) for every\n\t * enrolled aggregate. Returns the callback's result.\n\t */\n\tpublic async run<R>(\n\t\twork: (\n\t\t\tcontext: UnitOfWorkContext<RepositoriesOf<TDefinitions>>,\n\t\t) => Promise<R>,\n\t\toptions?: RunOptions,\n\t): Promise<R> {\n\t\t// Pre-flight: an already-aborted caller rejects with the signal's\n\t\t// reason before opening a transaction (no callback runs). Placed\n\t\t// before the active-guard so a doubly-bad call (aborted signal on an\n\t\t// already-running instance) is reported as aborted rather than as a\n\t\t// nesting error. The `??` fallback mirrors event-bus.ts and guards a\n\t\t// non-spec polyfill whose `reason` is undefined.\n\t\tif (options?.signal?.aborted) {\n\t\t\tthrow abortReason(\n\t\t\t\toptions.signal,\n\t\t\t\t\"UnitOfWork.run aborted before opening a transaction\",\n\t\t\t);\n\t\t}\n\t\tif (this._active) {\n\t\t\tthrow new NestedUnitOfWorkError();\n\t\t}\n\t\tthis._active = true;\n\n\t\tlet session: Session<Evt> | undefined;\n\t\tlet workCompleted = false;\n\t\tlet workThrew = false;\n\t\tlet workError: unknown;\n\n\t\ttry {\n\t\t\treturn await withCommit<Evt, R, TCtx>(\n\t\t\t\t{\n\t\t\t\t\toutbox: this.deps.outbox,\n\t\t\t\t\tbus: this.deps.bus,\n\t\t\t\t\tscope: this.deps.scope,\n\t\t\t\t\tonPublishError: this.deps.onPublishError,\n\t\t\t\t\tonPersisted: this.deps.onPersisted,\n\t\t\t\t\tonPersistError: this.deps.onPersistError,\n\t\t\t\t\tpostCommitTimeoutMs: this.deps.postCommitTimeoutMs,\n\t\t\t\t\tsignal: options?.signal,\n\t\t\t\t},\n\t\t\t\tasync (tx, enrollment) => {\n\t\t\t\t\t// Fresh state per scope invocation: a TransactionScope that\n\t\t\t\t\t// retries its callback (serialization-failure retry wrappers)\n\t\t\t\t\t// re-runs this fn, and state from the rolled-back attempt\n\t\t\t\t\t// (enrollments, identity-map entries, error flags) must not\n\t\t\t\t\t// leak into the retry. The previous attempt's session is\n\t\t\t\t\t// closed so its leaked contexts turn loud.\n\t\t\t\t\tsession?.close();\n\t\t\t\t\tconst s = new Session<Evt>(enrollment);\n\t\t\t\t\tsession = s;\n\t\t\t\t\tworkCompleted = false;\n\t\t\t\t\tworkThrew = false;\n\t\t\t\t\tworkError = undefined;\n\n\t\t\t\t\tconst repositories = this.buildRepositories(tx, s);\n\t\t\t\t\tconst context = makeContext(repositories, s, options?.signal);\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await work(context);\n\t\t\t\t\t\t// Validate tracking before sealing: a loaded aggregate that\n\t\t\t\t\t\t// changed without update intent would otherwise be lost.\n\t\t\t\t\t\t// Throws inside\n\t\t\t\t\t\t// the transaction, so the unit of work rolls back.\n\t\t\t\t\t\ts.assertReadyToCommit();\n\t\t\t\t\t\tawait s.flush(tx);\n\t\t\t\t\t\t// A flush may yield to the event loop. Re-check before the\n\t\t\t\t\t\t// transaction is allowed to commit so leaked concurrent work\n\t\t\t\t\t\t// cannot mutate an already registered aggregate mid-flush.\n\t\t\t\t\t\ts.assertReadyToCommit();\n\t\t\t\t\t\tworkCompleted = true;\n\t\t\t\t\t\t// Seal immediately: the aggregates snapshot below is what\n\t\t\t\t\t\t// gets harvested. A late registration from work still in\n\t\t\t\t\t\t// flight must throw\n\t\t\t\t\t\t// TransactionClosedError instead of being silently\n\t\t\t\t\t\t// accepted-but-never-harvested.\n\t\t\t\t\t\tconst commits = s.commitTokens;\n\t\t\t\t\t\ts.close();\n\t\t\t\t\t\treturn { result, commits };\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tworkThrew = true;\n\t\t\t\t\t\tworkError = error;\n\t\t\t\t\t\tthrow error;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthrow classifyRunError(error, {\n\t\t\t\tworkThrew,\n\t\t\t\tworkCompleted,\n\t\t\t\tworkError,\n\t\t\t\tsignal: options?.signal,\n\t\t\t});\n\t\t} finally {\n\t\t\tsession?.close();\n\t\t\tthis._active = false;\n\t\t}\n\t}\n\n\tprivate buildRepositories(\n\t\ttx: TCtx,\n\t\tsession: Session<Evt>,\n\t): RepositoriesOf<TDefinitions> {\n\t\tconst repositories = {} as RepositoriesOf<TDefinitions>;\n\t\tfor (const key of Object.keys(this.deps.repositories) as Array<\n\t\t\tkeyof TDefinitions\n\t\t>) {\n\t\t\tconst candidate = this.deps.repositories[key] as unknown;\n\t\t\tif (!isRepositoryDefinition(candidate)) {\n\t\t\t\tthrow new InvalidRepositoryDefinitionError(String(key));\n\t\t\t}\n\t\t\tconst definition = candidate as RuntimeRepositoryDefinition<Evt, TCtx>;\n\t\t\tconst adapter = definition.create(tx, session.trackingFor(definition));\n\t\t\trepositories[key] = bindRepositoryWrites(\n\t\t\t\tadapter,\n\t\t\t\tsession,\n\t\t\t\tdefinition,\n\t\t\t\tString(key),\n\t\t\t) as RepositoriesOf<TDefinitions>[typeof key];\n\t\t}\n\t\treturn repositories;\n\t}\n}\n\nfunction isRepositoryDefinition(value: unknown): value is object {\n\tif (value === null || typeof value !== \"object\") return false;\n\ttry {\n\t\tconst marker = Reflect.getOwnPropertyDescriptor(\n\t\t\tvalue,\n\t\t\trepositoryDefinitionBrand,\n\t\t);\n\t\treturn (\n\t\t\tmarker?.value === true &&\n\t\t\tmarker.configurable === false &&\n\t\t\tmarker.enumerable === false &&\n\t\t\tmarker.writable === false &&\n\t\t\tObject.isFrozen(value)\n\t\t);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Builds the application-facing repository facade. Standard lifecycle writes\n * are always supplied by the Unit of Work; similarly named adapter methods are\n * never invoked. Other methods are bound to the adapter so classes with private\n * fields keep their normal receiver.\n */\nfunction bindRepositoryWrites<TRepository, Evt extends AnyDomainEvent>(\n\tadapter: TRepository,\n\tsession: Session<Evt>,\n\tdefinition: RuntimePersistenceDefinition<Evt>,\n\trepository: string,\n): TRepository {\n\tif (adapter === null || typeof adapter !== \"object\") {\n\t\tthrow new InvalidRepositoryAdapterError(\n\t\t\trepository,\n\t\t\tadapter === null ? \"null\" : typeof adapter,\n\t\t);\n\t}\n\n\tconst state = createRepositoryFacadeState(\n\t\tadapter as object,\n\t\tsession,\n\t\tdefinition,\n\t);\n\tinstallRepositoryLifecycleOperations(state);\n\tforwardAdapterOwnProperties(state);\n\treturn new Proxy(\n\t\tstate.target,\n\t\tcreateRepositoryFacadeHandler(state),\n\t) as TRepository;\n}\n\nconst REPOSITORY_LIFECYCLE_OPERATIONS = [\"add\", \"update\", \"remove\"] as const;\n\ninterface GuardedMethodCacheEntry {\n\t/** The source function the wrapper was built over; identity-checked on\n\t * every read so a self-mutated adapter method cannot serve stale. */\n\treadonly sourceMethod: (...args: unknown[]) => unknown;\n\treadonly guarded: (...args: unknown[]) => unknown;\n}\n\ninterface RepositoryFacadeState<Evt extends AnyDomainEvent> {\n\treadonly source: object;\n\treadonly target: object;\n\treadonly session: Session<Evt>;\n\treadonly definition: RuntimePersistenceDefinition<Evt>;\n\treadonly methodCache: Map<PropertyKey, GuardedMethodCacheEntry>;\n\treadonly forwardedOwnProperties: Set<PropertyKey>;\n\treadonly writes: Set<PropertyKey>;\n}\n\nfunction createRepositoryFacadeState<Evt extends AnyDomainEvent>(\n\tsource: object,\n\tsession: Session<Evt>,\n\tdefinition: RuntimePersistenceDefinition<Evt>,\n): RepositoryFacadeState<Evt> {\n\treturn {\n\t\tsource,\n\t\ttarget: Object.create(Reflect.getPrototypeOf(source)) as object,\n\t\tsession,\n\t\tdefinition,\n\t\tmethodCache: new Map(),\n\t\tforwardedOwnProperties: new Set(),\n\t\twrites: new Set(),\n\t};\n}\n\nfunction repositoryOperationName(property: PropertyKey): string {\n\tconst name =\n\t\ttypeof property === \"symbol\"\n\t\t\t? (property.description ?? property.toString())\n\t\t\t: property;\n\treturn `repository.${name}`;\n}\n\nfunction isRepositoryLifecycleOperation(property: PropertyKey): boolean {\n\treturn REPOSITORY_LIFECYCLE_OPERATIONS.includes(\n\t\tproperty as (typeof REPOSITORY_LIFECYCLE_OPERATIONS)[number],\n\t);\n}\n\n/**\n * Own-or-inherited presence that stops BEFORE `Object.prototype`: members\n * every object inherits (`toString`, `valueOf`, `constructor`) are language\n * plumbing, not repository surface, and must not trip the facade's\n * session-open assertion.\n */\nfunction hasMemberBelowObjectPrototype(\n\tobject: object,\n\tproperty: PropertyKey,\n): boolean {\n\tlet current: object | null = object;\n\twhile (current !== null && current !== Object.prototype) {\n\t\tif (Reflect.getOwnPropertyDescriptor(current, property)) return true;\n\t\tcurrent = Reflect.getPrototypeOf(current);\n\t}\n\treturn false;\n}\n\nfunction readRepositorySource<Evt extends AnyDomainEvent>(\n\tstate: RepositoryFacadeState<Evt>,\n\tproperty: PropertyKey,\n): unknown {\n\tstate.session.assertOpen(repositoryOperationName(property));\n\tconst value = Reflect.get(state.source, property, state.source);\n\tif (typeof value !== \"function\") return value;\n\t// Cache validity is keyed on the CURRENT source function, not the\n\t// property name alone: adapter methods run with `this` bound to the raw\n\t// source, so a lazy-init self-assignment replaces the method without any\n\t// proxy trap firing. A name-only cache would keep serving the wrapper\n\t// closed over the replaced function for the rest of the run.\n\tconst cached = state.methodCache.get(property);\n\tif (cached && cached.sourceMethod === value) return cached.guarded;\n\tconst sourceMethod = value as (...args: unknown[]) => unknown;\n\tconst guarded = (...args: unknown[]): unknown => {\n\t\tstate.session.assertOpen(repositoryOperationName(property));\n\t\treturn Reflect.apply(sourceMethod, state.source, args);\n\t};\n\tstate.methodCache.set(property, { sourceMethod, guarded });\n\treturn guarded;\n}\n\nfunction defineForwardedRepositoryProperty<Evt extends AnyDomainEvent>(\n\tstate: RepositoryFacadeState<Evt>,\n\tproperty: PropertyKey,\n\tdescriptor: PropertyDescriptor,\n): void {\n\tObject.defineProperty(state.target, property, {\n\t\tconfigurable: true,\n\t\tenumerable: descriptor.enumerable ?? false,\n\t\tget: () => readRepositorySource(state, property),\n\t\tset:\n\t\t\t(\"value\" in descriptor && descriptor.writable) || descriptor.set\n\t\t\t\t? (value: unknown) => {\n\t\t\t\t\t\tstate.session.assertOpen(repositoryOperationName(property));\n\t\t\t\t\t\tif (!Reflect.set(state.source, property, value, state.source)) {\n\t\t\t\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\t\t\t`Cannot assign to repository property ${String(property)}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t});\n\tstate.forwardedOwnProperties.add(property);\n}\n\nfunction installRepositoryLifecycleOperations<Evt extends AnyDomainEvent>(\n\tstate: RepositoryFacadeState<Evt>,\n): void {\n\tconst operations = state.definition.physicalRemoval\n\t\t? REPOSITORY_LIFECYCLE_OPERATIONS\n\t\t: REPOSITORY_LIFECYCLE_OPERATIONS.slice(0, 2);\n\tfor (const operation of operations) {\n\t\tstate.writes.add(operation);\n\t\tObject.defineProperty(state.target, operation, {\n\t\t\tconfigurable: false,\n\t\t\tenumerable: false,\n\t\t\twritable: false,\n\t\t\tvalue: (aggregate: unknown) => {\n\t\t\t\tstate.session.assertOpen(repositoryOperationName(operation));\n\t\t\t\tstate.session[operation](\n\t\t\t\t\taggregate as IAggregateRoot<Id<string>, Evt>,\n\t\t\t\t\tstate.definition,\n\t\t\t\t);\n\t\t\t},\n\t\t});\n\t}\n}\n\nfunction forwardAdapterOwnProperties<Evt extends AnyDomainEvent>(\n\tstate: RepositoryFacadeState<Evt>,\n): void {\n\tfor (const property of Reflect.ownKeys(state.source)) {\n\t\tif (isRepositoryLifecycleOperation(property)) continue;\n\t\tconst descriptor = Reflect.getOwnPropertyDescriptor(state.source, property);\n\t\tif (descriptor) {\n\t\t\tdefineForwardedRepositoryProperty(state, property, descriptor);\n\t\t}\n\t}\n}\n\nfunction createRepositoryFacadeHandler<Evt extends AnyDomainEvent>(\n\tstate: RepositoryFacadeState<Evt>,\n): ProxyHandler<object> {\n\treturn {\n\t\tget: (target, property, receiver) => {\n\t\t\t// Language-level probes are not repository operations: promise\n\t\t\t// resolution reads `then` on any value returned from run(),\n\t\t\t// JSON.stringify probes `toJSON`, string interpolation reads\n\t\t\t// `toString`, and inspection utilities read well-known symbols.\n\t\t\t// One principled rule instead of one exemption per discovered\n\t\t\t// probe: only a property present BELOW Object.prototype is\n\t\t\t// repository surface and gets the session-open assertion.\n\t\t\t// Everything else is language plumbing and answers normally, so\n\t\t\t// logging a leaked facade after close cannot mask the original\n\t\t\t// failure. Member reads keep the loud TransactionClosedError\n\t\t\t// (a probe cannot leak state; a member read can).\n\t\t\tif (\n\t\t\t\t!hasMemberBelowObjectPrototype(target, property) &&\n\t\t\t\t!hasMemberBelowObjectPrototype(state.source, property)\n\t\t\t) {\n\t\t\t\treturn Reflect.get(target, property, receiver);\n\t\t\t}\n\t\t\tstate.session.assertOpen(repositoryOperationName(property));\n\t\t\tconst own = Reflect.getOwnPropertyDescriptor(target, property);\n\t\t\tif (own) return Reflect.get(target, property, receiver);\n\t\t\tif (property === \"remove\") return undefined;\n\t\t\treturn readRepositorySource(state, property);\n\t\t},\n\t\tset: (target, property, value, receiver) =>\n\t\t\tsetRepositoryFacadeProperty(state, target, property, value, receiver),\n\t\thas: (target, property) => {\n\t\t\tstate.session.assertOpen(repositoryOperationName(property));\n\t\t\treturn (\n\t\t\t\tstate.writes.has(property) ||\n\t\t\t\t(property !== \"remove\" &&\n\t\t\t\t\t(Reflect.has(target, property) ||\n\t\t\t\t\t\tReflect.has(state.source, property)))\n\t\t\t);\n\t\t},\n\t\tdefineProperty: (target, property, descriptor) =>\n\t\t\tdefineRepositoryFacadeProperty(state, target, property, descriptor),\n\t\tdeleteProperty: (target, property) =>\n\t\t\tdeleteRepositoryFacadeProperty(state, target, property),\n\t};\n}\n\nfunction setRepositoryFacadeProperty<Evt extends AnyDomainEvent>(\n\tstate: RepositoryFacadeState<Evt>,\n\ttarget: object,\n\tproperty: PropertyKey,\n\tvalue: unknown,\n\treceiver: unknown,\n): boolean {\n\tstate.session.assertOpen(repositoryOperationName(property));\n\tif (isRepositoryLifecycleOperation(property)) return false;\n\tif (Reflect.getOwnPropertyDescriptor(target, property)) {\n\t\tconst set = Reflect.set(target, property, value, receiver);\n\t\tif (set) state.methodCache.delete(property);\n\t\treturn set;\n\t}\n\tif (!Reflect.isExtensible(target)) return false;\n\tconst set = Reflect.set(state.source, property, value, state.source);\n\tconst descriptor = Reflect.getOwnPropertyDescriptor(state.source, property);\n\tif (set && descriptor) {\n\t\tdefineForwardedRepositoryProperty(state, property, descriptor);\n\t}\n\t// Every successful set invalidates the guarded-method cache, matching the\n\t// own-descriptor and delete paths: a cached wrapper closed over the\n\t// replaced function must not outlive the override (test spies, strategy\n\t// swaps).\n\tif (set) state.methodCache.delete(property);\n\treturn set;\n}\n\nfunction defineRepositoryFacadeProperty<Evt extends AnyDomainEvent>(\n\tstate: RepositoryFacadeState<Evt>,\n\ttarget: object,\n\tproperty: PropertyKey,\n\tdescriptor: PropertyDescriptor,\n): boolean {\n\tstate.session.assertOpen(repositoryOperationName(property));\n\tif (\n\t\tisRepositoryLifecycleOperation(property) &&\n\t\t!Reflect.getOwnPropertyDescriptor(target, property)\n\t) {\n\t\treturn false;\n\t}\n\tconst current = Reflect.getOwnPropertyDescriptor(target, property);\n\tif (!Reflect.defineProperty(target, property, descriptor)) return false;\n\tconst next = Reflect.getOwnPropertyDescriptor(target, property);\n\tif (\n\t\tstate.forwardedOwnProperties.has(property) &&\n\t\t(current?.get !== next?.get || current?.set !== next?.set)\n\t) {\n\t\tstate.forwardedOwnProperties.delete(property);\n\t}\n\treturn true;\n}\n\nfunction deleteRepositoryFacadeProperty<Evt extends AnyDomainEvent>(\n\tstate: RepositoryFacadeState<Evt>,\n\ttarget: object,\n\tproperty: PropertyKey,\n): boolean {\n\tstate.session.assertOpen(repositoryOperationName(property));\n\tif (isRepositoryLifecycleOperation(property)) return false;\n\tconst targetDescriptor = Reflect.getOwnPropertyDescriptor(target, property);\n\tif (targetDescriptor && !state.forwardedOwnProperties.has(property)) {\n\t\treturn Reflect.deleteProperty(target, property);\n\t}\n\tconst sourceDescriptor = Reflect.getOwnPropertyDescriptor(\n\t\tstate.source,\n\t\tproperty,\n\t);\n\tif (\n\t\ttargetDescriptor?.configurable === false ||\n\t\tsourceDescriptor?.configurable === false\n\t) {\n\t\treturn false;\n\t}\n\tif (!Reflect.deleteProperty(state.source, property)) return false;\n\tif (targetDescriptor && !Reflect.deleteProperty(target, property))\n\t\treturn false;\n\tstate.forwardedOwnProperties.delete(property);\n\tstate.methodCache.delete(property);\n\treturn true;\n}\n\ntype AggregateLifecycle = \"new\" | \"loaded\";\n\n/**\n * The immutable receipt one add/update/remove registration freezes: intent,\n * exact version and event batch, the sealed persistence baseline, and the\n * derived change set. It exists as ONE optional unit so registration,\n * rollback, and flush cannot half-apply it; `registration === undefined`\n * means \"tracked but no write registered\".\n */\ninterface WriteRegistration<Evt extends AnyDomainEvent> {\n\treadonly intent: AggregateWriteIntent;\n\treadonly version: Version;\n\treadonly events: ReadonlyArray<PendingDomainEvent<Evt>>;\n\treadonly baseline: PersistenceBaseline<\n\t\tIAggregateRoot<Id<string>, Evt>,\n\t\tunknown\n\t>;\n\treadonly changes: PersistenceChanges<unknown>;\n}\n\ninterface TrackedAggregate<Evt extends AnyDomainEvent> {\n\treadonly aggregate: IAggregateRoot<Id<string>, Evt>;\n\treadonly lifecycle: AggregateLifecycle;\n\treadonly expectedVersion: Version | undefined;\n\treadonly definition: RuntimePersistenceDefinition<Evt>;\n\treadonly baseline: PersistenceBaseline<\n\t\tIAggregateRoot<Id<string>, Evt>,\n\t\tunknown\n\t>;\n\tregistration?: WriteRegistration<Evt>;\n}\n\n/** Internal session implementation; closed by `run()`'s finally. */\nclass Session<Evt extends AnyDomainEvent> {\n\t// Read tracking order is independent of write registration order. Flush\n\t// follows this list so adapters observe the same explicit order as the use\n\t// case's add/update/remove calls. Enrollment and removal state are NOT\n\t// separate collections: both derive from each entry's registration, so\n\t// the bookkeeping cannot drift apart.\n\tprivate readonly _registeredWrites: TrackedAggregate<Evt>[] = [];\n\tprivate readonly _commitTokens = new Set<AggregateCommitToken<Evt>>();\n\tprivate readonly _identityMap = new IdentityMap();\n\t// What adapters receive: the typed read-only view, enforced at runtime.\n\t// Handing out the map itself would expose set/delete/clear to JavaScript\n\t// callers, and a stray clear() erases deletion tombstones and the\n\t// pending-event baselines behind UnenrolledChangesError.\n\tprivate readonly _identityMapView = Object.freeze({\n\t\tget: this._identityMap.get.bind(this._identityMap),\n\t\thas: this._identityMap.has.bind(this._identityMap),\n\t\tisDeleted: this._identityMap.isDeleted.bind(this._identityMap),\n\t}) as UnitOfWorkIdentityMap;\n\tprivate readonly _trackingByAggregate = new WeakMap<\n\t\tIAggregateRoot<Id<string>, Evt>,\n\t\tTrackedAggregate<Evt>\n\t>();\n\tprivate readonly _trackedAggregates = new Set<TrackedAggregate<Evt>>();\n\tprivate _closed = false;\n\n\tconstructor(private readonly commitEnrollment: CommitEnrollment<Evt>) {}\n\n\tpublic get identityMap(): UnitOfWorkIdentityMap {\n\t\tthis.assertOpen(\"tracking.identityMap\");\n\t\treturn this._identityMapView;\n\t}\n\n\tpublic trackingFor(\n\t\tdefinition: RuntimePersistenceDefinition<Evt>,\n\t): RepositoryTracking<IAggregateRoot<Id<string>, Evt>> {\n\t\tconst session = this;\n\t\treturn Object.freeze({\n\t\t\tget identityMap() {\n\t\t\t\treturn session.identityMap;\n\t\t\t},\n\t\t\ttrackLoaded: (aggregate: IAggregateRoot<Id<string>, Evt>) =>\n\t\t\t\tsession.trackLoaded(aggregate, definition),\n\t\t});\n\t}\n\n\t/** The registration of an instance, or undefined when none is tracked. */\n\tprivate registrationOf(\n\t\taggregate: object,\n\t): WriteRegistration<Evt> | undefined {\n\t\treturn this._trackingByAggregate.get(\n\t\t\taggregate as IAggregateRoot<Id<string>, Evt>,\n\t\t)?.registration;\n\t}\n\n\t/** Whether THIS instance registered a remove in this session. */\n\tprivate isRemovedInstance(aggregate: object): boolean {\n\t\treturn this.registrationOf(aggregate)?.intent === \"remove\";\n\t}\n\n\tprivate trackLoaded<TAggregate extends IAggregateRoot<Id<string>, Evt>>(\n\t\taggregate: TAggregate,\n\t\tdefinition: RuntimePersistenceDefinition<Evt>,\n\t): TAggregate {\n\t\tthis.assertOpen(\"tracking.trackLoaded\");\n\t\t// Ownership is checked BEFORE identity-map registration: a rejected\n\t\t// instance must not stay registered under the second definition's\n\t\t// class key with no tracking entry behind it.\n\t\tconst existing = this._trackingByAggregate.get(aggregate);\n\t\tif (existing && existing.definition !== definition) {\n\t\t\tthrow new AggregateTrackingError(\n\t\t\t\tString(aggregate.id),\n\t\t\t\t\"load\",\n\t\t\t\t\"different_repository\",\n\t\t\t\texisting.registration?.intent,\n\t\t\t);\n\t\t}\n\t\tthis._identityMap.set(definition.aggregate, aggregate.id, aggregate);\n\t\tif (existing) return aggregate;\n\n\t\tconst entry: TrackedAggregate<Evt> = {\n\t\t\taggregate,\n\t\t\tlifecycle: \"loaded\",\n\t\t\texpectedVersion: aggregate.version,\n\t\t\tdefinition,\n\t\t\tbaseline: capturePersistenceBaseline(definition.persistence, aggregate),\n\t\t};\n\t\tthis._trackingByAggregate.set(aggregate, entry);\n\t\tthis._trackedAggregates.add(entry);\n\t\treturn aggregate;\n\t}\n\n\tpublic add(\n\t\taggregate: IAggregateRoot<Id<string>, Evt>,\n\t\tdefinition: RuntimePersistenceDefinition<Evt>,\n\t): void {\n\t\tthis.assertOpen(\"repository.add\");\n\t\tthis.assertNotRemoved(aggregate, definition);\n\t\tconst existing = this._trackingByAggregate.get(aggregate);\n\t\tif (existing && existing.definition !== definition) {\n\t\t\tthrow new AggregateTrackingError(\n\t\t\t\tString(aggregate.id),\n\t\t\t\t\"add\",\n\t\t\t\t\"different_repository\",\n\t\t\t\texisting.registration?.intent,\n\t\t\t);\n\t\t}\n\t\tif (existing?.lifecycle === \"loaded\") {\n\t\t\tthrow new AggregateTrackingError(\n\t\t\t\tString(aggregate.id),\n\t\t\t\t\"add\",\n\t\t\t\t\"loaded_as_new\",\n\t\t\t\texisting.registration?.intent,\n\t\t\t);\n\t\t}\n\n\t\tlet entry = existing;\n\t\tconst newlyTracked = !entry;\n\t\tif (!entry) {\n\t\t\tthis._identityMap.set(definition.aggregate, aggregate.id, aggregate);\n\t\t\tentry = {\n\t\t\t\taggregate,\n\t\t\t\tlifecycle: \"new\",\n\t\t\t\texpectedVersion: undefined,\n\t\t\t\tdefinition,\n\t\t\t\tbaseline: insertPersistenceBaseline(definition.persistence),\n\t\t\t};\n\t\t\tthis._trackingByAggregate.set(aggregate, entry);\n\t\t\tthis._trackedAggregates.add(entry);\n\t\t}\n\n\t\ttry {\n\t\t\tthis.registerWrite(entry, \"add\", definition);\n\t\t} catch (error) {\n\t\t\t// A failed add must not leave a phantom: without this rollback,\n\t\t\t// findById would serve the never-persisted instance from the\n\t\t\t// identity map while the commit-readiness guard ignores \"new\"\n\t\t\t// lifecycle entries, so the transaction would commit without a\n\t\t\t// write for it.\n\t\t\tif (newlyTracked) {\n\t\t\t\tthis._trackingByAggregate.delete(aggregate);\n\t\t\t\tthis._trackedAggregates.delete(entry);\n\t\t\t\tthis._identityMap.discard(definition.aggregate, aggregate.id, aggregate);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tpublic update(\n\t\taggregate: IAggregateRoot<Id<string>, Evt>,\n\t\tdefinition: RuntimePersistenceDefinition<Evt>,\n\t): void {\n\t\tthis.assertOpen(\"repository.update\");\n\t\tconst entry = this.loadedEntryFor(aggregate, \"update\", definition);\n\t\tthis.registerWrite(entry, \"update\", definition);\n\t}\n\n\tpublic remove(\n\t\taggregate: IAggregateRoot<Id<string>, Evt>,\n\t\tdefinition: RuntimePersistenceDefinition<Evt>,\n\t): void {\n\t\tthis.assertOpen(\"repository.remove\");\n\t\t// Idempotent by reference, like add and update: a repeated remove of\n\t\t// the SAME instance re-declares the same final lifecycle outcome\n\t\t// (collection semantics; the enrollment layer already returns the\n\t\t// same token for a repeat enrollDeleted). The deletion-finality gate\n\t\t// stays sharp for everything else: add, update, and trackLoaded\n\t\t// after remove, and any OTHER instance with the same id, still\n\t\t// reject.\n\t\tconst entry = this._trackingByAggregate.get(aggregate);\n\t\tif (this.isRemovedInstance(aggregate) && entry?.definition === definition) {\n\t\t\treturn;\n\t\t}\n\t\tconst loaded = this.loadedEntryFor(aggregate, \"remove\", definition);\n\t\tthis.registerWrite(loaded, \"remove\", definition);\n\t}\n\n\t/** Registers persistence intent and commit enrollment as one operation. */\n\tprivate registerWrite(\n\t\tentry: TrackedAggregate<Evt>,\n\t\tintent: AggregateWriteIntent,\n\t\tdefinition: RuntimePersistenceDefinition<Evt>,\n\t): void {\n\t\tconst newlyRegistered = this.registerIntent(entry, intent);\n\t\ttry {\n\t\t\tif (intent === \"remove\") {\n\t\t\t\tthis.registerRemovedCommit(\n\t\t\t\t\tentry.aggregate,\n\t\t\t\t\tdefinition,\n\t\t\t\t\tentry.expectedVersion,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthis.registerSavedCommit(\n\t\t\t\t\tentry.aggregate,\n\t\t\t\t\tdefinition,\n\t\t\t\t\tentry.expectedVersion,\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (newlyRegistered) this.rollbackIntentRegistration(entry);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate loadedEntryFor(\n\t\taggregate: IAggregateRoot<Id<string>, Evt>,\n\t\toperation: \"update\" | \"remove\",\n\t\tdefinition: RuntimePersistenceDefinition<Evt>,\n\t): TrackedAggregate<Evt> {\n\t\tthis.assertNotRemoved(aggregate, definition);\n\t\tconst entry = this._trackingByAggregate.get(aggregate);\n\t\t// Repository-ownership violations report as such on every operation:\n\t\t// add and trackLoaded already use different_repository, and code\n\t\t// branching on the machine-readable reason must not get not_loaded\n\t\t// for the identical violation on the update/remove path.\n\t\tif (entry && entry.definition !== definition) {\n\t\t\tthrow new AggregateTrackingError(\n\t\t\t\tString(aggregate.id),\n\t\t\t\toperation,\n\t\t\t\t\"different_repository\",\n\t\t\t\tentry.registration?.intent,\n\t\t\t);\n\t\t}\n\t\t// An add()-registered aggregate IS tracked, just not \"loaded\": report\n\t\t// the real conflict with the registered intent. The not_loaded advice\n\t\t// (\"load it through the repository\") is impossible for an aggregate\n\t\t// that has no row yet and would actively mislead.\n\t\tif (\n\t\t\tentry &&\n\t\t\tentry.lifecycle === \"new\" &&\n\t\t\tentry.definition === definition\n\t\t) {\n\t\t\tthrow new AggregateTrackingError(\n\t\t\t\tString(aggregate.id),\n\t\t\t\toperation,\n\t\t\t\t\"conflicting_intent\",\n\t\t\t\tentry.registration?.intent,\n\t\t\t);\n\t\t}\n\t\tif (\n\t\t\t!entry ||\n\t\t\tentry.lifecycle !== \"loaded\" ||\n\t\t\tentry.definition !== definition\n\t\t) {\n\t\t\tthrow new AggregateTrackingError(\n\t\t\t\tString(aggregate.id),\n\t\t\t\toperation,\n\t\t\t\t\"not_loaded\",\n\t\t\t\tentry?.registration?.intent,\n\t\t\t);\n\t\t}\n\t\treturn entry;\n\t}\n\n\tprivate assertNotRemoved(\n\t\taggregate: IAggregateRoot<Id<string>, Evt>,\n\t\tdefinition: RuntimePersistenceDefinition<Evt>,\n\t): void {\n\t\tif (this._identityMap.isDeleted(definition.aggregate, aggregate.id)) {\n\t\t\tthrow new AggregateDeletedError(String(aggregate.id));\n\t\t}\n\t}\n\n\tprivate registerIntent(\n\t\tentry: TrackedAggregate<Evt>,\n\t\tintent: AggregateWriteIntent,\n\t): boolean {\n\t\tif (entry.registration !== undefined) {\n\t\t\tif (entry.registration.intent !== intent) {\n\t\t\t\tthrow new AggregateTrackingError(\n\t\t\t\t\tString(entry.aggregate.id),\n\t\t\t\t\tintent,\n\t\t\t\t\t\"conflicting_intent\",\n\t\t\t\t\tentry.registration.intent,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.assertUnchangedAfterRegistration(entry);\n\t\t\treturn false;\n\t\t}\n\n\t\tentry.registration = Object.freeze({\n\t\t\tintent,\n\t\t\tversion: entry.aggregate.version,\n\t\t\t// Already a frozen detached copy from the pendingEvents getter.\n\t\t\tevents: entry.aggregate.pendingEvents,\n\t\t\tbaseline: recapturePersistenceBaseline(entry.baseline, entry.aggregate),\n\t\t\tchanges: derivePersistenceChanges(entry.baseline, entry.aggregate),\n\t\t});\n\t\tthis._registeredWrites.push(entry);\n\t\treturn true;\n\t}\n\n\t/** Restores the pre-registration state when commit enrollment rejects. */\n\tprivate rollbackIntentRegistration(entry: TrackedAggregate<Evt>): void {\n\t\tconst index = this._registeredWrites.lastIndexOf(entry);\n\t\tif (index >= 0) this._registeredWrites.splice(index, 1);\n\t\tdelete entry.registration;\n\t}\n\n\tprivate assertUnchangedAfterRegistration(entry: TrackedAggregate<Evt>): void {\n\t\tconst registration = entry.registration;\n\t\tif (registration === undefined) return;\n\t\tconst currentEvents = entry.aggregate.pendingEvents;\n\t\t// Capture-to-capture drift, NOT changes().isEmpty(): the\n\t\t// PersistenceModel contract permits full-replacement change sets that\n\t\t// are never empty, so a non-empty change set proves nothing about\n\t\t// mutation after registration.\n\t\tconst persistenceChanged = persistenceProjectionDrifted(\n\t\t\tregistration.baseline,\n\t\t\tentry.aggregate,\n\t\t);\n\t\tconst sameEvents =\n\t\t\tcurrentEvents.length === registration.events.length &&\n\t\t\tcurrentEvents.every(\n\t\t\t\t(event, index) => event === registration.events[index],\n\t\t\t);\n\t\tif (\n\t\t\tregistration.version !== entry.aggregate.version ||\n\t\t\t!sameEvents ||\n\t\t\tpersistenceChanged\n\t\t) {\n\t\t\tthrow new AggregateTrackingError(\n\t\t\t\tString(entry.aggregate.id),\n\t\t\t\t\"commit\",\n\t\t\t\t\"mutated_after_registration\",\n\t\t\t\tregistration.intent,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate registerSavedCommit(\n\t\taggregate: IAggregateRoot<Id<string>, Evt>,\n\t\tdefinition: RuntimePersistenceDefinition<Evt>,\n\t\texpectedVersion: Version | undefined,\n\t): AggregateCommitToken<Evt> {\n\t\tthis.assertOpen(\"repository.add/update\");\n\t\t// Two gates, one invariant: the registration check catches the same\n\t\t// reference; the identity-map tombstone (keyed on the instance's\n\t\t// concrete class) catches a DIFFERENT instance with the same\n\t\t// type+id: e.g. one re-created via the static factory after the\n\t\t// delete. Both mean \"deleted is final within this operation\".\n\t\tif (\n\t\t\tthis.isRemovedInstance(aggregate) ||\n\t\t\tthis._identityMap.isDeleted(definition.aggregate, aggregate.id)\n\t\t) {\n\t\t\tthrow new AggregateDeletedError(String(aggregate.id));\n\t\t}\n\t\tconst token = this.commitEnrollment.enrollSaved(aggregate, {\n\t\t\texpectedVersion,\n\t\t});\n\t\tthis._commitTokens.add(token);\n\t\treturn token;\n\t}\n\n\tprivate registerRemovedCommit(\n\t\taggregate: IAggregateRoot<Id<string>, Evt>,\n\t\tdefinition: RuntimePersistenceDefinition<Evt>,\n\t\texpectedVersion: Version | undefined,\n\t): AggregateCommitToken<Evt> {\n\t\tthis.assertOpen(\"repository.remove\");\n\t\tconst token = this.commitEnrollment.enrollDeleted(aggregate, {\n\t\t\texpectedVersion,\n\t\t});\n\t\t// One call does ALL the deletion bookkeeping: the identity-map\n\t\t// entry is removed and tombstoned automatically (keyed on the\n\t\t// instance's concrete class), so repositories do not need a\n\t\t// second manual identityMap.delete() call; a forgotten leg of a\n\t\t// two-call protocol would silently weaken the deletion gate. The\n\t\t// removed state itself derives from the entry's registration.\n\t\t// Assumption (documented on IdentityMap): repositories key the\n\t\t// map with the same concrete class their factories produce.\n\t\t// Deleted aggregates stay in the harvest set: their recorded\n\t\t// deletion events must reach the outbox (repository.md, hard-\n\t\t// delete with event harvest). withCommit receives them in the\n\t\t// deleted token disposition, so the saved-only application observer\n\t\t// never fires for a deletion.\n\t\tthis._identityMap.delete(definition.aggregate, aggregate.id);\n\t\tthis._commitTokens.add(token);\n\t\treturn token;\n\t}\n\n\t/**\n\t * End-of-run safety net. A loaded aggregate whose version or pending event\n\t * batch changed without `update` intent would otherwise be silently lost.\n\t * An aggregate that changed after registration could persist state and\n\t * events from different moments. Both violations reject inside the\n\t * transaction.\n\t */\n\tpublic assertReadyToCommit(): void {\n\t\tfor (const entry of this._trackedAggregates) {\n\t\t\tif (entry.registration !== undefined) {\n\t\t\t\tthis.assertUnchangedAfterRegistration(entry);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// Capture-to-capture drift against the load-time baseline: a\n\t\t\t// full-replacement model's changes() is never empty, which would\n\t\t\t// misreport every merely-loaded aggregate as unenrolled changes.\n\t\t\tif (\n\t\t\t\tentry.lifecycle === \"loaded\" &&\n\t\t\t\t(entry.aggregate.version !== entry.expectedVersion ||\n\t\t\t\t\tpersistenceProjectionDrifted(entry.baseline, entry.aggregate))\n\t\t\t) {\n\t\t\t\tthrow new UnenrolledChangesError(String(entry.aggregate.id));\n\t\t\t}\n\t\t}\n\n\t\tfor (const instance of this._identityMap.instancesWithNewPendingEvents()) {\n\t\t\t// Any registration (add, update, or remove) means the instance is\n\t\t\t// enrolled and its batch will be harvested.\n\t\t\tif (\n\t\t\t\tinstance !== null &&\n\t\t\t\ttypeof instance === \"object\" &&\n\t\t\t\tthis.registrationOf(instance) !== undefined\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// Events were recorded on a loaded aggregate after it was\n\t\t\t// registered, yet it has no write intent: a forgotten update whose\n\t\t\t// events would be silently dropped.\n\t\t\tconst id = (instance as { id?: unknown }).id;\n\t\t\tthrow new UnenrolledChangesError(String(id));\n\t\t}\n\t}\n\n\t/** Flushes every registered receipt in deterministic registration order. */\n\tpublic async flush(transaction: unknown): Promise<void> {\n\t\tthis.assertOpen(\"unitOfWork.flush\");\n\t\tfor (const entry of this._registeredWrites) {\n\t\t\tconst registration = entry.registration;\n\t\t\tif (registration === undefined) {\n\t\t\t\tthrow new AggregateTrackingError(\n\t\t\t\t\tString(entry.aggregate.id),\n\t\t\t\t\t\"commit\",\n\t\t\t\t\t\"mutated_after_registration\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst write = Object.freeze({\n\t\t\t\tintent: registration.intent,\n\t\t\t\taggregateId: entry.aggregate.id,\n\t\t\t\texpectedVersion: entry.expectedVersion,\n\t\t\t\tversion: registration.version,\n\t\t\t\tchanges: registration.changes,\n\t\t\t\tevents: registration.events,\n\t\t\t}) as AggregatePersistenceWrite<IAggregateRoot<Id<string>, Evt>, unknown>;\n\t\t\ttry {\n\t\t\t\tawait entry.definition.flush(transaction, write);\n\t\t\t} catch (error) {\n\t\t\t\tthrow mapRepositoryPersistenceError(entry.definition, error, write);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic get commitTokens(): ReadonlyArray<AggregateCommitToken<Evt>> {\n\t\treturn [...this._commitTokens];\n\t}\n\n\tpublic close(): void {\n\t\tthis._closed = true;\n\t\t// Defensive: a leaked direct IdentityMap reference must not serve\n\t\t// stale instances into a later operation (that would silently\n\t\t// bypass OCC). The session getter already throws after close;\n\t\t// clearing covers refs captured before.\n\t\tthis._identityMap.clear();\n\t\tthis._trackedAggregates.clear();\n\t\tthis._registeredWrites.length = 0;\n\t\tthis._commitTokens.clear();\n\t}\n\n\tpublic assertOpen(operation: string): void {\n\t\tif (this._closed) {\n\t\t\tthrow new TransactionClosedError(operation);\n\t\t}\n\t}\n}\n\nfunction mapRepositoryPersistenceError<Evt extends AnyDomainEvent>(\n\tdefinition: RuntimePersistenceDefinition<Evt>,\n\terror: unknown,\n\twrite: AggregatePersistenceWrite<IAggregateRoot<Id<string>, Evt>, unknown>,\n): InfrastructureError {\n\tlet mapped: unknown;\n\ttry {\n\t\tmapped = definition.mapError(error, write);\n\t} catch (mapperError) {\n\t\tthrow new RepositoryErrorMappingFailedError({\n\t\t\taggregateId: String(write.aggregateId),\n\t\t\tintent: write.intent,\n\t\t\tpersistenceError: error,\n\t\t\tmapperError,\n\t\t});\n\t}\n\t// Copy-safe: an adapter package can carry its own copy of the kit, whose\n\t// InfrastructureError fails a plain instanceof here; rejecting it would\n\t// turn every retryable conflict into a non-retryable wiring crash that\n\t// blames a correct mapper.\n\tif (isInfrastructureErrorLike(mapped)) return mapped;\n\tthrow new RepositoryErrorMappingFailedError({\n\t\taggregateId: String(write.aggregateId),\n\t\tintent: write.intent,\n\t\tpersistenceError: error,\n\t\tmapperError: new TypeError(\n\t\t\t\"Repository mapError must return an InfrastructureError instance\",\n\t\t),\n\t});\n}\n\nfunction makeContext<TRepos, Evt extends AnyDomainEvent>(\n\trepositories: TRepos,\n\tsession: Session<Evt>,\n\tsignal: AbortSignal | undefined,\n): UnitOfWorkContext<TRepos> {\n\treturn {\n\t\tget repositories(): TRepos {\n\t\t\tsession.assertOpen(\"context.repositories\");\n\t\t\treturn repositories;\n\t\t},\n\t\t// The caller's own signal: exposed directly, not gated by\n\t\t// assertOpen, so polling `aborted` after close stays harmless.\n\t\tsignal,\n\t};\n}\n\n/**\n * Classifies a `withCommit` rejection into the error `run()` should throw,\n * using the flags captured inside the work wrapper. Pure and total: it\n * returns the error to throw rather than throwing itself, so `run()` reads\n * as orchestration and this decision is unit-testable in isolation.\n *\n * - `workThrew`: the work callback (or `assertAllChangesEnrolled`) threw.\n * The scope normally rethrows that error unchanged (rolled back, pass\n * through so a `ConcurrencyConflictError` & co. stay catchable as-is); a\n * scope that WRAPS the original is detected via the cause chain and also\n * passed through. Only a rejection that neither IS nor wraps the\n * callback's error indicates the rollback itself failed, which becomes a\n * {@link RollbackError}.\n * - `workCompleted`: the callback finished; the failure is post-completion.\n * A harvest-guard violation (an event missing aggregateId / aggregateType,\n * or an eventful persisted aggregate that did not advance its version) is a deterministic\n * programming bug, surfaced as its {@link EventHarvestError} (which does\n * NOT extend `InfrastructureError`, so a retry-on-Infrastructure handler\n * skips it). It is thrown inside `scope.transactional()`, so a wrapping\n * scope can nest it: walk the chain rather than a bare `instanceof`. Only\n * genuinely unforeseeable post-completion failures (outbox write, the\n * commit itself) become {@link CommitError}.\n * - Neither flag set: `withCommit` rejected before the callback ran (the\n * scope failed to even open a transaction); pass the error through.\n */\nfunction classifyRunError(\n\terror: unknown,\n\tstate: {\n\t\treadonly workThrew: boolean;\n\t\treadonly workCompleted: boolean;\n\t\treadonly workError: unknown;\n\t\treadonly signal: AbortSignal | undefined;\n\t},\n): unknown {\n\t// Cancellation wins over the attempt flags: a scope that rejects with\n\t// the caller's abort reason between retry attempts never re-enters the\n\t// work callback, so workThrew/workError still describe the PREVIOUS\n\t// attempt. Classifying by those stale flags would mislabel the abort as\n\t// a RollbackError carrying a retryable cause, inviting a retry of an\n\t// explicitly cancelled operation.\n\tif (\n\t\tstate.signal?.aborted &&\n\t\tstate.signal.reason !== undefined &&\n\t\t(error === state.signal.reason ||\n\t\t\tcauseChainContains(error, state.signal.reason))\n\t) {\n\t\treturn error;\n\t}\n\tif (state.workThrew) {\n\t\tif (\n\t\t\terror === state.workError ||\n\t\t\tcauseChainContains(error, state.workError)\n\t\t) {\n\t\t\treturn error;\n\t\t}\n\t\treturn new RollbackError(state.workError, error);\n\t}\n\tif (state.workCompleted) {\n\t\tconst harvestError = findHarvestErrorInChain(error);\n\t\tif (harvestError) {\n\t\t\treturn harvestError;\n\t\t}\n\t\treturn new CommitError(error);\n\t}\n\treturn error;\n}\n\n/**\n * Cycle-safe, getter-throw-safe walk over `error`'s standard `cause`\n * chain. `visit` runs for every object link (the top error included) and\n * receives the link plus its lazily read `cause`; a non-undefined return\n * stops the walk. A throwing `cause` getter (lazy deserialization, revoked\n * Proxy) ends the walk as no-match instead of replacing the real failure\n * with the getter's exception.\n */\nfunction findInCauseChain<T>(\n\terror: unknown,\n\tvisit: (link: object, cause: unknown) => T | undefined,\n): T | undefined {\n\tconst seen = new Set<unknown>();\n\tlet current: unknown = error;\n\twhile (\n\t\tcurrent !== null &&\n\t\ttypeof current === \"object\" &&\n\t\t!seen.has(current)\n\t) {\n\t\tseen.add(current);\n\t\tlet cause: unknown;\n\t\ttry {\n\t\t\tcause = (current as { cause?: unknown }).cause;\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst found = visit(current, cause);\n\t\tif (found !== undefined) return found;\n\t\tcurrent = cause;\n\t}\n\treturn undefined;\n}\n\n/**\n * Walks `error`'s `cause` chain and returns the first `EventHarvestError`,\n * or `undefined`. `withCommit` throws the harvest-guard error INSIDE\n * `scope.transactional`, so a wrapping scope can nest it; matching\n * only the top-level error would let the wrapper mask the non-retryable\n * type. `withCommit` and `run()` share this module, so the local\n * `instanceof` is reliable for the un-wrapped link.\n */\nfunction findHarvestErrorInChain(\n\terror: unknown,\n): EventHarvestError | undefined {\n\treturn findInCauseChain(error, (link) =>\n\t\tlink instanceof EventHarvestError ? link : undefined,\n\t);\n}\n\n/**\n * Whether `error`'s `cause` chain contains `target` by reference. A\n * `target` of `undefined`/`null` never matches: every error without a\n * `cause` property would otherwise \"contain\" a thrown `undefined`.\n */\nfunction causeChainContains(error: unknown, target: unknown): boolean {\n\tif (target === undefined || target === null) {\n\t\treturn false;\n\t}\n\treturn (\n\t\tfindInCauseChain(error, (_link, cause) =>\n\t\t\tcause === target ? true : undefined,\n\t\t) ?? false\n\t);\n}\n","/** Operational classification applied to one failed background delivery. */\nexport type DeliveryFailureKind = \"transient\" | \"permanent\" | \"unknown\";\n\n/** Consumer-owned translation from an adapter error to delivery semantics. */\nexport type DeliveryFailureClassifier = (error: unknown) => DeliveryFailureKind;\n\n/** Result of applying a delivery-failure classifier safely. */\nexport interface DeliveryFailureAssessment {\n\t/** How the shell will account for and recover from the failure. */\n\treadonly kind: DeliveryFailureKind;\n\t/** Classifier bug or invalid return value, when classification itself failed. */\n\treadonly classifierError?: unknown;\n}\n\nconst KINDS = new Set<DeliveryFailureKind>([\n\t\"transient\",\n\t\"permanent\",\n\t\"unknown\",\n]);\n\n/**\n * Default delivery classification. A retryable marker anywhere in the cause\n * chain, or a native `TimeoutError`, is transient. An explicit\n * `retryable: false` marker is permanent. Unmapped errors stay unknown and use\n * the shell's safe accounting default.\n */\nexport function classifyDeliveryFailure(error: unknown): DeliveryFailureKind {\n\tlet current = error;\n\tlet sawNonRetryable = false;\n\tconst seen = new Set<object>();\n\n\twhile (\n\t\tcurrent !== null &&\n\t\t(typeof current === \"object\" || typeof current === \"function\")\n\t) {\n\t\tconst node = current as object;\n\t\tif (seen.has(node)) break;\n\t\tseen.add(node);\n\n\t\ttry {\n\t\t\tconst candidate = current as {\n\t\t\t\treadonly name?: unknown;\n\t\t\t\treadonly retryable?: unknown;\n\t\t\t\treadonly cause?: unknown;\n\t\t\t};\n\t\t\tif (candidate.name === \"TimeoutError\") return \"transient\";\n\t\t\tif (candidate.retryable === true) return \"transient\";\n\t\t\tif (candidate.retryable === false) sawNonRetryable = true;\n\t\t\tcurrent = candidate.cause;\n\t\t} catch {\n\t\t\treturn \"unknown\";\n\t\t}\n\t}\n\n\treturn sawNonRetryable ? \"permanent\" : \"unknown\";\n}\n\n/** Applies a custom/default classifier without letting it break the worker. */\nexport function assessDeliveryFailure(\n\terror: unknown,\n\tclassifier: DeliveryFailureClassifier = classifyDeliveryFailure,\n): DeliveryFailureAssessment {\n\ttry {\n\t\tconst kind = classifier(error);\n\t\tif (KINDS.has(kind)) return Object.freeze({ kind });\n\t\treturn Object.freeze({\n\t\t\tkind: \"unknown\",\n\t\t\tclassifierError: new TypeError(\n\t\t\t\t`Delivery failure classifier returned invalid kind: ${String(kind)}`,\n\t\t\t),\n\t\t});\n\t} catch (classifierError) {\n\t\treturn Object.freeze({ kind: \"unknown\", classifierError });\n\t}\n}\n","/**\n * Exponential backoff with jitter, shared by every retry loop in the\n * kit (`RetryingTransactionScope` attempt delays, `OutboxDispatcher`\n * failure backoff).\n *\n * `attempt` is 1-based. The exponential value\n * (`baseDelayMs * 2^(attempt-1)`) is capped at `maxDelayMs`, then a\n * jitter band (`* random(0.8, 1.2)`) is applied and re-clamped to the\n * cap. Pure and deterministic given `random`. Result is never\n * negative.\n *\n * Deliberately not exported from the package entries: it is shared\n * kit plumbing, not public API.\n */\nexport function computeBackoffDelay(\n\tattempt: number,\n\topts: { baseDelayMs: number; maxDelayMs: number; random: () => number },\n): number {\n\tconst exponential = opts.baseDelayMs * 2 ** (attempt - 1);\n\tconst capped = Math.min(opts.maxDelayMs, exponential);\n\tconst jitter = 0.8 + opts.random() * 0.4; // [0.8, 1.2)\n\treturn Math.max(0, Math.min(opts.maxDelayMs, Math.round(capped * jitter)));\n}\n\n/**\n * Wraps an injected jitter source with observer-grade robustness: a\n * throwing or non-finite source degrades to the midpoint multiplier\n * (no jitter) instead of rejecting the poller that uses it, which\n * documents itself as never rejecting and is typically `void`ed.\n */\nexport function neutralJitterSource(source: () => number): () => number {\n\treturn () => {\n\t\ttry {\n\t\t\tconst value = source();\n\t\t\treturn Number.isFinite(value) ? value : 0.5;\n\t\t} catch {\n\t\t\treturn 0.5;\n\t\t}\n\t};\n}\n","/**\n * Awaits an in-flight pass on behalf of a joining caller without\n * letting a signal-less pass hold the joiner hostage: on the joiner's\n * abort this resolves `\"stopped\"` and leaves the pass running for its\n * owner. The pass promise must never reject (the pollers' documented\n * contract), so a plain `then` suffices; the abort listener is removed\n * once the pass settles.\n */\nexport function joinWithoutBlockingOnAbort(\n\tpass: Promise<\"drained\" | \"stopped\">,\n\tsignal: AbortSignal | undefined,\n): Promise<\"drained\" | \"stopped\"> {\n\tif (signal === undefined) return pass;\n\tif (signal.aborted) return Promise.resolve(\"stopped\");\n\treturn new Promise((resolve) => {\n\t\tconst onAbort = (): void => resolve(\"stopped\");\n\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\tvoid pass.then((outcome) => {\n\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\tresolve(outcome);\n\t\t});\n\t});\n}\n","import { abortReason } from \"./abort\";\n\n/**\n * Abortable `setTimeout` that RESOLVES early when the signal fires.\n * The graceful-stop variant: callers that treat an abort as \"stop\n * sleeping and wind down\" (a worker loop's idle or backoff sleep) use\n * this so the loop can observe `signal.aborted` and return cleanly.\n */\nexport function sleepResolvingOnAbort(\n\tms: number,\n\tsignal: AbortSignal,\n): Promise<void> {\n\tif (ms <= 0 || signal.aborted) return Promise.resolve();\n\treturn new Promise((resolve) => {\n\t\tconst done = (): void => {\n\t\t\tclearTimeout(timer);\n\t\t\tsignal.removeEventListener(\"abort\", done);\n\t\t\tresolve();\n\t\t};\n\t\tconst timer = setTimeout(done, ms);\n\t\tsignal.addEventListener(\"abort\", done, { once: true });\n\t});\n}\n\n/**\n * Abortable `setTimeout` that REJECTS with the signal's reason when it\n * fires. The cancellation variant: callers that treat an abort as \"this\n * operation failed, propagate it\" (a retry loop whose caller awaits the\n * result) use this so the rejection carries through.\n */\nexport function sleepRejectingOnAbort(\n\tms: number,\n\tsignal: AbortSignal | undefined,\n\tabortMessage: string,\n): Promise<void> {\n\treturn new Promise<void>((resolve, reject) => {\n\t\tif (signal?.aborted) {\n\t\t\treject(abortReason(signal, abortMessage));\n\t\t\treturn;\n\t\t}\n\t\tlet onAbort: (() => void) | undefined;\n\t\tconst timer = setTimeout(() => {\n\t\t\tif (onAbort && signal) signal.removeEventListener(\"abort\", onAbort);\n\t\t\tresolve();\n\t\t}, ms);\n\t\tif (signal) {\n\t\t\tonAbort = () => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\treject(abortReason(signal, abortMessage));\n\t\t\t};\n\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t}\n\t});\n}\n","import { computeBackoffDelay, neutralJitterSource } from \"./backoff\";\nimport { joinWithoutBlockingOnAbort } from \"./in-flight\";\nimport { sleepResolvingOnAbort } from \"./sleep\";\nimport { assertNonNegativeFinite, assertPositiveInteger } from \"./validate\";\n\n/** Numeric options every kit poll loop shares; see the concrete classes. */\nexport interface PollLoopOptions {\n\tbatchSize?: number;\n\tpollIntervalMs?: number;\n\tbaseDelayMs?: number;\n\tmaxDelayMs?: number;\n\trandom?: () => number;\n}\n\n/**\n * The hardened poll-loop shell shared by `OutboxDispatcher` and\n * `DeadlineProcessor`, so the operationally tricky parts exist exactly\n * once: the never-rejecting `run(signal)` cadence (idle sleep when\n * drained, jittered streak backoff when stopped), the reentrancy-safe\n * `drainOnce` that joins an in-flight pass instead of starting a\n * competing one, option validation, and the per-instance neutralized\n * jitter source. Subclasses implement one thing: {@link pass}, the\n * delivery semantics of their port. Internal plumbing, not exported\n * from the package entries.\n */\nexport abstract class PollLoop {\n\tprotected readonly batchSize: number;\n\tprivate readonly pollIntervalMs: number;\n\tprivate readonly baseDelayMs: number;\n\tprivate readonly maxDelayMs: number;\n\tprivate readonly jitter: () => number;\n\n\t/**\n\t * Failed cycles since the last clean one; drives the backoff.\n\t * Subclasses bump it once per failed cycle and reset it on clean or\n\t * empty cycles (a subclass may bump by more, e.g. to a record's\n\t * attempt count, via direct assignment).\n\t */\n\tprotected consecutiveFailures = 0;\n\n\t/** In-flight pass; overlapping drainOnce calls join it. */\n\tprivate inFlightPass?: Promise<\"drained\" | \"stopped\">;\n\n\tprotected constructor(context: string, options: PollLoopOptions) {\n\t\tconst batchSize = options.batchSize ?? 32;\n\t\tassertPositiveInteger(context, \"batchSize\", batchSize);\n\t\tthis.batchSize = batchSize;\n\t\tthis.pollIntervalMs = options.pollIntervalMs ?? 250;\n\t\tthis.baseDelayMs = options.baseDelayMs ?? 50;\n\t\tthis.maxDelayMs = options.maxDelayMs ?? 5000;\n\t\tassertNonNegativeFinite(context, \"pollIntervalMs\", this.pollIntervalMs);\n\t\tassertNonNegativeFinite(context, \"baseDelayMs\", this.baseDelayMs);\n\t\tassertNonNegativeFinite(context, \"maxDelayMs\", this.maxDelayMs);\n\t\tthis.jitter = neutralJitterSource(options.random ?? Math.random);\n\t}\n\n\t/**\n\t * One full pass over the backlog: loop batches until nothing is\n\t * pending (`\"drained\"`) or a failure ends the cycle (`\"stopped\"`).\n\t * Must never reject; only ever one pass is in flight.\n\t */\n\tprotected abstract pass(signal?: AbortSignal): Promise<\"drained\" | \"stopped\">;\n\n\t/**\n\t * Runs the poll loop until `signal` aborts, then resolves. Never\n\t * rejects: a `\"drained\"` pass sleeps `pollIntervalMs`, a `\"stopped\"`\n\t * one sleeps the current streak backoff.\n\t */\n\tasync run(signal: AbortSignal): Promise<void> {\n\t\twhile (!signal.aborted) {\n\t\t\tconst outcome = await this.drainOnce(signal);\n\t\t\tif (signal.aborted) return;\n\t\t\tif (outcome === \"drained\") {\n\t\t\t\tawait sleepResolvingOnAbort(this.pollIntervalMs, signal);\n\t\t\t} else {\n\t\t\t\tawait sleepResolvingOnAbort(this.currentBackoff(), signal);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Single pass for cron triggers and serverless runtimes; returns\n\t * without sleeping (the tick cadence is the retry pacing; only\n\t * `run` sleeps the backoff). Reentrancy-safe: a call during an\n\t * in-flight pass joins it, and the joining call's own `signal`\n\t * still ends its wait while the pass runs on for its owner.\n\t *\n\t * With producers that keep the backlog non-empty, \"until drained\"\n\t * can outlast a bounded invocation: pass a `signal` wired to your\n\t * runtime's deadline (`AbortSignal.timeout(...)`) so the pass ends\n\t * cleanly; completed work stays acknowledged, the rest waits for\n\t * the next tick.\n\t */\n\tasync drainOnce(signal?: AbortSignal): Promise<\"drained\" | \"stopped\"> {\n\t\tif (this.inFlightPass !== undefined) {\n\t\t\treturn joinWithoutBlockingOnAbort(this.inFlightPass, signal);\n\t\t}\n\t\tconst pass = this.pass(signal);\n\t\tthis.inFlightPass = pass;\n\t\ttry {\n\t\t\treturn await pass;\n\t\t} finally {\n\t\t\tthis.inFlightPass = undefined;\n\t\t}\n\t}\n\n\t/** Backoff for the current consecutive-failure streak. */\n\tprivate currentBackoff(): number {\n\t\treturn computeBackoffDelay(Math.max(1, this.consecutiveFailures), {\n\t\t\tbaseDelayMs: this.baseDelayMs,\n\t\t\tmaxDelayMs: this.maxDelayMs,\n\t\t\trandom: this.jitter,\n\t\t});\n\t}\n}\n","import {\n\tassessDeliveryFailure,\n\ttype DeliveryFailureAssessment,\n\ttype DeliveryFailureClassifier,\n} from \"../utils/delivery-failure\";\nimport {\n\tDEFAULT_EXECUTION_TIMEOUT_MS,\n\ttype ExecutionContext,\n\trunBoundedExecution,\n} from \"../utils/execution\";\nimport { captureObserverFunctions, reportToObserver } from \"../utils/observer\";\nimport { PollLoop } from \"../utils/poll-loop\";\nimport { assertNonNegativeFinite } from \"../utils/validate\";\nimport type {\n\tDeadLetterDeadline,\n\tDeadlineStore,\n\tDueDeadline,\n} from \"./deadline-store\";\n\n/**\n * Required operational observers for {@link DeadlineProcessor}. All hooks are\n * best-effort notifications: synchronous throws and rejected promises are\n * neutralized so observability cannot change delivery state. The processor\n * captures and freezes these function references at construction, so later\n * mutation of the supplied object cannot disable an operational channel.\n *\n * `onDeadLetter` fires immediately after `markFailed` reports the exact\n * transition. It is not a durable notification boundary: a process can stop\n * after the store commits the transition and before the callback runs. Keep\n * polling {@link DeadlineStore.deadLetters} for durable alerting and\n * reconciliation; the hook provides low-latency diagnostics.\n */\nexport interface DeadlineProcessorObservers<TPayload> {\n\t/**\n\t * A handler, acknowledgement, or failure-tracking operation failed.\n\t * Handler failures include their accounting assessment; store failures do\n\t * not consume poison-message attempts and have no assessment.\n\t */\n\treadonly onDeliveryError: (\n\t\terror: unknown,\n\t\tdeadline: DueDeadline<TPayload>,\n\t\tassessment?: DeliveryFailureAssessment,\n\t) => void;\n\t/** Reading the poll clock or due page failed. */\n\treadonly onPollError: (error: unknown) => void;\n\t/** A deadline crossed the store's dead-letter threshold. */\n\treadonly onDeadLetter: (deadline: DeadLetterDeadline<TPayload>) => void;\n}\n\n/** Construction options for {@link DeadlineProcessor}. */\nexport interface DeadlineProcessorOptions<TPayload> {\n\t/** The poll surface; see {@link DeadlineStore}. */\n\tstore: DeadlineStore<TPayload>;\n\n\t/** Complete, required operational observer bundle. */\n\tobservers: DeadlineProcessorObservers<TPayload>;\n\n\t/**\n\t * Receives each due deadline as an input. A throw signals delivery\n\t * failure: the processor reports it via `markFailed` (the store\n\t * dead-letters past its ceiling) and moves on to the next deadline;\n\t * neighbors are independent. Remember the guide's discipline: a\n\t * delivered deadline is a proposal, so check it against current\n\t * state before acting. Pass `context.signal` to I/O adapters or enforce a\n\t * native timeout no later than `context.deadlineAt`. The shell bounds its\n\t * wait but cannot terminate an ignored foreign promise; production handlers\n\t * must prevent zombie work from overlapping a retry.\n\t */\n\thandler: (\n\t\tdeadline: DueDeadline<TPayload>,\n\t\tcontext: ExecutionContext,\n\t) => Promise<void> | void;\n\n\t/** Deadlines fetched per poll. Default `32`. */\n\tbatchSize?: number;\n\n\t/** Idle sleep between polls when nothing is due. Default `250`ms. */\n\tpollIntervalMs?: number;\n\n\t/**\n\t * First backoff delay after a failed cycle; grows exponentially with\n\t * the processor's consecutive-failure streak and is jittered.\n\t * Default `50`ms.\n\t */\n\tbaseDelayMs?: number;\n\n\t/** Ceiling for the failure backoff. Default `5000`ms. */\n\tmaxDelayMs?: number;\n\n\t/**\n\t * Maximum time to await one deadline handler. The handler receives the same\n\t * deadline as an AbortSignal and an absolute `deadlineAt`. Default `30000`ms.\n\t */\n\tdeliveryTimeoutMs?: number;\n\n\t/**\n\t * Maximum time to await one poll-store read, acknowledgement, or failure\n\t * update. The store receives the same cooperative context. This bounds the\n\t * worker's wait; production adapters must also cancel or natively bound the\n\t * underlying I/O. Default `30000`ms.\n\t */\n\tstorageTimeoutMs?: number;\n\n\t/**\n\t * Classifies handler failures as transient, permanent, or unknown. Transient\n\t * failures back off without consuming the poison ceiling; permanent and\n\t * unknown failures count. The default walks the cause chain: native\n\t * `TimeoutError` and `retryable: true` are transient, `retryable: false` is\n\t * permanent, and unmapped errors are unknown. A throwing or invalid custom\n\t * classifier becomes unknown and is exposed through the observer assessment\n\t * without replacing the original handler error.\n\t */\n\tclassifyFailure?: DeliveryFailureClassifier;\n\n\t/**\n\t * Jitter source for the failure backoff, injectable for\n\t * deterministic tests. Default `Math.random`. Neutralized like every\n\t * user callback: a throwing or non-finite source degrades to the\n\t * midpoint multiplier.\n\t */\n\trandom?: () => number;\n\n\t/**\n\t * The clock the poll passes to {@link DeadlineStore.due}. Omit it to use\n\t * `() => new Date()`. An injected clock that throws or returns an invalid\n\t * `Date` fails the cycle before the store is read, reports through\n\t * `onPollError`, and participates in the normal failure backoff.\n\t */\n\tclock?: () => Date;\n}\n\n/**\n * The hardened delivery loop for {@link DeadlineStore}: poll due\n * deadlines, hand each one to the handler, acknowledge or report the\n * failure. The delivery semantics are deliberately simpler than the\n * outbox dispatcher's, because deadlines carry no ordering: a HANDLER\n * failure never stops the batch; the failing deadline is reported via\n * `markFailed` and its neighbors keep flowing in the same cycle.\n *\n * What it shares with the dispatcher is the loop hardening, which is\n * exactly the part hand-rolled loops get wrong:\n *\n * - **Never rejects.** Clock and poll errors, handler throws, ack failures,\n * and observer bugs are absorbed and reported; `run(signal)` resolves on\n * abort and never becomes an unhandled rejection.\n * - **Backs off under failure.** A cycle containing any failure grows\n * the jittered exponential backoff toward `maxDelayMs` (one step per\n * cycle); an empty backlog or a clean cycle resets the streak.\n * - **Reentrancy-safe.** A `drainOnce` call while a pass is in flight\n * joins that pass instead of starting a competing poll (overlapping\n * cron ticks would double-deliver); a joining call still honors its\n * own signal.\n * - **At-least-once.** A crash or ack failure after handling\n * redelivers; handlers stay idempotent (the guide shows the\n * idempotency-store wiring). Delivered deadlines are acknowledged in\n * ONE `markDelivered` call per cycle, and an ack failure ends the\n * cycle: it signals the store's write path, not a poison record, so\n * it is reported per affected deadline, never to `markFailed`\n * (counting it toward the poison ceiling would dead-letter healthy\n * work), and the backoff paces the redelivery instead of the pass\n * re-running every handler against a dead write path.\n * - **Bounded waiting requires bounded adapters.** Delivery and store operations\n * receive cooperative cancellation and an absolute deadline. The processor\n * returns after its configured bound even when a promise ignores the signal,\n * but only the adapter can terminate native I/O and prevent late work from\n * overlapping a retry. A late idempotent acknowledgement remains valid.\n *\n * Run one logical processor per store unless the adapter's `due`\n * claims records; the same rule as the dispatcher.\n */\nexport class DeadlineProcessor<TPayload = unknown> extends PollLoop {\n\tprivate readonly store: DeadlineStore<TPayload>;\n\tprivate readonly handler: (\n\t\tdeadline: DueDeadline<TPayload>,\n\t\tcontext: ExecutionContext,\n\t) => Promise<void> | void;\n\tprivate readonly clock: () => Date;\n\tprivate readonly observers: DeadlineProcessorObservers<TPayload>;\n\tprivate readonly deliveryTimeoutMs: number;\n\tprivate readonly storageTimeoutMs: number;\n\tprivate readonly classifyFailure?: DeliveryFailureClassifier;\n\n\tconstructor(options: DeadlineProcessorOptions<TPayload>) {\n\t\tsuper(\"DeadlineProcessor\", options);\n\t\tthis.observers = captureObserverFunctions(\n\t\t\t\"DeadlineProcessor\",\n\t\t\toptions.observers,\n\t\t\t[\"onDeliveryError\", \"onPollError\", \"onDeadLetter\"],\n\t\t);\n\t\tthis.store = options.store;\n\t\tthis.handler = options.handler;\n\t\tthis.classifyFailure = options.classifyFailure;\n\t\tthis.clock = options.clock ?? (() => new Date());\n\t\tthis.deliveryTimeoutMs =\n\t\t\toptions.deliveryTimeoutMs ?? DEFAULT_EXECUTION_TIMEOUT_MS;\n\t\tthis.storageTimeoutMs =\n\t\t\toptions.storageTimeoutMs ?? DEFAULT_EXECUTION_TIMEOUT_MS;\n\t\tassertNonNegativeFinite(\n\t\t\t\"DeadlineProcessor\",\n\t\t\t\"deliveryTimeoutMs\",\n\t\t\tthis.deliveryTimeoutMs,\n\t\t);\n\t\tassertNonNegativeFinite(\n\t\t\t\"DeadlineProcessor\",\n\t\t\t\"storageTimeoutMs\",\n\t\t\tthis.storageTimeoutMs,\n\t\t);\n\t}\n\n\t/**\n\t * One full delivery pass (the `run`/`drainOnce` shell lives on\n\t * {@link PollLoop}): delivers due deadlines batch by batch until\n\t * nothing is due or a cycle contained a failure.\n\t */\n\tprotected async pass(signal?: AbortSignal): Promise<\"drained\" | \"stopped\"> {\n\t\twhile (!signal?.aborted) {\n\t\t\tlet batch: ReadonlyArray<DueDeadline<TPayload>>;\n\t\t\ttry {\n\t\t\t\tbatch = await runBoundedExecution(\n\t\t\t\t\t\"DeadlineProcessor.due\",\n\t\t\t\t\t{ signal, timeoutMs: this.storageTimeoutMs },\n\t\t\t\t\t(context) => this.store.due(this.now(), this.batchSize, context),\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\tif (signal?.aborted) return \"stopped\";\n\t\t\t\tthis.consecutiveFailures += 1;\n\t\t\t\treportToObserver(() => this.observers.onPollError(error));\n\t\t\t\treturn \"stopped\";\n\t\t\t}\n\t\t\tif (batch.length === 0) {\n\t\t\t\tthis.consecutiveFailures = 0;\n\t\t\t\treturn \"drained\";\n\t\t\t}\n\n\t\t\t// Handler failures do NOT stop the batch: deadlines carry no\n\t\t\t// cross-address ordering, so a poison deadline blocks only\n\t\t\t// itself and is reported to the store's bounded retries.\n\t\t\tlet handlerFailed = false;\n\t\t\tconst delivered: DueDeadline<TPayload>[] = [];\n\t\t\tfor (const deadline of batch) {\n\t\t\t\tif (signal?.aborted) break;\n\t\t\t\tlet boundedContext: ExecutionContext | undefined;\n\t\t\t\ttry {\n\t\t\t\t\tawait runBoundedExecution(\n\t\t\t\t\t\t\"DeadlineProcessor.handler\",\n\t\t\t\t\t\t{ signal, timeoutMs: this.deliveryTimeoutMs },\n\t\t\t\t\t\t(context) => {\n\t\t\t\t\t\t\tboundedContext = context;\n\t\t\t\t\t\t\treturn this.handler(deadline, context);\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\tdelivered.push(deadline);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (signal?.aborted) break;\n\t\t\t\t\thandlerFailed = true;\n\t\t\t\t\tconst assessment = assessDeliveryFailure(error, this.classifyFailure);\n\t\t\t\t\treportToObserver(() =>\n\t\t\t\t\t\tthis.observers.onDeliveryError(error, deadline, assessment),\n\t\t\t\t\t);\n\t\t\t\t\t// The processor's own delivery budget expiring is\n\t\t\t\t\t// deterministic evidence against THIS deliveryId, not a\n\t\t\t\t\t// transient infrastructure hiccup: without consuming an\n\t\t\t\t\t// attempt, a handler that permanently ignores\n\t\t\t\t\t// context.signal never reaches the dead letter and every\n\t\t\t\t\t// poll re-serves it and spawns another zombie execution.\n\t\t\t\t\tconst ownBudgetExpired =\n\t\t\t\t\t\t!signal?.aborted && boundedContext?.signal.aborted === true;\n\t\t\t\t\tif (assessment.kind !== \"transient\" || ownBudgetExpired) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst deadLetter = await runBoundedExecution(\n\t\t\t\t\t\t\t\t\"DeadlineProcessor.markFailed\",\n\t\t\t\t\t\t\t\t{ signal, timeoutMs: this.storageTimeoutMs },\n\t\t\t\t\t\t\t\t(context) =>\n\t\t\t\t\t\t\t\t\tthis.store.markFailed(deadline.deliveryId, error, context),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (deadLetter !== undefined) {\n\t\t\t\t\t\t\t\treportToObserver(() => this.observers.onDeadLetter(deadLetter));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch (markError) {\n\t\t\t\t\t\t\tif (!signal?.aborted) {\n\t\t\t\t\t\t\t\treportToObserver(() =>\n\t\t\t\t\t\t\t\t\tthis.observers.onDeliveryError(markError, deadline),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// One ack round-trip per cycle. An ack failure DOES stop the\n\t\t\t// cycle: it signals the store's write path, not a poison\n\t\t\t// record; continuing would re-run every handler against a dead\n\t\t\t// write path on each backoff step. Every handled deadline will\n\t\t\t// redeliver (the documented duplicates), so each is reported.\n\t\t\tlet acked = true;\n\t\t\tif (delivered.length > 0) {\n\t\t\t\ttry {\n\t\t\t\t\t// A completed handler keeps one bounded acknowledgement attempt\n\t\t\t\t\t// when shutdown won immediately after completion. An acknowledgement\n\t\t\t\t\t// that was already running remains owner-cancellable.\n\t\t\t\t\tconst acknowledgementSignal = signal?.aborted ? undefined : signal;\n\t\t\t\t\tawait runBoundedExecution(\n\t\t\t\t\t\t\"DeadlineProcessor.markDelivered\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsignal: acknowledgementSignal,\n\t\t\t\t\t\t\ttimeoutMs: this.storageTimeoutMs,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t(context) =>\n\t\t\t\t\t\t\tthis.store.markDelivered(\n\t\t\t\t\t\t\t\tdelivered.map((deadline) => deadline.deliveryId),\n\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tacked = false;\n\t\t\t\t\tif (!signal?.aborted) {\n\t\t\t\t\t\tfor (const deadline of delivered) {\n\t\t\t\t\t\t\treportToObserver(() =>\n\t\t\t\t\t\t\t\tthis.observers.onDeliveryError(error, deadline),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (handlerFailed || !acked) {\n\t\t\t\t// One streak bump per failed cycle; run()'s backoff sleep\n\t\t\t\t// paces the retry (a bare drainOnce loop gets its pacing\n\t\t\t\t// from the tick cadence instead).\n\t\t\t\tthis.consecutiveFailures += 1;\n\t\t\t\treturn \"stopped\";\n\t\t\t}\n\t\t\tthis.consecutiveFailures = 0;\n\t\t\t// An abort mid-batch left deadlines unhandled; not a failure,\n\t\t\t// but not a drained backlog either.\n\t\t\tif (signal?.aborted) return \"stopped\";\n\t\t}\n\t\treturn \"stopped\";\n\t}\n\n\t/**\n\t * Reads and validates the poll clock before the store is consulted.\n\t * The caller's poll-error path reports any throw and applies backoff.\n\t */\n\tprivate now(): Date {\n\t\tconst value = this.clock();\n\t\tif (!(value instanceof Date) || Number.isNaN(value.getTime())) {\n\t\t\tthrow new TypeError(\"DeadlineProcessor: clock must return a valid Date\");\n\t\t}\n\t\treturn value;\n\t}\n}\n","import { InMemoryCapacityExceededError } from \"../core/errors\";\nimport {\n\tassertPositiveInteger,\n\tassertPositiveSafeInteger,\n} from \"../utils/validate\";\nimport type {\n\tDeadLetterDeadline,\n\tDeadlineStore,\n\tDueDeadline,\n} from \"./deadline-store\";\n\n/** Construction options for {@link InMemoryDeadlineStore}. */\nexport interface InMemoryDeadlineStoreOptions {\n\t/** Maximum records retained across pending and dead-letter states. */\n\treadonly maxRecords?: number;\n\n\t/**\n\t * How many failed delivery attempts move a deadline to the\n\t * dead-letter set. Default `5`.\n\t */\n\tmaxDeliveryAttempts?: number;\n}\n\ninterface StoredDeadline<TPayload> {\n\tdeliveryId: string;\n\tscope: string;\n\tkey: string;\n\tdueAt: Date;\n\tpayload: TPayload;\n\tattempts: number;\n\t/** Monotonic tie-breaker: scheduling order for equal due times. */\n\tsequence: number;\n\tlastError?: string;\n}\n\n/**\n * In-memory reference implementation of {@link DeadlineStore}: defines\n * the port's semantics and serves finite-lifetime tests and demos. Without\n * `maxRecords`, pending and dead-letter records are unbounded. A configured\n * limit rejects a new address before mutation; delivery state is never\n * silently evicted.\n *\n * **Not transaction-aware**, the same documented limitation as the\n * other in-memory references: a rolled-back `schedule` or `cancel`\n * stays applied here. The transactional half of the contract is the\n * SQL adapter's job; prove it with `createDeadlineStoreContractTests`\n * and its rollback capability.\n *\n * Payloads are deep-copied on schedule and on delivery\n * (`structuredClone`), so neither side can mutate the other's copy.\n */\nexport class InMemoryDeadlineStore<TPayload = unknown>\n\timplements DeadlineStore<TPayload>\n{\n\tprivate readonly pending = new Map<string, StoredDeadline<TPayload>>();\n\t/** Keyed by deliveryId: several incarnations of one address can be dead. */\n\tprivate readonly dead = new Map<string, StoredDeadline<TPayload>>();\n\tprivate readonly maxDeliveryAttempts: number;\n\tprivate readonly maxRecords: number | undefined;\n\tprivate nextSequence = 0;\n\n\tconstructor(options: InMemoryDeadlineStoreOptions = {}) {\n\t\tconst max = options.maxDeliveryAttempts ?? 5;\n\t\tassertPositiveInteger(\"InMemoryDeadlineStore\", \"maxDeliveryAttempts\", max);\n\t\tthis.maxDeliveryAttempts = max;\n\t\tif (options.maxRecords !== undefined) {\n\t\t\tassertPositiveSafeInteger(\n\t\t\t\t\"InMemoryDeadlineStore\",\n\t\t\t\t\"maxRecords\",\n\t\t\t\toptions.maxRecords,\n\t\t\t);\n\t\t}\n\t\tthis.maxRecords = options.maxRecords;\n\t}\n\n\tasync schedule(deadline: {\n\t\tscope: string;\n\t\tkey: string;\n\t\tdueAt: Date;\n\t\tpayload: TPayload;\n\t}): Promise<void> {\n\t\tconst deadlineAddress = address(deadline.scope, deadline.key);\n\t\tif (\n\t\t\t!this.pending.has(deadlineAddress) &&\n\t\t\tthis.maxRecords !== undefined &&\n\t\t\tthis.pending.size + this.dead.size >= this.maxRecords\n\t\t) {\n\t\t\tthrow new InMemoryCapacityExceededError({\n\t\t\t\tstore: \"InMemoryDeadlineStore\",\n\t\t\t\tresource: \"records\",\n\t\t\t\tlimit: this.maxRecords,\n\t\t\t\tcurrent: this.pending.size + this.dead.size,\n\t\t\t\tattempted: 1,\n\t\t\t});\n\t\t}\n\t\tconst sequence = this.nextSequence++;\n\t\t// Replacing an occupied address gets a FRESH incarnation: a late\n\t\t// ack or failure report against the old deliveryId must not touch\n\t\t// the successor.\n\t\tthis.pending.set(deadlineAddress, {\n\t\t\tdeliveryId: `deadline-${sequence}`,\n\t\t\tscope: deadline.scope,\n\t\t\tkey: deadline.key,\n\t\t\tdueAt: new Date(deadline.dueAt),\n\t\t\tpayload: structuredClone(deadline.payload),\n\t\t\tattempts: 0,\n\t\t\tsequence,\n\t\t});\n\t}\n\n\tasync cancel(scope: string, key: string): Promise<void> {\n\t\tthis.pending.delete(address(scope, key));\n\t}\n\n\tasync due(\n\t\tnow: Date,\n\t\tlimit: number,\n\t): Promise<ReadonlyArray<DueDeadline<TPayload>>> {\n\t\tif (!Number.isInteger(limit) || limit < 0) {\n\t\t\tthrow new Error(\n\t\t\t\t`InMemoryDeadlineStore: limit must be an integer >= 0, got ${limit}`,\n\t\t\t);\n\t\t}\n\t\t// \"Up to limit\": zero is a legal page size and yields an empty page\n\t\t// (a loop computing capacity - inFlight may legitimately pass it).\n\t\tif (limit === 0) return [];\n\t\treturn [...this.pending.values()]\n\t\t\t.filter((deadline) => deadline.dueAt.getTime() <= now.getTime())\n\t\t\t.sort(\n\t\t\t\t(a, b) =>\n\t\t\t\t\ta.dueAt.getTime() - b.dueAt.getTime() || a.sequence - b.sequence,\n\t\t\t)\n\t\t\t.slice(0, limit)\n\t\t\t.map((deadline) => toRecord(deadline));\n\t}\n\n\tasync markDelivered(deliveryIds: ReadonlyArray<string>): Promise<void> {\n\t\tfor (const deliveryId of deliveryIds) {\n\t\t\tthis.dead.delete(deliveryId);\n\t\t\tfor (const [key, deadline] of this.pending) {\n\t\t\t\tif (deadline.deliveryId === deliveryId) {\n\t\t\t\t\tthis.pending.delete(key);\n\t\t\t\t\tbreak; // deliveryIds are unique; nothing more to find\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tasync markFailed(\n\t\tdeliveryId: string,\n\t\terror?: unknown,\n\t): Promise<DeadLetterDeadline<TPayload> | undefined> {\n\t\tfor (const [key, deadline] of this.pending) {\n\t\t\tif (deadline.deliveryId !== deliveryId) continue;\n\t\t\tdeadline.attempts += 1;\n\t\t\t// An errorless report must not erase an earlier recorded reason.\n\t\t\tif (error !== undefined) deadline.lastError = String(error);\n\t\t\tif (deadline.attempts >= this.maxDeliveryAttempts) {\n\t\t\t\tthis.pending.delete(key);\n\t\t\t\tthis.dead.set(deadline.deliveryId, deadline);\n\t\t\t\treturn toDeadLetter(deadline);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t\t// Unknown, delivered, replaced, or already dead-lettered: a late\n\t\t// report must not resurrect or advance anything.\n\t\treturn undefined;\n\t}\n\n\tasync deadLetters(): Promise<ReadonlyArray<DeadLetterDeadline<TPayload>>> {\n\t\treturn [...this.dead.values()]\n\t\t\t.sort((a, b) => a.sequence - b.sequence)\n\t\t\t.map(toDeadLetter);\n\t}\n}\n\nfunction toDeadLetter<TPayload>(\n\tdeadline: StoredDeadline<TPayload>,\n): DeadLetterDeadline<TPayload> {\n\treturn {\n\t\t...toRecord(deadline),\n\t\t...(deadline.lastError === undefined\n\t\t\t? {}\n\t\t\t: { lastError: deadline.lastError }),\n\t};\n}\n\nfunction toRecord<TPayload>(\n\tdeadline: StoredDeadline<TPayload>,\n): DueDeadline<TPayload> {\n\treturn {\n\t\tdeliveryId: deadline.deliveryId,\n\t\tscope: deadline.scope,\n\t\tkey: deadline.key,\n\t\tdueAt: new Date(deadline.dueAt),\n\t\tpayload: structuredClone(deadline.payload),\n\t\tattempts: deadline.attempts,\n\t};\n}\n\n/** NUL-separated so no scope/key concatenation can collide. */\nfunction address(scope: string, key: string): string {\n\treturn `${scope}\\u0000${key}`;\n}\n","import { DomainError, KitWiringError } from \"../core/errors\";\n\n/** No transition is defined for the input in the current state. */\nexport class InvalidDomainTransitionError extends DomainError<\"INVALID_DOMAIN_TRANSITION\"> {\n\tconstructor(\n\t\tpublic readonly state: string,\n\t\tpublic readonly inputType: string,\n\t) {\n\t\tsuper({\n\t\t\tcode: \"INVALID_DOMAIN_TRANSITION\",\n\t\t\tmessage: `No domain transition from \"${state}\" on \"${inputType}\".`,\n\t\t});\n\t}\n}\n\n/** A defined transition was rejected by its domain guard. */\nexport class DomainTransitionGuardRejectedError extends DomainError<\"DOMAIN_TRANSITION_GUARD_REJECTED\"> {\n\tconstructor(\n\t\tpublic readonly state: string,\n\t\tpublic readonly inputType: string,\n\t) {\n\t\tsuper({\n\t\t\tcode: \"DOMAIN_TRANSITION_GUARD_REJECTED\",\n\t\t\tmessage: `Domain transition guard rejected \"${inputType}\" from \"${state}\".`,\n\t\t});\n\t}\n}\n\n/** The machine definition violates its runtime contract. */\nexport class InvalidDomainMachineDefinitionError extends KitWiringError<\"INVALID_DOMAIN_MACHINE_DEFINITION\"> {\n\tconstructor(message: string, cause?: unknown) {\n\t\tsuper(\"INVALID_DOMAIN_MACHINE_DEFINITION\", message, cause);\n\t}\n}\n\n/** Context contains unsupported or unsafe runtime data. */\nexport class InvalidDomainMachineContextError extends KitWiringError<\"INVALID_DOMAIN_MACHINE_CONTEXT\"> {\n\tconstructor(message: string, cause?: unknown) {\n\t\tsuper(\"INVALID_DOMAIN_MACHINE_CONTEXT\", message, cause);\n\t}\n}\n\n/** A supplied or produced snapshot is malformed or violates invariants. */\nexport class InvalidDomainMachineSnapshotError extends KitWiringError<\"INVALID_DOMAIN_MACHINE_SNAPSHOT\"> {\n\tconstructor(message: string, cause?: unknown) {\n\t\tsuper(\"INVALID_DOMAIN_MACHINE_SNAPSHOT\", message, cause);\n\t}\n}\n\n/** An input is malformed or contains unsupported runtime data. */\nexport class InvalidDomainMachineInputError extends KitWiringError<\"INVALID_DOMAIN_MACHINE_INPUT\"> {\n\tconstructor(message: string, cause?: unknown) {\n\t\tsuper(\"INVALID_DOMAIN_MACHINE_INPUT\", message, cause);\n\t}\n}\n\n/** A guard returned a value other than `boolean` or `DomainError`. */\nexport class InvalidDomainTransitionGuardResultError extends KitWiringError<\"INVALID_DOMAIN_TRANSITION_GUARD_RESULT\"> {\n\tconstructor(message: string, cause?: unknown) {\n\t\tsuper(\"INVALID_DOMAIN_TRANSITION_GUARD_RESULT\", message, cause);\n\t}\n}\n\n/** A reducer returned a malformed result or unsupported output data. */\nexport class InvalidDomainTransitionResultError extends KitWiringError<\"INVALID_DOMAIN_TRANSITION_RESULT\"> {\n\tconstructor(message: string, cause?: unknown) {\n\t\tsuper(\"INVALID_DOMAIN_TRANSITION_RESULT\", message, cause);\n\t}\n}\n\n/** A callback attempted to evaluate the same stateful machine recursively. */\nexport class ReentrantDomainStateMachineEvaluationError extends KitWiringError<\"REENTRANT_DOMAIN_STATE_MACHINE_EVALUATION\"> {\n\tconstructor() {\n\t\tsuper(\n\t\t\t\"REENTRANT_DOMAIN_STATE_MACHINE_EVALUATION\",\n\t\t\t\"Domain state machine callbacks cannot evaluate the same machine.\",\n\t\t);\n\t}\n}\n","import {\n\tfindPropertyDescriptor,\n\tisBuiltInObject,\n\tisIntrinsicConstructorPrototype,\n} from \"../utils/array/is-built-in\";\nimport { deepFreeze } from \"../value-object/value-object\";\nimport type { DomainMachineInput, DomainMachineReadonly } from \"./contracts\";\nimport {\n\tInvalidDomainMachineContextError,\n\tInvalidDomainMachineInputError,\n\tInvalidDomainTransitionResultError,\n} from \"./errors\";\n\ntype DomainMachineDataErrorFactory = (\n\tmessage: string,\n\tcause?: unknown,\n) =>\n\t| InvalidDomainMachineContextError\n\t| InvalidDomainMachineInputError\n\t| InvalidDomainTransitionResultError;\n\nconst DOMAIN_MACHINE_DATA_MAX_DEPTH = 256;\nconst DOMAIN_MACHINE_DATA_MAX_NODES = 10_000;\nconst DOMAIN_MACHINE_DATA_MAX_PROPERTIES = 100_000;\n\ntype DomainMachineDataTraversal = {\n\tnodes: number;\n\tproperties: number;\n};\n\nexport function copyDomainMachineOutputs<TOutput>(\n\toutputs: readonly (TOutput | DomainMachineReadonly<TOutput>)[] | undefined,\n): readonly DomainMachineReadonly<TOutput>[] {\n\ttry {\n\t\tconst copiedOutputs = cloneDomainMachineDataValue(\n\t\t\toutputs ?? [],\n\t\t\tcreateDomainTransitionOutputError,\n\t\t);\n\t\treturn deepFreeze(\n\t\t\tcopiedOutputs,\n\t\t) as readonly DomainMachineReadonly<TOutput>[];\n\t} catch (cause) {\n\t\tif (cause instanceof InvalidDomainTransitionResultError) {\n\t\t\tthrow cause;\n\t\t}\n\t\tthrow new InvalidDomainTransitionResultError(\n\t\t\t\"Domain transition result outputs must contain cloneable, deeply immutable data.\",\n\t\t\tcause,\n\t\t);\n\t}\n}\n\nexport function copyDomainMachineInput<TInput extends DomainMachineInput>(\n\tinput: TInput,\n): DomainMachineReadonly<TInput> {\n\ttry {\n\t\treturn deepFreeze(\n\t\t\tcloneDomainMachineDataValue(input, createDomainMachineInputError),\n\t\t) as DomainMachineReadonly<TInput>;\n\t} catch (cause) {\n\t\tif (cause instanceof InvalidDomainMachineInputError) {\n\t\t\tthrow cause;\n\t\t}\n\t\tthrow new InvalidDomainMachineInputError(\n\t\t\t\"Domain machine input must contain cloneable, deeply immutable data.\",\n\t\t\tcause,\n\t\t);\n\t}\n}\n\nexport function copyDomainMachineContext<TContext>(\n\tcontext: TContext | DomainMachineReadonly<TContext>,\n): DomainMachineReadonly<TContext> {\n\ttry {\n\t\treturn deepFreeze(\n\t\t\tcloneDomainMachineDataValue(context, createDomainMachineContextError),\n\t\t) as DomainMachineReadonly<TContext>;\n\t} catch (cause) {\n\t\tif (cause instanceof InvalidDomainMachineContextError) {\n\t\t\tthrow cause;\n\t\t}\n\t\tthrow new InvalidDomainMachineContextError(\n\t\t\t\"Domain machine context must contain cloneable, deeply immutable data.\",\n\t\t\tcause,\n\t\t);\n\t}\n}\n\nfunction createDomainMachineContextError(\n\tmessage: string,\n\tcause?: unknown,\n): InvalidDomainMachineContextError {\n\treturn new InvalidDomainMachineContextError(message, cause);\n}\n\nfunction createDomainMachineInputError(\n\tmessage: string,\n\tcause?: unknown,\n): InvalidDomainMachineInputError {\n\treturn new InvalidDomainMachineInputError(message, cause);\n}\n\nfunction createDomainTransitionOutputError(\n\tmessage: string,\n\tcause?: unknown,\n): InvalidDomainTransitionResultError {\n\treturn new InvalidDomainTransitionResultError(message, cause);\n}\n\nfunction cloneDomainMachineDataValue<TValue>(\n\tvalue: TValue,\n\terrorFactory: DomainMachineDataErrorFactory,\n\tseen = new WeakMap<object, unknown>(),\n\ttraversal: DomainMachineDataTraversal = { nodes: 0, properties: 0 },\n\tdepth = 0,\n): TValue {\n\tif (typeof value === \"function\") {\n\t\tthrow errorFactory(\"Domain machine data cannot contain function values.\");\n\t}\n\tif (value === null || typeof value !== \"object\") return value;\n\n\tconst source = value as object;\n\tif (depth > DOMAIN_MACHINE_DATA_MAX_DEPTH) {\n\t\tthrow errorFactory(\n\t\t\t`Domain machine data exceeds the maximum depth of ${DOMAIN_MACHINE_DATA_MAX_DEPTH}.`,\n\t\t);\n\t}\n\tconst existing = seen.get(source);\n\tif (existing !== undefined) return existing as TValue;\n\ttraversal.nodes += 1;\n\tif (traversal.nodes > DOMAIN_MACHINE_DATA_MAX_NODES) {\n\t\tthrow errorFactory(\n\t\t\t`Domain machine data contains more than ${DOMAIN_MACHINE_DATA_MAX_NODES.toLocaleString(\"en-US\")} object nodes.`,\n\t\t);\n\t}\n\tconst toStringTagDescriptor = findPropertyDescriptor(\n\t\tsource,\n\t\tSymbol.toStringTag,\n\t);\n\tif (\n\t\ttoStringTagDescriptor !== undefined &&\n\t\t!(\"value\" in toStringTagDescriptor)\n\t) {\n\t\tthrow errorFactory(\n\t\t\t\"Domain machine data cannot contain accessor properties.\",\n\t\t);\n\t}\n\n\tif (Array.isArray(value)) {\n\t\tif (!isIntrinsicArrayPrototype(Object.getPrototypeOf(value))) {\n\t\t\tthrow errorFactory(\n\t\t\t\t\"Domain machine data cannot contain custom Array instances.\",\n\t\t\t);\n\t\t}\n\t\tconst cloned: unknown[] = new Array(value.length);\n\t\tseen.set(source, cloned);\n\n\t\tfor (const key of readDomainMachineDataKeys(\n\t\t\tsource,\n\t\t\terrorFactory,\n\t\t\ttraversal,\n\t\t)) {\n\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(source, key);\n\t\t\tif (!descriptor) continue;\n\n\t\t\tif (!(\"value\" in descriptor)) {\n\t\t\t\tthrow errorFactory(\n\t\t\t\t\t\"Domain machine data cannot contain accessor properties.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (key === \"length\") continue;\n\n\t\t\tdescriptor.value = cloneDomainMachineDataValue(\n\t\t\t\tdescriptor.value,\n\t\t\t\terrorFactory,\n\t\t\t\tseen,\n\t\t\t\ttraversal,\n\t\t\t\tdepth + 1,\n\t\t\t);\n\t\t\tObject.defineProperty(cloned, key, descriptor);\n\t\t}\n\t\treturn cloned as TValue;\n\t}\n\n\tconst prototype = Object.getPrototypeOf(source);\n\tif (prototype !== null && !isIntrinsicObjectPrototype(prototype)) {\n\t\tthrow errorFactory(\n\t\t\t\"Domain machine data cannot contain custom class instances.\",\n\t\t);\n\t}\n\n\tconst tag = Object.prototype.toString.call(source);\n\tif (isBuiltInObject(source, tag) || ArrayBuffer.isView(source)) {\n\t\tthrow errorFactory(\n\t\t\t`Domain machine data cannot contain ${tag.slice(8, -1)} object values.`,\n\t\t);\n\t}\n\n\tconst cloned = Object.create(prototype === null ? null : Object.prototype);\n\tseen.set(source, cloned);\n\n\tfor (const key of readDomainMachineDataKeys(\n\t\tsource,\n\t\terrorFactory,\n\t\ttraversal,\n\t)) {\n\t\tconst descriptor = Object.getOwnPropertyDescriptor(source, key);\n\t\tif (!descriptor) continue;\n\n\t\tif (!(\"value\" in descriptor)) {\n\t\t\tthrow errorFactory(\n\t\t\t\t\"Domain machine data cannot contain accessor properties.\",\n\t\t\t);\n\t\t}\n\n\t\tdescriptor.value = cloneDomainMachineDataValue(\n\t\t\tdescriptor.value,\n\t\t\terrorFactory,\n\t\t\tseen,\n\t\t\ttraversal,\n\t\t\tdepth + 1,\n\t\t);\n\t\tObject.defineProperty(cloned, key, descriptor);\n\t}\n\n\treturn cloned as TValue;\n}\n\nfunction readDomainMachineDataKeys(\n\tvalue: object,\n\terrorFactory: DomainMachineDataErrorFactory,\n\ttraversal: DomainMachineDataTraversal,\n): readonly PropertyKey[] {\n\tconst keys = Reflect.ownKeys(value);\n\ttraversal.properties += keys.length;\n\tif (traversal.properties > DOMAIN_MACHINE_DATA_MAX_PROPERTIES) {\n\t\tthrow errorFactory(\n\t\t\t`Domain machine data contains more than ${DOMAIN_MACHINE_DATA_MAX_PROPERTIES.toLocaleString(\"en-US\")} own properties.`,\n\t\t);\n\t}\n\treturn keys;\n}\n\nexport function isRecord(\n\tvalue: unknown,\n): value is Record<PropertyKey, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport function isPlainRecord(\n\tvalue: unknown,\n): value is Record<PropertyKey, unknown> {\n\tif (!isRecord(value)) return false;\n\n\tconst prototype = Object.getPrototypeOf(value);\n\treturn prototype === null || isIntrinsicObjectPrototype(prototype);\n}\n\nfunction isIntrinsicArrayPrototype(prototype: object | null): boolean {\n\tif (prototype === null || !Array.isArray(prototype)) return false;\n\tif (!isIntrinsicConstructorPrototype(prototype, \"Array\")) return false;\n\n\tconst parentPrototype = Object.getPrototypeOf(prototype);\n\treturn (\n\t\tparentPrototype !== null && isIntrinsicObjectPrototype(parentPrototype)\n\t);\n}\n\nfunction isIntrinsicObjectPrototype(prototype: object): boolean {\n\treturn (\n\t\tObject.getPrototypeOf(prototype) === null &&\n\t\tisIntrinsicConstructorPrototype(prototype, \"Object\")\n\t);\n}\n\nexport function hasOwn<T extends object>(\n\tvalue: T,\n\tkey: PropertyKey,\n): key is keyof T {\n\treturn Object.hasOwn(value, key);\n}\n","import type {\n\tDomainMachineDefinition,\n\tDomainMachineInput,\n\tDomainMachineSnapshot,\n\tDomainStateNode,\n\tDomainTransition,\n} from \"./contracts\";\nimport { InvalidDomainMachineDefinitionError } from \"./errors\";\nimport { hasOwn, isPlainRecord } from \"./machine-data\";\n\nconst DOMAIN_MACHINE_DEFINITION_KEYS: ReadonlySet<PropertyKey> = new Set([\n\t\"initial\",\n\t\"initialContext\",\n\t\"validateSnapshot\",\n\t\"states\",\n]);\nconst DOMAIN_MACHINE_STATE_NODE_KEYS: ReadonlySet<PropertyKey> = new Set([\n\t\"terminal\",\n\t\"validateContext\",\n\t\"on\",\n]);\nconst DOMAIN_MACHINE_TRANSITION_KEYS: ReadonlySet<PropertyKey> = new Set([\n\t\"target\",\n\t\"guard\",\n\t\"reduce\",\n]);\n\nexport function copyDomainMachineDefinition<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n): DomainMachineDefinition<TState, TContext, TInput, TOutput> {\n\tconst states = readDomainMachineDefinitionProperty(\n\t\tdefinition,\n\t\t\"states\",\n\t) as DomainMachineDefinition<TState, TContext, TInput, TOutput>[\"states\"];\n\tconst copiedStates = Object.create(null) as {\n\t\t[TName in TState]: DomainStateNode<TState, TContext, TInput, TOutput>;\n\t};\n\n\tfor (const state of Object.keys(states) as TState[]) {\n\t\tconst node = readDomainMachineDefinitionProperty(\n\t\t\tstates,\n\t\t\tstate,\n\t\t) as DomainStateNode<TState, TContext, TInput, TOutput>;\n\t\tconst transitions = readOptionalDomainMachineDefinitionProperty(\n\t\t\tnode,\n\t\t\t\"on\",\n\t\t) as DomainStateNode<TState, TContext, TInput, TOutput>[\"on\"] | undefined;\n\t\tconst copiedTransitions = Object.create(null) as {\n\t\t\t[TType in TInput[\"type\"]]?: DomainTransition<\n\t\t\t\tTState,\n\t\t\t\tTContext,\n\t\t\t\tExtract<TInput, { readonly type: TType }>,\n\t\t\t\tTOutput\n\t\t\t>;\n\t\t};\n\n\t\tfor (const inputType of Object.keys(\n\t\t\ttransitions ?? {},\n\t\t) as TInput[\"type\"][]) {\n\t\t\tconst transition = readDomainMachineDefinitionProperty(\n\t\t\t\ttransitions as object,\n\t\t\t\tinputType,\n\t\t\t) as\n\t\t\t\t| DomainTransition<\n\t\t\t\t\t\tTState,\n\t\t\t\t\t\tTContext,\n\t\t\t\t\t\tExtract<TInput, { readonly type: typeof inputType }>,\n\t\t\t\t\t\tTOutput\n\t\t\t\t >\n\t\t\t\t| undefined;\n\t\t\tif (transition) {\n\t\t\t\tconst copiedTransition = Object.freeze({\n\t\t\t\t\ttarget: readDomainMachineDefinitionProperty(transition, \"target\"),\n\t\t\t\t\tguard: readOptionalDomainMachineDefinitionProperty(\n\t\t\t\t\t\ttransition,\n\t\t\t\t\t\t\"guard\",\n\t\t\t\t\t),\n\t\t\t\t\treduce: readOptionalDomainMachineDefinitionProperty(\n\t\t\t\t\t\ttransition,\n\t\t\t\t\t\t\"reduce\",\n\t\t\t\t\t),\n\t\t\t\t}) as DomainTransition<\n\t\t\t\t\tTState,\n\t\t\t\t\tTContext,\n\t\t\t\t\tExtract<TInput, { readonly type: typeof inputType }>,\n\t\t\t\t\tTOutput\n\t\t\t\t>;\n\t\t\t\tObject.defineProperty(copiedTransitions, inputType, {\n\t\t\t\t\tvalue: copiedTransition,\n\t\t\t\t\tenumerable: true,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tObject.defineProperty(copiedStates, state, {\n\t\t\tvalue: Object.freeze({\n\t\t\t\tterminal: readOptionalDomainMachineDefinitionProperty(node, \"terminal\"),\n\t\t\t\tvalidateContext: readOptionalDomainMachineDefinitionProperty(\n\t\t\t\t\tnode,\n\t\t\t\t\t\"validateContext\",\n\t\t\t\t),\n\t\t\t\ton: Object.freeze(copiedTransitions),\n\t\t\t}),\n\t\t\tenumerable: true,\n\t\t});\n\t}\n\n\treturn Object.freeze({\n\t\tinitial: readDomainMachineDefinitionProperty(\n\t\t\tdefinition,\n\t\t\t\"initial\",\n\t\t) as TState,\n\t\tinitialContext: readDomainMachineDefinitionProperty(\n\t\t\tdefinition,\n\t\t\t\"initialContext\",\n\t\t) as () => TContext,\n\t\tvalidateSnapshot: readOptionalDomainMachineDefinitionProperty(\n\t\t\tdefinition,\n\t\t\t\"validateSnapshot\",\n\t\t) as\n\t\t\t| ((snapshot: DomainMachineSnapshot<TState, TContext>) => boolean)\n\t\t\t| undefined,\n\t\tstates: Object.freeze(copiedStates),\n\t});\n}\n\n/**\n * Registry of definitions produced by `prepareDomainMachineDefinition`:\n * validated, defensively copied, deeply frozen. The runtime membership\n * proof lives in this module-private WeakSet (the stable copies are\n * frozen and must stay pure data, so no runtime brand property); the\n * compile-time proof is the required type brand on\n * {@link PreparedDomainMachineDefinition}. Only\n * `prepareDomainMachineDefinition` below adds to the set, so membership\n * always implies validated + copied + frozen.\n */\nconst preparedDefinitions = new WeakSet<object>();\n\ndeclare const preparedDefinitionBrand: unique symbol;\n\n/**\n * A machine definition that `prepareDomainMachineDefinition` has\n * validated, defensively copied, and deeply frozen. Assignable wherever\n * a plain `DomainMachineDefinition` is accepted; the reverse does NOT\n * hold (the brand is required), so an API that demands a prepared\n * definition rejects raw ones at compile time. The pure functions and\n * the `DomainStateMachine` constructor recognize prepared definitions\n * at runtime and skip their per-call validate-and-copy.\n */\nexport type PreparedDomainMachineDefinition<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput = never,\n> = DomainMachineDefinition<TState, TContext, TInput, TOutput> & {\n\treadonly [preparedDefinitionBrand]: true;\n};\n\n/**\n * The entry-point normalization every pure function and the\n * `DomainStateMachine` constructor share: a prepared definition passes\n * through untouched (already validated, copied, frozen); anything else\n * pays the documented per-call validate-and-copy.\n */\nexport function ensureStableDomainMachineDefinition<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n): DomainMachineDefinition<TState, TContext, TInput, TOutput> {\n\tif (preparedDefinitions.has(definition)) return definition;\n\tvalidateDomainMachineDefinition(definition);\n\tconst stable = copyDomainMachineDefinition(definition);\n\t// Re-validate the COPY: a Proxy can legally answer the copy's reads\n\t// differently from validation's (TOCTOU), so the object that will\n\t// actually be dispatched against must itself pass validation. Costs a\n\t// second pass on the raw path only; prepared definitions skip all of\n\t// this.\n\tvalidateDomainMachineDefinition(stable);\n\treturn stable;\n}\n\n/**\n * Validates and stabilizes a machine definition ONCE, for repeated use\n * with the pure functions. Without it, `transitionDomainState` and\n * `canTransitionDomainState` re-validate and defensively re-copy the\n * WHOLE definition on every call (the documented safety of the raw\n * path); on a hot dispatch path that is avoidable O(definition) work.\n * The `DomainStateMachine` class does the equivalent once in its\n * constructor; this export brings the same amortization to pure-API\n * users:\n *\n * ```ts\n * const prepared = prepareDomainMachineDefinition(orderLifecycle);\n * // per dispatch: no re-validation, no definition copy\n * const outcome = transitionDomainState(prepared, snapshot, input);\n * ```\n *\n * The returned definition is a deeply frozen copy, isolated from later\n * mutation of the input object. Preparing an already-prepared\n * definition returns it unchanged.\n */\nexport function prepareDomainMachineDefinition<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n): PreparedDomainMachineDefinition<TState, TContext, TInput, TOutput> {\n\tconst stable = ensureStableDomainMachineDefinition(definition);\n\tpreparedDefinitions.add(stable);\n\treturn stable as PreparedDomainMachineDefinition<\n\t\tTState,\n\t\tTContext,\n\t\tTInput,\n\t\tTOutput\n\t>;\n}\n\nexport function getTransition<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n\tstate: TState,\n\tinput: TInput,\n): DomainTransition<TState, TContext, TInput, TOutput> | undefined {\n\tconst transitions = definition.states[state].on;\n\tif (!transitions || !hasOwn(transitions, input.type)) return undefined;\n\n\treturn transitions[input.type as TInput[\"type\"]] as\n\t\t| DomainTransition<TState, TContext, TInput, TOutput>\n\t\t| undefined;\n}\n\nexport function validateDomainMachineDefinition<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n): void {\n\tconst candidate = definition as unknown;\n\tif (!isPlainRecord(candidate)) {\n\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\"Domain machine definition must be a plain object.\",\n\t\t);\n\t}\n\tassertDomainMachineDefinitionDataProperties(\n\t\tcandidate,\n\t\tDOMAIN_MACHINE_DEFINITION_KEYS,\n\t);\n\n\tconst initial = readDomainMachineDefinitionProperty(candidate, \"initial\");\n\tif (typeof initial !== \"string\") {\n\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\"Domain machine initial state must be a string data property.\",\n\t\t);\n\t}\n\n\tif (\n\t\ttypeof readDomainMachineDefinitionProperty(candidate, \"initialContext\") !==\n\t\t\"function\"\n\t) {\n\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\"Domain machine initialContext must be a function data property.\",\n\t\t);\n\t}\n\n\tconst validateSnapshot = readOptionalDomainMachineDefinitionProperty(\n\t\tcandidate,\n\t\t\"validateSnapshot\",\n\t);\n\tif (\n\t\tvalidateSnapshot !== undefined &&\n\t\ttypeof validateSnapshot !== \"function\"\n\t) {\n\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\"Domain machine validateSnapshot must be a function data property.\",\n\t\t);\n\t}\n\n\tconst statesCandidate = readDomainMachineDefinitionProperty(\n\t\tcandidate,\n\t\t\"states\",\n\t);\n\tif (!isPlainRecord(statesCandidate)) {\n\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\"Domain machine states must be a plain object data property.\",\n\t\t);\n\t}\n\tconst states: Record<PropertyKey, unknown> = statesCandidate;\n\tassertDomainMachineDefinitionEntryMap(states, \"state\");\n\n\tif (!hasOwn(states, initial)) {\n\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t`Initial domain machine state \"${initial}\" is not defined.`,\n\t\t);\n\t}\n\n\tfor (const state of Object.keys(states)) {\n\t\tconst node: unknown = readDomainMachineDefinitionProperty(states, state);\n\t\tif (!isPlainRecord(node)) {\n\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t`Domain machine state \"${state}\" must be a plain object data property.`,\n\t\t\t);\n\t\t}\n\t\tassertDomainMachineDefinitionDataProperties(\n\t\t\tnode,\n\t\t\tDOMAIN_MACHINE_STATE_NODE_KEYS,\n\t\t);\n\n\t\tconst terminal: unknown = readOptionalDomainMachineDefinitionProperty(\n\t\t\tnode,\n\t\t\t\"terminal\",\n\t\t);\n\t\tif (terminal !== undefined && typeof terminal !== \"boolean\") {\n\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t`Domain machine state \"${state}\" terminal flag must be a boolean.`,\n\t\t\t);\n\t\t}\n\n\t\tconst validateContext: unknown =\n\t\t\treadOptionalDomainMachineDefinitionProperty(node, \"validateContext\");\n\t\tif (\n\t\t\tvalidateContext !== undefined &&\n\t\t\ttypeof validateContext !== \"function\"\n\t\t) {\n\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t`Domain machine state \"${state}\" validateContext must be a function.`,\n\t\t\t);\n\t\t}\n\n\t\tconst transitions: unknown = readOptionalDomainMachineDefinitionProperty(\n\t\t\tnode,\n\t\t\t\"on\",\n\t\t);\n\t\tif (transitions !== undefined && !isPlainRecord(transitions)) {\n\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t`Domain machine state \"${state}\" transitions must be a plain object.`,\n\t\t\t);\n\t\t}\n\t\tif (isPlainRecord(transitions)) {\n\t\t\tassertDomainMachineDefinitionEntryMap(transitions, \"input\");\n\t\t}\n\n\t\tconst inputTypes = Object.keys(transitions ?? {});\n\t\tif (terminal === true && inputTypes.length > 0) {\n\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t`Terminal domain machine state \"${state}\" cannot declare transitions.`,\n\t\t\t);\n\t\t}\n\n\t\tfor (const inputType of inputTypes) {\n\t\t\tconst transition: unknown = readDomainMachineDefinitionProperty(\n\t\t\t\ttransitions as object,\n\t\t\t\tinputType,\n\t\t\t);\n\t\t\tif (!isPlainRecord(transition)) {\n\t\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t\t`Domain transition from \"${state}\" on \"${inputType}\" must be a plain object.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tassertDomainMachineDefinitionDataProperties(\n\t\t\t\ttransition,\n\t\t\t\tDOMAIN_MACHINE_TRANSITION_KEYS,\n\t\t\t);\n\n\t\t\tconst target: unknown = readDomainMachineDefinitionProperty(\n\t\t\t\ttransition,\n\t\t\t\t\"target\",\n\t\t\t);\n\t\t\tif (typeof target !== \"string\") {\n\t\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t\t`Domain transition from \"${state}\" on \"${inputType}\" must target a string state.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (!hasOwn(states, target)) {\n\t\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t\t`Domain transition from \"${state}\" on \"${inputType}\" targets unknown state \"${target}\".`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst guard: unknown = readOptionalDomainMachineDefinitionProperty(\n\t\t\t\ttransition,\n\t\t\t\t\"guard\",\n\t\t\t);\n\t\t\tif (guard !== undefined && typeof guard !== \"function\") {\n\t\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t\t`Domain transition from \"${state}\" on \"${inputType}\" guard must be a function.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst reduce: unknown = readOptionalDomainMachineDefinitionProperty(\n\t\t\t\ttransition,\n\t\t\t\t\"reduce\",\n\t\t\t);\n\t\t\tif (reduce !== undefined && typeof reduce !== \"function\") {\n\t\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t\t`Domain transition from \"${state}\" on \"${inputType}\" reduce must be a function.`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction assertDomainMachineDefinitionDataProperties(\n\tvalue: object,\n\tallowedKeys?: ReadonlySet<PropertyKey>,\n): void {\n\tfor (const key of Reflect.ownKeys(value)) {\n\t\tconst descriptor = Object.getOwnPropertyDescriptor(value, key);\n\t\tif (descriptor !== undefined && !(\"value\" in descriptor)) {\n\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t\"Domain machine definition must contain data properties only.\",\n\t\t\t);\n\t\t}\n\t\tif (allowedKeys !== undefined && !allowedKeys.has(key)) {\n\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t`Domain machine definition contains unknown property \"${String(key)}\".`,\n\t\t\t);\n\t\t}\n\t}\n}\n\nfunction assertDomainMachineDefinitionEntryMap(\n\tvalue: object,\n\tentryName: \"state\" | \"input\",\n): void {\n\tassertDomainMachineDefinitionDataProperties(value);\n\n\tfor (const key of Reflect.ownKeys(value)) {\n\t\tconst descriptor = Object.getOwnPropertyDescriptor(value, key);\n\t\tif (typeof key !== \"string\" || descriptor?.enumerable !== true) {\n\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t`Domain machine ${entryName} names must be enumerable string properties.`,\n\t\t\t);\n\t\t}\n\t}\n}\n\nfunction readDomainMachineDefinitionProperty(\n\tvalue: object,\n\tkey: PropertyKey,\n): unknown {\n\tconst descriptor = Object.getOwnPropertyDescriptor(value, key);\n\tif (descriptor === undefined || !(\"value\" in descriptor)) {\n\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\"Domain machine definition must contain data properties only.\",\n\t\t);\n\t}\n\n\treturn descriptor.value;\n}\n\nfunction readOptionalDomainMachineDefinitionProperty(\n\tvalue: object,\n\tkey: PropertyKey,\n): unknown {\n\tconst descriptor = Object.getOwnPropertyDescriptor(value, key);\n\tif (descriptor === undefined) return undefined;\n\tif (!(\"value\" in descriptor)) {\n\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\"Domain machine definition must contain data properties only.\",\n\t\t);\n\t}\n\n\treturn descriptor.value;\n}\n","import { DomainError } from \"../core/errors\";\nimport type {\n\tDomainMachineDefinition,\n\tDomainMachineInput,\n\tDomainMachineReadonly,\n\tDomainMachineSnapshot,\n\tDomainTransitionResult,\n} from \"./contracts\";\nimport {\n\tInvalidDomainMachineDefinitionError,\n\tInvalidDomainMachineInputError,\n\tInvalidDomainMachineSnapshotError,\n\tInvalidDomainTransitionGuardResultError,\n\tInvalidDomainTransitionResultError,\n} from \"./errors\";\nimport {\n\tcopyDomainMachineContext,\n\thasOwn,\n\tisPlainRecord,\n\tisRecord,\n} from \"./machine-data\";\n\nconst DOMAIN_TRANSITION_RESULT_KEYS: ReadonlySet<PropertyKey> = new Set([\n\t\"context\",\n\t\"outputs\",\n]);\n\nexport function prepareDomainMachineSnapshot<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n\tsnapshot: DomainMachineSnapshot<TState, TContext>,\n): DomainMachineSnapshot<TState, TContext> {\n\tvalidateDomainMachineSnapshot(definition, snapshot);\n\tconst preparedSnapshot = createDomainMachineSnapshot<TState, TContext>(\n\t\tsnapshot,\n\t);\n\t// Re-validate the COPY: a Proxy can answer the copy's reads differently\n\t// from validation's (TOCTOU), and the copy is what the machine runs on.\n\tvalidateDomainMachineSnapshot(definition, preparedSnapshot);\n\tvalidateDomainMachineSnapshotInvariant(definition, preparedSnapshot);\n\treturn preparedSnapshot;\n}\n\nexport function createDomainMachineSnapshotFromPreparedContext<\n\tTState extends string,\n\tTContext,\n>(\n\tstate: TState,\n\tcontext: DomainMachineReadonly<TContext>,\n): DomainMachineSnapshot<TState, TContext> {\n\treturn Object.freeze({ state, context });\n}\n\nexport function createDomainMachineSnapshot<\n\tTState extends string,\n\tTContext,\n>(snapshot: {\n\treadonly state: TState;\n\treadonly context: TContext | DomainMachineReadonly<TContext>;\n}): DomainMachineSnapshot<TState, TContext> {\n\treturn Object.freeze({\n\t\tstate: readDomainMachineSnapshotState(snapshot),\n\t\tcontext: copyDomainMachineContext<TContext>(\n\t\t\treadDomainMachineSnapshotContext(snapshot),\n\t\t),\n\t}) as DomainMachineSnapshot<TState, TContext>;\n}\n\nexport function validateDomainMachineSnapshot<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n\tsnapshot: DomainMachineSnapshot<TState, TContext>,\n): void {\n\tif (!isRecord(snapshot)) {\n\t\tthrow new InvalidDomainMachineSnapshotError(\n\t\t\t\"Domain machine snapshot must be an object.\",\n\t\t);\n\t}\n\n\tconst state = readDomainMachineSnapshotState(snapshot);\n\treadDomainMachineSnapshotContext(snapshot);\n\n\tif (!hasOwn(definition.states, state)) {\n\t\tthrow new InvalidDomainMachineSnapshotError(\n\t\t\t`Domain machine snapshot state \"${state}\" is not defined.`,\n\t\t);\n\t}\n}\n\nexport function validateDomainMachineSnapshotInvariant<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n\tsnapshot: DomainMachineSnapshot<TState, TContext>,\n): void {\n\tconst stateNode = definition.states[snapshot.state];\n\tif (stateNode.validateContext !== undefined) {\n\t\tconst validContext = stateNode.validateContext({\n\t\t\tstate: snapshot.state,\n\t\t\tcontext: snapshot.context,\n\t\t});\n\t\tif (typeof validContext !== \"boolean\") {\n\t\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\t`Domain machine state \"${snapshot.state}\" validateContext must return a boolean.`,\n\t\t\t);\n\t\t}\n\t\tif (!validContext) {\n\t\t\tthrow new InvalidDomainMachineSnapshotError(\n\t\t\t\t`Domain machine snapshot violates the context invariant for state \"${snapshot.state}\".`,\n\t\t\t);\n\t\t}\n\t}\n\n\tif (definition.validateSnapshot === undefined) return;\n\n\tconst valid = definition.validateSnapshot(snapshot);\n\tif (typeof valid !== \"boolean\") {\n\t\tthrow new InvalidDomainMachineDefinitionError(\n\t\t\t\"Domain machine validateSnapshot must return a boolean.\",\n\t\t);\n\t}\n\n\tif (!valid) {\n\t\tthrow new InvalidDomainMachineSnapshotError(\n\t\t\t`Domain machine snapshot violates invariants for state \"${snapshot.state}\".`,\n\t\t);\n\t}\n}\n\nfunction readDomainMachineSnapshotState<TState extends string>(snapshot: {\n\treadonly state: TState;\n}): TState {\n\tconst stateDescriptor = Object.getOwnPropertyDescriptor(snapshot, \"state\");\n\tif (\n\t\tstateDescriptor === undefined ||\n\t\t!(\"value\" in stateDescriptor) ||\n\t\ttypeof stateDescriptor.value !== \"string\"\n\t) {\n\t\tthrow new InvalidDomainMachineSnapshotError(\n\t\t\t\"Domain machine snapshot state must be a string data property.\",\n\t\t);\n\t}\n\n\treturn stateDescriptor.value as TState;\n}\n\nfunction readDomainMachineSnapshotContext<TContext>(snapshot: {\n\treadonly context: TContext;\n}): TContext {\n\tconst contextDescriptor = Object.getOwnPropertyDescriptor(\n\t\tsnapshot,\n\t\t\"context\",\n\t);\n\tif (contextDescriptor === undefined || !(\"value\" in contextDescriptor)) {\n\t\tthrow new InvalidDomainMachineSnapshotError(\n\t\t\t\"Domain machine snapshot context must be present as a data property.\",\n\t\t);\n\t}\n\n\treturn contextDescriptor.value as TContext;\n}\n\nexport function validateDomainMachineInput(\n\tinput: unknown,\n): asserts input is DomainMachineInput {\n\tif (!isDomainMachineInput(input)) {\n\t\tthrow new InvalidDomainMachineInputError(\n\t\t\t\"Domain machine input must be an object with a string type.\",\n\t\t);\n\t}\n}\n\nexport function isDomainMachineInput(\n\tinput: unknown,\n): input is DomainMachineInput {\n\tif (!isRecord(input)) return false;\n\n\tconst typeDescriptor = Object.getOwnPropertyDescriptor(input, \"type\");\n\treturn (\n\t\ttypeDescriptor !== undefined &&\n\t\t\"value\" in typeDescriptor &&\n\t\ttypeof typeDescriptor.value === \"string\"\n\t);\n}\n\nexport function resolveDomainTransitionGuardResult(\n\tresult: unknown,\n):\n\t| { readonly allowed: true }\n\t| { readonly allowed: false; readonly rejection?: DomainError } {\n\tif (typeof result === \"boolean\") return { allowed: result };\n\tif (result instanceof DomainError) {\n\t\treturn { allowed: false, rejection: result };\n\t}\n\n\tthrow new InvalidDomainTransitionGuardResultError(\n\t\t\"Domain transition guard must return a boolean or DomainError.\",\n\t);\n}\n\nexport function validateDomainTransitionResult<TContext, TOutput>(\n\tresult: DomainTransitionResult<TContext, TOutput> | undefined,\n): void {\n\tif (result === undefined) return;\n\n\tif (!isPlainRecord(result)) {\n\t\tthrow new InvalidDomainTransitionResultError(\n\t\t\t\"Domain transition result must be a plain object when returned.\",\n\t\t);\n\t}\n\n\tfor (const key of Reflect.ownKeys(result)) {\n\t\tif (!DOMAIN_TRANSITION_RESULT_KEYS.has(key)) {\n\t\t\tthrow new InvalidDomainTransitionResultError(\n\t\t\t\t`Domain transition result contains unknown property \"${String(key)}\".`,\n\t\t\t);\n\t\t}\n\t\tconst descriptor = Object.getOwnPropertyDescriptor(result, key);\n\t\tif (descriptor !== undefined && !(\"value\" in descriptor)) {\n\t\t\tthrow new InvalidDomainTransitionResultError(\n\t\t\t\t\"Domain transition result must contain data properties only.\",\n\t\t\t);\n\t\t}\n\t}\n\n\tconst outputs = readDomainTransitionResultOutputs(result);\n\tif (outputs !== undefined && !Array.isArray(outputs)) {\n\t\tthrow new InvalidDomainTransitionResultError(\n\t\t\t\"Domain transition result outputs must be an array when provided.\",\n\t\t);\n\t}\n}\n\nexport function readDomainTransitionResultContext<TContext, TOutput>(\n\tresult: DomainTransitionResult<TContext, TOutput> | undefined,\n):\n\t| { readonly hasContext: false }\n\t| { readonly hasContext: true; readonly context: TContext } {\n\tif (result === undefined) return { hasContext: false };\n\n\tconst contextDescriptor = Object.getOwnPropertyDescriptor(result, \"context\");\n\tif (contextDescriptor === undefined) return { hasContext: false };\n\tif (!(\"value\" in contextDescriptor)) {\n\t\tthrow new InvalidDomainTransitionResultError(\n\t\t\t\"Domain transition result context must be a data property when provided.\",\n\t\t);\n\t}\n\n\treturn { hasContext: true, context: contextDescriptor.value as TContext };\n}\n\nexport function readDomainTransitionResultOutputs<TContext, TOutput>(\n\tresult: DomainTransitionResult<TContext, TOutput> | undefined,\n): readonly TOutput[] | undefined {\n\tif (result === undefined) return undefined;\n\n\tconst outputsDescriptor = Object.getOwnPropertyDescriptor(result, \"outputs\");\n\tif (outputsDescriptor === undefined) return undefined;\n\tif (!(\"value\" in outputsDescriptor)) {\n\t\tthrow new InvalidDomainTransitionResultError(\n\t\t\t\"Domain transition result outputs must be a data property when provided.\",\n\t\t);\n\t}\n\n\treturn outputsDescriptor.value as readonly TOutput[] | undefined;\n}\n","import type {\n\tDomainMachineDefinition,\n\tDomainMachineInput,\n\tDomainMachineSnapshot,\n\tDomainTransitionOutcome,\n} from \"./contracts\";\nimport {\n\tensureStableDomainMachineDefinition,\n\tgetTransition,\n} from \"./definition\";\nimport {\n\tDomainTransitionGuardRejectedError,\n\tInvalidDomainTransitionError,\n} from \"./errors\";\nimport {\n\tcopyDomainMachineInput,\n\tcopyDomainMachineOutputs,\n} from \"./machine-data\";\nimport {\n\tcreateDomainMachineSnapshot,\n\tcreateDomainMachineSnapshotFromPreparedContext,\n\tisDomainMachineInput,\n\tprepareDomainMachineSnapshot,\n\treadDomainTransitionResultContext,\n\treadDomainTransitionResultOutputs,\n\tresolveDomainTransitionGuardResult,\n\tvalidateDomainMachineInput,\n\tvalidateDomainMachineSnapshotInvariant,\n\tvalidateDomainTransitionResult,\n} from \"./snapshot\";\n\n/** Creates and validates a fresh initial snapshot from a machine definition. */\nexport function createInitialDomainMachineSnapshot<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n): DomainMachineSnapshot<TState, TContext> {\n\tconst stableDefinition = ensureStableDomainMachineDefinition(definition);\n\treturn createInitialDomainMachineSnapshotFromPrepared(stableDefinition);\n}\n\nexport function createInitialDomainMachineSnapshotFromPrepared<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n): DomainMachineSnapshot<TState, TContext> {\n\tconst snapshot = createDomainMachineSnapshot<TState, TContext>({\n\t\tstate: definition.initial,\n\t\tcontext: definition.initialContext(),\n\t});\n\tvalidateDomainMachineSnapshotInvariant(definition, snapshot);\n\treturn snapshot;\n}\n\n/**\n * Checks whether an input currently has an allowed transition.\n *\n * Returns `false` for missing transitions, terminal states, rejected guards,\n * and inputs without an own string `type` property. Invalid payload data for a\n * matching transition and broken guard code still throw structured errors.\n */\nexport function canTransitionDomainState<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n\tsnapshot: DomainMachineSnapshot<TState, TContext>,\n\tinput: TInput,\n): boolean {\n\tconst stableDefinition = ensureStableDomainMachineDefinition(definition);\n\tconst currentSnapshot = prepareDomainMachineSnapshot(\n\t\tstableDefinition,\n\t\tsnapshot,\n\t);\n\treturn canTransitionPreparedDomainState(\n\t\tstableDefinition,\n\t\tcurrentSnapshot,\n\t\tinput,\n\t);\n}\n\nexport function canTransitionPreparedDomainState<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n\tsnapshot: DomainMachineSnapshot<TState, TContext>,\n\tinput: TInput,\n): boolean {\n\tif (!isDomainMachineInput(input)) return false;\n\n\tconst stateNode = definition.states[snapshot.state];\n\tif (stateNode.terminal === true) return false;\n\n\tconst transition = getTransition(definition, snapshot.state, input);\n\tif (!transition) return false;\n\n\tconst currentInput = copyDomainMachineInput(input);\n\tif (!transition.guard) return true;\n\n\tconst guardResult = transition.guard({\n\t\tstate: snapshot.state,\n\t\tcontext: snapshot.context,\n\t\tinput: currentInput,\n\t});\n\n\treturn resolveDomainTransitionGuardResult(guardResult).allowed;\n}\n\n/**\n * Applies one input without mutating the input definition or snapshot.\n *\n * @throws {@link InvalidDomainTransitionError} when no transition is defined.\n * @throws {@link DomainTransitionGuardRejectedError} when its guard rejects.\n * @throws A concrete `DomainError` returned by a rejecting guard.\n */\nexport function transitionDomainState<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n\tsnapshot: DomainMachineSnapshot<TState, TContext>,\n\tinput: TInput,\n): DomainTransitionOutcome<TState, TContext, TOutput> {\n\tconst stableDefinition = ensureStableDomainMachineDefinition(definition);\n\tconst currentSnapshot = prepareDomainMachineSnapshot(\n\t\tstableDefinition,\n\t\tsnapshot,\n\t);\n\treturn transitionPreparedDomainState(\n\t\tstableDefinition,\n\t\tcurrentSnapshot,\n\t\tinput,\n\t);\n}\n\nexport function transitionPreparedDomainState<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n\tsnapshot: DomainMachineSnapshot<TState, TContext>,\n\tinput: TInput,\n): DomainTransitionOutcome<TState, TContext, TOutput> {\n\tvalidateDomainMachineInput(input);\n\n\tconst from = snapshot.state;\n\tconst stateNode = definition.states[from];\n\tconst transition =\n\t\tstateNode.terminal === true\n\t\t\t? undefined\n\t\t\t: getTransition(definition, from, input);\n\n\tif (!transition) {\n\t\tthrow new InvalidDomainTransitionError(from, input.type);\n\t}\n\n\tconst currentInput = copyDomainMachineInput(input);\n\tconst guardResult =\n\t\ttransition.guard === undefined\n\t\t\t? true\n\t\t\t: transition.guard({\n\t\t\t\t\tstate: from,\n\t\t\t\t\tcontext: snapshot.context,\n\t\t\t\t\tinput: currentInput,\n\t\t\t\t});\n\tconst guardDecision = resolveDomainTransitionGuardResult(guardResult);\n\n\tif (!guardDecision.allowed) {\n\t\tif (guardDecision.rejection !== undefined) {\n\t\t\tthrow guardDecision.rejection;\n\t\t}\n\t\tthrow new DomainTransitionGuardRejectedError(from, currentInput.type);\n\t}\n\n\tconst result = transition.reduce?.({\n\t\tstate: from,\n\t\tcontext: snapshot.context,\n\t\tinput: currentInput,\n\t});\n\tvalidateDomainTransitionResult(result);\n\tconst contextResult = readDomainTransitionResultContext(result);\n\tconst nextContext = contextResult.hasContext\n\t\t? contextResult.context\n\t\t: snapshot.context;\n\tconst nextSnapshot =\n\t\tnextContext === snapshot.context\n\t\t\t? createDomainMachineSnapshotFromPreparedContext<TState, TContext>(\n\t\t\t\t\ttransition.target,\n\t\t\t\t\tsnapshot.context,\n\t\t\t\t)\n\t\t\t: createDomainMachineSnapshot<TState, TContext>({\n\t\t\t\t\tstate: transition.target,\n\t\t\t\t\tcontext: nextContext,\n\t\t\t\t});\n\tvalidateDomainMachineSnapshotInvariant(definition, nextSnapshot);\n\n\t// Frozen like every sibling return value (snapshots, outputs, the\n\t// analyzer result): the contract types the fields readonly, and the\n\t// runtime must not allow a cast to rewrite from/to.\n\treturn Object.freeze({\n\t\tfrom,\n\t\tto: transition.target,\n\t\tsnapshot: nextSnapshot,\n\t\toutputs: copyDomainMachineOutputs(\n\t\t\treadDomainTransitionResultOutputs(result),\n\t\t),\n\t});\n}\n","import type { DomainMachineDefinition, DomainMachineInput } from \"./contracts\";\nimport { ensureStableDomainMachineDefinition } from \"./definition\";\n\nexport type DomainMachineDefinitionDiagnostic<TState extends string> =\n\t| {\n\t\t\treadonly code: \"unreachable-state\";\n\t\t\treadonly state: TState;\n\t }\n\t| {\n\t\t\treadonly code: \"structural-dead-end\";\n\t\t\treadonly state: TState;\n\t }\n\t| {\n\t\t\treadonly code: \"no-terminal-path\";\n\t\t\treadonly state: TState;\n\t };\n\nexport type DomainMachineTransitionDescription<\n\tTState extends string,\n\tTInputType extends string,\n> = {\n\treadonly state: TState;\n\treadonly inputType: TInputType;\n\treadonly target: TState;\n\treadonly guarded: boolean;\n};\n\nexport type DomainMachineDefinitionAnalysis<\n\tTState extends string,\n\tTInputType extends string,\n> = {\n\treadonly diagnostics: readonly DomainMachineDefinitionDiagnostic<TState>[];\n\treadonly transitions: readonly DomainMachineTransitionDescription<\n\t\tTState,\n\t\tTInputType\n\t>[];\n\t/** States reachable when every guard is assumed to allow its transition. */\n\treadonly structurallyReachableStates: readonly TState[];\n\t/** States with a graph path to a terminal state when every guard is assumed to allow it. */\n\treadonly statesWithTerminalPath: readonly TState[];\n};\n\n/**\n * Inspects the declarative transition graph without executing definition callbacks.\n * Guarded edges are treated as possible edges, so diagnostics never claim more\n * runtime reachability than the static graph can prove.\n */\nexport function analyzeDomainMachineDefinition<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput,\n>(\n\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n): DomainMachineDefinitionAnalysis<TState, TInput[\"type\"]> {\n\t// The shared entry-point normalization: a prepared definition passes\n\t// through untouched (already validated, copied, frozen), a raw one\n\t// pays the documented per-call validate-and-copy.\n\tconst stableDefinition = ensureStableDomainMachineDefinition(definition);\n\tconst states = (Object.keys(stableDefinition.states) as TState[]).sort(\n\t\tcompareStrings,\n\t);\n\tconst outgoing = new Map<TState, TState[]>();\n\tconst incoming = new Map<TState, TState[]>();\n\tconst transitions: DomainMachineTransitionDescription<\n\t\tTState,\n\t\tTInput[\"type\"]\n\t>[] = [];\n\n\tfor (const state of states) {\n\t\toutgoing.set(state, []);\n\t\tincoming.set(state, []);\n\t}\n\n\tfor (const state of states) {\n\t\tconst stateTransitions = stableDefinition.states[state].on;\n\t\tconst inputTypes = (\n\t\t\tObject.keys(stateTransitions ?? {}) as TInput[\"type\"][]\n\t\t).sort(compareStrings);\n\n\t\tfor (const inputType of inputTypes) {\n\t\t\tconst transition = stateTransitions?.[inputType];\n\t\t\tif (transition === undefined) continue;\n\n\t\t\toutgoing.get(state)?.push(transition.target);\n\t\t\tincoming.get(transition.target)?.push(state);\n\t\t\ttransitions.push(\n\t\t\t\tObject.freeze({\n\t\t\t\t\tstate,\n\t\t\t\t\tinputType,\n\t\t\t\t\ttarget: transition.target,\n\t\t\t\t\tguarded: transition.guard !== undefined,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t}\n\n\tconst structurallyReachable = visitGraph(\n\t\t[stableDefinition.initial],\n\t\toutgoing,\n\t);\n\tconst terminalStates = states.filter(\n\t\t(state) => stableDefinition.states[state].terminal === true,\n\t);\n\tconst statesWithTerminalPath = visitGraph(terminalStates, incoming);\n\tconst diagnostics: DomainMachineDefinitionDiagnostic<TState>[] = [];\n\n\tfor (const state of states) {\n\t\tif (!structurallyReachable.has(state)) {\n\t\t\tdiagnostics.push(Object.freeze({ code: \"unreachable-state\", state }));\n\t\t}\n\t}\n\tfor (const state of states) {\n\t\tif (\n\t\t\tstableDefinition.states[state].terminal !== true &&\n\t\t\toutgoing.get(state)?.length === 0\n\t\t) {\n\t\t\tdiagnostics.push(Object.freeze({ code: \"structural-dead-end\", state }));\n\t\t}\n\t}\n\tfor (const state of states) {\n\t\tif (!statesWithTerminalPath.has(state)) {\n\t\t\tdiagnostics.push(Object.freeze({ code: \"no-terminal-path\", state }));\n\t\t}\n\t}\n\n\treturn Object.freeze({\n\t\tdiagnostics: Object.freeze(diagnostics),\n\t\ttransitions: Object.freeze(transitions),\n\t\tstructurallyReachableStates: Object.freeze(\n\t\t\tstates.filter((state) => structurallyReachable.has(state)),\n\t\t),\n\t\tstatesWithTerminalPath: Object.freeze(\n\t\t\tstates.filter((state) => statesWithTerminalPath.has(state)),\n\t\t),\n\t});\n}\n\nfunction visitGraph<TState extends string>(\n\tstartStates: readonly TState[],\n\tedges: ReadonlyMap<TState, readonly TState[]>,\n): ReadonlySet<TState> {\n\tconst visited = new Set<TState>();\n\tconst pending = [...startStates];\n\n\twhile (pending.length > 0) {\n\t\tconst state = pending.pop();\n\t\tif (state === undefined || visited.has(state)) continue;\n\n\t\tvisited.add(state);\n\t\tfor (const next of edges.get(state) ?? []) {\n\t\t\tif (!visited.has(next)) pending.push(next);\n\t\t}\n\t}\n\n\treturn visited;\n}\n\nfunction compareStrings(left: string, right: string): number {\n\treturn left < right ? -1 : left > right ? 1 : 0;\n}\n","import type {\n\tDomainMachineDefinition,\n\tDomainMachineInput,\n\tDomainMachineReadonly,\n\tDomainMachineSnapshot,\n\tDomainTransitionOutcome,\n} from \"./contracts\";\nimport { ensureStableDomainMachineDefinition } from \"./definition\";\nimport { ReentrantDomainStateMachineEvaluationError } from \"./errors\";\nimport {\n\tcreateDomainMachineSnapshot,\n\tprepareDomainMachineSnapshot,\n} from \"./snapshot\";\nimport {\n\tcanTransitionPreparedDomainState,\n\tcreateInitialDomainMachineSnapshotFromPrepared,\n\ttransitionPreparedDomainState,\n} from \"./transition\";\n\nexport type {\n\tDomainMachineDefinitionAnalysis,\n\tDomainMachineDefinitionDiagnostic,\n\tDomainMachineTransitionDescription,\n} from \"./analyzer\";\nexport { analyzeDomainMachineDefinition } from \"./analyzer\";\nexport type {\n\tDomainMachineDefinition,\n\tDomainMachineInput,\n\tDomainMachineReadonly,\n\tDomainMachineSnapshot,\n\tDomainStateNode,\n\tDomainTransition,\n\tDomainTransitionGuardResult,\n\tDomainTransitionOutcome,\n\tDomainTransitionResult,\n} from \"./contracts\";\nexport {\n\ttype PreparedDomainMachineDefinition,\n\tprepareDomainMachineDefinition,\n} from \"./definition\";\nexport {\n\tDomainTransitionGuardRejectedError,\n\tInvalidDomainMachineContextError,\n\tInvalidDomainMachineDefinitionError,\n\tInvalidDomainMachineInputError,\n\tInvalidDomainMachineSnapshotError,\n\tInvalidDomainTransitionError,\n\tInvalidDomainTransitionGuardResultError,\n\tInvalidDomainTransitionResultError,\n\tReentrantDomainStateMachineEvaluationError,\n} from \"./errors\";\nexport {\n\tcanTransitionDomainState,\n\tcreateInitialDomainMachineSnapshot,\n\ttransitionDomainState,\n} from \"./transition\";\n\n/**\n * Stateful convenience wrapper around the pure domain transition functions.\n *\n * Persist {@link snapshot}, not the machine instance. Pass a restored snapshot\n * to the second constructor overload to validate and reconstitute a machine.\n */\nexport class DomainStateMachine<\n\tTState extends string,\n\tTContext,\n\tTInput extends DomainMachineInput,\n\tTOutput = never,\n> {\n\tprivate readonly definition: DomainMachineDefinition<\n\t\tTState,\n\t\tTContext,\n\t\tTInput,\n\t\tTOutput\n\t>;\n\n\t#snapshot: DomainMachineSnapshot<TState, TContext>;\n\t#evaluating = false;\n\n\tconstructor(\n\t\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n\t);\n\tconstructor(\n\t\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n\t\tsnapshot: DomainMachineSnapshot<TState, TContext> | undefined,\n\t);\n\tconstructor(\n\t\tdefinition: DomainMachineDefinition<TState, TContext, TInput, TOutput>,\n\t\t...snapshotInput: [] | [DomainMachineSnapshot<TState, TContext> | undefined]\n\t) {\n\t\t// A prepared definition (prepareDomainMachineDefinition) passes\n\t\t// through; a raw one pays the one-time validate-and-copy here.\n\t\tthis.definition = ensureStableDomainMachineDefinition(definition);\n\t\t// Resolve the overload by the argument value, not the rest-parameter\n\t\t// arity: an explicit `undefined` snapshot (a natural result of a\n\t\t// nullable `repo.loadSnapshot(id)` or `map.get(id)` passed straight\n\t\t// through) means \"no snapshot\", so it must fall back to the initial\n\t\t// snapshot instead of failing validation.\n\t\tconst [suppliedSnapshot] = snapshotInput;\n\t\tif (suppliedSnapshot !== undefined) {\n\t\t\t// One shared implementation with the pure path (transition.ts);\n\t\t\t// hand-rolling the validate-copy-validate trio here would let\n\t\t\t// the class and pure snapshot preparation drift.\n\t\t\tthis.#snapshot = prepareDomainMachineSnapshot(\n\t\t\t\tthis.definition,\n\t\t\t\tsuppliedSnapshot,\n\t\t\t);\n\t\t} else {\n\t\t\tthis.#snapshot = createInitialDomainMachineSnapshotFromPrepared(\n\t\t\t\tthis.definition,\n\t\t\t);\n\t\t}\n\t}\n\n\t/** Returns a defensive, deeply frozen copy of the current snapshot. */\n\tget snapshot(): DomainMachineSnapshot<TState, TContext> {\n\t\treturn createDomainMachineSnapshot<TState, TContext>(this.#snapshot);\n\t}\n\n\t/** Current named control state. */\n\tget state(): TState {\n\t\treturn this.#snapshot.state;\n\t}\n\n\t/** Current deeply readonly context. */\n\tget context(): DomainMachineReadonly<TContext> {\n\t\treturn this.#snapshot.context;\n\t}\n\n\t/** Whether the current state permanently forbids outgoing transitions. */\n\tisTerminal(): boolean {\n\t\treturn this.definition.states[this.state].terminal === true;\n\t}\n\n\t/** Checks a transition without changing the current snapshot. */\n\tcan(input: TInput): boolean {\n\t\treturn this.evaluate(() =>\n\t\t\tcanTransitionPreparedDomainState(this.definition, this.#snapshot, input),\n\t\t);\n\t}\n\n\t/** Applies an input and advances the current snapshot on success. */\n\tdispatch(input: TInput): DomainTransitionOutcome<TState, TContext, TOutput> {\n\t\treturn this.evaluate(() => {\n\t\t\tconst result = transitionPreparedDomainState(\n\t\t\t\tthis.definition,\n\t\t\t\tthis.#snapshot,\n\t\t\t\tinput,\n\t\t\t);\n\t\t\tthis.#snapshot = result.snapshot;\n\t\t\treturn result;\n\t\t});\n\t}\n\n\tprivate evaluate<TResult>(operation: () => TResult): TResult {\n\t\tif (this.#evaluating) {\n\t\t\tthrow new ReentrantDomainStateMachineEvaluationError();\n\t\t}\n\n\t\tthis.#evaluating = true;\n\t\ttry {\n\t\t\treturn operation();\n\t\t} finally {\n\t\t\tthis.#evaluating = false;\n\t\t}\n\t}\n}\n","import type { AnyDomainEvent } from \"../aggregate/domain-event\";\nimport { abortReason } from \"../utils/abort\";\nimport {\n\tDEFAULT_EXECUTION_TIMEOUT_MS,\n\ttype ExecutionContext,\n\trunBoundedExecution,\n} from \"../utils/execution\";\nimport type {\n\tEventBus,\n\tEventHandler,\n\tOnceOptions,\n\tPublishOptions,\n} from \"./ports\";\n\n/**\n * Simple in-memory event bus implementation.\n * Supports multiple subscribers per event type (pub/sub pattern).\n *\n * @template Evt - The type of domain events (must extend DomainEvent)\n *\n * @example\n * ```typescript\n * const bus = new EventBusImpl<OrderEvent>();\n *\n * bus.subscribe(\"OrderCreated\", async (event) => {\n * await sendEmail(event.payload.customerId);\n * });\n *\n * bus.subscribe(\"OrderCreated\", async (event) => {\n * await logEvent(event);\n * });\n *\n * await bus.publish([orderCreatedEvent]);\n * // Both handlers will be called\n * ```\n */\nexport class EventBusImpl<Evt extends AnyDomainEvent> implements EventBus<Evt> {\n\tprivate readonly handlers = new Map<string, EventHandler<Evt>[]>();\n\tprivate readonly catchAllHandlers: EventHandler<Evt>[] = [];\n\n\tsubscribe<K extends Evt[\"type\"]>(\n\t\teventType: K,\n\t\thandler: EventHandler<Extract<Evt, { type: K }>>,\n\t): () => void {\n\t\tconst type = eventType;\n\t\tif (!this.handlers.has(type)) {\n\t\t\tthis.handlers.set(type, []);\n\t\t}\n\t\tconst handlersForType = this.handlers.get(type)!;\n\t\tconst casted = handler as EventHandler<Evt>;\n\t\thandlersForType.push(casted);\n\n\t\t// Return unsubscribe: removes exactly this subscription, even if the\n\t\t// same handler reference was subscribed multiple times (each call to\n\t\t// subscribe gets its own unsubscribe).\n\t\tlet removed = false;\n\t\treturn () => {\n\t\t\tif (removed) return;\n\t\t\tconst idx = handlersForType.indexOf(casted);\n\t\t\tif (idx !== -1) {\n\t\t\t\thandlersForType.splice(idx, 1);\n\t\t\t\tremoved = true;\n\t\t\t}\n\t\t\tif (handlersForType.length === 0) {\n\t\t\t\tthis.handlers.delete(type);\n\t\t\t}\n\t\t};\n\t}\n\n\t/**\n\t * See {@link EventBus.subscribeAll}: every published event, in the\n\t * same dispatch batch as its typed handlers.\n\t */\n\tsubscribeAll(handler: EventHandler<Evt>): () => void {\n\t\tthis.catchAllHandlers.push(handler);\n\n\t\t// Unsubscribe semantics as in subscribe(): removes exactly this\n\t\t// subscription, even when the same handler reference was\n\t\t// subscribed multiple times.\n\t\tlet removed = false;\n\t\treturn () => {\n\t\t\tif (removed) return;\n\t\t\tconst idx = this.catchAllHandlers.indexOf(handler);\n\t\t\tif (idx !== -1) {\n\t\t\t\tthis.catchAllHandlers.splice(idx, 1);\n\t\t\t\tremoved = true;\n\t\t\t}\n\t\t};\n\t}\n\n\tonce<K extends Evt[\"type\"]>(\n\t\teventType: K,\n\t\toptions?: OnceOptions,\n\t): Promise<Extract<Evt, { type: K }>> {\n\t\treturn new Promise<Extract<Evt, { type: K }>>((resolve, reject) => {\n\t\t\t// Reject synchronously if the signal is already aborted; don't\n\t\t\t// even subscribe.\n\t\t\tif (options?.signal?.aborted) {\n\t\t\t\treject(abortReason(options.signal, \"EventBus.once aborted\"));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\t\t\tlet settled = false;\n\t\t\tlet abortListener: (() => void) | undefined;\n\n\t\t\tconst cleanup = () => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tunsubscribe();\n\t\t\t\tif (timer !== undefined) clearTimeout(timer);\n\t\t\t\tif (abortListener && options?.signal) {\n\t\t\t\t\toptions.signal.removeEventListener(\"abort\", abortListener);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst unsubscribe = this.subscribe(eventType, (event) => {\n\t\t\t\tcleanup();\n\t\t\t\tresolve(event);\n\t\t\t});\n\n\t\t\tif (options?.signal) {\n\t\t\t\tabortListener = () => {\n\t\t\t\t\tcleanup();\n\t\t\t\t\treject(abortReason(options.signal!, \"EventBus.once aborted\"));\n\t\t\t\t};\n\t\t\t\toptions.signal.addEventListener(\"abort\", abortListener);\n\t\t\t}\n\n\t\t\tif (typeof options?.timeoutMs === \"number\") {\n\t\t\t\ttimer = setTimeout(() => {\n\t\t\t\t\tcleanup();\n\t\t\t\t\treject(\n\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t`EventBus.once timed out after ${options.timeoutMs}ms waiting for \"${eventType}\"`,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}, options.timeoutMs);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * See {@link EventBus.publish} for the full ordering / parallelism /\n\t * error-aggregation contract this implementation realises:\n\t * - events in input order, sequentially;\n\t * - handlers within one event in parallel via `Promise.allSettled`;\n\t * - errors collected and thrown after the batch (single Error, or\n\t * `AggregateError` for multiple failures).\n\t */\n\tasync publish(\n\t\tevents: ReadonlyArray<Evt>,\n\t\toptions: PublishOptions = {},\n\t): Promise<void> {\n\t\t// The errors array lives HERE, outside the bounded execution: the\n\t\t// abort/timeout race can reject while handlers already failed, and\n\t\t// the port contract promises that collected handler errors are\n\t\t// thrown after dispatch. An abort ends the batch but must not\n\t\t// swallow the failures that already happened.\n\t\tconst errors: Error[] = [];\n\t\ttry {\n\t\t\tawait runBoundedExecution(\n\t\t\t\t\"EventBus.publish\",\n\t\t\t\t{\n\t\t\t\t\tsignal: options.signal,\n\t\t\t\t\ttimeoutMs: options.timeoutMs ?? DEFAULT_EXECUTION_TIMEOUT_MS,\n\t\t\t\t},\n\t\t\t\t(context) => this.publishWithinContext(events, context, errors),\n\t\t\t);\n\t\t} catch (boundedError) {\n\t\t\tif (errors.length === 0) throw boundedError;\n\t\t\tthrow new AggregateError(\n\t\t\t\t[\n\t\t\t\t\tboundedError instanceof Error\n\t\t\t\t\t\t? boundedError\n\t\t\t\t\t\t: new Error(String(boundedError), { cause: boundedError }),\n\t\t\t\t\t...errors,\n\t\t\t\t],\n\t\t\t\t\"EventBus.publish aborted after handler failures\",\n\t\t\t);\n\t\t}\n\t\tif (errors.length === 1) {\n\t\t\tthrow errors[0];\n\t\t}\n\t\tif (errors.length > 1) {\n\t\t\tthrow new AggregateError(errors, \"Multiple event handlers failed\");\n\t\t}\n\t}\n\n\tprivate async publishWithinContext(\n\t\tevents: ReadonlyArray<Evt>,\n\t\tcontext: ExecutionContext,\n\t\terrors: Error[],\n\t): Promise<void> {\n\t\tfor (const event of events) {\n\t\t\tif (context.signal.aborted) {\n\t\t\t\tthrow abortReason(context.signal, \"EventBus.publish aborted\");\n\t\t\t}\n\t\t\t// Typed and catch-all handlers share ONE allSettled batch, so the\n\t\t\t// contract holds across both kinds: none sees the others' errors,\n\t\t\t// none is skipped when a peer fails. Snapshot so a handler\n\t\t\t// unsubscribing during dispatch doesn't shift indices while we\n\t\t\t// iterate. The async wrapper converts a synchronous throw\n\t\t\t// (EventHandler may return void) into a rejection; otherwise it\n\t\t\t// would escape before allSettled sees the array, skipping peers\n\t\t\t// and orphaning their promises.\n\t\t\tconst batch = [\n\t\t\t\t...(this.handlers.get(event.type) ?? []),\n\t\t\t\t...this.catchAllHandlers,\n\t\t\t];\n\t\t\tif (batch.length > 0) {\n\t\t\t\t// Each failure is recorded the moment it happens, not after the\n\t\t\t\t// whole batch settles: a hung peer would otherwise trap a\n\t\t\t\t// settled rejection inside allSettled, invisible to the\n\t\t\t\t// abort/timeout path that ends the publish.\n\t\t\t\tconst batchStart = errors.length;\n\t\t\t\tconst failedIndices: number[] = [];\n\t\t\t\tawait Promise.allSettled(\n\t\t\t\t\tbatch.map(async (handler, index) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait handler(event, context);\n\t\t\t\t\t\t} catch (reason) {\n\t\t\t\t\t\t\tfailedIndices.push(index);\n\t\t\t\t\t\t\terrors.push(\n\t\t\t\t\t\t\t\treason instanceof Error\n\t\t\t\t\t\t\t\t\t? reason\n\t\t\t\t\t\t\t\t\t: // Attach the raw reason as cause: a handler\n\t\t\t\t\t\t\t\t\t\t// rejecting with a structured payload must stay\n\t\t\t\t\t\t\t\t\t\t// diagnosable, not collapse to '[object Object]'.\n\t\t\t\t\t\t\t\t\t\tnew Error(String(reason), { cause: reason }),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\t// A settled batch reports its failures in subscription order\n\t\t\t\t// (the aggregation contract); recording order above is\n\t\t\t\t// settlement order so an abort mid-batch already sees them.\n\t\t\t\tconst settled = errors.splice(batchStart);\n\t\t\t\terrors.push(\n\t\t\t\t\t...failedIndices\n\t\t\t\t\t\t.map((index, i) => ({ index, error: settled[i] as Error }))\n\t\t\t\t\t\t.sort((a, b) => a.index - b.index)\n\t\t\t\t\t\t.map((entry) => entry.error),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (context.signal.aborted) {\n\t\t\t\tthrow abortReason(context.signal, \"EventBus.publish aborted\");\n\t\t\t}\n\t\t}\n\t}\n}\n","import type { AggregateAddress } from \"../aggregate/aggregate-address\";\nimport {\n\ttype AnyDomainEvent,\n\tcreateDomainEvent,\n\ttype DomainEvent,\n\ttype EventMetadata,\n} from \"../aggregate/domain-event\";\nimport { InvalidIntegrationMessageError } from \"../core/errors\";\nimport { deepFreeze } from \"../value-object/value-object\";\nimport {\n\tassertJsonValue,\n\tisJsonObject,\n\ttype JsonObject,\n\ttype JsonValue,\n} from \"./json-value\";\nimport type { CommitPosition, CommittedDomainEvent } from \"./ports\";\n\nexport type { JsonObject, JsonPrimitive, JsonValue } from \"./json-value\";\n\n/** Standard relationship headers carried by the public message envelope. */\nexport interface IntegrationMessageRelationships {\n\t/** Groups messages that belong to one operation or trace. */\n\treadonly correlationId?: string;\n\t/** Groups a long-running business interaction across several correlations. */\n\treadonly conversationId?: string;\n\t/** Identifies the message, event, or command that immediately caused this one. */\n\treadonly causationId?: string;\n}\n\n/** Application-owned public content produced from one internal domain event. */\nexport interface IntegrationMessageContent<\n\tTType extends string,\n\tTPayload extends JsonValue,\n\tTMetadata extends JsonObject = JsonObject,\n> extends IntegrationMessageRelationships {\n\treadonly type: TType;\n\treadonly version: number;\n\treadonly payload: TPayload;\n\t/** Custom JSON metadata; relationship header names are reserved. */\n\treadonly metadata?: TMetadata;\n}\n\n/**\n * JSON-safe broker envelope, deliberately separate from {@link DomainEvent}.\n * Standard message relationships are explicit headers rather than payload or\n * custom metadata. Its source cursor supports ordered, gap-aware projection\n * consumption.\n */\nexport interface IntegrationMessage<\n\tTType extends string = string,\n\tTPayload extends JsonValue = JsonValue,\n\tTMetadata extends JsonObject = JsonObject,\n> extends IntegrationMessageContent<TType, TPayload, TMetadata> {\n\treadonly messageId: string;\n\treadonly occurredAt: string;\n\treadonly source: AggregateAddress;\n\treadonly position: CommitPosition;\n}\n\n/** Maps a private domain event to its explicit public message schema. */\nexport type IntegrationMessageMapper<\n\tEvt extends AnyDomainEvent,\n\tTType extends string,\n\tTPayload extends JsonValue,\n\tTMetadata extends JsonObject = JsonObject,\n> = (event: Evt) => IntegrationMessageContent<TType, TPayload, TMetadata>;\n\n/**\n * Maps a committed domain event to a deeply frozen JSON-safe message. The\n * mapper explicitly chooses every public relationship header; producer-private\n * domain metadata is never copied implicitly. Values JSON would change or\n * discard reject as {@link InvalidIntegrationMessageError}.\n */\nexport function createIntegrationMessage<\n\tEvt extends AnyDomainEvent,\n\tTType extends string,\n\tTPayload extends JsonValue,\n\tTMetadata extends JsonObject = JsonObject,\n>(\n\trecord: CommittedDomainEvent<Evt>,\n\tmapper: IntegrationMessageMapper<Evt, TType, TPayload, TMetadata>,\n): IntegrationMessage<TType, TPayload, TMetadata> {\n\tconst content = mapper(record.event);\n\treturn stabilizeIntegrationMessage({\n\t\tmessageId: record.event.eventId,\n\t\ttype: content.type,\n\t\tversion: content.version,\n\t\toccurredAt: record.event.occurredAt.toISOString(),\n\t\t...relationshipHeaders(content),\n\t\tpayload: content.payload,\n\t\t...(content.metadata === undefined ? {} : { metadata: content.metadata }),\n\t\tsource: record.source,\n\t\tposition: record.position,\n\t});\n}\n\n/** Validates and serializes an integration message without lossy coercion. */\nexport function encodeIntegrationMessage(message: IntegrationMessage): string {\n\tassertIntegrationMessage(message);\n\treturn JSON.stringify(message);\n}\n\n/**\n * Parses and validates a broker body, normalizes supported RFC 3339 timestamps\n * to canonical UTC milliseconds, then defensively copies and deeply freezes it.\n */\nexport function decodeIntegrationMessage(\n\tserialized: string,\n): IntegrationMessage {\n\ttry {\n\t\treturn stabilizeIntegrationMessage(JSON.parse(serialized), \"wire\");\n\t} catch (error) {\n\t\tif (error instanceof InvalidIntegrationMessageError) throw error;\n\t\tthrow new InvalidIntegrationMessageError(\n\t\t\t\"$\",\n\t\t\t\"body is not valid JSON\",\n\t\t\terror,\n\t\t);\n\t}\n}\n\n/**\n * Composes a validated public message into a minted local projector input.\n * Relationship headers become local event metadata. The public JSON schema is\n * retained; producer-private domain types are not reconstructed.\n */\nexport function integrationMessageToCommittedEvent<\n\tTType extends string,\n\tTPayload extends JsonValue,\n\tTMetadata extends JsonObject = JsonObject,\n>(\n\tmessage: IntegrationMessage<TType, TPayload, TMetadata>,\n): CommittedDomainEvent<DomainEvent<TType, TPayload>> {\n\tconst stableMessage = stabilizeIntegrationMessage(message);\n\tconst metadata = localEventMetadata(stableMessage);\n\treturn {\n\t\tevent: createDomainEvent(stableMessage.type, stableMessage.payload, {\n\t\t\teventId: stableMessage.messageId,\n\t\t\taggregateId: stableMessage.source.aggregateId,\n\t\t\taggregateType: stableMessage.source.aggregateType,\n\t\t\toccurredAt: new Date(stableMessage.occurredAt),\n\t\t\tversion: stableMessage.version,\n\t\t\tmetadata,\n\t\t}),\n\t\tsource: stableMessage.source,\n\t\tposition: stableMessage.position,\n\t};\n}\n\nfunction stabilizeIntegrationMessage<T>(\n\tvalue: T,\n\ttimestampFormat: \"canonical\" | \"wire\" = \"canonical\",\n): T {\n\tassertIntegrationMessage(value, timestampFormat);\n\tconst copy = JSON.parse(JSON.stringify(value));\n\tif (timestampFormat === \"wire\") {\n\t\tcopy.occurredAt = normalizeWireTimestamp(copy.occurredAt);\n\t}\n\treturn deepFreeze(copy) as T;\n}\n\nfunction assertIntegrationMessage(\n\tvalue: unknown,\n\ttimestampFormat: \"canonical\" | \"wire\" = \"canonical\",\n): asserts value is IntegrationMessage {\n\tassertJsonValue(value, \"$\", invalid);\n\tif (!isJsonObject(value)) {\n\t\tinvalid(\"$\", \"envelope must be a plain JSON object\");\n\t}\n\tif (typeof value.messageId !== \"string\" || value.messageId.length === 0) {\n\t\tinvalid(\"$.messageId\", \"must be a non-empty string\");\n\t}\n\tfor (const field of RELATIONSHIP_FIELDS) {\n\t\tif (!Object.hasOwn(value, field)) continue;\n\t\tconst relationshipId = value[field];\n\t\tif (typeof relationshipId !== \"string\" || relationshipId.length === 0) {\n\t\t\tinvalid(`$.${field}`, \"must be a non-empty string when present\");\n\t\t}\n\t}\n\tif (typeof value.type !== \"string\" || value.type.length === 0) {\n\t\tinvalid(\"$.type\", \"must be a non-empty string\");\n\t}\n\tconst version = value.version;\n\tif (\n\t\ttypeof version !== \"number\" ||\n\t\t!Number.isInteger(version) ||\n\t\tversion < 1\n\t) {\n\t\tinvalid(\"$.version\", \"must be an integer >= 1\");\n\t}\n\tif (\n\t\ttypeof value.occurredAt !== \"string\" ||\n\t\t(timestampFormat === \"canonical\"\n\t\t\t? !isCanonicalIsoTimestamp(value.occurredAt)\n\t\t\t: normalizeWireTimestamp(value.occurredAt) === undefined)\n\t) {\n\t\tinvalid(\n\t\t\t\"$.occurredAt\",\n\t\t\ttimestampFormat === \"canonical\"\n\t\t\t\t? \"must be a canonical UTC ISO-8601 timestamp\"\n\t\t\t\t: \"must be an RFC 3339 timestamp with an explicit offset and at most millisecond precision\",\n\t\t);\n\t}\n\tif (!Object.hasOwn(value, \"payload\")) {\n\t\tinvalid(\"$.payload\", \"is required (use null for an empty JSON payload)\");\n\t}\n\tif (\n\t\tObject.hasOwn(value, \"metadata\") &&\n\t\tvalue.metadata !== undefined &&\n\t\t!isJsonObject(value.metadata)\n\t) {\n\t\tinvalid(\"$.metadata\", \"must be a plain JSON object when present\");\n\t}\n\tif (isJsonObject(value.metadata)) {\n\t\tfor (const field of RELATIONSHIP_FIELDS) {\n\t\t\tif (Object.hasOwn(value.metadata, field)) {\n\t\t\t\tinvalid(\n\t\t\t\t\t`$.metadata.${field}`,\n\t\t\t\t\t\"is reserved for the explicit message envelope header\",\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\tif (!isJsonObject(value.source)) {\n\t\tinvalid(\"$.source\", \"must be a plain JSON object\");\n\t}\n\tif (\n\t\ttypeof value.source.aggregateType !== \"string\" ||\n\t\tvalue.source.aggregateType.length === 0\n\t) {\n\t\tinvalid(\"$.source.aggregateType\", \"must be a non-empty string\");\n\t}\n\tif (\n\t\ttypeof value.source.aggregateId !== \"string\" ||\n\t\tvalue.source.aggregateId.length === 0\n\t) {\n\t\tinvalid(\"$.source.aggregateId\", \"must be a non-empty string\");\n\t}\n\tif (!isJsonObject(value.position)) {\n\t\tinvalid(\"$.position\", \"must be a plain JSON object\");\n\t}\n\tconst { position } = value;\n\tconst aggregateVersion = position.aggregateVersion;\n\tif (\n\t\ttypeof aggregateVersion !== \"number\" ||\n\t\t!Number.isInteger(aggregateVersion) ||\n\t\taggregateVersion < 0\n\t) {\n\t\tinvalid(\"$.position.aggregateVersion\", \"must be an integer >= 0\");\n\t}\n\tconst commitSequence = position.commitSequence;\n\tif (\n\t\ttypeof commitSequence !== \"number\" ||\n\t\t!Number.isInteger(commitSequence) ||\n\t\tcommitSequence < 0\n\t) {\n\t\tinvalid(\"$.position.commitSequence\", \"must be an integer >= 0\");\n\t}\n\tconst commitSize = position.commitSize;\n\tif (\n\t\ttypeof commitSize !== \"number\" ||\n\t\t!Number.isInteger(commitSize) ||\n\t\tcommitSize <= commitSequence\n\t) {\n\t\tinvalid(\n\t\t\t\"$.position.commitSize\",\n\t\t\t\"must be a positive integer greater than commitSequence\",\n\t\t);\n\t}\n\tif (!Object.hasOwn(position, \"previousEventfulAggregateVersion\")) {\n\t\tinvalid(\n\t\t\t\"$.position.previousEventfulAggregateVersion\",\n\t\t\t\"is required (use null at genesis)\",\n\t\t);\n\t}\n\tconst previous = position.previousEventfulAggregateVersion;\n\tif (\n\t\tprevious !== null &&\n\t\t(typeof previous !== \"number\" ||\n\t\t\t!Number.isInteger(previous) ||\n\t\t\tprevious < 0 ||\n\t\t\tprevious >= aggregateVersion)\n\t) {\n\t\tinvalid(\n\t\t\t\"$.position.previousEventfulAggregateVersion\",\n\t\t\t\"must be null at genesis or an earlier non-negative aggregate version\",\n\t\t);\n\t}\n}\n\nconst RELATIONSHIP_FIELDS = [\n\t\"correlationId\",\n\t\"conversationId\",\n\t\"causationId\",\n] as const;\n\nfunction relationshipHeaders(\n\tprimary: IntegrationMessageRelationships,\n): IntegrationMessageRelationships {\n\tconst { correlationId, conversationId, causationId } = primary;\n\treturn {\n\t\t...(correlationId === undefined ? {} : { correlationId }),\n\t\t...(conversationId === undefined ? {} : { conversationId }),\n\t\t...(causationId === undefined ? {} : { causationId }),\n\t};\n}\n\nfunction localEventMetadata(\n\tmessage: IntegrationMessage,\n): EventMetadata | undefined {\n\tconst relationships = relationshipHeaders(message);\n\tif (\n\t\tmessage.metadata === undefined &&\n\t\tObject.keys(relationships).length === 0\n\t) {\n\t\treturn undefined;\n\t}\n\treturn { ...message.metadata, ...relationships };\n}\n\nfunction isCanonicalIsoTimestamp(value: string): boolean {\n\tconst timestamp = new Date(value);\n\treturn (\n\t\t!Number.isNaN(timestamp.getTime()) && timestamp.toISOString() === value\n\t);\n}\n\nconst WIRE_TIMESTAMP =\n\t/^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d{1,3}))?(Z|[+-](\\d{2}):(\\d{2}))$/;\n\nfunction normalizeWireTimestamp(value: string): string | undefined {\n\tconst match = WIRE_TIMESTAMP.exec(value);\n\tif (match === null) return undefined;\n\n\tconst [\n\t\t,\n\t\tyear,\n\t\tmonth,\n\t\tday,\n\t\thour,\n\t\tminute,\n\t\tsecond,\n\t\t,\n\t\t,\n\t\toffsetHour,\n\t\toffsetMinute,\n\t] = match;\n\tconst numericYear = Number(year);\n\tconst numericMonth = Number(month);\n\tconst numericDay = Number(day);\n\tif (\n\t\tnumericMonth < 1 ||\n\t\tnumericMonth > 12 ||\n\t\tnumericDay < 1 ||\n\t\tnumericDay > daysInMonth(numericYear, numericMonth) ||\n\t\tNumber(hour) > 23 ||\n\t\tNumber(minute) > 59 ||\n\t\tNumber(second) > 59 ||\n\t\t(offsetHour !== undefined && Number(offsetHour) > 23) ||\n\t\t(offsetMinute !== undefined && Number(offsetMinute) > 59)\n\t) {\n\t\treturn undefined;\n\t}\n\n\tconst timestamp = new Date(value);\n\treturn Number.isNaN(timestamp.getTime())\n\t\t? undefined\n\t\t: timestamp.toISOString();\n}\n\nfunction daysInMonth(year: number, month: number): number {\n\tif (month === 2) {\n\t\treturn year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0) ? 29 : 28;\n\t}\n\treturn month === 4 || month === 6 || month === 9 || month === 11 ? 30 : 31;\n}\n\nfunction invalid(path: string, reason: string): never {\n\tthrow new InvalidIntegrationMessageError(path, reason);\n}\n","/**\n * Stable value address of one aggregate instance.\n *\n * Aggregate ids are type-scoped, so the raw id alone is not globally unique:\n * `SalesOrder 1` and `FulfillmentOrder 1` are different aggregates. Event\n * streams, snapshots, committed-event sources, and projection checkpoints\n * therefore carry both fields instead of defining boundary-specific variants.\n *\n * `aggregateType` is a stable technical stream category. Renaming it changes\n * persistence keys and orphans checkpoints unless the stored addresses are\n * migrated. When bounded contexts share infrastructure and reuse a domain\n * name, qualify it at the source (`sales.order`, `fulfillment.order`). The kit\n * deliberately adds no separate `boundedContext` field: qualification remains\n * the consumer's naming decision.\n */\nexport interface AggregateAddress<TAggregateId extends string = string> {\n\treadonly aggregateType: string;\n\treadonly aggregateId: TAggregateId;\n}\n\n/**\n * Collision-safe map-key encoding shared by the in-memory adapters.\n * Internal: durable adapters key on the two storage columns themselves.\n */\nexport function encodeAggregateAddress(address: AggregateAddress): string {\n\treturn JSON.stringify([address.aggregateType, address.aggregateId]);\n}\n","import {\n\ttype AggregateAddress,\n\tencodeAggregateAddress,\n} from \"../aggregate/aggregate-address\";\nimport type { AnyDomainEvent } from \"../aggregate/domain-event\";\nimport {\n\tEventHarvestError,\n\tInMemoryCapacityExceededError,\n} from \"../core/errors\";\nimport {\n\tassertPositiveInteger,\n\tassertPositiveSafeInteger,\n} from \"../utils/validate\";\nimport type {\n\tDeadLetterRecord,\n\tDispatchTrackingOutbox,\n\tEventCommitCandidate,\n\tEventCommitCandidatePosition,\n\tOutboxRecord,\n\tOutboxWriter,\n} from \"./ports\";\n\n/**\n * An {@link OutboxWriter} that deliberately drops every event: the\n * no-op (noop) writer, named for its consequence rather than its\n * mechanism, so the call site reads as the decision it is.\n *\n * `withCommit` and `UnitOfWork` require an outbox on purpose: the\n * asymmetry against the optional `bus` is the design. The bus is the\n * best-effort in-process fast path (post-commit, no durability), so it\n * may be omitted; the outbox is the delivery GUARANTEE, so running\n * without one is a decision, not a default. This writer is that\n * decision, made readable at the call site.\n *\n * Legitimate uses: aggregates that emit no events (`TEvent = never`,\n * nothing will ever be written), and deliberate best-effort setups\n * where the in-process bus is the only delivery and event loss on a\n * crash between commit and publish is ACCEPTED. Do not reach for an\n * undrained `InMemoryOutbox` instead: its pending map grows unbounded\n * (see the class docs).\n *\n * The name is long on purpose, same discipline as\n * `setStateWithoutVersionBump`: the dangerous variant carries the loud\n * name.\n */\nexport function outboxWriterAcceptingEventLoss<\n\tEvt extends AnyDomainEvent,\n>(): OutboxWriter<Evt> {\n\treturn {\n\t\tadd: async () => {},\n\t};\n}\n\n/** Construction options for {@link InMemoryOutbox}. */\nexport interface InMemoryOutboxOptions {\n\t/** Maximum records retained across pending and dead-letter states. */\n\treadonly maxRecords?: number;\n\n\t/** Maximum qualified aggregate source cursors retained by this instance. */\n\treadonly maxSources?: number;\n\n\t/**\n\t * Failed-delivery ceiling: once `markFailed` has been reported this\n\t * many times for a record, it moves to {@link InMemoryOutbox.deadLetters}\n\t * and stops coming back from `getPending`. Default `5`.\n\t */\n\tmaxDeliveryAttempts?: number;\n\n\t/**\n\t * Maximum recently dispatched event receipts (id, qualified source, and\n\t * candidate commit position) retained for idempotent `add` retries and\n\t * collision detection. Older receipts are evicted in dispatch order; a later\n\t * candidate behind its source head then rejects instead of rewinding the\n\t * cursor.\n\t * Default `10_000`.\n\t */\n\tmaxRetainedDispatchedEventIds?: number;\n}\n\ntype TrackedRecord<Evt extends AnyDomainEvent> = {\n\tdispatchId: string;\n\tevent: Evt;\n\tsource: OutboxRecord<Evt>[\"source\"];\n\tposition: OutboxRecord<Evt>[\"position\"];\n\tattempts: number;\n\tlastError?: string;\n};\n\ntype EventSourceCursor = {\n\taggregateVersion: number;\n\tpreviousEventfulAggregateVersion: number | null;\n\tcommitSize: number;\n\teventIdsBySequence: ReadonlyMap<number, string>;\n};\n\ntype DispatchedEventReceipt = {\n\treadonly source: AggregateAddress;\n\treadonly position: EventCommitCandidatePosition;\n};\n\n/**\n * In-memory reference implementation of `DispatchTrackingOutbox<Evt>`\n * (and therefore of the plain `Outbox<Evt>` port).\n *\n * Intended for finite-lifetime tests and quick-start demos. Without\n * `maxRecords` and `maxSources`, active delivery state and source cursors are\n * unbounded. Long-lived processes must configure both limits or use a durable\n * adapter. Exhaustion rejects the complete `add` batch before mutation;\n * correctness state is never silently evicted.\n * Uses the event's own `eventId` as the dispatch id: the common, clean\n * choice. Active storage is a `Map` keyed by `eventId`, and a bounded\n * recent-dispatch receipt cache keeps retries idempotent after acknowledgement.\n * Re-adding a pending event refreshes the stored commit envelope while the\n * delivery attempt count survives. Its commit sequence and size remain\n * immutable; only this transaction-unaware adapter may move a still-pending\n * event to another aggregate version after an outer rollback leaked the first\n * add. Dead-lettered and acknowledged retries must match the complete original\n * candidate receipt. Reusing an `eventId` for another source or commit position\n * throws {@link EventHarvestError} while the pending, dead-letter, or bounded\n * dispatched receipt still proves the collision. Insertion order is preserved:\n * `getPending` returns records in commit order, as the port contract requires.\n *\n * Dispatch tracking: `markFailed` increments the record's attempt count\n * and, at `maxDeliveryAttempts`, moves it to the dead-letter set\n * exposed by `deadLetters()`. Re-`add`ing a dead-lettered event\n * requeues it with a fresh attempts budget (the operator-facing\n * inverse of `deadLetters()`); `markDispatched` acks pending AND\n * dead-lettered records (manual redelivery then ack).\n * To link future eventful commits, the implementation also retains one\n * source cursor per qualified aggregate after dispatch. Consequently a\n * long-lived instance is bounded only when `maxRecords` and `maxSources` are\n * configured, plus `maxRetainedDispatchedEventIds`; use a durable adapter with\n * an explicit source-head lifecycle and an event-id unique key for unbounded\n * production workloads.\n *\n * For production, back the outbox with a transactional store so the\n * outbox row participates in the same transaction as the aggregate\n * write (see `TransactionScope` + `withCommit`). This class lives in\n * memory only: events are lost on process restart. Do NOT use it as a\n * dummy for bus-only setups without a dispatcher draining it: records\n * that are never `markDispatched` accumulate until `maxRecords` rejects a new\n * add, or without that option grow unbounded. For a deliberate no-delivery\n * setup use {@link outboxWriterAcceptingEventLoss} instead. Sharper still:\n * events `add()`ed inside a transaction that later rolls back are NOT\n * removed (the Map knows nothing about your scope's rollback). Tests\n * that assert rollback purity need an outbox that participates in the\n * test store's transactional semantics; see the reference adapter at\n * https://github.com/shi-rudo/ddd-kit-ts/blob/main/src/testing/repository-contract.test.ts\n * (repo-only, not shipped to npm).\n *\n * @example\n * ```ts\n * import { InMemoryOutbox, EventBusImpl } from \"@shirudo/ddd-kit\";\n *\n * const outbox = new InMemoryOutbox<OrderEvent>();\n * const bus = new EventBusImpl<OrderEvent>();\n *\n * const uow = makeOrderUnitOfWork({ outbox, bus });\n * await uow.run(async ({ repositories }) => {\n * const order = await repositories.orders.getById(id);\n * order.confirm();\n * repositories.orders.update(order);\n * return order.id;\n * });\n * ```\n */\nexport class InMemoryOutbox<Evt extends AnyDomainEvent>\n\timplements DispatchTrackingOutbox<Evt>\n{\n\tprivate readonly pending = new Map<string, TrackedRecord<Evt>>();\n\tprivate readonly dead = new Map<string, DeadLetterRecord<Evt>>();\n\t/** Latest eventful commit and its predecessor per qualified source. */\n\tprivate readonly sourceCursors = new Map<string, EventSourceCursor>();\n\t/** Bounded insertion-ordered receipts for exact retries after acknowledgement. */\n\tprivate readonly dispatchedEventIds = new Map<\n\t\tstring,\n\t\tDispatchedEventReceipt\n\t>();\n\tprivate readonly maxDeliveryAttempts: number;\n\tprivate readonly maxRetainedDispatchedEventIds: number;\n\tprivate readonly maxRecords: number | undefined;\n\tprivate readonly maxSources: number | undefined;\n\n\tconstructor(options?: InMemoryOutboxOptions) {\n\t\tconst max = options?.maxDeliveryAttempts ?? 5;\n\t\tassertPositiveInteger(\"InMemoryOutbox\", \"maxDeliveryAttempts\", max);\n\t\tthis.maxDeliveryAttempts = max;\n\t\tconst retained = options?.maxRetainedDispatchedEventIds ?? 10_000;\n\t\tassertPositiveInteger(\n\t\t\t\"InMemoryOutbox\",\n\t\t\t\"maxRetainedDispatchedEventIds\",\n\t\t\tretained,\n\t\t);\n\t\tthis.maxRetainedDispatchedEventIds = retained;\n\t\tif (options?.maxRecords !== undefined) {\n\t\t\tassertPositiveSafeInteger(\n\t\t\t\t\"InMemoryOutbox\",\n\t\t\t\t\"maxRecords\",\n\t\t\t\toptions.maxRecords,\n\t\t\t);\n\t\t}\n\t\tif (options?.maxSources !== undefined) {\n\t\t\tassertPositiveSafeInteger(\n\t\t\t\t\"InMemoryOutbox\",\n\t\t\t\t\"maxSources\",\n\t\t\t\toptions.maxSources,\n\t\t\t);\n\t\t}\n\t\tthis.maxRecords = options?.maxRecords;\n\t\tthis.maxSources = options?.maxSources;\n\t}\n\n\tasync add(events: ReadonlyArray<EventCommitCandidate<Evt>>): Promise<void> {\n\t\t// Prove identity/receipt and source-position consistency for the whole input\n\t\t// before mutating pending records or source heads. Otherwise a conflict later\n\t\t// in one add() call could reject only after its earlier prefix had leaked.\n\t\tthis.assertBatchEventReceiptIntegrity(events);\n\t\tthis.assertBatchPositionIntegrity(events);\n\t\tthis.assertCapacity(events);\n\t\tfor (const message of events) {\n\t\t\tconst { event, source, position } = message;\n\t\t\tconst dispatchedReceipt = this.dispatchedEventIds.get(event.eventId);\n\t\t\tif (dispatchedReceipt !== undefined) {\n\t\t\t\tassertSameEventSource(event, source, dispatchedReceipt.source);\n\t\t\t\tassertSameCandidateReceipt(\n\t\t\t\t\tevent,\n\t\t\t\t\tposition,\n\t\t\t\t\tdispatchedReceipt.position,\n\t\t\t\t);\n\t\t\t\t// eventId is the outbox idempotency key. Refresh its LRU position\n\t\t\t\t// without recreating a pending record or touching the source head.\n\t\t\t\tthis.rememberDispatched(\n\t\t\t\t\tevent.eventId,\n\t\t\t\t\tdispatchedReceipt.source,\n\t\t\t\t\tdispatchedReceipt.position,\n\t\t\t\t);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst existing = this.pending.get(event.eventId);\n\t\t\tconst deadLetter = this.dead.get(event.eventId);\n\t\t\tif (existing !== undefined) {\n\t\t\t\tassertSameEventSource(event, source, existing.source);\n\t\t\t\t// A pending record may move to another aggregateVersion only because\n\t\t\t\t// this in-memory adapter cannot observe rollback and the same event is\n\t\t\t\t// re-harvested. Its index and commit cardinality remain immutable.\n\t\t\t\tassertSameCandidateReceiptAllowingVersionRefresh(\n\t\t\t\t\tevent,\n\t\t\t\t\tposition,\n\t\t\t\t\texisting.position,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (deadLetter) {\n\t\t\t\tassertSameEventSource(event, source, deadLetter.source);\n\t\t\t\tassertSameCandidateReceipt(event, position, deadLetter.position);\n\t\t\t\t// Requeue the durable record exactly as committed. A dead letter is a\n\t\t\t\t// delivery state, not a new aggregate commit to re-finalize.\n\t\t\t\tthis.dead.delete(event.eventId);\n\t\t\t\tthis.pending.set(event.eventId, {\n\t\t\t\t\tdispatchId: deadLetter.dispatchId,\n\t\t\t\t\tevent: deadLetter.event,\n\t\t\t\t\tsource: deadLetter.source,\n\t\t\t\t\tposition: deadLetter.position,\n\t\t\t\t\tattempts: 0,\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst ownedSource = Object.freeze({ ...source });\n\t\t\tconst sourceKey = encodeAggregateAddress(source);\n\t\t\tconst sourceCursor = this.sourceCursors.get(sourceKey);\n\t\t\tlet staleHeadVersion: number | undefined;\n\t\t\tif (\n\t\t\t\texisting !== undefined &&\n\t\t\t\tposition.aggregateVersion < existing.position.aggregateVersion\n\t\t\t) {\n\t\t\t\tstaleHeadVersion = existing.position.aggregateVersion;\n\t\t\t} else if (\n\t\t\t\texisting === undefined &&\n\t\t\t\tsourceCursor !== undefined &&\n\t\t\t\tposition.aggregateVersion < sourceCursor.aggregateVersion\n\t\t\t) {\n\t\t\t\tstaleHeadVersion = sourceCursor.aggregateVersion;\n\t\t\t}\n\t\t\tif (staleHeadVersion !== undefined) {\n\t\t\t\tthrow staleHeadError(event, source, position, staleHeadVersion);\n\t\t\t}\n\t\t\tif (sourceCursor?.aggregateVersion === position.aggregateVersion) {\n\t\t\t\tif (sourceCursor.commitSize !== position.commitSize) {\n\t\t\t\t\tthrow new EventHarvestError(\n\t\t\t\t\t\t`InMemoryOutbox rejected event \"${event.eventId}\" for ` +\n\t\t\t\t\t\t\t`${source.aggregateType} ${source.aggregateId}: aggregate version ` +\n\t\t\t\t\t\t\t`${position.aggregateVersion} was already recorded with commitSize ` +\n\t\t\t\t\t\t\t`${sourceCursor.commitSize}, not ${position.commitSize}.`,\n\t\t\t\t\t\tevent.type,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst positionOwner = sourceCursor.eventIdsBySequence.get(\n\t\t\t\t\tposition.commitSequence,\n\t\t\t\t);\n\t\t\t\tif (positionOwner !== undefined && positionOwner !== event.eventId) {\n\t\t\t\t\tthrow new EventHarvestError(\n\t\t\t\t\t\t`InMemoryOutbox rejected event \"${event.eventId}\" for ` +\n\t\t\t\t\t\t\t`${source.aggregateType} ${source.aggregateId}: source position ` +\n\t\t\t\t\t\t\t`(${position.aggregateVersion}, ${position.commitSequence}) is ` +\n\t\t\t\t\t\t\t`already owned by event \"${positionOwner}\". One qualified source ` +\n\t\t\t\t\t\t\t\"position must identify exactly one immutable event.\",\n\t\t\t\t\t\tevent.type,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tlet previousEventfulAggregateVersion: number | null;\n\t\t\tconst refreshesLeakedCommit =\n\t\t\t\texisting !== undefined &&\n\t\t\t\texisting.position.aggregateVersion !== position.aggregateVersion;\n\t\t\tif (refreshesLeakedCommit) {\n\t\t\t\t// InMemoryOutbox cannot observe transaction rollback. A pending\n\t\t\t\t// record with the same eventId but a new commit version is therefore\n\t\t\t\t// a replacement for the leaked attempt, not its successor. Preserve\n\t\t\t\t// the event-source predecessor and move the in-memory source head.\n\t\t\t\tpreviousEventfulAggregateVersion =\n\t\t\t\t\texisting.position.previousEventfulAggregateVersion;\n\t\t\t\tif (\n\t\t\t\t\tsourceCursor?.aggregateVersion === existing.position.aggregateVersion\n\t\t\t\t) {\n\t\t\t\t\tthis.sourceCursors.set(sourceKey, {\n\t\t\t\t\t\taggregateVersion: position.aggregateVersion,\n\t\t\t\t\t\tpreviousEventfulAggregateVersion,\n\t\t\t\t\t\tcommitSize: position.commitSize,\n\t\t\t\t\t\teventIdsBySequence: new Map([\n\t\t\t\t\t\t\t[position.commitSequence, event.eventId],\n\t\t\t\t\t\t]),\n\t\t\t\t\t});\n\t\t\t\t} else if (\n\t\t\t\t\tsourceCursor?.aggregateVersion === position.aggregateVersion &&\n\t\t\t\t\t!sourceCursor.eventIdsBySequence.has(position.commitSequence)\n\t\t\t\t) {\n\t\t\t\t\tthis.sourceCursors.set(\n\t\t\t\t\t\tsourceKey,\n\t\t\t\t\t\tcursorWithEvent(\n\t\t\t\t\t\t\tsourceCursor,\n\t\t\t\t\t\t\tposition.commitSequence,\n\t\t\t\t\t\t\tevent.eventId,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else if (existing !== undefined) {\n\t\t\t\tpreviousEventfulAggregateVersion =\n\t\t\t\t\texisting.position.previousEventfulAggregateVersion;\n\t\t\t} else if (sourceCursor?.aggregateVersion === position.aggregateVersion) {\n\t\t\t\tpreviousEventfulAggregateVersion =\n\t\t\t\t\tsourceCursor.previousEventfulAggregateVersion;\n\t\t\t\tif (!sourceCursor.eventIdsBySequence.has(position.commitSequence)) {\n\t\t\t\t\tthis.sourceCursors.set(\n\t\t\t\t\t\tsourceKey,\n\t\t\t\t\t\tcursorWithEvent(\n\t\t\t\t\t\t\tsourceCursor,\n\t\t\t\t\t\t\tposition.commitSequence,\n\t\t\t\t\t\t\tevent.eventId,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tpreviousEventfulAggregateVersion =\n\t\t\t\t\tsourceCursor?.aggregateVersion ?? null;\n\t\t\t\tthis.sourceCursors.set(sourceKey, {\n\t\t\t\t\taggregateVersion: position.aggregateVersion,\n\t\t\t\t\tpreviousEventfulAggregateVersion,\n\t\t\t\t\tcommitSize: position.commitSize,\n\t\t\t\t\teventIdsBySequence: new Map([\n\t\t\t\t\t\t[position.commitSequence, event.eventId],\n\t\t\t\t\t]),\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst ownedPosition = Object.freeze({\n\t\t\t\t...position,\n\t\t\t\tpreviousEventfulAggregateVersion,\n\t\t\t});\n\t\t\tif (existing) {\n\t\t\t\t// Re-add refreshes the stored COPY but keeps the delivery\n\t\t\t\t// bookkeeping: a failed-commit-then-retry re-adds the same\n\t\t\t\t// eventId with a new commit position. Dispatching the stale\n\t\t\t\t// envelope would hand consumers a position from a commit that\n\t\t\t\t// never happened. Attempts belong to delivery, so they survive.\n\t\t\t\texisting.event = event;\n\t\t\t\texisting.source = ownedSource;\n\t\t\t\texisting.position = ownedPosition;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthis.pending.set(event.eventId, {\n\t\t\t\tdispatchId: event.eventId,\n\t\t\t\tevent,\n\t\t\t\tsource: ownedSource,\n\t\t\t\tposition: ownedPosition,\n\t\t\t\tattempts: 0,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate assertCapacity(\n\t\tevents: ReadonlyArray<EventCommitCandidate<Evt>>,\n\t): void {\n\t\tconst newRecordIds = new Set<string>();\n\t\tconst newSourceKeys = new Set<string>();\n\t\tfor (const { event, source } of events) {\n\t\t\tif (\n\t\t\t\tthis.pending.has(event.eventId) ||\n\t\t\t\tthis.dead.has(event.eventId) ||\n\t\t\t\tthis.dispatchedEventIds.has(event.eventId)\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tnewRecordIds.add(event.eventId);\n\t\t\tconst sourceKey = encodeAggregateAddress(source);\n\t\t\tif (!this.sourceCursors.has(sourceKey)) newSourceKeys.add(sourceKey);\n\t\t}\n\n\t\tconst currentRecords = this.pending.size + this.dead.size;\n\t\tif (\n\t\t\tthis.maxRecords !== undefined &&\n\t\t\tcurrentRecords + newRecordIds.size > this.maxRecords\n\t\t) {\n\t\t\tthrow new InMemoryCapacityExceededError({\n\t\t\t\tstore: \"InMemoryOutbox\",\n\t\t\t\tresource: \"records\",\n\t\t\t\tlimit: this.maxRecords,\n\t\t\t\tcurrent: currentRecords,\n\t\t\t\tattempted: newRecordIds.size,\n\t\t\t});\n\t\t}\n\t\tif (\n\t\t\tthis.maxSources !== undefined &&\n\t\t\tthis.sourceCursors.size + newSourceKeys.size > this.maxSources\n\t\t) {\n\t\t\tthrow new InMemoryCapacityExceededError({\n\t\t\t\tstore: \"InMemoryOutbox\",\n\t\t\t\tresource: \"sources\",\n\t\t\t\tlimit: this.maxSources,\n\t\t\t\tcurrent: this.sourceCursors.size,\n\t\t\t\tattempted: newSourceKeys.size,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate assertBatchEventReceiptIntegrity(\n\t\tevents: ReadonlyArray<EventCommitCandidate<Evt>>,\n\t): void {\n\t\tconst receiptsInBatch = new Map<\n\t\t\tstring,\n\t\t\t{\n\t\t\t\treadonly source: AggregateAddress;\n\t\t\t\treadonly position: EventCommitCandidatePosition;\n\t\t\t}\n\t\t>();\n\t\tfor (const { event, source, position } of events) {\n\t\t\tconst batchReceipt = receiptsInBatch.get(event.eventId);\n\t\t\tif (batchReceipt !== undefined) {\n\t\t\t\tassertSameEventSource(event, source, batchReceipt.source);\n\t\t\t\tassertSameCandidateReceipt(\n\t\t\t\t\tevent,\n\t\t\t\t\tposition,\n\t\t\t\t\tbatchReceipt.position,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\treceiptsInBatch.set(event.eventId, { source, position });\n\t\t\t}\n\t\t\tconst dispatchedReceipt = this.dispatchedEventIds.get(event.eventId);\n\t\t\tif (dispatchedReceipt !== undefined) {\n\t\t\t\tassertSameEventSource(event, source, dispatchedReceipt.source);\n\t\t\t\tassertSameCandidateReceipt(\n\t\t\t\t\tevent,\n\t\t\t\t\tposition,\n\t\t\t\t\tdispatchedReceipt.position,\n\t\t\t\t);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst existing = this.pending.get(event.eventId);\n\t\t\tif (existing !== undefined) {\n\t\t\t\tassertSameEventSource(event, source, existing.source);\n\t\t\t\tassertSameCandidateReceiptAllowingVersionRefresh(\n\t\t\t\t\tevent,\n\t\t\t\t\tposition,\n\t\t\t\t\texisting.position,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst deadLetter = this.dead.get(event.eventId);\n\t\t\tif (deadLetter !== undefined) {\n\t\t\t\tassertSameEventSource(event, source, deadLetter.source);\n\t\t\t\tassertSameCandidateReceipt(event, position, deadLetter.position);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate assertBatchPositionIntegrity(\n\t\tevents: ReadonlyArray<EventCommitCandidate<Evt>>,\n\t): void {\n\t\tconst simulatedCursors = new Map<string, EventSourceCursor>();\n\t\tfor (const { event, source, position } of events) {\n\t\t\tconst sourceKey = encodeAggregateAddress(source);\n\t\t\tconst cursor =\n\t\t\t\tsimulatedCursors.get(sourceKey) ?? this.sourceCursors.get(sourceKey);\n\t\t\tif (\n\t\t\t\tcursor === undefined ||\n\t\t\t\tposition.aggregateVersion > cursor.aggregateVersion\n\t\t\t) {\n\t\t\t\tsimulatedCursors.set(sourceKey, {\n\t\t\t\t\taggregateVersion: position.aggregateVersion,\n\t\t\t\t\tpreviousEventfulAggregateVersion: cursor?.aggregateVersion ?? null,\n\t\t\t\t\tcommitSize: position.commitSize,\n\t\t\t\t\teventIdsBySequence: new Map([\n\t\t\t\t\t\t[position.commitSequence, event.eventId],\n\t\t\t\t\t]),\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (position.aggregateVersion < cursor.aggregateVersion) {\n\t\t\t\t// Mirror of the main loop's stale-head rejection. A silent\n\t\t\t\t// `continue` here would break add()'s all-or-nothing promise:\n\t\t\t\t// the main loop would insert every earlier candidate and only\n\t\t\t\t// then throw for this one, leaving a pending event for a\n\t\t\t\t// commit the caller rolled back. Exact retries still dedupe:\n\t\t\t\t// dispatched receipts, dead letters, and a pending record at\n\t\t\t\t// or below the candidate version pass through.\n\t\t\t\tconst dedupes =\n\t\t\t\t\tthis.dispatchedEventIds.has(event.eventId) ||\n\t\t\t\t\tthis.dead.has(event.eventId);\n\t\t\t\tconst pendingRecord = this.pending.get(event.eventId);\n\t\t\t\tconst staleAgainstPending =\n\t\t\t\t\tpendingRecord !== undefined &&\n\t\t\t\t\tposition.aggregateVersion < pendingRecord.position.aggregateVersion;\n\t\t\t\tconst staleAgainstHead = pendingRecord === undefined && !dedupes;\n\t\t\t\tif (staleAgainstPending || staleAgainstHead) {\n\t\t\t\t\tthrow staleHeadError(\n\t\t\t\t\t\tevent,\n\t\t\t\t\t\tsource,\n\t\t\t\t\t\tposition,\n\t\t\t\t\t\tpendingRecord?.position.aggregateVersion ??\n\t\t\t\t\t\t\tcursor.aggregateVersion,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (cursor.commitSize !== position.commitSize) {\n\t\t\t\tthrow new EventHarvestError(\n\t\t\t\t\t`InMemoryOutbox rejected event \"${event.eventId}\" for ` +\n\t\t\t\t\t\t`${source.aggregateType} ${source.aggregateId}: aggregate version ` +\n\t\t\t\t\t\t`${position.aggregateVersion} was already recorded with commitSize ` +\n\t\t\t\t\t\t`${cursor.commitSize}, not ${position.commitSize}.`,\n\t\t\t\t\tevent.type,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst positionOwner = cursor.eventIdsBySequence.get(\n\t\t\t\tposition.commitSequence,\n\t\t\t);\n\t\t\tif (positionOwner !== undefined && positionOwner !== event.eventId) {\n\t\t\t\tthrow new EventHarvestError(\n\t\t\t\t\t`InMemoryOutbox rejected event \"${event.eventId}\" for ` +\n\t\t\t\t\t\t`${source.aggregateType} ${source.aggregateId}: source position ` +\n\t\t\t\t\t\t`(${position.aggregateVersion}, ${position.commitSequence}) is ` +\n\t\t\t\t\t\t`already owned by event \"${positionOwner}\". One qualified source ` +\n\t\t\t\t\t\t\"position must identify exactly one immutable event.\",\n\t\t\t\t\tevent.type,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (positionOwner === undefined) {\n\t\t\t\tsimulatedCursors.set(\n\t\t\t\t\tsourceKey,\n\t\t\t\t\tcursorWithEvent(cursor, position.commitSequence, event.eventId),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync getPending(limit?: number): Promise<ReadonlyArray<OutboxRecord<Evt>>> {\n\t\t// Copies, not the tracked internals: a caller mutating a returned\n\t\t// record must not corrupt the attempt bookkeeping. Map iteration\n\t\t// preserves insertion order, satisfying the port's ordering\n\t\t// contract. Stop at the limit instead of materializing the whole\n\t\t// backlog: a dispatcher polling a large backlog with a small batch\n\t\t// pays O(limit), not O(total pending). The clamp keeps a negative\n\t\t// limit (batchSize - inFlight going negative) at \"nothing\", not\n\t\t// \"everything but the last records\".\n\t\t// NaN (e.g. batchSize - inFlight with an undefined operand) clamps\n\t\t// to zero like the old slice(0, NaN) did, never to \"everything\".\n\t\tconst max =\n\t\t\ttypeof limit === \"number\"\n\t\t\t\t? Math.max(0, Number.isNaN(limit) ? 0 : limit)\n\t\t\t\t: Number.POSITIVE_INFINITY;\n\t\tconst batch: Array<OutboxRecord<Evt>> = [];\n\t\tfor (const record of this.pending.values()) {\n\t\t\tif (batch.length >= max) break;\n\t\t\tbatch.push({\n\t\t\t\tdispatchId: record.dispatchId,\n\t\t\t\tevent: record.event,\n\t\t\t\tsource: record.source,\n\t\t\t\tposition: record.position,\n\t\t\t\tattempts: record.attempts,\n\t\t\t});\n\t\t}\n\t\treturn batch;\n\t}\n\n\tasync markDispatched(dispatchIds: ReadonlyArray<string>): Promise<void> {\n\t\tfor (const id of dispatchIds) {\n\t\t\tconst record = this.pending.get(id) ?? this.dead.get(id);\n\t\t\tif (record !== undefined) {\n\t\t\t\tthis.rememberDispatched(id, record.source, record.position);\n\t\t\t}\n\t\t\tthis.pending.delete(id);\n\t\t\t// Manual redelivery then ack: dispatching a dead-lettered record\n\t\t\t// clears it too.\n\t\t\tthis.dead.delete(id);\n\t\t}\n\t}\n\n\tprivate rememberDispatched(\n\t\teventId: string,\n\t\tsource: AggregateAddress,\n\t\tposition: EventCommitCandidatePosition,\n\t): void {\n\t\tthis.dispatchedEventIds.delete(eventId);\n\t\tthis.dispatchedEventIds.set(eventId, {\n\t\t\tsource: Object.freeze({ ...source }),\n\t\t\tposition: Object.freeze({\n\t\t\t\taggregateVersion: position.aggregateVersion,\n\t\t\t\tcommitSequence: position.commitSequence,\n\t\t\t\tcommitSize: position.commitSize,\n\t\t\t}),\n\t\t});\n\t\twhile (this.dispatchedEventIds.size > this.maxRetainedDispatchedEventIds) {\n\t\t\tconst oldest = this.dispatchedEventIds.keys().next();\n\t\t\tif (oldest.done) break;\n\t\t\tthis.dispatchedEventIds.delete(oldest.value);\n\t\t}\n\t}\n\n\tasync markFailed(\n\t\tdispatchId: string,\n\t\terror?: unknown,\n\t): Promise<DeadLetterRecord<Evt> | undefined> {\n\t\tconst record = this.pending.get(dispatchId);\n\t\t// Unknown or already-dispatched (or already dead-lettered) id: a\n\t\t// late failure report must not resurrect anything.\n\t\tif (!record) return undefined;\n\t\trecord.attempts += 1;\n\t\trecord.lastError =\n\t\t\terror instanceof Error ? error.message : String(error ?? \"unknown\");\n\t\tif (record.attempts >= this.maxDeliveryAttempts) {\n\t\t\tthis.pending.delete(dispatchId);\n\t\t\tconst deadLetter: DeadLetterRecord<Evt> = {\n\t\t\t\tdispatchId: record.dispatchId,\n\t\t\t\tevent: record.event,\n\t\t\t\tsource: record.source,\n\t\t\t\tposition: record.position,\n\t\t\t\tattempts: record.attempts,\n\t\t\t\tlastError: record.lastError,\n\t\t\t};\n\t\t\tthis.dead.set(dispatchId, deadLetter);\n\t\t\treturn { ...deadLetter };\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tasync deadLetters(): Promise<ReadonlyArray<DeadLetterRecord<Evt>>> {\n\t\treturn [...this.dead.values()].map((record) => ({ ...record }));\n\t}\n}\n\nfunction cursorWithEvent(\n\tcursor: EventSourceCursor,\n\tcommitSequence: number,\n\teventId: string,\n): EventSourceCursor {\n\treturn {\n\t\t...cursor,\n\t\teventIdsBySequence: new Map(cursor.eventIdsBySequence).set(\n\t\t\tcommitSequence,\n\t\t\teventId,\n\t\t),\n\t};\n}\n\nfunction assertSameCandidateReceipt(\n\tevent: AnyDomainEvent,\n\treceived: EventCommitCandidatePosition,\n\trecorded: EventCommitCandidatePosition,\n): void {\n\tassertReceiptShape(event, received, recorded, false);\n}\n\n/**\n * The lenient variant for PENDING records only: this in-memory adapter\n * cannot observe rollback, so a re-harvested event may legitimately arrive\n * at a new aggregateVersion. Index and commit cardinality stay immutable.\n */\nfunction assertSameCandidateReceiptAllowingVersionRefresh(\n\tevent: AnyDomainEvent,\n\treceived: EventCommitCandidatePosition,\n\trecorded: EventCommitCandidatePosition,\n): void {\n\tassertReceiptShape(event, received, recorded, true);\n}\n\nfunction assertReceiptShape(\n\tevent: AnyDomainEvent,\n\treceived: EventCommitCandidatePosition,\n\trecorded: EventCommitCandidatePosition,\n\tallowAggregateVersionRefresh: boolean,\n): void {\n\tconst sameVersion =\n\t\tallowAggregateVersionRefresh ||\n\t\treceived.aggregateVersion === recorded.aggregateVersion;\n\tif (\n\t\tsameVersion &&\n\t\treceived.commitSequence === recorded.commitSequence &&\n\t\treceived.commitSize === recorded.commitSize\n\t) {\n\t\treturn;\n\t}\n\tthrow new EventHarvestError(\n\t\t`InMemoryOutbox rejected event \"${event.eventId}\": its commit candidate ` +\n\t\t\t`changed from (${recorded.aggregateVersion}, ${recorded.commitSequence}; ` +\n\t\t\t`commitSize=${recorded.commitSize}) to (${received.aggregateVersion}, ` +\n\t\t\t`${received.commitSequence}; commitSize=${received.commitSize}). ` +\n\t\t\t\"An exact redelivery must keep its source position immutable.\",\n\t\tevent.type,\n\t);\n}\n\nfunction staleHeadError(\n\tevent: { readonly eventId: string; readonly type: string },\n\tsource: AggregateAddress,\n\tposition: EventCommitCandidatePosition,\n\tstaleHeadVersion: number,\n): EventHarvestError {\n\treturn new EventHarvestError(\n\t\t`InMemoryOutbox rejected stale event \"${event.eventId}\" for ` +\n\t\t\t`${source.aggregateType} ${source.aggregateId} at aggregate version ` +\n\t\t\t`${position.aggregateVersion}: the event-source head is already ` +\n\t\t\t`${staleHeadVersion}. The dispatched-id receipt may have ` +\n\t\t\t\"expired; use a durable outbox with a transactional eventId unique key \" +\n\t\t\t\"for unbounded idempotency.\",\n\t\tevent.type,\n\t);\n}\n\nfunction assertSameEventSource(\n\tevent: AnyDomainEvent,\n\treceived: AggregateAddress,\n\trecorded: AggregateAddress,\n): void {\n\tif (\n\t\treceived.aggregateType === recorded.aggregateType &&\n\t\treceived.aggregateId === recorded.aggregateId\n\t) {\n\t\treturn;\n\t}\n\tthrow new EventHarvestError(\n\t\t`InMemoryOutbox rejected eventId collision for \"${event.eventId}\": ` +\n\t\t\t`it already belongs to ${recorded.aggregateType} ${recorded.aggregateId}, ` +\n\t\t\t`but was received for ${received.aggregateType} ${received.aggregateId}. ` +\n\t\t\t\"An eventId must identify one immutable event across all aggregate sources.\",\n\t\tevent.type,\n\t);\n}\n","import type { AnyDomainEvent } from \"../aggregate/domain-event\";\nimport {\n\tassessDeliveryFailure,\n\ttype DeliveryFailureAssessment,\n\ttype DeliveryFailureClassifier,\n} from \"../utils/delivery-failure\";\nimport {\n\tDEFAULT_EXECUTION_TIMEOUT_MS,\n\ttype ExecutionContext,\n\trunBoundedExecution,\n} from \"../utils/execution\";\nimport { captureObserverFunctions, reportToObserver } from \"../utils/observer\";\nimport { PollLoop } from \"../utils/poll-loop\";\nimport { assertNonNegativeFinite } from \"../utils/validate\";\nimport {\n\ttype DeadLetterRecord,\n\ttype DispatchTrackingOutbox,\n\ttype EventBus,\n\tisDispatchTrackingOutbox,\n\ttype Outbox,\n\ttype OutboxRecord,\n} from \"./ports\";\n\n/**\n * Required operational observers for {@link OutboxDispatcher}. All hooks are\n * best-effort notifications: synchronous throws and rejected promises are\n * neutralized so observability cannot change delivery state. The dispatcher\n * captures and freezes these function references at construction, so later\n * mutation of the supplied object cannot disable an operational channel.\n *\n * `onDeadLetter` fires immediately after `markFailed` reports the exact\n * transition. It is not a durable notification boundary: a process can stop\n * after the store commits the transition and before the callback runs. Keep\n * polling {@link DispatchTrackingOutbox.deadLetters} for durable alerting and\n * reconciliation; the hook provides low-latency diagnostics.\n */\nexport interface OutboxDispatcherObservers<Evt extends AnyDomainEvent> {\n\t/**\n\t * A publish, acknowledgement, or failure-tracking operation failed.\n\t * Delivery failures include their accounting assessment. Store failures do\n\t * not; they are operationally distinct from poison-message attempts.\n\t */\n\treadonly onDispatchError: (\n\t\terror: unknown,\n\t\trecord: OutboxRecord<Evt>,\n\t\tassessment?: DeliveryFailureAssessment,\n\t) => void;\n\t/** Reading the pending page failed. */\n\treadonly onPollError: (error: unknown) => void;\n\t/** A tracked record crossed the store's dead-letter threshold. */\n\treadonly onDeadLetter: (record: DeadLetterRecord<Evt>) => void;\n}\n\n/**\n * Delivery target of the {@link OutboxDispatcher}: one driven port with a\n * single question, \"deliver this record's event\". The consumer implements\n * it against the real transport (message broker, webhook, queue\n * producer); {@link eventBusSink} adapts the in-process `EventBus` for\n * setups without a broker.\n *\n * The sink is called once per record, sequentially, in commit order. A\n * throw signals delivery failure; the dispatcher stops the batch,\n * reports the failure, and retries later (see the dispatcher contract).\n * Sinks must tolerate duplicate delivery: the dispatcher is\n * at-least-once by construction (a crash or ack failure between\n * `publish` and `markDispatched` redelivers). Dedupe on\n * `record.event.eventId`; projection sinks use the event's full gap-proof\n * commit cursor.\n *\n * **Resolve only after the transport acknowledged.** The dispatcher\n * calls `markDispatched` as soon as `publish` resolves, so the\n * resolution IS the delivery confirmation: await the broker's ack\n * (Kafka producer confirm, SQS SendMessage response, JetStream publish\n * ack, HTTP 2xx) before returning. A fire-and-forget publish that\n * resolves early marks records dispatched that the broker may never\n * have stored, which silently voids the at-least-once guarantee the\n * outbox exists to provide.\n *\n * Pass `context.signal` into the transport or enforce a native timeout no\n * later than `context.deadlineAt`. The dispatcher bounds its own wait, but it\n * cannot terminate a foreign promise that ignores cancellation; such an\n * adapter can leave zombie I/O overlapping the retry and is not production\n * conforming. The record remains pending unless `publish` had already resolved\n * and its dispatch acknowledgement was persisted.\n */\nexport interface OutboxSink<Evt extends AnyDomainEvent> {\n\tpublish: (\n\t\trecord: OutboxRecord<Evt>,\n\t\tcontext: ExecutionContext,\n\t) => Promise<void>;\n}\n\n/**\n * Adapts the in-process {@link EventBus} as an {@link OutboxSink}: the\n * zero-broker setup where the outbox still provides durability and\n * replay, and subscribers run in-process. Handler errors propagate as\n * delivery failures, so failed events retry through the normal\n * dispatcher loop instead of being lost.\n *\n * **Do not combine with `withCommit`'s `bus` fast path on the same\n * bus.** `withCommit({ scope, outbox, bus })` already publishes every\n * committed event to that bus post-commit, and the outbox record stays\n * pending regardless; a dispatcher with `eventBusSink(bus)` then\n * publishes the same event to the same subscribers a second time, on\n * EVERY commit, by construction. Pick one: omit `bus` from `withCommit`\n * and let the dispatcher deliver (durable, replayable), or keep the\n * fast path and point the dispatcher's sink at a different transport.\n *\n * **Retries are per event, not per handler.** One `publish` fans out to\n * ALL subscribers of the event's type, and the bus reports errors only\n * after every handler ran; the outbox tracks the EVENT, not individual\n * handlers. When one subscriber keeps failing, each retry re-executes\n * its co-subscribers too, up to the attempt ceiling. In-process\n * handlers are therefore consumers in the checklist sense: they must\n * be idempotent (dedupe on `eventId`), or non-idempotent reactions\n * (send mail, charge a card) must not share an event subscription with\n * failure-prone handlers. Per-handler delivery tracking is what broker\n * consumer groups (or per-subscriber checkpoints, see the read-model\n * guide) provide; this sink deliberately does not reimplement it.\n *\n * **Subscribe first, then start the dispatcher.** Publishing to a bus\n * with ZERO subscribers for the event's type resolves as delivered\n * (pub/sub semantics: delivery to all current subscribers, even none),\n * so the dispatcher acks the record and it never comes back. Records\n * polled in a startup window before module wiring registered its\n * subscriptions are therefore consumed without any handler seeing\n * them; register every subscription before `run()`/`drainOnce()`. A\n * `subscribeAll` consumer counts as a subscriber for every type. The\n * same holds for reactions added later: a new subscriber does not see\n * already-dispatched history; replay is a read-model concern, not a\n * bus feature.\n */\nexport function eventBusSink<Evt extends AnyDomainEvent>(\n\tbus: EventBus<Evt>,\n): OutboxSink<Evt> {\n\treturn {\n\t\tpublish: (record, context) =>\n\t\t\tbus.publish([record.event], {\n\t\t\t\tsignal: context.signal,\n\t\t\t\ttimeoutMs: Math.max(0, context.deadlineAt - Date.now()),\n\t\t\t}),\n\t};\n}\n\n/** Construction options for {@link OutboxDispatcher}. */\nexport interface OutboxDispatcherOptions<Evt extends AnyDomainEvent> {\n\t/**\n\t * The poll surface. Pass a {@link DispatchTrackingOutbox} to get\n\t * bounded retries: the dispatcher reports each delivery failure via\n\t * `markFailed`, and the store dead-letters records past its attempt\n\t * ceiling so a poison message stops blocking the queue. With a plain\n\t * {@link Outbox}, a poison message retries forever, rate-limited by\n\t * the backoff ceiling (documented trade-off; prefer the tracking\n\t * port in production).\n\t *\n\t * The tracking capability is detected STRUCTURALLY at runtime\n\t * (`markFailed` and `deadLetters` both present). A wrapper or\n\t * decorator around a tracking outbox must forward both methods;\n\t * one that exposes only the plain `Outbox` surface silently turns\n\t * bounded retries off.\n\t */\n\toutbox: Outbox<Evt> | DispatchTrackingOutbox<Evt>;\n\n\t/** Where events go; see {@link OutboxSink}. */\n\tsink: OutboxSink<Evt>;\n\n\t/**\n\t * Complete, required operational observer bundle. A plain `Outbox` never\n\t * calls `onDeadLetter`, but the complete bundle remains required so changing\n\t * the adapter to a tracking outbox cannot silently omit the alarm path.\n\t */\n\tobservers: OutboxDispatcherObservers<Evt>;\n\n\t/** Records fetched per poll. Default `32`. */\n\tbatchSize?: number;\n\n\t/** Idle sleep between polls when the outbox is empty. Default `250`ms. */\n\tpollIntervalMs?: number;\n\n\t/**\n\t * First backoff delay after a failure; grows exponentially with the\n\t * failing record's attempt count or the dispatcher's own\n\t * consecutive-failure streak (whichever is larger, so the delay grows\n\t * even when the store does not track attempts) and is jittered.\n\t * Default `50`ms.\n\t */\n\tbaseDelayMs?: number;\n\n\t/** Ceiling for the failure backoff. Default `5000`ms. */\n\tmaxDelayMs?: number;\n\n\t/**\n\t * Maximum time to await one sink publication. The sink receives the same\n\t * deadline as an AbortSignal and an absolute `deadlineAt`. Default `30000`ms.\n\t */\n\tdeliveryTimeoutMs?: number;\n\n\t/**\n\t * Maximum time to await one poll-store read, acknowledgement, or failure\n\t * update. The store receives the same cooperative context. This bounds the\n\t * worker's wait; production adapters must also cancel or natively bound the\n\t * underlying I/O. Default `30000`ms.\n\t */\n\tstorageTimeoutMs?: number;\n\n\t/**\n\t * Jitter source for the failure backoff, injectable for deterministic\n\t * tests. Default `Math.random`.\n\t */\n\trandom?: () => number;\n\n\t/**\n\t * Classifies delivery errors as transient, permanent, or unknown. Transient\n\t * failures back off without consuming the poison ceiling; permanent and\n\t * unknown failures count. The default walks the cause chain: native\n\t * `TimeoutError` and `retryable: true` are transient, `retryable: false` is\n\t * permanent, and unmapped errors are unknown. A throwing or invalid custom\n\t * classifier becomes unknown and is exposed through the observer assessment\n\t * without replacing the original delivery error.\n\t */\n\tclassifyFailure?: DeliveryFailureClassifier;\n}\n\n/**\n * Minimal polling dispatcher over the {@link Outbox} poll surface: the\n * delivery half of the transactional outbox for setups that do not plug\n * in an external delivery solution (see the outbox guide, \"External\n * dispatchers\", for that path). Intended for tests, moduliths without a\n * broker, and single-process deployments; it is deliberately a loop\n * over the kit's own port, not a messaging framework.\n *\n * Contract:\n *\n * - **At-least-once.** `markDispatched` runs only AFTER successful\n * `sink.publish` calls (the delivered prefix of a batch is acked in\n * one call); a crash or a failed ack between publish and ack\n * redelivers. Sinks and subscribers dedupe on `eventId` or the\n * full gap-proof commit cursor\n * (`domain-event-design.md`).\n * - **Sequential, stop-on-failure.** Records dispatch one at a time in\n * commit order, and the first failure stops the batch: continuing\n * past a failed event would break the per-aggregate causal order\n * `withCommit` promises subscribers. The price is head-of-line\n * blocking; the escape is the tracking outbox's attempt ceiling,\n * which dead-letters a poison record so the queue flows again.\n * - **Never rejects, always backs off.** Storage errors from\n * `getPending` and `markDispatched` are reported to the observers and\n * absorbed; every failed cycle grows the backoff (per the failing\n * record's attempts or the dispatcher's consecutive-failure streak)\n * toward `maxDelayMs`, so a persistent fault degrades to a slow,\n * observable retry cadence instead of a hot loop or a dead loop.\n * - **Bounded retries only with tracking.** With a\n * {@link DispatchTrackingOutbox}, permanent and unknown delivery failures\n * are reported via `markFailed`; transient failures back off without\n * consuming the poison ceiling. The shared default recognizes native\n * timeouts and `retryable` markers, and consumers can override it through\n * {@link OutboxDispatcherOptions.classifyFailure};\n * the store owns the ceiling and the dead-letter set (wire\n * `deadLetters()` to alerting). An ack failure\n * (`markDispatched` throwing) is NOT reported as a delivery failure:\n * the events were delivered, and counting them toward the poison\n * ceiling would dead-letter healthy records; they surface via\n * `onDispatchError`, once per record of the delivered prefix (every\n * one of them will redeliver), and a persistent ack fault is an\n * operational incident the observer makes visible on every cycle.\n * - **One logical instance per outbox** unless the adapter's\n * `getPending` claims records (see the port contract). The dispatcher\n * itself adds no cross-instance coordination.\n * - **Graceful stop.** `run(signal)` resolves (never rejects) when the\n * signal fires: mid-sleep immediately, mid-batch after the in-flight\n * record settles.\n *\n * For cron triggers and serverless runtimes, use {@link drainOnce} per\n * tick instead of the long-running `run`.\n *\n * @example\n * ```ts\n * const dispatcher = new OutboxDispatcher({\n * outbox,\n * sink,\n * observers: {\n * onDispatchError: (error, record) =>\n * log.warn({ error, eventId: record.event.eventId }, \"dispatch failed\"),\n * onPollError: (error) => log.warn({ error }, \"outbox poll failed\"),\n * onDeadLetter: (record) =>\n * alerts.page({ eventId: record.event.eventId }, \"outbox dead letter\"),\n * },\n * });\n * const stop = new AbortController();\n * void dispatcher.run(stop.signal);\n * // on shutdown:\n * stop.abort();\n * ```\n */\nexport class OutboxDispatcher<Evt extends AnyDomainEvent> extends PollLoop {\n\tprivate readonly outbox: Outbox<Evt> | DispatchTrackingOutbox<Evt>;\n\tprivate readonly sink: OutboxSink<Evt>;\n\tprivate readonly classifyFailure?: DeliveryFailureClassifier;\n\tprivate readonly observers: OutboxDispatcherObservers<Evt>;\n\tprivate readonly deliveryTimeoutMs: number;\n\tprivate readonly storageTimeoutMs: number;\n\n\t/**\n\t * Whether the outbox passed at construction implements the\n\t * dispatch-tracking protocol (`markFailed` AND `deadLetters`), i.e.\n\t * whether bounded retries and dead-lettering are active. Detection\n\t * is structural and happens ONCE, here. Assert this in your wiring\n\t * tests: a decorator that forwards only the plain `Outbox` methods\n\t * silently turns tracking off, and this flag is where that loss\n\t * becomes visible instead of surfacing as an endless poison retry.\n\t */\n\treadonly usesDispatchTracking: boolean;\n\n\t/** The tracking view of the outbox, when it qualifies (see above). */\n\tprivate readonly trackingOutbox?: DispatchTrackingOutbox<Evt>;\n\n\tconstructor(options: OutboxDispatcherOptions<Evt>) {\n\t\tsuper(\"OutboxDispatcher\", options);\n\t\tthis.observers = captureObserverFunctions(\n\t\t\t\"OutboxDispatcher\",\n\t\t\toptions.observers,\n\t\t\t[\"onDispatchError\", \"onPollError\", \"onDeadLetter\"],\n\t\t);\n\t\tthis.outbox = options.outbox;\n\t\tthis.trackingOutbox = isDispatchTrackingOutbox(options.outbox)\n\t\t\t? options.outbox\n\t\t\t: undefined;\n\t\tthis.usesDispatchTracking = this.trackingOutbox !== undefined;\n\t\tthis.sink = options.sink;\n\t\tthis.classifyFailure = options.classifyFailure;\n\t\tthis.deliveryTimeoutMs =\n\t\t\toptions.deliveryTimeoutMs ?? DEFAULT_EXECUTION_TIMEOUT_MS;\n\t\tthis.storageTimeoutMs =\n\t\t\toptions.storageTimeoutMs ?? DEFAULT_EXECUTION_TIMEOUT_MS;\n\t\tassertNonNegativeFinite(\n\t\t\t\"OutboxDispatcher\",\n\t\t\t\"deliveryTimeoutMs\",\n\t\t\tthis.deliveryTimeoutMs,\n\t\t);\n\t\tassertNonNegativeFinite(\n\t\t\t\"OutboxDispatcher\",\n\t\t\t\"storageTimeoutMs\",\n\t\t\tthis.storageTimeoutMs,\n\t\t);\n\t}\n\n\t/**\n\t * One full dispatch pass (the `run`/`drainOnce` shell lives on\n\t * {@link PollLoop}): dispatches pending records batch by batch until\n\t * the backlog is empty or a failure stops progress. A `\"stopped\"`\n\t * pass leaves the failed record pending (or dead-lettered by a\n\t * tracking outbox); the next cycle retries it.\n\t */\n\tprotected async pass(signal?: AbortSignal): Promise<\"drained\" | \"stopped\"> {\n\t\twhile (!signal?.aborted) {\n\t\t\tlet batch: ReadonlyArray<OutboxRecord<Evt>>;\n\t\t\ttry {\n\t\t\t\tbatch = await runBoundedExecution(\n\t\t\t\t\t\"OutboxDispatcher.getPending\",\n\t\t\t\t\t{ signal, timeoutMs: this.storageTimeoutMs },\n\t\t\t\t\t(context) => this.outbox.getPending(this.batchSize, context),\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\tif (signal?.aborted) return \"stopped\";\n\t\t\t\tthis.consecutiveFailures += 1;\n\t\t\t\treportToObserver(() => this.observers.onPollError(error));\n\t\t\t\treturn \"stopped\";\n\t\t\t}\n\t\t\tif (batch.length === 0) {\n\t\t\t\t// An empty backlog is proof of a healthy state: reset the\n\t\t\t\t// failure streak so the next, unrelated failure starts its\n\t\t\t\t// backoff at attempt 1 instead of inheriting an old streak\n\t\t\t\t// (e.g. after the store dead-lettered a poison record).\n\t\t\t\tthis.consecutiveFailures = 0;\n\t\t\t\treturn \"drained\";\n\t\t\t}\n\t\t\tconst completed = await this.dispatchBatch(batch, signal);\n\t\t\tif (!completed) return \"stopped\";\n\t\t}\n\t\treturn \"stopped\";\n\t}\n\n\t/**\n\t * Dispatches one batch sequentially and acks the delivered prefix in\n\t * a single `markDispatched` call. Returns `true` when every record\n\t * was delivered and acked, `false` when the pass stopped early\n\t * (publish failure, ack failure, or abort).\n\t */\n\tprivate async dispatchBatch(\n\t\tbatch: ReadonlyArray<OutboxRecord<Evt>>,\n\t\tsignal?: AbortSignal,\n\t): Promise<boolean> {\n\t\tconst delivered: string[] = [];\n\t\tlet failedRecord: OutboxRecord<Evt> | undefined;\n\t\tlet failure: unknown;\n\t\tfor (const record of batch) {\n\t\t\tif (signal?.aborted) break;\n\t\t\ttry {\n\t\t\t\tawait runBoundedExecution(\n\t\t\t\t\t\"OutboxDispatcher.publish\",\n\t\t\t\t\t{ signal, timeoutMs: this.deliveryTimeoutMs },\n\t\t\t\t\t(context) => this.sink.publish(record, context),\n\t\t\t\t);\n\t\t\t\tdelivered.push(record.dispatchId);\n\t\t\t} catch (error) {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tfailedRecord = record;\n\t\t\t\tfailure = error;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// Ack the delivered prefix in one round-trip, before handling the\n\t\t// failure, so delivered records do not redeliver.\n\t\tlet acked = true;\n\t\tif (delivered.length > 0) {\n\t\t\ttry {\n\t\t\t\t// A broker acknowledgement that won the publish/abort race must still\n\t\t\t\t// get one bounded persistence attempt. If shutdown had already fired\n\t\t\t\t// before this ack starts, the storage timeout owns that short grace\n\t\t\t\t// period; an ack already in flight remains owner-cancellable.\n\t\t\t\tconst acknowledgementSignal = signal?.aborted ? undefined : signal;\n\t\t\t\tawait runBoundedExecution(\n\t\t\t\t\t\"OutboxDispatcher.markDispatched\",\n\t\t\t\t\t{\n\t\t\t\t\t\tsignal: acknowledgementSignal,\n\t\t\t\t\t\ttimeoutMs: this.storageTimeoutMs,\n\t\t\t\t\t},\n\t\t\t\t\t(context) => this.outbox.markDispatched(delivered, context),\n\t\t\t\t);\n\t\t\t\tthis.consecutiveFailures = 0;\n\t\t\t} catch (error) {\n\t\t\t\t// The events WERE delivered; a failed ack means they will\n\t\t\t\t// redeliver (the documented at-least-once duplicates), so it\n\t\t\t\t// must not count toward the poison ceiling. The growing\n\t\t\t\t// consecutive-failure backoff rate-limits the duplicates.\n\t\t\t\t// Every record in the delivered prefix is affected; report\n\t\t\t\t// each one, so the operator can match the coming duplicates\n\t\t\t\t// to this ack failure instead of chasing them individually.\n\t\t\t\tacked = false;\n\t\t\t\tif (!signal?.aborted) {\n\t\t\t\t\tfor (const context of batch.slice(0, delivered.length)) {\n\t\t\t\t\t\treportToObserver(() =>\n\t\t\t\t\t\t\tthis.observers.onDispatchError(error, context),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (failedRecord !== undefined) {\n\t\t\tconst record = failedRecord;\n\t\t\tconst error = failure;\n\t\t\tconst assessment = assessDeliveryFailure(error, this.classifyFailure);\n\t\t\treportToObserver(() =>\n\t\t\t\tthis.observers.onDispatchError(error, record, assessment),\n\t\t\t);\n\t\t\tconst tracking = this.trackingOutbox;\n\t\t\tif (tracking !== undefined && assessment.kind !== \"transient\") {\n\t\t\t\ttry {\n\t\t\t\t\tconst deadLetter = await runBoundedExecution(\n\t\t\t\t\t\t\"OutboxDispatcher.markFailed\",\n\t\t\t\t\t\t{ signal, timeoutMs: this.storageTimeoutMs },\n\t\t\t\t\t\t(context) => tracking.markFailed(record.dispatchId, error, context),\n\t\t\t\t\t);\n\t\t\t\t\tif (deadLetter !== undefined) {\n\t\t\t\t\t\treportToObserver(() => this.observers.onDeadLetter(deadLetter));\n\t\t\t\t\t}\n\t\t\t\t} catch (markError) {\n\t\t\t\t\tif (!signal?.aborted) {\n\t\t\t\t\t\treportToObserver(() =>\n\t\t\t\t\t\t\tthis.observers.onDispatchError(markError, record),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// One streak bump per failed cycle, whatever combination of ack and\n\t\t// publish failures occurred, so the backoff grows exactly one\n\t\t// exponential step per cycle as documented.\n\t\tif (failedRecord !== undefined || !acked) {\n\t\t\tthis.consecutiveFailures = Math.max(\n\t\t\t\tthis.consecutiveFailures + 1,\n\t\t\t\t(failedRecord?.attempts ?? 0) + 1,\n\t\t\t);\n\t\t}\n\t\tif (failedRecord !== undefined) return false;\n\t\tif (!acked) return false;\n\t\t// An abort mid-batch left records unpublished; not a failure, but\n\t\t// not a completed batch either.\n\t\tif (signal?.aborted && delivered.length < batch.length) return false;\n\t\treturn true;\n\t}\n}\n","import type { AggregateAddress } from \"../aggregate/aggregate-address\";\nimport type { AnyDomainEvent } from \"../aggregate/domain-event\";\nimport type { CommitPosition } from \"../events/ports\";\n\n/**\n * A projection's gap-proof cursor into one aggregate's commit chain.\n * `aggregateVersion` plus `commitSequence` orders events; `commitSize`\n * proves the current commit is complete; `previousEventfulAggregateVersion`\n * links the next commit to the eventful predecessor. `withCommit` supplies\n * the current commit facts; the event source finalizes the predecessor on the\n * surrounding `CommittedDomainEvent`.\n *\n * A source MUST map exactly one immutable receipt to each qualified position:\n * one `eventId`, one `commitSize`, and one eventful predecessor. Custom\n * envelopes may translate another store's cursor into these fields, but\n * changing any part of an already observed receipt destroys the proof and is\n * a source-adapter bug.\n */\nexport type ProjectionPosition = CommitPosition;\n\n/**\n * Durable receipt for the last event one projection applied from an aggregate\n * stream. The position answers \"how far?\"; `lastAppliedEventId` identifies the\n * event at exactly that watermark. Together they let the projector distinguish\n * a true watermark redelivery from a source changing the event identity,\n * commit cardinality, or predecessor at the same position. Older positions\n * still rely on the source's immutable-receipt-per-position contract because a\n * checkpoint deliberately retains no full history.\n */\nexport interface ProjectionCheckpoint {\n\treadonly position: ProjectionPosition;\n\treadonly lastAppliedEventId: string;\n}\n\n/**\n * `true` when `candidate` comes strictly after `reference` in the\n * per-aggregate tuple order (higher version, or same version and higher\n * commit sequence). This comparison alone does not prove continuity;\n * the projector checks the boundary fields before advancing.\n */\nexport function isPositionAfter(\n\tcandidate: ProjectionPosition,\n\treference: ProjectionPosition,\n): boolean {\n\tif (candidate.aggregateVersion !== reference.aggregateVersion) {\n\t\treturn candidate.aggregateVersion > reference.aggregateVersion;\n\t}\n\treturn candidate.commitSequence > reference.commitSequence;\n}\n\n/**\n * Driven port for projection checkpoints: the per-`(projection,\n * aggregateType, aggregateId)` watermark receipt that makes a projection\n * idempotent and rebuild-safe. The {@link\n * ProjectionCheckpointStore.withCheckpointLocks} callback and every\n * {@link ProjectionCheckpointStore.load} / {@link\n * ProjectionCheckpointStore.save} it contains run inside the SAME transaction\n * as the read-model update (the `Projector` guarantees the pairing); the store\n * itself is a dumb last-write-wins record, monotonicity is the projector's job.\n *\n * Production adapters put the checkpoint table in the same database\n * as the read model, so update and checkpoint commit atomically: a\n * checkpoint without its update loses events, an update without its\n * checkpoint replays work. Verify an adapter with\n * `createProjectionCheckpointStoreContractTests` from\n * `@shirudo/ddd-kit/testing`.\n *\n * @template TCtx - The transaction context of the ambient\n * `TransactionScope` (a knex trx, a drizzle tx, a pg client)\n */\nexport interface ProjectionCheckpointStore<TCtx = unknown> {\n\t/**\n\t * Runs the complete checkpoint read / read-model update / checkpoint save\n\t * critical section with exclusive access to every supplied\n\t * `(projection, aggregateType, aggregateId)` key.\n\t *\n\t * Exclusivity MUST cover keys for which no checkpoint row exists yet. A\n\t * plain `SELECT ... FOR UPDATE` against the checkpoint table is therefore\n\t * insufficient at genesis: use transaction-scoped advisory/key locks, or\n\t * first materialize durable lock rows and lock those. Acquire multiple keys\n\t * in a deterministic order to avoid deadlocks, and keep database locks until\n\t * the surrounding transaction commits or rolls back. On entry, `work` must\n\t * observe checkpoint commits made by the preceding lock holder; choose the\n\t * transaction isolation level accordingly, or surface and retry a\n\t * serialization conflict instead of applying against a stale snapshot.\n\t *\n\t * Implementations may serialize more than the requested keys, but never\n\t * less. The callback is non-reentrant for an overlapping key set.\n\t */\n\twithCheckpointLocks<R>(\n\t\tctx: TCtx,\n\t\tprojection: string,\n\t\taddresses: ReadonlyArray<AggregateAddress>,\n\t\twork: () => Promise<R>,\n\t): Promise<R>;\n\n\t/**\n\t * The stored watermark receipt for `(projection, address)`, or `undefined`\n\t * when this projection has never applied an event of that\n\t * aggregate. Called inside the projector's transaction.\n\t */\n\tload(\n\t\tctx: TCtx,\n\t\tprojection: string,\n\t\taddress: AggregateAddress,\n\t): Promise<ProjectionCheckpoint | undefined>;\n\n\t/**\n\t * Persists the watermark receipt, overwriting a previous one (last write\n\t * wins; the projector only calls this with advancing checkpoints).\n\t * Called inside the projector's transaction, after the read-model\n\t * update it accounts for.\n\t */\n\tsave(\n\t\tctx: TCtx,\n\t\tprojection: string,\n\t\taddress: AggregateAddress,\n\t\tcheckpoint: ProjectionCheckpoint,\n\t): Promise<void>;\n\n\t/**\n\t * The wait-for-version building block: `true` when the stored\n\t * watermark for `(projection, address)` is at or past\n\t * `position`. Runs OUTSIDE any transaction (a query-side poll).\n\t *\n\t * Pass the position of the LAST event your commit emitted: all\n\t * events of one commit share the `aggregateVersion`, so comparing\n\t * on the version alone would report \"reached\" while later events\n\t * of the same commit are still unapplied.\n\t */\n\thasReached(\n\t\tprojection: string,\n\t\taddress: AggregateAddress,\n\t\tposition: ProjectionPosition,\n\t): Promise<boolean>;\n\n\t/**\n\t * Deletes every checkpoint of `projection` (other projections'\n\t * checkpoints are untouched): the rebuild entry point. Called\n\t * inside the rebuild transaction, together with the projection's\n\t * `truncate`, so a rebuild starts from a consistent zero.\n\t */\n\treset(ctx: TCtx, projection: string): Promise<void>;\n}\n\n/**\n * One projection: the consumer-owned mapping from events to ONE read\n * model (one table/view per projection; run several `Projector`s for\n * several read shapes). The kit owns the mechanics around it\n * (cursor skip, atomic checkpointing, rebuild); the handler owns the\n * read-model writes.\n *\n * The projector feed MUST contain every committed envelope for each aggregate\n * address it carries, including event types this read model does not use.\n * Handle those events as explicit no-ops in `apply`: the projector still\n * advances their cursor. Filtering a broker subscription by event type drops\n * positions from the source chain and turns the next commit into a real gap.\n * For correctness-critical read models, use `projectionFromHandlers` to make\n * every event in the declared union a compile-time handler-or-ignore decision;\n * implement this interface directly when intentionally partial routing is the\n * better fit.\n */\nexport interface Projection<Evt extends AnyDomainEvent, TCtx = unknown> {\n\t/**\n\t * Stable unique name; keys the checkpoints. Renaming it orphans the\n\t * old checkpoints and replays everything under the new name.\n\t */\n\tname: string;\n\n\t/**\n\t * Applies ONE event's read-model change inside the ambient\n\t * transaction. The projector's cursor already filtered duplicates\n\t * and stale events, so plain writes are safe; route on\n\t * `event.type` and handle creates, updates, deletes, corrections,\n\t * and tombstones explicitly (an upsert-only handler silently\n\t * retains stale rows). For a known event type this projection does not use,\n\t * return without writing; that explicit no-op still consumes and checkpoints\n\t * the envelope's source position.\n\t *\n\t * MUST be side-effect-free beyond the read model: no mails, no\n\t * external calls, no commands. A rebuild replays every event; side\n\t * effects would fire again.\n\t */\n\tapply(ctx: TCtx, event: Evt): Promise<void>;\n\n\t/**\n\t * Optional: clears the read model, called by `Projector.reset()`\n\t * in the same transaction as the checkpoint reset, so a rebuild\n\t * never observes a half-cleared state. Without it, truncating the\n\t * read model before a rebuild is the caller's responsibility.\n\t */\n\ttruncate?(ctx: TCtx): Promise<void>;\n}\n","import {\n\ttype AggregateAddress,\n\tencodeAggregateAddress,\n} from \"../aggregate/aggregate-address\";\nimport { InMemoryCapacityExceededError } from \"../core/errors\";\nimport { assertPositiveSafeInteger } from \"../utils/validate\";\nimport {\n\tisPositionAfter,\n\ttype ProjectionCheckpoint,\n\ttype ProjectionCheckpointStore,\n\ttype ProjectionPosition,\n} from \"./ports\";\n\nexport interface InMemoryProjectionCheckpointStoreOptions {\n\t/** Maximum checkpoints across all projection names and aggregate addresses. */\n\treadonly maxCheckpoints?: number;\n}\n\n/**\n * In-memory reference implementation of\n * {@link ProjectionCheckpointStore}: defines the port's semantics and\n * serves tests and in-memory read models.\n *\n * Its checkpoint-key locks serialize competing projectors only inside one\n * process and only when they share this store instance. It is **not\n * transaction-aware** (the `ctx` parameter is ignored): a rolled-back\n * projector batch does not roll back its checkpoints. Use it for tests and\n * disposable in-memory read models; production atomicity is the durable\n * adapter's contract, proved with `createProjectionCheckpointStoreContractTests`\n * and its rollback capability.\n *\n * Without `maxCheckpoints`, checkpoint retention is unbounded and supported\n * only for finite-lifetime tests and demos. A configured limit rejects a new\n * address before mutation; existing watermarks remain updatable and are never\n * evicted because forgetting one would change projection correctness.\n *\n * Do not nest `withCheckpointLocks` calls whose key sets overlap. This\n * reference has no async-context tracking for reentrancy: a nested call waits\n * on the key its caller still holds and therefore neither enters nor fails\n * loudly.\n */\nexport class InMemoryProjectionCheckpointStore\n\timplements ProjectionCheckpointStore<unknown>\n{\n\t/** projection name -> JSON [aggregateType, aggregateId] -> receipt */\n\tprivate readonly checkpoints = new Map<\n\t\tstring,\n\t\tMap<string, ProjectionCheckpoint>\n\t>();\n\t/** Full checkpoint key -> tail of the process-local exclusive-access queue. */\n\tprivate readonly lockTails = new Map<string, Promise<void>>();\n\tprivate readonly maxCheckpoints: number | undefined;\n\tprivate checkpointCount = 0;\n\n\tconstructor(options: InMemoryProjectionCheckpointStoreOptions = {}) {\n\t\tif (options.maxCheckpoints !== undefined) {\n\t\t\tassertPositiveSafeInteger(\n\t\t\t\t\"InMemoryProjectionCheckpointStore\",\n\t\t\t\t\"maxCheckpoints\",\n\t\t\t\toptions.maxCheckpoints,\n\t\t\t);\n\t\t}\n\t\tthis.maxCheckpoints = options.maxCheckpoints;\n\t}\n\n\tasync withCheckpointLocks<R>(\n\t\t_ctx: unknown,\n\t\tprojection: string,\n\t\taddresses: ReadonlyArray<AggregateAddress>,\n\t\twork: () => Promise<R>,\n\t): Promise<R> {\n\t\tconst keys = [\n\t\t\t...new Set(\n\t\t\t\taddresses.map((address) =>\n\t\t\t\t\tJSON.stringify([\n\t\t\t\t\t\tprojection,\n\t\t\t\t\t\taddress.aggregateType,\n\t\t\t\t\t\taddress.aggregateId,\n\t\t\t\t\t]),\n\t\t\t\t),\n\t\t\t),\n\t\t].sort();\n\t\tconst releases: Array<() => void> = [];\n\n\t\tfor (const key of keys) {\n\t\t\tconst previous = this.lockTails.get(key) ?? Promise.resolve();\n\t\t\tlet releaseCurrent!: () => void;\n\t\t\tconst current = new Promise<void>((resolve) => {\n\t\t\t\treleaseCurrent = resolve;\n\t\t\t});\n\t\t\tconst tail = previous.then(() => current);\n\t\t\tthis.lockTails.set(key, tail);\n\t\t\tawait previous;\n\t\t\treleases.push(() => {\n\t\t\t\treleaseCurrent();\n\t\t\t\tif (this.lockTails.get(key) === tail) this.lockTails.delete(key);\n\t\t\t});\n\t\t}\n\n\t\ttry {\n\t\t\treturn await work();\n\t\t} finally {\n\t\t\tfor (let index = releases.length - 1; index >= 0; index -= 1) {\n\t\t\t\treleases[index]?.();\n\t\t\t}\n\t\t}\n\t}\n\n\tasync load(\n\t\t_ctx: unknown,\n\t\tprojection: string,\n\t\taddress: AggregateAddress,\n\t): Promise<ProjectionCheckpoint | undefined> {\n\t\tconst stored = this.checkpoints\n\t\t\t.get(projection)\n\t\t\t?.get(encodeAggregateAddress(address));\n\t\t// Detached copy: a caller mutating the loaded receipt must not\n\t\t// move the stored watermark.\n\t\treturn stored === undefined\n\t\t\t? undefined\n\t\t\t: { ...stored, position: { ...stored.position } };\n\t}\n\n\tasync save(\n\t\t_ctx: unknown,\n\t\tprojection: string,\n\t\taddress: AggregateAddress,\n\t\tcheckpoint: ProjectionCheckpoint,\n\t): Promise<void> {\n\t\tconst addressKey = encodeAggregateAddress(address);\n\t\tlet perAggregate = this.checkpoints.get(projection);\n\t\tconst isNewCheckpoint = perAggregate?.has(addressKey) !== true;\n\t\tif (\n\t\t\tisNewCheckpoint &&\n\t\t\tthis.maxCheckpoints !== undefined &&\n\t\t\tthis.checkpointCount >= this.maxCheckpoints\n\t\t) {\n\t\t\tthrow new InMemoryCapacityExceededError({\n\t\t\t\tstore: \"InMemoryProjectionCheckpointStore\",\n\t\t\t\tresource: \"checkpoints\",\n\t\t\t\tlimit: this.maxCheckpoints,\n\t\t\t\tcurrent: this.checkpointCount,\n\t\t\t\tattempted: 1,\n\t\t\t});\n\t\t}\n\t\tif (perAggregate === undefined) {\n\t\t\tperAggregate = new Map();\n\t\t\tthis.checkpoints.set(projection, perAggregate);\n\t\t}\n\t\tperAggregate.set(addressKey, {\n\t\t\t...checkpoint,\n\t\t\tposition: { ...checkpoint.position },\n\t\t});\n\t\tif (isNewCheckpoint) this.checkpointCount += 1;\n\t}\n\n\tasync hasReached(\n\t\tprojection: string,\n\t\taddress: AggregateAddress,\n\t\tposition: ProjectionPosition,\n\t): Promise<boolean> {\n\t\tconst stored = this.checkpoints\n\t\t\t.get(projection)\n\t\t\t?.get(encodeAggregateAddress(address));\n\t\tif (stored === undefined) return false;\n\t\treturn !isPositionAfter(position, stored.position);\n\t}\n\n\tasync reset(_ctx: unknown, projection: string): Promise<void> {\n\t\tthis.checkpointCount -= this.checkpoints.get(projection)?.size ?? 0;\n\t\tthis.checkpoints.delete(projection);\n\t}\n}\n","import type { AnyDomainEvent } from \"../aggregate/domain-event\";\nimport { MissingHandlerError } from \"../core/errors\";\nimport type { Projection } from \"./ports\";\n\n/**\n * Explicit no-op entry for {@link ProjectionHandlers}. The projector still\n * consumes and checkpoints the event; only the read-model write is skipped.\n */\nexport const ignoreProjectionEvent = Symbol(\"ignoreProjectionEvent\");\n\n/** One discriminator-narrowed projection handler. */\nexport type ProjectionEventHandler<Evt extends AnyDomainEvent, TCtx> = (\n\tctx: TCtx,\n\tevent: Evt,\n) => Promise<void>;\n\n/**\n * Exhaustive handler map for a declared event union. Every discriminator needs\n * either a narrowed handler or {@link ignoreProjectionEvent}; adding an event\n * to `Evt` therefore creates a compile error until the projection decides how\n * to handle it.\n */\nexport type ProjectionHandlers<Evt extends AnyDomainEvent, TCtx> = {\n\treadonly [K in Evt[\"type\"]]:\n\t\t| ProjectionEventHandler<Extract<Evt, { type: K }>, TCtx>\n\t\t| typeof ignoreProjectionEvent;\n};\n\ntype RuntimeProjectionHandlerEntry<TCtx, Evt extends AnyDomainEvent> =\n\t| ProjectionEventHandler<Evt, TCtx>\n\t| typeof ignoreProjectionEvent;\n\n/** Construction options for {@link projectionFromHandlers}. */\nexport interface ProjectionFromHandlersOptions<\n\tEvt extends AnyDomainEvent,\n\tTCtx,\n> {\n\t/** Stable projection name used by its checkpoints. */\n\treadonly name: string;\n\t/** One handler or explicit ignore token for every event in `Evt`. */\n\treadonly handlers: ProjectionHandlers<Evt, TCtx>;\n\t/** Optional read-model reset passed through to {@link Projection.truncate}. */\n\treadonly truncate?: (ctx: TCtx) => Promise<void>;\n}\n\n/**\n * Builds a {@link Projection} from an exhaustive, discriminator-narrowed\n * handler map. This is the correctness-oriented alternative to a free-form\n * `Projection.apply`: extending `Evt` forces every projection using that union\n * to add a handler or an explicit {@link ignoreProjectionEvent} entry.\n *\n * The compile-time proof is only as complete as the supplied `Evt` union.\n * At runtime, an undeclared type (including object-prototype names such as\n * `constructor`) throws {@link MissingHandlerError}; the projector rejects the\n * batch without advancing its checkpoint.\n *\n * @example\n * ```ts\n * const projection = projectionFromHandlers<OrderEvent, DbTx>({\n * name: \"order-list\",\n * handlers: {\n * OrderPlaced: async (tx, event) => {\n * await tx.orders.insert({ id: event.aggregateId });\n * },\n * OrderShipped: ignoreProjectionEvent,\n * },\n * });\n * ```\n */\nexport function projectionFromHandlers<Evt extends AnyDomainEvent, TCtx>(\n\toptions: ProjectionFromHandlersOptions<Evt, TCtx>,\n): Projection<Evt, TCtx> {\n\treturn {\n\t\tname: options.name,\n\t\ttruncate: options.truncate,\n\t\tapply: async (ctx, event) => {\n\t\t\tconst entry = Object.hasOwn(options.handlers, event.type)\n\t\t\t\t? (options.handlers[event.type as Evt[\"type\"]] as\n\t\t\t\t\t\t| RuntimeProjectionHandlerEntry<TCtx, Evt>\n\t\t\t\t\t\t| undefined)\n\t\t\t\t: undefined;\n\t\t\tif (entry === undefined) {\n\t\t\t\tthrow new MissingHandlerError(event.type);\n\t\t\t}\n\t\t\tif (entry === ignoreProjectionEvent) return;\n\t\t\tawait entry(ctx, event);\n\t\t},\n\t};\n}\n","import {\n\ttype AggregateAddress,\n\tencodeAggregateAddress,\n} from \"../aggregate/aggregate-address\";\nimport type { AnyDomainEvent } from \"../aggregate/domain-event\";\nimport {\n\tForeignEventError,\n\tProjectionGapError,\n\tProjectionIdentityViolationError,\n\tProjectionOrderViolationError,\n\tProjectionReceiptViolationError,\n\tUnprojectableEventError,\n} from \"../core/errors\";\nimport type { OutboxSink } from \"../events/outbox-dispatcher\";\nimport type { CommittedDomainEvent } from \"../events/ports\";\nimport type { TransactionScope } from \"../repo/scope\";\nimport { abortReason } from \"../utils/abort\";\nimport {\n\tisPositionAfter,\n\ttype Projection,\n\ttype ProjectionCheckpoint,\n\ttype ProjectionCheckpointStore,\n\ttype ProjectionPosition,\n} from \"./ports\";\n\n/** Construction options for {@link Projector}. */\nexport interface ProjectorOptions<Evt extends AnyDomainEvent, TCtx> {\n\t/**\n\t * The transaction boundary that makes read-model update and\n\t * checkpoint atomic. Wire the SAME scope (same database) the\n\t * read model and the checkpoint table live in.\n\t */\n\tscope: TransactionScope<TCtx>;\n\n\t/** The checkpoint store; see {@link ProjectionCheckpointStore}. */\n\tcheckpoints: ProjectionCheckpointStore<TCtx>;\n\n\t/** The consumer-owned event-to-read-model mapping. */\n\tprojection: Projection<Evt, TCtx>;\n}\n\n/** Controls one atomic projection batch. */\nexport interface ProjectOptions {\n\t/** Cancellation forwarded cooperatively to the projection transaction. */\n\treadonly signal?: AbortSignal;\n}\n\n/** Outcome of one {@link Projector.project} batch. */\nexport interface ProjectionBatchResult {\n\t/** Events applied and checkpointed in this batch. */\n\tapplied: number;\n\t/** Events skipped at positions already traversed under the source contract. */\n\tskipped: number;\n}\n\n/**\n * The projection runner: applies event batches to ONE projection with\n * the mechanics `read-model-design.md` demands, so the consumer's\n * {@link Projection.apply} can be a plain mapping.\n *\n * Contract:\n *\n * - **Update and checkpoint commit atomically.** One batch runs in one\n * `TransactionScope` transaction; each advanced aggregate's watermark\n * is saved once, inside that transaction, after its events applied. A\n * failure anywhere rolls back the WHOLE batch (updates and\n * checkpoints together), so redelivery replays it from the previous\n * watermark. It is never possible to checkpoint an unapplied event or\n * apply an uncheckpointed one, and a retrying scope re-runs the\n * callback from zero (counts included).\n * - **Gaps reject instead of becoming silent skips.** `commitSize`\n * proves every event in a commit was consumed, while\n * `previousEventfulAggregateVersion` links the next eventful commit to the\n * checkpoint. A missing sequence, incomplete commit, missing aggregate\n * commit, or non-genesis first event throws before its event is applied.\n * Because checkpoints advance only across a verified chain, a position\n * at or behind the watermark is already traversed and can be skipped under\n * the source's one-logical-event-per-position contract.\n * - **Feeds are complete per aggregate address.** Once a feed supplies one\n * address, it must supply every committed envelope in that address's cursor\n * chain. Do not event-type-filter a projector subscription. Irrelevant event\n * types are explicit no-ops in `Projection.apply`; invoking the handler and\n * checkpointing their positions preserves continuity.\n * - **The watermark carries an exact receipt.** A different `eventId` at the\n * exact stored watermark, or at one position inside the current batch,\n * throws {@link ProjectionIdentityViolationError} before `apply`. The same\n * ID with a changed commit size or predecessor throws\n * {@link ProjectionReceiptViolationError}. The checkpoint deliberately keeps\n * no full position history, so older skips continue to rely on the source\n * contract rather than claiming a receipt proof it cannot provide.\n * - **Batch inversions reject as transport violations.** Before applying, the\n * projector scans distinct positions that were still unseen at batch start.\n * A descending pair for one aggregate throws\n * {@link ProjectionOrderViolationError}; positions the stored checkpoint had\n * already covered and exact receipts repeated inside the batch remain valid\n * redeliveries.\n * - **Malformed envelopes reject loudly.** A missing/empty `eventId`, a\n * missing/invalid `position`, missing `source.aggregateId` /\n * `source.aggregateType`, or an optional event address contradicting its\n * authoritative envelope source fails the batch BEFORE anything is applied.\n * The domain event remains persistence-agnostic.\n * - **Competing instances serialize by checkpoint key.** The required\n * {@link ProjectionCheckpointStore.withCheckpointLocks} callback covers the\n * complete load / apply / save critical section for every addressed\n * aggregate. The adapter must lock a key even when its checkpoint row does\n * not exist yet; a plain row lock is insufficient at genesis. Without that\n * adapter guarantee, only a hard single-projector deployment is safe.\n *\n * Feeding: hand batches to {@link Projector.project} from any source\n * (an outbox poll, a queue consumer, a replay), or wire the projector\n * straight into an `OutboxDispatcher` via {@link Projector.toOutboxSink}.\n *\n * Rebuild: {@link Projector.reset} clears checkpoints and (when the\n * projection provides `truncate`) the read model in one transaction;\n * then replay the source through `project` again. Rebuild-safety is\n * exactly why {@link Projection.apply} must be side-effect-free.\n */\nexport class Projector<Evt extends AnyDomainEvent, TCtx = unknown> {\n\tprivate readonly scope: TransactionScope<TCtx>;\n\tprivate readonly checkpoints: ProjectionCheckpointStore<TCtx>;\n\tprivate readonly projection: Projection<Evt, TCtx>;\n\n\tconstructor(options: ProjectorOptions<Evt, TCtx>) {\n\t\tthis.scope = options.scope;\n\t\tthis.checkpoints = options.checkpoints;\n\t\tthis.projection = options.projection;\n\t}\n\n\t/**\n\t * Applies one batch: one transaction and one exclusive checkpoint-key\n\t * section, per envelope a cursor check and `apply`, then one checkpoint save\n\t * per advanced aggregate. Rejects\n\t * (after rollback) when a handler throws or an envelope carries no\n\t * valid cursor; the caller's at-least-once redelivery retries the batch.\n\t * The input must be a complete, ordered feed per aggregate address; an\n\t * event-type-filtered subscription cannot satisfy the cursor contract.\n\t * An already-aborted signal rejects before validation or transaction setup.\n\t * In-flight cancellation is forwarded to the transaction scope rather than\n\t * raced, so the adapter remains the authority on rollback and atomicity.\n\t */\n\tasync project(\n\t\tevents: ReadonlyArray<CommittedDomainEvent<Evt>>,\n\t\toptions: ProjectOptions = {},\n\t): Promise<ProjectionBatchResult> {\n\t\tif (options.signal?.aborted) {\n\t\t\tthrow abortReason(\n\t\t\t\toptions.signal,\n\t\t\t\t\"Projector.project aborted before opening a transaction\",\n\t\t\t);\n\t\t}\n\t\t// Validate cursors BEFORE opening the transaction: a malformed\n\t\t// batch must not burn a transaction or apply a prefix.\n\t\tconst cursored = events.map(({ event, source, position }) => {\n\t\t\tif (typeof event.eventId !== \"string\" || event.eventId.length === 0) {\n\t\t\t\tthrow new UnprojectableEventError(\n\t\t\t\t\tthis.projection.name,\n\t\t\t\t\ttypeof event.eventId === \"string\" ? event.eventId : \"<missing>\",\n\t\t\t\t\t\"carries no non-empty eventId. Projection checkpoints retain the \" +\n\t\t\t\t\t\t\"event identity at their watermark, so every projectable event must \" +\n\t\t\t\t\t\t\"have a stable identifier.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (position === undefined) {\n\t\t\t\tthrow new UnprojectableEventError(\n\t\t\t\t\tthis.projection.name,\n\t\t\t\t\tevent.eventId,\n\t\t\t\t\t\"carries no complete projection cursor envelope. Events written \" +\n\t\t\t\t\t\t\"by withCommit are wrapped automatically; other sources must \" +\n\t\t\t\t\t\t\"provide source and position explicitly.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (!isValidPosition(position)) {\n\t\t\t\tthrow new UnprojectableEventError(\n\t\t\t\t\tthis.projection.name,\n\t\t\t\t\tevent.eventId,\n\t\t\t\t\t\"carries an invalid projection cursor: aggregateVersion and \" +\n\t\t\t\t\t\t\"commitSequence must be non-negative integers, commitSize must \" +\n\t\t\t\t\t\t\"be a positive integer greater than commitSequence, and \" +\n\t\t\t\t\t\t\"previousEventfulAggregateVersion must be an earlier non-negative \" +\n\t\t\t\t\t\t\"version or null at genesis.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (source === undefined) {\n\t\t\t\tthrow new UnprojectableEventError(\n\t\t\t\t\tthis.projection.name,\n\t\t\t\t\tevent.eventId,\n\t\t\t\t\t\"carries no aggregateId/aggregateType in its commit envelope source.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst { aggregateId, aggregateType } = source;\n\t\t\tif (!aggregateId || !aggregateType) {\n\t\t\t\tthrow new UnprojectableEventError(\n\t\t\t\t\tthis.projection.name,\n\t\t\t\t\tevent.eventId,\n\t\t\t\t\t\"carries no aggregateId/aggregateType; the checkpoint watermark \" +\n\t\t\t\t\t\t\"is keyed per (aggregateType, aggregateId), because ids are \" +\n\t\t\t\t\t\t\"type-scoped. Events written by withCommit carry both stamps.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst idContradictsSource =\n\t\t\t\tevent.aggregateId !== undefined && event.aggregateId !== aggregateId;\n\t\t\tconst typeContradictsSource =\n\t\t\t\tevent.aggregateType !== undefined &&\n\t\t\t\tevent.aggregateType !== aggregateType;\n\t\t\tif (idContradictsSource || typeContradictsSource) {\n\t\t\t\tthrow new ForeignEventError(\n\t\t\t\t\taggregateId,\n\t\t\t\t\taggregateType,\n\t\t\t\t\tevent.type,\n\t\t\t\t\tevent.aggregateId,\n\t\t\t\t\tevent.aggregateType,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst address: AggregateAddress = { aggregateType, aggregateId };\n\t\t\treturn { event, position, address };\n\t\t});\n\t\tconst lockAddresses = [\n\t\t\t...new Map(\n\t\t\t\tcursored.map(\n\t\t\t\t\t({ address }) => [encodeAggregateAddress(address), address] as const,\n\t\t\t\t),\n\t\t\t).entries(),\n\t\t]\n\t\t\t.sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))\n\t\t\t.map(([, address]) => address);\n\n\t\t// Everything mutable lives INSIDE the transactional callback: a\n\t\t// retrying scope re-runs it from zero, so a rolled-back attempt\n\t\t// can never leak counts or watermarks into the next one.\n\t\tconst projectWithLocks = async (\n\t\t\tctx: TCtx,\n\t\t): Promise<ProjectionBatchResult> => {\n\t\t\tlet applied = 0;\n\t\t\tlet skipped = 0;\n\t\t\t// Load and validate every addressed checkpoint before any handler\n\t\t\t// runs. Legacy/partial rows therefore cannot turn a batch prefix\n\t\t\t// into visible work even under the in-memory passthrough scope.\n\t\t\tconst checkpointsAtBatchStart = new Map<\n\t\t\t\tstring,\n\t\t\t\tProjectionCheckpoint | undefined\n\t\t\t>();\n\t\t\tconst watermarks = new Map<string, ProjectionPosition | undefined>();\n\t\t\tfor (const { event, address } of cursored) {\n\t\t\t\tconst key = encodeAggregateAddress(address);\n\t\t\t\tif (watermarks.has(key)) continue;\n\t\t\t\tconst stored = await this.checkpoints.load(\n\t\t\t\t\tctx,\n\t\t\t\t\tthis.projection.name,\n\t\t\t\t\taddress,\n\t\t\t\t);\n\t\t\t\tif (stored !== undefined && !isValidCheckpoint(stored)) {\n\t\t\t\t\tthrow new UnprojectableEventError(\n\t\t\t\t\t\tthis.projection.name,\n\t\t\t\t\t\tevent.eventId,\n\t\t\t\t\t\t\"found a stored checkpoint with an invalid or legacy cursor. \" +\n\t\t\t\t\t\t\t\"Migrate the commitSize/previousEventfulAggregateVersion/\" +\n\t\t\t\t\t\t\t\"lastAppliedEventId columns or \" +\n\t\t\t\t\t\t\t\"reset and rebuild this projection.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tcheckpointsAtBatchStart.set(key, stored);\n\t\t\t\twatermarks.set(key, stored?.position);\n\t\t\t}\n\n\t\t\t// A checkpoint remembers the complete receipt at exactly its watermark. A\n\t\t\t// different eventId or different commit-boundary metadata at that same\n\t\t\t// ordered position is therefore a provable source collision. Older\n\t\t\t// positions cannot be identity-checked without retaining an unbounded\n\t\t\t// per-position ledger and continue to rely on the source contract that one\n\t\t\t// position names one immutable logical event receipt.\n\t\t\tfor (const { event, position, address } of cursored) {\n\t\t\t\tconst stored = checkpointsAtBatchStart.get(\n\t\t\t\t\tencodeAggregateAddress(address),\n\t\t\t\t);\n\t\t\t\tif (\n\t\t\t\t\tstored !== undefined &&\n\t\t\t\t\tisSameOrderedPosition(position, stored.position)\n\t\t\t\t) {\n\t\t\t\t\tif (event.eventId !== stored.lastAppliedEventId) {\n\t\t\t\t\t\tthrow new ProjectionIdentityViolationError(\n\t\t\t\t\t\t\tthis.projection.name,\n\t\t\t\t\t\t\tevent.eventId,\n\t\t\t\t\t\t\tstored.lastAppliedEventId,\n\t\t\t\t\t\t\tformatPosition(position),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tif (!isSamePositionReceipt(position, stored.position)) {\n\t\t\t\t\t\tthrow new ProjectionReceiptViolationError(\n\t\t\t\t\t\t\tthis.projection.name,\n\t\t\t\t\t\t\tevent.eventId,\n\t\t\t\t\t\t\tformatReceipt(stored.position),\n\t\t\t\t\t\t\tformatReceipt(position),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst batchReceiptsByPosition = new Map<\n\t\t\t\tstring,\n\t\t\t\t{ eventId: string; position: ProjectionPosition }\n\t\t\t>();\n\t\t\tfor (const { event, position, address } of cursored) {\n\t\t\t\tconst key = addressedPositionKey(address, position);\n\t\t\t\tconst recorded = batchReceiptsByPosition.get(key);\n\t\t\t\tif (recorded !== undefined && recorded.eventId !== event.eventId) {\n\t\t\t\t\tthrow new ProjectionIdentityViolationError(\n\t\t\t\t\t\tthis.projection.name,\n\t\t\t\t\t\tevent.eventId,\n\t\t\t\t\t\trecorded.eventId,\n\t\t\t\t\t\tformatPosition(position),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\trecorded !== undefined &&\n\t\t\t\t\t!isSamePositionReceipt(position, recorded.position)\n\t\t\t\t) {\n\t\t\t\t\tthrow new ProjectionReceiptViolationError(\n\t\t\t\t\t\tthis.projection.name,\n\t\t\t\t\t\tevent.eventId,\n\t\t\t\t\t\tformatReceipt(recorded.position),\n\t\t\t\t\t\tformatReceipt(position),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbatchReceiptsByPosition.set(key, {\n\t\t\t\t\teventId: event.eventId,\n\t\t\t\t\tposition,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// A descending pair among DISTINCT positions that were still unseen at\n\t\t\t// batch start is direct evidence of transport reordering. Ignore positions\n\t\t\t// the stored checkpoint had already covered and exact receipts already seen\n\t\t\t// in this batch: those are harmless redeliveries. The preceding collision\n\t\t\t// pass proved that a repeated ordered position has the same eventId and full\n\t\t\t// receipt, so this skip cannot hide conflicting source data.\n\t\t\tconst newestUnprocessed = new Map<string, ProjectionPosition>();\n\t\t\tconst positionsSeenInBatch = new Set<string>();\n\t\t\tfor (const { event, position, address } of cursored) {\n\t\t\t\tconst key = encodeAggregateAddress(address);\n\t\t\t\tconst stored = watermarks.get(key);\n\t\t\t\tif (stored !== undefined && !isPositionAfter(position, stored))\n\t\t\t\t\tcontinue;\n\t\t\t\tconst positionKey = addressedPositionKey(address, position);\n\t\t\t\tif (positionsSeenInBatch.has(positionKey)) continue;\n\t\t\t\tpositionsSeenInBatch.add(positionKey);\n\t\t\t\tconst newest = newestUnprocessed.get(key);\n\t\t\t\tif (newest !== undefined && isPositionAfter(newest, position)) {\n\t\t\t\t\tthrow new ProjectionOrderViolationError(\n\t\t\t\t\t\tthis.projection.name,\n\t\t\t\t\t\tevent.eventId,\n\t\t\t\t\t\tformatPosition(newest),\n\t\t\t\t\t\tformatPosition(position),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (newest === undefined || isPositionAfter(position, newest)) {\n\t\t\t\t\tnewestUnprocessed.set(key, position);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Prove the whole batch's cursor chain before mutating the read\n\t\t\t// model. The simulated watermark also provides intra-batch dedupe\n\t\t\t// without relying on checkpoint-store read-your-writes behavior.\n\t\t\tconst advanced = new Map<\n\t\t\t\tstring,\n\t\t\t\t{ address: AggregateAddress; checkpoint: ProjectionCheckpoint }\n\t\t\t>();\n\t\t\tconst toApply: Array<{ event: Evt }> = [];\n\t\t\tfor (const { event, position, address } of cursored) {\n\t\t\t\tconst key = encodeAggregateAddress(address);\n\t\t\t\tconst watermark = watermarks.get(key);\n\t\t\t\tif (watermark !== undefined && !isPositionAfter(position, watermark)) {\n\t\t\t\t\tskipped += 1;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (!isContiguousPosition(position, watermark)) {\n\t\t\t\t\tthrow new ProjectionGapError(\n\t\t\t\t\t\tthis.projection.name,\n\t\t\t\t\t\tevent.eventId,\n\t\t\t\t\t\tformatPosition(watermark),\n\t\t\t\t\t\tformatPosition(position),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\twatermarks.set(key, position);\n\t\t\t\tadvanced.set(key, {\n\t\t\t\t\taddress,\n\t\t\t\t\tcheckpoint: {\n\t\t\t\t\t\tposition,\n\t\t\t\t\t\tlastAppliedEventId: event.eventId,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\ttoApply.push({ event });\n\t\t\t\tapplied += 1;\n\t\t\t}\n\t\t\tfor (const { event } of toApply) {\n\t\t\t\tawait this.projection.apply(ctx, event);\n\t\t\t}\n\t\t\tfor (const { address, checkpoint } of advanced.values()) {\n\t\t\t\tawait this.checkpoints.save(\n\t\t\t\t\tctx,\n\t\t\t\t\tthis.projection.name,\n\t\t\t\t\taddress,\n\t\t\t\t\tcheckpoint,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn { applied, skipped };\n\t\t};\n\t\treturn this.scope.transactional(\n\t\t\t(ctx) =>\n\t\t\t\tthis.checkpoints.withCheckpointLocks(\n\t\t\t\t\tctx,\n\t\t\t\t\tthis.projection.name,\n\t\t\t\t\tlockAddresses,\n\t\t\t\t\t() => projectWithLocks(ctx),\n\t\t\t\t),\n\t\t\t{ signal: options.signal },\n\t\t);\n\t}\n\n\t/**\n\t * The wait-for-version query: `true` when this projection has\n\t * processed the addressed aggregate at least up to `position`. Pass the\n\t * position of the last event the awaited commit emitted (see\n\t * {@link ProjectionCheckpointStore.hasReached} for why the full\n\t * cursor, not just the version).\n\t */\n\thasProcessed(\n\t\taddress: AggregateAddress,\n\t\tposition: ProjectionPosition,\n\t): Promise<boolean> {\n\t\treturn this.checkpoints.hasReached(this.projection.name, address, position);\n\t}\n\n\t/**\n\t * Rebuild entry point: one transaction that clears this\n\t * projection's checkpoints and, when the projection provides\n\t * `truncate`, the read model with them. Replay the source through\n\t * {@link Projector.project} afterwards. Stop all live consumers for this\n\t * projection before reset and keep them stopped through catch-up replay;\n\t * rebuild is not coordinated by the per-address delivery locks.\n\t */\n\tasync reset(): Promise<void> {\n\t\tawait this.scope.transactional(async (ctx) => {\n\t\t\tawait this.projection.truncate?.(ctx);\n\t\t\tawait this.checkpoints.reset(ctx, this.projection.name);\n\t\t});\n\t}\n\n\t/**\n\t * Adapts this projector as an `OutboxSink`, so an `OutboxDispatcher`\n\t * can feed it directly: each record becomes a single-event batch\n\t * (apply + checkpoint in its own transaction), a throw leaves the\n\t * record pending for the dispatcher's retry/dead-letter mechanics.\n\t * Duplicates the dispatcher redelivers are absorbed by the cursor.\n\t *\n\t * **Dead-lettering a projection event stalls that aggregate chain.**\n\t * A later event cannot advance past the missing commit/sequence: it\n\t * fails with `ProjectionGapError` until the dead letter is repaired\n\t * and replayed (or the projection is reset and rebuilt). No unseen\n\t * event is silently classified as a duplicate.\n\t */\n\ttoOutboxSink(): OutboxSink<Evt> {\n\t\treturn {\n\t\t\tpublish: async (record, context) => {\n\t\t\t\tawait this.project([record], { signal: context.signal });\n\t\t\t},\n\t\t};\n\t}\n}\n\ntype GapAwareProjectionPosition = ProjectionPosition & {\n\tcommitSize: number;\n\tpreviousEventfulAggregateVersion: number | null;\n};\n\nfunction isGapAwarePosition(\n\tposition: ProjectionPosition,\n): position is GapAwareProjectionPosition {\n\treturn (\n\t\tNumber.isInteger(position.commitSize) &&\n\t\tObject.hasOwn(position, \"previousEventfulAggregateVersion\")\n\t);\n}\n\nfunction isValidPosition(\n\tposition: ProjectionPosition,\n): position is GapAwareProjectionPosition {\n\tif (!isGapAwarePosition(position)) return false;\n\tconst previous = position.previousEventfulAggregateVersion;\n\treturn (\n\t\tNumber.isInteger(position.aggregateVersion) &&\n\t\tposition.aggregateVersion >= 0 &&\n\t\tNumber.isInteger(position.commitSequence) &&\n\t\tposition.commitSequence >= 0 &&\n\t\tposition.commitSize > position.commitSequence &&\n\t\t(previous === null ||\n\t\t\t(Number.isInteger(previous) &&\n\t\t\t\tprevious >= 0 &&\n\t\t\t\tprevious < position.aggregateVersion))\n\t);\n}\n\nfunction isValidCheckpoint(\n\tcheckpoint: unknown,\n): checkpoint is ProjectionCheckpoint {\n\tif (typeof checkpoint !== \"object\" || checkpoint === null) return false;\n\tconst candidate = checkpoint as Partial<ProjectionCheckpoint>;\n\treturn (\n\t\ttypeof candidate.lastAppliedEventId === \"string\" &&\n\t\tcandidate.lastAppliedEventId.length > 0 &&\n\t\tcandidate.position !== undefined &&\n\t\tisValidPosition(candidate.position)\n\t);\n}\n\nfunction isSameOrderedPosition(\n\tleft: ProjectionPosition,\n\tright: ProjectionPosition,\n): boolean {\n\treturn (\n\t\tleft.aggregateVersion === right.aggregateVersion &&\n\t\tleft.commitSequence === right.commitSequence\n\t);\n}\n\nfunction isSamePositionReceipt(\n\tleft: ProjectionPosition,\n\tright: ProjectionPosition,\n): boolean {\n\treturn (\n\t\tisSameOrderedPosition(left, right) &&\n\t\tleft.commitSize === right.commitSize &&\n\t\tleft.previousEventfulAggregateVersion ===\n\t\t\tright.previousEventfulAggregateVersion\n\t);\n}\n\nfunction addressedPositionKey(\n\taddress: AggregateAddress,\n\tposition: ProjectionPosition,\n): string {\n\treturn JSON.stringify([\n\t\taddress.aggregateType,\n\t\taddress.aggregateId,\n\t\tposition.aggregateVersion,\n\t\tposition.commitSequence,\n\t]);\n}\n\nfunction isContiguousPosition(\n\tcandidate: GapAwareProjectionPosition,\n\twatermark: ProjectionPosition | undefined,\n): boolean {\n\tif (\n\t\tcandidate.commitSize < 1 ||\n\t\tcandidate.commitSequence < 0 ||\n\t\tcandidate.commitSequence >= candidate.commitSize\n\t) {\n\t\treturn false;\n\t}\n\tif (watermark === undefined) {\n\t\treturn (\n\t\t\tcandidate.commitSequence === 0 &&\n\t\t\tcandidate.previousEventfulAggregateVersion === null\n\t\t);\n\t}\n\tif (!isGapAwarePosition(watermark)) return false;\n\tif (candidate.aggregateVersion === watermark.aggregateVersion) {\n\t\treturn (\n\t\t\tcandidate.previousEventfulAggregateVersion ===\n\t\t\t\twatermark.previousEventfulAggregateVersion &&\n\t\t\tcandidate.commitSize === watermark.commitSize &&\n\t\t\tcandidate.commitSequence === watermark.commitSequence + 1\n\t\t);\n\t}\n\treturn (\n\t\twatermark.commitSequence === watermark.commitSize - 1 &&\n\t\tcandidate.commitSequence === 0 &&\n\t\tcandidate.previousEventfulAggregateVersion === watermark.aggregateVersion\n\t);\n}\n\nfunction formatPosition(position: ProjectionPosition | undefined): string {\n\tif (position === undefined) return \"genesis\";\n\treturn `(${position.aggregateVersion}, ${position.commitSequence})`;\n}\n\nfunction formatReceipt(position: ProjectionPosition): string {\n\treturn (\n\t\t`(${position.aggregateVersion}, ${position.commitSequence}; ` +\n\t\t`commitSize=${position.commitSize}, ` +\n\t\t`previousEventfulAggregateVersion=${String(\n\t\t\tposition.previousEventfulAggregateVersion,\n\t\t)})`\n\t);\n}\n","import {\n\ttype AggregateAddress,\n\tencodeAggregateAddress,\n} from \"../aggregate/aggregate-address\";\nimport type { AnyDomainEvent } from \"../aggregate/domain-event\";\nimport {\n\tConcurrencyConflictError,\n\tInMemoryCapacityExceededError,\n} from \"../core/errors\";\nimport { assertPositiveSafeInteger } from \"../utils/validate\";\nimport type {\n\tEventStore,\n\tEventStoreAppendOptions,\n\tReadStreamOptions,\n\tStreamReadResult,\n} from \"./event-store\";\n\n/** Optional fail-loud capacities for the finite-lifetime reference store. */\nexport interface InMemoryEventStoreOptions {\n\t/** Maximum aggregate streams retained by this instance. */\n\treadonly maxStreams?: number;\n\t/** Maximum events retained across every stream in this instance. */\n\treadonly maxEvents?: number;\n}\n\nfunction assertStreamPosition(\n\tname: \"fromVersion\" | \"toVersion\",\n\tvalue: number | undefined,\n): void {\n\tif (value !== undefined && (!Number.isSafeInteger(value) || value < 0)) {\n\t\tthrow new RangeError(\n\t\t\t`InMemoryEventStore: ${name} must be a non-negative safe integer, got ${String(value)}`,\n\t\t);\n\t}\n}\n\n/**\n * In-memory reference implementation of `EventStore<Evt>`.\n *\n * Intended for finite-lifetime tests and quick-start demos. With no capacity\n * options, streams and events are unbounded for the lifetime of the instance.\n * Long-lived processes must configure `maxStreams` and `maxEvents` or use a\n * durable adapter. Capacity exhaustion rejects before mutation with\n * `InMemoryCapacityExceededError`; histories are never silently evicted.\n * Implements the full port contract: expectedVersion-guarded appends\n * (throwing `ConcurrencyConflictError` on mismatch), atomic rejected\n * appends, explicit missing/existing stream state with the actual head,\n * append-order reads, mandatory page bounds, and `(fromVersion, toVersion]`\n * slicing. Invalid limits or positions reject with `RangeError`.\n *\n * For production, back the port with a durable store whose append and\n * the aggregate transaction share atomicity (a table with a\n * `(aggregate_type, aggregate_id, position)` unique key inside the same\n * transaction, or a dedicated event store). Same caveat as\n * `InMemoryOutbox`: this class\n * lives in memory only and knows nothing about your `TransactionScope`\n * rollbacks; events appended inside a transaction that later rolls back\n * are NOT removed. The event-sourced repository contract suite's\n * reference environment shows the snapshot/restore pattern for\n * rollback-pure in-memory testing.\n */\nexport class InMemoryEventStore<Evt extends AnyDomainEvent>\n\timplements EventStore<Evt>\n{\n\tprivate readonly streams = new Map<string, Evt[]>();\n\tprivate readonly maxStreams: number | undefined;\n\tprivate readonly maxEvents: number | undefined;\n\tprivate totalEvents = 0;\n\n\tconstructor(options: InMemoryEventStoreOptions = {}) {\n\t\tif (options.maxStreams !== undefined) {\n\t\t\tassertPositiveSafeInteger(\n\t\t\t\t\"InMemoryEventStore\",\n\t\t\t\t\"maxStreams\",\n\t\t\t\toptions.maxStreams,\n\t\t\t);\n\t\t}\n\t\tif (options.maxEvents !== undefined) {\n\t\t\tassertPositiveSafeInteger(\n\t\t\t\t\"InMemoryEventStore\",\n\t\t\t\t\"maxEvents\",\n\t\t\t\toptions.maxEvents,\n\t\t\t);\n\t\t}\n\t\tthis.maxStreams = options.maxStreams;\n\t\tthis.maxEvents = options.maxEvents;\n\t}\n\n\tasync append(\n\t\tstream: AggregateAddress,\n\t\tevents: ReadonlyArray<Evt>,\n\t\toptions: EventStoreAppendOptions,\n\t): Promise<void> {\n\t\tif (events.length === 0) return;\n\t\tconst key = encodeAggregateAddress(stream);\n\t\tconst existing = this.streams.get(key);\n\t\tif ((existing?.length ?? 0) !== options.expectedVersion) {\n\t\t\tthrow new ConcurrencyConflictError({\n\t\t\t\taggregateType: stream.aggregateType,\n\t\t\t\taggregateId: stream.aggregateId,\n\t\t\t\texpectedVersion: options.expectedVersion,\n\t\t\t\tactualVersion: existing?.length ?? 0,\n\t\t\t});\n\t\t}\n\t\tif (\n\t\t\texisting === undefined &&\n\t\t\tthis.maxStreams !== undefined &&\n\t\t\tthis.streams.size >= this.maxStreams\n\t\t) {\n\t\t\tthrow new InMemoryCapacityExceededError({\n\t\t\t\tstore: \"InMemoryEventStore\",\n\t\t\t\tresource: \"streams\",\n\t\t\t\tlimit: this.maxStreams,\n\t\t\t\tcurrent: this.streams.size,\n\t\t\t\tattempted: 1,\n\t\t\t});\n\t\t}\n\t\tif (\n\t\t\tthis.maxEvents !== undefined &&\n\t\t\tthis.totalEvents + events.length > this.maxEvents\n\t\t) {\n\t\t\tthrow new InMemoryCapacityExceededError({\n\t\t\t\tstore: \"InMemoryEventStore\",\n\t\t\t\tresource: \"events\",\n\t\t\t\tlimit: this.maxEvents,\n\t\t\t\tcurrent: this.totalEvents,\n\t\t\t\tattempted: events.length,\n\t\t\t});\n\t\t}\n\t\t// Atomic by construction: the conflict check above throws before\n\t\t// anything is written (including the get-or-create, so a rejected\n\t\t// append on a nonexistent stream leaves no empty entry behind).\n\t\t// Pushing in place keeps append O(batch) instead of O(stream) per\n\t\t// call; no caller ever holds the internal array (readStream\n\t\t// slices). Element-wise, not push(...events): a spread into\n\t\t// arguments overflows the engine's argument limit on huge batches.\n\t\tlet storedEvents = existing;\n\t\tif (storedEvents === undefined) {\n\t\t\tstoredEvents = [];\n\t\t\tthis.streams.set(key, storedEvents);\n\t\t}\n\t\tfor (const event of events) {\n\t\t\t// Detached on write and on read: the port forbids handing out\n\t\t\t// live internal state, and a caller-mutated plain event must not\n\t\t\t// rewrite stored history. Kit-minted events are already frozen;\n\t\t\t// the clone detaches them from the shared graph as well.\n\t\t\tstoredEvents.push(structuredClone(event));\n\t\t}\n\t\tthis.totalEvents += events.length;\n\t}\n\n\tasync readStream(\n\t\tstream: AggregateAddress,\n\t\toptions: ReadStreamOptions,\n\t): Promise<StreamReadResult<Evt>> {\n\t\tif (!Number.isSafeInteger(options?.limit) || options.limit < 1) {\n\t\t\tthrow new RangeError(\n\t\t\t\t`InMemoryEventStore: limit must be a positive safe integer, got ${String(options?.limit)}`,\n\t\t\t);\n\t\t}\n\t\tassertStreamPosition(\"fromVersion\", options.fromVersion);\n\t\tassertStreamPosition(\"toVersion\", options.toVersion);\n\t\tconst events = this.streams.get(encodeAggregateAddress(stream));\n\t\tif (events === undefined) {\n\t\t\treturn { exists: false, lastVersion: 0, events: [] };\n\t\t}\n\t\tconst fromVersion = options.fromVersion ?? 0;\n\t\tconst toVersion = options.toVersion;\n\t\tconst pageEnd = Math.min(\n\t\t\ttoVersion ?? events.length,\n\t\t\tfromVersion + options.limit,\n\t\t);\n\t\t// Cloned, not sliced: slice() copies the ARRAY but hands out live\n\t\t// references to the stored elements, and a reader mutating one would\n\t\t// silently corrupt every later replay.\n\t\treturn {\n\t\t\texists: true,\n\t\t\tlastVersion: events.length,\n\t\t\tevents: structuredClone(events.slice(fromVersion, pageEnd)),\n\t\t};\n\t}\n}\n","import type { AggregateSnapshot } from \"../aggregate/aggregate\";\nimport {\n\ttype AggregateAddress,\n\tencodeAggregateAddress,\n} from \"../aggregate/aggregate-address\";\nimport { assertPositiveSafeInteger } from \"../utils/validate\";\nimport type { SnapshotStore } from \"./snapshot-store\";\n\nexport interface InMemorySnapshotStoreOptions {\n\t/** Maximum retained snapshots. The least recently used entry is evicted. */\n\treadonly maxEntries?: number;\n\t/** Snapshot lifetime from the most recent save. Loads do not extend it. */\n\treadonly ttlMs?: number;\n\t/** Store-local clock used only when `ttlMs` is configured. */\n\treadonly clock?: () => Date;\n}\n\ninterface StoredSnapshot<TState> {\n\treadonly snapshot: AggregateSnapshot<TState>;\n\treadonly expiresAtMs?: number;\n}\n\n/**\n * In-memory reference implementation of {@link SnapshotStore}: defines\n * the port's semantics and serves tests and demos. Snapshots are\n * deep-copied on save AND load (`structuredClone`; snapshot state is\n * serialisable data by the `SnapshotModel` contract), so neither the caller\n * nor the store can mutate the other's copy.\n *\n * Unconfigured retention is intended only for finite-lifetime tests and\n * demos. Unlike event history, receipts, or checkpoints, snapshots are\n * rebuildable derived data, so `maxEntries` may evict the least recently used\n * entry and `ttlMs` may expire it safely. A load updates LRU recency but does\n * not extend TTL; only another save does.\n */\nexport class InMemorySnapshotStore<TState = unknown>\n\timplements SnapshotStore<TState>\n{\n\tprivate readonly snapshots = new Map<string, StoredSnapshot<TState>>();\n\tprivate readonly maxEntries: number | undefined;\n\tprivate readonly ttlMs: number | undefined;\n\tprivate readonly clock: () => Date;\n\n\tconstructor(options: InMemorySnapshotStoreOptions = {}) {\n\t\tif (options.maxEntries !== undefined) {\n\t\t\tassertPositiveSafeInteger(\n\t\t\t\t\"InMemorySnapshotStore\",\n\t\t\t\t\"maxEntries\",\n\t\t\t\toptions.maxEntries,\n\t\t\t);\n\t\t}\n\t\tif (options.ttlMs !== undefined) {\n\t\t\tassertPositiveSafeInteger(\n\t\t\t\t\"InMemorySnapshotStore\",\n\t\t\t\t\"ttlMs\",\n\t\t\t\toptions.ttlMs,\n\t\t\t);\n\t\t}\n\t\tthis.maxEntries = options.maxEntries;\n\t\tthis.ttlMs = options.ttlMs;\n\t\tthis.clock = options.clock ?? (() => new Date());\n\t}\n\n\tasync load(\n\t\taddress: AggregateAddress,\n\t): Promise<AggregateSnapshot<TState> | undefined> {\n\t\tconst key = encodeAggregateAddress(address);\n\t\tconst stored = this.snapshots.get(key);\n\t\tif (stored === undefined) return undefined;\n\t\tif (\n\t\t\tstored.expiresAtMs !== undefined &&\n\t\t\tthis.readClock() >= stored.expiresAtMs\n\t\t) {\n\t\t\tthis.snapshots.delete(key);\n\t\t\treturn undefined;\n\t\t}\n\t\t// Map order is the LRU order. A read makes this entry most recent but\n\t\t// deliberately preserves its original expiry.\n\t\tthis.snapshots.delete(key);\n\t\tthis.snapshots.set(key, stored);\n\t\treturn structuredClone(stored.snapshot);\n\t}\n\n\tasync save(\n\t\taddress: AggregateAddress,\n\t\tsnapshot: AggregateSnapshot<TState>,\n\t): Promise<void> {\n\t\t// Clone before changing retention state: an unsupported snapshot value\n\t\t// must not evict a valid entry.\n\t\tconst ownedSnapshot = structuredClone(snapshot);\n\t\tconst key = encodeAggregateAddress(address);\n\t\tlet expiresAtMs: number | undefined;\n\t\tif (this.ttlMs !== undefined) {\n\t\t\tconst nowMs = this.readClock();\n\t\t\tthis.deleteExpired(nowMs);\n\t\t\texpiresAtMs = nowMs + this.ttlMs;\n\t\t}\n\t\tif (this.snapshots.has(key)) {\n\t\t\tthis.snapshots.delete(key);\n\t\t} else if (\n\t\t\tthis.maxEntries !== undefined &&\n\t\t\tthis.snapshots.size >= this.maxEntries\n\t\t) {\n\t\t\tconst oldest = this.snapshots.keys().next();\n\t\t\tif (!oldest.done) this.snapshots.delete(oldest.value);\n\t\t}\n\t\tthis.snapshots.set(key, { snapshot: ownedSnapshot, expiresAtMs });\n\t}\n\n\tasync delete(address: AggregateAddress): Promise<void> {\n\t\tthis.snapshots.delete(encodeAggregateAddress(address));\n\t}\n\n\tprivate readClock(): number {\n\t\tconst now = this.clock();\n\t\tif (!(now instanceof Date) || !Number.isFinite(now.getTime())) {\n\t\t\tthrow new TypeError(\n\t\t\t\t\"InMemorySnapshotStore: clock must return a valid Date\",\n\t\t\t);\n\t\t}\n\t\treturn now.getTime();\n\t}\n\n\tprivate deleteExpired(nowMs: number): void {\n\t\tfor (const [key, stored] of this.snapshots) {\n\t\t\tif (stored.expiresAtMs !== undefined && nowMs >= stored.expiresAtMs) {\n\t\t\t\tthis.snapshots.delete(key);\n\t\t\t}\n\t\t}\n\t}\n}\n","import { someChainRetryable } from \"@shirudo/base-error\";\nimport { abortReason } from \"../utils/abort\";\nimport { computeBackoffDelay, neutralJitterSource } from \"../utils/backoff\";\nimport { reportToObserver } from \"../utils/observer\";\nimport { sleepRejectingOnAbort } from \"../utils/sleep\";\nimport {\n\tassertNonNegativeFinite,\n\tassertPositiveInteger,\n} from \"../utils/validate\";\nimport type { TransactionalOptions, TransactionScope } from \"./scope\";\n\n/**\n * Tuning for {@link RetryingTransactionScope}. All fields are optional;\n * the defaults suit optimistic-concurrency retries (a handful of writers\n * racing one aggregate), not high-fan-out hot-row contention.\n */\nexport interface RetryPolicy {\n\t/** Total tries, including the first. Default `3` (1 initial + 2 retries). */\n\tmaxAttempts?: number;\n\t/** First backoff delay; doubles each retry. Default `50`ms. */\n\tbaseDelayMs?: number;\n\t/** Ceiling for the backoff delay. Default `1000`ms. */\n\tmaxDelayMs?: number;\n\t/**\n\t * Classifier deciding whether an error is worth retrying. Default\n\t * {@link someChainRetryable} (walks the cause chain for the loose\n\t * `retryable === true` marker, so `ConcurrencyConflictError` matches\n\t * even when an adapter wraps it). Override to add driver-specific\n\t * serialization codes (Postgres 40001, MySQL 1213, SQLite SQLITE_BUSY)\n\t * that your adapter has not mapped to a retryable kit error.\n\t *\n\t * Guarded like `onRetry`: a THROWING classifier counts as \"not\n\t * retryable\" and the transaction's ORIGINAL error surfaces, never the\n\t * classifier's own failure.\n\t */\n\tisRetryable?: (error: unknown) => boolean;\n\t/**\n\t * Observer fired before each backoff wait (logging / metrics).\n\t * Neutralised like the `withCommit` observers: a synchronous throw or\n\t * an async rejection is swallowed, so a buggy observer can neither\n\t * abort the retry loop nor mask the original retryable error.\n\t */\n\tonRetry?: (info: {\n\t\tattempt: number;\n\t\terror: unknown;\n\t\tdelayMs: number;\n\t}) => void;\n\t/** Backoff wait. Default an abortable `setTimeout`. Injectable for tests. */\n\tsleep?: (ms: number, signal?: AbortSignal) => Promise<void>;\n\t/** Jitter source in `[0, 1)`. Default `Math.random`. Injectable for tests. */\n\trandom?: () => number;\n}\n\nconst DEFAULT_MAX_ATTEMPTS = 3;\nconst DEFAULT_BASE_DELAY_MS = 50;\nconst DEFAULT_MAX_DELAY_MS = 1000;\n\nconst ABORT_MESSAGE = \"RetryingTransactionScope aborted\";\n\n/** Abortable `setTimeout`; rejects with the signal reason if aborted. */\nfunction defaultSleep(ms: number, signal?: AbortSignal): Promise<void> {\n\treturn sleepRejectingOnAbort(ms, signal, ABORT_MESSAGE);\n}\n\n/**\n * A {@link TransactionScope} that retries its inner scope on transient\n * failures with exponential backoff and jitter. Compose it transparently:\n *\n * ```ts\n * const scope = new RetryingTransactionScope(drizzleScope, { maxAttempts: 5 });\n * const uow = new UnitOfWork({ scope, outbox, repositories });\n * ```\n *\n * **Retries the transaction only.** Each attempt re-invokes the inner\n * `transactional` with a fresh transaction, so the work callback must be\n * reload-safe (load aggregates via `findById` inside it, never capture an\n * aggregate from a previous attempt) and free of non-transactional side\n * effects before commit. `withCommit` publishes AFTER the commit, so the\n * in-process publish is outside the retried region and never duplicated;\n * publish failures are handled by `onPublishError`, not retried here.\n *\n * **Classification is by error, not by guesswork.** Only errors the\n * `isRetryable` predicate accepts are retried; everything else (a\n * `DomainError`, `EventHarvestError`, `UnenrolledChangesError`,\n * `DuplicateAggregateError`, a non-Error throw) surfaces immediately.\n * After `maxAttempts` the last error is rethrown unchanged, so a caller\n * can still match `ConcurrencyConflictError` and map it to HTTP 409.\n *\n * **Cancellation.** The `AbortSignal` from `transactional` options is\n * checked before each attempt and aborts the backoff wait, so an\n * `AbortSignal.timeout(ms)` bounds total elapsed time (there is\n * deliberately no separate max-elapsed knob).\n */\nexport class RetryingTransactionScope<TCtx> implements TransactionScope<TCtx> {\n\t// Policy resolved and validated once at construction (a misconfigured\n\t// policy is a wiring bug and fails fast, never at run time).\n\tprivate readonly maxAttempts: number;\n\tprivate readonly baseDelayMs: number;\n\tprivate readonly maxDelayMs: number;\n\tprivate readonly isRetryable: (error: unknown) => boolean;\n\tprivate readonly sleep: (ms: number, signal?: AbortSignal) => Promise<void>;\n\tprivate readonly random: () => number;\n\tprivate readonly onRetry?: RetryPolicy[\"onRetry\"];\n\n\tconstructor(\n\t\tprivate readonly inner: TransactionScope<TCtx>,\n\t\tpolicy: RetryPolicy = {},\n\t) {\n\t\tthis.maxAttempts = policy.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;\n\t\tthis.baseDelayMs = policy.baseDelayMs ?? DEFAULT_BASE_DELAY_MS;\n\t\tthis.maxDelayMs = policy.maxDelayMs ?? DEFAULT_MAX_DELAY_MS;\n\t\tassertPositiveInteger(\n\t\t\t\"RetryingTransactionScope\",\n\t\t\t\"maxAttempts\",\n\t\t\tthis.maxAttempts,\n\t\t);\n\t\tassertNonNegativeFinite(\n\t\t\t\"RetryingTransactionScope\",\n\t\t\t\"baseDelayMs\",\n\t\t\tthis.baseDelayMs,\n\t\t);\n\t\tassertNonNegativeFinite(\n\t\t\t\"RetryingTransactionScope\",\n\t\t\t\"maxDelayMs\",\n\t\t\tthis.maxDelayMs,\n\t\t);\n\t\tthis.isRetryable = policy.isRetryable ?? someChainRetryable;\n\t\tthis.sleep = policy.sleep ?? defaultSleep;\n\t\t// Wrapped like the poll loop's jitter: an injected source that throws\n\t\t// or returns a non-finite value must not replace the transaction's\n\t\t// original retryable error or eliminate the backoff.\n\t\tthis.random = neutralJitterSource(policy.random ?? Math.random);\n\t\tthis.onRetry = policy.onRetry;\n\t}\n\n\tasync transactional<T>(\n\t\tfn: (ctx: TCtx) => Promise<T>,\n\t\toptions?: TransactionalOptions,\n\t): Promise<T> {\n\t\tconst { maxAttempts, isRetryable, sleep } = this;\n\t\tconst signal = options?.signal;\n\t\tconst isRetryableSafe = (error: unknown): boolean => {\n\t\t\ttry {\n\t\t\t\treturn isRetryable(error);\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t};\n\n\t\tfor (let attempt = 1; attempt <= maxAttempts; attempt++) {\n\t\t\tif (signal?.aborted) {\n\t\t\t\tthrow abortReason(signal, ABORT_MESSAGE);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn await this.inner.transactional(fn, options);\n\t\t\t} catch (error) {\n\t\t\t\t// Exhausted, or a failure retrying cannot fix: surface it\n\t\t\t\t// unchanged so the caller keeps the original error type.\n\t\t\t\t// The classifier itself is guarded like the onRetry observer\n\t\t\t\t// below: a throwing classifier (a custom predicate bug, or\n\t\t\t\t// the default someChainRetryable on a circular cause chain)\n\t\t\t\t// must not replace the transaction's failure, so its throw\n\t\t\t\t// counts as \"not retryable\" and the ORIGINAL error surfaces.\n\t\t\t\tif (attempt === maxAttempts || !isRetryableSafe(error)) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tconst delayMs = computeBackoffDelay(attempt, {\n\t\t\t\t\tbaseDelayMs: this.baseDelayMs,\n\t\t\t\t\tmaxDelayMs: this.maxDelayMs,\n\t\t\t\t\trandom: this.random,\n\t\t\t\t});\n\t\t\t\t// Observer only: a throwing or async-rejecting onRetry must\n\t\t\t\t// neither abort the retry loop nor mask the original error.\n\t\t\t\treportToObserver(() => this.onRetry?.({ attempt, error, delayMs }));\n\t\t\t\t// An abort during the wait rejects out of the loop with the\n\t\t\t\t// signal reason: cancellation wins over another attempt.\n\t\t\t\tawait sleep(delayMs, signal);\n\t\t\t}\n\t\t}\n\t\t// Unreachable: the loop either returns or throws on the last attempt.\n\t\tthrow new Error(\"RetryingTransactionScope: exhausted without result\");\n\t}\n}\n","import type { AggregateSnapshot, Version } from \"../aggregate/aggregate\";\nimport { SnapshotTimeValidationError } from \"../aggregate/domain-event-errors\";\nimport {\n\tisDomainErrorLike,\n\tSnapshotCorruptedError,\n\tSnapshotSchemaMismatchError,\n} from \"../core/errors\";\nimport type { Id } from \"../core/id\";\nimport { isBuiltInObject } from \"../utils/array/is-built-in\";\nimport { assertPositiveSafeInteger } from \"../utils/validate\";\n\ninterface SnapshotAggregate {\n\treadonly id: Id<string>;\n\treadonly version: Version;\n}\n\n/**\n * Adapter-owned mapping between an OO aggregate and its stored snapshot DTO.\n *\n * Snapshot shape, schema migration, envelope construction, and reconstitution\n * are persistence concerns. The aggregate remains responsible for producing a\n * valid domain object; it does not know when or how snapshots are stored.\n */\nexport interface SnapshotModel<\n\tTAggregate extends SnapshotAggregate,\n\tTSnapshotState,\n> {\n\t/** Stable type name used to address schema errors and snapshot storage. */\n\treadonly aggregateType: string;\n\n\t/** Current schema version of the stored snapshot DTO. */\n\treadonly schemaVersion: number;\n\n\t/** Projects the current aggregate into a persistence DTO. */\n\tcapture(aggregate: TAggregate): TSnapshotState;\n\n\t/**\n\t * Reconstitutes a fresh, valid aggregate without recording a new decision.\n\t * This is normally a call to a static aggregate factory.\n\t *\n\t * A snapshot persisted under yesterday's decision rules must keep loading\n\t * after a rule change (\"replay from zero equals snapshot plus tail\"), so\n\t * prefer a factory path that does not re-run current `validateState`\n\t * rules against the stored blob. When the factory does validate and\n\t * throws a `DomainError`, `reconstituteAggregateFromSnapshot` surfaces it\n\t * as a {@link SnapshotCorruptedError} so the documented load recipe can\n\t * discard the derived snapshot and refold from the stream; the load then\n\t * still succeeds, at the cost of a full replay on every hit.\n\t */\n\treconstitute(\n\t\tid: TAggregate[\"id\"],\n\t\tstate: TSnapshotState,\n\t\tversion: Version,\n\t): TAggregate;\n\n\t/** Upgrades an older stored DTO into the model's current DTO shape. */\n\treadonly migrate?: (\n\t\tstored: unknown,\n\t\tstoredSchemaVersion: number,\n\t) => TSnapshotState;\n}\n\n/** Type-inference helper for declaring an adapter-owned snapshot model. */\nexport function defineSnapshotModel<\n\tTAggregate extends SnapshotAggregate,\n\tTSnapshotState,\n>(\n\tmodel: SnapshotModel<TAggregate, TSnapshotState>,\n): SnapshotModel<TAggregate, TSnapshotState> {\n\t// Validated AFTER the spread, on what actually survives it: the spread\n\t// copies own enumerable properties only, so capture/reconstitute carried\n\t// on a prototype (class instance) vanish silently and would surface much\n\t// later as a raw TypeError outside the corruption channel.\n\tconst detached = Object.freeze({ ...model });\n\tassertSnapshotModel(detached);\n\treturn detached;\n}\n\n/**\n * Captures a detached persistence envelope at an application-supplied time.\n * The application decides when snapshotting is worthwhile; this function does\n * not read a clock or perform I/O.\n */\nexport function captureAggregateSnapshot<\n\tTAggregate extends SnapshotAggregate,\n\tTSnapshotState,\n>(\n\tmodel: SnapshotModel<TAggregate, TSnapshotState>,\n\taggregate: TAggregate,\n\tsnapshotAt: Date,\n): AggregateSnapshot<TSnapshotState> {\n\tassertSnapshotModel(model);\n\tconst recordedAt = copySnapshotAt(snapshotAt);\n\tconst state = detachSnapshotState(model.capture(aggregate));\n\treturn Object.freeze({\n\t\tstate,\n\t\tversion: aggregate.version,\n\t\tsnapshotAt: recordedAt,\n\t\tschemaVersion: model.schemaVersion,\n\t});\n}\n\n/**\n * Reconstitutes a fresh aggregate from a stored snapshot through the owning\n * adapter model. A missing schema version denotes the original schema `1`.\n *\n * A `DomainError` thrown while interpreting the stored blob (the model's\n * `migrate`, or current `validateState` rules running inside the model's\n * reconstitution factory) is surfaced as a {@link SnapshotCorruptedError}:\n * a snapshot is DERIVED data, so the caller's discard-and-refold branch must\n * see one catchable corruption channel instead of a raw domain rejection\n * escaping `getById` after a rule change. `SnapshotSchemaMismatchError`\n * (a configuration gap, not corruption) and non-domain throws propagate.\n */\nexport function reconstituteAggregateFromSnapshot<\n\tTAggregate extends SnapshotAggregate,\n\tTSnapshotState,\n>(\n\tmodel: SnapshotModel<TAggregate, TSnapshotState>,\n\tid: TAggregate[\"id\"],\n\tsnapshot: AggregateSnapshot<unknown>,\n): TAggregate {\n\tassertSnapshotModel(model);\n\tconst storedSchemaVersion = snapshot.schemaVersion ?? 1;\n\tlet aggregate: TAggregate;\n\ttry {\n\t\tlet state: TSnapshotState;\n\t\tif (storedSchemaVersion === model.schemaVersion) {\n\t\t\tstate = detachSnapshotState(snapshot.state) as TSnapshotState;\n\t\t} else if (model.migrate) {\n\t\t\tstate = detachSnapshotState(\n\t\t\t\tmodel.migrate(detachSnapshotState(snapshot.state), storedSchemaVersion),\n\t\t\t);\n\t\t} else {\n\t\t\tthrow new SnapshotSchemaMismatchError({\n\t\t\t\taggregateType: model.aggregateType,\n\t\t\t\taggregateId: String(id),\n\t\t\t\texpectedSchemaVersion: model.schemaVersion,\n\t\t\t\tactualSchemaVersion: storedSchemaVersion,\n\t\t\t});\n\t\t}\n\t\taggregate = model.reconstitute(id, state, snapshot.version);\n\t} catch (error) {\n\t\t// Copy-safe: the model factory may run in another loaded copy of the\n\t\t// kit (adapter package, dual CJS/ESM load), whose DomainError fails a\n\t\t// plain instanceof; the corruption channel must catch it regardless.\n\t\tif (isDomainErrorLike(error)) {\n\t\t\tthrow new SnapshotCorruptedError(\n\t\t\t\t`Snapshot of ${model.aggregateType} ${String(id)} (schema ` +\n\t\t\t\t\t`${storedSchemaVersion}, version ${String(snapshot.version)}) was ` +\n\t\t\t\t\t\"rejected during reconstitution. Discard the derived snapshot and \" +\n\t\t\t\t\t\"refold from the stream.\",\n\t\t\t\terror,\n\t\t\t);\n\t\t}\n\t\tthrow error;\n\t}\n\t// Post-condition, not corruption: a factory that ignores the version\n\t// parameter (a forgotten markRestored) is a deterministic model wiring\n\t// bug. Routing it into the discard-and-refold channel would mask it as\n\t// perpetual silent refolding, so it throws raw instead.\n\tif (aggregate.version !== snapshot.version) {\n\t\tthrow new TypeError(\n\t\t\t`SnapshotModel.reconstitute for ${model.aggregateType} ${String(id)} ` +\n\t\t\t\t`returned an aggregate at version ${String(aggregate.version)} for a ` +\n\t\t\t\t`snapshot at version ${String(snapshot.version)}. Reconstitution must ` +\n\t\t\t\t\"restore the persisted version; call markRestored(version) inside \" +\n\t\t\t\t\"the aggregate factory.\",\n\t\t);\n\t}\n\treturn aggregate;\n}\n\nfunction assertSnapshotModel(model: {\n\treadonly aggregateType: string;\n\treadonly schemaVersion: number;\n\treadonly capture: unknown;\n\treadonly reconstitute: unknown;\n\treadonly migrate?: unknown;\n}): void {\n\tif (\n\t\ttypeof model.aggregateType !== \"string\" ||\n\t\tmodel.aggregateType.trim().length === 0\n\t) {\n\t\tthrow new TypeError(\n\t\t\t\"SnapshotModel.aggregateType must be a non-empty string\",\n\t\t);\n\t}\n\tassertPositiveSafeInteger(\"SnapshotModel\", \"schemaVersion\", model.schemaVersion);\n\tfor (const key of [\"capture\", \"reconstitute\"] as const) {\n\t\tif (typeof model[key] !== \"function\") {\n\t\t\tthrow new TypeError(\n\t\t\t\t`SnapshotModel.${key} is missing or not a function. ` +\n\t\t\t\t\t\"defineSnapshotModel copies own enumerable properties only; \" +\n\t\t\t\t\t\"prototype methods are not carried. Pass a plain object literal.\",\n\t\t\t);\n\t\t}\n\t}\n\tif (model.migrate !== undefined && typeof model.migrate !== \"function\") {\n\t\tthrow new TypeError(\"SnapshotModel.migrate must be a function when set\");\n\t}\n}\n\nfunction copySnapshotAt(snapshotAt: Date): Date {\n\tif (!(snapshotAt instanceof Date) || !Number.isFinite(snapshotAt.getTime())) {\n\t\tthrow new SnapshotTimeValidationError();\n\t}\n\treturn new Date(snapshotAt.getTime());\n}\n\nfunction detachSnapshotState<T>(state: T): T {\n\tassertSnapshotSafe(state, \"\", new WeakSet());\n\treturn structuredClone(state);\n}\n\n/**\n * Rejects graphs that structured cloning would lose or silently degrade.\n * Snapshot models map class-based domain state to plain persistence DTOs.\n */\nfunction assertSnapshotSafe(\n\tvalue: unknown,\n\tpath: string,\n\tseen: WeakSet<object>,\n): void {\n\tif (typeof value === \"function\") {\n\t\tthrow new TypeError(\n\t\t\t`snapshot state${path} is a function; map it to serialisable data in the snapshot model`,\n\t\t);\n\t}\n\t// Guided rejection instead of the raw DataCloneError DOMException that\n\t// structuredClone throws for symbols, which no recovery channel catches.\n\tif (typeof value === \"symbol\") {\n\t\tthrow new TypeError(\n\t\t\t`snapshot state${path} is a symbol; map it to serialisable data in the snapshot model`,\n\t\t);\n\t}\n\tif (value === null || typeof value !== \"object\") return;\n\tconst object = value as object;\n\tif (seen.has(object)) return;\n\tseen.add(object);\n\n\tif (Array.isArray(object)) {\n\t\tfor (let index = 0; index < object.length; index++) {\n\t\t\tassertSnapshotSafe(object[index], `${path}[${index}]`, seen);\n\t\t}\n\t\treturn;\n\t}\n\n\tconst tag = Object.prototype.toString.call(object);\n\tif (isBuiltInObject(object, tag)) {\n\t\tif (tag === \"[object Map]\") {\n\t\t\tlet index = 0;\n\t\t\tfor (const [key, entry] of object as Map<unknown, unknown>) {\n\t\t\t\tassertSnapshotSafe(key, `${path}<map key #${index}>`, seen);\n\t\t\t\tassertSnapshotSafe(entry, `${path}<map value #${index}>`, seen);\n\t\t\t\tindex++;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (tag === \"[object Set]\") {\n\t\t\tlet index = 0;\n\t\t\tfor (const member of object as Set<unknown>) {\n\t\t\t\tassertSnapshotSafe(member, `${path}<set member #${index}>`, seen);\n\t\t\t\tindex++;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (\n\t\t\ttag === \"[object Promise]\" ||\n\t\t\ttag === \"[object WeakMap]\" ||\n\t\t\ttag === \"[object WeakSet]\"\n\t\t) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`snapshot state${path} is a ${tag.slice(8, -1)} and cannot be persisted`,\n\t\t\t);\n\t\t}\n\t\tif (tag === \"[object Error]\") {\n\t\t\tthrow new TypeError(\n\t\t\t\t`snapshot state${path} is an Error; map it to plain data in the snapshot model`,\n\t\t\t);\n\t\t}\n\t\treturn;\n\t}\n\n\tconst prototype = Object.getPrototypeOf(object);\n\tif (prototype === Object.prototype || prototype === null) {\n\t\tfor (const key of Reflect.ownKeys(object)) {\n\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(object, key);\n\t\t\tif (!descriptor?.enumerable) continue;\n\t\t\tif (typeof key === \"symbol\") {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t`snapshot state${path} has a symbol-keyed property; map it to plain data in the snapshot model`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tassertSnapshotSafe(\n\t\t\t\t(object as Record<PropertyKey, unknown>)[key],\n\t\t\t\t`${path}.${key}`,\n\t\t\t\tseen,\n\t\t\t);\n\t\t}\n\t\treturn;\n\t}\n\n\tconst name: string = prototype.constructor?.name || \"anonymous class\";\n\tthrow new TypeError(\n\t\t`snapshot state${path} is a class instance (${name}); map it to plain data in the snapshot model`,\n\t);\n}\n","/**\n * The composite structure of a combinator-built specification, exposed\n * for adapters that translate specifications into storage queries. An\n * adapter walks `composite` recursively down to the named leaves and\n * translates each one. This is deliberately not an expression tree:\n * predicates stay opaque functions, and only the boolean structure and\n * the leaf names are visible from outside.\n */\nexport type SpecificationComposite<T> =\n\t| {\n\t\t\treadonly operator: \"and\";\n\t\t\treadonly left: Specification<T>;\n\t\t\treadonly right: Specification<T>;\n\t }\n\t| {\n\t\t\treadonly operator: \"or\";\n\t\t\treadonly left: Specification<T>;\n\t\t\treadonly right: Specification<T>;\n\t }\n\t| { readonly operator: \"not\"; readonly inner: Specification<T> };\n\n/**\n * Specification: a named, executable domain criterion (Evans/Fowler).\n * \"Which candidates qualify?\" becomes an object in the ubiquitous\n * language instead of an inline predicate or a leaked query builder:\n * `overdueInvoices.and(highValue.not())` reads like the business rule\n * it encodes, evaluates in memory via {@link isSatisfiedBy}, and can be\n * translated by a repository adapter into its storage's query language.\n *\n * The same object serves three places. Domain logic calls\n * `spec.isSatisfiedBy(candidate)` directly. An in-memory repository or\n * test fake implements its lookup as a plain filter,\n * `rows.filter((r) => spec.isSatisfiedBy(r))`, with no translation\n * layer. And a storage adapter translates leaf specifications\n * explicitly (matching on {@link name}, or narrowing to the class for\n * parameterized leaves) while recursing through {@link composite} for\n * combinator nodes; the repository guide walks through it. The kit\n * ships this convention and deliberately no translation machinery:\n * no expression trees, no LINQ-style providers.\n *\n * The class is deliberately left open: the combinators can be\n * overridden and `composite` can be set by subclasses. That is what\n * makes a classic visitor/double-dispatch layer buildable on top,\n * for consumers who want the compiler to enforce translation\n * completeness across several targets; the repository guide's\n * \"A visitor layer on top\" section shows the full construction.\n *\n * Take the name from the ubiquitous language. It is what an adapter\n * matches on, what diagnostics print, and what ties the object back to\n * the rule as the domain expert stated it. If no expert would\n * recognize the name, what you have is a code predicate, not a\n * specification.\n *\n * Subclass for parameterized specifications, or use the\n * {@link specification} factory for flat ones:\n *\n * @example\n * ```typescript\n * class OverdueInvoice extends Specification<Invoice> {\n * readonly name = \"overdue invoice\";\n * constructor(private readonly today: Date) { super(); }\n * isSatisfiedBy(invoice: Invoice): boolean {\n * return invoice.dueDate < this.today && invoice.status === \"open\";\n * }\n * }\n *\n * const dunningCandidates = new OverdueInvoice(today)\n * .and(specification(\"in dunning grace period\", (i: Invoice) =>\n * i.remindersSent < 3,\n * ));\n * ```\n */\nexport abstract class Specification<T> {\n\t/**\n\t * The ubiquitous-language name of the criterion. Leaf names are what\n\t * adapters translate and diagnostics print; combinator nodes derive\n\t * theirs (`\"(a and b)\"`, `\"(not a)\"`).\n\t */\n\tabstract readonly name: string;\n\n\t/**\n\t * The composite structure for combinator-built specifications;\n\t * `undefined` on leaves. See {@link SpecificationComposite}.\n\t */\n\treadonly composite?: SpecificationComposite<T>;\n\n\t/** In-memory evaluation: does `candidate` meet the criterion? */\n\tabstract isSatisfiedBy(candidate: T): boolean;\n\n\t/** Both criteria must hold (short-circuits like `&&`). */\n\tand(other: Specification<T>): Specification<T> {\n\t\treturn new BinaryCompositeSpecification(\"and\", this, other);\n\t}\n\n\t/** Either criterion suffices (short-circuits like `||`). */\n\tor(other: Specification<T>): Specification<T> {\n\t\treturn new BinaryCompositeSpecification(\"or\", this, other);\n\t}\n\n\t/** The criterion must not hold. */\n\tnot(): Specification<T> {\n\t\treturn new NotSpecification(this);\n\t}\n\n\t/** The name, so diagnostics and test output read in domain language. */\n\ttoString(): string {\n\t\treturn this.name;\n\t}\n}\n\n/**\n * Builds a leaf specification from a name and a predicate: the\n * lightweight alternative to subclassing for criteria without\n * parameters worth a class of their own. The predicate must be pure\n * (no side effects, no mutation of the candidate): specifications are\n * evaluated freely and repeatedly, in tests, combinators, and\n * in-memory repositories.\n */\nexport function specification<T>(\n\tname: string,\n\tpredicate: (candidate: T) => boolean,\n): Specification<T> {\n\tif (name.trim().length === 0 || name !== name.trim()) {\n\t\tthrow new Error(\n\t\t\t\"specification: the name must be a non-empty ubiquitous-language term \" +\n\t\t\t\t\"without leading or trailing whitespace; adapters match it as an \" +\n\t\t\t\t\"exact string, and padding is invisible in every diagnostic\",\n\t\t);\n\t}\n\treturn new PredicateSpecification(name, predicate);\n}\n\nclass PredicateSpecification<T> extends Specification<T> {\n\tconstructor(\n\t\treadonly name: string,\n\t\tprivate readonly predicate: (candidate: T) => boolean,\n\t) {\n\t\tsuper();\n\t}\n\n\tisSatisfiedBy(candidate: T): boolean {\n\t\treturn this.predicate(candidate);\n\t}\n}\n\nclass BinaryCompositeSpecification<T> extends Specification<T> {\n\toverride readonly composite: {\n\t\treadonly operator: \"and\" | \"or\";\n\t\treadonly left: Specification<T>;\n\t\treadonly right: Specification<T>;\n\t};\n\tprivate cachedName?: string;\n\n\tconstructor(\n\t\toperator: \"and\" | \"or\",\n\t\tleft: Specification<T>,\n\t\tright: Specification<T>,\n\t) {\n\t\tsuper();\n\t\t// Frozen like every plain object the kit hands out: readonly is\n\t\t// compile-time only, and an adapter mutating the structure would\n\t\t// silently diverge from name and evaluation.\n\t\tthis.composite = Object.freeze({ operator, left, right });\n\t}\n\n\t// Lazy with a cache: deep chains would otherwise pay quadratic\n\t// string work at construction for names only diagnostics read.\n\tget name(): string {\n\t\tthis.cachedName ??= `(${this.composite.left.name} ${this.composite.operator} ${this.composite.right.name})`;\n\t\treturn this.cachedName;\n\t}\n\n\tisSatisfiedBy(candidate: T): boolean {\n\t\tconst { operator, left, right } = this.composite;\n\t\treturn operator === \"and\"\n\t\t\t? left.isSatisfiedBy(candidate) && right.isSatisfiedBy(candidate)\n\t\t\t: left.isSatisfiedBy(candidate) || right.isSatisfiedBy(candidate);\n\t}\n}\n\nclass NotSpecification<T> extends Specification<T> {\n\toverride readonly composite: {\n\t\treadonly operator: \"not\";\n\t\treadonly inner: Specification<T>;\n\t};\n\tprivate cachedName?: string;\n\n\tconstructor(inner: Specification<T>) {\n\t\tsuper();\n\t\tthis.composite = Object.freeze({ operator: \"not\", inner });\n\t}\n\n\tget name(): string {\n\t\tthis.cachedName ??= `(not ${this.composite.inner.name})`;\n\t\treturn this.cachedName;\n\t}\n\n\tisSatisfiedBy(candidate: T): boolean {\n\t\treturn !this.composite.inner.isSatisfiedBy(candidate);\n\t}\n}\n","import { ValidationError } from \"@shirudo/base-error\";\nimport { err, ok, type Result } from \"@shirudo/result\";\nimport { type VO, vo } from \"../value-object/value-object\";\n\n/**\n * Builds an immutable value object while collecting **all** validation\n * violations into a single {@link ValidationError}, instead of failing on the\n * first one. This is the Result-first, multi-error counterpart to\n * `voWithValidation` (which returns a single string message).\n *\n * The `validate` callback receives a fresh `ValidationError` to push field\n * issues onto (via `addIssue` / `addIssues`) and the raw input. When no issue\n * was recorded the input is frozen into a `VO<T>` and returned as `Ok`;\n * otherwise the populated `ValidationError` is returned as `Err`.\n *\n * `ValidationError` comes from `@shirudo/base-error`; import it from there to\n * narrow the `Err` branch, exactly as `Result` is imported from\n * `@shirudo/result`. At the HTTP boundary, `toProblemDetails` from\n * `@shirudo/ddd-kit/http` surfaces the issues as an RFC 9457 result.\n *\n * @example\n * ```ts\n * const result = voValidated(\n * { email, age },\n * (issues, m) => {\n * if (!isEmail(m.email))\n * issues.addIssue({ message: \"must be a valid email\", path: [\"email\"] });\n * if (m.age < 0)\n * issues.addIssue({ message: \"must not be negative\", path: [\"age\"] });\n * },\n * \"Registration is invalid\",\n * );\n * // result.isErr() → result.error.publicIssues() has both violations\n * ```\n */\nexport function voValidated<T>(\n\tt: T,\n\tvalidate: (issues: ValidationError, value: T) => void,\n\tmessage = \"Validation failed\",\n): Result<VO<T>, ValidationError> {\n\tconst issues = new ValidationError(message);\n\tvalidate(issues, t);\n\treturn issues.hasIssues() ? err(issues) : ok(vo(t));\n}\n"],"mappings":"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"}