@arts-n-crafts/ts 3.15.0 → 3.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,575 @@
1
+ interface BaseMetadata {
2
+ /** Correlates a flow across services (end-to-end). */
3
+ correlationId?: string;
4
+ /** Points to the immediate cause (often previous message id). */
5
+ causationId?: string;
6
+ /** Trace identifier for distributed tracing. */
7
+ traceId?: string;
8
+ /** Schema version of this event's metadata/payload. */
9
+ schemaVersion?: number;
10
+ /** Tenant identifier for multi-tenant systems. */
11
+ tenantId?: string;
12
+ /** Actor or user responsible for the change. */
13
+ userId?: string;
14
+ /** Marker: domain events originate internally. */
15
+ /**
16
+ * Producer identifier. Prefer your service name, e.g., "orders-service".
17
+ */
18
+ source?: string;
19
+ /** Room for additive extensions. */
20
+ [key: string]: unknown;
21
+ }
22
+
23
+ type WithIdentifier<T = object> = {
24
+ id: string;
25
+ } & T;
26
+
27
+ interface CommandMetadata extends BaseMetadata {
28
+ }
29
+ interface Command<TType = string, TPayload = unknown> extends WithIdentifier {
30
+ /** Unique command id. */
31
+ id: string;
32
+ /** Command type, e.g., "CreateOrder". */
33
+ type: TType;
34
+ /** Target aggregate type (optional; may be inferred). */
35
+ aggregateType?: string;
36
+ /** Target aggregate id (optional for create commands). */
37
+ aggregateId?: string;
38
+ /** Business intent payload. */
39
+ payload: TPayload;
40
+ /** When the command was issued. */
41
+ timestamp: number;
42
+ /** Expected aggregate version for optimistic concurrency. */
43
+ expectedVersion?: number;
44
+ /** Optional metadata. */
45
+ metadata?: Partial<CommandMetadata>;
46
+ /** Discriminator for the message intent. */
47
+ kind: 'command';
48
+ }
49
+
50
+ interface CommandHandler<CommandType extends Command, TReturnType = Promise<void>> {
51
+ execute(aCommand: CommandType): TReturnType;
52
+ }
53
+
54
+ /**
55
+ * Domain events are internal, immutable, state-changing facts appended to the
56
+ * aggregate event stream (event sourcing). They do not leave the bounded
57
+ * context directly; map them to IntegrationEvents when publishing externally.
58
+ */
59
+ interface DomainEventMetadata extends BaseMetadata {
60
+ }
61
+ interface DomainEvent<TPayload = unknown> {
62
+ /** Unique id for this domain event. */
63
+ id: string;
64
+ /** Event type, e.g., "OrderCreated". */
65
+ type: string;
66
+ /** Aggregate type, e.g., "Order". */
67
+ aggregateType: string;
68
+ /** Aggregate id. */
69
+ aggregateId: string;
70
+ /** Event payload (state change details). */
71
+ payload: TPayload;
72
+ /**
73
+ * Event time in epoch milliseconds (internal consistency for ES and sorting).
74
+ * Prefer number internally; convert to ISO for outbound messages.
75
+ */
76
+ timestamp: number;
77
+ /** Optional metadata; keep it small and stable. */
78
+ metadata: Partial<DomainEventMetadata>;
79
+ /** Discriminator for the message intent. */
80
+ kind: 'domain';
81
+ }
82
+
83
+ /**
84
+ * ISO 8601 datetime string, e.g., "2025-12-20T13:59:59.123Z".
85
+ */
86
+ type ISODateTime = string;
87
+
88
+ /**
89
+ * ExternalEvent is a fact emitted by another bounded context or third-party.
90
+ * Your service treats it as an immutable notification and may react to it
91
+ * (e.g., drive a saga or translate it into an internal Command).
92
+ */
93
+ interface ExternalEventMetadata extends BaseMetadata {
94
+ }
95
+ interface ExternalEvent<TPayload = unknown> {
96
+ /** Producer-assigned id (treat as opaque). */
97
+ id: string;
98
+ /** External type, e.g., "PaymentSettled". */
99
+ type: string;
100
+ /** Event payload as produced by the external system. */
101
+ payload: TPayload;
102
+ /** ISO timestamp from the producer. */
103
+ timestamp: ISODateTime;
104
+ /** Optional metadata from the producer. */
105
+ metadata?: Partial<ExternalEventMetadata>;
106
+ /** Discriminator for the message intent. */
107
+ kind: 'external';
108
+ }
109
+
110
+ /**
111
+ * Integration events are the wire contract you publish externally (Kafka, audit,
112
+ * New Relic). The same envelope carries both accepted domain facts and rejected
113
+ * decisions. Keep the schema stable and evolve with schemaVersion.
114
+ */
115
+ interface IntegrationEventMetadata extends BaseMetadata {
116
+ /** Outcome of the decision. */
117
+ outcome?: 'accepted' | 'rejected';
118
+ /** Correlation and routing fields. */
119
+ aggregateType?: string;
120
+ aggregateId?: string;
121
+ commandType?: string;
122
+ commandId?: string;
123
+ expectedVersion?: number;
124
+ currentVersion?: number;
125
+ }
126
+ interface IntegrationEvent<TPayload = unknown> {
127
+ /** Stable id for idempotency. */
128
+ id: string;
129
+ /** Event type, e.g., "OrderCreated" or "CreateOrderRejected". */
130
+ type: string;
131
+ /** Event payload. For rejections include reasonCode and related info. */
132
+ payload: TPayload;
133
+ /** ISO timestamp (external consistency). */
134
+ timestamp: ISODateTime;
135
+ /** Standardized, extensible metadata. */
136
+ metadata: Partial<IntegrationEventMetadata>;
137
+ /** Discriminator for the message intent. */
138
+ kind: 'integration';
139
+ }
140
+
141
+ interface Handling<TEvent extends DomainEvent | IntegrationEvent | ExternalEvent, TReturnType> {
142
+ handle(anEvent: TEvent): TReturnType;
143
+ }
144
+ interface EventHandler<TEvent extends DomainEvent | IntegrationEvent | ExternalEvent, TReturnType = Promise<void>> extends Handling<TEvent, TReturnType> {
145
+ }
146
+
147
+ type Module = Record<symbol, unknown>;
148
+
149
+ interface QueryMetadata extends BaseMetadata {
150
+ }
151
+ interface Query<TType = string, TPayload = unknown> extends WithIdentifier {
152
+ type: TType;
153
+ payload: TPayload;
154
+ timestamp: number;
155
+ metadata: Partial<QueryMetadata>;
156
+ /** Discriminator for the message intent. */
157
+ kind: 'query';
158
+ }
159
+
160
+ interface QueryHandler<TQuery extends Query, TProjection = Promise<unknown>> {
161
+ execute(aQuery: TQuery): TProjection;
162
+ }
163
+
164
+ type FilledArray = [Record<string, unknown>, ...Record<string, unknown>[]];
165
+
166
+ type Maybe<T> = T | null | undefined;
167
+
168
+ type Nullable<T> = {
169
+ [P in keyof T]: T[P] | null;
170
+ };
171
+
172
+ type Primitive = string | number | boolean | bigint | symbol | null | undefined;
173
+
174
+ /**
175
+ * UnixTimestamp in seconds since the Unix epoch.
176
+ * Example: 1734719999 (represents "2025-12-20T13:59:59Z")
177
+ *
178
+ * Usage (JavaScript/TypeScript):
179
+ * ```ts
180
+ * const now: UnixTimestampInSeconds = Math.floor(new Date().getTime() / 1000);
181
+ * ```
182
+ *
183
+ * Notes:
184
+ * - Prefer milliseconds for higher resolution; use seconds when interoperating
185
+ * with systems/APIs that expect second precision.
186
+ */
187
+ type UnixTimestampInSeconds = number;
188
+
189
+ declare function createCommand<TType extends string, TPayload>(type: TType, aggregateId: string, aggregateType: string, payload: TPayload, metadata?: Partial<CommandMetadata>): Command<TType, TPayload>;
190
+
191
+ declare function createQuery<TType extends string, TPayload>(type: TType, payload: TPayload, metadata?: QueryMetadata): Query<TType, TPayload>;
192
+
193
+ declare const getTimestamp: (date?: Date) => number;
194
+
195
+ declare function isCommand(candidate: unknown): candidate is Command<string, unknown>;
196
+
197
+ declare function isQuery(candidate: unknown): candidate is Query<unknown>;
198
+
199
+ interface Identifiable<TId> {
200
+ id: TId;
201
+ }
202
+ interface HasProperties<TProps extends object> {
203
+ props: TProps;
204
+ }
205
+ interface hasOutbox<TEvent extends DomainEvent> {
206
+ uncommittedEvents: TEvent[];
207
+ }
208
+ interface EventBased<TEvent extends DomainEvent> {
209
+ fromEvents(events: TEvent[]): void;
210
+ }
211
+ interface AggregateRoot<TId, TProps extends object, TEvent extends DomainEvent> extends Identifiable<TId>, HasProperties<TProps>, hasOutbox<TEvent> {
212
+ get id(): TId;
213
+ get props(): TProps;
214
+ get uncommittedEvents(): TEvent[];
215
+ }
216
+ interface EventBasedAggregateRoot<TId, TProps extends object, TEvent extends DomainEvent> extends AggregateRoot<TId, TProps, TEvent>, EventBased<TEvent> {
217
+ }
218
+
219
+ /**
220
+ * Rejection models a failed command decision. It is NOT part of the aggregate
221
+ * event stream. Persist via an outbox/inbox if you need durability and emit an
222
+ * IntegrationEvent with outcome="rejected" for external consumers.
223
+ */
224
+ interface RejectionMetadata extends BaseMetadata {
225
+ }
226
+ interface Rejection<TDetails = unknown> {
227
+ /** Unique id; derive from commandId if possible for dedupe. */
228
+ id: string;
229
+ /** Rejection type, format e.g., "{commandType}Rejected", "{commandType}Failed". Example "CreateUserRejected" */
230
+ type: string;
231
+ /** Discriminator for the message intent. */
232
+ kind: 'rejection';
233
+ /** Aggregate type when known (for correlation). */
234
+ aggregateType?: string;
235
+ /** Aggregate id when known (for correlation/partitioning). */
236
+ aggregateId?: string;
237
+ /** The command that was rejected. */
238
+ commandId: string;
239
+ /** The command type, e.g., "CreateOrder". */
240
+ commandType: string;
241
+ /** Short machine-readable code, e.g., "VERSION_CONFLICT", "VALIDATION_FAILED". */
242
+ reasonCode: string | 'VERSION_CONFLICT' | 'VALIDATION_FAILED';
243
+ /** Human-readable summary (avoid PII if externalized). */
244
+ reason?: string;
245
+ /** Classification for routing/metrics. */
246
+ classification?: 'business' | 'validation' | 'concurrency' | 'technical';
247
+ /** Hint to infra/ops whether retry makes sense. */
248
+ retryable?: boolean;
249
+ /** Structured details specific to this rejection. */
250
+ details?: TDetails;
251
+ /**
252
+ * Only for VALIDATION_FAILED: list of field-level errors.
253
+ */
254
+ validationErrors?: Array<{
255
+ field?: string;
256
+ code: string;
257
+ message?: string;
258
+ }>;
259
+ /** ISO timestamp for external consistency. */
260
+ timestamp: number;
261
+ /** Optional metadata (trace/correlation/tenant). */
262
+ metadata?: RejectionMetadata;
263
+ }
264
+
265
+ interface Decider<TState, TCommand, TEvent extends DomainEvent, TRejection extends Rejection> {
266
+ decide(this: void, command: TCommand, currentState: TState): (TEvent | TRejection)[];
267
+ evolve(this: void, currentState: TState, event: TEvent): TState;
268
+ initialState(this: void, id: string): TState;
269
+ }
270
+
271
+ interface Loadable$1<TReturnType> {
272
+ load(aggregateId: string): TReturnType;
273
+ }
274
+ interface Storable<TEvent, TReturnType = Promise<void>> {
275
+ store(events: TEvent[]): TReturnType;
276
+ }
277
+ interface Repository<TEvent, TLoadReturnType, TStoreReturnType = Promise<void>> extends Loadable$1<TLoadReturnType>, Storable<TEvent, TStoreReturnType> {
278
+ readonly streamName: string;
279
+ }
280
+
281
+ type QueryNode = {
282
+ type: 'eq' | 'gt' | 'lt';
283
+ field: string | number | symbol;
284
+ value: Primitive;
285
+ } | {
286
+ type: 'and' | 'or';
287
+ nodes: QueryNode[];
288
+ } | {
289
+ type: 'not';
290
+ node: QueryNode;
291
+ };
292
+
293
+ interface Specification<T> {
294
+ isSatisfiedBy(entity: T): boolean;
295
+ }
296
+ declare abstract class CompositeSpecification<T> implements Specification<T> {
297
+ abstract isSatisfiedBy(entity: T): boolean;
298
+ abstract toQuery(): QueryNode;
299
+ and(other: CompositeSpecification<T>): CompositeSpecification<T>;
300
+ or(other: CompositeSpecification<T>): CompositeSpecification<T>;
301
+ not(): CompositeSpecification<T>;
302
+ }
303
+ declare class AndSpecification<T> extends CompositeSpecification<T> {
304
+ private left;
305
+ private right;
306
+ constructor(left: CompositeSpecification<T>, right: CompositeSpecification<T>);
307
+ isSatisfiedBy(entity: T): boolean;
308
+ toQuery(): QueryNode;
309
+ }
310
+ declare class OrSpecification<T> extends CompositeSpecification<T> {
311
+ private left;
312
+ private right;
313
+ constructor(left: CompositeSpecification<T>, right: CompositeSpecification<T>);
314
+ isSatisfiedBy(entity: T): boolean;
315
+ toQuery(): QueryNode;
316
+ }
317
+ declare class NotSpecification<T> extends CompositeSpecification<T> {
318
+ private spec;
319
+ constructor(spec: CompositeSpecification<T>);
320
+ isSatisfiedBy(entity: T): boolean;
321
+ toQuery(): QueryNode;
322
+ }
323
+
324
+ declare class FieldEquals<T> extends CompositeSpecification<T> {
325
+ private field;
326
+ private value;
327
+ constructor(field: keyof T, value: Primitive);
328
+ isSatisfiedBy(entity: T): boolean;
329
+ toQuery(): QueryNode;
330
+ }
331
+
332
+ declare class FieldGreaterThan<T> extends CompositeSpecification<T> {
333
+ private field;
334
+ private value;
335
+ constructor(field: keyof T, value: number);
336
+ private isNumber;
337
+ isSatisfiedBy(entity: T): boolean;
338
+ toQuery(): QueryNode;
339
+ }
340
+
341
+ declare function createQueryNode(type: 'eq' | 'gt' | 'lt', field: string | number | symbol, value: Primitive): QueryNode;
342
+ declare function createQueryNode(type: 'and' | 'or', field: undefined, value: QueryNode[]): QueryNode;
343
+ declare function createQueryNode(type: 'not', field: undefined, value: QueryNode): QueryNode;
344
+
345
+ declare function createDomainEvent<TPayload = unknown>(type: string, aggregateId: string, aggregateType: string, payload: TPayload, metadata?: Partial<DomainEventMetadata>): DomainEvent<TPayload>;
346
+
347
+ declare function createRejection<TDetails = unknown>(rejectionSpecifics: {
348
+ commandId: Rejection['commandId'];
349
+ commandType: Rejection['commandType'];
350
+ reasonCode: Rejection['reasonCode'];
351
+ reason?: Rejection['reason'];
352
+ aggregateType?: Rejection['aggregateType'];
353
+ aggregateId?: Rejection['aggregateId'];
354
+ classification: Rejection['classification'];
355
+ retryable?: Rejection['retryable'];
356
+ validationErrors?: Rejection['validationErrors'];
357
+ type: 'Failed' | 'Rejected' | string;
358
+ details?: TDetails;
359
+ }, metadata?: Partial<RejectionMetadata>): Rejection<TDetails>;
360
+
361
+ declare function isDomainEvent(event: unknown): event is DomainEvent;
362
+
363
+ declare function isEvent(event: unknown): event is DomainEvent | IntegrationEvent | ExternalEvent | Rejection;
364
+
365
+ interface Registerable$1<TCommand extends Command, TResult = void> {
366
+ register(aTypeOfCommand: TCommand['type'], anHandler: CommandHandler<TCommand>): TResult;
367
+ }
368
+ interface Executable$3<TCommand extends Command, TResult = Promise<void>> {
369
+ execute(aCommand: TCommand): TResult;
370
+ }
371
+ interface CommandBus<TCommand extends Command, TExecutionResult = Promise<void>, TRegisterResult = void> extends Executable$3<TCommand, TExecutionResult>, Registerable$1<TCommand, TRegisterResult> {
372
+ }
373
+
374
+ declare class SimpleCommandBus<TCommand extends Command> implements CommandBus<TCommand> {
375
+ private handlers;
376
+ register(aTypeOfCommand: TCommand['type'], anHandler: CommandHandler<TCommand>): void;
377
+ execute(aCommand: TCommand): Promise<void>;
378
+ }
379
+
380
+ declare enum Operation {
381
+ CREATE = "CREATE",
382
+ PUT = "PUT",
383
+ PATCH = "PATCH",
384
+ DELETE = "DELETE"
385
+ }
386
+ interface Statement<TModel> {
387
+ operation: Operation;
388
+ payload: TModel;
389
+ }
390
+ interface CreateStatement<TModel> extends Statement<TModel> {
391
+ operation: Operation.CREATE;
392
+ payload: TModel;
393
+ }
394
+ interface PutStatement<TModel> extends Statement<TModel> {
395
+ operation: Operation.PUT;
396
+ payload: TModel;
397
+ }
398
+ interface PatchStatement<TModel> extends Statement<Partial<TModel>> {
399
+ operation: Operation.PATCH;
400
+ payload: WithIdentifier<Partial<TModel>>;
401
+ }
402
+ interface DeleteStatement extends Statement<WithIdentifier> {
403
+ operation: Operation.DELETE;
404
+ payload: WithIdentifier;
405
+ }
406
+ interface Executable$2<TModel, TReturnType = Promise<void>> {
407
+ execute(tableName: string, statement: CreateStatement<TModel>): TReturnType;
408
+ execute(tableName: string, statement: PutStatement<TModel>): TReturnType;
409
+ execute(tableName: string, statement: PatchStatement<TModel>): TReturnType;
410
+ execute(tableName: string, statement: DeleteStatement): TReturnType;
411
+ }
412
+ interface QueryAble<TModel, TReturnType = Promise<TModel[]>> {
413
+ query(collectionName: string, specification: CompositeSpecification<TModel>): TReturnType;
414
+ }
415
+ interface Database<TModel, TExecuteReturnType = Promise<void>, TQueryReturnType = Promise<TModel[]>> extends QueryAble<TModel, TQueryReturnType>, Executable$2<TModel, TExecuteReturnType> {
416
+ }
417
+
418
+ declare class SimpleDatabase<TModel extends WithIdentifier> implements Database<TModel, Promise<void>, Promise<TModel[]>> {
419
+ private readonly datasource;
420
+ private simulateOffline;
421
+ query(tableName: string, specification: CompositeSpecification<TModel>): Promise<TModel[]>;
422
+ execute(tableName: string, statement: CreateStatement<TModel> | PutStatement<TModel> | PatchStatement<TModel> | DeleteStatement): Promise<void>;
423
+ goOffline(): void;
424
+ }
425
+
426
+ interface Executable$1<TInput, TResult> {
427
+ execute(input: TInput): TResult;
428
+ }
429
+ interface Directive<TInput, TResult = void> extends Executable$1<TInput, TResult> {
430
+ }
431
+
432
+ interface EventProducer<TEvent extends DomainEvent | IntegrationEvent | ExternalEvent, TReturnType = Promise<void>> {
433
+ publish(stream: string, anEvent: TEvent): TReturnType;
434
+ }
435
+ interface EventConsumer<TEvent extends DomainEvent | IntegrationEvent | ExternalEvent, TEventHandler = EventHandler<TEvent>, TConsumeReturnType = Promise<void>, TSubscribeReturnType = void> {
436
+ subscribe(stream: string, handler: TEventHandler): TSubscribeReturnType;
437
+ consume(stream: string, anEvent: TEvent): TConsumeReturnType;
438
+ }
439
+
440
+ declare class SimpleEventBus<TEvent extends DomainEvent | IntegrationEvent | ExternalEvent> implements EventConsumer<TEvent>, EventProducer<TEvent> {
441
+ private handlers;
442
+ subscribe(stream: string, aHandler: EventHandler<TEvent>): void;
443
+ consume(stream: string, anEvent: TEvent): Promise<void>;
444
+ publish(stream: string, anEvent: TEvent): Promise<void>;
445
+ }
446
+
447
+ declare function createIntegrationEvent<TPayload = unknown>(type: string, payload: TPayload, metadata?: Partial<IntegrationEventMetadata>): IntegrationEvent<TPayload>;
448
+
449
+ declare function isIntegrationEvent<TPayload>(event: unknown): event is IntegrationEvent<TPayload>;
450
+
451
+ type StreamKey = `${string}#${string}`;
452
+
453
+ /**
454
+ * StoredEvent wraps a DomainEvent for persistence in the event store with its
455
+ * stream coordinates and version. This table must be immutable, append-only.
456
+ */
457
+ interface StoredEvent<TEvent> {
458
+ /** Same as DomainEvent.id. */
459
+ id: string;
460
+ /** Stream key, e.g., `${aggregateType}#${aggregateId}`. */
461
+ streamKey: StreamKey;
462
+ /** Aggregate version after applying this event. */
463
+ version: number;
464
+ /** Epoch millis for write-time ordering. */
465
+ timestamp: number;
466
+ /** The actual domain event. */
467
+ event: TEvent;
468
+ }
469
+
470
+ interface Loadable<TEvent, TReturnType = Promise<StoredEvent<TEvent>>> {
471
+ load(streamName: string, aggregateId: string): TReturnType;
472
+ }
473
+ interface Appendable<TEvent, TReturnType = Promise<void>> {
474
+ append(streamName: string, events: TEvent[]): TReturnType;
475
+ }
476
+ interface EventStore<TEvent, TAppendReturnType = Promise<void>, TLoadReturnType = Promise<TEvent[]>> extends Loadable<TEvent, TLoadReturnType>, Appendable<TEvent, TAppendReturnType> {
477
+ }
478
+
479
+ interface OutboxEntry {
480
+ id: string;
481
+ event: DomainEvent;
482
+ published: boolean;
483
+ retryCount: number;
484
+ lastAttemptAt?: number;
485
+ }
486
+
487
+ interface Queueable<TReturnType = Promise<void>> {
488
+ enqueue(event: OutboxEntry['event']): TReturnType;
489
+ }
490
+ interface Outbox<TEnqueueReturnType = Promise<void>, TGetPendingReturnType = Promise<OutboxEntry[]>, TMarkAsPublishedReturnType = Promise<void>, TMarkAsFailedReturnType = Promise<void>> extends Queueable<TEnqueueReturnType> {
491
+ getPending(limit?: number): TGetPendingReturnType;
492
+ markAsPublished(id: string): TMarkAsPublishedReturnType;
493
+ markAsFailed(id: string): TMarkAsFailedReturnType;
494
+ }
495
+
496
+ declare class SimpleEventStore<TEvent extends DomainEvent> implements EventStore<TEvent, Promise<void>, Promise<TEvent[]>> {
497
+ private readonly database;
498
+ private readonly outbox?;
499
+ private readonly tableName;
500
+ constructor(database: Database<StoredEvent<TEvent>, Promise<void>, Promise<StoredEvent<TEvent>[]>>, outbox?: Outbox | undefined);
501
+ load(streamName: string, aggregateId: string): Promise<TEvent[]>;
502
+ append(streamName: string, events: TEvent[]): Promise<void>;
503
+ }
504
+
505
+ declare function createStoredEvent<TEvent extends DomainEvent>(streamName: string, version: number, event: TEvent): StoredEvent<TEvent>;
506
+
507
+ interface Runnable<TReturnType = Promise<void>> {
508
+ runOnce(): TReturnType;
509
+ }
510
+ interface Tickable<TReturnType = Promise<void>> {
511
+ tick(): TReturnType;
512
+ }
513
+ interface Startable<TReturnType = void> {
514
+ start(intervalMs: number): TReturnType;
515
+ }
516
+ interface OutboxWorker extends Runnable, Tickable, Startable {
517
+ }
518
+
519
+ declare class GenericOutboxWorker implements OutboxWorker {
520
+ protected outbox: Outbox;
521
+ protected eventBus: EventProducer<DomainEvent | IntegrationEvent | ExternalEvent>;
522
+ protected stream: string;
523
+ constructor(outbox: Outbox, eventBus: EventProducer<DomainEvent | IntegrationEvent | ExternalEvent>, stream: string);
524
+ runOnce(): Promise<void>;
525
+ tick(): Promise<void>;
526
+ start(intervalMs: number): void;
527
+ }
528
+
529
+ declare class InMemoryOutbox implements Outbox {
530
+ protected entries: OutboxEntry[];
531
+ protected idCounter: number;
532
+ enqueue(event: DomainEvent<unknown>): Promise<void>;
533
+ getPending(limit?: number): Promise<OutboxEntry[]>;
534
+ markAsPublished(id: string): Promise<void>;
535
+ markAsFailed(id: string): Promise<void>;
536
+ }
537
+
538
+ declare function createOutboxEntry(event: DomainEvent<unknown>): OutboxEntry;
539
+
540
+ interface Registerable<TQuery extends Query, TResult = void> {
541
+ register(aTypeOfQuery: TQuery['type'], anHandler: QueryHandler<TQuery>): TResult;
542
+ }
543
+ interface Executable<TQuery extends Query, TResult = Promise<unknown>> {
544
+ execute(aQuery: TQuery): TResult;
545
+ }
546
+ interface QueryBus<TQuery extends Query, TExecutionResult, TRegisterResult = void> extends Executable<TQuery, TExecutionResult>, Registerable<TQuery, TRegisterResult> {
547
+ }
548
+
549
+ declare class SimpleQueryBus<TQuery extends Query, TProjection> implements QueryBus<TQuery, Promise<TProjection>> {
550
+ private handlers;
551
+ register(aTypeOfQuery: TQuery['type'], anHandler: QueryHandler<TQuery, Promise<TProjection>>): void;
552
+ execute(aQuery: TQuery): Promise<TProjection>;
553
+ }
554
+
555
+ declare class SimpleRepository<TState, TCommand, TEvent extends DomainEvent, TRejection extends Rejection> implements Repository<TEvent, Promise<TState>, Promise<void>> {
556
+ private readonly eventStore;
557
+ readonly streamName: string;
558
+ private readonly evolveFn;
559
+ private readonly initialState;
560
+ constructor(eventStore: EventStore<TEvent, Promise<void>, Promise<TEvent[]>>, streamName: string, evolveFn: Decider<TState, TCommand, TEvent, TRejection>['evolve'], initialState: Decider<TState, TCommand, TEvent, TRejection>['initialState']);
561
+ load(aggregateId: string): Promise<TState>;
562
+ store(events: TEvent[]): Promise<void>;
563
+ }
564
+
565
+ declare function fail(anExpression: Error): () => never;
566
+
567
+ declare function invariant(condition: boolean, onInvalid: () => never): asserts condition;
568
+
569
+ declare function isEqual<T>(a: T, b: T): boolean;
570
+
571
+ declare function parseAsError(value: unknown): Error;
572
+
573
+ declare function makeStreamKey(streamName: string, aggregateId: string): StreamKey;
574
+
575
+ export { type AggregateRoot, AndSpecification, type BaseMetadata, type Command, type CommandBus, type CommandHandler, type CommandMetadata, CompositeSpecification, type CreateStatement, type Database, type Decider, type DeleteStatement, type Directive, type DomainEvent, type DomainEventMetadata, type EventBasedAggregateRoot, type EventConsumer, type EventHandler, type EventProducer, type EventStore, FieldEquals, FieldGreaterThan, type FilledArray, GenericOutboxWorker, type ISODateTime, InMemoryOutbox, type IntegrationEvent, type IntegrationEventMetadata, type Maybe, type Module, NotSpecification, type Nullable, Operation, OrSpecification, type Outbox, type OutboxEntry, type OutboxWorker, type PatchStatement, type Primitive, type PutStatement, type Query, type QueryBus, type QueryHandler, type QueryMetadata, type QueryNode, type Rejection, type RejectionMetadata, type Repository, SimpleCommandBus, SimpleDatabase, SimpleEventBus, SimpleEventStore, SimpleQueryBus, SimpleRepository, type Specification, type StoredEvent, type StreamKey, type UnixTimestampInSeconds, type WithIdentifier, createCommand, createDomainEvent, createIntegrationEvent, createOutboxEntry, createQuery, createQueryNode, createRejection, createStoredEvent, fail, getTimestamp, invariant, isCommand, isDomainEvent, isEqual, isEvent, isIntegrationEvent, isQuery, makeStreamKey, parseAsError };