@fbsm/saga-nestjs 0.0.1-beta.0 → 0.1.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +100 -92
- package/dist/index.cjs +40 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +45 -8
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -24,30 +24,31 @@ SagaModule.forRootAsync(options: SagaModuleAsyncOptions): DynamicModule
|
|
|
24
24
|
|
|
25
25
|
**`SagaModuleOptions`** (extends `RunnerOptions`):
|
|
26
26
|
|
|
27
|
-
| Field
|
|
28
|
-
|
|
29
|
-
| `
|
|
30
|
-
| `transport`
|
|
31
|
-
| `retryPolicy.maxRetries`
|
|
32
|
-
| `retryPolicy.initialDelayMs` | `number`
|
|
33
|
-
| `fromBeginning`
|
|
34
|
-
| `topicPrefix`
|
|
35
|
-
| `otel.enabled`
|
|
36
|
-
| `otel.exporterUrl`
|
|
37
|
-
| `logger`
|
|
27
|
+
| Field | Type | Default | Description |
|
|
28
|
+
| ---------------------------- | --------------- | ------------------- | -------------------------------------------------------- |
|
|
29
|
+
| `groupId` | `string` | — | Kafka consumer group ID |
|
|
30
|
+
| `transport` | `SagaTransport` | — | Transport implementation (e.g., `KafkaTransport`) |
|
|
31
|
+
| `retryPolicy.maxRetries` | `number` | `3` | Max retry attempts for `SagaRetryableError` |
|
|
32
|
+
| `retryPolicy.initialDelayMs` | `number` | `200` | Initial retry delay in ms (doubles each attempt) |
|
|
33
|
+
| `fromBeginning` | `boolean` | `false` | Read from beginning of topics |
|
|
34
|
+
| `topicPrefix` | `string` | `''` | Prefix prepended to eventType for topic names |
|
|
35
|
+
| `otel.enabled` | `boolean` | `false` | Enable OpenTelemetry tracing and W3C context propagation |
|
|
36
|
+
| `otel.exporterUrl` | `string` | — | OTel exporter URL |
|
|
37
|
+
| `logger` | `SagaLogger` | `ConsoleSagaLogger` | Custom logger |
|
|
38
38
|
|
|
39
39
|
**Async configuration**:
|
|
40
|
+
|
|
40
41
|
```typescript
|
|
41
42
|
SagaModule.forRootAsync({
|
|
42
43
|
imports: [ConfigModule],
|
|
43
44
|
inject: [ConfigService],
|
|
44
45
|
useFactory: (config: ConfigService) => ({
|
|
45
|
-
|
|
46
|
+
groupId: config.get("KAFKA_GROUP_ID"),
|
|
46
47
|
transport: new KafkaTransport({
|
|
47
|
-
brokers: config.get(
|
|
48
|
+
brokers: config.get("KAFKA_BROKERS").split(","),
|
|
48
49
|
}),
|
|
49
50
|
}),
|
|
50
|
-
})
|
|
51
|
+
});
|
|
51
52
|
```
|
|
52
53
|
|
|
53
54
|
### `@SagaParticipant()`
|
|
@@ -58,7 +59,7 @@ Class decorator. Marks a class for auto-discovery by the saga runner. Must exten
|
|
|
58
59
|
@Injectable()
|
|
59
60
|
@SagaParticipant()
|
|
60
61
|
export class PaymentParticipant extends SagaParticipantBase {
|
|
61
|
-
readonly serviceId =
|
|
62
|
+
readonly serviceId = "payment-service";
|
|
62
63
|
}
|
|
63
64
|
```
|
|
64
65
|
|
|
@@ -78,10 +79,10 @@ async handleInventoryIssue(event: IncomingEvent, emit: Emit) {}
|
|
|
78
79
|
|
|
79
80
|
**`SagaHandlerOptions`**:
|
|
80
81
|
|
|
81
|
-
| Field
|
|
82
|
-
|
|
83
|
-
| `final` | `boolean`
|
|
84
|
-
| `fork`
|
|
82
|
+
| Field | Type | Description |
|
|
83
|
+
| ------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
84
|
+
| `final` | `boolean` | Marks the handler as the last step. Auto-adds `hint: 'final'` to all emitted events. |
|
|
85
|
+
| `fork` | `boolean \| ForkConfig` | Every `emit()` inside the handler creates a new sub-saga. The framework generates a new `sagaId`, adds `hint: 'fork'`, and propagates `parentSagaId`/`rootSagaId`. |
|
|
85
86
|
|
|
86
87
|
`final` and `fork` are **mutually exclusive** — using both throws `SagaInvalidHandlerConfigError`.
|
|
87
88
|
|
|
@@ -91,23 +92,23 @@ async handleInventoryIssue(event: IncomingEvent, emit: Emit) {}
|
|
|
91
92
|
|
|
92
93
|
Abstract base class for saga participants.
|
|
93
94
|
|
|
94
|
-
| Property / Method
|
|
95
|
-
|
|
96
|
-
| `serviceId`
|
|
97
|
-
| `on`
|
|
95
|
+
| Property / Method | Type | Description |
|
|
96
|
+
| --------------------- | --------------------------------------- | ----------------------------------------------------- |
|
|
97
|
+
| `serviceId` | `string` (abstract) | Unique service identifier |
|
|
98
|
+
| `on` | `Record<string, EventHandler>` | Auto-populated handler registry |
|
|
98
99
|
| `onRetryExhausted?()` | `(event, error, emit) => Promise<void>` | Called when `SagaRetryableError` exceeds `maxRetries` |
|
|
99
100
|
|
|
100
101
|
### `SagaPublisherProvider`
|
|
101
102
|
|
|
102
103
|
Injectable service to initiate sagas or emit events. See [Core Functions](../doc/core-functions.md) for detailed semantics.
|
|
103
104
|
|
|
104
|
-
| Method
|
|
105
|
-
|
|
106
|
-
| `start(fn, opts?)`
|
|
107
|
-
| `startChild(fn, opts?)`
|
|
108
|
-
| `emit(params)`
|
|
109
|
-
| `emitToParent(params \| fn)`
|
|
110
|
-
| `forSaga(sagaId, parentCtx?, causationId?)` | Get a bound `Emit` function for manual use
|
|
105
|
+
| Method | Description |
|
|
106
|
+
| ------------------------------------------- | ------------------------------------------------ |
|
|
107
|
+
| `start(fn, opts?)` | Start a new root saga |
|
|
108
|
+
| `startChild(fn, opts?)` | Start a child saga linked to the current context |
|
|
109
|
+
| `emit(params)` | Emit an event in the current saga context |
|
|
110
|
+
| `emitToParent(params \| fn)` | Emit to the parent saga |
|
|
111
|
+
| `forSaga(sagaId, parentCtx?, causationId?)` | Get a bound `Emit` function for manual use |
|
|
111
112
|
|
|
112
113
|
### Types
|
|
113
114
|
|
|
@@ -115,12 +116,12 @@ Injectable service to initiate sagas or emit events. See [Core Functions](../doc
|
|
|
115
116
|
type Emit = <T extends object>(params: EmitParams<T>) => Promise<void>;
|
|
116
117
|
|
|
117
118
|
interface EmitParams<T extends object = Record<string, unknown>> {
|
|
118
|
-
eventType: string;
|
|
119
|
-
stepName: string;
|
|
119
|
+
eventType: string; // Event type (also used as topic name)
|
|
120
|
+
stepName: string; // Logical step name for tracing
|
|
120
121
|
stepDescription?: string;
|
|
121
|
-
payload: T;
|
|
122
|
-
hint?: EventHint;
|
|
123
|
-
key?: string;
|
|
122
|
+
payload: T; // Event payload
|
|
123
|
+
hint?: EventHint; // 'compensation' | 'final' | 'fork'
|
|
124
|
+
key?: string; // Optional partition key
|
|
124
125
|
}
|
|
125
126
|
|
|
126
127
|
interface IncomingEvent<T = Record<string, unknown>> {
|
|
@@ -152,20 +153,20 @@ A basic participant that handles one event and emits another.
|
|
|
152
153
|
|
|
153
154
|
```typescript
|
|
154
155
|
// payment.participant.ts
|
|
155
|
-
import { Injectable } from
|
|
156
|
+
import { Injectable } from "@nestjs/common";
|
|
156
157
|
import {
|
|
157
158
|
SagaParticipant,
|
|
158
159
|
SagaParticipantBase,
|
|
159
160
|
SagaHandler,
|
|
160
|
-
} from
|
|
161
|
-
import type { IncomingEvent, Emit } from
|
|
161
|
+
} from "@fbsm/saga-nestjs";
|
|
162
|
+
import type { IncomingEvent, Emit } from "@fbsm/saga-core";
|
|
162
163
|
|
|
163
164
|
@Injectable()
|
|
164
165
|
@SagaParticipant()
|
|
165
166
|
export class PaymentParticipant extends SagaParticipantBase {
|
|
166
|
-
readonly serviceId =
|
|
167
|
+
readonly serviceId = "payment-service";
|
|
167
168
|
|
|
168
|
-
@SagaHandler(
|
|
169
|
+
@SagaHandler("order.created")
|
|
169
170
|
async handleOrderCreated(event: IncomingEvent, emit: Emit): Promise<void> {
|
|
170
171
|
const { orderId, amount } = event.payload as {
|
|
171
172
|
orderId: string;
|
|
@@ -176,8 +177,8 @@ export class PaymentParticipant extends SagaParticipantBase {
|
|
|
176
177
|
const transactionId = `txn-${Date.now()}`;
|
|
177
178
|
|
|
178
179
|
await emit({
|
|
179
|
-
eventType:
|
|
180
|
-
stepName:
|
|
180
|
+
eventType: "payment.completed",
|
|
181
|
+
stepName: "process-payment",
|
|
181
182
|
payload: { orderId, transactionId, amount },
|
|
182
183
|
});
|
|
183
184
|
}
|
|
@@ -186,10 +187,10 @@ export class PaymentParticipant extends SagaParticipantBase {
|
|
|
186
187
|
|
|
187
188
|
```typescript
|
|
188
189
|
// orders.controller.ts
|
|
189
|
-
import { Controller, Post, Body } from
|
|
190
|
-
import { SagaPublisherProvider } from
|
|
190
|
+
import { Controller, Post, Body } from "@nestjs/common";
|
|
191
|
+
import { SagaPublisherProvider } from "@fbsm/saga-nestjs";
|
|
191
192
|
|
|
192
|
-
@Controller(
|
|
193
|
+
@Controller("orders")
|
|
193
194
|
export class OrdersController {
|
|
194
195
|
constructor(private readonly sagaPublisher: SagaPublisherProvider) {}
|
|
195
196
|
|
|
@@ -197,8 +198,8 @@ export class OrdersController {
|
|
|
197
198
|
async create(@Body() body: { amount: number }) {
|
|
198
199
|
const { sagaId } = await this.sagaPublisher.start(async () => {
|
|
199
200
|
await this.sagaPublisher.emit({
|
|
200
|
-
eventType:
|
|
201
|
-
stepName:
|
|
201
|
+
eventType: "order.created",
|
|
202
|
+
stepName: "create-order",
|
|
202
203
|
payload: { orderId: `order-${Date.now()}`, amount: body.amount },
|
|
203
204
|
});
|
|
204
205
|
});
|
|
@@ -216,19 +217,19 @@ A handler that forks N sub-sagas and coordinates their completion via `emitToPar
|
|
|
216
217
|
|
|
217
218
|
```typescript
|
|
218
219
|
// bulk-orchestration.participant.ts
|
|
219
|
-
import { Injectable } from
|
|
220
|
+
import { Injectable } from "@nestjs/common";
|
|
220
221
|
import {
|
|
221
222
|
SagaParticipant,
|
|
222
223
|
SagaParticipantBase,
|
|
223
224
|
SagaHandler,
|
|
224
225
|
SagaPublisherProvider,
|
|
225
|
-
} from
|
|
226
|
-
import type { IncomingEvent, Emit } from
|
|
226
|
+
} from "@fbsm/saga-nestjs";
|
|
227
|
+
import type { IncomingEvent, Emit } from "@fbsm/saga-core";
|
|
227
228
|
|
|
228
229
|
@Injectable()
|
|
229
230
|
@SagaParticipant()
|
|
230
231
|
export class BulkOrchestrationParticipant extends SagaParticipantBase {
|
|
231
|
-
readonly serviceId =
|
|
232
|
+
readonly serviceId = "bulk-orchestration";
|
|
232
233
|
|
|
233
234
|
private completionCount = new Map<string, { total: number; done: number }>();
|
|
234
235
|
|
|
@@ -237,7 +238,7 @@ export class BulkOrchestrationParticipant extends SagaParticipantBase {
|
|
|
237
238
|
}
|
|
238
239
|
|
|
239
240
|
// Each emit() inside this handler creates a separate sub-saga
|
|
240
|
-
@SagaHandler(
|
|
241
|
+
@SagaHandler("bulk.requested", { fork: true })
|
|
241
242
|
async handleBulkRequested(event: IncomingEvent, emit: Emit): Promise<void> {
|
|
242
243
|
const { batchId, items } = event.payload as {
|
|
243
244
|
batchId: string;
|
|
@@ -249,15 +250,15 @@ export class BulkOrchestrationParticipant extends SagaParticipantBase {
|
|
|
249
250
|
// N emits = N sub-sagas (each gets its own sagaId)
|
|
250
251
|
for (const item of items) {
|
|
251
252
|
await emit({
|
|
252
|
-
eventType:
|
|
253
|
-
stepName:
|
|
253
|
+
eventType: "item.processing.requested",
|
|
254
|
+
stepName: "request-item-processing",
|
|
254
255
|
payload: { batchId, item },
|
|
255
256
|
});
|
|
256
257
|
}
|
|
257
258
|
}
|
|
258
259
|
|
|
259
260
|
// Called when each sub-saga completes
|
|
260
|
-
@SagaHandler(
|
|
261
|
+
@SagaHandler("item.processing.completed")
|
|
261
262
|
async handleItemCompleted(event: IncomingEvent): Promise<void> {
|
|
262
263
|
const { batchId } = event.payload as { batchId: string };
|
|
263
264
|
|
|
@@ -271,10 +272,10 @@ export class BulkOrchestrationParticipant extends SagaParticipantBase {
|
|
|
271
272
|
this.completionCount.delete(batchId);
|
|
272
273
|
|
|
273
274
|
await this.sagaPublisher.emitToParent({
|
|
274
|
-
eventType:
|
|
275
|
-
stepName:
|
|
275
|
+
eventType: "bulk.completed",
|
|
276
|
+
stepName: "complete-bulk",
|
|
276
277
|
payload: { batchId, totalProcessed: counter.total },
|
|
277
|
-
hint:
|
|
278
|
+
hint: "final",
|
|
278
279
|
});
|
|
279
280
|
}
|
|
280
281
|
}
|
|
@@ -286,9 +287,9 @@ export class BulkOrchestrationParticipant extends SagaParticipantBase {
|
|
|
286
287
|
@Injectable()
|
|
287
288
|
@SagaParticipant()
|
|
288
289
|
export class ItemProcessorParticipant extends SagaParticipantBase {
|
|
289
|
-
readonly serviceId =
|
|
290
|
+
readonly serviceId = "item-processor";
|
|
290
291
|
|
|
291
|
-
@SagaHandler(
|
|
292
|
+
@SagaHandler("item.processing.requested", { final: true })
|
|
292
293
|
async handleProcessing(event: IncomingEvent, emit: Emit): Promise<void> {
|
|
293
294
|
const { batchId, item } = event.payload as {
|
|
294
295
|
batchId: string;
|
|
@@ -298,9 +299,9 @@ export class ItemProcessorParticipant extends SagaParticipantBase {
|
|
|
298
299
|
// Process item...
|
|
299
300
|
|
|
300
301
|
await emit({
|
|
301
|
-
eventType:
|
|
302
|
-
stepName:
|
|
303
|
-
payload: { batchId, item, status:
|
|
302
|
+
eventType: "item.processing.completed",
|
|
303
|
+
stepName: "process-item",
|
|
304
|
+
payload: { batchId, item, status: "done" },
|
|
304
305
|
});
|
|
305
306
|
// hint: 'final' auto-added by framework
|
|
306
307
|
}
|
|
@@ -308,6 +309,7 @@ export class ItemProcessorParticipant extends SagaParticipantBase {
|
|
|
308
309
|
```
|
|
309
310
|
|
|
310
311
|
**Flow**:
|
|
312
|
+
|
|
311
313
|
```
|
|
312
314
|
POST /bulk → bulk.requested [fork x N]
|
|
313
315
|
Sub-saga 1: item.processing.requested → item.processing.completed [final]
|
|
@@ -326,12 +328,12 @@ Full flow showing how AsyncLocalStorage context propagates through `start()` →
|
|
|
326
328
|
@Injectable()
|
|
327
329
|
@SagaParticipant()
|
|
328
330
|
export class OrchestrationParticipant extends SagaParticipantBase {
|
|
329
|
-
readonly serviceId =
|
|
331
|
+
readonly serviceId = "orchestration";
|
|
330
332
|
|
|
331
333
|
// Fork: each emit creates a sub-saga with its own context
|
|
332
334
|
// Inside the handler, SagaContext.current() returns the PARENT saga context
|
|
333
335
|
// The framework wraps each emit in a NEW context for the sub-saga
|
|
334
|
-
@SagaHandler(
|
|
336
|
+
@SagaHandler("task.requested", { fork: true })
|
|
335
337
|
async handleTaskRequested(event: IncomingEvent, emit: Emit): Promise<void> {
|
|
336
338
|
const { taskId } = event.payload as { taskId: string };
|
|
337
339
|
|
|
@@ -341,14 +343,14 @@ export class OrchestrationParticipant extends SagaParticipantBase {
|
|
|
341
343
|
// - rootSagaId inherited
|
|
342
344
|
// - hint: 'fork' auto-added
|
|
343
345
|
await emit({
|
|
344
|
-
eventType:
|
|
345
|
-
stepName:
|
|
346
|
+
eventType: "validation.requested",
|
|
347
|
+
stepName: "request-validation",
|
|
346
348
|
payload: { taskId },
|
|
347
349
|
});
|
|
348
350
|
}
|
|
349
351
|
|
|
350
352
|
// Parent receives the result when sub-saga calls emitToParent()
|
|
351
|
-
@SagaHandler(
|
|
353
|
+
@SagaHandler("task.completed", { final: true })
|
|
352
354
|
async handleTaskCompleted(event: IncomingEvent, emit: Emit): Promise<void> {
|
|
353
355
|
const { taskId, result } = event.payload as {
|
|
354
356
|
taskId: string;
|
|
@@ -356,8 +358,8 @@ export class OrchestrationParticipant extends SagaParticipantBase {
|
|
|
356
358
|
};
|
|
357
359
|
|
|
358
360
|
await emit({
|
|
359
|
-
eventType:
|
|
360
|
-
stepName:
|
|
361
|
+
eventType: "task.done",
|
|
362
|
+
stepName: "finish-task",
|
|
361
363
|
payload: { taskId, result },
|
|
362
364
|
});
|
|
363
365
|
// hint: 'final' auto-added
|
|
@@ -370,30 +372,30 @@ export class OrchestrationParticipant extends SagaParticipantBase {
|
|
|
370
372
|
@Injectable()
|
|
371
373
|
@SagaParticipant()
|
|
372
374
|
export class ValidatorParticipant extends SagaParticipantBase {
|
|
373
|
-
readonly serviceId =
|
|
375
|
+
readonly serviceId = "validator";
|
|
374
376
|
|
|
375
377
|
constructor(private readonly sagaPublisher: SagaPublisherProvider) {
|
|
376
378
|
super();
|
|
377
379
|
}
|
|
378
380
|
|
|
379
381
|
// Final handler in the sub-saga
|
|
380
|
-
@SagaHandler(
|
|
382
|
+
@SagaHandler("validation.requested", { final: true })
|
|
381
383
|
async handleValidation(event: IncomingEvent, emit: Emit): Promise<void> {
|
|
382
384
|
const { taskId } = event.payload as { taskId: string };
|
|
383
385
|
|
|
384
386
|
// Emit within the sub-saga (hint: 'final' auto-added)
|
|
385
387
|
await emit({
|
|
386
|
-
eventType:
|
|
387
|
-
stepName:
|
|
388
|
+
eventType: "validation.completed",
|
|
389
|
+
stepName: "validate",
|
|
388
390
|
payload: { taskId, valid: true },
|
|
389
391
|
});
|
|
390
392
|
|
|
391
393
|
// Report back to parent saga
|
|
392
394
|
// emitToParent reads parentSagaId from AsyncLocalStorage
|
|
393
395
|
await this.sagaPublisher.emitToParent({
|
|
394
|
-
eventType:
|
|
395
|
-
stepName:
|
|
396
|
-
payload: { taskId, result:
|
|
396
|
+
eventType: "task.completed",
|
|
397
|
+
stepName: "report-to-parent",
|
|
398
|
+
payload: { taskId, result: "validated" },
|
|
397
399
|
});
|
|
398
400
|
}
|
|
399
401
|
}
|
|
@@ -417,6 +419,7 @@ async createTask() {
|
|
|
417
419
|
```
|
|
418
420
|
|
|
419
421
|
**Context flow**:
|
|
422
|
+
|
|
420
423
|
```
|
|
421
424
|
start() → ALS context: { sagaId: A, rootSagaId: A }
|
|
422
425
|
→ task.requested (handler runs in context A)
|
|
@@ -433,11 +436,11 @@ start() → ALS context: { sagaId: A, rootSagaId: A }
|
|
|
433
436
|
For when you need full control or can't use callbacks (e.g., Express middleware, testing).
|
|
434
437
|
|
|
435
438
|
```typescript
|
|
436
|
-
import { Controller, Post, Body } from
|
|
437
|
-
import { v7 as uuidv7 } from
|
|
438
|
-
import { SagaPublisherProvider } from
|
|
439
|
+
import { Controller, Post, Body } from "@nestjs/common";
|
|
440
|
+
import { v7 as uuidv7 } from "uuid";
|
|
441
|
+
import { SagaPublisherProvider } from "@fbsm/saga-nestjs";
|
|
439
442
|
|
|
440
|
-
@Controller(
|
|
443
|
+
@Controller("orders")
|
|
441
444
|
export class ManualOrdersController {
|
|
442
445
|
constructor(private readonly sagaPublisher: SagaPublisherProvider) {}
|
|
443
446
|
|
|
@@ -450,35 +453,39 @@ export class ManualOrdersController {
|
|
|
450
453
|
const emit = this.sagaPublisher.forSaga(sagaId);
|
|
451
454
|
|
|
452
455
|
await emit({
|
|
453
|
-
eventType:
|
|
454
|
-
stepName:
|
|
456
|
+
eventType: "order.created",
|
|
457
|
+
stepName: "create-order",
|
|
455
458
|
payload: { orderId: `order-${Date.now()}`, amount: body.amount },
|
|
456
459
|
});
|
|
457
460
|
|
|
458
461
|
return { sagaId };
|
|
459
462
|
}
|
|
460
463
|
|
|
461
|
-
@Post(
|
|
464
|
+
@Post("with-child")
|
|
462
465
|
async createWithChild(@Body() body: { amount: number }) {
|
|
463
466
|
const sagaId = uuidv7();
|
|
464
467
|
const rootEmit = this.sagaPublisher.forSaga(sagaId);
|
|
465
468
|
|
|
466
469
|
await rootEmit({
|
|
467
|
-
eventType:
|
|
468
|
-
stepName:
|
|
470
|
+
eventType: "order.created",
|
|
471
|
+
stepName: "create-order",
|
|
469
472
|
payload: { orderId: `order-${Date.now()}`, amount: body.amount },
|
|
470
473
|
});
|
|
471
474
|
|
|
472
475
|
// Manually create a child saga
|
|
473
476
|
const childSagaId = uuidv7();
|
|
474
|
-
const childEmit = this.sagaPublisher.forSaga(
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
477
|
+
const childEmit = this.sagaPublisher.forSaga(
|
|
478
|
+
childSagaId,
|
|
479
|
+
{
|
|
480
|
+
parentSagaId: sagaId,
|
|
481
|
+
rootSagaId: sagaId,
|
|
482
|
+
},
|
|
483
|
+
sagaId,
|
|
484
|
+
); // causationId
|
|
478
485
|
|
|
479
486
|
await childEmit({
|
|
480
|
-
eventType:
|
|
481
|
-
stepName:
|
|
487
|
+
eventType: "fulfillment.started",
|
|
488
|
+
stepName: "start-fulfillment",
|
|
482
489
|
payload: { orderId: `order-${Date.now()}` },
|
|
483
490
|
});
|
|
484
491
|
|
|
@@ -488,6 +495,7 @@ export class ManualOrdersController {
|
|
|
488
495
|
```
|
|
489
496
|
|
|
490
497
|
**When to use manual mode**:
|
|
498
|
+
|
|
491
499
|
- Testing: create emit functions with known saga IDs
|
|
492
500
|
- Non-callback patterns: when wrapping in a callback is impractical
|
|
493
501
|
- Migration: gradually adopting the library in existing code
|
package/dist/index.cjs
CHANGED
|
@@ -54,7 +54,9 @@ var SAGA_OPTIONS_TOKEN = /* @__PURE__ */ Symbol("SAGA_OPTIONS_TOKEN");
|
|
|
54
54
|
var SAGA_TRANSPORT_TOKEN = /* @__PURE__ */ Symbol("SAGA_TRANSPORT_TOKEN");
|
|
55
55
|
var SAGA_PARTICIPANT_METADATA = /* @__PURE__ */ Symbol("SAGA_PARTICIPANT_METADATA");
|
|
56
56
|
var SAGA_HANDLER_METADATA = /* @__PURE__ */ Symbol("SAGA_HANDLER_METADATA");
|
|
57
|
-
var SAGA_HANDLER_OPTIONS_METADATA = /* @__PURE__ */ Symbol(
|
|
57
|
+
var SAGA_HANDLER_OPTIONS_METADATA = /* @__PURE__ */ Symbol(
|
|
58
|
+
"SAGA_HANDLER_OPTIONS_METADATA"
|
|
59
|
+
);
|
|
58
60
|
|
|
59
61
|
// src/providers/saga-runner.provider.ts
|
|
60
62
|
var import_common = require("@nestjs/common");
|
|
@@ -95,7 +97,10 @@ var SagaRunnerProvider = class {
|
|
|
95
97
|
if ("on" in instance && typeof instance.on === "object") {
|
|
96
98
|
Object.assign(instance.on, on);
|
|
97
99
|
}
|
|
98
|
-
const handlerOptionsMap = Reflect.getMetadata(
|
|
100
|
+
const handlerOptionsMap = Reflect.getMetadata(
|
|
101
|
+
SAGA_HANDLER_OPTIONS_METADATA,
|
|
102
|
+
instance.constructor
|
|
103
|
+
);
|
|
99
104
|
const handlerOptions = {};
|
|
100
105
|
if (handlerOptionsMap) {
|
|
101
106
|
for (const [eventType, opts] of handlerOptionsMap.entries()) {
|
|
@@ -160,8 +165,20 @@ var SagaModule = class {
|
|
|
160
165
|
const otelCtx = (0, import_saga_core3.createOtelContext)(options.otel?.enabled ?? false);
|
|
161
166
|
const registry = new import_saga_core3.SagaRegistry();
|
|
162
167
|
const parser = new import_saga_core3.SagaParser(otelCtx);
|
|
163
|
-
const publisher = new import_saga_core3.SagaPublisher(
|
|
164
|
-
|
|
168
|
+
const publisher = new import_saga_core3.SagaPublisher(
|
|
169
|
+
options.transport,
|
|
170
|
+
otelCtx,
|
|
171
|
+
options.topicPrefix
|
|
172
|
+
);
|
|
173
|
+
const runner = new import_saga_core3.SagaRunner(
|
|
174
|
+
registry,
|
|
175
|
+
options.transport,
|
|
176
|
+
publisher,
|
|
177
|
+
parser,
|
|
178
|
+
options,
|
|
179
|
+
otelCtx,
|
|
180
|
+
options.logger
|
|
181
|
+
);
|
|
165
182
|
return {
|
|
166
183
|
module: SagaModule,
|
|
167
184
|
imports: [import_core2.DiscoveryModule],
|
|
@@ -215,7 +232,15 @@ var SagaModule = class {
|
|
|
215
232
|
provide: import_saga_core3.SagaRunner,
|
|
216
233
|
useFactory: (registry, publisher, parser, opts) => {
|
|
217
234
|
const otelCtx = (0, import_saga_core3.createOtelContext)(opts.otel?.enabled ?? false);
|
|
218
|
-
return new import_saga_core3.SagaRunner(
|
|
235
|
+
return new import_saga_core3.SagaRunner(
|
|
236
|
+
registry,
|
|
237
|
+
opts.transport,
|
|
238
|
+
publisher,
|
|
239
|
+
parser,
|
|
240
|
+
opts,
|
|
241
|
+
otelCtx,
|
|
242
|
+
opts.logger
|
|
243
|
+
);
|
|
219
244
|
},
|
|
220
245
|
inject: [import_saga_core3.SagaRegistry, import_saga_core3.SagaPublisher, import_saga_core3.SagaParser, SAGA_OPTIONS_TOKEN]
|
|
221
246
|
}
|
|
@@ -253,8 +278,16 @@ function SagaHandler(...args) {
|
|
|
253
278
|
existingOptions.set(eventType, options);
|
|
254
279
|
}
|
|
255
280
|
}
|
|
256
|
-
Reflect.defineMetadata(
|
|
257
|
-
|
|
281
|
+
Reflect.defineMetadata(
|
|
282
|
+
SAGA_HANDLER_METADATA,
|
|
283
|
+
existingMap,
|
|
284
|
+
target.constructor
|
|
285
|
+
);
|
|
286
|
+
Reflect.defineMetadata(
|
|
287
|
+
SAGA_HANDLER_OPTIONS_METADATA,
|
|
288
|
+
existingOptions,
|
|
289
|
+
target.constructor
|
|
290
|
+
);
|
|
258
291
|
};
|
|
259
292
|
}
|
|
260
293
|
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/saga.module.ts","../src/constants.ts","../src/providers/saga-runner.provider.ts","../src/providers/saga-publisher.provider.ts","../src/decorators/saga-handler.decorator.ts","../src/decorators/saga-participant.decorator.ts","../src/saga-participant-base.ts"],"sourcesContent":["// Module\nexport { SagaModule } from './saga.module';\n\n// Provider\nexport { SagaPublisherProvider } from './providers/saga-publisher.provider';\n\n// Decorators\nexport { SagaHandler } from './decorators/saga-handler.decorator';\nexport type { SagaHandlerOptions } from './decorators/saga-handler.decorator';\nexport { SagaParticipant } from './decorators/saga-participant.decorator';\n\n// Base class\nexport { SagaParticipantBase } from './saga-participant-base';\n\n// Constants (tokens for advanced usage)\nexport { SAGA_OPTIONS_TOKEN, SAGA_TRANSPORT_TOKEN } from './constants';\n\n// Options\nexport type { SagaModuleOptions, SagaModuleAsyncOptions } from './saga-module-options.interface';\n\n// Re-exports from core for consumer convenience\nexport {\n SagaError,\n SagaRetryableError,\n SagaDuplicateHandlerError,\n SagaParseError,\n SagaTransportNotConnectedError,\n} from '@fbsm/saga-core';\nexport type {\n SagaEvent,\n IncomingEvent,\n Emit,\n EmitParams,\n EventHint,\n EventHandler,\n ParentSagaContext,\n HandlerConfig,\n SagaTransport,\n} from '@fbsm/saga-core';\n","import { Module, DynamicModule, type Provider } from '@nestjs/common';\nimport { DiscoveryModule } from '@nestjs/core';\nimport {\n SagaRunner,\n SagaRegistry,\n SagaPublisher,\n SagaParser,\n createOtelContext,\n} from '@fbsm/saga-core';\nimport { SAGA_OPTIONS_TOKEN, SAGA_TRANSPORT_TOKEN } from './constants';\nimport type { SagaModuleOptions, SagaModuleAsyncOptions } from './saga-module-options.interface';\nimport { SagaRunnerProvider } from './providers/saga-runner.provider';\nimport { SagaPublisherProvider } from './providers/saga-publisher.provider';\n\n@Module({})\nexport class SagaModule {\n static forRoot(options: SagaModuleOptions): DynamicModule {\n const otelCtx = createOtelContext(options.otel?.enabled ?? false);\n const registry = new SagaRegistry();\n const parser = new SagaParser(otelCtx);\n const publisher = new SagaPublisher(options.transport, otelCtx, options.topicPrefix);\n const runner = new SagaRunner(registry, options.transport, publisher, parser, options, otelCtx, options.logger);\n\n return {\n module: SagaModule,\n imports: [DiscoveryModule],\n global: true,\n providers: [\n { provide: SAGA_OPTIONS_TOKEN, useValue: options },\n { provide: SAGA_TRANSPORT_TOKEN, useValue: options.transport },\n { provide: SagaRegistry, useValue: registry },\n { provide: SagaParser, useValue: parser },\n { provide: SagaPublisher, useValue: publisher },\n { provide: SagaRunner, useValue: runner },\n SagaRunnerProvider,\n SagaPublisherProvider,\n ],\n exports: [SagaPublisherProvider, SagaPublisher, SAGA_OPTIONS_TOKEN],\n };\n }\n\n static forRootAsync(options: SagaModuleAsyncOptions): DynamicModule {\n const asyncProviders: Provider[] = [\n {\n provide: SAGA_OPTIONS_TOKEN,\n useFactory: options.useFactory,\n inject: options.inject ?? [],\n },\n {\n provide: SAGA_TRANSPORT_TOKEN,\n useFactory: (opts: SagaModuleOptions) => opts.transport,\n inject: [SAGA_OPTIONS_TOKEN],\n },\n {\n provide: SagaRegistry,\n useFactory: () => new SagaRegistry(),\n },\n {\n provide: SagaParser,\n useFactory: (opts: SagaModuleOptions) => {\n const otelCtx = createOtelContext(opts.otel?.enabled ?? false);\n return new SagaParser(otelCtx);\n },\n inject: [SAGA_OPTIONS_TOKEN],\n },\n {\n provide: SagaPublisher,\n useFactory: (opts: SagaModuleOptions) => {\n const otelCtx = createOtelContext(opts.otel?.enabled ?? false);\n return new SagaPublisher(opts.transport, otelCtx, opts.topicPrefix);\n },\n inject: [SAGA_OPTIONS_TOKEN],\n },\n {\n provide: SagaRunner,\n useFactory: (\n registry: SagaRegistry,\n publisher: SagaPublisher,\n parser: SagaParser,\n opts: SagaModuleOptions,\n ) => {\n const otelCtx = createOtelContext(opts.otel?.enabled ?? false);\n return new SagaRunner(registry, opts.transport, publisher, parser, opts, otelCtx, opts.logger);\n },\n inject: [SagaRegistry, SagaPublisher, SagaParser, SAGA_OPTIONS_TOKEN],\n },\n ];\n\n return {\n module: SagaModule,\n imports: [...(options.imports ?? []), DiscoveryModule],\n global: true,\n providers: [...asyncProviders, SagaRunnerProvider, SagaPublisherProvider],\n exports: [SagaPublisherProvider, SagaPublisher, SAGA_OPTIONS_TOKEN],\n };\n }\n}\n","export const SAGA_OPTIONS_TOKEN = Symbol('SAGA_OPTIONS_TOKEN');\nexport const SAGA_TRANSPORT_TOKEN = Symbol('SAGA_TRANSPORT_TOKEN');\nexport const SAGA_PARTICIPANT_METADATA = Symbol('SAGA_PARTICIPANT_METADATA');\nexport const SAGA_HANDLER_METADATA = Symbol('SAGA_HANDLER_METADATA');\nexport const SAGA_HANDLER_OPTIONS_METADATA = Symbol('SAGA_HANDLER_OPTIONS_METADATA');\n","import { Inject, Injectable, Logger, OnModuleInit, OnModuleDestroy } from '@nestjs/common';\nimport { DiscoveryService } from '@nestjs/core';\nimport { SagaRunner, SagaRegistry } from '@fbsm/saga-core';\nimport type { EventHandler } from '@fbsm/saga-core';\nimport { SAGA_PARTICIPANT_METADATA, SAGA_HANDLER_METADATA, SAGA_HANDLER_OPTIONS_METADATA } from '../constants';\nimport type { SagaHandlerOptions } from '../decorators/saga-handler.decorator';\nimport type { HandlerConfig } from '@fbsm/saga-core';\n\n@Injectable()\nexport class SagaRunnerProvider implements OnModuleInit, OnModuleDestroy {\n private readonly logger = new Logger('SagaRunner');\n\n constructor(\n @Inject(DiscoveryService) private readonly discoveryService: DiscoveryService,\n @Inject(SagaRegistry) private readonly registry: SagaRegistry,\n @Inject(SagaRunner) private readonly runner: SagaRunner,\n ) {}\n\n async onModuleInit(): Promise<void> {\n const providers = this.discoveryService.getProviders();\n\n for (const wrapper of providers) {\n const instance = wrapper.instance;\n if (!instance || !instance.constructor) {\n continue;\n }\n\n const isParticipant = Reflect.getMetadata(\n SAGA_PARTICIPANT_METADATA,\n instance.constructor,\n );\n\n if (!isParticipant) {\n continue;\n }\n\n const handlesMap: Map<string, string | symbol> | undefined =\n Reflect.getMetadata(SAGA_HANDLER_METADATA, instance.constructor);\n\n if (!handlesMap || handlesMap.size === 0) {\n continue;\n }\n\n const on: Record<string, EventHandler<any>> = {};\n \n for (const [eventType, methodName] of handlesMap.entries()) {\n const method = (instance as any)[methodName];\n if (typeof method === 'function') {\n on[eventType] = method.bind(instance);\n }\n }\n\n // Populate the `on` property if instance extends SagaParticipantBase\n if ('on' in instance && typeof instance.on === 'object') {\n Object.assign(instance.on, on);\n }\n\n // Extract handler options (final, fork, etc.) from decorator metadata\n const handlerOptionsMap: Map<string, SagaHandlerOptions> | undefined =\n Reflect.getMetadata(SAGA_HANDLER_OPTIONS_METADATA, instance.constructor);\n\n const handlerOptions: Record<string, HandlerConfig> = {};\n if (handlerOptionsMap) {\n for (const [eventType, opts] of handlerOptionsMap.entries()) {\n handlerOptions[eventType] = { final: opts.final, fork: !!opts.fork };\n }\n }\n\n const serviceId = (instance as any).serviceId ?? 'unknown';\n this.logger.log(\n `Registered participant \"${serviceId}\" handling: [${Object.keys(on).join(', ')}]`,\n );\n\n this.registry.register({\n serviceId,\n on,\n handlerOptions: Object.keys(handlerOptions).length > 0 ? handlerOptions : undefined,\n onRetryExhausted:\n typeof (instance as any).onRetryExhausted === 'function'\n ? (instance as any).onRetryExhausted.bind(instance)\n : undefined,\n });\n }\n\n await this.runner.start();\n }\n\n async onModuleDestroy(): Promise<void> {\n await this.runner.stop();\n }\n}\n","import { Inject, Injectable } from '@nestjs/common';\nimport type { Emit, EmitParams, ParentSagaContext, SagaStartOptions } from '@fbsm/saga-core';\nimport { SagaPublisher } from '@fbsm/saga-core';\n\n@Injectable()\nexport class SagaPublisherProvider {\n constructor(@Inject(SagaPublisher) private readonly publisher: SagaPublisher) {}\n\n start<R>(fn: () => R | Promise<R>, opts?: SagaStartOptions): Promise<{ sagaId: string; result: Awaited<R> }> {\n return this.publisher.start(fn, opts);\n }\n\n startChild<R>(fn: () => R | Promise<R>, opts?: SagaStartOptions): Promise<{ sagaId: string; result: Awaited<R> }> {\n return this.publisher.startChild(fn, opts);\n }\n\n emit<T extends object>(params: EmitParams<T>): Promise<void> {\n return this.publisher.emit(params);\n }\n\n emitToParent<T extends object>(paramsOrFn: EmitParams<T> | (() => void | Promise<void>)): Promise<void> {\n return this.publisher.emitToParent(paramsOrFn);\n }\n\n forSaga(sagaId: string, parentCtx?: ParentSagaContext, causationId?: string): Emit {\n return this.publisher.forSaga(sagaId, parentCtx, causationId);\n }\n}\n","import { SAGA_HANDLER_METADATA, SAGA_HANDLER_OPTIONS_METADATA } from '../constants';\n\nimport type { ForkConfig } from '@fbsm/saga-core';\n\nexport interface SagaHandlerOptions {\n final?: boolean;\n fork?: boolean | ForkConfig;\n}\n\nexport function SagaHandler(\n ...args: [...string[]] | [...string[], SagaHandlerOptions]\n): MethodDecorator {\n let eventTypes: string[];\n let options: SagaHandlerOptions = {};\n\n const lastArg = args[args.length - 1];\n if (typeof lastArg === 'object' && lastArg !== null) {\n options = lastArg as SagaHandlerOptions;\n eventTypes = args.slice(0, -1) as string[];\n } else {\n eventTypes = args as string[];\n }\n\n return (target, propertyKey) => {\n const existingMap: Map<string, string | symbol> =\n Reflect.getMetadata(SAGA_HANDLER_METADATA, target.constructor) ?? new Map();\n const existingOptions: Map<string, SagaHandlerOptions> =\n Reflect.getMetadata(SAGA_HANDLER_OPTIONS_METADATA, target.constructor) ?? new Map();\n\n for (const eventType of eventTypes) {\n existingMap.set(eventType, propertyKey);\n if (options.final || options.fork) {\n existingOptions.set(eventType, options);\n }\n }\n\n Reflect.defineMetadata(SAGA_HANDLER_METADATA, existingMap, target.constructor);\n Reflect.defineMetadata(SAGA_HANDLER_OPTIONS_METADATA, existingOptions, target.constructor);\n };\n}\n","import { SAGA_PARTICIPANT_METADATA } from '../constants';\n\nexport function SagaParticipant(): ClassDecorator {\n return (target) => {\n Reflect.defineMetadata(SAGA_PARTICIPANT_METADATA, true, target);\n };\n}\n","import type {\n SagaParticipant,\n EventHandler,\n IncomingEvent,\n Emit,\n} from '@fbsm/saga-core';\nimport { SagaRetryableError } from '@fbsm/saga-core';\n\nexport abstract class SagaParticipantBase implements SagaParticipant {\n abstract readonly serviceId: string;\n\n readonly on: Record<string, EventHandler<any>> = {};\n\n onRetryExhausted?(\n event: IncomingEvent,\n error: SagaRetryableError,\n emit: Emit,\n ): Promise<void>;\n}\n"],"mappings":"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","names":["import_common","import_core","import_saga_core","import_common","import_saga_core","import_saga_core"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/saga.module.ts","../src/constants.ts","../src/providers/saga-runner.provider.ts","../src/providers/saga-publisher.provider.ts","../src/decorators/saga-handler.decorator.ts","../src/decorators/saga-participant.decorator.ts","../src/saga-participant-base.ts"],"sourcesContent":["// Module\nexport { SagaModule } from \"./saga.module\";\n\n// Provider\nexport { SagaPublisherProvider } from \"./providers/saga-publisher.provider\";\n\n// Decorators\nexport { SagaHandler } from \"./decorators/saga-handler.decorator\";\nexport type { SagaHandlerOptions } from \"./decorators/saga-handler.decorator\";\nexport { SagaParticipant } from \"./decorators/saga-participant.decorator\";\n\n// Base class\nexport { SagaParticipantBase } from \"./saga-participant-base\";\n\n// Constants (tokens for advanced usage)\nexport { SAGA_OPTIONS_TOKEN, SAGA_TRANSPORT_TOKEN } from \"./constants\";\n\n// Options\nexport type {\n SagaModuleOptions,\n SagaModuleAsyncOptions,\n} from \"./saga-module-options.interface\";\n\n// Re-exports from core for consumer convenience\nexport {\n SagaError,\n SagaRetryableError,\n SagaDuplicateHandlerError,\n SagaParseError,\n SagaTransportNotConnectedError,\n} from \"@fbsm/saga-core\";\nexport type {\n SagaEvent,\n IncomingEvent,\n Emit,\n EmitParams,\n EventHint,\n EventHandler,\n ParentSagaContext,\n HandlerConfig,\n SagaTransport,\n} from \"@fbsm/saga-core\";\n","import { Module, DynamicModule, type Provider } from \"@nestjs/common\";\nimport { DiscoveryModule } from \"@nestjs/core\";\nimport {\n SagaRunner,\n SagaRegistry,\n SagaPublisher,\n SagaParser,\n createOtelContext,\n} from \"@fbsm/saga-core\";\nimport { SAGA_OPTIONS_TOKEN, SAGA_TRANSPORT_TOKEN } from \"./constants\";\nimport type {\n SagaModuleOptions,\n SagaModuleAsyncOptions,\n} from \"./saga-module-options.interface\";\nimport { SagaRunnerProvider } from \"./providers/saga-runner.provider\";\nimport { SagaPublisherProvider } from \"./providers/saga-publisher.provider\";\n\n@Module({})\nexport class SagaModule {\n static forRoot(options: SagaModuleOptions): DynamicModule {\n const otelCtx = createOtelContext(options.otel?.enabled ?? false);\n const registry = new SagaRegistry();\n const parser = new SagaParser(otelCtx);\n const publisher = new SagaPublisher(\n options.transport,\n otelCtx,\n options.topicPrefix,\n );\n const runner = new SagaRunner(\n registry,\n options.transport,\n publisher,\n parser,\n options,\n otelCtx,\n options.logger,\n );\n\n return {\n module: SagaModule,\n imports: [DiscoveryModule],\n global: true,\n providers: [\n { provide: SAGA_OPTIONS_TOKEN, useValue: options },\n { provide: SAGA_TRANSPORT_TOKEN, useValue: options.transport },\n { provide: SagaRegistry, useValue: registry },\n { provide: SagaParser, useValue: parser },\n { provide: SagaPublisher, useValue: publisher },\n { provide: SagaRunner, useValue: runner },\n SagaRunnerProvider,\n SagaPublisherProvider,\n ],\n exports: [SagaPublisherProvider, SagaPublisher, SAGA_OPTIONS_TOKEN],\n };\n }\n\n static forRootAsync(options: SagaModuleAsyncOptions): DynamicModule {\n const asyncProviders: Provider[] = [\n {\n provide: SAGA_OPTIONS_TOKEN,\n useFactory: options.useFactory,\n inject: options.inject ?? [],\n },\n {\n provide: SAGA_TRANSPORT_TOKEN,\n useFactory: (opts: SagaModuleOptions) => opts.transport,\n inject: [SAGA_OPTIONS_TOKEN],\n },\n {\n provide: SagaRegistry,\n useFactory: () => new SagaRegistry(),\n },\n {\n provide: SagaParser,\n useFactory: (opts: SagaModuleOptions) => {\n const otelCtx = createOtelContext(opts.otel?.enabled ?? false);\n return new SagaParser(otelCtx);\n },\n inject: [SAGA_OPTIONS_TOKEN],\n },\n {\n provide: SagaPublisher,\n useFactory: (opts: SagaModuleOptions) => {\n const otelCtx = createOtelContext(opts.otel?.enabled ?? false);\n return new SagaPublisher(opts.transport, otelCtx, opts.topicPrefix);\n },\n inject: [SAGA_OPTIONS_TOKEN],\n },\n {\n provide: SagaRunner,\n useFactory: (\n registry: SagaRegistry,\n publisher: SagaPublisher,\n parser: SagaParser,\n opts: SagaModuleOptions,\n ) => {\n const otelCtx = createOtelContext(opts.otel?.enabled ?? false);\n return new SagaRunner(\n registry,\n opts.transport,\n publisher,\n parser,\n opts,\n otelCtx,\n opts.logger,\n );\n },\n inject: [SagaRegistry, SagaPublisher, SagaParser, SAGA_OPTIONS_TOKEN],\n },\n ];\n\n return {\n module: SagaModule,\n imports: [...(options.imports ?? []), DiscoveryModule],\n global: true,\n providers: [...asyncProviders, SagaRunnerProvider, SagaPublisherProvider],\n exports: [SagaPublisherProvider, SagaPublisher, SAGA_OPTIONS_TOKEN],\n };\n }\n}\n","export const SAGA_OPTIONS_TOKEN = Symbol(\"SAGA_OPTIONS_TOKEN\");\nexport const SAGA_TRANSPORT_TOKEN = Symbol(\"SAGA_TRANSPORT_TOKEN\");\nexport const SAGA_PARTICIPANT_METADATA = Symbol(\"SAGA_PARTICIPANT_METADATA\");\nexport const SAGA_HANDLER_METADATA = Symbol(\"SAGA_HANDLER_METADATA\");\nexport const SAGA_HANDLER_OPTIONS_METADATA = Symbol(\n \"SAGA_HANDLER_OPTIONS_METADATA\",\n);\n","import {\n Inject,\n Injectable,\n Logger,\n OnModuleInit,\n OnModuleDestroy,\n} from \"@nestjs/common\";\nimport { DiscoveryService } from \"@nestjs/core\";\nimport { SagaRunner, SagaRegistry } from \"@fbsm/saga-core\";\nimport type { EventHandler } from \"@fbsm/saga-core\";\nimport {\n SAGA_PARTICIPANT_METADATA,\n SAGA_HANDLER_METADATA,\n SAGA_HANDLER_OPTIONS_METADATA,\n} from \"../constants\";\nimport type { SagaHandlerOptions } from \"../decorators/saga-handler.decorator\";\nimport type { HandlerConfig } from \"@fbsm/saga-core\";\n\n@Injectable()\nexport class SagaRunnerProvider implements OnModuleInit, OnModuleDestroy {\n private readonly logger = new Logger(\"SagaRunner\");\n\n constructor(\n @Inject(DiscoveryService)\n private readonly discoveryService: DiscoveryService,\n @Inject(SagaRegistry) private readonly registry: SagaRegistry,\n @Inject(SagaRunner) private readonly runner: SagaRunner,\n ) {}\n\n async onModuleInit(): Promise<void> {\n const providers = this.discoveryService.getProviders();\n\n for (const wrapper of providers) {\n const instance = wrapper.instance;\n if (!instance || !instance.constructor) {\n continue;\n }\n\n const isParticipant = Reflect.getMetadata(\n SAGA_PARTICIPANT_METADATA,\n instance.constructor,\n );\n\n if (!isParticipant) {\n continue;\n }\n\n const handlesMap: Map<string, string | symbol> | undefined =\n Reflect.getMetadata(SAGA_HANDLER_METADATA, instance.constructor);\n\n if (!handlesMap || handlesMap.size === 0) {\n continue;\n }\n\n const on: Record<string, EventHandler<any>> = {};\n\n for (const [eventType, methodName] of handlesMap.entries()) {\n const method = (instance as any)[methodName];\n if (typeof method === \"function\") {\n on[eventType] = method.bind(instance);\n }\n }\n\n // Populate the `on` property if instance extends SagaParticipantBase\n if (\"on\" in instance && typeof instance.on === \"object\") {\n Object.assign(instance.on, on);\n }\n\n // Extract handler options (final, fork, etc.) from decorator metadata\n const handlerOptionsMap: Map<string, SagaHandlerOptions> | undefined =\n Reflect.getMetadata(\n SAGA_HANDLER_OPTIONS_METADATA,\n instance.constructor,\n );\n\n const handlerOptions: Record<string, HandlerConfig> = {};\n if (handlerOptionsMap) {\n for (const [eventType, opts] of handlerOptionsMap.entries()) {\n handlerOptions[eventType] = { final: opts.final, fork: !!opts.fork };\n }\n }\n\n const serviceId = (instance as any).serviceId ?? \"unknown\";\n this.logger.log(\n `Registered participant \"${serviceId}\" handling: [${Object.keys(on).join(\", \")}]`,\n );\n\n this.registry.register({\n serviceId,\n on,\n handlerOptions:\n Object.keys(handlerOptions).length > 0 ? handlerOptions : undefined,\n onRetryExhausted:\n typeof (instance as any).onRetryExhausted === \"function\"\n ? (instance as any).onRetryExhausted.bind(instance)\n : undefined,\n });\n }\n\n await this.runner.start();\n }\n\n async onModuleDestroy(): Promise<void> {\n await this.runner.stop();\n }\n}\n","import { Inject, Injectable } from \"@nestjs/common\";\nimport type {\n Emit,\n EmitParams,\n ParentSagaContext,\n SagaStartOptions,\n} from \"@fbsm/saga-core\";\nimport { SagaPublisher } from \"@fbsm/saga-core\";\n\n@Injectable()\nexport class SagaPublisherProvider {\n constructor(\n @Inject(SagaPublisher) private readonly publisher: SagaPublisher,\n ) {}\n\n start<R>(\n fn: () => R | Promise<R>,\n opts?: SagaStartOptions,\n ): Promise<{ sagaId: string; result: Awaited<R> }> {\n return this.publisher.start(fn, opts);\n }\n\n startChild<R>(\n fn: () => R | Promise<R>,\n opts?: SagaStartOptions,\n ): Promise<{ sagaId: string; result: Awaited<R> }> {\n return this.publisher.startChild(fn, opts);\n }\n\n emit<T extends object>(params: EmitParams<T>): Promise<void> {\n return this.publisher.emit(params);\n }\n\n emitToParent<T extends object>(\n paramsOrFn: EmitParams<T> | (() => void | Promise<void>),\n ): Promise<void> {\n return this.publisher.emitToParent(paramsOrFn);\n }\n\n forSaga(\n sagaId: string,\n parentCtx?: ParentSagaContext,\n causationId?: string,\n ): Emit {\n return this.publisher.forSaga(sagaId, parentCtx, causationId);\n }\n}\n","import {\n SAGA_HANDLER_METADATA,\n SAGA_HANDLER_OPTIONS_METADATA,\n} from \"../constants\";\n\nimport type { ForkConfig } from \"@fbsm/saga-core\";\n\nexport interface SagaHandlerOptions {\n final?: boolean;\n fork?: boolean | ForkConfig;\n}\n\nexport function SagaHandler(\n ...args: [...string[]] | [...string[], SagaHandlerOptions]\n): MethodDecorator {\n let eventTypes: string[];\n let options: SagaHandlerOptions = {};\n\n const lastArg = args[args.length - 1];\n if (typeof lastArg === \"object\" && lastArg !== null) {\n options = lastArg as SagaHandlerOptions;\n eventTypes = args.slice(0, -1) as string[];\n } else {\n eventTypes = args as string[];\n }\n\n return (target, propertyKey) => {\n const existingMap: Map<string, string | symbol> =\n Reflect.getMetadata(SAGA_HANDLER_METADATA, target.constructor) ??\n new Map();\n const existingOptions: Map<string, SagaHandlerOptions> =\n Reflect.getMetadata(SAGA_HANDLER_OPTIONS_METADATA, target.constructor) ??\n new Map();\n\n for (const eventType of eventTypes) {\n existingMap.set(eventType, propertyKey);\n if (options.final || options.fork) {\n existingOptions.set(eventType, options);\n }\n }\n\n Reflect.defineMetadata(\n SAGA_HANDLER_METADATA,\n existingMap,\n target.constructor,\n );\n Reflect.defineMetadata(\n SAGA_HANDLER_OPTIONS_METADATA,\n existingOptions,\n target.constructor,\n );\n };\n}\n","import { SAGA_PARTICIPANT_METADATA } from \"../constants\";\n\nexport function SagaParticipant(): ClassDecorator {\n return (target) => {\n Reflect.defineMetadata(SAGA_PARTICIPANT_METADATA, true, target);\n };\n}\n","import type {\n SagaParticipant,\n EventHandler,\n IncomingEvent,\n Emit,\n} from \"@fbsm/saga-core\";\nimport { SagaRetryableError } from \"@fbsm/saga-core\";\n\nexport abstract class SagaParticipantBase implements SagaParticipant {\n abstract readonly serviceId: string;\n\n readonly on: Record<string, EventHandler<any>> = {};\n\n onRetryExhausted?(\n event: IncomingEvent,\n error: SagaRetryableError,\n emit: Emit,\n ): Promise<void>;\n}\n"],"mappings":"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","names":["import_common","import_core","import_saga_core","import_common","import_saga_core","import_saga_core"]}
|
package/dist/index.js
CHANGED
|
@@ -26,10 +26,16 @@ var SAGA_OPTIONS_TOKEN = /* @__PURE__ */ Symbol("SAGA_OPTIONS_TOKEN");
|
|
|
26
26
|
var SAGA_TRANSPORT_TOKEN = /* @__PURE__ */ Symbol("SAGA_TRANSPORT_TOKEN");
|
|
27
27
|
var SAGA_PARTICIPANT_METADATA = /* @__PURE__ */ Symbol("SAGA_PARTICIPANT_METADATA");
|
|
28
28
|
var SAGA_HANDLER_METADATA = /* @__PURE__ */ Symbol("SAGA_HANDLER_METADATA");
|
|
29
|
-
var SAGA_HANDLER_OPTIONS_METADATA = /* @__PURE__ */ Symbol(
|
|
29
|
+
var SAGA_HANDLER_OPTIONS_METADATA = /* @__PURE__ */ Symbol(
|
|
30
|
+
"SAGA_HANDLER_OPTIONS_METADATA"
|
|
31
|
+
);
|
|
30
32
|
|
|
31
33
|
// src/providers/saga-runner.provider.ts
|
|
32
|
-
import {
|
|
34
|
+
import {
|
|
35
|
+
Inject,
|
|
36
|
+
Injectable,
|
|
37
|
+
Logger
|
|
38
|
+
} from "@nestjs/common";
|
|
33
39
|
import { DiscoveryService } from "@nestjs/core";
|
|
34
40
|
import { SagaRunner, SagaRegistry } from "@fbsm/saga-core";
|
|
35
41
|
var SagaRunnerProvider = class {
|
|
@@ -67,7 +73,10 @@ var SagaRunnerProvider = class {
|
|
|
67
73
|
if ("on" in instance && typeof instance.on === "object") {
|
|
68
74
|
Object.assign(instance.on, on);
|
|
69
75
|
}
|
|
70
|
-
const handlerOptionsMap = Reflect.getMetadata(
|
|
76
|
+
const handlerOptionsMap = Reflect.getMetadata(
|
|
77
|
+
SAGA_HANDLER_OPTIONS_METADATA,
|
|
78
|
+
instance.constructor
|
|
79
|
+
);
|
|
71
80
|
const handlerOptions = {};
|
|
72
81
|
if (handlerOptionsMap) {
|
|
73
82
|
for (const [eventType, opts] of handlerOptionsMap.entries()) {
|
|
@@ -132,8 +141,20 @@ var SagaModule = class {
|
|
|
132
141
|
const otelCtx = createOtelContext(options.otel?.enabled ?? false);
|
|
133
142
|
const registry = new SagaRegistry2();
|
|
134
143
|
const parser = new SagaParser(otelCtx);
|
|
135
|
-
const publisher = new SagaPublisher2(
|
|
136
|
-
|
|
144
|
+
const publisher = new SagaPublisher2(
|
|
145
|
+
options.transport,
|
|
146
|
+
otelCtx,
|
|
147
|
+
options.topicPrefix
|
|
148
|
+
);
|
|
149
|
+
const runner = new SagaRunner2(
|
|
150
|
+
registry,
|
|
151
|
+
options.transport,
|
|
152
|
+
publisher,
|
|
153
|
+
parser,
|
|
154
|
+
options,
|
|
155
|
+
otelCtx,
|
|
156
|
+
options.logger
|
|
157
|
+
);
|
|
137
158
|
return {
|
|
138
159
|
module: SagaModule,
|
|
139
160
|
imports: [DiscoveryModule],
|
|
@@ -187,7 +208,15 @@ var SagaModule = class {
|
|
|
187
208
|
provide: SagaRunner2,
|
|
188
209
|
useFactory: (registry, publisher, parser, opts) => {
|
|
189
210
|
const otelCtx = createOtelContext(opts.otel?.enabled ?? false);
|
|
190
|
-
return new SagaRunner2(
|
|
211
|
+
return new SagaRunner2(
|
|
212
|
+
registry,
|
|
213
|
+
opts.transport,
|
|
214
|
+
publisher,
|
|
215
|
+
parser,
|
|
216
|
+
opts,
|
|
217
|
+
otelCtx,
|
|
218
|
+
opts.logger
|
|
219
|
+
);
|
|
191
220
|
},
|
|
192
221
|
inject: [SagaRegistry2, SagaPublisher2, SagaParser, SAGA_OPTIONS_TOKEN]
|
|
193
222
|
}
|
|
@@ -225,8 +254,16 @@ function SagaHandler(...args) {
|
|
|
225
254
|
existingOptions.set(eventType, options);
|
|
226
255
|
}
|
|
227
256
|
}
|
|
228
|
-
Reflect.defineMetadata(
|
|
229
|
-
|
|
257
|
+
Reflect.defineMetadata(
|
|
258
|
+
SAGA_HANDLER_METADATA,
|
|
259
|
+
existingMap,
|
|
260
|
+
target.constructor
|
|
261
|
+
);
|
|
262
|
+
Reflect.defineMetadata(
|
|
263
|
+
SAGA_HANDLER_OPTIONS_METADATA,
|
|
264
|
+
existingOptions,
|
|
265
|
+
target.constructor
|
|
266
|
+
);
|
|
230
267
|
};
|
|
231
268
|
}
|
|
232
269
|
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/saga.module.ts","../src/constants.ts","../src/providers/saga-runner.provider.ts","../src/providers/saga-publisher.provider.ts","../src/decorators/saga-handler.decorator.ts","../src/decorators/saga-participant.decorator.ts","../src/saga-participant-base.ts","../src/index.ts"],"sourcesContent":["import { Module, DynamicModule, type Provider } from '@nestjs/common';\nimport { DiscoveryModule } from '@nestjs/core';\nimport {\n SagaRunner,\n SagaRegistry,\n SagaPublisher,\n SagaParser,\n createOtelContext,\n} from '@fbsm/saga-core';\nimport { SAGA_OPTIONS_TOKEN, SAGA_TRANSPORT_TOKEN } from './constants';\nimport type { SagaModuleOptions, SagaModuleAsyncOptions } from './saga-module-options.interface';\nimport { SagaRunnerProvider } from './providers/saga-runner.provider';\nimport { SagaPublisherProvider } from './providers/saga-publisher.provider';\n\n@Module({})\nexport class SagaModule {\n static forRoot(options: SagaModuleOptions): DynamicModule {\n const otelCtx = createOtelContext(options.otel?.enabled ?? false);\n const registry = new SagaRegistry();\n const parser = new SagaParser(otelCtx);\n const publisher = new SagaPublisher(options.transport, otelCtx, options.topicPrefix);\n const runner = new SagaRunner(registry, options.transport, publisher, parser, options, otelCtx, options.logger);\n\n return {\n module: SagaModule,\n imports: [DiscoveryModule],\n global: true,\n providers: [\n { provide: SAGA_OPTIONS_TOKEN, useValue: options },\n { provide: SAGA_TRANSPORT_TOKEN, useValue: options.transport },\n { provide: SagaRegistry, useValue: registry },\n { provide: SagaParser, useValue: parser },\n { provide: SagaPublisher, useValue: publisher },\n { provide: SagaRunner, useValue: runner },\n SagaRunnerProvider,\n SagaPublisherProvider,\n ],\n exports: [SagaPublisherProvider, SagaPublisher, SAGA_OPTIONS_TOKEN],\n };\n }\n\n static forRootAsync(options: SagaModuleAsyncOptions): DynamicModule {\n const asyncProviders: Provider[] = [\n {\n provide: SAGA_OPTIONS_TOKEN,\n useFactory: options.useFactory,\n inject: options.inject ?? [],\n },\n {\n provide: SAGA_TRANSPORT_TOKEN,\n useFactory: (opts: SagaModuleOptions) => opts.transport,\n inject: [SAGA_OPTIONS_TOKEN],\n },\n {\n provide: SagaRegistry,\n useFactory: () => new SagaRegistry(),\n },\n {\n provide: SagaParser,\n useFactory: (opts: SagaModuleOptions) => {\n const otelCtx = createOtelContext(opts.otel?.enabled ?? false);\n return new SagaParser(otelCtx);\n },\n inject: [SAGA_OPTIONS_TOKEN],\n },\n {\n provide: SagaPublisher,\n useFactory: (opts: SagaModuleOptions) => {\n const otelCtx = createOtelContext(opts.otel?.enabled ?? false);\n return new SagaPublisher(opts.transport, otelCtx, opts.topicPrefix);\n },\n inject: [SAGA_OPTIONS_TOKEN],\n },\n {\n provide: SagaRunner,\n useFactory: (\n registry: SagaRegistry,\n publisher: SagaPublisher,\n parser: SagaParser,\n opts: SagaModuleOptions,\n ) => {\n const otelCtx = createOtelContext(opts.otel?.enabled ?? false);\n return new SagaRunner(registry, opts.transport, publisher, parser, opts, otelCtx, opts.logger);\n },\n inject: [SagaRegistry, SagaPublisher, SagaParser, SAGA_OPTIONS_TOKEN],\n },\n ];\n\n return {\n module: SagaModule,\n imports: [...(options.imports ?? []), DiscoveryModule],\n global: true,\n providers: [...asyncProviders, SagaRunnerProvider, SagaPublisherProvider],\n exports: [SagaPublisherProvider, SagaPublisher, SAGA_OPTIONS_TOKEN],\n };\n }\n}\n","export const SAGA_OPTIONS_TOKEN = Symbol('SAGA_OPTIONS_TOKEN');\nexport const SAGA_TRANSPORT_TOKEN = Symbol('SAGA_TRANSPORT_TOKEN');\nexport const SAGA_PARTICIPANT_METADATA = Symbol('SAGA_PARTICIPANT_METADATA');\nexport const SAGA_HANDLER_METADATA = Symbol('SAGA_HANDLER_METADATA');\nexport const SAGA_HANDLER_OPTIONS_METADATA = Symbol('SAGA_HANDLER_OPTIONS_METADATA');\n","import { Inject, Injectable, Logger, OnModuleInit, OnModuleDestroy } from '@nestjs/common';\nimport { DiscoveryService } from '@nestjs/core';\nimport { SagaRunner, SagaRegistry } from '@fbsm/saga-core';\nimport type { EventHandler } from '@fbsm/saga-core';\nimport { SAGA_PARTICIPANT_METADATA, SAGA_HANDLER_METADATA, SAGA_HANDLER_OPTIONS_METADATA } from '../constants';\nimport type { SagaHandlerOptions } from '../decorators/saga-handler.decorator';\nimport type { HandlerConfig } from '@fbsm/saga-core';\n\n@Injectable()\nexport class SagaRunnerProvider implements OnModuleInit, OnModuleDestroy {\n private readonly logger = new Logger('SagaRunner');\n\n constructor(\n @Inject(DiscoveryService) private readonly discoveryService: DiscoveryService,\n @Inject(SagaRegistry) private readonly registry: SagaRegistry,\n @Inject(SagaRunner) private readonly runner: SagaRunner,\n ) {}\n\n async onModuleInit(): Promise<void> {\n const providers = this.discoveryService.getProviders();\n\n for (const wrapper of providers) {\n const instance = wrapper.instance;\n if (!instance || !instance.constructor) {\n continue;\n }\n\n const isParticipant = Reflect.getMetadata(\n SAGA_PARTICIPANT_METADATA,\n instance.constructor,\n );\n\n if (!isParticipant) {\n continue;\n }\n\n const handlesMap: Map<string, string | symbol> | undefined =\n Reflect.getMetadata(SAGA_HANDLER_METADATA, instance.constructor);\n\n if (!handlesMap || handlesMap.size === 0) {\n continue;\n }\n\n const on: Record<string, EventHandler<any>> = {};\n \n for (const [eventType, methodName] of handlesMap.entries()) {\n const method = (instance as any)[methodName];\n if (typeof method === 'function') {\n on[eventType] = method.bind(instance);\n }\n }\n\n // Populate the `on` property if instance extends SagaParticipantBase\n if ('on' in instance && typeof instance.on === 'object') {\n Object.assign(instance.on, on);\n }\n\n // Extract handler options (final, fork, etc.) from decorator metadata\n const handlerOptionsMap: Map<string, SagaHandlerOptions> | undefined =\n Reflect.getMetadata(SAGA_HANDLER_OPTIONS_METADATA, instance.constructor);\n\n const handlerOptions: Record<string, HandlerConfig> = {};\n if (handlerOptionsMap) {\n for (const [eventType, opts] of handlerOptionsMap.entries()) {\n handlerOptions[eventType] = { final: opts.final, fork: !!opts.fork };\n }\n }\n\n const serviceId = (instance as any).serviceId ?? 'unknown';\n this.logger.log(\n `Registered participant \"${serviceId}\" handling: [${Object.keys(on).join(', ')}]`,\n );\n\n this.registry.register({\n serviceId,\n on,\n handlerOptions: Object.keys(handlerOptions).length > 0 ? handlerOptions : undefined,\n onRetryExhausted:\n typeof (instance as any).onRetryExhausted === 'function'\n ? (instance as any).onRetryExhausted.bind(instance)\n : undefined,\n });\n }\n\n await this.runner.start();\n }\n\n async onModuleDestroy(): Promise<void> {\n await this.runner.stop();\n }\n}\n","import { Inject, Injectable } from '@nestjs/common';\nimport type { Emit, EmitParams, ParentSagaContext, SagaStartOptions } from '@fbsm/saga-core';\nimport { SagaPublisher } from '@fbsm/saga-core';\n\n@Injectable()\nexport class SagaPublisherProvider {\n constructor(@Inject(SagaPublisher) private readonly publisher: SagaPublisher) {}\n\n start<R>(fn: () => R | Promise<R>, opts?: SagaStartOptions): Promise<{ sagaId: string; result: Awaited<R> }> {\n return this.publisher.start(fn, opts);\n }\n\n startChild<R>(fn: () => R | Promise<R>, opts?: SagaStartOptions): Promise<{ sagaId: string; result: Awaited<R> }> {\n return this.publisher.startChild(fn, opts);\n }\n\n emit<T extends object>(params: EmitParams<T>): Promise<void> {\n return this.publisher.emit(params);\n }\n\n emitToParent<T extends object>(paramsOrFn: EmitParams<T> | (() => void | Promise<void>)): Promise<void> {\n return this.publisher.emitToParent(paramsOrFn);\n }\n\n forSaga(sagaId: string, parentCtx?: ParentSagaContext, causationId?: string): Emit {\n return this.publisher.forSaga(sagaId, parentCtx, causationId);\n }\n}\n","import { SAGA_HANDLER_METADATA, SAGA_HANDLER_OPTIONS_METADATA } from '../constants';\n\nimport type { ForkConfig } from '@fbsm/saga-core';\n\nexport interface SagaHandlerOptions {\n final?: boolean;\n fork?: boolean | ForkConfig;\n}\n\nexport function SagaHandler(\n ...args: [...string[]] | [...string[], SagaHandlerOptions]\n): MethodDecorator {\n let eventTypes: string[];\n let options: SagaHandlerOptions = {};\n\n const lastArg = args[args.length - 1];\n if (typeof lastArg === 'object' && lastArg !== null) {\n options = lastArg as SagaHandlerOptions;\n eventTypes = args.slice(0, -1) as string[];\n } else {\n eventTypes = args as string[];\n }\n\n return (target, propertyKey) => {\n const existingMap: Map<string, string | symbol> =\n Reflect.getMetadata(SAGA_HANDLER_METADATA, target.constructor) ?? new Map();\n const existingOptions: Map<string, SagaHandlerOptions> =\n Reflect.getMetadata(SAGA_HANDLER_OPTIONS_METADATA, target.constructor) ?? new Map();\n\n for (const eventType of eventTypes) {\n existingMap.set(eventType, propertyKey);\n if (options.final || options.fork) {\n existingOptions.set(eventType, options);\n }\n }\n\n Reflect.defineMetadata(SAGA_HANDLER_METADATA, existingMap, target.constructor);\n Reflect.defineMetadata(SAGA_HANDLER_OPTIONS_METADATA, existingOptions, target.constructor);\n };\n}\n","import { SAGA_PARTICIPANT_METADATA } from '../constants';\n\nexport function SagaParticipant(): ClassDecorator {\n return (target) => {\n Reflect.defineMetadata(SAGA_PARTICIPANT_METADATA, true, target);\n };\n}\n","import type {\n SagaParticipant,\n EventHandler,\n IncomingEvent,\n Emit,\n} from '@fbsm/saga-core';\nimport { SagaRetryableError } from '@fbsm/saga-core';\n\nexport abstract class SagaParticipantBase implements SagaParticipant {\n abstract readonly serviceId: string;\n\n readonly on: Record<string, EventHandler<any>> = {};\n\n onRetryExhausted?(\n event: IncomingEvent,\n error: SagaRetryableError,\n emit: Emit,\n ): Promise<void>;\n}\n","// Module\nexport { SagaModule } from './saga.module';\n\n// Provider\nexport { SagaPublisherProvider } from './providers/saga-publisher.provider';\n\n// Decorators\nexport { SagaHandler } from './decorators/saga-handler.decorator';\nexport type { SagaHandlerOptions } from './decorators/saga-handler.decorator';\nexport { SagaParticipant } from './decorators/saga-participant.decorator';\n\n// Base class\nexport { SagaParticipantBase } from './saga-participant-base';\n\n// Constants (tokens for advanced usage)\nexport { SAGA_OPTIONS_TOKEN, SAGA_TRANSPORT_TOKEN } from './constants';\n\n// Options\nexport type { SagaModuleOptions, SagaModuleAsyncOptions } from './saga-module-options.interface';\n\n// Re-exports from core for consumer convenience\nexport {\n SagaError,\n SagaRetryableError,\n SagaDuplicateHandlerError,\n SagaParseError,\n SagaTransportNotConnectedError,\n} from '@fbsm/saga-core';\nexport type {\n SagaEvent,\n IncomingEvent,\n Emit,\n EmitParams,\n EventHint,\n EventHandler,\n ParentSagaContext,\n HandlerConfig,\n SagaTransport,\n} from '@fbsm/saga-core';\n"],"mappings":"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","names":["SagaRunner","SagaRegistry","SagaPublisher","Inject","Injectable","Injectable","Inject","SagaRegistry","SagaPublisher","SagaRunner"]}
|
|
1
|
+
{"version":3,"sources":["../src/saga.module.ts","../src/constants.ts","../src/providers/saga-runner.provider.ts","../src/providers/saga-publisher.provider.ts","../src/decorators/saga-handler.decorator.ts","../src/decorators/saga-participant.decorator.ts","../src/saga-participant-base.ts","../src/index.ts"],"sourcesContent":["import { Module, DynamicModule, type Provider } from \"@nestjs/common\";\nimport { DiscoveryModule } from \"@nestjs/core\";\nimport {\n SagaRunner,\n SagaRegistry,\n SagaPublisher,\n SagaParser,\n createOtelContext,\n} from \"@fbsm/saga-core\";\nimport { SAGA_OPTIONS_TOKEN, SAGA_TRANSPORT_TOKEN } from \"./constants\";\nimport type {\n SagaModuleOptions,\n SagaModuleAsyncOptions,\n} from \"./saga-module-options.interface\";\nimport { SagaRunnerProvider } from \"./providers/saga-runner.provider\";\nimport { SagaPublisherProvider } from \"./providers/saga-publisher.provider\";\n\n@Module({})\nexport class SagaModule {\n static forRoot(options: SagaModuleOptions): DynamicModule {\n const otelCtx = createOtelContext(options.otel?.enabled ?? false);\n const registry = new SagaRegistry();\n const parser = new SagaParser(otelCtx);\n const publisher = new SagaPublisher(\n options.transport,\n otelCtx,\n options.topicPrefix,\n );\n const runner = new SagaRunner(\n registry,\n options.transport,\n publisher,\n parser,\n options,\n otelCtx,\n options.logger,\n );\n\n return {\n module: SagaModule,\n imports: [DiscoveryModule],\n global: true,\n providers: [\n { provide: SAGA_OPTIONS_TOKEN, useValue: options },\n { provide: SAGA_TRANSPORT_TOKEN, useValue: options.transport },\n { provide: SagaRegistry, useValue: registry },\n { provide: SagaParser, useValue: parser },\n { provide: SagaPublisher, useValue: publisher },\n { provide: SagaRunner, useValue: runner },\n SagaRunnerProvider,\n SagaPublisherProvider,\n ],\n exports: [SagaPublisherProvider, SagaPublisher, SAGA_OPTIONS_TOKEN],\n };\n }\n\n static forRootAsync(options: SagaModuleAsyncOptions): DynamicModule {\n const asyncProviders: Provider[] = [\n {\n provide: SAGA_OPTIONS_TOKEN,\n useFactory: options.useFactory,\n inject: options.inject ?? [],\n },\n {\n provide: SAGA_TRANSPORT_TOKEN,\n useFactory: (opts: SagaModuleOptions) => opts.transport,\n inject: [SAGA_OPTIONS_TOKEN],\n },\n {\n provide: SagaRegistry,\n useFactory: () => new SagaRegistry(),\n },\n {\n provide: SagaParser,\n useFactory: (opts: SagaModuleOptions) => {\n const otelCtx = createOtelContext(opts.otel?.enabled ?? false);\n return new SagaParser(otelCtx);\n },\n inject: [SAGA_OPTIONS_TOKEN],\n },\n {\n provide: SagaPublisher,\n useFactory: (opts: SagaModuleOptions) => {\n const otelCtx = createOtelContext(opts.otel?.enabled ?? false);\n return new SagaPublisher(opts.transport, otelCtx, opts.topicPrefix);\n },\n inject: [SAGA_OPTIONS_TOKEN],\n },\n {\n provide: SagaRunner,\n useFactory: (\n registry: SagaRegistry,\n publisher: SagaPublisher,\n parser: SagaParser,\n opts: SagaModuleOptions,\n ) => {\n const otelCtx = createOtelContext(opts.otel?.enabled ?? false);\n return new SagaRunner(\n registry,\n opts.transport,\n publisher,\n parser,\n opts,\n otelCtx,\n opts.logger,\n );\n },\n inject: [SagaRegistry, SagaPublisher, SagaParser, SAGA_OPTIONS_TOKEN],\n },\n ];\n\n return {\n module: SagaModule,\n imports: [...(options.imports ?? []), DiscoveryModule],\n global: true,\n providers: [...asyncProviders, SagaRunnerProvider, SagaPublisherProvider],\n exports: [SagaPublisherProvider, SagaPublisher, SAGA_OPTIONS_TOKEN],\n };\n }\n}\n","export const SAGA_OPTIONS_TOKEN = Symbol(\"SAGA_OPTIONS_TOKEN\");\nexport const SAGA_TRANSPORT_TOKEN = Symbol(\"SAGA_TRANSPORT_TOKEN\");\nexport const SAGA_PARTICIPANT_METADATA = Symbol(\"SAGA_PARTICIPANT_METADATA\");\nexport const SAGA_HANDLER_METADATA = Symbol(\"SAGA_HANDLER_METADATA\");\nexport const SAGA_HANDLER_OPTIONS_METADATA = Symbol(\n \"SAGA_HANDLER_OPTIONS_METADATA\",\n);\n","import {\n Inject,\n Injectable,\n Logger,\n OnModuleInit,\n OnModuleDestroy,\n} from \"@nestjs/common\";\nimport { DiscoveryService } from \"@nestjs/core\";\nimport { SagaRunner, SagaRegistry } from \"@fbsm/saga-core\";\nimport type { EventHandler } from \"@fbsm/saga-core\";\nimport {\n SAGA_PARTICIPANT_METADATA,\n SAGA_HANDLER_METADATA,\n SAGA_HANDLER_OPTIONS_METADATA,\n} from \"../constants\";\nimport type { SagaHandlerOptions } from \"../decorators/saga-handler.decorator\";\nimport type { HandlerConfig } from \"@fbsm/saga-core\";\n\n@Injectable()\nexport class SagaRunnerProvider implements OnModuleInit, OnModuleDestroy {\n private readonly logger = new Logger(\"SagaRunner\");\n\n constructor(\n @Inject(DiscoveryService)\n private readonly discoveryService: DiscoveryService,\n @Inject(SagaRegistry) private readonly registry: SagaRegistry,\n @Inject(SagaRunner) private readonly runner: SagaRunner,\n ) {}\n\n async onModuleInit(): Promise<void> {\n const providers = this.discoveryService.getProviders();\n\n for (const wrapper of providers) {\n const instance = wrapper.instance;\n if (!instance || !instance.constructor) {\n continue;\n }\n\n const isParticipant = Reflect.getMetadata(\n SAGA_PARTICIPANT_METADATA,\n instance.constructor,\n );\n\n if (!isParticipant) {\n continue;\n }\n\n const handlesMap: Map<string, string | symbol> | undefined =\n Reflect.getMetadata(SAGA_HANDLER_METADATA, instance.constructor);\n\n if (!handlesMap || handlesMap.size === 0) {\n continue;\n }\n\n const on: Record<string, EventHandler<any>> = {};\n\n for (const [eventType, methodName] of handlesMap.entries()) {\n const method = (instance as any)[methodName];\n if (typeof method === \"function\") {\n on[eventType] = method.bind(instance);\n }\n }\n\n // Populate the `on` property if instance extends SagaParticipantBase\n if (\"on\" in instance && typeof instance.on === \"object\") {\n Object.assign(instance.on, on);\n }\n\n // Extract handler options (final, fork, etc.) from decorator metadata\n const handlerOptionsMap: Map<string, SagaHandlerOptions> | undefined =\n Reflect.getMetadata(\n SAGA_HANDLER_OPTIONS_METADATA,\n instance.constructor,\n );\n\n const handlerOptions: Record<string, HandlerConfig> = {};\n if (handlerOptionsMap) {\n for (const [eventType, opts] of handlerOptionsMap.entries()) {\n handlerOptions[eventType] = { final: opts.final, fork: !!opts.fork };\n }\n }\n\n const serviceId = (instance as any).serviceId ?? \"unknown\";\n this.logger.log(\n `Registered participant \"${serviceId}\" handling: [${Object.keys(on).join(\", \")}]`,\n );\n\n this.registry.register({\n serviceId,\n on,\n handlerOptions:\n Object.keys(handlerOptions).length > 0 ? handlerOptions : undefined,\n onRetryExhausted:\n typeof (instance as any).onRetryExhausted === \"function\"\n ? (instance as any).onRetryExhausted.bind(instance)\n : undefined,\n });\n }\n\n await this.runner.start();\n }\n\n async onModuleDestroy(): Promise<void> {\n await this.runner.stop();\n }\n}\n","import { Inject, Injectable } from \"@nestjs/common\";\nimport type {\n Emit,\n EmitParams,\n ParentSagaContext,\n SagaStartOptions,\n} from \"@fbsm/saga-core\";\nimport { SagaPublisher } from \"@fbsm/saga-core\";\n\n@Injectable()\nexport class SagaPublisherProvider {\n constructor(\n @Inject(SagaPublisher) private readonly publisher: SagaPublisher,\n ) {}\n\n start<R>(\n fn: () => R | Promise<R>,\n opts?: SagaStartOptions,\n ): Promise<{ sagaId: string; result: Awaited<R> }> {\n return this.publisher.start(fn, opts);\n }\n\n startChild<R>(\n fn: () => R | Promise<R>,\n opts?: SagaStartOptions,\n ): Promise<{ sagaId: string; result: Awaited<R> }> {\n return this.publisher.startChild(fn, opts);\n }\n\n emit<T extends object>(params: EmitParams<T>): Promise<void> {\n return this.publisher.emit(params);\n }\n\n emitToParent<T extends object>(\n paramsOrFn: EmitParams<T> | (() => void | Promise<void>),\n ): Promise<void> {\n return this.publisher.emitToParent(paramsOrFn);\n }\n\n forSaga(\n sagaId: string,\n parentCtx?: ParentSagaContext,\n causationId?: string,\n ): Emit {\n return this.publisher.forSaga(sagaId, parentCtx, causationId);\n }\n}\n","import {\n SAGA_HANDLER_METADATA,\n SAGA_HANDLER_OPTIONS_METADATA,\n} from \"../constants\";\n\nimport type { ForkConfig } from \"@fbsm/saga-core\";\n\nexport interface SagaHandlerOptions {\n final?: boolean;\n fork?: boolean | ForkConfig;\n}\n\nexport function SagaHandler(\n ...args: [...string[]] | [...string[], SagaHandlerOptions]\n): MethodDecorator {\n let eventTypes: string[];\n let options: SagaHandlerOptions = {};\n\n const lastArg = args[args.length - 1];\n if (typeof lastArg === \"object\" && lastArg !== null) {\n options = lastArg as SagaHandlerOptions;\n eventTypes = args.slice(0, -1) as string[];\n } else {\n eventTypes = args as string[];\n }\n\n return (target, propertyKey) => {\n const existingMap: Map<string, string | symbol> =\n Reflect.getMetadata(SAGA_HANDLER_METADATA, target.constructor) ??\n new Map();\n const existingOptions: Map<string, SagaHandlerOptions> =\n Reflect.getMetadata(SAGA_HANDLER_OPTIONS_METADATA, target.constructor) ??\n new Map();\n\n for (const eventType of eventTypes) {\n existingMap.set(eventType, propertyKey);\n if (options.final || options.fork) {\n existingOptions.set(eventType, options);\n }\n }\n\n Reflect.defineMetadata(\n SAGA_HANDLER_METADATA,\n existingMap,\n target.constructor,\n );\n Reflect.defineMetadata(\n SAGA_HANDLER_OPTIONS_METADATA,\n existingOptions,\n target.constructor,\n );\n };\n}\n","import { SAGA_PARTICIPANT_METADATA } from \"../constants\";\n\nexport function SagaParticipant(): ClassDecorator {\n return (target) => {\n Reflect.defineMetadata(SAGA_PARTICIPANT_METADATA, true, target);\n };\n}\n","import type {\n SagaParticipant,\n EventHandler,\n IncomingEvent,\n Emit,\n} from \"@fbsm/saga-core\";\nimport { SagaRetryableError } from \"@fbsm/saga-core\";\n\nexport abstract class SagaParticipantBase implements SagaParticipant {\n abstract readonly serviceId: string;\n\n readonly on: Record<string, EventHandler<any>> = {};\n\n onRetryExhausted?(\n event: IncomingEvent,\n error: SagaRetryableError,\n emit: Emit,\n ): Promise<void>;\n}\n","// Module\nexport { SagaModule } from \"./saga.module\";\n\n// Provider\nexport { SagaPublisherProvider } from \"./providers/saga-publisher.provider\";\n\n// Decorators\nexport { SagaHandler } from \"./decorators/saga-handler.decorator\";\nexport type { SagaHandlerOptions } from \"./decorators/saga-handler.decorator\";\nexport { SagaParticipant } from \"./decorators/saga-participant.decorator\";\n\n// Base class\nexport { SagaParticipantBase } from \"./saga-participant-base\";\n\n// Constants (tokens for advanced usage)\nexport { SAGA_OPTIONS_TOKEN, SAGA_TRANSPORT_TOKEN } from \"./constants\";\n\n// Options\nexport type {\n SagaModuleOptions,\n SagaModuleAsyncOptions,\n} from \"./saga-module-options.interface\";\n\n// Re-exports from core for consumer convenience\nexport {\n SagaError,\n SagaRetryableError,\n SagaDuplicateHandlerError,\n SagaParseError,\n SagaTransportNotConnectedError,\n} from \"@fbsm/saga-core\";\nexport type {\n SagaEvent,\n IncomingEvent,\n Emit,\n EmitParams,\n EventHint,\n EventHandler,\n ParentSagaContext,\n HandlerConfig,\n SagaTransport,\n} from \"@fbsm/saga-core\";\n"],"mappings":"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","names":["SagaRunner","SagaRegistry","SagaPublisher","Inject","Injectable","Injectable","Inject","SagaRegistry","SagaPublisher","SagaRunner"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fbsm/saga-nestjs",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0-beta.2",
|
|
4
4
|
"description": "NestJS integration for saga choreography: dynamic module, decorators, auto-discovery",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "fbsm",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"dist"
|
|
40
40
|
],
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@fbsm/saga-core": "0.0
|
|
42
|
+
"@fbsm/saga-core": "0.1.0-beta.2"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"@nestjs/common": "^10.0.0",
|