nestjs-serverless-workflow 0.0.4 → 0.0.5
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 +279 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
# Introduction
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/nestjs-serverless-workflow)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
A powerful, tree-shakable workflow and state machine library for NestJS applications, optimized for serverless environments like AWS Lambda.
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- 🎯 **State Machine Engine**: Define workflows with states, transitions, and events
|
|
11
|
+
- 🔄 **Event-Driven Architecture**: Integrate with message brokers (SQS, Kafka, RabbitMQ, etc.)
|
|
12
|
+
- ⚡ **Serverless Optimized**: Built for AWS Lambda with automatic timeout handling
|
|
13
|
+
- 📦 **Tree-Shakable**: Subpath exports ensure minimal bundle sizes
|
|
14
|
+
- 🛡️ **Type-Safe**: Full TypeScript support with comprehensive type definitions
|
|
15
|
+
- 🔁 **Retry Logic**: Built-in retry mechanisms with exponential backoff
|
|
16
|
+
- 🎨 **Decorator-Based API**: Clean, declarative workflow definitions
|
|
17
|
+
- 📊 **Saga Pattern Support**: Distributed transaction managementa (TODO)
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# Using npm
|
|
23
|
+
npm install nestjs-serverless-workflow @nestjs/common @nestjs/core reflect-metadata rxjs
|
|
24
|
+
|
|
25
|
+
# Using bun
|
|
26
|
+
bun add nestjs-serverless-workflow @nestjs/common @nestjs/core reflect-metadata rxjs
|
|
27
|
+
|
|
28
|
+
# Using yarn
|
|
29
|
+
yarn add nestjs-serverless-workflow @nestjs/common @nestjs/core reflect-metadata rxjs
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Quick Start
|
|
33
|
+
|
|
34
|
+
### 1. Define Your Entity
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
export enum OrderStatus {
|
|
38
|
+
Pending = 'pending',
|
|
39
|
+
Processing = 'processing',
|
|
40
|
+
Completed = 'completed',
|
|
41
|
+
Failed = 'failed',
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export class Order {
|
|
45
|
+
id: string;
|
|
46
|
+
status: OrderStatus;
|
|
47
|
+
// ... other properties
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 2. Create a Workflow
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
import { Workflow, OnEvent, Entity, Payload } from 'nestjs-serverless-workflow/core';
|
|
55
|
+
|
|
56
|
+
@Workflow({
|
|
57
|
+
name: 'OrderWorkflow',
|
|
58
|
+
states: {
|
|
59
|
+
finals: [OrderStatus.Completed, OrderStatus.Failed],
|
|
60
|
+
idles: [OrderStatus.Pending],
|
|
61
|
+
failed: OrderStatus.Failed,
|
|
62
|
+
},
|
|
63
|
+
transitions: [
|
|
64
|
+
{
|
|
65
|
+
from: [OrderStatus.Pending],
|
|
66
|
+
to: OrderStatus.Processing,
|
|
67
|
+
event: 'order.submit',
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
from: [OrderStatus.Processing],
|
|
71
|
+
to: OrderStatus.Completed,
|
|
72
|
+
event: 'order.complete',
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
entityService: 'entity.order',
|
|
76
|
+
brokerPublisher: 'broker.order',
|
|
77
|
+
})
|
|
78
|
+
export class OrderWorkflow {
|
|
79
|
+
@OnEvent('order.submit')
|
|
80
|
+
async onSubmit(@Entity() entity: Order, @Payload() data: any) {
|
|
81
|
+
console.log('Order submitted:', entity.id);
|
|
82
|
+
return entity;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@OnEvent('order.complete')
|
|
86
|
+
async onComplete(@Entity() entity: Order) {
|
|
87
|
+
console.log('Order completed:', entity.id);
|
|
88
|
+
return entity;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 3. Implement Entity Service
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
import { Injectable } from '@nestjs/common';
|
|
97
|
+
import { IWorkflowEntity } from 'nestjs-serverless-workflow/core';
|
|
98
|
+
|
|
99
|
+
@Injectable()
|
|
100
|
+
export class OrderEntityService implements IWorkflowEntity<Order, OrderStatus> {
|
|
101
|
+
async create(): Promise<Order> {
|
|
102
|
+
// Create new order
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async load(urn: string): Promise<Order | null> {
|
|
106
|
+
// Load order from database
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async update(entity: Order, status: OrderStatus): Promise<Order> {
|
|
110
|
+
// Update order status
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
status(entity: Order): OrderStatus {
|
|
114
|
+
return entity.status;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
urn(entity: Order): string {
|
|
118
|
+
return entity.id;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### 4. Register the Module
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
import { Module } from '@nestjs/common';
|
|
127
|
+
import { WorkflowModule } from 'nestjs-serverless-workflow/core';
|
|
128
|
+
import { OrderWorkflow } from './order.workflow';
|
|
129
|
+
import { OrderEntityService } from './order-entity.service';
|
|
130
|
+
|
|
131
|
+
@Module({
|
|
132
|
+
imports: [
|
|
133
|
+
WorkflowModule.register({
|
|
134
|
+
entities: [{ provide: 'entity.order', useClass: OrderEntityService }],
|
|
135
|
+
workflows: [OrderWorkflow],
|
|
136
|
+
brokers: [{ provide: 'broker.order', useClass: MySqsEmitter }],
|
|
137
|
+
}),
|
|
138
|
+
],
|
|
139
|
+
})
|
|
140
|
+
export class OrderModule {}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Documentation
|
|
144
|
+
|
|
145
|
+
📚 **[Full Documentation](https://tung-dnt.github.io/nestjs-serverless-workflow/)**
|
|
146
|
+
|
|
147
|
+
- [Getting Started](https://tung-dnt.github.io/nestjs-serverless-workflow/docs/getting-started)
|
|
148
|
+
- [Workflow Module](https://tung-dnt.github.io/nestjs-serverless-workflow/docs/workflow)
|
|
149
|
+
- [Event Bus](https://tung-dnt.github.io/nestjs-serverless-workflow/docs/event-bus)
|
|
150
|
+
- [Lambda Adapter](https://tung-dnt.github.io/nestjs-serverless-workflow/docs/adapters)
|
|
151
|
+
- [API Reference](https://tung-dnt.github.io/nestjs-serverless-workflow/docs/api-reference/workflow-module)
|
|
152
|
+
- [Examples](https://tung-dnt.github.io/nestjs-serverless-workflow/docs/examples/lambda-order-state-machine)
|
|
153
|
+
|
|
154
|
+
## Package Structure
|
|
155
|
+
|
|
156
|
+
The library is organized into tree-shakable subpath exports:
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
nestjs-serverless-workflow/
|
|
160
|
+
├── core # Core workflow engine (decorators, services, types)
|
|
161
|
+
├── event-bus # Event publishing and broker integration
|
|
162
|
+
├── adapter # Runtime adapters (Lambda, HTTP)
|
|
163
|
+
└── exception # Custom exception types
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Import Only What You Need
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
// Only imports workflow module
|
|
170
|
+
import { WorkflowModule } from 'nestjs-serverless-workflow/core';
|
|
171
|
+
|
|
172
|
+
// Only imports event bus
|
|
173
|
+
import { IBrokerPublisher } from 'nestjs-serverless-workflow/event-bus';
|
|
174
|
+
|
|
175
|
+
// Only imports Lambda adapter
|
|
176
|
+
import { LambdaEventHandler } from 'nestjs-serverless-workflow/adapter';
|
|
177
|
+
|
|
178
|
+
// Only imports exceptions
|
|
179
|
+
import { UnretriableException } from 'nestjs-serverless-workflow/exception';
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
This ensures minimal bundle sizes and faster cold starts in serverless environments.
|
|
183
|
+
|
|
184
|
+
## Examples
|
|
185
|
+
|
|
186
|
+
Check out the [examples directory](https://github.com/tung-dnt/nestjs-serverless-workflow/tree/main/examples) for complete working examples:
|
|
187
|
+
|
|
188
|
+
- **[Lambda Order State Machine](https://github.com/tung-dnt/nestjs-serverless-workflow/tree/main/examples/lambda-order-state-machine/)**: Complete AWS Lambda example with SQS and DynamoDB
|
|
189
|
+
|
|
190
|
+
## Key Concepts
|
|
191
|
+
|
|
192
|
+
### States
|
|
193
|
+
|
|
194
|
+
States represent the different stages your entity can be in:
|
|
195
|
+
|
|
196
|
+
- **Finals**: Terminal states where the workflow ends
|
|
197
|
+
- **Idles**: States where the workflow waits for external events
|
|
198
|
+
- **Failed**: The failure state to transition to on errors
|
|
199
|
+
|
|
200
|
+
### Transitions
|
|
201
|
+
|
|
202
|
+
Transitions define how entities move from one state to another, triggered by events:
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
{
|
|
206
|
+
from: [OrderStatus.Pending],
|
|
207
|
+
to: OrderStatus.Processing,
|
|
208
|
+
event: 'order.submit',
|
|
209
|
+
conditions: [
|
|
210
|
+
(entity: Order, payload: any) => entity.items.length > 0,
|
|
211
|
+
],
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Events
|
|
216
|
+
|
|
217
|
+
Events trigger state transitions. Define event handlers using the `@OnEvent` decorator:
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
@OnEvent('order.submit')
|
|
221
|
+
async onSubmit(@Entity() entity: Order, @Payload() data: any) {
|
|
222
|
+
// Handle the event
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## AWS Lambda Integration
|
|
227
|
+
|
|
228
|
+
The library includes a Lambda adapter that handles:
|
|
229
|
+
|
|
230
|
+
- Automatic timeout management
|
|
231
|
+
- Batch item failures
|
|
232
|
+
- Graceful shutdown before timeout
|
|
233
|
+
- SQS event source integration
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
import { LambdaEventHandler } from 'nestjs-serverless-workflow/adapter';
|
|
237
|
+
import { type SQSHandler } from 'aws-lambda';
|
|
238
|
+
|
|
239
|
+
const app = await NestFactory.createApplicationContext(AppModule);
|
|
240
|
+
export const handler: SQSHandler = LambdaEventHandler(app);
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Requirements
|
|
244
|
+
|
|
245
|
+
- Node.js >= 20.0.0 or Bun >= 1.3.4
|
|
246
|
+
- NestJS >= 11.0.0
|
|
247
|
+
- TypeScript >= 5.0.0
|
|
248
|
+
|
|
249
|
+
## Contributing
|
|
250
|
+
|
|
251
|
+
Contributions are welcome! Please read our [Contributing Guide](https://github.com/tung-dnt/nestjs-serverless-workflow/tree/main/CONTRIBUTING.md) for details on:
|
|
252
|
+
|
|
253
|
+
- Code style and conventions
|
|
254
|
+
- Development setup
|
|
255
|
+
- Testing guidelines
|
|
256
|
+
- Pull request process
|
|
257
|
+
|
|
258
|
+
## License
|
|
259
|
+
|
|
260
|
+
This project is licensed under the MIT License - see the [LICENSE](https://github.com/tung-dnt/nestjs-serverless-workflow/tree/main/LICENSE) file for details.
|
|
261
|
+
|
|
262
|
+
## Author
|
|
263
|
+
|
|
264
|
+
**Thomas Do (tung-dnt)**
|
|
265
|
+
|
|
266
|
+
- GitHub: [@tung-dnt](https://github.com/tung-dnt)
|
|
267
|
+
- Repository: [nestjs-serverless-workflow](https://github.com/tung-dnt/nestjs-serverless-workflow)
|
|
268
|
+
|
|
269
|
+
## Support
|
|
270
|
+
|
|
271
|
+
- 📖 [Documentation](https://tung-dnt.github.io/nestjs-serverless-workflow/)
|
|
272
|
+
- 🐛 [Issue Tracker](https://github.com/tung-dnt/nestjs-serverless-workflow/issues)
|
|
273
|
+
- 💬 [Discussions](https://github.com/tung-dnt/nestjs-serverless-workflow/discussions)
|
|
274
|
+
|
|
275
|
+
## Related Projects
|
|
276
|
+
|
|
277
|
+
- [NestJS](https://nestjs.com/) - A progressive Node.js framework
|
|
278
|
+
- [AWS Lambda](https://aws.amazon.com/lambda/) - Serverless compute service
|
|
279
|
+
- [AWS SQS](https://aws.amazon.com/sqs/) - Message queuing service
|