@shirudo/ddd-kit 3.0.0-rc.4 → 3.0.0-rc.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -20
- package/dist/chunks/{errors.d.ts → kit-errors.d.ts} +272 -48
- package/dist/chunks/{errors.js → kit-errors.js} +275 -57
- package/dist/chunks/kit-errors.js.map +1 -0
- package/dist/chunks/ports.js +829 -95
- package/dist/chunks/ports.js.map +1 -1
- package/dist/chunks/snapshot-store.d.ts +925 -1338
- package/dist/http.d.ts +2 -3
- package/dist/http.js +1 -1
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +3431 -2435
- package/dist/index.js +6226 -5488
- package/dist/index.js.map +1 -1
- package/dist/money.d.ts +11 -11
- package/dist/money.js +9 -9
- package/dist/money.js.map +1 -1
- package/dist/{presentation.d.ts → public-errors.d.ts} +5 -6
- package/dist/{presentation.js → public-errors.js} +5 -5
- package/dist/public-errors.js.map +1 -0
- package/dist/testing.d.ts +61 -11
- package/dist/testing.js +526 -56
- package/dist/testing.js.map +1 -1
- package/package.json +17 -17
- package/dist/chunks/deep-equal-except.js +0 -639
- package/dist/chunks/deep-equal-except.js.map +0 -1
- package/dist/chunks/errors.js.map +0 -1
- package/dist/chunks/utils.d.ts +0 -110
- package/dist/presentation.js.map +0 -1
- package/dist/utils.d.ts +0 -2
- package/dist/utils.js +0 -3
package/README.md
CHANGED
|
@@ -23,22 +23,6 @@ clear boundaries around persistence and side effects.
|
|
|
23
23
|

|
|
24
24
|

