@nest-batch/core 0.2.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 (476) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +368 -0
  3. package/dist/src/adapters/in-process.adapter.d.ts +140 -0
  4. package/dist/src/adapters/in-process.adapter.d.ts.map +1 -0
  5. package/dist/src/adapters/in-process.adapter.js +86 -0
  6. package/dist/src/adapters/in-process.adapter.js.map +1 -0
  7. package/dist/src/adapters/index.d.ts +18 -0
  8. package/dist/src/adapters/index.d.ts.map +1 -0
  9. package/dist/src/adapters/index.js +35 -0
  10. package/dist/src/adapters/index.js.map +1 -0
  11. package/dist/src/builder/batch-builder.d.ts +26 -0
  12. package/dist/src/builder/batch-builder.d.ts.map +1 -0
  13. package/dist/src/builder/batch-builder.js +25 -0
  14. package/dist/src/builder/batch-builder.js.map +1 -0
  15. package/dist/src/builder/flow-builder.d.ts +59 -0
  16. package/dist/src/builder/flow-builder.d.ts.map +1 -0
  17. package/dist/src/builder/flow-builder.js +115 -0
  18. package/dist/src/builder/flow-builder.js.map +1 -0
  19. package/dist/src/builder/index.d.ts +5 -0
  20. package/dist/src/builder/index.d.ts.map +1 -0
  21. package/dist/src/builder/index.js +23 -0
  22. package/dist/src/builder/index.js.map +1 -0
  23. package/dist/src/builder/job-builder.d.ts +76 -0
  24. package/dist/src/builder/job-builder.d.ts.map +1 -0
  25. package/dist/src/builder/job-builder.js +166 -0
  26. package/dist/src/builder/job-builder.js.map +1 -0
  27. package/dist/src/builder/step-builder.d.ts +74 -0
  28. package/dist/src/builder/step-builder.d.ts.map +1 -0
  29. package/dist/src/builder/step-builder.js +144 -0
  30. package/dist/src/builder/step-builder.js.map +1 -0
  31. package/dist/src/compiler/builder-types.d.ts +20 -0
  32. package/dist/src/compiler/builder-types.d.ts.map +1 -0
  33. package/dist/src/compiler/builder-types.js +6 -0
  34. package/dist/src/compiler/builder-types.js.map +1 -0
  35. package/dist/src/compiler/definition-compiler.d.ts +99 -0
  36. package/dist/src/compiler/definition-compiler.d.ts.map +1 -0
  37. package/dist/src/compiler/definition-compiler.js +257 -0
  38. package/dist/src/compiler/definition-compiler.js.map +1 -0
  39. package/dist/src/compiler/index.d.ts +3 -0
  40. package/dist/src/compiler/index.d.ts.map +1 -0
  41. package/dist/src/compiler/index.js +21 -0
  42. package/dist/src/compiler/index.js.map +1 -0
  43. package/dist/src/core/errors.d.ts +77 -0
  44. package/dist/src/core/errors.d.ts.map +1 -0
  45. package/dist/src/core/errors.js +170 -0
  46. package/dist/src/core/errors.js.map +1 -0
  47. package/dist/src/core/execution-context/index.d.ts +4 -0
  48. package/dist/src/core/execution-context/index.d.ts.map +1 -0
  49. package/dist/src/core/execution-context/index.js +22 -0
  50. package/dist/src/core/execution-context/index.js.map +1 -0
  51. package/dist/src/core/execution-context/json-value.d.ts +5 -0
  52. package/dist/src/core/execution-context/json-value.d.ts.map +1 -0
  53. package/dist/src/core/execution-context/json-value.js +6 -0
  54. package/dist/src/core/execution-context/json-value.js.map +1 -0
  55. package/dist/src/core/execution-context/serializer.d.ts +4 -0
  56. package/dist/src/core/execution-context/serializer.d.ts.map +1 -0
  57. package/dist/src/core/execution-context/serializer.js +34 -0
  58. package/dist/src/core/execution-context/serializer.js.map +1 -0
  59. package/dist/src/core/execution-context/validator.d.ts +18 -0
  60. package/dist/src/core/execution-context/validator.d.ts.map +1 -0
  61. package/dist/src/core/execution-context/validator.js +90 -0
  62. package/dist/src/core/execution-context/validator.js.map +1 -0
  63. package/dist/src/core/index.d.ts +8 -0
  64. package/dist/src/core/index.d.ts.map +1 -0
  65. package/dist/src/core/index.js +26 -0
  66. package/dist/src/core/index.js.map +1 -0
  67. package/dist/src/core/ir/decider-definition.d.ts +20 -0
  68. package/dist/src/core/ir/decider-definition.d.ts.map +1 -0
  69. package/dist/src/core/ir/decider-definition.js +6 -0
  70. package/dist/src/core/ir/decider-definition.js.map +1 -0
  71. package/dist/src/core/ir/index.d.ts +8 -0
  72. package/dist/src/core/ir/index.d.ts.map +1 -0
  73. package/dist/src/core/ir/index.js +26 -0
  74. package/dist/src/core/ir/index.js.map +1 -0
  75. package/dist/src/core/ir/job-definition.d.ts +15 -0
  76. package/dist/src/core/ir/job-definition.d.ts.map +1 -0
  77. package/dist/src/core/ir/job-definition.js +6 -0
  78. package/dist/src/core/ir/job-definition.js.map +1 -0
  79. package/dist/src/core/ir/listener-definition.d.ts +10 -0
  80. package/dist/src/core/ir/listener-definition.d.ts.map +1 -0
  81. package/dist/src/core/ir/listener-definition.js +6 -0
  82. package/dist/src/core/ir/listener-definition.js.map +1 -0
  83. package/dist/src/core/ir/policy-config.d.ts +24 -0
  84. package/dist/src/core/ir/policy-config.d.ts.map +1 -0
  85. package/dist/src/core/ir/policy-config.js +6 -0
  86. package/dist/src/core/ir/policy-config.js.map +1 -0
  87. package/dist/src/core/ir/refs.d.ts +42 -0
  88. package/dist/src/core/ir/refs.d.ts.map +1 -0
  89. package/dist/src/core/ir/refs.js +18 -0
  90. package/dist/src/core/ir/refs.js.map +1 -0
  91. package/dist/src/core/ir/step-definition.d.ts +59 -0
  92. package/dist/src/core/ir/step-definition.d.ts.map +1 -0
  93. package/dist/src/core/ir/step-definition.js +6 -0
  94. package/dist/src/core/ir/step-definition.js.map +1 -0
  95. package/dist/src/core/ir/transition-definition.d.ts +8 -0
  96. package/dist/src/core/ir/transition-definition.d.ts.map +1 -0
  97. package/dist/src/core/ir/transition-definition.js +6 -0
  98. package/dist/src/core/ir/transition-definition.js.map +1 -0
  99. package/dist/src/core/item/index.d.ts +2 -0
  100. package/dist/src/core/item/index.d.ts.map +1 -0
  101. package/dist/src/core/item/index.js +20 -0
  102. package/dist/src/core/item/index.js.map +1 -0
  103. package/dist/src/core/item/interfaces.d.ts +64 -0
  104. package/dist/src/core/item/interfaces.d.ts.map +1 -0
  105. package/dist/src/core/item/interfaces.js +6 -0
  106. package/dist/src/core/item/interfaces.js.map +1 -0
  107. package/dist/src/core/repository/index.d.ts +3 -0
  108. package/dist/src/core/repository/index.d.ts.map +1 -0
  109. package/dist/src/core/repository/index.js +21 -0
  110. package/dist/src/core/repository/index.js.map +1 -0
  111. package/dist/src/core/repository/job-repository.d.ts +60 -0
  112. package/dist/src/core/repository/job-repository.d.ts.map +1 -0
  113. package/dist/src/core/repository/job-repository.js +27 -0
  114. package/dist/src/core/repository/job-repository.js.map +1 -0
  115. package/dist/src/core/repository/types.d.ts +84 -0
  116. package/dist/src/core/repository/types.d.ts.map +1 -0
  117. package/dist/src/core/repository/types.js +6 -0
  118. package/dist/src/core/repository/types.js.map +1 -0
  119. package/dist/src/core/status.d.ts +29 -0
  120. package/dist/src/core/status.d.ts.map +1 -0
  121. package/dist/src/core/status.js +58 -0
  122. package/dist/src/core/status.js.map +1 -0
  123. package/dist/src/core/transaction/index.d.ts +2 -0
  124. package/dist/src/core/transaction/index.d.ts.map +1 -0
  125. package/dist/src/core/transaction/index.js +20 -0
  126. package/dist/src/core/transaction/index.js.map +1 -0
  127. package/dist/src/core/transaction/transaction-manager.d.ts +8 -0
  128. package/dist/src/core/transaction/transaction-manager.d.ts.map +1 -0
  129. package/dist/src/core/transaction/transaction-manager.js +14 -0
  130. package/dist/src/core/transaction/transaction-manager.js.map +1 -0
  131. package/dist/src/core/validation/definition-validator.d.ts +46 -0
  132. package/dist/src/core/validation/definition-validator.d.ts.map +1 -0
  133. package/dist/src/core/validation/definition-validator.js +177 -0
  134. package/dist/src/core/validation/definition-validator.js.map +1 -0
  135. package/dist/src/core/validation/index.d.ts +2 -0
  136. package/dist/src/core/validation/index.d.ts.map +1 -0
  137. package/dist/src/core/validation/index.js +20 -0
  138. package/dist/src/core/validation/index.js.map +1 -0
  139. package/dist/src/decorators/constants.d.ts +10 -0
  140. package/dist/src/decorators/constants.d.ts.map +1 -0
  141. package/dist/src/decorators/constants.js +50 -0
  142. package/dist/src/decorators/constants.js.map +1 -0
  143. package/dist/src/decorators/flow.decorator.d.ts +25 -0
  144. package/dist/src/decorators/flow.decorator.d.ts.map +1 -0
  145. package/dist/src/decorators/flow.decorator.js +19 -0
  146. package/dist/src/decorators/flow.decorator.js.map +1 -0
  147. package/dist/src/decorators/index.d.ts +8 -0
  148. package/dist/src/decorators/index.d.ts.map +1 -0
  149. package/dist/src/decorators/index.js +26 -0
  150. package/dist/src/decorators/index.js.map +1 -0
  151. package/dist/src/decorators/item.decorators.d.ts +32 -0
  152. package/dist/src/decorators/item.decorators.d.ts.map +1 -0
  153. package/dist/src/decorators/item.decorators.js +40 -0
  154. package/dist/src/decorators/item.decorators.js.map +1 -0
  155. package/dist/src/decorators/job.decorator.d.ts +11 -0
  156. package/dist/src/decorators/job.decorator.d.ts.map +1 -0
  157. package/dist/src/decorators/job.decorator.js +17 -0
  158. package/dist/src/decorators/job.decorator.js.map +1 -0
  159. package/dist/src/decorators/listener.decorators.d.ts +56 -0
  160. package/dist/src/decorators/listener.decorators.d.ts.map +1 -0
  161. package/dist/src/decorators/listener.decorators.js +157 -0
  162. package/dist/src/decorators/listener.decorators.js.map +1 -0
  163. package/dist/src/decorators/step.decorator.d.ts +25 -0
  164. package/dist/src/decorators/step.decorator.d.ts.map +1 -0
  165. package/dist/src/decorators/step.decorator.js +21 -0
  166. package/dist/src/decorators/step.decorator.js.map +1 -0
  167. package/dist/src/decorators/tasklet.decorator.d.ts +7 -0
  168. package/dist/src/decorators/tasklet.decorator.d.ts.map +1 -0
  169. package/dist/src/decorators/tasklet.decorator.js +21 -0
  170. package/dist/src/decorators/tasklet.decorator.js.map +1 -0
  171. package/dist/src/execution/batch-worker-runner.d.ts +27 -0
  172. package/dist/src/execution/batch-worker-runner.d.ts.map +1 -0
  173. package/dist/src/execution/batch-worker-runner.js +147 -0
  174. package/dist/src/execution/batch-worker-runner.js.map +1 -0
  175. package/dist/src/execution/chunk-step-executor.d.ts +86 -0
  176. package/dist/src/execution/chunk-step-executor.d.ts.map +1 -0
  177. package/dist/src/execution/chunk-step-executor.js +482 -0
  178. package/dist/src/execution/chunk-step-executor.js.map +1 -0
  179. package/dist/src/execution/execution-strategy.d.ts +110 -0
  180. package/dist/src/execution/execution-strategy.d.ts.map +1 -0
  181. package/dist/src/execution/execution-strategy.js +13 -0
  182. package/dist/src/execution/execution-strategy.js.map +1 -0
  183. package/dist/src/execution/external-task-execution-strategy.d.ts +36 -0
  184. package/dist/src/execution/external-task-execution-strategy.d.ts.map +1 -0
  185. package/dist/src/execution/external-task-execution-strategy.js +97 -0
  186. package/dist/src/execution/external-task-execution-strategy.js.map +1 -0
  187. package/dist/src/execution/in-process-execution-strategy.d.ts +129 -0
  188. package/dist/src/execution/in-process-execution-strategy.d.ts.map +1 -0
  189. package/dist/src/execution/in-process-execution-strategy.js +141 -0
  190. package/dist/src/execution/in-process-execution-strategy.js.map +1 -0
  191. package/dist/src/execution/index.d.ts +14 -0
  192. package/dist/src/execution/index.d.ts.map +1 -0
  193. package/dist/src/execution/index.js +32 -0
  194. package/dist/src/execution/index.js.map +1 -0
  195. package/dist/src/execution/job-executor.d.ts +145 -0
  196. package/dist/src/execution/job-executor.d.ts.map +1 -0
  197. package/dist/src/execution/job-executor.js +475 -0
  198. package/dist/src/execution/job-executor.js.map +1 -0
  199. package/dist/src/execution/job-explorer.d.ts +15 -0
  200. package/dist/src/execution/job-explorer.d.ts.map +1 -0
  201. package/dist/src/execution/job-explorer.js +84 -0
  202. package/dist/src/execution/job-explorer.js.map +1 -0
  203. package/dist/src/execution/job-key.d.ts +3 -0
  204. package/dist/src/execution/job-key.d.ts.map +1 -0
  205. package/dist/src/execution/job-key.js +43 -0
  206. package/dist/src/execution/job-key.js.map +1 -0
  207. package/dist/src/execution/job-launcher.d.ts +75 -0
  208. package/dist/src/execution/job-launcher.d.ts.map +1 -0
  209. package/dist/src/execution/job-launcher.js +112 -0
  210. package/dist/src/execution/job-launcher.js.map +1 -0
  211. package/dist/src/execution/job-operator.d.ts +22 -0
  212. package/dist/src/execution/job-operator.d.ts.map +1 -0
  213. package/dist/src/execution/job-operator.js +125 -0
  214. package/dist/src/execution/job-operator.js.map +1 -0
  215. package/dist/src/execution/listener-invoker.d.ts +164 -0
  216. package/dist/src/execution/listener-invoker.d.ts.map +1 -0
  217. package/dist/src/execution/listener-invoker.js +246 -0
  218. package/dist/src/execution/listener-invoker.js.map +1 -0
  219. package/dist/src/execution/ref-resolver.d.ts +40 -0
  220. package/dist/src/execution/ref-resolver.d.ts.map +1 -0
  221. package/dist/src/execution/ref-resolver.js +41 -0
  222. package/dist/src/execution/ref-resolver.js.map +1 -0
  223. package/dist/src/execution/tasklet-step-executor.d.ts +79 -0
  224. package/dist/src/execution/tasklet-step-executor.d.ts.map +1 -0
  225. package/dist/src/execution/tasklet-step-executor.js +138 -0
  226. package/dist/src/execution/tasklet-step-executor.js.map +1 -0
  227. package/dist/src/explorer/batch-explorer.d.ts +138 -0
  228. package/dist/src/explorer/batch-explorer.d.ts.map +1 -0
  229. package/dist/src/explorer/batch-explorer.js +167 -0
  230. package/dist/src/explorer/batch-explorer.js.map +1 -0
  231. package/dist/src/explorer/index.d.ts +2 -0
  232. package/dist/src/explorer/index.d.ts.map +1 -0
  233. package/dist/src/explorer/index.js +20 -0
  234. package/dist/src/explorer/index.js.map +1 -0
  235. package/dist/src/flow/flow-evaluator.d.ts +30 -0
  236. package/dist/src/flow/flow-evaluator.d.ts.map +1 -0
  237. package/dist/src/flow/flow-evaluator.js +80 -0
  238. package/dist/src/flow/flow-evaluator.js.map +1 -0
  239. package/dist/src/flow/index.d.ts +2 -0
  240. package/dist/src/flow/index.d.ts.map +1 -0
  241. package/dist/src/flow/index.js +20 -0
  242. package/dist/src/flow/index.js.map +1 -0
  243. package/dist/src/index.d.ts +18 -0
  244. package/dist/src/index.d.ts.map +1 -0
  245. package/dist/src/index.js +90 -0
  246. package/dist/src/index.js.map +1 -0
  247. package/dist/src/io/checkpoint.d.ts +7 -0
  248. package/dist/src/io/checkpoint.d.ts.map +1 -0
  249. package/dist/src/io/checkpoint.js +56 -0
  250. package/dist/src/io/checkpoint.js.map +1 -0
  251. package/dist/src/io/database.d.ts +50 -0
  252. package/dist/src/io/database.d.ts.map +1 -0
  253. package/dist/src/io/database.js +108 -0
  254. package/dist/src/io/database.js.map +1 -0
  255. package/dist/src/io/file-readers.d.ts +54 -0
  256. package/dist/src/io/file-readers.d.ts.map +1 -0
  257. package/dist/src/io/file-readers.js +167 -0
  258. package/dist/src/io/file-readers.js.map +1 -0
  259. package/dist/src/io/file-writers.d.ts +31 -0
  260. package/dist/src/io/file-writers.d.ts.map +1 -0
  261. package/dist/src/io/file-writers.js +80 -0
  262. package/dist/src/io/file-writers.js.map +1 -0
  263. package/dist/src/io/index.d.ts +6 -0
  264. package/dist/src/io/index.d.ts.map +1 -0
  265. package/dist/src/io/index.js +24 -0
  266. package/dist/src/io/index.js.map +1 -0
  267. package/dist/src/io/s3.d.ts +50 -0
  268. package/dist/src/io/s3.d.ts.map +1 -0
  269. package/dist/src/io/s3.js +96 -0
  270. package/dist/src/io/s3.js.map +1 -0
  271. package/dist/src/listeners/builtin-listeners.d.ts +77 -0
  272. package/dist/src/listeners/builtin-listeners.d.ts.map +1 -0
  273. package/dist/src/listeners/builtin-listeners.js +108 -0
  274. package/dist/src/listeners/builtin-listeners.js.map +1 -0
  275. package/dist/src/listeners/index.d.ts +8 -0
  276. package/dist/src/listeners/index.d.ts.map +1 -0
  277. package/dist/src/listeners/index.js +25 -0
  278. package/dist/src/listeners/index.js.map +1 -0
  279. package/dist/src/module/adapter-options.d.ts +39 -0
  280. package/dist/src/module/adapter-options.d.ts.map +1 -0
  281. package/dist/src/module/adapter-options.js +34 -0
  282. package/dist/src/module/adapter-options.js.map +1 -0
  283. package/dist/src/module/adapter.d.ts +157 -0
  284. package/dist/src/module/adapter.d.ts.map +1 -0
  285. package/dist/src/module/adapter.js +80 -0
  286. package/dist/src/module/adapter.js.map +1 -0
  287. package/dist/src/module/batch-schedule-registry.d.ts +110 -0
  288. package/dist/src/module/batch-schedule-registry.d.ts.map +1 -0
  289. package/dist/src/module/batch-schedule-registry.js +0 -0
  290. package/dist/src/module/batch-schedule-registry.js.map +1 -0
  291. package/dist/src/module/index.d.ts +14 -0
  292. package/dist/src/module/index.d.ts.map +1 -0
  293. package/dist/src/module/index.js +31 -0
  294. package/dist/src/module/index.js.map +1 -0
  295. package/dist/src/module/nest-batch.module.d.ts +236 -0
  296. package/dist/src/module/nest-batch.module.d.ts.map +1 -0
  297. package/dist/src/module/nest-batch.module.js +475 -0
  298. package/dist/src/module/nest-batch.module.js.map +1 -0
  299. package/dist/src/module/tokens.d.ts +83 -0
  300. package/dist/src/module/tokens.d.ts.map +1 -0
  301. package/dist/src/module/tokens.js +58 -0
  302. package/dist/src/module/tokens.js.map +1 -0
  303. package/dist/src/observability/event-types.d.ts +55 -0
  304. package/dist/src/observability/event-types.d.ts.map +1 -0
  305. package/dist/src/observability/event-types.js +36 -0
  306. package/dist/src/observability/event-types.js.map +1 -0
  307. package/dist/src/observability/exporters.d.ts +35 -0
  308. package/dist/src/observability/exporters.d.ts.map +1 -0
  309. package/dist/src/observability/exporters.js +93 -0
  310. package/dist/src/observability/exporters.js.map +1 -0
  311. package/dist/src/observability/index.d.ts +3 -0
  312. package/dist/src/observability/index.d.ts.map +1 -0
  313. package/dist/src/observability/index.js +21 -0
  314. package/dist/src/observability/index.js.map +1 -0
  315. package/dist/src/partition-helpers.d.ts +127 -0
  316. package/dist/src/partition-helpers.d.ts.map +1 -0
  317. package/dist/src/partition-helpers.js +136 -0
  318. package/dist/src/partition-helpers.js.map +1 -0
  319. package/dist/src/policies/backoff.d.ts +3 -0
  320. package/dist/src/policies/backoff.d.ts.map +1 -0
  321. package/dist/src/policies/backoff.js +34 -0
  322. package/dist/src/policies/backoff.js.map +1 -0
  323. package/dist/src/policies/index.d.ts +4 -0
  324. package/dist/src/policies/index.d.ts.map +1 -0
  325. package/dist/src/policies/index.js +22 -0
  326. package/dist/src/policies/index.js.map +1 -0
  327. package/dist/src/policies/retry-policy.d.ts +13 -0
  328. package/dist/src/policies/retry-policy.d.ts.map +1 -0
  329. package/dist/src/policies/retry-policy.js +55 -0
  330. package/dist/src/policies/retry-policy.js.map +1 -0
  331. package/dist/src/policies/skip-policy.d.ts +12 -0
  332. package/dist/src/policies/skip-policy.d.ts.map +1 -0
  333. package/dist/src/policies/skip-policy.js +44 -0
  334. package/dist/src/policies/skip-policy.js.map +1 -0
  335. package/dist/src/registry/index.d.ts +2 -0
  336. package/dist/src/registry/index.d.ts.map +1 -0
  337. package/dist/src/registry/index.js +20 -0
  338. package/dist/src/registry/index.js.map +1 -0
  339. package/dist/src/registry/job-registry.d.ts +16 -0
  340. package/dist/src/registry/job-registry.d.ts.map +1 -0
  341. package/dist/src/registry/job-registry.js +50 -0
  342. package/dist/src/registry/job-registry.js.map +1 -0
  343. package/dist/src/repository/id-generator.d.ts +18 -0
  344. package/dist/src/repository/id-generator.d.ts.map +1 -0
  345. package/dist/src/repository/id-generator.js +37 -0
  346. package/dist/src/repository/id-generator.js.map +1 -0
  347. package/dist/src/repository/in-memory/in-memory-job-repository.d.ts +49 -0
  348. package/dist/src/repository/in-memory/in-memory-job-repository.d.ts.map +1 -0
  349. package/dist/src/repository/in-memory/in-memory-job-repository.js +291 -0
  350. package/dist/src/repository/in-memory/in-memory-job-repository.js.map +1 -0
  351. package/dist/src/repository/in-memory/index.d.ts +2 -0
  352. package/dist/src/repository/in-memory/index.d.ts.map +1 -0
  353. package/dist/src/repository/in-memory/index.js +20 -0
  354. package/dist/src/repository/in-memory/index.js.map +1 -0
  355. package/dist/src/repository/index.d.ts +4 -0
  356. package/dist/src/repository/index.d.ts.map +1 -0
  357. package/dist/src/repository/index.js +22 -0
  358. package/dist/src/repository/index.js.map +1 -0
  359. package/dist/src/repository/uuid-v7.d.ts +20 -0
  360. package/dist/src/repository/uuid-v7.d.ts.map +1 -0
  361. package/dist/src/repository/uuid-v7.js +31 -0
  362. package/dist/src/repository/uuid-v7.js.map +1 -0
  363. package/dist/src/scheduling/batch-scheduled.d.ts +87 -0
  364. package/dist/src/scheduling/batch-scheduled.d.ts.map +1 -0
  365. package/dist/src/scheduling/batch-scheduled.js +170 -0
  366. package/dist/src/scheduling/batch-scheduled.js.map +1 -0
  367. package/dist/src/transaction/in-memory-transaction-manager.d.ts +16 -0
  368. package/dist/src/transaction/in-memory-transaction-manager.d.ts.map +1 -0
  369. package/dist/src/transaction/in-memory-transaction-manager.js +33 -0
  370. package/dist/src/transaction/in-memory-transaction-manager.js.map +1 -0
  371. package/dist/src/transaction/index.d.ts +2 -0
  372. package/dist/src/transaction/index.d.ts.map +1 -0
  373. package/dist/src/transaction/index.js +20 -0
  374. package/dist/src/transaction/index.js.map +1 -0
  375. package/dist/tests/contracts/index.d.ts +26 -0
  376. package/dist/tests/contracts/index.d.ts.map +1 -0
  377. package/dist/tests/contracts/index.js +37 -0
  378. package/dist/tests/contracts/index.js.map +1 -0
  379. package/dist/tests/contracts/job-repository.contract.d.ts +46 -0
  380. package/dist/tests/contracts/job-repository.contract.d.ts.map +1 -0
  381. package/dist/tests/contracts/job-repository.contract.js +644 -0
  382. package/dist/tests/contracts/job-repository.contract.js.map +1 -0
  383. package/package.json +80 -0
  384. package/src/adapters/in-process.adapter.ts +182 -0
  385. package/src/adapters/index.ts +17 -0
  386. package/src/builder/batch-builder.ts +32 -0
  387. package/src/builder/flow-builder.ts +141 -0
  388. package/src/builder/index.ts +4 -0
  389. package/src/builder/job-builder.ts +206 -0
  390. package/src/builder/step-builder.ts +190 -0
  391. package/src/compiler/builder-types.ts +27 -0
  392. package/src/compiler/definition-compiler.ts +325 -0
  393. package/src/compiler/index.ts +2 -0
  394. package/src/core/errors.ts +125 -0
  395. package/src/core/execution-context/index.ts +3 -0
  396. package/src/core/execution-context/json-value.ts +3 -0
  397. package/src/core/execution-context/serializer.ts +21 -0
  398. package/src/core/execution-context/validator.ts +103 -0
  399. package/src/core/index.ts +7 -0
  400. package/src/core/ir/decider-definition.ts +25 -0
  401. package/src/core/ir/index.ts +7 -0
  402. package/src/core/ir/job-definition.ts +15 -0
  403. package/src/core/ir/listener-definition.ts +19 -0
  404. package/src/core/ir/policy-config.ts +19 -0
  405. package/src/core/ir/refs.ts +42 -0
  406. package/src/core/ir/step-definition.ts +62 -0
  407. package/src/core/ir/transition-definition.ts +9 -0
  408. package/src/core/item/index.ts +1 -0
  409. package/src/core/item/interfaces.ts +70 -0
  410. package/src/core/repository/index.ts +2 -0
  411. package/src/core/repository/job-repository.ts +100 -0
  412. package/src/core/repository/types.ts +91 -0
  413. package/src/core/status.ts +31 -0
  414. package/src/core/transaction/index.ts +1 -0
  415. package/src/core/transaction/transaction-manager.ts +8 -0
  416. package/src/core/validation/definition-validator.ts +215 -0
  417. package/src/core/validation/index.ts +1 -0
  418. package/src/decorators/constants.ts +9 -0
  419. package/src/decorators/flow.decorator.ts +31 -0
  420. package/src/decorators/index.ts +7 -0
  421. package/src/decorators/item.decorators.ts +51 -0
  422. package/src/decorators/job.decorator.ts +16 -0
  423. package/src/decorators/listener.decorators.ts +142 -0
  424. package/src/decorators/step.decorator.ts +33 -0
  425. package/src/decorators/tasklet.decorator.ts +14 -0
  426. package/src/execution/batch-worker-runner.ts +142 -0
  427. package/src/execution/chunk-step-executor.ts +594 -0
  428. package/src/execution/execution-strategy.ts +115 -0
  429. package/src/execution/external-task-execution-strategy.ts +104 -0
  430. package/src/execution/in-process-execution-strategy.ts +207 -0
  431. package/src/execution/index.ts +13 -0
  432. package/src/execution/job-executor.ts +553 -0
  433. package/src/execution/job-explorer.ts +73 -0
  434. package/src/execution/job-key.ts +35 -0
  435. package/src/execution/job-launcher.ts +132 -0
  436. package/src/execution/job-operator.ts +127 -0
  437. package/src/execution/listener-invoker.ts +389 -0
  438. package/src/execution/ref-resolver.ts +64 -0
  439. package/src/execution/tasklet-step-executor.ts +182 -0
  440. package/src/explorer/batch-explorer.ts +251 -0
  441. package/src/explorer/index.ts +1 -0
  442. package/src/flow/flow-evaluator.ts +89 -0
  443. package/src/flow/index.ts +1 -0
  444. package/src/index.ts +24 -0
  445. package/src/io/checkpoint.ts +47 -0
  446. package/src/io/database.ts +114 -0
  447. package/src/io/file-readers.ts +191 -0
  448. package/src/io/file-writers.ts +99 -0
  449. package/src/io/index.ts +5 -0
  450. package/src/io/s3.ts +117 -0
  451. package/src/listeners/builtin-listeners.ts +151 -0
  452. package/src/listeners/index.ts +7 -0
  453. package/src/module/adapter-options.ts +38 -0
  454. package/src/module/adapter.ts +160 -0
  455. package/src/module/batch-schedule-registry.ts +0 -0
  456. package/src/module/index.ts +13 -0
  457. package/src/module/nest-batch.module.ts +674 -0
  458. package/src/module/tokens.ts +95 -0
  459. package/src/observability/event-types.ts +61 -0
  460. package/src/observability/exporters.ts +96 -0
  461. package/src/observability/index.ts +2 -0
  462. package/src/partition-helpers.ts +204 -0
  463. package/src/policies/backoff.ts +22 -0
  464. package/src/policies/index.ts +3 -0
  465. package/src/policies/retry-policy.ts +57 -0
  466. package/src/policies/skip-policy.ts +51 -0
  467. package/src/registry/index.ts +1 -0
  468. package/src/registry/job-registry.ts +42 -0
  469. package/src/repository/id-generator.ts +25 -0
  470. package/src/repository/in-memory/in-memory-job-repository.ts +334 -0
  471. package/src/repository/in-memory/index.ts +1 -0
  472. package/src/repository/index.ts +3 -0
  473. package/src/repository/uuid-v7.ts +40 -0
  474. package/src/scheduling/batch-scheduled.ts +257 -0
  475. package/src/transaction/in-memory-transaction-manager.ts +23 -0
  476. package/src/transaction/index.ts +1 -0
