@nextage/era-lib 1.0.176 → 1.0.178
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/build/events/base-event.controller.d.ts +56 -15
- package/build/events/base-event.controller.d.ts.map +1 -1
- package/build/events/base-event.controller.js +98 -32
- package/build/events/base-event.controller.js.map +1 -1
- package/build/events/event-relay.d.ts +26 -0
- package/build/events/event-relay.d.ts.map +1 -0
- package/build/events/event-relay.js +95 -0
- package/build/events/event-relay.js.map +1 -0
- package/build/events/field-map.d.ts +9 -0
- package/build/events/field-map.d.ts.map +1 -0
- package/build/events/field-map.js +26 -0
- package/build/events/field-map.js.map +1 -0
- package/build/events/index.d.ts +3 -0
- package/build/events/index.d.ts.map +1 -1
- package/build/events/index.js +3 -0
- package/build/events/index.js.map +1 -1
- package/build/events/publisher-registry.d.ts +21 -0
- package/build/events/publisher-registry.d.ts.map +1 -0
- package/build/events/publisher-registry.js +46 -0
- package/build/events/publisher-registry.js.map +1 -0
- package/build/events/types/index.d.ts +2 -0
- package/build/events/types/index.d.ts.map +1 -1
- package/build/events/types/index.js +2 -0
- package/build/events/types/index.js.map +1 -1
- package/build/events/types/outbox.interfaces.d.ts +10 -0
- package/build/events/types/outbox.interfaces.d.ts.map +1 -1
- package/build/events/types/relay.constants.d.ts +3 -0
- package/build/events/types/relay.constants.d.ts.map +1 -0
- package/build/events/types/relay.constants.js +9 -0
- package/build/events/types/relay.constants.js.map +1 -0
- package/build/events/types/relay.interfaces.d.ts +11 -0
- package/build/events/types/relay.interfaces.d.ts.map +1 -0
- package/build/events/types/relay.interfaces.js +5 -0
- package/build/events/types/relay.interfaces.js.map +1 -0
- package/package.json +1 -1
|
@@ -3,14 +3,42 @@ import { BaseMongoDoc } from '@nextage/nx-frame-be/build/common/base/base.interf
|
|
|
3
3
|
import { BaseController } from '@nextage/nx-frame-be/build/common/base/base.controller';
|
|
4
4
|
import { NxContext } from '@nextage/nx-frame-be';
|
|
5
5
|
import { Event, IPublisher } from './interfaces';
|
|
6
|
+
import { PublisherProvider } from './types/relay.interfaces';
|
|
6
7
|
import { QueueEventType } from './types/enums';
|
|
7
|
-
export declare abstract class BaseEventCtrl<TCreate extends Event, TUpdate extends Event, TRemove extends Event, TAttrs, TDoc extends BaseMongoDoc, TModel extends BaseModel<TAttrs, TDoc, any>> extends BaseController<TAttrs, TDoc, TModel> {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
export declare abstract class BaseEventCtrl<TCreate extends Event, TUpdate extends Event, TRemove extends Event, TAttrs, TDoc extends BaseMongoDoc, TModel extends BaseModel<TAttrs, TDoc, any>> extends BaseController<TAttrs, TDoc, TModel> implements PublisherProvider {
|
|
9
|
+
/**
|
|
10
|
+
* Declarative publish field-map (Step 3.4c). The default parsePub* methods pick
|
|
11
|
+
* exactly these keys from the entity, replacing the ~57 hand-written per-controller
|
|
12
|
+
* parsers. `pubFields` drives BOTH create and update; set `pubUpdateFields` only
|
|
13
|
+
* for the rare create ≠ update case; `pubRemoveFields` is the leaner remove subset.
|
|
14
|
+
* A subclass may still OVERRIDE parsePub* directly for non-pick (computed) payloads.
|
|
15
|
+
*/
|
|
16
|
+
protected pubFields: (keyof TAttrs)[];
|
|
17
|
+
protected pubUpdateFields?: (keyof TAttrs)[];
|
|
18
|
+
protected pubRemoveFields: (keyof TAttrs)[];
|
|
19
|
+
/**
|
|
20
|
+
* Default create/update/remove parsers: a pure pick over the declared field-map.
|
|
21
|
+
* Overridable when a payload needs computed values (see e.g. i18n-shaped events).
|
|
22
|
+
*
|
|
23
|
+
* @param item
|
|
24
|
+
* @param type
|
|
25
|
+
*/
|
|
26
|
+
protected parsePubCreateItem(item: TAttrs, type: QueueEventType): TCreate['data'];
|
|
27
|
+
protected parsePubUpdateItem(item: TAttrs, type: QueueEventType): TUpdate['data'];
|
|
28
|
+
protected parsePubRemoveItem(item: TAttrs, type: QueueEventType): TRemove['data'];
|
|
11
29
|
protected abstract createPublisher: IPublisher<TCreate>[];
|
|
12
30
|
protected abstract updatePublisher: IPublisher<TUpdate>[];
|
|
13
31
|
protected abstract removePublisher: IPublisher<TRemove>[];
|
|
32
|
+
constructor(config: {
|
|
33
|
+
model: TModel;
|
|
34
|
+
mergeUpdate?: boolean;
|
|
35
|
+
});
|
|
36
|
+
/**
|
|
37
|
+
* All publishers this controller owns (create + update + remove). Read LAZILY by
|
|
38
|
+
* the relay's publisher registry to route a `sent:false` outbox row back to its
|
|
39
|
+
* publisher family by subject — so it runs after the subclass field initialisers.
|
|
40
|
+
*/
|
|
41
|
+
eventPublishers(): IPublisher<Event>[];
|
|
14
42
|
private publishConfig?;
|
|
15
43
|
/**
|
|
16
44
|
* Inizializza la configurazione dei publisher (lazy initialization)
|
|
@@ -23,12 +51,24 @@ export declare abstract class BaseEventCtrl<TCreate extends Event, TUpdate exten
|
|
|
23
51
|
* @param context
|
|
24
52
|
*/
|
|
25
53
|
/**
|
|
54
|
+
* Build the parsed, ready-to-publish message for a write: parse the payload,
|
|
55
|
+
* resolve the subject (shared by every publisher of the type — same event on
|
|
56
|
+
* NATS + msg) and stamp the OUTGOING cascade meta from `context._event` (root
|
|
57
|
+
* when absent). Returns undefined when the type has no publisher/parser. Built
|
|
58
|
+
* ONCE and reused for both the outbox row and the immediate dispatch.
|
|
26
59
|
*
|
|
27
60
|
* @param item
|
|
28
61
|
* @param type
|
|
29
62
|
* @param context
|
|
30
63
|
*/
|
|
31
|
-
|
|
64
|
+
private buildMessage;
|
|
65
|
+
/**
|
|
66
|
+
* Dispatch a prepared message on every publisher of its type. Shared by the
|
|
67
|
+
* immediate post-commit dispatch and the relay replay.
|
|
68
|
+
*
|
|
69
|
+
* @param msg
|
|
70
|
+
*/
|
|
71
|
+
private publishMessage;
|
|
32
72
|
/**
|
|
33
73
|
* Overridable post-write / post-read enrichment of the RETURNED document (e.g.
|
|
34
74
|
* populate references, attach a joined aggregate). Runs AFTER the atomic write
|
|
@@ -81,22 +121,23 @@ export declare abstract class BaseEventCtrl<TCreate extends Event, TUpdate exten
|
|
|
81
121
|
*/
|
|
82
122
|
remove(id: string, context: NxContext): Promise<TDoc>;
|
|
83
123
|
/**
|
|
84
|
-
* Persist an outbox row (sent:false) for
|
|
85
|
-
*
|
|
86
|
-
*
|
|
124
|
+
* Persist an outbox row (sent:false) for the prepared message inside the
|
|
125
|
+
* caller's transaction. The row carries the subject + parsed payload + cascade
|
|
126
|
+
* meta, so the relay can replay it faithfully. Returns the row id, or undefined
|
|
127
|
+
* when there is no message or no outbox registered (the event is then still
|
|
128
|
+
* dispatched, just not tracked).
|
|
87
129
|
*
|
|
88
|
-
* @param
|
|
89
|
-
* @param type
|
|
130
|
+
* @param msg
|
|
90
131
|
* @param context
|
|
91
132
|
*/
|
|
92
133
|
private enqueueOutbox;
|
|
93
134
|
/**
|
|
94
|
-
* Dispatch the
|
|
95
|
-
* the transaction commits, so `publish` (a non-DB side effect) is
|
|
96
|
-
* by `withTransaction` and a broker failure leaves a recoverable
|
|
135
|
+
* Dispatch the prepared message to the broker, then mark the outbox row as sent.
|
|
136
|
+
* Runs AFTER the transaction commits, so `publish` (a non-DB side effect) is
|
|
137
|
+
* never retried by `withTransaction` and a broker failure leaves a recoverable
|
|
138
|
+
* sent:false row for the relay (Step 3.5).
|
|
97
139
|
*
|
|
98
|
-
* @param
|
|
99
|
-
* @param type
|
|
140
|
+
* @param msg
|
|
100
141
|
* @param outboxId
|
|
101
142
|
* @param context
|
|
102
143
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-event.controller.d.ts","sourceRoot":"","sources":["../../src/events/base-event.controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"base-event.controller.d.ts","sourceRoot":"","sources":["../../src/events/base-event.controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAuB,mDAAmD,CAAC;AAC/F,OAAO,EAAE,YAAY,EAAE,MAAoB,wDAAwD,CAAC;AACpG,OAAO,EAAE,cAAc,EAAE,MAAkB,wDAAwD,CAAC;AAEpG,OAAO,EAAE,SAAS,EAAE,MAAuB,sBAAsB,CAAC;AAGlE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAe,cAAc,CAAC;AAO1D,OAAO,EAAE,iBAAiB,EAAE,MAAe,0BAA0B,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAkB,eAAe,CAAC;AAO3D,8BAAsB,aAAa,CAAC,OAAO,SAAS,KAAK,EAAE,OAAO,SAAS,KAAK,EAAE,OAAO,SAAS,KAAK,EAAE,MAAM,EAAE,IAAI,SAAS,YAAY,EAAE,MAAM,SAAS,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,CAAE,SAAQ,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAE,YAAW,iBAAiB;IAMhQ;;;;;;OAMG;IACH,SAAS,CAAC,SAAS,EAAS,CAAC,MAAM,MAAM,CAAC,EAAE,CAAM;IAClD,SAAS,CAAC,eAAe,CAAC,EAAE,CAAC,MAAM,MAAM,CAAC,EAAE,CAAC;IAC7C,SAAS,CAAC,eAAe,EAAG,CAAC,MAAM,MAAM,CAAC,EAAE,CAAM;IAElD;;;;;;OAMG;IACH,SAAS,CAAC,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAI,OAAO,CAAC,MAAM,CAAC;IAIlF,SAAS,CAAC,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAI,OAAO,CAAC,MAAM,CAAC;IAIlF,SAAS,CAAC,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAI,OAAO,CAAC,MAAM,CAAC;IAIlF,SAAS,CAAC,QAAQ,CAAC,eAAe,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;IAC1D,SAAS,CAAC,QAAQ,CAAC,eAAe,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;IAC1D,SAAS,CAAC,QAAQ,CAAC,eAAe,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBAK9C,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,OAAO,CAAA;KAAE;IAM5D;;;;OAIG;IACH,eAAe,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE;IAKtC,OAAO,CAAC,aAAa,CAAC,CAAmD;IAEzE;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAqBxB;;;;;OAKG;IAoBH;;;;;;;;;;OAUG;IACH,OAAO,CAAC,YAAY;IAcpB;;;;;OAKG;YACW,cAAc;IAM5B;;;;;;;;;OASG;cACa,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAKzE;;;;;OAKG;IACY,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAMzE;;;;;OAKG;IACH;;;;;;;;;;OAUG;IACY,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBtE;;;;;;OAMG;IACY,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBlF;;;;;OAKG;IACY,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBpE;;;;;;;;;OASG;YACW,aAAa;IAY3B;;;;;;;;;OASG;YACW,cAAc;CAU7B"}
|
|
@@ -5,8 +5,53 @@ const base_controller_1 = require("@nextage/nx-frame-be/build/common/base/base.c
|
|
|
5
5
|
const mongo_utils_1 = require("@nextage/nx-frame-be/build/common/base/mongo-utils");
|
|
6
6
|
const outbox_1 = require("./outbox");
|
|
7
7
|
const cascade_1 = require("./cascade");
|
|
8
|
+
const field_map_1 = require("./field-map");
|
|
9
|
+
const publisher_registry_1 = require("./publisher-registry");
|
|
8
10
|
const enums_1 = require("./types/enums");
|
|
9
11
|
class BaseEventCtrl extends base_controller_1.BaseController {
|
|
12
|
+
/**
|
|
13
|
+
* Default create/update/remove parsers: a pure pick over the declared field-map.
|
|
14
|
+
* Overridable when a payload needs computed values (see e.g. i18n-shaped events).
|
|
15
|
+
*
|
|
16
|
+
* @param item
|
|
17
|
+
* @param type
|
|
18
|
+
*/
|
|
19
|
+
parsePubCreateItem(item, type) {
|
|
20
|
+
return (0, field_map_1.pickPubFields)(item, this.pubFields);
|
|
21
|
+
}
|
|
22
|
+
parsePubUpdateItem(item, type) {
|
|
23
|
+
return (0, field_map_1.pickPubFields)(item, this.pubUpdateFields ?? this.pubFields);
|
|
24
|
+
}
|
|
25
|
+
parsePubRemoveItem(item, type) {
|
|
26
|
+
return (0, field_map_1.pickPubFields)(item, this.pubRemoveFields);
|
|
27
|
+
}
|
|
28
|
+
// protected abstract createPublisher: Publisher<TCreate> | NatsPublisher<TCreate>;
|
|
29
|
+
// protected abstract updatePublisher: Publisher<TUpdate> | NatsPublisher<TUpdate>;
|
|
30
|
+
// protected abstract removePublisher: Publisher<TRemove> | NatsPublisher<TRemove>;
|
|
31
|
+
constructor(config) {
|
|
32
|
+
super(config);
|
|
33
|
+
// protected abstract CreatePublisher: new (client: MsgClientInterface) => Publisher<TCreate> | NatsPublisher<TCreate>;
|
|
34
|
+
// protected abstract UpdatePublisher: new (client: MsgClientInterface) => Publisher<TUpdate> | NatsPublisher<TUpdate>;
|
|
35
|
+
// protected abstract RemovePublisher: new (client: MsgClientInterface) => Publisher<TRemove> | NatsPublisher<TRemove>;
|
|
36
|
+
/**
|
|
37
|
+
* Declarative publish field-map (Step 3.4c). The default parsePub* methods pick
|
|
38
|
+
* exactly these keys from the entity, replacing the ~57 hand-written per-controller
|
|
39
|
+
* parsers. `pubFields` drives BOTH create and update; set `pubUpdateFields` only
|
|
40
|
+
* for the rare create ≠ update case; `pubRemoveFields` is the leaner remove subset.
|
|
41
|
+
* A subclass may still OVERRIDE parsePub* directly for non-pick (computed) payloads.
|
|
42
|
+
*/
|
|
43
|
+
this.pubFields = [];
|
|
44
|
+
this.pubRemoveFields = [];
|
|
45
|
+
(0, publisher_registry_1.registerPublisherProvider)(this);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* All publishers this controller owns (create + update + remove). Read LAZILY by
|
|
49
|
+
* the relay's publisher registry to route a `sent:false` outbox row back to its
|
|
50
|
+
* publisher family by subject — so it runs after the subclass field initialisers.
|
|
51
|
+
*/
|
|
52
|
+
eventPublishers() {
|
|
53
|
+
return [...this.createPublisher, ...this.updatePublisher, ...this.removePublisher];
|
|
54
|
+
}
|
|
10
55
|
/**
|
|
11
56
|
* Inizializza la configurazione dei publisher (lazy initialization)
|
|
12
57
|
*/
|
|
@@ -52,18 +97,36 @@ class BaseEventCtrl extends base_controller_1.BaseController {
|
|
|
52
97
|
// }
|
|
53
98
|
// }
|
|
54
99
|
/**
|
|
100
|
+
* Build the parsed, ready-to-publish message for a write: parse the payload,
|
|
101
|
+
* resolve the subject (shared by every publisher of the type — same event on
|
|
102
|
+
* NATS + msg) and stamp the OUTGOING cascade meta from `context._event` (root
|
|
103
|
+
* when absent). Returns undefined when the type has no publisher/parser. Built
|
|
104
|
+
* ONCE and reused for both the outbox row and the immediate dispatch.
|
|
55
105
|
*
|
|
56
106
|
* @param item
|
|
57
107
|
* @param type
|
|
58
108
|
* @param context
|
|
59
109
|
*/
|
|
60
|
-
|
|
110
|
+
buildMessage(item, type, context) {
|
|
61
111
|
const { publishers, parser } = this.getPublishConfig()[type] ?? {};
|
|
62
112
|
if (!publishers?.length || !parser)
|
|
63
|
-
return;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
113
|
+
return undefined;
|
|
114
|
+
return {
|
|
115
|
+
type,
|
|
116
|
+
subject: publishers[0].subject,
|
|
117
|
+
data: parser(item, type),
|
|
118
|
+
meta: (0, cascade_1.outgoingMeta)(context?._event),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Dispatch a prepared message on every publisher of its type. Shared by the
|
|
123
|
+
* immediate post-commit dispatch and the relay replay.
|
|
124
|
+
*
|
|
125
|
+
* @param msg
|
|
126
|
+
*/
|
|
127
|
+
async publishMessage(msg) {
|
|
128
|
+
const publishers = this.getPublishConfig()[msg.type]?.publishers ?? [];
|
|
129
|
+
await Promise.all(publishers.map(pub => pub.publish(msg.data, msg.meta)));
|
|
67
130
|
}
|
|
68
131
|
/**
|
|
69
132
|
* Overridable post-write / post-read enrichment of the RETURNED document (e.g.
|
|
@@ -106,15 +169,15 @@ class BaseEventCtrl extends base_controller_1.BaseController {
|
|
|
106
169
|
* @returns
|
|
107
170
|
*/
|
|
108
171
|
async create(item, context) {
|
|
109
|
-
let
|
|
172
|
+
let msg;
|
|
110
173
|
let outboxId;
|
|
111
174
|
const res = await this.withTransaction(context, async (ctx) => {
|
|
112
175
|
const created = await super.create(item, ctx);
|
|
113
|
-
|
|
114
|
-
outboxId = await this.enqueueOutbox(
|
|
176
|
+
msg = this.buildMessage(created.toJSON(), enums_1.QueueEventType.create, context);
|
|
177
|
+
outboxId = await this.enqueueOutbox(msg, ctx);
|
|
115
178
|
return created;
|
|
116
179
|
});
|
|
117
|
-
await this.dispatchOutbox(
|
|
180
|
+
await this.dispatchOutbox(msg, outboxId, context);
|
|
118
181
|
return this.decorateDoc(res, context);
|
|
119
182
|
}
|
|
120
183
|
/**
|
|
@@ -125,15 +188,15 @@ class BaseEventCtrl extends base_controller_1.BaseController {
|
|
|
125
188
|
* @returns
|
|
126
189
|
*/
|
|
127
190
|
async update(id, item, context) {
|
|
128
|
-
let
|
|
191
|
+
let msg;
|
|
129
192
|
let outboxId;
|
|
130
193
|
const res = await this.withTransaction(context, async (ctx) => {
|
|
131
194
|
const updated = await super.update(id, item, ctx);
|
|
132
|
-
|
|
133
|
-
outboxId = await this.enqueueOutbox(
|
|
195
|
+
msg = this.buildMessage({ id, ...updated.toObject() }, enums_1.QueueEventType.update, context);
|
|
196
|
+
outboxId = await this.enqueueOutbox(msg, ctx);
|
|
134
197
|
return updated;
|
|
135
198
|
});
|
|
136
|
-
await this.dispatchOutbox(
|
|
199
|
+
await this.dispatchOutbox(msg, outboxId, context);
|
|
137
200
|
return this.decorateDoc(res, context);
|
|
138
201
|
}
|
|
139
202
|
/**
|
|
@@ -143,47 +206,50 @@ class BaseEventCtrl extends base_controller_1.BaseController {
|
|
|
143
206
|
* @returns
|
|
144
207
|
*/
|
|
145
208
|
async remove(id, context) {
|
|
146
|
-
let
|
|
209
|
+
let msg;
|
|
147
210
|
let outboxId;
|
|
148
211
|
const res = await this.withTransaction(context, async (ctx) => {
|
|
149
212
|
const removed = await this.model.remove(id, ctx);
|
|
150
|
-
|
|
151
|
-
outboxId = await this.enqueueOutbox(
|
|
213
|
+
msg = this.buildMessage({ id, ...removed.toObject() }, enums_1.QueueEventType.remove, context);
|
|
214
|
+
outboxId = await this.enqueueOutbox(msg, ctx);
|
|
152
215
|
return removed;
|
|
153
216
|
});
|
|
154
|
-
await this.dispatchOutbox(
|
|
217
|
+
await this.dispatchOutbox(msg, outboxId, context);
|
|
155
218
|
return res;
|
|
156
219
|
}
|
|
157
220
|
/**
|
|
158
|
-
* Persist an outbox row (sent:false) for
|
|
159
|
-
*
|
|
160
|
-
*
|
|
221
|
+
* Persist an outbox row (sent:false) for the prepared message inside the
|
|
222
|
+
* caller's transaction. The row carries the subject + parsed payload + cascade
|
|
223
|
+
* meta, so the relay can replay it faithfully. Returns the row id, or undefined
|
|
224
|
+
* when there is no message or no outbox registered (the event is then still
|
|
225
|
+
* dispatched, just not tracked).
|
|
161
226
|
*
|
|
162
|
-
* @param
|
|
163
|
-
* @param type
|
|
227
|
+
* @param msg
|
|
164
228
|
* @param context
|
|
165
229
|
*/
|
|
166
|
-
async enqueueOutbox(
|
|
230
|
+
async enqueueOutbox(msg, context) {
|
|
167
231
|
const outbox = (0, outbox_1.getOutbox)();
|
|
168
|
-
if (!outbox)
|
|
232
|
+
if (!outbox || !msg)
|
|
169
233
|
return undefined;
|
|
170
234
|
const id = (0, mongo_utils_1.genObjectId)().toString();
|
|
171
|
-
const evt = { id, type, data:
|
|
235
|
+
const evt = { id, type: msg.type, subject: msg.subject, data: msg.data, meta: msg.meta };
|
|
172
236
|
await outbox.create(evt, context);
|
|
173
237
|
return id;
|
|
174
238
|
}
|
|
175
239
|
/**
|
|
176
|
-
* Dispatch the
|
|
177
|
-
* the transaction commits, so `publish` (a non-DB side effect) is
|
|
178
|
-
* by `withTransaction` and a broker failure leaves a recoverable
|
|
240
|
+
* Dispatch the prepared message to the broker, then mark the outbox row as sent.
|
|
241
|
+
* Runs AFTER the transaction commits, so `publish` (a non-DB side effect) is
|
|
242
|
+
* never retried by `withTransaction` and a broker failure leaves a recoverable
|
|
243
|
+
* sent:false row for the relay (Step 3.5).
|
|
179
244
|
*
|
|
180
|
-
* @param
|
|
181
|
-
* @param type
|
|
245
|
+
* @param msg
|
|
182
246
|
* @param outboxId
|
|
183
247
|
* @param context
|
|
184
248
|
*/
|
|
185
|
-
async dispatchOutbox(
|
|
186
|
-
|
|
249
|
+
async dispatchOutbox(msg, outboxId, context) {
|
|
250
|
+
if (!msg)
|
|
251
|
+
return;
|
|
252
|
+
await this.publishMessage(msg);
|
|
187
253
|
const outbox = (0, outbox_1.getOutbox)();
|
|
188
254
|
if (outbox && outboxId)
|
|
189
255
|
await outbox.markSent(outboxId, context);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-event.controller.js","sourceRoot":"","sources":["../../src/events/base-event.controller.ts"],"names":[],"mappings":";;;AAEA,
|
|
1
|
+
{"version":3,"file":"base-event.controller.js","sourceRoot":"","sources":["../../src/events/base-event.controller.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { EventRelayOptions } from './types/relay.interfaces';
|
|
2
|
+
export declare class EventRelay {
|
|
3
|
+
private readonly batchSize;
|
|
4
|
+
private readonly intervalMs;
|
|
5
|
+
private readonly onError;
|
|
6
|
+
private readonly onSkip;
|
|
7
|
+
private timer?;
|
|
8
|
+
private draining;
|
|
9
|
+
constructor(opts?: EventRelayOptions);
|
|
10
|
+
/**
|
|
11
|
+
* Drain one batch: the oldest `sent:false` rows → re-publish each on every
|
|
12
|
+
* publisher registered for its subject → mark it sent. A row whose subject has
|
|
13
|
+
* no registered publisher (controller not loaded) is skipped and retried on the
|
|
14
|
+
* next tick. Returns the number of rows successfully re-published. Never throws
|
|
15
|
+
* for a single row/broker failure — that row simply stays `sent:false`.
|
|
16
|
+
*/
|
|
17
|
+
drainOnce(): Promise<number>;
|
|
18
|
+
/**
|
|
19
|
+
* Start the relay: an immediate startup drain, then a periodic sweep every
|
|
20
|
+
* `intervalMs`. The timer is `unref`'d so it never keeps the process alive.
|
|
21
|
+
*/
|
|
22
|
+
start(): void;
|
|
23
|
+
/** Stop the periodic sweep (graceful shutdown / test teardown). */
|
|
24
|
+
stop(): void;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=event-relay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-relay.d.ts","sourceRoot":"","sources":["../../src/events/event-relay.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,iBAAiB,EAAE,MAAwC,0BAA0B,CAAC;AAG/F,qBAAa,UAAU;IAErB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAU;IACpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;IACpD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4C;IAEnE,OAAO,CAAC,KAAK,CAAC,CAAmC;IACjD,OAAO,CAAC,QAAQ,CAAS;gBAEb,IAAI,GAAE,iBAAsB;IAQxC;;;;;;OAMG;IACG,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;IA2ClC;;;OAGG;IACH,KAAK,IAAI,IAAI;IAab,mEAAmE;IACnE,IAAI,IAAI,IAAI;CAOb"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* ────────────────────────────────────────────────────────────────────────────
|
|
3
|
+
* EVENT RELAY — at-least-once redelivery of `sent:false` outbox rows (Step 3.5)
|
|
4
|
+
*
|
|
5
|
+
* Closes finding E1: with the atomic outbox (3.4) an entity + its outbox row are
|
|
6
|
+
* committed together, then published post-commit; if the broker is down or the
|
|
7
|
+
* process crashes in that window the row stays `sent:false` and — until now — was
|
|
8
|
+
* never re-published. The relay drains those rows:
|
|
9
|
+
* • at startup → recover events accumulated while THIS service was down;
|
|
10
|
+
* • periodically → recover from a transient broker/network outage while the
|
|
11
|
+
* process stays up (the publish failed but we did not crash).
|
|
12
|
+
*
|
|
13
|
+
* Re-publish is safe (at-least-once): downstream consumers are version-guarded
|
|
14
|
+
* (3.3), so a duplicate delivery is idempotent. Routing back to the publisher is
|
|
15
|
+
* via the subject persisted on the row + the publisher registry.
|
|
16
|
+
* ──────────────────────────────────────────────────────────────────────────── */
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.EventRelay = void 0;
|
|
19
|
+
const outbox_1 = require("./outbox");
|
|
20
|
+
const publisher_registry_1 = require("./publisher-registry");
|
|
21
|
+
const relay_constants_1 = require("./types/relay.constants");
|
|
22
|
+
class EventRelay {
|
|
23
|
+
constructor(opts = {}) {
|
|
24
|
+
this.draining = false;
|
|
25
|
+
this.batchSize = opts.batchSize ?? relay_constants_1.DEFAULT_RELAY_BATCH_SIZE;
|
|
26
|
+
this.intervalMs = opts.intervalMs ?? relay_constants_1.DEFAULT_RELAY_INTERVAL_MS;
|
|
27
|
+
this.onError = opts.onError ?? (() => { });
|
|
28
|
+
this.onSkip = opts.onSkip ?? (() => { });
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Drain one batch: the oldest `sent:false` rows → re-publish each on every
|
|
32
|
+
* publisher registered for its subject → mark it sent. A row whose subject has
|
|
33
|
+
* no registered publisher (controller not loaded) is skipped and retried on the
|
|
34
|
+
* next tick. Returns the number of rows successfully re-published. Never throws
|
|
35
|
+
* for a single row/broker failure — that row simply stays `sent:false`.
|
|
36
|
+
*/
|
|
37
|
+
async drainOnce() {
|
|
38
|
+
const outbox = (0, outbox_1.getOutbox)();
|
|
39
|
+
if (!outbox)
|
|
40
|
+
return 0;
|
|
41
|
+
// Re-entrancy guard: a slow batch must not overlap the periodic tick.
|
|
42
|
+
if (this.draining)
|
|
43
|
+
return 0;
|
|
44
|
+
this.draining = true;
|
|
45
|
+
let sent = 0;
|
|
46
|
+
try {
|
|
47
|
+
const rows = await outbox.findUnsent(this.batchSize);
|
|
48
|
+
for (const row of rows) {
|
|
49
|
+
const publishers = (0, publisher_registry_1.resolvePublishers)(row.subject);
|
|
50
|
+
if (!publishers.length) {
|
|
51
|
+
this.onSkip(row.subject, row.id);
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
await Promise.all(publishers.map(pub => pub.publish(row.data, row.meta)));
|
|
56
|
+
await outbox.markSent(row.id, {});
|
|
57
|
+
sent++;
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
// Leave the row sent:false for the next tick; do not abort the batch.
|
|
61
|
+
this.onError(err);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
this.onError(err);
|
|
67
|
+
}
|
|
68
|
+
finally {
|
|
69
|
+
this.draining = false;
|
|
70
|
+
}
|
|
71
|
+
return sent;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Start the relay: an immediate startup drain, then a periodic sweep every
|
|
75
|
+
* `intervalMs`. The timer is `unref`'d so it never keeps the process alive.
|
|
76
|
+
*/
|
|
77
|
+
start() {
|
|
78
|
+
if (this.timer)
|
|
79
|
+
return;
|
|
80
|
+
void this.drainOnce().catch(err => this.onError(err));
|
|
81
|
+
this.timer = setInterval(() => {
|
|
82
|
+
void this.drainOnce().catch(err => this.onError(err));
|
|
83
|
+
}, this.intervalMs);
|
|
84
|
+
this.timer.unref?.();
|
|
85
|
+
}
|
|
86
|
+
/** Stop the periodic sweep (graceful shutdown / test teardown). */
|
|
87
|
+
stop() {
|
|
88
|
+
if (this.timer) {
|
|
89
|
+
clearInterval(this.timer);
|
|
90
|
+
this.timer = undefined;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
exports.EventRelay = EventRelay;
|
|
95
|
+
//# sourceMappingURL=event-relay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-relay.js","sourceRoot":"","sources":["../../src/events/event-relay.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build a new object holding exactly `keys` picked from `item`, preserving
|
|
3
|
+
* `undefined` values for absent fields (parity with a hand-written literal).
|
|
4
|
+
*
|
|
5
|
+
* @param item source entity
|
|
6
|
+
* @param keys published field set
|
|
7
|
+
*/
|
|
8
|
+
export declare function pickPubFields<T>(item: T, keys: readonly (keyof T)[]): Record<string, unknown>;
|
|
9
|
+
//# sourceMappingURL=field-map.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"field-map.d.ts","sourceRoot":"","sources":["../../src/events/field-map.ts"],"names":[],"mappings":"AASA;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAS7F"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* ────────────────────────────────────────────────────────────────────────────
|
|
3
|
+
* FIELD-MAP — declarative publish payload picker (Step 3.4c)
|
|
4
|
+
*
|
|
5
|
+
* Backs the default parsePub{Create,Update,Remove}Item of BaseEventCtrl: a pure
|
|
6
|
+
* key-pick that replaces ~57 hand-written per-controller parsers. Keys are copied
|
|
7
|
+
* UNCONDITIONALLY (a missing value lands as `undefined`) so the produced payload
|
|
8
|
+
* is byte-for-byte identical to the old `{ a: item.a, b: item.b }` object literal.
|
|
9
|
+
* ──────────────────────────────────────────────────────────────────────────── */
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.pickPubFields = pickPubFields;
|
|
12
|
+
/**
|
|
13
|
+
* Build a new object holding exactly `keys` picked from `item`, preserving
|
|
14
|
+
* `undefined` values for absent fields (parity with a hand-written literal).
|
|
15
|
+
*
|
|
16
|
+
* @param item source entity
|
|
17
|
+
* @param keys published field set
|
|
18
|
+
*/
|
|
19
|
+
function pickPubFields(item, keys) {
|
|
20
|
+
const out = {};
|
|
21
|
+
for (const key of keys) {
|
|
22
|
+
out[key] = item?.[key];
|
|
23
|
+
}
|
|
24
|
+
return out;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=field-map.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"field-map.js","sourceRoot":"","sources":["../../src/events/field-map.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;AASlF,sCASC;AAhBD;;;;;;GAMG;AACH,SAAgB,aAAa,CAAI,IAAO,EAAE,IAA0B;IAElE,MAAM,GAAG,GAA4B,EAAE,CAAC;IAExC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,GAAG,CAAC,GAAa,CAAC,GAAI,IAAY,EAAE,CAAC,GAAG,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC"}
|
package/build/events/index.d.ts
CHANGED
|
@@ -3,7 +3,10 @@ export * from './interfaces';
|
|
|
3
3
|
export * from './types';
|
|
4
4
|
export * from './base-event.controller';
|
|
5
5
|
export * from './cascade';
|
|
6
|
+
export * from './event-relay';
|
|
7
|
+
export * from './field-map';
|
|
6
8
|
export * from './outbox';
|
|
9
|
+
export * from './publisher-registry';
|
|
7
10
|
export * from './msg-client-manager';
|
|
8
11
|
export * from './msg-wrapper';
|
|
9
12
|
export * from './base-listener';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/events/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AAExB,cAAc,yBAAyB,CAAC;AACxC,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/events/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AAExB,cAAc,yBAAyB,CAAC;AACxC,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,sBAAsB,CAAC;AAGrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AAGjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AAGtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,QAAQ,CAAC;AAGvB,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,qBAAqB,CAAC;AACpC,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAGhC,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AAGjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC"}
|
package/build/events/index.js
CHANGED
|
@@ -19,7 +19,10 @@ __exportStar(require("./interfaces"), exports);
|
|
|
19
19
|
__exportStar(require("./types"), exports);
|
|
20
20
|
__exportStar(require("./base-event.controller"), exports);
|
|
21
21
|
__exportStar(require("./cascade"), exports);
|
|
22
|
+
__exportStar(require("./event-relay"), exports);
|
|
23
|
+
__exportStar(require("./field-map"), exports);
|
|
22
24
|
__exportStar(require("./outbox"), exports);
|
|
25
|
+
__exportStar(require("./publisher-registry"), exports);
|
|
23
26
|
// messages on memory
|
|
24
27
|
__exportStar(require("./msg-client-manager"), exports);
|
|
25
28
|
__exportStar(require("./msg-wrapper"), exports);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/events/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA8B;AAC9B,+CAA6B;AAC7B,0CAAwB;AAExB,0DAAwC;AACxC,4CAA0B;AAC1B,2CAAyB;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/events/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA8B;AAC9B,+CAA6B;AAC7B,0CAAwB;AAExB,0DAAwC;AACxC,4CAA0B;AAC1B,gDAA8B;AAC9B,8CAA4B;AAC5B,2CAAyB;AACzB,uDAAqC;AAErC,qBAAqB;AACrB,uDAAqC;AACrC,gDAA8B;AAC9B,kDAAgC;AAChC,mDAAiC;AAEjC,mBAAmB;AACnB,wDAAsC;AACtC,iDAA+B;AAC/B,uDAAqC;AACrC,wDAAsC;AAEtC,YAAY;AACZ,iDAA+B;AAC/B,yCAAuB;AAEvB,aAAa;AACb,kDAAgC;AAChC,gDAA8B;AAC9B,6CAA2B;AAC3B,mDAAiC;AACjC,iDAA+B;AAC/B,4CAA0B;AAC1B,sDAAoC;AACpC,2CAAyB;AACzB,kDAAgC;AAEhC,cAAc;AACd,4CAA0B;AAC1B,kDAAgC;AAChC,oDAAkC;AAClC,qDAAmC;AACnC,qDAAmC;AACnC,oDAAkC;AAClC,iDAA+B;AAC/B,mDAAiC;AAEjC,oBAAoB;AACpB,kDAAgC;AAChC,+CAA6B;AAE7B,kBAAkB;AAClB,mCAAmC;AAEnC,cAAc"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Event, IPublisher } from './interfaces';
|
|
2
|
+
import { PublisherProvider } from './types/relay.interfaces';
|
|
3
|
+
/**
|
|
4
|
+
* Register a controller as a publisher provider. Idempotent (Set-backed): a
|
|
5
|
+
* singleton controller constructed once registers once. Called from the
|
|
6
|
+
* BaseEventCtrl constructor with `this`.
|
|
7
|
+
*
|
|
8
|
+
* @param provider
|
|
9
|
+
*/
|
|
10
|
+
export declare function registerPublisherProvider(provider: PublisherProvider): void;
|
|
11
|
+
/**
|
|
12
|
+
* All registered publishers whose `subject` matches, gathered across every
|
|
13
|
+
* provider. Read lazily at call time, so a provider registered in a constructor
|
|
14
|
+
* (before its publisher fields are initialised) still resolves correctly later.
|
|
15
|
+
*
|
|
16
|
+
* @param subject
|
|
17
|
+
*/
|
|
18
|
+
export declare function resolvePublishers(subject: string): IPublisher<Event>[];
|
|
19
|
+
/** Clear all registered providers (test isolation). */
|
|
20
|
+
export declare function clearPublisherProviders(): void;
|
|
21
|
+
//# sourceMappingURL=publisher-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publisher-registry.d.ts","sourceRoot":"","sources":["../../src/events/publisher-registry.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAI7D;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAG3E;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,EAAE,CAStE;AAED,uDAAuD;AACvD,wBAAgB,uBAAuB,IAAI,IAAI,CAG9C"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* ────────────────────────────────────────────────────────────────────────────
|
|
3
|
+
* PUBLISHER REGISTRY — subject → publisher resolution for the relay (Step 3.5)
|
|
4
|
+
*
|
|
5
|
+
* The relay reads a `sent:false` outbox row and must re-publish it, but the
|
|
6
|
+
* concrete publisher lives PER-CONTROLLER (create/update/removePublisher on each
|
|
7
|
+
* BaseEventCtrl). A controller registers ITSELF as a provider in its constructor;
|
|
8
|
+
* the relay later asks `resolvePublishers(subject)`, which reads each provider's
|
|
9
|
+
* `eventPublishers()` LAZILY — so it runs at relay-time (fields initialised), not
|
|
10
|
+
* at construction-time (subclass field initialisers run AFTER super()).
|
|
11
|
+
* ──────────────────────────────────────────────────────────────────────────── */
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.registerPublisherProvider = registerPublisherProvider;
|
|
14
|
+
exports.resolvePublishers = resolvePublishers;
|
|
15
|
+
exports.clearPublisherProviders = clearPublisherProviders;
|
|
16
|
+
const _providers = new Set();
|
|
17
|
+
/**
|
|
18
|
+
* Register a controller as a publisher provider. Idempotent (Set-backed): a
|
|
19
|
+
* singleton controller constructed once registers once. Called from the
|
|
20
|
+
* BaseEventCtrl constructor with `this`.
|
|
21
|
+
*
|
|
22
|
+
* @param provider
|
|
23
|
+
*/
|
|
24
|
+
function registerPublisherProvider(provider) {
|
|
25
|
+
_providers.add(provider);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* All registered publishers whose `subject` matches, gathered across every
|
|
29
|
+
* provider. Read lazily at call time, so a provider registered in a constructor
|
|
30
|
+
* (before its publisher fields are initialised) still resolves correctly later.
|
|
31
|
+
*
|
|
32
|
+
* @param subject
|
|
33
|
+
*/
|
|
34
|
+
function resolvePublishers(subject) {
|
|
35
|
+
const out = [];
|
|
36
|
+
for (const provider of _providers)
|
|
37
|
+
for (const pub of provider.eventPublishers())
|
|
38
|
+
if (pub.subject === subject)
|
|
39
|
+
out.push(pub);
|
|
40
|
+
return out;
|
|
41
|
+
}
|
|
42
|
+
/** Clear all registered providers (test isolation). */
|
|
43
|
+
function clearPublisherProviders() {
|
|
44
|
+
_providers.clear();
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=publisher-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publisher-registry.js","sourceRoot":"","sources":["../../src/events/publisher-registry.ts"],"names":[],"mappings":";AAAA;;;;;;;;;kFASkF;;AAclF,8DAGC;AASD,8CASC;AAGD,0DAGC;AApCD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAqB,CAAC;AAEhD;;;;;;GAMG;AACH,SAAgB,yBAAyB,CAAC,QAA2B;IAEnE,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAC3B,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,iBAAiB,CAAC,OAAe;IAE/C,MAAM,GAAG,GAAwB,EAAE,CAAC;IAEpC,KAAK,MAAM,QAAQ,IAAI,UAAU;QAC/B,KAAK,MAAM,GAAG,IAAI,QAAQ,CAAC,eAAe,EAAE;YAC1C,IAAI,GAAG,CAAC,OAAO,KAAK,OAAO;gBAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAE/C,OAAO,GAAG,CAAC;AACb,CAAC;AAED,uDAAuD;AACvD,SAAgB,uBAAuB;IAErC,UAAU,CAAC,KAAK,EAAE,CAAC;AACrB,CAAC"}
|
|
@@ -15,12 +15,14 @@ export * from './vulnerability.enums';
|
|
|
15
15
|
export * from './asset.constants';
|
|
16
16
|
export * from './dlq.constants';
|
|
17
17
|
export * from './event-envelope.constants';
|
|
18
|
+
export * from './relay.constants';
|
|
18
19
|
export * from './asset.interfaces';
|
|
19
20
|
export * from './control.interfaces';
|
|
20
21
|
export * from './dlq.interfaces';
|
|
21
22
|
export * from './event-envelope.interfaces';
|
|
22
23
|
export * from './events.interfaces';
|
|
23
24
|
export * from './outbox.interfaces';
|
|
25
|
+
export * from './relay.interfaces';
|
|
24
26
|
export * from './risk-analysis.interfaces';
|
|
25
27
|
export * from './threat.interfaces';
|
|
26
28
|
export * from './vulnerability.interfaces';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/events/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AAExB,cAAc,uBAAuB,CAAC;AACtC,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AAEtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/events/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AAExB,cAAc,uBAAuB,CAAC;AACtC,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AAEtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAElC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAG3C,cAAc,kBAAkB,CAAC"}
|
|
@@ -31,12 +31,14 @@ __exportStar(require("./vulnerability.enums"), exports);
|
|
|
31
31
|
__exportStar(require("./asset.constants"), exports);
|
|
32
32
|
__exportStar(require("./dlq.constants"), exports);
|
|
33
33
|
__exportStar(require("./event-envelope.constants"), exports);
|
|
34
|
+
__exportStar(require("./relay.constants"), exports);
|
|
34
35
|
__exportStar(require("./asset.interfaces"), exports);
|
|
35
36
|
__exportStar(require("./control.interfaces"), exports);
|
|
36
37
|
__exportStar(require("./dlq.interfaces"), exports);
|
|
37
38
|
__exportStar(require("./event-envelope.interfaces"), exports);
|
|
38
39
|
__exportStar(require("./events.interfaces"), exports);
|
|
39
40
|
__exportStar(require("./outbox.interfaces"), exports);
|
|
41
|
+
__exportStar(require("./relay.interfaces"), exports);
|
|
40
42
|
__exportStar(require("./risk-analysis.interfaces"), exports);
|
|
41
43
|
__exportStar(require("./threat.interfaces"), exports);
|
|
42
44
|
__exportStar(require("./vulnerability.interfaces"), exports);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/events/types/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB;AAExB,wDAAsC;AACtC,gDAA8B;AAC9B,sDAAoC;AACpC,wDAAsC;AACtC,uDAAqC;AACrC,kDAAgC;AAChC,4DAA0C;AAC1C,iDAA+B;AAC/B,uDAAqC;AACrC,wDAAsC;AACtC,iDAA+B;AAC/B,oDAAkC;AAClC,wDAAsC;AAEtC,oDAAkC;AAClC,kDAAgC;AAChC,6DAA2C;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/events/types/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB;AAExB,wDAAsC;AACtC,gDAA8B;AAC9B,sDAAoC;AACpC,wDAAsC;AACtC,uDAAqC;AACrC,kDAAgC;AAChC,4DAA0C;AAC1C,iDAA+B;AAC/B,uDAAqC;AACrC,wDAAsC;AACtC,iDAA+B;AAC/B,oDAAkC;AAClC,wDAAsC;AAEtC,oDAAkC;AAClC,kDAAgC;AAChC,6DAA2C;AAC3C,oDAAkC;AAElC,qDAAmC;AACnC,uDAAqC;AACrC,mDAAiC;AACjC,8DAA4C;AAC5C,sDAAoC;AACpC,sDAAoC;AACpC,qDAAmC;AACnC,6DAA2C;AAC3C,sDAAoC;AACpC,6DAA2C;AAE3C,YAAY;AACZ,mDAAiC"}
|
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
import { NxContext } from '@nextage/nx-frame-be';
|
|
2
2
|
import { QueueEventType } from './enums';
|
|
3
|
+
import { EventMeta } from './event-envelope.interfaces';
|
|
3
4
|
export interface OutboxEvent {
|
|
4
5
|
id: string;
|
|
5
6
|
type: QueueEventType;
|
|
7
|
+
subject: string;
|
|
6
8
|
data: any;
|
|
9
|
+
meta?: EventMeta;
|
|
10
|
+
}
|
|
11
|
+
export interface OutboxMessage {
|
|
12
|
+
type: QueueEventType;
|
|
13
|
+
subject: string;
|
|
14
|
+
data: any;
|
|
15
|
+
meta: EventMeta;
|
|
7
16
|
}
|
|
8
17
|
export interface OutboxPort {
|
|
9
18
|
create(evt: OutboxEvent, context: NxContext): Promise<void>;
|
|
10
19
|
markSent(id: string, context: NxContext): Promise<void>;
|
|
20
|
+
findUnsent(limit: number): Promise<OutboxEvent[]>;
|
|
11
21
|
}
|
|
12
22
|
//# sourceMappingURL=outbox.interfaces.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"outbox.interfaces.d.ts","sourceRoot":"","sources":["../../../src/events/types/outbox.interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAW,sBAAsB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"outbox.interfaces.d.ts","sourceRoot":"","sources":["../../../src/events/types/outbox.interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAW,sBAAsB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAW,6BAA6B,CAAC;AAS7D,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAO,MAAM,CAAC;IAChB,IAAI,EAAK,cAAc,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAK,GAAG,CAAC;IACb,IAAI,CAAC,EAAI,SAAS,CAAC;CACpB;AAQD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAK,cAAc,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAK,GAAG,CAAC;IACb,IAAI,EAAK,SAAS,CAAC;CACpB;AAUD,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,GAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,GAAQ,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D,UAAU,CAAC,KAAK,EAAE,MAAM,GAAuB,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;CACvE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay.constants.d.ts","sourceRoot":"","sources":["../../../src/events/types/relay.constants.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,wBAAwB,MAAO,CAAC;AAC7C,eAAO,MAAM,yBAAyB,QAAS,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Relay (Step 3.5) tuning defaults. The relay redelivers `sent:false` outbox rows
|
|
3
|
+
// at startup (recover from a previous crash) and periodically (recover from a
|
|
4
|
+
// transient broker/network outage while the process stays up).
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DEFAULT_RELAY_INTERVAL_MS = exports.DEFAULT_RELAY_BATCH_SIZE = void 0;
|
|
7
|
+
exports.DEFAULT_RELAY_BATCH_SIZE = 100; // rows drained per tick
|
|
8
|
+
exports.DEFAULT_RELAY_INTERVAL_MS = 30000; // 30s periodic sweep
|
|
9
|
+
//# sourceMappingURL=relay.constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay.constants.js","sourceRoot":"","sources":["../../../src/events/types/relay.constants.ts"],"names":[],"mappings":";AAAA,kFAAkF;AAClF,8EAA8E;AAC9E,+DAA+D;;;AAElD,QAAA,wBAAwB,GAAI,GAAG,CAAC,CAAI,wBAAwB;AAC5D,QAAA,yBAAyB,GAAG,KAAM,CAAC,CAAC,qBAAqB"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Event, IPublisher } from '../interfaces';
|
|
2
|
+
export interface EventRelayOptions {
|
|
3
|
+
batchSize?: number;
|
|
4
|
+
intervalMs?: number;
|
|
5
|
+
onError?: (err: unknown) => void;
|
|
6
|
+
onSkip?: (subject: string, id: string) => void;
|
|
7
|
+
}
|
|
8
|
+
export interface PublisherProvider {
|
|
9
|
+
eventPublishers(): IPublisher<Event>[];
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=relay.interfaces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay.interfaces.d.ts","sourceRoot":"","sources":["../../../src/events/types/relay.interfaces.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAIlD,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAG,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAK,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IACpC,MAAM,CAAC,EAAM,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CACpD;AAKD,MAAM,WAAW,iBAAiB;IAChC,eAAe,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;CACxC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Relay (Step 3.5) contracts. Kept separate from the relay/registry logic that
|
|
3
|
+
// consumes them (house rule: types live in `<concern>.interfaces.ts`).
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
//# sourceMappingURL=relay.interfaces.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay.interfaces.js","sourceRoot":"","sources":["../../../src/events/types/relay.interfaces.ts"],"names":[],"mappings":";AAAA,+EAA+E;AAC/E,uEAAuE"}
|