@zdavison/matador 2.0.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/cli.ts +453 -0
- package/dist/checkpoint/context.d.ts +59 -0
- package/dist/checkpoint/context.d.ts.map +1 -0
- package/dist/checkpoint/context.js +140 -0
- package/dist/checkpoint/context.test.d.ts +2 -0
- package/dist/checkpoint/context.test.d.ts.map +1 -0
- package/dist/checkpoint/context.test.js +424 -0
- package/dist/checkpoint/index.d.ts +7 -0
- package/dist/checkpoint/index.d.ts.map +1 -0
- package/dist/checkpoint/index.js +6 -0
- package/dist/checkpoint/stores/memory.d.ts +29 -0
- package/dist/checkpoint/stores/memory.d.ts.map +1 -0
- package/dist/checkpoint/stores/memory.js +39 -0
- package/dist/checkpoint/stores/noop.d.ts +14 -0
- package/dist/checkpoint/stores/noop.d.ts.map +1 -0
- package/dist/checkpoint/stores/noop.js +18 -0
- package/dist/checkpoint/stores/stores.test.d.ts +2 -0
- package/dist/checkpoint/stores/stores.test.d.ts.map +1 -0
- package/dist/checkpoint/stores/stores.test.js +146 -0
- package/dist/checkpoint/types.d.ts +119 -0
- package/dist/checkpoint/types.d.ts.map +1 -0
- package/dist/checkpoint/types.js +1 -0
- package/dist/codec/codec.d.ts +29 -0
- package/dist/codec/codec.d.ts.map +1 -0
- package/dist/codec/codec.js +15 -0
- package/dist/codec/header-aware-codec.d.ts +36 -0
- package/dist/codec/header-aware-codec.d.ts.map +1 -0
- package/dist/codec/header-aware-codec.js +1 -0
- package/dist/codec/index.d.ts +6 -0
- package/dist/codec/index.d.ts.map +1 -0
- package/dist/codec/index.js +3 -0
- package/dist/codec/json-codec.d.ts +13 -0
- package/dist/codec/json-codec.d.ts.map +1 -0
- package/dist/codec/json-codec.js +64 -0
- package/dist/codec/rabbitmq-codec.d.ts +28 -0
- package/dist/codec/rabbitmq-codec.d.ts.map +1 -0
- package/dist/codec/rabbitmq-codec.js +242 -0
- package/dist/codec/rabbitmq-codec.test.d.ts +2 -0
- package/dist/codec/rabbitmq-codec.test.d.ts.map +1 -0
- package/dist/codec/rabbitmq-codec.test.js +433 -0
- package/dist/core/fanout.d.ts +59 -0
- package/dist/core/fanout.d.ts.map +1 -0
- package/dist/core/fanout.js +121 -0
- package/dist/core/fanout.test.d.ts +2 -0
- package/dist/core/fanout.test.d.ts.map +1 -0
- package/dist/core/fanout.test.js +1055 -0
- package/dist/core/index.d.ts +7 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +3 -0
- package/dist/core/matador.d.ts +133 -0
- package/dist/core/matador.d.ts.map +1 -0
- package/dist/core/matador.js +222 -0
- package/dist/core/matador.test.d.ts +2 -0
- package/dist/core/matador.test.d.ts.map +1 -0
- package/dist/core/matador.test.js +446 -0
- package/dist/core/shutdown.d.ts +78 -0
- package/dist/core/shutdown.d.ts.map +1 -0
- package/dist/core/shutdown.js +111 -0
- package/dist/core/shutdown.test.d.ts +2 -0
- package/dist/core/shutdown.test.d.ts.map +1 -0
- package/dist/core/shutdown.test.js +524 -0
- package/dist/errors/checkpoint-errors.d.ts +30 -0
- package/dist/errors/checkpoint-errors.d.ts.map +1 -0
- package/dist/errors/checkpoint-errors.js +49 -0
- package/dist/errors/has-description.d.ts +18 -0
- package/dist/errors/has-description.d.ts.map +1 -0
- package/dist/errors/has-description.js +9 -0
- package/dist/errors/index.d.ts +6 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +22 -0
- package/dist/errors/matador-errors.d.ts +183 -0
- package/dist/errors/matador-errors.d.ts.map +1 -0
- package/dist/errors/matador-errors.js +376 -0
- package/dist/errors/retry-errors.d.ts +67 -0
- package/dist/errors/retry-errors.d.ts.map +1 -0
- package/dist/errors/retry-errors.js +108 -0
- package/dist/hooks/index.d.ts +4 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +2 -0
- package/dist/hooks/safe-hooks.d.ts +34 -0
- package/dist/hooks/safe-hooks.d.ts.map +1 -0
- package/dist/hooks/safe-hooks.js +135 -0
- package/dist/hooks/types.d.ts +189 -0
- package/dist/hooks/types.d.ts.map +1 -0
- package/dist/hooks/types.js +9 -0
- package/dist/index.cjs +3156 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +23 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/pipeline/index.d.ts +3 -0
- package/dist/pipeline/index.d.ts.map +1 -0
- package/dist/pipeline/index.js +1 -0
- package/dist/pipeline/pipeline.d.ts +60 -0
- package/dist/pipeline/pipeline.d.ts.map +1 -0
- package/dist/pipeline/pipeline.js +261 -0
- package/dist/pipeline/pipeline.test.d.ts +2 -0
- package/dist/pipeline/pipeline.test.d.ts.map +1 -0
- package/dist/pipeline/pipeline.test.js +1065 -0
- package/dist/retry/index.d.ts +4 -0
- package/dist/retry/index.d.ts.map +1 -0
- package/dist/retry/index.js +1 -0
- package/dist/retry/policy.d.ts +43 -0
- package/dist/retry/policy.d.ts.map +1 -0
- package/dist/retry/policy.js +1 -0
- package/dist/retry/standard-policy.d.ts +44 -0
- package/dist/retry/standard-policy.d.ts.map +1 -0
- package/dist/retry/standard-policy.js +102 -0
- package/dist/retry/standard-policy.test.d.ts +2 -0
- package/dist/retry/standard-policy.test.d.ts.map +1 -0
- package/dist/retry/standard-policy.test.js +190 -0
- package/dist/schema/index.d.ts +4 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +2 -0
- package/dist/schema/registry.d.ts +63 -0
- package/dist/schema/registry.d.ts.map +1 -0
- package/dist/schema/registry.js +171 -0
- package/dist/schema/registry.test.d.ts +2 -0
- package/dist/schema/registry.test.d.ts.map +1 -0
- package/dist/schema/registry.test.js +278 -0
- package/dist/schema/types.d.ts +158 -0
- package/dist/schema/types.d.ts.map +1 -0
- package/dist/schema/types.js +74 -0
- package/dist/schema/types.test.d.ts +2 -0
- package/dist/schema/types.test.d.ts.map +1 -0
- package/dist/schema/types.test.js +243 -0
- package/dist/topology/builder.d.ts +66 -0
- package/dist/topology/builder.d.ts.map +1 -0
- package/dist/topology/builder.js +156 -0
- package/dist/topology/builder.test.d.ts +2 -0
- package/dist/topology/builder.test.d.ts.map +1 -0
- package/dist/topology/builder.test.js +222 -0
- package/dist/topology/index.d.ts +5 -0
- package/dist/topology/index.d.ts.map +1 -0
- package/dist/topology/index.js +2 -0
- package/dist/topology/types.d.ts +76 -0
- package/dist/topology/types.d.ts.map +1 -0
- package/dist/topology/types.js +18 -0
- package/dist/transport/capabilities.d.ts +66 -0
- package/dist/transport/capabilities.d.ts.map +1 -0
- package/dist/transport/capabilities.js +18 -0
- package/dist/transport/connection-manager.d.ts +95 -0
- package/dist/transport/connection-manager.d.ts.map +1 -0
- package/dist/transport/connection-manager.js +144 -0
- package/dist/transport/index.d.ts +11 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/index.js +5 -0
- package/dist/transport/local/local-transport.d.ts +62 -0
- package/dist/transport/local/local-transport.d.ts.map +1 -0
- package/dist/transport/local/local-transport.js +241 -0
- package/dist/transport/local/local-transport.test.d.ts +2 -0
- package/dist/transport/local/local-transport.test.d.ts.map +1 -0
- package/dist/transport/local/local-transport.test.js +192 -0
- package/dist/transport/multi/multi-transport.d.ts +94 -0
- package/dist/transport/multi/multi-transport.d.ts.map +1 -0
- package/dist/transport/multi/multi-transport.js +184 -0
- package/dist/transport/multi/multi-transport.test.d.ts +2 -0
- package/dist/transport/multi/multi-transport.test.d.ts.map +1 -0
- package/dist/transport/multi/multi-transport.test.js +236 -0
- package/dist/transport/rabbitmq/rabbitmq-transport.d.ts +73 -0
- package/dist/transport/rabbitmq/rabbitmq-transport.d.ts.map +1 -0
- package/dist/transport/rabbitmq/rabbitmq-transport.js +518 -0
- package/dist/transport/transport.d.ts +152 -0
- package/dist/transport/transport.d.ts.map +1 -0
- package/dist/transport/transport.js +1 -0
- package/dist/types/common.d.ts +41 -0
- package/dist/types/common.d.ts.map +1 -0
- package/dist/types/common.js +12 -0
- package/dist/types/envelope.d.ts +82 -0
- package/dist/types/envelope.d.ts.map +1 -0
- package/dist/types/envelope.js +36 -0
- package/dist/types/event.d.ts +96 -0
- package/dist/types/event.d.ts.map +1 -0
- package/dist/types/event.js +26 -0
- package/dist/types/event.test.d.ts +2 -0
- package/dist/types/event.test.d.ts.map +1 -0
- package/dist/types/event.test.js +130 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +4 -0
- package/dist/types/subscriber.d.ts +207 -0
- package/dist/types/subscriber.d.ts.map +1 -0
- package/dist/types/subscriber.js +99 -0
- package/examples/config.ts +126 -0
- package/examples/event.ts +26 -0
- package/examples/order-event.json +19 -0
- package/package.json +66 -0
- package/src/checkpoint/context.test.ts +510 -0
- package/src/checkpoint/context.ts +213 -0
- package/src/checkpoint/index.ts +30 -0
- package/src/checkpoint/stores/memory.ts +47 -0
- package/src/checkpoint/stores/noop.ts +22 -0
- package/src/checkpoint/stores/stores.test.ts +177 -0
- package/src/checkpoint/types.ts +147 -0
- package/src/codec/codec.ts +42 -0
- package/src/codec/header-aware-codec.ts +41 -0
- package/src/codec/index.ts +11 -0
- package/src/codec/json-codec.ts +69 -0
- package/src/codec/rabbitmq-codec.test.ts +516 -0
- package/src/codec/rabbitmq-codec.ts +336 -0
- package/src/core/fanout.test.ts +1351 -0
- package/src/core/fanout.ts +184 -0
- package/src/core/index.ts +12 -0
- package/src/core/matador.test.ts +575 -0
- package/src/core/matador.ts +344 -0
- package/src/core/shutdown.test.ts +853 -0
- package/src/core/shutdown.ts +165 -0
- package/src/errors/checkpoint-errors.ts +62 -0
- package/src/errors/has-description.ts +25 -0
- package/src/errors/index.ts +57 -0
- package/src/errors/matador-errors.ts +477 -0
- package/src/errors/retry-errors.ts +134 -0
- package/src/hooks/index.ts +15 -0
- package/src/hooks/safe-hooks.ts +223 -0
- package/src/hooks/types.ts +248 -0
- package/src/index.ts +231 -0
- package/src/pipeline/index.ts +2 -0
- package/src/pipeline/pipeline.test.ts +1317 -0
- package/src/pipeline/pipeline.ts +371 -0
- package/src/retry/index.ts +4 -0
- package/src/retry/policy.ts +46 -0
- package/src/retry/standard-policy.test.ts +282 -0
- package/src/retry/standard-policy.ts +156 -0
- package/src/schema/index.ts +16 -0
- package/src/schema/registry.test.ts +339 -0
- package/src/schema/registry.ts +226 -0
- package/src/schema/types.test.ts +281 -0
- package/src/schema/types.ts +217 -0
- package/src/topology/builder.test.ts +275 -0
- package/src/topology/builder.ts +199 -0
- package/src/topology/index.ts +15 -0
- package/src/topology/types.ts +109 -0
- package/src/transport/capabilities.ts +88 -0
- package/src/transport/connection-manager.ts +218 -0
- package/src/transport/index.ts +42 -0
- package/src/transport/local/local-transport.test.ts +262 -0
- package/src/transport/local/local-transport.ts +327 -0
- package/src/transport/multi/multi-transport.test.ts +320 -0
- package/src/transport/multi/multi-transport.ts +294 -0
- package/src/transport/rabbitmq/rabbitmq-transport.ts +753 -0
- package/src/transport/transport.ts +200 -0
- package/src/types/common.ts +53 -0
- package/src/types/envelope.ts +152 -0
- package/src/types/event.test.ts +157 -0
- package/src/types/event.ts +118 -0
- package/src/types/index.ts +52 -0
- package/src/types/subscriber.ts +310 -0
- package/test/e2e/multi-transport.e2e.test.ts +236 -0
- package/test/e2e/rabbitmq-transport.e2e.test.ts +327 -0
- package/test/e2e/transport-compliance.e2e.test.ts +505 -0
- package/test/integration/matador.integration.test.ts +634 -0
- package/tsconfig.json +29 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/tsup.config.ts +13 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { TransportSendError } from '../errors/index.js';
|
|
2
|
+
import type { SafeHooks } from '../hooks/index.js';
|
|
3
|
+
import type { SchemaRegistry } from '../schema/index.js';
|
|
4
|
+
import { getQualifiedQueueName } from '../topology/index.js';
|
|
5
|
+
import type { Transport } from '../transport/index.js';
|
|
6
|
+
import type {
|
|
7
|
+
AnySubscriber,
|
|
8
|
+
Event,
|
|
9
|
+
EventClass,
|
|
10
|
+
EventOptions,
|
|
11
|
+
} from '../types/index.js';
|
|
12
|
+
import { createEnvelope } from '../types/index.js';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Configuration for the fanout engine.
|
|
16
|
+
*/
|
|
17
|
+
export interface FanoutConfig {
|
|
18
|
+
readonly transport: Transport;
|
|
19
|
+
readonly schema: SchemaRegistry;
|
|
20
|
+
readonly hooks: SafeHooks;
|
|
21
|
+
readonly namespace: string;
|
|
22
|
+
readonly defaultQueue: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Result of sending an event.
|
|
27
|
+
*/
|
|
28
|
+
export interface SendResult {
|
|
29
|
+
readonly eventKey: string;
|
|
30
|
+
readonly subscribersSent: number;
|
|
31
|
+
readonly subscribersSkipped: number;
|
|
32
|
+
readonly errors: readonly SendError[];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Error during send.
|
|
37
|
+
*/
|
|
38
|
+
export interface SendError {
|
|
39
|
+
readonly subscriberName: string;
|
|
40
|
+
readonly queue: string;
|
|
41
|
+
readonly error: Error;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Engine for fanning out events to subscribers.
|
|
46
|
+
*
|
|
47
|
+
* Handles:
|
|
48
|
+
* 1. Getting subscribers from schema
|
|
49
|
+
* 2. Filtering by enabled() hook
|
|
50
|
+
* 3. Creating envelopes for each subscriber
|
|
51
|
+
* 4. Sending to appropriate queues via transport
|
|
52
|
+
*/
|
|
53
|
+
export class FanoutEngine {
|
|
54
|
+
private readonly transport: Transport;
|
|
55
|
+
private readonly schema: SchemaRegistry;
|
|
56
|
+
private readonly hooks: SafeHooks;
|
|
57
|
+
private readonly namespace: string;
|
|
58
|
+
private readonly defaultQueue: string;
|
|
59
|
+
private enqueuingCount = 0;
|
|
60
|
+
|
|
61
|
+
constructor(config: FanoutConfig) {
|
|
62
|
+
this.transport = config.transport;
|
|
63
|
+
this.schema = config.schema;
|
|
64
|
+
this.hooks = config.hooks;
|
|
65
|
+
this.namespace = config.namespace;
|
|
66
|
+
this.defaultQueue = config.defaultQueue;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Current count of events being enqueued.
|
|
71
|
+
*/
|
|
72
|
+
get eventsBeingEnqueuedCount(): number {
|
|
73
|
+
return this.enqueuingCount;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Sends an event to all registered subscribers.
|
|
78
|
+
*/
|
|
79
|
+
async send<T>(
|
|
80
|
+
eventClass: EventClass<T>,
|
|
81
|
+
event: Event<T>,
|
|
82
|
+
options: EventOptions = {},
|
|
83
|
+
): Promise<SendResult> {
|
|
84
|
+
const eventKey = eventClass.key;
|
|
85
|
+
const subscribers = this.schema.getSubscribers(eventKey);
|
|
86
|
+
|
|
87
|
+
const errors: SendError[] = [];
|
|
88
|
+
let sent = 0;
|
|
89
|
+
let skipped = 0;
|
|
90
|
+
|
|
91
|
+
// Load universal metadata
|
|
92
|
+
const universalMetadata = await this.hooks.loadUniversalMetadata();
|
|
93
|
+
|
|
94
|
+
// Merge event.metadata with options.metadata (options takes precedence)
|
|
95
|
+
const mergedMetadata =
|
|
96
|
+
event.metadata || options.metadata
|
|
97
|
+
? { ...event.metadata, ...options.metadata }
|
|
98
|
+
: undefined;
|
|
99
|
+
|
|
100
|
+
for (const subscriber of subscribers) {
|
|
101
|
+
// Check if subscriber is enabled
|
|
102
|
+
const enabled = await this.isSubscriberEnabled(subscriber);
|
|
103
|
+
if (!enabled) {
|
|
104
|
+
skipped++;
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Determine target queue
|
|
109
|
+
const targetQueue = subscriber.targetQueue ?? this.defaultQueue;
|
|
110
|
+
const qualifiedQueue = getQualifiedQueueName(this.namespace, targetQueue);
|
|
111
|
+
|
|
112
|
+
// Create envelope
|
|
113
|
+
const envelope = createEnvelope({
|
|
114
|
+
eventKey,
|
|
115
|
+
eventDescription: eventClass.description,
|
|
116
|
+
targetSubscriber: subscriber.name,
|
|
117
|
+
data: event.data,
|
|
118
|
+
importance: subscriber.importance ?? 'should-investigate',
|
|
119
|
+
correlationId: options.correlationId,
|
|
120
|
+
metadata: mergedMetadata,
|
|
121
|
+
universalMetadata,
|
|
122
|
+
delayMs: options.delayMs,
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// Send to transport
|
|
126
|
+
this.enqueuingCount++;
|
|
127
|
+
try {
|
|
128
|
+
const usedTransport = await this.transport.send(
|
|
129
|
+
qualifiedQueue,
|
|
130
|
+
envelope,
|
|
131
|
+
options.delayMs !== undefined
|
|
132
|
+
? { delay: options.delayMs }
|
|
133
|
+
: undefined,
|
|
134
|
+
);
|
|
135
|
+
sent++;
|
|
136
|
+
|
|
137
|
+
await this.hooks.onEnqueueSuccess({
|
|
138
|
+
envelope,
|
|
139
|
+
queue: qualifiedQueue,
|
|
140
|
+
transport: usedTransport,
|
|
141
|
+
});
|
|
142
|
+
} catch (error) {
|
|
143
|
+
const cause = error instanceof Error ? error : new Error(String(error));
|
|
144
|
+
const err = new TransportSendError(qualifiedQueue, cause);
|
|
145
|
+
errors.push({
|
|
146
|
+
subscriberName: subscriber.name,
|
|
147
|
+
queue: qualifiedQueue,
|
|
148
|
+
error: err,
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
await this.hooks.onEnqueueError({
|
|
152
|
+
envelope,
|
|
153
|
+
error: err,
|
|
154
|
+
transport: this.transport.name,
|
|
155
|
+
});
|
|
156
|
+
} finally {
|
|
157
|
+
this.enqueuingCount--;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return {
|
|
162
|
+
eventKey,
|
|
163
|
+
subscribersSent: sent,
|
|
164
|
+
subscribersSkipped: skipped,
|
|
165
|
+
errors,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
private async isSubscriberEnabled(
|
|
170
|
+
subscriber: AnySubscriber,
|
|
171
|
+
): Promise<boolean> {
|
|
172
|
+
if (!subscriber.enabled) {
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
try {
|
|
177
|
+
const result = await subscriber.enabled();
|
|
178
|
+
return result;
|
|
179
|
+
} catch {
|
|
180
|
+
// If enabled check fails, consider it enabled
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type { SendError, SendResult, FanoutConfig } from './fanout.js';
|
|
2
|
+
export { FanoutEngine } from './fanout.js';
|
|
3
|
+
|
|
4
|
+
export type {
|
|
5
|
+
HandlersState,
|
|
6
|
+
ShutdownConfig,
|
|
7
|
+
ShutdownState,
|
|
8
|
+
} from './shutdown.js';
|
|
9
|
+
export { defaultShutdownConfig, ShutdownManager } from './shutdown.js';
|
|
10
|
+
|
|
11
|
+
export type { MatadorConfig } from './matador.js';
|
|
12
|
+
export { Matador } from './matador.js';
|