@zdavison/matador-nest 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/dist/constants.d.ts +13 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +12 -0
- package/dist/decorators/index.d.ts +3 -0
- package/dist/decorators/index.d.ts.map +1 -0
- package/dist/decorators/index.js +2 -0
- package/dist/decorators/matador-subscriber.decorator.d.ts +20 -0
- package/dist/decorators/matador-subscriber.decorator.d.ts.map +1 -0
- package/dist/decorators/matador-subscriber.decorator.js +26 -0
- package/dist/decorators/on-matador-event.decorator.d.ts +24 -0
- package/dist/decorators/on-matador-event.decorator.d.ts.map +1 -0
- package/dist/decorators/on-matador-event.decorator.js +38 -0
- package/dist/discovery/index.d.ts +2 -0
- package/dist/discovery/index.d.ts.map +1 -0
- package/dist/discovery/index.js +1 -0
- package/dist/discovery/subscriber-discovery.service.d.ts +37 -0
- package/dist/discovery/subscriber-discovery.service.d.ts.map +1 -0
- package/dist/discovery/subscriber-discovery.service.js +144 -0
- package/dist/index.cjs +495 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/module/index.d.ts +2 -0
- package/dist/module/index.d.ts.map +1 -0
- package/dist/module/index.js +1 -0
- package/dist/module/matador.module.d.ts +71 -0
- package/dist/module/matador.module.d.ts.map +1 -0
- package/dist/module/matador.module.js +146 -0
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +1 -0
- package/dist/services/matador.service.d.ts +105 -0
- package/dist/services/matador.service.d.ts.map +1 -0
- package/dist/services/matador.service.js +209 -0
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +1 -0
- package/dist/testing/matador-testing.module.d.ts +53 -0
- package/dist/testing/matador-testing.module.d.ts.map +1 -0
- package/dist/testing/matador-testing.module.js +77 -0
- package/dist/testing.cjs +498 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +2 -0
- package/dist/testing.d.ts +2 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +2 -0
- package/dist/testing.js.map +1 -0
- package/dist/types.d.ts +88 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/package.json +61 -0
- package/src/constants.ts +14 -0
- package/src/decorators/index.ts +2 -0
- package/src/decorators/matador-subscriber.decorator.ts +27 -0
- package/src/decorators/on-matador-event.decorator.ts +68 -0
- package/src/discovery/index.ts +1 -0
- package/src/discovery/subscriber-discovery.service.ts +181 -0
- package/src/index.ts +28 -0
- package/src/module/index.ts +1 -0
- package/src/module/matador.module.ts +162 -0
- package/src/services/index.ts +1 -0
- package/src/services/matador.service.ts +283 -0
- package/src/testing/index.ts +1 -0
- package/src/testing/matador-testing.module.ts +71 -0
- package/src/testing.ts +2 -0
- package/src/types.ts +119 -0
- package/test/decorators.test.ts +132 -0
- package/test/discovery.test.ts +278 -0
- package/tsconfig.json +32 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/tsup.config.ts +23 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type DynamicModule } from '@nestjs/common';
|
|
2
|
+
import type { MatadorModuleOptions } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Testing module for Matador with sensible defaults for unit/integration tests.
|
|
5
|
+
*
|
|
6
|
+
* Uses LocalTransport by default, which processes messages synchronously
|
|
7
|
+
* in-memory without requiring external infrastructure.
|
|
8
|
+
*
|
|
9
|
+
* @example Basic usage
|
|
10
|
+
* ```typescript
|
|
11
|
+
* describe('NotificationService', () => {
|
|
12
|
+
* let module: TestingModule;
|
|
13
|
+
* let matadorService: MatadorService;
|
|
14
|
+
*
|
|
15
|
+
* beforeEach(async () => {
|
|
16
|
+
* module = await Test.createTestingModule({
|
|
17
|
+
* imports: [MatadorTestingModule.forTest()],
|
|
18
|
+
* providers: [NotificationService],
|
|
19
|
+
* }).compile();
|
|
20
|
+
*
|
|
21
|
+
* matadorService = module.get(MatadorService);
|
|
22
|
+
* await module.init();
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* it('processes events', async () => {
|
|
26
|
+
* await matadorService.send(UserCreatedEvent, { userId: '123' });
|
|
27
|
+
* await matadorService.waitForIdle();
|
|
28
|
+
* // Assert expected behavior
|
|
29
|
+
* });
|
|
30
|
+
* });
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @example With custom overrides
|
|
34
|
+
* ```typescript
|
|
35
|
+
* MatadorTestingModule.forTest({
|
|
36
|
+
* topology: TopologyBuilder.create()
|
|
37
|
+
* .withNamespace('custom-test')
|
|
38
|
+
* .addQueue('my-queue')
|
|
39
|
+
* .build(),
|
|
40
|
+
* consumeFrom: ['my-queue'],
|
|
41
|
+
* })
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare class MatadorTestingModule {
|
|
45
|
+
/**
|
|
46
|
+
* Creates a testing module with LocalTransport and default configuration.
|
|
47
|
+
*
|
|
48
|
+
* @param overrides - Optional overrides for the default configuration
|
|
49
|
+
* @returns Dynamic module configuration
|
|
50
|
+
*/
|
|
51
|
+
static forTest(overrides?: Partial<MatadorModuleOptions>): DynamicModule;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=matador-testing.module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matador-testing.module.d.ts","sourceRoot":"","sources":["../../src/testing/matador-testing.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAU,MAAM,gBAAgB,CAAC;AAG5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAExD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,qBACa,oBAAoB;IAC/B;;;;;OAKG;IACH,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,GAAG,aAAa;CAgBzE"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { Module } from '@nestjs/common';
|
|
8
|
+
import { LocalTransport, TopologyBuilder } from '@zdavison/matador';
|
|
9
|
+
import { MatadorModule } from '../module/matador.module.js';
|
|
10
|
+
/**
|
|
11
|
+
* Testing module for Matador with sensible defaults for unit/integration tests.
|
|
12
|
+
*
|
|
13
|
+
* Uses LocalTransport by default, which processes messages synchronously
|
|
14
|
+
* in-memory without requiring external infrastructure.
|
|
15
|
+
*
|
|
16
|
+
* @example Basic usage
|
|
17
|
+
* ```typescript
|
|
18
|
+
* describe('NotificationService', () => {
|
|
19
|
+
* let module: TestingModule;
|
|
20
|
+
* let matadorService: MatadorService;
|
|
21
|
+
*
|
|
22
|
+
* beforeEach(async () => {
|
|
23
|
+
* module = await Test.createTestingModule({
|
|
24
|
+
* imports: [MatadorTestingModule.forTest()],
|
|
25
|
+
* providers: [NotificationService],
|
|
26
|
+
* }).compile();
|
|
27
|
+
*
|
|
28
|
+
* matadorService = module.get(MatadorService);
|
|
29
|
+
* await module.init();
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* it('processes events', async () => {
|
|
33
|
+
* await matadorService.send(UserCreatedEvent, { userId: '123' });
|
|
34
|
+
* await matadorService.waitForIdle();
|
|
35
|
+
* // Assert expected behavior
|
|
36
|
+
* });
|
|
37
|
+
* });
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* @example With custom overrides
|
|
41
|
+
* ```typescript
|
|
42
|
+
* MatadorTestingModule.forTest({
|
|
43
|
+
* topology: TopologyBuilder.create()
|
|
44
|
+
* .withNamespace('custom-test')
|
|
45
|
+
* .addQueue('my-queue')
|
|
46
|
+
* .build(),
|
|
47
|
+
* consumeFrom: ['my-queue'],
|
|
48
|
+
* })
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
let MatadorTestingModule = class MatadorTestingModule {
|
|
52
|
+
/**
|
|
53
|
+
* Creates a testing module with LocalTransport and default configuration.
|
|
54
|
+
*
|
|
55
|
+
* @param overrides - Optional overrides for the default configuration
|
|
56
|
+
* @returns Dynamic module configuration
|
|
57
|
+
*/
|
|
58
|
+
static forTest(overrides) {
|
|
59
|
+
const defaultOptions = {
|
|
60
|
+
transport: new LocalTransport(),
|
|
61
|
+
topology: TopologyBuilder.create()
|
|
62
|
+
.withNamespace('test')
|
|
63
|
+
.addQueue('events')
|
|
64
|
+
.build(),
|
|
65
|
+
consumeFrom: ['events'],
|
|
66
|
+
autoStart: true,
|
|
67
|
+
};
|
|
68
|
+
return MatadorModule.forRoot({
|
|
69
|
+
...defaultOptions,
|
|
70
|
+
...overrides,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
MatadorTestingModule = __decorate([
|
|
75
|
+
Module({})
|
|
76
|
+
], MatadorTestingModule);
|
|
77
|
+
export { MatadorTestingModule };
|
package/dist/testing.cjs
ADDED
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var common = require('@nestjs/common');
|
|
4
|
+
var matador = require('@zdavison/matador');
|
|
5
|
+
var core = require('@nestjs/core');
|
|
6
|
+
|
|
7
|
+
var __defProp = Object.defineProperty;
|
|
8
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
9
|
+
|
|
10
|
+
// src/constants.ts
|
|
11
|
+
var MATADOR_EVENT_HANDLERS = /* @__PURE__ */ Symbol("MATADOR_EVENT_HANDLERS");
|
|
12
|
+
var MATADOR_OPTIONS = /* @__PURE__ */ Symbol("MATADOR_OPTIONS");
|
|
13
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
14
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
15
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
16
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
17
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
18
|
+
}
|
|
19
|
+
__name(_ts_decorate, "_ts_decorate");
|
|
20
|
+
function _ts_metadata(k, v) {
|
|
21
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
22
|
+
}
|
|
23
|
+
__name(_ts_metadata, "_ts_metadata");
|
|
24
|
+
var SubscriberDiscoveryService = class {
|
|
25
|
+
static {
|
|
26
|
+
__name(this, "SubscriberDiscoveryService");
|
|
27
|
+
}
|
|
28
|
+
discoveryService;
|
|
29
|
+
schema = {};
|
|
30
|
+
discovered = false;
|
|
31
|
+
constructor(discoveryService) {
|
|
32
|
+
this.discoveryService = discoveryService;
|
|
33
|
+
}
|
|
34
|
+
onModuleInit() {
|
|
35
|
+
this.discoverSubscribers();
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Discovers all @OnMatadorEvent decorated methods and builds the schema.
|
|
39
|
+
*/
|
|
40
|
+
discoverSubscribers() {
|
|
41
|
+
if (this.discovered) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const providers = this.discoveryService.getProviders();
|
|
45
|
+
for (const wrapper of providers) {
|
|
46
|
+
const { instance } = wrapper;
|
|
47
|
+
if (!instance || typeof instance !== "object") {
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
const handlers = Reflect.getMetadata(MATADOR_EVENT_HANDLERS, instance.constructor);
|
|
51
|
+
if (!handlers || handlers.length === 0) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
for (const handler of handlers) {
|
|
55
|
+
this.registerHandler(instance, handler);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
this.discovered = true;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Registers a single handler method as a subscriber.
|
|
62
|
+
*/
|
|
63
|
+
registerHandler(instance, metadata) {
|
|
64
|
+
const { eventClass, options, methodName } = metadata;
|
|
65
|
+
const className = instance.constructor.name;
|
|
66
|
+
const subscriberName = options.name ?? `${className}.${methodName}`;
|
|
67
|
+
const isResumable = options.idempotent === "resumable";
|
|
68
|
+
const boundMethod = instance[methodName].bind(instance);
|
|
69
|
+
const subscriber = isResumable ? matador.createSubscriber({
|
|
70
|
+
name: subscriberName,
|
|
71
|
+
description: options.description,
|
|
72
|
+
idempotent: "resumable",
|
|
73
|
+
importance: options.importance,
|
|
74
|
+
targetQueue: options.targetQueue,
|
|
75
|
+
enabled: options.enabled,
|
|
76
|
+
callback: /* @__PURE__ */ __name(async (envelope, context) => {
|
|
77
|
+
await boundMethod(envelope, context);
|
|
78
|
+
}, "callback")
|
|
79
|
+
}) : matador.createSubscriber({
|
|
80
|
+
name: subscriberName,
|
|
81
|
+
description: options.description,
|
|
82
|
+
idempotent: options.idempotent,
|
|
83
|
+
importance: options.importance,
|
|
84
|
+
targetQueue: options.targetQueue,
|
|
85
|
+
enabled: options.enabled,
|
|
86
|
+
callback: /* @__PURE__ */ __name(async (envelope) => {
|
|
87
|
+
await boundMethod(envelope);
|
|
88
|
+
}, "callback")
|
|
89
|
+
});
|
|
90
|
+
this.addToSchema(eventClass, subscriber);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Adds a subscriber to the schema for an event.
|
|
94
|
+
*/
|
|
95
|
+
addToSchema(eventClass, subscriber) {
|
|
96
|
+
const eventKey = eventClass.key;
|
|
97
|
+
const existing = this.schema[eventKey];
|
|
98
|
+
if (existing) {
|
|
99
|
+
const [existingEventClass, existingSubscribers] = existing;
|
|
100
|
+
this.schema[eventKey] = [
|
|
101
|
+
existingEventClass,
|
|
102
|
+
[
|
|
103
|
+
...existingSubscribers,
|
|
104
|
+
subscriber
|
|
105
|
+
]
|
|
106
|
+
];
|
|
107
|
+
} else {
|
|
108
|
+
this.schema[eventKey] = [
|
|
109
|
+
eventClass,
|
|
110
|
+
[
|
|
111
|
+
subscriber
|
|
112
|
+
]
|
|
113
|
+
];
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Gets the discovered schema.
|
|
118
|
+
* Must be called after onModuleInit has run.
|
|
119
|
+
*/
|
|
120
|
+
getSchema() {
|
|
121
|
+
return this.schema;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Gets the schema merged with additional events from options.
|
|
125
|
+
*/
|
|
126
|
+
getMergedSchema(options) {
|
|
127
|
+
const mergedSchema = {
|
|
128
|
+
...this.schema
|
|
129
|
+
};
|
|
130
|
+
if (options.additionalEvents) {
|
|
131
|
+
for (const [eventClass, subscribers] of options.additionalEvents) {
|
|
132
|
+
const existing = mergedSchema[eventClass.key];
|
|
133
|
+
if (existing) {
|
|
134
|
+
const [existingEventClass, existingSubscribers] = existing;
|
|
135
|
+
mergedSchema[eventClass.key] = [
|
|
136
|
+
existingEventClass,
|
|
137
|
+
[
|
|
138
|
+
...existingSubscribers,
|
|
139
|
+
...subscribers
|
|
140
|
+
]
|
|
141
|
+
];
|
|
142
|
+
} else {
|
|
143
|
+
mergedSchema[eventClass.key] = [
|
|
144
|
+
eventClass,
|
|
145
|
+
subscribers
|
|
146
|
+
];
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return mergedSchema;
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
SubscriberDiscoveryService = _ts_decorate([
|
|
154
|
+
common.Injectable(),
|
|
155
|
+
_ts_metadata("design:type", Function),
|
|
156
|
+
_ts_metadata("design:paramtypes", [
|
|
157
|
+
typeof core.DiscoveryService === "undefined" ? Object : core.DiscoveryService
|
|
158
|
+
])
|
|
159
|
+
], SubscriberDiscoveryService);
|
|
160
|
+
function _ts_decorate2(decorators, target, key, desc) {
|
|
161
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
162
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
163
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
164
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
165
|
+
}
|
|
166
|
+
__name(_ts_decorate2, "_ts_decorate");
|
|
167
|
+
function _ts_metadata2(k, v) {
|
|
168
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
169
|
+
}
|
|
170
|
+
__name(_ts_metadata2, "_ts_metadata");
|
|
171
|
+
function _ts_param(paramIndex, decorator) {
|
|
172
|
+
return function(target, key) {
|
|
173
|
+
decorator(target, key, paramIndex);
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
__name(_ts_param, "_ts_param");
|
|
177
|
+
var MatadorService = class _MatadorService {
|
|
178
|
+
static {
|
|
179
|
+
__name(this, "MatadorService");
|
|
180
|
+
}
|
|
181
|
+
options;
|
|
182
|
+
discoveryService;
|
|
183
|
+
logger = new common.Logger(_MatadorService.name);
|
|
184
|
+
matador;
|
|
185
|
+
isShuttingDown = false;
|
|
186
|
+
isStarted = false;
|
|
187
|
+
constructor(options, discoveryService) {
|
|
188
|
+
this.options = options;
|
|
189
|
+
this.discoveryService = discoveryService;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Called when MatadorModule is initialized.
|
|
193
|
+
* Builds Matador instance and starts if startOn === 'onModuleInit'.
|
|
194
|
+
*/
|
|
195
|
+
async onModuleInit() {
|
|
196
|
+
this.initializeMatador();
|
|
197
|
+
if (this.shouldAutoStart() && this.options.startOn === "onModuleInit") {
|
|
198
|
+
await this.doStart();
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Called after all modules are initialized and the app is ready to start.
|
|
203
|
+
* Starts Matador if startOn === 'onApplicationBootstrap' (default).
|
|
204
|
+
*/
|
|
205
|
+
async onApplicationBootstrap() {
|
|
206
|
+
const startOn = this.options.startOn ?? "onApplicationBootstrap";
|
|
207
|
+
if (this.shouldAutoStart() && startOn === "onApplicationBootstrap") {
|
|
208
|
+
await this.doStart();
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Called when MatadorModule is destroyed.
|
|
213
|
+
* Shuts down Matador if shutdownOn === 'onModuleDestroy'.
|
|
214
|
+
*/
|
|
215
|
+
async onModuleDestroy() {
|
|
216
|
+
if (this.options.shutdownOn === "onModuleDestroy") {
|
|
217
|
+
await this.doShutdown();
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Called when the application receives a shutdown signal (SIGTERM, etc).
|
|
222
|
+
* Shuts down Matador if shutdownOn === 'beforeApplicationShutdown' (default).
|
|
223
|
+
*/
|
|
224
|
+
async beforeApplicationShutdown() {
|
|
225
|
+
const shutdownOn = this.options.shutdownOn ?? "beforeApplicationShutdown";
|
|
226
|
+
if (shutdownOn === "beforeApplicationShutdown") {
|
|
227
|
+
await this.doShutdown();
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Called after beforeApplicationShutdown completes.
|
|
232
|
+
* Shuts down Matador if shutdownOn === 'onApplicationShutdown'.
|
|
233
|
+
*/
|
|
234
|
+
async onApplicationShutdown() {
|
|
235
|
+
if (this.options.shutdownOn === "onApplicationShutdown") {
|
|
236
|
+
await this.doShutdown();
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
async send(eventOrClass, dataOrOptions, options) {
|
|
240
|
+
if (this.isShuttingDown) {
|
|
241
|
+
throw new Error("Cannot send events during shutdown");
|
|
242
|
+
}
|
|
243
|
+
const isEventClass = typeof eventOrClass === "function" && "key" in eventOrClass;
|
|
244
|
+
if (isEventClass) {
|
|
245
|
+
return this.matador.send(eventOrClass, dataOrOptions, options);
|
|
246
|
+
}
|
|
247
|
+
return this.matador.send(eventOrClass, dataOrOptions);
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Gets the underlying Matador instance for advanced operations.
|
|
251
|
+
*/
|
|
252
|
+
getMatador() {
|
|
253
|
+
return this.matador;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Starts consuming (if autoStart was false).
|
|
257
|
+
*/
|
|
258
|
+
async start() {
|
|
259
|
+
return this.doStart();
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Checks if connected to transport.
|
|
263
|
+
*/
|
|
264
|
+
isConnected() {
|
|
265
|
+
return this.matador?.isConnected() ?? false;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Checks if shutdown is in progress.
|
|
269
|
+
*/
|
|
270
|
+
isShutdownInProgress() {
|
|
271
|
+
return this.isShuttingDown;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Waits for all pending messages to be processed.
|
|
275
|
+
*/
|
|
276
|
+
async waitForIdle(timeoutMs) {
|
|
277
|
+
return this.matador.waitForIdle(timeoutMs);
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Initializes the Matador instance with discovered schema.
|
|
281
|
+
*/
|
|
282
|
+
initializeMatador() {
|
|
283
|
+
const mergedSchema = this.discoveryService.getMergedSchema(this.options);
|
|
284
|
+
const registry = new matador.SchemaRegistry();
|
|
285
|
+
for (const entry of Object.values(mergedSchema)) {
|
|
286
|
+
if (matador.isSchemaEntryTuple(entry)) {
|
|
287
|
+
const [eventClass, subscribers] = entry;
|
|
288
|
+
registry.register(eventClass, subscribers);
|
|
289
|
+
} else {
|
|
290
|
+
registry.register(entry.eventClass, entry.subscribers);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
const validation = registry.validate();
|
|
294
|
+
if (!validation.valid) {
|
|
295
|
+
const errors = validation.issues.filter((i) => i.severity === "error");
|
|
296
|
+
if (errors.length > 0) {
|
|
297
|
+
throw new Error(`Invalid Matador schema: ${errors.map((i) => i.message).join(", ")}`);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
this.matador = new matador.Matador({
|
|
301
|
+
transport: this.options.transport,
|
|
302
|
+
topology: this.options.topology,
|
|
303
|
+
schema: mergedSchema,
|
|
304
|
+
consumeFrom: this.options.consumeFrom ? [
|
|
305
|
+
...this.options.consumeFrom
|
|
306
|
+
] : void 0,
|
|
307
|
+
codec: this.options.codec,
|
|
308
|
+
retryPolicy: this.options.retryPolicy,
|
|
309
|
+
checkpointStore: this.options.checkpointStore,
|
|
310
|
+
shutdownConfig: this.options.shutdownConfig
|
|
311
|
+
}, this.options.hooks);
|
|
312
|
+
this.logger.log("Matador instance initialized");
|
|
313
|
+
}
|
|
314
|
+
shouldAutoStart() {
|
|
315
|
+
return this.options.autoStart !== false;
|
|
316
|
+
}
|
|
317
|
+
async doStart() {
|
|
318
|
+
if (this.isStarted) {
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
await this.matador.start();
|
|
322
|
+
this.isStarted = true;
|
|
323
|
+
this.logger.log("Matador started");
|
|
324
|
+
}
|
|
325
|
+
async doShutdown() {
|
|
326
|
+
if (!this.isStarted || this.isShuttingDown) {
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
this.isShuttingDown = true;
|
|
330
|
+
this.logger.log("Graceful shutdown initiated, draining in-flight messages");
|
|
331
|
+
const timeoutMs = this.options.shutdownConfig?.gracefulShutdownTimeout ?? 3e4;
|
|
332
|
+
const drained = await this.matador.waitForIdle(timeoutMs);
|
|
333
|
+
if (!drained) {
|
|
334
|
+
this.logger.warn(`Shutdown timeout reached after ${timeoutMs}ms, some messages may not have completed`);
|
|
335
|
+
}
|
|
336
|
+
await this.matador.shutdown();
|
|
337
|
+
this.logger.log("Matador shutdown complete");
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
MatadorService = _ts_decorate2([
|
|
341
|
+
common.Injectable(),
|
|
342
|
+
_ts_param(0, common.Inject(MATADOR_OPTIONS)),
|
|
343
|
+
_ts_metadata2("design:type", Function),
|
|
344
|
+
_ts_metadata2("design:paramtypes", [
|
|
345
|
+
typeof MatadorModuleOptions === "undefined" ? Object : MatadorModuleOptions,
|
|
346
|
+
typeof SubscriberDiscoveryService === "undefined" ? Object : SubscriberDiscoveryService
|
|
347
|
+
])
|
|
348
|
+
], MatadorService);
|
|
349
|
+
|
|
350
|
+
// src/module/matador.module.ts
|
|
351
|
+
function _ts_decorate3(decorators, target, key, desc) {
|
|
352
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
353
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
354
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
355
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
356
|
+
}
|
|
357
|
+
__name(_ts_decorate3, "_ts_decorate");
|
|
358
|
+
var MatadorModule = class _MatadorModule {
|
|
359
|
+
static {
|
|
360
|
+
__name(this, "MatadorModule");
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Configures the MatadorModule with static options.
|
|
364
|
+
*
|
|
365
|
+
* @param options - Module configuration options
|
|
366
|
+
* @returns Dynamic module configuration
|
|
367
|
+
*/
|
|
368
|
+
static forRoot(options) {
|
|
369
|
+
return {
|
|
370
|
+
module: _MatadorModule,
|
|
371
|
+
imports: [
|
|
372
|
+
core.DiscoveryModule
|
|
373
|
+
],
|
|
374
|
+
providers: [
|
|
375
|
+
{
|
|
376
|
+
provide: MATADOR_OPTIONS,
|
|
377
|
+
useValue: options
|
|
378
|
+
},
|
|
379
|
+
core.DiscoveryService,
|
|
380
|
+
SubscriberDiscoveryService,
|
|
381
|
+
MatadorService
|
|
382
|
+
],
|
|
383
|
+
exports: [
|
|
384
|
+
MatadorService
|
|
385
|
+
]
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Configures the MatadorModule with async options.
|
|
390
|
+
* Use this when you need to inject dependencies like ConfigService.
|
|
391
|
+
*
|
|
392
|
+
* @param options - Async module configuration options
|
|
393
|
+
* @returns Dynamic module configuration
|
|
394
|
+
*/
|
|
395
|
+
static forRootAsync(options) {
|
|
396
|
+
const asyncProviders = this.createAsyncProviders(options);
|
|
397
|
+
return {
|
|
398
|
+
module: _MatadorModule,
|
|
399
|
+
imports: [
|
|
400
|
+
core.DiscoveryModule,
|
|
401
|
+
...options.imports ?? []
|
|
402
|
+
],
|
|
403
|
+
providers: [
|
|
404
|
+
...asyncProviders,
|
|
405
|
+
core.DiscoveryService,
|
|
406
|
+
SubscriberDiscoveryService,
|
|
407
|
+
MatadorService
|
|
408
|
+
],
|
|
409
|
+
exports: [
|
|
410
|
+
MatadorService
|
|
411
|
+
]
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Creates async providers for the module options.
|
|
416
|
+
*/
|
|
417
|
+
static createAsyncProviders(options) {
|
|
418
|
+
if (options.useFactory) {
|
|
419
|
+
return [
|
|
420
|
+
{
|
|
421
|
+
provide: MATADOR_OPTIONS,
|
|
422
|
+
useFactory: options.useFactory,
|
|
423
|
+
inject: options.inject ?? []
|
|
424
|
+
}
|
|
425
|
+
];
|
|
426
|
+
}
|
|
427
|
+
if (options.useClass) {
|
|
428
|
+
return [
|
|
429
|
+
{
|
|
430
|
+
provide: options.useClass,
|
|
431
|
+
useClass: options.useClass
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
provide: MATADOR_OPTIONS,
|
|
435
|
+
useFactory: /* @__PURE__ */ __name(async (factory) => factory.createMatadorOptions(), "useFactory"),
|
|
436
|
+
inject: [
|
|
437
|
+
options.useClass
|
|
438
|
+
]
|
|
439
|
+
}
|
|
440
|
+
];
|
|
441
|
+
}
|
|
442
|
+
if (options.useExisting) {
|
|
443
|
+
return [
|
|
444
|
+
{
|
|
445
|
+
provide: MATADOR_OPTIONS,
|
|
446
|
+
useFactory: /* @__PURE__ */ __name(async (factory) => factory.createMatadorOptions(), "useFactory"),
|
|
447
|
+
inject: [
|
|
448
|
+
options.useExisting
|
|
449
|
+
]
|
|
450
|
+
}
|
|
451
|
+
];
|
|
452
|
+
}
|
|
453
|
+
throw new Error("MatadorModule.forRootAsync() requires useFactory, useClass, or useExisting");
|
|
454
|
+
}
|
|
455
|
+
};
|
|
456
|
+
MatadorModule = _ts_decorate3([
|
|
457
|
+
common.Global(),
|
|
458
|
+
common.Module({})
|
|
459
|
+
], MatadorModule);
|
|
460
|
+
|
|
461
|
+
// src/testing/matador-testing.module.ts
|
|
462
|
+
function _ts_decorate4(decorators, target, key, desc) {
|
|
463
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
464
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
465
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
466
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
467
|
+
}
|
|
468
|
+
__name(_ts_decorate4, "_ts_decorate");
|
|
469
|
+
exports.MatadorTestingModule = class MatadorTestingModule {
|
|
470
|
+
static {
|
|
471
|
+
__name(this, "MatadorTestingModule");
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Creates a testing module with LocalTransport and default configuration.
|
|
475
|
+
*
|
|
476
|
+
* @param overrides - Optional overrides for the default configuration
|
|
477
|
+
* @returns Dynamic module configuration
|
|
478
|
+
*/
|
|
479
|
+
static forTest(overrides) {
|
|
480
|
+
const defaultOptions = {
|
|
481
|
+
transport: new matador.LocalTransport(),
|
|
482
|
+
topology: matador.TopologyBuilder.create().withNamespace("test").addQueue("events").build(),
|
|
483
|
+
consumeFrom: [
|
|
484
|
+
"events"
|
|
485
|
+
],
|
|
486
|
+
autoStart: true
|
|
487
|
+
};
|
|
488
|
+
return MatadorModule.forRoot({
|
|
489
|
+
...defaultOptions,
|
|
490
|
+
...overrides
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
};
|
|
494
|
+
exports.MatadorTestingModule = _ts_decorate4([
|
|
495
|
+
common.Module({})
|
|
496
|
+
], exports.MatadorTestingModule);
|
|
497
|
+
//# sourceMappingURL=testing.cjs.map
|
|
498
|
+
//# sourceMappingURL=testing.cjs.map
|