@nestjs-transactional/outbox 1.0.0-alpha.0

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 (126) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +396 -0
  3. package/dist/api/completed-event-publications.d.ts +31 -0
  4. package/dist/api/completed-event-publications.js +58 -0
  5. package/dist/api/completed-event-publications.js.map +1 -0
  6. package/dist/api/failed-event-publications.d.ts +36 -0
  7. package/dist/api/failed-event-publications.js +75 -0
  8. package/dist/api/failed-event-publications.js.map +1 -0
  9. package/dist/api/incomplete-event-publications.d.ts +28 -0
  10. package/dist/api/incomplete-event-publications.js +72 -0
  11. package/dist/api/incomplete-event-publications.js.map +1 -0
  12. package/dist/decorators/inject-decorators.d.ts +85 -0
  13. package/dist/decorators/inject-decorators.js +100 -0
  14. package/dist/decorators/inject-decorators.js.map +1 -0
  15. package/dist/decorators/outbox-events-handler.decorator.d.ts +97 -0
  16. package/dist/decorators/outbox-events-handler.decorator.js +58 -0
  17. package/dist/decorators/outbox-events-handler.decorator.js.map +1 -0
  18. package/dist/dispatcher/data-source-outbox-publisher.d.ts +69 -0
  19. package/dist/dispatcher/data-source-outbox-publisher.js +127 -0
  20. package/dist/dispatcher/data-source-outbox-publisher.js.map +1 -0
  21. package/dist/dispatcher/event-publication-processor.d.ts +69 -0
  22. package/dist/dispatcher/event-publication-processor.js +192 -0
  23. package/dist/dispatcher/event-publication-processor.js.map +1 -0
  24. package/dist/dispatcher/outbox-event-publisher.d.ts +129 -0
  25. package/dist/dispatcher/outbox-event-publisher.js +172 -0
  26. package/dist/dispatcher/outbox-event-publisher.js.map +1 -0
  27. package/dist/dispatcher/processor-options.d.ts +24 -0
  28. package/dist/dispatcher/processor-options.js +15 -0
  29. package/dist/dispatcher/processor-options.js.map +1 -0
  30. package/dist/externalization/errors.d.ts +21 -0
  31. package/dist/externalization/errors.js +30 -0
  32. package/dist/externalization/errors.js.map +1 -0
  33. package/dist/externalization/event-externalizer.d.ts +49 -0
  34. package/dist/externalization/event-externalizer.js +14 -0
  35. package/dist/externalization/event-externalizer.js.map +1 -0
  36. package/dist/externalization/externalization-registry.d.ts +56 -0
  37. package/dist/externalization/externalization-registry.js +103 -0
  38. package/dist/externalization/externalization-registry.js.map +1 -0
  39. package/dist/externalization/externalized.decorator.d.ts +121 -0
  40. package/dist/externalization/externalized.decorator.js +87 -0
  41. package/dist/externalization/externalized.decorator.js.map +1 -0
  42. package/dist/externalization/types.d.ts +39 -0
  43. package/dist/externalization/types.js +3 -0
  44. package/dist/externalization/types.js.map +1 -0
  45. package/dist/index.d.ts +38 -0
  46. package/dist/index.js +58 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/interfaces/outbox-event-handler.interface.d.ts +32 -0
  49. package/dist/interfaces/outbox-event-handler.interface.js +3 -0
  50. package/dist/interfaces/outbox-event-handler.interface.js.map +1 -0
  51. package/dist/module/outbox-processing.module.d.ts +29 -0
  52. package/dist/module/outbox-processing.module.js +66 -0
  53. package/dist/module/outbox-processing.module.js.map +1 -0
  54. package/dist/module/outbox.module.d.ts +196 -0
  55. package/dist/module/outbox.module.js +604 -0
  56. package/dist/module/outbox.module.js.map +1 -0
  57. package/dist/recovery/staleness-monitor.d.ts +39 -0
  58. package/dist/recovery/staleness-monitor.js +118 -0
  59. package/dist/recovery/staleness-monitor.js.map +1 -0
  60. package/dist/recovery/startup-recovery.d.ts +37 -0
  61. package/dist/recovery/startup-recovery.js +55 -0
  62. package/dist/recovery/startup-recovery.js.map +1 -0
  63. package/dist/registry/event-publication-registry.d.ts +70 -0
  64. package/dist/registry/event-publication-registry.js +138 -0
  65. package/dist/registry/event-publication-registry.js.map +1 -0
  66. package/dist/registry/listener-registry.d.ts +52 -0
  67. package/dist/registry/listener-registry.js +67 -0
  68. package/dist/registry/listener-registry.js.map +1 -0
  69. package/dist/registry/multi-ds-listener-registrar.d.ts +78 -0
  70. package/dist/registry/multi-ds-listener-registrar.js +112 -0
  71. package/dist/registry/multi-ds-listener-registrar.js.map +1 -0
  72. package/dist/registry/outbox-listener-scanner.d.ts +66 -0
  73. package/dist/registry/outbox-listener-scanner.js +192 -0
  74. package/dist/registry/outbox-listener-scanner.js.map +1 -0
  75. package/dist/repository/event-publication-repository.d.ts +112 -0
  76. package/dist/repository/event-publication-repository.js +6 -0
  77. package/dist/repository/event-publication-repository.js.map +1 -0
  78. package/dist/serialization/event-serializer.d.ts +28 -0
  79. package/dist/serialization/event-serializer.js +6 -0
  80. package/dist/serialization/event-serializer.js.map +1 -0
  81. package/dist/serialization/event-type-registry.d.ts +41 -0
  82. package/dist/serialization/event-type-registry.js +79 -0
  83. package/dist/serialization/event-type-registry.js.map +1 -0
  84. package/dist/serialization/event-type-resolver.d.ts +43 -0
  85. package/dist/serialization/event-type-resolver.js +66 -0
  86. package/dist/serialization/event-type-resolver.js.map +1 -0
  87. package/dist/serialization/json-event-serializer.d.ts +20 -0
  88. package/dist/serialization/json-event-serializer.js +64 -0
  89. package/dist/serialization/json-event-serializer.js.map +1 -0
  90. package/dist/testing/assertable-published-events.d.ts +71 -0
  91. package/dist/testing/assertable-published-events.js +124 -0
  92. package/dist/testing/assertable-published-events.js.map +1 -0
  93. package/dist/testing/in-memory-repository.d.ts +52 -0
  94. package/dist/testing/in-memory-repository.js +230 -0
  95. package/dist/testing/in-memory-repository.js.map +1 -0
  96. package/dist/testing/index.d.ts +4 -0
  97. package/dist/testing/index.js +20 -0
  98. package/dist/testing/index.js.map +1 -0
  99. package/dist/testing/published-events.d.ts +62 -0
  100. package/dist/testing/published-events.js +110 -0
  101. package/dist/testing/published-events.js.map +1 -0
  102. package/dist/tokens/index.d.ts +2 -0
  103. package/dist/tokens/index.js +14 -0
  104. package/dist/tokens/index.js.map +1 -0
  105. package/dist/tokens/token-utils.d.ts +68 -0
  106. package/dist/tokens/token-utils.js +98 -0
  107. package/dist/tokens/token-utils.js.map +1 -0
  108. package/dist/types/completion-mode.d.ts +16 -0
  109. package/dist/types/completion-mode.js +20 -0
  110. package/dist/types/completion-mode.js.map +1 -0
  111. package/dist/types/errors.d.ts +50 -0
  112. package/dist/types/errors.js +64 -0
  113. package/dist/types/errors.js.map +1 -0
  114. package/dist/types/event-publication.d.ts +47 -0
  115. package/dist/types/event-publication.js +3 -0
  116. package/dist/types/event-publication.js.map +1 -0
  117. package/dist/types/publication-status.d.ts +26 -0
  118. package/dist/types/publication-status.js +30 -0
  119. package/dist/types/publication-status.js.map +1 -0
  120. package/dist/types/resubmission-options.d.ts +37 -0
  121. package/dist/types/resubmission-options.js +62 -0
  122. package/dist/types/resubmission-options.js.map +1 -0
  123. package/dist/types/staleness-config.d.ts +18 -0
  124. package/dist/types/staleness-config.js +10 -0
  125. package/dist/types/staleness-config.js.map +1 -0
  126. package/package.json +77 -0