|
|
25
25
|
|
|
26
|
-
## When This Helps
|
|
27
|
-
|
|
28
|
-
Use this kit when your TypeScript code has domain rules that deserve more than
|
|
29
|
-
DTOs and service functions:
|
|
30
|
-
|
|
31
|
-
- an order can only be confirmed once
|
|
32
|
-
- a booking must stay inside an allowed date range
|
|
33
|
-
- money must never lose precision at a JSON boundary
|
|
34
|
-
- optimistic concurrency conflicts must be handled deliberately
|
|
35
|
-
- domain events must be persisted and dispatched reliably
|
|
36
|
-
- repository adapters must prove they enforce the same contract
|
|
37
|
-
|
|
38
|
-
The library is intentionally boring at the edges. It does not ship an ORM, a
|
|
39
|
-
message broker, decorators, a dependency-injection container, or a web
|
|
40
|
-
framework. Those choices belong to the application.
|
|
41
|
-
|
|
42
26
|
## Installation
|
|
43
27
|
|
|
44
28
|
```bash
|
|
@@ -55,7 +39,7 @@ Cloudflare Workers, Vercel Edge, Deno, and Bun.
|
|
|
55
39
|
|
|
56
40
|
```ts
|
|
57
41
|
import {
|
|
58
|
-
|
|
42
|
+
StateStoredAggregate,
|
|
59
43
|
DomainError,
|
|
60
44
|
type DomainEvent,
|
|
61
45
|
type Id,
|
|
@@ -85,7 +69,7 @@ class OrderAlreadyConfirmedError extends DomainError<
|
|
|
85
69
|
}
|
|
86
70
|
}
|
|
87
71
|
|
|
88
|
-
class Order extends
|
|
72
|
+
class Order extends StateStoredAggregate<OrderState, OrderId, OrderEvent> {
|
|
89
73
|
protected readonly aggregateType = "Order";
|
|
90
74
|
|
|
91
75
|
private constructor(id: OrderId, state: OrderState) {
|
|
@@ -105,7 +89,7 @@ class Order extends AggregateRoot<OrderState, OrderId, OrderEvent> {
|
|
|
105
89
|
throw new OrderAlreadyConfirmedError(this.id);
|
|
106
90
|
}
|
|
107
91
|
|
|
108
|
-
this.
|
|
92
|
+
this.setState(
|
|
109
93
|
{ status: "confirmed" },
|
|
110
94
|
this.createEvent("OrderConfirmed", { orderId: this.id }),
|
|
111
95
|
);
|
|
@@ -125,7 +109,7 @@ That example is deliberately small, but it shows the core shape:
|
|
|
125
109
|
|
|
126
110
|
- The aggregate owns the rule.
|
|
127
111
|
- The domain throws an error when an invariant is broken.
|
|
128
|
-
- `
|
|
112
|
+
- `setState(...)` changes the state and records the event together.
|
|
129
113
|
- `createEvent(...)` captures the immutable domain decision and aggregate source.
|
|
130
114
|
- The application shell adds event identity, recording time, and trace metadata.
|
|
131
115
|
- Persistence stays outside the aggregate.
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { StructuredError } from "@shirudo/base-error";
|
|
2
|
-
|
|
3
|
-
//#region src/core/errors.d.ts
|
|
2
|
+
//#region src/errors/kit-errors.d.ts
|
|
4
3
|
/**
|
|
5
4
|
* **The kit's error identity model (since v3).** Every kit error is a
|
|
6
5
|
* structured error carrying exactly ONE identifier: `code`, a stable
|
|
@@ -89,7 +88,7 @@ declare abstract class KitWiringError<TCode extends string> extends StructuredEr
|
|
|
89
88
|
* Library-internal concrete subclasses: {@link AggregateNotFoundError},
|
|
90
89
|
* {@link ConcurrencyConflictError}, {@link DuplicateAggregateError},
|
|
91
90
|
* plus the unit-of-work lifecycle wrappers `CommitError` and
|
|
92
|
-
* `RollbackError` (in `src/
|
|
91
|
+
* `RollbackError` (in `src/application/unit-of-work/errors.ts`).
|
|
93
92
|
*/
|
|
94
93
|
declare abstract class InfrastructureError<TCode extends string = string> extends StructuredError<TCode, "INFRASTRUCTURE"> {
|
|
95
94
|
protected constructor(options: KitErrorOptions<TCode>);
|
|
@@ -136,18 +135,15 @@ declare class InMemoryCapacityExceededError extends InfrastructureError<"IN_MEMO
|
|
|
136
135
|
constructor(options: InMemoryCapacityExceededErrorOptions);
|
|
137
136
|
}
|
|
138
137
|
/**
|
|
139
|
-
* Thrown when
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
* a domain or infrastructure failure.
|
|
138
|
+
* Thrown when a projection built with `projectionFromHandlers` receives an
|
|
139
|
+
* event type with no own handler entry: the declared event union and the
|
|
140
|
+
* handler map disagree at runtime, which is a programming / configuration
|
|
141
|
+
* bug rather than a domain or infrastructure failure.
|
|
144
142
|
*
|
|
145
143
|
* Deliberately **not** on `DomainError` or `InfrastructureError`:
|
|
146
144
|
* a generic `catch (e instanceof DomainError)` handler at the App
|
|
147
145
|
* layer must not mask a forgotten handler; this should crash loud and
|
|
148
|
-
* fail the calling Use Case so the bug surfaces in development.
|
|
149
|
-
* replay through `loadFromHistory` also lets it propagate uncaught instead
|
|
150
|
-
* of wrapping it in `Result.Err`.
|
|
146
|
+
* fail the calling Use Case so the bug surfaces in development.
|
|
151
147
|
*
|
|
152
148
|
* Use `isBaseError(e)` from `@shirudo/base-error` to detect
|
|
153
149
|
* "any structured error from the kit or any other BaseError-using
|
|
@@ -157,6 +153,43 @@ declare class MissingHandlerError extends KitWiringError<"MISSING_HANDLER"> {
|
|
|
157
153
|
readonly eventType: string;
|
|
158
154
|
constructor(eventType: string, cause?: unknown);
|
|
159
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* Thrown by an event-sourced aggregate when `apply()` or replay reaches an
|
|
158
|
+
* event type with no own entry in the `folds` map: the declared event union
|
|
159
|
+
* and the map disagree at runtime. Same posture as
|
|
160
|
+
* {@link MissingHandlerError}: a deterministic bug, never a domain
|
|
161
|
+
* rejection, so it propagates through `replayHistory` instead of riding its
|
|
162
|
+
* `Result`.
|
|
163
|
+
*/
|
|
164
|
+
declare class MissingFoldError extends KitWiringError<"MISSING_FOLD"> {
|
|
165
|
+
readonly eventType: string;
|
|
166
|
+
constructor(eventType: string, cause?: unknown);
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Thrown by an event-sourced aggregate when a fold returns `undefined`
|
|
170
|
+
* for an event, which is almost always a fold without a `return` statement.
|
|
171
|
+
* Storing that result would set the aggregate state to `undefined`, record
|
|
172
|
+
* the fact anyway on the apply path, and leave every later fold working on
|
|
173
|
+
* nothing. Same posture as {@link MissingFoldError}: a deterministic bug
|
|
174
|
+
* in the folds map, never a domain rejection, so it propagates through
|
|
175
|
+
* `replayHistory` instead of riding its `Result`.
|
|
176
|
+
*/
|
|
177
|
+
declare class FoldReturnedNoStateError extends KitWiringError<"FOLD_RETURNED_NO_STATE"> {
|
|
178
|
+
readonly eventType: string;
|
|
179
|
+
constructor(eventType: string);
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Thrown by `EventSourcedAggregate.setState`: on an event-sourced aggregate
|
|
183
|
+
* the state changes only through `apply()`, where the fact is recorded and
|
|
184
|
+
* the version advances with it. A direct state write would leave the
|
|
185
|
+
* instance ahead of its stream with nothing to replay. A wiring error: a
|
|
186
|
+
* deterministic bug in the aggregate's own code, the remedy is an event
|
|
187
|
+
* and a handler.
|
|
188
|
+
*/
|
|
189
|
+
declare class DirectStateMutationError extends KitWiringError<"DIRECT_STATE_MUTATION"> {
|
|
190
|
+
readonly aggregateId: string;
|
|
191
|
+
constructor(aggregateId: string);
|
|
192
|
+
}
|
|
160
193
|
/**
|
|
161
194
|
* Thrown by `Projector.project` when an event cannot be projected
|
|
162
195
|
* safely because its cursor is missing or malformed, or its aggregate
|
|
@@ -246,16 +279,19 @@ declare class InvalidCommandMessageError extends InfrastructureError<"INVALID_CO
|
|
|
246
279
|
constructor(path: string, reason: string, cause?: unknown);
|
|
247
280
|
}
|
|
248
281
|
/**
|
|
249
|
-
* Thrown by `Entity` (constructor and `setState`)
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
* `
|
|
282
|
+
* Thrown by `Entity` (constructor and `setState`), by the event-sourced
|
|
283
|
+
* fold (`apply` and replay), by the event constructors for the payload,
|
|
284
|
+
* and by the event metadata helpers (`createDomainEvent`'s
|
|
285
|
+
* `options.metadata`, `mergeMetadata`, `copyMetadata`) when the value
|
|
286
|
+
* carries an own `"__proto__"` data key:
|
|
253
287
|
* the shape `JSON.parse` produces for hostile DB rows or request bodies
|
|
254
288
|
* handed to reconstitute factories. Such a key can never be legitimate
|
|
255
289
|
* domain state; accepting it would hand a prototype-pollution payload to
|
|
256
290
|
* every downstream consumer that copies the state through `[[Set]]`
|
|
257
291
|
* (`Object.assign`, for-in assignment loops), and dropping it would be
|
|
258
|
-
* silent data mutation.
|
|
292
|
+
* silent data mutation. The check looks at the root object only; nested
|
|
293
|
+
* objects are not walked, and a class instance is an ownership transfer
|
|
294
|
+
* that passes.
|
|
259
295
|
*
|
|
260
296
|
* Deliberately **not** a `DomainError` or `InfrastructureError` (same
|
|
261
297
|
* posture as {@link MissingHandlerError}): untrusted input reaching the
|
|
@@ -269,7 +305,37 @@ declare class HostileStateKeyError extends KitWiringError<"HOSTILE_STATE_KEY"> {
|
|
|
269
305
|
constructor(key: string, subject?: string);
|
|
270
306
|
}
|
|
271
307
|
/**
|
|
272
|
-
* Thrown by `
|
|
308
|
+
* Thrown by the `Entity` constructor when the id is not a non-blank
|
|
309
|
+
* string. That covers `null`, `undefined`, a blank string, and a
|
|
310
|
+
* non-string value that reached the constructor through a cast. An
|
|
311
|
+
* entity without a usable identity cannot be tracked, compared, or
|
|
312
|
+
* persisted, so the construction fails before any state is stored. A
|
|
313
|
+
* wiring error: a deterministic bug at the call site, never a domain
|
|
314
|
+
* rejection.
|
|
315
|
+
*/
|
|
316
|
+
declare class MissingEntityIdError extends KitWiringError<"MISSING_ENTITY_ID"> {
|
|
317
|
+
constructor(
|
|
318
|
+
/** The rejected value, for the message only; never a usable id. */
|
|
319
|
+
received: unknown);
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Thrown when a number that is not a valid aggregate version reaches the
|
|
323
|
+
* kit: `toVersion`, `markReconstituted`, `setVersion`, and the post-commit
|
|
324
|
+
* acknowledgement all reject it. A version is a safe integer of at least
|
|
325
|
+
* zero, and a restore never moves below the current version. A wiring
|
|
326
|
+
* error: an adapter passed a corrupt row value or a wrong number, and
|
|
327
|
+
* the optimistic-concurrency cursor must not carry it. Not retryable.
|
|
328
|
+
*/
|
|
329
|
+
declare class InvalidVersionError extends KitWiringError<"INVALID_VERSION"> {
|
|
330
|
+
readonly value: unknown;
|
|
331
|
+
/** Why the value was rejected, for example "is not a safe integer". */
|
|
332
|
+
readonly reason: string;
|
|
333
|
+
constructor(value: unknown,
|
|
334
|
+
/** Why the value was rejected, for example "is not a safe integer". */
|
|
335
|
+
reason: string);
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Thrown by `EventSourcedAggregate.replayHistory` when the replay target
|
|
273
339
|
* carries unflushed `pendingEvents`. Replaying persisted facts onto that
|
|
274
340
|
* instance would advance the version underneath decisions made against an
|
|
275
341
|
* older state and could later claim history the stream does not carry.
|
|
@@ -291,6 +357,23 @@ declare class UnreplayableAggregateError extends KitWiringError<"UNREPLAYABLE_AG
|
|
|
291
357
|
readonly aggregateId: string;
|
|
292
358
|
constructor(aggregateId: string, reason: string);
|
|
293
359
|
}
|
|
360
|
+
/**
|
|
361
|
+
* Constructor options for {@link MisaddressedEventError} and
|
|
362
|
+
* {@link ForeignEventError}: the address of the aggregate that received the
|
|
363
|
+
* event, and the address fields the event carries. A missing field on the
|
|
364
|
+
* event matches by default, so `actual` names only what the event states.
|
|
365
|
+
*/
|
|
366
|
+
interface AggregateAddressMismatchOptions {
|
|
367
|
+
readonly expected: {
|
|
368
|
+
readonly aggregateType: string;
|
|
369
|
+
readonly aggregateId: string;
|
|
370
|
+
};
|
|
371
|
+
readonly actual: {
|
|
372
|
+
readonly aggregateType?: string;
|
|
373
|
+
readonly aggregateId?: string;
|
|
374
|
+
};
|
|
375
|
+
readonly eventType: string;
|
|
376
|
+
}
|
|
294
377
|
/**
|
|
295
378
|
* Thrown by `EventSourcedAggregate.apply()` when a NEW event carries an
|
|
296
379
|
* `aggregateId` or `aggregateType` naming a different aggregate: a
|
|
@@ -304,12 +387,36 @@ declare class UnreplayableAggregateError extends KitWiringError<"UNREPLAYABLE_AG
|
|
|
304
387
|
* infrastructure, and handlers for one must not absorb the other.
|
|
305
388
|
*/
|
|
306
389
|
declare class MisaddressedEventError extends KitWiringError<"MISADDRESSED_EVENT"> {
|
|
307
|
-
|
|
308
|
-
readonly
|
|
390
|
+
/** Address of the aggregate that received the event. */
|
|
391
|
+
readonly expected: AggregateAddressMismatchOptions["expected"];
|
|
392
|
+
/** Address fields the event carries. */
|
|
393
|
+
readonly actual: AggregateAddressMismatchOptions["actual"];
|
|
309
394
|
readonly eventType: string;
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
395
|
+
constructor(options: AggregateAddressMismatchOptions);
|
|
396
|
+
}
|
|
397
|
+
/** Constructor options for {@link SnapshotVersionNotRestoredError}. */
|
|
398
|
+
interface SnapshotVersionNotRestoredErrorOptions {
|
|
399
|
+
readonly aggregateType: string;
|
|
400
|
+
readonly aggregateId: string;
|
|
401
|
+
/** The version the snapshot carries. */
|
|
402
|
+
readonly snapshotVersion: number;
|
|
403
|
+
/** The version the factory's aggregate reports. */
|
|
404
|
+
readonly restoredVersion: number;
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Thrown by `reconstituteAggregateFromSnapshot` when the `reconstitute`
|
|
408
|
+
* factory returns an aggregate at a version other than the snapshot
|
|
409
|
+
* version. The factory ignored the version parameter, usually a forgotten
|
|
410
|
+
* `markReconstituted(version)`. A wiring error in the snapshot model,
|
|
411
|
+
* never snapshot corruption: routing it into the discard-and-refold
|
|
412
|
+
* channel would mask it as perpetual silent refolding.
|
|
413
|
+
*/
|
|
414
|
+
declare class SnapshotVersionNotRestoredError extends KitWiringError<"SNAPSHOT_VERSION_NOT_RESTORED"> {
|
|
415
|
+
readonly aggregateType: string;
|
|
416
|
+
readonly aggregateId: string;
|
|
417
|
+
readonly snapshotVersion: number;
|
|
418
|
+
readonly restoredVersion: number;
|
|
419
|
+
constructor(options: SnapshotVersionNotRestoredErrorOptions);
|
|
313
420
|
}
|
|
314
421
|
/**
|
|
315
422
|
* The structural-integrity rejection for a stored snapshot. A consumer's
|
|
@@ -326,17 +433,20 @@ declare class SnapshotCorruptedError extends InfrastructureError<"SNAPSHOT_CORRU
|
|
|
326
433
|
}
|
|
327
434
|
/**
|
|
328
435
|
* Thrown when an event reaches the aggregate's recording paths
|
|
329
|
-
* (`apply`, `
|
|
436
|
+
* (`apply`, `setState`, `addDomainEvent`) without having been minted by
|
|
330
437
|
* the kit's constructors: `createDomainEvent`,
|
|
331
|
-
* `createDomainEventFromFacts`, `createUncommittedDomainEvent`, or
|
|
332
|
-
*
|
|
333
|
-
*
|
|
334
|
-
*
|
|
335
|
-
*
|
|
336
|
-
*
|
|
337
|
-
*
|
|
338
|
-
*
|
|
339
|
-
*
|
|
438
|
+
* `createDomainEventFromFacts`, `createUncommittedDomainEvent`, or the
|
|
439
|
+
* aggregate `createEvent` helper. Those constructors deep-freeze the
|
|
440
|
+
* event, defensively copy payload and metadata, and mark the result as
|
|
441
|
+
* minted. The mark has two tiers: a
|
|
442
|
+
* module-private one for events of this loaded copy of the kit, and a
|
|
443
|
+
* cooperative `Symbol.for` brand that a second loaded copy stamps and
|
|
444
|
+
* recognizes. Anything else (a hand-rolled literal, a shallow-frozen
|
|
445
|
+
* copy with mutable nested data) is rejected: a mutable event recorded
|
|
446
|
+
* next to a state change can silently diverge from it afterwards. A
|
|
447
|
+
* wiring error: deterministic bug at the call site, the remedy is
|
|
448
|
+
* minting through the constructors. The gate catches accidents, not
|
|
449
|
+
* adversaries: code in the same process can fake the brand.
|
|
340
450
|
*/
|
|
341
451
|
declare class UnmintedEventError extends KitWiringError<"UNMINTED_EVENT"> {
|
|
342
452
|
constructor(eventType: string);
|
|
@@ -355,20 +465,68 @@ declare class ReentrantEventRecordingError extends KitWiringError<"REENTRANT_EVE
|
|
|
355
465
|
constructor(aggregateId: string);
|
|
356
466
|
}
|
|
357
467
|
/**
|
|
358
|
-
* Thrown
|
|
359
|
-
*
|
|
360
|
-
*
|
|
468
|
+
* Thrown when two facts of one aggregate would carry the same `eventId`.
|
|
469
|
+
* Two causes, two sites: the aggregate rejects a recorded event that is
|
|
470
|
+
* already pending at the append, before the state moves; and
|
|
471
|
+
* `recordPendingEvents` rejects a stamp provider that returns one reused
|
|
472
|
+
* stamp (or repeats an explicit id). Either would mint two distinct facts
|
|
361
473
|
* sharing one identity, and downstream idempotent consumers keyed on
|
|
362
|
-
* `eventId` silently drop one of them. A wiring error: deterministic bug
|
|
363
|
-
* the stamp provider, the remedy is one fresh
|
|
474
|
+
* `eventId` silently drop one of them. A wiring error: deterministic bug at
|
|
475
|
+
* the append site or in the stamp provider, the remedy is one fresh
|
|
476
|
+
* identity per fact.
|
|
364
477
|
*/
|
|
365
478
|
declare class DuplicateEventIdError extends KitWiringError<"DUPLICATE_EVENT_ID"> {
|
|
366
479
|
/** The identity two pending events would have shared. */
|
|
367
480
|
readonly eventId: string;
|
|
368
|
-
constructor(aggregateId: string,
|
|
481
|
+
constructor(aggregateId: string,
|
|
482
|
+
/** The identity two pending events would have shared. */
|
|
483
|
+
eventId: string);
|
|
484
|
+
}
|
|
485
|
+
/** Constructor options for {@link PendingEventLimitExceededError}. */
|
|
486
|
+
interface PendingEventLimitExceededErrorOptions {
|
|
487
|
+
readonly aggregateType: string;
|
|
488
|
+
readonly aggregateId: string;
|
|
489
|
+
/** The configured `maxPendingEvents`. */
|
|
490
|
+
readonly limit: number;
|
|
491
|
+
/** Events pending before the rejected recording. */
|
|
492
|
+
readonly pending: number;
|
|
493
|
+
/** Events the rejected recording would have added. */
|
|
494
|
+
readonly added: number;
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Thrown when a recording would grow the pending list of an aggregate past
|
|
498
|
+
* `AggregateConfig.maxPendingEvents`. The check runs before the state
|
|
499
|
+
* moves, so the rejected decision records nothing and moves nothing. The
|
|
500
|
+
* limit is a modelling signal, not a runtime budget: a decision that emits
|
|
501
|
+
* hundreds of facts points at a missing aggregate boundary, and a retry
|
|
502
|
+
* repeats it. A wiring error: split the aggregate, or emit fewer facts
|
|
503
|
+
* per decision.
|
|
504
|
+
*/
|
|
505
|
+
declare class PendingEventLimitExceededError extends KitWiringError<"PENDING_EVENT_LIMIT_EXCEEDED"> {
|
|
506
|
+
readonly aggregateType: string;
|
|
507
|
+
readonly aggregateId: string;
|
|
508
|
+
readonly limit: number;
|
|
509
|
+
readonly pending: number;
|
|
510
|
+
readonly added: number;
|
|
511
|
+
constructor(options: PendingEventLimitExceededErrorOptions);
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Thrown by the post-commit acknowledgement of an aggregate when the
|
|
515
|
+
* committed batch is not the prefix of its pending events any more. The
|
|
516
|
+
* batch is longer than the pending list, or an event in it is not the
|
|
517
|
+
* pending event at the same position. Acknowledging such a batch would
|
|
518
|
+
* drop decisions the commit never persisted or keep events it did. The
|
|
519
|
+
* pending list stays untouched. A wiring error in application commit
|
|
520
|
+
* orchestration: acknowledge exactly the batch that was enrolled, once.
|
|
521
|
+
*/
|
|
522
|
+
declare class PendingEventBatchMismatchError extends KitWiringError<"PENDING_EVENT_BATCH_MISMATCH"> {
|
|
523
|
+
readonly aggregateId: string;
|
|
524
|
+
readonly batchLength: number;
|
|
525
|
+
readonly pendingLength: number;
|
|
526
|
+
constructor(aggregateId: string, batchLength: number, pendingLength: number);
|
|
369
527
|
}
|
|
370
528
|
/**
|
|
371
|
-
* Thrown by persisted-event consumers (including `
|
|
529
|
+
* Thrown by persisted-event consumers (including `replayHistory` and
|
|
372
530
|
* `Projector`) when an event carries an
|
|
373
531
|
* `aggregateId` or `aggregateType` that names a different aggregate:
|
|
374
532
|
* the persisted row belongs to someone else (a miswired stream read,
|
|
@@ -385,12 +543,12 @@ declare class DuplicateEventIdError extends KitWiringError<"DUPLICATE_EVENT_ID">
|
|
|
385
543
|
* {@link MisaddressedEventError}.
|
|
386
544
|
*/
|
|
387
545
|
declare class ForeignEventError extends InfrastructureError<"FOREIGN_EVENT"> {
|
|
388
|
-
|
|
389
|
-
readonly
|
|
546
|
+
/** Address of the aggregate that received the event. */
|
|
547
|
+
readonly expected: AggregateAddressMismatchOptions["expected"];
|
|
548
|
+
/** Address fields the event carries. */
|
|
549
|
+
readonly actual: AggregateAddressMismatchOptions["actual"];
|
|
390
550
|
readonly eventType: string;
|
|
391
|
-
|
|
392
|
-
readonly actualAggregateType?: string | undefined;
|
|
393
|
-
constructor(expectedAggregateId: string, expectedAggregateType: string, eventType: string, actualAggregateId?: string | undefined, actualAggregateType?: string | undefined);
|
|
551
|
+
constructor(options: AggregateAddressMismatchOptions);
|
|
394
552
|
}
|
|
395
553
|
/** Constructor options for {@link NonProgressingEventStreamPageError}. */
|
|
396
554
|
interface NonProgressingEventStreamPageErrorOptions {
|
|
@@ -419,6 +577,35 @@ declare class NonProgressingEventStreamPageError extends InfrastructureError<"NO
|
|
|
419
577
|
readonly targetVersion: number;
|
|
420
578
|
constructor(options: NonProgressingEventStreamPageErrorOptions);
|
|
421
579
|
}
|
|
580
|
+
/** Constructor options for {@link ReplayHeadMismatchError}. */
|
|
581
|
+
interface ReplayHeadMismatchErrorOptions {
|
|
582
|
+
readonly aggregateType: string;
|
|
583
|
+
readonly aggregateId: string;
|
|
584
|
+
/** Pinned inclusive stream head the replay had to reach. */
|
|
585
|
+
readonly targetVersion: number;
|
|
586
|
+
/** Version the aggregate holds after the replay. */
|
|
587
|
+
readonly actualVersion: number;
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Thrown by a load recipe when the replayed aggregate does not end at the
|
|
591
|
+
* pinned stream head. Events carry no stream position, so the aggregate
|
|
592
|
+
* cannot detect a tail that overlaps the restored version or a page that
|
|
593
|
+
* lies outside the requested window; only the caller, which pinned the
|
|
594
|
+
* head, can compare. A snapshot catch-up passes only the events after the
|
|
595
|
+
* restored version, and the final version must equal the head.
|
|
596
|
+
*
|
|
597
|
+
* This is a non-retryable infrastructure error: the persistence adapter
|
|
598
|
+
* contradicted its port contract. Run `createEventStoreContractTests` and
|
|
599
|
+
* `createEsRepositoryContractTests` against the adapter and fix its
|
|
600
|
+
* windowing.
|
|
601
|
+
*/
|
|
602
|
+
declare class ReplayHeadMismatchError extends InfrastructureError<"REPLAY_HEAD_MISMATCH"> {
|
|
603
|
+
readonly aggregateType: string;
|
|
604
|
+
readonly aggregateId: string;
|
|
605
|
+
readonly targetVersion: number;
|
|
606
|
+
readonly actualVersion: number;
|
|
607
|
+
constructor(options: ReplayHeadMismatchErrorOptions);
|
|
608
|
+
}
|
|
422
609
|
/**
|
|
423
610
|
* Thrown when an event harvested from an aggregate cannot be safely composed
|
|
424
611
|
* into a commit envelope, or when an outbox can prove that accepting a
|
|
@@ -441,7 +628,44 @@ declare class NonProgressingEventStreamPageError extends InfrastructureError<"NO
|
|
|
441
628
|
declare class EventHarvestError extends KitWiringError<"EVENT_HARVEST_FAILED"> {
|
|
442
629
|
/** The `type` of the offending event, for programmatic routing. */
|
|
443
630
|
readonly eventType?: string | undefined;
|
|
444
|
-
constructor(message: string,
|
|
631
|
+
constructor(message: string,
|
|
632
|
+
/** The `type` of the offending event, for programmatic routing. */
|
|
633
|
+
eventType?: string | undefined);
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* Thrown at bootstrap when the global key of a kit capability registry
|
|
637
|
+
* already holds a value that is not a registry: another module claimed
|
|
638
|
+
* the key. The kit neither shares that value nor overwrites it, because a
|
|
639
|
+
* silent replacement would break whichever module owned the key first. A
|
|
640
|
+
* wiring error in the host process; the remedy is one owner per key.
|
|
641
|
+
*/
|
|
642
|
+
declare class CapabilityRegistryConflictError extends KitWiringError<"CAPABILITY_REGISTRY_CONFLICT"> {
|
|
643
|
+
readonly key: symbol;
|
|
644
|
+
constructor(key: symbol);
|
|
645
|
+
}
|
|
646
|
+
/**
|
|
647
|
+
* Thrown when a kit operation receives an instance that this package did
|
|
648
|
+
* not construct: a structural lookalike, a repository DTO, or an instance
|
|
649
|
+
* from an incompatible copy of the package. Such an instance carries none
|
|
650
|
+
* of the kit-managed capabilities the operation needs. A wiring error:
|
|
651
|
+
* extend the kit's base classes and run one compatible package copy.
|
|
652
|
+
*/
|
|
653
|
+
declare class UnmanagedInstanceError extends KitWiringError<"UNMANAGED_INSTANCE"> {
|
|
654
|
+
/** The kit operation that rejected the instance. */
|
|
655
|
+
readonly operation: string;
|
|
656
|
+
/** What was rejected: "aggregate", "entity", "the persistence baseline". */
|
|
657
|
+
readonly subject: string;
|
|
658
|
+
/** The rejected instance's id, when it has one. */
|
|
659
|
+
readonly instanceId?: unknown | undefined;
|
|
660
|
+
constructor(
|
|
661
|
+
/** The kit operation that rejected the instance. */
|
|
662
|
+
operation: string,
|
|
663
|
+
/** What was rejected: "aggregate", "entity", "the persistence baseline". */
|
|
664
|
+
subject: string,
|
|
665
|
+
/** The rejected instance's id, when it has one. */
|
|
666
|
+
instanceId?: unknown | undefined,
|
|
667
|
+
/** One extra sentence about the registry state, when it explains the rejection. */
|
|
668
|
+
detail?: string);
|
|
445
669
|
}
|
|
446
670
|
/** Constructor options for {@link UnregisteredHandlerError}. */
|
|
447
671
|
interface UnregisteredHandlerErrorOptions {
|
|
@@ -779,7 +1003,7 @@ declare class IdempotencyCompletionWithoutClaimError extends KitWiringError<"IDE
|
|
|
779
1003
|
* base-error `matchError` cases that cover kit and consumer codes
|
|
780
1004
|
* together, without importing anything from base-error.
|
|
781
1005
|
*/
|
|
782
|
-
type KitErrorCode = "AGGREGATE_DELETED" | "AGGREGATE_NOT_FOUND" | "AGGREGATE_TRACKING" | "COMMIT_FAILED" | "CONCURRENCY_CONFLICT" | "DOMAIN_TRANSITION_GUARD_REJECTED" | "DUPLICATE_AGGREGATE" | "DUPLICATE_EVENT_ID" | "DUPLICATE_HANDLER_REGISTRATION" | "ERROR_MAPPER_FAILED" | "EVENT_ADDRESS_INVALID" | "EVENT_HARVEST_FAILED" | "EVENT_ID_INVALID" | "EVENT_ID_REQUIRED" | "EVENT_OCCURRED_AT_INVALID" | "EVENT_OCCURRED_AT_REQUIRED" | "EVENT_SCHEMA_VERSION_INVALID" | "EVENT_TYPE_INVALID" | "FOREIGN_EVENT" | "HOSTILE_STATE_KEY" | "IDEMPOTENCY_CLAIM_LOST" | "IDEMPOTENCY_COMPLETED_WITHOUT_CLAIM" | "IDEMPOTENCY_IN_FLIGHT" | "IDEMPOTENCY_KEY_REUSE" | "IDEMPOTENCY_RECONCILIATION_REQUIRED" | "IN_MEMORY_CAPACITY_EXCEEDED" | "INVALID_DOMAIN_MACHINE_CONTEXT" | "INVALID_DOMAIN_MACHINE_DEFINITION" | "INVALID_DOMAIN_MACHINE_INPUT" | "INVALID_DOMAIN_MACHINE_SNAPSHOT" | "INVALID_DOMAIN_TRANSITION" | "INVALID_DOMAIN_TRANSITION_GUARD_RESULT" | "INVALID_DOMAIN_TRANSITION_RESULT" | "INVALID_COMMAND_MESSAGE" | "INVALID_INTEGRATION_MESSAGE" | "INVALID_MONEY" | "INVALID_REPOSITORY_ADAPTER" | "INVALID_REPOSITORY_DEFINITION" | "MISADDRESSED_EVENT" | "MISSING_HANDLER" | "MONEY_CURRENCY_MISMATCH" | "MONEY_PRECISION_LOSS" | "MONEY_SCALE_MISMATCH" | "NESTED_UNIT_OF_WORK" | "NON_PROGRESSING_EVENT_STREAM_PAGE" | "PROJECTION_GAP" | "PROJECTION_IDENTITY_VIOLATION" | "PROJECTION_ORDER_VIOLATION" | "PROJECTION_RECEIPT_VIOLATION" | "REENTRANT_DOMAIN_STATE_MACHINE_EVALUATION" | "REENTRANT_EVENT_RECORDING" | "REPOSITORY_ERROR_MAPPING_FAILED" | "ROLLBACK_FAILED" | "SNAPSHOT_CORRUPTED" | "SNAPSHOT_SCHEMA_MISMATCH" | "SNAPSHOT_TIME_INVALID" | "TRANSACTION_CLOSED" | "UNENROLLED_CHANGES" | "UNKNOWN_CURRENCY" | "UNMINTED_EVENT" | "UNPROJECTABLE_EVENT" | "UNREGISTERED_HANDLER" | "UNREPLAYABLE_AGGREGATE";
|
|
1006
|
+
type KitErrorCode = "AGGREGATE_DELETED" | "AGGREGATE_NOT_FOUND" | "AGGREGATE_TRACKING" | "CAPABILITY_REGISTRY_CONFLICT" | "COMMIT_FAILED" | "CONCURRENCY_CONFLICT" | "DIRECT_STATE_MUTATION" | "DOMAIN_TRANSITION_GUARD_REJECTED" | "DUPLICATE_AGGREGATE" | "DUPLICATE_EVENT_ID" | "DUPLICATE_HANDLER_REGISTRATION" | "ERROR_MAPPER_FAILED" | "EVENT_ADDRESS_INVALID" | "EVENT_BUS_CLOSED" | "EVENT_HARVEST_FAILED" | "EVENT_ID_INVALID" | "EVENT_ID_REQUIRED" | "EVENT_OCCURRED_AT_INVALID" | "EVENT_OCCURRED_AT_REQUIRED" | "EVENT_SCHEMA_VERSION_INVALID" | "EVENT_TYPE_INVALID" | "FOLD_RETURNED_NO_STATE" | "FOREIGN_EVENT" | "HOSTILE_STATE_KEY" | "IDEMPOTENCY_CLAIM_LOST" | "IDEMPOTENCY_COMPLETED_WITHOUT_CLAIM" | "IDEMPOTENCY_IN_FLIGHT" | "IDEMPOTENCY_KEY_REUSE" | "IDEMPOTENCY_RECONCILIATION_REQUIRED" | "IN_MEMORY_CAPACITY_EXCEEDED" | "INVALID_DOMAIN_MACHINE_CONTEXT" | "INVALID_DOMAIN_MACHINE_DEFINITION" | "INVALID_DOMAIN_MACHINE_INPUT" | "INVALID_DOMAIN_MACHINE_SNAPSHOT" | "INVALID_DOMAIN_TRANSITION" | "INVALID_DOMAIN_TRANSITION_GUARD_RESULT" | "INVALID_DOMAIN_TRANSITION_RESULT" | "INVALID_COMMAND_MESSAGE" | "INVALID_INTEGRATION_MESSAGE" | "INVALID_MONEY" | "INVALID_REPOSITORY_ADAPTER" | "INVALID_REPOSITORY_DEFINITION" | "INVALID_VERSION" | "MISADDRESSED_EVENT" | "MISSING_ENTITY_ID" | "MISSING_FOLD" | "MISSING_HANDLER" | "MONEY_CURRENCY_MISMATCH" | "MONEY_PRECISION_LOSS" | "MONEY_SCALE_MISMATCH" | "NESTED_UNIT_OF_WORK" | "NON_PROGRESSING_EVENT_STREAM_PAGE" | "PENDING_EVENT_BATCH_MISMATCH" | "PENDING_EVENT_LIMIT_EXCEEDED" | "PROJECTION_GAP" | "PROJECTION_IDENTITY_VIOLATION" | "PROJECTION_ORDER_VIOLATION" | "PROJECTION_RECEIPT_VIOLATION" | "PUBLISH_DEPTH_EXCEEDED" | "REENTRANT_DOMAIN_STATE_MACHINE_EVALUATION" | "REENTRANT_EVENT_RECORDING" | "REPLAY_HEAD_MISMATCH" | "REPOSITORY_ERROR_MAPPING_FAILED" | "ROLLBACK_FAILED" | "SNAPSHOT_CORRUPTED" | "SNAPSHOT_SCHEMA_MISMATCH" | "SNAPSHOT_TIME_INVALID" | "SNAPSHOT_VERSION_NOT_RESTORED" | "TRANSACTION_CLOSED" | "UNENROLLED_CHANGES" | "UNKNOWN_CURRENCY" | "UNMANAGED_INSTANCE" | "UNMINTED_EVENT" | "UNPROJECTABLE_EVENT" | "UNREGISTERED_HANDLER" | "UNREPLAYABLE_AGGREGATE";
|
|
783
1007
|
//#endregion
|
|
784
|
-
export {
|
|
785
|
-
//# sourceMappingURL=errors.d.ts.map
|
|
1008
|
+
export { ReplayHeadMismatchError as $, InMemoryCapacityExceededError as A, MissingEntityIdError as B, IdempotencyCompletionWithoutClaimError as C, IdempotencyKeyReuseErrorOptions as D, IdempotencyKeyReuseError as E, InvalidVersionError as F, PendingEventBatchMismatchError as G, MissingHandlerError as H, KitErrorCode as I, ProjectionGapError as J, PendingEventLimitExceededError as K, KitErrorOptions as L, InfrastructureError as M, InvalidCommandMessageError as N, IdempotencyReconciliationRequiredError as O, InvalidIntegrationMessageError as P, ReentrantEventRecordingError as Q, KitWiringError as R, IdempotencyClaimLostErrorOptions as S, IdempotencyInFlightErrorOptions as T, NonProgressingEventStreamPageError as U, MissingFoldError as V, NonProgressingEventStreamPageErrorOptions as W, ProjectionOrderViolationError as X, ProjectionIdentityViolationError as Y, ProjectionReceiptViolationError as Z, EventHarvestError as _, CapabilityRegistryConflictError as a, SnapshotVersionNotRestoredErrorOptions as at, HostileStateKeyError as b, DirectStateMutationError as c, UnmintedEventError as ct, DuplicateAggregateErrorOptions as d, UnregisteredHandlerErrorOptions as dt, ReplayHeadMismatchErrorOptions as et, DuplicateEventIdError as f, UnreplayableAggregateError as ft, ErrorMapperFailedErrorOptions as g, ErrorMapperFailedError as h, AggregateNotFoundErrorOptions as i, SnapshotVersionNotRestoredError as it, InMemoryCapacityExceededErrorOptions as j, IdempotencyReconciliationRequiredErrorOptions as k, DomainError as l, UnprojectableEventError as lt, DuplicateHandlerRegistrationErrorOptions as m, isInfrastructureErrorLike as mt, AggregateDeletedError as n, SnapshotSchemaMismatchError as nt, ConcurrencyConflictError as o, UnenrolledChangesError as ot, DuplicateHandlerRegistrationError as p, isDomainErrorLike as pt, PendingEventLimitExceededErrorOptions as q, AggregateNotFoundError as r, SnapshotSchemaMismatchErrorOptions as rt, ConcurrencyConflictErrorOptions as s, UnmanagedInstanceError as st, AggregateAddressMismatchOptions as t, SnapshotCorruptedError as tt, DuplicateAggregateError as u, UnregisteredHandlerError as ut, FoldReturnedNoStateError as v, IdempotencyInFlightError as w, IdempotencyClaimLostError as x, ForeignEventError as y, MisaddressedEventError as z };
|
|
1009
|
+
//# sourceMappingURL=kit-errors.d.ts.map
|