@nest-batch/core 0.2.3 → 0.2.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.ko.md +95 -0
- package/README.md +56 -332
- package/package.json +3 -2
package/README.ko.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# @nest-batch/core
|
|
2
|
+
|
|
3
|
+
NestJS용 batch engine core입니다. job model, decorator, launcher/explorer/operator
|
|
4
|
+
service, in-process transport, 그리고 `@nest-batch/*` 패키지들이 사용하는 adapter
|
|
5
|
+
contract를 제공합니다.
|
|
6
|
+
|
|
7
|
+
English: [README.md](./README.md)
|
|
8
|
+
|
|
9
|
+
## 설치
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pnpm add @nest-batch/core reflect-metadata
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
peer dependency:
|
|
16
|
+
|
|
17
|
+
- `@nestjs/common` `^10 || ^11`
|
|
18
|
+
- `@nestjs/core` `^10 || ^11`
|
|
19
|
+
- `reflect-metadata` `^0.2`
|
|
20
|
+
|
|
21
|
+
## Public Import
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import {
|
|
25
|
+
Batch,
|
|
26
|
+
BatchScheduled,
|
|
27
|
+
InProcessAdapter,
|
|
28
|
+
JobExplorer,
|
|
29
|
+
JobLauncher,
|
|
30
|
+
JobOperator,
|
|
31
|
+
NestBatchModule,
|
|
32
|
+
} from '@nest-batch/core';
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`Batch.Jobable`, `Batch.Stepable`, `Batch.Tasklet`, `Batch.ItemReader`,
|
|
36
|
+
`Batch.ItemProcessor`, `Batch.ItemWriter`, listener decorator는 `Batch` namespace로
|
|
37
|
+
사용합니다.
|
|
38
|
+
|
|
39
|
+
## Module Wiring
|
|
40
|
+
|
|
41
|
+
core에는 persistence adapter 하나와 transport adapter 하나가 필요합니다.
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import { Module } from '@nestjs/common';
|
|
45
|
+
import { InProcessAdapter, NestBatchModule } from '@nest-batch/core';
|
|
46
|
+
import { MikroOrmAdapter } from '@nest-batch/mikro-orm';
|
|
47
|
+
|
|
48
|
+
@Module({
|
|
49
|
+
imports: [
|
|
50
|
+
NestBatchModule.forRoot({
|
|
51
|
+
adapters: {
|
|
52
|
+
persistence: MikroOrmAdapter.forRoot(),
|
|
53
|
+
transport: InProcessAdapter.forRoot(),
|
|
54
|
+
},
|
|
55
|
+
}),
|
|
56
|
+
],
|
|
57
|
+
})
|
|
58
|
+
export class AppModule {}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`InProcessAdapter`는 이 패키지에 포함되어 있습니다. 다른 transport adapter는 sibling
|
|
62
|
+
package로 제공합니다.
|
|
63
|
+
|
|
64
|
+
## Job 정의
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
import { Injectable } from '@nestjs/common';
|
|
68
|
+
import { Batch } from '@nest-batch/core';
|
|
69
|
+
|
|
70
|
+
@Injectable()
|
|
71
|
+
@Batch.Jobable({ id: 'send-digest', restartable: true })
|
|
72
|
+
export class SendDigestJob {
|
|
73
|
+
@Batch.Stepable({ id: 'send' })
|
|
74
|
+
@Batch.Tasklet()
|
|
75
|
+
async send(): Promise<void> {
|
|
76
|
+
await sendDigestEmails();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
job class를 Nest provider로 등록하면 application boot 시점에 `NestBatchModule`이
|
|
82
|
+
`@Batch.Jobable` provider를 발견합니다.
|
|
83
|
+
|
|
84
|
+
## 실행과 조회
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
await jobLauncher.launch('send-digest', { businessDate: '2026-06-25' });
|
|
88
|
+
|
|
89
|
+
const executions = await jobExplorer.listJobExecutions({
|
|
90
|
+
status: 'COMPLETED',
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
`JobLauncher`는 작업을 시작하고, `JobExplorer`는 durable state를 읽으며,
|
|
95
|
+
`JobOperator`는 stop, restart, abandon, start-next-instance operation을 제공합니다.
|
package/README.md
CHANGED
|
@@ -1,371 +1,95 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @nest-batch/core
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
It does not own persistence, transport, or scheduling. Those live in
|
|
7
|
-
[sibling packages](#what-is-not-in-core).
|
|
3
|
+
Core batch engine for NestJS. This package provides the public job model,
|
|
4
|
+
decorators, launcher/explorer/operator services, in-process transport, and the
|
|
5
|
+
adapter contracts used by the `@nest-batch/*` package family.
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
`@nestjs/common`, `@nestjs/core`, and `reflect-metadata`. Anything
|
|
11
|
-
specific to a database, a queue, or a scheduler is injected through
|
|
12
|
-
tokens at the DI boundary, so a host app can swap persistence and
|
|
13
|
-
transport without touching the core.
|
|
14
|
-
|
|
15
|
-
---
|
|
7
|
+
Korean: [README.ko.md](./README.ko.md)
|
|
16
8
|
|
|
17
9
|
## Install
|
|
18
10
|
|
|
19
11
|
```bash
|
|
20
|
-
pnpm add @nest-batch/core
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
Peer dependencies are pulled in by the host app:
|
|
24
|
-
|
|
25
|
-
| Package | Range |
|
|
26
|
-
| ------------------ | --------- |
|
|
27
|
-
| `@nestjs/common` | `^11.0.0` |
|
|
28
|
-
| `@nestjs/core` | `^11.0.0` |
|
|
29
|
-
| `reflect-metadata` | `^0.2.2` |
|
|
30
|
-
|
|
31
|
-
Core supports Nest 10 and 11.
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
## Conceptual model
|
|
36
|
-
|
|
37
|
-
The model is a direct port of Spring Batch's mental model. If you've
|
|
38
|
-
written a Spring Batch job, you already know 80% of this.
|
|
39
|
-
|
|
40
|
-
```
|
|
41
|
-
Job
|
|
42
|
-
└── Step (one or more)
|
|
43
|
-
├── Chunk step (read → process → write in fixed-size chunks)
|
|
44
|
-
│ ├── ItemReader<T>
|
|
45
|
-
│ ├── ItemProcessor<T, R>
|
|
46
|
-
│ └── ItemWriter<R>
|
|
47
|
-
└── Tasklet (single-method work unit, no chunking)
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
### Job
|
|
51
|
-
|
|
52
|
-
A named unit of work. The host app declares one with the `@Jobable`
|
|
53
|
-
decorator or the `BatchBuilder` fluent API. A job has:
|
|
54
|
-
|
|
55
|
-
- a unique `id`
|
|
56
|
-
- an ordered list of `Step`s
|
|
57
|
-
- a `JobParameters` shape (the params that pin a `JobInstance`)
|
|
58
|
-
|
|
59
|
-
### Step
|
|
60
|
-
|
|
61
|
-
A step is either a **chunk step** or a **tasklet step**. The compiler
|
|
62
|
-
decides which one based on which handler method you provide. Each step
|
|
63
|
-
runs inside a `StepExecution` row in the batch meta schema, and the
|
|
64
|
-
`StepExecution.id` is the unit of restart/checkpoint.
|
|
65
|
-
|
|
66
|
-
### Chunk step
|
|
67
|
-
|
|
68
|
-
A chunk step reads `chunkSize` items, processes them, writes them, and
|
|
69
|
-
repeats until the reader is exhausted. The chunk is the unit of
|
|
70
|
-
transaction: if any item in the chunk fails, the whole chunk rolls
|
|
71
|
-
back. This is the model Spring Batch uses, and we keep it.
|
|
72
|
-
|
|
73
|
-
The reader, processor, and writer are plain Nest providers. You can
|
|
74
|
-
declare them with `@ItemReader`, `@ItemProcessor`, `@ItemWriter` (under
|
|
75
|
-
the `Batch` namespace) or with method references on the job
|
|
76
|
-
class itself. Three reference kinds are accepted:
|
|
77
|
-
|
|
78
|
-
- `BuilderLambda` — a function value captured by the builder.
|
|
79
|
-
- `Method` — a method on the job class.
|
|
80
|
-
- `ProviderToken` — a Nest DI token resolved at runtime.
|
|
81
|
-
|
|
82
|
-
### Tasklet step
|
|
83
|
-
|
|
84
|
-
A single method that runs to completion. Useful for one-off work that
|
|
85
|
-
doesn't fit the read/process/write shape (e.g. "run this SQL and
|
|
86
|
-
move on"). A tasklet is the right answer when you don't need chunking,
|
|
87
|
-
skip, or restart.
|
|
88
|
-
|
|
89
|
-
### Listeners
|
|
90
|
-
|
|
91
|
-
Listeners fire around every transition in the engine. You tag a method
|
|
92
|
-
on your provider with one of the listener decorators, and the engine
|
|
93
|
-
calls it at the right moment. The full set:
|
|
94
|
-
|
|
95
|
-
| Decorator | Fires |
|
|
96
|
-
| ----------------- | --------------------------------------------- |
|
|
97
|
-
| `@BeforeJob` | Before a job execution starts. |
|
|
98
|
-
| `@AfterJob` | After a job execution finishes (any status). |
|
|
99
|
-
| `@BeforeStep` | Before a step execution starts. |
|
|
100
|
-
| `@AfterStep` | After a step execution finishes (any status). |
|
|
101
|
-
| `@BeforeChunk` | Before each chunk (read-process-write cycle). |
|
|
102
|
-
| `@AfterChunk` | After each chunk finishes successfully. |
|
|
103
|
-
| `@OnChunkError` | When a chunk throws. |
|
|
104
|
-
| `@BeforeRead` | Before each item is read. |
|
|
105
|
-
| `@AfterRead` | After each item is read. |
|
|
106
|
-
| `@OnReadError` | When the reader throws. |
|
|
107
|
-
| `@BeforeProcess` | Before each item is processed. |
|
|
108
|
-
| `@AfterProcess` | After each item is processed. |
|
|
109
|
-
| `@OnProcessError` | When the processor throws. |
|
|
110
|
-
| `@BeforeWrite` | Before the writer receives a chunk. |
|
|
111
|
-
| `@AfterWrite` | After the writer finishes a chunk. |
|
|
112
|
-
| `@OnWriteError` | When the writer throws. |
|
|
113
|
-
| `@OnSkipRead` | When a read is skipped by the skip policy. |
|
|
114
|
-
| `@OnSkipProcess` | When a processed item is skipped. |
|
|
115
|
-
| `@OnSkipWrite` | When a write is skipped. |
|
|
116
|
-
|
|
117
|
-
You can mark a listener as `nonCritical: true` via
|
|
118
|
-
`@BeforeJob({ nonCritical: true })` if the engine should swallow
|
|
119
|
-
exceptions from it. A critical listener that throws fails the
|
|
120
|
-
execution.
|
|
121
|
-
|
|
122
|
-
### Skip and retry policies
|
|
123
|
-
|
|
124
|
-
Skip and retry are Batch Core concerns, not transport concerns. The
|
|
125
|
-
default policy is "fail on first error", and you can swap in:
|
|
126
|
-
|
|
127
|
-
- `LimitSkipPolicy` — skip up to N items of a given kind
|
|
128
|
-
(read/process/write), then fail.
|
|
129
|
-
- `ClassifySkipPolicy` — skip based on the exception class.
|
|
130
|
-
- `ExponentialBackoffRetryPolicy` — retry with exponential backoff.
|
|
131
|
-
- `FixedDelayRetryPolicy` — retry with a fixed delay.
|
|
132
|
-
|
|
133
|
-
The BullMQ package reuses these policies. It does **not** reimplement
|
|
134
|
-
them. See "what is NOT in core" below.
|
|
135
|
-
|
|
136
|
-
---
|
|
137
|
-
|
|
138
|
-
## Polymorphic `JobLauncher`
|
|
139
|
-
|
|
140
|
-
`JobLauncher` is the public entry point for starting a job. Its
|
|
141
|
-
signature is:
|
|
142
|
-
|
|
143
|
-
```ts
|
|
144
|
-
launch(jobId: string, params: JobParameters = {}): Promise<JobExecution>
|
|
12
|
+
pnpm add @nest-batch/core reflect-metadata
|
|
145
13
|
```
|
|
146
14
|
|
|
147
|
-
|
|
15
|
+
Peer dependencies:
|
|
148
16
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
so semantically-identical params yield the same key.
|
|
153
|
-
3. `createExecutionAtomic(jobId, jobKey, params)` — atomic
|
|
154
|
-
get-or-create instance + `SELECT ... FOR UPDATE SKIP LOCKED` to
|
|
155
|
-
serialize concurrent launches + running-execution check + insert.
|
|
156
|
-
4. Delegate to whatever `IExecutionStrategy` is bound to the
|
|
157
|
-
`EXECUTION_STRATEGY` token. The default is the in-process strategy;
|
|
158
|
-
`@nest-batch/bullmq` overrides it with a transport strategy.
|
|
17
|
+
- `@nestjs/common` `^10 || ^11`
|
|
18
|
+
- `@nestjs/core` `^10 || ^11`
|
|
19
|
+
- `reflect-metadata` `^0.2`
|
|
159
20
|
|
|
160
|
-
|
|
21
|
+
## Public Imports
|
|
161
22
|
|
|
162
23
|
```ts
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
24
|
+
import {
|
|
25
|
+
Batch,
|
|
26
|
+
BatchScheduled,
|
|
27
|
+
InProcessAdapter,
|
|
28
|
+
JobExplorer,
|
|
29
|
+
JobLauncher,
|
|
30
|
+
JobOperator,
|
|
31
|
+
NestBatchModule,
|
|
32
|
+
} from '@nest-batch/core';
|
|
171
33
|
```
|
|
172
34
|
|
|
173
|
-
`
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
state in-process. The launcher resolves the persisted
|
|
177
|
-
`JobExecution` and returns it.
|
|
178
|
-
- `{ kind: 'enqueued', queueJobId }` — the strategy handed off to a
|
|
179
|
-
transport. The launcher still resolves the latest persisted
|
|
180
|
-
`JobExecution` (which is in `STARTING` / `STARTED` because the
|
|
181
|
-
executor has not run yet on the launcher process).
|
|
182
|
-
|
|
183
|
-
The `JobLauncher.launch` API is intentionally stable. Strategies
|
|
184
|
-
change; the public surface does not.
|
|
35
|
+
Use the `Batch` namespace for decorators such as `Batch.Jobable`,
|
|
36
|
+
`Batch.Stepable`, `Batch.Tasklet`, `Batch.ItemReader`, `Batch.ItemProcessor`,
|
|
37
|
+
`Batch.ItemWriter`, and listener decorators.
|
|
185
38
|
|
|
186
|
-
|
|
39
|
+
## Module Wiring
|
|
187
40
|
|
|
188
|
-
|
|
41
|
+
Core requires one persistence adapter and one transport adapter.
|
|
189
42
|
|
|
190
43
|
```ts
|
|
191
44
|
import { Module } from '@nestjs/common';
|
|
192
|
-
import {
|
|
193
|
-
|
|
194
|
-
JobRepository,
|
|
195
|
-
TransactionManager,
|
|
196
|
-
InProcessExecutionStrategy,
|
|
197
|
-
IN_PROCESS_EXECUTION_STRATEGY_PROVIDER,
|
|
198
|
-
} from '@nest-batch/core';
|
|
199
|
-
import { MikroORMJobRepository, MikroORMTransactionManager } from '@nest-batch/mikro-orm';
|
|
200
|
-
import { MikroOrmModule } from '@mikro-orm/nestjs';
|
|
201
|
-
import { BATCH_META_ENTITIES } from '@nest-batch/mikro-orm';
|
|
202
|
-
import { ProductEntity } from './entities/product.entity';
|
|
45
|
+
import { InProcessAdapter, NestBatchModule } from '@nest-batch/core';
|
|
46
|
+
import { MikroOrmAdapter } from '@nest-batch/mikro-orm';
|
|
203
47
|
|
|
204
48
|
@Module({
|
|
205
49
|
imports: [
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
50
|
+
NestBatchModule.forRoot({
|
|
51
|
+
adapters: {
|
|
52
|
+
persistence: MikroOrmAdapter.forRoot(),
|
|
53
|
+
transport: InProcessAdapter.forRoot(),
|
|
54
|
+
},
|
|
209
55
|
}),
|
|
210
|
-
NestBatchModule.forRoot(),
|
|
211
|
-
],
|
|
212
|
-
providers: [
|
|
213
|
-
{ provide: JobRepository, useClass: MikroORMJobRepository },
|
|
214
|
-
{ provide: TransactionManager, useClass: MikroORMTransactionManager },
|
|
215
|
-
InProcessExecutionStrategy,
|
|
216
|
-
IN_PROCESS_EXECUTION_STRATEGY_PROVIDER,
|
|
217
56
|
],
|
|
218
57
|
})
|
|
219
58
|
export class AppModule {}
|
|
220
59
|
```
|
|
221
60
|
|
|
222
|
-
`
|
|
223
|
-
|
|
224
|
-
`BatchExplorer`, `FlowEvaluator`, and `BatchScheduleRegistry` so
|
|
225
|
-
consumers can inject them from outside.
|
|
61
|
+
`InProcessAdapter` is included in this package. Other transport adapters are
|
|
62
|
+
available as sibling packages.
|
|
226
63
|
|
|
227
|
-
|
|
228
|
-
need to come from a config service or another async source:
|
|
64
|
+
## Define a Job
|
|
229
65
|
|
|
230
66
|
```ts
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
67
|
+
import { Injectable } from '@nestjs/common';
|
|
68
|
+
import { Batch } from '@nest-batch/core';
|
|
69
|
+
|
|
70
|
+
@Injectable()
|
|
71
|
+
@Batch.Jobable({ id: 'send-digest', restartable: true })
|
|
72
|
+
export class SendDigestJob {
|
|
73
|
+
@Batch.Stepable({ id: 'send' })
|
|
74
|
+
@Batch.Tasklet()
|
|
75
|
+
async send(): Promise<void> {
|
|
76
|
+
await sendDigestEmails();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
241
79
|
```
|
|
242
80
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
## Listener resolver
|
|
81
|
+
Register the job class as a Nest provider. `NestBatchModule` discovers
|
|
82
|
+
registered `@Batch.Jobable` providers when the application boots.
|
|
246
83
|
|
|
247
|
-
|
|
248
|
-
`BatchExplorer` finds, reading the `BATCH_LISTENER_METADATA` slot from
|
|
249
|
-
each method, and building a per-job, per-step resolver map. The map
|
|
250
|
-
is populated once at `OnApplicationBootstrap` (see
|
|
251
|
-
`BatchBootstrapper`) and is read on every transition.
|
|
252
|
-
|
|
253
|
-
Critical vs non-critical semantics:
|
|
254
|
-
|
|
255
|
-
- A **critical** listener that throws fails the execution. The
|
|
256
|
-
executor records the failure and the listener exception is part of
|
|
257
|
-
the failure context.
|
|
258
|
-
- A **non-critical** listener that throws is logged and contained. The
|
|
259
|
-
execution continues.
|
|
260
|
-
|
|
261
|
-
The two paths are separated on purpose. Critical listener failures
|
|
262
|
-
should be loud, non-critical ones should not poison the run.
|
|
263
|
-
|
|
264
|
-
---
|
|
265
|
-
|
|
266
|
-
## Contract suite
|
|
267
|
-
|
|
268
|
-
`@nest-batch/core` ships a contract suite that the adapter packages
|
|
269
|
-
use to prove they implement the repository and transaction
|
|
270
|
-
contracts correctly. It is exposed at
|
|
271
|
-
`@nest-batch/core/test-contracts`:
|
|
84
|
+
## Launch and Inspect
|
|
272
85
|
|
|
273
86
|
```ts
|
|
274
|
-
|
|
275
|
-
runJobRepositoryContract,
|
|
276
|
-
runTransactionManagerContract,
|
|
277
|
-
} from '@nest-batch/core/test-contracts';
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
The contract covers:
|
|
87
|
+
await jobLauncher.launch('send-digest', { businessDate: '2026-06-25' });
|
|
281
88
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
- `createStepExecution` / `updateStepExecution` / `getStepExecution` — same for step rows.
|
|
286
|
-
- `getExecutionContext` / `saveExecutionContext` — versioning, optimistic concurrency.
|
|
287
|
-
- `findLatestStepExecution` — restart/checkpoint lookup; must return
|
|
288
|
-
the most recent `StepExecution` for `(jobExecutionId, stepName)`.
|
|
289
|
-
- `TransactionManager` — wrap / commit / rollback / nested.
|
|
290
|
-
|
|
291
|
-
`@nest-batch/mikro-orm` and `@nest-batch/typeorm` both run this suite
|
|
292
|
-
against their implementations. The in-memory reference implementation
|
|
293
|
-
in core also passes it. If you write a custom adapter, the suite is
|
|
294
|
-
how you prove it satisfies the contract.
|
|
295
|
-
|
|
296
|
-
---
|
|
297
|
-
|
|
298
|
-
## Public API surface
|
|
299
|
-
|
|
300
|
-
Everything in `@nest-batch/core` is reachable from the package root.
|
|
301
|
-
The barrel re-exports:
|
|
302
|
-
|
|
303
|
-
- `./core` — IR (`JobDefinition`, `StepDefinition`, ...), errors, status, execution context, item interfaces, repository/transaction contracts.
|
|
304
|
-
- `./compiler` — turns discovered jobs into compiled IR.
|
|
305
|
-
- `./registry` — `JobRegistry` and friends.
|
|
306
|
-
- `./execution` — `JobLauncher`, `JobExecutor`, `InProcessExecutionStrategy`, `IExecutionStrategy`, `EXECUTION_STRATEGY`, `ChunkStepExecutor`, `TaskletStepExecutor`, `ListenerInvoker`, `RefResolver`.
|
|
307
|
-
- `./transaction` — `TransactionManager` token and contract.
|
|
308
|
-
- `./repository` — `JobRepository` token, contract, in-memory reference, ID generators.
|
|
309
|
-
- `./decorators` — under the `Batch` namespace (`@Jobable`, `@ItemReader`, `@ItemProcessor`, `@ItemWriter`, `@Tasklet`, listener decorators).
|
|
310
|
-
- `./scheduling/batch-scheduled` — `@BatchScheduled` and its schedule option/error types are also re-exported directly from the package root.
|
|
311
|
-
- `./module` — `NestBatchModule`, tokens, options.
|
|
312
|
-
- `./builder` — fluent `BatchBuilder`, `JobBuilder`, `StepBuilder`, `FlowBuilder`.
|
|
313
|
-
- `./explorer` — `BatchExplorer` (the metadata scanner).
|
|
314
|
-
- `./listeners` — built-in `LoggingListener`, `MetricsListener`, `TimingListener` reference implementations.
|
|
315
|
-
- `./policies` — `LimitSkipPolicy`, `ClassifySkipPolicy`, retry policies, backoff helpers.
|
|
316
|
-
- `./flow` — `FlowEvaluator` for the `on` / `from` / `end` flow DSL.
|
|
317
|
-
- `./observability` — `BatchObserver` contract, `BATCH_EVENT` constants, `NoopBatchObserver` default.
|
|
318
|
-
|
|
319
|
-
Decorator names collide with interface names (e.g. `Tasklet` is both a
|
|
320
|
-
decorator and an interface). Decorators are re-exported under
|
|
321
|
-
`Batch`; interfaces are reachable as bare names from
|
|
322
|
-
`./core/item`. `BatchDecorators` remains available as a backward-compatible
|
|
323
|
-
alias. This is intentional.
|
|
324
|
-
|
|
325
|
-
---
|
|
326
|
-
|
|
327
|
-
## What is NOT in core
|
|
328
|
-
|
|
329
|
-
Core is the engine. The following live in sibling packages and are
|
|
330
|
-
injected at the DI boundary:
|
|
331
|
-
|
|
332
|
-
| Concern | Package | Why |
|
|
333
|
-
| ----------------------------- | ----------------------- | ----------------------------------------------------------------- |
|
|
334
|
-
| **Persistence (MikroORM)** | `@nest-batch/mikro-orm` | Exposes the batch meta entities; the host owns migrations. |
|
|
335
|
-
| **Persistence (TypeORM 1.0)** | `@nest-batch/typeorm` | Exposes the same table contract as TypeORM 1.0.0 entities. |
|
|
336
|
-
| **Transport (BullMQ)** | `@nest-batch/bullmq` | The Redis-backed execution strategy. Owns Queue/Worker lifecycle. |
|
|
337
|
-
| **Drizzle** | _not in this release_ | Explicitly excluded and deferred. See `MIGRATION.md`. |
|
|
338
|
-
|
|
339
|
-
Core itself does **not** ship:
|
|
340
|
-
|
|
341
|
-
- A default `JobRepository` (the choice of DB is the host's).
|
|
342
|
-
- A default `TransactionManager` (same).
|
|
343
|
-
- A default transport (in-process is the default; siblings override).
|
|
344
|
-
- An admin UI.
|
|
345
|
-
- A metrics backend (Prometheus, OpenTelemetry, ...).
|
|
346
|
-
- A tracing backend.
|
|
347
|
-
- A webhook or notification system.
|
|
348
|
-
- A job visualization dashboard.
|
|
349
|
-
- Multi-tenant routing.
|
|
350
|
-
|
|
351
|
-
These are out of scope by design. If you need one, write a
|
|
352
|
-
`BatchObserver` adapter that hooks into the event stream, or open an
|
|
353
|
-
issue if you think it belongs in core.
|
|
354
|
-
|
|
355
|
-
---
|
|
356
|
-
|
|
357
|
-
## Scripts
|
|
358
|
-
|
|
359
|
-
```bash
|
|
360
|
-
pnpm --filter @nest-batch/core build # SWC transpile + tsc declarations
|
|
361
|
-
pnpm --filter @nest-batch/core test # vitest run
|
|
362
|
-
pnpm --filter @nest-batch/core test:watch # vitest watch
|
|
363
|
-
pnpm --filter @nest-batch/core test:e2e # vitest e2e (requires Postgres/Redis)
|
|
364
|
-
pnpm --filter @nest-batch/core typecheck # tsc --noEmit
|
|
89
|
+
const executions = await jobExplorer.listJobExecutions({
|
|
90
|
+
status: 'COMPLETED',
|
|
91
|
+
});
|
|
365
92
|
```
|
|
366
93
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
forbidden integration package (`bullmq`, `mikro-orm`, `typeorm`,
|
|
370
|
-
`drizzle-orm`) shows up as a core import. The small `cron` dependency
|
|
371
|
-
is intentionally allowed for the built-in in-process scheduler bridge.
|
|
94
|
+
`JobLauncher` starts work, `JobExplorer` reads durable state, and `JobOperator`
|
|
95
|
+
provides stop, restart, abandon, and start-next-instance operations.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nest-batch/core",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "Batch processing engine for NestJS — jobs, steps, chunk-oriented processing, and the persistence/transport contracts the @nest-batch adapters implement.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "easdkr",
|
|
@@ -28,7 +28,8 @@
|
|
|
28
28
|
"dist/src",
|
|
29
29
|
"dist/tests/contracts",
|
|
30
30
|
"src",
|
|
31
|
-
"README.md"
|
|
31
|
+
"README.md",
|
|
32
|
+
"README.ko.md"
|
|
32
33
|
],
|
|
33
34
|
"exports": {
|
|
34
35
|
".": {
|