@shirudo/ddd-kit 1.0.0-rc.6 → 1.0.0-rc.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +281 -17
- package/dist/index.js +137 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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/aggregate-root.ts","../src/core/errors.ts","../src/aggregate/event-sourced-aggregate.ts","../src/app/command-bus.ts","../src/app/handler.ts","../src/app/query-bus.ts","../src/events/event-bus.ts","../src/events/outbox.ts"],"names":["tagA","tagB","len","clone","err","ok"],"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 * The detection is purely tag-based — `Object.prototype.toString` reads\n * `Symbol.toStringTag`, which gives the same answer across realms (an\n * iframe's `Date` has the same tag as the main window's `Date`). The\n * previous strategy also checked `globalThis[name] === constructor` and a\n * `proto !== Object.prototype` heuristic; both broke for cross-realm\n * objects and the latter additionally misclassified ordinary user classes\n * as built-ins. Tag-only is the simplest robust choice.\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/**\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.\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// All TypedArrays produce tags ending in \"Array]\" — future-proof match.\n\tif (tag.endsWith(\"Array]\")) return true;\n\t// ArrayBuffer view covers DataView + all TypedArrays as a belt-and-braces.\n\tif (ArrayBuffer.isView(obj)) return true;\n\treturn BUILT_IN_TAGS.has(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 * 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 (arrA[i] !== arrB[i]) return false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t// 5. Tag-based type detection (robust across realms)\n\tconst tagA = objToString.call(objA);\n\tconst tagB = objToString.call(objB);\n\tif (tagA !== tagB) return false;\n\n\tswitch (tagA) {\n\t\tcase \"[object Array]\": {\n\t\t\tconst arrA = objA as unknown[];\n\t\t\tconst arrB = objB as unknown[];\n\t\t\tconst len = arrA.length;\n\t\t\tif (len !== arrB.length) return false;\n\n\t\t\tfor (let i = 0; i < len; i++) {\n\t\t\t\tif (!deepEqualInner(arrA[i], arrB[i], visited)) return false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\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\tconst timeA = (objA as Date).getTime();\n\t\t\tconst timeB = (objB as Date).getTime();\n\t\t\treturn timeA === timeB;\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)\n\t\t\treturn (objA as any).valueOf() === (objB as any).valueOf();\n\t\t}\n\n\t\tdefault: {\n\t\t\t// 6. Check if this is an unhandled built-in type (future-proof)\n\t\t\t// If both are built-ins but not handled above, they should be compared by reference\n\t\t\t// (since we don't know their internal structure)\n\t\t\tif (isBuiltInObject(objA, tagA) && isBuiltInObject(objB, tagB)) {\n\t\t\t\t// Unhandled built-in types: compare by reference as fallback\n\t\t\t\t// This ensures new built-ins don't fall through to plain object comparison\n\t\t\t\treturn objA === objB;\n\t\t\t}\n\n\t\t\t// 7. Fallback: plain / custom objects → compare own enumerable keys + values\n\t\t\tconst recA = objA as Record<string | symbol, unknown>;\n\t\t\tconst recB = objB as Record<string | symbol, unknown>;\n\n\t\t\tconst stringKeysA = Object.keys(objA as object);\n\t\t\tconst stringKeysB = Object.keys(objB as object);\n\t\t\tif (stringKeysA.length !== stringKeysB.length) return false;\n\n\t\t\tconst symbolKeysA = Object.getOwnPropertySymbols(objA as object);\n\t\t\tconst symbolKeysB = Object.getOwnPropertySymbols(objB as object);\n\t\t\tif (symbolKeysA.length !== symbolKeysB.length) return false;\n\n\t\t\t// Build the B-side symbol set once; the previous impl rebuilt the\n\t\t\t// array and ran .includes per key, which was quadratic.\n\t\t\tconst symbolKeysBSet = new Set<symbol>(symbolKeysB);\n\n\t\t\tfor (const key of stringKeysA) {\n\t\t\t\tif (!objHasOwn.call(objB, key)) return false;\n\t\t\t}\n\t\t\tfor (const key of symbolKeysA) {\n\t\t\t\tif (!symbolKeysBSet.has(key)) return false;\n\t\t\t}\n\n\t\t\tfor (const key of stringKeysA) {\n\t\t\t\tif (!deepEqualInner(recA[key], recB[key], visited)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const key of symbolKeysA) {\n\t\t\t\tif (!deepEqualInner(recA[key], recB[key], visited)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\t}\n}\n","import { isBuiltInObject } 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 (Date, RegExp, Map, Set,\n * TypedArrays, ArrayBuffer, DataView) are cloned by type rather than walked\n * — their internal structure has no key filtering to apply. Cycles are\n * preserved: a cycle `a → a` clones to `a' → a'`.\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\treturn omitInternal(value, options, ignoreKeys, [], visited) as T;\n}\n\nfunction omitInternal(\n\tvalue: unknown,\n\toptions: DeepOmitOptions,\n\tignoreKeys: ReadonlySet<Key> | undefined,\n\tpath: PathSegment[],\n\tvisited: WeakMap<object, unknown>,\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: return cached clone if already visited. Use `has` (not\n\t// `cached !== undefined`) so a legitimately-undefined cached clone\n\t// would not be misclassified as \"never seen\".\n\tif (visited.has(obj)) {\n\t\treturn visited.get(obj);\n\t}\n\n\tconst tag = Object.prototype.toString.call(obj);\n\n\t// Arrays: recursively process elements\n\tif (tag === \"[object Array]\") {\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(arr[i], options, ignoreKeys, path, visited);\n\t\t\tpath.pop();\n\t\t}\n\t\treturn clone;\n\t}\n\n\t// Built-in atomic types: clone by type rather than walk.\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),\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),\n\t\t);\n\t\tpath.pop();\n\t}\n\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. ArrayBuffer, DataView,\n * Boolean/Number/String wrappers).\n */\nfunction cloneBuiltIn(obj: object, tag: string): unknown {\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 { 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 * 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 */\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 if (visited.has(obj as object)) {\n return obj as Readonly<T>;\n }\n visited.add(obj as object);\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 * Creates a deeply immutable value object from the given data.\n *\n * The input is first deep-cloned with `structuredClone`, then the clone\n * is frozen — so calling `vo(input)` never freezes the caller's own\n * object graph as a side-effect. Mutating the input afterwards does not\n * bleed into the VO.\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(structuredClone(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 * @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: ${JSON.stringify(t)}`,\n );\n }\n return ok(vo(t));\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 deeply frozen to ensure immutability.\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 this.props = deepFreeze({ ...props });\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. For multi-tenant request isolation (e.g. one factory per\n * tenant in a single Worker invocation) **prefer the per-call\n * `options.eventId`** instead of mutating the global. Same caveat applies\n * to `setClockFactory`.\n */\nexport function setEventIdFactory(factory: EventIdFactory): void {\n\tcurrentEventIdFactory = factory;\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 */\nexport function setClockFactory(factory: ClockFactory): void {\n\tcurrentClockFactory = factory;\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 * @param type - The event type\n * @param payload - The event payload\n * @param options - Optional event configuration\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\toccurredAt: options?.occurredAt ?? 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\treturn Object.assign({}, ...metadataObjects.filter(Boolean));\n}\n","import type { Id } from \"../core/id\";\n\n// Re-export domain event types for convenience\nexport * from \"./domain-event\";\n\n// Re-export interfaces from their respective files\nexport type { IAggregateRoot } from \"./aggregate-root\";\nexport type { IEventSourcedAggregate } from \"./event-sourced-aggregate\";\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 * 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\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(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 * @param newState - The new state\n\t */\n\tprotected setState(newState: TState): void {\n\t\tthis.validateState(newState);\n\t\tthis._state = freezeShallow(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/**\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, freezeShallow } from \"../entity/entity\";\nimport type {\n\tAggregateSnapshot,\n\tVersion,\n} from \"./aggregate\";\n\n/**\n * Marker interface for Aggregate Roots.\n *\n * In Domain-Driven Design, an Aggregate Root is an Entity (the parent Entity of the aggregate).\n * It represents the aggregate externally and is the only object that external code\n * is allowed to hold references to. All access to child entities within the aggregate\n * must go through the Aggregate Root.\n *\n * An Aggregate consists of:\n * - One Aggregate Root (Entity with id + version)\n * - Optional child entities (Entities with id + state, but no own version)\n * - Optional value objects\n *\n * The Aggregate Root has identity (id), state, and version for optimistic concurrency control.\n * Child entities exist only within the aggregate boundary and are versioned through\n * the Aggregate Root.\n *\n * @template TId - The type of the aggregate root identifier\n *\n * @example\n * ```typescript\n * class Order extends AggregateRoot<OrderState, OrderId> implements IAggregateRoot<OrderId> {\n * // Order is an Aggregate Root (an Entity with version)\n * // OrderState contains child entities (e.g., OrderItem) and value objects\n * }\n * ```\n */\nexport interface IAggregateRoot<TId extends Id<string>, TEvent = never> {\n\t/**\n\t * Unique identifier of the aggregate root entity.\n\t */\n\treadonly id: TId;\n\n\t/**\n\t * Version number for optimistic concurrency control.\n\t * Incremented on each state change to detect concurrent modifications.\n\t * This version applies to the entire aggregate, including all child entities.\n\t */\n\treadonly version: Version;\n\n\t/**\n\t * Read-only list of domain events recorded on this aggregate that have\n\t * not yet been flushed to the outbox / persistence layer. Both state-\n\t * stored (`AggregateRoot`) and event-sourced (`EventSourcedAggregate`)\n\t * aggregates expose them under the same name, so Repository.save() can\n\t * harvest them uniformly without branching on the aggregate flavour.\n\t */\n\treadonly pendingEvents: ReadonlyArray<TEvent>;\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\tclearPendingEvents(): void;\n\n\t/**\n\t * Post-save hook: a `Repository.save()` implementation calls this with\n\t * the persisted version after a successful write to push the new\n\t * version back into the aggregate and clear pendingEvents (they are\n\t * now safely on the write side / in the outbox).\n\t *\n\t * Required by the interface so a Repository implementation can call it\n\t * via the published `IAggregateRoot` contract without taking the\n\t * abstract class as a compile-time dependency.\n\t *\n\t * @param version - The version assigned by the persistence layer\n\t */\n\tmarkPersisted(version: Version): void;\n}\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 management for optimistic concurrency control\n * - Domain event tracking for side-effects\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 * constructor(id: OrderId, initialState: OrderState) {\n * super(id, initialState);\n * }\n *\n * confirm(): void {\n * this.setState({ ...this.state, status: \"confirmed\" }, true);\n * }\n * }\n * ```\n */\nexport abstract class AggregateRoot<\n\tTState,\n\tTId extends Id<string>,\n\tTEvent = never,\n>\n\textends Entity<TState, TId>\n\timplements IAggregateRoot<TId, TEvent> {\n\tprivate _version: Version = 0 as Version;\n\n\tpublic get version(): Version {\n\t\treturn this._version;\n\t}\n\n\tprotected setVersion(version: Version): void {\n\t\tthis._version = version;\n\t}\n\n\tprivate readonly _config: AggregateConfig;\n\tprivate readonly _autoVersionBump: boolean;\n\tprivate _pendingEvents: TEvent[] = [];\n\n\t/**\n\t * Read-only list of domain events recorded on this aggregate that have\n\t * 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. Call this after the events have been\n\t * dispatched (typically `markPersisted` handles it for you).\n\t */\n\tpublic clearPendingEvents(): void {\n\t\tthis._pendingEvents = [];\n\t}\n\n\t/**\n\t * Post-save hook called by a `Repository.save()` implementation to push\n\t * the persisted version back into the in-memory aggregate and clear\n\t * pendingEvents (they are now safely on the write side / in the\n\t * outbox).\n\t *\n\t * Use this so `save()` can keep its `Promise<void>` return type: the\n\t * caller holds the aggregate reference, which is up to date after this\n\t * call.\n\t */\n\tpublic markPersisted(version: Version): void {\n\t\tthis.setVersion(version);\n\t\tthis._pendingEvents = [];\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 * { type: \"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\tprotected constructor(\n\t\tid: TId,\n\t\tinitialState: TState,\n\t\tconfig?: AggregateConfig,\n\t) {\n\t\tsuper(id, initialState);\n\t\tthis._config = config ?? {};\n\t\tthis._autoVersionBump = this._config.autoVersionBump ?? false;\n\t}\n\n\t/**\n\t * Records a domain event for later publication.\n\t *\n\t * **Ordering: record AFTER state mutation.** Vernon (IDDD §8) is\n\t * explicit: a domain event describes something that has just happened\n\t * to the aggregate — its existence implies the state change already\n\t * occurred. Concretely:\n\t *\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.setState({ ...this.state, status: \"confirmed\" }, true);\n\t * this.addDomainEvent({ type: \"OrderConfirmed\", orderId: this.id });\n\t * // ↑ post-mutation. The event represents the committed fact.\n\t * }\n\t * ```\n\t *\n\t * Recording before mutation is a footgun: if a subsequent invariant\n\t * check throws, the event has already been queued but the state never\n\t * actually changed — consumers see an event for a fact that did not\n\t * happen.\n\t *\n\t * `EventSourcedAggregate.apply()` enforces this ordering structurally;\n\t * `AggregateRoot` leaves it as a convention because the state-mutation\n\t * path (`setState`) is decoupled from event recording.\n\t *\n\t * @param event - The domain event to record\n\t */\n\tprotected addDomainEvent(event: TEvent): void {\n\t\tthis._pendingEvents.push(event);\n\t}\n\n\t/**\n\t * Manually bumps the aggregate version.\n\t * Call this after state changes for Optimistic Concurrency Control.\n\t *\n\t * If `autoVersionBump` is enabled, this is called automatically\n\t * when using `setState()`.\n\t */\n\tprotected bumpVersion(): void {\n\t\tthis.setVersion((this._version + 1) as Version);\n\t}\n\n\t/**\n\t * Sets the state and optionally bumps the version automatically.\n\t * This is a convenience method for state mutations.\n\t * Automatically validates the newState using `validateState()`.\n\t * Overrides Entity.setState to add version bumping.\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(\n\t\tnewState: TState,\n\t\tbumpVersion?: boolean,\n\t): 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 * Creates a snapshot of the current aggregate state.\n\t * Useful for performance optimization, backup/restore, and audit trails.\n\t *\n\t * @returns A snapshot containing the current state and version\n\t *\n\t * @example\n\t * ```typescript\n\t * const snapshot = aggregate.createSnapshot();\n\t * await snapshotRepository.save(aggregate.id, snapshot);\n\t * ```\n\t */\n\tpublic createSnapshot(): AggregateSnapshot<TState> {\n\t\treturn {\n\t\t\tstate: structuredClone(this._state),\n\t\t\tversion: this.version,\n\t\t\tsnapshotAt: new Date(),\n\t\t};\n\t}\n\n\t/**\n\t * Restores the aggregate from a snapshot.\n\t * This is useful for loading aggregates from snapshots instead of\n\t * rebuilding them from scratch.\n\t * Validates the restored state.\n\t *\n\t * @param snapshot - The snapshot to restore from\n\t *\n\t * @example\n\t * ```typescript\n\t * const snapshot = await snapshotRepository.getLatest(aggregateId);\n\t * aggregate.restoreFromSnapshot(snapshot);\n\t * ```\n\t */\n\tpublic restoreFromSnapshot(snapshot: AggregateSnapshot<TState>): void {\n\t\tconst cloned = structuredClone(snapshot.state);\n\t\tthis.validateState(cloned);\n\t\tthis._state = freezeShallow(cloned);\n\t\tthis.setVersion(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 { Entity, freezeShallow } from \"../entity/entity\";\nimport type { IAggregateRoot } from \"./aggregate-root\";\nimport type { AnyDomainEvent } from \"./domain-event\";\nimport type {\n\tAggregateSnapshot,\n\tVersion,\n} from \"./aggregate\";\n\n/**\n * Interface for Event-Sourced Aggregate Roots.\n * Defines the contract for aggregates that manage state changes via event sourcing.\n *\n * @template TId - The type of 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 `Result`\n\t * because event-stream corruption is an expected recoverable failure\n\t * at the infrastructure boundary.\n\t *\n\t * @param history - An ordered list of past events\n\t */\n\tloadFromHistory(history: ReadonlyArray<TEvent>): Result<void, DomainError>;\n}\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 boundary.\n * The difference is persistence: state is derived from events, not stored directly.\n * Events are the single source of truth — all state changes go through `apply()` → handler.\n *\n * Extends `Entity` directly (not `AggregateRoot`) so that `setState()` and\n * `addDomainEvent()` are not available. This enforces the event sourcing pattern\n * at the type level — there is no way to mutate state without going through an event handler.\n *\n * `apply()` and `validateEvent()` throw `DomainError`-derived exceptions on\n * invariant violations. Subclasses override `validateEvent()` to throw their\n * own concrete subclasses (e.g. `OrderAlreadyConfirmedError`). Only the\n * infrastructure-boundary methods (`loadFromHistory`,\n * `restoreFromSnapshotWithEvents`) return `Result` — they catch `DomainError`\n * during replay so callers can react to corrupted event streams without\n * try/catch.\n *\n * @template TState - The type of the aggregate state (contains child entities and value objects)\n * @template TEvent - The union type of all domain events\n * @template TId - The type of 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 * confirm(): void {\n * this.apply(createDomainEvent(\"OrderConfirmed\", {}));\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\tTState,\n\tTEvent extends AnyDomainEvent,\n\tTId extends Id<string>,\n> extends Entity<TState, TId>\n\timplements IEventSourcedAggregate<TId, TEvent> {\n\n\t// --- Version management (own, not inherited from AggregateRoot) ---\n\n\tprivate _version: Version = 0 as Version;\n\n\tpublic get version(): Version {\n\t\treturn this._version;\n\t}\n\n\tprivate setVersion(version: Version): void {\n\t\tthis._version = version;\n\t}\n\n\t// --- Event tracking ---\n\n\tprivate _pendingEvents: TEvent[] = [];\n\n\tpublic get pendingEvents(): ReadonlyArray<TEvent> {\n\t\treturn Object.freeze(this._pendingEvents.slice());\n\t}\n\n\tpublic clearPendingEvents(): void {\n\t\tthis._pendingEvents = [];\n\t}\n\n\t/**\n\t * Post-save hook called by a `Repository.save()` implementation to push\n\t * the persisted version back into the in-memory aggregate and clear the\n\t * pending events (they are now in the event store / outbox). Lets\n\t * `save()` keep its `Promise<void>` return type.\n\t */\n\tpublic markPersisted(version: Version): void {\n\t\tthis.setVersion(version);\n\t\tthis._pendingEvents = [];\n\t}\n\n\tprotected constructor(id: TId, initialState: TState) {\n\t\tsuper(id, initialState);\n\t}\n\n\t// --- Event application ---\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\t\t// no-op by default\n\t}\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\tconst handler = this.handlers[event.type as keyof typeof this.handlers] as\n\t\t\t| Handler<TState, TEvent>\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._pendingEvents.push(event);\n\t\t\tthis.setVersion((this._version + 1) as Version);\n\t\t}\n\t}\n\n\t// --- History & Snapshots ---\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 * 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(history: ReadonlyArray<TEvent>): Result<void, DomainError> {\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\tif (e instanceof DomainError) return err(e);\n\t\t\t\tthrow e;\n\t\t\t}\n\t\t}\n\t\tthis.setVersion((startVersion + history.length) as Version);\n\t\treturn ok();\n\t}\n\n\t/**\n\t * Creates a snapshot of the current aggregate state.\n\t */\n\tpublic createSnapshot(): AggregateSnapshot<TState> {\n\t\treturn {\n\t\t\tstate: structuredClone(this._state),\n\t\t\tversion: this._version,\n\t\t\tsnapshotAt: new Date(),\n\t\t};\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<TState>,\n\t\teventsAfterSnapshot: ReadonlyArray<TEvent>,\n\t): Result<void, DomainError> {\n\t\tconst previousState = this._state;\n\t\tconst previousVersion = this._version;\n\n\t\tthis._state = freezeShallow(structuredClone(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.setVersion((snapshot.version + eventsAfterSnapshot.length) as Version);\n\t\treturn ok();\n\t}\n\n\t/**\n\t * A map of event types to their corresponding handlers.\n\t * Subclasses MUST implement this property.\n\t */\n\tprotected abstract readonly handlers: {\n\t\t[K in TEvent[\"type\"]]: Handler<TState, Extract<TEvent, { type: K }>>;\n\t};\n}\n","import { err, type Result } from \"@shirudo/result\";\nimport type { Command, CommandHandler } from \"./command\";\n\n/**\n * Internal adapter shape for handlers stored in the map.\n *\n * Registered handlers are typed as `CommandHandler<C, TMap[K]>` — narrower\n * input, specific return — and cannot be stored directly in a heterogeneous\n * map (function-parameter contravariance). The closure in `register`\n * downcasts `Command` to the handler's expected `C` based on the\n * dispatch-key invariant (we only call this entry when `cmd.type` matches\n * the key it was registered under). Result is widened to `unknown` here\n * and narrowed back via the public overloads on `execute`.\n */\ntype StoredCommandHandler = (\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\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(\n\t\t\t\terror instanceof Error ? error.message : String(error),\n\t\t\t);\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 * 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 * 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 * @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},\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\tconst harvested = fnResult.aggregates.flatMap(\n\t\t\t\t(agg) => agg.pendingEvents,\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, 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\tagg.markPersisted(agg.version);\n\t}\n\n\tif (deps.bus && events.length > 0) {\n\t\tawait deps.bus.publish(events);\n\t}\n\n\treturn result;\n}\n","import { err, ok, type Result } from \"@shirudo/result\";\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\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(\n\t\t\t\terror instanceof Error ? error.message : String(error),\n\t\t\t);\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.\n\t\t\t\tconst results = await Promise.allSettled(\n\t\t\t\t\thandlersForType.slice().map((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: new Error(String(result.reason)),\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\treturn typeof limit === \"number\" ? all.slice(0, limit) : all;\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"]}
|
|
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/aggregate-root.ts","../src/core/errors.ts","../src/aggregate/event-sourced-aggregate.ts","../src/app/command-bus.ts","../src/app/handler.ts","../src/app/query-bus.ts","../src/events/event-bus.ts","../src/events/outbox.ts"],"names":["tagA","tagB","len","clone","err","ok"],"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 * The detection is purely tag-based — `Object.prototype.toString` reads\n * `Symbol.toStringTag`, which gives the same answer across realms (an\n * iframe's `Date` has the same tag as the main window's `Date`). The\n * previous strategy also checked `globalThis[name] === constructor` and a\n * `proto !== Object.prototype` heuristic; both broke for cross-realm\n * objects and the latter additionally misclassified ordinary user classes\n * as built-ins. Tag-only is the simplest robust choice.\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/**\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.\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// All TypedArrays produce tags ending in \"Array]\" — future-proof match.\n\tif (tag.endsWith(\"Array]\")) return true;\n\t// ArrayBuffer view covers DataView + all TypedArrays as a belt-and-braces.\n\tif (ArrayBuffer.isView(obj)) return true;\n\treturn BUILT_IN_TAGS.has(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 * 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 (arrA[i] !== arrB[i]) return false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t// 5. Tag-based type detection (robust across realms)\n\tconst tagA = objToString.call(objA);\n\tconst tagB = objToString.call(objB);\n\tif (tagA !== tagB) return false;\n\n\tswitch (tagA) {\n\t\tcase \"[object Array]\": {\n\t\t\tconst arrA = objA as unknown[];\n\t\t\tconst arrB = objB as unknown[];\n\t\t\tconst len = arrA.length;\n\t\t\tif (len !== arrB.length) return false;\n\n\t\t\tfor (let i = 0; i < len; i++) {\n\t\t\t\tif (!deepEqualInner(arrA[i], arrB[i], visited)) return false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\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\tconst timeA = (objA as Date).getTime();\n\t\t\tconst timeB = (objB as Date).getTime();\n\t\t\treturn timeA === timeB;\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)\n\t\t\treturn (objA as any).valueOf() === (objB as any).valueOf();\n\t\t}\n\n\t\tdefault: {\n\t\t\t// 6. Check if this is an unhandled built-in type (future-proof)\n\t\t\t// If both are built-ins but not handled above, they should be compared by reference\n\t\t\t// (since we don't know their internal structure)\n\t\t\tif (isBuiltInObject(objA, tagA) && isBuiltInObject(objB, tagB)) {\n\t\t\t\t// Unhandled built-in types: compare by reference as fallback\n\t\t\t\t// This ensures new built-ins don't fall through to plain object comparison\n\t\t\t\treturn objA === objB;\n\t\t\t}\n\n\t\t\t// 7. Fallback: plain / custom objects → compare own enumerable keys + values\n\t\t\tconst recA = objA as Record<string | symbol, unknown>;\n\t\t\tconst recB = objB as Record<string | symbol, unknown>;\n\n\t\t\tconst stringKeysA = Object.keys(objA as object);\n\t\t\tconst stringKeysB = Object.keys(objB as object);\n\t\t\tif (stringKeysA.length !== stringKeysB.length) return false;\n\n\t\t\tconst symbolKeysA = Object.getOwnPropertySymbols(objA as object);\n\t\t\tconst symbolKeysB = Object.getOwnPropertySymbols(objB as object);\n\t\t\tif (symbolKeysA.length !== symbolKeysB.length) return false;\n\n\t\t\t// Build the B-side symbol set once; the previous impl rebuilt the\n\t\t\t// array and ran .includes per key, which was quadratic.\n\t\t\tconst symbolKeysBSet = new Set<symbol>(symbolKeysB);\n\n\t\t\tfor (const key of stringKeysA) {\n\t\t\t\tif (!objHasOwn.call(objB, key)) return false;\n\t\t\t}\n\t\t\tfor (const key of symbolKeysA) {\n\t\t\t\tif (!symbolKeysBSet.has(key)) return false;\n\t\t\t}\n\n\t\t\tfor (const key of stringKeysA) {\n\t\t\t\tif (!deepEqualInner(recA[key], recB[key], visited)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const key of symbolKeysA) {\n\t\t\t\tif (!deepEqualInner(recA[key], recB[key], visited)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\t}\n}\n","import { isBuiltInObject } 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 (Date, RegExp, Map, Set,\n * TypedArrays, ArrayBuffer, DataView) are cloned by type rather than walked\n * — their internal structure has no key filtering to apply. Cycles are\n * preserved: a cycle `a → a` clones to `a' → a'`.\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\treturn omitInternal(value, options, ignoreKeys, [], visited) as T;\n}\n\nfunction omitInternal(\n\tvalue: unknown,\n\toptions: DeepOmitOptions,\n\tignoreKeys: ReadonlySet<Key> | undefined,\n\tpath: PathSegment[],\n\tvisited: WeakMap<object, unknown>,\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: return cached clone if already visited. Use `has` (not\n\t// `cached !== undefined`) so a legitimately-undefined cached clone\n\t// would not be misclassified as \"never seen\".\n\tif (visited.has(obj)) {\n\t\treturn visited.get(obj);\n\t}\n\n\tconst tag = Object.prototype.toString.call(obj);\n\n\t// Arrays: recursively process elements\n\tif (tag === \"[object Array]\") {\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(arr[i], options, ignoreKeys, path, visited);\n\t\t\tpath.pop();\n\t\t}\n\t\treturn clone;\n\t}\n\n\t// Built-in atomic types: clone by type rather than walk.\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),\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),\n\t\t);\n\t\tpath.pop();\n\t}\n\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. ArrayBuffer, DataView,\n * Boolean/Number/String wrappers).\n */\nfunction cloneBuiltIn(obj: object, tag: string): unknown {\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 { 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 * 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 */\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 if (visited.has(obj as object)) {\n return obj as Readonly<T>;\n }\n visited.add(obj as object);\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 * Creates a deeply immutable value object from the given data.\n *\n * The input is first deep-cloned with `structuredClone`, then the clone\n * is frozen — so calling `vo(input)` never freezes the caller's own\n * object graph as a side-effect. Mutating the input afterwards does not\n * bleed into the VO.\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(structuredClone(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 * @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: ${JSON.stringify(t)}`,\n );\n }\n return ok(vo(t));\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 deeply frozen to ensure immutability.\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 this.props = deepFreeze({ ...props });\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 * @param type - The event type\n * @param payload - The event payload\n * @param options - Optional event configuration\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\toccurredAt: options?.occurredAt ?? 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\treturn Object.assign({}, ...metadataObjects.filter(Boolean));\n}\n","import type { Id } from \"../core/id\";\n\n// Re-export domain event types for convenience\nexport * from \"./domain-event\";\n\n// Re-export interfaces from their respective files\nexport type { IAggregateRoot } from \"./aggregate-root\";\nexport type { IEventSourcedAggregate } from \"./event-sourced-aggregate\";\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 * 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\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(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 * @param newState - The new state\n\t */\n\tprotected setState(newState: TState): void {\n\t\tthis.validateState(newState);\n\t\tthis._state = freezeShallow(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/**\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, freezeShallow } from \"../entity/entity\";\nimport type {\n\tAggregateSnapshot,\n\tVersion,\n} from \"./aggregate\";\n\n/**\n * Marker interface for Aggregate Roots.\n *\n * In Domain-Driven Design, an Aggregate Root is an Entity (the parent Entity of the aggregate).\n * It represents the aggregate externally and is the only object that external code\n * is allowed to hold references to. All access to child entities within the aggregate\n * must go through the Aggregate Root.\n *\n * An Aggregate consists of:\n * - One Aggregate Root (Entity with id + version)\n * - Optional child entities (Entities with id + state, but no own version)\n * - Optional value objects\n *\n * The Aggregate Root has identity (id), state, and version for optimistic concurrency control.\n * Child entities exist only within the aggregate boundary and are versioned through\n * the Aggregate Root.\n *\n * @template TId - The type of the aggregate root identifier\n *\n * @example\n * ```typescript\n * class Order extends AggregateRoot<OrderState, OrderId> implements IAggregateRoot<OrderId> {\n * // Order is an Aggregate Root (an Entity with version)\n * // OrderState contains child entities (e.g., OrderItem) and value objects\n * }\n * ```\n */\nexport interface IAggregateRoot<TId extends Id<string>, TEvent = never> {\n\t/**\n\t * Unique identifier of the aggregate root entity.\n\t */\n\treadonly id: TId;\n\n\t/**\n\t * Version number for optimistic concurrency control.\n\t * Incremented on each state change to detect concurrent modifications.\n\t * This version applies to the entire aggregate, including all child entities.\n\t */\n\treadonly version: Version;\n\n\t/**\n\t * Read-only list of domain events recorded on this aggregate that have\n\t * not yet been flushed to the outbox / persistence layer. Both state-\n\t * stored (`AggregateRoot`) and event-sourced (`EventSourcedAggregate`)\n\t * aggregates expose them under the same name, so Repository.save() can\n\t * harvest them uniformly without branching on the aggregate flavour.\n\t */\n\treadonly pendingEvents: ReadonlyArray<TEvent>;\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\tclearPendingEvents(): void;\n\n\t/**\n\t * Post-save hook: a `Repository.save()` implementation calls this with\n\t * the persisted version after a successful write to push the new\n\t * version back into the aggregate and clear pendingEvents (they are\n\t * now safely on the write side / in the outbox).\n\t *\n\t * Required by the interface so a Repository implementation can call it\n\t * via the published `IAggregateRoot` contract without taking the\n\t * abstract class as a compile-time dependency.\n\t *\n\t * @param version - The version assigned by the persistence layer\n\t */\n\tmarkPersisted(version: Version): void;\n}\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 management for optimistic concurrency control\n * - Domain event tracking for side-effects\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 * constructor(id: OrderId, initialState: OrderState) {\n * super(id, initialState);\n * }\n *\n * confirm(): void {\n * this.setState({ ...this.state, status: \"confirmed\" }, true);\n * }\n * }\n * ```\n */\nexport abstract class AggregateRoot<\n\tTState,\n\tTId extends Id<string>,\n\tTEvent = never,\n>\n\textends Entity<TState, TId>\n\timplements IAggregateRoot<TId, TEvent> {\n\tprivate _version: Version = 0 as Version;\n\n\tpublic get version(): Version {\n\t\treturn this._version;\n\t}\n\n\tprotected setVersion(version: Version): void {\n\t\tthis._version = version;\n\t}\n\n\tprivate readonly _config: AggregateConfig;\n\tprivate readonly _autoVersionBump: boolean;\n\tprivate _pendingEvents: TEvent[] = [];\n\n\t/**\n\t * Read-only list of domain events recorded on this aggregate that have\n\t * 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. Call this after the events have been\n\t * dispatched (typically `markPersisted` handles it for you).\n\t */\n\tpublic clearPendingEvents(): void {\n\t\tthis._pendingEvents = [];\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.setVersion(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 * **`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\t\t// no-op by default\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 * { type: \"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\tprotected constructor(\n\t\tid: TId,\n\t\tinitialState: TState,\n\t\tconfig?: AggregateConfig,\n\t) {\n\t\tsuper(id, initialState);\n\t\tthis._config = config ?? {};\n\t\tthis._autoVersionBump = this._config.autoVersionBump ?? false;\n\t}\n\n\t/**\n\t * Records a domain event for later publication.\n\t *\n\t * **Ordering: record AFTER state mutation.** Vernon (IDDD §8) is\n\t * explicit: a domain event describes something that has just happened\n\t * to the aggregate — its existence implies the state change already\n\t * occurred. Concretely:\n\t *\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.setState({ ...this.state, status: \"confirmed\" }, true);\n\t * this.addDomainEvent({ type: \"OrderConfirmed\", orderId: this.id });\n\t * // ↑ post-mutation. The event represents the committed fact.\n\t * }\n\t * ```\n\t *\n\t * Recording before mutation is a footgun: if a subsequent invariant\n\t * check throws, the event has already been queued but the state never\n\t * actually changed — consumers see an event for a fact that did not\n\t * happen.\n\t *\n\t * `EventSourcedAggregate.apply()` enforces this ordering structurally;\n\t * `AggregateRoot` leaves it as a convention because the state-mutation\n\t * path (`setState`) is decoupled from event recording.\n\t *\n\t * @param event - The domain event to record\n\t */\n\tprotected addDomainEvent(event: TEvent): void {\n\t\tthis._pendingEvents.push(event);\n\t}\n\n\t/**\n\t * Manually bumps the aggregate version.\n\t * Call this after state changes for Optimistic Concurrency Control.\n\t *\n\t * If `autoVersionBump` is enabled, this is called automatically\n\t * when using `setState()`.\n\t */\n\tprotected bumpVersion(): void {\n\t\tthis.setVersion((this._version + 1) as Version);\n\t}\n\n\t/**\n\t * Sets the state and optionally bumps the version automatically.\n\t * This is a convenience method for state mutations.\n\t * Automatically validates the newState using `validateState()`.\n\t * Overrides Entity.setState to add version bumping.\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(\n\t\tnewState: TState,\n\t\tbumpVersion?: boolean,\n\t): 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 * Creates a snapshot of the current aggregate state.\n\t * Useful for performance optimization, backup/restore, and audit trails.\n\t *\n\t * @returns A snapshot containing the current state and version\n\t *\n\t * @example\n\t * ```typescript\n\t * const snapshot = aggregate.createSnapshot();\n\t * await snapshotRepository.save(aggregate.id, snapshot);\n\t * ```\n\t */\n\tpublic createSnapshot(): AggregateSnapshot<TState> {\n\t\treturn {\n\t\t\tstate: structuredClone(this._state),\n\t\t\tversion: this.version,\n\t\t\tsnapshotAt: new Date(),\n\t\t};\n\t}\n\n\t/**\n\t * Restores the aggregate from a snapshot.\n\t * This is useful for loading aggregates from snapshots instead of\n\t * rebuilding them from scratch.\n\t * Validates the restored state.\n\t *\n\t * @param snapshot - The snapshot to restore from\n\t *\n\t * @example\n\t * ```typescript\n\t * const snapshot = await snapshotRepository.getLatest(aggregateId);\n\t * aggregate.restoreFromSnapshot(snapshot);\n\t * ```\n\t */\n\tpublic restoreFromSnapshot(snapshot: AggregateSnapshot<TState>): void {\n\t\tconst cloned = structuredClone(snapshot.state);\n\t\tthis.validateState(cloned);\n\t\tthis._state = freezeShallow(cloned);\n\t\tthis.setVersion(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 { Entity, freezeShallow } from \"../entity/entity\";\nimport type { IAggregateRoot } from \"./aggregate-root\";\nimport type { AnyDomainEvent } from \"./domain-event\";\nimport type {\n\tAggregateSnapshot,\n\tVersion,\n} from \"./aggregate\";\n\n/**\n * Interface for Event-Sourced Aggregate Roots.\n * Defines the contract for aggregates that manage state changes via event sourcing.\n *\n * @template TId - The type of 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 `Result`\n\t * because event-stream corruption is an expected recoverable failure\n\t * at the infrastructure boundary.\n\t *\n\t * @param history - An ordered list of past events\n\t */\n\tloadFromHistory(history: ReadonlyArray<TEvent>): Result<void, DomainError>;\n}\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 boundary.\n * The difference is persistence: state is derived from events, not stored directly.\n * Events are the single source of truth — all state changes go through `apply()` → handler.\n *\n * Extends `Entity` directly (not `AggregateRoot`) so that `setState()` and\n * `addDomainEvent()` are not available. This enforces the event sourcing pattern\n * at the type level — there is no way to mutate state without going through an event handler.\n *\n * `apply()` and `validateEvent()` throw `DomainError`-derived exceptions on\n * invariant violations. Subclasses override `validateEvent()` to throw their\n * own concrete subclasses (e.g. `OrderAlreadyConfirmedError`). Only the\n * infrastructure-boundary methods (`loadFromHistory`,\n * `restoreFromSnapshotWithEvents`) return `Result` — they catch `DomainError`\n * during replay so callers can react to corrupted event streams without\n * try/catch.\n *\n * @template TState - The type of the aggregate state (contains child entities and value objects)\n * @template TEvent - The union type of all domain events\n * @template TId - The type of 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 * confirm(): void {\n * this.apply(createDomainEvent(\"OrderConfirmed\", {}));\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\tTState,\n\tTEvent extends AnyDomainEvent,\n\tTId extends Id<string>,\n> extends Entity<TState, TId>\n\timplements IEventSourcedAggregate<TId, TEvent> {\n\n\t// --- Version management (own, not inherited from AggregateRoot) ---\n\n\tprivate _version: Version = 0 as Version;\n\n\tpublic get version(): Version {\n\t\treturn this._version;\n\t}\n\n\tprivate setVersion(version: Version): void {\n\t\tthis._version = version;\n\t}\n\n\t// --- Event tracking ---\n\n\tprivate _pendingEvents: TEvent[] = [];\n\n\tpublic get pendingEvents(): ReadonlyArray<TEvent> {\n\t\treturn Object.freeze(this._pendingEvents.slice());\n\t}\n\n\tpublic clearPendingEvents(): void {\n\t\tthis._pendingEvents = [];\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.setVersion(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 * **`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\t\t// no-op by default\n\t}\n\n\tprotected constructor(id: TId, initialState: TState) {\n\t\tsuper(id, initialState);\n\t}\n\n\t// --- Event application ---\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\t\t// no-op by default\n\t}\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\tconst handler = this.handlers[event.type as keyof typeof this.handlers] as\n\t\t\t| Handler<TState, TEvent>\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._pendingEvents.push(event);\n\t\t\tthis.setVersion((this._version + 1) as Version);\n\t\t}\n\t}\n\n\t// --- History & Snapshots ---\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 * 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(history: ReadonlyArray<TEvent>): Result<void, DomainError> {\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\tif (e instanceof DomainError) return err(e);\n\t\t\t\tthrow e;\n\t\t\t}\n\t\t}\n\t\tthis.setVersion((startVersion + history.length) as Version);\n\t\treturn ok();\n\t}\n\n\t/**\n\t * Creates a snapshot of the current aggregate state.\n\t */\n\tpublic createSnapshot(): AggregateSnapshot<TState> {\n\t\treturn {\n\t\t\tstate: structuredClone(this._state),\n\t\t\tversion: this._version,\n\t\t\tsnapshotAt: new Date(),\n\t\t};\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<TState>,\n\t\teventsAfterSnapshot: ReadonlyArray<TEvent>,\n\t): Result<void, DomainError> {\n\t\tconst previousState = this._state;\n\t\tconst previousVersion = this._version;\n\n\t\tthis._state = freezeShallow(structuredClone(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.setVersion((snapshot.version + eventsAfterSnapshot.length) as Version);\n\t\treturn ok();\n\t}\n\n\t/**\n\t * A map of event types to their corresponding handlers.\n\t * Subclasses MUST implement this property.\n\t */\n\tprotected abstract readonly handlers: {\n\t\t[K in TEvent[\"type\"]]: Handler<TState, Extract<TEvent, { type: K }>>;\n\t};\n}\n","import { err, type Result } from \"@shirudo/result\";\nimport type { Command, CommandHandler } from \"./command\";\n\n/**\n * Internal adapter shape for handlers stored in the map.\n *\n * Registered handlers are typed as `CommandHandler<C, TMap[K]>` — narrower\n * input, specific return — and cannot be stored directly in a heterogeneous\n * map (function-parameter contravariance). The closure in `register`\n * downcasts `Command` to the handler's expected `C` based on the\n * dispatch-key invariant (we only call this entry when `cmd.type` matches\n * the key it was registered under). Result is widened to `unknown` here\n * and narrowed back via the public overloads on `execute`.\n */\ntype StoredCommandHandler = (\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\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(\n\t\t\t\terror instanceof Error ? error.message : String(error),\n\t\t\t);\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 * 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},\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\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\tagg.markPersisted(agg.version);\n\t}\n\n\tif (deps.bus && events.length > 0) {\n\t\tawait deps.bus.publish(events);\n\t}\n\n\treturn result;\n}\n","import { err, ok, type Result } from \"@shirudo/result\";\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\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(\n\t\t\t\terror instanceof Error ? error.message : String(error),\n\t\t\t);\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.\n\t\t\t\tconst results = await Promise.allSettled(\n\t\t\t\t\thandlersForType.slice().map((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: new Error(String(result.reason)),\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\treturn typeof limit === \"number\" ? all.slice(0, limit) : all;\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"]}
|