@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,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ _export_star(require("./listener-invoker"), exports);
6
+ _export_star(require("./tasklet-step-executor"), exports);
7
+ _export_star(require("./chunk-step-executor"), exports);
8
+ _export_star(require("./job-executor"), exports);
9
+ _export_star(require("./job-launcher"), exports);
10
+ _export_star(require("./job-explorer"), exports);
11
+ _export_star(require("./job-operator"), exports);
12
+ _export_star(require("./batch-worker-runner"), exports);
13
+ _export_star(require("./external-task-execution-strategy"), exports);
14
+ _export_star(require("./job-key"), exports);
15
+ _export_star(require("./execution-strategy"), exports);
16
+ _export_star(require("./ref-resolver"), exports);
17
+ _export_star(require("./in-process-execution-strategy"), exports);
18
+ function _export_star(from, to) {
19
+ Object.keys(from).forEach(function(k) {
20
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
21
+ Object.defineProperty(to, k, {
22
+ enumerable: true,
23
+ get: function() {
24
+ return from[k];
25
+ }
26
+ });
27
+ }
28
+ });
29
+ return from;
30
+ }
31
+
32
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/execution/index.ts"],"sourcesContent":["export * from './listener-invoker';\nexport * from './tasklet-step-executor';\nexport * from './chunk-step-executor';\nexport * from './job-executor';\nexport * from './job-launcher';\nexport * from './job-explorer';\nexport * from './job-operator';\nexport * from './batch-worker-runner';\nexport * from './external-task-execution-strategy';\nexport * from './job-key';\nexport * from './execution-strategy';\nexport * from './ref-resolver';\nexport * from './in-process-execution-strategy';\n"],"names":[],"mappings":";;;;qBAAc;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA"}
@@ -0,0 +1,145 @@
1
+ import type { JobDefinition } from '../core/ir';
2
+ import { JobRepository, type JobParameters, type JobExecution } from '../core/repository';
3
+ import { TransactionManager } from '../core/transaction';
4
+ import { TaskletStepExecutor } from './tasklet-step-executor';
5
+ import { ChunkStepExecutor } from './chunk-step-executor';
6
+ import { ListenerInvoker } from './listener-invoker';
7
+ import { FlowEvaluator } from '../flow/flow-evaluator';
8
+ import { type BatchObserver } from '../observability';
9
+ /**
10
+ * JobExecutor — drives a single JobExecution to completion.
11
+ *
12
+ * Flow (per ORACLE verdict 3c):
13
+ * 1. Mark execution as STARTED.
14
+ * 2. `before:job:*` listeners.
15
+ * 3. Loop:
16
+ * a. Look up the current step (jobDef.steps[currentStepId]). If the
17
+ * step is missing, mark the job FAILED with exit code
18
+ * `NO_SUCH_STEP` and break.
19
+ * b. Create a StepExecution, run it (tasklet or chunk), and persist
20
+ * the result via `updateStepExecution`. During the run, the
21
+ * step's own `after-step:*` listeners fire (see
22
+ * `TaskletStepExecutor.execute` step 4 / `ChunkStepExecutor`).
23
+ * Those listeners run BEFORE we evaluate transitions so they get
24
+ * a chance to mutate the result (e.g. flip COMPLETED → FAILED)
25
+ * and the resulting flow routing sees the override.
26
+ * c. Map the (possibly overridden) step status to a
27
+ * `FlowExecutionStatus` and ask the `FlowEvaluator` for the next
28
+ * step. `null` means END.
29
+ * d. If the step FAILED and the evaluator returned `null`
30
+ * (no recovery transition matches), short-circuit the job to
31
+ * FAILED — we must not continue running subsequent steps
32
+ * declared in the graph, because none are reachable.
33
+ * 4. `after:job:*` listeners (with the final status).
34
+ *
35
+ * Out of scope (future tasks):
36
+ * - Concurrency control (Task 38).
37
+ * - `on-error:job:*` listener invocation when the executor itself
38
+ * throws (the catch block can be wired to it in a follow-up).
39
+ */
40
+ export declare class JobExecutor {
41
+ private readonly repository;
42
+ private readonly transactionManager;
43
+ private readonly taskletExecutor;
44
+ private readonly chunkExecutor;
45
+ private readonly listenerInvoker;
46
+ private readonly flowEvaluator;
47
+ private readonly observer;
48
+ private readonly logger;
49
+ constructor(repository: JobRepository, transactionManager: TransactionManager, taskletExecutor: TaskletStepExecutor, chunkExecutor: ChunkStepExecutor, listenerInvoker: ListenerInvoker, flowEvaluator: FlowEvaluator, observer?: BatchObserver);
50
+ /**
51
+ * Execute a JobExecution against its `JobDefinition`. Returns the
52
+ * final, persisted `JobExecution` (status = COMPLETED | FAILED).
53
+ *
54
+ * Restart behavior (per Metis verdict 3b — restartable opt-in, per
55
+ * ORACLE 3b — default-on for persisted repositories):
56
+ * - If `execution.status` is `FAILED` on entry, this is a restart
57
+ * attempt. We require `jobDef.restartable === true`; otherwise we
58
+ * throw `JobNotRestartableError` and leave the execution alone.
59
+ * - For each chunk step, we look up the latest FAILED StepExecution
60
+ * for that step in this job execution. If one exists, we read its
61
+ * ExecutionContext's `lastChunkIndex` checkpoint and pass it to the
62
+ * `ChunkStepExecutor` as `resumeFromChunkIndex`, which then skips
63
+ * chunks ≤ that index. Tasklet steps always re-run from scratch
64
+ * (they have no chunk-level resume granularity in this MVP).
65
+ *
66
+ * Partition routing (T8): the optional third argument carries the
67
+ * `partitionIndex` / `partitionCount` pair the transport attached
68
+ * to the job. When set, the chunk executor bounds the read loop
69
+ * to the partition's range (see `packages/core/src/partition-helpers.ts`).
70
+ */
71
+ execute(execution: JobExecution, jobDef: JobDefinition, partition?: {
72
+ partitionIndex?: number;
73
+ partitionCount?: number;
74
+ }): Promise<JobExecution>;
75
+ /**
76
+ * Build a listener resolver map for the given job. Walks every
77
+ * `ListenerDefinition` in `jobDef.listeners` (job-level + step-level +
78
+ * chunk-level + item-level + skip-level) and resolves each ref into a
79
+ * callable `ListenerEntry` keyed by `${phase}:${kind}:${name}`.
80
+ *
81
+ * The returned map is consumed by `ListenerInvoker.invokeBefore /
82
+ * invokeAfter / invokeOnError / invokeOnSkip*` (Task 20 API). The legacy
83
+ * step-level methods (`invokeBeforeStep` etc.) consume a derived
84
+ * legacy-shaped map produced by `buildLegacyStepResolvers` — that
85
+ * conversion happens at the call site, not here, so this method stays
86
+ * the single source of truth for the new shape.
87
+ *
88
+ * Ref resolution rules:
89
+ * - `RefKind.BuilderLambda` → use `ref.fn` directly (the compiler
90
+ * pre-binds decorator-discovered methods
91
+ * and the builder API ships bare fns).
92
+ * - `RefKind.Method` → requires the Jobable instance. Until
93
+ * a `ModuleRef` is wired (Task 9+), this
94
+ * branch logs a warning and is skipped.
95
+ * - `RefKind.ProviderToken` → resolved in Task 9 against a
96
+ * pre-built provider map. Skipped here
97
+ * with a warning.
98
+ */
99
+ private buildResolverMap;
100
+ /**
101
+ * Resolve a single `ListenerDefinition` to its callable function, or
102
+ * `null` if the ref kind is not yet supported. See `buildResolverMap`
103
+ * for the per-kind resolution contract.
104
+ */
105
+ private resolveListenerRef;
106
+ /**
107
+ * Derive the `name` segment of the resolver key. Method refs carry a
108
+ * `classToken` + `methodName` pair that uniquely identifies the bound
109
+ * method; BuilderLambda refs do not carry a name (the compiler drops
110
+ * the method name when it pre-binds), so we mint a `lambda-N` name
111
+ * from a per-job counter to guarantee uniqueness.
112
+ */
113
+ private resolveListenerName;
114
+ /**
115
+ * Derive a legacy `Map<string, ListenerResolver>` from a new
116
+ * `ResolverMap`, containing only the step-level entries with their
117
+ * keys translated from `${phase}:step:${name}` back to the legacy
118
+ * `${phase}-step:${name}` shape. The `nonCritical` flag is dropped
119
+ * (legacy `ListenerResolver` is a bare function with no metadata).
120
+ *
121
+ * This is the bridge the `TaskletStepExecutor` (which still consumes
122
+ * the legacy shape) needs until it migrates to the new API. Kept as
123
+ * a private helper so the conversion logic is in one place.
124
+ */
125
+ private buildLegacyStepResolvers;
126
+ /**
127
+ * Read the `lastChunkIndex` checkpoint from the step-scoped
128
+ * ExecutionContext for `stepExecutionId`. Returns `undefined` when the
129
+ * step has no recorded checkpoint (e.g., the prior run failed on the
130
+ * very first chunk and never got a chance to write one). The chunk
131
+ * executor treats `undefined` as "no resume; start from the beginning".
132
+ */
133
+ private getLastCheckpoint;
134
+ private resolveDeciderExitStatus;
135
+ /**
136
+ * Dispatch a BatchEvent to the configured observer. Errors thrown by
137
+ * the observer are swallowed: a failing logger/queue must not crash
138
+ * the executor (the job's persisted state is the source of truth).
139
+ */
140
+ private emit;
141
+ }
142
+ export type { StepExecutionResult } from './tasklet-step-executor';
143
+ export type { ChunkExecutionResult } from './chunk-step-executor';
144
+ export type { JobParameters, JobExecution };
145
+ //# sourceMappingURL=job-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"job-executor.d.ts","sourceRoot":"","sources":["../../../src/execution/job-executor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAsB,MAAM,YAAY,CAAC;AAEpE,OAAO,EAAE,aAAa,EAAE,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAGzD,OAAO,EAAE,mBAAmB,EAA4B,MAAM,yBAAyB,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAA6B,MAAM,uBAAuB,CAAC;AACrF,OAAO,EACL,eAAe,EAGhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,kBAAkB,CAAC;AAa1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBACa,WAAW;IAIpB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAE3B,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAE9B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAX3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;gBAGpC,UAAU,EAAE,aAAa,EAEzB,kBAAkB,EAAE,kBAAkB,EACtC,eAAe,EAAE,mBAAmB,EACpC,aAAa,EAAE,iBAAiB,EAChC,eAAe,EAAE,eAAe,EAChC,aAAa,EAAE,aAAa,EAE5B,QAAQ,GAAE,aAAuC;IAGpE;;;;;;;;;;;;;;;;;;;;OAoBG;IACG,OAAO,CACX,SAAS,EAAE,YAAY,EACvB,MAAM,EAAE,aAAa,EACrB,SAAS,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,GAC/D,OAAO,CAAC,YAAY,CAAC;IA6RxB;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,OAAO,CAAC,gBAAgB;IAqBxB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IA0B1B;;;;;;OAMG;IACH,OAAO,CAAC,mBAAmB;IAO3B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,wBAAwB;IAchC;;;;;;OAMG;YACW,iBAAiB;YASjB,wBAAwB;IAYtC;;;;OAIG;YACW,IAAI;CAQnB;AAID,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,YAAY,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAClE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC"}
@@ -0,0 +1,475 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "JobExecutor", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return JobExecutor;
9
+ }
10
+ });
11
+ const _common = require("@nestjs/common");
12
+ const _ir = require("../core/ir");
13
+ const _repository = require("../core/repository");
14
+ const _transaction = require("../core/transaction");
15
+ const _status = require("../core/status");
16
+ const _errors = require("../core/errors");
17
+ const _taskletstepexecutor = require("./tasklet-step-executor");
18
+ const _chunkstepexecutor = require("./chunk-step-executor");
19
+ const _listenerinvoker = require("./listener-invoker");
20
+ const _flowevaluator = require("../flow/flow-evaluator");
21
+ const _observability = require("../observability");
22
+ function _ts_decorate(decorators, target, key, desc) {
23
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
24
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
25
+ else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
26
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
27
+ }
28
+ function _ts_metadata(k, v) {
29
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
30
+ }
31
+ function _ts_param(paramIndex, decorator) {
32
+ return function(target, key) {
33
+ decorator(target, key, paramIndex);
34
+ };
35
+ }
36
+ let JobExecutor = class JobExecutor {
37
+ repository;
38
+ transactionManager;
39
+ taskletExecutor;
40
+ chunkExecutor;
41
+ listenerInvoker;
42
+ flowEvaluator;
43
+ observer;
44
+ logger = new _common.Logger(JobExecutor.name);
45
+ constructor(repository, transactionManager, taskletExecutor, chunkExecutor, listenerInvoker, flowEvaluator, observer = new _observability.NoopBatchObserver()){
46
+ this.repository = repository;
47
+ this.transactionManager = transactionManager;
48
+ this.taskletExecutor = taskletExecutor;
49
+ this.chunkExecutor = chunkExecutor;
50
+ this.listenerInvoker = listenerInvoker;
51
+ this.flowEvaluator = flowEvaluator;
52
+ this.observer = observer;
53
+ }
54
+ /**
55
+ * Execute a JobExecution against its `JobDefinition`. Returns the
56
+ * final, persisted `JobExecution` (status = COMPLETED | FAILED).
57
+ *
58
+ * Restart behavior (per Metis verdict 3b — restartable opt-in, per
59
+ * ORACLE 3b — default-on for persisted repositories):
60
+ * - If `execution.status` is `FAILED` on entry, this is a restart
61
+ * attempt. We require `jobDef.restartable === true`; otherwise we
62
+ * throw `JobNotRestartableError` and leave the execution alone.
63
+ * - For each chunk step, we look up the latest FAILED StepExecution
64
+ * for that step in this job execution. If one exists, we read its
65
+ * ExecutionContext's `lastChunkIndex` checkpoint and pass it to the
66
+ * `ChunkStepExecutor` as `resumeFromChunkIndex`, which then skips
67
+ * chunks ≤ that index. Tasklet steps always re-run from scratch
68
+ * (they have no chunk-level resume granularity in this MVP).
69
+ *
70
+ * Partition routing (T8): the optional third argument carries the
71
+ * `partitionIndex` / `partitionCount` pair the transport attached
72
+ * to the job. When set, the chunk executor bounds the read loop
73
+ * to the partition's range (see `packages/core/src/partition-helpers.ts`).
74
+ */ async execute(execution, jobDef, partition) {
75
+ // Capture the pre-execute status. For a fresh launch, the launcher
76
+ // created the execution with status STARTING; for a restart, the
77
+ // caller (JobLauncher.run) hands us a terminal execution that can
78
+ // be resumed.
79
+ const isRestart = execution.status === _status.JobStatus.FAILED || execution.status === _status.JobStatus.STOPPED;
80
+ if (isRestart && !jobDef.restartable) {
81
+ throw new _errors.JobNotRestartableError(jobDef.id);
82
+ }
83
+ await this.repository.updateJobExecution(execution.id, {
84
+ status: _status.JobStatus.STARTED,
85
+ startTime: new Date()
86
+ });
87
+ await this.emit({
88
+ type: _observability.BATCH_EVENT.JOB_STARTED,
89
+ timestamp: new Date(),
90
+ jobExecutionId: execution.id,
91
+ data: {
92
+ jobName: jobDef.id
93
+ }
94
+ });
95
+ // Build the full resolver map once. The same map powers both the
96
+ // job-level `invokeBefore` / `invokeAfter` calls below and the
97
+ // step-level resolvers handed to the TaskletStepExecutor (derived
98
+ // by `buildLegacyStepResolvers` into the legacy key shape). Building
99
+ // it once per execution avoids re-walking the IR on every step.
100
+ const jobResolvers = this.buildResolverMap(jobDef);
101
+ const stepResolvers = this.buildLegacyStepResolvers(jobResolvers);
102
+ await this.listenerInvoker.invokeBefore(jobResolvers, 'job', {
103
+ jobExecutionId: execution.id,
104
+ stepExecutionId: '<job>'
105
+ });
106
+ // Cache the step order once. `Object.keys` returns insertion order
107
+ // for string keys (per ES2015+), so this is the canonical
108
+ // declaration order — used for the linear fallback below.
109
+ const stepOrder = Object.keys(jobDef.steps);
110
+ let currentStepId = jobDef.startStepId;
111
+ let finalStatus = _status.JobStatus.COMPLETED;
112
+ let currentStepExecutionId = null;
113
+ try {
114
+ while(currentStepId !== null){
115
+ const step = jobDef.steps[currentStepId];
116
+ if (!step) {
117
+ await this.repository.updateJobExecution(execution.id, {
118
+ status: _status.JobStatus.FAILED,
119
+ endTime: new Date(),
120
+ exitCode: 'NO_SUCH_STEP',
121
+ exitMessage: `Step "${currentStepId}" not found`
122
+ });
123
+ finalStatus = _status.JobStatus.FAILED;
124
+ break;
125
+ }
126
+ // Restart path: if this is a restart and the current step is a
127
+ // chunk step, locate the latest FAILED step execution for the
128
+ // same step name and load its `lastChunkIndex` checkpoint. That
129
+ // value is passed to the chunk executor as `resumeFromChunkIndex`.
130
+ // For tasklet steps (and chunk steps with no prior failure) we
131
+ // leave `resumeFromChunkIndex` undefined — the chunk executor
132
+ // treats undefined as "start from the beginning".
133
+ //
134
+ // Look this up BEFORE createStepExecution so the just-created
135
+ // STARTING step isn't returned as the "latest" entry.
136
+ let resumeFromChunkIndex;
137
+ if (isRestart && step.kind === 'chunk') {
138
+ const priorFailed = await this.repository.findLatestStepExecution(execution.id, step.id);
139
+ if (priorFailed && priorFailed.status === _status.StepStatus.FAILED) {
140
+ resumeFromChunkIndex = await this.getLastCheckpoint(priorFailed.id);
141
+ }
142
+ }
143
+ const stepExecution = await this.repository.createStepExecution(execution.id, step.id);
144
+ currentStepExecutionId = stepExecution.id;
145
+ await this.emit({
146
+ type: _observability.BATCH_EVENT.STEP_STARTED,
147
+ timestamp: new Date(),
148
+ jobExecutionId: execution.id,
149
+ stepExecutionId: stepExecution.id,
150
+ data: {
151
+ stepId: step.id,
152
+ kind: step.kind
153
+ }
154
+ });
155
+ let result;
156
+ try {
157
+ if (step.kind === 'tasklet') {
158
+ result = await this.taskletExecutor.execute(step, {
159
+ jobExecutionId: execution.id,
160
+ jobRepository: this.repository,
161
+ transactionManager: this.transactionManager,
162
+ listenerInvoker: this.listenerInvoker,
163
+ listenerResolvers: stepResolvers
164
+ });
165
+ } else {
166
+ // Forward the partition routing (T8) when the transport
167
+ // supplied one. The chunk executor uses the partition
168
+ // index + count + the step's `partitions.range` to bound
169
+ // its read loop. Absent partition args fall through to
170
+ // the 0.1.0 non-partitioned chunk pipeline.
171
+ const partitionArgs = partition?.partitionIndex !== undefined && partition?.partitionCount !== undefined ? {
172
+ partitionIndex: partition.partitionIndex,
173
+ partitionCount: partition.partitionCount
174
+ } : {};
175
+ result = await this.chunkExecutor.execute(step, {
176
+ jobExecutionId: execution.id,
177
+ stepExecutionId: stepExecution.id,
178
+ jobRepository: this.repository,
179
+ transactionManager: this.transactionManager,
180
+ listenerInvoker: this.listenerInvoker,
181
+ jobExecutionId2: execution.id,
182
+ resolvers: new Map(),
183
+ ...resumeFromChunkIndex !== undefined ? {
184
+ resumeFromChunkIndex
185
+ } : {},
186
+ ...partitionArgs
187
+ });
188
+ }
189
+ } catch (stepErr) {
190
+ // The executor itself threw (e.g. resolveReader threw in a
191
+ // chunk step before the executor's own try-catch could catch
192
+ // it). Persist the step as FAILED with the error message and
193
+ // re-raise so the outer handler marks the job FAILED.
194
+ await this.repository.updateStepExecution(stepExecution.id, {
195
+ status: _status.StepStatus.FAILED,
196
+ exitCode: 'FAILED',
197
+ exitMessage: stepErr instanceof Error ? stepErr.message : String(stepErr),
198
+ endTime: new Date()
199
+ });
200
+ currentStepExecutionId = null;
201
+ throw stepErr;
202
+ }
203
+ currentStepExecutionId = null;
204
+ await this.repository.updateStepExecution(stepExecution.id, {
205
+ status: result.status,
206
+ ...result.readCount !== undefined ? {
207
+ readCount: result.readCount
208
+ } : {},
209
+ ...result.writeCount !== undefined ? {
210
+ writeCount: result.writeCount
211
+ } : {},
212
+ ...result.skipCount !== undefined ? {
213
+ skipCount: result.skipCount
214
+ } : {},
215
+ ...'commitCount' in result && result.commitCount !== undefined ? {
216
+ commitCount: result.commitCount
217
+ } : {},
218
+ exitCode: result.exitCode,
219
+ exitMessage: result.exitMessage,
220
+ endTime: new Date()
221
+ });
222
+ await this.emit({
223
+ type: result.status === _status.StepStatus.COMPLETED ? _observability.BATCH_EVENT.STEP_COMPLETED : result.status === _status.StepStatus.FAILED ? _observability.BATCH_EVENT.STEP_FAILED : _observability.BATCH_EVENT.STEP_COMPLETED,
224
+ timestamp: new Date(),
225
+ jobExecutionId: execution.id,
226
+ stepExecutionId: stepExecution.id,
227
+ data: {
228
+ stepId: step.id,
229
+ status: result.status,
230
+ ...result.exitCode !== undefined ? {
231
+ exitCode: result.exitCode
232
+ } : {}
233
+ }
234
+ });
235
+ // Map StepStatus -> FlowExecutionStatus. Anything other than
236
+ // COMPLETED/FAILED collapses to UNKNOWN → evaluator returns
237
+ // null → flow ends.
238
+ const flowStatus = result.status === _status.StepStatus.COMPLETED ? _status.FlowExecutionStatus.COMPLETED : result.status === _status.StepStatus.FAILED ? _status.FlowExecutionStatus.FAILED : _status.FlowExecutionStatus.UNKNOWN;
239
+ const deciderExitStatus = await this.resolveDeciderExitStatus(jobDef, currentStepId, {
240
+ jobExecution: execution,
241
+ stepId: step.id,
242
+ stepExecutionId: stepExecution.id,
243
+ stepStatus: result.status,
244
+ exitCode: result.exitCode,
245
+ exitMessage: result.exitMessage
246
+ });
247
+ const flowExitStatus = deciderExitStatus ?? (result.exitCode || flowStatus);
248
+ let evaluatorResult = await this.flowEvaluator.evaluate(jobDef.transitions, currentStepId, flowExitStatus);
249
+ // Distinguish "no transition declared" (linear fallback) from
250
+ // "transition declared with toStepId: null" (explicit END).
251
+ // FlowEvaluator returns null for both, so we inspect the
252
+ // transition list directly.
253
+ let hasMatchingTransition = jobDef.transitions.some((t)=>this.flowEvaluator.matches(t, currentStepId, flowExitStatus));
254
+ if (!hasMatchingTransition && flowExitStatus !== flowStatus) {
255
+ evaluatorResult = await this.flowEvaluator.evaluate(jobDef.transitions, currentStepId, flowStatus);
256
+ hasMatchingTransition = jobDef.transitions.some((t)=>this.flowEvaluator.matches(t, currentStepId, flowStatus));
257
+ }
258
+ let nextStepId;
259
+ if (hasMatchingTransition) {
260
+ // Explicit transition: respect its target, including null
261
+ // (END). Do not fall through to linear order.
262
+ nextStepId = evaluatorResult;
263
+ } else if (result.status === _status.StepStatus.FAILED) {
264
+ // FAILED with no matching transition → short-circuit. The
265
+ // graph declares no path forward, so the job is FAILED — we
266
+ // must not invent a "next" step.
267
+ await this.repository.updateJobExecution(execution.id, {
268
+ status: _status.JobStatus.FAILED,
269
+ endTime: new Date(),
270
+ exitCode: result.exitCode,
271
+ exitMessage: result.exitMessage
272
+ });
273
+ finalStatus = _status.JobStatus.FAILED;
274
+ break;
275
+ } else {
276
+ // COMPLETED with no transition → linear fallback to the next
277
+ // step in declaration order. If we're already on the last
278
+ // step, the job ends.
279
+ const currentIdx = stepOrder.indexOf(currentStepId);
280
+ const nextIdx = currentIdx + 1;
281
+ nextStepId = nextIdx < stepOrder.length ? stepOrder[nextIdx] : null;
282
+ }
283
+ currentStepId = nextStepId;
284
+ }
285
+ if (finalStatus === _status.JobStatus.COMPLETED) {
286
+ await this.repository.updateJobExecution(execution.id, {
287
+ status: _status.JobStatus.COMPLETED,
288
+ endTime: new Date(),
289
+ exitCode: 'COMPLETED'
290
+ });
291
+ }
292
+ } catch (err) {
293
+ // Defensive: leave the job FAILED rather than crash the host.
294
+ await this.repository.updateJobExecution(execution.id, {
295
+ status: _status.JobStatus.FAILED,
296
+ endTime: new Date(),
297
+ exitMessage: err instanceof Error ? err.message : String(err)
298
+ });
299
+ finalStatus = _status.JobStatus.FAILED;
300
+ }
301
+ // `after:job:*` listeners run once the job is in a terminal state.
302
+ // They receive the final status as the second positional argument
303
+ // (the `args` slot in the current API; the legacy builder path used
304
+ // the same shape). The resolver map is the same one built above;
305
+ // we re-use it to avoid a second IR walk.
306
+ await this.listenerInvoker.invokeAfter(jobResolvers, 'job', {
307
+ jobExecutionId: execution.id,
308
+ stepExecutionId: '<job>'
309
+ }, [
310
+ {
311
+ status: finalStatus
312
+ }
313
+ ]);
314
+ await this.emit({
315
+ type: finalStatus === _status.JobStatus.COMPLETED ? _observability.BATCH_EVENT.JOB_COMPLETED : _observability.BATCH_EVENT.JOB_FAILED,
316
+ timestamp: new Date(),
317
+ jobExecutionId: execution.id,
318
+ data: {
319
+ status: finalStatus
320
+ }
321
+ });
322
+ return await this.repository.getJobExecution(execution.id);
323
+ }
324
+ /**
325
+ * Build a listener resolver map for the given job. Walks every
326
+ * `ListenerDefinition` in `jobDef.listeners` (job-level + step-level +
327
+ * chunk-level + item-level + skip-level) and resolves each ref into a
328
+ * callable `ListenerEntry` keyed by `${phase}:${kind}:${name}`.
329
+ *
330
+ * The returned map is consumed by `ListenerInvoker.invokeBefore /
331
+ * invokeAfter / invokeOnError / invokeOnSkip*` (Task 20 API). The legacy
332
+ * step-level methods (`invokeBeforeStep` etc.) consume a derived
333
+ * legacy-shaped map produced by `buildLegacyStepResolvers` — that
334
+ * conversion happens at the call site, not here, so this method stays
335
+ * the single source of truth for the new shape.
336
+ *
337
+ * Ref resolution rules:
338
+ * - `RefKind.BuilderLambda` → use `ref.fn` directly (the compiler
339
+ * pre-binds decorator-discovered methods
340
+ * and the builder API ships bare fns).
341
+ * - `RefKind.Method` → requires the Jobable instance. Until
342
+ * a `ModuleRef` is wired (Task 9+), this
343
+ * branch logs a warning and is skipped.
344
+ * - `RefKind.ProviderToken` → resolved in Task 9 against a
345
+ * pre-built provider map. Skipped here
346
+ * with a warning.
347
+ */ buildResolverMap(jobDef) {
348
+ const resolvers = new Map();
349
+ let lambdaCounter = 0;
350
+ for (const def of jobDef.listeners){
351
+ const fn = this.resolveListenerRef(def);
352
+ if (fn === null) continue;
353
+ const name = this.resolveListenerName(def.ref, lambdaCounter);
354
+ if (def.ref.kind === _ir.RefKind.BuilderLambda) lambdaCounter += 1;
355
+ const key = `${def.phase}:${def.kind}:${name}`;
356
+ resolvers.set(key, {
357
+ fn,
358
+ ...def.nonCritical !== undefined ? {
359
+ nonCritical: def.nonCritical
360
+ } : {}
361
+ });
362
+ }
363
+ return resolvers;
364
+ }
365
+ /**
366
+ * Resolve a single `ListenerDefinition` to its callable function, or
367
+ * `null` if the ref kind is not yet supported. See `buildResolverMap`
368
+ * for the per-kind resolution contract.
369
+ */ resolveListenerRef(def) {
370
+ const ref = def.ref;
371
+ switch(ref.kind){
372
+ case _ir.RefKind.BuilderLambda:
373
+ return ref.fn ?? null;
374
+ case _ir.RefKind.Method:
375
+ this.logger.warn(`JobExecutor: Method-ref listener (classToken=${ref.classToken ?? '<unknown>'}, ` + `methodName=${ref.methodName ?? '<unknown>'}) requires a Jobable instance; ` + 'this resolution path lands in a follow-up task. Listener skipped.');
376
+ return null;
377
+ case _ir.RefKind.ProviderToken:
378
+ this.logger.warn(`JobExecutor: ProviderToken-ref listener (token=${ref.token ?? '<empty>'}) ` + 'is resolved in Task 9. Listener skipped.');
379
+ return null;
380
+ default:
381
+ {
382
+ const _exhaustive = ref.kind;
383
+ void _exhaustive;
384
+ return null;
385
+ }
386
+ }
387
+ }
388
+ /**
389
+ * Derive the `name` segment of the resolver key. Method refs carry a
390
+ * `classToken` + `methodName` pair that uniquely identifies the bound
391
+ * method; BuilderLambda refs do not carry a name (the compiler drops
392
+ * the method name when it pre-binds), so we mint a `lambda-N` name
393
+ * from a per-job counter to guarantee uniqueness.
394
+ */ resolveListenerName(ref, lambdaCounter) {
395
+ if (ref.kind === _ir.RefKind.Method) {
396
+ return `${ref.classToken ?? '<unknown>'}.${ref.methodName ?? '<unknown>'}`;
397
+ }
398
+ return `lambda-${lambdaCounter}`;
399
+ }
400
+ /**
401
+ * Derive a legacy `Map<string, ListenerResolver>` from a new
402
+ * `ResolverMap`, containing only the step-level entries with their
403
+ * keys translated from `${phase}:step:${name}` back to the legacy
404
+ * `${phase}-step:${name}` shape. The `nonCritical` flag is dropped
405
+ * (legacy `ListenerResolver` is a bare function with no metadata).
406
+ *
407
+ * This is the bridge the `TaskletStepExecutor` (which still consumes
408
+ * the legacy shape) needs until it migrates to the new API. Kept as
409
+ * a private helper so the conversion logic is in one place.
410
+ */ buildLegacyStepResolvers(resolvers) {
411
+ const legacy = new Map();
412
+ for (const [key, entry] of resolvers.entries()){
413
+ if (key.startsWith('before:step:')) {
414
+ legacy.set(`before-step:${key.slice('before:step:'.length)}`, entry.fn);
415
+ } else if (key.startsWith('after:step:')) {
416
+ legacy.set(`after-step:${key.slice('after:step:'.length)}`, entry.fn);
417
+ } else if (key.startsWith('on-error:step:')) {
418
+ legacy.set(`on-step-error:${key.slice('on-error:step:'.length)}`, entry.fn);
419
+ }
420
+ }
421
+ return legacy;
422
+ }
423
+ /**
424
+ * Read the `lastChunkIndex` checkpoint from the step-scoped
425
+ * ExecutionContext for `stepExecutionId`. Returns `undefined` when the
426
+ * step has no recorded checkpoint (e.g., the prior run failed on the
427
+ * very first chunk and never got a chance to write one). The chunk
428
+ * executor treats `undefined` as "no resume; start from the beginning".
429
+ */ async getLastCheckpoint(stepExecutionId) {
430
+ const ctx = await this.repository.getExecutionContext({
431
+ stepExecutionId
432
+ });
433
+ if (ctx.data === null || typeof ctx.data !== 'object' || Array.isArray(ctx.data)) {
434
+ return undefined;
435
+ }
436
+ const value = ctx.data.lastChunkIndex;
437
+ return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
438
+ }
439
+ async resolveDeciderExitStatus(jobDef, afterStepId, context) {
440
+ const decider = (jobDef.deciders ?? []).find((d)=>d.afterStepId === afterStepId);
441
+ if (decider === undefined) return undefined;
442
+ const status = await decider.decide(context);
443
+ const trimmed = status.trim();
444
+ return trimmed.length > 0 ? trimmed : undefined;
445
+ }
446
+ /**
447
+ * Dispatch a BatchEvent to the configured observer. Errors thrown by
448
+ * the observer are swallowed: a failing logger/queue must not crash
449
+ * the executor (the job's persisted state is the source of truth).
450
+ */ async emit(event) {
451
+ try {
452
+ await this.observer.onEvent(event);
453
+ } catch {
454
+ // intentional: observer failures are best-effort and must not
455
+ // affect the executor's own state transitions.
456
+ }
457
+ }
458
+ };
459
+ JobExecutor = _ts_decorate([
460
+ (0, _common.Injectable)(),
461
+ _ts_param(1, (0, _common.Inject)((0, _common.forwardRef)(()=>_transaction.TransactionManager))),
462
+ _ts_param(6, (0, _common.Optional)()),
463
+ _ts_metadata("design:type", Function),
464
+ _ts_metadata("design:paramtypes", [
465
+ typeof _repository.JobRepository === "undefined" ? Object : _repository.JobRepository,
466
+ typeof _transaction.TransactionManager === "undefined" ? Object : _transaction.TransactionManager,
467
+ typeof _taskletstepexecutor.TaskletStepExecutor === "undefined" ? Object : _taskletstepexecutor.TaskletStepExecutor,
468
+ typeof _chunkstepexecutor.ChunkStepExecutor === "undefined" ? Object : _chunkstepexecutor.ChunkStepExecutor,
469
+ typeof _listenerinvoker.ListenerInvoker === "undefined" ? Object : _listenerinvoker.ListenerInvoker,
470
+ typeof _flowevaluator.FlowEvaluator === "undefined" ? Object : _flowevaluator.FlowEvaluator,
471
+ typeof BatchObserver === "undefined" ? Object : BatchObserver
472
+ ])
473
+ ], JobExecutor);
474
+
475
+ //# sourceMappingURL=job-executor.js.map