@relaybus/core 0.2.0 → 0.3.1
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 +120 -8
- package/dist/chunk-J76M7XTS.cjs +323 -0
- package/dist/chunk-J76M7XTS.cjs.map +1 -0
- package/dist/chunk-NOR5JHVN.js +295 -0
- package/dist/chunk-NOR5JHVN.js.map +1 -0
- package/dist/index.cjs +2775 -1625
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +321 -471
- package/dist/index.d.ts +321 -471
- package/dist/index.js +2712 -1625
- package/dist/index.js.map +1 -1
- package/dist/internal/index.cjs +662 -0
- package/dist/internal/index.cjs.map +1 -0
- package/dist/internal/index.d.cts +438 -0
- package/dist/internal/index.d.ts +438 -0
- package/dist/internal/index.js +617 -0
- package/dist/internal/index.js.map +1 -0
- package/dist/transport-BlfzIBZD.d.cts +535 -0
- package/dist/transport-BlfzIBZD.d.ts +535 -0
- package/package.json +18 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,114 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
now(): Date;
|
|
4
|
-
}
|
|
5
|
-
declare const systemClock: Clock;
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* A duration in milliseconds, or a string such as `'250ms'`, `'30s'`, `'5m'`,
|
|
9
|
-
* `'1h'` or `'7d'`.
|
|
10
|
-
*/
|
|
11
|
-
type Duration = number | `${number}${DurationUnit}`;
|
|
12
|
-
type DurationUnit = 'ms' | 's' | 'm' | 'h' | 'd';
|
|
13
|
-
declare function toMilliseconds(value: Duration, name: string): number;
|
|
14
|
-
/** Largest delay Node.js timers support. Longer values fire after 1ms instead. */
|
|
15
|
-
declare const MAX_TIMER_DELAY_MS = 2147483647;
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* The Standard Schema interface (https://standardschema.dev), copied as the
|
|
19
|
-
* specification recommends so relaybus needs no runtime dependency. Zod,
|
|
20
|
-
* Valibot, ArkType and other libraries implement it.
|
|
21
|
-
*/
|
|
22
|
-
interface StandardSchemaV1<Input = unknown, Output = Input> {
|
|
23
|
-
readonly '~standard': StandardSchemaV1.Props<Input, Output>;
|
|
24
|
-
}
|
|
25
|
-
declare namespace StandardSchemaV1 {
|
|
26
|
-
interface Props<Input = unknown, Output = Input> {
|
|
27
|
-
readonly version: 1;
|
|
28
|
-
readonly vendor: string;
|
|
29
|
-
readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>;
|
|
30
|
-
readonly types?: Types<Input, Output> | undefined;
|
|
31
|
-
}
|
|
32
|
-
type Result<Output> = SuccessResult<Output> | FailureResult;
|
|
33
|
-
interface SuccessResult<Output> {
|
|
34
|
-
readonly value: Output;
|
|
35
|
-
readonly issues?: undefined;
|
|
36
|
-
}
|
|
37
|
-
interface FailureResult {
|
|
38
|
-
readonly issues: ReadonlyArray<Issue>;
|
|
39
|
-
}
|
|
40
|
-
interface Issue {
|
|
41
|
-
readonly message: string;
|
|
42
|
-
readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
|
|
43
|
-
}
|
|
44
|
-
interface PathSegment {
|
|
45
|
-
readonly key: PropertyKey;
|
|
46
|
-
}
|
|
47
|
-
interface Types<Input = unknown, Output = Input> {
|
|
48
|
-
readonly input: Input;
|
|
49
|
-
readonly output: Output;
|
|
50
|
-
}
|
|
51
|
-
type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['input'];
|
|
52
|
-
type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['output'];
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/** String metadata carried with an event, such as `traceparent`. */
|
|
56
|
-
type EventHeaders = Readonly<Record<string, string>>;
|
|
57
|
-
/**
|
|
58
|
-
* An event as stored and delivered. Field names follow CloudEvents where they
|
|
59
|
-
* overlap (`id`, `type`, `source`, `time` as `occurredAt`, `subject` as `key`).
|
|
60
|
-
*/
|
|
61
|
-
interface EventEnvelope<TPayload = unknown> {
|
|
62
|
-
/** Globally unique id. Handlers and transports deduplicate on it. */
|
|
63
|
-
readonly id: string;
|
|
64
|
-
/** Event type, for example `order.created.v1`. */
|
|
65
|
-
readonly type: string;
|
|
66
|
-
/** Logical name of the publishing service. */
|
|
67
|
-
readonly source: string;
|
|
68
|
-
/** Ordering and partition key. Events sharing a key are handled in publish order. */
|
|
69
|
-
readonly key: string | null;
|
|
70
|
-
readonly payload: TPayload;
|
|
71
|
-
readonly headers: EventHeaders;
|
|
72
|
-
/** Id shared by every event of one business flow. */
|
|
73
|
-
readonly correlationId: string | null;
|
|
74
|
-
/** Id of the event whose handler published this one. */
|
|
75
|
-
readonly causationId: string | null;
|
|
76
|
-
readonly occurredAt: Date;
|
|
77
|
-
}
|
|
78
|
-
/** An instance of a class created with {@link defineEvent}. */
|
|
79
|
-
interface DomainEvent<TPayload = unknown> {
|
|
80
|
-
readonly type: string;
|
|
81
|
-
readonly payload: TPayload;
|
|
82
|
-
}
|
|
83
|
-
/** A class created with {@link defineEvent}. */
|
|
84
|
-
interface EventClass<TPayload = unknown> {
|
|
85
|
-
new (payload: TPayload): DomainEvent<TPayload>;
|
|
86
|
-
readonly type: string;
|
|
87
|
-
readonly schema: StandardSchemaV1<unknown, TPayload> | undefined;
|
|
88
|
-
}
|
|
89
|
-
/** Payload type of an event class: `PayloadOf<typeof OrderPlaced>`. */
|
|
90
|
-
type PayloadOf<TEvent> = TEvent extends EventClass<infer TPayload> ? TPayload : never;
|
|
91
|
-
/** Anything that names an event type: an event class or the type string itself. */
|
|
92
|
-
type EventReference = {
|
|
93
|
-
readonly type: string;
|
|
94
|
-
} | string;
|
|
95
|
-
interface DefineEventOptions<TSchema extends StandardSchemaV1> {
|
|
96
|
-
/** Validates the payload on publish and before every handler call. */
|
|
97
|
-
readonly schema: TSchema;
|
|
98
|
-
}
|
|
99
|
-
declare function assertEventType(type: string): void;
|
|
100
|
-
/**
|
|
101
|
-
* Defines an event type. Extend the returned class to name it:
|
|
102
|
-
*
|
|
103
|
-
* ```ts
|
|
104
|
-
* export class OrderPlaced extends defineEvent<{ orderId: string }>('order.placed.v1') {}
|
|
105
|
-
* export class OrderShipped extends defineEvent('order.shipped.v1', { schema: orderShippedSchema }) {}
|
|
106
|
-
* ```
|
|
107
|
-
*/
|
|
108
|
-
declare function defineEvent<TSchema extends StandardSchemaV1>(type: string, options: DefineEventOptions<TSchema>): EventClass<StandardSchemaV1.InferOutput<TSchema>>;
|
|
109
|
-
declare function defineEvent<TPayload>(type: string): EventClass<TPayload>;
|
|
110
|
-
/** Runs a Standard Schema and returns its output, or throws {@link EventValidationError}. */
|
|
111
|
-
declare function validatePayload<TPayload>(type: string, schema: StandardSchemaV1<unknown, TPayload> | undefined, payload: unknown): Promise<TPayload>;
|
|
1
|
+
import { D as Duration, E as EventEnvelope, a as DomainEvent, S as StandardSchemaV1, P as PayloadOf, C as ClaimedDelivery, b as EventHeaders, c as EventStoreStatistics, d as ErrorInfo, e as PurgeResult, f as EventStore, T as Transport, g as EventReference, h as Clock, A as AppendEntry, i as AppendResult, j as ClaimRequest, L as LeaseReference, k as DeliveryQuery, l as DeliveryRecord, m as PurgeRequest, n as EventClass } from './transport-BlfzIBZD.cjs';
|
|
2
|
+
export { o as AttemptsExhaustedError, p as CloseOptions, q as ConfigurationError, r as DELIVERY_STATUSES, s as DefineEventKeyOptions, t as DefineEventOptions, u as DeliveryStatus, v as DispatcherStoppedError, w as DrainIncompleteError, x as EventKeyFunction, y as EventStoreTransactionOptions, z as EventValidationError, H as HandlerTimeoutError, I as InvalidEnvelopeError, B as InvalidTransportMessage, F as LeaseLostError, G as LifecycleError, M as MAX_TIMER_DELAY_MS, N as NewDelivery, J as NonRetryableError, R as RelayBusError, K as TransactionRequiredError, O as TransactionTimeoutError, Q as TransportMessage, U as TransportMessageHandler, V as TransportSubscriptionHooks, W as ValidationIssue, X as assertEventType, Y as defineEvent, Z as systemClock, _ as toErrorInfo, $ as toMilliseconds, a0 as validatePayload } from './transport-BlfzIBZD.cjs';
|
|
112
3
|
|
|
113
4
|
/**
|
|
114
5
|
* How the delay between attempts is randomized.
|
|
@@ -430,7 +321,7 @@ interface CatalogDeclaration<TCatalog extends Catalog = Catalog, TName extends k
|
|
|
430
321
|
* Declares that this service consumes events of a catalog, typically one
|
|
431
322
|
* shared between services through a contracts package. `start()` fails unless
|
|
432
323
|
* every declared event has a local handler (`subscribeCatalog`, `subscribe`,
|
|
433
|
-
* `@
|
|
324
|
+
* `@RelayBusCatalogConsumer`, `@RelayBusConsumer`); a route to a transport does not count.
|
|
434
325
|
* Without `events`, every event of the catalog is declared. Unknown names do
|
|
435
326
|
* not compile and are rejected at runtime with a {@link ConfigurationError}.
|
|
436
327
|
*
|
|
@@ -458,269 +349,175 @@ declare function consume<TCatalog extends Catalog, const TName extends keyof TCa
|
|
|
458
349
|
declare function produce<TCatalog extends Catalog, const TName extends keyof TCatalog = keyof TCatalog>(catalog: TCatalog, options?: CatalogEventSelection<TName>): CatalogDeclaration<TCatalog, TName>;
|
|
459
350
|
|
|
460
351
|
/**
|
|
461
|
-
*
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
name: string;
|
|
465
|
-
}
|
|
466
|
-
/** Invalid options passed to a relaybus component. */
|
|
467
|
-
declare class ConfigurationError extends RelayBusError {
|
|
468
|
-
name: string;
|
|
469
|
-
}
|
|
470
|
-
/**
|
|
471
|
-
* Thrown by `publish` when no transaction can be found and the bus runs with
|
|
472
|
-
* `transactionMode: 'required'` (the default). Publishing outside a transaction
|
|
473
|
-
* would reintroduce the dual-write problem the outbox exists to prevent.
|
|
474
|
-
*/
|
|
475
|
-
declare class TransactionRequiredError extends RelayBusError {
|
|
476
|
-
name: string;
|
|
477
|
-
}
|
|
478
|
-
/**
|
|
479
|
-
* Throw from a handler to dead-letter the delivery immediately, skipping the
|
|
480
|
-
* remaining retry attempts.
|
|
481
|
-
*/
|
|
482
|
-
declare class NonRetryableError extends RelayBusError {
|
|
483
|
-
name: string;
|
|
484
|
-
}
|
|
485
|
-
/** A payload failed its event schema. Never retried: the payload will not change. */
|
|
486
|
-
declare class EventValidationError extends NonRetryableError {
|
|
487
|
-
readonly issues: readonly ValidationIssue[];
|
|
488
|
-
name: string;
|
|
489
|
-
constructor(message: string, issues: readonly ValidationIssue[]);
|
|
490
|
-
}
|
|
491
|
-
/**
|
|
492
|
-
* A message received from a broker is not a valid event. Never retried:
|
|
493
|
-
* transports should dead-letter it instead of redelivering it forever.
|
|
494
|
-
*/
|
|
495
|
-
declare class InvalidEnvelopeError extends NonRetryableError {
|
|
496
|
-
name: string;
|
|
497
|
-
}
|
|
498
|
-
/** The worker no longer owns the delivery it was processing. */
|
|
499
|
-
declare class LeaseLostError extends RelayBusError {
|
|
500
|
-
name: string;
|
|
501
|
-
/**
|
|
502
|
-
* Whether the store said so (a fenced write returned false). A worker that only noticed
|
|
503
|
-
* locally that its lease ran out may still own the delivery in the store and has to give it back.
|
|
504
|
-
*/
|
|
505
|
-
readonly storeConfirmed: boolean;
|
|
506
|
-
constructor(message: string, options?: {
|
|
507
|
-
readonly storeConfirmed?: boolean;
|
|
508
|
-
});
|
|
509
|
-
}
|
|
510
|
-
/** A handler did not settle within its configured timeout. Retried like any failure. */
|
|
511
|
-
declare class HandlerTimeoutError extends RelayBusError {
|
|
512
|
-
name: string;
|
|
513
|
-
}
|
|
514
|
-
/**
|
|
515
|
-
* Reason of a handler's abort signal when the bus stops before the handler
|
|
516
|
-
* finished. The delivery is released and runs again without losing an attempt.
|
|
352
|
+
* RFC 9562 UUID version 7: 48-bit Unix millisecond timestamp followed by random
|
|
353
|
+
* bits. Time-ordered, so it keeps B-tree indexes compact, and globally unique,
|
|
354
|
+
* so it is safe as an idempotency key across services.
|
|
517
355
|
*/
|
|
518
|
-
declare
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
interface ValidationIssue {
|
|
522
|
-
readonly message: string;
|
|
523
|
-
readonly path?: readonly PropertyKey[] | undefined;
|
|
524
|
-
}
|
|
525
|
-
/** Serializable snapshot of an error, stored with failed deliveries. */
|
|
526
|
-
interface ErrorInfo {
|
|
527
|
-
readonly name: string;
|
|
528
|
-
readonly message: string;
|
|
529
|
-
readonly stack?: string | undefined;
|
|
530
|
-
}
|
|
531
|
-
declare function toErrorInfo(error: unknown): ErrorInfo;
|
|
356
|
+
declare function createUuidV7(timestamp?: number): string;
|
|
357
|
+
/** Produces unique identifiers for events, deliveries and lease tokens. */
|
|
358
|
+
type IdentifierGenerator = () => string;
|
|
532
359
|
|
|
533
|
-
/**
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
interface NewDelivery {
|
|
546
|
-
readonly id: string;
|
|
547
|
-
/** Stable handler id. Together with the event id it is unique. */
|
|
548
|
-
readonly handler: string;
|
|
549
|
-
readonly availableAt: Date;
|
|
550
|
-
}
|
|
551
|
-
interface AppendEntry {
|
|
552
|
-
readonly event: EventEnvelope;
|
|
553
|
-
readonly deliveries: readonly NewDelivery[];
|
|
554
|
-
}
|
|
555
|
-
interface AppendResult {
|
|
556
|
-
/** Events written by this call. */
|
|
557
|
-
readonly appendedEventIds: readonly string[];
|
|
558
|
-
/** Events that already existed. Their missing deliveries were still added. */
|
|
559
|
-
readonly duplicateEventIds: readonly string[];
|
|
560
|
-
/** Deliveries written by this call. Existing (event, handler) pairs are skipped. */
|
|
561
|
-
readonly appendedDeliveryCount: number;
|
|
562
|
-
}
|
|
563
|
-
/**
|
|
564
|
-
* Lease expiry is compared with the `now` the caller passes, taken from the
|
|
565
|
-
* bus clock. Keep worker clocks synchronized (NTP): a skew larger than a third
|
|
566
|
-
* of the lease duration lets another worker reclaim a delivery that is still running.
|
|
360
|
+
/** Event header that carries the W3C trace context (`version-traceid-parentid-flags`). */
|
|
361
|
+
declare const TRACEPARENT_HEADER = "traceparent";
|
|
362
|
+
/** Event header that carries the vendor part of the W3C trace context. */
|
|
363
|
+
declare const TRACESTATE_HEADER = "tracestate";
|
|
364
|
+
/** A W3C Trace Context as it travels in event headers. */
|
|
365
|
+
interface TraceContext {
|
|
366
|
+
readonly traceparent: string;
|
|
367
|
+
readonly tracestate?: string;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* The W3C trace context an event carries in its headers, or undefined when it has none or a
|
|
371
|
+
* malformed one. A handler or a consumer span continues the publisher's trace from it.
|
|
567
372
|
*
|
|
568
|
-
*
|
|
569
|
-
*
|
|
570
|
-
*
|
|
571
|
-
* is relinquished; every delivery of the group carries the group's fencing token.
|
|
572
|
-
*/
|
|
573
|
-
interface ClaimRequest {
|
|
574
|
-
/** Only deliveries of these handlers are claimed. */
|
|
575
|
-
readonly handlers: readonly string[];
|
|
576
|
-
readonly limit: number;
|
|
577
|
-
readonly leaseOwner: string;
|
|
578
|
-
readonly leaseExpiresAt: Date;
|
|
579
|
-
readonly now: Date;
|
|
580
|
-
}
|
|
581
|
-
/**
|
|
582
|
-
* Proof of ownership. Every state change after a claim must present it
|
|
583
|
-
* (fencing). A lease stays valid until another claim replaces it, even after
|
|
584
|
-
* its expiry time; expiry only makes the delivery claimable again.
|
|
373
|
+
* ```ts
|
|
374
|
+
* bus.subscribe(OrderPlaced, (event) => startSpan({ parent: traceContextOf(event.headers) }), ...)
|
|
375
|
+
* ```
|
|
585
376
|
*/
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
readonly handler: string;
|
|
592
|
-
/** Attempt number of this claim, starting at 1. */
|
|
593
|
-
readonly attempt: number;
|
|
594
|
-
readonly leaseExpiresAt: Date;
|
|
595
|
-
readonly event: EventEnvelope;
|
|
596
|
-
}
|
|
597
|
-
interface DeliveryRecord {
|
|
598
|
-
readonly id: string;
|
|
599
|
-
readonly handler: string;
|
|
600
|
-
readonly status: DeliveryStatus;
|
|
601
|
-
readonly attempts: number;
|
|
602
|
-
readonly availableAt: Date;
|
|
603
|
-
readonly leaseOwner: string | null;
|
|
604
|
-
readonly leaseExpiresAt: Date | null;
|
|
605
|
-
readonly lastError: ErrorInfo | null;
|
|
606
|
-
readonly createdAt: Date;
|
|
607
|
-
readonly updatedAt: Date;
|
|
608
|
-
readonly completedAt: Date | null;
|
|
609
|
-
readonly event: EventEnvelope;
|
|
610
|
-
}
|
|
611
|
-
interface DeliveryQuery {
|
|
612
|
-
readonly status?: DeliveryStatus;
|
|
613
|
-
readonly handler?: string;
|
|
614
|
-
readonly eventType?: string;
|
|
615
|
-
readonly eventId?: string;
|
|
616
|
-
/** Default 100. */
|
|
617
|
-
readonly limit?: number;
|
|
618
|
-
}
|
|
619
|
-
interface PurgeRequest {
|
|
620
|
-
/** Delete completed deliveries completed before this instant. */
|
|
621
|
-
readonly completedBefore?: Date;
|
|
622
|
-
/** Delete dead deliveries last updated before this instant. */
|
|
623
|
-
readonly deadBefore?: Date;
|
|
377
|
+
declare function traceContextOf(headers: EventHeaders): TraceContext | undefined;
|
|
378
|
+
/** A `publish` or `publishAll` call. */
|
|
379
|
+
interface PublishTraceInput {
|
|
380
|
+
/** The type of every event of the call, in order. */
|
|
381
|
+
readonly eventTypes: readonly string[];
|
|
624
382
|
}
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
readonly
|
|
383
|
+
/** A route sending one event to its transport. */
|
|
384
|
+
interface SendTraceInput {
|
|
385
|
+
readonly envelope: EventEnvelope;
|
|
386
|
+
readonly transport: string;
|
|
387
|
+
/** The messaging system of the transport (`kafka`, `rabbitmq`), else its name. */
|
|
388
|
+
readonly system: string;
|
|
389
|
+
readonly destination: string;
|
|
629
390
|
}
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
readonly
|
|
633
|
-
readonly completed: number;
|
|
634
|
-
readonly dead: number;
|
|
635
|
-
/** `availableAt` of the oldest delivery that is due but not yet processed. */
|
|
636
|
-
readonly oldestDueAt: Date | null;
|
|
391
|
+
/** A local handler running for one claimed delivery. */
|
|
392
|
+
interface ProcessTraceInput {
|
|
393
|
+
readonly delivery: ClaimedDelivery;
|
|
637
394
|
}
|
|
638
395
|
/**
|
|
639
|
-
*
|
|
640
|
-
*
|
|
641
|
-
*
|
|
642
|
-
* Every implementation must pass the contract suite in `@relaybus/testing`.
|
|
396
|
+
* Tracing hooks, for example from `@relaybus/otel`. Each one wraps an operation: it starts a span,
|
|
397
|
+
* calls `run` inside it and ends the span when the returned promise settles, passing its result or
|
|
398
|
+
* error through unchanged. relaybus itself depends on no tracing library.
|
|
643
399
|
*/
|
|
644
|
-
interface
|
|
645
|
-
/** Creates tables, collections and indexes when they do not exist. */
|
|
646
|
-
setup?(): Promise<void>;
|
|
647
|
-
/** Runs `work` inside a new database transaction and commits when it resolves. */
|
|
648
|
-
transaction<T>(work: (transaction: TTransaction) => Promise<T>): Promise<T>;
|
|
649
|
-
/**
|
|
650
|
-
* Writes events and their deliveries inside `transaction`. Idempotent on
|
|
651
|
-
* event id and on (event id, handler). Assigns a per-key sequence to keyed
|
|
652
|
-
* events in commit order.
|
|
653
|
-
*/
|
|
654
|
-
append(transaction: TTransaction, entries: readonly AppendEntry[], now: Date): Promise<AppendResult>;
|
|
655
|
-
/**
|
|
656
|
-
* Leases up to `limit` deliveries that are due: pending with `availableAt <= now`,
|
|
657
|
-
* or processing with an expired lease. A keyed delivery is only claimable when
|
|
658
|
-
* no earlier delivery of the same handler and key is pending or processing.
|
|
659
|
-
* Counts the attempt (`attempt` of the result; a store may persist the count
|
|
660
|
-
* only when the attempt fails or its lease is lost). Safe to call from many
|
|
661
|
-
* processes at once.
|
|
662
|
-
*/
|
|
663
|
-
claim(request: ClaimRequest): Promise<ClaimedDelivery[]>;
|
|
664
|
-
/** Extends a lease the caller still holds. Returns false when the lease was lost. */
|
|
665
|
-
extendLease(lease: LeaseReference, leaseExpiresAt: Date, now: Date): Promise<boolean>;
|
|
666
|
-
/**
|
|
667
|
-
* Marks a leased delivery completed by deleting it (or moving it to the
|
|
668
|
-
* completion history, when the store keeps one). With `transaction` the change
|
|
669
|
-
* commits together with the handler's own writes. Returns false when the lease
|
|
670
|
-
* was lost.
|
|
671
|
-
*/
|
|
672
|
-
complete(lease: LeaseReference, now: Date, transaction?: TTransaction): Promise<boolean>;
|
|
673
|
-
/** Returns a leased delivery to pending, due at `availableAt`. */
|
|
674
|
-
reschedule(lease: LeaseReference, availableAt: Date, error: ErrorInfo, now: Date): Promise<boolean>;
|
|
675
|
-
/**
|
|
676
|
-
* Gives a leased delivery back without counting the attempt: pending, due
|
|
677
|
-
* now, attempts decremented. Used when a handler is aborted at shutdown.
|
|
678
|
-
*/
|
|
679
|
-
release(lease: LeaseReference, now: Date): Promise<boolean>;
|
|
400
|
+
interface RelayBusTracer {
|
|
680
401
|
/**
|
|
681
|
-
*
|
|
682
|
-
* every
|
|
683
|
-
*
|
|
684
|
-
* {@link EventStore.complete}. Optional: the dispatcher falls back to
|
|
685
|
-
* `complete` when a store does not implement it.
|
|
402
|
+
* Wraps one publish call. `run` takes the trace headers (`traceparent`, `tracestate`) to write
|
|
403
|
+
* into every event of the call, so its consumers continue the trace; headers passed to
|
|
404
|
+
* `publish` explicitly win.
|
|
686
405
|
*/
|
|
687
|
-
|
|
688
|
-
/** Moves a leased delivery to dead. */
|
|
689
|
-
bury(lease: LeaseReference, error: ErrorInfo, now: Date): Promise<boolean>;
|
|
690
|
-
listDeliveries(query: DeliveryQuery): Promise<DeliveryRecord[]>;
|
|
691
|
-
/** Moves dead deliveries back to pending with a fresh attempt budget. Returns how many moved. */
|
|
692
|
-
requeue(deliveryIds: readonly string[], now: Date): Promise<number>;
|
|
693
|
-
purge(request: PurgeRequest): Promise<PurgeResult>;
|
|
694
|
-
statistics(now: Date): Promise<EventStoreStatistics>;
|
|
406
|
+
publish?<T>(input: PublishTraceInput, run: (headers: EventHeaders) => Promise<T>): Promise<T>;
|
|
695
407
|
/**
|
|
696
|
-
*
|
|
697
|
-
*
|
|
698
|
-
* Called at graceful shutdown after the owner's deliveries settled. Groups
|
|
699
|
-
* with running deliveries stay leased. Optional.
|
|
408
|
+
* Wraps one send of a route. `run` takes the trace headers to send the event with, in place of
|
|
409
|
+
* the ones it was stored with, so the consumer's trace continues from this send.
|
|
700
410
|
*/
|
|
701
|
-
|
|
411
|
+
send?<T>(input: SendTraceInput, run: (headers: EventHeaders) => Promise<T>): Promise<T>;
|
|
702
412
|
/**
|
|
703
|
-
*
|
|
704
|
-
*
|
|
705
|
-
* A hint, never a guarantee: a report may be late, merged with others, or lost (while a connection
|
|
706
|
-
* is re-established, for instance), and polling still finds every delivery. Resolves with a function
|
|
707
|
-
* that stops listening, or with `undefined` when this store cannot listen. Optional.
|
|
413
|
+
* Wraps one run of a local handler; the handler runs inside `run`, so what it publishes or calls
|
|
414
|
+
* joins the span. The event's own trace context is in `traceContextOf(delivery.event.headers)`.
|
|
708
415
|
*/
|
|
709
|
-
|
|
710
|
-
/** Releases connections the store opened itself. */
|
|
711
|
-
close?(): Promise<void>;
|
|
416
|
+
process?<T>(input: ProcessTraceInput, run: () => Promise<T>): Promise<T>;
|
|
712
417
|
}
|
|
713
418
|
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
type
|
|
722
|
-
|
|
723
|
-
|
|
419
|
+
type FailureStage = 'claim' | 'dispatch' | 'complete' | 'reschedule' | 'bury' | 'release' | 'relinquish' | 'extend-lease' | 'purge' | 'watch' | 'backlog' | 'observer';
|
|
420
|
+
/** How a timed operation ended. On `error` the event carries the error. */
|
|
421
|
+
type OperationOutcome = 'success' | 'error';
|
|
422
|
+
/** Whether a delivery runs a local handler or forwards its event to a transport (a route). */
|
|
423
|
+
type DeliveryKind = 'handler' | 'route';
|
|
424
|
+
/** A `publish` or `publishAll` call returned or threw. */
|
|
425
|
+
interface PublishFinishedEvent {
|
|
426
|
+
/** The type of every event of the call, in order. */
|
|
427
|
+
readonly eventTypes: readonly string[];
|
|
428
|
+
readonly durationMs: number;
|
|
429
|
+
readonly outcome: OperationOutcome;
|
|
430
|
+
readonly error?: ErrorInfo;
|
|
431
|
+
}
|
|
432
|
+
/** One claim query of the dispatcher answered or failed. */
|
|
433
|
+
interface ClaimFinishedEvent {
|
|
434
|
+
/** Handler ids the claim asked for. */
|
|
435
|
+
readonly handlers: readonly string[];
|
|
436
|
+
/** Most deliveries the claim asked for (the batch size of this query). */
|
|
437
|
+
readonly requested: number;
|
|
438
|
+
readonly claimed: number;
|
|
439
|
+
/** Distinct leases among the claimed deliveries: a store that leases lanes counts each lane once. */
|
|
440
|
+
readonly lanes: number;
|
|
441
|
+
readonly durationMs: number;
|
|
442
|
+
readonly outcome: OperationOutcome;
|
|
443
|
+
readonly error?: ErrorInfo;
|
|
444
|
+
}
|
|
445
|
+
/** A handler (or a route's send) is about to run for a claimed delivery. */
|
|
446
|
+
interface HandlerStartedEvent {
|
|
447
|
+
readonly delivery: ClaimedDelivery;
|
|
448
|
+
readonly kind: DeliveryKind;
|
|
449
|
+
/** From the event's `occurredAt` to this start, across services for a received event. */
|
|
450
|
+
readonly endToEndLatencyMs: number;
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* A handler run ended: it resolved (`success`) or threw, timed out, lost its lease or was
|
|
454
|
+
* stopped (`error`). What happens to the delivery next is reported by the delivery hooks.
|
|
455
|
+
*/
|
|
456
|
+
interface HandlerFinishedEvent {
|
|
457
|
+
readonly delivery: ClaimedDelivery;
|
|
458
|
+
readonly kind: DeliveryKind;
|
|
459
|
+
readonly durationMs: number;
|
|
460
|
+
readonly outcome: OperationOutcome;
|
|
461
|
+
readonly error?: ErrorInfo;
|
|
462
|
+
}
|
|
463
|
+
/** A route handed an event to its transport, which acknowledged it or failed. */
|
|
464
|
+
interface TransportSentEvent {
|
|
465
|
+
readonly envelope: EventEnvelope;
|
|
466
|
+
/** Name of the transport. */
|
|
467
|
+
readonly transport: string;
|
|
468
|
+
/** The messaging system of the transport (`kafka`, `rabbitmq`), else its name. */
|
|
469
|
+
readonly system: string;
|
|
470
|
+
readonly destination: string;
|
|
471
|
+
readonly durationMs: number;
|
|
472
|
+
readonly outcome: OperationOutcome;
|
|
473
|
+
readonly error?: ErrorInfo;
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* What `receive` did with an event from a broker: stored it (`accepted`), found it stored already
|
|
477
|
+
* (`duplicate`), had no handler for it (`ignored`), rejected it as malformed (`invalid`) or failed
|
|
478
|
+
* (`error`, the broker redelivers it).
|
|
479
|
+
*/
|
|
480
|
+
type ReceiveOutcome = 'accepted' | 'duplicate' | 'ignored' | 'invalid' | 'error';
|
|
481
|
+
/** One event from a broker went through `receive`. */
|
|
482
|
+
interface ReceiveFinishedEvent {
|
|
483
|
+
/** Name of the transport that delivered it; undefined when `bus.receive` was called directly. */
|
|
484
|
+
readonly transport: string | undefined;
|
|
485
|
+
/** Messaging system of that transport (`kafka`, `rabbitmq`), else its name. */
|
|
486
|
+
readonly system: string | undefined;
|
|
487
|
+
/** Topic, routing key or queue it arrived on, when the transport tells. */
|
|
488
|
+
readonly destination: string | undefined;
|
|
489
|
+
/** The event's type and source as received; undefined when missing or not text. */
|
|
490
|
+
readonly eventType: string | undefined;
|
|
491
|
+
readonly source: string | undefined;
|
|
492
|
+
/** W3C trace context the event carries, to continue the trace of its publisher. */
|
|
493
|
+
readonly traceContext: TraceContext | undefined;
|
|
494
|
+
readonly outcome: ReceiveOutcome;
|
|
495
|
+
readonly durationMs: number;
|
|
496
|
+
readonly error?: ErrorInfo;
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* A transport could not decode an inbound message (codec failure, malformed record) and
|
|
500
|
+
* dead-lettered or skipped it. It never reached the bus, so `onReceiveFinished` does not see it.
|
|
501
|
+
*/
|
|
502
|
+
interface InvalidMessageEvent {
|
|
503
|
+
/** Name of the transport. */
|
|
504
|
+
readonly transport: string;
|
|
505
|
+
/** The messaging system of the transport (`kafka`, `rabbitmq`), else its name. */
|
|
506
|
+
readonly system: string;
|
|
507
|
+
/** Topic, routing key or queue the message arrived on. */
|
|
508
|
+
readonly destination: string;
|
|
509
|
+
/** Why the message was rejected. */
|
|
510
|
+
readonly reason: string;
|
|
511
|
+
readonly error: ErrorInfo;
|
|
512
|
+
}
|
|
513
|
+
/** A periodic reading of the store's backlog (`RelayBusOptions.backlogInterval`). */
|
|
514
|
+
interface BacklogEvent {
|
|
515
|
+
/** Deliveries waiting to run, due or not. */
|
|
516
|
+
readonly pending: number;
|
|
517
|
+
/** How long the oldest due delivery has waited; 0 when none is due. */
|
|
518
|
+
readonly oldestPendingAgeMs: number;
|
|
519
|
+
readonly statistics: EventStoreStatistics;
|
|
520
|
+
}
|
|
724
521
|
/**
|
|
725
522
|
* Hooks for logging, metrics and tracing. Every method is optional, runs
|
|
726
523
|
* synchronously on the hot path and must not throw; errors it throws are
|
|
@@ -769,6 +566,17 @@ interface RelayBusObserver {
|
|
|
769
566
|
readonly stage: FailureStage;
|
|
770
567
|
readonly error: ErrorInfo;
|
|
771
568
|
}): void;
|
|
569
|
+
/** A publish call ended; called before the publishing transaction commits. */
|
|
570
|
+
onPublishFinished?(event: PublishFinishedEvent): void;
|
|
571
|
+
onClaimFinished?(event: ClaimFinishedEvent): void;
|
|
572
|
+
onHandlerStarted?(event: HandlerStartedEvent): void;
|
|
573
|
+
onHandlerFinished?(event: HandlerFinishedEvent): void;
|
|
574
|
+
onTransportSent?(event: TransportSentEvent): void;
|
|
575
|
+
onReceiveFinished?(event: ReceiveFinishedEvent): void;
|
|
576
|
+
/** A transport rejected an inbound message it could not decode. */
|
|
577
|
+
onInvalidMessage?(event: InvalidMessageEvent): void;
|
|
578
|
+
/** Called every `backlogInterval` while the bus runs, when that option is set. */
|
|
579
|
+
onBacklog?(event: BacklogEvent): void;
|
|
772
580
|
}
|
|
773
581
|
/** Minimal logger. Nest's `Logger` and `console` both satisfy it. */
|
|
774
582
|
interface RelayBusLogger {
|
|
@@ -777,34 +585,6 @@ interface RelayBusLogger {
|
|
|
777
585
|
error(message: string): void;
|
|
778
586
|
}
|
|
779
587
|
|
|
780
|
-
/** Receives an event from a broker. Resolve only after it is durably stored. */
|
|
781
|
-
type TransportMessageHandler = (envelope: EventEnvelope) => Promise<void>;
|
|
782
|
-
/**
|
|
783
|
-
* Broker port used to exchange events between services.
|
|
784
|
-
*
|
|
785
|
-
* Outbound: the bus calls `publish` from a delivery, so a broker outage only
|
|
786
|
-
* delays events; the outbox keeps them. `publish` must resolve only after the
|
|
787
|
-
* broker acknowledged the message.
|
|
788
|
-
*
|
|
789
|
-
* Inbound: `subscribe` must acknowledge a message only after `onMessage`
|
|
790
|
-
* resolved, and redeliver it when `onMessage` rejects (at-least-once).
|
|
791
|
-
*/
|
|
792
|
-
interface Transport {
|
|
793
|
-
/** Unique name referenced by routes and subscriptions. */
|
|
794
|
-
readonly name: string;
|
|
795
|
-
connect?(): Promise<void>;
|
|
796
|
-
publish(envelope: EventEnvelope, destination: string): Promise<void>;
|
|
797
|
-
subscribe?(destinations: readonly string[], onMessage: TransportMessageHandler): Promise<void>;
|
|
798
|
-
/**
|
|
799
|
-
* Whether the transport can currently publish and, when subscribed, is
|
|
800
|
-
* consuming. Health checks use it to report a dead consumer or a lost
|
|
801
|
-
* connection. Transports without it count as ready.
|
|
802
|
-
*/
|
|
803
|
-
isReady?(): boolean;
|
|
804
|
-
/** Releases connections. A closed transport is not reopened. */
|
|
805
|
-
close(): Promise<void>;
|
|
806
|
-
}
|
|
807
|
-
|
|
808
588
|
/**
|
|
809
589
|
* - `required`: `publish` throws {@link TransactionRequiredError} when it finds no transaction.
|
|
810
590
|
* - `optional`: `publish` opens its own transaction instead. The event is still durable,
|
|
@@ -830,7 +610,11 @@ interface DispatcherOptions {
|
|
|
830
610
|
readonly pollInterval?: Duration;
|
|
831
611
|
/** Lease length; renewed every third of it while the handler runs. Default `'30s'`. */
|
|
832
612
|
readonly leaseDuration?: Duration;
|
|
833
|
-
/**
|
|
613
|
+
/**
|
|
614
|
+
* Longest `stop` takes in all, and its default `timeout`: waiting for running handlers, handing
|
|
615
|
+
* back leases, closing transports and the store. Past it, `stop` aborts the handlers still
|
|
616
|
+
* running, force-closes what relaybus opened itself and resolves. Default `'30s'`.
|
|
617
|
+
*/
|
|
834
618
|
readonly shutdownTimeout?: Duration;
|
|
835
619
|
/**
|
|
836
620
|
* Longest a finished delivery waits so that deliveries finishing around the
|
|
@@ -855,6 +639,11 @@ interface RetentionOptions {
|
|
|
855
639
|
/** How often the cleanup runs. Default `'1h'`. */
|
|
856
640
|
readonly interval?: Duration;
|
|
857
641
|
}
|
|
642
|
+
/**
|
|
643
|
+
* Every route to one destination of one transport is one handler,
|
|
644
|
+
* `relaybus.transport:<transport>:<destination>`: its events of one key are sent in commit
|
|
645
|
+
* order whatever their types. Such routes must resolve to the same `retry` and `timeout`.
|
|
646
|
+
*/
|
|
858
647
|
interface RouteOptions {
|
|
859
648
|
/** Event class or type forwarded to the transport. */
|
|
860
649
|
readonly event: EventReference;
|
|
@@ -877,6 +666,15 @@ interface RelayBusOptions<TTransaction = unknown> {
|
|
|
877
666
|
readonly source?: string;
|
|
878
667
|
/** Default `'required'`. */
|
|
879
668
|
readonly transactionMode?: TransactionMode;
|
|
669
|
+
/**
|
|
670
|
+
* Time budget of every `bus.transaction` (and `@RelayBusTransaction()` method). The store makes
|
|
671
|
+
* the database enforce it where it can (PostgreSQL: `statement_timeout`, plus
|
|
672
|
+
* `idle_in_transaction_session_timeout` and on PostgreSQL 17+ `transaction_timeout`; MongoDB:
|
|
673
|
+
* `maxCommitTimeMS`), and a transaction that still runs past
|
|
674
|
+
* it is rolled back with a {@link TransactionTimeoutError}. Keep calls to other services out of
|
|
675
|
+
* transactions instead of raising it. Default `'5s'`.
|
|
676
|
+
*/
|
|
677
|
+
readonly transactionTimeout?: Duration;
|
|
880
678
|
/**
|
|
881
679
|
* Finds the caller's active transaction when none is passed to `publish`
|
|
882
680
|
* and none was opened with `bus.transaction`, for example from
|
|
@@ -898,7 +696,23 @@ interface RelayBusOptions<TTransaction = unknown> {
|
|
|
898
696
|
readonly subscriptions?: readonly InboundSubscriptionOptions[];
|
|
899
697
|
/** Create tables and indexes on start. Default true. */
|
|
900
698
|
readonly setupStore?: boolean;
|
|
699
|
+
/**
|
|
700
|
+
* Hooks for logging and metrics. The hooks an observer implements are read when the bus is
|
|
701
|
+
* created; the newer ones (`onPublishFinished` and the other timed hooks) are skipped entirely,
|
|
702
|
+
* clock reads included, when no observer implements them.
|
|
703
|
+
*/
|
|
901
704
|
readonly observers?: readonly RelayBusObserver[];
|
|
705
|
+
/**
|
|
706
|
+
* Spans around publish, send and handler runs, and the W3C trace context written into published
|
|
707
|
+
* events (`traceparent`, `tracestate` headers). `@relaybus/otel` provides one. Default: none.
|
|
708
|
+
*/
|
|
709
|
+
readonly tracer?: RelayBusTracer;
|
|
710
|
+
/**
|
|
711
|
+
* Reads `statistics()` this often while the bus runs and reports the backlog (pending deliveries,
|
|
712
|
+
* age of the oldest due one) to the observers' `onBacklog`. Each reading is a store query, so it
|
|
713
|
+
* is off unless set; `'15s'` to `'1m'` suits metrics scraped every minute. Default: off.
|
|
714
|
+
*/
|
|
715
|
+
readonly backlogInterval?: Duration;
|
|
902
716
|
/** Default: `console`. */
|
|
903
717
|
readonly logger?: RelayBusLogger;
|
|
904
718
|
readonly clock?: Clock;
|
|
@@ -921,7 +735,9 @@ interface PublishOptions<TTransaction = unknown> {
|
|
|
921
735
|
/**
|
|
922
736
|
* Ordering and partition key. Events with the same key are handled one at a
|
|
923
737
|
* time per handler, in commit order. A delayed or retrying event holds back
|
|
924
|
-
* later events of its key.
|
|
738
|
+
* later events of its key. Default: the `key` of the event's definition
|
|
739
|
+
* (`defineEvent(type, { key })`), else none. An explicit key wins over the definition's, and in
|
|
740
|
+
* `publishAll` applies to every event of the call.
|
|
925
741
|
*/
|
|
926
742
|
readonly key?: string;
|
|
927
743
|
/** Deliver no earlier than this delay from now. */
|
|
@@ -942,6 +758,106 @@ interface PublishOneOptions<TTransaction = unknown> extends PublishOptions<TTran
|
|
|
942
758
|
readonly id?: string;
|
|
943
759
|
}
|
|
944
760
|
type ReceiveStatus = 'accepted' | 'duplicate' | 'ignored';
|
|
761
|
+
|
|
762
|
+
/** The publishing half of a bus, which a {@link CatalogPublisher} delegates to. */
|
|
763
|
+
interface PublishTarget<TTransaction> {
|
|
764
|
+
publish<TPayload>(event: DomainEvent<TPayload>, options?: PublishOneOptions<TTransaction>): Promise<EventEnvelope<TPayload>>;
|
|
765
|
+
publishAll(events: readonly DomainEvent[], options?: PublishOptions<TTransaction>): Promise<EventEnvelope[]>;
|
|
766
|
+
}
|
|
767
|
+
/**
|
|
768
|
+
* A view of a bus that publishes only the events of one catalog, or only the
|
|
769
|
+
* events a service produces from it. Obtain it with `bus.forCatalog(catalog)`
|
|
770
|
+
* or `bus.forCatalog(catalog, { events: ['OrderPlaced'] })`. Publishing an
|
|
771
|
+
* event outside the view fails to compile; a mistyped event that gets past the
|
|
772
|
+
* compiler (a cast, plain JavaScript, or a class with a structurally identical
|
|
773
|
+
* payload) is rejected with a {@link ConfigurationError} before anything is stored.
|
|
774
|
+
*
|
|
775
|
+
* ```ts
|
|
776
|
+
* const orders = bus.forCatalog(OrderEvents);
|
|
777
|
+
* await orders.publish(new OrderPlaced({ orderId }));
|
|
778
|
+
* await orders.publish(new UserRegistered({ userId })); // compile error
|
|
779
|
+
* ```
|
|
780
|
+
*/
|
|
781
|
+
declare class CatalogPublisher<TCatalog extends Catalog, TTransaction = unknown, TName extends keyof TCatalog = keyof TCatalog> {
|
|
782
|
+
#private;
|
|
783
|
+
/**
|
|
784
|
+
* Throws {@link ConfigurationError} when `catalog` was not created with
|
|
785
|
+
* `defineCatalog` or `options.events` names no event, an unknown event or
|
|
786
|
+
* the same event twice.
|
|
787
|
+
*/
|
|
788
|
+
constructor(catalog: TCatalog, target: PublishTarget<TTransaction>, options?: CatalogEventSelection<TName>);
|
|
789
|
+
/** Same as `bus.publish`, limited to the events of the view. */
|
|
790
|
+
publish<TEvent extends CatalogEvents<TCatalog, TName>>(event: TEvent, options?: PublishOneOptions<TTransaction>): Promise<EventEnvelope<TEvent['payload']>>;
|
|
791
|
+
/** Same as `bus.publishAll`, limited to the events of the view. Nothing is stored unless every event belongs to it. */
|
|
792
|
+
publishAll(events: readonly CatalogEvents<TCatalog, TName>[], options?: PublishOptions<TTransaction>): Promise<EventEnvelope[]>;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
/** Transaction handle of {@link InMemoryEventStore}. Writes apply on commit only. */
|
|
796
|
+
declare class InMemoryTransaction {
|
|
797
|
+
#private;
|
|
798
|
+
get state(): 'open' | 'committed' | 'rolled-back';
|
|
799
|
+
enqueue(operation: () => void): void;
|
|
800
|
+
/** Runs `finisher` once the transaction commits or rolls back, like a lock release. */
|
|
801
|
+
onFinish(finisher: () => void): void;
|
|
802
|
+
commit(): void;
|
|
803
|
+
rollback(): void;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
interface InMemoryEventStoreOptions {
|
|
807
|
+
/** Allow use when `NODE_ENV` is `production`. Data is lost on restart. Default false. */
|
|
808
|
+
readonly allowInProduction?: boolean;
|
|
809
|
+
readonly generateIdentifier?: IdentifierGenerator;
|
|
810
|
+
/**
|
|
811
|
+
* Keep a record of completed deliveries (status `completed`, listed, counted
|
|
812
|
+
* and purged by `retention.completed`). Default false: a completed delivery
|
|
813
|
+
* is deleted, like in the database stores.
|
|
814
|
+
*/
|
|
815
|
+
readonly retainCompleted?: boolean;
|
|
816
|
+
}
|
|
817
|
+
/**
|
|
818
|
+
* Event store kept in process memory, with the same semantics as the database
|
|
819
|
+
* stores: transactional appends, leases, fencing and per-key ordering. Payloads
|
|
820
|
+
* are round-tripped through JSON exactly like a database would store them.
|
|
821
|
+
* Meant for tests and local development.
|
|
822
|
+
*/
|
|
823
|
+
declare class InMemoryEventStore implements EventStore<InMemoryTransaction> {
|
|
824
|
+
#private;
|
|
825
|
+
constructor(options?: InMemoryEventStoreOptions);
|
|
826
|
+
transaction<T>(work: (transaction: InMemoryTransaction) => Promise<T>): Promise<T>;
|
|
827
|
+
append(transaction: InMemoryTransaction, entries: readonly AppendEntry[], now: Date): Promise<AppendResult>;
|
|
828
|
+
claim(request: ClaimRequest): Promise<ClaimedDelivery[]>;
|
|
829
|
+
extendLease(lease: LeaseReference, leaseExpiresAt: Date, now: Date): Promise<boolean>;
|
|
830
|
+
complete(lease: LeaseReference, now: Date, transaction?: InMemoryTransaction): Promise<boolean>;
|
|
831
|
+
completeMany(leases: readonly LeaseReference[], now: Date): Promise<boolean[]>;
|
|
832
|
+
reschedule(lease: LeaseReference, availableAt: Date, error: ErrorInfo, now: Date): Promise<boolean>;
|
|
833
|
+
release(lease: LeaseReference, now: Date): Promise<boolean>;
|
|
834
|
+
bury(lease: LeaseReference, error: ErrorInfo, now: Date): Promise<boolean>;
|
|
835
|
+
listDeliveries(query: DeliveryQuery): Promise<DeliveryRecord[]>;
|
|
836
|
+
requeue(deliveryIds: readonly string[], now: Date): Promise<number>;
|
|
837
|
+
purge(request: PurgeRequest): Promise<PurgeResult>;
|
|
838
|
+
statistics(now: Date): Promise<EventStoreStatistics>;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
interface StopOptions {
|
|
842
|
+
/**
|
|
843
|
+
* Longest the whole `stop` may take. Default: `dispatcher.shutdownTimeout`. Keep it below the time
|
|
844
|
+
* the platform waits before killing the process (Kubernetes `terminationGracePeriodSeconds`).
|
|
845
|
+
*/
|
|
846
|
+
readonly timeout?: Duration;
|
|
847
|
+
}
|
|
848
|
+
/** How a `stop` went. */
|
|
849
|
+
interface StopResult {
|
|
850
|
+
/** False when the deadline passed and `stop` aborted handlers or force-closed connections. */
|
|
851
|
+
readonly graceful: boolean;
|
|
852
|
+
/**
|
|
853
|
+
* Deliveries whose handlers still ran at the deadline. Their leases expire after
|
|
854
|
+
* `dispatcher.leaseDuration` and another process runs them again (at-least-once).
|
|
855
|
+
*/
|
|
856
|
+
readonly abandonedDeliveries: number;
|
|
857
|
+
/** Time `stop` took, on the bus clock. */
|
|
858
|
+
readonly durationMs: number;
|
|
859
|
+
}
|
|
860
|
+
|
|
945
861
|
/**
|
|
946
862
|
* Reliable event bus: events are stored with business data in one transaction,
|
|
947
863
|
* then dispatched to every subscribed handler and route with independent
|
|
@@ -1005,9 +921,16 @@ declare class RelayBus<TTransaction = unknown> {
|
|
|
1005
921
|
publishAll(events: readonly DomainEvent[], options?: PublishOptions<TTransaction>): Promise<EventEnvelope[]>;
|
|
1006
922
|
/**
|
|
1007
923
|
* Runs `work` in a new store transaction. `publish` calls inside it join the
|
|
1008
|
-
* transaction without passing it explicitly.
|
|
924
|
+
* transaction without passing it explicitly. The transaction is held to `transactionTimeout`
|
|
925
|
+
* and rolled back with a {@link TransactionTimeoutError} when it runs past it.
|
|
1009
926
|
*/
|
|
1010
927
|
transaction<T>(work: (transaction: TTransaction) => Promise<T>): Promise<T>;
|
|
928
|
+
/**
|
|
929
|
+
* The transaction `publish` would join right now: the one of the enclosing `bus.transaction`
|
|
930
|
+
* (or `@RelayBusTransaction()` method, or transactional handler), else the one
|
|
931
|
+
* `transactionResolver` finds. Repositories use it to write in the same transaction.
|
|
932
|
+
*/
|
|
933
|
+
currentTransaction(): TTransaction | undefined;
|
|
1011
934
|
/**
|
|
1012
935
|
* Stores an event received from a broker and schedules it for local handlers.
|
|
1013
936
|
* Idempotent on the event id. Transports call it and acknowledge the message
|
|
@@ -1022,10 +945,15 @@ declare class RelayBus<TTransaction = unknown> {
|
|
|
1022
945
|
*/
|
|
1023
946
|
start(): Promise<void>;
|
|
1024
947
|
/**
|
|
1025
|
-
* Stops
|
|
1026
|
-
*
|
|
948
|
+
* Stops claiming, waits for running handlers, hands back leases, closes transports and the store,
|
|
949
|
+
* all within `options.timeout` (default `dispatcher.shutdownTimeout`). When the deadline passes it
|
|
950
|
+
* aborts the handlers still running, force-closes what relaybus opened itself (never pools or
|
|
951
|
+
* clients the application passed in) and resolves anyway: it never rejects because of the
|
|
952
|
+
* deadline. Abandoned deliveries stay leased until their lease expires and then run again
|
|
953
|
+
* (at-least-once). Waits for a start in progress first. Safe to call more than once: later calls
|
|
954
|
+
* get the result of the first.
|
|
1027
955
|
*/
|
|
1028
|
-
stop(): Promise<
|
|
956
|
+
stop(options?: StopOptions): Promise<StopResult>;
|
|
1029
957
|
/**
|
|
1030
958
|
* Claims and runs one batch of due deliveries, resolving when they settle.
|
|
1031
959
|
* Returns how many ran. Intended for tests and scripts.
|
|
@@ -1044,82 +972,4 @@ declare class RelayBus<TTransaction = unknown> {
|
|
|
1044
972
|
purgeExpired(): Promise<PurgeResult>;
|
|
1045
973
|
}
|
|
1046
974
|
|
|
1047
|
-
|
|
1048
|
-
interface PublishTarget<TTransaction> {
|
|
1049
|
-
publish<TPayload>(event: DomainEvent<TPayload>, options?: PublishOneOptions<TTransaction>): Promise<EventEnvelope<TPayload>>;
|
|
1050
|
-
publishAll(events: readonly DomainEvent[], options?: PublishOptions<TTransaction>): Promise<EventEnvelope[]>;
|
|
1051
|
-
}
|
|
1052
|
-
/**
|
|
1053
|
-
* A view of a bus that publishes only the events of one catalog, or only the
|
|
1054
|
-
* events a service produces from it. Obtain it with `bus.forCatalog(catalog)`
|
|
1055
|
-
* or `bus.forCatalog(catalog, { events: ['OrderPlaced'] })`. Publishing an
|
|
1056
|
-
* event outside the view fails to compile; a mistyped event that gets past the
|
|
1057
|
-
* compiler (a cast, plain JavaScript, or a class with a structurally identical
|
|
1058
|
-
* payload) is rejected with a {@link ConfigurationError} before anything is stored.
|
|
1059
|
-
*
|
|
1060
|
-
* ```ts
|
|
1061
|
-
* const orders = bus.forCatalog(OrderEvents);
|
|
1062
|
-
* await orders.publish(new OrderPlaced({ orderId }));
|
|
1063
|
-
* await orders.publish(new UserRegistered({ userId })); // compile error
|
|
1064
|
-
* ```
|
|
1065
|
-
*/
|
|
1066
|
-
declare class CatalogPublisher<TCatalog extends Catalog, TTransaction = unknown, TName extends keyof TCatalog = keyof TCatalog> {
|
|
1067
|
-
#private;
|
|
1068
|
-
/**
|
|
1069
|
-
* Throws {@link ConfigurationError} when `catalog` was not created with
|
|
1070
|
-
* `defineCatalog` or `options.events` names no event, an unknown event or
|
|
1071
|
-
* the same event twice.
|
|
1072
|
-
*/
|
|
1073
|
-
constructor(catalog: TCatalog, target: PublishTarget<TTransaction>, options?: CatalogEventSelection<TName>);
|
|
1074
|
-
/** Same as `bus.publish`, limited to the events of the view. */
|
|
1075
|
-
publish<TEvent extends CatalogEvents<TCatalog, TName>>(event: TEvent, options?: PublishOneOptions<TTransaction>): Promise<EventEnvelope<TEvent['payload']>>;
|
|
1076
|
-
/** Same as `bus.publishAll`, limited to the events of the view. Nothing is stored unless every event belongs to it. */
|
|
1077
|
-
publishAll(events: readonly CatalogEvents<TCatalog, TName>[], options?: PublishOptions<TTransaction>): Promise<EventEnvelope[]>;
|
|
1078
|
-
}
|
|
1079
|
-
|
|
1080
|
-
interface InMemoryEventStoreOptions {
|
|
1081
|
-
/** Allow use when `NODE_ENV` is `production`. Data is lost on restart. Default false. */
|
|
1082
|
-
readonly allowInProduction?: boolean;
|
|
1083
|
-
readonly generateIdentifier?: IdentifierGenerator;
|
|
1084
|
-
/**
|
|
1085
|
-
* Keep a record of completed deliveries (status `completed`, listed, counted
|
|
1086
|
-
* and purged by `retention.completed`). Default false: a completed delivery
|
|
1087
|
-
* is deleted, like in the database stores.
|
|
1088
|
-
*/
|
|
1089
|
-
readonly retainCompleted?: boolean;
|
|
1090
|
-
}
|
|
1091
|
-
/** Transaction handle of {@link InMemoryEventStore}. Writes apply on commit only. */
|
|
1092
|
-
declare class InMemoryTransaction {
|
|
1093
|
-
#private;
|
|
1094
|
-
get state(): 'open' | 'committed' | 'rolled-back';
|
|
1095
|
-
enqueue(operation: () => void): void;
|
|
1096
|
-
/** Runs `finisher` once the transaction commits or rolls back, like a lock release. */
|
|
1097
|
-
onFinish(finisher: () => void): void;
|
|
1098
|
-
commit(): void;
|
|
1099
|
-
rollback(): void;
|
|
1100
|
-
}
|
|
1101
|
-
/**
|
|
1102
|
-
* Event store kept in process memory, with the same semantics as the database
|
|
1103
|
-
* stores: transactional appends, leases, fencing and per-key ordering. Payloads
|
|
1104
|
-
* are round-tripped through JSON exactly like a database would store them.
|
|
1105
|
-
* Meant for tests and local development.
|
|
1106
|
-
*/
|
|
1107
|
-
declare class InMemoryEventStore implements EventStore<InMemoryTransaction> {
|
|
1108
|
-
#private;
|
|
1109
|
-
constructor(options?: InMemoryEventStoreOptions);
|
|
1110
|
-
transaction<T>(work: (transaction: InMemoryTransaction) => Promise<T>): Promise<T>;
|
|
1111
|
-
append(transaction: InMemoryTransaction, entries: readonly AppendEntry[], now: Date): Promise<AppendResult>;
|
|
1112
|
-
claim(request: ClaimRequest): Promise<ClaimedDelivery[]>;
|
|
1113
|
-
extendLease(lease: LeaseReference, leaseExpiresAt: Date, now: Date): Promise<boolean>;
|
|
1114
|
-
complete(lease: LeaseReference, now: Date, transaction?: InMemoryTransaction): Promise<boolean>;
|
|
1115
|
-
completeMany(leases: readonly LeaseReference[], now: Date): Promise<boolean[]>;
|
|
1116
|
-
reschedule(lease: LeaseReference, availableAt: Date, error: ErrorInfo, now: Date): Promise<boolean>;
|
|
1117
|
-
release(lease: LeaseReference, now: Date): Promise<boolean>;
|
|
1118
|
-
bury(lease: LeaseReference, error: ErrorInfo, now: Date): Promise<boolean>;
|
|
1119
|
-
listDeliveries(query: DeliveryQuery): Promise<DeliveryRecord[]>;
|
|
1120
|
-
requeue(deliveryIds: readonly string[], now: Date): Promise<number>;
|
|
1121
|
-
purge(request: PurgeRequest): Promise<PurgeResult>;
|
|
1122
|
-
statistics(now: Date): Promise<EventStoreStatistics>;
|
|
1123
|
-
}
|
|
1124
|
-
|
|
1125
|
-
export { type AppendEntry, type AppendResult, type Catalog, type CatalogDeclaration, type CatalogDescription, type CatalogEntry, type CatalogEventClass, type CatalogEventName, type CatalogEventSelection, type CatalogEvents, CatalogPublisher, type CatalogRole, type ClaimRequest, type ClaimedDelivery, type Clock, ConfigurationError, DEFAULT_RETRY_POLICY, DEFAULT_ROUTE_RETRY_POLICY, DELIVERY_STATUSES, type DefineCatalogOptions, type DefineEventOptions, type DeliveryQuery, type DeliveryRecord, type DeliveryStatus, type DispatcherOptions, DispatcherStoppedError, type DomainEvent, type Duration, type ErrorInfo, type EventClass, type EventEnvelope, type EventHandler, type EventHeaders, type EventOf, type EventReference, type EventStore, type EventStoreStatistics, EventValidationError, type FailureStage, type HandlerContext, type HandlerDescriptor, type HandlerShapeOf, HandlerTimeoutError, type HandlersOf, type IdentifierGenerator, InMemoryEventStore, type InMemoryEventStoreOptions, InMemoryTransaction, type InboundSubscriptionOptions, InvalidEnvelopeError, type JitterStrategy, LeaseLostError, type LeaseReference, MAX_TIMER_DELAY_MS, type MatchingHandlers, type NewDelivery, type NoExtraHandlers, NonRetryableError, type PartialHandlersOf, type PayloadOf, type PublishOneOptions, type PublishOptions, type PublishTarget, type PurgeRequest, type PurgeResult, type ReceiveStatus, RelayBus, RelayBusError, type RelayBusLogger, type RelayBusObserver, type RelayBusOptions, type RetentionOptions, type RetryPolicy, type RetryPolicyOptions, type RouteOptions, StandardSchemaV1, type SubscribeCatalogOptions, type SubscribeOptions, type TransactionMode, TransactionRequiredError, type Transport, type TransportMessageHandler, type UnroutedEventPolicy, type ValidationIssue, assertEventType, computeRetryDelay, consume, createRetryPolicy, createUuidV7, defineCatalog, defineEvent, defineHandlers, describeCatalog, isRetryableError, produce, systemClock, toErrorInfo, toMilliseconds, validatePayload };
|
|
975
|
+
export { AppendEntry, AppendResult, type BacklogEvent, type Catalog, type CatalogDeclaration, type CatalogDescription, type CatalogEntry, type CatalogEventClass, type CatalogEventName, type CatalogEventSelection, type CatalogEvents, CatalogPublisher, type CatalogRole, type ClaimFinishedEvent, ClaimRequest, ClaimedDelivery, Clock, DEFAULT_RETRY_POLICY, DEFAULT_ROUTE_RETRY_POLICY, type DefineCatalogOptions, type DeliveryKind, DeliveryQuery, DeliveryRecord, type DispatcherOptions, DomainEvent, Duration, ErrorInfo, EventClass, EventEnvelope, type EventHandler, EventHeaders, type EventOf, EventReference, EventStore, EventStoreStatistics, type FailureStage, type HandlerContext, type HandlerDescriptor, type HandlerFinishedEvent, type HandlerShapeOf, type HandlerStartedEvent, type HandlersOf, type IdentifierGenerator, InMemoryEventStore, type InMemoryEventStoreOptions, InMemoryTransaction, type InboundSubscriptionOptions, type InvalidMessageEvent, type JitterStrategy, LeaseReference, type MatchingHandlers, type NoExtraHandlers, type OperationOutcome, type PartialHandlersOf, PayloadOf, type ProcessTraceInput, type PublishFinishedEvent, type PublishOneOptions, type PublishOptions, type PublishTarget, type PublishTraceInput, PurgeRequest, PurgeResult, type ReceiveFinishedEvent, type ReceiveOutcome, type ReceiveStatus, RelayBus, type RelayBusLogger, type RelayBusObserver, type RelayBusOptions, type RelayBusTracer, type RetentionOptions, type RetryPolicy, type RetryPolicyOptions, type RouteOptions, type SendTraceInput, StandardSchemaV1, type StopOptions, type StopResult, type SubscribeCatalogOptions, type SubscribeOptions, TRACEPARENT_HEADER, TRACESTATE_HEADER, type TraceContext, type TransactionMode, Transport, type TransportSentEvent, type UnroutedEventPolicy, computeRetryDelay, consume, createRetryPolicy, createUuidV7, defineCatalog, defineHandlers, describeCatalog, isRetryableError, produce, traceContextOf };
|