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

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.
@@ -1 +1 @@
1
- {"version":3,"file":"ports.js","names":[],"sources":["../../src/value-object/value-object.ts","../../src/aggregate/clock.ts","../../src/aggregate/domain-event-errors.ts","../../src/aggregate/domain-event.ts","../../src/events/ports.ts"],"sourcesContent":["import { deepEqual } from \"../utils/array/deep-equal\";\nimport {\n deepEqualExcept,\n type DeepEqualExceptOptions,\n} from \"../utils/array/deep-equal-except\";\nimport {\n builtInTagWithoutInvokingAccessors,\n hasIntrinsicPrototypeChain,\n isIntrinsicConstructorPrototype,\n mutableBuiltInTagWithoutInvokingAccessors,\n} from \"../utils/array/is-built-in\";\nimport { err, ok, type Result } from \"@shirudo/result\";\n\n// ============================================================================\n// Functional Value Object API\n// ============================================================================\n\nexport type VO<T> = Readonly<T>;\n\n/**\n * `Object.freeze` does not protect internal slots: a frozen Date still\n * accepts `setTime`, a frozen Map still accepts `set`. To make the\n * \"deeply immutable\" guarantee real, the mutator methods are shadowed\n * with own throwing functions BEFORE the freeze. The shadows are\n * non-enumerable, so they are invisible to `Object.keys`/spread (deep\n * equality is unaffected) and `structuredClone` drops them (a `vo()`\n * round-trip never sees them).\n */\nconst DATE_MUTATORS: readonly string[] = [\n \"setTime\",\n \"setMilliseconds\",\n \"setUTCMilliseconds\",\n \"setSeconds\",\n \"setUTCSeconds\",\n \"setMinutes\",\n \"setUTCMinutes\",\n \"setHours\",\n \"setUTCHours\",\n \"setDate\",\n \"setUTCDate\",\n \"setMonth\",\n \"setUTCMonth\",\n \"setFullYear\",\n \"setUTCFullYear\",\n \"setYear\",\n];\n\n// One thrower function per (typeName, method) for the lifetime of the\n// module: createDomainEvent deep-freezes a Date per event, so fresh\n// per-instance closures would be pure allocation churn on a hot path.\nconst mutationThrowers = new Map<string, () => never>();\nconst mapEntries = Map.prototype.entries;\nconst setValues = Set.prototype.values;\n\nfunction mutationThrower(typeName: string, method: string): () => never {\n const key = `${typeName}.${method}`;\n let thrower = mutationThrowers.get(key);\n if (!thrower) {\n thrower = function throwFrozenMutation(): never {\n throw new TypeError(\n `Cannot call ${method}() on a ${typeName} inside a deeply frozen value`,\n );\n };\n mutationThrowers.set(key, thrower);\n }\n return thrower;\n}\n\n// Reused descriptor: Object.defineProperty reads it synchronously, so a\n// single mutable module-level object avoids one allocation per method.\nconst shadowDescriptor = {\n value: undefined as unknown,\n writable: false,\n enumerable: false,\n configurable: false,\n};\n\nfunction shadowMutators(\n obj: object,\n typeName: string,\n methods: readonly string[],\n): void {\n // A non-extensible built-in (frozen, sealed, or preventExtensions'd)\n // cannot receive shadow properties, so skip it (best effort; the caller\n // chose to lock it themselves).\n if (!Object.isExtensible(obj)) return;\n for (const method of methods) {\n shadowDescriptor.value = mutationThrower(typeName, method);\n Object.defineProperty(obj, method, shadowDescriptor);\n }\n}\n\n/**\n * Deep freezes an object and all its nested properties recursively, then\n * returns it. Iterates both string-keyed and symbol-keyed own properties\n * so the freeze symmetry matches `deepEqual` (which also considers symbol\n * keys). Handles circular references by tracking visited objects.\n *\n * Note: `deepFreeze` mutates its argument in place; it sets `[[Frozen]]`\n * on the object you pass in. Callers that need to avoid touching the\n * input (e.g. `vo()`) should deep-clone first.\n *\n * Date/Map/Set keep internal-slot mutability under `Object.freeze`\n * (`setTime`, `set`, `add`, … still work on frozen instances), so their\n * mutator methods are shadowed with throwing own properties and Map/Set\n * contents are frozen recursively. The shadows are non-enumerable:\n * invisible to `Object.keys`, spread, `deepEqual`, and `structuredClone`.\n *\n * The shadowing is deny-by-enumeration: only the mutators known at\n * release time are blocked. If the runtime grows a NEW mutator (e.g. the\n * stage-3 `Map.prototype.getOrInsert` upsert proposal), it is not blocked\n * until the list is updated. Treat the mutator blocking as a guard rail,\n * not a security boundary.\n *\n * Limitation: ArrayBuffer views (TypedArrays, DataView) are passed through\n * unfrozen, because the spec forbids freezing a view with elements, and\n * freezing cannot protect the underlying buffer. Their contents remain mutable.\n */\nexport function deepFreeze<T>(obj: T, visited = new WeakSet<object>()): Readonly<T> {\n if (obj === null || typeof obj !== \"object\") {\n return obj as Readonly<T>;\n }\n // ArrayBuffer views are atomic: Object.freeze on a typed array with\n // elements throws per spec, and freezing cannot protect the underlying\n // buffer anyway, so views are returned as-is (their contents stay\n // mutable). Mirrors deepEqual, which also treats views atomically.\n if (ArrayBuffer.isView(obj)) {\n return obj as Readonly<T>;\n }\n if (visited.has(obj as object)) {\n return obj as Readonly<T>;\n }\n visited.add(obj as object);\n\n // Date/Map/Set keep internal-slot mutability under Object.freeze:\n // shadow their mutators and freeze Map/Set contents (entries are not\n // own keys, so the key walk below would miss them). Internal-slot brand\n // probes distinguish genuine built-ins without invoking toStringTag\n // accessors; spoofed plain objects are frozen structurally.\n const mutableBuiltInTag = mutableBuiltInTagWithoutInvokingAccessors(\n obj as object,\n );\n if (mutableBuiltInTag !== undefined) {\n if (mutableBuiltInTag === \"[object Date]\") {\n shadowMutators(obj as object, \"Date\", DATE_MUTATORS);\n } else if (mutableBuiltInTag === \"[object Map]\") {\n for (const [key, value] of obj as unknown as Map<\n unknown,\n unknown\n >) {\n deepFreeze(key, visited);\n deepFreeze(value, visited);\n }\n shadowMutators(obj as object, \"Map\", [\"set\", \"delete\", \"clear\"]);\n } else if (mutableBuiltInTag === \"[object Set]\") {\n for (const member of obj as unknown as Set<unknown>) {\n deepFreeze(member, visited);\n }\n shadowMutators(obj as object, \"Set\", [\"add\", \"delete\", \"clear\"]);\n }\n }\n\n // Reflect.ownKeys returns both string and symbol own keys.\n const keys = Reflect.ownKeys(obj);\n for (const key of keys) {\n const value = (obj as Record<string | symbol, unknown>)[key];\n if (value !== null && typeof value === \"object\") {\n deepFreeze(value, visited);\n }\n }\n\n return Object.freeze(obj) as Readonly<T>;\n}\n\n/**\n * Deep clone used by `vo()` and the `ValueObject` constructor.\n *\n * Plain objects, arrays, and Map values are walked manually so\n * that symbol-keyed properties survive (which `structuredClone` silently\n * drops; they would otherwise be invisible to `voEquals`, whose\n * `deepEqual` DOES consider symbol keys) and shared references / cycles\n * keep their identity across Map boundaries. Function values throw,\n * preserving `vo()`'s documented data-not-behaviour gate. Built-ins without\n * immutable value semantics throw a descriptive `TypeError`. Custom class\n * instances and subclasses of built-ins are rejected because cloning them\n * without invoking their\n * constructor can silently lose private or non-enumerable state. Map keys\n * and Set members must be primitive because their equality is\n * identity-based and object identity cannot survive defensive cloning.\n * Accessor properties are rejected without invoking them. Admitted atomic\n * built-ins (Date, RegExp and primitive wrappers) delegate to\n * `structuredClone`, brand-verified so a `Symbol.toStringTag` spoofer is\n * walked as the plain object it is. `__proto__` own keys are copied as\n * inert data properties.\n */\nfunction cloneForVo(value: unknown, visited: WeakMap<object, unknown>): unknown {\n if (typeof value === \"function\") {\n throw new TypeError(\n \"vo() does not accept function values: Value Objects are data, not behaviour\",\n );\n }\n if (value === null || typeof value !== \"object\") {\n return value;\n }\n const obj = value as object;\n if (ArrayBuffer.isView(obj)) {\n throwUnsupportedValueSemantics(\n builtInTagWithoutInvokingAccessors(obj) ??\n \"[object ArrayBuffer view]\",\n );\n }\n if (visited.has(obj)) {\n return visited.get(obj);\n }\n\n if (Array.isArray(obj)) {\n if (!hasIntrinsicPrototypeChain(obj, \"Array\")) {\n throwUnsupportedClassInstance();\n }\n const clone: unknown[] = new Array(obj.length);\n visited.set(obj, clone);\n for (const key of Reflect.ownKeys(obj)) {\n if (key === \"length\") continue;\n const descriptor = Object.getOwnPropertyDescriptor(obj, key);\n if (descriptor === undefined) continue;\n if (!(\"value\" in descriptor)) {\n throwUnsupportedAccessorProperty();\n }\n // Drop non-enumerable string keys just like the plain-object branch\n // below, so an array and an object carrying the same hidden property\n // clone to the same value surface. Array indices are enumerable and\n // therefore preserved.\n if (typeof key === \"string\" && !descriptor.enumerable) continue;\n descriptor.value = cloneForVo(descriptor.value, visited);\n Object.defineProperty(clone, key, descriptor);\n }\n return clone;\n }\n\n const tag = builtInTagWithoutInvokingAccessors(obj);\n if (tag !== undefined) {\n if (!hasIntrinsicPrototypeChain(obj)) {\n throwUnsupportedClassInstance();\n }\n if (tag === \"[object Map]\") {\n const clone = new Map<unknown, unknown>();\n visited.set(obj, clone);\n for (const [key, entry] of mapEntries.call(\n obj as Map<unknown, unknown>,\n )) {\n if (!isPrimitiveValue(key)) {\n throw new TypeError(\n \"vo() Map keys must be primitive values to preserve value equality\",\n );\n }\n clone.set(key, cloneForVo(entry, visited));\n }\n return clone;\n }\n if (tag === \"[object Set]\") {\n const clone = new Set<unknown>();\n visited.set(obj, clone);\n for (const member of setValues.call(obj as Set<unknown>)) {\n if (!isPrimitiveValue(member)) {\n throw new TypeError(\n \"vo() Set members must be primitive values to preserve value equality\",\n );\n }\n clone.add(member);\n }\n return clone;\n }\n if (\n tag === \"[object Promise]\" ||\n tag === \"[object WeakMap]\" ||\n tag === \"[object WeakSet]\"\n ) {\n throw new TypeError(\n `vo() cannot clone a ${tag.slice(8, -1)}: Value Objects are plain data`,\n );\n }\n if (\n tag === \"[object Error]\" ||\n tag === \"[object ArrayBuffer]\" ||\n tag === \"[object SharedArrayBuffer]\"\n ) {\n throwUnsupportedValueSemantics(tag);\n }\n if (tag === \"[object RegExp]\") {\n // A global or sticky RegExp carries observable mutable scan state:\n // every test()/exec() writes lastIndex, so it is a stateful object,\n // not a value. Deep-freezing it makes lastIndex non-writable and\n // crashes matching, so reject it instead of admitting a half-frozen\n // value. A plain (non-global, non-sticky) RegExp never touches\n // lastIndex and stays a genuine immutable value.\n const regExp = obj as RegExp;\n if (regExp.global || regExp.sticky) {\n throw new TypeError(\n \"vo() cannot accept a global or sticky RegExp: its lastIndex is mutable scan state, not an immutable value\",\n );\n }\n }\n // Atomic built-ins admitted by the VO contract: Date, RegExp and\n // primitive wrappers all have stable value semantics in deepEqual.\n const builtInClone = structuredClone(obj);\n visited.set(obj, builtInClone);\n return builtInClone;\n }\n\n const prototype = Object.getPrototypeOf(obj);\n if (\n prototype !== null &&\n (!isIntrinsicConstructorPrototype(prototype, \"Object\") ||\n Object.getPrototypeOf(prototype) !== null)\n ) {\n throwUnsupportedClassInstance();\n }\n\n // Normalize cross-realm records to the local Object prototype.\n const clone = Object.create(prototype === null ? null : Object.prototype);\n visited.set(obj, clone);\n for (const key of Reflect.ownKeys(obj)) {\n const descriptor = Object.getOwnPropertyDescriptor(obj, key);\n if (descriptor === undefined) continue;\n if (!(\"value\" in descriptor)) {\n throwUnsupportedAccessorProperty();\n }\n if (typeof key === \"string\" && !descriptor.enumerable) continue;\n // defineProperty (not assignment) so an own \"__proto__\" key can\n // never invoke the prototype setter.\n Object.defineProperty(clone, key, {\n value: cloneForVo(descriptor.value, visited),\n writable: true,\n enumerable: descriptor.enumerable,\n configurable: true,\n });\n }\n return clone;\n}\n\nfunction throwUnsupportedClassInstance(): never {\n throw new TypeError(\n \"vo() cannot clone custom class instances: Value Objects are plain data\",\n );\n}\n\nfunction throwUnsupportedAccessorProperty(): never {\n throw new TypeError(\n \"vo() cannot clone accessor properties: Value Objects are plain data\",\n );\n}\n\nfunction throwUnsupportedValueSemantics(tag: string): never {\n const name = tag.startsWith(\"[object \") ? tag.slice(8, -1) : tag;\n throw new TypeError(\n `vo() cannot accept ${name} values: Value Objects require immutable value semantics`,\n );\n}\n\nfunction isPrimitiveValue(value: unknown): boolean {\n return (\n value === null ||\n (typeof value !== \"object\" && typeof value !== \"function\")\n );\n}\n\n/**\n * Creates a deeply immutable value object from the given data.\n *\n * The input is first deep-cloned, then the clone is frozen, so calling\n * `vo(input)` never freezes the caller's own object graph as a\n * side-effect. Mutating the input afterwards does not bleed into the VO.\n * Symbol-keyed properties are preserved (matching `voEquals`); function\n * values and custom class instances are rejected (Value Objects are plain\n * data, not behaviour-bearing object graphs). Inputs must be trusted and\n * Proxy-free: ECMAScript provides no portable way to identify a transparent\n * Proxy without potentially executing its traps, so `vo()` is not a sandbox\n * for hostile in-process objects. Built-ins that cannot provide immutable,\n * value-based semantics are rejected instead of weakening the VO contract.\n *\n * @example\n * ```typescript\n * const nested = { lat: 52.5, lng: 13.4 };\n * const address = vo({ street: \"Main St\", coordinates: nested });\n * address.coordinates.lat = 99; // ❌ Cannot assign to read-only property\n * nested.lat = 0; // ✅ caller's input still mutable\n * ```\n */\nexport function vo<T>(t: T): VO<T> {\n return deepFreeze(cloneForVo(t, new WeakMap()) as T);\n}\n\n/**\n * Compares two value objects for equality based on their values.\n * Uses deep equality comparison that handles:\n * - Nested objects and arrays\n * - Primitives (including NaN)\n * - Dates, Maps, Sets, RegExp\n * - Symbol keys\n * - Circular references\n *\n * @param a - First value object\n * @param b - Second value object\n * @returns true if both objects have the same values, false otherwise\n *\n * @example\n * ```typescript\n * const money1 = vo({ amount: 100, currency: \"USD\" });\n * const money2 = vo({ amount: 100, currency: \"USD\" });\n * voEquals(money1, money2); // true\n *\n * const address1 = vo({\n * street: \"Main St\",\n * coordinates: { lat: 52.5, lng: 13.4 }\n * });\n * const address2 = vo({\n * street: \"Main St\",\n * coordinates: { lat: 52.5, lng: 13.4 }\n * });\n * voEquals(address1, address2); // true\n * ```\n */\nexport function voEquals<T>(a: VO<T>, b: VO<T>): boolean {\n return deepEqual(a, b);\n}\n\n/**\n * Compares two value objects for equality while ignoring specified keys.\n * Useful for comparing value objects that contain metadata or optional fields\n * that should not affect equality comparison.\n *\n * @param a - First value object\n * @param b - Second value object\n * @param options - Options specifying which keys to ignore during comparison\n * @returns true if both objects have the same values (after ignoring specified keys), false otherwise\n *\n * @example\n * ```typescript\n * // Value object with metadata\n * const address1 = vo({\n * street: \"Main St\",\n * city: \"Berlin\",\n * metadata: { createdAt: \"2024-01-01\", updatedAt: \"2024-01-02\" }\n * });\n *\n * const address2 = vo({\n * street: \"Main St\",\n * city: \"Berlin\",\n * metadata: { createdAt: \"2024-01-01\", updatedAt: \"2024-01-03\" }\n * });\n *\n * // Compare ignoring metadata timestamps\n * voEqualsExcept(address1, address2, {\n * ignoreKeys: [\"updatedAt\"],\n * ignoreKeyPredicate: (key, path) => path.includes(\"metadata\")\n * }); // true\n *\n * // Compare ignoring all metadata\n * voEqualsExcept(address1, address2, {\n * ignoreKeyPredicate: (key, path) => path.includes(\"metadata\")\n * }); // true\n * ```\n */\nexport function voEqualsExcept<T>(\n a: VO<T>,\n b: VO<T>,\n options: DeepEqualExceptOptions,\n): boolean {\n return deepEqualExcept(a, b, options);\n}\n\n/**\n * Creates a value object with optional validation.\n * Returns a Result type instead of throwing an error.\n *\n * Note: the Result covers VALIDATION failures only. Non-data values and\n * built-ins without immutable value semantics still throw a\n * `TypeError` from `vo()`; they cannot occur in parsed JSON and signal\n * a programming error, not a validation failure.\n *\n * @param t - The data to convert into a value object\n * @param validate - Validation function that returns true if valid\n * @param errorMessage - Optional custom error message if validation fails\n * @returns Result containing the value object if valid, or an error message if validation fails\n *\n * @example\n * ```typescript\n * const result = voWithValidation(\n * { amount: 100, currency: \"USD\" },\n * (m) => m.amount >= 0 && m.currency.length === 3,\n * \"Invalid money: amount must be non-negative and currency must be 3 characters\"\n * );\n *\n * if (result.ok) {\n * console.log(result.value); // Use the value object\n * } else {\n * console.error(result.error); // Handle validation error\n * }\n * ```\n */\nexport function voWithValidation<T>(\n t: T,\n validate: (value: T) => boolean,\n errorMessage?: string,\n): Result<VO<T>, string> {\n if (!validate(t)) {\n return err(\n errorMessage ?? `Validation failed for value object: ${describeValue(t)}`,\n );\n }\n return ok(vo(t));\n}\n\n/**\n * Best-effort rendering of a value for the default validation-failure\n * message. `JSON.stringify` throws for cyclic and BigInt-bearing values, and\n * the error path of a Result-returning function must never throw itself.\n */\nfunction describeValue(value: unknown): string {\n try {\n const json = JSON.stringify(value);\n if (json !== undefined) return json;\n } catch {\n // Cyclic or BigInt-bearing values cannot be JSON-serialised.\n }\n return String(value);\n}\n\n// ============================================================================\n// Class-based Value Object API\n// ============================================================================\n\n/**\n * Interface for Value Objects.\n * Value Objects are immutable and defined by their properties.\n *\n * @template T - The shape of the value object's properties\n */\nexport interface IValueObject<T extends object> {\n /**\n * The immutable properties of the value object.\n */\n readonly props: Readonly<T>;\n\n /**\n * Checks if this value object is equal to another.\n * Uses deep equality comparison on the properties.\n *\n * @param other - The other value object to compare\n * @returns true if the properties are deeply equal\n */\n equals(other: IValueObject<T>): boolean;\n\n /**\n * Creates a clone of the value object with optional property overrides.\n *\n * @param props - Optional properties to override\n * @returns A new instance of the value object\n */\n clone(props?: Partial<T>): IValueObject<T>;\n\n /**\n * Serializes the value object to its raw properties for JSON operations.\n *\n * @returns The raw properties object\n */\n toJSON(): Readonly<T>;\n}\n\n/**\n * Abstract base class for creating Value Objects.\n * Value Objects are immutable and defined by their properties.\n *\n * @template T - The shape of the value object's properties\n */\nexport abstract class ValueObject<T extends object> implements IValueObject<T> {\n public readonly props: Readonly<T>;\n\n /**\n * Creates a new ValueObject.\n * The plain-data properties are deep-cloned and then deeply\n * frozen, so the caller's own object graph is never frozen or mutated,\n * and later mutation of the input does not bleed into the value object.\n *\n * @param props - The properties of the value object\n * @example\n * ```ts\n * class Money extends ValueObject<{ amount: number; currency: string }> {\n * constructor(props: { amount: number; currency: string }) {\n * super(props);\n * }\n *\n * protected validate(props: { amount: number; currency: string }): void {\n * if (props.amount < 0) throw new Error(\"Amount cannot be negative\");\n * }\n * }\n * ```\n */\n constructor(props: T) {\n this.validate(props);\n // Same clone as vo(): Map/Set contents are walked (so the caller's\n // entries are never frozen or shadowed in place), and functions and\n // custom class instances are rejected. A shallow `{ ...props }` or\n // deepOmit (which aliases reference-compared built-ins by design)\n // would let deepFreeze reach caller-owned objects.\n this.props = deepFreeze(cloneForVo(props, new WeakMap()) as T);\n }\n\n /**\n * Optional validation hook that can be overridden by subclasses.\n * Should throw an error if validation fails.\n *\n * @param props - The properties to validate\n * @throws Error if validation fails\n */\n protected validate(props: T): void {\n // Default implementation does nothing\n }\n\n /**\n * Checks if this value object is equal to another.\n * Uses deep equality comparison on the properties and checks for constructor equality.\n *\n * @param other - The other value object to compare\n * @returns true if the properties are deeply equal and constructors match\n */\n public equals(other: ValueObject<T>): boolean {\n if (other === null || other === undefined) {\n return false;\n }\n\n if (this.constructor !== other.constructor) {\n return false;\n }\n\n return deepEqual(this.props, other.props);\n }\n\n /**\n * Creates a clone of the value object with optional property overrides.\n *\n * @param props - Optional properties to override\n * @returns A new instance of the value object\n */\n public clone(props?: Partial<T>): this {\n const Constructor = this.constructor as new (props: T) => this;\n const merged = { ...this.props, ...(props || {}) } as T;\n // A `{ ...spread }` copies only enumerable own keys, so any\n // non-enumerable own property that cloneForVo preserved on this.props\n // (e.g. a non-enumerable symbol) would be dropped, making\n // `x.equals(x.clone())` false because deepEqual counts all own symbols.\n // Re-attach every non-enumerable own key the caller did not override.\n for (const key of Reflect.ownKeys(this.props)) {\n const descriptor = Object.getOwnPropertyDescriptor(this.props, key);\n if (descriptor === undefined || descriptor.enumerable) continue;\n if (props && Object.hasOwn(props, key)) continue;\n Object.defineProperty(merged, key, {\n value: (this.props as Record<PropertyKey, unknown>)[\n key as PropertyKey\n ],\n writable: true,\n enumerable: false,\n configurable: true,\n });\n }\n return new Constructor(merged);\n }\n\n /**\n * Serializes the value object to its raw properties for JSON operations.\n *\n * @returns The raw properties object\n */\n public toJSON(): Readonly<T> {\n return this.props;\n }\n\n\n}\n","/**\n * Clock function producing a valid `Date` for the current instant.\n * Event-clock reads throw `TypeError` when the result is invalid.\n */\nexport type ClockFactory = () => Date;\n\n/** Immutable library default captured by the default domain-event factory. */\nexport const defaultClockFactory: ClockFactory = () => new Date();\n\n/** Internal defensive event-clock read. */\nexport function readClock(factory: ClockFactory): Date {\n\tconst reading = factory();\n\tconst value = reading instanceof Date ? reading.getTime() : Number.NaN;\n\tif (!Number.isFinite(value)) {\n\t\tthrow new TypeError(\"domain-event clock must return a valid Date\");\n\t}\n\treturn new Date(value);\n}\n","export type DomainEventValidationCode =\n\t| \"EVENT_ID_REQUIRED\"\n\t| \"EVENT_ID_INVALID\"\n\t| \"EVENT_TYPE_INVALID\"\n\t| \"EVENT_OCCURRED_AT_REQUIRED\"\n\t| \"EVENT_OCCURRED_AT_INVALID\"\n\t| \"EVENT_SCHEMA_VERSION_INVALID\"\n\t| \"EVENT_ADDRESS_INVALID\";\n\nexport type DomainEventValidationField =\n\t| \"eventId\"\n\t| \"type\"\n\t| \"occurredAt\"\n\t| \"version\"\n\t| \"aggregateId\"\n\t| \"aggregateType\";\n\n/**\n * Stable contract error for malformed domain-event data.\n *\n * It remains a `TypeError` for JavaScript callers while exposing a code and\n * field that do not depend on the wording of the human-readable message.\n */\nexport class DomainEventValidationError extends TypeError {\n\t// The kit's error identity model applies here too: name === code, so\n\t// there is no second identifier to keep in sync.\n\toverride readonly name: string;\n\n\tconstructor(\n\t\treadonly code: DomainEventValidationCode,\n\t\treadonly field: DomainEventValidationField,\n\t\tmessage: string,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = code;\n\t\tObject.setPrototypeOf(this, new.target.prototype);\n\t}\n}\n\nexport class SnapshotTimeValidationError extends TypeError {\n\toverride readonly name = \"SNAPSHOT_TIME_INVALID\";\n\treadonly code = \"SNAPSHOT_TIME_INVALID\" as const;\n\treadonly field = \"snapshotAt\" as const;\n\n\tconstructor() {\n\t\tsuper(\"snapshotAt must be a valid Date\");\n\t\tObject.setPrototypeOf(this, new.target.prototype);\n\t}\n}\n","import { assertNoHostileOwnProtoKey } from \"../core/errors\";\nimport { deepFreeze } from \"../value-object/value-object\";\nimport { type ClockFactory, defaultClockFactory, readClock } from \"./clock\";\nimport { DomainEventValidationError } from \"./domain-event-errors\";\n\nexport type { ClockFactory } from \"./clock\";\n\n/**\n * Factory function producing a fresh, unique event identifier for each call.\n *\n * The library ships a default that uses Web Crypto `crypto.randomUUID()`\n * (works on Node 19+, modern browsers in secure contexts, Deno, Bun,\n * Cloudflare Workers, Vercel Edge, and any runtime that implements Web\n * Crypto). Note that `crypto.randomUUID()` returns **UUID v4** (purely\n * random); for production event stores prefer a **time-ordered** id\n * format (UUID v7 / ULID / KSUID) so B-tree indexes on the eventId\n * column stay clustered and `ORDER BY eventId` matches creation order.\n * Supply one to {@link createDomainEventFactory} to use UUID v7, ULID,\n * KSUID, or another collision-safe format without mutating module state.\n */\nexport type EventIdFactory = () => string;\n\nconst defaultEventIdFactory: EventIdFactory = () => crypto.randomUUID();\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\treadonly correlationId?: string;\n\n\t/**\n\t * Conversation ID shared by every message in one long-running business\n\t * interaction, even when that interaction spans several correlations.\n\t */\n\treadonly conversationId?: 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\treadonly causationId?: string;\n\n\t/**\n\t * W3C Trace Context parent for technical tracing across process boundaries.\n\t * This is distinct from business correlation and conversation identifiers.\n\t */\n\treadonly traceparent?: string;\n\n\t/** Optional W3C vendor trace state associated with `traceparent`. */\n\treadonly tracestate?: string;\n\n\t/**\n\t * User ID of the person or system that triggered the event.\n\t */\n\treadonly userId?: string;\n\n\t/**\n\t * Source service or component that produced the event.\n\t */\n\treadonly source?: string;\n\n\t/**\n\t * Additional custom metadata fields.\n\t * Allows extensibility for domain-specific metadata.\n\t */\n\treadonly [key: string]: unknown;\n}\n\n/**\n * Domain Event represents something meaningful that happened in the domain.\n * Events are immutable and carry information about what occurred.\n *\n * **Events are PLAIN DATA objects**, constructed via `createDomainEvent`\n * (or the aggregate's `createEvent` plus application-shell recording path)\n * and deeply frozen. Class-based\n * event objects that satisfy this shape structurally via prototype\n * members are unsupported.\n *\n * **Field-accretion boundary.** Persistence positions, commit boundaries,\n * broker offsets, and other delivery concerns belong in an event envelope,\n * not on the domain event itself.\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`. Convenience constructors default to\n\t * `crypto.randomUUID()`; strict construction requires the caller to supply it.\n\t */\n\treadonly eventId: string;\n\n\t/**\n\t * The type of the event, used for routing and handling.\n\t */\n\treadonly type: 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\treadonly aggregateId?: 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\treadonly aggregateType?: 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\treadonly payload: P;\n\n\t/**\n\t * Timestamp when the accepted fact was recorded by the application shell.\n\t * Put business-relevant time in the payload under a domain name.\n\t */\n\treadonly occurredAt: Date;\n\n\t/**\n\t * Event schema version for handling schema evolution.\n\t * Required for safe schema migration in event-sourced systems.\n\t * Use 1 for the initial schema version.\n\t *\n\t * This is the event PAYLOAD schema version, not a persisted aggregate\n\t * position. Commit positions live on `CommittedDomainEvent`.\n\t */\n\treadonly version: number;\n\n\t/**\n\t * Optional metadata for traceability, correlation, and auditing.\n\t * Includes correlationId, conversationId, causationId, userId, source, and\n\t * custom fields.\n\t */\n\treadonly metadata?: 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 * A domain event accepted by an aggregate but not yet given its recording\n * identity, recording time, or delivery metadata.\n *\n * The aggregate owns the event type, payload, source address, and payload\n * schema version because those values describe the business fact it produced.\n * The application shell later turns this value into a {@link DomainEvent}.\n */\nexport interface UncommittedDomainEvent<T extends string, P = void> {\n\treadonly type: T;\n\treadonly aggregateId?: string;\n\treadonly aggregateType?: string;\n\treadonly payload: P;\n\treadonly version: number;\n}\n\n/** Upper-bound alias for any uncommitted domain-event shape. */\nexport type AnyUncommittedDomainEvent = UncommittedDomainEvent<string, unknown>;\n\n/** Derives the uncommitted shape represented by a concrete event or event union. */\nexport type UncommittedDomainEventOf<TEvent extends AnyDomainEvent> =\n\tTEvent extends DomainEvent<infer TType, infer TPayload>\n\t\t? UncommittedDomainEvent<TType, TPayload>\n\t\t: never;\n\n/** An aggregate may hold unstamped decisions and already recorded events together. */\nexport type PendingDomainEvent<TEvent extends AnyDomainEvent> =\n\t| TEvent\n\t| UncommittedDomainEventOf<TEvent>;\n\n/** Producer-owned options for an uncommitted event. */\nexport interface CreateUncommittedDomainEventOptions {\n\treadonly aggregateId?: string;\n\treadonly aggregateType?: string;\n\treadonly version?: number;\n}\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/** Technical recording data attached by the application shell. */\nexport interface DomainEventStamp {\n\t/** Stable identity for this event instance. */\n\treadonly eventId: string;\n\t/** Time at which the accepted domain fact was recorded. */\n\treadonly occurredAt: Date;\n\t/** Optional correlation, causation, actor, and source metadata. */\n\treadonly metadata?: EventMetadata;\n}\n\n/** Full strict-construction options, including producer-owned event fields. */\nexport interface CreateDomainEventFromFactsOptions extends DomainEventStamp {\n\treadonly aggregateId?: string;\n\treadonly aggregateType?: string;\n\treadonly version?: number;\n}\n\n/** Overrides accepted when an application-shell factory creates a stamp. */\nexport interface CreateDomainEventStampOptions {\n\treadonly eventId?: string;\n\treadonly occurredAt?: Date;\n\treadonly metadata?: EventMetadata;\n}\n\n/** Dependencies captured by one immutable domain-event factory instance. */\nexport interface DomainEventFactoryOptions {\n\t/** Event-id generator. Defaults to Web Crypto `crypto.randomUUID()`. */\n\treadonly eventIdFactory?: EventIdFactory;\n\t/** Event-recording clock. Defaults to `() => new Date()`. */\n\treadonly clock?: ClockFactory;\n}\n\n/**\n * Instance-bound event constructor. Each factory permanently captures its\n * own event-id and clock dependencies, so request and test instances cannot\n * overwrite one another through module state.\n */\nexport interface DomainEventFactory {\n\t/**\n\t * Creates immutable technical recording data in the application shell.\n\t */\n\treadonly createStamp: (\n\t\toptions?: CreateDomainEventStampOptions,\n\t) => DomainEventStamp;\n\treadonly create: {\n\t\t<T extends string>(\n\t\t\ttype: T,\n\t\t\tpayload?: undefined,\n\t\t\toptions?: CreateDomainEventOptions,\n\t\t): DomainEvent<T, void>;\n\t\t<T extends string, P>(\n\t\t\ttype: T,\n\t\t\tpayload: P,\n\t\t\toptions?: CreateDomainEventOptions,\n\t\t): DomainEvent<T, P>;\n\t};\n\t/**\n\t * Reads the captured clock and returns a defensive `Date` copy.\n\t * Throws `TypeError` when the clock does not return a valid date.\n\t */\n\treadonly now: () => Date;\n}\n\n/**\n * Creates an immutable, instance-bound domain-event factory.\n *\n * The supplied functions are read once and captured by value. The returned\n * object is frozen, so another request, test, or library cannot replace its\n * policy. Its {@link DomainEventFactory.createStamp} method is the\n * application-shell bridge that records an accepted aggregate decision.\n * Passing the factory through `AggregateConfig`\n * enables the explicitly named convenience methods, whose defaults read time\n * and randomness.\n *\n * @example\n * ```ts\n * const domainEvents = createDomainEventFactory({\n * eventIdFactory: () => uuidv7(),\n * clock: () => new Date(),\n * });\n * order.confirm();\n * recordPendingEvents(order, domainEvents);\n * ```\n */\nexport function createDomainEventFactory(\n\toptions: DomainEventFactoryOptions = {},\n): DomainEventFactory {\n\tconst eventIdFactory = options.eventIdFactory ?? defaultEventIdFactory;\n\tconst clock = options.clock ?? defaultClockFactory;\n\tconst create = (<T extends string, P>(\n\t\ttype: T,\n\t\tpayload?: P,\n\t\tcreateOptions?: CreateDomainEventOptions,\n\t): DomainEvent<T, P> =>\n\t\tmintDomainEvent(\n\t\t\ttype,\n\t\t\tpayload,\n\t\t\tcreateOptions,\n\t\t\teventIdFactory,\n\t\t\tclock,\n\t\t)) as DomainEventFactory[\"create\"];\n\tconst createStamp = (\n\t\tstampOptions: CreateDomainEventStampOptions = {},\n\t): DomainEventStamp => {\n\t\tconst explicitOccurredAt =\n\t\t\tstampOptions.occurredAt === undefined\n\t\t\t\t? undefined\n\t\t\t\t: copyValidEventDate(stampOptions.occurredAt);\n\t\tif (stampOptions.eventId !== undefined) {\n\t\t\tassertNonBlankEventField(\n\t\t\t\tstampOptions.eventId,\n\t\t\t\t\"eventId\",\n\t\t\t\t\"EVENT_ID_INVALID\",\n\t\t\t);\n\t\t}\n\t\tconst eventId = stampOptions.eventId ?? eventIdFactory();\n\t\tassertNonBlankEventField(eventId, \"eventId\", \"EVENT_ID_INVALID\");\n\t\tconst occurredAt = explicitOccurredAt ?? readEventClock(clock);\n\t\tconst metadata = guardedMetadataClone(stampOptions.metadata);\n\t\tconst stamp: DomainEventStamp = {\n\t\t\teventId,\n\t\t\toccurredAt,\n\t\t\tmetadata,\n\t\t};\n\t\tconst owned = deepFreeze(stamp) as DomainEventStamp;\n\t\tFACTORY_OWNED_EVENT_STAMPS.add(owned);\n\t\treturn owned;\n\t};\n\n\treturn Object.freeze({\n\t\tcreateStamp,\n\t\tcreate,\n\t\tnow: () => readClock(clock),\n\t});\n}\n\n/**\n * Immutable UUID-v4/platform-clock factory used by the top-level\n * {@link createDomainEvent}. It cannot be reconfigured; construct an instance\n * with {@link createDomainEventFactory} for custom policy.\n */\nexport const defaultDomainEventFactory: DomainEventFactory =\n\tcreateDomainEventFactory();\n\n/**\n * Creates a domain event with default values.\n * Sets occurredAt to current date and version to 1 if not provided.\n *\n * **Input ownership.** The event is deeply frozen, and `payload` and\n * `metadata` are deep-cloned first, so the caller's own objects are never\n * frozen in place and later mutation of them does not bleed into the\n * event (same contract as `vo()`). The clone follows the plain-data event\n * contract via `structuredClone`: functions, Promise, and WeakMap/WeakSet\n * values throw a `TypeError`; symbol-keyed properties are not carried\n * over.\n *\n * **For aggregate-internal events, prefer `this.createEvent(...)` on\n * `AggregateRoot` / `EventSourcedAggregate`.** That helper auto-injects\n * `aggregateId` (from `this.id`) and `aggregateType` (from the\n * aggregate's declared `aggregateType` property), which downstream\n * consumers (outbox dispatchers, projection handlers, audit logs)\n * route by. The `withCommit` harvest boundary now validates both fields\n * are present and throws if they're missing, so a direct\n * `createDomainEvent(...)` call inside an aggregate that forgets the\n * options is caught at runtime. Record pending decisions in the application\n * shell before repository persistence or outbox harvest.\n *\n * Use `createDomainEvent(...)` directly for events that don't belong to\n * an aggregate: system events, integration events, configuration events,\n * test fixtures. For those, set `aggregateId` / `aggregateType` in\n * `options` if downstream consumers expect routing metadata.\n *\n * @param type - The event type\n * @param payload - The event payload\n * @param options - Optional event configuration (including `aggregateId`\n * and `aggregateType` for routing)\n * @returns A domain event\n *\n * @example\n * ```typescript\n * const event = createDomainEvent(\"OrderCreated\", { orderId: \"123\" });\n * ```\n */\n// Every event createDomainEvent returns is registered here: an\n// unforgeable mint marker (nothing outside this module can add to the\n// set), so the aggregate recording paths can check \"minted by the\n// constructor\" directly instead of approximating it with frozen-ness\n// probes. Minted implies deeply frozen with owned payload/metadata\n// (binary buffers, which cannot be frozen, are rejected at the door).\n// WeakSet entries do not keep events alive.\nconst MINTED_EVENTS = new WeakSet<object>();\nconst UNCOMMITTED_EVENTS = new WeakSet<object>();\nconst FACTORY_OWNED_EVENT_STAMPS = new WeakSet<object>();\n\n// Cooperative cross-instance tier of the mint check: a WeakSet is\n// bound to ONE loaded copy of this module, so an event legitimately\n// minted by a second copy of the kit (duplicate npm dependency, dual\n// CJS/ESM load, plugin bundle) would be rejected as unminted. Such\n// events are recognized by this global-registry brand instead, which\n// every constructor and kit-derived copy stamps (non-enumerable, so it\n// never leaks into spreads, JSON, or equality). The brand is forgeable\n// BY DESIGN: the mint gate catches accidental hand-rolled literals, it\n// is not a security boundary against code that deliberately fakes the\n// brand inside the same process.\nconst MINT_BRAND = Symbol.for(\"@shirudo/ddd-kit.mintedEvent\");\nconst UNCOMMITTED_BRAND = Symbol.for(\"@shirudo/ddd-kit.uncommittedEvent\");\n\nfunction stampMintBrand(event: object): void {\n\tObject.defineProperty(event, MINT_BRAND, {\n\t\tvalue: true,\n\t\tenumerable: false,\n\t\twritable: false,\n\t\tconfigurable: false,\n\t});\n}\n\nfunction stampUncommittedBrand(event: object): void {\n\tObject.defineProperty(event, UNCOMMITTED_BRAND, {\n\t\tvalue: true,\n\t\tenumerable: false,\n\t\twritable: false,\n\t\tconfigurable: false,\n\t});\n}\n\nfunction isFactoryOwnedDomainEventStamp(stamp: object): boolean {\n\treturn FACTORY_OWNED_EVENT_STAMPS.has(stamp);\n}\n\n/**\n * Whether `event` came out of {@link createDomainEvent} (or a helper\n * built on it, such as the aggregate `createEvent` helper), i.e. is deeply frozen with\n * defensively copied payload and metadata. Two tiers: events of THIS\n * loaded copy of the kit are verified unforgeably via the module's\n * WeakSet; events minted by ANOTHER copy (duplicate dependency, dual\n * CJS/ESM load) are recognized cooperatively via a global-registry\n * brand. Module-internal export for the aggregate recording paths;\n * not part of the package entries.\n */\nexport function isMintedEvent(event: object): event is AnyDomainEvent {\n\treturn (\n\t\tMINTED_EVENTS.has(event) ||\n\t\t(event as Record<symbol, unknown>)[MINT_BRAND] === true\n\t);\n}\n\n/** Whether a value was created by {@link createUncommittedDomainEvent}. */\nexport function isUncommittedDomainEvent(\n\tevent: object,\n): event is AnyUncommittedDomainEvent {\n\treturn (\n\t\tUNCOMMITTED_EVENTS.has(event) ||\n\t\t(event as Record<symbol, unknown>)[UNCOMMITTED_BRAND] === true\n\t);\n}\n\nexport function createUncommittedDomainEvent<T extends string>(\n\ttype: T,\n\tpayload?: undefined,\n\toptions?: CreateUncommittedDomainEventOptions,\n): UncommittedDomainEvent<T, void>;\nexport function createUncommittedDomainEvent<T extends string, P>(\n\ttype: T,\n\tpayload: P,\n\toptions?: CreateUncommittedDomainEventOptions,\n): UncommittedDomainEvent<T, P>;\nexport function createUncommittedDomainEvent<T extends string, P>(\n\ttype: T,\n\tpayload?: P,\n\toptions?: CreateUncommittedDomainEventOptions,\n): UncommittedDomainEvent<T, P> {\n\tassertProducerOwnedEventFields(type, options);\n\tconst event: UncommittedDomainEvent<T, P> = {\n\t\ttype,\n\t\taggregateId: options?.aggregateId,\n\t\taggregateType: options?.aggregateType,\n\t\tpayload: cloneOwnedEventData(payload as P, \"payload\"),\n\t\tversion: options?.version ?? 1,\n\t};\n\tstampUncommittedBrand(event);\n\tconst uncommitted = deepFreeze(event) as UncommittedDomainEvent<T, P>;\n\tUNCOMMITTED_EVENTS.add(uncommitted);\n\treturn uncommitted;\n}\n\n/** Brands and freezes a kit-derived copy of an uncommitted event. */\nexport function adoptUncommittedDomainEvent<T extends object>(copy: T): T {\n\tstampUncommittedBrand(copy);\n\tObject.freeze(copy);\n\tUNCOMMITTED_EVENTS.add(copy);\n\treturn copy;\n}\n\n/**\n * Attaches shell-owned recording data to an accepted aggregate decision.\n *\n * The decision supplies the domain type, payload, source address, and payload\n * schema version. The stamp supplies only event identity, recording time, and\n * trace metadata.\n */\nexport function recordDomainEvent<T extends string, P>(\n\tevent: UncommittedDomainEvent<T, P>,\n\tstamp: DomainEventStamp,\n): DomainEvent<T, P> {\n\tif (!isUncommittedDomainEvent(event)) {\n\t\tthrow new TypeError(\n\t\t\t\"recordDomainEvent requires an event created by createUncommittedDomainEvent\",\n\t\t);\n\t}\n\tif (isFactoryOwnedDomainEventStamp(stamp)) {\n\t\t// createStamp already validated, defensively copied, and deep-froze\n\t\t// every stamp field; re-validating or re-copying here would only pay\n\t\t// the work twice per recorded event.\n\t\treturn mintRecordedEvent(event, stamp.eventId, stamp.occurredAt, stamp.metadata);\n\t}\n\t// A caller-built stamp is caller-owned and unfrozen: validate and copy\n\t// the stamp fields before they enter the immutable event.\n\tassertNonBlankEventField(stamp.eventId, \"eventId\", \"EVENT_ID_INVALID\");\n\tconst occurredAt = deepFreeze(copyValidEventDate(stamp.occurredAt)) as Date;\n\tconst metadata = guardedMetadataClone(stamp.metadata);\n\treturn mintRecordedEvent(\n\t\tevent,\n\t\tstamp.eventId,\n\t\toccurredAt,\n\t\tmetadata === undefined ? undefined : (deepFreeze(metadata) as EventMetadata),\n\t);\n}\n\n/**\n * Single mint tail for both stamp provenances. The stamp fields arrive\n * pre-validated, copied, and frozen (by `createStamp` for factory-owned\n * stamps, by `recordDomainEvent` for caller-built stamps); the uncommitted\n * event's payload is already defensively cloned and deeply frozen by its\n * constructor and is shared instead of paying a second deep copy per event.\n */\nfunction mintRecordedEvent<T extends string, P>(\n\tevent: UncommittedDomainEvent<T, P>,\n\teventId: string,\n\toccurredAt: Date,\n\tmetadata: EventMetadata | undefined,\n): DomainEvent<T, P> {\n\tassertProducerOwnedEventFields(event.type, event);\n\tconst recorded: DomainEvent<T, P> = {\n\t\teventId,\n\t\ttype: event.type,\n\t\taggregateId: event.aggregateId,\n\t\taggregateType: event.aggregateType,\n\t\tpayload: event.payload,\n\t\toccurredAt,\n\t\tversion: event.version,\n\t\tmetadata,\n\t};\n\tstampMintBrand(recorded);\n\tObject.freeze(recorded);\n\tMINTED_EVENTS.add(recorded);\n\treturn recorded;\n}\n\n/**\n * Brands, freezes, and registers a kit-derived copy of a minted event\n * (e.g. the address-stamped copy `apply()` creates) as minted itself.\n * The copy shares the already-frozen payload/metadata of its source,\n * so the mint guarantee carries over. Stamping the cooperative brand\n * before freezing keeps the copy recognizable by another loaded kit\n * instance as well as by this instance's WeakSet. Module-internal\n * export; not part of the package entries.\n */\nexport function adoptMintedEvent<T extends object>(copy: T): T {\n\tstampMintBrand(copy);\n\tObject.freeze(copy);\n\tMINTED_EVENTS.add(copy);\n\treturn copy;\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\treturn defaultDomainEventFactory.create(\n\t\ttype,\n\t\tpayload as P,\n\t\toptions,\n\t) as DomainEvent<T, P>;\n}\n\n/**\n * Creates an already minted domain event exclusively from explicit envelope\n * facts. Unlike {@link createDomainEvent}, it has no clock or event-id fallback\n * and is useful when replay, migration, or a caller-owned boundary already has\n * the final identity and occurrence time.\n *\n * Aggregate behavior normally creates an {@link UncommittedDomainEvent} through\n * its protected `createEvent` helper. The application shell later records that\n * pending fact with caller-owned time and identity.\n */\nexport function createDomainEventFromFacts<T extends string>(\n\ttype: T,\n\tpayload: undefined,\n\toptions: CreateDomainEventFromFactsOptions,\n): DomainEvent<T, void>;\nexport function createDomainEventFromFacts<T extends string, P>(\n\ttype: T,\n\tpayload: P,\n\toptions: CreateDomainEventFromFactsOptions,\n): DomainEvent<T, P>;\nexport function createDomainEventFromFacts<T extends string, P>(\n\ttype: T,\n\tpayload: P | undefined,\n\toptions: CreateDomainEventFromFactsOptions,\n): DomainEvent<T, P> {\n\tif (options?.eventId === undefined) {\n\t\tmissingExplicitEventId();\n\t}\n\tif (options.occurredAt === undefined) {\n\t\tmissingExplicitOccurredAt();\n\t}\n\treturn mintDomainEvent(\n\t\ttype,\n\t\tpayload,\n\t\toptions,\n\t\tmissingExplicitEventId,\n\t\tmissingExplicitOccurredAt,\n\t);\n}\n\nfunction missingExplicitEventId(): string {\n\tthrow new DomainEventValidationError(\n\t\t\"EVENT_ID_REQUIRED\",\n\t\t\"eventId\",\n\t\t\"createDomainEventFromFacts requires an explicit eventId\",\n\t);\n}\n\nfunction missingExplicitOccurredAt(): Date {\n\tthrow new DomainEventValidationError(\n\t\t\"EVENT_OCCURRED_AT_REQUIRED\",\n\t\t\"occurredAt\",\n\t\t\"createDomainEventFromFacts requires an explicit occurredAt\",\n\t);\n}\n\nfunction mintDomainEvent<T extends string, P>(\n\ttype: T,\n\tpayload: P | undefined,\n\toptions: CreateDomainEventOptions | undefined,\n\teventIdFactory: EventIdFactory,\n\tclock: ClockFactory,\n): DomainEvent<T, P> {\n\tassertProducerOwnedEventFields(type, options);\n\tconst eventId = options?.eventId ?? eventIdFactory();\n\tassertNonBlankEventField(eventId, \"eventId\", \"EVENT_ID_INVALID\");\n\tconst occurredAt =\n\t\toptions?.occurredAt === undefined\n\t\t\t? readEventClock(clock)\n\t\t\t: copyValidEventDate(options.occurredAt);\n\tconst version = options?.version ?? 1;\n\tconst event: DomainEvent<T, P> = {\n\t\teventId,\n\t\ttype,\n\t\taggregateId: options?.aggregateId,\n\t\taggregateType: options?.aggregateType,\n\t\t// Defensive copies throughout: the deep-freeze below must never\n\t\t// reach the caller's own object graph. Without the clone, passing\n\t\t// (parts of) live aggregate state as payload, or reusing a metadata\n\t\t// object across events, would freeze the caller's objects in place;\n\t\t// the next mutation then throws far away from the cause. Same\n\t\t// ownership contract as `vo()` and the occurredAt copy.\n\t\tpayload: cloneOwnedEventData(payload as P, \"payload\"),\n\t\t// A caller-supplied occurredAt and a factory reading are both copied\n\t\t// before the event is frozen, so neither aliases caller-owned state.\n\t\toccurredAt,\n\t\tversion,\n\t\tmetadata: guardedMetadataClone(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\t// Brand BEFORE the freeze (a frozen object rejects new properties);\n\t// non-enumerable, so spreads, JSON, and equality never see it.\n\tstampMintBrand(event);\n\tconst minted = deepFreeze(event) as DomainEvent<T, P>;\n\tMINTED_EVENTS.add(minted);\n\treturn minted;\n}\n\nfunction assertProducerOwnedEventFields(\n\ttype: unknown,\n\toptions:\n\t\t| CreateDomainEventOptions\n\t\t| CreateUncommittedDomainEventOptions\n\t\t| undefined,\n): void {\n\tassertNonBlankEventField(type, \"type\", \"EVENT_TYPE_INVALID\");\n\tconst version = options?.version ?? 1;\n\tif (\n\t\t!Number.isSafeInteger(version) ||\n\t\ttypeof version !== \"number\" ||\n\t\tversion < 1\n\t) {\n\t\tthrow new DomainEventValidationError(\n\t\t\t\"EVENT_SCHEMA_VERSION_INVALID\",\n\t\t\t\"version\",\n\t\t\t\"domain-event version must be a safe integer greater than or equal to 1\",\n\t\t);\n\t}\n\tif (options?.aggregateId !== undefined) {\n\t\tassertNonBlankEventField(\n\t\t\toptions.aggregateId,\n\t\t\t\"aggregateId\",\n\t\t\t\"EVENT_ADDRESS_INVALID\",\n\t\t);\n\t}\n\tif (options?.aggregateType !== undefined) {\n\t\tassertNonBlankEventField(\n\t\t\toptions.aggregateType,\n\t\t\t\"aggregateType\",\n\t\t\t\"EVENT_ADDRESS_INVALID\",\n\t\t);\n\t}\n}\n\nfunction assertNonBlankEventField(\n\tvalue: unknown,\n\tfield: \"eventId\" | \"type\" | \"aggregateId\" | \"aggregateType\",\n\tcode: \"EVENT_ID_INVALID\" | \"EVENT_TYPE_INVALID\" | \"EVENT_ADDRESS_INVALID\",\n): asserts value is string {\n\tif (typeof value !== \"string\" || value.trim().length === 0) {\n\t\tthrow new DomainEventValidationError(\n\t\t\tcode,\n\t\t\tfield,\n\t\t\t`domain-event ${field} must be a non-blank string`,\n\t\t);\n\t}\n}\n\nfunction copyValidEventDate(value: unknown): Date {\n\tif (!(value instanceof Date) || !Number.isFinite(value.getTime())) {\n\t\tthrow new DomainEventValidationError(\n\t\t\t\"EVENT_OCCURRED_AT_INVALID\",\n\t\t\t\"occurredAt\",\n\t\t\t\"domain-event occurredAt must be a valid Date\",\n\t\t);\n\t}\n\treturn new Date(value.getTime());\n}\n\nfunction readEventClock(clock: ClockFactory): Date {\n\treturn copyValidEventDate(clock());\n}\n\n/**\n * Deep-clones caller-supplied event data (payload, metadata) before the\n * event is frozen, so `createDomainEvent` never freezes or aliases the\n * caller's own object graph. Primitives pass through unchanged.\n *\n * Uses `structuredClone`, which matches the documented plain-data event\n * contract: functions, Promise, and WeakMap/WeakSet values throw a\n * descriptive `TypeError` (they are not data); symbol-keyed properties\n * are not carried over; a class instance would silently lose its\n * prototype, which the plain-data contract already rules out.\n */\nfunction cloneOwnedEventData<T>(value: T, field: \"payload\" | \"metadata\"): T {\n\tif (typeof value === \"function\") {\n\t\tthrow new TypeError(\n\t\t\t`createDomainEvent: ${field} must not be a function: domain events are plain data`,\n\t\t);\n\t}\n\tif (value === null || typeof value !== \"object\") {\n\t\treturn value;\n\t}\n\t// Binary buffers are rejected BEFORE the clone: freezing cannot make\n\t// them immutable (the spec forbids freezing a view with elements, and\n\t// a frozen view still shares its mutable buffer), so accepting them\n\t// would break the mint guarantee \"minted implies deeply frozen\". They\n\t// do not survive JSON either, the wire discipline events already\n\t// document; encode binary as a string (base64/hex) or store it\n\t// outside the event and reference it.\n\tassertNoBinaryData(value, field);\n\ttry {\n\t\treturn structuredClone(value);\n\t} catch (cause) {\n\t\tthrow new TypeError(\n\t\t\t`createDomainEvent: ${field} must be plain, structured-cloneable data ` +\n\t\t\t\t`(no functions, Promises, or WeakMap/WeakSet values): domain events ` +\n\t\t\t\t`are plain data`,\n\t\t\t{ cause },\n\t\t);\n\t}\n}\n\nfunction isBinaryData(value: object): boolean {\n\treturn (\n\t\tArrayBuffer.isView(value) ||\n\t\tvalue instanceof ArrayBuffer ||\n\t\t(typeof SharedArrayBuffer !== \"undefined\" &&\n\t\t\tvalue instanceof SharedArrayBuffer)\n\t);\n}\n\n/**\n * Walks caller-supplied event data and rejects binary buffers anywhere\n * in the graph (TypedArray, DataView, ArrayBuffer, SharedArrayBuffer):\n * they are mutable by construction, so the deep-freeze that backs the\n * mint guarantee cannot cover them. Runs before the structured clone,\n * on the small plain-data graphs events are documented to carry.\n */\nfunction assertNoBinaryData(\n\tvalue: unknown,\n\tfield: \"payload\" | \"metadata\",\n\tvisited = new WeakSet<object>(),\n): void {\n\tif (value === null || typeof value !== \"object\") return;\n\tif (isBinaryData(value)) {\n\t\tthrow new TypeError(\n\t\t\t`createDomainEvent: ${field} must not contain binary buffers ` +\n\t\t\t\t`(TypedArray, DataView, ArrayBuffer, SharedArrayBuffer): they stay ` +\n\t\t\t\t`mutable under freezing and do not survive JSON. Encode binary as ` +\n\t\t\t\t`a string (base64/hex) or store it outside the event.`,\n\t\t);\n\t}\n\tif (visited.has(value)) return;\n\tvisited.add(value);\n\tif (value instanceof Map) {\n\t\tfor (const [k, v] of value) {\n\t\t\tassertNoBinaryData(k, field, visited);\n\t\t\tassertNoBinaryData(v, field, visited);\n\t\t}\n\t\treturn;\n\t}\n\tif (value instanceof Set) {\n\t\tfor (const v of value) assertNoBinaryData(v, field, visited);\n\t\treturn;\n\t}\n\tif (Array.isArray(value)) {\n\t\tfor (const v of value) assertNoBinaryData(v, field, visited);\n\t\treturn;\n\t}\n\tfor (const key of Object.keys(value)) {\n\t\tassertNoBinaryData((value as Record<string, unknown>)[key], field, visited);\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\t// Guard BOTH inputs: additional metadata from the caller AND the\n\t// source event's metadata, because events can be hand-built without\n\t// createDomainEvent. Spread itself is safe (CreateDataProperty, never\n\t// the __proto__ setter); the guard is about not CARRYING the payload.\n\tif (sourceEvent.metadata !== undefined) {\n\t\tassertNoHostileOwnProtoKey(sourceEvent.metadata, \"Event metadata\");\n\t}\n\tif (additionalMetadata !== undefined) {\n\t\tassertNoHostileOwnProtoKey(additionalMetadata, \"Event metadata\");\n\t}\n\treturn {\n\t\t...(sourceEvent.metadata ?? {}),\n\t\t...(additionalMetadata ?? {}),\n\t};\n}\n\n/**\n * Merges multiple metadata objects into one.\n * Later metadata objects override earlier ones for the same keys.\n *\n * @example\n * ```typescript\n * const metadata = mergeMetadata(\n * { correlationId: \"corr-123\" },\n * { userId: \"user-456\" },\n * { source: \"order-service\" }\n * );\n * ```\n */\nexport function mergeMetadata(\n\t...metadataObjects: Array<EventMetadata | undefined>\n): EventMetadata {\n\t// Copy via defineProperty, not Object.assign: assign uses [[Set]],\n\t// which invokes the `__proto__` setter for an own \"__proto__\" key\n\t// (typical of JSON.parse'd metadata from outbox rows or message\n\t// envelopes) and would install an attacker-controlled prototype.\n\tconst merged: Record<PropertyKey, unknown> = {};\n\tfor (const metadata of metadataObjects) {\n\t\tif (!metadata) continue;\n\t\tassertNoHostileOwnProtoKey(metadata, \"Event metadata\");\n\t\tfor (const key of Reflect.ownKeys(metadata)) {\n\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(metadata, key);\n\t\t\tif (!descriptor?.enumerable) continue;\n\t\t\tObject.defineProperty(merged, key, {\n\t\t\t\tvalue: (metadata as Record<PropertyKey, unknown>)[key],\n\t\t\t\twritable: true,\n\t\t\t\tenumerable: true,\n\t\t\t\tconfigurable: true,\n\t\t\t});\n\t\t}\n\t}\n\treturn merged as EventMetadata;\n}\n\n/**\n * Clones event metadata with the loud `__proto__` rejection applied at\n * the SOURCE: structuredClone preserves an own `__proto__` data key, so\n * without this guard a hostile envelope would ride into the frozen\n * event and re-arm downstream.\n */\nfunction guardedMetadataClone(\n\tmetadata: EventMetadata | undefined,\n): EventMetadata | undefined {\n\tif (metadata !== undefined) {\n\t\tassertNoHostileOwnProtoKey(metadata, \"Event metadata\");\n\t}\n\treturn cloneOwnedEventData(metadata, \"metadata\") as EventMetadata | undefined;\n}\n","import type { AggregateAddress } from \"../aggregate/aggregate-address\";\nimport type { AnyDomainEvent } from \"../aggregate/domain-event\";\nimport type { ExecutionContext } from \"../utils/execution\";\n\n/**\n * Event handler function type for subscribing to domain events. The execution\n * context carries the publication's cooperative cancellation and deadline;\n * those runtime controls belong to the imperative shell, never to the domain\n * event itself.\n *\n * @template Evt - The type of domain event\n */\nexport type EventHandler<Evt> = (\n\tevent: Evt,\n\tcontext: ExecutionContext,\n) => Promise<void> | void;\n\n/** Controls one bounded in-process event publication. */\nexport interface PublishOptions {\n\t/** Owner/request cancellation propagated to every event handler. */\n\treadonly signal?: AbortSignal;\n\t/** Maximum time to await the complete publication. Default `30000`ms. */\n\treadonly timeoutMs?: number;\n}\n\n/**\n * Event Bus interface for publishing and subscribing to domain events.\n * Supports multiple subscribers per event type (pub/sub pattern).\n *\n * @template Evt - The type of domain events\n *\n * @example\n * ```typescript\n * const bus = new EventBus<OrderEvent>();\n *\n * // Subscribe to specific event types\n * bus.subscribe(\"OrderCreated\", async (event) => {\n * await sendEmail(event.payload.customerId);\n * });\n *\n * bus.subscribe(\"OrderShipped\", async (event) => {\n * await updateInventory(event.payload.orderId);\n * });\n *\n * // Publish events\n * await bus.publish([orderCreatedEvent, orderShippedEvent]);\n * ```\n */\nexport interface EventBus<Evt extends AnyDomainEvent> {\n\t/**\n\t * Publishes events to all subscribed handlers.\n\t *\n\t * **Ordering & parallelism contract:**\n\t *\n\t * 1. **Events run in input order.** `publish([a, b, c])` dispatches `a`,\n\t * awaits all of its handlers, then dispatches `b`, and so on. The\n\t * library never reorders or parallelises across events.\n\t * 2. **Handlers within a single event run in parallel.** All handlers\n\t * subscribed to `event.type` are awaited via `Promise.allSettled`:\n\t * none of them sees the others' errors and none is skipped if a\n\t * peer fails.\n\t * 3. **Errors are collected and thrown AFTER everything dispatches.**\n\t * If one handler throws, remaining handlers for that event still\n\t * run, and remaining events in the batch still publish. Once\n\t * `publish` reaches the end of the batch it throws: the single\n\t * error directly if there was one, or an `AggregateError`\n\t * (\"Multiple event handlers failed\") containing every captured\n\t * error otherwise. Callers that need fail-fast semantics should\n\t * publish events one at a time and not rely on batch atomicity.\n\t *\n\t * The contract is intentionally simple and in-process. For\n\t * cross-process delivery (RabbitMQ, Kafka, etc.), use the `Outbox`\n\t * port and a dedicated dispatcher.\n\t *\n\t * @param events - Array of events to publish\n\t * @param options - Owner cancellation and publication timeout\n\t */\n\tpublish: (\n\t\tevents: ReadonlyArray<Evt>,\n\t\toptions?: PublishOptions,\n\t) => Promise<void>;\n\n\t/**\n\t * Subscribes a handler to a specific event type.\n\t * Multiple handlers can subscribe to the same event type.\n\t *\n\t * @param eventType - The event type to subscribe to\n\t * @param handler - The handler function to call when events of this type are published\n\t * @returns A function to unsubscribe the handler\n\t *\n\t * @example\n\t * ```typescript\n\t * const unsubscribe = bus.subscribe(\"OrderCreated\", async (event) => {\n\t * console.log(\"Order created:\", event.payload.orderId);\n\t * });\n\t *\n\t * // Later: unsubscribe\n\t * unsubscribe();\n\t * ```\n\t */\n\tsubscribe: <K extends Evt[\"type\"]>(\n\t\teventType: K,\n\t\thandler: EventHandler<Extract<Evt, { type: K }>>,\n\t) => () => void;\n\n\t/**\n\t * Subscribes a handler to EVERY event type: the subscription for\n\t * cross-cutting consumers (audit log, metrics, dev logging,\n\t * forward-all) that would otherwise have to enumerate the union's\n\t * event types and silently miss every type added later.\n\t *\n\t * Catch-all handlers run in the SAME `Promise.allSettled` batch as\n\t * the event's typed handlers, so the publish contract is unchanged:\n\t * awaited delivery, no handler skipped when a peer fails, errors\n\t * collected and thrown after the batch, events in input order.\n\t *\n\t * Deliberately minimal: no predicate subscriptions (filter in your\n\t * handler; it is one line) and no glob/topic patterns (topic routing\n\t * belongs to broker sinks: Kafka topics, JetStream subjects).\n\t *\n\t * @param handler - Called with every published event, typed as the\n\t * full event union; narrow via `event.type` in the handler\n\t * @returns A function to unsubscribe the handler\n\t *\n\t * @example\n\t * ```typescript\n\t * const unsubscribe = bus.subscribeAll(async (event) => {\n\t * await auditLog.append(event.type, event.eventId, event.payload);\n\t * });\n\t * ```\n\t */\n\tsubscribeAll: (handler: EventHandler<Evt>) => () => void;\n\n\t/**\n\t * Subscribes to the next occurrence of an event type.\n\t * Returns a Promise that resolves with the event data.\n\t * Automatically unsubscribes after the first event.\n\t *\n\t * @param eventType - The event type to wait for\n\t * @returns A Promise that resolves with the event\n\t *\n\t * @example\n\t * ```typescript\n\t * const event = await bus.once(\"OrderCreated\");\n\t * console.log(\"Order created:\", event.payload.orderId);\n\t * ```\n\t */\n\tonce: <K extends Evt[\"type\"]>(\n\t\teventType: K,\n\t\toptions?: OnceOptions,\n\t) => Promise<Extract<Evt, { type: K }>>;\n}\n\n/**\n * Options for `EventBus.once()`. Both fields are optional; without them\n * `once()` waits forever (the historical behaviour).\n */\nexport interface OnceOptions {\n\t/**\n\t * Aborts the wait. When `signal` fires, `once()` rejects with\n\t * `signal.reason` (or a generic abort error if none was supplied) and\n\t * the internal subscription is removed.\n\t */\n\tsignal?: AbortSignal;\n\n\t/**\n\t * Rejects with a timeout error after this many milliseconds if no event\n\t * has arrived. The internal subscription and timer are cleaned up\n\t * regardless of which path settles the promise.\n\t */\n\ttimeoutMs?: number;\n}\n\n/**\n * Gap-proof position finalized by the event source at the persistence\n * boundary. It is deliberately separate from `DomainEvent`: these values\n * describe a stored commit, not the business fact itself.\n */\nexport interface CommitPosition {\n\t/** Aggregate OCC version reached by this eventful commit. */\n\treadonly aggregateVersion: number;\n\t/** Zero-based event index inside this aggregate commit. */\n\treadonly commitSequence: number;\n\t/** Total number of events emitted by this aggregate commit. */\n\treadonly commitSize: number;\n\t/**\n\t * Aggregate version of the immediately preceding EVENTFUL commit for this\n\t * qualified aggregate source, or `null` when this is its first eventful\n\t * commit. State-only persistence is intentionally absent from this chain.\n\t *\n\t * The outbox/event-store adapter owns this value. It must read and advance\n\t * the source head atomically with inserting the committed event envelope;\n\t * application orchestration cannot derive it from the Unit of Work's OCC\n\t * receipt because state-only commits are intentionally absent here.\n\t */\n\treadonly previousEventfulAggregateVersion: number | null;\n}\n\n/**\n * Commit information known by the application transaction before the outbox\n * source has linked this eventful commit to its predecessor.\n */\nexport type EventCommitCandidatePosition = Omit<\n\tCommitPosition,\n\t\"previousEventfulAggregateVersion\"\n>;\n\n/**\n * A bare domain event prepared for the transactional outbox. The outbox source\n * owns the predecessor link and turns this candidate into a\n * {@link CommittedDomainEvent} when it persists the record.\n */\nexport interface EventCommitCandidate<Evt extends AnyDomainEvent> {\n\treadonly event: Evt;\n\treadonly source: AggregateAddress;\n\treadonly position: EventCommitCandidatePosition;\n}\n\n/**\n * A domain event enriched after persistence has established its source and\n * commit position. Outboxes and projectors consume this envelope; in-process\n * domain handlers continue to consume the bare {@link DomainEvent} value.\n */\nexport interface CommittedDomainEvent<Evt extends AnyDomainEvent> {\n\treadonly event: Evt;\n\treadonly source: AggregateAddress;\n\treadonly position: CommitPosition;\n}\n\n/**\n * One pending event in the outbox plus the opaque id the implementation\n * needs to ack it via `markDispatched`. The library does not prescribe\n * what `dispatchId` looks like: an implementation can reuse the event's\n * own `eventId`, generate its own UUID, use the row's auto-increment\n * primary key, or whatever the storage layer prefers.\n */\nexport interface OutboxRecord<Evt extends AnyDomainEvent>\n\textends CommittedDomainEvent<Evt> {\n\tdispatchId: string;\n\n\t/**\n\t * Failed delivery attempts so far. Populated by implementations that\n\t * track dispatch failures (see {@link DispatchTrackingOutbox});\n\t * plain `Outbox` implementations may omit it.\n\t */\n\tattempts?: number;\n}\n\n/** A record that exhausted its delivery attempts; see {@link DispatchTrackingOutbox.deadLetters}. */\nexport interface DeadLetterRecord<Evt extends AnyDomainEvent>\n\textends CommittedDomainEvent<Evt> {\n\tdispatchId: string;\n\t/** Failed delivery attempts when the record was dead-lettered. */\n\tattempts: number;\n\t/** Human-readable rendering of the last delivery error, if recorded. */\n\tlastError?: string;\n}\n\n/**\n * Write half of the transactional outbox: the only outbox capability the\n * write side (`withCommit`, `UnitOfWork`) depends on. Persisting the\n * events atomically with the aggregate state is the kit's guarantee;\n * DELIVERY is a separate, replaceable concern.\n *\n * Implement ONLY this interface to plug in an external delivery\n * solution: `add()` writes into that solution's outbox storage inside\n * the ambient transaction, and its own listener (polling or\n * WAL/CDC-based, such as a Debezium-style connector, a delivery\n * library, or a broker-native outbox) owns delivery entirely. The\n * kit-side poll surface ({@link Outbox}) is then never involved. See\n * the outbox guide, \"External dispatchers\".\n */\nexport interface OutboxWriter<Evt extends AnyDomainEvent> {\n\t/**\n\t * Finalizes and persists event commit candidates. Called from inside\n\t * `withCommit`'s transactional callback, atomically with the aggregate\n\t * write.\n\t *\n\t * For every qualified aggregate source, the adapter must serialize source\n\t * advancement, read its last eventful aggregate version, write that value as\n\t * `previousEventfulAggregateVersion` on every event in the candidate's\n\t * commit, and advance the source head to `aggregateVersion` in the SAME\n\t * transaction. A state-only aggregate commit does not call `add()` and must\n\t * therefore not advance this event-source head.\n\t *\n\t * A qualified source position `(aggregateType, aggregateId,\n\t * aggregateVersion, commitSequence)` MUST identify one immutable event. All\n\t * candidates for the same aggregate commit MUST also agree on `commitSize`.\n\t * Enforce both constraints before advancing the source head; a conflicting\n\t * retry must reject without replacing the stored event or changing the head.\n\t *\n\t * **Idempotency:** implementations should dedupe on\n\t * `candidate.event.eventId`. `withCommit` itself does not retry, but the\n\t * surrounding use case (a queue consumer, an HTTP retry, a transactional\n\t * outbox-dispatcher loop) may legitimately invoke the same write more than\n\t * once. A unique-key constraint on `(eventId)` in the outbox table is the\n\t * standard implementation; the source-head update and dedupe decision must\n\t * share the transaction. Idempotency applies only to an exact candidate\n\t * retry: the same event ID, qualified source, aggregate version, commit\n\t * sequence, and commit size. Reusing an `eventId` for another source or\n\t * position is a caller bug: adapters that retain the conflicting record\n\t * should reject it rather than replace or silently reinterpret it as a retry.\n\t */\n\tadd: (events: ReadonlyArray<EventCommitCandidate<Evt>>) => Promise<void>;\n}\n\n/**\n * Transactional outbox port: the bridge between the write-side\n * transaction and the (out-of-band) event dispatcher.\n *\n * Lifecycle:\n * 1. `add()` inside the write transaction (`withCommit` calls this) so\n * events persist atomically with the aggregate state\n * ({@link OutboxWriter}, the only part the write side needs).\n * 2. An outbox dispatcher (the kit's `OutboxDispatcher` or your own)\n * polls `getPending()` and forwards the events to subscribers /\n * external brokers.\n * 3. After successful dispatch, the dispatcher calls `markDispatched()`\n * with the records' `dispatchId`s so they don't come back next poll.\n *\n * `markDispatched` is required to be idempotent: calling it with an id\n * that's already marked is a no-op, not an error. This lets the\n * dispatcher safely retry on partial-failure.\n *\n * **Competing dispatcher instances** are an adapter contract, not a\n * dispatcher feature: a transactional implementation that should\n * support several concurrent pollers must make `getPending` claim the\n * returned records (`FOR UPDATE SKIP LOCKED` or equivalent). Without\n * claiming, run one logical dispatcher per outbox.\n *\n * The bundled dispatcher supplies an {@link ExecutionContext} to every poll-side\n * operation. Production adapters MUST pass its signal to native I/O or enforce\n * a native timeout no later than `deadlineAt`; the shell can bound its wait but\n * cannot terminate a promise that ignores cancellation. A timed-out write has\n * an unknown outcome. Acknowledgements must remain idempotent when they complete\n * late; a late failure update may count its original delivery attempt and must\n * still no-op after the record was dispatched.\n */\nexport interface Outbox<Evt extends AnyDomainEvent> extends OutboxWriter<Evt> {\n\t/**\n\t * Returns up to `limit` outbox records that have not yet been\n\t * dispatched, **in the order `add()` persisted them** (commit order).\n\t * The ordering is part of the port contract: `withCommit` promises\n\t * subscribers per-aggregate causal order, and a sequential dispatcher\n\t * can only honor that promise when this read is ordered. SQL-backed\n\t * implementations need a monotonic position column (an auto-increment\n\t * primary key works) and an `ORDER BY` on it; a bare `SELECT` returns\n\t * rows in storage order, not insertion order. The dispatcher polls\n\t * this on a schedule. When `limit` is omitted, the implementation\n\t * decides on a default page size. The bundled dispatcher always supplies\n\t * `context`; it is optional only so existing adapters remain assignable.\n\t */\n\tgetPending: (\n\t\tlimit?: number,\n\t\tcontext?: ExecutionContext,\n\t) => Promise<ReadonlyArray<OutboxRecord<Evt>>>;\n\n\t/**\n\t * Marks the given dispatch records as delivered so subsequent\n\t * `getPending` calls don't return them. Must be idempotent on\n\t * already-marked ids, including a late completion after the caller's\n\t * storage deadline. The bundled dispatcher always supplies `context`.\n\t */\n\tmarkDispatched: (\n\t\tdispatchIds: ReadonlyArray<string>,\n\t\tcontext?: ExecutionContext,\n\t) => Promise<void>;\n}\n\n/**\n * Optional extension of {@link Outbox} for dispatchers that track\n * delivery failures. Without failure tracking, a poison message (an\n * event whose delivery always throws) is redelivered forever: it comes\n * back from every `getPending` poll, blocks per-aggregate ordering\n * behind it, and burns the dispatcher's cycles. This extension gives\n * the dispatcher a bounded-retry story: report each failed delivery via\n * {@link markFailed}; the implementation moves records past its\n * attempt ceiling to a dead-letter set that `getPending` no longer\n * returns, and {@link deadLetters} exposes them for alerting, manual\n * inspection, and redelivery (deliver by hand, then ack via\n * `markDispatched`, which also clears dead-lettered records).\n *\n * See the outbox guide's dispatcher recipe for the retry-then-dead-letter\n * loop this port shape supports.\n */\nexport interface DispatchTrackingOutbox<Evt extends AnyDomainEvent>\n\textends Outbox<Evt> {\n\t/**\n\t * Records one failed delivery attempt for the given record:\n\t * increments its attempt count (surfaced as\n\t * {@link OutboxRecord.attempts}) and, once the implementation's\n\t * ceiling is reached, moves the record to the dead-letter set.\n\t * A no-op for unknown or already-dispatched ids (a late failure\n\t * report after a successful retry must not resurrect the record).\n\t * Returns the exact dead-letter record only on the call that performs\n\t * that transition; retries below the ceiling and no-ops return\n\t * `undefined`. This lets productive pollers emit an immediate signal\n\t * without scanning the durable dead-letter set after every failure. A late\n\t * completion may count that original delivery attempt; it must still no-op if\n\t * the record was dispatched in the meantime. The bundled dispatcher never\n\t * reissues the same store call and always supplies `context`.\n\t */\n\tmarkFailed: (\n\t\tdispatchId: string,\n\t\terror?: unknown,\n\t\tcontext?: ExecutionContext,\n\t) => Promise<DeadLetterRecord<Evt> | undefined>;\n\n\t/**\n\t * Records that exhausted their delivery attempts. They no longer\n\t * come back from `getPending`; wire this to durable alerting and\n\t * reconciliation so poison messages surface even if the poller stops\n\t * between this store transition and its immediate observer callback.\n\t */\n\tdeadLetters: () => Promise<ReadonlyArray<DeadLetterRecord<Evt>>>;\n}\n\n/**\n * Discriminates a {@link DispatchTrackingOutbox} from a plain\n * {@link Outbox} at runtime. The single source of truth for the check;\n * the dispatcher and the contract suite both use it, so what counts as\n * a tracking outbox cannot drift between them. Both tracking methods\n * must be present: a plain adapter that happens to expose an unrelated\n * `markFailed` helper must not be mistaken for one that implements the\n * tracking protocol and then be fed `(dispatchId, error)` arguments it\n * never asked for. Internal plumbing, not exported from the package\n * entries.\n */\nexport function isDispatchTrackingOutbox<Evt extends AnyDomainEvent>(\n\toutbox: Outbox<Evt> | DispatchTrackingOutbox<Evt>,\n): outbox is DispatchTrackingOutbox<Evt> {\n\tconst candidate = outbox as DispatchTrackingOutbox<Evt>;\n\treturn (\n\t\ttypeof candidate.markFailed === \"function\" &&\n\t\ttypeof candidate.deadLetters === \"function\"\n\t);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ports.js","names":["m","s"],"sources":["../../src/internal/structural/is-built-in.ts","../../src/internal/structural/deep-equal.ts","../../src/internal/structural/deep-omit.ts","../../src/internal/structural/deep-equal-except.ts","../../src/domain/value-object/value-object.ts","../../src/internal/cooperative-brand.ts","../../src/domain/event/clock.ts","../../src/domain/event/domain-event-errors.ts","../../src/domain/event/domain-event.ts","../../src/messaging/outbox/ports.ts"],"sourcesContent":["/**\n * Set of `Object.prototype.toString.call(x)` tags that the library treats\n * as built-in atomic types. Members of this set are compared/cloned by\n * reference (or with type-specific logic) rather than walked structurally.\n *\n * Detection is tag-based, since `Object.prototype.toString` gives the same\n * answer across realms (an iframe's `Date` has the same tag as the main\n * window's `Date`), and then brand-verified via internal-slot probes,\n * because `Symbol.toStringTag` lets any plain object claim a built-in tag.\n * The previous strategy also checked `globalThis[name] === constructor`\n * and a `proto !== Object.prototype` heuristic; both broke for cross-realm\n * objects and the latter additionally misclassified ordinary user classes\n * as built-ins.\n */\nconst BUILT_IN_TAGS: ReadonlySet<string> = new Set([\n\t\"[object Date]\",\n\t\"[object RegExp]\",\n\t\"[object Map]\",\n\t\"[object Set]\",\n\t\"[object WeakMap]\",\n\t\"[object WeakSet]\",\n\t\"[object Promise]\",\n\t\"[object Error]\",\n\t\"[object Boolean]\",\n\t\"[object Number]\",\n\t\"[object String]\",\n\t\"[object BigInt]\",\n\t\"[object ArrayBuffer]\",\n\t\"[object SharedArrayBuffer]\",\n\t\"[object DataView]\",\n]);\n\n// Intrinsic probes for brand verification. Each one reads an internal slot\n// and throws a TypeError when `this` is not a genuine instance, the only\n// check a plain object cannot spoof via `Symbol.toStringTag`. Captured once\n// so a tampered prototype cannot redirect the probe later.\nfunction intrinsicGetter(\n\tproto: object,\n\tprop: string,\n): (this: unknown) => unknown {\n\tconst get = Object.getOwnPropertyDescriptor(proto, prop)?.get;\n\t// Spec-guaranteed accessors on intrinsic prototypes: unreachable\n\t// unless the environment itself is broken.\n\tif (!get) throw new Error(`missing intrinsic getter for ${prop}`);\n\treturn get;\n}\n\nconst dateGetTime = Date.prototype.getTime;\nconst mapSizeGet = intrinsicGetter(Map.prototype, \"size\");\nconst setSizeGet = intrinsicGetter(Set.prototype, \"size\");\nconst weakMapHas = WeakMap.prototype.has;\nconst weakSetHas = WeakSet.prototype.has;\nconst dataViewByteLengthGet = intrinsicGetter(DataView.prototype, \"byteLength\");\nconst arrayBufferByteLengthGet = intrinsicGetter(\n\tArrayBuffer.prototype,\n\t\"byteLength\",\n);\nconst sharedArrayBufferByteLengthGet =\n\ttypeof SharedArrayBuffer === \"undefined\"\n\t\t? undefined\n\t\t: intrinsicGetter(SharedArrayBuffer.prototype, \"byteLength\");\nconst regExpSourceGet = intrinsicGetter(RegExp.prototype, \"source\");\nconst booleanValueOf = Boolean.prototype.valueOf;\nconst numberValueOf = Number.prototype.valueOf;\nconst stringValueOf = String.prototype.valueOf;\nconst bigIntValueOf = BigInt.prototype.valueOf;\nconst functionToString = Function.prototype.toString;\nconst PROBE_KEY = {};\n\nconst INTRINSIC_CONSTRUCTOR_NAMES = [\n\t\"Object\",\n\t\"Array\",\n\t\"Date\",\n\t\"RegExp\",\n\t\"Map\",\n\t\"Set\",\n\t\"WeakMap\",\n\t\"WeakSet\",\n\t\"Promise\",\n\t\"Error\",\n\t\"EvalError\",\n\t\"RangeError\",\n\t\"ReferenceError\",\n\t\"SyntaxError\",\n\t\"TypeError\",\n\t\"URIError\",\n\t\"AggregateError\",\n\t\"Boolean\",\n\t\"Number\",\n\t\"String\",\n\t\"BigInt\",\n\t\"ArrayBuffer\",\n\t\"SharedArrayBuffer\",\n\t\"DataView\",\n\t\"Int8Array\",\n\t\"Uint8Array\",\n\t\"Uint8ClampedArray\",\n\t\"Int16Array\",\n\t\"Uint16Array\",\n\t\"Int32Array\",\n\t\"Uint32Array\",\n\t\"Float32Array\",\n\t\"Float64Array\",\n\t\"BigInt64Array\",\n\t\"BigUint64Array\",\n] as const;\n\nconst intrinsicConstructorSources: ReadonlyMap<string, string> = new Map(\n\tINTRINSIC_CONSTRUCTOR_NAMES.flatMap((name) => {\n\t\tconst descriptor = Object.getOwnPropertyDescriptor(globalThis, name);\n\t\tconst intrinsic = descriptor?.value;\n\t\treturn typeof intrinsic === \"function\"\n\t\t\t? [[name, functionToString.call(intrinsic)] as const]\n\t\t\t: [];\n\t}),\n);\nconst intrinsicConstructorSourceSet: ReadonlySet<string> = new Set(\n\tintrinsicConstructorSources.values(),\n);\nconst ERROR_INTRINSIC_NAMES = [\n\t\"Error\",\n\t\"EvalError\",\n\t\"RangeError\",\n\t\"ReferenceError\",\n\t\"SyntaxError\",\n\t\"TypeError\",\n\t\"URIError\",\n\t\"AggregateError\",\n] as const;\n\nexport function isIntrinsicConstructorPrototype(\n\tprototype: object,\n\texpectedName?: string,\n): boolean {\n\tconst constructorDescriptor = Object.getOwnPropertyDescriptor(\n\t\tprototype,\n\t\t\"constructor\",\n\t);\n\tconst candidateConstructor = constructorDescriptor?.value;\n\tif (\n\t\tconstructorDescriptor === undefined ||\n\t\t!(\"value\" in constructorDescriptor) ||\n\t\ttypeof candidateConstructor !== \"function\"\n\t) {\n\t\treturn false;\n\t}\n\n\tlet candidateSource: string;\n\ttry {\n\t\tcandidateSource = functionToString.call(candidateConstructor);\n\t} catch {\n\t\treturn false;\n\t}\n\tconst expectedSource =\n\t\texpectedName === undefined\n\t\t\t? undefined\n\t\t\t: intrinsicConstructorSources.get(expectedName);\n\tif (\n\t\t(expectedSource !== undefined && candidateSource !== expectedSource) ||\n\t\t(expectedSource === undefined &&\n\t\t\t!intrinsicConstructorSourceSet.has(candidateSource))\n\t) {\n\t\treturn false;\n\t}\n\n\tconst nameDescriptor = Object.getOwnPropertyDescriptor(\n\t\tcandidateConstructor,\n\t\t\"name\",\n\t);\n\tconst candidateName =\n\t\tnameDescriptor !== undefined &&\n\t\t\"value\" in nameDescriptor &&\n\t\ttypeof nameDescriptor.value === \"string\"\n\t\t\t? nameDescriptor.value\n\t\t\t: undefined;\n\tconst intrinsicName = expectedName ?? candidateName;\n\tconst intrinsicSource =\n\t\tintrinsicName === undefined\n\t\t\t? undefined\n\t\t\t: intrinsicConstructorSources.get(intrinsicName);\n\treturn (\n\t\tcandidateName === intrinsicName &&\n\t\tintrinsicSource !== undefined &&\n\t\tcandidateSource === intrinsicSource &&\n\t\tObject.getOwnPropertyDescriptor(candidateConstructor, \"prototype\")\n\t\t\t?.value === prototype\n\t);\n}\n\n/**\n * Accepts an intrinsic prototype, optionally behind transparent\n * `Symbol.toStringTag` override layers. A user-defined subclass has its own\n * non-native constructor and is therefore rejected before reaching the\n * intrinsic prototype.\n */\nexport function hasIntrinsicPrototypeChain(\n\tvalue: object,\n\texpectedName?: string,\n): boolean {\n\tconst visited = new WeakSet<object>();\n\tlet prototype = Object.getPrototypeOf(value);\n\n\twhile (prototype !== null && !visited.has(prototype)) {\n\t\tvisited.add(prototype);\n\t\tif (Object.hasOwn(prototype, \"constructor\")) {\n\t\t\treturn isIntrinsicConstructorPrototype(prototype, expectedName);\n\t\t}\n\t\tconst ownKeys = Reflect.ownKeys(prototype);\n\t\tif (ownKeys.length !== 1 || ownKeys[0] !== Symbol.toStringTag) {\n\t\t\treturn false;\n\t\t}\n\t\tprototype = Object.getPrototypeOf(prototype);\n\t}\n\n\treturn false;\n}\n\n/**\n * Tags that `deepEqual` compares BY REFERENCE (its unhandled-built-in\n * fallback) and that `deepOmit` must therefore ALIAS rather than clone:\n * a clone would break `deepEqualExcept(x, x)` reflexivity. Single source\n * of truth so the two modules cannot drift: if `deepEqual` ever learns a\n * by-value comparison for one of these, remove it here and add a clone\n * case in `deepOmit`'s `cloneBuiltIn` in the same change.\n */\nexport const REFERENCE_COMPARED_TAGS: ReadonlySet<string> = new Set([\n\t\"[object Error]\",\n\t\"[object ArrayBuffer]\",\n\t\"[object SharedArrayBuffer]\",\n\t\"[object Promise]\",\n\t\"[object WeakMap]\",\n\t\"[object WeakSet]\",\n]);\n\n/**\n * Intrinsic tags of OPAQUE exotics: objects whose internal state no\n * structural walk can observe (boxed Symbols, generator objects,\n * WeakRefs, FinalizationRegistry handles). `deepEqual` compares them by\n * identity and `deepOmit` passes them through by reference; treating\n * them as (empty) plain objects would make ALL such exotics equal to\n * each other. Deliberately a curated INTRINSIC list, not \"every unknown\n * tag\": a user class exposing its own `Symbol.toStringTag` (e.g.\n * \"Money\") keeps structural comparison, and a plain object spoofing one\n * of these intrinsic tags gets the identity semantics of the thing it\n * claims to be.\n */\nconst OPAQUE_EXOTIC_TAGS: ReadonlySet<string> = new Set([\n\t\"[object Symbol]\",\n\t\"[object Generator]\",\n\t\"[object AsyncGenerator]\",\n\t\"[object WeakRef]\",\n\t\"[object FinalizationRegistry]\",\n]);\n\n/** True when `tag` names an opaque intrinsic; see {@link OPAQUE_EXOTIC_TAGS}. */\nexport function isOpaqueExoticTag(tag: string): boolean {\n\treturn OPAQUE_EXOTIC_TAGS.has(tag);\n}\n\nexport function findPropertyDescriptor(\n\tvalue: object,\n\tkey: PropertyKey,\n): PropertyDescriptor | undefined {\n\tconst visited = new WeakSet<object>();\n\tlet current: object | null = value;\n\n\twhile (current !== null && !visited.has(current)) {\n\t\tvisited.add(current);\n\t\tconst descriptor = Object.getOwnPropertyDescriptor(current, key);\n\t\tif (descriptor !== undefined) return descriptor;\n\t\tcurrent = Object.getPrototypeOf(current);\n\t}\n\n\treturn undefined;\n}\n\nexport function builtInTagWithoutInvokingAccessors(\n\tvalue: object,\n): string | undefined {\n\tif (ArrayBuffer.isView(value)) {\n\t\treturn hasBrand(value, \"[object DataView]\")\n\t\t\t? \"[object DataView]\"\n\t\t\t: \"[object TypedArray]\";\n\t}\n\n\tconst descriptor = findPropertyDescriptor(value, Symbol.toStringTag);\n\tif (descriptor !== undefined && !(\"value\" in descriptor)) {\n\t\treturn builtInTagFromBrand(value);\n\t}\n\n\tconst tag = Object.prototype.toString.call(value);\n\tif (BUILT_IN_TAGS.has(tag) && hasBrand(value, tag)) {\n\t\treturn tag;\n\t}\n\treturn descriptor === undefined ? undefined : builtInTagFromBrand(value);\n}\n\nfunction builtInTagFromBrand(value: object): string | undefined {\n\tif (hasBrand(value, \"[object Date]\")) return \"[object Date]\";\n\tif (hasBrand(value, \"[object RegExp]\")) return \"[object RegExp]\";\n\tif (hasBrand(value, \"[object Map]\")) return \"[object Map]\";\n\tif (hasBrand(value, \"[object Set]\")) return \"[object Set]\";\n\tif (hasBrand(value, \"[object WeakMap]\")) return \"[object WeakMap]\";\n\tif (hasBrand(value, \"[object WeakSet]\")) return \"[object WeakSet]\";\n\tif (hasBrand(value, \"[object DataView]\")) return \"[object DataView]\";\n\tif (hasBrand(value, \"[object ArrayBuffer]\")) return \"[object ArrayBuffer]\";\n\tif (hasBrand(value, \"[object SharedArrayBuffer]\")) {\n\t\treturn \"[object SharedArrayBuffer]\";\n\t}\n\tif (hasBrand(value, \"[object Boolean]\")) return \"[object Boolean]\";\n\tif (hasBrand(value, \"[object Number]\")) return \"[object Number]\";\n\tif (hasBrand(value, \"[object String]\")) return \"[object String]\";\n\tif (hasBrand(value, \"[object BigInt]\")) return \"[object BigInt]\";\n\tif (hasNativePrototype(value, \"Promise\")) return \"[object Promise]\";\n\tif (hasNativePrototype(value, \"Error\")) return \"[object Error]\";\n\treturn undefined;\n}\n\nfunction hasNativePrototype(value: object, expectedName: string): boolean {\n\tconst visited = new WeakSet<object>();\n\tlet prototype = Object.getPrototypeOf(value);\n\n\twhile (prototype !== null && !visited.has(prototype)) {\n\t\tvisited.add(prototype);\n\t\tif (isIntrinsicConstructorPrototype(prototype, expectedName)) {\n\t\t\treturn true;\n\t\t}\n\t\tprototype = Object.getPrototypeOf(prototype);\n\t}\n\treturn false;\n}\n\n/**\n * Verifies that `obj` genuinely is the type its tag claims, via an\n * internal-slot probe. Promise and Error have no side-effect-free standard\n * probe, so their visible tags remain conservative; masked instances are\n * identified separately through their native prototype chain.\n */\nfunction hasBrand(obj: object, tag: string): boolean {\n\ttry {\n\t\tswitch (tag) {\n\t\t\tcase \"[object Date]\":\n\t\t\t\tdateGetTime.call(obj);\n\t\t\t\treturn true;\n\t\t\tcase \"[object RegExp]\":\n\t\t\t\tregExpSourceGet.call(obj);\n\t\t\t\treturn true;\n\t\t\tcase \"[object Map]\":\n\t\t\t\tmapSizeGet.call(obj);\n\t\t\t\treturn true;\n\t\t\tcase \"[object Set]\":\n\t\t\t\tsetSizeGet.call(obj);\n\t\t\t\treturn true;\n\t\t\tcase \"[object WeakMap]\":\n\t\t\t\tweakMapHas.call(obj, PROBE_KEY);\n\t\t\t\treturn true;\n\t\t\tcase \"[object WeakSet]\":\n\t\t\t\tweakSetHas.call(obj, PROBE_KEY);\n\t\t\t\treturn true;\n\t\t\tcase \"[object DataView]\":\n\t\t\t\tdataViewByteLengthGet.call(obj);\n\t\t\t\treturn true;\n\t\t\tcase \"[object ArrayBuffer]\":\n\t\t\t\tarrayBufferByteLengthGet.call(obj);\n\t\t\t\treturn true;\n\t\t\tcase \"[object SharedArrayBuffer]\":\n\t\t\t\tif (!sharedArrayBufferByteLengthGet) return false;\n\t\t\t\tsharedArrayBufferByteLengthGet.call(obj);\n\t\t\t\treturn true;\n\t\t\tcase \"[object Boolean]\":\n\t\t\t\tbooleanValueOf.call(obj);\n\t\t\t\treturn true;\n\t\t\tcase \"[object Number]\":\n\t\t\t\tnumberValueOf.call(obj);\n\t\t\t\treturn true;\n\t\t\tcase \"[object String]\":\n\t\t\t\tstringValueOf.call(obj);\n\t\t\t\treturn true;\n\t\t\tcase \"[object BigInt]\":\n\t\t\t\tbigIntValueOf.call(obj);\n\t\t\t\treturn true;\n\t\t\tcase \"[object Promise]\":\n\t\t\t\treturn hasNativePrototype(obj, \"Promise\");\n\t\t\tcase \"[object Error]\":\n\t\t\t\treturn ERROR_INTRINSIC_NAMES.some((name) =>\n\t\t\t\t\thasNativePrototype(obj, name),\n\t\t\t\t);\n\t\t\tdefault:\n\t\t\t\treturn false;\n\t\t}\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Returns `true` when `obj` is a built-in JavaScript type that should be\n * treated atomically (compared/cloned as a unit, not walked structurally).\n * Cross-realm safe, and brand-verified: a plain object spoofing a built-in\n * tag via `Symbol.toStringTag` returns `false` and is walked structurally\n * like any other plain object instead of crashing type-specific code.\n *\n * @param obj - The object to classify\n * @param tag - The result of `Object.prototype.toString.call(obj)`, passed\n * in so callers that already computed it don't pay twice\n */\nexport function isBuiltInObject(obj: object, tag: string): boolean {\n\t// ArrayBuffer views (DataView + all TypedArrays, present and future)\n\t// carry an unforgeable internal slot, the strongest brand check.\n\tif (ArrayBuffer.isView(obj)) return true;\n\t// A built-in-looking TypedArray tag WITHOUT the view brand is spoofed.\n\tif (tag.endsWith(\"Array]\")) return false;\n\treturn BUILT_IN_TAGS.has(tag) && hasBrand(obj, tag);\n}\n\n/**\n * Brand-verified `WeakMap` check that holds across realms. `instanceof\n * WeakMap` binds to the constructor of one realm, so a WeakMap from a `vm`\n * context or an iframe reads as a foreign value. The internal-slot probe\n * answers the same in every realm, and a plain object cannot spoof it\n * through `Symbol.toStringTag`.\n */\nexport function isWeakMap(value: unknown): value is WeakMap<object, unknown> {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\thasBrand(value, \"[object WeakMap]\")\n\t);\n}\n","import { isBuiltInObject, isOpaqueExoticTag } from \"./is-built-in\";\n\nconst objProto = Object.prototype;\nconst objToString = objProto.toString;\nconst objHasOwn = objProto.hasOwnProperty;\n\n/**\n * SameValueZero: `===` plus NaN-equals-NaN (and `+0 === -0`, unlike\n * `Object.is`). The numeric semantics `deepEqual` documents for primitives,\n * applied consistently inside TypedArrays, Dates and Number wrappers.\n */\nfunction sameValueZero(a: unknown, b: unknown): boolean {\n\treturn a === b || (Number.isNaN(a as number) && Number.isNaN(b as number));\n}\n\n/**\n * Performs a deep equality check between two values.\n *\n * This function compares values recursively, handling:\n * - Primitives (with special handling for NaN)\n * - Arrays (nested arrays supported)\n * - Objects (plain objects and class instances)\n * - TypedArrays (Uint8Array, Int32Array, etc.)\n * - DataView\n * - Maps and Sets\n * - Dates and RegExp\n * - Wrapper objects (Boolean, Number, String)\n * - Circular references (detected and handled)\n *\n * @param a - The first value to compare\n * @param b - The second value to compare\n * @returns `true` if the values are deeply equal, `false` otherwise\n *\n * @example\n * ```ts\n * deepEqual([1, 2, 3], [1, 2, 3]); // true\n * deepEqual({ a: 1, b: [2, 3] }, { a: 1, b: [2, 3] }); // true\n * deepEqual(NaN, NaN); // true\n * deepEqual([1, 2], [1, 2, 3]); // false\n * ```\n */\nexport function deepEqual(a: unknown, b: unknown): boolean {\n\treturn deepEqualInner(a, b, new WeakMap<object, WeakSet<object>>());\n}\n\n/**\n * Visited pair tracker for cycle detection. The cache is a pair-set:\n * for every left-hand object we keep the set of right-hand objects we\n * have already paired it with. Encountering an already-known pair returns\n * the cycle hypothesis (assume equal); a new (a, b') pair with b' ≠ any\n * previously cached b for that a is walked normally. The previous shape\n * (`WeakMap<object, object>`) could only remember one B per A, which\n * could short-circuit unrelated comparisons that happened to revisit the\n * same A with a different B.\n */\ntype VisitedPairs = WeakMap<object, WeakSet<object>>;\n\n/**\n * Internal recursive function for deep equality comparison.\n *\n * @internal\n */\nfunction deepEqualInner(\n\ta: unknown,\n\tb: unknown,\n\tvisited: VisitedPairs,\n): boolean {\n\t// 1. Fast path: reference equality\n\tif (a === b) return true;\n\n\tconst typeA = typeof a;\n\tconst typeB = typeof b;\n\n\t// 2. If one is not an object → primitive / function\n\tif (typeA !== \"object\" || a === null || typeB !== \"object\" || b === null) {\n\t\t// Special case: NaN should be equal\n\t\tif (typeA === \"number\" && typeB === \"number\") {\n\t\t\treturn Number.isNaN(a as number) && Number.isNaN(b as number);\n\t\t}\n\t\t// Everything else is directly unequal with !== (including functions)\n\t\treturn false;\n\t}\n\n\t// From here on: both are non-null objects\n\n\tconst objA = a as object;\n\tconst objB = b as object;\n\n\t// 3. Cycles: already seen this exact (a, b) pair?\n\tlet cachedBs = visited.get(objA);\n\tif (cachedBs?.has(objB)) {\n\t\t// Cycle hypothesis: pretend equal so the walk can terminate. If the\n\t\t// structure is actually unequal elsewhere, a different recursive\n\t\t// branch will surface the mismatch.\n\t\treturn true;\n\t}\n\tif (!cachedBs) {\n\t\tcachedBs = new WeakSet();\n\t\tvisited.set(objA, cachedBs);\n\t}\n\tcachedBs.add(objB);\n\n\t// 4. Handle Typed Arrays / DataView first\n\tif (ArrayBuffer.isView(objA) || ArrayBuffer.isView(objB)) {\n\t\tif (!ArrayBuffer.isView(objA) || !ArrayBuffer.isView(objB)) return false;\n\n\t\tconst tagA = objToString.call(objA);\n\t\tconst tagB = objToString.call(objB);\n\t\tif (tagA !== tagB) return false;\n\n\t\t// DataView: compare byte by byte\n\t\tif (tagA === \"[object DataView]\") {\n\t\t\tconst viewA = objA as DataView;\n\t\t\tconst viewB = objB as DataView;\n\t\t\tif (viewA.byteLength !== viewB.byteLength) return false;\n\n\t\t\tconst len = viewA.byteLength;\n\t\t\tfor (let i = 0; i < len; i++) {\n\t\t\t\tif (viewA.getUint8(i) !== viewB.getUint8(i)) return false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\t// Typed Arrays: element by element (length + numeric index access are\n\t\t// part of the TypedArray contract; the indexed read is sound).\n\t\tconst arrA = objA as unknown as Record<number, unknown> & {\n\t\t\tlength: number;\n\t\t};\n\t\tconst arrB = objB as unknown as Record<number, unknown> & {\n\t\t\tlength: number;\n\t\t};\n\n\t\tconst len = arrA.length;\n\t\tif (len !== arrB.length) return false;\n\n\t\tfor (let i = 0; i < len; i++) {\n\t\t\tif (!sameValueZero(arrA[i], arrB[i])) return false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t// 5. Arrays: `Array.isArray` is brand-based and immune to\n\t// `Symbol.toStringTag` spoofing (a spoofed tag would otherwise route a\n\t// real array away from element comparison, or a plain object into it).\n\tif (Array.isArray(objA) || Array.isArray(objB)) {\n\t\tif (!Array.isArray(objA) || !Array.isArray(objB)) return false;\n\t\tif (objA.length !== objB.length) return false;\n\n\t\tconst keysA = Reflect.ownKeys(objA).filter((key) => key !== \"length\");\n\t\tconst keysB = Reflect.ownKeys(objB).filter((key) => key !== \"length\");\n\t\tif (keysA.length !== keysB.length) return false;\n\n\t\tconst arrA = objA as unknown as Record<PropertyKey, unknown>;\n\t\tconst arrB = objB as unknown as Record<PropertyKey, unknown>;\n\t\tfor (const key of keysA) {\n\t\t\tif (!objHasOwn.call(objB, key)) return false;\n\t\t\t// Read the element by access (invoking any getter) rather than\n\t\t\t// comparing accessor descriptors by function identity, so an array\n\t\t\t// index defined as a getter is compared by the value it yields,\n\t\t\t// matching how comparePlainObjects treats accessor properties.\n\t\t\t// Sparse holes stay observable through the key-set comparison above:\n\t\t\t// a hole leaves no own key, so two arrays that differ by a hole vs\n\t\t\t// an explicit undefined have different key sets.\n\t\t\tif (!deepEqualInner(arrA[key], arrB[key], visited)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t// 6. Tag-based type detection (robust across realms), brand-verified:\n\t// a plain object spoofing a built-in tag is compared as a plain object\n\t// instead of crashing type-specific code below.\n\tconst tagA = objToString.call(objA);\n\tconst tagB = objToString.call(objB);\n\tif (tagA !== tagB) return false;\n\n\tconst builtInA = isBuiltInObject(objA, tagA);\n\tconst builtInB = isBuiltInObject(objB, tagB);\n\t// A genuine built-in never equals a spoofed lookalike.\n\tif (builtInA !== builtInB) return false;\n\n\tif (!builtInA) {\n\t\t// Opaque intrinsics (boxed Symbol, generator, WeakRef, ...):\n\t\t// identity is the only honest comparison; symmetric because\n\t\t// tagA === tagB was already enforced above.\n\t\tif (isOpaqueExoticTag(tagA)) return objA === objB;\n\t\treturn comparePlainObjects(objA, objB, visited);\n\t}\n\n\tswitch (tagA) {\n\t\tcase \"[object Map]\": {\n\t\t\tconst mapA = objA as Map<unknown, unknown>;\n\t\t\tconst mapB = objB as Map<unknown, unknown>;\n\n\t\t\tif (mapA.size !== mapB.size) return false;\n\n\t\t\tfor (const [key, valA] of mapA) {\n\t\t\t\t// Map keys according to JS semantics: reference / SameValueZero\n\t\t\t\tif (!mapB.has(key)) return false;\n\t\t\t\tconst valB = mapB.get(key);\n\t\t\t\tif (!deepEqualInner(valA, valB, visited)) return false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tcase \"[object Set]\": {\n\t\t\tconst setA = objA as Set<unknown>;\n\t\t\tconst setB = objB as Set<unknown>;\n\n\t\t\tif (setA.size !== setB.size) return false;\n\n\t\t\t// Set elements: same reference (JS semantics)\n\t\t\tfor (const value of setA) {\n\t\t\t\tif (!setB.has(value)) return false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tcase \"[object Date]\": {\n\t\t\t// SameValueZero so two invalid Dates (getTime() === NaN) compare\n\t\t\t// equal, matching the primitive NaN semantics.\n\t\t\treturn sameValueZero((objA as Date).getTime(), (objB as Date).getTime());\n\t\t}\n\n\t\tcase \"[object RegExp]\": {\n\t\t\tconst regA = objA as RegExp;\n\t\t\tconst regB = objB as RegExp;\n\t\t\treturn regA.source === regB.source && regA.flags === regB.flags;\n\t\t}\n\n\t\tcase \"[object Boolean]\":\n\t\tcase \"[object Number]\":\n\t\tcase \"[object String]\":\n\t\tcase \"[object BigInt]\": {\n\t\t\t// Wrapper objects (Boolean/Number/String/BigInt); SameValueZero so\n\t\t\t// two NaN Number wrappers compare equal.\n\t\t\treturn sameValueZero(\n\t\t\t\t(objA as { valueOf(): unknown }).valueOf(),\n\t\t\t\t(objB as { valueOf(): unknown }).valueOf(),\n\t\t\t);\n\t\t}\n\n\t\tdefault: {\n\t\t\t// Unhandled but brand-trusted built-ins: compared by reference.\n\t\t\t// Their internal structure is unknown, and this keeps new\n\t\t\t// built-ins from falling through to plain-object comparison.\n\t\t\t// This branch IS the REFERENCE_COMPARED_TAGS contract exported\n\t\t\t// from is-built-in.ts (and consumed by deepOmit's cloneBuiltIn):\n\t\t\t// adding a by-value case above means removing the tag there.\n\t\t\treturn objA === objB;\n\t\t}\n\t}\n}\n\n/**\n * Plain / custom objects: compare own enumerable string keys + own symbol\n * keys and their values. Used both as the final fallback and for objects\n * whose built-in-looking tag failed brand verification.\n */\nfunction comparePlainObjects(\n\tobjA: object,\n\tobjB: object,\n\tvisited: VisitedPairs,\n): boolean {\n\tconst recA = objA as Record<string | symbol, unknown>;\n\tconst recB = objB as Record<string | symbol, unknown>;\n\n\t// Own string keys including non-enumerable ones: symbols are already\n\t// counted through Object.getOwnPropertySymbols (which ignores\n\t// enumerability), so using Object.keys here would let two objects that\n\t// differ only by a non-enumerable string property compare equal.\n\tconst stringKeysA = Object.getOwnPropertyNames(objA);\n\tconst stringKeysB = Object.getOwnPropertyNames(objB);\n\tif (stringKeysA.length !== stringKeysB.length) return false;\n\n\tconst symbolKeysA = Object.getOwnPropertySymbols(objA);\n\tconst symbolKeysB = Object.getOwnPropertySymbols(objB);\n\tif (symbolKeysA.length !== symbolKeysB.length) return false;\n\n\t// Build the B-side symbol set once; the previous impl rebuilt the\n\t// array and ran .includes per key, which was quadratic.\n\tconst symbolKeysBSet = new Set<symbol>(symbolKeysB);\n\n\tfor (const key of stringKeysA) {\n\t\tif (!objHasOwn.call(objB, key)) return false;\n\t}\n\tfor (const key of symbolKeysA) {\n\t\tif (!symbolKeysBSet.has(key)) return false;\n\t}\n\n\tfor (const key of stringKeysA) {\n\t\tif (!deepEqualInner(recA[key], recB[key], visited)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\tfor (const key of symbolKeysA) {\n\t\tif (!deepEqualInner(recA[key], recB[key], visited)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n","import {\n\tisBuiltInObject,\n\tisOpaqueExoticTag,\n\tREFERENCE_COMPARED_TAGS,\n} from \"./is-built-in\";\n\nexport type DeepOmitKey = string | symbol;\nexport type DeepOmitPathSegment = 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 DeepOmitKey[];\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: DeepOmitKey,\n\t\tpath: readonly DeepOmitPathSegment[],\n\t) => boolean;\n}\n\n/**\n * Creates a deep copy of `value` with certain keys removed according to the\n * provided rules.\n *\n * Walks the object tree and skips keys that match `ignoreKeys` /\n * `ignoreKeyPredicate`. Built-in atomic types that `deepEqual` compares by\n * value (Date, RegExp, Map, Set, TypedArrays, DataView) are cloned by type\n * rather than walked, since their internal structure has no key filtering to\n * apply. Types that `deepEqual` compares by reference (Error, ArrayBuffer,\n * SharedArrayBuffer, Promise, WeakMap, WeakSet) are passed through by\n * reference, so `deepEqualExcept(x, x)` stays reflexive. Cycles are\n * preserved: a cycle `a → a` clones to `a' → a'`. Arrays retain sparse\n * holes and all non-ignored own properties, including symbol keys.\n *\n * **Shared references.** Without `ignoreKeyPredicate`, an object reached\n * via several paths dedupes to a single clone. With a predicate, each\n * path gets its own clone, because the predicate may decide differently per\n * path, so memoising the first path's result would be wrong. This is\n * inherently exponential for diamond-shaped sharing (a node reachable\n * via 2^n paths is cloned 2^n times); the walk aborts with a descriptive\n * error after {@link PATH_SENSITIVE_VISIT_BUDGET} node visits instead of\n * hanging the process.\n *\n * **Prototype-pollution safety.** `__proto__` and `constructor` keys\n * encountered as *own* properties of the input (typical of `JSON.parse`\n * output) are copied as inert data properties via `Object.defineProperty`\n * so the clone graph cannot bleed into `Object.prototype`.\n *\n * **Class instances.** When the input is a class instance, the clone is\n * built via `Object.create(proto)` so the prototype is preserved, but the\n * constructor is NOT re-invoked, so class invariants enforced by the\n * constructor are not re-checked. `deepOmit` is therefore best used for\n * comparison/serialisation (`voEqualsExcept`, `deepEqualExcept`), not as\n * a general-purpose clone for behaviour-carrying objects.\n *\n * @param value - The value to create a deep copy from\n * @param options - Options specifying which keys to ignore\n * @returns A deep copy of `value` with specified keys removed\n */\nexport function deepOmit<T>(value: T, options: DeepOmitOptions): T {\n\tconst visited = new WeakMap<object, unknown>();\n\t// Materialise ignoreKeys as a Set once so the inner loop probes O(1).\n\tconst ignoreKeys = options.ignoreKeys\n\t\t? new Set<DeepOmitKey>(options.ignoreKeys)\n\t\t: undefined;\n\t// With a path-sensitive predicate, a clone computed under one path must\n\t// NOT be reused for the same object reached via another path (the\n\t// predicate may decide differently there). The cache then only tracks\n\t// in-progress ancestors (pure cycle detection) instead of memoising\n\t// completed subtrees. Without a predicate, results are path-independent\n\t// and shared references keep deduplicating to one clone. The budget\n\t// bounds the per-path expansion (exponential on diamond sharing).\n\tconst budget = options.ignoreKeyPredicate ? { visits: 0 } : undefined;\n\treturn omitInternal(value, options, ignoreKeys, [], visited, budget) as T;\n}\n\n/**\n * Maximum object-node visits for a single path-sensitive `deepOmit` walk.\n * Per-path cloning expands exponentially on diamond-shaped sharing; past\n * this bound the walk throws instead of hanging the process. One million\n * visits covers any realistically tree-shaped input.\n */\nconst PATH_SENSITIVE_VISIT_BUDGET = 1_000_000;\n\nfunction omitInternal(\n\tvalue: unknown,\n\toptions: DeepOmitOptions,\n\tignoreKeys: ReadonlySet<DeepOmitKey> | undefined,\n\tpath: DeepOmitPathSegment[],\n\tvisited: WeakMap<object, unknown>,\n\tbudget: { visits: number } | undefined,\n): unknown {\n\tif (value === null) return value;\n\tif (typeof value !== \"object\") return value;\n\n\tconst obj = value as object;\n\n\t// Cycles (and, in the path-independent case, shared references): return\n\t// the cached clone. Use `has` (not `cached !== undefined`) so a\n\t// legitimately-undefined cached clone would not be misclassified as\n\t// \"never seen\".\n\tif (visited.has(obj)) {\n\t\treturn visited.get(obj);\n\t}\n\n\tif (budget && ++budget.visits > PATH_SENSITIVE_VISIT_BUDGET) {\n\t\tthrow new Error(\n\t\t\t`deepOmit: exceeded ${PATH_SENSITIVE_VISIT_BUDGET} node visits. ` +\n\t\t\t\t`With ignoreKeyPredicate, objects reached via shared references ` +\n\t\t\t\t`are cloned once per path (the predicate may decide differently ` +\n\t\t\t\t`per path), which expands exponentially on diamond-shaped ` +\n\t\t\t\t`sharing. Restructure the input to a tree, or use ignoreKeys ` +\n\t\t\t\t`for path-independent filtering.`,\n\t\t);\n\t}\n\n\t// Arrays: recursively process every own property so sparse holes, custom\n\t// properties, symbols, and descriptors remain observable to deepEqual.\n\t// `Array.isArray` is brand-based and immune to `Symbol.toStringTag` spoofing.\n\tif (Array.isArray(obj)) {\n\t\tconst arr = obj as unknown[];\n\t\tconst clone: unknown[] = new Array(arr.length);\n\t\tconst lengthDescriptor = Object.getOwnPropertyDescriptor(arr, \"length\");\n\t\tvisited.set(obj, clone);\n\t\tfor (const key of Reflect.ownKeys(arr)) {\n\t\t\tif (key === \"length\") continue;\n\t\t\tconst segment = arrayPathSegment(key);\n\t\t\t// Key filtering never applies to array elements (numeric indices):\n\t\t\t// dropping an element would leave a hole and make structurally\n\t\t\t// different arrays compare equal through deepEqualExcept. It still\n\t\t\t// applies to custom (non-index) own properties on the array.\n\t\t\tif (\n\t\t\t\ttypeof segment !== \"number\" &&\n\t\t\t\tshouldIgnoreKey(key, path, ignoreKeys, options)\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(arr, key);\n\t\t\tif (descriptor === undefined) continue;\n\n\t\t\tpath.push(segment);\n\t\t\tif (\"value\" in descriptor) {\n\t\t\t\tdescriptor.value = omitInternal(\n\t\t\t\t\tdescriptor.value,\n\t\t\t\t\toptions,\n\t\t\t\t\tignoreKeys,\n\t\t\t\t\tpath,\n\t\t\t\t\tvisited,\n\t\t\t\t\tbudget,\n\t\t\t\t);\n\t\t\t}\n\t\t\tObject.defineProperty(clone, key, descriptor);\n\t\t\tpath.pop();\n\t\t}\n\t\tif (lengthDescriptor !== undefined) {\n\t\t\tObject.defineProperty(clone, \"length\", lengthDescriptor);\n\t\t}\n\t\tif (budget) visited.delete(obj);\n\t\treturn clone;\n\t}\n\n\tconst tag = Object.prototype.toString.call(obj);\n\n\t// Built-in atomic types: clone by type rather than walk. The detection\n\t// is brand-verified: a plain object spoofing a built-in tag falls\n\t// through to the plain-object walk below.\n\tif (isBuiltInObject(obj, tag)) {\n\t\tconst builtInClone = cloneBuiltIn(obj, tag);\n\t\tvisited.set(obj, builtInClone);\n\t\treturn builtInClone;\n\t}\n\n\t// Opaque intrinsics (boxed Symbol, generator, WeakRef, ...): pass\n\t// through by reference, mirroring deepEqual's identity comparison; a\n\t// plain \"clone\" would carry none of their internal state and could\n\t// never compare equal to anything, including itself.\n\tif (isOpaqueExoticTag(tag)) {\n\t\tvisited.set(obj, obj);\n\t\treturn obj;\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\t// Own property NAMES, not Object.keys: deepEqual compares plain objects\n\t// via getOwnPropertyNames (including non-enumerables, test-pinned\n\t// there), so dropping non-enumerable keys here would break the\n\t// deepEqualExcept-equals-deepEqual equivalence. getOwnPropertySymbols\n\t// includes non-enumerable symbols the same way.\n\tconst stringKeys = Object.getOwnPropertyNames(obj);\n\tconst symbolKeys = Object.getOwnPropertySymbols(obj);\n\n\tfor (const key of [...stringKeys, ...symbolKeys]) {\n\t\tif (shouldIgnoreKey(key, path, ignoreKeys, options)) continue;\n\t\tpath.push(key);\n\t\tassignOwn(\n\t\t\tclone,\n\t\t\tkey,\n\t\t\tomitInternal(\n\t\t\t\t(obj as Record<PropertyKey, unknown>)[key],\n\t\t\t\toptions,\n\t\t\t\tignoreKeys,\n\t\t\t\tpath,\n\t\t\t\tvisited,\n\t\t\t\tbudget,\n\t\t\t),\n\t\t\t// Preserve the source's enumerability so the clone stays an\n\t\t\t// exact key-set image (JSON.stringify, for-in, spread behave\n\t\t\t// the same on clone and original).\n\t\t\tObject.getOwnPropertyDescriptor(obj, key)?.enumerable ?? true,\n\t\t);\n\t\tpath.pop();\n\t}\n\n\tif (budget) visited.delete(obj);\n\treturn clone;\n}\n\nfunction arrayPathSegment(key: string | symbol): DeepOmitPathSegment {\n\tif (typeof key === \"symbol\") return key;\n\tconst index = Number(key);\n\treturn Number.isInteger(index) &&\n\t\tindex >= 0 &&\n\t\tindex < 4_294_967_295 &&\n\t\tString(index) === key\n\t\t? index\n\t\t: key;\n}\n\n/**\n * Assigns `value` as an OWN data property on `target` without going through\n * any inherited setter; critically, it never invokes the `__proto__` setter\n * even when `key === \"__proto__\"`. Required to defeat prototype-pollution\n * payloads that ship `__proto__` as a parsed-JSON own key.\n */\nfunction assignOwn(\n\ttarget: object,\n\tkey: PropertyKey,\n\tvalue: unknown,\n\tenumerable = true,\n): void {\n\tObject.defineProperty(target, key, {\n\t\tvalue,\n\t\twritable: true,\n\t\tenumerable,\n\t\tconfigurable: true,\n\t});\n}\n\n/**\n * Clones a built-in atomic type by case. Falls back to `structuredClone`\n * for anything not explicitly enumerated (e.g. DataView, TypedArrays,\n * Boolean/Number/String wrappers, all of which `deepEqual` compares by\n * value). Types that `deepEqual` compares BY REFERENCE (the shared\n * {@link REFERENCE_COMPARED_TAGS} set) are passed through by reference\n * instead; cloning them would make `deepEqualExcept(x, x)` false.\n * Promise/WeakMap/WeakSet additionally cannot be cloned at all\n * (`structuredClone` rejects them).\n */\nfunction cloneBuiltIn(obj: object, tag: string): unknown {\n\tif (REFERENCE_COMPARED_TAGS.has(tag)) return obj;\n\tswitch (tag) {\n\t\tcase \"[object Date]\":\n\t\t\treturn new Date((obj as Date).getTime());\n\t\tcase \"[object RegExp]\": {\n\t\t\tconst re = obj as RegExp;\n\t\t\tconst copy = new RegExp(re.source, re.flags);\n\t\t\tcopy.lastIndex = re.lastIndex;\n\t\t\treturn copy;\n\t\t}\n\t\tcase \"[object Map]\": {\n\t\t\tconst m = obj as Map<unknown, unknown>;\n\t\t\treturn new Map(m);\n\t\t}\n\t\tcase \"[object Set]\": {\n\t\t\tconst s = obj as Set<unknown>;\n\t\t\treturn new Set(s);\n\t\t}\n\t\tdefault:\n\t\t\treturn structuredClone(obj);\n\t}\n}\n\nfunction shouldIgnoreKey(\n\tkey: DeepOmitKey,\n\tpath: readonly DeepOmitPathSegment[],\n\tignoreKeys: ReadonlySet<DeepOmitKey> | undefined,\n\toptions: DeepOmitOptions,\n): boolean {\n\tif (ignoreKeys?.has(key)) return true;\n\t// The walk reuses ONE path array via push/pop; hand the predicate a\n\t// snapshot so paths it captures stay valid after the walk. Paid only\n\t// on the (already path-sensitive, budget-guarded) predicate mode.\n\tif (options.ignoreKeyPredicate?.(key, path.slice())) 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 { err, ok, type Result } from \"@shirudo/result\";\nimport { deepEqual } from \"../../internal/structural/deep-equal\";\nimport {\n\ttype DeepEqualExceptOptions,\n\tdeepEqualExcept,\n} from \"../../internal/structural/deep-equal-except\";\nimport {\n\tbuiltInTagWithoutInvokingAccessors,\n\thasIntrinsicPrototypeChain,\n\tisIntrinsicConstructorPrototype,\n} from \"../../internal/structural/is-built-in\";\n\n// ============================================================================\n// Functional Value Object API\n// ============================================================================\n\nexport type VO<T> = Readonly<T>;\n\n/**\n * `Object.freeze` does not protect internal slots: a frozen Date still\n * accepts `setTime`, a frozen Map still accepts `set`. To make the\n * \"deeply immutable\" guarantee real, the mutator methods are shadowed\n * with own throwing functions BEFORE the freeze. The shadows are\n * non-enumerable, so they are invisible to `Object.keys`/spread (deep\n * equality is unaffected) and `structuredClone` drops them (a `vo()`\n * round-trip never sees them).\n */\nconst DATE_MUTATORS: readonly string[] = [\n\t\"setTime\",\n\t\"setMilliseconds\",\n\t\"setUTCMilliseconds\",\n\t\"setSeconds\",\n\t\"setUTCSeconds\",\n\t\"setMinutes\",\n\t\"setUTCMinutes\",\n\t\"setHours\",\n\t\"setUTCHours\",\n\t\"setDate\",\n\t\"setUTCDate\",\n\t\"setMonth\",\n\t\"setUTCMonth\",\n\t\"setFullYear\",\n\t\"setUTCFullYear\",\n\t\"setYear\",\n];\n\n// One thrower function per (typeName, method) for the lifetime of the\n// module: createDomainEvent deep-freezes a Date per event, so fresh\n// per-instance closures would be pure allocation churn on a hot path.\nconst mutationThrowers = new Map<string, () => never>();\nconst mapEntries = Map.prototype.entries;\nconst setValues = Set.prototype.values;\n\nfunction mutationThrower(typeName: string, method: string): () => never {\n\tconst key = `${typeName}.${method}`;\n\tlet thrower = mutationThrowers.get(key);\n\tif (!thrower) {\n\t\tthrower = function throwFrozenMutation(): never {\n\t\t\tthrow new TypeError(\n\t\t\t\t`Cannot call ${method}() on a ${typeName} inside a deeply frozen value`,\n\t\t\t);\n\t\t};\n\t\tmutationThrowers.set(key, thrower);\n\t}\n\treturn thrower;\n}\n\n// Reused descriptor: Object.defineProperty reads it synchronously, so a\n// single mutable module-level object avoids one allocation per method.\nconst shadowDescriptor = {\n\tvalue: undefined as unknown,\n\twritable: false,\n\tenumerable: false,\n\tconfigurable: false,\n};\n\n/** Returns whether the shadows were installed. */\nfunction shadowMutators(\n\tobj: object,\n\ttypeName: string,\n\tmethods: readonly string[],\n): boolean {\n\t// A non-extensible built-in (frozen, sealed, or preventExtensions'd)\n\t// cannot receive shadow properties, so skip it (best effort; the caller\n\t// chose to lock it themselves).\n\tif (!Object.isExtensible(obj)) return false;\n\tfor (const method of methods) {\n\t\tshadowDescriptor.value = mutationThrower(typeName, method);\n\t\tObject.defineProperty(obj, method, shadowDescriptor);\n\t}\n\treturn true;\n}\n\n// Every ValueObject constructor records the class of the instance under\n// this key, as an own, non-enumerable, locked data property. The record\n// lets cloneForVo admit a value object inside another one by reference,\n// and it makes deepEqual class-aware: deepEqual counts own symbol keys and\n// compares functions by identity, so two nested value objects of different\n// classes compare unequal without deepEqual knowing about value objects.\n// The key is a Symbol.for, so an instance built by a second loaded copy of\n// this kit version is recognized too.\n//\n// A nested value object keeps all of its state in `props`: cloneForVo\n// rejects an instance with an own key outside `props` and the record. The\n// data gates never see the own fields of a subclass, and deepEqual counts\n// them. An open field would let ungated or mutable state into the value,\n// and nested equality would differ from `equals`. With that rule the\n// deepFreeze walk that follows the clone freezes the instance in place\n// and reaches nothing but its own sealed props.\n//\n// This is not a cooperative brand (see internal/cooperative-brand.ts).\n// That probe reads a `true` on a frozen carrier. An instance is open\n// until the walk reaches it, and the stored value must be the class. The\n// frozen carrier here is `props`, and the probe checks it. Like every kit\n// marker it catches accidents, not adversaries. The key version stamps\n// the shape of the record (its value is the class); bump it when that\n// shape changes.\nconst VALUE_OBJECT_CLASS = Symbol.for(\"@shirudo/ddd-kit/value-object-class/v1\");\n\nfunction recordValueObjectClass(\n\tinstance: object,\n\tvalueObjectClass: unknown,\n): void {\n\tObject.defineProperty(instance, VALUE_OBJECT_CLASS, {\n\t\tvalue: valueObjectClass,\n\t\tenumerable: false,\n\t\twritable: false,\n\t\tconfigurable: false,\n\t});\n}\n\nfunction isValueObjectInstance(value: unknown): boolean {\n\tif (value === null || typeof value !== \"object\") {\n\t\treturn false;\n\t}\n\tconst record = Reflect.getOwnPropertyDescriptor(value, VALUE_OBJECT_CLASS);\n\tif (\n\t\trecord === undefined ||\n\t\ttypeof record.value !== \"function\" ||\n\t\trecord.enumerable !== false ||\n\t\trecord.writable !== false ||\n\t\trecord.configurable !== false\n\t) {\n\t\treturn false;\n\t}\n\tconst props = Reflect.getOwnPropertyDescriptor(value, \"props\");\n\treturn props !== undefined && isSealedProps(props.value);\n}\n\n// deepFreeze passes a RegExp through unfrozen (see its doc), and a RegExp\n// is the one such built-in that cloneForVo admits as the whole props.\nfunction isSealedProps(props: unknown): boolean {\n\tif (typeof props !== \"object\" || props === null) {\n\t\treturn false;\n\t}\n\treturn (\n\t\tObject.isFrozen(props) ||\n\t\tbuiltInTagWithoutInvokingAccessors(props) === \"[object RegExp]\"\n\t);\n}\n\n// A class record under any descriptor, or sealed own props, marks an\n// instance that a kit copy of another version or a clone produced.\nfunction looksLikeValueObject(instance: object): boolean {\n\tif (Object.hasOwn(instance, VALUE_OBJECT_CLASS)) {\n\t\treturn true;\n\t}\n\tconst props = Reflect.getOwnPropertyDescriptor(instance, \"props\");\n\treturn props !== undefined && isSealedProps(props.value);\n}\n\nfunction openValueObjectKeys(instance: object): PropertyKey[] {\n\treturn Reflect.ownKeys(instance).filter(\n\t\t(key) => key !== \"props\" && key !== VALUE_OBJECT_CLASS,\n\t);\n}\n\nfunction rejectValueObjectAsInput(input: unknown, entry: string): void {\n\tif (isValueObjectInstance(input)) {\n\t\tthrow new TypeError(\n\t\t\t`${entry} does not accept a value object as its input: nest the value object under a key, or pass its props`,\n\t\t);\n\t}\n}\n\n/**\n * Deep freezes an object and all its nested properties recursively, then\n * returns it. Iterates both string-keyed and symbol-keyed own properties\n * so the freeze symmetry matches `deepEqual` (which also considers symbol\n * keys). Handles circular references by tracking visited objects.\n *\n * Note: `deepFreeze` mutates its argument in place; it sets `[[Frozen]]`\n * on the object you pass in. Callers that need to avoid touching the\n * input (e.g. `vo()`) should deep-clone first.\n *\n * Date/Map/Set keep internal-slot mutability under `Object.freeze`\n * (`setTime`, `set`, `add`, … still work on frozen instances), so their\n * mutator methods are shadowed with throwing own properties and Map/Set\n * contents are frozen recursively. The shadows are non-enumerable:\n * invisible to `Object.keys`, spread, `deepEqual`, and `structuredClone`.\n *\n * The shadowing is deny-by-enumeration: only the mutators known at\n * release time are blocked. If the runtime grows a NEW mutator (e.g. the\n * stage-3 `Map.prototype.getOrInsert` upsert proposal), it is not blocked\n * until the list is updated. Treat the mutator blocking as a guard rail,\n * not a security boundary.\n *\n * Two kinds of built-in pass through unfrozen. ArrayBuffer views\n * (TypedArrays, DataView): the spec forbids freezing a view with elements,\n * and a freeze cannot protect the underlying buffer, so their contents stay\n * mutable. RegExp: pattern and flags live in immutable internal slots, and\n * the only own data property, `lastIndex`, is scan state that every global\n * or sticky match writes. A frozen RegExp protects nothing and throws on\n * the first such match, so the RegExp keeps matching instead. A view or a\n * RegExp passes through whole: an expando property on it stays open, and\n * the walk does not enter its subtree.\n */\n// Every object whose whole subtree this module sealed: frozen, with every\n// Date, Map, and Set below it carrying the kit's mutator shadows. A later\n// walk stops at such an object, so a state written as `{ ...state, status }`\n// costs the root object, not the whole graph. A built-in frozen by the\n// caller takes no shadows and stays mutable through its prototype (a\n// frozen Date still answers setTime), so the objects that hold it are\n// walked again; their sealed siblings are not. A walk that meets a cycle\n// memoizes nothing, because a subtree's seal then depends on an ancestor\n// still in progress. The shadows are cooperative (see shadowMutators): a\n// member added through a prototype call that bypasses them is not seen by\n// a later walk either.\nconst DEEP_FROZEN = new WeakSet<object>();\n\n// Built-ins whose mutator shadows this module installed. They are\n// non-extensible afterwards like a caller-frozen one, and this set is what\n// tells the two apart on the next walk.\nconst KIT_SHADOWED = new WeakSet<object>();\n\ninterface FreezeWalk {\n\tcyclic: boolean;\n\treadonly sealed: object[];\n\t/** Objects this walk finished, with the seal of their subtree. */\n\treadonly done: Map<object, boolean>;\n\t/** Objects this walk is still inside of: a repeat visit is a cycle. */\n\treadonly inProgress: Set<object>;\n}\n\nexport function deepFreeze<T>(obj: T): Readonly<T> {\n\tconst walk: FreezeWalk = {\n\t\tcyclic: false,\n\t\tsealed: [],\n\t\tdone: new Map(),\n\t\tinProgress: new Set(),\n\t};\n\tfreezeDeep(obj, walk);\n\tif (!walk.cyclic) {\n\t\tfor (const object of walk.sealed) DEEP_FROZEN.add(object);\n\t}\n\treturn obj as Readonly<T>;\n}\n\n/** Freezes `obj` and its subtree; returns whether the subtree is sealed. */\nfunction freezeDeep(obj: unknown, walk: FreezeWalk): boolean {\n\tif (obj === null || typeof obj !== \"object\") {\n\t\treturn true;\n\t}\n\tif (DEEP_FROZEN.has(obj)) {\n\t\treturn true;\n\t}\n\t// ArrayBuffer views are atomic: Object.freeze on a typed array with\n\t// elements throws per spec, and freezing cannot protect the underlying\n\t// buffer anyway, so views are returned as-is (their contents stay\n\t// mutable). Mirrors deepEqual, which also treats views atomically.\n\tif (ArrayBuffer.isView(obj)) {\n\t\treturn true;\n\t}\n\t// A shared reference (two edges to one object) is finished on the first\n\t// visit and answers with its seal; only an object still in progress is\n\t// a cycle.\n\tconst finished = walk.done.get(obj);\n\tif (finished !== undefined) {\n\t\treturn finished;\n\t}\n\tif (walk.inProgress.has(obj)) {\n\t\twalk.cyclic = true;\n\t\treturn true;\n\t}\n\n\t// Internal-slot brand probes distinguish genuine built-ins without\n\t// invoking toStringTag accessors; spoofed plain objects are frozen\n\t// structurally.\n\tconst builtInTag = builtInTagWithoutInvokingAccessors(obj);\n\t// Atomic like a view, and like a view never bookkept: see the deepFreeze\n\t// doc.\n\tif (builtInTag === \"[object RegExp]\") {\n\t\treturn true;\n\t}\n\twalk.inProgress.add(obj);\n\tlet sealed = true;\n\n\t// Date/Map/Set keep internal-slot mutability under Object.freeze:\n\t// shadow their mutators and freeze Map/Set contents (entries are not\n\t// own keys, so the key walk below would miss them).\n\tif (\n\t\tbuiltInTag === \"[object Date]\" ||\n\t\tbuiltInTag === \"[object Map]\" ||\n\t\tbuiltInTag === \"[object Set]\"\n\t) {\n\t\tlet shadowed = KIT_SHADOWED.has(obj);\n\t\tif (builtInTag === \"[object Date]\") {\n\t\t\tshadowed = shadowMutators(obj, \"Date\", DATE_MUTATORS) || shadowed;\n\t\t} else if (builtInTag === \"[object Map]\") {\n\t\t\tfor (const [key, value] of obj as Map<unknown, unknown>) {\n\t\t\t\tif (!freezeDeep(key, walk)) sealed = false;\n\t\t\t\tif (!freezeDeep(value, walk)) sealed = false;\n\t\t\t}\n\t\t\tshadowed =\n\t\t\t\tshadowMutators(obj, \"Map\", [\"set\", \"delete\", \"clear\"]) || shadowed;\n\t\t} else if (builtInTag === \"[object Set]\") {\n\t\t\tfor (const member of obj as Set<unknown>) {\n\t\t\t\tif (!freezeDeep(member, walk)) sealed = false;\n\t\t\t}\n\t\t\tshadowed =\n\t\t\t\tshadowMutators(obj, \"Set\", [\"add\", \"delete\", \"clear\"]) || shadowed;\n\t\t}\n\t\tif (shadowed) KIT_SHADOWED.add(obj);\n\t\telse sealed = false;\n\t}\n\n\t// Reflect.ownKeys returns both string and symbol own keys.\n\tconst keys = Reflect.ownKeys(obj);\n\tfor (const key of keys) {\n\t\tconst value = (obj as Record<string | symbol, unknown>)[key];\n\t\tif (value !== null && typeof value === \"object\") {\n\t\t\tif (!freezeDeep(value, walk)) sealed = false;\n\t\t}\n\t}\n\n\tObject.freeze(obj);\n\twalk.inProgress.delete(obj);\n\twalk.done.set(obj, sealed);\n\tif (sealed) walk.sealed.push(obj);\n\treturn sealed;\n}\n\n/**\n * Deep clone used by `vo()` and the `ValueObject` constructor.\n *\n * Plain objects, arrays, and Map values are walked manually so\n * that symbol-keyed properties survive (which `structuredClone` silently\n * drops; they would otherwise be invisible to `voEquals`, whose\n * `deepEqual` DOES consider symbol keys) and shared references / cycles\n * keep their identity across Map boundaries. Function values throw,\n * preserving `vo()`'s documented data-not-behaviour gate. Built-ins without\n * immutable value semantics throw a descriptive `TypeError`. A kit\n * `ValueObject` instance is admitted by reference (see\n * `VALUE_OBJECT_CLASS`). Every other custom class instance and every\n * subclass of a built-in is rejected because cloning it without invoking\n * its constructor can silently lose private or non-enumerable state. Map\n * keys and Set members must be primitive because their equality is\n * identity-based and object identity cannot survive defensive cloning.\n * Accessor properties are rejected without invoking them. Admitted atomic\n * built-ins (Date, RegExp and primitive wrappers) delegate to\n * `structuredClone`, brand-verified so a `Symbol.toStringTag` spoofer is\n * walked as the plain object it is. `__proto__` own keys are copied as\n * inert data properties.\n */\nfunction cloneForVo(\n\tvalue: unknown,\n\tvisited: WeakMap<object, unknown>,\n): unknown {\n\tif (typeof value === \"function\") {\n\t\tthrow new TypeError(\n\t\t\t\"vo() does not accept function values: Value Objects are data, not behaviour\",\n\t\t);\n\t}\n\tif (value === null || typeof value !== \"object\") {\n\t\treturn value;\n\t}\n\tconst obj = value as object;\n\tif (ArrayBuffer.isView(obj)) {\n\t\tthrowUnsupportedValueSemantics(\n\t\t\tbuiltInTagWithoutInvokingAccessors(obj) ?? \"[object ArrayBuffer view]\",\n\t\t);\n\t}\n\tif (visited.has(obj)) {\n\t\treturn visited.get(obj);\n\t}\n\n\tif (Array.isArray(obj)) {\n\t\tif (!hasIntrinsicPrototypeChain(obj, \"Array\")) {\n\t\t\tthrowUnsupportedClassInstance(obj);\n\t\t}\n\t\tconst clone: unknown[] = new Array(obj.length);\n\t\tvisited.set(obj, clone);\n\t\tfor (const key of Reflect.ownKeys(obj)) {\n\t\t\tif (key === \"length\") continue;\n\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(obj, key);\n\t\t\tif (descriptor === undefined) continue;\n\t\t\tif (!(\"value\" in descriptor)) {\n\t\t\t\tthrowUnsupportedAccessorProperty();\n\t\t\t}\n\t\t\t// Drop non-enumerable string keys just like the plain-object branch\n\t\t\t// below, so an array and an object carrying the same hidden property\n\t\t\t// clone to the same value surface. Array indices are enumerable and\n\t\t\t// therefore preserved.\n\t\t\tif (typeof key === \"string\" && !descriptor.enumerable) continue;\n\t\t\tdescriptor.value = cloneForVo(descriptor.value, visited);\n\t\t\tObject.defineProperty(clone, key, descriptor);\n\t\t}\n\t\treturn clone;\n\t}\n\n\tconst tag = builtInTagWithoutInvokingAccessors(obj);\n\tif (tag !== undefined) {\n\t\tif (!hasIntrinsicPrototypeChain(obj)) {\n\t\t\tthrowUnsupportedClassInstance(obj);\n\t\t}\n\t\tif (tag === \"[object Map]\") {\n\t\t\tconst clone = new Map<unknown, unknown>();\n\t\t\tvisited.set(obj, clone);\n\t\t\tfor (const [key, entry] of mapEntries.call(\n\t\t\t\tobj as Map<unknown, unknown>,\n\t\t\t)) {\n\t\t\t\tif (!isPrimitiveValue(key)) {\n\t\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\t\"vo() Map keys must be primitive values to preserve value equality\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tclone.set(key, cloneForVo(entry, visited));\n\t\t\t}\n\t\t\treturn clone;\n\t\t}\n\t\tif (tag === \"[object Set]\") {\n\t\t\tconst clone = new Set<unknown>();\n\t\t\tvisited.set(obj, clone);\n\t\t\tfor (const member of setValues.call(obj as Set<unknown>)) {\n\t\t\t\tif (!isPrimitiveValue(member)) {\n\t\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\t\"vo() Set members must be primitive values to preserve value equality\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tclone.add(member);\n\t\t\t}\n\t\t\treturn clone;\n\t\t}\n\t\tif (\n\t\t\ttag === \"[object Promise]\" ||\n\t\t\ttag === \"[object WeakMap]\" ||\n\t\t\ttag === \"[object WeakSet]\"\n\t\t) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`vo() cannot clone a ${tag.slice(8, -1)}: Value Objects are plain data`,\n\t\t\t);\n\t\t}\n\t\tif (\n\t\t\ttag === \"[object Error]\" ||\n\t\t\ttag === \"[object ArrayBuffer]\" ||\n\t\t\ttag === \"[object SharedArrayBuffer]\"\n\t\t) {\n\t\t\tthrowUnsupportedValueSemantics(tag);\n\t\t}\n\t\tif (tag === \"[object RegExp]\") {\n\t\t\t// A global or sticky RegExp carries observable mutable scan state:\n\t\t\t// every test()/exec() writes lastIndex, so it is a stateful object,\n\t\t\t// not a value. deepFreeze passes a RegExp through, so nothing else\n\t\t\t// stops that write; reject it at admission. A plain (non-global,\n\t\t\t// non-sticky) RegExp never touches lastIndex and stays a genuine\n\t\t\t// immutable value.\n\t\t\tconst regExp = obj as RegExp;\n\t\t\tif (regExp.global || regExp.sticky) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\"vo() cannot accept a global or sticky RegExp: its lastIndex is mutable scan state, not an immutable value\",\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\t// Atomic built-ins admitted by the VO contract: Date, RegExp and\n\t\t// primitive wrappers all have stable value semantics in deepEqual.\n\t\tconst builtInClone = structuredClone(obj);\n\t\tvisited.set(obj, builtInClone);\n\t\treturn builtInClone;\n\t}\n\n\tconst prototype = Object.getPrototypeOf(obj);\n\tif (\n\t\tprototype !== null &&\n\t\t(!isIntrinsicConstructorPrototype(prototype, \"Object\") ||\n\t\t\tObject.getPrototypeOf(prototype) !== null)\n\t) {\n\t\tif (isValueObjectInstance(obj)) {\n\t\t\tconst openKeys = openValueObjectKeys(obj);\n\t\t\tif (openKeys.length > 0) throwOpenValueObjectFields(openKeys);\n\t\t\treturn obj;\n\t\t}\n\t\tthrowUnsupportedClassInstance(obj);\n\t}\n\n\t// Normalize cross-realm records to the local Object prototype.\n\tconst clone = Object.create(prototype === null ? null : Object.prototype);\n\tvisited.set(obj, clone);\n\tfor (const key of Reflect.ownKeys(obj)) {\n\t\tconst descriptor = Object.getOwnPropertyDescriptor(obj, key);\n\t\tif (descriptor === undefined) continue;\n\t\tif (!(\"value\" in descriptor)) {\n\t\t\tthrowUnsupportedAccessorProperty();\n\t\t}\n\t\tif (typeof key === \"string\" && !descriptor.enumerable) continue;\n\t\t// defineProperty (not assignment) so an own \"__proto__\" key can\n\t\t// never invoke the prototype setter.\n\t\tObject.defineProperty(clone, key, {\n\t\t\tvalue: cloneForVo(descriptor.value, visited),\n\t\t\twritable: true,\n\t\t\tenumerable: descriptor.enumerable,\n\t\t\tconfigurable: true,\n\t\t});\n\t}\n\treturn clone;\n}\n\nfunction throwUnsupportedClassInstance(instance: object): never {\n\tconst valueObjectHint = looksLikeValueObject(instance)\n\t\t? \". A value object is recognized only when a copy of this kit version built it and its props are frozen\"\n\t\t: \"\";\n\tthrow new TypeError(\n\t\t`vo() cannot clone custom class instances: Value Objects are plain data${valueObjectHint}`,\n\t);\n}\n\nfunction throwOpenValueObjectFields(keys: readonly PropertyKey[]): never {\n\tthrow new TypeError(\n\t\t`vo() cannot nest a value object with own fields outside props (${keys.map(String).join(\", \")}): keep the state of a value object in props`,\n\t);\n}\n\nfunction throwUnsupportedAccessorProperty(): never {\n\tthrow new TypeError(\n\t\t\"vo() cannot clone accessor properties: Value Objects are plain data\",\n\t);\n}\n\nfunction throwUnsupportedValueSemantics(tag: string): never {\n\tconst name = tag.startsWith(\"[object \") ? tag.slice(8, -1) : tag;\n\tthrow new TypeError(\n\t\t`vo() cannot accept ${name} values: Value Objects require immutable value semantics`,\n\t);\n}\n\nfunction isPrimitiveValue(value: unknown): boolean {\n\treturn (\n\t\tvalue === null || (typeof value !== \"object\" && typeof value !== \"function\")\n\t);\n}\n\n/**\n * Creates a deeply immutable value object from the given data.\n *\n * The input is first deep-cloned, then the clone is frozen, so calling\n * `vo(input)` never freezes the caller's own object graph as a\n * side-effect. Mutating the input afterwards does not bleed into the VO.\n * Symbol-keyed properties are preserved (matching `voEquals`). A kit\n * `ValueObject` instance nested in the input is kept by reference and\n * frozen in place; it must keep all of its state in `props`. A value\n * object as the input itself is rejected.\n * Function values and every other custom class instance are rejected\n * (Value Objects are plain data, not behaviour-bearing object graphs). Inputs must be trusted and\n * Proxy-free: ECMAScript provides no portable way to identify a transparent\n * Proxy without potentially executing its traps, so `vo()` is not a sandbox\n * for hostile in-process objects. Built-ins that cannot provide immutable,\n * value-based semantics are rejected instead of weakening the VO contract.\n *\n * @example\n * ```typescript\n * const nested = { lat: 52.5, lng: 13.4 };\n * const address = vo({ street: \"Main St\", coordinates: nested });\n * address.coordinates.lat = 99; // ❌ Cannot assign to read-only property\n * nested.lat = 0; // ✅ caller's input still mutable\n * ```\n */\nexport function vo<T>(t: T): VO<T> {\n\trejectValueObjectAsInput(t, \"vo()\");\n\treturn deepFreeze(cloneForVo(t, new WeakMap()) as T);\n}\n\n/**\n * Compares two value objects for equality based on their values.\n * Uses deep equality comparison that handles:\n * - Nested objects and arrays\n * - Primitives (including NaN)\n * - Dates, Maps, Sets, RegExp\n * - Symbol keys\n * - Circular references\n *\n * @param a - First value object\n * @param b - Second value object\n * @returns true if both objects have the same values, false otherwise\n *\n * @example\n * ```typescript\n * const money1 = vo({ amount: 100, currency: \"USD\" });\n * const money2 = vo({ amount: 100, currency: \"USD\" });\n * voEquals(money1, money2); // true\n *\n * const address1 = vo({\n * street: \"Main St\",\n * coordinates: { lat: 52.5, lng: 13.4 }\n * });\n * const address2 = vo({\n * street: \"Main St\",\n * coordinates: { lat: 52.5, lng: 13.4 }\n * });\n * voEquals(address1, address2); // true\n * ```\n */\nexport function voEquals<T>(a: VO<T>, b: VO<T>): boolean {\n\treturn 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 * The walk enters a nested `ValueObject` instance like any other object,\n * so inside it the path continues with `props`; `ignoreKeys: [\"props\"]`\n * empties every nested value object. The key under which the kit records\n * the class of the instance is never ignored.\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\ta: VO<T>,\n\tb: VO<T>,\n\toptions: DeepEqualExceptOptions,\n): boolean {\n\treturn deepEqualExcept(a, b, keepValueObjectClass(options));\n}\n\n// Without the class record two nested value objects of different classes\n// compare equal, so no option may ignore it.\nfunction keepValueObjectClass(\n\toptions: DeepEqualExceptOptions,\n): DeepEqualExceptOptions {\n\tconst { ignoreKeys, ignoreKeyPredicate } = options;\n\treturn {\n\t\t...options,\n\t\tignoreKeys: ignoreKeys?.filter((key) => key !== VALUE_OBJECT_CLASS),\n\t\tignoreKeyPredicate:\n\t\t\tignoreKeyPredicate &&\n\t\t\t((key, path) =>\n\t\t\t\tkey !== VALUE_OBJECT_CLASS && ignoreKeyPredicate(key, path)),\n\t};\n}\n\n/**\n * Creates a value object with optional validation.\n * Returns a Result type instead of throwing an error.\n *\n * Note: the Result covers VALIDATION failures only. Non-data values and\n * built-ins without immutable value semantics still throw a\n * `TypeError` from `vo()`; they cannot occur in parsed JSON and signal\n * a programming error, not a validation failure.\n *\n * @param t - The data to convert into a value object\n * @param validate - Validation function that returns true if valid\n * @param errorMessage - Optional custom error message if validation fails\n * @returns Result containing the value object if valid, or an error message if validation fails\n *\n * @example\n * ```typescript\n * const result = voWithValidation(\n * { amount: 100, currency: \"USD\" },\n * (m) => m.amount >= 0 && m.currency.length === 3,\n * \"Invalid money: amount must be non-negative and currency must be 3 characters\"\n * );\n *\n * if (result.ok) {\n * console.log(result.value); // Use the value object\n * } else {\n * console.error(result.error); // Handle validation error\n * }\n * ```\n */\nexport function voWithValidation<T>(\n\tt: T,\n\tvalidate: (value: T) => boolean,\n\terrorMessage?: string,\n): Result<VO<T>, string> {\n\tif (!validate(t)) {\n\t\treturn err(\n\t\t\terrorMessage ?? `Validation failed for value object: ${describeValue(t)}`,\n\t\t);\n\t}\n\treturn ok(vo(t));\n}\n\n/**\n * Best-effort rendering of a value for the default validation-failure\n * message. `JSON.stringify` throws for cyclic and BigInt-bearing values, and\n * the error path of a Result-returning function must never throw itself.\n */\nfunction describeValue(value: unknown): string {\n\ttry {\n\t\tconst json = JSON.stringify(value);\n\t\tif (json !== undefined) return json;\n\t} catch {\n\t\t// Cyclic or BigInt-bearing values cannot be JSON-serialised.\n\t}\n\treturn String(value);\n}\n\n// ============================================================================\n// Class-based Value Object API\n// ============================================================================\n\n/**\n * Interface for Value Objects.\n * Value Objects are immutable and defined by their properties.\n *\n * @template T - The shape of the value object's properties\n */\nexport interface IValueObject<T extends object> {\n\t/**\n\t * The immutable properties of the value object.\n\t */\n\treadonly props: Readonly<T>;\n\n\t/**\n\t * Checks if this value object is equal to another.\n\t * Uses deep equality comparison on the properties.\n\t *\n\t * @param other - The other value object to compare\n\t * @returns true if the properties are deeply equal\n\t */\n\tequals(other: IValueObject<T>): boolean;\n\n\t/**\n\t * Creates a clone of the value object with optional property overrides.\n\t *\n\t * @param props - Optional properties to override\n\t * @returns A new instance of the value object\n\t */\n\tclone(props?: Partial<T>): IValueObject<T>;\n\n\t/**\n\t * Serializes the value object to its raw properties for JSON operations.\n\t *\n\t * @returns The raw properties object\n\t */\n\ttoJSON(): Readonly<T>;\n}\n\n/**\n * Abstract base class for creating Value Objects.\n * Value Objects are immutable and defined by their properties. A value\n * object can hold other value objects in its props. Every instance\n * records its class under an own symbol key, so `equals` compares a\n * nested value object by class and props and does not call its `equals`\n * method.\n *\n * @template T - The shape of the value object's properties\n */\nexport abstract class ValueObject<T extends object> implements IValueObject<T> {\n\tpublic readonly props: Readonly<T>;\n\n\t/**\n\t * Creates a new ValueObject.\n\t * The plain-data properties are deep-cloned and then deeply\n\t * frozen, so the caller's own object graph is never frozen or mutated,\n\t * and later mutation of the input does not bleed into the value object.\n\t *\n\t * @param props - The properties of the value object\n\t * @example\n\t * ```ts\n\t * class Money extends ValueObject<{ amount: number; currency: string }> {\n\t * constructor(props: { amount: number; currency: string }) {\n\t * super(props);\n\t * }\n\t *\n\t * protected validate(props: { amount: number; currency: string }): void {\n\t * if (props.amount < 0) throw new Error(\"Amount cannot be negative\");\n\t * }\n\t * }\n\t * ```\n\t */\n\tconstructor(props: T) {\n\t\trejectValueObjectAsInput(props, \"new ValueObject()\");\n\t\tthis.validate(props);\n\t\t// Same clone as vo(): Map/Set contents are walked (so the caller's\n\t\t// entries are never frozen or shadowed in place), nested value\n\t\t// objects are kept by reference, and functions and other custom\n\t\t// class instances are rejected. A shallow `{ ...props }` or\n\t\t// deepOmit (which aliases reference-compared built-ins by design)\n\t\t// would let deepFreeze reach caller-owned objects.\n\t\tthis.props = deepFreeze(cloneForVo(props, new WeakMap()) as T);\n\t\trecordValueObjectClass(this, this.constructor);\n\t}\n\n\t/**\n\t * Optional validation hook that can be overridden by subclasses.\n\t * Should throw an error if validation fails.\n\t *\n\t * @param props - The properties to validate\n\t * @throws Error if validation fails\n\t */\n\tprotected validate(props: T): void {\n\t\t// Default implementation does nothing\n\t}\n\n\t/**\n\t * Checks if this value object is equal to another.\n\t * Uses deep equality comparison on the properties and checks for constructor equality.\n\t *\n\t * @param other - The other value object to compare\n\t * @returns true if the properties are deeply equal and constructors match\n\t */\n\tpublic equals(other: ValueObject<T>): boolean {\n\t\tif (other === null || other === undefined) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (this.constructor !== other.constructor) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn deepEqual(this.props, other.props);\n\t}\n\n\t/**\n\t * Creates a clone of the value object with optional property overrides.\n\t *\n\t * @param props - Optional properties to override\n\t * @returns A new instance of the value object\n\t */\n\tpublic clone(props?: Partial<T>): this {\n\t\tconst Constructor = this.constructor as new (props: T) => this;\n\t\tconst merged = { ...this.props, ...(props || {}) } as T;\n\t\t// A `{ ...spread }` copies only enumerable own keys, so any\n\t\t// non-enumerable own property that cloneForVo preserved on this.props\n\t\t// (e.g. a non-enumerable symbol) would be dropped, making\n\t\t// `x.equals(x.clone())` false because deepEqual counts all own symbols.\n\t\t// Re-attach every non-enumerable own key the caller did not override.\n\t\tfor (const key of Reflect.ownKeys(this.props)) {\n\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(this.props, key);\n\t\t\tif (descriptor === undefined || descriptor.enumerable) continue;\n\t\t\tif (props && Object.hasOwn(props, key)) continue;\n\t\t\tObject.defineProperty(merged, key, {\n\t\t\t\tvalue: (this.props as Record<PropertyKey, unknown>)[key as PropertyKey],\n\t\t\t\twritable: true,\n\t\t\t\tenumerable: false,\n\t\t\t\tconfigurable: true,\n\t\t\t});\n\t\t}\n\t\treturn new Constructor(merged);\n\t}\n\n\t/**\n\t * Serializes the value object to its raw properties for JSON operations.\n\t *\n\t * @returns The raw properties object\n\t */\n\tpublic toJSON(): Readonly<T> {\n\t\treturn this.props;\n\t}\n}\n","/**\n * A cooperative brand marks an object that a kit constructor produced, so\n * a second loaded copy of the kit (duplicate npm dependency, dual CJS/ESM\n * load, plugin bundle) recognizes it. A module-private WeakSet cannot do\n * that: it is bound to one loaded copy. The brand is a `Symbol.for` key\n * with the value `true`. The property is non-enumerable, so it never\n * leaks into spreads, JSON, or equality, and non-writable and\n * non-configurable, so nothing edits it after the stamp.\n *\n * The probe reads the brand as an OWN property with exactly these\n * attributes and requires the carrier to be frozen. An object that\n * inherits a branded object through its prototype can carry mutable own\n * overrides; a branded object that is still open can change after the\n * stamp. Neither is what the constructor produced. Every stamp site\n * therefore freezes the carrier right after {@link stampCooperativeBrand}.\n *\n * The brand is forgeable BY DESIGN. It catches accidental hand-rolled\n * literals; it is not a security boundary against code in the same\n * process that fakes it on purpose.\n *\n * Internal utility (not exported from the package barrels).\n */\nexport function stampCooperativeBrand(target: object, brand: symbol): void {\n\tObject.defineProperty(target, brand, {\n\t\tvalue: true,\n\t\tenumerable: false,\n\t\twritable: false,\n\t\tconfigurable: false,\n\t});\n}\n\n/**\n * Whether `value` carries `brand` as an own, non-enumerable, non-writable,\n * non-configurable `true` and is frozen. A Proxy trap that throws reads\n * as unbranded.\n */\nexport function hasCooperativeBrand(\n\tvalue: unknown,\n\tbrand: symbol,\n): value is object {\n\tif (\n\t\tvalue === null ||\n\t\t(typeof value !== \"object\" && typeof value !== \"function\")\n\t) {\n\t\treturn false;\n\t}\n\ttry {\n\t\tconst marker = Reflect.getOwnPropertyDescriptor(value, brand);\n\t\treturn (\n\t\t\tmarker?.value === true &&\n\t\t\tmarker.enumerable === false &&\n\t\t\tmarker.writable === false &&\n\t\t\tmarker.configurable === false &&\n\t\t\tObject.isFrozen(value)\n\t\t);\n\t} catch {\n\t\treturn false;\n\t}\n}\n","/**\n * Clock function producing a valid `Date` for the current instant.\n * Event-clock reads throw `TypeError` when the result is invalid.\n */\nexport type ClockFactory = () => Date;\n\n/** Immutable library default captured by the default domain-event factory. */\nexport const defaultClockFactory: ClockFactory = () => new Date();\n\n/** Internal defensive event-clock read. */\nexport function readClock(factory: ClockFactory): Date {\n\tconst reading = factory();\n\tconst value = reading instanceof Date ? reading.getTime() : Number.NaN;\n\tif (!Number.isFinite(value)) {\n\t\tthrow new TypeError(\"domain-event clock must return a valid Date\");\n\t}\n\treturn new Date(value);\n}\n","export type DomainEventValidationCode =\n\t| \"EVENT_ID_REQUIRED\"\n\t| \"EVENT_ID_INVALID\"\n\t| \"EVENT_TYPE_INVALID\"\n\t| \"EVENT_OCCURRED_AT_REQUIRED\"\n\t| \"EVENT_OCCURRED_AT_INVALID\"\n\t| \"EVENT_SCHEMA_VERSION_INVALID\"\n\t| \"EVENT_ADDRESS_INVALID\";\n\nexport type DomainEventValidationField =\n\t| \"eventId\"\n\t| \"type\"\n\t| \"occurredAt\"\n\t| \"schemaVersion\"\n\t| \"aggregateId\"\n\t| \"aggregateType\";\n\n/**\n * Stable contract error for malformed domain-event data.\n *\n * It remains a `TypeError` for JavaScript callers while exposing a code and\n * field that do not depend on the wording of the human-readable message.\n */\nexport class DomainEventValidationError extends TypeError {\n\t// The kit's error identity model applies here too: name === code, so\n\t// there is no second identifier to keep in sync.\n\toverride readonly name: string;\n\n\tconstructor(\n\t\treadonly code: DomainEventValidationCode,\n\t\treadonly field: DomainEventValidationField,\n\t\tmessage: string,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = code;\n\t\tObject.setPrototypeOf(this, new.target.prototype);\n\t}\n}\n\nexport class SnapshotTimeValidationError extends TypeError {\n\toverride readonly name = \"SNAPSHOT_TIME_INVALID\";\n\treadonly code = \"SNAPSHOT_TIME_INVALID\" as const;\n\treadonly field = \"snapshotAt\" as const;\n\n\tconstructor() {\n\t\tsuper(\"snapshotAt must be a valid Date\");\n\t\tObject.setPrototypeOf(this, new.target.prototype);\n\t}\n}\n","import { assertNoHostileOwnProtoKey } from \"../../errors/kit-errors\";\nimport {\n\thasCooperativeBrand,\n\tstampCooperativeBrand,\n} from \"../../internal/cooperative-brand\";\nimport { deepFreeze } from \"../value-object/value-object\";\nimport { type ClockFactory, defaultClockFactory, readClock } from \"./clock\";\nimport { DomainEventValidationError } from \"./domain-event-errors\";\n\nexport type { ClockFactory } from \"./clock\";\n\n/**\n * Factory function producing a fresh, unique event identifier for each call.\n *\n * The library ships a default that uses Web Crypto `crypto.randomUUID()`\n * (works on Node 19+, modern browsers in secure contexts, Deno, Bun,\n * Cloudflare Workers, Vercel Edge, and any runtime that implements Web\n * Crypto). Note that `crypto.randomUUID()` returns **UUID v4** (purely\n * random); for production event stores prefer a **time-ordered** id\n * format (UUID v7 / ULID / KSUID) so B-tree indexes on the eventId\n * column stay clustered and `ORDER BY eventId` matches creation order.\n * Supply one to {@link createDomainEventFactory} to use UUID v7, ULID,\n * KSUID, or another collision-safe format without mutating module state.\n */\nexport type EventIdFactory = () => string;\n\nconst defaultEventIdFactory: EventIdFactory = () => crypto.randomUUID();\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\treadonly correlationId?: string;\n\n\t/**\n\t * Conversation ID shared by every message in one long-running business\n\t * interaction, even when that interaction spans several correlations.\n\t */\n\treadonly conversationId?: 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\treadonly causationId?: string;\n\n\t/**\n\t * W3C Trace Context parent for technical tracing across process boundaries.\n\t * This is distinct from business correlation and conversation identifiers.\n\t */\n\treadonly traceparent?: string;\n\n\t/** Optional W3C vendor trace state associated with `traceparent`. */\n\treadonly tracestate?: string;\n\n\t/**\n\t * User ID of the person or system that triggered the event.\n\t */\n\treadonly userId?: string;\n\n\t/**\n\t * Source service or component that produced the event.\n\t */\n\treadonly source?: string;\n\n\t/**\n\t * Additional custom metadata fields.\n\t * Allows extensibility for domain-specific metadata.\n\t */\n\treadonly [key: string]: unknown;\n}\n\n/**\n * Domain Event represents something meaningful that happened in the domain.\n * Events are immutable and carry information about what occurred.\n *\n * **Events are PLAIN DATA objects**, constructed via `createDomainEvent`\n * (or the aggregate's `createEvent` plus application-shell recording path)\n * and deeply frozen. Class-based\n * event objects that satisfy this shape structurally via prototype\n * members are unsupported.\n *\n * **Field-accretion boundary.** Persistence positions, commit boundaries,\n * broker offsets, and other delivery concerns belong in an event envelope,\n * not on the domain event itself.\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`. Convenience constructors default to\n\t * `crypto.randomUUID()`; strict construction requires the caller to supply it.\n\t */\n\treadonly eventId: string;\n\n\t/**\n\t * The type of the event, used for routing and handling.\n\t */\n\treadonly type: 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\treadonly aggregateId?: 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\treadonly aggregateType?: 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\treadonly payload: P;\n\n\t/**\n\t * Timestamp when the accepted fact was recorded by the application shell.\n\t * Put business-relevant time in the payload under a domain name.\n\t */\n\treadonly occurredAt: Date;\n\n\t/**\n\t * Event schema version for handling schema evolution.\n\t * Required for safe schema migration in event-sourced systems.\n\t * Use 1 for the initial schema version.\n\t *\n\t * This is the event PAYLOAD schema version, not a persisted aggregate\n\t * position. Commit positions live on `CommittedDomainEvent`. It is\n\t * also not `AggregateSnapshot.schemaVersion`: that field versions the\n\t * stored snapshot state shape. The two evolve independently.\n\t */\n\treadonly schemaVersion: number;\n\n\t/**\n\t * Optional metadata for traceability, correlation, and auditing.\n\t * Includes correlationId, conversationId, causationId, userId, source, and\n\t * custom fields.\n\t */\n\treadonly metadata?: 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 * A domain event accepted by an aggregate but not yet given its recording\n * identity, recording time, or delivery metadata.\n *\n * The aggregate owns the event type, payload, source address, and payload\n * schema version because those values describe the business fact it produced.\n * The application shell later turns this value into a {@link DomainEvent}.\n */\nexport interface UncommittedDomainEvent<T extends string, P = void> {\n\treadonly type: T;\n\treadonly aggregateId?: string;\n\treadonly aggregateType?: string;\n\treadonly payload: P;\n\treadonly schemaVersion: number;\n}\n\n/** Upper-bound alias for any uncommitted domain-event shape. */\nexport type AnyUncommittedDomainEvent = UncommittedDomainEvent<string, unknown>;\n\n/** Derives the uncommitted shape represented by a concrete event or event union. */\nexport type UncommittedDomainEventOf<TEvent extends AnyDomainEvent> =\n\tTEvent extends DomainEvent<infer TType, infer TPayload>\n\t\t? UncommittedDomainEvent<TType, TPayload>\n\t\t: never;\n\n/** An aggregate may hold unstamped decisions and already recorded events together. */\nexport type PendingDomainEvent<TEvent extends AnyDomainEvent> =\n\t| TEvent\n\t| UncommittedDomainEventOf<TEvent>;\n\n/** Producer-owned options for an uncommitted event. */\nexport interface CreateUncommittedDomainEventOptions {\n\treadonly aggregateId?: string;\n\treadonly aggregateType?: string;\n\treadonly schemaVersion?: number;\n}\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\tschemaVersion?: number;\n\n\t/**\n\t * Event metadata: correlation, causation, user, source, custom fields.\n\t */\n\tmetadata?: EventMetadata;\n}\n\n/** Technical recording data attached by the application shell. */\nexport interface DomainEventStamp {\n\t/** Stable identity for this event instance. */\n\treadonly eventId: string;\n\t/** Time at which the accepted domain fact was recorded. */\n\treadonly occurredAt: Date;\n\t/** Optional correlation, causation, actor, and source metadata. */\n\treadonly metadata?: EventMetadata;\n}\n\n/** Full strict-construction options, including producer-owned event fields. */\nexport interface CreateDomainEventFromFactsOptions extends DomainEventStamp {\n\treadonly aggregateId?: string;\n\treadonly aggregateType?: string;\n\treadonly schemaVersion?: number;\n}\n\n/** Overrides accepted when an application-shell factory creates a stamp. */\nexport interface CreateDomainEventStampOptions {\n\treadonly eventId?: string;\n\treadonly occurredAt?: Date;\n\treadonly metadata?: EventMetadata;\n}\n\n/** Dependencies captured by one immutable domain-event factory instance. */\nexport interface DomainEventFactoryOptions {\n\t/** Event-id generator. Defaults to Web Crypto `crypto.randomUUID()`. */\n\treadonly eventIdFactory?: EventIdFactory;\n\t/** Event-recording clock. Defaults to `() => new Date()`. */\n\treadonly clock?: ClockFactory;\n\t/**\n\t * Origin stamped on every event this factory mints, unless the call site\n\t * names one itself.\n\t *\n\t * A plain value, not a factory like the two above. Those produce a new\n\t * value for each event. An origin identifies the system that mints them\n\t * and does not change between two of them.\n\t */\n\treadonly source?: string;\n}\n\n/**\n * Instance-bound event constructor. Each factory permanently captures its\n * own event-id and clock dependencies, so request and test instances cannot\n * overwrite one another through module state.\n */\nexport interface DomainEventFactory {\n\t/**\n\t * Creates immutable technical recording data in the application shell.\n\t */\n\treadonly createStamp: (\n\t\toptions?: CreateDomainEventStampOptions,\n\t) => DomainEventStamp;\n\treadonly create: {\n\t\t<T extends string>(\n\t\t\ttype: T,\n\t\t\tpayload?: undefined,\n\t\t\toptions?: CreateDomainEventOptions,\n\t\t): DomainEvent<T, void>;\n\t\t<T extends string, P>(\n\t\t\ttype: T,\n\t\t\tpayload: P,\n\t\t\toptions?: CreateDomainEventOptions,\n\t\t): DomainEvent<T, P>;\n\t};\n\t/**\n\t * Reads the captured clock and returns a defensive `Date` copy.\n\t * Throws `TypeError` when the clock does not return a valid date.\n\t */\n\treadonly now: () => Date;\n}\n\n/**\n * Creates an immutable, instance-bound domain-event factory.\n *\n * The supplied functions are read once and captured by value. The returned\n * object is frozen, so another request, test, or library cannot replace its\n * policy. Its {@link DomainEventFactory.createStamp} method is the\n * application-shell bridge that records an accepted aggregate decision.\n * Passing the factory through `AggregateConfig`\n * enables the explicitly named convenience methods, whose defaults read time\n * and randomness.\n *\n * @example\n * ```ts\n * const domainEvents = createDomainEventFactory({\n * eventIdFactory: () => uuidv7(),\n * clock: () => new Date(),\n * });\n * order.confirm();\n * recordPendingEvents(order, domainEvents);\n * ```\n */\n/**\n * Fills the origin of a factory into options that name none.\n *\n * A call site that states its own source keeps it: an explicit fact about one\n * event outranks the default of the factory that mints it.\n */\nfunction withFactorySource<T extends { readonly metadata?: EventMetadata }>(\n\toptions: T | undefined,\n\tsource: string | undefined,\n): T {\n\tconst given = (options ?? {}) as T;\n\tif (source === undefined || given.metadata?.source !== undefined) {\n\t\treturn given;\n\t}\n\treturn { ...given, metadata: { ...given.metadata, source } };\n}\n\nexport function createDomainEventFactory(\n\toptions: DomainEventFactoryOptions = {},\n): DomainEventFactory {\n\tconst eventIdFactory = options.eventIdFactory ?? defaultEventIdFactory;\n\tconst clock = options.clock ?? defaultClockFactory;\n\tconst { source } = options;\n\tconst create = (<T extends string, P>(\n\t\ttype: T,\n\t\tpayload?: P,\n\t\tcreateOptions?: CreateDomainEventOptions,\n\t): DomainEvent<T, P> =>\n\t\tmintDomainEvent(\n\t\t\ttype,\n\t\t\tpayload,\n\t\t\twithFactorySource(createOptions, source),\n\t\t\teventIdFactory,\n\t\t\tclock,\n\t\t)) as DomainEventFactory[\"create\"];\n\tconst createStamp = (\n\t\tstampOptions: CreateDomainEventStampOptions = {},\n\t): DomainEventStamp => {\n\t\tconst explicitOccurredAt =\n\t\t\tstampOptions.occurredAt === undefined\n\t\t\t\t? undefined\n\t\t\t\t: copyValidEventDate(stampOptions.occurredAt);\n\t\tif (stampOptions.eventId !== undefined) {\n\t\t\tassertNonBlankEventField(\n\t\t\t\tstampOptions.eventId,\n\t\t\t\t\"eventId\",\n\t\t\t\t\"EVENT_ID_INVALID\",\n\t\t\t);\n\t\t}\n\t\tconst eventId = stampOptions.eventId ?? eventIdFactory();\n\t\tassertNonBlankEventField(eventId, \"eventId\", \"EVENT_ID_INVALID\");\n\t\tconst occurredAt = explicitOccurredAt ?? readEventClock(clock);\n\t\tconst metadata = cloneOwnedEventData(\n\t\t\twithFactorySource(stampOptions, source).metadata,\n\t\t\t\"metadata\",\n\t\t);\n\t\tconst stamp: DomainEventStamp = {\n\t\t\teventId,\n\t\t\toccurredAt,\n\t\t\tmetadata,\n\t\t};\n\t\tconst owned = deepFreeze(stamp) as DomainEventStamp;\n\t\tFACTORY_OWNED_EVENT_STAMPS.add(owned);\n\t\treturn owned;\n\t};\n\n\treturn Object.freeze({\n\t\tcreateStamp,\n\t\tcreate,\n\t\tnow: () => readClock(clock),\n\t});\n}\n\n/**\n * Immutable UUID-v4/platform-clock factory used by the top-level\n * {@link createDomainEvent}. It cannot be reconfigured; construct an instance\n * with {@link createDomainEventFactory} for custom policy.\n */\nexport const defaultDomainEventFactory: DomainEventFactory =\n\tcreateDomainEventFactory();\n\n/**\n * Creates a domain event with default values.\n * Sets occurredAt to current date and schemaVersion to 1 if not provided.\n *\n * **Input ownership.** The event is deeply frozen, and `payload` and\n * `metadata` are deep-cloned first, so the caller's own objects are never\n * frozen in place and later mutation of them does not bleed into the\n * event (same contract as `vo()`). The clone follows the plain-data event\n * contract via `structuredClone`: functions, Promise, and WeakMap/WeakSet\n * values throw a `TypeError`; symbol-keyed properties are not carried\n * over.\n *\n * **For aggregate-internal events, prefer `this.createEvent(...)` on\n * `StateStoredAggregate` / `EventSourcedAggregate`.** That helper auto-injects\n * `aggregateId` (from `this.id`) and `aggregateType` (from the\n * aggregate's declared `aggregateType` property), which downstream\n * consumers (outbox dispatchers, projection handlers, audit logs)\n * route by. The commit boundary validates that both fields are present\n * and throws if they are missing, so a direct `createDomainEvent(...)`\n * call inside an aggregate that forgets the options is caught at\n * runtime. Record pending decisions in the application\n * shell before repository persistence or outbox harvest.\n *\n * Use `createDomainEvent(...)` directly for events that don't belong to\n * an aggregate: system events, integration events, configuration events,\n * test fixtures. For those, set `aggregateId` / `aggregateType` in\n * `options` if downstream consumers expect routing metadata.\n *\n * @param type - The event type\n * @param payload - The event payload\n * @param options - Optional event configuration (including `aggregateId`\n * and `aggregateType` for routing)\n * @returns A domain event\n *\n * @example\n * ```typescript\n * const event = createDomainEvent(\"OrderCreated\", { orderId: \"123\" });\n * ```\n */\n// Every recorded event a kit constructor returns is registered here: the\n// module-private tier of the recorded-event marker (nothing outside this\n// module can add to the set), so the aggregate recording paths can check\n// \"minted by the constructor\" directly instead of approximating it with\n// frozen-ness probes. Minted implies deeply frozen with owned payload/metadata\n// (binary buffers, which cannot be frozen, are rejected at the door).\n// WeakSet entries do not keep events alive.\nconst RECORDED_EVENTS = new WeakSet<object>();\nconst UNCOMMITTED_EVENTS = new WeakSet<object>();\nconst FACTORY_OWNED_EVENT_STAMPS = new WeakSet<object>();\n\n// Cooperative cross-instance tier of the mint check: a WeakSet is\n// bound to ONE loaded copy of this module, so an event legitimately\n// minted by a second copy of the kit would be rejected as unminted.\n// Such events are recognized by the cooperative brand instead, which\n// every constructor and kit-derived copy stamps before it freezes the\n// event (see `cooperative-brand.ts` for the probe rules).\n// The key strings are the cross-copy wire contract: every kit copy in a\n// process reads and stamps the same keys. The constant names follow the\n// shapes; the keys never change.\nconst RECORDED_BRAND = Symbol.for(\"@shirudo/ddd-kit.mintedEvent\");\nconst UNCOMMITTED_BRAND = Symbol.for(\"@shirudo/ddd-kit.uncommittedEvent\");\n\nfunction stampRecordedBrand(event: object): void {\n\tstampCooperativeBrand(event, RECORDED_BRAND);\n}\n\nfunction stampUncommittedBrand(event: object): void {\n\tstampCooperativeBrand(event, UNCOMMITTED_BRAND);\n}\n\nfunction isFactoryOwnedDomainEventStamp(stamp: object): boolean {\n\treturn FACTORY_OWNED_EVENT_STAMPS.has(stamp);\n}\n\n/**\n * Whether `event` is a recorded domain event: it came out of\n * {@link createDomainEvent}, {@link createDomainEventFromFacts}, or\n * {@link recordDomainEvent}, so it is deeply frozen with defensively copied\n * payload and metadata. An uncommitted decision carries the other brand; see\n * {@link isUncommittedDomainEvent}. Two tiers: events of THIS\n * loaded copy of the kit are verified through the module-private\n * WeakSet; events minted by ANOTHER copy (duplicate dependency, dual\n * CJS/ESM load) are recognized through a cooperative `Symbol.for`\n * brand that code in the same process can fake. The gate catches\n * accidents, not adversaries. Module-internal export for the aggregate\n * recording paths; not part of the package entries.\n */\nexport function isRecordedDomainEvent(event: object): event is AnyDomainEvent {\n\treturn (\n\t\tRECORDED_EVENTS.has(event) || hasCooperativeBrand(event, RECORDED_BRAND)\n\t);\n}\n\n/** Whether a value was created by {@link createUncommittedDomainEvent}. */\nexport function isUncommittedDomainEvent(\n\tevent: object,\n): event is AnyUncommittedDomainEvent {\n\treturn (\n\t\tUNCOMMITTED_EVENTS.has(event) ||\n\t\thasCooperativeBrand(event, UNCOMMITTED_BRAND)\n\t);\n}\n\nexport function createUncommittedDomainEvent<T extends string>(\n\ttype: T,\n\tpayload?: undefined,\n\toptions?: CreateUncommittedDomainEventOptions,\n): UncommittedDomainEvent<T, void>;\nexport function createUncommittedDomainEvent<T extends string, P>(\n\ttype: T,\n\tpayload: P,\n\toptions?: CreateUncommittedDomainEventOptions,\n): UncommittedDomainEvent<T, P>;\nexport function createUncommittedDomainEvent<T extends string, P>(\n\ttype: T,\n\tpayload?: P,\n\toptions?: CreateUncommittedDomainEventOptions,\n): UncommittedDomainEvent<T, P> {\n\tassertProducerOwnedEventFields(type, options);\n\tconst event: UncommittedDomainEvent<T, P> = {\n\t\ttype,\n\t\taggregateId: options?.aggregateId,\n\t\taggregateType: options?.aggregateType,\n\t\tpayload: cloneOwnedEventData(payload as P, \"payload\"),\n\t\tschemaVersion: options?.schemaVersion ?? 1,\n\t};\n\tstampUncommittedBrand(event);\n\tconst uncommitted = deepFreeze(event) as UncommittedDomainEvent<T, P>;\n\tUNCOMMITTED_EVENTS.add(uncommitted);\n\treturn uncommitted;\n}\n\n/** Brands and freezes a kit-derived copy of an uncommitted event. */\nexport function adoptUncommittedDomainEvent<T extends object>(copy: T): T {\n\tstampUncommittedBrand(copy);\n\tObject.freeze(copy);\n\tUNCOMMITTED_EVENTS.add(copy);\n\treturn copy;\n}\n\n/**\n * Attaches shell-owned recording data to an accepted aggregate decision.\n *\n * The decision supplies the domain type, payload, source address, and payload\n * schema version. The stamp supplies only event identity, recording time, and\n * trace metadata.\n */\nexport function recordDomainEvent<T extends string, P>(\n\tevent: UncommittedDomainEvent<T, P>,\n\tstamp: DomainEventStamp,\n): DomainEvent<T, P> {\n\tif (!isUncommittedDomainEvent(event)) {\n\t\tthrow new TypeError(\n\t\t\t\"recordDomainEvent requires an event created by createUncommittedDomainEvent\",\n\t\t);\n\t}\n\tif (isFactoryOwnedDomainEventStamp(stamp)) {\n\t\t// createStamp already validated, defensively copied, and deep-froze\n\t\t// every stamp field; re-validating or re-copying here would only pay\n\t\t// the work twice per recorded event.\n\t\treturn mintRecordedEvent(\n\t\t\tevent,\n\t\t\tstamp.eventId,\n\t\t\tstamp.occurredAt,\n\t\t\tstamp.metadata,\n\t\t);\n\t}\n\t// A caller-built stamp is caller-owned and unfrozen: validate and copy\n\t// the stamp fields before they enter the immutable event.\n\tassertNonBlankEventField(stamp.eventId, \"eventId\", \"EVENT_ID_INVALID\");\n\tconst occurredAt = deepFreeze(copyValidEventDate(stamp.occurredAt)) as Date;\n\tconst metadata = cloneOwnedEventData(stamp.metadata, \"metadata\");\n\treturn mintRecordedEvent(\n\t\tevent,\n\t\tstamp.eventId,\n\t\toccurredAt,\n\t\tmetadata === undefined\n\t\t\t? undefined\n\t\t\t: (deepFreeze(metadata) as EventMetadata),\n\t);\n}\n\n/**\n * Single mint tail for both stamp provenances. The stamp fields arrive\n * pre-validated, copied, and frozen (by `createStamp` for factory-owned\n * stamps, by `recordDomainEvent` for caller-built stamps); the uncommitted\n * event's payload is already defensively cloned and deeply frozen by its\n * constructor and is shared instead of paying a second deep copy per event.\n */\nfunction mintRecordedEvent<T extends string, P>(\n\tevent: UncommittedDomainEvent<T, P>,\n\teventId: string,\n\toccurredAt: Date,\n\tmetadata: EventMetadata | undefined,\n): DomainEvent<T, P> {\n\tassertProducerOwnedEventFields(event.type, event);\n\tconst recorded: DomainEvent<T, P> = {\n\t\teventId,\n\t\ttype: event.type,\n\t\taggregateId: event.aggregateId,\n\t\taggregateType: event.aggregateType,\n\t\tpayload: event.payload,\n\t\toccurredAt,\n\t\tschemaVersion: event.schemaVersion,\n\t\tmetadata,\n\t};\n\tstampRecordedBrand(recorded);\n\tObject.freeze(recorded);\n\tRECORDED_EVENTS.add(recorded);\n\treturn recorded;\n}\n\n/**\n * Brands, freezes, and registers a kit-derived copy of a recorded event\n * (e.g. the address-stamped copy `apply()` creates) as recorded itself.\n * The copy shares the already-frozen payload/metadata of its source,\n * so the mint guarantee carries over. Stamping the cooperative brand\n * before freezing keeps the copy recognizable by another loaded kit\n * instance as well as by this instance's WeakSet. Module-internal\n * export; not part of the package entries.\n */\nexport function adoptRecordedDomainEvent<T extends object>(copy: T): T {\n\tstampRecordedBrand(copy);\n\tObject.freeze(copy);\n\tRECORDED_EVENTS.add(copy);\n\treturn copy;\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\treturn defaultDomainEventFactory.create(\n\t\ttype,\n\t\tpayload as P,\n\t\toptions,\n\t) as DomainEvent<T, P>;\n}\n\n/**\n * Creates an already minted domain event exclusively from explicit envelope\n * facts. Unlike {@link createDomainEvent}, it has no clock or event-id fallback\n * and is useful when replay, migration, or a caller-owned boundary already has\n * the final identity and occurrence time.\n *\n * Aggregate behavior normally creates an {@link UncommittedDomainEvent} through\n * its protected `createEvent` helper. The application shell later records that\n * pending fact with caller-owned time and identity.\n */\nexport function createDomainEventFromFacts<T extends string>(\n\ttype: T,\n\tpayload: undefined,\n\toptions: CreateDomainEventFromFactsOptions,\n): DomainEvent<T, void>;\nexport function createDomainEventFromFacts<T extends string, P>(\n\ttype: T,\n\tpayload: P,\n\toptions: CreateDomainEventFromFactsOptions,\n): DomainEvent<T, P>;\nexport function createDomainEventFromFacts<T extends string, P>(\n\ttype: T,\n\tpayload: P | undefined,\n\toptions: CreateDomainEventFromFactsOptions,\n): DomainEvent<T, P> {\n\tif (options?.eventId === undefined) {\n\t\tmissingExplicitEventId();\n\t}\n\tif (options.occurredAt === undefined) {\n\t\tmissingExplicitOccurredAt();\n\t}\n\treturn mintDomainEvent(\n\t\ttype,\n\t\tpayload,\n\t\toptions,\n\t\tmissingExplicitEventId,\n\t\tmissingExplicitOccurredAt,\n\t);\n}\n\nfunction missingExplicitEventId(): string {\n\tthrow new DomainEventValidationError(\n\t\t\"EVENT_ID_REQUIRED\",\n\t\t\"eventId\",\n\t\t\"createDomainEventFromFacts requires an explicit eventId\",\n\t);\n}\n\nfunction missingExplicitOccurredAt(): Date {\n\tthrow new DomainEventValidationError(\n\t\t\"EVENT_OCCURRED_AT_REQUIRED\",\n\t\t\"occurredAt\",\n\t\t\"createDomainEventFromFacts requires an explicit occurredAt\",\n\t);\n}\n\nfunction mintDomainEvent<T extends string, P>(\n\ttype: T,\n\tpayload: P | undefined,\n\toptions: CreateDomainEventOptions | undefined,\n\teventIdFactory: EventIdFactory,\n\tclock: ClockFactory,\n): DomainEvent<T, P> {\n\tassertProducerOwnedEventFields(type, options);\n\tconst eventId = options?.eventId ?? eventIdFactory();\n\tassertNonBlankEventField(eventId, \"eventId\", \"EVENT_ID_INVALID\");\n\tconst occurredAt =\n\t\toptions?.occurredAt === undefined\n\t\t\t? readEventClock(clock)\n\t\t\t: copyValidEventDate(options.occurredAt);\n\tconst schemaVersion = options?.schemaVersion ?? 1;\n\tconst event: DomainEvent<T, P> = {\n\t\teventId,\n\t\ttype,\n\t\taggregateId: options?.aggregateId,\n\t\taggregateType: options?.aggregateType,\n\t\t// Defensive copies throughout: the deep-freeze below must never\n\t\t// reach the caller's own object graph. Without the clone, passing\n\t\t// (parts of) live aggregate state as payload, or reusing a metadata\n\t\t// object across events, would freeze the caller's objects in place;\n\t\t// the next mutation then throws far away from the cause. Same\n\t\t// ownership contract as `vo()` and the occurredAt copy.\n\t\tpayload: cloneOwnedEventData(payload as P, \"payload\"),\n\t\t// A caller-supplied occurredAt and a factory reading are both copied\n\t\t// before the event is frozen, so neither aliases caller-owned state.\n\t\toccurredAt,\n\t\tschemaVersion,\n\t\tmetadata: cloneOwnedEventData(options?.metadata, \"metadata\"),\n\t};\n\t// Deep-freeze so a mutating subscriber cannot poison subsequent\n\t// handlers: events are facts of the past and must be immutable\n\t// (Vernon, IDDD §8).\n\t// Brand BEFORE the freeze (a frozen object rejects new properties);\n\t// non-enumerable, so spreads, JSON, and equality never see it.\n\tstampRecordedBrand(event);\n\tconst minted = deepFreeze(event) as DomainEvent<T, P>;\n\tRECORDED_EVENTS.add(minted);\n\treturn minted;\n}\n\nfunction assertProducerOwnedEventFields(\n\ttype: unknown,\n\toptions:\n\t\t| CreateDomainEventOptions\n\t\t| CreateUncommittedDomainEventOptions\n\t\t| undefined,\n): void {\n\tassertNonBlankEventField(type, \"type\", \"EVENT_TYPE_INVALID\");\n\tconst schemaVersion = options?.schemaVersion ?? 1;\n\tif (\n\t\t!Number.isSafeInteger(schemaVersion) ||\n\t\ttypeof schemaVersion !== \"number\" ||\n\t\tschemaVersion < 1\n\t) {\n\t\tthrow new DomainEventValidationError(\n\t\t\t\"EVENT_SCHEMA_VERSION_INVALID\",\n\t\t\t\"schemaVersion\",\n\t\t\t\"domain-event schemaVersion must be a safe integer greater than or equal to 1\",\n\t\t);\n\t}\n\tif (options?.aggregateId !== undefined) {\n\t\tassertNonBlankEventField(\n\t\t\toptions.aggregateId,\n\t\t\t\"aggregateId\",\n\t\t\t\"EVENT_ADDRESS_INVALID\",\n\t\t);\n\t}\n\tif (options?.aggregateType !== undefined) {\n\t\tassertNonBlankEventField(\n\t\t\toptions.aggregateType,\n\t\t\t\"aggregateType\",\n\t\t\t\"EVENT_ADDRESS_INVALID\",\n\t\t);\n\t}\n}\n\nfunction assertNonBlankEventField(\n\tvalue: unknown,\n\tfield: \"eventId\" | \"type\" | \"aggregateId\" | \"aggregateType\",\n\tcode: \"EVENT_ID_INVALID\" | \"EVENT_TYPE_INVALID\" | \"EVENT_ADDRESS_INVALID\",\n): asserts value is string {\n\tif (typeof value !== \"string\" || value.trim().length === 0) {\n\t\tthrow new DomainEventValidationError(\n\t\t\tcode,\n\t\t\tfield,\n\t\t\t`domain-event ${field} must be a non-blank string`,\n\t\t);\n\t}\n}\n\nfunction copyValidEventDate(value: unknown): Date {\n\tif (!(value instanceof Date) || !Number.isFinite(value.getTime())) {\n\t\tthrow new DomainEventValidationError(\n\t\t\t\"EVENT_OCCURRED_AT_INVALID\",\n\t\t\t\"occurredAt\",\n\t\t\t\"domain-event occurredAt must be a valid Date\",\n\t\t);\n\t}\n\treturn new Date(value.getTime());\n}\n\nfunction readEventClock(clock: ClockFactory): Date {\n\treturn copyValidEventDate(clock());\n}\n\n/**\n * Deep-clones caller-supplied event data (payload, metadata) before the\n * event is frozen, so `createDomainEvent` never freezes or aliases the\n * caller's own object graph. Primitives pass through unchanged.\n *\n * Uses `structuredClone`, which matches the documented plain-data event\n * contract: functions, Promise, and WeakMap/WeakSet values throw a\n * descriptive `TypeError` (they are not data); symbol-keyed properties\n * are not carried over; a class instance would silently lose its\n * prototype, which the plain-data contract already rules out.\n */\nfunction cloneOwnedEventData<T>(value: T, field: \"payload\" | \"metadata\"): T {\n\tif (typeof value === \"function\") {\n\t\tthrow new TypeError(\n\t\t\t`createDomainEvent: ${field} must not be a function: domain events are plain data`,\n\t\t);\n\t}\n\t// Metadata is an object or absent; a null from a JSON envelope would\n\t// mint and then fail every metadata read far from the producer.\n\tif (value === null && field === \"metadata\") {\n\t\tthrow new TypeError(\n\t\t\t\"createDomainEvent: metadata must be an object or undefined; received null\",\n\t\t);\n\t}\n\tif (value === null || typeof value !== \"object\") {\n\t\treturn value;\n\t}\n\t// An own \"__proto__\" data key survives structuredClone and would\n\t// re-arm prototype pollution in every [[Set]]-based consumer of the\n\t// event; reject it at the root, the same contract as entity state.\n\tassertNoHostileOwnProtoKey(\n\t\tvalue,\n\t\tfield === \"payload\" ? \"Event payload\" : \"Event metadata\",\n\t);\n\t// Binary buffers are rejected BEFORE the clone: freezing cannot make\n\t// them immutable (the spec forbids freezing a view with elements, and\n\t// a frozen view still shares its mutable buffer), so accepting them\n\t// would break the mint guarantee \"minted implies deeply frozen\". They\n\t// do not survive JSON either, the wire discipline events already\n\t// document; encode binary as a string (base64/hex) or store it\n\t// outside the event and reference it.\n\tassertNoBinaryData(value, field);\n\ttry {\n\t\treturn structuredClone(value);\n\t} catch (cause) {\n\t\tthrow new TypeError(\n\t\t\t`createDomainEvent: ${field} must be plain, structured-cloneable data ` +\n\t\t\t\t`(no functions, Promises, or WeakMap/WeakSet values): domain events ` +\n\t\t\t\t`are plain data`,\n\t\t\t{ cause },\n\t\t);\n\t}\n}\n\nfunction isBinaryData(value: object): boolean {\n\treturn (\n\t\tArrayBuffer.isView(value) ||\n\t\tvalue instanceof ArrayBuffer ||\n\t\t(typeof SharedArrayBuffer !== \"undefined\" &&\n\t\t\tvalue instanceof SharedArrayBuffer)\n\t);\n}\n\n/**\n * Walks caller-supplied event data and rejects binary buffers anywhere\n * in the graph (TypedArray, DataView, ArrayBuffer, SharedArrayBuffer):\n * they are mutable by construction, so the deep-freeze that backs the\n * mint guarantee cannot cover them. Runs before the structured clone,\n * on the small plain-data graphs events are documented to carry.\n */\nfunction assertNoBinaryData(\n\tvalue: unknown,\n\tfield: \"payload\" | \"metadata\",\n\tvisited = new WeakSet<object>(),\n): void {\n\tif (value === null || typeof value !== \"object\") return;\n\tif (isBinaryData(value)) {\n\t\tthrow new TypeError(\n\t\t\t`createDomainEvent: ${field} must not contain binary buffers ` +\n\t\t\t\t`(TypedArray, DataView, ArrayBuffer, SharedArrayBuffer): they stay ` +\n\t\t\t\t`mutable under freezing and do not survive JSON. Encode binary as ` +\n\t\t\t\t`a string (base64/hex) or store it outside the event.`,\n\t\t);\n\t}\n\tif (visited.has(value)) return;\n\tvisited.add(value);\n\tif (value instanceof Map) {\n\t\tfor (const [k, v] of value) {\n\t\t\tassertNoBinaryData(k, field, visited);\n\t\t\tassertNoBinaryData(v, field, visited);\n\t\t}\n\t\treturn;\n\t}\n\tif (value instanceof Set) {\n\t\tfor (const v of value) assertNoBinaryData(v, field, visited);\n\t\treturn;\n\t}\n\tif (Array.isArray(value)) {\n\t\tfor (const v of value) assertNoBinaryData(v, field, visited);\n\t\treturn;\n\t}\n\tfor (const key of Object.keys(value)) {\n\t\tassertNoBinaryData((value as Record<string, unknown>)[key], field, visited);\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.eventId }) }\n * );\n * ```\n */\nexport function copyMetadata(\n\tsourceEvent: AnyDomainEvent,\n\tadditionalMetadata?: Partial<EventMetadata>,\n): EventMetadata {\n\t// Guard BOTH inputs: additional metadata from the caller AND the\n\t// source event's metadata, because events can be hand-built without\n\t// createDomainEvent. Spread itself is safe (CreateDataProperty, never\n\t// the __proto__ setter); the guard is about not CARRYING the payload.\n\tif (sourceEvent.metadata !== undefined) {\n\t\tassertNoHostileOwnProtoKey(sourceEvent.metadata, \"Event metadata\");\n\t}\n\tif (additionalMetadata !== undefined) {\n\t\tassertNoHostileOwnProtoKey(additionalMetadata, \"Event metadata\");\n\t}\n\treturn {\n\t\t...(sourceEvent.metadata ?? {}),\n\t\t...(additionalMetadata ?? {}),\n\t};\n}\n\n/**\n * Merges multiple metadata objects into one.\n * Later metadata objects override earlier ones for the same keys.\n *\n * @example\n * ```typescript\n * const metadata = mergeMetadata(\n * { correlationId: \"corr-123\" },\n * { userId: \"user-456\" },\n * { source: \"order-service\" }\n * );\n * ```\n */\nexport function mergeMetadata(\n\t...metadataObjects: Array<EventMetadata | undefined>\n): EventMetadata {\n\t// Copy via defineProperty, not Object.assign: assign uses [[Set]],\n\t// which invokes the `__proto__` setter for an own \"__proto__\" key\n\t// (typical of JSON.parse'd metadata from outbox rows or message\n\t// envelopes) and would install an attacker-controlled prototype.\n\tconst merged: Record<PropertyKey, unknown> = {};\n\tfor (const metadata of metadataObjects) {\n\t\tif (!metadata) continue;\n\t\tassertNoHostileOwnProtoKey(metadata, \"Event metadata\");\n\t\tfor (const key of Reflect.ownKeys(metadata)) {\n\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(metadata, key);\n\t\t\tif (!descriptor?.enumerable) continue;\n\t\t\tObject.defineProperty(merged, key, {\n\t\t\t\tvalue: (metadata as Record<PropertyKey, unknown>)[key],\n\t\t\t\twritable: true,\n\t\t\t\tenumerable: true,\n\t\t\t\tconfigurable: true,\n\t\t\t});\n\t\t}\n\t}\n\treturn merged as EventMetadata;\n}\n","import type { AnyDomainEvent } from \"../../domain/event/domain-event\";\nimport type { ExecutionContext } from \"../../internal/async/execution\";\nimport type {\n\tCommittedDomainEvent,\n\tEventCommitCandidate,\n} from \"../committed-event\";\n\n/**\n * One pending event in the outbox plus the opaque id the implementation\n * needs to ack it via `markDispatched`. The library does not prescribe\n * what `dispatchId` looks like: an implementation can reuse the event's\n * own `eventId`, generate its own UUID, use the row's auto-increment\n * primary key, or whatever the storage layer prefers.\n */\nexport interface OutboxRecord<Evt extends AnyDomainEvent>\n\textends CommittedDomainEvent<Evt> {\n\tdispatchId: string;\n\n\t/**\n\t * Failed delivery attempts so far. Populated by implementations that\n\t * track dispatch failures (see {@link DispatchTrackingOutbox});\n\t * plain `Outbox` implementations may omit it.\n\t */\n\tattempts?: number;\n}\n\n/** A record that exhausted its delivery attempts; see {@link DispatchTrackingOutbox.deadLetters}. */\nexport interface DeadLetterRecord<Evt extends AnyDomainEvent>\n\textends CommittedDomainEvent<Evt> {\n\tdispatchId: string;\n\t/** Failed delivery attempts when the record was dead-lettered. */\n\tattempts: number;\n\t/** Human-readable rendering of the last delivery error, if recorded. */\n\tlastError?: string;\n}\n\n/**\n * Write half of the transactional outbox: the only outbox capability the\n * write side (`withCommit`, `UnitOfWork`) depends on. Persisting the\n * events atomically with the aggregate state is the kit's guarantee;\n * DELIVERY is a separate, replaceable concern.\n *\n * Implement ONLY this interface to plug in an external delivery\n * solution: `add()` writes into that solution's outbox storage inside\n * the ambient transaction, and its own listener (polling or\n * WAL/CDC-based, such as a Debezium-style connector, a delivery\n * library, or a broker-native outbox) owns delivery entirely. The\n * kit-side poll surface ({@link Outbox}) is then never involved. See\n * the outbox guide, \"External dispatchers\".\n */\nexport interface OutboxWriter<Evt extends AnyDomainEvent> {\n\t/**\n\t * Finalizes and persists event commit candidates. Called from inside\n\t * `withCommit`'s transactional callback, atomically with the aggregate\n\t * write.\n\t *\n\t * For every qualified aggregate source, the adapter must serialize source\n\t * advancement, read its last eventful aggregate version, write that value as\n\t * `previousEventfulAggregateVersion` on every event in the candidate's\n\t * commit, and advance the source head to `aggregateVersion` in the SAME\n\t * transaction. A state-only aggregate commit does not call `add()` and must\n\t * therefore not advance this event-source head.\n\t *\n\t * A qualified source position `(aggregateType, aggregateId,\n\t * aggregateVersion, commitSequence)` MUST identify one immutable event. All\n\t * candidates for the same aggregate commit MUST also agree on `commitSize`.\n\t * Enforce both constraints before advancing the source head; a conflicting\n\t * retry must reject without replacing the stored event or changing the head.\n\t *\n\t * **Idempotency:** implementations should dedupe on\n\t * `candidate.event.eventId`. `withCommit` itself does not retry, but the\n\t * surrounding use case (a queue consumer, an HTTP retry, a transactional\n\t * outbox-dispatcher loop) may legitimately invoke the same write more than\n\t * once. A unique-key constraint on `(eventId)` in the outbox table is the\n\t * standard implementation; the source-head update and dedupe decision must\n\t * share the transaction. Idempotency applies only to an exact candidate\n\t * retry: the same event ID, qualified source, aggregate version, commit\n\t * sequence, and commit size. Reusing an `eventId` for another source or\n\t * position is a caller bug: adapters that retain the conflicting record\n\t * should reject it rather than replace or silently reinterpret it as a retry.\n\t */\n\tadd: (events: ReadonlyArray<EventCommitCandidate<Evt>>) => Promise<void>;\n}\n\n/**\n * Transactional outbox port: the bridge between the write-side\n * transaction and the (out-of-band) event dispatcher.\n *\n * Lifecycle:\n * 1. `add()` inside the write transaction (`withCommit` calls this) so\n * events persist atomically with the aggregate state\n * ({@link OutboxWriter}, the only part the write side needs).\n * 2. An outbox dispatcher (the kit's `OutboxDispatcher` or your own)\n * polls `getPending()` and forwards the events to subscribers /\n * external brokers.\n * 3. After successful dispatch, the dispatcher calls `markDispatched()`\n * with the records' `dispatchId`s so they don't come back next poll.\n *\n * `markDispatched` is required to be idempotent: calling it with an id\n * that's already marked is a no-op, not an error. This lets the\n * dispatcher safely retry on partial-failure.\n *\n * **Competing dispatcher instances** are an adapter contract, not a\n * dispatcher feature: a transactional implementation that should\n * support several concurrent pollers must make `getPending` claim the\n * returned records (`FOR UPDATE SKIP LOCKED` or equivalent). Without\n * claiming, run one logical dispatcher per outbox.\n *\n * The bundled dispatcher supplies an {@link ExecutionContext} to every poll-side\n * operation. Production adapters MUST pass its signal to native I/O or enforce\n * a native timeout no later than `deadlineAt`; the shell can bound its wait but\n * cannot terminate a promise that ignores cancellation. A timed-out write has\n * an unknown outcome. Acknowledgements must remain idempotent when they complete\n * late; a late failure update may count its original delivery attempt and must\n * still no-op after the record was dispatched.\n */\nexport interface Outbox<Evt extends AnyDomainEvent> extends OutboxWriter<Evt> {\n\t/**\n\t * Returns up to `limit` outbox records that have not yet been\n\t * dispatched, **in the order `add()` persisted them** (commit order).\n\t * The ordering is part of the port contract: `withCommit` promises\n\t * subscribers per-aggregate causal order, and a sequential dispatcher\n\t * can only honor that promise when this read is ordered. SQL-backed\n\t * implementations need a monotonic position column (an auto-increment\n\t * primary key works) and an `ORDER BY` on it; a bare `SELECT` returns\n\t * rows in storage order, not insertion order. The dispatcher polls\n\t * this on a schedule. When `limit` is omitted, the implementation\n\t * decides on a default page size. The bundled dispatcher always supplies\n\t * `context`; it is optional only so existing adapters remain assignable.\n\t */\n\tgetPending: (\n\t\tlimit?: number,\n\t\tcontext?: ExecutionContext,\n\t) => Promise<ReadonlyArray<OutboxRecord<Evt>>>;\n\n\t/**\n\t * Marks the given dispatch records as delivered so subsequent\n\t * `getPending` calls don't return them. Must be idempotent on\n\t * already-marked ids, including a late completion after the caller's\n\t * storage deadline. The bundled dispatcher always supplies `context`.\n\t */\n\tmarkDispatched: (\n\t\tdispatchIds: ReadonlyArray<string>,\n\t\tcontext?: ExecutionContext,\n\t) => Promise<void>;\n}\n\n/**\n * Optional extension of {@link Outbox} for dispatchers that track\n * delivery failures. Without failure tracking, a poison message (an\n * event whose delivery always throws) is redelivered forever: it comes\n * back from every `getPending` poll, blocks per-aggregate ordering\n * behind it, and burns the dispatcher's cycles. This extension gives\n * the dispatcher a bounded-retry story: report each failed delivery via\n * {@link markFailed}; the implementation moves records past its\n * attempt ceiling to a dead-letter set that `getPending` no longer\n * returns, and {@link deadLetters} exposes them for alerting, manual\n * inspection, and redelivery (deliver by hand, then ack via\n * `markDispatched`, which also clears dead-lettered records).\n *\n * See the outbox guide's dispatcher recipe for the retry-then-dead-letter\n * loop this port shape supports.\n */\nexport interface DispatchTrackingOutbox<Evt extends AnyDomainEvent>\n\textends Outbox<Evt> {\n\t/**\n\t * Records one failed delivery attempt for the given record:\n\t * increments its attempt count (surfaced as\n\t * {@link OutboxRecord.attempts}) and, once the implementation's\n\t * ceiling is reached, moves the record to the dead-letter set.\n\t * A no-op for unknown or already-dispatched ids (a late failure\n\t * report after a successful retry must not resurrect the record).\n\t * Returns the exact dead-letter record only on the call that performs\n\t * that transition; retries below the ceiling and no-ops return\n\t * `undefined`. This lets productive pollers emit an immediate signal\n\t * without scanning the durable dead-letter set after every failure. A late\n\t * completion may count that original delivery attempt; it must still no-op if\n\t * the record was dispatched in the meantime. The bundled dispatcher never\n\t * reissues the same store call and always supplies `context`.\n\t */\n\tmarkFailed: (\n\t\tdispatchId: string,\n\t\terror?: unknown,\n\t\tcontext?: ExecutionContext,\n\t) => Promise<DeadLetterRecord<Evt> | undefined>;\n\n\t/**\n\t * Records that exhausted their delivery attempts. They no longer\n\t * come back from `getPending`; wire this to durable alerting and\n\t * reconciliation so poison messages surface even if the poller stops\n\t * between this store transition and its immediate observer callback.\n\t */\n\tdeadLetters: () => Promise<ReadonlyArray<DeadLetterRecord<Evt>>>;\n}\n\n/**\n * Discriminates a {@link DispatchTrackingOutbox} from a plain\n * {@link Outbox} at runtime. The single source of truth for the check;\n * the dispatcher and the contract suite both use it, so what counts as\n * a tracking outbox cannot drift between them. Both tracking methods\n * must be present: a plain adapter that happens to expose an unrelated\n * `markFailed` helper must not be mistaken for one that implements the\n * tracking protocol and then be fed `(dispatchId, error)` arguments it\n * never asked for. Internal plumbing, not exported from the package\n * entries.\n */\nexport function isDispatchTrackingOutbox<Evt extends AnyDomainEvent>(\n\toutbox: Outbox<Evt> | DispatchTrackingOutbox<Evt>,\n): outbox is DispatchTrackingOutbox<Evt> {\n\tconst candidate = outbox as DispatchTrackingOutbox<Evt>;\n\treturn (\n\t\ttypeof candidate.markFailed === \"function\" &&\n\t\ttypeof candidate.deadLetters === \"function\"\n\t);\n}\n"],"mappings":"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"}