@nextage/era-lib 1.0.174 → 1.0.176

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.
Files changed (51) hide show
  1. package/build/events/base-event.controller.d.ts +52 -1
  2. package/build/events/base-event.controller.d.ts.map +1 -1
  3. package/build/events/base-event.controller.js +104 -10
  4. package/build/events/base-event.controller.js.map +1 -1
  5. package/build/events/base-listener.d.ts +17 -0
  6. package/build/events/base-listener.d.ts.map +1 -1
  7. package/build/events/base-listener.js +38 -3
  8. package/build/events/base-listener.js.map +1 -1
  9. package/build/events/base-nats-listener.d.ts +17 -0
  10. package/build/events/base-nats-listener.d.ts.map +1 -1
  11. package/build/events/base-nats-listener.js +40 -2
  12. package/build/events/base-nats-listener.js.map +1 -1
  13. package/build/events/base-nats-publisher.d.ts +6 -1
  14. package/build/events/base-nats-publisher.d.ts.map +1 -1
  15. package/build/events/base-nats-publisher.js +8 -9
  16. package/build/events/base-nats-publisher.js.map +1 -1
  17. package/build/events/base-publisher.d.ts +5 -1
  18. package/build/events/base-publisher.d.ts.map +1 -1
  19. package/build/events/base-publisher.js +7 -2
  20. package/build/events/base-publisher.js.map +1 -1
  21. package/build/events/cascade.d.ts +13 -0
  22. package/build/events/cascade.d.ts.map +1 -0
  23. package/build/events/cascade.js +87 -0
  24. package/build/events/cascade.js.map +1 -0
  25. package/build/events/index.d.ts +2 -0
  26. package/build/events/index.d.ts.map +1 -1
  27. package/build/events/index.js +2 -0
  28. package/build/events/index.js.map +1 -1
  29. package/build/events/interfaces.d.ts +2 -1
  30. package/build/events/interfaces.d.ts.map +1 -1
  31. package/build/events/outbox.d.ts +12 -0
  32. package/build/events/outbox.d.ts.map +1 -0
  33. package/build/events/outbox.js +17 -0
  34. package/build/events/outbox.js.map +1 -0
  35. package/build/events/types/event-envelope.constants.d.ts +2 -0
  36. package/build/events/types/event-envelope.constants.d.ts.map +1 -0
  37. package/build/events/types/event-envelope.constants.js +11 -0
  38. package/build/events/types/event-envelope.constants.js.map +1 -0
  39. package/build/events/types/event-envelope.interfaces.d.ts +23 -0
  40. package/build/events/types/event-envelope.interfaces.d.ts.map +1 -0
  41. package/build/events/types/event-envelope.interfaces.js +3 -0
  42. package/build/events/types/event-envelope.interfaces.js.map +1 -0
  43. package/build/events/types/index.d.ts +3 -0
  44. package/build/events/types/index.d.ts.map +1 -1
  45. package/build/events/types/index.js +3 -0
  46. package/build/events/types/index.js.map +1 -1
  47. package/build/events/types/outbox.interfaces.d.ts +12 -0
  48. package/build/events/types/outbox.interfaces.d.ts.map +1 -0
  49. package/build/events/types/outbox.interfaces.js +3 -0
  50. package/build/events/types/outbox.interfaces.js.map +1 -0
  51. package/package.json +2 -2
@@ -30,6 +30,35 @@ export declare abstract class BaseEventCtrl<TCreate extends Event, TUpdate exten
30
30
  */
31
31
  publish(item: TAttrs, type: QueueEventType, context: NxContext): Promise<void>;
32
32
  /**
33
+ * Overridable post-write / post-read enrichment of the RETURNED document (e.g.
34
+ * populate references, attach a joined aggregate). Runs AFTER the atomic write
35
+ * and event dispatch, so a subclass can shape the doc handed back to its
36
+ * resolvers WITHOUT overriding create / update / get — which would shadow the
37
+ * transactional outbox (that was the E3 regression). Default: identity.
38
+ *
39
+ * @param doc
40
+ * @param context
41
+ */
42
+ protected decorateDoc(doc: TDoc, context: NxContext): Promise<TDoc>;
43
+ /**
44
+ * Read one entity and apply the subclass `decorateDoc` enrichment.
45
+ *
46
+ * @param id
47
+ * @param context
48
+ */
49
+ get(id: string, context?: NxContext): Promise<TDoc | null>;
50
+ /**
51
+ *
52
+ * @param item
53
+ * @param context
54
+ * @returns
55
+ */
56
+ /**
57
+ * Create the entity and its outbox row ATOMICALLY (same transaction when the
58
+ * deployment supports it), then dispatch the event and mark the row sent after
59
+ * commit. A broker failure leaves the row at sent:false (recoverable), never a
60
+ * lost event (fixes the E2 non-atomic gap; the per-controller override that used
61
+ * to do this 3-op dance is removed — E3).
33
62
  *
34
63
  * @param item
35
64
  * @param context
@@ -38,6 +67,7 @@ export declare abstract class BaseEventCtrl<TCreate extends Event, TUpdate exten
38
67
  create(item: TAttrs, context: NxContext): Promise<TDoc>;
39
68
  /**
40
69
  *
70
+ * @param id
41
71
  * @param item
42
72
  * @param context
43
73
  * @returns
@@ -45,10 +75,31 @@ export declare abstract class BaseEventCtrl<TCreate extends Event, TUpdate exten
45
75
  update(id: string, item: TAttrs, context: NxContext): Promise<TDoc>;
46
76
  /**
47
77
  *
48
- * @param item
78
+ * @param id
49
79
  * @param context
50
80
  * @returns
51
81
  */
52
82
  remove(id: string, context: NxContext): Promise<TDoc>;
83
+ /**
84
+ * Persist an outbox row (sent:false) for `item` inside the caller's transaction.
85
+ * Returns the row id, or undefined when no outbox is registered (the event is
86
+ * then still published, just not tracked).
87
+ *
88
+ * @param item
89
+ * @param type
90
+ * @param context
91
+ */
92
+ private enqueueOutbox;
93
+ /**
94
+ * Dispatch the event to the broker, then mark the outbox row as sent. Runs AFTER
95
+ * the transaction commits, so `publish` (a non-DB side effect) is never retried
96
+ * by `withTransaction` and a broker failure leaves a recoverable sent:false row.
97
+ *
98
+ * @param item
99
+ * @param type
100
+ * @param outboxId
101
+ * @param context
102
+ */
103
+ private dispatchOutbox;
53
104
  }
54
105
  //# sourceMappingURL=base-event.controller.d.ts.map
