nestjs-temporal-core 2.0.7 → 3.0.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 (101) hide show
  1. package/README.md +124 -558
  2. package/dist/client/temporal-client.module.d.ts +4 -2
  3. package/dist/client/temporal-client.module.js +59 -78
  4. package/dist/client/temporal-client.module.js.map +1 -1
  5. package/dist/client/temporal-client.service.d.ts +4 -3
  6. package/dist/client/temporal-client.service.js +43 -27
  7. package/dist/client/temporal-client.service.js.map +1 -1
  8. package/dist/client/temporal-schedule.service.d.ts +8 -2
  9. package/dist/client/temporal-schedule.service.js +86 -65
  10. package/dist/client/temporal-schedule.service.js.map +1 -1
  11. package/dist/constants.d.ts +171 -32
  12. package/dist/constants.js +164 -19
  13. package/dist/constants.js.map +1 -1
  14. package/dist/decorators/communication.decorators.d.ts +5 -0
  15. package/dist/decorators/communication.decorators.js +66 -0
  16. package/dist/decorators/communication.decorators.js.map +1 -0
  17. package/dist/decorators/core.decorators.d.ts +6 -0
  18. package/dist/decorators/core.decorators.js +87 -0
  19. package/dist/decorators/core.decorators.js.map +1 -0
  20. package/dist/decorators/index.d.ts +5 -6
  21. package/dist/decorators/index.js +5 -6
  22. package/dist/decorators/index.js.map +1 -1
  23. package/dist/decorators/parameter.decorators.d.ts +2 -0
  24. package/dist/decorators/parameter.decorators.js +29 -0
  25. package/dist/decorators/parameter.decorators.js.map +1 -0
  26. package/dist/decorators/scheduling.decorators.d.ts +4 -0
  27. package/dist/decorators/scheduling.decorators.js +37 -0
  28. package/dist/decorators/scheduling.decorators.js.map +1 -0
  29. package/dist/decorators/workflow-starter.decorator.d.ts +2 -0
  30. package/dist/decorators/workflow-starter.decorator.js +14 -0
  31. package/dist/decorators/workflow-starter.decorator.js.map +1 -0
  32. package/dist/discovery/index.d.ts +2 -0
  33. package/dist/discovery/index.js +19 -0
  34. package/dist/discovery/index.js.map +1 -0
  35. package/dist/discovery/schedule-manager.service.d.ts +36 -0
  36. package/dist/discovery/schedule-manager.service.js +215 -0
  37. package/dist/discovery/schedule-manager.service.js.map +1 -0
  38. package/dist/discovery/workflow-discovery.service.d.ts +36 -0
  39. package/dist/discovery/workflow-discovery.service.js +216 -0
  40. package/dist/discovery/workflow-discovery.service.js.map +1 -0
  41. package/dist/index.d.ts +15 -8
  42. package/dist/index.js +27 -11
  43. package/dist/index.js.map +1 -1
  44. package/dist/interfaces/core.interface.d.ts +112 -0
  45. package/dist/interfaces/{base.interface.js → core.interface.js} +1 -1
  46. package/dist/interfaces/core.interface.js.map +1 -0
  47. package/dist/interfaces/discovery.interface.d.ts +61 -0
  48. package/dist/interfaces/{client.interface.js → discovery.interface.js} +1 -1
  49. package/dist/interfaces/discovery.interface.js.map +1 -0
  50. package/dist/interfaces/index.d.ts +4 -4
  51. package/dist/interfaces/index.js +4 -4
  52. package/dist/interfaces/index.js.map +1 -1
  53. package/dist/interfaces/scheduling.interface.d.ts +17 -0
  54. package/dist/interfaces/{temporal.interface.js → scheduling.interface.js} +1 -1
  55. package/dist/interfaces/scheduling.interface.js.map +1 -0
  56. package/dist/interfaces/worker.interface.d.ts +20 -17
  57. package/dist/interfaces/workflow.interface.d.ts +41 -1
  58. package/dist/temporal.module.d.ts +17 -1
  59. package/dist/temporal.module.js +120 -53
  60. package/dist/temporal.module.js.map +1 -1
  61. package/dist/temporal.service.d.ts +50 -8
  62. package/dist/temporal.service.js +166 -18
  63. package/dist/temporal.service.js.map +1 -1
  64. package/dist/tsconfig.tsbuildinfo +1 -1
  65. package/dist/worker/index.d.ts +1 -1
  66. package/dist/worker/index.js +1 -1
  67. package/dist/worker/index.js.map +1 -1
  68. package/dist/worker/temporal-metadata.accessor.d.ts +21 -6
  69. package/dist/worker/temporal-metadata.accessor.js +153 -22
  70. package/dist/worker/temporal-metadata.accessor.js.map +1 -1
  71. package/dist/worker/temporal-worker.module.d.ts +1 -1
  72. package/dist/worker/temporal-worker.module.js +6 -7
  73. package/dist/worker/temporal-worker.module.js.map +1 -1
  74. package/dist/worker/worker-manager.service.d.ts +24 -7
  75. package/dist/worker/worker-manager.service.js +218 -85
  76. package/dist/worker/worker-manager.service.js.map +1 -1
  77. package/package.json +51 -19
  78. package/dist/decorators/activity-method.decorator.d.ts +0 -2
  79. package/dist/decorators/activity-method.decorator.js +0 -35
  80. package/dist/decorators/activity-method.decorator.js.map +0 -1
  81. package/dist/decorators/activity.decorator.d.ts +0 -2
  82. package/dist/decorators/activity.decorator.js +0 -14
  83. package/dist/decorators/activity.decorator.js.map +0 -1
  84. package/dist/decorators/query-method.decorator.d.ts +0 -1
  85. package/dist/decorators/query-method.decorator.js +0 -17
  86. package/dist/decorators/query-method.decorator.js.map +0 -1
  87. package/dist/decorators/signal-method.decorator.d.ts +0 -1
  88. package/dist/decorators/signal-method.decorator.js +0 -17
  89. package/dist/decorators/signal-method.decorator.js.map +0 -1
  90. package/dist/decorators/workflow-method.decorator.d.ts +0 -2
  91. package/dist/decorators/workflow-method.decorator.js +0 -26
  92. package/dist/decorators/workflow-method.decorator.js.map +0 -1
  93. package/dist/decorators/workflow.decorator.d.ts +0 -2
  94. package/dist/decorators/workflow.decorator.js +0 -16
  95. package/dist/decorators/workflow.decorator.js.map +0 -1
  96. package/dist/interfaces/base.interface.d.ts +0 -13
  97. package/dist/interfaces/base.interface.js.map +0 -1
  98. package/dist/interfaces/client.interface.d.ts +0 -30
  99. package/dist/interfaces/client.interface.js.map +0 -1
  100. package/dist/interfaces/temporal.interface.d.ts +0 -33
  101. package/dist/interfaces/temporal.interface.js.map +0 -1