@@ -0,0 +1,325 @@
1
+ import 'reflect-metadata';
2
+ import { Injectable, Logger } from '@nestjs/common';
3
+ import {
4
+ RefKind,
5
+ type JobDefinition,
6
+ type StepDefinition,
7
+ type ChunkStepDefinition,
8
+ type TaskletStepDefinition,
9
+ type ReaderRef,
10
+ type ProcessorRef,
11
+ type WriterRef,
12
+ type TaskletRef,
13
+ type ListenerRef,
14
+ type ListenerDefinition,
15
+ type TransitionDefinition,
16
+ } from '../core/ir';
17
+ import { FlowExecutionStatus } from '../core/status';
18
+ import { BatchError, InvalidFlowGraphError } from '../core/errors';
19
+ import { DefinitionValidator } from '../core/validation/definition-validator';
20
+ import { validatePartitions, InvalidPartitionsError } from '../partition-helpers';
21
+ import type { DiscoveredJob } from '../explorer/batch-explorer';
22
+ import {
23
+ BATCH_ITEM_READER_METADATA,
24
+ BATCH_ITEM_PROCESSOR_METADATA,
25
+ BATCH_ITEM_WRITER_METADATA,
26
+ } from '../decorators/constants';
27
+ import type { JobBuilderConfig } from './builder-types';
28
+
29
+ /**
30
+ * Thrown when a chunk step on a discovered class cannot resolve a required
31
+ * item handler method (`@ItemReader` or `@ItemWriter`) on the class prototype.
32
+ *
33
+ * Distinct from `InvalidFlowGraphError` because this is a *static* class-shape
34
+ * problem (the class is missing a decorator), not a flow-graph problem
35
+ * (transitions, start, reachability). The `code` is stable for callers
36
+ * that want to switch on it.
37
+ */
38
+ export class ProviderNotFoundError extends BatchError {
39
+ readonly code = 'PROVIDER_NOT_FOUND';
40
+ constructor(token: string) {
41
+ super(`Provider not found: ${token}`, { token });
42
+ }
43
+ }
44
+
45
+ /**
46
+ * `DefinitionCompiler` is the bridge between metadata-rich sources
47
+ * (decorator-discovered classes, fluent builder configs) and the
48
+ * `JobDefinition` IR consumed by the rest of the runtime.
49
+ *
50
+ * Two compilation paths share the same output type:
51
+ *
52
+ * - `compileFromDiscovered(discovered)` walks the class prototype
53
+ * (resolved by `BatchExplorer` in Task 7) and binds reader /
54
+ * processor / writer / tasklet / listener methods into `Ref`s.
55
+ * - `compileFromBuilderConfig(config)` accepts a plain-data config
56
+ * from the builder API and copies it into a `JobDefinition`.
57
+ *
58
+ * Both paths run the same `DefinitionValidator` before returning, so
59
+ * downstream consumers can assume the IR is structurally sound.
60
+ *
61
+ * The compiler does NOT register the job — that is `JobRegistry`'s job
62
+ * (Task 9). The compiler is pure: it produces IR, nothing else.
63
+ */
64
+ @Injectable()
65
+ export class DefinitionCompiler {
66
+ private readonly logger = new Logger(DefinitionCompiler.name);
67
+ private readonly validator = new DefinitionValidator();
68
+
69
+ /**
70
+ * Compile from a discovered class. Resolves reader/processor/writer methods
71
+ * on the class prototype and assembles StepDefinitions. Validates before returning.
72
+ */
73
+ compileFromDiscovered(discovered: DiscoveredJob): JobDefinition {
74
+ const steps: Record<string, StepDefinition> = {};
75
+ const startStepId = discovered.stepMethods[0]?.options.id ?? '';
76
+ const classToken = discovered.classRef.name;
77
+
78
+ for (const step of discovered.stepMethods) {
79
+ if (step.isTasklet) {
80
+ steps[step.options.id] = this.buildTaskletStep(discovered, classToken, step);
81
+ } else {
82
+ steps[step.options.id] = this.buildChunkStep(discovered, classToken, step);
83
+ }
84
+ }
85
+
86
+ const listenerDefs: ListenerDefinition[] = discovered.listenerMethods.map((l) => ({
87
+ kind: l.kind,
88
+ phase: l.phase,
89
+ nonCritical: l.nonCritical,
90
+ ref: this.buildListenerRef(discovered, classToken, l.methodName),
91
+ }));
92
+
93
+ const transitions: TransitionDefinition[] = discovered.transitionMethods.map((t) => ({
94
+ fromStepId: t.fromStep,
95
+ onStatus:
96
+ (FlowExecutionStatus as Record<string, FlowExecutionStatus>)[t.onStatus] ??
97
+ FlowExecutionStatus.UNKNOWN,
98
+ toStepId: t.toStep,
99
+ }));
100
+
101
+ const job: JobDefinition = {
102
+ id: discovered.jobOptions.id,
103
+ steps,
104
+ startStepId,
105
+ transitions,
106
+ deciders: [],
107
+ listeners: listenerDefs,
108
+ restartable: discovered.jobOptions.restartable ?? false,
109
+ allowDuplicateInstances: discovered.jobOptions.allowDuplicateInstances ?? false,
110
+ };
111
+
112
+ this.logger.log(
113
+ `Compiled job "${job.id}" from "${classToken}": ${
114
+ Object.keys(steps).length
115
+ } step(s), ${listenerDefs.length} listener(s), ${transitions.length} transition(s)`,
116
+ );
117
+
118
+ this.validator.validate(job);
119
+ return job;
120
+ }
121
+
122
+ /**
123
+ * Compile from a builder config. Used by the fluent Builder API.
124
+ * Same validation as `compileFromDiscovered`.
125
+ */
126
+ compileFromBuilderConfig(config: JobBuilderConfig): JobDefinition {
127
+ const steps: Record<string, StepDefinition> = {};
128
+ for (const s of config.steps) {
129
+ steps[s.id] = s;
130
+ }
131
+ const job: JobDefinition = {
132
+ id: config.id,
133
+ steps,
134
+ startStepId: config.startStepId,
135
+ transitions: config.transitions,
136
+ deciders: config.deciders ?? [],
137
+ listeners: config.listeners,
138
+ restartable: config.restartable,
139
+ allowDuplicateInstances: config.allowDuplicateInstances,
140
+ };
141
+ this.validator.validate(job);
142
+ return job;
143
+ }
144
+
145
+ // --- private helpers --------------------------------------------------
146
+
147
+ /**
148
+ * Resolve a listener method on a discovered class to a callable
149
+ * `ListenerRef`. Mirrors the tasklet-ref resolution in
150
+ * `buildTaskletStep`: if the DI container has already instantiated
151
+ * the class (which is the case by the time the explorer walks
152
+ * providers at `onModuleInit`), the method is pre-bound to the
153
+ * instance and the returned ref is a `BuilderLambda` carrying the
154
+ * bound function. This lets the runtime resolver map call the
155
+ * listener directly without holding onto the instance or a
156
+ * `ModuleRef`.
157
+ *
158
+ * When the instance is not yet available (factory providers that
159
+ * have not been instantiated, late-bound providers, etc.) the ref
160
+ * stays as a `Method` and the runtime resolver will throw a
161
+ * deterministic error if it cannot resolve the class. The
162
+ * pre-binding is a pure optimisation for the common
163
+ * `providers: [MyClass]` case — the test suite exercises that path.
164
+ */
165
+ private buildListenerRef(
166
+ discovered: DiscoveredJob,
167
+ classToken: string,
168
+ methodName: string,
169
+ ): ListenerRef {
170
+ const instance = discovered.instance as
171
+ | Record<string, (...args: unknown[]) => unknown>
172
+ | undefined;
173
+ const method = instance?.[methodName];
174
+ if (method) {
175
+ return {
176
+ kind: RefKind.BuilderLambda,
177
+ fn: method.bind(discovered.instance) as (...args: any[]) => unknown,
178
+ };
179
+ }
180
+ return { kind: RefKind.Method, classToken, methodName };
181
+ }
182
+
183
+ /**
184
+ * Build a `TaskletStepDefinition` for a `@Stepable` + `@Tasklet` method.
185
+ *
186
+ * If a DI-resolved instance is available on the `DiscoveredJob`, the
187
+ * tasklet ref is a `BuilderLambda` (bound function) so the executor
188
+ * can call it directly. Otherwise we fall back to a `Method` ref that
189
+ * the executor resolves at runtime against the DI container.
190
+ */
191
+ private buildTaskletStep(
192
+ discovered: DiscoveredJob,
193
+ classToken: string,
194
+ step: DiscoveredJob['stepMethods'][number],
195
+ ): TaskletStepDefinition {
196
+ const instance = discovered.instance as
197
+ | Record<string, (...args: unknown[]) => unknown>
198
+ | undefined;
199
+ const method = instance?.[step.methodName];
200
+ const taskletRef: TaskletRef = method
201
+ ? { kind: RefKind.BuilderLambda, fn: () => method.bind(discovered.instance) }
202
+ : { kind: RefKind.Method, classToken, methodName: step.methodName };
203
+ return {
204
+ kind: 'tasklet',
205
+ id: step.options.id,
206
+ tasklet: taskletRef,
207
+ listeners: [],
208
+ };
209
+ }
210
+
211
+ /**
212
+ * Build a `ChunkStepDefinition` for a `@Stepable` (no `@Tasklet`) method.
213
+ * Requires `@ItemReader` and `@ItemWriter` on the class; `@ItemProcessor`
214
+ * is optional.
215
+ *
216
+ * Throws `ProviderNotFoundError` if a required handler is missing.
217
+ */
218
+ private buildChunkStep(
219
+ discovered: DiscoveredJob,
220
+ classToken: string,
221
+ step: DiscoveredJob['stepMethods'][number],
222
+ ): ChunkStepDefinition {
223
+ const reader = this.findItemMethod(discovered, BATCH_ITEM_READER_METADATA);
224
+ const processor = this.findItemMethod(discovered, BATCH_ITEM_PROCESSOR_METADATA);
225
+ const writer = this.findItemMethod(discovered, BATCH_ITEM_WRITER_METADATA);
226
+
227
+ if (!reader) {
228
+ throw new ProviderNotFoundError(
229
+ `@ItemReader for job ${discovered.jobOptions.id} (step ${step.options.id})`,
230
+ );
231
+ }
232
+ if (!writer) {
233
+ throw new ProviderNotFoundError(
234
+ `@ItemWriter for job ${discovered.jobOptions.id} (step ${step.options.id})`,
235
+ );
236
+ }
237
+
238
+ const readerRef: ReaderRef = this.buildItemMethodRef(discovered, classToken, reader);
239
+ const writerRef: WriterRef = this.buildItemMethodRef(discovered, classToken, writer);
240
+
241
+ // Validate the partition config at compile time so a typo
242
+ // (e.g. `count: 0`) fails at module load rather than at
243
+ // runtime when the launcher pre-creates the execution.
244
+ // `DefinitionValidator.validate` does the same check later
245
+ // (the IR is the source of truth), but the compiler is the
246
+ // first place we have the value in hand and we want the
247
+ // earliest possible failure for a decorator-discovered job.
248
+ try {
249
+ validatePartitions(step.options.partitions);
250
+ } catch (err) {
251
+ if (err instanceof InvalidPartitionsError) {
252
+ throw new InvalidFlowGraphError(
253
+ 'INVALID_PARTITIONS',
254
+ `Step "${step.options.id}" has invalid partitions: ${err.message}`,
255
+ { jobId: discovered.jobOptions.id, stepId: step.options.id, partitions: step.options.partitions },
256
+ );
257
+ }
258
+ throw err;
259
+ }
260
+
261
+ return {
262
+ kind: 'chunk',
263
+ id: step.options.id,
264
+ chunkSize: step.options.chunkSize ?? 100,
265
+ reader: readerRef,
266
+ writer: writerRef,
267
+ skipPolicy: step.options.skipPolicy,
268
+ retryPolicy: step.options.retryPolicy,
269
+ listeners: [],
270
+ ...(step.options.partitions !== undefined
271
+ ? { partitions: step.options.partitions }
272
+ : {}),
273
+ ...(processor
274
+ ? {
275
+ processor: this.buildItemMethodRef(discovered, classToken, processor) satisfies ProcessorRef,
276
+ }
277
+ : {}),
278
+ };
279
+ }
280
+
281
+ private buildItemMethodRef(
282
+ discovered: DiscoveredJob,
283
+ classToken: string,
284
+ methodName: string,
285
+ ): ReaderRef | ProcessorRef | WriterRef {
286
+ const instance = discovered.instance as
287
+ | Record<string, (...args: unknown[]) => unknown>
288
+ | undefined;
289
+ const method = instance?.[methodName];
290
+ if (method) {
291
+ return {
292
+ kind: RefKind.BuilderLambda,
293
+ fn: () => method.bind(discovered.instance),
294
+ };
295
+ }
296
+ return {
297
+ kind: RefKind.Method,
298
+ classToken,
299
+ methodName,
300
+ };
301
+ }
302
+
303
+ /**
304
+ * Walks the prototype chain (including inherited prototypes, stopping
305
+ * at `Object.prototype`) looking for a method carrying the given
306
+ * `BATCH_ITEM_*` metadata key.
307
+ *
308
+ * Returns the method name or `undefined`. The explorer only records
309
+ * `@Stepable` / listener / transition methods; item handlers are
310
+ * resolved here at compile time.
311
+ */
312
+ private findItemMethod(discovered: DiscoveredJob, metadataKey: string): string | undefined {
313
+ const proto = discovered.classRef.prototype as object | undefined;
314
+ if (!proto) return undefined;
315
+ let p: object | null = proto;
316
+ while (p && p !== Object.prototype) {
317
+ for (const name of Object.getOwnPropertyNames(p)) {
318
+ if (name === 'constructor') continue;
319
+ if (Reflect.getMetadata(metadataKey, p, name) === true) return name;
320
+ }
321
+ p = Object.getPrototypeOf(p);
322
+ }
323
+ return undefined;
324
+ }
325
+ }
@@ -0,0 +1,2 @@
1
+ export * from './builder-types';
2
+ export * from './definition-compiler';
@@ -0,0 +1,125 @@
1
+ export abstract class BatchError extends Error {
2
+ abstract readonly code: string;
3
+ readonly details?: unknown;
4
+ constructor(message: string, details?: unknown) {
5
+ super(message);
6
+ this.name = this.constructor.name;
7
+ this.details = details;
8
+ if (Error.captureStackTrace) {
9
+ Error.captureStackTrace(this, this.constructor);
10
+ }
11
+ }
12
+ }
13
+
14
+ export class JobNotFoundError extends BatchError {
15
+ readonly code = 'JOB_NOT_FOUND';
16
+ constructor(jobId: string) {
17
+ super(`Job not found: ${jobId}`, { jobId });
18
+ }
19
+ }
20
+
21
+ export class DuplicateJobDefinitionError extends BatchError {
22
+ readonly code = 'DUPLICATE_JOB';
23
+ constructor(jobId: string) {
24
+ super(`Job already registered: ${jobId}`, { jobId });
25
+ }
26
+ }
27
+
28
+ export class InvalidFlowGraphError extends BatchError {
29
+ readonly code: string;
30
+ constructor(code: string, message: string, details?: unknown) {
31
+ super(message, details);
32
+ this.code = code;
33
+ }
34
+ }
35
+
36
+ export class SkipLimitExceededError extends BatchError {
37
+ readonly code = 'SKIP_LIMIT_EXCEEDED';
38
+ constructor(limit: number, message?: string) {
39
+ super(message ?? `Skip limit exceeded: ${limit}`, { limit });
40
+ }
41
+ }
42
+
43
+ export class RetryLimitExceededError extends BatchError {
44
+ readonly code = 'RETRY_LIMIT_EXCEEDED';
45
+ constructor(limit: number, message?: string) {
46
+ super(message ?? `Retry limit exceeded: ${limit}`, { limit });
47
+ }
48
+ }
49
+
50
+ export class JobExecutionAlreadyRunningError extends BatchError {
51
+ readonly code = 'JOB_EXECUTION_ALREADY_RUNNING';
52
+ constructor(jobInstanceId: string) {
53
+ super(`Job instance already running: ${jobInstanceId}`, { jobInstanceId });
54
+ }
55
+ }
56
+
57
+ export class JobExecutionNotFoundError extends BatchError {
58
+ readonly code = 'JOB_EXECUTION_NOT_FOUND';
59
+ constructor(executionId: string) {
60
+ super(`Job execution not found: ${executionId}`, { executionId });
61
+ }
62
+ }
63
+
64
+ export class JobInstanceNotFoundError extends BatchError {
65
+ readonly code = 'JOB_INSTANCE_NOT_FOUND';
66
+ constructor(jobInstanceId: string) {
67
+ super(`Job instance not found: ${jobInstanceId}`, { jobInstanceId });
68
+ }
69
+ }
70
+
71
+ export class InvalidJobOperationError extends BatchError {
72
+ readonly code = 'INVALID_JOB_OPERATION';
73
+ constructor(operation: string, message: string, details?: unknown) {
74
+ super(message, { operation, ...(typeof details === 'object' && details !== null ? details : {}) });
75
+ }
76
+ }
77
+
78
+ export class UnsupportedJobRepositoryOperationError extends BatchError {
79
+ readonly code = 'UNSUPPORTED_JOB_REPOSITORY_OPERATION';
80
+ constructor(operation: string) {
81
+ super(`JobRepository operation is not supported by this adapter: ${operation}`, {
82
+ operation,
83
+ });
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Thrown when a restart is attempted against a JobDefinition that was
89
+ * declared with `restartable: false`. Restarting a FAILED execution is
90
+ * opt-in — by default the in-memory repository and most adapters are
91
+ * non-restartable because their contexts are process-local and lost on
92
+ * crash. (Per Metis: in-memory is `restartable: false` by default.)
93
+ */
94
+ export class JobNotRestartableError extends BatchError {
95
+ readonly code = 'JOB_NOT_RESTARTABLE';
96
+ constructor(jobId: string) {
97
+ super(`Job is not restartable: ${jobId}`, { jobId });
98
+ }
99
+ }
100
+
101
+ export class InvalidExecutionContextError extends BatchError {
102
+ readonly code = 'INVALID_EXECUTION_CONTEXT';
103
+ constructor(message: string, details?: unknown) {
104
+ super(message, details);
105
+ }
106
+ }
107
+
108
+ /**
109
+ * Thrown when a `RefKind.ProviderToken` ref cannot be resolved against
110
+ * the executor's `providerResolvers` map (Task 9). The message always
111
+ * carries the unresolved token id and the role (`reader` / `processor`
112
+ * / `writer` / `tasklet` / `listener`) so log lines and test failures
113
+ * identify the missing provider deterministically.
114
+ *
115
+ * Distinct from `ProviderNotFoundError` in the compiler, which fires
116
+ * during IR compilation when a chunk step is missing a required item
117
+ * handler method. This error fires at runtime when the DI binding for
118
+ * an already-shaped ref cannot be located.
119
+ */
120
+ export class ProviderTokenNotFoundError extends BatchError {
121
+ readonly code = 'PROVIDER_TOKEN_NOT_FOUND';
122
+ constructor(token: string, role: string) {
123
+ super(`No provider bound for ${role} token: ${token}`, { token, role });
124
+ }
125
+ }
@@ -0,0 +1,3 @@
1
+ export * from './json-value';
2
+ export * from './validator';
3
+ export * from './serializer';
@@ -0,0 +1,3 @@
1
+ export type JsonPrimitive = string | number | boolean | null;
2
+
3
+ export type JsonValue = JsonPrimitive | JsonValue[] | { [k: string]: JsonValue };
@@ -0,0 +1,21 @@
1
+ import { InvalidExecutionContextError } from '../errors';
2
+ import type { JsonValue } from './json-value';
3
+
4
+ export function serializeContext(ctx: unknown): string {
5
+ return JSON.stringify(
6
+ ctx,
7
+ function (this: unknown, key: string, value: unknown): unknown {
8
+ if (typeof value === 'bigint') {
9
+ throw new InvalidExecutionContextError(
10
+ `Cannot serialize BigInt at key "${key}"`,
11
+ { key },
12
+ );
13
+ }
14
+ return value;
15
+ },
16
+ );
17
+ }
18
+
19
+ export function deserializeContext<T extends JsonValue>(raw: string): T {
20
+ return JSON.parse(raw) as T;
21
+ }
@@ -0,0 +1,103 @@
1
+ import { InvalidExecutionContextError } from '../errors';
2
+ import type { JsonValue } from './json-value';
3
+
4
+ const MAX_DEPTH = 100;
5
+
6
+ function isPlainObject(v: unknown): v is Record<string, unknown> {
7
+ if (v === null || typeof v !== 'object') return false;
8
+ if (Array.isArray(v)) return false;
9
+ const proto = Object.getPrototypeOf(v);
10
+ return proto === Object.prototype || proto === null;
11
+ }
12
+
13
+ /**
14
+ * Asserts that `value` is JSON-serializable. Throws InvalidExecutionContextError
15
+ * with `details.path` on the first non-serializable value encountered.
16
+ *
17
+ * Rejection rules:
18
+ * - undefined (top level only; inside objects/arrays: silently omitted)
19
+ * - function, bigint, symbol
20
+ * - non-finite numbers (NaN, Infinity, -Infinity)
21
+ * - class instances (anything with a non-Object prototype that is not Date/RegExp)
22
+ * - circular references
23
+ * - nesting depth > 100
24
+ *
25
+ * `seen` and `depth` are threaded through recursive calls so cycles and depth
26
+ * are tracked across the whole object graph, not per call.
27
+ */
28
+ export function assertJsonSerializable(
29
+ value: unknown,
30
+ path = '$',
31
+ seen: WeakSet<object> = new WeakSet(),
32
+ depth = 0,
33
+ ): void {
34
+ if (value === null) return;
35
+
36
+ const t = typeof value;
37
+ if (t === 'undefined') {
38
+ throw new InvalidExecutionContextError(
39
+ `Value at ${path} is undefined (must be omitted or null)`,
40
+ { path },
41
+ );
42
+ }
43
+ if (t === 'string' || t === 'boolean') return;
44
+ if (t === 'number') {
45
+ if (!Number.isFinite(value as number)) {
46
+ throw new InvalidExecutionContextError(
47
+ `Value at ${path} is not a finite number`,
48
+ { path, value },
49
+ );
50
+ }
51
+ return;
52
+ }
53
+ if (t === 'bigint') {
54
+ throw new InvalidExecutionContextError(`Value at ${path} is a BigInt`, { path });
55
+ }
56
+ if (t === 'symbol') {
57
+ throw new InvalidExecutionContextError(`Value at ${path} is a Symbol`, { path });
58
+ }
59
+ if (t === 'function') {
60
+ throw new InvalidExecutionContextError(`Value at ${path} is a function`, { path });
61
+ }
62
+
63
+ // object types
64
+ if (value instanceof Date) return;
65
+ if (value instanceof RegExp) return;
66
+
67
+ if (depth > MAX_DEPTH) {
68
+ throw new InvalidExecutionContextError(`Max depth exceeded at ${path}`, { path });
69
+ }
70
+ const objRef = value as object;
71
+ if (seen.has(objRef)) {
72
+ throw new InvalidExecutionContextError(
73
+ `Circular reference detected at ${path}`,
74
+ { path },
75
+ );
76
+ }
77
+ seen.add(objRef);
78
+
79
+ if (Array.isArray(value)) {
80
+ const arr = value as unknown[];
81
+ for (let i = 0; i < arr.length; i++) {
82
+ assertJsonSerializable(arr[i], `${path}[${i}]`, seen, depth + 1);
83
+ }
84
+ return;
85
+ }
86
+ if (isPlainObject(value)) {
87
+ const obj = value;
88
+ for (const key of Object.keys(obj)) {
89
+ const v = obj[key];
90
+ if (v === undefined) continue; // undefined values in objects are silently omitted
91
+ assertJsonSerializable(v, `${path}.${key}`, seen, depth + 1);
92
+ }
93
+ return;
94
+ }
95
+ // class instance
96
+ throw new InvalidExecutionContextError(
97
+ `Value at ${path} is a class instance (not plain object)`,
98
+ { path, ctor: (value as object).constructor?.name },
99
+ );
100
+ }
101
+
102
+ // Re-export JsonValue for downstream convenience.
103
+ export type { JsonValue } from './json-value';
@@ -0,0 +1,7 @@
1
+ export * from './status';
2
+ export * from './errors';
3
+ export * from './ir';
4
+ export * from './execution-context';
5
+ export * from './item';
6
+ export * from './repository';
7
+ export * from './transaction';
@@ -0,0 +1,25 @@
1
+ import type { JobExecution } from '../repository/types';
2
+ import type { StepStatus } from '../status';
3
+
4
+ export interface JobExecutionDeciderContext {
5
+ readonly jobExecution: JobExecution;
6
+ readonly stepId: string;
7
+ readonly stepExecutionId: string;
8
+ readonly stepStatus: StepStatus;
9
+ readonly exitCode: string;
10
+ readonly exitMessage: string;
11
+ }
12
+
13
+ export type JobExecutionDecider = (
14
+ context: JobExecutionDeciderContext,
15
+ ) => string | Promise<string>;
16
+
17
+ export interface DeciderDefinition {
18
+ readonly afterStepId: string;
19
+ readonly decide: JobExecutionDecider;
20
+ }
21
+
22
+ export interface ReusableFlowDefinition {
23
+ readonly transitions: readonly import('./transition-definition').TransitionDefinition[];
24
+ readonly deciders?: readonly DeciderDefinition[];
25
+ }
@@ -0,0 +1,7 @@
1
+ export * from './job-definition';
2
+ export * from './step-definition';
3
+ export * from './transition-definition';
4
+ export * from './decider-definition';
5
+ export * from './listener-definition';
6
+ export * from './policy-config';
7
+ export * from './refs';
@@ -0,0 +1,15 @@
1
+ import type { StepDefinition } from './step-definition';
2
+ import type { TransitionDefinition } from './transition-definition';
3
+ import type { ListenerDefinition } from './listener-definition';
4
+ import type { DeciderDefinition } from './decider-definition';
5
+
6
+ export interface JobDefinition {
7
+ id: string;
8
+ steps: Record<string, StepDefinition>;
9
+ startStepId: string;
10
+ transitions: TransitionDefinition[];
11
+ deciders?: DeciderDefinition[];
12
+ listeners: ListenerDefinition[];
13
+ restartable: boolean;
14
+ allowDuplicateInstances: boolean;
15
+ }
@@ -0,0 +1,19 @@
1
+ import type { ListenerRef } from './refs';
2
+
3
+ export type ListenerKind =
4
+ | 'job'
5
+ | 'step'
6
+ | 'chunk'
7
+ | 'item-read'
8
+ | 'item-process'
9
+ | 'item-write'
10
+ | 'skip'
11
+ | 'transition';
12
+ export type ListenerPhase = 'before' | 'after' | 'on-error';
13
+
14
+ export interface ListenerDefinition {
15
+ kind: ListenerKind;
16
+ ref: ListenerRef;
17
+ phase: ListenerPhase;
18
+ nonCritical?: boolean;
19
+ }
@@ -0,0 +1,19 @@
1
+ export type ErrorClass = new (...args: any[]) => Error;
2
+ export type ErrorPredicate = (err: unknown) => boolean;
3
+ export type Skippable = ErrorClass | ErrorPredicate;
4
+
5
+ export interface SkipPolicyConfig {
6
+ limit: number;
7
+ skippable: Skippable[];
8
+ }
9
+
10
+ export type BackoffConfig =
11
+ | { type: 'fixed'; ms: number }
12
+ | { type: 'exponential'; initialMs: number; maxMs?: number; factor?: number }
13
+ | { type: 'none' };
14
+
15
+ export interface RetryPolicyConfig {
16
+ limit: number;
17
+ retryable: Skippable[];
18
+ backoff: BackoffConfig;
19
+ }