@@ -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,MAAc,mDAAmD,CAAC;AACtF,OAAO,EAAE,YAAY,EAAE,MAAW,wDAAwD,CAAC;AAC3F,OAAO,EAAE,cAAc,EAAE,MAAS,wDAAwD,CAAC;AAC3F,OAAO,EAAE,SAAS,EAAE,MAAc,sBAAsB,CAAC;AAGzD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAS,eAAe,CAAC;AAOlD,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,CAAC;IAMnO,SAAS,CAAC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAI,OAAO,CAAC,MAAM,CAAC;IAC3F,SAAS,CAAC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAI,OAAO,CAAC,MAAM,CAAC;IAC3F,SAAS,CAAC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAI,OAAO,CAAC,MAAM,CAAC;IAE3F,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;IAK1D,OAAO,CAAC,aAAa,CAAC,CAAmD;IAEzE;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAqBxB;;;;;OAKG;IAoBH;;;;;OAKG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAUpF;;;;;OAKG;IACY,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAQtE;;;;;OAKG;IACY,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAQlF;;;;;OAKG;IACY,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;CAOrE"}
1
+ {"version":3,"file":"base-event.controller.d.ts","sourceRoot":"","sources":["../../src/events/base-event.controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAc,mDAAmD,CAAC;AACtF,OAAO,EAAE,YAAY,EAAE,MAAW,wDAAwD,CAAC;AAC3F,OAAO,EAAE,cAAc,EAAE,MAAS,wDAAwD,CAAC;AAE3F,OAAO,EAAE,SAAS,EAAE,MAAc,sBAAsB,CAAC;AAGzD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAKjD,OAAO,EAAE,cAAc,EAAE,MAAS,eAAe,CAAC;AAOlD,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,CAAC;IAMnO,SAAS,CAAC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAI,OAAO,CAAC,MAAM,CAAC;IAC3F,SAAS,CAAC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAI,OAAO,CAAC,MAAM,CAAC;IAC3F,SAAS,CAAC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAI,OAAO,CAAC,MAAM,CAAC;IAE3F,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;IAK1D,OAAO,CAAC,aAAa,CAAC,CAAmD;IAEzE;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAqBxB;;;;;OAKG;IAoBH;;;;;OAKG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAWpF;;;;;;;;;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;;;;;;;;OAQG;YACW,aAAa;IAY3B;;;;;;;;;OASG;YACW,cAAc;CAQ7B"}
@@ -2,6 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BaseEventCtrl = void 0;
4
4
  const base_controller_1 = require("@nextage/nx-frame-be/build/common/base/base.controller");
5
+ const mongo_utils_1 = require("@nextage/nx-frame-be/build/common/base/mongo-utils");
6
+ const outbox_1 = require("./outbox");
7
+ const cascade_1 = require("./cascade");
5
8
  const enums_1 = require("./types/enums");
6
9
  class BaseEventCtrl extends base_controller_1.BaseController {
7
10
  /**
@@ -59,41 +62,132 @@ class BaseEventCtrl extends base_controller_1.BaseController {
59
62
  if (!publishers?.length || !parser)
60
63
  return;
61
64
  const data = parser(item, type);
62
- await Promise.all(publishers.map(pub => pub.publish(data)));
65
+ const meta = (0, cascade_1.outgoingMeta)(context?._event);
66
+ await Promise.all(publishers.map(pub => pub.publish(data, meta)));
63
67
  }
64
68
  /**
69
+ * Overridable post-write / post-read enrichment of the RETURNED document (e.g.
70
+ * populate references, attach a joined aggregate). Runs AFTER the atomic write
71
+ * and event dispatch, so a subclass can shape the doc handed back to its
72
+ * resolvers WITHOUT overriding create / update / get — which would shadow the
73
+ * transactional outbox (that was the E3 regression). Default: identity.
74
+ *
75
+ * @param doc
76
+ * @param context
77
+ */
78
+ async decorateDoc(doc, context) {
79
+ return doc;
80
+ }
81
+ /**
82
+ * Read one entity and apply the subclass `decorateDoc` enrichment.
83
+ *
84
+ * @param id
85
+ * @param context
86
+ */
87
+ async get(id, context) {
88
+ const doc = await super.get(id, context);
89
+ return doc ? this.decorateDoc(doc, context ?? {}) : doc;
90
+ }
91
+ /**
92
+ *
93
+ * @param item
94
+ * @param context
95
+ * @returns
96
+ */
97
+ /**
98
+ * Create the entity and its outbox row ATOMICALLY (same transaction when the
99
+ * deployment supports it), then dispatch the event and mark the row sent after
100
+ * commit. A broker failure leaves the row at sent:false (recoverable), never a
101
+ * lost event (fixes the E2 non-atomic gap; the per-controller override that used
102
+ * to do this 3-op dance is removed — E3).
65
103
  *
66
104
  * @param item
67
105
  * @param context
68
106
  * @returns
69
107
  */
70
108
  async create(item, context) {
71
- const res = await super.create(item, context); // this.model.create(item, context);
72
- await this.publish(res.toJSON(), enums_1.QueueEventType.create, context);
73
- return res;
109
+ let payload;
110
+ let outboxId;
111
+ const res = await this.withTransaction(context, async (ctx) => {
112
+ const created = await super.create(item, ctx);
113
+ payload = created.toJSON();
114
+ outboxId = await this.enqueueOutbox(payload, enums_1.QueueEventType.create, ctx);
115
+ return created;
116
+ });
117
+ await this.dispatchOutbox(payload, enums_1.QueueEventType.create, outboxId, context);
118
+ return this.decorateDoc(res, context);
74
119
  }
75
120
  /**
76
121
  *
122
+ * @param id
77
123
  * @param item
78
124
  * @param context
79
125
  * @returns
80
126
  */
81
127
  async update(id, item, context) {
82
- const res = await super.update(id, item, context);
83
- await this.publish({ id, ...res.toObject() }, enums_1.QueueEventType.update, context);
84
- return res;
128
+ let payload;
129
+ let outboxId;
130
+ const res = await this.withTransaction(context, async (ctx) => {
131
+ const updated = await super.update(id, item, ctx);
132
+ payload = { id, ...updated.toObject() };
133
+ outboxId = await this.enqueueOutbox(payload, enums_1.QueueEventType.update, ctx);
134
+ return updated;
135
+ });
136
+ await this.dispatchOutbox(payload, enums_1.QueueEventType.update, outboxId, context);
137
+ return this.decorateDoc(res, context);
85
138
  }
86
139
  /**
87
140
  *
88
- * @param item
141
+ * @param id
89
142
  * @param context
90
143
  * @returns
91
144
  */
92
145
  async remove(id, context) {
93
- const res = await this.model.remove(id, context);
94
- await this.publish({ id, ...res.toObject() }, enums_1.QueueEventType.remove, context);
146
+ let payload;
147
+ let outboxId;
148
+ const res = await this.withTransaction(context, async (ctx) => {
149
+ const removed = await this.model.remove(id, ctx);
150
+ payload = { id, ...removed.toObject() };
151
+ outboxId = await this.enqueueOutbox(payload, enums_1.QueueEventType.remove, ctx);
152
+ return removed;
153
+ });
154
+ await this.dispatchOutbox(payload, enums_1.QueueEventType.remove, outboxId, context);
95
155
  return res;
96
156
  }
157
+ /**
158
+ * Persist an outbox row (sent:false) for `item` inside the caller's transaction.
159
+ * Returns the row id, or undefined when no outbox is registered (the event is
160
+ * then still published, just not tracked).
161
+ *
162
+ * @param item
163
+ * @param type
164
+ * @param context
165
+ */
166
+ async enqueueOutbox(item, type, context) {
167
+ const outbox = (0, outbox_1.getOutbox)();
168
+ if (!outbox)
169
+ return undefined;
170
+ const id = (0, mongo_utils_1.genObjectId)().toString();
171
+ const evt = { id, type, data: item };
172
+ await outbox.create(evt, context);
173
+ return id;
174
+ }
175
+ /**
176
+ * Dispatch the event to the broker, then mark the outbox row as sent. Runs AFTER
177
+ * the transaction commits, so `publish` (a non-DB side effect) is never retried
178
+ * by `withTransaction` and a broker failure leaves a recoverable sent:false row.
179
+ *
180
+ * @param item
181
+ * @param type
182
+ * @param outboxId
183
+ * @param context
184
+ */
185
+ async dispatchOutbox(item, type, outboxId, context) {
186
+ await this.publish(item, type, context);
187
+ const outbox = (0, outbox_1.getOutbox)();
188
+ if (outbox && outboxId)
189
+ await outbox.markSent(outboxId, context);
190
+ }
97
191
  }
98
192
  exports.BaseEventCtrl = BaseEventCtrl;
99
193
  //# sourceMappingURL=base-event.controller.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"base-event.controller.js","sourceRoot":"","sources":["../../src/events/base-event.controller.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base-event.controller.js","sourceRoot":"","sources":["../../src/events/base-event.controller.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,7 @@
1
+ import { NxContext } from '@nextage/nx-frame-be';
1
2
  import { Message } from './event-message';
2
3
  import { Event, MsgClientInterface, EventSubOptions } from './interfaces';
4
+ import { EventContext, IncomingEventRef } from './types/event-envelope.interfaces';
3
5
  export declare abstract class Listener<T extends Event> {
4
6
  abstract subject: T['subject'];
5
7
  abstract queueGroupName: string;
@@ -8,6 +10,7 @@ export declare abstract class Listener<T extends Event> {
8
10
  private subscription;
9
11
  private messageStack;
10
12
  private wait;
13
+ protected _incoming: IncomingEventRef | undefined;
11
14
  protected ackWait: number;
12
15
  constructor(client: MsgClientInterface);
13
16
  subscriptionOptions(): EventSubOptions;
@@ -17,6 +20,20 @@ export declare abstract class Listener<T extends Event> {
17
20
  * @returns
18
21
  */
19
22
  checkMessages(): Promise<void>;
23
+ /**
24
+ * Process a single message: unwrap the envelope, apply the cascade loop-guard,
25
+ * then dispatch to `onMessage`. A guard violation (runaway depth or revisited
26
+ * subject) is skipped — the in-memory bus has no ack/redelivery to fight — and
27
+ * the in-flight reference is always cleared so `nextContext` never leaks the
28
+ * previous event.
29
+ */
30
+ protected handleMessage(msg: Message): Promise<void>;
31
+ /**
32
+ * Build a child context carrying the in-flight event reference, so any event
33
+ * this listener republishes inherits the correlation and advances the cascade
34
+ * depth / visited lineage. Returns a fresh object (never mutates `base`).
35
+ */
36
+ protected nextContext(base?: NxContext): EventContext;
20
37
  /**
21
38
  *
22
39
  */
@@ -1 +1 @@
1
- {"version":3,"file":"base-listener.d.ts","sourceRoot":"","sources":["../../src/events/base-listener.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAA2C,iBAAiB,CAAC;AAE/E,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE1E,8BAAsB,QAAQ,CAAC,CAAC,SAAS,KAAK;IAE5C,QAAQ,CAAC,OAAO,EAAS,CAAC,CAAC,SAAS,CAAC,CAAC;IACtC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAEhC,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAEhE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,YAAY,CAAmC;IAEvD,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,IAAI,CAA+B;IAE3C,SAAS,CAAC,OAAO,EAAQ,MAAM,CAAe;gBAEjC,MAAM,EAAE,kBAAkB;IAIvC,mBAAmB,IAAI,eAAe;IAKhC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB7B;;;OAGG;IACG,aAAa;IAkBnB;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B;;;;OAIG;IACH,OAAO,CAAC,YAAY;CAKrB"}
1
+ {"version":3,"file":"base-listener.d.ts","sourceRoot":"","sources":["../../src/events/base-listener.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,SAAS,EAAE,MAAqB,sBAAsB,CAAC;AAClF,OAAO,EAAE,OAAO,EAAE,MAAyC,iBAAiB,CAAC;AAE7E,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAkB,mCAAmC,CAAC;AAG/F,8BAAsB,QAAQ,CAAC,CAAC,SAAS,KAAK;IAE5C,QAAQ,CAAC,OAAO,EAAS,CAAC,CAAC,SAAS,CAAC,CAAC;IACtC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAEhC,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAEhE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,YAAY,CAAmC;IAEvD,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,IAAI,CAA+B;IAI3C,SAAS,CAAC,SAAS,EAAM,gBAAgB,GAAG,SAAS,CAAC;IAEtD,SAAS,CAAC,OAAO,EAAQ,MAAM,CAAe;gBAEjC,MAAM,EAAE,kBAAkB;IAIvC,mBAAmB,IAAI,eAAe;IAKhC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB7B;;;OAGG;IACG,aAAa;IAsBnB;;;;;;OAMG;cACa,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAwB1D;;;;OAIG;IACH,SAAS,CAAC,WAAW,CAAC,IAAI,GAAE,SAAc,GAAG,YAAY;IAKzD;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B;;;;OAIG;IACH,OAAO,CAAC,YAAY;CAKrB"}
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Listener = void 0;
4
4
  const nx_frame_be_1 = require("@nextage/nx-frame-be");
5
+ const cascade_1 = require("./cascade");
5
6
  class Listener {
6
7
  constructor(client) {
7
8
  this.messageStack = [];
@@ -33,11 +34,45 @@ class Listener {
33
34
  if (!msg)
34
35
  return;
35
36
  this.wait = true;
36
- const parsedData = this.parseMessage(msg);
37
- const res = await this.onMessage(parsedData, msg);
38
- this.wait = false;
37
+ try {
38
+ await this.handleMessage(msg);
39
+ }
40
+ finally {
41
+ this.wait = false;
42
+ }
39
43
  await this.checkMessages();
40
44
  }
45
+ /**
46
+ * Process a single message: unwrap the envelope, apply the cascade loop-guard,
47
+ * then dispatch to `onMessage`. A guard violation (runaway depth or revisited
48
+ * subject) is skipped — the in-memory bus has no ack/redelivery to fight — and
49
+ * the in-flight reference is always cleared so `nextContext` never leaks the
50
+ * previous event.
51
+ */
52
+ async handleMessage(msg) {
53
+ try {
54
+ const { id, data, meta } = (0, cascade_1.unwrapEnvelope)(this.parseMessage(msg));
55
+ const violation = (0, cascade_1.cascadeViolation)(meta, this.subject);
56
+ if (violation) {
57
+ nx_frame_be_1.APP.logger.warn(`🔁 Cascade guard tripped on '${this.subject}': ${violation}`, (0, nx_frame_be_1.logClassCtx)(this));
58
+ }
59
+ else {
60
+ this._incoming = { id, subject: this.subject, meta };
61
+ await this.onMessage(data, msg);
62
+ }
63
+ }
64
+ finally {
65
+ this._incoming = undefined;
66
+ }
67
+ }
68
+ /**
69
+ * Build a child context carrying the in-flight event reference, so any event
70
+ * this listener republishes inherits the correlation and advances the cascade
71
+ * depth / visited lineage. Returns a fresh object (never mutates `base`).
72
+ */
73
+ nextContext(base = {}) {
74
+ return this._incoming ? { ...base, _event: this._incoming } : { ...base };
75
+ }
41
76
  /**
42
77
  *
43
78
  */
@@ -1 +1 @@
1
- {"version":3,"file":"base-listener.js","sourceRoot":"","sources":["../../src/events/base-listener.ts"],"names":[],"mappings":";;;AAAA,sDAAoF;AAKpF,MAAsB,QAAQ;IAe5B,YAAa,MAA0B;QAL/B,iBAAY,GAAiB,EAAE,CAAC;QAChC,SAAI,GAAyB,KAAK,CAAC;QAEjC,YAAO,GAAoB,CAAC,GAAG,IAAI,CAAC;QAG5C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,mBAAmB;QAEjB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,KAAK,CAAC,MAAM;QAEV,IAAI,CAAC,YAAY,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAC7C,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,mBAAmB,EAAE,CAC3B,CAAC;QAEF,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC,SAAS,EAAE,CAAC,GAAY,EAAE,EAAE;YAEhD,iBAAG,CAAC,MAAM,CAAC,IAAI,CAAC,2BAA2B,IAAI,CAAC,OAAO,MAAM,IAAI,CAAC,cAAc,EAAE,EAAE,IAAA,yBAAW,EAAC,IAAI,CAAC,CAAC,CAAC;YAEvG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC5B,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,6CAA6C;YAC7C,mCAAmC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,aAAa;QAEjB,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM;YACxC,OAAO;QAET,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;QAEtC,IAAI,CAAC,GAAG;YACN,OAAO;QAET,IAAI,CAAC,IAAI,GAAU,IAAI,CAAC;QACxB,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,GAAG,GAAU,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QACzD,IAAI,CAAC,IAAI,GAAU,KAAK,CAAC;QAEzB,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QAER,IAAI,IAAI,CAAC,YAAY;YACnB,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC/C,CAAC;IAED;;;;OAIG;IACK,YAAY,CAAC,GAAY;QAE/B,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;QAC3B,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IACzF,CAAC;CACF;AApFD,4BAoFC"}
1
+ {"version":3,"file":"base-listener.js","sourceRoot":"","sources":["../../src/events/base-listener.ts"],"names":[],"mappings":";;;AAAA,sDAAkF;AAKlF,uCAAuE;AAEvE,MAAsB,QAAQ;IAmB5B,YAAa,MAA0B;QAT/B,iBAAY,GAAiB,EAAE,CAAC;QAChC,SAAI,GAAyB,KAAK,CAAC;QAMjC,YAAO,GAAoB,CAAC,GAAG,IAAI,CAAC;QAG5C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,mBAAmB;QAEjB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,KAAK,CAAC,MAAM;QAEV,IAAI,CAAC,YAAY,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAC7C,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,mBAAmB,EAAE,CAC3B,CAAC;QAEF,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC,SAAS,EAAE,CAAC,GAAY,EAAE,EAAE;YAEhD,iBAAG,CAAC,MAAM,CAAC,IAAI,CAAC,2BAA2B,IAAI,CAAC,OAAO,MAAM,IAAI,CAAC,cAAc,EAAE,EAAE,IAAA,yBAAW,EAAC,IAAI,CAAC,CAAC,CAAC;YAEvG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC5B,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,6CAA6C;YAC7C,mCAAmC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,aAAa;QAEjB,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM;YACxC,OAAO;QAET,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;QAEtC,IAAI,CAAC,GAAG;YACN,OAAO;QAET,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QAEjB,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAChC,CAAC;gBACO,CAAC;YACP,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC;QACpB,CAAC;QAED,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED;;;;;;OAMG;IACO,KAAK,CAAC,aAAa,CAAC,GAAY;QAExC,IAAI,CAAC;YAEH,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,IAAA,wBAAc,EAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;YAElE,MAAM,SAAS,GAAG,IAAA,0BAAgB,EAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YAEvD,IAAI,SAAS,EAAE,CAAC;gBAEd,iBAAG,CAAC,MAAM,CAAC,IAAI,CAAC,gCAAgC,IAAI,CAAC,OAAO,MAAM,SAAS,EAAE,EAAE,IAAA,yBAAW,EAAC,IAAI,CAAC,CAAC,CAAC;YACpG,CAAC;iBACI,CAAC;gBAEJ,IAAI,CAAC,SAAS,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC;gBACrD,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;gBACO,CAAC;YAEP,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC7B,CAAC;IACH,CAAC;IAED;;;;OAIG;IACO,WAAW,CAAC,OAAkB,EAAE;QAExC,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC;IAC5E,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QAER,IAAI,IAAI,CAAC,YAAY;YACnB,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC/C,CAAC;IAED;;;;OAIG;IACK,YAAY,CAAC,GAAY;QAE/B,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;QAC3B,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IACzF,CAAC;CACF;AArID,4BAqIC"}
@@ -1,4 +1,6 @@
1
+ import { NxContext } from '@nextage/nx-frame-be';
1
2
  import { Event, MsgClientInterface, EventSubOptions } from './interfaces';
3
+ import { EventContext, IncomingEventRef } from './types/event-envelope.interfaces';
2
4
  import { JsMsg } from 'nats';
3
5
  export declare abstract class NatsListener<T extends Event> {
4
6
  private readonly client;
@@ -7,6 +9,7 @@ export declare abstract class NatsListener<T extends Event> {
7
9
  abstract streamName: string;
8
10
  private consumer?;
9
11
  private isListening;
12
+ protected _incoming?: IncomingEventRef;
10
13
  protected ackWait: number;
11
14
  protected maxDeliver: number;
12
15
  protected nakBackoffMs: number[];
@@ -37,6 +40,20 @@ export declare abstract class NatsListener<T extends Event> {
37
40
  * than `term()`, so an unreachable DLQ never causes silent message loss.
38
41
  */
39
42
  protected handleMessage(msg: JsMsg): Promise<void>;
43
+ /**
44
+ * Park a cascade-guard violation on the DLQ and terminate it so it never
45
+ * re-enters the source stream. Falls back to `nak` only if the DLQ is
46
+ * unreachable, so a loop is never silently lost.
47
+ */
48
+ protected dropCascadeViolation(msg: JsMsg, reason: string): Promise<void>;
49
+ /**
50
+ * Build a child context carrying the in-flight event reference, so any event
51
+ * this listener republishes inherits the correlation, is marked as caused by
52
+ * the current event, and advances the cascade depth / visited lineage. Returns
53
+ * a fresh object (never mutates the shared base context). At the root — or when
54
+ * no event is in flight — it is just a copy of `base`.
55
+ */
56
+ protected nextContext(base?: NxContext): EventContext;
40
57
  /**
41
58
  * Parks a failed message on the DLQ stream. Returns `true` on success so the
42
59
  * caller can safely `term()` the original; returns `false` if the DLQ could
@@ -1 +1 @@
1
- {"version":3,"file":"base-nats-listener.d.ts","sourceRoot":"","sources":["../../src/events/base-nats-listener.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAG1E,OAAO,EAAY,KAAK,EAAE,MAAiC,MAAM,CAAC;AAElE,8BAAsB,YAAY,CAAC,CAAC,SAAS,KAAK;IAqBnC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAnBpC,QAAQ,CAAC,OAAO,EAAS,CAAC,CAAC,SAAS,CAAC,CAAC;IACtC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAM,MAAM,CAAC;IAEhC,OAAO,CAAC,QAAQ,CAAC,CAAiB;IAClC,OAAO,CAAC,WAAW,CAAsB;IAEzC,SAAS,CAAC,OAAO,EAAQ,MAAM,CAAuB;IACtD,SAAS,CAAC,UAAU,EAAK,MAAM,CAAK;IAMpC,SAAS,CAAC,YAAY,EAAG,MAAM,EAAE,CAAuB;IAGxD,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;gBAEhC,MAAM,EAAE,kBAAkB;IAExD;;;OAGG;IACH,mBAAmB,IAAI,eAAe;IAKtC;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB7B;;;;OAIG;YACW,eAAe;IAqB7B;;;;;;;;OAQG;cACa,aAAa,CAAC,GAAG,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAgCxD;;;;OAIG;cACa,gBAAgB,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAyB9E;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAe3B;;;OAGG;IACH,OAAO,CAAC,eAAe;IAKvB;;OAEG;IACH,OAAO,CAAC,UAAU;IAMlB;;;;OAIG;IACH,OAAO,CAAC,MAAM;IAKd;;;;OAIG;IACH,OAAO,CAAC,YAAY;CAYrB"}
1
+ {"version":3,"file":"base-nats-listener.d.ts","sourceRoot":"","sources":["../../src/events/base-nats-listener.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,SAAS,EAAE,MAAkC,sBAAsB,CAAC;AAClF,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAG1E,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAkB,mCAAmC,CAAC;AAE/F,OAAO,EAAY,KAAK,EAAE,MAAiC,MAAM,CAAC;AAElE,8BAAsB,YAAY,CAAC,CAAC,SAAS,KAAK;IA2BnC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAzBpC,QAAQ,CAAC,OAAO,EAAS,CAAC,CAAC,SAAS,CAAC,CAAC;IACtC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAM,MAAM,CAAC;IAEhC,OAAO,CAAC,QAAQ,CAAC,CAAiB;IAClC,OAAO,CAAC,WAAW,CAAsB;IAMzC,SAAS,CAAC,SAAS,CAAC,EAAK,gBAAgB,CAAC;IAE1C,SAAS,CAAC,OAAO,EAAQ,MAAM,CAAuB;IACtD,SAAS,CAAC,UAAU,EAAK,MAAM,CAAK;IAMpC,SAAS,CAAC,YAAY,EAAG,MAAM,EAAE,CAAuB;IAGxD,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;gBAEhC,MAAM,EAAE,kBAAkB;IAExD;;;OAGG;IACH,mBAAmB,IAAI,eAAe;IAKtC;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB7B;;;;OAIG;YACW,eAAe;IAqB7B;;;;;;;;OAQG;cACa,aAAa,CAAC,GAAG,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAmDxD;;;;OAIG;cACa,oBAAoB,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAU/E;;;;;;OAMG;IACH,SAAS,CAAC,WAAW,CAAC,IAAI,GAAE,SAAc,GAAG,YAAY;IAKzD;;;;OAIG;cACa,gBAAgB,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAyB9E;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAe3B;;;OAGG;IACH,OAAO,CAAC,eAAe;IAKvB;;OAEG;IACH,OAAO,CAAC,UAAU;IAMlB;;;;OAIG;IACH,OAAO,CAAC,MAAM;IAKd;;;;OAIG;IACH,OAAO,CAAC,YAAY;CAYrB"}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NatsListener = void 0;
4
4
  const nx_frame_be_1 = require("@nextage/nx-frame-be");
5
5
  const dlq_constants_1 = require("./types/dlq.constants");
6
+ const cascade_1 = require("./cascade");
6
7
  class NatsListener {
7
8
  constructor(client) {
8
9
  this.client = client;
@@ -75,8 +76,19 @@ class NatsListener {
75
76
  async handleMessage(msg) {
76
77
  try {
77
78
  nx_frame_be_1.APP.logger.info(`📥 Received message on '${this.subject}'`);
78
- const parsed = this.parseMessage(msg);
79
- await this.onMessage(parsed.data, msg);
79
+ const { id, data, meta } = (0, cascade_1.unwrapEnvelope)(this.parseMessage(msg));
80
+ // Cascade governance: a runaway depth or a revisited subject is a loop, not
81
+ // a transient failure — park it on the DLQ and drop it immediately (no
82
+ // retries, which would only replay the same loop three more times).
83
+ const violation = (0, cascade_1.cascadeViolation)(meta, this.subject);
84
+ if (violation) {
85
+ await this.dropCascadeViolation(msg, violation);
86
+ return;
87
+ }
88
+ // Expose the in-flight event so `onMessage` can thread its metadata into any
89
+ // republished event via `nextContext`.
90
+ this._incoming = { id, subject: this.subject, meta };
91
+ await this.onMessage(data, msg);
80
92
  msg.ack();
81
93
  nx_frame_be_1.APP.logger.info(`✅ Message acknowledged on '${this.subject}'`);
82
94
  }
@@ -94,6 +106,32 @@ class NatsListener {
94
106
  msg.nak(this.backoffFor(deliveries));
95
107
  }
96
108
  }
109
+ finally {
110
+ this._incoming = undefined;
111
+ }
112
+ }
113
+ /**
114
+ * Park a cascade-guard violation on the DLQ and terminate it so it never
115
+ * re-enters the source stream. Falls back to `nak` only if the DLQ is
116
+ * unreachable, so a loop is never silently lost.
117
+ */
118
+ async dropCascadeViolation(msg, reason) {
119
+ nx_frame_be_1.APP.logger.warn(`🔁 Cascade guard tripped on '${this.subject}': ${reason}`);
120
+ const parked = await this.sendToDeadLetter(msg, new Error(`cascade-guard: ${reason}`));
121
+ if (parked)
122
+ msg.term();
123
+ else
124
+ msg.nak(this.backoffFor(this.deliveryAttempt(msg)));
125
+ }
126
+ /**
127
+ * Build a child context carrying the in-flight event reference, so any event
128
+ * this listener republishes inherits the correlation, is marked as caused by
129
+ * the current event, and advances the cascade depth / visited lineage. Returns
130
+ * a fresh object (never mutates the shared base context). At the root — or when
131
+ * no event is in flight — it is just a copy of `base`.
132
+ */
133
+ nextContext(base = {}) {
134
+ return this._incoming ? { ...base, _event: this._incoming } : { ...base };
97
135
  }
98
136
  /**
99
137
  * Parks a failed message on the DLQ stream. Returns `true` on success so the
@@ -1 +1 @@
1
- {"version":3,"file":"base-nats-listener.js","sourceRoot":"","sources":["../../src/events/base-nats-listener.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base-nats-listener.js","sourceRoot":"","sources":["../../src/events/base-nats-listener.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,19 @@
1
1
  import { JetStreamPublishOptions } from 'nats';
2
2
  import { Event, IPublisher, MsgClientInterface } from './interfaces';
3
+ import { EventMeta } from './types/event-envelope.interfaces';
3
4
  export declare abstract class NatsPublisher<T extends Event> implements IPublisher<T, Partial<JetStreamPublishOptions>> {
4
5
  private readonly client;
5
6
  abstract subject: T['subject'];
6
7
  constructor(client: MsgClientInterface);
7
8
  /**
9
+ * Emit the event wrapped in the shared in-band envelope (id / subject / data /
10
+ * timestamp / cascade meta). The metadata rides in the payload so loop-guard and
11
+ * causation tracing stay transport agnostic.
8
12
  *
9
13
  * @param data
14
+ * @param meta
10
15
  * @param options
11
16
  */
12
- publish(data: T['data'], options?: Partial<JetStreamPublishOptions>): Promise<void>;
17
+ publish(data: T['data'], meta?: EventMeta, options?: Partial<JetStreamPublishOptions>): Promise<void>;
13
18
  }
14
19
  //# sourceMappingURL=base-nats-publisher.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"base-nats-publisher.d.ts","sourceRoot":"","sources":["../../src/events/base-nats-publisher.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAoB,MAAM,CAAC;AAC7D,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAErE,8BAAsB,aAAa,CAAC,CAAC,SAAS,KAAK,CAAE,YAAW,UAAU,CAAC,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAIjG,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC;gBAEF,MAAM,EAAE,kBAAkB;IAEvD;;;;OAIG;IACG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAsB1F"}
1
+ {"version":3,"file":"base-nats-publisher.d.ts","sourceRoot":"","sources":["../../src/events/base-nats-publisher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAoB,MAAM,CAAC;AAC7D,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,MAAkC,mCAAmC,CAAC;AAG1F,8BAAsB,aAAa,CAAC,CAAC,SAAS,KAAK,CAAE,YAAW,UAAU,CAAC,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAIjG,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC;gBAEF,MAAM,EAAE,kBAAkB;IAEvD;;;;;;;;OAQG;IACG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAiB5G"}
@@ -1,25 +1,24 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NatsPublisher = void 0;
4
- const nx_frame_be_1 = require("@nextage/nx-frame-be");
4
+ const cascade_1 = require("./cascade");
5
5
  class NatsPublisher {
6
6
  constructor(client) {
7
7
  this.client = client;
8
8
  }
9
9
  /**
10
+ * Emit the event wrapped in the shared in-band envelope (id / subject / data /
11
+ * timestamp / cascade meta). The metadata rides in the payload so loop-guard and
12
+ * causation tracing stay transport agnostic.
10
13
  *
11
14
  * @param data
15
+ * @param meta
12
16
  * @param options
13
17
  */
14
- async publish(data, options) {
18
+ async publish(data, meta, options) {
15
19
  try {
16
- const message = {
17
- id: (0, nx_frame_be_1.uuid)(),
18
- subject: this.subject,
19
- data,
20
- timestamp: new Date().toISOString(),
21
- };
22
- await this.client.publish(this.subject, JSON.stringify(message), options);
20
+ const envelope = (0, cascade_1.buildEnvelope)(this.subject, data, meta);
21
+ await this.client.publish(this.subject, JSON.stringify(envelope), options);
23
22
  }
24
23
  catch (error) {
25
24
  console.error(`❌ Failed to publish to '${this.subject}':`, error);
@@ -1 +1 @@
1
- {"version":3,"file":"base-nats-publisher.js","sourceRoot":"","sources":["../../src/events/base-nats-publisher.ts"],"names":[],"mappings":";;;AAAA,sDAA6E;AAI7E,MAAsB,aAAa;IAIjC,YAA6B,MAA0B;QAA1B,WAAM,GAAN,MAAM,CAAoB;IAAG,CAAC;IAE3D;;;;OAIG;IACH,KAAK,CAAC,OAAO,CAAC,IAAe,EAAE,OAA0C;QAExE,IAAI,CAAC;YAEF,MAAM,OAAO,GAAG;gBACd,EAAE,EAAO,IAAA,kBAAI,GAAE;gBACf,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,IAAI;gBACJ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACpC,CAAC;YAEF,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CACvB,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EACvB,OAAO,CACR,CAAC;QAEJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,2BAA2B,IAAI,CAAC,OAAO,IAAI,EAAE,KAAK,CAAC,CAAC;YAClE,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF;AAjCD,sCAiCC"}
1
+ {"version":3,"file":"base-nats-publisher.js","sourceRoot":"","sources":["../../src/events/base-nats-publisher.ts"],"names":[],"mappings":";;;AAGA,uCAAkE;AAElE,MAAsB,aAAa;IAIjC,YAA6B,MAA0B;QAA1B,WAAM,GAAN,MAAM,CAAoB;IAAG,CAAC;IAE3D;;;;;;;;OAQG;IACH,KAAK,CAAC,OAAO,CAAC,IAAe,EAAE,IAAgB,EAAE,OAA0C;QAE1F,IAAI,CAAC;YAEF,MAAM,QAAQ,GAAG,IAAA,uBAAa,EAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YAEzD,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CACvB,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EACxB,OAAO,CACR,CAAC;QAEJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,2BAA2B,IAAI,CAAC,OAAO,IAAI,EAAE,KAAK,CAAC,CAAC;YAClE,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF;AAhCD,sCAgCC"}
@@ -1,13 +1,17 @@
1
1
  import { Event, IPublisher, MsgClientInterface } from './interfaces';
2
+ import { EventMeta } from './types/event-envelope.interfaces';
2
3
  export declare abstract class Publisher<T extends Event> implements IPublisher<T> {
3
4
  abstract subject: T['subject'];
4
5
  private readonly client;
5
6
  constructor(client: MsgClientInterface);
6
7
  /**
8
+ * Emit the event wrapped in the shared in-band envelope, so the msg bus carries
9
+ * the same cascade metadata as the NATS transport (transport-agnostic tracing).
7
10
  *
8
11
  * @param data
12
+ * @param meta
9
13
  * @returns
10
14
  */
11
- publish(data: T['data']): Promise<void>;
15
+ publish(data: T['data'], meta?: EventMeta): Promise<void>;
12
16
  }
13
17
  //# sourceMappingURL=base-publisher.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"base-publisher.d.ts","sourceRoot":"","sources":["../../src/events/base-publisher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAErE,8BAAsB,SAAS,CAAC,CAAC,SAAS,KAAK,CAAE,YAAW,UAAU,CAAC,CAAC,CAAC;IAEvE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC;IAE/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;gBAEhC,MAAM,EAAE,kBAAkB;IAKtC;;;;OAIG;IACG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAI9C"}
1
+ {"version":3,"file":"base-publisher.d.ts","sourceRoot":"","sources":["../../src/events/base-publisher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,MAAkC,mCAAmC,CAAC;AAG1F,8BAAsB,SAAS,CAAC,CAAC,SAAS,KAAK,CAAE,YAAW,UAAU,CAAC,CAAC,CAAC;IAEvE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC;IAE/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;gBAEhC,MAAM,EAAE,kBAAkB;IAKtC;;;;;;;OAOG;IACG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;CAKhE"}
@@ -1,17 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Publisher = void 0;
4
+ const cascade_1 = require("./cascade");
4
5
  class Publisher {
5
6
  constructor(client) {
6
7
  this.client = client;
7
8
  }
8
9
  /**
10
+ * Emit the event wrapped in the shared in-band envelope, so the msg bus carries
11
+ * the same cascade metadata as the NATS transport (transport-agnostic tracing).
9
12
  *
10
13
  * @param data
14
+ * @param meta
11
15
  * @returns
12
16
  */
13
- async publish(data) {
14
- return await this.client.publish(this.subject, JSON.stringify(data));
17
+ async publish(data, meta) {
18
+ const envelope = (0, cascade_1.buildEnvelope)(this.subject, data, meta);
19
+ return await this.client.publish(this.subject, JSON.stringify(envelope));
15
20
  }
16
21
  }
17
22
  exports.Publisher = Publisher;
@@ -1 +1 @@
1
- {"version":3,"file":"base-publisher.js","sourceRoot":"","sources":["../../src/events/base-publisher.ts"],"names":[],"mappings":";;;AAEA,MAAsB,SAAS;IAM7B,YAAY,MAA0B;QAEpC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,OAAO,CAAC,IAAe;QAE3B,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IACvE,CAAC;CACF;AApBD,8BAoBC"}
1
+ {"version":3,"file":"base-publisher.js","sourceRoot":"","sources":["../../src/events/base-publisher.ts"],"names":[],"mappings":";;;AAEA,uCAAkE;AAElE,MAAsB,SAAS;IAM7B,YAAY,MAA0B;QAEpC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,OAAO,CAAC,IAAe,EAAE,IAAgB;QAE7C,MAAM,QAAQ,GAAG,IAAA,uBAAa,EAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACzD,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3E,CAAC;CACF;AAxBD,8BAwBC"}
@@ -0,0 +1,13 @@
1
+ import { EventEnvelope, EventMeta, IncomingEventRef } from './types/event-envelope.interfaces';
2
+ export declare function rootMeta(): EventMeta;
3
+ export declare function nextMeta(incoming: IncomingEventRef): EventMeta;
4
+ export declare function outgoingMeta(incoming?: IncomingEventRef): EventMeta;
5
+ export declare function normalizeMeta(meta?: Partial<EventMeta>): EventMeta;
6
+ export declare function unwrapEnvelope<T = any>(parsed: any): {
7
+ id: string;
8
+ data: T;
9
+ meta: EventMeta;
10
+ };
11
+ export declare function cascadeViolation(meta: EventMeta, subject: string): string | undefined;
12
+ export declare function buildEnvelope<T>(subject: string, data: T, meta?: EventMeta): EventEnvelope<T>;
13
+ //# sourceMappingURL=cascade.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cascade.d.ts","sourceRoot":"","sources":["../../src/events/cascade.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAY/F,wBAAgB,QAAQ,IAAI,SAAS,CAGpC;AAKD,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,GAAG,SAAS,CAQ9D;AAID,wBAAgB,YAAY,CAAC,QAAQ,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAGnE;AAID,wBAAgB,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,CAWlE;AAQD,wBAAgB,cAAc,CAAC,CAAC,GAAG,GAAG,EAAE,MAAM,EAAE,GAAG,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,CAAC,CAAC;IAAC,IAAI,EAAE,SAAS,CAAA;CAAE,CAW7F;AAMD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CASrF;AAGD,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS,GAAG,aAAa,CAAC,CAAC,CAAC,CAS7F"}
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.rootMeta = rootMeta;
4
+ exports.nextMeta = nextMeta;
5
+ exports.outgoingMeta = outgoingMeta;
6
+ exports.normalizeMeta = normalizeMeta;
7
+ exports.unwrapEnvelope = unwrapEnvelope;
8
+ exports.cascadeViolation = cascadeViolation;
9
+ exports.buildEnvelope = buildEnvelope;
10
+ const nx_frame_be_1 = require("@nextage/nx-frame-be");
11
+ const event_envelope_constants_1 = require("./types/event-envelope.constants");
12
+ // ──────────────────────────────────────────────────────────────────────────────
13
+ // Cascade metadata helpers
14
+ //
15
+ // Pure functions that derive and validate the tracing metadata carried by every
16
+ // event. They are transport agnostic (no NATS / msg types) so both listener
17
+ // families and `BaseEventCtrl` share exactly the same rules.
18
+ // ──────────────────────────────────────────────────────────────────────────────
19
+ // Metadata for a ROOT event (no parent in flight): a brand-new correlation.
20
+ function rootMeta() {
21
+ return { correlationId: (0, nx_frame_be_1.uuid)(), depth: 0, visited: [] };
22
+ }
23
+ // Metadata for an event published WHILE processing `incoming`: same correlation,
24
+ // caused by `incoming`, one hop deeper, with `incoming.subject` appended to the
25
+ // visited lineage (so a later re-touch of that subject is detectable as a cycle).
26
+ function nextMeta(incoming) {
27
+ return {
28
+ correlationId: incoming.meta.correlationId,
29
+ causationId: incoming.id,
30
+ depth: incoming.meta.depth + 1,
31
+ visited: [...incoming.meta.visited, incoming.subject],
32
+ };
33
+ }
34
+ // Outgoing metadata for a publish: `nextMeta` when a parent event is in flight
35
+ // (cascade), otherwise a fresh `rootMeta` (root command).
36
+ function outgoingMeta(incoming) {
37
+ return incoming ? nextMeta(incoming) : rootMeta();
38
+ }
39
+ // Normalize possibly-missing/partial metadata read off the wire into a full
40
+ // `EventMeta` (legacy / bare payloads have none → treated as a fresh root).
41
+ function normalizeMeta(meta) {
42
+ if (!meta || typeof meta.depth !== 'number' || !Array.isArray(meta.visited) || !meta.correlationId)
43
+ return rootMeta();
44
+ return {
45
+ correlationId: meta.correlationId,
46
+ causationId: meta.causationId,
47
+ depth: meta.depth,
48
+ visited: meta.visited,
49
+ };
50
+ }
51
+ // Unwrap a parsed payload into `{ id, data, meta }`, tolerating three shapes:
52
+ // - full envelope { id, subject, data, timestamp, meta } (current)
53
+ // - NATS envelope { id, subject, data, timestamp } (pre-meta)
54
+ // - bare data the event data object itself (legacy msg path)
55
+ // The heuristic keys on `data` + (`meta` | `subject`); event data objects never
56
+ // carry a `subject` field, so bare payloads are never mistaken for envelopes.
57
+ function unwrapEnvelope(parsed) {
58
+ const isEnvelope = parsed
59
+ && typeof parsed === 'object'
60
+ && 'data' in parsed
61
+ && ('meta' in parsed || 'subject' in parsed);
62
+ if (isEnvelope)
63
+ return { id: parsed.id ?? (0, nx_frame_be_1.uuid)(), data: parsed.data, meta: normalizeMeta(parsed.meta) };
64
+ return { id: (0, nx_frame_be_1.uuid)(), data: parsed, meta: rootMeta() };
65
+ }
66
+ // Decide whether processing `subject` at this `meta` violates cascade governance.
67
+ // Returns a human-readable reason (for the DLQ / logs) or `undefined` when safe:
68
+ // - depth ceiling reached → runaway loop
69
+ // - `subject` already visited in this lineage → cycle
70
+ function cascadeViolation(meta, subject) {
71
+ if (meta.depth >= event_envelope_constants_1.MAX_CASCADE_DEPTH)
72
+ return `cascade depth ${meta.depth} >= ${event_envelope_constants_1.MAX_CASCADE_DEPTH} (runaway loop)`;
73
+ if (meta.visited.includes(subject))
74
+ return `cascade cycle: subject '${subject}' already visited [${meta.visited.join(' -> ')}]`;
75
+ return undefined;
76
+ }
77
+ // Build the envelope a publisher puts on the wire.
78
+ function buildEnvelope(subject, data, meta) {
79
+ return {
80
+ id: (0, nx_frame_be_1.uuid)(),
81
+ subject,
82
+ data,
83
+ timestamp: new Date().toISOString(),
84
+ meta: meta ?? rootMeta(),
85
+ };
86
+ }
87
+ //# sourceMappingURL=cascade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cascade.js","sourceRoot":"","sources":["../../src/events/cascade.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,8 @@ export * from './types/enums';
2
2
  export * from './interfaces';
3
3
  export * from './types';
4
4
  export * from './base-event.controller';
5
+ export * from './cascade';
6
+ export * from './outbox';
5
7
  export * from './msg-client-manager';
6
8
  export * from './msg-wrapper';
7
9
  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;AAGxC,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"}
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;AAGzB,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"}
@@ -18,6 +18,8 @@ __exportStar(require("./types/enums"), exports);
18
18
  __exportStar(require("./interfaces"), exports);
19
19
  __exportStar(require("./types"), exports);
20
20
  __exportStar(require("./base-event.controller"), exports);
21
+ __exportStar(require("./cascade"), exports);
22
+ __exportStar(require("./outbox"), exports);
21
23
  // messages on memory
22
24
  __exportStar(require("./msg-client-manager"), exports);
23
25
  __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;AAExC,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"}
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;AAEzB,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"}
@@ -1,4 +1,5 @@
1
1
  import { Subjects } from './types/enums';
2
+ import { EventMeta } from './types/event-envelope.interfaces';
2
3
  import { NxObject } from '@nextage/nx-frame-be';
3
4
  export interface MsgClientInterface {
4
5
  publish: (subject: string, payload: string, options?: NxObject) => Promise<any>;
@@ -15,6 +16,6 @@ export interface Event {
15
16
  }
16
17
  export interface IPublisher<T extends Event, O = undefined> {
17
18
  subject: T['subject'];
18
- publish(data: T['data'], options?: O): Promise<void>;
19
+ publish(data: T['data'], meta?: EventMeta, options?: O): Promise<void>;
19
20
  }
20
21
  //# sourceMappingURL=interfaces.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../../src/events/interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;IACnF,SAAS,EAAI,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;IACrC,WAAW,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;CACtC;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAK,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,KAAK;IACpB,OAAO,EAAE,QAAQ,CAAC;IAClB,IAAI,EAAK,GAAG,CAAC;CACd;AAED,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,KAAK,EAAE,CAAC,GAAG,SAAS;IACxD,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC;IACtB,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtD"}
1
+ {"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../../src/events/interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAO,eAAe,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAO,sBAAsB,CAAC;AAEjD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;IACnF,SAAS,EAAI,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;IACrC,WAAW,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;CACtC;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAK,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,KAAK;IACpB,OAAO,EAAE,QAAQ,CAAC;IAClB,IAAI,EAAK,GAAG,CAAC;CACd;AAED,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,KAAK,EAAE,CAAC,GAAG,SAAS;IACxD,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC;IACtB,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxE"}
@@ -0,0 +1,12 @@
1
+ import { OutboxPort } from './types/outbox.interfaces';
2
+ /**
3
+ * Register the process-wide outbox implementation. Called once, at service
4
+ * bootstrap (app-layer phase), with the service's own `event` model.
5
+ */
6
+ export declare const registerOutbox: (port: OutboxPort) => void;
7
+ /**
8
+ * Current outbox implementation, or `undefined` when none was registered (the
9
+ * controller then publishes WITHOUT persisting an outbox row — graceful default).
10
+ */
11
+ export declare const getOutbox: () => OutboxPort | undefined;
12
+ //# sourceMappingURL=outbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox.d.ts","sourceRoot":"","sources":["../../src/events/outbox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAIvD;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAI,MAAM,UAAU,KAAG,IAA2B,CAAC;AAE9E;;;GAGG;AACH,eAAO,MAAM,SAAS,QAAO,UAAU,GAAG,SAAoB,CAAC"}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getOutbox = exports.registerOutbox = void 0;
4
+ let _outbox;
5
+ /**
6
+ * Register the process-wide outbox implementation. Called once, at service
7
+ * bootstrap (app-layer phase), with the service's own `event` model.
8
+ */
9
+ const registerOutbox = (port) => { _outbox = port; };
10
+ exports.registerOutbox = registerOutbox;
11
+ /**
12
+ * Current outbox implementation, or `undefined` when none was registered (the
13
+ * controller then publishes WITHOUT persisting an outbox row — graceful default).
14
+ */
15
+ const getOutbox = () => _outbox;
16
+ exports.getOutbox = getOutbox;
17
+ //# sourceMappingURL=outbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox.js","sourceRoot":"","sources":["../../src/events/outbox.ts"],"names":[],"mappings":";;;AAEA,IAAI,OAA+B,CAAC;AAEpC;;;GAGG;AACI,MAAM,cAAc,GAAG,CAAC,IAAgB,EAAQ,EAAE,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAAjE,QAAA,cAAc,kBAAmD;AAE9E;;;GAGG;AACI,MAAM,SAAS,GAAG,GAA2B,EAAE,CAAC,OAAO,CAAC;AAAlD,QAAA,SAAS,aAAyC"}
@@ -0,0 +1,2 @@
1
+ export declare const MAX_CASCADE_DEPTH = 10;
2
+ //# sourceMappingURL=event-envelope.constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-envelope.constants.d.ts","sourceRoot":"","sources":["../../../src/events/types/event-envelope.constants.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,iBAAiB,KAAK,CAAC"}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ // ──────────────────────────────────────────────────────────────────────────────
3
+ // Cascade governance constants
4
+ // ──────────────────────────────────────────────────────────────────────────────
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MAX_CASCADE_DEPTH = void 0;
7
+ // Maximum number of cascade hops before an event is treated as a runaway loop and
8
+ // dead-lettered instead of processed. The real cascades are depth <= 2; this is a
9
+ // wide anti-runaway ceiling, not a tuning knob.
10
+ exports.MAX_CASCADE_DEPTH = 10;
11
+ //# sourceMappingURL=event-envelope.constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-envelope.constants.js","sourceRoot":"","sources":["../../../src/events/types/event-envelope.constants.ts"],"names":[],"mappings":";AAAA,iFAAiF;AACjF,gCAAgC;AAChC,iFAAiF;;;AAEjF,kFAAkF;AAClF,kFAAkF;AAClF,gDAAgD;AACnC,QAAA,iBAAiB,GAAG,EAAE,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { NxContext } from '@nextage/nx-frame-be';
2
+ export interface EventMeta {
3
+ correlationId: string;
4
+ causationId?: string;
5
+ depth: number;
6
+ visited: string[];
7
+ }
8
+ export interface EventEnvelope<T = any> {
9
+ id: string;
10
+ subject: string;
11
+ data: T;
12
+ timestamp: string;
13
+ meta: EventMeta;
14
+ }
15
+ export interface IncomingEventRef {
16
+ id: string;
17
+ subject: string;
18
+ meta: EventMeta;
19
+ }
20
+ export interface EventContext extends NxContext {
21
+ _event?: IncomingEventRef;
22
+ }
23
+ //# sourceMappingURL=event-envelope.interfaces.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-envelope.interfaces.d.ts","sourceRoot":"","sources":["../../../src/events/types/event-envelope.interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAiBjD,MAAM,WAAW,SAAS;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAG,MAAM,CAAC;IACtB,KAAK,EAAU,MAAM,CAAC;IACtB,OAAO,EAAQ,MAAM,EAAE,CAAC;CACzB;AAGD,MAAM,WAAW,aAAa,CAAC,CAAC,GAAG,GAAG;IACpC,EAAE,EAAS,MAAM,CAAC;IAClB,OAAO,EAAI,MAAM,CAAC;IAClB,IAAI,EAAO,CAAC,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAO,SAAS,CAAC;CACtB;AAKD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAO,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAK,SAAS,CAAC;CACpB;AAGD,MAAM,WAAW,YAAa,SAAQ,SAAS;IAC7C,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC3B"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=event-envelope.interfaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-envelope.interfaces.js","sourceRoot":"","sources":["../../../src/events/types/event-envelope.interfaces.ts"],"names":[],"mappings":""}
@@ -14,10 +14,13 @@ export * from './treatment.enums';
14
14
  export * from './vulnerability.enums';
15
15
  export * from './asset.constants';
16
16
  export * from './dlq.constants';
17
+ export * from './event-envelope.constants';
17
18
  export * from './asset.interfaces';
18
19
  export * from './control.interfaces';
19
20
  export * from './dlq.interfaces';
21
+ export * from './event-envelope.interfaces';
20
22
  export * from './events.interfaces';
23
+ export * from './outbox.interfaces';
21
24
  export * from './risk-analysis.interfaces';
22
25
  export * from './threat.interfaces';
23
26
  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;AAEhC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAG3C,cAAc,kBAAkB,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;AAE3C,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,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAG3C,cAAc,kBAAkB,CAAC"}
@@ -30,10 +30,13 @@ __exportStar(require("./treatment.enums"), exports);
30
30
  __exportStar(require("./vulnerability.enums"), exports);
31
31
  __exportStar(require("./asset.constants"), exports);
32
32
  __exportStar(require("./dlq.constants"), exports);
33
+ __exportStar(require("./event-envelope.constants"), exports);
33
34
  __exportStar(require("./asset.interfaces"), exports);
34
35
  __exportStar(require("./control.interfaces"), exports);
35
36
  __exportStar(require("./dlq.interfaces"), exports);
37
+ __exportStar(require("./event-envelope.interfaces"), exports);
36
38
  __exportStar(require("./events.interfaces"), exports);
39
+ __exportStar(require("./outbox.interfaces"), exports);
37
40
  __exportStar(require("./risk-analysis.interfaces"), exports);
38
41
  __exportStar(require("./threat.interfaces"), exports);
39
42
  __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;AAEhC,qDAAmC;AACnC,uDAAqC;AACrC,mDAAiC;AACjC,sDAAoC;AACpC,6DAA2C;AAC3C,sDAAoC;AACpC,6DAA2C;AAE3C,YAAY;AACZ,mDAAiC"}
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;AAE3C,qDAAmC;AACnC,uDAAqC;AACrC,mDAAiC;AACjC,8DAA4C;AAC5C,sDAAoC;AACpC,sDAAoC;AACpC,6DAA2C;AAC3C,sDAAoC;AACpC,6DAA2C;AAE3C,YAAY;AACZ,mDAAiC"}
@@ -0,0 +1,12 @@
1
+ import { NxContext } from '@nextage/nx-frame-be';
2
+ import { QueueEventType } from './enums';
3
+ export interface OutboxEvent {
4
+ id: string;
5
+ type: QueueEventType;
6
+ data: any;
7
+ }
8
+ export interface OutboxPort {
9
+ create(evt: OutboxEvent, context: NxContext): Promise<void>;
10
+ markSent(id: string, context: NxContext): Promise<void>;
11
+ }
12
+ //# sourceMappingURL=outbox.interfaces.d.ts.map
@@ -0,0 +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;AAKzC,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAI,MAAM,CAAC;IACb,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,EAAE,GAAG,CAAC;CACX;AASD,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;CAC9D"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=outbox.interfaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox.interfaces.js","sourceRoot":"","sources":["../../../src/events/types/outbox.interfaces.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextage/era-lib",
3
- "version": "1.0.174",
3
+ "version": "1.0.176",
4
4
  "main": "./build/index.js",
5
5
  "types": "./build/index.d.ts",
6
6
  "files": [
@@ -22,7 +22,7 @@
22
22
  "license": "ISC",
23
23
  "description": "ERA shared backend library (@nextage/era-lib): events, models, services, bootstrap orchestrator and utils on top of @nextage/nx-frame-be. See README.md and CHANGELOG.md.",
24
24
  "dependencies": {
25
- "@nextage/nx-frame-be": "^1.0.40",
25
+ "@nextage/nx-frame-be": "^1.0.41",
26
26
  "@types/express-jwt": "^7.4.2",
27
27
  "@types/express-rate-limit": "^6.0.0",
28
28
  "@types/express-session": "^1.18.2",