package/README.md CHANGED
@@ -1,49 +1,60 @@
1
1
  # NestJS Temporal Core
2
2
 
3
- A simplified NestJS integration for [Temporal.io](https://temporal.io/) that provides seamless worker and client support for building reliable distributed applications.
3
+ A comprehensive NestJS integration for [Temporal.io](https://temporal.io/) that provides seamless worker and client support with auto-discovery, declarative scheduling, and enterprise-ready features for building reliable distributed applications.
4
+
5
+ [![npm version](https://badge.fury.io/js/nestjs-temporal-core.svg)](https://badge.fury.io/js/nestjs-temporal-core)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+ [![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](http://www.typescriptlang.org/)
8
+
9
+ ## 📚 Documentation
10
+
11
+ ### Quick Links
12
+ - **[🚀 Getting Started](./docs/getting-started.md)** - Installation, basic setup, and first workflow
13
+ - **[⚙️ Configuration](./docs/configuration.md)** - Complete configuration reference and examples
14
+ - **[📖 API Reference](./docs/api-reference.md)** - Detailed API documentation for all services and decorators
15
+ - **[🍳 Examples & Recipes](./docs/examples.md)** - Practical examples and common patterns
16
+ - **[🏗️ Best Practices](./docs/best-practices.md)** - Production guidelines and optimization tips
17
+ - **[🔄 Migration Guide](./docs/migration.md)** - Upgrading from previous versions
18
+ - **[🔧 Troubleshooting](./docs/troubleshooting.md)** - Common issues and solutions
19
+
20
+ ### Advanced Topics
21
+ - **[🏢 Enterprise Features](./docs/enterprise.md)** - Advanced features for production deployments
22
+ - **[📊 Monitoring & Health](./docs/monitoring.md)** - Health checks, metrics, and observability
23
+ - **[🔐 Security](./docs/security.md)** - TLS, authentication, and security best practices
24
+ - **[🧪 Testing](./docs/testing.md)** - Testing workflows and activities
25
+ - **[🐳 Deployment](./docs/deployment.md)** - Docker, Kubernetes, and cloud deployment guides
4
26
 
5
27
  ## Overview
6
28
 
7
- NestJS Temporal Core makes it easy to integrate Temporal.io with your NestJS applications. Temporal is a durable execution system for reliable microservices and workflow orchestration.
29
+ NestJS Temporal Core makes it easy to integrate Temporal.io with your NestJS applications using familiar decorator patterns. Temporal is a durable execution system for reliable microservices and workflow orchestration.
8
30
 
9
- ## Features
31
+ ## Features
10
32
 
11
33
  - 🚀 **Easy NestJS Integration** - Simple module registration with unified configuration
34
+ - 🎯 **Auto-Discovery** - Automatic discovery of workflow controllers and scheduled workflows
12
35
  - 🔄 **Complete Lifecycle Management** - Automatic worker initialization and graceful shutdown
13
- - 🎯 **Declarative Decorators** - Type-safe `@Activity()`, `@ActivityMethod()`, `@Workflow()`, and more
14
- - 🔌 **Connection Management** - Simplified connection handling with TLS support
36
+ - 📋 **Declarative Decorators** - NestJS-style `@WorkflowController`, `@Cron`, `@Interval`, and more
37
+ - 🕐 **Smart Scheduling** - Built-in cron and interval-based workflow scheduling with management
38
+ - 🔌 **Connection Management** - Simplified connection handling with TLS and Temporal Cloud support
15
39
  - 🔒 **Type Safety** - Clean, strongly typed interfaces for all Temporal concepts
16
- - 📡 **Client Utilities** - Methods for starting, signaling, and querying workflows
17
- - 📊 **Worker Management** - Simple worker lifecycle control and monitoring
18
- - 📅 **Scheduling** - Support for cron and interval-based workflow scheduling
40
+ - 📡 **Enhanced Client** - Methods for starting, signaling, and querying workflows with auto-discovery
41
+ - 📊 **Worker Management** - Advanced worker lifecycle control, monitoring, and health checks
42
+ - 🏭 **Production Ready** - Environment-aware configuration, health monitoring, and graceful degradation
19
43
 
20
- ## Installation
44
+ ## 🚀 Quick Start
45
+
46
+ ### Installation
21
47
 
22
48
  ```bash
23
49
  npm install nestjs-temporal-core @temporalio/client @temporalio/worker @temporalio/workflow
24
50
  ```
25
51
 
26
- ## Quick Start
27
-
28
- ### 1. Enable Shutdown Hooks
29
-
30
- First, make sure to enable shutdown hooks in your `main.ts` file:
31
-
32
- ```typescript
33
- async function bootstrap() {
34
- const app = await NestFactory.create(AppModule);
35
- app.enableShutdownHooks();
36
- await app.listen(3000);
37
- }
38
- bootstrap();
39
- ```
40
-
41
- ### 2. Register the Module
52
+ ### Basic Setup
42
53
 
43
54
  ```typescript
55
+ // app.module.ts
44
56
  import { Module } from '@nestjs/common';
45
57
  import { TemporalModule } from 'nestjs-temporal-core';
46
- import { EmailActivities } from './activities/email.activities';
47
58
 
48
59
  @Module({
49
60
  imports: [
@@ -65,586 +76,141 @@ import { EmailActivities } from './activities/email.activities';
65
76
  export class AppModule {}
66
77
  ```
67
78
 
68
- ### 3. Define Activities
79
+ ### Create a Workflow Controller
69
80
 
70
81
  ```typescript
71
- import { Activity, ActivityMethod } from 'nestjs-temporal-core';
72
-
73
- @Activity()
74
- export class EmailActivities {
75
- @ActivityMethod()
76
- async sendWelcomeEmail(to: string): Promise<boolean> {
77
- // Implementation
78
- console.log(`Sending welcome email to ${to}`);
79
- return true;
80
- }
82
+ import { WorkflowController, WorkflowMethod, Cron, Signal, Query } from 'nestjs-temporal-core';
81
83
 
82
- @ActivityMethod('sendPromoEmail')
83
- async sendPromotion(to: string, promoCode: string): Promise<boolean> {
84
- // Implementation
85
- console.log(`Sending promo ${promoCode} to ${to}`);
86
- return true;
84
+ @WorkflowController({ taskQueue: 'orders' })
85
+ export class OrderWorkflowController {
86
+ private status = 'pending';
87
+
88
+ @WorkflowMethod()
89
+ async processOrder(orderId: string, customerId: string): Promise<string> {
90
+ this.status = 'processing';
91
+ // Workflow logic here
92
+ this.status = 'completed';
93
+ return this.status;
87
94
  }
88
- }
89
- ```
90
95
 
91
- ### 4. Define Workflows
92
-
93
- Create a workflow file in your workflows directory:
94
-
95
- ```typescript
96
- // workflows/email-workflow.ts
97
- import { proxyActivities } from '@temporalio/workflow';
98
-
99
- // Activities interface
100
- interface EmailActivities {
101
- sendWelcomeEmail(to: string): Promise<boolean>;
102
- sendPromoEmail(to: string, promoCode: string): Promise<boolean>;
103
- }
104
-
105
- const activities = proxyActivities<EmailActivities>({
106
- startToCloseTimeout: '30s',
107
- });
108
-
109
- export async function sendWelcomeWorkflow(email: string): Promise<boolean> {
110
- return await activities.sendWelcomeEmail(email);
111
- }
112
-
113
- export async function sendPromoWorkflow(email: string, promoCode: string): Promise<boolean> {
114
- return await activities.sendPromoEmail(email, promoCode);
115
- }
116
- ```
117
-
118
- ### 5. Use the Temporal Service
119
-
120
- ```typescript
121
- import { Injectable } from '@nestjs/common';
122
- import { TemporalService } from 'nestjs-temporal-core';
123
-
124
- @Injectable()
125
- export class EmailService {
126
- constructor(private readonly temporalService: TemporalService) {}
127
-
128
- async sendWelcomeEmail(email: string): Promise<string> {
129
- // Use the simplified API to start a workflow
130
- const { workflowId } = await this.temporalService.startWorkflow(
131
- 'sendWelcomeWorkflow',
132
- [email],
133
- 'my-task-queue',
134
- {
135
- workflowId: `welcome-${email}-${Date.now()}`,
136
- },
137
- );
138
-
139
- return workflowId;
96
+ @Cron('0 8 * * *', {
97
+ scheduleId: 'daily-order-report',
98
+ description: 'Generate daily order report'
99
+ })
100
+ @WorkflowMethod()
101
+ async generateDailyReport(): Promise<void> {
102
+ console.log('Generating daily order report...');
140
103
  }
141
104
 
142
- async sendPromoEmail(email: string, promoCode: string): Promise<string> {
143
- // Use the client service directly for more options
144
- const { workflowId } = await this.temporalService
145
- .getClient()
146
- .startWorkflow('sendPromoWorkflow', [email, promoCode], {
147
- taskQueue: 'my-task-queue',
148
- workflowId: `promo-${email}-${Date.now()}`,
149
- retry: {
150
- maximumAttempts: 3,
151
- },
152
- });
153
-
154
- return workflowId;
105
+ @Signal('addItem')
106
+ async addItemToOrder(item: any): Promise<void> {
107
+ console.log('Item added to order:', item);
155
108
  }
156
- }
157
- ```
158
-
159
- ## Advanced Features
160
109
 
161
- ### Using Signals and Queries
162
-
163
- ```typescript
164
- import { Injectable } from '@nestjs/common';
165
- import { TemporalService } from 'nestjs-temporal-core';
166
-
167
- @Injectable()
168
- export class OrderService {
169
- constructor(private readonly temporalService: TemporalService) {}
170
-
171
- async addItemToOrder(orderId: string, item: string): Promise<void> {
172
- // Signal a running workflow
173
- await this.temporalService.getClient().signalWorkflow(orderId, 'addItem', [item]);
174
- }
175
-
176
- async getOrderStatus(orderId: string): Promise<string> {
177
- // Query a running workflow
178
- return await this.temporalService.getClient().queryWorkflow(orderId, 'getStatus');
110
+ @Query('getStatus')
111
+ getOrderStatus(): string {
112
+ return this.status;
179
113
  }
180
114
  }
181
115
  ```
182
116
 
183
- ### Schedule Management
117
+ ### Use the Service
184
118
 
185
119
  ```typescript
186
120
  import { Injectable } from '@nestjs/common';
187
121
  import { TemporalService } from 'nestjs-temporal-core';
188
122
 
189
123
  @Injectable()
190
- export class ReportingService {
124
+ export class OrderService {
191
125
  constructor(private readonly temporalService: TemporalService) {}
192
126
 
193
- async scheduleDailyReport(): Promise<string> {
194
- const handle = await this.temporalService.getScheduleService().createCronWorkflow(
195
- 'daily-report',
196
- 'generateReportWorkflow',
197
- '0 0 * * *', // Daily at midnight
198
- 'reports-queue',
199
- ['daily-summary'],
127
+ async processOrder(orderId: string, customerId: string): Promise<string> {
128
+ const { workflowId } = await this.temporalService.startWorkflow(
129
+ 'processOrder',
130
+ [orderId, customerId],
131
+ { workflowId: `order-${orderId}` }
200
132
  );
201
133
 
202
- return handle.scheduleId;
203
- }
204
-
205
- async pauseReporting(): Promise<void> {
206
- await this.temporalService
207
- .getScheduleService()
208
- .pauseSchedule('daily-report', 'Paused for maintenance');
209
- }
210
-
211
- async resumeReporting(): Promise<void> {
212
- await this.temporalService.getScheduleService().resumeSchedule('daily-report');
213
- }
214
- }
215
- ```
216
-
217
- ## Configuration Options
218
-
219
- ### Async Configuration
220
-
221
- ```typescript
222
- import { Module } from '@nestjs/common';
223
- import { ConfigModule, ConfigService } from '@nestjs/config';
224
- import { TemporalModule } from 'nestjs-temporal-core';
225
- import { EmailActivities } from './activities/email.activities';
226
-
227
- @Module({
228
- imports: [
229
- ConfigModule.forRoot(),
230
- TemporalModule.registerAsync({
231
- imports: [ConfigModule],
232
- inject: [ConfigService],
233
- useFactory: (configService: ConfigService) => ({
234
- connection: {
235
- address: configService.get('TEMPORAL_ADDRESS'),
236
- namespace: configService.get('TEMPORAL_NAMESPACE'),
237
- apiKey: configService.get('TEMPORAL_API_KEY'),
238
- },
239
- taskQueue: configService.get('TEMPORAL_TASK_QUEUE'),
240
- worker: {
241
- workflowsPath: './dist/workflows',
242
- activityClasses: [EmailActivities],
243
- },
244
-
245
- isGlobal: true,
246
- }),
247
- }),
248
- ],
249
- })
250
- export class AppModule {}
251
- ```
252
-
253
- ### Secure Connection with TLS
254
-
255
- ```typescript
256
- TemporalModule.register({
257
- connection: {
258
- address: 'temporal.example.com:7233',
259
- namespace: 'production',
260
- tls: {
261
- // Simple boolean for default TLS
262
- // tls: true,
263
-
264
- // Or detailed configuration
265
- serverName: 'temporal.example.com',
266
- clientCertPair: {
267
- crt: fs.readFileSync('./certs/client.crt'),
268
- key: fs.readFileSync('./certs/client.key'),
269
- ca: fs.readFileSync('./certs/ca.crt'),
270
- },
271
- },
272
- // For Temporal Cloud
273
- apiKey: process.env.TEMPORAL_API_KEY,
274
- },
275
- // ...other options
276
- });
277
- ```
278
-
279
- ```
280
-
281
- ## API Reference
282
-
283
- ### Core Modules
284
-
285
- - `TemporalModule` - Unified module for both client and worker functionality
286
- - `TemporalClientModule` - Client-only module for workflow operations
287
- - `TemporalWorkerModule` - Worker-only module for running activities
288
-
289
- ### Decorators
290
-
291
- - `@Activity(options?)` - Marks a class as a Temporal activity
292
- - `@ActivityMethod(options?)` - Marks a method as an activity implementation
293
- - `@Workflow(options)` - Marks a class as a Temporal workflow
294
- - `@WorkflowMethod(options?)` - Marks the primary workflow execution method
295
- - `@SignalMethod(name?)` - Marks a method as a signal handler
296
- - `@QueryMethod(name?)` - Marks a method as a query handler
297
-
298
- ### Services
299
-
300
- #### TemporalService
301
-
302
- - `getClient()` - Get the client service
303
- - `getScheduleService()` - Get the schedule service
304
- - `getWorkerManager()` - Get the worker manager (if available)
305
- - `startWorkflow()` - Simplified method to start a workflow
306
- - `hasWorker()` - Check if worker functionality is available
307
-
308
-
309
- #### TemporalClientService
310
-
311
- - `startWorkflow()` - Start a new workflow execution
312
- - `signalWorkflow()` - Send a signal to a running workflow
313
- - `queryWorkflow()` - Query a running workflow
314
- - `terminateWorkflow()` - Terminate a running workflow
315
- - `cancelWorkflow()` - Request cancellation of a workflow
316
- - `getWorkflowHandle()` - Get a handle to manage a workflow
317
- - `describeWorkflow()` - Get workflow execution details
318
- - `listWorkflows()` - List workflows matching a query
319
-
320
- #### TemporalScheduleService
321
-
322
- - `createCronWorkflow()` - Create a workflow scheduled by cron expression
323
- - `createIntervalWorkflow()` - Create a workflow scheduled by time interval
324
- - `pauseSchedule()` - Pause a schedule
325
- - `resumeSchedule()` - Resume a paused schedule
326
- - `deleteSchedule()` - Delete a schedule
327
- - `triggerNow()` - Trigger an immediate execution
328
- - `listSchedules()` - List all schedules
329
-
330
- #### WorkerManager
331
-
332
- - `startWorker()` - Manually start the worker
333
- - `shutdown()` - Gracefully shutdown the worker
334
- - `getWorker()` - Get the underlying worker instance
335
-
336
- ## Project Structure
337
-
338
- When integrating Temporal with your NestJS application, organizing your code properly helps maintain separation of concerns and follows NestJS conventions. Here's a recommended project structure:
339
-
340
- ```
341
-
342
- src/
343
- ├── temporal/
344
- │ ├── activities/
345
- │ │ ├── email.activities.ts
346
- │ │ ├── payment.activities.ts
347
- │ │ └── index.ts
348
- │ ├── workflows/
349
- │ │ ├── email-workflows.ts
350
- │ │ ├── payment-workflows.ts
351
- │ │ └── index.ts
352
- │ ├── interfaces/
353
- │ │ ├── email.interfaces.ts
354
- │ │ └── payment.interfaces.ts
355
- │ └── temporal.module.ts
356
- ├── modules/
357
- │ ├── email/
358
- │ │ ├── email.service.ts
359
- │ │ ├── email.controller.ts
360
- │ │ └── email.module.ts
361
- │ └── payment/
362
- │ ├── payment.service.ts
363
- │ ├── payment.controller.ts
364
- │ └── payment.module.ts
365
- └── app.module.ts
366
-
367
- ````
368
-
369
- ### Key Files and Their Purpose
370
-
371
- 1. **Activities (src/temporal/activities/)**:
372
- - Contains activity classes decorated with `@Activity()`
373
- - Each activity class should group related functionality
374
-
375
- 2. **Workflows (src/temporal/workflows/)**:
376
- - Contains workflow definitions that orchestrate activities
377
- - Workflows should be in separate files based on domain
378
-
379
- 3. **Interfaces (src/temporal/interfaces/)**:
380
- - TypeScript interfaces that define activity and workflow parameters/returns
381
- - Helps maintain type safety between activities and workflows
382
-
383
- 4. **Temporal Module (src/temporal/temporal.module.ts)**:
384
- - Centralizes Temporal configuration
385
- - Imports and registers all activities
386
-
387
- 5. **Business Services (src/modules/*/)**:
388
- - Inject the TemporalService
389
- - Use it to start workflows and interact with Temporal
390
-
391
- ## Integration Examples
392
-
393
- ### Activity Definition
394
-
395
- ```typescript
396
- // src/temporal/activities/email.activities.ts
397
- import { Activity, ActivityMethod } from 'nestjs-temporal-core';
398
- import { Injectable } from '@nestjs/common';
399
- import { EmailService } from '../../modules/email/email.service';
400
-
401
- @Injectable()
402
- @Activity()
403
- export class EmailActivities {
404
- constructor(private readonly emailService: EmailService) {}
405
-
406
- @ActivityMethod()
407
- async sendWelcomeEmail(to: string, name: string): Promise<boolean> {
408
- await this.emailService.sendEmail({
409
- to,
410
- subject: 'Welcome!',
411
- body: `Hello ${name}, welcome to our platform!`,
412
- });
413
- return true;
414
- }
415
-
416
- @ActivityMethod()
417
- async sendPasswordReset(to: string, resetToken: string): Promise<boolean> {
418
- await this.emailService.sendEmail({
419
- to,
420
- subject: 'Password Reset',
421
- body: `Please use this token to reset your password: ${resetToken}`,
422
- });
423
- return true;
424
- }
425
- }
426
- ````
427
-
428
- ```typescript
429
- // src/temporal/activities/index.ts
430
- export * from './email.activities';
431
- export * from './payment.activities';
432
- // Export all other activity classes
433
- ```
434
-
435
- ### Workflow Definition
436
-
437
- ```typescript
438
- // src/temporal/workflows/email-workflows.ts
439
- import { proxyActivities } from '@temporalio/workflow';
440
-
441
- // Define the interface of activities this workflow will use
442
- export interface EmailActivities {
443
- sendWelcomeEmail(to: string, name: string): Promise<boolean>;
444
- sendPasswordReset(to: string, resetToken: string): Promise<boolean>;
445
- }
446
-
447
- // Create a proxy to the activities
448
- const activities = proxyActivities<EmailActivities>({
449
- startToCloseTimeout: '30 seconds',
450
- });
451
-
452
- // Welcome workflow with retry logic
453
- export async function welcomeUserWorkflow(email: string, name: string): Promise<boolean> {
454
- let attempts = 0;
455
- const maxAttempts = 3;
456
-
457
- while (attempts < maxAttempts) {
458
- try {
459
- return await activities.sendWelcomeEmail(email, name);
460
- } catch (error) {
461
- attempts++;
462
- if (attempts >= maxAttempts) {
463
- throw error;
464
- }
465
- // Wait before retrying
466
- await new Promise((resolve) => setTimeout(resolve, 5000));
467
- }
134
+ return workflowId;
468
135
  }
469
-
470
- return false;
471
- }
472
-
473
- // Password reset workflow
474
- export async function passwordResetWorkflow(email: string, resetToken: string): Promise<boolean> {
475
- return await activities.sendPasswordReset(email, resetToken);
476
136
  }
477
137
  ```
478
138
 
479
- ### Scheduled Workflow Example
139
+ ## 📖 Core Concepts
480
140
 
481
- ```typescript
482
- // src/temporal/workflows/scheduled-workflows.ts
483
- import { proxyActivities } from '@temporalio/workflow';
141
+ ### Workflow Controllers
142
+ New NestJS-style controllers for defining workflows with auto-discovery and declarative scheduling.
484
143
 
485
- interface ReportActivities {
486
- generateDailyReport(): Promise<string>;
487
- emailReportToAdmins(reportUrl: string): Promise<boolean>;
488
- }
144
+ ### Activities
145
+ Reusable business logic components that can be called from workflows.
489
146
 
490
- const activities = proxyActivities<ReportActivities>({
491
- startToCloseTimeout: '10 minutes',
492
- });
147
+ ### Scheduling
148
+ Built-in support for cron and interval-based workflow scheduling using decorators.
493
149
 
494
- // This workflow will be scheduled to run daily
495
- export async function dailyReportWorkflow(): Promise<void> {
496
- const reportUrl = await activities.generateDailyReport();
497
- await activities.emailReportToAdmins(reportUrl);
498
- }
499
- ```
150
+ ### Auto-Discovery
151
+ Automatic detection and registration of workflow controllers and scheduled workflows.
500
152
 
501
- ### Setting Up the Temporal Module
502
-
503
- ```typescript
504
- // src/temporal/temporal.module.ts
505
- import { Module } from '@nestjs/common';
506
- import { TemporalModule } from 'nestjs-temporal-core';
507
- import { ConfigModule, ConfigService } from '@nestjs/config';
508
- import * as path from 'path';
509
- import { EmailActivities, PaymentActivities } from './activities';
510
- import { EmailModule } from '../modules/email/email.module';
511
- import { PaymentModule } from '../modules/payment/payment.module';
153
+ ## 🏗️ Architecture
512
154
 
513
- @Module({
514
- imports: [
515
- EmailModule,
516
- PaymentModule,
517
- TemporalModule.registerAsync({
518
- imports: [ConfigModule],
519
- inject: [ConfigService],
520
- useFactory: (configService: ConfigService) => ({
521
- connection: {
522
- address: configService.get('TEMPORAL_ADDRESS', 'localhost:7233'),
523
- namespace: configService.get('TEMPORAL_NAMESPACE', 'default'),
524
- },
525
- taskQueue: configService.get('TEMPORAL_TASK_QUEUE', 'my-app-queue'),
526
- worker: {
527
- workflowsPath: path.resolve(__dirname, 'workflows'),
528
- activityClasses: [EmailActivities, PaymentActivities],
529
- autoStart: true,
530
- },
531
- isGlobal: true,
532
- }),
533
- }),
534
- ],
535
- providers: [EmailActivities, PaymentActivities],
536
- exports: [TemporalModule],
537
- })
538
- export class TemporalAppModule {}
539
155
  ```
540
-
541
- ### Using Temporal in Business Services
542
-
543
- ```typescript
544
- // src/modules/email/email.service.ts
545
- import { Injectable } from '@nestjs/common';
546
- import { TemporalService } from 'nestjs-temporal-core';
547
-
548
- @Injectable()
549
- export class EmailService {
550
- constructor(private readonly temporalService: TemporalService) {}
551
-
552
- // Your actual email sending functionality
553
- async sendEmail(options: { to: string; subject: string; body: string }): Promise<void> {
554
- // Implementation...
555
- }
556
-
557
- // Triggering a Temporal workflow
558
- async sendWelcomeEmail(email: string, name: string): Promise<string> {
559
- const { workflowId } = await this.temporalService.startWorkflow(
560
- 'welcomeUserWorkflow',
561
- [email, name],
562
- 'my-app-queue',
563
- { workflowId: `welcome-${email}-${Date.now()}` },
564
- );
565
-
566
- return workflowId;
567
- }
568
- }
156
+ ┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
157
+ │ NestJS App │ │ Temporal Server │ │ Worker Process
158
+ │ │ │ │ │ │
159
+ │ ┌─────────────┐ │ │ ┌──────────────┐ │ │ ┌─────────────┐ │
160
+ │ Controllers │ │───▶│ │ Workflows │ │───▶│ │ Activities │ │
161
+ │ Services │ │ │ │ Schedules │ │ │ │ Workers │ │
162
+ └─────────────┘ │ │ └──────────────┘ │ │ └─────────────┘ │
163
+ └─────────────────┘ └──────────────────┘ └─────────────────┘
569
164
  ```
570
165
 
571
- ### Setting Up Scheduled Workflows
572
-
573
- ```typescript
574
- // src/modules/reports/report.service.ts
575
- import { Injectable, OnModuleInit } from '@nestjs/common';
576
- import { TemporalService } from 'nestjs-temporal-core';
577
-
578
- @Injectable()
579
- export class ReportService implements OnModuleInit {
580
- constructor(private readonly temporalService: TemporalService) {}
166
+ ## 🎯 Use Cases
581
167
 
582
- async onModuleInit() {
583
- // Set up scheduled workflows when the module initializes
584
- await this.setupDailyReport();
585
- }
586
-
587
- private async setupDailyReport() {
588
- try {
589
- // Check if the schedule already exists
590
- const schedules = await this.temporalService.getScheduleService().listSchedules();
591
-
592
- if (!schedules.some((s) => s.scheduleId === 'daily-report')) {
593
- // Create a new schedule
594
- await this.temporalService.getScheduleService().createCronWorkflow(
595
- 'daily-report',
596
- 'dailyReportWorkflow',
597
- '0 8 * * *', // Run every day at 8 AM
598
- 'my-app-queue',
599
- [], // No arguments needed for this workflow
600
- 'Daily business report generation',
601
- );
602
-
603
- console.log('Daily report schedule created');
604
- }
605
- } catch (error) {
606
- console.error('Failed to set up daily report schedule:', error);
607
- }
608
- }
609
- }
610
- ```
168
+ - **Order Processing** - Reliable order fulfillment with compensation
169
+ - **Payment Processing** - Multi-step payment flows with retries
170
+ - **Data Pipelines** - Long-running data processing workflows
171
+ - **Scheduled Jobs** - Cron-based and interval-based background tasks
172
+ - **Saga Patterns** - Distributed transaction management
173
+ - **Human Tasks** - Workflows requiring human intervention
174
+ - **Microservice Orchestration** - Coordinating multiple services
611
175
 
612
- ## Best Practices
176
+ ## 🌟 What's New in v3.0
613
177
 
614
- 1. **Activity Design**
178
+ - **🎮 Workflow Controllers** - NestJS-style workflow definition
179
+ - **📅 Declarative Scheduling** - `@Cron` and `@Interval` decorators
180
+ - **🔍 Auto-Discovery** - Automatic workflow and schedule detection
181
+ - **📊 Enhanced Monitoring** - Built-in health checks and metrics
182
+ - **🏭 Production Features** - Worker presets, graceful shutdown, error handling
183
+ - **🔧 Better Developer Experience** - Improved APIs and TypeScript support
615
184
 
616
- - Keep activities focused on single responsibilities
617
- - Set appropriate timeouts for expected durations
618
- - Use dependency injection within activity classes
185
+ ## 📦 Packages
619
186
 
620
- 2. **Workflow Design**
187
+ | Package | Version | Description |
188
+ | ---------------------- | ------------------------------------------------------------------------------------------------------------------- | ------------------------ |
189
+ | `nestjs-temporal-core` | [![npm](https://img.shields.io/npm/v/nestjs-temporal-core.svg)](https://www.npmjs.com/package/nestjs-temporal-core) | Main integration package |
190
+ | `@temporalio/client` | [![npm](https://img.shields.io/npm/v/@temporalio/client.svg)](https://www.npmjs.com/package/@temporalio/client) | Temporal client library |
191
+ | `@temporalio/worker` | [![npm](https://img.shields.io/npm/v/@temporalio/worker.svg)](https://www.npmjs.com/package/@temporalio/worker) | Temporal worker library |
192
+ | `@temporalio/workflow` | [![npm](https://img.shields.io/npm/v/@temporalio/workflow.svg)](https://www.npmjs.com/package/@temporalio/workflow) | Workflow runtime library |
621
193
 
622
- - Make workflows deterministic
623
- - Use signals for external events
624
- - Use queries for retrieving workflow state
625
- - Separate workflows by domain/function
194
+ ## 🤝 Community
626
195
 
627
- 3. **Configuration**
196
+ - **GitHub Discussions** - Ask questions and share ideas
197
+ - **Issues** - Report bugs and request features
198
+ - **Pull Requests** - Contribute to the project
628
199
 
629
- - Use meaningful workflow IDs for tracking
630
- - Configure appropriate timeouts for activities and workflows
631
- - Implement proper error handling
200
+ ## 📄 License
632
201
 
633
- 4. **Lifecycle Management**
202
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
634
203
 
635
- - Enable NestJS shutdown hooks
636
- - Configure proper worker shutdown grace periods
637
- - Consider using OnModuleInit to set up schedules
204
+ ## 👨‍💻 Author
638
205
 
639
- 5. **Security**
640
- - Implement proper TLS security for production environments
641
- - Use namespaces to isolate different environments
642
- - Use API keys for Temporal Cloud authentication
206
+ **Harsh M** - [GitHub](https://github.com/harsh-simform)
643
207
 
644
- ## License
208
+ ## 🙏 Acknowledgments
645
209
 
646
- MIT
210
+ - [Temporal.io](https://temporal.io/) - For the amazing workflow engine
211
+ - [NestJS](https://nestjs.com/) - For the incredible framework
212
+ - [TypeScript](https://www.typescriptlang.org/) - For making JavaScript enjoyable
647
213
 
648
- ## Author
214
+ ---
649
215
 
650
- Harsh M
216
+ **[📚 Continue to Getting Started →](./docs/getting-started.md)**