@shirudo/ddd-kit 3.0.0-rc.13 → 3.0.0-rc.15

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":"read-stream-pages.js","names":["#position"],"sources":["../../src/internal/structural/copy-plain-state.ts","../../src/domain/event/clock.ts","../../src/domain/event/domain-event-errors.ts","../../src/domain/event/domain-event.ts","../../src/internal/async/abort.ts","../../src/internal/validate.ts","../../src/internal/async/execution.ts","../../src/messaging/outbox/ports.ts","../../src/persistence/event-store/event-stream-page-guards.ts","../../src/persistence/event-store/read-stream-pages.ts"],"sourcesContent":["import {\n\ttype BuiltInTag,\n\tbuiltInTagWithoutInvokingAccessors,\n\tbuiltInTypeName,\n\thasIntrinsicPrototypeChain,\n\tisIntrinsicConstructorPrototype,\n} from \"./is-built-in\";\nimport { isMutatorShadow } from \"./shadowed-mutators\";\n\n/**\n * Returns a copy of `state` that shares no object with the original.\n * Throws a `TypeError` that names the path when the graph carries a value\n * a structured clone would lose or silently degrade. A class instance, a\n * subclass of a built-in included, loses the methods on its prototype. A\n * symbol-keyed, non-enumerable, or accessor property and an expando on a\n * built-in are dropped. A function or a symbol value throws a raw\n * `DataCloneError`. An Error, a Promise, a WeakMap, or a WeakSet cannot be\n * copied at all. A SharedArrayBuffer and a view over one keep sharing\n * their memory. A Proxy fails in the walk or in the clone; a failure in\n * the clone is rethrown as a `TypeError` with the cause. An error that a\n * Proxy trap throws in the walk passes unchanged, so a coded error of the\n * caller keeps its code.\n *\n * The walk reads the graph through property descriptors and walks a Map\n * or a Set with the built-in iteration, so no accessor and no own iterator\n * of the state runs. A Proxy runs its traps during the walk. A trap can\n * change the graph, and an accessor that a trap adds runs during the\n * clone. A second walk checks the clone, so a value that a trap swapped in\n * and the content of a built-in whose prototype was replaced are rejected\n * too. A trap that changes the graph after the first walk can still hide a\n * value that the copy drops: the walks catch accidents, not a hostile\n * Proxy. The second walk also follows the steps of the first walk: the kind\n * of each object and the key of each data property, in walk order. A copy\n * that differs throws, because a built-in whose prototype was replaced is\n * a built-in again in the copy and loses its own properties. `subject`\n * names the state in the messages.\n *\n * Plain objects (from any realm), arrays, Dates, Maps, Sets, bigints, and\n * typed arrays pass. A RegExp passes: pattern and flags survive the clone,\n * and `lastIndex` restores as 0. The scan state of a global or sticky\n * pattern is not domain data. On a built-in, the mutator shadows of a deep\n * freeze, the `lastIndex` of a RegExp, and the `length` of a boxed String\n * pass: they are machinery, not data. Every other non-enumerable property\n * throws. A non-enumerable symbol key passes anywhere: it is metadata by\n * convention.\n *\n * The concrete entity uses it for the plain state of a plain-data\n * state. The snapshot model uses it for the captured DTO and the restored\n * state. A state that carries a class-based child is mapped to plain data\n * first, in the entity or in the model.\n */\nexport function copyPlainState<T>(\n\tstate: T,\n\tsubject = \"copyPlainState: state\",\n): T {\n\treturn copyState(state, subject, \"clone\");\n}\n\n/**\n * {@link copyPlainState} that also rejects what `deepFreeze` cannot make\n * immutable: binary data (a typed array, a DataView, an ArrayBuffer, or a\n * SharedArrayBuffer) and a RegExp. The walk rejects such a value at its\n * tag, before it reads the indices of a typed array. Kit modules only.\n */\nexport function copyFreezableState<T>(state: T, subject: string): T {\n\treturn copyState(state, subject, \"freeze\");\n}\n\nfunction copyState<T>(state: T, subject: string, rule: Walk[\"rule\"]): T {\n\tconst recording = new StepRecording();\n\tassertCopyable(state, \"\", newWalk(subject, rule, recording));\n\tlet copy: T;\n\ttry {\n\t\tcopy = structuredClone(state);\n\t} catch (cause) {\n\t\tthrow new TypeError(\n\t\t\t`${subject} holds a Proxy or a host object that cannot be cloned, or a view over a detached or shrunk buffer; the cause names the value; map it to plain data`,\n\t\t\t{ cause },\n\t\t);\n\t}\n\t// The first walk trusts the prototype of an object, and a Proxy trap can\n\t// change the graph after it. The copy has genuine prototypes and no\n\t// Proxy, so this walk checks exactly what the caller gets. A built-in\n\t// whose prototype was replaced passes the first walk as a record, and\n\t// the copy drops its own properties. A count of the properties can\n\t// balance out with the content of the built-in, so this walk compares\n\t// each of its steps with the step of the first walk.\n\tconst comparison = new StepComparison(recording, subject);\n\tassertCopyable(copy, \"\", newWalk(subject, rule, comparison));\n\tcomparison.assertComplete();\n\treturn copy;\n}\n\nconst INDEX_KEY = /^(0|[1-9]\\d*)$/;\nconst BINARY_DATA_TAGS: ReadonlySet<BuiltInTag> = new Set<BuiltInTag>([\n\t\"[object TypedArray]\",\n\t\"[object DataView]\",\n\t\"[object ArrayBuffer]\",\n\t\"[object SharedArrayBuffer]\",\n]);\nconst REGEXP_TAG: BuiltInTag = \"[object RegExp]\";\nconst STRING_TAG: BuiltInTag = \"[object String]\";\nconst mapEntries = Map.prototype.entries;\nconst setValues = Set.prototype.values;\n\n/**\n * A step of a walk: the kind of an object that the walk enters, or the key\n * of a data property of a record or an array that it checks. A kind is a\n * symbol, so no key can be equal to it.\n */\ntype Step = string | symbol;\n\nconst RECORD_STEP = Symbol(\"record\");\nconst ARRAY_STEP = Symbol(\"array\");\nconst builtInSteps = new Map<BuiltInTag, symbol>();\n\nfunction builtInStep(tag: BuiltInTag): symbol {\n\tlet kind = builtInSteps.get(tag);\n\tif (kind === undefined) {\n\t\tkind = Symbol(tag);\n\t\tbuiltInSteps.set(tag, kind);\n\t}\n\treturn kind;\n}\n\n/**\n * The steps of the walk over the original, in walk order.\n */\nclass StepRecording {\n\treadonly steps: Step[] = [];\n\n\ttake(next: Step): void {\n\t\tthis.steps.push(next);\n\t}\n}\n\n/**\n * The walk over the copy compares each of its steps with the step of the\n * walk over the original at the same position. Structured clone keeps the\n * order of the keys, of Map entries, and of Set members, and it keeps\n * shared references, so the walk over an unchanged copy takes the same\n * steps. A step that differs, or a step that is missing, means that the\n * copy changed.\n */\nclass StepComparison {\n\t#position = 0;\n\n\tconstructor(\n\t\tprivate readonly recording: StepRecording,\n\t\tprivate readonly subject: string,\n\t) {}\n\n\ttake(next: Step, path: string): void {\n\t\tconst expected = this.recording.steps[this.#position];\n\t\tif (expected !== next) {\n\t\t\tthrowChangedInCopy(this.subject, path, expected, next);\n\t\t}\n\t\tthis.#position += 1;\n\t}\n\n\tassertComplete(): void {\n\t\tif (this.#position < this.recording.steps.length) {\n\t\t\tthrowChangedInCopy(\n\t\t\t\tthis.subject,\n\t\t\t\t\"\",\n\t\t\t\tthis.recording.steps[this.#position],\n\t\t\t\tundefined,\n\t\t\t);\n\t\t}\n\t}\n}\n\n/**\n * The objects that the walk has seen, the subject that its messages name,\n * its rule, and its steps. `\"clone\"` accepts what a structured clone\n * keeps. `\"freeze\"` also rejects what `deepFreeze` cannot make immutable.\n */\ninterface Walk {\n\treadonly seen: WeakSet<object>;\n\treadonly subject: string;\n\treadonly rule: \"clone\" | \"freeze\";\n\treadonly trace: StepRecording | StepComparison;\n}\n\nfunction newWalk(\n\tsubject: string,\n\trule: Walk[\"rule\"],\n\ttrace: Walk[\"trace\"],\n): Walk {\n\treturn { seen: new WeakSet(), subject, rule, trace };\n}\n\nfunction step(walk: Walk, next: Step, path: string): void {\n\twalk.trace.take(next, path);\n}\n\nfunction throwChangedInCopy(\n\tsubject: string,\n\tpath: string,\n\texpected: Step | undefined,\n\tfound: Step | undefined,\n): never {\n\tthrow new TypeError(\n\t\t`${subject}${path} changed in the copy: the state has ${describeStep(expected)} there, and the copy has ${describeStep(found)}; a built-in whose prototype was replaced is a built-in again in the copy and loses its own properties, and a Proxy trap can change the graph; map it to plain data`,\n\t);\n}\n\nfunction describeStep(step: Step | undefined): string {\n\tif (step === undefined) return \"nothing\";\n\tif (typeof step === \"string\") return `the key \"${step}\"`;\n\tif (step === RECORD_STEP) return \"a record\";\n\tif (step === ARRAY_STEP) return \"an array\";\n\tconst name = builtInTypeName(step.description as BuiltInTag);\n\treturn /^[AEIOU]/.test(name) ? `an ${name}` : `a ${name}`;\n}\n\nfunction assertCopyable(value: unknown, path: string, walk: Walk): void {\n\tif (typeof value === \"function\") {\n\t\tthrow new TypeError(\n\t\t\t`${walk.subject}${path} is a function; map it to plain data`,\n\t\t);\n\t}\n\t// Guided rejection instead of the raw DataCloneError DOMException that\n\t// structuredClone throws for symbols, which no recovery channel catches.\n\tif (typeof value === \"symbol\") {\n\t\tthrow new TypeError(\n\t\t\t`${walk.subject}${path} is a symbol; map it to plain data`,\n\t\t);\n\t}\n\tif (value === null || typeof value !== \"object\") return;\n\tconst object = value as object;\n\tif (walk.seen.has(object)) return;\n\twalk.seen.add(object);\n\n\tif (Array.isArray(object)) {\n\t\tif (!hasIntrinsicPrototypeChain(object, \"Array\")) {\n\t\t\tthrowClassInstance(object, path, walk.subject);\n\t\t}\n\t\tstep(walk, ARRAY_STEP, path);\n\t\tassertOwnPropertiesCopyable(object, path, walk, \"array\");\n\t\treturn;\n\t}\n\n\tconst tag = builtInTagWithoutInvokingAccessors(object);\n\tif (tag !== undefined) {\n\t\t// The tag comes from the internal slot, so a subclass gets the same\n\t\t// message as its built-in.\n\t\tif (walk.rule === \"freeze\") assertFreezable(tag, path, walk.subject);\n\t\tif (!hasIntrinsicPrototypeChain(object)) {\n\t\t\tthrowClassInstance(object, path, walk.subject);\n\t\t}\n\t\tstep(walk, builtInStep(tag), path);\n\t\tif (tag === \"[object Map]\") {\n\t\t\tlet index = 0;\n\t\t\tfor (const [key, entry] of mapEntries.call(\n\t\t\t\tobject as Map<unknown, unknown>,\n\t\t\t)) {\n\t\t\t\tassertCopyable(key, `${path}<map key #${index}>`, walk);\n\t\t\t\tassertCopyable(entry, `${path}<map value #${index}>`, walk);\n\t\t\t\tindex++;\n\t\t\t}\n\t\t} else if (tag === \"[object Set]\") {\n\t\t\tlet index = 0;\n\t\t\tfor (const member of setValues.call(object as Set<unknown>)) {\n\t\t\t\tassertCopyable(member, `${path}<set member #${index}>`, walk);\n\t\t\t\tindex++;\n\t\t\t}\n\t\t} else if (\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`${walk.subject}${path} is a ${builtInTypeName(tag)} and cannot be copied`,\n\t\t\t);\n\t\t} else if (tag === \"[object Error]\") {\n\t\t\tthrow new TypeError(\n\t\t\t\t`${walk.subject}${path} is an Error; map it to plain data`,\n\t\t\t);\n\t\t} else if (sharesMemory(object, tag)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`${walk.subject}${path} is backed by a SharedArrayBuffer and the copy would share its memory; map it to plain data`,\n\t\t\t);\n\t\t}\n\t\tassertOwnPropertiesCopyable(object, path, walk, tag);\n\t\treturn;\n\t}\n\n\tconst prototype = Object.getPrototypeOf(object);\n\tconst isPlainRecord =\n\t\tprototype === null ||\n\t\t(isIntrinsicConstructorPrototype(prototype, \"Object\") &&\n\t\t\tObject.getPrototypeOf(prototype) === null);\n\tif (!isPlainRecord) {\n\t\tthrowClassInstance(object, path, walk.subject);\n\t}\n\tstep(walk, RECORD_STEP, path);\n\tassertOwnPropertiesCopyable(object, path, walk, \"record\");\n}\n\n/**\n * Audits the own properties the clone would copy or drop. The clone keeps\n * the enumerable own keys of a record and of an array, expandos included,\n * and drops every own key of another built-in. `length` on an array is\n * its own machinery, not data, and so are the keys that\n * {@link isBuiltInMachinery} names. The index keys of a built-in below its\n * content length are its content and pass as such. Another index key of a\n * built-in is an expando. `owner` is the kind of `object`: an array, a\n * record, or the tag of a built-in.\n */\nfunction assertOwnPropertiesCopyable(\n\tobject: object,\n\tpath: string,\n\twalk: Walk,\n\towner: \"array\" | \"record\" | BuiltInTag,\n): void {\n\tconst tag = owner === \"array\" || owner === \"record\" ? undefined : owner;\n\tconst contentLength = tag === undefined ? 0 : contentLengthOf(object, tag);\n\tfor (const key of Reflect.ownKeys(object)) {\n\t\tconst descriptor = Object.getOwnPropertyDescriptor(object, key);\n\t\tif (descriptor === undefined) continue;\n\t\tif (typeof key === \"symbol\") {\n\t\t\tif (!descriptor.enumerable) continue;\n\t\t\tthrow new TypeError(\n\t\t\t\t`${walk.subject}${path} has a symbol-keyed property; map it to plain data`,\n\t\t\t);\n\t\t}\n\t\tif (owner === \"array\" && key === \"length\") continue;\n\t\tconst isIndex = INDEX_KEY.test(key);\n\t\tconst memberPath = isIndex ? `${path}[${key}]` : `${path}.${key}`;\n\t\tif (!descriptor.enumerable) {\n\t\t\tif (tag !== undefined && isBuiltInMachinery(tag, key, descriptor)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthrow new TypeError(\n\t\t\t\t`${walk.subject}${memberPath} is not enumerable and the clone would drop it; map it to plain data`,\n\t\t\t);\n\t\t}\n\t\tif (tag !== undefined && isIndex && Number(key) < contentLength) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (!(\"value\" in descriptor)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`${walk.subject}${memberPath} is an accessor property; map it to plain data`,\n\t\t\t);\n\t\t}\n\t\tif (tag !== undefined) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`${walk.subject}${memberPath} is an expando on a ${constructorName(Object.getPrototypeOf(object)) ?? \"built-in\"} and the clone would drop it; map it to plain data`,\n\t\t\t);\n\t\t}\n\t\tstep(walk, key, memberPath);\n\t\tassertCopyable(descriptor.value, memberPath, walk);\n\t}\n}\n\n/**\n * Whether an own non-enumerable property of a built-in is machinery, not\n * data: a function that shadows a mutator of a frozen Date, Map, or Set,\n * the scan position of a RegExp, or the length of a boxed String. The\n * clone drops the shadow and rebuilds the other two from the internal\n * slots.\n */\nfunction isBuiltInMachinery(\n\ttag: BuiltInTag,\n\tkey: string,\n\tdescriptor: PropertyDescriptor,\n): boolean {\n\treturn (\n\t\tisMutatorShadow(tag, key, descriptor) ||\n\t\t(tag === REGEXP_TAG && key === \"lastIndex\") ||\n\t\t(tag === STRING_TAG && key === \"length\")\n\t);\n}\n\n/**\n * The number of index keys that hold the content of a built-in: the\n * elements of a typed array and the characters of a boxed String.\n */\nfunction contentLengthOf(object: object, tag: BuiltInTag): number {\n\tif (tag === \"[object TypedArray]\") {\n\t\treturn typedArrayLength.call(object as ArrayBufferView);\n\t}\n\tif (tag === STRING_TAG) return stringValueOf.call(object).length;\n\treturn 0;\n}\n\n// The built-in readers read the internal slot, so an own `buffer` or\n// `length` accessor of the state does not run.\nconst typedArrayLength = Object.getOwnPropertyDescriptor(\n\tObject.getPrototypeOf(Uint8Array.prototype),\n\t\"length\",\n)?.get as (this: ArrayBufferView) => number;\nconst stringValueOf = String.prototype.valueOf;\nconst typedArrayBuffer = Object.getOwnPropertyDescriptor(\n\tObject.getPrototypeOf(Uint8Array.prototype),\n\t\"buffer\",\n)?.get as (this: ArrayBufferView) => ArrayBufferLike;\nconst dataViewBuffer = Object.getOwnPropertyDescriptor(\n\tDataView.prototype,\n\t\"buffer\",\n)?.get as (this: DataView) => ArrayBufferLike;\n\nfunction sharesMemory(object: object, tag: BuiltInTag): boolean {\n\tif (tag === \"[object SharedArrayBuffer]\") return true;\n\tif (tag === \"[object TypedArray]\") {\n\t\treturn isSharedArrayBuffer(\n\t\t\ttypedArrayBuffer.call(object as ArrayBufferView),\n\t\t);\n\t}\n\tif (tag === \"[object DataView]\") {\n\t\treturn isSharedArrayBuffer(dataViewBuffer.call(object as DataView));\n\t}\n\treturn false;\n}\n\nfunction isSharedArrayBuffer(buffer: ArrayBufferLike): boolean {\n\treturn (\n\t\tbuiltInTagWithoutInvokingAccessors(buffer) === \"[object SharedArrayBuffer]\"\n\t);\n}\n\nfunction assertFreezable(tag: BuiltInTag, path: string, subject: string): void {\n\tif (BINARY_DATA_TAGS.has(tag)) {\n\t\tthrow new TypeError(\n\t\t\t`${subject}${path} is binary data; binary buffers (a typed array, a DataView, an ArrayBuffer, or a SharedArrayBuffer) stay mutable under freezing and JSON does not keep them; encode the data as a string, for example base64`,\n\t\t);\n\t}\n\tif (tag === REGEXP_TAG) {\n\t\tthrow new TypeError(\n\t\t\t`${subject}${path} is a RegExp; a freeze cannot make it immutable, because compile() changes the pattern of a frozen RegExp before it throws, and a frozen global or sticky pattern throws on a match; keep its source and flags as strings`,\n\t\t);\n\t}\n}\n\nfunction throwClassInstance(\n\tobject: object,\n\tpath: string,\n\tsubject: string,\n): never {\n\tconst name =\n\t\tconstructorName(Object.getPrototypeOf(object)) ?? \"anonymous class\";\n\tthrow new TypeError(\n\t\t`${subject}${path} is a class instance (${name}); map it to plain data`,\n\t);\n}\n\n/**\n * The name of the constructor of `prototype`, read through property\n * descriptors, so that no accessor runs.\n */\nfunction constructorName(prototype: object | null): string | undefined {\n\tif (prototype === null) return undefined;\n\tconst owner = Object.getOwnPropertyDescriptor(\n\t\tprototype,\n\t\t\"constructor\",\n\t)?.value;\n\tif (typeof owner !== \"function\") return undefined;\n\tconst name = Object.getOwnPropertyDescriptor(owner, \"name\")?.value;\n\treturn typeof name === \"string\" && name !== \"\" ? name : undefined;\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_AGGREGATE_IDENTITY_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 { assertNoOwnProtoKey } from \"../../errors/kit-errors\";\nimport {\n\tapplyCooperativeBrand,\n\thasCooperativeBrand,\n} from \"../../internal/cooperative-brand\";\nimport { copyFreezableState } from \"../../internal/structural/copy-plain-state\";\nimport { isIntrinsicConstructorPrototype } from \"../../internal/structural/is-built-in\";\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 stamping)\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 event id,\n * stamp time, or delivery metadata.\n *\n * The aggregate owns the event type, payload, source aggregate identity,\n * and payload schema version because those values describe the business\n * fact it produced.\n * The application shell later turns this value into a {@link DomainEvent}.\n */\nexport interface UnstampedDomainEvent<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 unstamped domain-event shape. */\nexport type AnyUnstampedDomainEvent = UnstampedDomainEvent<string, unknown>;\n\n/** Derives the unstamped shape represented by a concrete event or event union. */\nexport type UnstampedDomainEventOf<TEvent extends AnyDomainEvent> =\n\tTEvent extends DomainEvent<infer TType, infer TPayload>\n\t\t? UnstampedDomainEvent<TType, TPayload>\n\t\t: never;\n\n/** An aggregate may hold unstamped decisions and already stamped events together. */\nexport type PendingDomainEvent<TEvent extends AnyDomainEvent> =\n\t| TEvent\n\t| UnstampedDomainEventOf<TEvent>;\n\n/** Producer-owned options for an unstamped event. */\nexport interface CreateUnstampedDomainEventOptions {\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 stamp 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 CreateStampedDomainEventOptions 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 builds, 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 builds 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 stamp 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 * stampPendingEvents(order, domainEvents);\n * ```\n */\nexport function createDomainEventFactory(\n\toptions: DomainEventFactoryOptions = {},\n): DomainEventFactory {\n\treturn buildDomainEventFactory(options, \"DomainEventFactory.create\");\n}\n\n/** `createOperation` is the name that the errors of `create` give. */\nfunction buildDomainEventFactory(\n\toptions: DomainEventFactoryOptions,\n\tcreateOperation: string,\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\tbuildDomainEvent(\n\t\t\ttype,\n\t\t\tpayload,\n\t\t\tcreateOptions,\n\t\t\teventIdFactory,\n\t\t\tclock,\n\t\t\tcreateOperation,\n\t\t\tsource,\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 = ownedEventMetadata(\n\t\t\tstampOptions.metadata,\n\t\t\t\"DomainEventFactory.createStamp\",\n\t\t\tsource,\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\tbuildDomainEventFactory({}, \"createDomainEvent\");\n\n// Every stamped 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// \"built by a kit constructor\" directly instead of approximating it with\n// frozen-ness probes. Kit-built 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 STAMPED_EVENTS = new WeakSet<object>();\nconst UNSTAMPED_EVENTS = new WeakSet<object>();\nconst FACTORY_OWNED_EVENT_STAMPS = new WeakSet<object>();\n\n// Cooperative cross-instance tier of the kit-built check: a WeakSet is\n// bound to ONE loaded copy of this module, so an event legitimately\n// built by a second copy of the kit would be rejected as hand-built.\n// Such events are recognized by the cooperative brand instead, which\n// every constructor and kit-derived copy applies 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 applies the same keys. The constant names follow the\n// vocabulary; the key strings never change, so an older word in a key is\n// part of the contract, not a name.\nconst STAMPED_BRAND = Symbol.for(\"@shirudo/ddd-kit.mintedEvent\");\nconst UNSTAMPED_BRAND = Symbol.for(\"@shirudo/ddd-kit.uncommittedEvent\");\n\nfunction brandStampedEvent(event: object): void {\n\tapplyCooperativeBrand(event, STAMPED_BRAND);\n}\n\nfunction brandUnstampedEvent(event: object): void {\n\tapplyCooperativeBrand(event, UNSTAMPED_BRAND);\n}\n\nfunction isFactoryOwnedDomainEventStamp(stamp: object): boolean {\n\treturn FACTORY_OWNED_EVENT_STAMPS.has(stamp);\n}\n\n/**\n * Whether `event` is a stamped domain event: it came out of\n * {@link createDomainEvent}, {@link createStampedDomainEvent}, or\n * {@link stampDomainEvent}, so it is deeply frozen with defensively copied\n * payload and metadata. An unstamped decision carries the other brand; see\n * {@link isUnstampedDomainEvent}. Two tiers: events of THIS\n * loaded copy of the kit are verified through the module-private\n * WeakSet; events built 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 isStampedDomainEvent(event: object): event is AnyDomainEvent {\n\treturn STAMPED_EVENTS.has(event) || hasCooperativeBrand(event, STAMPED_BRAND);\n}\n\n/** Whether a value is a kit-built unstamped event. */\nexport function isUnstampedDomainEvent(\n\tevent: object,\n): event is AnyUnstampedDomainEvent {\n\treturn (\n\t\tUNSTAMPED_EVENTS.has(event) || hasCooperativeBrand(event, UNSTAMPED_BRAND)\n\t);\n}\n\n/**\n * Creates an unstamped domain event: the event that an aggregate method\n * returns before the application shell stamps it. The payload and the\n * metadata follow the input ownership rule of {@link createDomainEvent}.\n */\nexport function createUnstampedDomainEvent<T extends string>(\n\ttype: T,\n\tpayload?: undefined,\n\toptions?: CreateUnstampedDomainEventOptions,\n): UnstampedDomainEvent<T, void>;\nexport function createUnstampedDomainEvent<T extends string, P>(\n\ttype: T,\n\tpayload: P,\n\toptions?: CreateUnstampedDomainEventOptions,\n): UnstampedDomainEvent<T, P>;\nexport function createUnstampedDomainEvent<T extends string, P>(\n\ttype: T,\n\tpayload?: P,\n\toptions?: CreateUnstampedDomainEventOptions,\n): UnstampedDomainEvent<T, P> {\n\treturn buildUnstampedDomainEvent(\n\t\ttype,\n\t\tpayload,\n\t\toptions,\n\t\t\"createUnstampedDomainEvent\",\n\t);\n}\n\n/**\n * {@link createUnstampedDomainEvent} whose errors name `operation`, the\n * function that the caller called. Module-internal export; not part of the\n * package entries.\n */\nexport function buildUnstampedDomainEvent<T extends string, P>(\n\ttype: T,\n\tpayload: P | undefined,\n\toptions: CreateUnstampedDomainEventOptions | undefined,\n\toperation: string,\n): UnstampedDomainEvent<T, P> {\n\tassertProducerOwnedEventFields(type, options);\n\tconst event: UnstampedDomainEvent<T, P> = {\n\t\ttype,\n\t\taggregateId: options?.aggregateId,\n\t\taggregateType: options?.aggregateType,\n\t\tpayload: cloneOwnedEventData(payload as P, \"payload\", operation),\n\t\tschemaVersion: options?.schemaVersion ?? 1,\n\t};\n\tbrandUnstampedEvent(event);\n\tconst unstamped = deepFreeze(event) as UnstampedDomainEvent<T, P>;\n\tUNSTAMPED_EVENTS.add(unstamped);\n\treturn unstamped;\n}\n\n/** Brands and freezes a kit-derived copy of an unstamped event. */\nexport function adoptUnstampedDomainEvent<T extends object>(copy: T): T {\n\tbrandUnstampedEvent(copy);\n\tObject.freeze(copy);\n\tUNSTAMPED_EVENTS.add(copy);\n\treturn copy;\n}\n\n/**\n * Attaches shell-owned stamp data to an accepted aggregate decision.\n *\n * The decision supplies the domain type, payload, source aggregate\n * identity, and payload schema version. The stamp supplies only event\n * identity, stamp time, and trace metadata.\n */\nexport function stampDomainEvent<T extends string, P>(\n\tevent: UnstampedDomainEvent<T, P>,\n\tstamp: DomainEventStamp,\n): DomainEvent<T, P> {\n\tif (!isUnstampedDomainEvent(event)) {\n\t\tthrow new TypeError(\n\t\t\t\"stampDomainEvent requires an unstamped event from an aggregate's createEvent\",\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 stamped event.\n\t\treturn buildStampedEvent(\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 = ownedEventMetadata(stamp.metadata, \"stampDomainEvent\");\n\treturn buildStampedEvent(\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 build tail for both stamp provenances. The stamp fields arrive\n * pre-validated, copied, and frozen (by `createStamp` for factory-owned\n * stamps, by `stampDomainEvent` for caller-built stamps); the unstamped\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 buildStampedEvent<T extends string, P>(\n\tevent: UnstampedDomainEvent<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\tbrandStampedEvent(recorded);\n\tObject.freeze(recorded);\n\tSTAMPED_EVENTS.add(recorded);\n\treturn recorded;\n}\n\n/**\n * Brands, freezes, and registers a kit-derived copy of a stamped event\n * (e.g. the copy `apply()` stamps with the aggregate identity) as recorded\n * itself.\n * The copy shares the already-frozen payload/metadata of its source,\n * so the kit-built guarantee carries over. Applying 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 adoptStampedDomainEvent<T extends object>(copy: T): T {\n\tbrandStampedEvent(copy);\n\tObject.freeze(copy);\n\tSTAMPED_EVENTS.add(copy);\n\treturn copy;\n}\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 event\n * (same contract as `valueObject()`). The event data rule checks the data before the\n * copy and the copy after it. So the copy loses no data without an error,\n * and no getter of the data runs. The in-memory event store applies the\n * same rule on append. The checks catch accidents, not a hostile `Proxy`: a\n * trap that changes the data during the check can hide a loss. An error\n * that a `Proxy` trap throws passes unchanged, so a coded error of the\n * caller keeps its code. These values throw a `TypeError`: a function, a\n * Promise, a WeakMap or a WeakSet, an `Error`, a host object such as a\n * `File`, a binary buffer, a `RegExp`, and shared memory. The same holds\n * for what the copy would lose or change: a class instance, an accessor, an\n * enumerable symbol-keyed property, a non-enumerable data property, and an\n * expando on a built-in. A non-enumerable symbol key is metadata by\n * convention, and the event does not get it. Map a value object to plain\n * data before it goes into an event. `toJSON()` of a `ValueObject` is\n * shallow, so map a nested value object too.\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. Stamp pending decisions in the application\n * shell before repository persistence or outbox collection.\n *\n * Use `createDomainEvent(...)` directly for events that don't belong to\n * an aggregate: system events, integration events, configuration events,\n * test fixtures. For those, set `aggregateId` / `aggregateType` in\n * `options` if downstream consumers expect routing metadata.\n *\n * @param type - The event type\n * @param payload - The event payload\n * @param options - Optional event configuration (including `aggregateId`\n * and `aggregateType` for routing)\n * @returns A domain event\n *\n * @example\n * ```typescript\n * const event = createDomainEvent(\"OrderCreated\", { orderId: \"123\" });\n * ```\n */\nexport function createDomainEvent<T extends string>(\n\ttype: T,\n\tpayload?: undefined,\n\toptions?: CreateDomainEventOptions,\n): DomainEvent<T, void>;\nexport function createDomainEvent<T extends string, P>(\n\ttype: T,\n\tpayload: P,\n\toptions?: CreateDomainEventOptions,\n): DomainEvent<T, P>;\nexport function createDomainEvent<T extends string, P>(\n\ttype: T,\n\tpayload?: P,\n\toptions?: CreateDomainEventOptions,\n): DomainEvent<T, P> {\n\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 a kit-built, stamped 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 UnstampedDomainEvent} through\n * its protected `createEvent` helper. The application shell later records that\n * pending fact with caller-owned time and identity.\n */\nexport function createStampedDomainEvent<T extends string>(\n\ttype: T,\n\tpayload: undefined,\n\toptions: CreateStampedDomainEventOptions,\n): DomainEvent<T, void>;\nexport function createStampedDomainEvent<T extends string, P>(\n\ttype: T,\n\tpayload: P,\n\toptions: CreateStampedDomainEventOptions,\n): DomainEvent<T, P>;\nexport function createStampedDomainEvent<T extends string, P>(\n\ttype: T,\n\tpayload: P | undefined,\n\toptions: CreateStampedDomainEventOptions,\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 buildDomainEvent(\n\t\ttype,\n\t\tpayload,\n\t\toptions,\n\t\tmissingExplicitEventId,\n\t\tmissingExplicitOccurredAt,\n\t\t\"createStampedDomainEvent\",\n\t);\n}\n\nfunction missingExplicitEventId(): string {\n\tthrow new DomainEventValidationError(\n\t\t\"EVENT_ID_REQUIRED\",\n\t\t\"eventId\",\n\t\t\"createStampedDomainEvent 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\"createStampedDomainEvent requires an explicit occurredAt\",\n\t);\n}\n\nfunction buildDomainEvent<T extends string, P>(\n\ttype: T,\n\tpayload: P | undefined,\n\toptions: CreateDomainEventOptions | undefined,\n\teventIdFactory: EventIdFactory,\n\tclock: ClockFactory,\n\toperation: string,\n\tfactorySource?: string,\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 `valueObject()` and the occurredAt copy.\n\t\tpayload: cloneOwnedEventData(payload as P, \"payload\", operation),\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: ownedEventMetadata(options?.metadata, operation, factorySource),\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\tbrandStampedEvent(event);\n\tconst built = deepFreeze(event) as DomainEvent<T, P>;\n\tSTAMPED_EVENTS.add(built);\n\treturn built;\n}\n\nfunction assertProducerOwnedEventFields(\n\ttype: unknown,\n\toptions:\n\t\t| CreateDomainEventOptions\n\t\t| CreateUnstampedDomainEventOptions\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_AGGREGATE_IDENTITY_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_AGGREGATE_IDENTITY_INVALID\",\n\t\t);\n\t}\n}\n\nfunction assertNonBlankEventField(\n\tvalue: unknown,\n\tfield: \"eventId\" | \"type\" | \"aggregateId\" | \"aggregateType\",\n\tcode:\n\t\t| \"EVENT_ID_INVALID\"\n\t\t| \"EVENT_TYPE_INVALID\"\n\t\t| \"EVENT_AGGREGATE_IDENTITY_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 * Copies the caller's metadata and checks the copy. Metadata is a plain\n * record or absent; a null from a JSON envelope would build and then fail\n * every metadata read far from the producer. A factory origin fills\n * `source` only after the check, and a call site that names its own source\n * keeps it: an explicit fact about one event outranks the default of the\n * factory that builds it.\n */\nfunction ownedEventMetadata(\n\tmetadata: EventMetadata | undefined,\n\toperation: string,\n\tfactorySource?: string,\n): EventMetadata | undefined {\n\tif (metadata === undefined) {\n\t\treturn factorySource === undefined ? undefined : { source: factorySource };\n\t}\n\tconst owned: unknown = cloneOwnedEventData(metadata, \"metadata\", operation);\n\tif (!isPlainRecordCopy(owned)) {\n\t\t// The copy is the kit's own, so its tag runs no caller code.\n\t\tconst received =\n\t\t\ttypeof owned === \"object\"\n\t\t\t\t? owned === null\n\t\t\t\t\t? \"null\"\n\t\t\t\t\t: Object.prototype.toString.call(owned)\n\t\t\t\t: `a ${typeof owned}`;\n\t\tthrow new TypeError(\n\t\t\t`${operation}: metadata must be an object or undefined, and a plain record; received ${received}`,\n\t\t);\n\t}\n\tconst record = owned as EventMetadata;\n\tif (factorySource === undefined || record.source !== undefined) {\n\t\treturn record;\n\t}\n\treturn { ...record, source: factorySource };\n}\n\n/**\n * True for a structured-clone copy of a plain record. A runtime such as\n * Vercel Edge returns the copy with the `Object.prototype` of another realm,\n * so the check compares the source text of the constructor, not the\n * prototype object.\n */\nfunction isPlainRecordCopy(copy: unknown): boolean {\n\tif (typeof copy !== \"object\" || copy === null) return false;\n\tconst prototype = Object.getPrototypeOf(copy);\n\treturn (\n\t\tprototype !== null &&\n\t\tisIntrinsicConstructorPrototype(prototype, \"Object\") &&\n\t\tObject.getPrototypeOf(prototype) === null\n\t);\n}\n\n/**\n * Deep-clones caller-supplied event data (payload, metadata) before the\n * event is frozen, so a constructor never freezes or aliases the caller's\n * own object graph. {@link copyFreezableState} checks the data and the\n * clone; its JSDoc states the rule and its limits.\n */\nfunction cloneOwnedEventData<T>(\n\tvalue: T,\n\tfield: \"payload\" | \"metadata\",\n\toperation: string,\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. The\n\t// check runs first, so this key throws its own error whatever else is\n\t// wrong with the data.\n\tif (value !== null && typeof value === \"object\") {\n\t\tassertNoOwnProtoKey(value, `Event ${field} of ${operation}`);\n\t}\n\t// The freeze rule keeps the guarantee \"kit-built implies deeply\n\t// frozen\".\n\treturn copyFreezableState(value, `${operation}: ${field}`);\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\tassertNoOwnProtoKey(sourceEvent.metadata, \"Event metadata\");\n\t}\n\tif (additionalMetadata !== undefined) {\n\t\tassertNoOwnProtoKey(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\tassertNoOwnProtoKey(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 * The value to reject with when an `AbortSignal` has fired.\n *\n * Returns the signal's `reason` (a `DOMException` `AbortError` for\n * `controller.abort()`, `TimeoutError` for `AbortSignal.timeout`), falling\n * back to a plain `Error` with `fallbackMessage` when `reason` is nullish.\n * A spec-compliant signal always populates `reason` when aborted, so the\n * fallback only fires for a non-spec polyfill; without it, a bare\n * `throw undefined` would surface, breaking `instanceof Error` handling.\n *\n * Centralizes the `signal.reason ?? new Error(...)` idiom used at every\n * abort site (event bus, `withCommit`, `UnitOfWork.run`, the retrying\n * scope) so a single fix covers all of them.\n */\nexport function abortReason(\n\tsignal: AbortSignal,\n\tfallbackMessage: string,\n): unknown {\n\treturn signal.reason ?? new Error(fallbackMessage);\n}\n\n/**\n * Waits for `promise`, but REJECTS with the signal's reason as soon as the\n * signal fires. The promise keeps running; only the wait ends. The abort\n * listener goes away when the promise settles.\n */\nexport function waitRejectingOnAbort<T>(\n\tpromise: Promise<T>,\n\tsignal: AbortSignal | undefined,\n\tabortMessage: string,\n): Promise<T> {\n\tif (signal === undefined) return promise;\n\treturn new Promise<T>((resolve, reject) => {\n\t\tif (signal.aborted) {\n\t\t\treject(abortReason(signal, abortMessage));\n\t\t\treturn;\n\t\t}\n\t\tconst onAbort = (): void => reject(abortReason(signal, abortMessage));\n\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\tpromise.then(\n\t\t\t(value) => {\n\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\tresolve(value);\n\t\t\t},\n\t\t\t(error: unknown) => {\n\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\treject(error);\n\t\t\t},\n\t\t);\n\t});\n}\n","/**\n * Shared construction-time guards for numeric options. `context` names\n * the throwing component so the error reads like the component's own\n * validation (\"OutboxDispatcher: pollIntervalMs must be...\").\n */\n\n/** Guard for numeric options that must be a non-negative finite number. */\nexport function assertNonNegativeFinite(\n\tcontext: string,\n\tfield: string,\n\tvalue: number,\n): void {\n\tif (!Number.isFinite(value) || value < 0) {\n\t\tthrow new Error(\n\t\t\t`${context}: ${field} must be a non-negative finite number, got ${value}`,\n\t\t);\n\t}\n}\n\n/**\n * The largest delay that `setTimeout` honors. A larger delay does not wait\n * longer: the runtime fires the timer after about 1 ms.\n */\nexport const MAX_TIMER_DELAY_MS = 2_147_483_647;\n\n/** Guard for time options that a timer waits for, in milliseconds. */\nexport function assertTimerDelay(\n\tcontext: string,\n\tfield: string,\n\tvalue: number,\n): void {\n\tif (!Number.isFinite(value) || value < 0 || value > MAX_TIMER_DELAY_MS) {\n\t\tthrow new RangeError(\n\t\t\t`${context}: ${field} must be a finite number of milliseconds from 0 ` +\n\t\t\t\t`to ${MAX_TIMER_DELAY_MS}, got ${value}`,\n\t\t);\n\t}\n}\n\n/** Guard for count options that must be a whole number of at least 1. */\nexport function assertPositiveInteger(\n\tcontext: string,\n\tfield: string,\n\tvalue: number,\n): void {\n\tif (!Number.isInteger(value) || value < 1) {\n\t\tthrow new Error(\n\t\t\t`${context}: ${field} must be an integer >= 1, got ${value}`,\n\t\t);\n\t}\n}\n\n/** Guard for retained-record capacities that must fit exact JS integers. */\nexport function assertPositiveSafeInteger(\n\tcontext: string,\n\tfield: string,\n\tvalue: number,\n): void {\n\tif (!Number.isSafeInteger(value) || value < 1) {\n\t\tthrow new RangeError(\n\t\t\t`${context}: ${field} must be a positive safe integer, got ${value}`,\n\t\t);\n\t}\n}\n\n/** Guard for stream positions that must fit exact JS integers. */\nexport function assertNonNegativeSafeInteger(\n\tcontext: string,\n\tfield: string,\n\tvalue: number,\n): void {\n\tif (!Number.isSafeInteger(value) || value < 0) {\n\t\tthrow new RangeError(\n\t\t\t`${context}: ${field} must be a non-negative safe integer, got ${value}`,\n\t\t);\n\t}\n}\n","import { assertNonNegativeFinite, assertTimerDelay } from \"../validate\";\nimport { abortReason } from \"./abort\";\n\n/** Cancellation and deadline controls for one bounded shell operation. */\nexport interface ExecutionContext {\n\t/** Cooperative cancellation for the in-flight operation. */\n\treadonly signal: AbortSignal;\n\t/** Absolute Unix epoch millisecond at which the shell stops waiting. */\n\treadonly deadlineAt: number;\n}\n\n/** Caller controls for one bounded shell operation. */\ntype ExecutionOptions =\n\t| {\n\t\t\t/** Optional owner/request cancellation signal. */\n\t\t\treadonly signal?: AbortSignal;\n\t\t\t/** Maximum time the shell waits for the operation. */\n\t\t\treadonly timeoutMs: number;\n\t\t\treadonly deadlineAt?: never;\n\t }\n\t| {\n\t\t\t/** Optional owner/request cancellation signal. */\n\t\t\treadonly signal?: AbortSignal;\n\t\t\treadonly timeoutMs?: never;\n\t\t\t/** Shared absolute deadline for a multi-operation budget. */\n\t\t\treadonly deadlineAt: number;\n\t };\n\n/** Default bound for delivery and post-commit operations. */\nexport const DEFAULT_EXECUTION_TIMEOUT_MS = 30_000;\n\n/**\n * Owner signal of each child signal that {@link runBoundedExecution} created.\n *\n * One bounded operation often wraps another, and every hop derives a fresh\n * signal. A consumer that follows a call chain by signal identity alone loses\n * the link at the first hop. Key and value are both weak: a long chain of\n * nested operations must not hold its whole ancestry alive.\n */\nconst executionOwners = new WeakMap<AbortSignal, WeakRef<AbortSignal>>();\n\n/**\n * The signal that a bounded execution derived this one from, or `undefined`\n * when the signal did not come from {@link runBoundedExecution} or had no\n * owner. Walk it to follow a chain across nested bounded executions.\n */\nexport function ownerSignalOf(signal: AbortSignal): AbortSignal | undefined {\n\treturn executionOwners.get(signal)?.deref();\n}\n\n/**\n * Runs one operation with a child signal that combines owner cancellation and a\n * shell-owned timeout. The returned promise settles on abort even when an\n * adapter ignores the signal; the adapter promise remains observed so a later\n * rejection cannot become an unhandled rejection.\n *\n * This bounds how long the shell waits; JavaScript cannot forcibly terminate\n * an arbitrary promise. An I/O adapter that must prevent zombie work and\n * overlapping retries has to pass `context.signal` to its native operation or\n * enforce a native timeout no later than `context.deadlineAt`.\n */\nexport function runBoundedExecution<T>(\n\tlabel: string,\n\toptions: ExecutionOptions,\n\toperation: (context: ExecutionContext) => Promise<T> | T,\n): Promise<T> {\n\tif (options.deadlineAt === undefined) {\n\t\tassertTimerDelay(label, \"timeoutMs\", options.timeoutMs);\n\t} else {\n\t\tassertNonNegativeFinite(label, \"deadlineAt\", options.deadlineAt);\n\t}\n\tconst startedAt = Date.now();\n\tconst deadlineAt = options.deadlineAt ?? startedAt + options.timeoutMs;\n\tconst timeoutMs = Math.max(0, deadlineAt - startedAt);\n\tif (options.deadlineAt !== undefined) {\n\t\tassertTimerDelay(label, \"the time until deadlineAt\", timeoutMs);\n\t}\n\tconst timeoutError = (): DOMException =>\n\t\tnew DOMException(`${label} timed out after ${timeoutMs}ms`, \"TimeoutError\");\n\tconst controller = new AbortController();\n\tconst context = Object.freeze({\n\t\tsignal: controller.signal,\n\t\tdeadlineAt,\n\t});\n\tconst ownerSignal = options.signal;\n\tif (ownerSignal !== undefined) {\n\t\texecutionOwners.set(controller.signal, new WeakRef(ownerSignal));\n\t}\n\tconst abortFromOwner = (): void => {\n\t\tcontroller.abort(\n\t\t\townerSignal === undefined\n\t\t\t\t? new Error(`${label} aborted`)\n\t\t\t\t: abortReason(ownerSignal, `${label} aborted`),\n\t\t);\n\t};\n\n\tif (ownerSignal?.aborted) abortFromOwner();\n\telse ownerSignal?.addEventListener(\"abort\", abortFromOwner, { once: true });\n\tif (\n\t\t!controller.signal.aborted &&\n\t\toptions.deadlineAt !== undefined &&\n\t\tdeadlineAt <= startedAt\n\t) {\n\t\tcontroller.abort(timeoutError());\n\t}\n\n\tconst timer = setTimeout(() => {\n\t\tcontroller.abort(timeoutError());\n\t}, timeoutMs);\n\n\treturn new Promise<T>((resolve, reject) => {\n\t\tlet settled = false;\n\t\tconst finish = (complete: () => void): void => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tclearTimeout(timer);\n\t\t\townerSignal?.removeEventListener(\"abort\", abortFromOwner);\n\t\t\tcontroller.signal.removeEventListener(\"abort\", onAbort);\n\t\t\tcomplete();\n\t\t};\n\t\tconst onAbort = (): void => {\n\t\t\t// Defer one microtask so a promise that settled immediately before the\n\t\t\t// abort keeps its acknowledgement semantics. If abort happened first,\n\t\t\t// this microtask was queued first and still wins deterministically.\n\t\t\tqueueMicrotask(() =>\n\t\t\t\tfinish(() =>\n\t\t\t\t\treject(abortReason(controller.signal, `${label} aborted`)),\n\t\t\t\t),\n\t\t\t);\n\t\t};\n\n\t\tif (controller.signal.aborted) {\n\t\t\tonAbort();\n\t\t\treturn;\n\t\t}\n\t\tcontroller.signal.addEventListener(\"abort\", onAbort, { once: true });\n\t\tlet outcome: Promise<T>;\n\t\ttry {\n\t\t\toutcome = Promise.resolve(operation(context));\n\t\t} catch (error) {\n\t\t\tfinish(() => reject(error));\n\t\t\treturn;\n\t\t}\n\t\toutcome.then(\n\t\t\t(value) => finish(() => resolve(value)),\n\t\t\t(error) => finish(() => reject(error)),\n\t\t);\n\t});\n}\n","import type { AggregateIdentity } from \"../../domain/aggregate/aggregate-identity\";\nimport 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\t/**\n\t * Ends the event sources of removed aggregates. Called from inside\n\t * `withCommit`'s transactional callback, after `add()`, atomically with\n\t * the removal.\n\t *\n\t * For every source that has a head, the adapter marks the head as ended\n\t * in the SAME transaction. The mark must outlive any retention of heads:\n\t * a pruned ended head opens the source again. A source without a head\n\t * has no events, so it has no continuity to protect: it stays open, and\n\t * its first event starts a new head. After the mark, `add()` must reject\n\t * a new event of that source: its aggregate was created again under a\n\t * removed identity, which the kit does not support. An exact retry of a\n\t * stored event stays idempotent, and ending a source twice is not an\n\t * error.\n\t */\n\tendEventSources: (sources: ReadonlyArray<AggregateIdentity>) => 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","import type { AggregateIdentity } from \"../../domain/aggregate/aggregate-identity\";\nimport { InvalidEventStreamPageError } from \"../../errors/kit-errors\";\n\nexport function assertValidHead(\n\tstream: AggregateIdentity,\n\tlastVersion: unknown,\n\tfromVersion: number,\n\ttargetVersion?: number,\n): asserts lastVersion is number {\n\tif (Number.isSafeInteger(lastVersion) && (lastVersion as number) >= 1) return;\n\tthrow new InvalidEventStreamPageError({\n\t\tidentity: stream,\n\t\treason: \"invalid_head\",\n\t\tfromVersion,\n\t\ttargetVersion,\n\t\tlastVersion,\n\t});\n}\n\nexport function assertHeadNotBehindFirstPage(\n\tstream: AggregateIdentity,\n\tlastVersion: number,\n\tfirstPageLastVersion: number,\n\tfromVersion: number,\n\ttargetVersion: number,\n): void {\n\tif (lastVersion >= firstPageLastVersion) return;\n\tthrow new InvalidEventStreamPageError({\n\t\tidentity: stream,\n\t\treason: \"head_regressed\",\n\t\tfromVersion,\n\t\ttargetVersion,\n\t\tlastVersion,\n\t\tfirstPageLastVersion,\n\t});\n}\n\nexport function assertPageNotEmpty(\n\tstream: AggregateIdentity,\n\teventCount: number,\n\tfromVersion: number,\n\ttargetVersion: number,\n): void {\n\tif (eventCount > 0) return;\n\tthrow new InvalidEventStreamPageError({\n\t\tidentity: stream,\n\t\treason: \"empty_page\",\n\t\tfromVersion,\n\t\ttargetVersion,\n\t});\n}\n\nexport function assertPageWithinWindow(\n\tstream: AggregateIdentity,\n\teventCount: number,\n\tfromVersion: number,\n\ttargetVersion: number,\n): void {\n\tif (eventCount <= targetVersion - fromVersion) return;\n\tthrow new InvalidEventStreamPageError({\n\t\tidentity: stream,\n\t\treason: \"page_past_target\",\n\t\tfromVersion,\n\t\ttargetVersion,\n\t\teventCount,\n\t});\n}\n\nexport function assertPageWithinLimit(\n\tstream: AggregateIdentity,\n\teventCount: number,\n\tlimit: number,\n\tfromVersion: number,\n\ttargetVersion: number,\n): void {\n\tif (eventCount <= limit) return;\n\tthrow new InvalidEventStreamPageError({\n\t\tidentity: stream,\n\t\treason: \"page_over_limit\",\n\t\tfromVersion,\n\t\ttargetVersion,\n\t\teventCount,\n\t\tlimit,\n\t});\n}\n","import type { AggregateIdentity } from \"../../domain/aggregate/aggregate-identity\";\nimport type { AnyDomainEvent } from \"../../domain/event/domain-event\";\nimport { InvalidEventStreamPageError } from \"../../errors/kit-errors\";\nimport { abortReason } from \"../../internal/async/abort\";\nimport {\n\tassertNonNegativeSafeInteger,\n\tassertPositiveSafeInteger,\n} from \"../../internal/validate\";\nimport type { EventStreamReader, ReadStreamOptions } from \"./event-store\";\nimport {\n\tassertHeadNotBehindFirstPage,\n\tassertPageNotEmpty,\n\tassertPageWithinLimit,\n\tassertPageWithinWindow,\n\tassertValidHead,\n} from \"./event-stream-page-guards\";\nimport type { ReplayableStreamPages } from \"./reconstitute-from-stream-pages\";\n\n/** Options for {@link readStreamPages}. */\nexport interface ReadStreamPagesOptions\n\textends Pick<ReadStreamOptions, \"limit\" | \"fromVersion\" | \"signal\"> {\n\t/**\n\t * The version a point-in-time read asks for (inclusive, 1-based event\n\t * count). Without it, the target version is the head that the first page\n\t * reports. A value beyond the head does not clamp: see\n\t * {@link pinTargetVersion}. Must be a positive safe integer when present.\n\t * Version 0 is the state before the first event, and no replay can end\n\t * there.\n\t */\n\treadonly toVersion?: number;\n}\n\n/**\n * A stream read with the target version pinned on its first page.\n *\n * The first page decides the state of the stream once, in three branches.\n * An absent stream is `exists: false`. An existing stream whose window lies\n * outside it is `reachable: false` and carries the actual head. The\n * remaining branch carries the target version and the pages after the\n * cursor. The other two branches both carry `reachable: false`, so one\n * guard narrows to the branch that\n * {@link reconstituteAggregateFromStreamPages} accepts. The caller decides\n * what the other two branches mean before the replay.\n */\nexport type StreamPages<Evt extends AnyDomainEvent> =\n\t| AbsentStreamPages\n\t| UnreachableStreamPages\n\t| ReachableStreamPages<Evt>;\n\n/** The branch of {@link StreamPages} for a stream the store does not hold. */\nexport interface AbsentStreamPages {\n\treadonly exists: false;\n\treadonly reachable: false;\n}\n\n/**\n * The branch of {@link StreamPages} for a window that lies outside an\n * existing stream: the cursor lies beyond the target version, or the\n * target version lies beyond the head ({@link pinTargetVersion}).\n *\n * The caller tells the causes apart from its own inputs. A snapshot\n * version above `lastVersion` means that the snapshot outlived its stream:\n * discard it and replay from zero. A `toVersion` above `lastVersion` means\n * that the stream has not reached that version: answer not found and keep\n * the snapshot. A snapshot version above `toVersion` means that the\n * snapshot is too new for the request: keep it and replay from zero up to\n * `toVersion`.\n */\nexport interface UnreachableStreamPages {\n\treadonly exists: true;\n\treadonly reachable: false;\n\n\t/** The cursor the read started at: `fromVersion`, or `0`. */\n\treadonly fromVersion: number;\n\n\t/** The actual stream head on the first page. */\n\treadonly lastVersion: number;\n}\n\n/** The branch of {@link StreamPages} that the replay accepts. */\nexport interface ReachableStreamPages<Evt extends AnyDomainEvent>\n\textends ReplayableStreamPages<Evt> {\n\treadonly exists: true;\n\treadonly reachable: true;\n}\n\n/** Options for {@link pinTargetVersion}. */\nexport interface PinTargetVersionOptions {\n\t/** The cursor of the read: the replay starts after this version. */\n\treadonly fromVersion: number;\n\n\t/** The version a point-in-time read asks for. Defaults to `lastVersion`. */\n\treadonly toVersion?: number;\n\n\t/** The head of the existing stream: its event count. */\n\treadonly lastVersion: number;\n}\n\n/** The verdict of {@link pinTargetVersion}. */\nexport type PinnedTargetVersion =\n\t| { readonly reachable: true; readonly targetVersion: number }\n\t| { readonly reachable: false };\n\n/**\n * Pins the target version of a replay window on an existing stream, or\n * reports the window as unreachable.\n *\n * The target version is `toVersion` when given, else `lastVersion`. The\n * window is unreachable when `fromVersion` lies beyond the target version,\n * or the target version lies beyond `lastVersion`. The call never clamps\n * such a window to the head, so a request for version 10 of a stream that\n * ends at 7 never loads the latest state by accident.\n *\n * This is the decision `readStreamPages` makes on its first page. An\n * adapter that pages on its own makes it with this call, then hands its\n * pages to `reconstituteAggregateFromStreamPages`. Values that are not safe\n * integers, a negative `fromVersion`, and a `toVersion` or `lastVersion`\n * below 1 reject with `RangeError`: an existing stream holds at least one\n * event, and no replay can end at version 0.\n */\nexport function pinTargetVersion(\n\toptions: PinTargetVersionOptions,\n): PinnedTargetVersion {\n\tassertNonNegativeSafeInteger(\n\t\t\"pinTargetVersion\",\n\t\t\"fromVersion\",\n\t\toptions.fromVersion,\n\t);\n\tif (options.toVersion !== undefined) {\n\t\tassertPositiveSafeInteger(\n\t\t\t\"pinTargetVersion\",\n\t\t\t\"toVersion\",\n\t\t\toptions.toVersion,\n\t\t);\n\t}\n\tassertPositiveSafeInteger(\n\t\t\"pinTargetVersion\",\n\t\t\"lastVersion\",\n\t\toptions.lastVersion,\n\t);\n\treturn decideTargetVersion(options);\n}\n\nfunction decideTargetVersion(\n\twindow: PinTargetVersionOptions,\n): PinnedTargetVersion {\n\tconst targetVersion = window.toVersion ?? window.lastVersion;\n\tif (\n\t\twindow.fromVersion > targetVersion ||\n\t\ttargetVersion > window.lastVersion\n\t) {\n\t\treturn { reachable: false };\n\t}\n\treturn { reachable: true, targetVersion };\n}\n\n/**\n * Reads one stream in bounded pages up to a pinned target version.\n *\n * The call reads the first page. That page decides existence and reports\n * the head. The call then makes the window decision of\n * {@link pinTargetVersion}: the target version is `toVersion` when given,\n * else the head, and a window outside the stream is unreachable.\n *\n * The first iteration of `pages` yields the first page that the call read\n * and then reads the continuation pages, one page at a time. Every later\n * iteration reads all pages from the store again, so no two iterations\n * share an event object. Each of these reads passes the target version as\n * `toVersion` and starts after the events that the earlier pages\n * returned. Streams are append-only, so an iteration yields one stable\n * prefix even when another writer appends during the replay.\n *\n * The call checks every page against the `readStream` contract and throws\n * {@link InvalidEventStreamPageError} for a page that breaks it: a head\n * that is not a safe integer of at least 1, an empty page while events\n * remain in the window, a page with more events than its window has left\n * or than `limit`, and a continuation page that reports the stream absent\n * or a head below the head of the first page.\n *\n * Invalid options reject with `RangeError` before any page is read:\n * `limit` and `toVersion` must be positive safe integers, `fromVersion` a\n * non-negative one. The call passes `signal` to every page read, and it\n * checks the signal before each page read as well. An aborted signal\n * rejects with its `reason`.\n */\nexport async function readStreamPages<Evt extends AnyDomainEvent>(\n\treader: EventStreamReader<Evt>,\n\tstream: AggregateIdentity,\n\toptions: ReadStreamPagesOptions,\n): Promise<StreamPages<Evt>> {\n\tassertPositiveSafeInteger(\"readStreamPages\", \"limit\", options.limit);\n\tconst fromVersion = options.fromVersion ?? 0;\n\tassertNonNegativeSafeInteger(\"readStreamPages\", \"fromVersion\", fromVersion);\n\tif (options.toVersion !== undefined) {\n\t\tassertPositiveSafeInteger(\n\t\t\t\"readStreamPages\",\n\t\t\t\"toVersion\",\n\t\t\toptions.toVersion,\n\t\t);\n\t}\n\tthrowIfAborted(options.signal);\n\tconst identity: AggregateIdentity = {\n\t\taggregateType: stream.aggregateType,\n\t\taggregateId: stream.aggregateId,\n\t};\n\tconst first = await reader.readStream(identity, {\n\t\tfromVersion,\n\t\tlimit: options.limit,\n\t\t...(options.toVersion === undefined\n\t\t\t? {}\n\t\t\t: { toVersion: options.toVersion }),\n\t\t...(options.signal === undefined ? {} : { signal: options.signal }),\n\t});\n\tif (!first.exists) return { exists: false, reachable: false };\n\tassertValidHead(identity, first.lastVersion, fromVersion);\n\tconst pinned = decideTargetVersion({\n\t\tfromVersion,\n\t\ttoVersion: options.toVersion,\n\t\tlastVersion: first.lastVersion,\n\t});\n\tif (!pinned.reachable) {\n\t\treturn {\n\t\t\texists: true,\n\t\t\treachable: false,\n\t\t\tfromVersion,\n\t\t\tlastVersion: first.lastVersion,\n\t\t};\n\t}\n\tif (fromVersion < pinned.targetVersion) {\n\t\tassertPageNotEmpty(\n\t\t\tidentity,\n\t\t\tfirst.events.length,\n\t\t\tfromVersion,\n\t\t\tpinned.targetVersion,\n\t\t);\n\t}\n\tassertPageWithinWindow(\n\t\tidentity,\n\t\tfirst.events.length,\n\t\tfromVersion,\n\t\tpinned.targetVersion,\n\t);\n\tassertPageWithinLimit(\n\t\tidentity,\n\t\tfirst.events.length,\n\t\toptions.limit,\n\t\tfromVersion,\n\t\tpinned.targetVersion,\n\t);\n\tconst window: PinnedWindow = {\n\t\tstream: identity,\n\t\tfromVersion,\n\t\tfirstPageLastVersion: first.lastVersion,\n\t\ttargetVersion: pinned.targetVersion,\n\t\tlimit: options.limit,\n\t\tsignal: options.signal,\n\t};\n\tlet unreadFirstPage: ReadonlyArray<Evt> | undefined = first.events;\n\treturn {\n\t\texists: true,\n\t\treachable: true,\n\t\tstream: identity,\n\t\tfromVersion,\n\t\ttargetVersion: pinned.targetVersion,\n\t\tpages: {\n\t\t\t[Symbol.asyncIterator]: () => {\n\t\t\t\tconst firstPage = unreadFirstPage;\n\t\t\t\tunreadFirstPage = undefined;\n\t\t\t\treturn readPinnedPages(reader, window, firstPage);\n\t\t\t},\n\t\t},\n\t};\n}\n\ninterface PinnedWindow {\n\treadonly stream: AggregateIdentity;\n\treadonly fromVersion: number;\n\treadonly firstPageLastVersion: number;\n\treadonly targetVersion: number;\n\treadonly limit: number;\n\treadonly signal: AbortSignal | undefined;\n}\n\nasync function* readPinnedPages<Evt extends AnyDomainEvent>(\n\treader: EventStreamReader<Evt>,\n\twindow: PinnedWindow,\n\tfirstPage: ReadonlyArray<Evt> | undefined,\n): AsyncGenerator<ReadonlyArray<Evt>, void, undefined> {\n\tlet cursor = window.fromVersion;\n\tif (firstPage !== undefined) {\n\t\tif (firstPage.length > 0) yield firstPage;\n\t\tcursor += firstPage.length;\n\t}\n\twhile (cursor < window.targetVersion) {\n\t\tthrowIfAborted(window.signal);\n\t\tconst page = await reader.readStream(window.stream, {\n\t\t\tfromVersion: cursor,\n\t\t\ttoVersion: window.targetVersion,\n\t\t\tlimit: window.limit,\n\t\t\t...(window.signal === undefined ? {} : { signal: window.signal }),\n\t\t});\n\t\tif (!page.exists) {\n\t\t\tthrow new InvalidEventStreamPageError({\n\t\t\t\tidentity: window.stream,\n\t\t\t\treason: \"stream_vanished\",\n\t\t\t\tfromVersion: cursor,\n\t\t\t\ttargetVersion: window.targetVersion,\n\t\t\t});\n\t\t}\n\t\tassertValidHead(\n\t\t\twindow.stream,\n\t\t\tpage.lastVersion,\n\t\t\tcursor,\n\t\t\twindow.targetVersion,\n\t\t);\n\t\tassertHeadNotBehindFirstPage(\n\t\t\twindow.stream,\n\t\t\tpage.lastVersion,\n\t\t\twindow.firstPageLastVersion,\n\t\t\tcursor,\n\t\t\twindow.targetVersion,\n\t\t);\n\t\tassertPageNotEmpty(\n\t\t\twindow.stream,\n\t\t\tpage.events.length,\n\t\t\tcursor,\n\t\t\twindow.targetVersion,\n\t\t);\n\t\tassertPageWithinWindow(\n\t\t\twindow.stream,\n\t\t\tpage.events.length,\n\t\t\tcursor,\n\t\t\twindow.targetVersion,\n\t\t);\n\t\tassertPageWithinLimit(\n\t\t\twindow.stream,\n\t\t\tpage.events.length,\n\t\t\twindow.limit,\n\t\t\tcursor,\n\t\t\twindow.targetVersion,\n\t\t);\n\t\tyield page.events;\n\t\tcursor += page.events.length;\n\t}\n}\n\nfunction throwIfAborted(signal: AbortSignal | undefined): void {\n\tif (signal?.aborted) throw abortReason(signal, \"readStreamPages aborted\");\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"read-stream-pages.js","names":["#position"],"sources":["../../src/internal/structural/copy-plain-state.ts","../../src/internal/uuid-v7.ts","../../src/domain/event/clock.ts","../../src/domain/event/domain-event-errors.ts","../../src/domain/event/domain-event.ts","../../src/internal/async/abort.ts","../../src/internal/validate.ts","../../src/internal/async/execution.ts","../../src/messaging/outbox/ports.ts","../../src/persistence/event-store/event-stream-page-guards.ts","../../src/persistence/event-store/read-stream-pages.ts"],"sourcesContent":["import {\n\ttype BuiltInTag,\n\tbuiltInTagWithoutInvokingAccessors,\n\tbuiltInTypeName,\n\thasIntrinsicPrototypeChain,\n\tisIntrinsicConstructorPrototype,\n} from \"./is-built-in\";\nimport { isMutatorShadow } from \"./shadowed-mutators\";\n\n/**\n * Returns a copy of `state` that shares no object with the original.\n * Throws a `TypeError` that names the path when the graph carries a value\n * a structured clone would lose or silently degrade. A class instance, a\n * subclass of a built-in included, loses the methods on its prototype. A\n * symbol-keyed, non-enumerable, or accessor property and an expando on a\n * built-in are dropped. A function or a symbol value throws a raw\n * `DataCloneError`. An Error, a Promise, a WeakMap, or a WeakSet cannot be\n * copied at all. A SharedArrayBuffer and a view over one keep sharing\n * their memory. A Proxy fails in the walk or in the clone; a failure in\n * the clone is rethrown as a `TypeError` with the cause. An error that a\n * Proxy trap throws in the walk passes unchanged, so a coded error of the\n * caller keeps its code.\n *\n * The walk reads the graph through property descriptors and walks a Map\n * or a Set with the built-in iteration, so no accessor and no own iterator\n * of the state runs. A Proxy runs its traps during the walk. A trap can\n * change the graph, and an accessor that a trap adds runs during the\n * clone. A second walk checks the clone, so a value that a trap swapped in\n * and the content of a built-in whose prototype was replaced are rejected\n * too. A trap that changes the graph after the first walk can still hide a\n * value that the copy drops: the walks catch accidents, not a hostile\n * Proxy. The second walk also follows the steps of the first walk: the kind\n * of each object and the key of each data property, in walk order. A copy\n * that differs throws, because a built-in whose prototype was replaced is\n * a built-in again in the copy and loses its own properties. `subject`\n * names the state in the messages.\n *\n * Plain objects (from any realm), arrays, Dates, Maps, Sets, bigints, and\n * typed arrays pass. A RegExp passes: pattern and flags survive the clone,\n * and `lastIndex` restores as 0. The scan state of a global or sticky\n * pattern is not domain data. On a built-in, the mutator shadows of a deep\n * freeze, the `lastIndex` of a RegExp, and the `length` of a boxed String\n * pass: they are machinery, not data. Every other non-enumerable property\n * throws. A non-enumerable symbol key passes anywhere: it is metadata by\n * convention.\n *\n * The concrete entity uses it for the plain state of a plain-data\n * state. The snapshot model uses it for the captured DTO and the restored\n * state. A state that carries a class-based child is mapped to plain data\n * first, in the entity or in the model.\n */\nexport function copyPlainState<T>(\n\tstate: T,\n\tsubject = \"copyPlainState: state\",\n): T {\n\treturn copyState(state, subject, \"clone\");\n}\n\n/**\n * {@link copyPlainState} that also rejects what `deepFreeze` cannot make\n * immutable: binary data (a typed array, a DataView, an ArrayBuffer, or a\n * SharedArrayBuffer) and a RegExp. The walk rejects such a value at its\n * tag, before it reads the indices of a typed array. Kit modules only.\n */\nexport function copyFreezableState<T>(state: T, subject: string): T {\n\treturn copyState(state, subject, \"freeze\");\n}\n\nfunction copyState<T>(state: T, subject: string, rule: Walk[\"rule\"]): T {\n\tconst recording = new StepRecording();\n\tassertCopyable(state, \"\", newWalk(subject, rule, recording));\n\tlet copy: T;\n\ttry {\n\t\tcopy = structuredClone(state);\n\t} catch (cause) {\n\t\tthrow new TypeError(\n\t\t\t`${subject} holds a Proxy or a host object that cannot be cloned, or a view over a detached or shrunk buffer; the cause names the value; map it to plain data`,\n\t\t\t{ cause },\n\t\t);\n\t}\n\t// The first walk trusts the prototype of an object, and a Proxy trap can\n\t// change the graph after it. The copy has genuine prototypes and no\n\t// Proxy, so this walk checks exactly what the caller gets. A built-in\n\t// whose prototype was replaced passes the first walk as a record, and\n\t// the copy drops its own properties. A count of the properties can\n\t// balance out with the content of the built-in, so this walk compares\n\t// each of its steps with the step of the first walk.\n\tconst comparison = new StepComparison(recording, subject);\n\tassertCopyable(copy, \"\", newWalk(subject, rule, comparison));\n\tcomparison.assertComplete();\n\treturn copy;\n}\n\nconst INDEX_KEY = /^(0|[1-9]\\d*)$/;\nconst BINARY_DATA_TAGS: ReadonlySet<BuiltInTag> = new Set<BuiltInTag>([\n\t\"[object TypedArray]\",\n\t\"[object DataView]\",\n\t\"[object ArrayBuffer]\",\n\t\"[object SharedArrayBuffer]\",\n]);\nconst REGEXP_TAG: BuiltInTag = \"[object RegExp]\";\nconst STRING_TAG: BuiltInTag = \"[object String]\";\nconst mapEntries = Map.prototype.entries;\nconst setValues = Set.prototype.values;\n\n/**\n * A step of a walk: the kind of an object that the walk enters, or the key\n * of a data property of a record or an array that it checks. A kind is a\n * symbol, so no key can be equal to it.\n */\ntype Step = string | symbol;\n\nconst RECORD_STEP = Symbol(\"record\");\nconst ARRAY_STEP = Symbol(\"array\");\nconst builtInSteps = new Map<BuiltInTag, symbol>();\n\nfunction builtInStep(tag: BuiltInTag): symbol {\n\tlet kind = builtInSteps.get(tag);\n\tif (kind === undefined) {\n\t\tkind = Symbol(tag);\n\t\tbuiltInSteps.set(tag, kind);\n\t}\n\treturn kind;\n}\n\n/**\n * The steps of the walk over the original, in walk order.\n */\nclass StepRecording {\n\treadonly steps: Step[] = [];\n\n\ttake(next: Step): void {\n\t\tthis.steps.push(next);\n\t}\n}\n\n/**\n * The walk over the copy compares each of its steps with the step of the\n * walk over the original at the same position. Structured clone keeps the\n * order of the keys, of Map entries, and of Set members, and it keeps\n * shared references, so the walk over an unchanged copy takes the same\n * steps. A step that differs, or a step that is missing, means that the\n * copy changed.\n */\nclass StepComparison {\n\t#position = 0;\n\n\tconstructor(\n\t\tprivate readonly recording: StepRecording,\n\t\tprivate readonly subject: string,\n\t) {}\n\n\ttake(next: Step, path: string): void {\n\t\tconst expected = this.recording.steps[this.#position];\n\t\tif (expected !== next) {\n\t\t\tthrowChangedInCopy(this.subject, path, expected, next);\n\t\t}\n\t\tthis.#position += 1;\n\t}\n\n\tassertComplete(): void {\n\t\tif (this.#position < this.recording.steps.length) {\n\t\t\tthrowChangedInCopy(\n\t\t\t\tthis.subject,\n\t\t\t\t\"\",\n\t\t\t\tthis.recording.steps[this.#position],\n\t\t\t\tundefined,\n\t\t\t);\n\t\t}\n\t}\n}\n\n/**\n * The objects that the walk has seen, the subject that its messages name,\n * its rule, and its steps. `\"clone\"` accepts what a structured clone\n * keeps. `\"freeze\"` also rejects what `deepFreeze` cannot make immutable.\n */\ninterface Walk {\n\treadonly seen: WeakSet<object>;\n\treadonly subject: string;\n\treadonly rule: \"clone\" | \"freeze\";\n\treadonly trace: StepRecording | StepComparison;\n}\n\nfunction newWalk(\n\tsubject: string,\n\trule: Walk[\"rule\"],\n\ttrace: Walk[\"trace\"],\n): Walk {\n\treturn { seen: new WeakSet(), subject, rule, trace };\n}\n\nfunction step(walk: Walk, next: Step, path: string): void {\n\twalk.trace.take(next, path);\n}\n\nfunction throwChangedInCopy(\n\tsubject: string,\n\tpath: string,\n\texpected: Step | undefined,\n\tfound: Step | undefined,\n): never {\n\tthrow new TypeError(\n\t\t`${subject}${path} changed in the copy: the state has ${describeStep(expected)} there, and the copy has ${describeStep(found)}; a built-in whose prototype was replaced is a built-in again in the copy and loses its own properties, and a Proxy trap can change the graph; map it to plain data`,\n\t);\n}\n\nfunction describeStep(step: Step | undefined): string {\n\tif (step === undefined) return \"nothing\";\n\tif (typeof step === \"string\") return `the key \"${step}\"`;\n\tif (step === RECORD_STEP) return \"a record\";\n\tif (step === ARRAY_STEP) return \"an array\";\n\tconst name = builtInTypeName(step.description as BuiltInTag);\n\treturn /^[AEIOU]/.test(name) ? `an ${name}` : `a ${name}`;\n}\n\nfunction assertCopyable(value: unknown, path: string, walk: Walk): void {\n\tif (typeof value === \"function\") {\n\t\tthrow new TypeError(\n\t\t\t`${walk.subject}${path} is a function; map it to plain data`,\n\t\t);\n\t}\n\t// Guided rejection instead of the raw DataCloneError DOMException that\n\t// structuredClone throws for symbols, which no recovery channel catches.\n\tif (typeof value === \"symbol\") {\n\t\tthrow new TypeError(\n\t\t\t`${walk.subject}${path} is a symbol; map it to plain data`,\n\t\t);\n\t}\n\tif (value === null || typeof value !== \"object\") return;\n\tconst object = value as object;\n\tif (walk.seen.has(object)) return;\n\twalk.seen.add(object);\n\n\tif (Array.isArray(object)) {\n\t\tif (!hasIntrinsicPrototypeChain(object, \"Array\")) {\n\t\t\tthrowClassInstance(object, path, walk.subject);\n\t\t}\n\t\tstep(walk, ARRAY_STEP, path);\n\t\tassertOwnPropertiesCopyable(object, path, walk, \"array\");\n\t\treturn;\n\t}\n\n\tconst tag = builtInTagWithoutInvokingAccessors(object);\n\tif (tag !== undefined) {\n\t\t// The tag comes from the internal slot, so a subclass gets the same\n\t\t// message as its built-in.\n\t\tif (walk.rule === \"freeze\") assertFreezable(tag, path, walk.subject);\n\t\tif (!hasIntrinsicPrototypeChain(object)) {\n\t\t\tthrowClassInstance(object, path, walk.subject);\n\t\t}\n\t\tstep(walk, builtInStep(tag), path);\n\t\tif (tag === \"[object Map]\") {\n\t\t\tlet index = 0;\n\t\t\tfor (const [key, entry] of mapEntries.call(\n\t\t\t\tobject as Map<unknown, unknown>,\n\t\t\t)) {\n\t\t\t\tassertCopyable(key, `${path}<map key #${index}>`, walk);\n\t\t\t\tassertCopyable(entry, `${path}<map value #${index}>`, walk);\n\t\t\t\tindex++;\n\t\t\t}\n\t\t} else if (tag === \"[object Set]\") {\n\t\t\tlet index = 0;\n\t\t\tfor (const member of setValues.call(object as Set<unknown>)) {\n\t\t\t\tassertCopyable(member, `${path}<set member #${index}>`, walk);\n\t\t\t\tindex++;\n\t\t\t}\n\t\t} else if (\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`${walk.subject}${path} is a ${builtInTypeName(tag)} and cannot be copied`,\n\t\t\t);\n\t\t} else if (tag === \"[object Error]\") {\n\t\t\tthrow new TypeError(\n\t\t\t\t`${walk.subject}${path} is an Error; map it to plain data`,\n\t\t\t);\n\t\t} else if (sharesMemory(object, tag)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`${walk.subject}${path} is backed by a SharedArrayBuffer and the copy would share its memory; map it to plain data`,\n\t\t\t);\n\t\t}\n\t\tassertOwnPropertiesCopyable(object, path, walk, tag);\n\t\treturn;\n\t}\n\n\tconst prototype = Object.getPrototypeOf(object);\n\tconst isPlainRecord =\n\t\tprototype === null ||\n\t\t(isIntrinsicConstructorPrototype(prototype, \"Object\") &&\n\t\t\tObject.getPrototypeOf(prototype) === null);\n\tif (!isPlainRecord) {\n\t\tthrowClassInstance(object, path, walk.subject);\n\t}\n\tstep(walk, RECORD_STEP, path);\n\tassertOwnPropertiesCopyable(object, path, walk, \"record\");\n}\n\n/**\n * Audits the own properties the clone would copy or drop. The clone keeps\n * the enumerable own keys of a record and of an array, expandos included,\n * and drops every own key of another built-in. `length` on an array is\n * its own machinery, not data, and so are the keys that\n * {@link isBuiltInMachinery} names. The index keys of a built-in below its\n * content length are its content and pass as such. Another index key of a\n * built-in is an expando. `owner` is the kind of `object`: an array, a\n * record, or the tag of a built-in.\n */\nfunction assertOwnPropertiesCopyable(\n\tobject: object,\n\tpath: string,\n\twalk: Walk,\n\towner: \"array\" | \"record\" | BuiltInTag,\n): void {\n\tconst tag = owner === \"array\" || owner === \"record\" ? undefined : owner;\n\tconst contentLength = tag === undefined ? 0 : contentLengthOf(object, tag);\n\tfor (const key of Reflect.ownKeys(object)) {\n\t\tconst descriptor = Object.getOwnPropertyDescriptor(object, key);\n\t\tif (descriptor === undefined) continue;\n\t\tif (typeof key === \"symbol\") {\n\t\t\tif (!descriptor.enumerable) continue;\n\t\t\tthrow new TypeError(\n\t\t\t\t`${walk.subject}${path} has a symbol-keyed property; map it to plain data`,\n\t\t\t);\n\t\t}\n\t\tif (owner === \"array\" && key === \"length\") continue;\n\t\tconst isIndex = INDEX_KEY.test(key);\n\t\tconst memberPath = isIndex ? `${path}[${key}]` : `${path}.${key}`;\n\t\tif (!descriptor.enumerable) {\n\t\t\tif (tag !== undefined && isBuiltInMachinery(tag, key, descriptor)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthrow new TypeError(\n\t\t\t\t`${walk.subject}${memberPath} is not enumerable and the clone would drop it; map it to plain data`,\n\t\t\t);\n\t\t}\n\t\tif (tag !== undefined && isIndex && Number(key) < contentLength) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (!(\"value\" in descriptor)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`${walk.subject}${memberPath} is an accessor property; map it to plain data`,\n\t\t\t);\n\t\t}\n\t\tif (tag !== undefined) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`${walk.subject}${memberPath} is an expando on a ${constructorName(Object.getPrototypeOf(object)) ?? \"built-in\"} and the clone would drop it; map it to plain data`,\n\t\t\t);\n\t\t}\n\t\tstep(walk, key, memberPath);\n\t\tassertCopyable(descriptor.value, memberPath, walk);\n\t}\n}\n\n/**\n * Whether an own non-enumerable property of a built-in is machinery, not\n * data: a function that shadows a mutator of a frozen Date, Map, or Set,\n * the scan position of a RegExp, or the length of a boxed String. The\n * clone drops the shadow and rebuilds the other two from the internal\n * slots.\n */\nfunction isBuiltInMachinery(\n\ttag: BuiltInTag,\n\tkey: string,\n\tdescriptor: PropertyDescriptor,\n): boolean {\n\treturn (\n\t\tisMutatorShadow(tag, key, descriptor) ||\n\t\t(tag === REGEXP_TAG && key === \"lastIndex\") ||\n\t\t(tag === STRING_TAG && key === \"length\")\n\t);\n}\n\n/**\n * The number of index keys that hold the content of a built-in: the\n * elements of a typed array and the characters of a boxed String.\n */\nfunction contentLengthOf(object: object, tag: BuiltInTag): number {\n\tif (tag === \"[object TypedArray]\") {\n\t\treturn typedArrayLength.call(object as ArrayBufferView);\n\t}\n\tif (tag === STRING_TAG) return stringValueOf.call(object).length;\n\treturn 0;\n}\n\n// The built-in readers read the internal slot, so an own `buffer` or\n// `length` accessor of the state does not run.\nconst typedArrayLength = Object.getOwnPropertyDescriptor(\n\tObject.getPrototypeOf(Uint8Array.prototype),\n\t\"length\",\n)?.get as (this: ArrayBufferView) => number;\nconst stringValueOf = String.prototype.valueOf;\nconst typedArrayBuffer = Object.getOwnPropertyDescriptor(\n\tObject.getPrototypeOf(Uint8Array.prototype),\n\t\"buffer\",\n)?.get as (this: ArrayBufferView) => ArrayBufferLike;\nconst dataViewBuffer = Object.getOwnPropertyDescriptor(\n\tDataView.prototype,\n\t\"buffer\",\n)?.get as (this: DataView) => ArrayBufferLike;\n\nfunction sharesMemory(object: object, tag: BuiltInTag): boolean {\n\tif (tag === \"[object SharedArrayBuffer]\") return true;\n\tif (tag === \"[object TypedArray]\") {\n\t\treturn isSharedArrayBuffer(\n\t\t\ttypedArrayBuffer.call(object as ArrayBufferView),\n\t\t);\n\t}\n\tif (tag === \"[object DataView]\") {\n\t\treturn isSharedArrayBuffer(dataViewBuffer.call(object as DataView));\n\t}\n\treturn false;\n}\n\nfunction isSharedArrayBuffer(buffer: ArrayBufferLike): boolean {\n\treturn (\n\t\tbuiltInTagWithoutInvokingAccessors(buffer) === \"[object SharedArrayBuffer]\"\n\t);\n}\n\nfunction assertFreezable(tag: BuiltInTag, path: string, subject: string): void {\n\tif (BINARY_DATA_TAGS.has(tag)) {\n\t\tthrow new TypeError(\n\t\t\t`${subject}${path} is binary data; binary buffers (a typed array, a DataView, an ArrayBuffer, or a SharedArrayBuffer) stay mutable under freezing and JSON does not keep them; encode the data as a string, for example base64`,\n\t\t);\n\t}\n\tif (tag === REGEXP_TAG) {\n\t\tthrow new TypeError(\n\t\t\t`${subject}${path} is a RegExp; a freeze cannot make it immutable, because compile() changes the pattern of a frozen RegExp before it throws, and a frozen global or sticky pattern throws on a match; keep its source and flags as strings`,\n\t\t);\n\t}\n}\n\nfunction throwClassInstance(\n\tobject: object,\n\tpath: string,\n\tsubject: string,\n): never {\n\tconst name =\n\t\tconstructorName(Object.getPrototypeOf(object)) ?? \"anonymous class\";\n\tthrow new TypeError(\n\t\t`${subject}${path} is a class instance (${name}); map it to plain data`,\n\t);\n}\n\n/**\n * The name of the constructor of `prototype`, read through property\n * descriptors, so that no accessor runs.\n */\nfunction constructorName(prototype: object | null): string | undefined {\n\tif (prototype === null) return undefined;\n\tconst owner = Object.getOwnPropertyDescriptor(\n\t\tprototype,\n\t\t\"constructor\",\n\t)?.value;\n\tif (typeof owner !== \"function\") return undefined;\n\tconst name = Object.getOwnPropertyDescriptor(owner, \"name\")?.value;\n\treturn typeof name === \"string\" && name !== \"\" ? name : undefined;\n}\n","const COUNTER_LIMIT = 2 ** 42;\n\nlet lastMilliseconds = Number.NEGATIVE_INFINITY;\nlet counter = 0;\n\n/**\n * RFC 9562 UUID version 7: the Unix time in milliseconds in the first 48 bits,\n * then random bits from Web Crypto. A B-tree index on such ids stays\n * clustered.\n *\n * The ids of one process sort in creation order. Ids from several processes\n * interleave within one millisecond and depend on their clocks. Within one\n * millisecond of one process, a 42-bit counter increases by one per id: the\n * 12 bits of `rand_a` and the first 30 bits of `rand_b`. It starts at a random\n * value with its top bit clear, so it does not run out in practice, also not\n * on a runtime that stops the clock during a request. If it runs out, the time\n * field moves one millisecond ahead. A clock that goes back does not move the\n * time field back. This is method 1 of RFC 9562, section 6.2.\n */\nexport function uuidV7(): string {\n\tconst bytes = new Uint8Array(16);\n\tglobalThis.crypto.getRandomValues(bytes);\n\tconst view = new DataView(bytes.buffer);\n\t// The time field below overwrites bytes 0 to 5, so their random bits\n\t// seed the counter without taking bits from the rest of the id.\n\tconst seed = (view.getUint16(0) & 0x01ff) * 2 ** 32 + view.getUint32(2);\n\tconst now = Date.now();\n\tif (now > lastMilliseconds) {\n\t\tlastMilliseconds = now;\n\t\tcounter = seed;\n\t} else if (counter + 1 < COUNTER_LIMIT) {\n\t\tcounter += 1;\n\t} else {\n\t\tlastMilliseconds += 1;\n\t\tcounter = seed;\n\t}\n\n\t// Bit operators work on 32 bits, and the time needs 48.\n\tlet time = lastMilliseconds;\n\tfor (let index = 5; index >= 0; index -= 1) {\n\t\tbytes[index] = time % 0x100;\n\t\ttime = Math.floor(time / 0x100);\n\t}\n\tconst counterHigh = Math.floor(counter / 2 ** 24);\n\tconst counterLow = counter % 2 ** 24;\n\tview.setUint16(6, 0x7000 | (counterHigh >>> 6));\n\tview.setUint8(8, 0x80 | (counterHigh & 0x3f));\n\tview.setUint8(9, counterLow >>> 16);\n\tview.setUint16(10, counterLow & 0xffff);\n\n\tlet hex = \"\";\n\tfor (const byte of bytes) hex += byte.toString(16).padStart(2, \"0\");\n\treturn `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\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_AGGREGATE_IDENTITY_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 { assertNoOwnProtoKey } from \"../../errors/kit-errors\";\nimport {\n\tapplyCooperativeBrand,\n\thasCooperativeBrand,\n} from \"../../internal/cooperative-brand\";\nimport { copyFreezableState } from \"../../internal/structural/copy-plain-state\";\nimport { isIntrinsicConstructorPrototype } from \"../../internal/structural/is-built-in\";\nimport { uuidV7 } from \"../../internal/uuid-v7\";\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 creates a time-ordered **UUID v7** from\n * Web Crypto random bits (works on Node 19+, modern browsers in secure\n * contexts, Deno, Bun, Cloudflare Workers, Vercel Edge, and any runtime that\n * implements Web Crypto). A B-tree index on the eventId column stays\n * clustered. The id is no ordering authority: ids from several processes\n * interleave within one millisecond, and clock skew can invert them. Order\n * events by aggregate version or stream position. Supply another generator\n * to {@link createDomainEventFactory} to\n * use ULID, KSUID, or another collision-safe format without mutating module\n * state.\n */\nexport type EventIdFactory = () => string;\n\nconst defaultEventIdFactory: EventIdFactory = uuidV7;\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 stamping)\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 a UUID v7;\n\t * 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 application shell stamped the accepted fact.\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 event id,\n * stamp time, or delivery metadata.\n *\n * The aggregate owns the event type, payload, source aggregate identity,\n * and payload schema version because those values describe the business\n * fact it produced.\n * The application shell later turns this value into a {@link DomainEvent}.\n */\nexport interface UnstampedDomainEvent<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 unstamped domain-event shape. */\nexport type AnyUnstampedDomainEvent = UnstampedDomainEvent<string, unknown>;\n\n/** Derives the unstamped shape represented by a concrete event or event union. */\nexport type UnstampedDomainEventOf<TEvent extends AnyDomainEvent> =\n\tTEvent extends DomainEvent<infer TType, infer TPayload>\n\t\t? UnstampedDomainEvent<TType, TPayload>\n\t\t: never;\n\n/** An aggregate may hold unstamped decisions and already stamped events together. */\nexport type PendingDomainEvent<TEvent extends AnyDomainEvent> =\n\t| TEvent\n\t| UnstampedDomainEventOf<TEvent>;\n\n/**\n * Options of `createEvent` in an aggregate. The aggregate fills its own\n * identity, so only the schema version of the payload is left.\n */\nexport interface CreateEventOptions {\n\treadonly schemaVersion?: number;\n}\n\n/** Producer-owned options for an unstamped event. */\nexport interface CreateUnstampedDomainEventOptions extends CreateEventOptions {\n\treadonly aggregateId?: string;\n\treadonly aggregateType?: string;\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 generate a UUID v7.\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 stamp 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 CreateStampedDomainEventOptions 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 a UUID v7 from Web Crypto random bits. */\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 builds, 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 builds 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 stamp 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 stamps 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 * const uow = new UnitOfWork({ ...deps, eventStampFactory: domainEvents });\n * ```\n */\nexport function createDomainEventFactory(\n\toptions: DomainEventFactoryOptions = {},\n): DomainEventFactory {\n\treturn buildDomainEventFactory(options, \"DomainEventFactory.create\");\n}\n\n/** `createOperation` is the name that the errors of `create` give. */\nfunction buildDomainEventFactory(\n\toptions: DomainEventFactoryOptions,\n\tcreateOperation: string,\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\tbuildDomainEvent(\n\t\t\ttype,\n\t\t\tpayload,\n\t\t\tcreateOptions,\n\t\t\teventIdFactory,\n\t\t\tclock,\n\t\t\tcreateOperation,\n\t\t\tsource,\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 = ownedEventMetadata(\n\t\t\tstampOptions.metadata,\n\t\t\t\"DomainEventFactory.createStamp\",\n\t\t\tsource,\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\tbuildDomainEventFactory({}, \"createDomainEvent\");\n\n// Every stamped 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// \"built by a kit constructor\" directly instead of approximating it with\n// frozen-ness probes. Kit-built 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 STAMPED_EVENTS = new WeakSet<object>();\nconst UNSTAMPED_EVENTS = new WeakSet<object>();\nconst FACTORY_OWNED_EVENT_STAMPS = new WeakSet<object>();\n\n// Cooperative cross-instance tier of the kit-built check: a WeakSet is\n// bound to ONE loaded copy of this module, so an event legitimately\n// built by a second copy of the kit would be rejected as hand-built.\n// Such events are recognized by the cooperative brand instead, which\n// every constructor and kit-derived copy applies 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 applies the same keys. The constant names follow the\n// vocabulary; the key strings never change, so an older word in a key is\n// part of the contract, not a name.\nconst STAMPED_BRAND = Symbol.for(\"@shirudo/ddd-kit.mintedEvent\");\nconst UNSTAMPED_BRAND = Symbol.for(\"@shirudo/ddd-kit.uncommittedEvent\");\n\nfunction brandStampedEvent(event: object): void {\n\tapplyCooperativeBrand(event, STAMPED_BRAND);\n}\n\nfunction brandUnstampedEvent(event: object): void {\n\tapplyCooperativeBrand(event, UNSTAMPED_BRAND);\n}\n\nfunction isFactoryOwnedDomainEventStamp(stamp: object): boolean {\n\treturn FACTORY_OWNED_EVENT_STAMPS.has(stamp);\n}\n\n/**\n * Whether `event` is a stamped domain event: it came out of\n * {@link createDomainEvent}, {@link createStampedDomainEvent}, or\n * {@link stampDomainEvent}, so it is deeply frozen with defensively copied\n * payload and metadata. An unstamped decision carries the other brand; see\n * {@link isUnstampedDomainEvent}. Two tiers: events of THIS\n * loaded copy of the kit are verified through the module-private\n * WeakSet; events built 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 isStampedDomainEvent(event: object): event is AnyDomainEvent {\n\treturn STAMPED_EVENTS.has(event) || hasCooperativeBrand(event, STAMPED_BRAND);\n}\n\n/** Whether a value is a kit-built unstamped event. */\nexport function isUnstampedDomainEvent(\n\tevent: object,\n): event is AnyUnstampedDomainEvent {\n\treturn (\n\t\tUNSTAMPED_EVENTS.has(event) || hasCooperativeBrand(event, UNSTAMPED_BRAND)\n\t);\n}\n\n/**\n * Creates an unstamped domain event: the event that an aggregate method\n * returns before the application shell stamps it. The payload and the\n * metadata follow the input ownership rule of {@link createDomainEvent}.\n */\nexport function createUnstampedDomainEvent<T extends string>(\n\ttype: T,\n\tpayload?: undefined,\n\toptions?: CreateUnstampedDomainEventOptions,\n): UnstampedDomainEvent<T, void>;\nexport function createUnstampedDomainEvent<T extends string, P>(\n\ttype: T,\n\tpayload: P,\n\toptions?: CreateUnstampedDomainEventOptions,\n): UnstampedDomainEvent<T, P>;\nexport function createUnstampedDomainEvent<T extends string, P>(\n\ttype: T,\n\tpayload?: P,\n\toptions?: CreateUnstampedDomainEventOptions,\n): UnstampedDomainEvent<T, P> {\n\treturn buildUnstampedDomainEvent(\n\t\ttype,\n\t\tpayload,\n\t\toptions,\n\t\t\"createUnstampedDomainEvent\",\n\t);\n}\n\n/**\n * {@link createUnstampedDomainEvent} whose errors name `operation`, the\n * function that the caller called. Module-internal export; not part of the\n * package entries.\n */\nexport function buildUnstampedDomainEvent<T extends string, P>(\n\ttype: T,\n\tpayload: P | undefined,\n\toptions: CreateUnstampedDomainEventOptions | undefined,\n\toperation: string,\n): UnstampedDomainEvent<T, P> {\n\tassertProducerOwnedEventFields(type, options);\n\tconst event: UnstampedDomainEvent<T, P> = {\n\t\ttype,\n\t\taggregateId: options?.aggregateId,\n\t\taggregateType: options?.aggregateType,\n\t\tpayload: cloneOwnedEventData(payload as P, \"payload\", operation),\n\t\tschemaVersion: options?.schemaVersion ?? 1,\n\t};\n\tbrandUnstampedEvent(event);\n\tconst unstamped = deepFreeze(event) as UnstampedDomainEvent<T, P>;\n\tUNSTAMPED_EVENTS.add(unstamped);\n\treturn unstamped;\n}\n\n/** Brands and freezes a kit-derived copy of an unstamped event. */\nexport function adoptUnstampedDomainEvent<T extends object>(copy: T): T {\n\tbrandUnstampedEvent(copy);\n\tObject.freeze(copy);\n\tUNSTAMPED_EVENTS.add(copy);\n\treturn copy;\n}\n\n/**\n * Attaches shell-owned stamp data to an accepted aggregate decision.\n *\n * The decision supplies the domain type, payload, source aggregate\n * identity, and payload schema version. The stamp supplies only event\n * identity, stamp time, and trace metadata.\n */\nexport function stampDomainEvent<T extends string, P>(\n\tevent: UnstampedDomainEvent<T, P>,\n\tstamp: DomainEventStamp,\n): DomainEvent<T, P> {\n\tif (!isUnstampedDomainEvent(event)) {\n\t\tthrow new TypeError(\n\t\t\t\"stampDomainEvent requires an unstamped event from an aggregate's createEvent\",\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 stamped event.\n\t\treturn buildStampedEvent(\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 = ownedEventMetadata(stamp.metadata, \"stampDomainEvent\");\n\treturn buildStampedEvent(\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 build tail for both stamp provenances. The stamp fields arrive\n * pre-validated, copied, and frozen (by `createStamp` for factory-owned\n * stamps, by `stampDomainEvent` for caller-built stamps); the unstamped\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 buildStampedEvent<T extends string, P>(\n\tevent: UnstampedDomainEvent<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\tbrandStampedEvent(recorded);\n\tObject.freeze(recorded);\n\tSTAMPED_EVENTS.add(recorded);\n\treturn recorded;\n}\n\n/**\n * Brands, freezes, and registers a kit-derived copy of a stamped event\n * (e.g. the copy `apply()` stamps with the aggregate identity) as recorded\n * itself.\n * The copy shares the already-frozen payload/metadata of its source,\n * so the kit-built guarantee carries over. Applying 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 adoptStampedDomainEvent<T extends object>(copy: T): T {\n\tbrandStampedEvent(copy);\n\tObject.freeze(copy);\n\tSTAMPED_EVENTS.add(copy);\n\treturn copy;\n}\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 event\n * (same contract as `valueObject()`). The event data rule checks the data before the\n * copy and the copy after it. So the copy loses no data without an error,\n * and no getter of the data runs. The in-memory event store applies the\n * same rule on append. The checks catch accidents, not a hostile `Proxy`: a\n * trap that changes the data during the check can hide a loss. An error\n * that a `Proxy` trap throws passes unchanged, so a coded error of the\n * caller keeps its code. These values throw a `TypeError`: a function, a\n * Promise, a WeakMap or a WeakSet, an `Error`, a host object such as a\n * `File`, a binary buffer, a `RegExp`, and shared memory. The same holds\n * for what the copy would lose or change: a class instance, an accessor, an\n * enumerable symbol-keyed property, a non-enumerable data property, and an\n * expando on a built-in. A non-enumerable symbol key is metadata by\n * convention, and the event does not get it. Map a value object to plain\n * data before it goes into an event. `toJSON()` of a `ValueObject` is\n * shallow, so map a nested value object too.\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. Stamp pending decisions in the application\n * shell before repository persistence or outbox collection.\n *\n * Use `createDomainEvent(...)` directly for events that don't belong to\n * an aggregate: system events, integration events, configuration events,\n * test fixtures. For those, set `aggregateId` / `aggregateType` in\n * `options` if downstream consumers expect routing metadata.\n *\n * @param type - The event type\n * @param payload - The event payload\n * @param options - Optional event configuration (including `aggregateId`\n * and `aggregateType` for routing)\n * @returns A domain event\n *\n * @example\n * ```typescript\n * const event = createDomainEvent(\"OrderCreated\", { orderId: \"123\" });\n * ```\n */\nexport function createDomainEvent<T extends string>(\n\ttype: T,\n\tpayload?: undefined,\n\toptions?: CreateDomainEventOptions,\n): DomainEvent<T, void>;\nexport function createDomainEvent<T extends string, P>(\n\ttype: T,\n\tpayload: P,\n\toptions?: CreateDomainEventOptions,\n): DomainEvent<T, P>;\nexport function createDomainEvent<T extends string, P>(\n\ttype: T,\n\tpayload?: P,\n\toptions?: CreateDomainEventOptions,\n): DomainEvent<T, P> {\n\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 a kit-built, stamped 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 UnstampedDomainEvent} through\n * its protected `createEvent` helper. The application shell later records that\n * pending fact with caller-owned time and identity.\n */\nexport function createStampedDomainEvent<T extends string>(\n\ttype: T,\n\tpayload: undefined,\n\toptions: CreateStampedDomainEventOptions,\n): DomainEvent<T, void>;\nexport function createStampedDomainEvent<T extends string, P>(\n\ttype: T,\n\tpayload: P,\n\toptions: CreateStampedDomainEventOptions,\n): DomainEvent<T, P>;\nexport function createStampedDomainEvent<T extends string, P>(\n\ttype: T,\n\tpayload: P | undefined,\n\toptions: CreateStampedDomainEventOptions,\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 buildDomainEvent(\n\t\ttype,\n\t\tpayload,\n\t\toptions,\n\t\tmissingExplicitEventId,\n\t\tmissingExplicitOccurredAt,\n\t\t\"createStampedDomainEvent\",\n\t);\n}\n\nfunction missingExplicitEventId(): string {\n\tthrow new DomainEventValidationError(\n\t\t\"EVENT_ID_REQUIRED\",\n\t\t\"eventId\",\n\t\t\"createStampedDomainEvent 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\"createStampedDomainEvent requires an explicit occurredAt\",\n\t);\n}\n\nfunction buildDomainEvent<T extends string, P>(\n\ttype: T,\n\tpayload: P | undefined,\n\toptions: CreateDomainEventOptions | undefined,\n\teventIdFactory: EventIdFactory,\n\tclock: ClockFactory,\n\toperation: string,\n\tfactorySource?: string,\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 `valueObject()` and the occurredAt copy.\n\t\tpayload: cloneOwnedEventData(payload as P, \"payload\", operation),\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: ownedEventMetadata(options?.metadata, operation, factorySource),\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\tbrandStampedEvent(event);\n\tconst built = deepFreeze(event) as DomainEvent<T, P>;\n\tSTAMPED_EVENTS.add(built);\n\treturn built;\n}\n\nfunction assertProducerOwnedEventFields(\n\ttype: unknown,\n\toptions:\n\t\t| CreateDomainEventOptions\n\t\t| CreateUnstampedDomainEventOptions\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_AGGREGATE_IDENTITY_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_AGGREGATE_IDENTITY_INVALID\",\n\t\t);\n\t}\n}\n\nfunction assertNonBlankEventField(\n\tvalue: unknown,\n\tfield: \"eventId\" | \"type\" | \"aggregateId\" | \"aggregateType\",\n\tcode:\n\t\t| \"EVENT_ID_INVALID\"\n\t\t| \"EVENT_TYPE_INVALID\"\n\t\t| \"EVENT_AGGREGATE_IDENTITY_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 * Copies the caller's metadata and checks the copy. Metadata is a plain\n * record or absent; a null from a JSON envelope would build and then fail\n * every metadata read far from the producer. A factory origin fills\n * `source` only after the check, and a call site that names its own source\n * keeps it: an explicit fact about one event outranks the default of the\n * factory that builds it.\n */\nfunction ownedEventMetadata(\n\tmetadata: EventMetadata | undefined,\n\toperation: string,\n\tfactorySource?: string,\n): EventMetadata | undefined {\n\tif (metadata === undefined) {\n\t\treturn factorySource === undefined ? undefined : { source: factorySource };\n\t}\n\tconst owned: unknown = cloneOwnedEventData(metadata, \"metadata\", operation);\n\tif (!isPlainRecordCopy(owned)) {\n\t\t// The copy is the kit's own, so its tag runs no caller code.\n\t\tconst received =\n\t\t\ttypeof owned === \"object\"\n\t\t\t\t? owned === null\n\t\t\t\t\t? \"null\"\n\t\t\t\t\t: Object.prototype.toString.call(owned)\n\t\t\t\t: `a ${typeof owned}`;\n\t\tthrow new TypeError(\n\t\t\t`${operation}: metadata must be an object or undefined, and a plain record; received ${received}`,\n\t\t);\n\t}\n\tconst record = owned as EventMetadata;\n\tif (factorySource === undefined || record.source !== undefined) {\n\t\treturn record;\n\t}\n\treturn { ...record, source: factorySource };\n}\n\n/**\n * True for a structured-clone copy of a plain record. A runtime such as\n * Vercel Edge returns the copy with the `Object.prototype` of another realm,\n * so the check compares the source text of the constructor, not the\n * prototype object.\n */\nfunction isPlainRecordCopy(copy: unknown): boolean {\n\tif (typeof copy !== \"object\" || copy === null) return false;\n\tconst prototype = Object.getPrototypeOf(copy);\n\treturn (\n\t\tprototype !== null &&\n\t\tisIntrinsicConstructorPrototype(prototype, \"Object\") &&\n\t\tObject.getPrototypeOf(prototype) === null\n\t);\n}\n\n/**\n * Deep-clones caller-supplied event data (payload, metadata) before the\n * event is frozen, so a constructor never freezes or aliases the caller's\n * own object graph. {@link copyFreezableState} checks the data and the\n * clone; its JSDoc states the rule and its limits.\n */\nfunction cloneOwnedEventData<T>(\n\tvalue: T,\n\tfield: \"payload\" | \"metadata\",\n\toperation: string,\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. The\n\t// check runs first, so this key throws its own error whatever else is\n\t// wrong with the data.\n\tif (value !== null && typeof value === \"object\") {\n\t\tassertNoOwnProtoKey(value, `Event ${field} of ${operation}`);\n\t}\n\t// The freeze rule keeps the guarantee \"kit-built implies deeply\n\t// frozen\".\n\treturn copyFreezableState(value, `${operation}: ${field}`);\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\tassertNoOwnProtoKey(sourceEvent.metadata, \"Event metadata\");\n\t}\n\tif (additionalMetadata !== undefined) {\n\t\tassertNoOwnProtoKey(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\tassertNoOwnProtoKey(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 * The value to reject with when an `AbortSignal` has fired.\n *\n * Returns the signal's `reason` (a `DOMException` `AbortError` for\n * `controller.abort()`, `TimeoutError` for `AbortSignal.timeout`), falling\n * back to a plain `Error` with `fallbackMessage` when `reason` is nullish.\n * A spec-compliant signal always populates `reason` when aborted, so the\n * fallback only fires for a non-spec polyfill; without it, a bare\n * `throw undefined` would surface, breaking `instanceof Error` handling.\n *\n * Centralizes the `signal.reason ?? new Error(...)` idiom used at every\n * abort site (event bus, `withCommit`, `UnitOfWork.run`, the retrying\n * scope) so a single fix covers all of them.\n */\nexport function abortReason(\n\tsignal: AbortSignal,\n\tfallbackMessage: string,\n): unknown {\n\treturn signal.reason ?? new Error(fallbackMessage);\n}\n\n/**\n * Waits for `promise`, but REJECTS with the signal's reason as soon as the\n * signal fires. The promise keeps running; only the wait ends. The abort\n * listener goes away when the promise settles.\n */\nexport function waitRejectingOnAbort<T>(\n\tpromise: Promise<T>,\n\tsignal: AbortSignal | undefined,\n\tabortMessage: string,\n): Promise<T> {\n\tif (signal === undefined) return promise;\n\treturn new Promise<T>((resolve, reject) => {\n\t\tif (signal.aborted) {\n\t\t\treject(abortReason(signal, abortMessage));\n\t\t\treturn;\n\t\t}\n\t\tconst onAbort = (): void => reject(abortReason(signal, abortMessage));\n\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\tpromise.then(\n\t\t\t(value) => {\n\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\tresolve(value);\n\t\t\t},\n\t\t\t(error: unknown) => {\n\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\treject(error);\n\t\t\t},\n\t\t);\n\t});\n}\n","/**\n * Shared construction-time guards for numeric options. `context` names\n * the throwing component so the error reads like the component's own\n * validation (\"OutboxDispatcher: pollIntervalMs must be...\").\n */\n\n/** Guard for numeric options that must be a non-negative finite number. */\nexport function assertNonNegativeFinite(\n\tcontext: string,\n\tfield: string,\n\tvalue: number,\n): void {\n\tif (!Number.isFinite(value) || value < 0) {\n\t\tthrow new Error(\n\t\t\t`${context}: ${field} must be a non-negative finite number, got ${value}`,\n\t\t);\n\t}\n}\n\n/**\n * The largest delay that `setTimeout` honors. A larger delay does not wait\n * longer: the runtime fires the timer after about 1 ms.\n */\nexport const MAX_TIMER_DELAY_MS = 2_147_483_647;\n\n/** Guard for time options that a timer waits for, in milliseconds. */\nexport function assertTimerDelay(\n\tcontext: string,\n\tfield: string,\n\tvalue: number,\n): void {\n\tif (!Number.isFinite(value) || value < 0 || value > MAX_TIMER_DELAY_MS) {\n\t\tthrow new RangeError(\n\t\t\t`${context}: ${field} must be a finite number of milliseconds from 0 ` +\n\t\t\t\t`to ${MAX_TIMER_DELAY_MS}, got ${value}`,\n\t\t);\n\t}\n}\n\n/** Guard for count options that must be a whole number of at least 1. */\nexport function assertPositiveInteger(\n\tcontext: string,\n\tfield: string,\n\tvalue: number,\n): void {\n\tif (!Number.isInteger(value) || value < 1) {\n\t\tthrow new Error(\n\t\t\t`${context}: ${field} must be an integer >= 1, got ${value}`,\n\t\t);\n\t}\n}\n\n/** Guard for retained-record capacities that must fit exact JS integers. */\nexport function assertPositiveSafeInteger(\n\tcontext: string,\n\tfield: string,\n\tvalue: number,\n): void {\n\tif (!Number.isSafeInteger(value) || value < 1) {\n\t\tthrow new RangeError(\n\t\t\t`${context}: ${field} must be a positive safe integer, got ${value}`,\n\t\t);\n\t}\n}\n\n/** Guard for stream positions that must fit exact JS integers. */\nexport function assertNonNegativeSafeInteger(\n\tcontext: string,\n\tfield: string,\n\tvalue: number,\n): void {\n\tif (!Number.isSafeInteger(value) || value < 0) {\n\t\tthrow new RangeError(\n\t\t\t`${context}: ${field} must be a non-negative safe integer, got ${value}`,\n\t\t);\n\t}\n}\n","import { assertNonNegativeFinite, assertTimerDelay } from \"../validate\";\nimport { abortReason } from \"./abort\";\n\n/** Cancellation and deadline controls for one bounded shell operation. */\nexport interface ExecutionContext {\n\t/** Cooperative cancellation for the in-flight operation. */\n\treadonly signal: AbortSignal;\n\t/** Absolute Unix epoch millisecond at which the shell stops waiting. */\n\treadonly deadlineAt: number;\n}\n\n/** Caller controls for one bounded shell operation. */\ntype ExecutionOptions =\n\t| {\n\t\t\t/** Optional owner/request cancellation signal. */\n\t\t\treadonly signal?: AbortSignal;\n\t\t\t/** Maximum time the shell waits for the operation. */\n\t\t\treadonly timeoutMs: number;\n\t\t\treadonly deadlineAt?: never;\n\t }\n\t| {\n\t\t\t/** Optional owner/request cancellation signal. */\n\t\t\treadonly signal?: AbortSignal;\n\t\t\treadonly timeoutMs?: never;\n\t\t\t/** Shared absolute deadline for a multi-operation budget. */\n\t\t\treadonly deadlineAt: number;\n\t };\n\n/** Default bound for delivery and post-commit operations. */\nexport const DEFAULT_EXECUTION_TIMEOUT_MS = 30_000;\n\n/**\n * Owner signal of each child signal that {@link runBoundedExecution} created.\n *\n * One bounded operation often wraps another, and every hop derives a fresh\n * signal. A consumer that follows a call chain by signal identity alone loses\n * the link at the first hop. Key and value are both weak: a long chain of\n * nested operations must not hold its whole ancestry alive.\n */\nconst executionOwners = new WeakMap<AbortSignal, WeakRef<AbortSignal>>();\n\n/**\n * The signal that a bounded execution derived this one from, or `undefined`\n * when the signal did not come from {@link runBoundedExecution} or had no\n * owner. Walk it to follow a chain across nested bounded executions.\n */\nexport function ownerSignalOf(signal: AbortSignal): AbortSignal | undefined {\n\treturn executionOwners.get(signal)?.deref();\n}\n\n/**\n * Runs one operation with a child signal that combines owner cancellation and a\n * shell-owned timeout. The returned promise settles on abort even when an\n * adapter ignores the signal; the adapter promise remains observed so a later\n * rejection cannot become an unhandled rejection.\n *\n * This bounds how long the shell waits; JavaScript cannot forcibly terminate\n * an arbitrary promise. An I/O adapter that must prevent zombie work and\n * overlapping retries has to pass `context.signal` to its native operation or\n * enforce a native timeout no later than `context.deadlineAt`.\n */\nexport function runBoundedExecution<T>(\n\tlabel: string,\n\toptions: ExecutionOptions,\n\toperation: (context: ExecutionContext) => Promise<T> | T,\n): Promise<T> {\n\tif (options.deadlineAt === undefined) {\n\t\tassertTimerDelay(label, \"timeoutMs\", options.timeoutMs);\n\t} else {\n\t\tassertNonNegativeFinite(label, \"deadlineAt\", options.deadlineAt);\n\t}\n\tconst startedAt = Date.now();\n\tconst deadlineAt = options.deadlineAt ?? startedAt + options.timeoutMs;\n\tconst timeoutMs = Math.max(0, deadlineAt - startedAt);\n\tif (options.deadlineAt !== undefined) {\n\t\tassertTimerDelay(label, \"the time until deadlineAt\", timeoutMs);\n\t}\n\tconst timeoutError = (): DOMException =>\n\t\tnew DOMException(`${label} timed out after ${timeoutMs}ms`, \"TimeoutError\");\n\tconst controller = new AbortController();\n\tconst context = Object.freeze({\n\t\tsignal: controller.signal,\n\t\tdeadlineAt,\n\t});\n\tconst ownerSignal = options.signal;\n\tif (ownerSignal !== undefined) {\n\t\texecutionOwners.set(controller.signal, new WeakRef(ownerSignal));\n\t}\n\tconst abortFromOwner = (): void => {\n\t\tcontroller.abort(\n\t\t\townerSignal === undefined\n\t\t\t\t? new Error(`${label} aborted`)\n\t\t\t\t: abortReason(ownerSignal, `${label} aborted`),\n\t\t);\n\t};\n\n\tif (ownerSignal?.aborted) abortFromOwner();\n\telse ownerSignal?.addEventListener(\"abort\", abortFromOwner, { once: true });\n\tif (\n\t\t!controller.signal.aborted &&\n\t\toptions.deadlineAt !== undefined &&\n\t\tdeadlineAt <= startedAt\n\t) {\n\t\tcontroller.abort(timeoutError());\n\t}\n\n\tconst timer = setTimeout(() => {\n\t\tcontroller.abort(timeoutError());\n\t}, timeoutMs);\n\n\treturn new Promise<T>((resolve, reject) => {\n\t\tlet settled = false;\n\t\tconst finish = (complete: () => void): void => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tclearTimeout(timer);\n\t\t\townerSignal?.removeEventListener(\"abort\", abortFromOwner);\n\t\t\tcontroller.signal.removeEventListener(\"abort\", onAbort);\n\t\t\tcomplete();\n\t\t};\n\t\tconst onAbort = (): void => {\n\t\t\t// Defer one microtask so a promise that settled immediately before the\n\t\t\t// abort keeps its acknowledgement semantics. If abort happened first,\n\t\t\t// this microtask was queued first and still wins deterministically.\n\t\t\tqueueMicrotask(() =>\n\t\t\t\tfinish(() =>\n\t\t\t\t\treject(abortReason(controller.signal, `${label} aborted`)),\n\t\t\t\t),\n\t\t\t);\n\t\t};\n\n\t\tif (controller.signal.aborted) {\n\t\t\tonAbort();\n\t\t\treturn;\n\t\t}\n\t\tcontroller.signal.addEventListener(\"abort\", onAbort, { once: true });\n\t\tlet outcome: Promise<T>;\n\t\ttry {\n\t\t\toutcome = Promise.resolve(operation(context));\n\t\t} catch (error) {\n\t\t\tfinish(() => reject(error));\n\t\t\treturn;\n\t\t}\n\t\toutcome.then(\n\t\t\t(value) => finish(() => resolve(value)),\n\t\t\t(error) => finish(() => reject(error)),\n\t\t);\n\t});\n}\n","import type { AggregateIdentity } from \"../../domain/aggregate/aggregate-identity\";\nimport 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\t/**\n\t * Ends the event sources of removed aggregates. Called from inside\n\t * `withCommit`'s transactional callback, after `add()`, atomically with\n\t * the removal.\n\t *\n\t * For every source that has a head, the adapter marks the head as ended\n\t * in the SAME transaction. The mark must outlive any retention of heads:\n\t * a pruned ended head opens the source again. A source without a head\n\t * has no events, so it has no continuity to protect: it stays open, and\n\t * its first event starts a new head. After the mark, `add()` must reject\n\t * a new event of that source: its aggregate was created again under a\n\t * removed identity, which the kit does not support. An exact retry of a\n\t * stored event stays idempotent, and ending a source twice is not an\n\t * error.\n\t */\n\tendEventSources: (sources: ReadonlyArray<AggregateIdentity>) => 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","import type { AggregateIdentity } from \"../../domain/aggregate/aggregate-identity\";\nimport { InvalidEventStreamPageError } from \"../../errors/kit-errors\";\n\nexport function assertValidHead(\n\tstream: AggregateIdentity,\n\tlastVersion: unknown,\n\tfromVersion: number,\n\ttargetVersion?: number,\n): asserts lastVersion is number {\n\tif (Number.isSafeInteger(lastVersion) && (lastVersion as number) >= 1) return;\n\tthrow new InvalidEventStreamPageError({\n\t\tidentity: stream,\n\t\treason: \"invalid_head\",\n\t\tfromVersion,\n\t\ttargetVersion,\n\t\tlastVersion,\n\t});\n}\n\nexport function assertHeadNotBehindFirstPage(\n\tstream: AggregateIdentity,\n\tlastVersion: number,\n\tfirstPageLastVersion: number,\n\tfromVersion: number,\n\ttargetVersion: number,\n): void {\n\tif (lastVersion >= firstPageLastVersion) return;\n\tthrow new InvalidEventStreamPageError({\n\t\tidentity: stream,\n\t\treason: \"head_regressed\",\n\t\tfromVersion,\n\t\ttargetVersion,\n\t\tlastVersion,\n\t\tfirstPageLastVersion,\n\t});\n}\n\nexport function assertPageNotEmpty(\n\tstream: AggregateIdentity,\n\teventCount: number,\n\tfromVersion: number,\n\ttargetVersion: number,\n): void {\n\tif (eventCount > 0) return;\n\tthrow new InvalidEventStreamPageError({\n\t\tidentity: stream,\n\t\treason: \"empty_page\",\n\t\tfromVersion,\n\t\ttargetVersion,\n\t});\n}\n\nexport function assertPageWithinWindow(\n\tstream: AggregateIdentity,\n\teventCount: number,\n\tfromVersion: number,\n\ttargetVersion: number,\n): void {\n\tif (eventCount <= targetVersion - fromVersion) return;\n\tthrow new InvalidEventStreamPageError({\n\t\tidentity: stream,\n\t\treason: \"page_past_target\",\n\t\tfromVersion,\n\t\ttargetVersion,\n\t\teventCount,\n\t});\n}\n\nexport function assertPageWithinLimit(\n\tstream: AggregateIdentity,\n\teventCount: number,\n\tlimit: number,\n\tfromVersion: number,\n\ttargetVersion: number,\n): void {\n\tif (eventCount <= limit) return;\n\tthrow new InvalidEventStreamPageError({\n\t\tidentity: stream,\n\t\treason: \"page_over_limit\",\n\t\tfromVersion,\n\t\ttargetVersion,\n\t\teventCount,\n\t\tlimit,\n\t});\n}\n","import type { AggregateIdentity } from \"../../domain/aggregate/aggregate-identity\";\nimport type { AnyDomainEvent } from \"../../domain/event/domain-event\";\nimport { InvalidEventStreamPageError } from \"../../errors/kit-errors\";\nimport { abortReason } from \"../../internal/async/abort\";\nimport {\n\tassertNonNegativeSafeInteger,\n\tassertPositiveSafeInteger,\n} from \"../../internal/validate\";\nimport type { EventStreamReader, ReadStreamOptions } from \"./event-store\";\nimport {\n\tassertHeadNotBehindFirstPage,\n\tassertPageNotEmpty,\n\tassertPageWithinLimit,\n\tassertPageWithinWindow,\n\tassertValidHead,\n} from \"./event-stream-page-guards\";\nimport type { ReplayableStreamPages } from \"./reconstitute-from-stream-pages\";\n\n/** Options for {@link readStreamPages}. */\nexport interface ReadStreamPagesOptions\n\textends Pick<ReadStreamOptions, \"limit\" | \"fromVersion\" | \"signal\"> {\n\t/**\n\t * The version a point-in-time read asks for (inclusive, 1-based event\n\t * count). Without it, the target version is the head that the first page\n\t * reports. A value beyond the head does not clamp: see\n\t * {@link pinTargetVersion}. Must be a positive safe integer when present.\n\t * Version 0 is the state before the first event, and no replay can end\n\t * there.\n\t */\n\treadonly toVersion?: number;\n}\n\n/**\n * A stream read with the target version pinned on its first page.\n *\n * The first page decides the state of the stream once, in three branches.\n * An absent stream is `exists: false`. An existing stream whose window lies\n * outside it is `reachable: false` and carries the actual head. The\n * remaining branch carries the target version and the pages after the\n * cursor. The other two branches both carry `reachable: false`, so one\n * guard narrows to the branch that\n * {@link reconstituteAggregateFromStreamPages} accepts. The caller decides\n * what the other two branches mean before the replay.\n */\nexport type StreamPages<Evt extends AnyDomainEvent> =\n\t| AbsentStreamPages\n\t| UnreachableStreamPages\n\t| ReachableStreamPages<Evt>;\n\n/** The branch of {@link StreamPages} for a stream the store does not hold. */\nexport interface AbsentStreamPages {\n\treadonly exists: false;\n\treadonly reachable: false;\n}\n\n/**\n * The branch of {@link StreamPages} for a window that lies outside an\n * existing stream: the cursor lies beyond the target version, or the\n * target version lies beyond the head ({@link pinTargetVersion}).\n *\n * The caller tells the causes apart from its own inputs. A snapshot\n * version above `lastVersion` means that the snapshot outlived its stream:\n * discard it and replay from zero. A `toVersion` above `lastVersion` means\n * that the stream has not reached that version: answer not found and keep\n * the snapshot. A snapshot version above `toVersion` means that the\n * snapshot is too new for the request: keep it and replay from zero up to\n * `toVersion`.\n */\nexport interface UnreachableStreamPages {\n\treadonly exists: true;\n\treadonly reachable: false;\n\n\t/** The cursor the read started at: `fromVersion`, or `0`. */\n\treadonly fromVersion: number;\n\n\t/** The actual stream head on the first page. */\n\treadonly lastVersion: number;\n}\n\n/** The branch of {@link StreamPages} that the replay accepts. */\nexport interface ReachableStreamPages<Evt extends AnyDomainEvent>\n\textends ReplayableStreamPages<Evt> {\n\treadonly exists: true;\n\treadonly reachable: true;\n}\n\n/** Options for {@link pinTargetVersion}. */\nexport interface PinTargetVersionOptions {\n\t/** The cursor of the read: the replay starts after this version. */\n\treadonly fromVersion: number;\n\n\t/** The version a point-in-time read asks for. Defaults to `lastVersion`. */\n\treadonly toVersion?: number;\n\n\t/** The head of the existing stream: its event count. */\n\treadonly lastVersion: number;\n}\n\n/** The verdict of {@link pinTargetVersion}. */\nexport type PinnedTargetVersion =\n\t| { readonly reachable: true; readonly targetVersion: number }\n\t| { readonly reachable: false };\n\n/**\n * Pins the target version of a replay window on an existing stream, or\n * reports the window as unreachable.\n *\n * The target version is `toVersion` when given, else `lastVersion`. The\n * window is unreachable when `fromVersion` lies beyond the target version,\n * or the target version lies beyond `lastVersion`. The call never clamps\n * such a window to the head, so a request for version 10 of a stream that\n * ends at 7 never loads the latest state by accident.\n *\n * This is the decision `readStreamPages` makes on its first page. An\n * adapter that pages on its own makes it with this call, then hands its\n * pages to `reconstituteAggregateFromStreamPages`. Values that are not safe\n * integers, a negative `fromVersion`, and a `toVersion` or `lastVersion`\n * below 1 reject with `RangeError`: an existing stream holds at least one\n * event, and no replay can end at version 0.\n */\nexport function pinTargetVersion(\n\toptions: PinTargetVersionOptions,\n): PinnedTargetVersion {\n\tassertNonNegativeSafeInteger(\n\t\t\"pinTargetVersion\",\n\t\t\"fromVersion\",\n\t\toptions.fromVersion,\n\t);\n\tif (options.toVersion !== undefined) {\n\t\tassertPositiveSafeInteger(\n\t\t\t\"pinTargetVersion\",\n\t\t\t\"toVersion\",\n\t\t\toptions.toVersion,\n\t\t);\n\t}\n\tassertPositiveSafeInteger(\n\t\t\"pinTargetVersion\",\n\t\t\"lastVersion\",\n\t\toptions.lastVersion,\n\t);\n\treturn decideTargetVersion(options);\n}\n\nfunction decideTargetVersion(\n\twindow: PinTargetVersionOptions,\n): PinnedTargetVersion {\n\tconst targetVersion = window.toVersion ?? window.lastVersion;\n\tif (\n\t\twindow.fromVersion > targetVersion ||\n\t\ttargetVersion > window.lastVersion\n\t) {\n\t\treturn { reachable: false };\n\t}\n\treturn { reachable: true, targetVersion };\n}\n\n/**\n * Reads one stream in bounded pages up to a pinned target version.\n *\n * The call reads the first page. That page decides existence and reports\n * the head. The call then makes the window decision of\n * {@link pinTargetVersion}: the target version is `toVersion` when given,\n * else the head, and a window outside the stream is unreachable.\n *\n * The first iteration of `pages` yields the first page that the call read\n * and then reads the continuation pages, one page at a time. Every later\n * iteration reads all pages from the store again, so no two iterations\n * share an event object. Each of these reads passes the target version as\n * `toVersion` and starts after the events that the earlier pages\n * returned. Streams are append-only, so an iteration yields one stable\n * prefix even when another writer appends during the replay.\n *\n * The call checks every page against the `readStream` contract and throws\n * {@link InvalidEventStreamPageError} for a page that breaks it: a head\n * that is not a safe integer of at least 1, an empty page while events\n * remain in the window, a page with more events than its window has left\n * or than `limit`, and a continuation page that reports the stream absent\n * or a head below the head of the first page.\n *\n * Invalid options reject with `RangeError` before any page is read:\n * `limit` and `toVersion` must be positive safe integers, `fromVersion` a\n * non-negative one. The call passes `signal` to every page read, and it\n * checks the signal before each page read as well. An aborted signal\n * rejects with its `reason`.\n */\nexport async function readStreamPages<Evt extends AnyDomainEvent>(\n\treader: EventStreamReader<Evt>,\n\tstream: AggregateIdentity,\n\toptions: ReadStreamPagesOptions,\n): Promise<StreamPages<Evt>> {\n\tassertPositiveSafeInteger(\"readStreamPages\", \"limit\", options.limit);\n\tconst fromVersion = options.fromVersion ?? 0;\n\tassertNonNegativeSafeInteger(\"readStreamPages\", \"fromVersion\", fromVersion);\n\tif (options.toVersion !== undefined) {\n\t\tassertPositiveSafeInteger(\n\t\t\t\"readStreamPages\",\n\t\t\t\"toVersion\",\n\t\t\toptions.toVersion,\n\t\t);\n\t}\n\tthrowIfAborted(options.signal);\n\tconst identity: AggregateIdentity = {\n\t\taggregateType: stream.aggregateType,\n\t\taggregateId: stream.aggregateId,\n\t};\n\tconst first = await reader.readStream(identity, {\n\t\tfromVersion,\n\t\tlimit: options.limit,\n\t\t...(options.toVersion === undefined\n\t\t\t? {}\n\t\t\t: { toVersion: options.toVersion }),\n\t\t...(options.signal === undefined ? {} : { signal: options.signal }),\n\t});\n\tif (!first.exists) return { exists: false, reachable: false };\n\tassertValidHead(identity, first.lastVersion, fromVersion);\n\tconst pinned = decideTargetVersion({\n\t\tfromVersion,\n\t\ttoVersion: options.toVersion,\n\t\tlastVersion: first.lastVersion,\n\t});\n\tif (!pinned.reachable) {\n\t\treturn {\n\t\t\texists: true,\n\t\t\treachable: false,\n\t\t\tfromVersion,\n\t\t\tlastVersion: first.lastVersion,\n\t\t};\n\t}\n\tif (fromVersion < pinned.targetVersion) {\n\t\tassertPageNotEmpty(\n\t\t\tidentity,\n\t\t\tfirst.events.length,\n\t\t\tfromVersion,\n\t\t\tpinned.targetVersion,\n\t\t);\n\t}\n\tassertPageWithinWindow(\n\t\tidentity,\n\t\tfirst.events.length,\n\t\tfromVersion,\n\t\tpinned.targetVersion,\n\t);\n\tassertPageWithinLimit(\n\t\tidentity,\n\t\tfirst.events.length,\n\t\toptions.limit,\n\t\tfromVersion,\n\t\tpinned.targetVersion,\n\t);\n\tconst window: PinnedWindow = {\n\t\tstream: identity,\n\t\tfromVersion,\n\t\tfirstPageLastVersion: first.lastVersion,\n\t\ttargetVersion: pinned.targetVersion,\n\t\tlimit: options.limit,\n\t\tsignal: options.signal,\n\t};\n\tlet unreadFirstPage: ReadonlyArray<Evt> | undefined = first.events;\n\treturn {\n\t\texists: true,\n\t\treachable: true,\n\t\tstream: identity,\n\t\tfromVersion,\n\t\ttargetVersion: pinned.targetVersion,\n\t\tpages: {\n\t\t\t[Symbol.asyncIterator]: () => {\n\t\t\t\tconst firstPage = unreadFirstPage;\n\t\t\t\tunreadFirstPage = undefined;\n\t\t\t\treturn readPinnedPages(reader, window, firstPage);\n\t\t\t},\n\t\t},\n\t};\n}\n\ninterface PinnedWindow {\n\treadonly stream: AggregateIdentity;\n\treadonly fromVersion: number;\n\treadonly firstPageLastVersion: number;\n\treadonly targetVersion: number;\n\treadonly limit: number;\n\treadonly signal: AbortSignal | undefined;\n}\n\nasync function* readPinnedPages<Evt extends AnyDomainEvent>(\n\treader: EventStreamReader<Evt>,\n\twindow: PinnedWindow,\n\tfirstPage: ReadonlyArray<Evt> | undefined,\n): AsyncGenerator<ReadonlyArray<Evt>, void, undefined> {\n\tlet cursor = window.fromVersion;\n\tif (firstPage !== undefined) {\n\t\tif (firstPage.length > 0) yield firstPage;\n\t\tcursor += firstPage.length;\n\t}\n\twhile (cursor < window.targetVersion) {\n\t\tthrowIfAborted(window.signal);\n\t\tconst page = await reader.readStream(window.stream, {\n\t\t\tfromVersion: cursor,\n\t\t\ttoVersion: window.targetVersion,\n\t\t\tlimit: window.limit,\n\t\t\t...(window.signal === undefined ? {} : { signal: window.signal }),\n\t\t});\n\t\tif (!page.exists) {\n\t\t\tthrow new InvalidEventStreamPageError({\n\t\t\t\tidentity: window.stream,\n\t\t\t\treason: \"stream_vanished\",\n\t\t\t\tfromVersion: cursor,\n\t\t\t\ttargetVersion: window.targetVersion,\n\t\t\t});\n\t\t}\n\t\tassertValidHead(\n\t\t\twindow.stream,\n\t\t\tpage.lastVersion,\n\t\t\tcursor,\n\t\t\twindow.targetVersion,\n\t\t);\n\t\tassertHeadNotBehindFirstPage(\n\t\t\twindow.stream,\n\t\t\tpage.lastVersion,\n\t\t\twindow.firstPageLastVersion,\n\t\t\tcursor,\n\t\t\twindow.targetVersion,\n\t\t);\n\t\tassertPageNotEmpty(\n\t\t\twindow.stream,\n\t\t\tpage.events.length,\n\t\t\tcursor,\n\t\t\twindow.targetVersion,\n\t\t);\n\t\tassertPageWithinWindow(\n\t\t\twindow.stream,\n\t\t\tpage.events.length,\n\t\t\tcursor,\n\t\t\twindow.targetVersion,\n\t\t);\n\t\tassertPageWithinLimit(\n\t\t\twindow.stream,\n\t\t\tpage.events.length,\n\t\t\twindow.limit,\n\t\t\tcursor,\n\t\t\twindow.targetVersion,\n\t\t);\n\t\tyield page.events;\n\t\tcursor += page.events.length;\n\t}\n}\n\nfunction throwIfAborted(signal: AbortSignal | undefined): void {\n\tif (signal?.aborted) throw abortReason(signal, \"readStreamPages aborted\");\n}\n"],"mappings":"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"}