@shirudo/ddd-kit 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -18
- package/dist/aggregate-BGdgvqKh.d.ts +716 -0
- package/dist/http.d.ts +2 -2
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +767 -656
- package/dist/index.js +775 -55
- package/dist/index.js.map +1 -1
- package/dist/testing.d.ts +252 -0
- package/dist/testing.js +793 -0
- package/dist/testing.js.map +1 -0
- package/dist/utils.d.ts +3 -3
- package/dist/utils.js.map +1 -1
- package/package.json +6 -2
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/domain-event.ts","../src/aggregate/aggregate.ts","../src/entity/entity.ts","../src/aggregate/base-aggregate.ts","../src/aggregate/aggregate-root.ts","../src/core/errors.ts","../src/aggregate/event-sourced-aggregate.ts","../src/app/describe-thrown.ts","../src/app/command-bus.ts","../src/app/handler.ts","../src/app/query-bus.ts","../src/events/event-bus.ts","../src/events/outbox.ts","../src/validation/vo-validated.ts"],"names":["tagA","tagB","len","clone","ok","err"],"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 — `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 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 regExpSourceGet = intrinsicGetter(RegExp.prototype, \"source\");\nconst booleanValueOf = Boolean.prototype.valueOf;\nconst numberValueOf = Number.prototype.valueOf;\nconst stringValueOf = String.prototype.valueOf;\nconst PROBE_KEY = {};\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\n/**\n * Verifies that `obj` genuinely is the type its tag claims, via an\n * internal-slot probe. Tags without a cheap probe (Promise, Error,\n * SharedArrayBuffer) are trusted — their downstream handling is\n * reference-based and cannot crash on a spoofed object.\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 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\tdefault:\n\t\t\t\treturn true;\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\tconst arrA = objA as unknown[];\n\t\tconst arrB = objB as unknown[];\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 (!deepEqualInner(arrA[i], arrB[i], visited)) return false;\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\t\t// Wrapper objects (new Boolean/Number/String); 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\tconst stringKeysA = Object.keys(objA);\n\tconst stringKeysB = Object.keys(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 — 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'`.\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 — 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 elements. `Array.isArray` is brand-based —\n\t// immune to `Symbol.toStringTag` spoofing, unlike the tag check below.\n\tif (Array.isArray(obj)) {\n\t\tconst arr = obj as unknown[];\n\t\tconst clone: unknown[] = new Array(arr.length);\n\t\tvisited.set(obj, clone);\n\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\tpath.push(i);\n\t\t\tclone[i] = omitInternal(\n\t\t\t\tarr[i],\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\tpath.pop();\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\n/**\n * Assigns `value` as an OWN data property on `target` without going through\n * any inherited setter — critically, 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 { isBuiltInObject } 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>();\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 — 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 — the spec forbids freezing a view with elements, and freezing\n * 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). Brand-verified via\n // isBuiltInObject: a plain object spoofing one of these tags through\n // Symbol.toStringTag is just frozen as a plain object.\n const tag = Object.prototype.toString.call(obj);\n if (isBuiltInObject(obj as object, tag)) {\n if (tag === \"[object Date]\") {\n shadowMutators(obj as object, \"Date\", DATE_MUTATORS);\n } else if (tag === \"[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 (tag === \"[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, class instances (prototype-preserving — the constructor\n * is NOT re-invoked), arrays, and Map/Set entries 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/Set boundaries. Function values throw,\n * preserving `vo()`'s documented data-not-behaviour gate; Promise /\n * WeakMap / WeakSet throw a descriptive `TypeError` (they have no\n * meaningful value semantics). Atomic built-ins (Date, RegExp,\n * TypedArrays, ArrayBuffer, wrappers, Error) 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 (visited.has(obj)) {\n return visited.get(obj);\n }\n\n if (Array.isArray(obj)) {\n const clone: unknown[] = new Array(obj.length);\n visited.set(obj, clone);\n for (let i = 0; i < obj.length; i++) {\n clone[i] = cloneForVo(obj[i], visited);\n }\n return clone;\n }\n\n const tag = Object.prototype.toString.call(obj);\n if (isBuiltInObject(obj, tag)) {\n if (tag === \"[object Map]\") {\n const clone = new Map<unknown, unknown>();\n visited.set(obj, clone);\n for (const [key, entry] of obj as Map<unknown, unknown>) {\n clone.set(cloneForVo(key, visited), 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 obj as Set<unknown>) {\n clone.add(cloneForVo(member, visited));\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 // Atomic built-ins: Date, RegExp, TypedArrays, ArrayBuffer,\n // wrappers, Error.\n const builtInClone = structuredClone(obj);\n visited.set(obj, builtInClone);\n return builtInClone;\n }\n\n // Plain objects AND class instances: prototype-preserving key walk.\n const clone = Object.create(Object.getPrototypeOf(obj));\n visited.set(obj, clone);\n for (const key of Reflect.ownKeys(obj)) {\n const descriptor = Object.getOwnPropertyDescriptor(obj, key);\n if (!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(\n (obj as Record<PropertyKey, unknown>)[key],\n visited,\n ),\n writable: true,\n enumerable: true,\n configurable: true,\n });\n }\n return clone;\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 are rejected (Value Objects are data, not behaviour).\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 * - TypedArrays and DataView\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 in\n * the input (functions, Promise/WeakMap/WeakSet) 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 —\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 properties are deep-cloned (prototype-preserving) and then deeply\n * frozen — 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(): prototype-preserving, Map/Set contents\n // walked (so the caller's entries are never frozen or shadowed in\n // place), function values 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 return new Constructor({ ...this.props, ...(props || {}) });\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","import { deepFreeze } from \"../value-object/value-object\";\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` and\n * `createDomainEventWithMetadata`. Call once during application bootstrap,\n * 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 * Internal guard for the scoped factory helpers. Throws a clear error\n * when the user-supplied `fn` returns a thenable — the helpers are\n * synchronous-only, and a silent async-misuse would restore the factory\n * before the awaited body of `fn` runs, leaving the awaited code\n * reading the previous factory.\n */\nfunction 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\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` — out of scope for this helper;\n * 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 * 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` must be reproducible.\n */\nexport type ClockFactory = () => Date;\n\nconst defaultClockFactory: ClockFactory = () => new Date();\nlet currentClockFactory: ClockFactory = defaultClockFactory;\n\n/**\n * Replaces the global clock factory used by `createDomainEvent` and\n * `createDomainEventWithMetadata`. Call once during application bootstrap\n * (or per-test 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 {@link 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 — same constraints (and same runtime thenable\n * guard) as {@link withEventIdFactory}.\n *\n * **When to prefer the per-call `options.occurredAt` instead.** Same\n * trade-off as {@link 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 * 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 * @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\tversion: 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 * 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 * **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\tpayload: payload as P,\n\t\t// Defensive copy — the event must not share the caller's live Date\n\t\t// instance, or a later mutation of it would bleed into the event.\n\t\toccurredAt: options?.occurredAt\n\t\t\t? new Date(options.occurredAt.getTime())\n\t\t\t: currentClockFactory(),\n\t\tversion: options?.version ?? 1,\n\t\tmetadata: options?.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 * Creates a domain event with metadata for traceability.\n * Convenience function for creating events with correlation and causation IDs.\n *\n * @example\n * ```typescript\n * const event = createDomainEventWithMetadata(\n * \"OrderCreated\",\n * { orderId: \"123\" },\n * { correlationId: \"corr-123\", causationId: \"cmd-456\", userId: \"user-789\" }\n * );\n * ```\n */\nexport function createDomainEventWithMetadata<T extends string, P>(\n\ttype: T,\n\tpayload: P,\n\tmetadata: EventMetadata,\n\toptions?: Omit<CreateDomainEventOptions, \"metadata\">,\n): DomainEvent<T, P> {\n\treturn createDomainEvent(type, payload, {\n\t\t...options,\n\t\tmetadata,\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\tstate: TState;\n\n\t/**\n\t * The version of the aggregate when the snapshot was taken.\n\t */\n\tversion: Version;\n\n\t/**\n\t * Timestamp when the snapshot was created.\n\t */\n\tsnapshotAt: Date;\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","/**\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 `EntityBase<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 * - `EntityBase<TState, TId>` - Base class for entities with state\n * - `Entity<TId>` - Simple class for entities without state management\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 EntityBase<OrderItemState, ItemId> {\n * constructor(id: ItemId, initialState: OrderItemState) {\n * super(id, initialState);\n * }\n *\n * updateQuantity(quantity: number): void {\n * this._state = { ...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\";\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 * this._state = { ...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 * The state object is **shallowly frozen** — direct property writes\n\t * (`entity.state.foo = …`) throw in strict mode, but writes to nested\n\t * objects (`entity.state.address.zip = …`) bypass the freeze. For deep\n\t * immutability either model nested data with `vo()` (which freezes\n\t * deeply) or reach for a structural-sharing library like Immer at the\n\t * App layer. The shallow contract is intentional: deep freezing on\n\t * every state write is too expensive for hot paths, and DDD aggregates\n\t * normally treat their own 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.\n\t */\n\tprotected _state: 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}.\n\t */\n\tprotected constructor(id: TId, initialState: TState) {\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._state = freezeShallow(shallowCopyOwned(initialState));\n\t\tthis.validateState(this._state);\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 = freezeShallow(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` and its subclasses to prevent\n * outside mutation of state read through the `state` getter without paying\n * the cost of a deep clone on every read.\n *\n * Exported so that sibling classes (`EventSourcedAggregate`, `AggregateRoot`)\n * can apply the same freeze when they bypass `setState` and assign\n * `this._state` directly.\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 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 {\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 * @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 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\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: new Date(),\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 — the helper sets\n\t * 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 { freezeShallow } from \"../entity/entity\";\nimport { BaseAggregate } from \"./base-aggregate\";\nimport type { AggregateSnapshot } 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.\n */\nexport interface AggregateConfig {\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. Set to `true` only if you have\n\t * a subclass that never passes `bumpVersion` and you want every state\n\t * change to advance the version anyway.\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\tprotected constructor(\n\t\tid: TId,\n\t\tinitialState: TState,\n\t\tconfig?: AggregateConfig,\n\t) {\n\t\tsuper(id, initialState);\n\t\tthis._autoVersionBump = config?.autoVersionBump ?? false;\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 * @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(snapshot.state);\n\t\tthis.validateState(restored);\n\t\tthis._state = freezeShallow(restored);\n\t\tthis.markRestored(snapshot.version);\n\t}\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()`, `getUserMessage()`,\n * `isRetryable`, …).\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}.\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}\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 class AggregateNotFoundError extends InfrastructureError<\"AggregateNotFoundError\"> {\n\tconstructor(\n\t\tpublic readonly aggregateType: string,\n\t\tpublic readonly id: string,\n\t\tcause?: unknown,\n\t) {\n\t\tsuper(`Aggregate not found: ${aggregateType}(${id})`, cause);\n\t\tthis.withUserMessage(\n\t\t\t`The requested ${aggregateType} could not be found.`,\n\t\t);\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 * `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 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\tconstructor(\n\t\tpublic readonly aggregateType: string,\n\t\tpublic readonly aggregateId: string,\n\t\tpublic readonly expectedVersion: number,\n\t\tpublic readonly actualVersion: number,\n\t\tcause?: unknown,\n\t) {\n\t\tsuper(\n\t\t\t`Concurrency conflict on ${aggregateType}(${aggregateId}): expected version ${expectedVersion}, actual ${actualVersion}`,\n\t\t\tcause,\n\t\t);\n\t\tthis.withUserMessage(\n\t\t\t\"This resource was updated by another request. Please reload and try again.\",\n\t\t);\n\t}\n}\n","import { err, ok, type Result } from \"@shirudo/result\";\nimport type { Id } from \"../core/id\";\nimport { DomainError, MissingHandlerError } from \"../core/errors\";\nimport { freezeShallow } from \"../entity/entity\";\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 * — 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 = freezeShallow(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 — 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 v=3;\n\t * an aggregate already at v=1 (e.g. after a creation event) loading\n\t * 2 events ends at v=3, not v=2.\n\t */\n\tpublic loadFromHistory(\n\t\thistory: ReadonlyArray<TEvent>,\n\t): Result<void, DomainError> {\n\t\t// Empty stream: nothing was loaded — 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\tpublic restoreFromSnapshotWithEvents(\n\t\tsnapshot: AggregateSnapshot<TSnapshotState>,\n\t\teventsAfterSnapshot: ReadonlyArray<TEvent>,\n\t): Result<void, DomainError> {\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\tthis._state = freezeShallow(this.fromSnapshotState(snapshot.state));\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 * 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 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 = (\n\tcmd: Command,\n) => Promise<Result<unknown, string>>;\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 * 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<TMap extends CommandTypeMap = CommandTypeMap> {\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 error message\n\t */\n\texecute<C extends Command & { type: keyof TMap & string }>(\n\t\tcommand: C,\n\t): Promise<Result<TMap[C[\"type\"]], string>>;\n\texecute<C extends Command, R>(command: C): Promise<Result<R, string>>;\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>(\n\t\tcommandType: K,\n\t\thandler: CommandHandler<C, TMap[K]>,\n\t): 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<TMap extends CommandTypeMap = CommandTypeMap>\n\timplements ICommandBus<TMap>\n{\n\tprivate readonly handlers = new Map<string, StoredCommandHandler>();\n\n\tregister<\n\t\tK extends keyof TMap & string,\n\t\tC extends Command & { type: K } = Command & { type: K },\n\t>(\n\t\tcommandType: K,\n\t\thandler: CommandHandler<C, TMap[K]>,\n\t): 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\"]], string>>;\n\tasync execute<C extends Command, R>(\n\t\tcommand: C,\n\t): Promise<Result<R, string>>;\n\tasync execute<C extends Command, R>(\n\t\tcommand: C,\n\t): Promise<Result<R, string>> {\n\t\tconst handler = this.handlers.get(command.type);\n\t\tif (!handler) {\n\t\t\treturn err(`No handler registered for command type: ${command.type}`);\n\t\t}\n\t\ttry {\n\t\t\treturn (await handler(command)) as Result<R, string>;\n\t\t} catch (error) {\n\t\t\treturn err(describeThrown(error));\n\t\t}\n\t}\n}\n","import type { IAggregateRoot } from \"../aggregate/aggregate-root\";\nimport type { AnyDomainEvent } from \"../aggregate/domain-event\";\nimport type { Id } from \"../core/id\";\nimport type { EventBus, Outbox } from \"../events/ports\";\nimport type { TransactionScope } from \"../repo/scope\";\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.\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.\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 * **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},\n\tfn: (ctx: TCtx) => Promise<{\n\t\tresult: R;\n\t\taggregates: ReadonlyArray<IAggregateRoot<Id<string>, Evt>>;\n\t}>,\n): Promise<R> {\n\tconst { result, aggregates, 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\tconst harvested = uniqueAggregates.flatMap(\n\t\t\t\t(agg) => agg.pendingEvents,\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 Error(\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);\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 { ...fnResult, aggregates: uniqueAggregates, events: harvested };\n\t\t},\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.\n\tfor (const agg of aggregates) {\n\t\ttry {\n\t\t\tagg.markPersisted(agg.version);\n\t\t} catch {\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.\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).\n\t\t\ttry {\n\t\t\t\tdeps.onPublishError?.(error, events);\n\t\t\t} catch {\n\t\t\t\t// Observer-only hook: its own failure must not break the\n\t\t\t\t// post-commit invariant either.\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result;\n}\n","import { err, ok, type Result } from \"@shirudo/result\";\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 * 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<TMap extends QueryTypeMap = QueryTypeMap> {\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\"]], string>>;\n\texecute<Q extends Query, R>(query: Q): Promise<Result<R, string>>;\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>(\n\t\tqueryType: K,\n\t\thandler: QueryHandler<Q, TMap[K]>,\n\t): 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>\n\timplements IQueryBus<TMap>\n{\n\tprivate readonly handlers = new Map<string, StoredQueryHandler>();\n\n\tregister<\n\t\tK extends keyof TMap & string,\n\t\tQ extends Query & { type: K } = Query & { type: K },\n\t>(\n\t\tqueryType: K,\n\t\thandler: QueryHandler<Q, TMap[K]>,\n\t): 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\"]], string>>;\n\tasync execute<Q extends Query, R>(query: Q): Promise<Result<R, string>>;\n\tasync execute<Q extends Query, R>(query: Q): Promise<Result<R, string>> {\n\t\tconst handler = this.handlers.get(query.type);\n\t\tif (!handler) {\n\t\t\treturn err(`No handler registered for query type: ${query.type}`);\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(describeThrown(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 Error(`No handler registered for query type: ${query.type}`);\n\t\t}\n\t\treturn (await handler(query)) as R;\n\t}\n}\n","import type { AnyDomainEvent } from \"../aggregate/domain-event\";\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(options.signal.reason ?? new Error(\"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(\n\t\t\t\t\t\toptions.signal!.reason ?? new Error(\"EventBus.once aborted\"),\n\t\t\t\t\t);\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 { Outbox, OutboxRecord } from \"./ports\";\n\n/**\n * In-memory reference implementation of `Outbox<Evt>`.\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<string, OutboxRecord<Evt>>` keyed by\n * `eventId`, so re-adding the same event is naturally idempotent (the\n * duplicate entry overwrites itself; `getPending` returns each event at\n * most once).\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.\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> implements Outbox<Evt> {\n\tprivate readonly pending = new Map<string, OutboxRecord<Evt>>();\n\n\tasync add(events: ReadonlyArray<Evt>): Promise<void> {\n\t\tfor (const event of events) {\n\t\t\tthis.pending.set(event.eventId, {\n\t\t\t\tdispatchId: event.eventId,\n\t\t\t\tevent,\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\tconst all = [...this.pending.values()];\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) this.pending.delete(id);\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,"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/domain-event.ts","../src/aggregate/aggregate.ts","../src/entity/entity.ts","../src/aggregate/base-aggregate.ts","../src/aggregate/aggregate-root.ts","../src/core/errors.ts","../src/aggregate/event-sourced-aggregate.ts","../src/app/describe-thrown.ts","../src/app/command-bus.ts","../src/utils/abort.ts","../src/app/handler.ts","../src/repo/identity-map.ts","../src/app/unit-of-work.ts","../src/app/query-bus.ts","../src/events/event-bus.ts","../src/events/outbox.ts","../src/repo/retrying-scope.ts","../src/validation/vo-validated.ts"],"names":["tagA","tagB","len","clone","ok","err","BaseError"],"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 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 regExpSourceGet = intrinsicGetter(RegExp.prototype, \"source\");\nconst booleanValueOf = Boolean.prototype.valueOf;\nconst numberValueOf = Number.prototype.valueOf;\nconst stringValueOf = String.prototype.valueOf;\nconst PROBE_KEY = {};\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\n/**\n * Verifies that `obj` genuinely is the type its tag claims, via an\n * internal-slot probe. Tags without a cheap probe (Promise, Error,\n * SharedArrayBuffer) are trusted: their downstream handling is\n * reference-based and cannot crash on a spoofed object.\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 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\tdefault:\n\t\t\t\treturn true;\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\tconst arrA = objA as unknown[];\n\t\tconst arrB = objB as unknown[];\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 (!deepEqualInner(arrA[i], arrB[i], visited)) return false;\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\t\t// Wrapper objects (new Boolean/Number/String); 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\tconst stringKeysA = Object.keys(objA);\n\tconst stringKeysB = Object.keys(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'`.\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 elements. `Array.isArray` is brand-based,\n\t// immune to `Symbol.toStringTag` spoofing, unlike the tag check below.\n\tif (Array.isArray(obj)) {\n\t\tconst arr = obj as unknown[];\n\t\tconst clone: unknown[] = new Array(arr.length);\n\t\tvisited.set(obj, clone);\n\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\tpath.push(i);\n\t\t\tclone[i] = omitInternal(\n\t\t\t\tarr[i],\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\tpath.pop();\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\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 { isBuiltInObject } 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>();\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). Brand-verified via\n // isBuiltInObject: a plain object spoofing one of these tags through\n // Symbol.toStringTag is just frozen as a plain object.\n const tag = Object.prototype.toString.call(obj);\n if (isBuiltInObject(obj as object, tag)) {\n if (tag === \"[object Date]\") {\n shadowMutators(obj as object, \"Date\", DATE_MUTATORS);\n } else if (tag === \"[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 (tag === \"[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, class instances (prototype-preserving, since the constructor\n * is NOT re-invoked), arrays, and Map/Set entries 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/Set boundaries. Function values throw,\n * preserving `vo()`'s documented data-not-behaviour gate; Promise /\n * WeakMap / WeakSet throw a descriptive `TypeError` (they have no\n * meaningful value semantics). Atomic built-ins (Date, RegExp,\n * TypedArrays, ArrayBuffer, wrappers, Error) 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 (visited.has(obj)) {\n return visited.get(obj);\n }\n\n if (Array.isArray(obj)) {\n const clone: unknown[] = new Array(obj.length);\n visited.set(obj, clone);\n for (let i = 0; i < obj.length; i++) {\n clone[i] = cloneForVo(obj[i], visited);\n }\n return clone;\n }\n\n const tag = Object.prototype.toString.call(obj);\n if (isBuiltInObject(obj, tag)) {\n if (tag === \"[object Map]\") {\n const clone = new Map<unknown, unknown>();\n visited.set(obj, clone);\n for (const [key, entry] of obj as Map<unknown, unknown>) {\n clone.set(cloneForVo(key, visited), 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 obj as Set<unknown>) {\n clone.add(cloneForVo(member, visited));\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 // Atomic built-ins: Date, RegExp, TypedArrays, ArrayBuffer,\n // wrappers, Error.\n const builtInClone = structuredClone(obj);\n visited.set(obj, builtInClone);\n return builtInClone;\n }\n\n // Plain objects AND class instances: prototype-preserving key walk.\n const clone = Object.create(Object.getPrototypeOf(obj));\n visited.set(obj, clone);\n for (const key of Reflect.ownKeys(obj)) {\n const descriptor = Object.getOwnPropertyDescriptor(obj, key);\n if (!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(\n (obj as Record<PropertyKey, unknown>)[key],\n visited,\n ),\n writable: true,\n enumerable: true,\n configurable: true,\n });\n }\n return clone;\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 are rejected (Value Objects are data, not behaviour).\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 * - TypedArrays and DataView\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 in\n * the input (functions, Promise/WeakMap/WeakSet) 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 properties are deep-cloned (prototype-preserving) 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(): prototype-preserving, Map/Set contents\n // walked (so the caller's entries are never frozen or shadowed in\n // place), function values 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 return new Constructor({ ...this.props, ...(props || {}) });\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","import { deepFreeze } from \"../value-object/value-object\";\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` and\n * `createDomainEventWithMetadata`. Call once during application bootstrap,\n * 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 * Internal guard for the scoped factory helpers. Throws a clear error\n * when the user-supplied `fn` returns a thenable: the helpers are\n * synchronous-only, and a silent async-misuse would restore the factory\n * before the awaited body of `fn` runs, leaving the awaited code\n * reading the previous factory.\n */\nfunction 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\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 * 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` must be reproducible.\n */\nexport type ClockFactory = () => Date;\n\nconst defaultClockFactory: ClockFactory = () => new Date();\nlet currentClockFactory: ClockFactory = defaultClockFactory;\n\n/**\n * Replaces the global clock factory used by `createDomainEvent` and\n * `createDomainEventWithMetadata`. Call once during application bootstrap\n * (or per-test 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 {@link 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 {@link withEventIdFactory}.\n *\n * **When to prefer the per-call `options.occurredAt` instead.** Same\n * trade-off as {@link 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 * 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 ordering (\"apply projections up to aggregate\n\t * version N\"), idempotency watermarks, debugging, and integration\n\t * logs. Optional at the type level: events created outside an\n\t * aggregate (system/integration events) and events from older kit\n\t * versions 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 * **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\tpayload: payload as P,\n\t\t// Defensive copy: the event must not share the caller's live Date\n\t\t// instance, or a later mutation of it would bleed into the event.\n\t\toccurredAt: options?.occurredAt\n\t\t\t? new Date(options.occurredAt.getTime())\n\t\t\t: currentClockFactory(),\n\t\tversion: options?.version ?? 1,\n\t\taggregateVersion: options?.aggregateVersion,\n\t\tmetadata: options?.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 * Creates a domain event with metadata for traceability.\n * Convenience function for creating events with correlation and causation IDs.\n *\n * @example\n * ```typescript\n * const event = createDomainEventWithMetadata(\n * \"OrderCreated\",\n * { orderId: \"123\" },\n * { correlationId: \"corr-123\", causationId: \"cmd-456\", userId: \"user-789\" }\n * );\n * ```\n */\nexport function createDomainEventWithMetadata<T extends string, P>(\n\ttype: T,\n\tpayload: P,\n\tmetadata: EventMetadata,\n\toptions?: Omit<CreateDomainEventOptions, \"metadata\">,\n): DomainEvent<T, P> {\n\treturn createDomainEvent(type, payload, {\n\t\t...options,\n\t\tmetadata,\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\tstate: TState;\n\n\t/**\n\t * The version of the aggregate when the snapshot was taken.\n\t */\n\tversion: Version;\n\n\t/**\n\t * Timestamp when the snapshot was created.\n\t */\n\tsnapshotAt: Date;\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","/**\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 `EntityBase<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 * - `EntityBase<TState, TId>` - Base class for entities with state\n * - `Entity<TId>` - Simple class for entities without state management\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 EntityBase<OrderItemState, ItemId> {\n * constructor(id: ItemId, initialState: OrderItemState) {\n * super(id, initialState);\n * }\n *\n * updateQuantity(quantity: number): void {\n * this._state = { ...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\";\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 * this._state = { ...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 * The state object is **shallowly frozen**: direct property writes\n\t * (`entity.state.foo = …`) throw in strict mode, but writes to nested\n\t * objects (`entity.state.address.zip = …`) bypass the freeze. For deep\n\t * immutability either model nested data with `vo()` (which freezes\n\t * deeply) or reach for a structural-sharing library like Immer at the\n\t * App layer. The shallow contract is intentional: deep freezing on\n\t * every state write is too expensive for hot paths, and DDD aggregates\n\t * normally treat their own 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.\n\t */\n\tprotected _state: 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}.\n\t */\n\tprotected constructor(id: TId, initialState: TState) {\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._state = freezeShallow(shallowCopyOwned(initialState));\n\t\tthis.validateState(this._state);\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 = freezeShallow(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` and its subclasses to prevent\n * outside mutation of state read through the `state` getter without paying\n * the cost of a deep clone on every read.\n *\n * Exported so that sibling classes (`EventSourcedAggregate`, `AggregateRoot`)\n * can apply the same freeze when they bypass `setState` and assign\n * `this._state` directly.\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 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 {\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\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: new Date(),\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 { freezeShallow } 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.\n */\nexport interface AggregateConfig {\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. Set to `true` only if you have\n\t * a subclass that never passes `bumpVersion` and you want every state\n\t * change to advance the version anyway.\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);\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 * @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(snapshot.state);\n\t\tthis.validateState(restored);\n\t\tthis._state = freezeShallow(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 { 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()`, `getUserMessage()`,\n * `isRetryable`, …).\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 `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/**\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 class AggregateNotFoundError extends InfrastructureError<\"AggregateNotFoundError\"> {\n\tconstructor(\n\t\tpublic readonly aggregateType: string,\n\t\tpublic readonly id: string,\n\t\tcause?: unknown,\n\t) {\n\t\tsuper(`Aggregate not found: ${aggregateType}(${id})`, cause, {\n\t\t\tname: \"AggregateNotFoundError\",\n\t\t});\n\t\tthis.withUserMessage(\n\t\t\t`The requested ${aggregateType} could not be found.`,\n\t\t);\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 class DuplicateAggregateError extends InfrastructureError<\"DuplicateAggregateError\"> {\n\tconstructor(\n\t\tpublic readonly aggregateType: string,\n\t\tpublic readonly aggregateId: string,\n\t\tcause?: unknown,\n\t) {\n\t\tsuper(\n\t\t\t`Duplicate aggregate: ${aggregateType}(${aggregateId}) already exists`,\n\t\t\tcause,\n\t\t\t{ name: \"DuplicateAggregateError\" },\n\t\t);\n\t\tthis.withUserMessage(\n\t\t\t`This ${aggregateType} already exists. It may have been created by a concurrent request.`,\n\t\t);\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 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\tconstructor(\n\t\tpublic readonly aggregateType: string,\n\t\tpublic readonly aggregateId: string,\n\t\tpublic readonly expectedVersion: number,\n\t\tpublic readonly actualVersion: number,\n\t\tcause?: unknown,\n\t) {\n\t\tsuper(\n\t\t\t`Concurrency conflict on ${aggregateType}(${aggregateId}): expected version ${expectedVersion}, actual ${actualVersion}`,\n\t\t\tcause,\n\t\t\t{ name: \"ConcurrencyConflictError\" },\n\t\t);\n\t\tthis.withUserMessage(\n\t\t\t\"This resource was updated by another request. Please reload and try again.\",\n\t\t);\n\t}\n}\n","import { err, ok, type Result } from \"@shirudo/result\";\nimport type { Id } from \"../core/id\";\nimport { DomainError, MissingHandlerError } from \"../core/errors\";\nimport { freezeShallow } from \"../entity/entity\";\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 = freezeShallow(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 v=3;\n\t * an aggregate already at v=1 (e.g. after a creation event) loading\n\t * 2 events ends at v=3, not v=2.\n\t */\n\tpublic loadFromHistory(\n\t\thistory: ReadonlyArray<TEvent>,\n\t): Result<void, DomainError> {\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\tpublic restoreFromSnapshotWithEvents(\n\t\tsnapshot: AggregateSnapshot<TSnapshotState>,\n\t\teventsAfterSnapshot: ReadonlyArray<TEvent>,\n\t): Result<void, DomainError> {\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\tthis._state = freezeShallow(this.fromSnapshotState(snapshot.state));\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 * 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 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 = (\n\tcmd: Command,\n) => Promise<Result<unknown, string>>;\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 * 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<TMap extends CommandTypeMap = CommandTypeMap> {\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 error message\n\t */\n\texecute<C extends Command & { type: keyof TMap & string }>(\n\t\tcommand: C,\n\t): Promise<Result<TMap[C[\"type\"]], string>>;\n\texecute<C extends Command, R>(command: C): Promise<Result<R, string>>;\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>(\n\t\tcommandType: K,\n\t\thandler: CommandHandler<C, TMap[K]>,\n\t): 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<TMap extends CommandTypeMap = CommandTypeMap>\n\timplements ICommandBus<TMap>\n{\n\tprivate readonly handlers = new Map<string, StoredCommandHandler>();\n\n\tregister<\n\t\tK extends keyof TMap & string,\n\t\tC extends Command & { type: K } = Command & { type: K },\n\t>(\n\t\tcommandType: K,\n\t\thandler: CommandHandler<C, TMap[K]>,\n\t): 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\"]], string>>;\n\tasync execute<C extends Command, R>(\n\t\tcommand: C,\n\t): Promise<Result<R, string>>;\n\tasync execute<C extends Command, R>(\n\t\tcommand: C,\n\t): Promise<Result<R, string>> {\n\t\tconst handler = this.handlers.get(command.type);\n\t\tif (!handler) {\n\t\t\treturn err(`No handler registered for command type: ${command.type}`);\n\t\t}\n\t\ttry {\n\t\t\treturn (await handler(command)) as Result<R, string>;\n\t\t} catch (error) {\n\t\t\treturn err(describeThrown(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","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\";\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 ordering and idempotency watermarks.\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 * 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 {\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.\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).\n\t\t\ttry {\n\t\t\t\tdeps.onPublishError?.(error, events);\n\t\t\t} catch {\n\t\t\t\t// Observer-only hook: its own failure must not break the\n\t\t\t\t// post-commit invariant either.\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result;\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\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\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\tif (workThrew) {\n\t\t\t\t// The scope normally rethrows the callback's error unchanged\n\t\t\t\t// (rolled back, pass through - ConcurrencyConflictError & co.\n\t\t\t\t// stay catchable as-is). A scope that WRAPS the original is\n\t\t\t\t// detected via the cause chain and also passed through. Only\n\t\t\t\t// a rejection that neither IS nor wraps the callback's error\n\t\t\t\t// indicates the rollback itself failed.\n\t\t\t\tif (error === workError || causeChainContains(error, workError)) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tthrow new RollbackError(workError, error);\n\t\t\t}\n\t\t\tif (workCompleted) {\n\t\t\t\t// A harvest-guard violation (an event missing aggregateId /\n\t\t\t\t// aggregateType, or an aggregateVersion ahead of the commit\n\t\t\t\t// version) is a deterministic programming bug, not a transient\n\t\t\t\t// commit failure. Surface the EventHarvestError itself: it does\n\t\t\t\t// not extend InfrastructureError, so a retry-on-Infrastructure\n\t\t\t\t// handler skips it instead of looping forever. The guard throws\n\t\t\t\t// inside scope.transactional(), so a wrapping scope can nest it\n\t\t\t\t// in its cause chain; walk the chain (same treatment the\n\t\t\t\t// RollbackError path uses) rather than a bare instanceof, and\n\t\t\t\t// re-throw the harvest error so the non-retryable type is never\n\t\t\t\t// masked by the wrapper. Only genuinely post-completion failures\n\t\t\t\t// the caller could not foresee (outbox write, the commit itself)\n\t\t\t\t// become CommitError.\n\t\t\t\tconst harvestError = findHarvestErrorInChain(error);\n\t\t\t\tif (harvestError) {\n\t\t\t\t\tthrow harvestError;\n\t\t\t\t}\n\t\t\t\tthrow new CommitError(error);\n\t\t\t}\n\t\t\t// Neither flag set: withCommit rejected before the callback ran\n\t\t\t// (e.g. the scope failed to even open a transaction).\n\t\t\tthrow error;\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 * 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 { err, ok, type Result } from \"@shirudo/result\";\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 * 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<TMap extends QueryTypeMap = QueryTypeMap> {\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\"]], string>>;\n\texecute<Q extends Query, R>(query: Q): Promise<Result<R, string>>;\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>(\n\t\tqueryType: K,\n\t\thandler: QueryHandler<Q, TMap[K]>,\n\t): 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>\n\timplements IQueryBus<TMap>\n{\n\tprivate readonly handlers = new Map<string, StoredQueryHandler>();\n\n\tregister<\n\t\tK extends keyof TMap & string,\n\t\tQ extends Query & { type: K } = Query & { type: K },\n\t>(\n\t\tqueryType: K,\n\t\thandler: QueryHandler<Q, TMap[K]>,\n\t): 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\"]], string>>;\n\tasync execute<Q extends Query, R>(query: Q): Promise<Result<R, string>>;\n\tasync execute<Q extends Query, R>(query: Q): Promise<Result<R, string>> {\n\t\tconst handler = this.handlers.get(query.type);\n\t\tif (!handler) {\n\t\t\treturn err(`No handler registered for query type: ${query.type}`);\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(describeThrown(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 Error(`No handler registered for query type: ${query.type}`);\n\t\t}\n\t\treturn (await handler(query)) as R;\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 { Outbox, OutboxRecord } from \"./ports\";\n\n/**\n * In-memory reference implementation of `Outbox<Evt>`.\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<string, OutboxRecord<Evt>>` keyed by\n * `eventId`, so re-adding the same event is naturally idempotent (the\n * duplicate entry overwrites itself; `getPending` returns each event at\n * most once).\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> implements Outbox<Evt> {\n\tprivate readonly pending = new Map<string, OutboxRecord<Evt>>();\n\n\tasync add(events: ReadonlyArray<Evt>): Promise<void> {\n\t\tfor (const event of events) {\n\t\t\tthis.pending.set(event.eventId, {\n\t\t\t\tdispatchId: event.eventId,\n\t\t\t\tevent,\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\tconst all = [...this.pending.values()];\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) this.pending.delete(id);\n\t}\n}\n","import { someChainRetryable } from \"@shirudo/base-error\";\nimport { abortReason } from \"../utils/abort\";\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/** Observer fired before each backoff wait (logging / metrics). */\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\tthis.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"]}
|