@@ -0,0 +1,230 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.InMemoryEventPublicationRepository = void 0;
16
+ /* eslint-disable @typescript-eslint/require-await --
17
+ * This in-memory reference implementation has synchronous method
18
+ * bodies but must return Promises per the EventPublicationRepository
19
+ * SPI contract. Real persistence backends (TypeORM, Prisma, ...) will
20
+ * have awaits throughout.
21
+ */
22
+ const node_crypto_1 = require("node:crypto");
23
+ const common_1 = require("@nestjs/common");
24
+ const core_1 = require("@nestjs-transactional/core");
25
+ const errors_1 = require("../types/errors");
26
+ const publication_status_1 = require("../types/publication-status");
27
+ /**
28
+ * In-memory reference implementation of {@link EventPublicationRepository}.
29
+ *
30
+ * Intended for unit and integration tests of outbox consumers that
31
+ * do not want to spin up a real database. Not thread-safe — do not use
32
+ * in production.
33
+ *
34
+ * Optional `TransactionManager` enables transaction-aware behaviour:
35
+ * when a mutating method is called inside an active transaction, the
36
+ * repository registers an `afterRollback` hook that undoes the change
37
+ * — so the visible state after rollback matches what a real
38
+ * transactional backend would show. When no `TransactionManager` is
39
+ * provided (or no transaction is active), mutations apply immediately
40
+ * and are not undone.
41
+ *
42
+ * Exposes a few extra methods beyond the SPI (`reset`, `getAll`,
43
+ * `count`) to help tests set up and assert on state.
44
+ */
45
+ let InMemoryEventPublicationRepository = class InMemoryEventPublicationRepository {
46
+ transactionManager;
47
+ publications = new Map();
48
+ constructor(transactionManager) {
49
+ this.transactionManager = transactionManager;
50
+ }
51
+ async createAll(inputs) {
52
+ const created = [];
53
+ for (const input of inputs) {
54
+ const publication = {
55
+ id: (0, node_crypto_1.randomUUID)(),
56
+ listenerId: input.listenerId,
57
+ eventType: input.eventType,
58
+ serializedEvent: input.serializedEvent,
59
+ publicationDate: input.publicationDate ?? new Date(),
60
+ status: publication_status_1.PublicationStatus.PUBLISHED,
61
+ completionDate: null,
62
+ lastResubmissionDate: null,
63
+ completionAttempts: 0,
64
+ failureReason: null,
65
+ };
66
+ this.publications.set(publication.id, publication);
67
+ created.push(publication);
68
+ }
69
+ this.trackRollback(() => {
70
+ for (const p of created) {
71
+ this.publications.delete(p.id);
72
+ }
73
+ });
74
+ return created;
75
+ }
76
+ async findById(id) {
77
+ return this.publications.get(id) ?? null;
78
+ }
79
+ async updateStatus(id, status, options = {}) {
80
+ const existing = this.publications.get(id);
81
+ if (!existing) {
82
+ throw new errors_1.PublicationNotFoundError(id);
83
+ }
84
+ const updated = {
85
+ ...existing,
86
+ status,
87
+ completionDate: options.completionDate ?? existing.completionDate,
88
+ failureReason: options.failureReason ?? existing.failureReason,
89
+ completionAttempts: options.incrementAttempts
90
+ ? existing.completionAttempts + 1
91
+ : existing.completionAttempts,
92
+ lastResubmissionDate: options.lastResubmissionDate ?? existing.lastResubmissionDate,
93
+ };
94
+ this.publications.set(id, updated);
95
+ this.trackRollback(() => {
96
+ this.publications.set(id, existing);
97
+ });
98
+ }
99
+ async tryClaim(id) {
100
+ const existing = this.publications.get(id);
101
+ if (!existing) {
102
+ return false;
103
+ }
104
+ if (existing.status !== publication_status_1.PublicationStatus.PUBLISHED &&
105
+ existing.status !== publication_status_1.PublicationStatus.RESUBMITTED) {
106
+ return false;
107
+ }
108
+ await this.updateStatus(id, publication_status_1.PublicationStatus.PROCESSING, { incrementAttempts: true });
109
+ return true;
110
+ }
111
+ async findReadyForProcessing(limit) {
112
+ return Array.from(this.publications.values())
113
+ .filter((p) => p.status === publication_status_1.PublicationStatus.PUBLISHED ||
114
+ p.status === publication_status_1.PublicationStatus.RESUBMITTED)
115
+ .slice(0, limit);
116
+ }
117
+ async findStale(beforeDate, statuses) {
118
+ return Array.from(this.publications.values()).filter((p) => statuses.includes(p.status) && p.publicationDate < beforeDate);
119
+ }
120
+ async findCompleted(options) {
121
+ let result = Array.from(this.publications.values()).filter((p) => p.status === publication_status_1.PublicationStatus.COMPLETED);
122
+ const olderThan = options?.olderThan;
123
+ if (olderThan) {
124
+ result = result.filter((p) => p.completionDate !== null && p.completionDate < olderThan);
125
+ }
126
+ const limit = options?.limit;
127
+ if (limit !== undefined) {
128
+ result = result.slice(0, limit);
129
+ }
130
+ return result;
131
+ }
132
+ async findIncomplete() {
133
+ return Array.from(this.publications.values()).filter((p) => p.status !== publication_status_1.PublicationStatus.COMPLETED);
134
+ }
135
+ async findFailed(options) {
136
+ let result = Array.from(this.publications.values()).filter((p) => p.status === publication_status_1.PublicationStatus.FAILED);
137
+ const minAge = options?.minAge;
138
+ if (minAge) {
139
+ const threshold = new Date(Date.now() - minAge);
140
+ result = result.filter((p) => p.publicationDate < threshold);
141
+ }
142
+ const maxAttempts = options?.maxAttempts;
143
+ if (maxAttempts !== undefined) {
144
+ result = result.filter((p) => p.completionAttempts <= maxAttempts);
145
+ }
146
+ return result;
147
+ }
148
+ async deleteCompleted(olderThan) {
149
+ const deleted = [];
150
+ for (const [id, p] of this.publications.entries()) {
151
+ if (p.status !== publication_status_1.PublicationStatus.COMPLETED) {
152
+ continue;
153
+ }
154
+ if (olderThan && (p.completionDate === null || p.completionDate >= olderThan)) {
155
+ continue;
156
+ }
157
+ deleted.push([id, p]);
158
+ }
159
+ for (const [id] of deleted) {
160
+ this.publications.delete(id);
161
+ }
162
+ if (deleted.length > 0) {
163
+ this.trackRollback(() => {
164
+ for (const [id, p] of deleted) {
165
+ this.publications.set(id, p);
166
+ }
167
+ });
168
+ }
169
+ return deleted.length;
170
+ }
171
+ async archiveCompleted(id) {
172
+ const existing = this.publications.get(id);
173
+ this.publications.delete(id);
174
+ if (existing !== undefined) {
175
+ this.trackRollback(() => {
176
+ this.publications.set(id, existing);
177
+ });
178
+ }
179
+ }
180
+ async delete(id) {
181
+ const existing = this.publications.get(id);
182
+ this.publications.delete(id);
183
+ if (existing !== undefined) {
184
+ this.trackRollback(() => {
185
+ this.publications.set(id, existing);
186
+ });
187
+ }
188
+ }
189
+ // --- Testing helpers (not part of the SPI) ---
190
+ /** Drop every stored publication. Does not interact with transactions. */
191
+ reset() {
192
+ this.publications.clear();
193
+ }
194
+ /** Snapshot of every stored publication, in insertion order. */
195
+ getAll() {
196
+ return Array.from(this.publications.values());
197
+ }
198
+ /** Number of stored publications. */
199
+ count() {
200
+ return this.publications.size;
201
+ }
202
+ /**
203
+ * If a `TransactionManager` was provided and a transaction is active,
204
+ * register the given `undo` closure to fire on rollback. Otherwise
205
+ * this is a no-op.
206
+ */
207
+ trackRollback(undo) {
208
+ if (this.transactionManager === undefined) {
209
+ return;
210
+ }
211
+ try {
212
+ this.transactionManager.registerAfterRollback(async () => {
213
+ undo();
214
+ });
215
+ }
216
+ catch (err) {
217
+ if (err instanceof core_1.IllegalTransactionStateError) {
218
+ return;
219
+ }
220
+ throw err;
221
+ }
222
+ }
223
+ };
224
+ exports.InMemoryEventPublicationRepository = InMemoryEventPublicationRepository;
225
+ exports.InMemoryEventPublicationRepository = InMemoryEventPublicationRepository = __decorate([
226
+ (0, common_1.Injectable)(),
227
+ __param(0, (0, common_1.Optional)()),
228
+ __metadata("design:paramtypes", [core_1.TransactionManager])
229
+ ], InMemoryEventPublicationRepository);
230
+ //# sourceMappingURL=in-memory-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-memory-repository.js","sourceRoot":"","sources":["../../src/testing/in-memory-repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export * from './in-memory-repository';
2
+ export * from './published-events';
3
+ export * from './assertable-published-events';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./in-memory-repository"), exports);
18
+ __exportStar(require("./published-events"), exports);
19
+ __exportStar(require("./assertable-published-events"), exports);
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,yDAAuC;AACvC,qDAAmC;AACnC,gEAA8C"}
@@ -0,0 +1,62 @@
1
+ import { type Type } from '@nestjs/common';
2
+ import { type EventPublicationRepository } from '../repository/event-publication-repository';
3
+ import { type EventSerializer } from '../serialization/event-serializer';
4
+ import type { EventPublication } from '../types/event-publication';
5
+ /**
6
+ * Test utility for inspecting events that were published through the
7
+ * outbox during a test run.
8
+ *
9
+ * Inspired by Spring Modulith's `PublishedEvents`. Reads from whichever
10
+ * `EventPublicationRepository` implementation is wired — typically
11
+ * {@link InMemoryEventPublicationRepository} for unit-level tests, or
12
+ * the TypeORM-backed repository for integration tests against a real
13
+ * database. The events are deserialized back into application objects
14
+ * via the configured {@link EventSerializer} so tests can assert on
15
+ * the same typed payloads the listeners would receive.
16
+ */
17
+ export declare class PublishedEvents {
18
+ private readonly repository;
19
+ private readonly serializer;
20
+ constructor(repository: EventPublicationRepository, serializer: EventSerializer);
21
+ /**
22
+ * Every publication visible to the repository, regardless of status.
23
+ * Events are returned as deserialized application objects. Ordering
24
+ * mirrors the repository's own — typically insertion order for the
25
+ * in-memory impl, unspecified for SQL-backed ones.
26
+ */
27
+ all(): Promise<unknown[]>;
28
+ /**
29
+ * Narrow the view to events of a specific class. Subsequent
30
+ * `matching(...)` / `count()` / `get()` calls filter only within
31
+ * that class.
32
+ */
33
+ ofType<T extends object>(eventType: Type<T>): PublishedEventsView<T>;
34
+ private collectAll;
35
+ }
36
+ /**
37
+ * Fluent filter view returned by {@link PublishedEvents.ofType}. Each
38
+ * `matching(...)` call produces a new view with the extra predicate
39
+ * appended — predicates are conjunctive (all must hold). Materialise
40
+ * the view with `get()` or `count()`.
41
+ */
42
+ export declare class PublishedEventsView<T extends object> {
43
+ private readonly fetchAll;
44
+ private readonly serializer;
45
+ private readonly eventType;
46
+ private readonly predicates;
47
+ constructor(fetchAll: () => Promise<EventPublication[]>, serializer: EventSerializer, eventType: Type<T>, predicates: readonly ((event: T) => boolean)[]);
48
+ /**
49
+ * Filter on a boolean predicate over the deserialized event.
50
+ */
51
+ matching(predicate: (event: T) => boolean): PublishedEventsView<T>;
52
+ /**
53
+ * Filter on equality of a derived value. Equivalent to
54
+ * `matching((e) => getter(e) === expected)` but cheaper to read.
55
+ */
56
+ matching<K>(getter: (event: T) => K, expected: K): PublishedEventsView<T>;
57
+ /** Number of matching events. Materialises the view. */
58
+ count(): Promise<number>;
59
+ /** Deserialized, filtered events. Materialises the view. */
60
+ get(): Promise<T[]>;
61
+ }
62
+ //# sourceMappingURL=published-events.d.ts.map
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.PublishedEventsView = exports.PublishedEvents = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const event_publication_repository_1 = require("../repository/event-publication-repository");
18
+ const event_serializer_1 = require("../serialization/event-serializer");
19
+ /**
20
+ * Test utility for inspecting events that were published through the
21
+ * outbox during a test run.
22
+ *
23
+ * Inspired by Spring Modulith's `PublishedEvents`. Reads from whichever
24
+ * `EventPublicationRepository` implementation is wired — typically
25
+ * {@link InMemoryEventPublicationRepository} for unit-level tests, or
26
+ * the TypeORM-backed repository for integration tests against a real
27
+ * database. The events are deserialized back into application objects
28
+ * via the configured {@link EventSerializer} so tests can assert on
29
+ * the same typed payloads the listeners would receive.
30
+ */
31
+ let PublishedEvents = class PublishedEvents {
32
+ repository;
33
+ serializer;
34
+ constructor(repository, serializer) {
35
+ this.repository = repository;
36
+ this.serializer = serializer;
37
+ }
38
+ /**
39
+ * Every publication visible to the repository, regardless of status.
40
+ * Events are returned as deserialized application objects. Ordering
41
+ * mirrors the repository's own — typically insertion order for the
42
+ * in-memory impl, unspecified for SQL-backed ones.
43
+ */
44
+ async all() {
45
+ const rows = await this.collectAll();
46
+ return rows.map((pub) => this.serializer.deserialize(pub.serializedEvent, pub.eventType));
47
+ }
48
+ /**
49
+ * Narrow the view to events of a specific class. Subsequent
50
+ * `matching(...)` / `count()` / `get()` calls filter only within
51
+ * that class.
52
+ */
53
+ ofType(eventType) {
54
+ return new PublishedEventsView(() => this.collectAll(), this.serializer, eventType, []);
55
+ }
56
+ async collectAll() {
57
+ const [incomplete, completed] = await Promise.all([
58
+ this.repository.findIncomplete(),
59
+ this.repository.findCompleted(),
60
+ ]);
61
+ return [...incomplete, ...completed];
62
+ }
63
+ };
64
+ exports.PublishedEvents = PublishedEvents;
65
+ exports.PublishedEvents = PublishedEvents = __decorate([
66
+ (0, common_1.Injectable)(),
67
+ __param(0, (0, common_1.Inject)(event_publication_repository_1.EVENT_PUBLICATION_REPOSITORY)),
68
+ __param(1, (0, common_1.Inject)(event_serializer_1.EVENT_SERIALIZER)),
69
+ __metadata("design:paramtypes", [Object, Object])
70
+ ], PublishedEvents);
71
+ /**
72
+ * Fluent filter view returned by {@link PublishedEvents.ofType}. Each
73
+ * `matching(...)` call produces a new view with the extra predicate
74
+ * appended — predicates are conjunctive (all must hold). Materialise
75
+ * the view with `get()` or `count()`.
76
+ */
77
+ class PublishedEventsView {
78
+ fetchAll;
79
+ serializer;
80
+ eventType;
81
+ predicates;
82
+ constructor(fetchAll, serializer, eventType, predicates) {
83
+ this.fetchAll = fetchAll;
84
+ this.serializer = serializer;
85
+ this.eventType = eventType;
86
+ this.predicates = predicates;
87
+ }
88
+ matching(fnOrGetter, expected) {
89
+ // eslint-disable-next-line prefer-rest-params -- arguments.length distinguishes the two overloads reliably, including when `expected` is intentionally `undefined`.
90
+ const argCount = arguments.length;
91
+ const predicate = argCount > 1
92
+ ? (event) => fnOrGetter(event) === expected
93
+ : fnOrGetter;
94
+ return new PublishedEventsView(this.fetchAll, this.serializer, this.eventType, [...this.predicates, predicate]);
95
+ }
96
+ /** Number of matching events. Materialises the view. */
97
+ async count() {
98
+ return (await this.get()).length;
99
+ }
100
+ /** Deserialized, filtered events. Materialises the view. */
101
+ async get() {
102
+ const rows = await this.fetchAll();
103
+ const typed = rows
104
+ .filter((pub) => pub.eventType === this.eventType.name)
105
+ .map((pub) => this.serializer.deserialize(pub.serializedEvent, pub.eventType));
106
+ return typed.filter((event) => this.predicates.every((pred) => pred(event)));
107
+ }
108
+ }
109
+ exports.PublishedEventsView = PublishedEventsView;
110
+ //# sourceMappingURL=published-events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"published-events.js","sourceRoot":"","sources":["../../src/testing/published-events.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAA+D;AAE/D,6FAGoD;AACpD,wEAA2F;AAG3F;;;;;;;;;;;GAWG;AAEI,IAAM,eAAe,GAArB,MAAM,eAAe;IAGP;IAEA;IAJnB,YAEmB,UAAsC,EAEtC,UAA2B;QAF3B,eAAU,GAAV,UAAU,CAA4B;QAEtC,eAAU,GAAV,UAAU,CAAiB;IAC3C,CAAC;IAEJ;;;;;OAKG;IACH,KAAK,CAAC,GAAG;QACP,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QACrC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CACtB,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,eAAe,EAAE,GAAG,CAAC,SAAS,CAAC,CAChE,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAmB,SAAkB;QACzC,OAAO,IAAI,mBAAmB,CAC5B,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,EACvB,IAAI,CAAC,UAAU,EACf,SAAS,EACT,EAAE,CACH,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,UAAU;QACtB,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAChD,IAAI,CAAC,UAAU,CAAC,cAAc,EAAE;YAChC,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE;SAChC,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,UAAU,EAAE,GAAG,SAAS,CAAC,CAAC;IACvC,CAAC;CACF,CAAA;AA1CY,0CAAe;0BAAf,eAAe;IAD3B,IAAA,mBAAU,GAAE;IAGR,WAAA,IAAA,eAAM,EAAC,2DAA4B,CAAC,CAAA;IAEpC,WAAA,IAAA,eAAM,EAAC,mCAAgB,CAAC,CAAA;;GAJhB,eAAe,CA0C3B;AAED;;;;;GAKG;AACH,MAAa,mBAAmB;IAEX;IACA;IACA;IACA;IAJnB,YACmB,QAA2C,EAC3C,UAA2B,EAC3B,SAAkB,EAClB,UAA8C;QAH9C,aAAQ,GAAR,QAAQ,CAAmC;QAC3C,eAAU,GAAV,UAAU,CAAiB;QAC3B,cAAS,GAAT,SAAS,CAAS;QAClB,eAAU,GAAV,UAAU,CAAoC;IAC9D,CAAC;IAWJ,QAAQ,CACN,UAAuD,EACvD,QAAY;QAEZ,oKAAoK;QACpK,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC;QAClC,MAAM,SAAS,GACb,QAAQ,GAAG,CAAC;YACV,CAAC,CAAC,CAAC,KAAQ,EAAW,EAAE,CAAE,UAA8B,CAAC,KAAK,CAAC,KAAM,QAAc;YACnF,CAAC,CAAE,UAAoC,CAAC;QAE5C,OAAO,IAAI,mBAAmB,CAC5B,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,SAAS,EACd,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAChC,CAAC;IACJ,CAAC;IAED,wDAAwD;IACxD,KAAK,CAAC,KAAK;QACT,OAAO,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC;IACnC,CAAC;IAED,4DAA4D;IAC5D,KAAK,CAAC,GAAG;QACP,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QACnC,MAAM,KAAK,GAAQ,IAAI;aACpB,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;aACtD,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,eAAe,EAAE,GAAG,CAAC,SAAS,CAAM,CAAC,CAAC;QACtF,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC/E,CAAC;CACF;AAjDD,kDAiDC"}
@@ -0,0 +1,2 @@
1
+ export { getEventExternalizerToken, getEventPublicationProcessorToken, getEventPublicationRegistryToken, getEventPublicationRepositoryToken, getEventTypeRegistryToken, getExternalizationRegistryToken, getOutboxEventSerializerToken, getOutboxListenerRegistryToken, getOutboxPublisherToken, } from './token-utils';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getOutboxPublisherToken = exports.getOutboxListenerRegistryToken = exports.getOutboxEventSerializerToken = exports.getExternalizationRegistryToken = exports.getEventTypeRegistryToken = exports.getEventPublicationRepositoryToken = exports.getEventPublicationRegistryToken = exports.getEventPublicationProcessorToken = exports.getEventExternalizerToken = void 0;
4
+ var token_utils_1 = require("./token-utils");
5
+ Object.defineProperty(exports, "getEventExternalizerToken", { enumerable: true, get: function () { return token_utils_1.getEventExternalizerToken; } });
6
+ Object.defineProperty(exports, "getEventPublicationProcessorToken", { enumerable: true, get: function () { return token_utils_1.getEventPublicationProcessorToken; } });
7
+ Object.defineProperty(exports, "getEventPublicationRegistryToken", { enumerable: true, get: function () { return token_utils_1.getEventPublicationRegistryToken; } });
8
+ Object.defineProperty(exports, "getEventPublicationRepositoryToken", { enumerable: true, get: function () { return token_utils_1.getEventPublicationRepositoryToken; } });
9
+ Object.defineProperty(exports, "getEventTypeRegistryToken", { enumerable: true, get: function () { return token_utils_1.getEventTypeRegistryToken; } });
10
+ Object.defineProperty(exports, "getExternalizationRegistryToken", { enumerable: true, get: function () { return token_utils_1.getExternalizationRegistryToken; } });
11
+ Object.defineProperty(exports, "getOutboxEventSerializerToken", { enumerable: true, get: function () { return token_utils_1.getOutboxEventSerializerToken; } });
12
+ Object.defineProperty(exports, "getOutboxListenerRegistryToken", { enumerable: true, get: function () { return token_utils_1.getOutboxListenerRegistryToken; } });
13
+ Object.defineProperty(exports, "getOutboxPublisherToken", { enumerable: true, get: function () { return token_utils_1.getOutboxPublisherToken; } });
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tokens/index.ts"],"names":[],"mappings":";;;AAAA,6CAUuB;AATrB,wHAAA,yBAAyB,OAAA;AACzB,gIAAA,iCAAiC,OAAA;AACjC,+HAAA,gCAAgC,OAAA;AAChC,iIAAA,kCAAkC,OAAA;AAClC,wHAAA,yBAAyB,OAAA;AACzB,8HAAA,+BAA+B,OAAA;AAC/B,4HAAA,6BAA6B,OAAA;AAC7B,6HAAA,8BAA8B,OAAA;AAC9B,sHAAA,uBAAuB,OAAA"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Outbox-side token utilities. Mirror the core utilities (ADR-018) —
3
+ * deterministic DI tokens derived from a dataSource name, default
4
+ * `'default'`, format `${dataSource}${Component}`.
5
+ *
6
+ * One per outbox component the application can have a per-dataSource
7
+ * instance of: publisher, registries, processor, repository,
8
+ * externalizer, serializer. Per-dataSource scoping is what lets a
9
+ * modular monolith run separate outbox stacks per bounded context
10
+ * without contention on a single `event_publication` table.
11
+ */
12
+ /**
13
+ * DI token for the per-dataSource `OutboxEventPublisher`. The
14
+ * default-injected publisher is the smart facade (DD-024); this
15
+ * token resolves to the underlying per-dataSource publisher.
16
+ */
17
+ export declare function getOutboxPublisherToken(dataSource?: string): string;
18
+ /**
19
+ * DI token for the per-dataSource `EventTypeRegistry`. Event-type
20
+ * registrations from `OutboxModule.forFeature(...)` accumulate into
21
+ * the registry bound to the same dataSource — they do not bleed
22
+ * across dataSources.
23
+ */
24
+ export declare function getEventTypeRegistryToken(dataSource?: string): string;
25
+ /**
26
+ * DI token for the per-dataSource `EventPublicationRegistry` — the
27
+ * lifecycle coordinator that owns publication state transitions.
28
+ */
29
+ export declare function getEventPublicationRegistryToken(dataSource?: string): string;
30
+ /**
31
+ * DI token for the per-dataSource `EventPublicationProcessor` —
32
+ * the async worker that drains publications and dispatches them to
33
+ * listeners + externalizer.
34
+ */
35
+ export declare function getEventPublicationProcessorToken(dataSource?: string): string;
36
+ /**
37
+ * DI token for the per-dataSource `OutboxListenerRegistry` —
38
+ * registry of listener entries scanned from `@OutboxEventsHandler`
39
+ * classes (and, when wired, `@IntegrationEventsHandler` classes
40
+ * routed via the outbox).
41
+ */
42
+ export declare function getOutboxListenerRegistryToken(dataSource?: string): string;
43
+ /**
44
+ * DI token for the per-dataSource `ExternalizationRegistry`.
45
+ */
46
+ export declare function getExternalizationRegistryToken(dataSource?: string): string;
47
+ /**
48
+ * DI token for the per-dataSource `EventPublicationRepository`.
49
+ * Adapter packages (`outbox-typeorm`, future `outbox-prisma`, etc.)
50
+ * register their concrete repository under this token.
51
+ */
52
+ export declare function getEventPublicationRepositoryToken(dataSource?: string): string;
53
+ /**
54
+ * DI token for the per-dataSource `EventExternalizer`. Multi-adapter
55
+ * processes can wire externalization independently per outbox stack
56
+ * — e.g. the `'billing'` outbox emits to Kafka, the `'audit'` outbox
57
+ * is internal-only and binds no externalizer.
58
+ */
59
+ export declare function getEventExternalizerToken(dataSource?: string): string;
60
+ /**
61
+ * DI token for the per-dataSource `EventSerializer`. Distinct
62
+ * dataSources may use distinct serialization strategies (e.g.
63
+ * one JSON, another schema-validated) — the token-per-dataSource
64
+ * pattern keeps that pluggable without forcing one strategy
65
+ * process-wide.
66
+ */
67
+ export declare function getOutboxEventSerializerToken(dataSource?: string): string;
68
+ //# sourceMappingURL=token-utils.d.ts.map
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getOutboxPublisherToken = getOutboxPublisherToken;
4
+ exports.getEventTypeRegistryToken = getEventTypeRegistryToken;
5
+ exports.getEventPublicationRegistryToken = getEventPublicationRegistryToken;
6
+ exports.getEventPublicationProcessorToken = getEventPublicationProcessorToken;
7
+ exports.getOutboxListenerRegistryToken = getOutboxListenerRegistryToken;
8
+ exports.getExternalizationRegistryToken = getExternalizationRegistryToken;
9
+ exports.getEventPublicationRepositoryToken = getEventPublicationRepositoryToken;
10
+ exports.getEventExternalizerToken = getEventExternalizerToken;
11
+ exports.getOutboxEventSerializerToken = getOutboxEventSerializerToken;
12
+ const core_1 = require("@nestjs-transactional/core");
13
+ /**
14
+ * Outbox-side token utilities. Mirror the core utilities (ADR-018) —
15
+ * deterministic DI tokens derived from a dataSource name, default
16
+ * `'default'`, format `${dataSource}${Component}`.
17
+ *
18
+ * One per outbox component the application can have a per-dataSource
19
+ * instance of: publisher, registries, processor, repository,
20
+ * externalizer, serializer. Per-dataSource scoping is what lets a
21
+ * modular monolith run separate outbox stacks per bounded context
22
+ * without contention on a single `event_publication` table.
23
+ */
24
+ /**
25
+ * DI token for the per-dataSource `OutboxEventPublisher`. The
26
+ * default-injected publisher is the smart facade (DD-024); this
27
+ * token resolves to the underlying per-dataSource publisher.
28
+ */
29
+ function getOutboxPublisherToken(dataSource = core_1.DEFAULT_DATA_SOURCE_NAME) {
30
+ return `${dataSource}OutboxEventPublisher`;
31
+ }
32
+ /**
33
+ * DI token for the per-dataSource `EventTypeRegistry`. Event-type
34
+ * registrations from `OutboxModule.forFeature(...)` accumulate into
35
+ * the registry bound to the same dataSource — they do not bleed
36
+ * across dataSources.
37
+ */
38
+ function getEventTypeRegistryToken(dataSource = core_1.DEFAULT_DATA_SOURCE_NAME) {
39
+ return `${dataSource}EventTypeRegistry`;
40
+ }
41
+ /**
42
+ * DI token for the per-dataSource `EventPublicationRegistry` — the
43
+ * lifecycle coordinator that owns publication state transitions.
44
+ */
45
+ function getEventPublicationRegistryToken(dataSource = core_1.DEFAULT_DATA_SOURCE_NAME) {
46
+ return `${dataSource}EventPublicationRegistry`;
47
+ }
48
+ /**
49
+ * DI token for the per-dataSource `EventPublicationProcessor` —
50
+ * the async worker that drains publications and dispatches them to
51
+ * listeners + externalizer.
52
+ */
53
+ function getEventPublicationProcessorToken(dataSource = core_1.DEFAULT_DATA_SOURCE_NAME) {
54
+ return `${dataSource}EventPublicationProcessor`;
55
+ }
56
+ /**
57
+ * DI token for the per-dataSource `OutboxListenerRegistry` —
58
+ * registry of listener entries scanned from `@OutboxEventsHandler`
59
+ * classes (and, when wired, `@IntegrationEventsHandler` classes
60
+ * routed via the outbox).
61
+ */
62
+ function getOutboxListenerRegistryToken(dataSource = core_1.DEFAULT_DATA_SOURCE_NAME) {
63
+ return `${dataSource}OutboxListenerRegistry`;
64
+ }
65
+ /**
66
+ * DI token for the per-dataSource `ExternalizationRegistry`.
67
+ */
68
+ function getExternalizationRegistryToken(dataSource = core_1.DEFAULT_DATA_SOURCE_NAME) {
69
+ return `${dataSource}ExternalizationRegistry`;
70
+ }
71
+ /**
72
+ * DI token for the per-dataSource `EventPublicationRepository`.
73
+ * Adapter packages (`outbox-typeorm`, future `outbox-prisma`, etc.)
74
+ * register their concrete repository under this token.
75
+ */
76
+ function getEventPublicationRepositoryToken(dataSource = core_1.DEFAULT_DATA_SOURCE_NAME) {
77
+ return `${dataSource}EventPublicationRepository`;
78
+ }
79
+ /**
80
+ * DI token for the per-dataSource `EventExternalizer`. Multi-adapter
81
+ * processes can wire externalization independently per outbox stack
82
+ * — e.g. the `'billing'` outbox emits to Kafka, the `'audit'` outbox
83
+ * is internal-only and binds no externalizer.
84
+ */
85
+ function getEventExternalizerToken(dataSource = core_1.DEFAULT_DATA_SOURCE_NAME) {
86
+ return `${dataSource}EventExternalizer`;
87
+ }
88
+ /**
89
+ * DI token for the per-dataSource `EventSerializer`. Distinct
90
+ * dataSources may use distinct serialization strategies (e.g.
91
+ * one JSON, another schema-validated) — the token-per-dataSource
92
+ * pattern keeps that pluggable without forcing one strategy
93
+ * process-wide.
94
+ */
95
+ function getOutboxEventSerializerToken(dataSource = core_1.DEFAULT_DATA_SOURCE_NAME) {
96
+ return `${dataSource}OutboxEventSerializer`;
97
+ }
98
+ //# sourceMappingURL=token-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-utils.js","sourceRoot":"","sources":["../../src/tokens/token-utils.ts"],"names":[],"mappings":";;AAmBA,0DAIC;AAQD,8DAIC;AAMD,4EAIC;AAOD,8EAIC;AAQD,wEAIC;AAKD,0EAIC;AAOD,gFAIC;AAQD,8DAIC;AASD,sEAIC;AAjHD,qDAAsE;AAEtE;;;;;;;;;;GAUG;AAEH;;;;GAIG;AACH,SAAgB,uBAAuB,CACrC,aAAqB,+BAAwB;IAE7C,OAAO,GAAG,UAAU,sBAAsB,CAAC;AAC7C,CAAC;AAED;;;;;GAKG;AACH,SAAgB,yBAAyB,CACvC,aAAqB,+BAAwB;IAE7C,OAAO,GAAG,UAAU,mBAAmB,CAAC;AAC1C,CAAC;AAED;;;GAGG;AACH,SAAgB,gCAAgC,CAC9C,aAAqB,+BAAwB;IAE7C,OAAO,GAAG,UAAU,0BAA0B,CAAC;AACjD,CAAC;AAED;;;;GAIG;AACH,SAAgB,iCAAiC,CAC/C,aAAqB,+BAAwB;IAE7C,OAAO,GAAG,UAAU,2BAA2B,CAAC;AAClD,CAAC;AAED;;;;;GAKG;AACH,SAAgB,8BAA8B,CAC5C,aAAqB,+BAAwB;IAE7C,OAAO,GAAG,UAAU,wBAAwB,CAAC;AAC/C,CAAC;AAED;;GAEG;AACH,SAAgB,+BAA+B,CAC7C,aAAqB,+BAAwB;IAE7C,OAAO,GAAG,UAAU,yBAAyB,CAAC;AAChD,CAAC;AAED;;;;GAIG;AACH,SAAgB,kCAAkC,CAChD,aAAqB,+BAAwB;IAE7C,OAAO,GAAG,UAAU,4BAA4B,CAAC;AACnD,CAAC;AAED;;;;;GAKG;AACH,SAAgB,yBAAyB,CACvC,aAAqB,+BAAwB;IAE7C,OAAO,GAAG,UAAU,mBAAmB,CAAC;AAC1C,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,6BAA6B,CAC3C,aAAqB,+BAAwB;IAE7C,OAAO,GAAG,UAAU,uBAAuB,CAAC;AAC9C,CAAC"}