nestjs-temporal-core 3.0.1 → 3.0.4
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 +274 -139
- package/dist/client/temporal-client.module.d.ts +9 -3
- package/dist/client/temporal-client.module.js +43 -13
- package/dist/client/temporal-client.module.js.map +1 -1
- package/dist/client/temporal-client.service.d.ts +10 -3
- package/dist/client/temporal-client.service.js +15 -6
- package/dist/client/temporal-client.service.js.map +1 -1
- package/dist/client/temporal-schedule.service.d.ts +21 -5
- package/dist/client/temporal-schedule.service.js +42 -10
- package/dist/client/temporal-schedule.service.js.map +1 -1
- package/dist/constants.d.ts +47 -70
- package/dist/constants.js +51 -74
- package/dist/constants.js.map +1 -1
- package/dist/decorators/activity.decorator.d.ts +3 -0
- package/dist/decorators/activity.decorator.js +39 -0
- package/dist/decorators/activity.decorator.js.map +1 -0
- package/dist/decorators/index.d.ts +4 -5
- package/dist/decorators/index.js +17 -19
- package/dist/decorators/index.js.map +1 -1
- package/dist/decorators/parameter.decorator.d.ts +7 -0
- package/dist/decorators/parameter.decorator.js +69 -0
- package/dist/decorators/parameter.decorator.js.map +1 -0
- package/dist/decorators/{scheduling.decorators.d.ts → scheduling.decorator.d.ts} +1 -1
- package/dist/decorators/{scheduling.decorators.js → scheduling.decorator.js} +24 -1
- package/dist/decorators/scheduling.decorator.js.map +1 -0
- package/dist/decorators/workflow.decorator.d.ts +3 -0
- package/dist/decorators/workflow.decorator.js +58 -0
- package/dist/decorators/workflow.decorator.js.map +1 -0
- package/dist/discovery/index.d.ts +2 -2
- package/dist/discovery/index.js +2 -2
- package/dist/discovery/index.js.map +1 -1
- package/dist/discovery/{workflow-discovery.service.d.ts → temporal-discovery.service.d.ts} +21 -18
- package/dist/discovery/temporal-discovery.service.js +190 -0
- package/dist/discovery/temporal-discovery.service.js.map +1 -0
- package/dist/discovery/{schedule-manager.service.d.ts → temporal-schedule-manager.service.d.ts} +20 -15
- package/dist/discovery/{schedule-manager.service.js → temporal-schedule-manager.service.js} +96 -76
- package/dist/discovery/temporal-schedule-manager.service.js.map +1 -0
- package/dist/index.d.ts +6 -11
- package/dist/index.js +16 -16
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +193 -0
- package/dist/interfaces.js +9 -0
- package/dist/interfaces.js.map +1 -0
- package/dist/temporal.module.d.ts +2 -1
- package/dist/temporal.module.js +84 -49
- package/dist/temporal.module.js.map +1 -1
- package/dist/temporal.service.d.ts +34 -26
- package/dist/temporal.service.js +76 -47
- package/dist/temporal.service.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/worker/index.d.ts +1 -1
- package/dist/worker/index.js +1 -1
- package/dist/worker/index.js.map +1 -1
- package/dist/worker/temporal-metadata.accessor.d.ts +13 -5
- package/dist/worker/temporal-metadata.accessor.js +38 -26
- package/dist/worker/temporal-metadata.accessor.js.map +1 -1
- package/dist/worker/{worker-manager.service.d.ts → temporal-worker-manager.service.d.ts} +13 -4
- package/dist/worker/{worker-manager.service.js → temporal-worker-manager.service.js} +58 -22
- package/dist/worker/temporal-worker-manager.service.js.map +1 -0
- package/dist/worker/temporal-worker.module.d.ts +14 -4
- package/dist/worker/temporal-worker.module.js +81 -15
- package/dist/worker/temporal-worker.module.js.map +1 -1
- package/package.json +12 -6
- package/dist/decorators/communication.decorators.d.ts +0 -5
- package/dist/decorators/communication.decorators.js +0 -66
- package/dist/decorators/communication.decorators.js.map +0 -1
- package/dist/decorators/core.decorators.d.ts +0 -6
- package/dist/decorators/core.decorators.js +0 -87
- package/dist/decorators/core.decorators.js.map +0 -1
- package/dist/decorators/parameter.decorators.d.ts +0 -2
- package/dist/decorators/parameter.decorators.js +0 -29
- package/dist/decorators/parameter.decorators.js.map +0 -1
- package/dist/decorators/scheduling.decorators.js.map +0 -1
- package/dist/decorators/workflow-starter.decorator.d.ts +0 -2
- package/dist/decorators/workflow-starter.decorator.js +0 -14
- package/dist/decorators/workflow-starter.decorator.js.map +0 -1
- package/dist/discovery/schedule-manager.service.js.map +0 -1
- package/dist/discovery/workflow-discovery.service.js +0 -216
- package/dist/discovery/workflow-discovery.service.js.map +0 -1
- package/dist/interfaces/activity.interface.d.ts +0 -8
- package/dist/interfaces/activity.interface.js +0 -3
- package/dist/interfaces/activity.interface.js.map +0 -1
- package/dist/interfaces/core.interface.d.ts +0 -112
- package/dist/interfaces/core.interface.js +0 -3
- package/dist/interfaces/core.interface.js.map +0 -1
- package/dist/interfaces/discovery.interface.d.ts +0 -61
- package/dist/interfaces/discovery.interface.js +0 -3
- package/dist/interfaces/discovery.interface.js.map +0 -1
- package/dist/interfaces/index.d.ts +0 -9
- package/dist/interfaces/index.js +0 -29
- package/dist/interfaces/index.js.map +0 -1
- package/dist/interfaces/scheduling.interface.d.ts +0 -17
- package/dist/interfaces/scheduling.interface.js +0 -3
- package/dist/interfaces/scheduling.interface.js.map +0 -1
- package/dist/interfaces/worker.interface.d.ts +0 -23
- package/dist/interfaces/worker.interface.js +0 -3
- package/dist/interfaces/worker.interface.js.map +0 -1
- package/dist/interfaces/workflow.interface.d.ts +0 -55
- package/dist/interfaces/workflow.interface.js +0 -3
- package/dist/interfaces/workflow.interface.js.map +0 -1
- package/dist/worker/worker-manager.service.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,206 +1,341 @@
|
|
|
1
1
|
# NestJS Temporal Core
|
|
2
2
|
|
|
3
|
-
A comprehensive NestJS integration for [Temporal.io](https://temporal.io/) that provides seamless
|
|
3
|
+
A comprehensive NestJS integration for [Temporal.io](https://temporal.io/) that provides seamless workflow orchestration with auto-discovery, declarative scheduling, and production-ready features.
|
|
4
4
|
|
|
5
5
|
[](https://badge.fury.io/js/nestjs-temporal-core)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
7
|
[](http://www.typescriptlang.org/)
|
|
8
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
|
-
|
|
17
9
|
## Overview
|
|
18
10
|
|
|
19
|
-
NestJS Temporal Core
|
|
11
|
+
NestJS Temporal Core brings Temporal's durable execution to NestJS with familiar decorator patterns and automatic discovery. Build reliable distributed systems with activities and scheduled tasks using native NestJS conventions.
|
|
20
12
|
|
|
21
|
-
##
|
|
13
|
+
## 💡 Example Repository
|
|
22
14
|
|
|
23
|
-
|
|
24
|
-
- 🎯 **Auto-Discovery** - Automatic discovery of workflow controllers and scheduled workflows
|
|
25
|
-
- 🔄 **Complete Lifecycle Management** - Automatic worker initialization and graceful shutdown
|
|
26
|
-
- 📋 **Declarative Decorators** - NestJS-style `@WorkflowController`, `@Cron`, `@Interval`, and more
|
|
27
|
-
- 🕐 **Smart Scheduling** - Built-in cron and interval-based workflow scheduling with management
|
|
28
|
-
- 🔌 **Connection Management** - Simplified connection handling with TLS and Temporal Cloud support
|
|
29
|
-
- 🔒 **Type Safety** - Clean, strongly typed interfaces for all Temporal concepts
|
|
30
|
-
- 📡 **Enhanced Client** - Methods for starting, signaling, and querying workflows with auto-discovery
|
|
31
|
-
- 📊 **Worker Management** - Advanced worker lifecycle control, monitoring, and health checks
|
|
32
|
-
- 🏭 **Production Ready** - Environment-aware configuration, health monitoring, and graceful degradation
|
|
15
|
+
🔗 **[Complete Example Project](https://github.com/harsh-simform/nestjs-temporal-core-example)** - Check out our full working example repository to see NestJS Temporal Core in action with real-world use cases, configuration examples, and best practices.
|
|
33
16
|
|
|
34
|
-
## 🚀
|
|
17
|
+
## 🚀 Key Features
|
|
18
|
+
|
|
19
|
+
- **🎯 NestJS-Native** - Familiar patterns: `@Activity`, `@Cron`, `@Interval`
|
|
20
|
+
- **🔍 Auto-Discovery** - Automatically finds and registers activities and schedules
|
|
21
|
+
- **📅 Declarative Scheduling** - Built-in cron and interval scheduling that just works
|
|
22
|
+
- **🔄 Unified Service** - Single `TemporalService` for all operations
|
|
23
|
+
- **⚙️ Flexible Setup** - Client-only, worker-only, or unified deployments
|
|
24
|
+
- **🏥 Health Monitoring** - Comprehensive status monitoring and health checks
|
|
25
|
+
- **🔧 Production Ready** - TLS, connection management, graceful shutdowns
|
|
26
|
+
- **📊 Complete Integration** - Full-featured module architecture
|
|
35
27
|
|
|
36
|
-
|
|
28
|
+
## 📦 Installation
|
|
37
29
|
|
|
38
30
|
```bash
|
|
39
31
|
npm install nestjs-temporal-core @temporalio/client @temporalio/worker @temporalio/workflow
|
|
40
32
|
```
|
|
41
33
|
|
|
42
|
-
|
|
34
|
+
## 🚀 Quick Start
|
|
35
|
+
|
|
36
|
+
### 1. Module Setup
|
|
43
37
|
|
|
44
38
|
```typescript
|
|
45
39
|
// app.module.ts
|
|
46
40
|
import { Module } from '@nestjs/common';
|
|
47
41
|
import { TemporalModule } from 'nestjs-temporal-core';
|
|
42
|
+
import { EmailActivities } from './activities/email.activities';
|
|
48
43
|
|
|
49
44
|
@Module({
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
],
|
|
45
|
+
imports: [
|
|
46
|
+
TemporalModule.register({
|
|
47
|
+
connection: {
|
|
48
|
+
address: 'localhost:7233',
|
|
49
|
+
namespace: 'default',
|
|
50
|
+
},
|
|
51
|
+
taskQueue: 'my-app',
|
|
52
|
+
worker: {
|
|
53
|
+
workflowsPath: './dist/workflows',
|
|
54
|
+
activityClasses: [EmailActivities], // Auto-discovered
|
|
55
|
+
},
|
|
56
|
+
}),
|
|
57
|
+
],
|
|
58
|
+
providers: [EmailActivities],
|
|
65
59
|
})
|
|
66
60
|
export class AppModule {}
|
|
67
61
|
```
|
|
68
62
|
|
|
69
|
-
### Create
|
|
63
|
+
### 2. Create Activities
|
|
70
64
|
|
|
71
65
|
```typescript
|
|
72
|
-
|
|
66
|
+
// activities/email.activities.ts
|
|
67
|
+
import { Injectable } from '@nestjs/common';
|
|
68
|
+
import { Activity, ActivityMethod } from 'nestjs-temporal-core';
|
|
73
69
|
|
|
74
|
-
@
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
})
|
|
90
|
-
@WorkflowMethod()
|
|
91
|
-
async generateDailyReport(): Promise<void> {
|
|
92
|
-
console.log('Generating daily order report...');
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
@Signal('addItem')
|
|
96
|
-
async addItemToOrder(item: any): Promise<void> {
|
|
97
|
-
console.log('Item added to order:', item);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
@Query('getStatus')
|
|
101
|
-
getOrderStatus(): string {
|
|
102
|
-
return this.status;
|
|
103
|
-
}
|
|
70
|
+
@Injectable()
|
|
71
|
+
@Activity()
|
|
72
|
+
export class EmailActivities {
|
|
73
|
+
@ActivityMethod()
|
|
74
|
+
async sendWelcomeEmail(email: string, name: string): Promise<boolean> {
|
|
75
|
+
console.log(`Sending welcome email to ${email}`);
|
|
76
|
+
// Your email logic here
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
@ActivityMethod()
|
|
81
|
+
async sendNotification(email: string, message: string): Promise<void> {
|
|
82
|
+
console.log(`Notification to ${email}: ${message}`);
|
|
83
|
+
// Your notification logic here
|
|
84
|
+
}
|
|
104
85
|
}
|
|
105
86
|
```
|
|
106
87
|
|
|
107
|
-
###
|
|
88
|
+
### 3. Create Scheduled Workflows
|
|
108
89
|
|
|
109
90
|
```typescript
|
|
91
|
+
// services/scheduled.service.ts
|
|
110
92
|
import { Injectable } from '@nestjs/common';
|
|
111
|
-
import {
|
|
93
|
+
import { Cron, Interval } from 'nestjs-temporal-core';
|
|
112
94
|
|
|
113
95
|
@Injectable()
|
|
114
|
-
export class
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
96
|
+
export class ScheduledService {
|
|
97
|
+
// Automatic scheduling - runs at 9 AM daily
|
|
98
|
+
@Cron('0 9 * * *', {
|
|
99
|
+
scheduleId: 'daily-user-report',
|
|
100
|
+
description: 'Generate daily user report'
|
|
101
|
+
})
|
|
102
|
+
async generateDailyReport(): Promise<void> {
|
|
103
|
+
console.log('Generating daily user report...');
|
|
104
|
+
// Report generation logic
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Interval-based scheduling - runs every hour
|
|
108
|
+
@Interval('1h', {
|
|
109
|
+
scheduleId: 'hourly-cleanup',
|
|
110
|
+
description: 'Hourly cleanup task'
|
|
111
|
+
})
|
|
112
|
+
async cleanupTask(): Promise<void> {
|
|
113
|
+
console.log('Running cleanup task...');
|
|
114
|
+
// Cleanup logic
|
|
115
|
+
}
|
|
126
116
|
}
|
|
127
117
|
```
|
|
128
118
|
|
|
129
|
-
|
|
119
|
+
### 4. Use in Services
|
|
130
120
|
|
|
131
|
-
|
|
132
|
-
|
|
121
|
+
```typescript
|
|
122
|
+
// services/user.service.ts
|
|
123
|
+
import { Injectable } from '@nestjs/common';
|
|
124
|
+
import { TemporalService } from 'nestjs-temporal-core';
|
|
133
125
|
|
|
134
|
-
|
|
135
|
-
|
|
126
|
+
@Injectable()
|
|
127
|
+
export class UserService {
|
|
128
|
+
constructor(private readonly temporal: TemporalService) {}
|
|
129
|
+
|
|
130
|
+
async processUser(email: string, name: string): Promise<string> {
|
|
131
|
+
// Start workflow directly with client
|
|
132
|
+
const { workflowId } = await this.temporal.startWorkflow(
|
|
133
|
+
'processUser',
|
|
134
|
+
[email, name],
|
|
135
|
+
{
|
|
136
|
+
taskQueue: 'user-processing',
|
|
137
|
+
workflowId: `user-${email}-${Date.now()}`
|
|
138
|
+
}
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
return workflowId;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
async getUserStatus(workflowId: string): Promise<string> {
|
|
145
|
+
return await this.temporal.queryWorkflow(workflowId, 'getStatus');
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
async updateUserStatus(workflowId: string, status: string): Promise<void> {
|
|
149
|
+
await this.temporal.signalWorkflow(workflowId, 'updateStatus', [status]);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Schedule management
|
|
153
|
+
async pauseDailyReport(): Promise<void> {
|
|
154
|
+
await this.temporal.pauseSchedule('daily-user-report', 'Maintenance mode');
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
async resumeDailyReport(): Promise<void> {
|
|
158
|
+
await this.temporal.resumeSchedule('daily-user-report');
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
```
|
|
136
162
|
|
|
137
|
-
|
|
138
|
-
Built-in support for cron and interval-based workflow scheduling using decorators.
|
|
163
|
+
## ⚙️ Configuration Options
|
|
139
164
|
|
|
140
|
-
###
|
|
141
|
-
|
|
165
|
+
### Basic Configuration
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
TemporalModule.register({
|
|
169
|
+
connection: {
|
|
170
|
+
address: 'localhost:7233',
|
|
171
|
+
namespace: 'default',
|
|
172
|
+
},
|
|
173
|
+
taskQueue: 'my-app',
|
|
174
|
+
worker: {
|
|
175
|
+
workflowsPath: './dist/workflows',
|
|
176
|
+
activityClasses: [EmailActivities, PaymentActivities],
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
```
|
|
142
180
|
|
|
143
|
-
|
|
181
|
+
### Client-Only Mode
|
|
144
182
|
|
|
183
|
+
```typescript
|
|
184
|
+
TemporalModule.forClient({
|
|
185
|
+
connection: {
|
|
186
|
+
address: 'temporal.company.com:7233',
|
|
187
|
+
namespace: 'production',
|
|
188
|
+
tls: true,
|
|
189
|
+
},
|
|
190
|
+
});
|
|
145
191
|
```
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
192
|
+
|
|
193
|
+
### Worker-Only Mode
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
TemporalModule.forWorker({
|
|
197
|
+
connection: {
|
|
198
|
+
address: 'localhost:7233',
|
|
199
|
+
namespace: 'development',
|
|
200
|
+
},
|
|
201
|
+
taskQueue: 'worker-queue',
|
|
202
|
+
workflowsPath: './dist/workflows',
|
|
203
|
+
activityClasses: [ProcessingActivities],
|
|
204
|
+
});
|
|
154
205
|
```
|
|
155
206
|
|
|
156
|
-
|
|
207
|
+
### Async Configuration
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
TemporalModule.registerAsync({
|
|
211
|
+
imports: [ConfigModule],
|
|
212
|
+
useFactory: (config: ConfigService) => ({
|
|
213
|
+
connection: {
|
|
214
|
+
address: config.get('TEMPORAL_ADDRESS'),
|
|
215
|
+
namespace: config.get('TEMPORAL_NAMESPACE'),
|
|
216
|
+
},
|
|
217
|
+
taskQueue: config.get('TEMPORAL_TASK_QUEUE'),
|
|
218
|
+
worker: {
|
|
219
|
+
workflowsPath: './dist/workflows',
|
|
220
|
+
activityClasses: [EmailActivities],
|
|
221
|
+
},
|
|
222
|
+
}),
|
|
223
|
+
inject: [ConfigService],
|
|
224
|
+
});
|
|
225
|
+
```
|
|
157
226
|
|
|
158
|
-
|
|
159
|
-
- **Payment Processing** - Multi-step payment flows with retries
|
|
160
|
-
- **Data Pipelines** - Long-running data processing workflows
|
|
161
|
-
- **Scheduled Jobs** - Cron-based and interval-based background tasks
|
|
162
|
-
- **Saga Patterns** - Distributed transaction management
|
|
163
|
-
- **Human Tasks** - Workflows requiring human intervention
|
|
164
|
-
- **Microservice Orchestration** - Coordinating multiple services
|
|
227
|
+
## 📋 Core Concepts
|
|
165
228
|
|
|
166
|
-
|
|
229
|
+
### Auto-Discovery
|
|
230
|
+
The module automatically discovers and registers:
|
|
231
|
+
- **Activity Classes** marked with `@Activity`
|
|
232
|
+
- **Scheduled Workflows** marked with `@Cron` or `@Interval`
|
|
233
|
+
- **Signals and Queries** within classes
|
|
167
234
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
235
|
+
### Scheduling Made Simple
|
|
236
|
+
```typescript
|
|
237
|
+
// Just add the decorator - schedule is created automatically!
|
|
238
|
+
@Cron('0 8 * * *', { scheduleId: 'daily-report' })
|
|
239
|
+
async generateReport(): Promise<void> {
|
|
240
|
+
// This will run every day at 8 AM
|
|
241
|
+
}
|
|
242
|
+
```
|
|
174
243
|
|
|
175
|
-
##
|
|
244
|
+
## 🔧 Common Use Cases
|
|
176
245
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
246
|
+
### Scheduled Reports
|
|
247
|
+
```typescript
|
|
248
|
+
@Injectable()
|
|
249
|
+
export class ReportService {
|
|
250
|
+
@Cron('0 0 * * 0', { scheduleId: 'weekly-sales-report' })
|
|
251
|
+
async generateWeeklySalesReport(): Promise<void> {
|
|
252
|
+
// Automatically runs every Sunday at midnight
|
|
253
|
+
console.log('Generating weekly sales report...');
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
```
|
|
183
257
|
|
|
184
|
-
|
|
258
|
+
### Data Processing
|
|
259
|
+
```typescript
|
|
260
|
+
@Injectable()
|
|
261
|
+
@Activity()
|
|
262
|
+
export class DataProcessingActivities {
|
|
263
|
+
@ActivityMethod()
|
|
264
|
+
async processFile(filePath: string): Promise<string> {
|
|
265
|
+
console.log(`Processing file: ${filePath}`);
|
|
266
|
+
// File processing logic
|
|
267
|
+
return 'processed';
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
@ActivityMethod()
|
|
271
|
+
async sendNotification(message: string): Promise<void> {
|
|
272
|
+
console.log(`Sending notification: ${message}`);
|
|
273
|
+
// Notification logic
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
```
|
|
185
277
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
278
|
+
### Monitoring Tasks
|
|
279
|
+
```typescript
|
|
280
|
+
@Injectable()
|
|
281
|
+
export class MonitoringService {
|
|
282
|
+
@Interval('5m', {
|
|
283
|
+
scheduleId: 'health-check',
|
|
284
|
+
description: 'Health check every 5 minutes'
|
|
285
|
+
})
|
|
286
|
+
async healthCheck(): Promise<void> {
|
|
287
|
+
console.log('Running health check...');
|
|
288
|
+
// Health check logic
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
```
|
|
189
292
|
|
|
190
|
-
##
|
|
293
|
+
## 📊 Monitoring & Health Checks
|
|
191
294
|
|
|
192
|
-
|
|
295
|
+
```typescript
|
|
296
|
+
@Injectable()
|
|
297
|
+
export class MonitoringService {
|
|
298
|
+
constructor(private readonly temporal: TemporalService) {}
|
|
299
|
+
|
|
300
|
+
async getSystemHealth() {
|
|
301
|
+
// Comprehensive health status
|
|
302
|
+
const health = await this.temporal.getOverallHealth();
|
|
303
|
+
return {
|
|
304
|
+
status: health.status, // 'healthy' | 'degraded' | 'unhealthy'
|
|
305
|
+
components: health.components,
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
async getDiscoveryInfo() {
|
|
310
|
+
// What was discovered
|
|
311
|
+
const schedules = this.temporal.getManagedSchedules();
|
|
312
|
+
const stats = this.temporal.getDiscoveryStats();
|
|
313
|
+
|
|
314
|
+
return { schedules, stats };
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
async manageSchedules() {
|
|
318
|
+
// Schedule management
|
|
319
|
+
await this.temporal.pauseSchedule('daily-report', 'Maintenance');
|
|
320
|
+
await this.temporal.resumeSchedule('daily-report');
|
|
321
|
+
await this.temporal.triggerSchedule('daily-report'); // Run now
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
```
|
|
193
325
|
|
|
194
|
-
##
|
|
326
|
+
## 🌟 Why This Package?
|
|
195
327
|
|
|
196
|
-
|
|
328
|
+
- **🎯 NestJS First** - Built specifically for NestJS with familiar patterns
|
|
329
|
+
- **🔄 Auto-Discovery** - No manual registration, just use decorators
|
|
330
|
+
- **📅 Built-in Scheduling** - Cron jobs that integrate with workflows
|
|
331
|
+
- **🔧 Production Ready** - Health checks, monitoring, graceful shutdowns
|
|
332
|
+
- **📚 Easy to Learn** - Familiar NestJS service patterns
|
|
333
|
+
- **🚀 Scalable** - Client-only, worker-only, or unified deployments
|
|
197
334
|
|
|
198
|
-
##
|
|
335
|
+
## 🤝 Contributing
|
|
199
336
|
|
|
200
|
-
|
|
201
|
-
- [NestJS](https://nestjs.com/) - For the incredible framework
|
|
202
|
-
- [TypeScript](https://www.typescriptlang.org/) - For making JavaScript enjoyable
|
|
337
|
+
Contributions welcome! Please read our [Contributing Guide](./CONTRIBUTING.md) for details.
|
|
203
338
|
|
|
204
|
-
|
|
339
|
+
## 📄 License
|
|
205
340
|
|
|
206
|
-
|
|
341
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { DynamicModule } from '@nestjs/common';
|
|
2
|
-
import {
|
|
2
|
+
import { TemporalAsyncOptions, TemporalOptions } from '../interfaces';
|
|
3
3
|
export declare class TemporalClientModule {
|
|
4
4
|
private static readonly logger;
|
|
5
|
-
static register(options:
|
|
6
|
-
static registerAsync(options:
|
|
5
|
+
static register(options: TemporalOptions): DynamicModule;
|
|
6
|
+
static registerAsync(options: TemporalAsyncOptions): DynamicModule;
|
|
7
|
+
static forClient(options: {
|
|
8
|
+
connection: TemporalOptions['connection'];
|
|
9
|
+
isGlobal?: boolean;
|
|
10
|
+
}): DynamicModule;
|
|
7
11
|
private static createClientProvider;
|
|
8
12
|
private static createAsyncClientProvider;
|
|
9
13
|
private static createAsyncProviders;
|
|
10
14
|
private static createClientInstance;
|
|
11
15
|
private static enhanceClientWithShutdown;
|
|
16
|
+
private static extractClientOptions;
|
|
17
|
+
private static validateOptions;
|
|
12
18
|
}
|
|
@@ -15,18 +15,19 @@ const temporal_client_service_1 = require("./temporal-client.service");
|
|
|
15
15
|
const temporal_schedule_service_1 = require("./temporal-schedule.service");
|
|
16
16
|
let TemporalClientModule = TemporalClientModule_1 = class TemporalClientModule {
|
|
17
17
|
static register(options) {
|
|
18
|
+
const clientOptions = this.extractClientOptions(options);
|
|
18
19
|
return {
|
|
19
20
|
module: TemporalClientModule_1,
|
|
20
21
|
providers: [
|
|
21
22
|
{
|
|
22
|
-
provide: constants_1.
|
|
23
|
-
useValue:
|
|
23
|
+
provide: constants_1.TEMPORAL_MODULE_OPTIONS,
|
|
24
|
+
useValue: clientOptions,
|
|
24
25
|
},
|
|
25
|
-
this.createClientProvider(
|
|
26
|
+
this.createClientProvider(clientOptions),
|
|
26
27
|
temporal_client_service_1.TemporalClientService,
|
|
27
28
|
temporal_schedule_service_1.TemporalScheduleService,
|
|
28
29
|
],
|
|
29
|
-
exports: [temporal_client_service_1.TemporalClientService, temporal_schedule_service_1.TemporalScheduleService],
|
|
30
|
+
exports: [temporal_client_service_1.TemporalClientService, temporal_schedule_service_1.TemporalScheduleService, constants_1.TEMPORAL_CLIENT],
|
|
30
31
|
};
|
|
31
32
|
}
|
|
32
33
|
static registerAsync(options) {
|
|
@@ -39,9 +40,15 @@ let TemporalClientModule = TemporalClientModule_1 = class TemporalClientModule {
|
|
|
39
40
|
temporal_client_service_1.TemporalClientService,
|
|
40
41
|
temporal_schedule_service_1.TemporalScheduleService,
|
|
41
42
|
],
|
|
42
|
-
exports: [temporal_client_service_1.TemporalClientService, temporal_schedule_service_1.TemporalScheduleService],
|
|
43
|
+
exports: [temporal_client_service_1.TemporalClientService, temporal_schedule_service_1.TemporalScheduleService, constants_1.TEMPORAL_CLIENT],
|
|
43
44
|
};
|
|
44
45
|
}
|
|
46
|
+
static forClient(options) {
|
|
47
|
+
return this.register({
|
|
48
|
+
connection: options.connection,
|
|
49
|
+
isGlobal: options.isGlobal,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
45
52
|
static createClientProvider(options) {
|
|
46
53
|
return {
|
|
47
54
|
provide: constants_1.TEMPORAL_CLIENT,
|
|
@@ -51,15 +58,18 @@ let TemporalClientModule = TemporalClientModule_1 = class TemporalClientModule {
|
|
|
51
58
|
static createAsyncClientProvider() {
|
|
52
59
|
return {
|
|
53
60
|
provide: constants_1.TEMPORAL_CLIENT,
|
|
54
|
-
useFactory: async (
|
|
55
|
-
|
|
61
|
+
useFactory: async (temporalOptions) => {
|
|
62
|
+
const clientOptions = this.extractClientOptions(temporalOptions);
|
|
63
|
+
return this.createClientInstance(clientOptions);
|
|
64
|
+
},
|
|
65
|
+
inject: [constants_1.TEMPORAL_MODULE_OPTIONS],
|
|
56
66
|
};
|
|
57
67
|
}
|
|
58
68
|
static createAsyncProviders(options) {
|
|
59
69
|
if (options.useFactory) {
|
|
60
70
|
return [
|
|
61
71
|
{
|
|
62
|
-
provide: constants_1.
|
|
72
|
+
provide: constants_1.TEMPORAL_MODULE_OPTIONS,
|
|
63
73
|
useFactory: options.useFactory,
|
|
64
74
|
inject: options.inject || [],
|
|
65
75
|
},
|
|
@@ -68,8 +78,8 @@ let TemporalClientModule = TemporalClientModule_1 = class TemporalClientModule {
|
|
|
68
78
|
if (options.useClass) {
|
|
69
79
|
return [
|
|
70
80
|
{
|
|
71
|
-
provide: constants_1.
|
|
72
|
-
useFactory: async (optionsFactory) => optionsFactory.
|
|
81
|
+
provide: constants_1.TEMPORAL_MODULE_OPTIONS,
|
|
82
|
+
useFactory: async (optionsFactory) => optionsFactory.createTemporalOptions(),
|
|
73
83
|
inject: [options.useClass],
|
|
74
84
|
},
|
|
75
85
|
{
|
|
@@ -81,8 +91,8 @@ let TemporalClientModule = TemporalClientModule_1 = class TemporalClientModule {
|
|
|
81
91
|
if (options.useExisting) {
|
|
82
92
|
return [
|
|
83
93
|
{
|
|
84
|
-
provide: constants_1.
|
|
85
|
-
useFactory: async (optionsFactory) => optionsFactory.
|
|
94
|
+
provide: constants_1.TEMPORAL_MODULE_OPTIONS,
|
|
95
|
+
useFactory: async (optionsFactory) => optionsFactory.createTemporalOptions(),
|
|
86
96
|
inject: [options.useExisting],
|
|
87
97
|
},
|
|
88
98
|
];
|
|
@@ -105,7 +115,7 @@ let TemporalClientModule = TemporalClientModule_1 = class TemporalClientModule {
|
|
|
105
115
|
};
|
|
106
116
|
}
|
|
107
117
|
connection = await client_1.Connection.connect(connectionConfig);
|
|
108
|
-
const namespace = options.namespace || constants_1.DEFAULT_NAMESPACE;
|
|
118
|
+
const namespace = options.connection.namespace || constants_1.DEFAULT_NAMESPACE;
|
|
109
119
|
this.logger.log(`Connected to Temporal server, using namespace "${namespace}"`);
|
|
110
120
|
const client = new client_1.Client({ connection, namespace });
|
|
111
121
|
return this.enhanceClientWithShutdown(client);
|
|
@@ -141,6 +151,26 @@ let TemporalClientModule = TemporalClientModule_1 = class TemporalClientModule {
|
|
|
141
151
|
};
|
|
142
152
|
return enhancedClient;
|
|
143
153
|
}
|
|
154
|
+
static extractClientOptions(options) {
|
|
155
|
+
return {
|
|
156
|
+
connection: {
|
|
157
|
+
address: options.connection.address,
|
|
158
|
+
namespace: options.connection.namespace,
|
|
159
|
+
tls: options.connection.tls,
|
|
160
|
+
apiKey: options.connection.apiKey,
|
|
161
|
+
metadata: options.connection.metadata,
|
|
162
|
+
},
|
|
163
|
+
allowConnectionFailure: true,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
static validateOptions(options) {
|
|
167
|
+
if (!options.connection) {
|
|
168
|
+
throw new Error('Connection configuration is required');
|
|
169
|
+
}
|
|
170
|
+
if (!options.connection.address) {
|
|
171
|
+
throw new Error('Connection address is required');
|
|
172
|
+
}
|
|
173
|
+
}
|
|
144
174
|
};
|
|
145
175
|
exports.TemporalClientModule = TemporalClientModule;
|
|
146
176
|
TemporalClientModule.logger = new common_1.Logger(TemporalClientModule_1.name);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"temporal-client.module.js","sourceRoot":"","sources":["../../src/client/temporal-client.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAOwB;AACxB,+CAAwD;
|
|
1
|
+
{"version":3,"file":"temporal-client.module.js","sourceRoot":"","sources":["../../src/client/temporal-client.module.ts"],"names":[],"mappings":"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"}
|