@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,79 @@
1
+ import type { TaskletStepDefinition } from '../core/ir';
2
+ import type { JobRepository, StepExecution, ExecutionScope } from '../core/repository';
3
+ import type { TransactionManager } from '../core/transaction';
4
+ import { StepStatus, JobStatus } from '../core/status';
5
+ import { ListenerInvoker, type ListenerResolver } from './listener-invoker';
6
+ import { type ProviderResolvers } from './ref-resolver';
7
+ /**
8
+ * Bundled dependencies + state for a single `TaskletStepExecutor.execute()` call.
9
+ * The caller (JobExecutor, Task 20) owns lifecycle and persistence.
10
+ */
11
+ export interface TaskletExecutionContext {
12
+ jobExecutionId: string;
13
+ jobRepository: JobRepository;
14
+ transactionManager: TransactionManager;
15
+ listenerInvoker: ListenerInvoker;
16
+ /** Map from ListenerRef key (`phase:name`) to actual function. */
17
+ listenerResolvers: Map<string, ListenerResolver>;
18
+ /** Optional map of provider-token id → already-resolved provider instance
19
+ * for `RefKind.ProviderToken` tasklet refs. */
20
+ providerResolvers?: ProviderResolvers;
21
+ }
22
+ /**
23
+ * Result of a single tasklet step. Mirrors the subset of `StepExecutionPatch`
24
+ * that the executor can fill in BEFORE the JobExecutor persists it.
25
+ *
26
+ * - `status` — `COMPLETED` if the tasklet returned, `FAILED` if it threw
27
+ * - `exitCode` — short string label (`COMPLETED` / `FAILED`)
28
+ * - `exitMessage` — tasklet's return value (on success) or error message (on failure)
29
+ * - `readCount`/`writeCount`/`skipCount` — always 0 for tasklets (no chunk loop)
30
+ */
31
+ export interface StepExecutionResult {
32
+ status: StepStatus;
33
+ exitCode: string;
34
+ exitMessage: string;
35
+ readCount: number;
36
+ writeCount: number;
37
+ skipCount: number;
38
+ }
39
+ /**
40
+ * TaskletStepExecutor — runs a single tasklet step.
41
+ *
42
+ * Orchestration contract (in order):
43
+ * 1. `before-step:*` listeners (always run; failures bubble up)
44
+ * 2. `transactionManager.withTransaction(tasklet.execute, ctx)`
45
+ * 3a. On success → result `{ status: COMPLETED, exitCode: 'COMPLETED', exitMessage: <return> }`
46
+ * 3b. On error → `on-step-error:*` listeners → result `{ status: FAILED, exitCode: 'FAILED', exitMessage: <err> }`
47
+ * 4. `after-step:*` listeners (always run, receives the result)
48
+ *
49
+ * Persistence of the StepExecution is the caller's responsibility —
50
+ * this executor returns a `StepExecutionResult` and the JobExecutor (Task 20)
51
+ * applies it via `jobRepository.updateStepExecution()`.
52
+ *
53
+ * Read/write counts are always 0 for tasklets; the chunk executor (Task 18)
54
+ * produces non-zero counts.
55
+ */
56
+ export declare class TaskletStepExecutor {
57
+ /**
58
+ * Execute a tasklet step. Returns the step execution result.
59
+ * The caller (JobExecutor, Task 20) handles persistence of the StepExecution.
60
+ */
61
+ execute(step: TaskletStepDefinition, context: TaskletExecutionContext): Promise<StepExecutionResult>;
62
+ /**
63
+ * Resolve a `TaskletRef` to a `Tasklet` instance.
64
+ *
65
+ * Supported kinds:
66
+ * - `builder-lambda` — `taskletRef.fn` is the bound tasklet function.
67
+ * - `provider-token` — looked up in `context.providerResolvers` against
68
+ * `taskletRef.token`. The bound instance must
69
+ * expose an `execute(ctx)` method.
70
+ *
71
+ * Method refs are pre-resolved by the caller and wrapped in a
72
+ * `builder-lambda` ref before reaching this executor.
73
+ */
74
+ private resolveTasklet;
75
+ }
76
+ export type { Tasklet, TaskletContext } from '../core/item';
77
+ export type { StepExecution, ExecutionScope };
78
+ export { StepStatus, JobStatus };
79
+ //# sourceMappingURL=tasklet-step-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasklet-step-executor.d.ts","sourceRoot":"","sources":["../../../src/execution/tasklet-step-executor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAsB,MAAM,YAAY,CAAC;AAG5E,OAAO,KAAK,EACV,aAAa,EAEb,aAAa,EACb,cAAc,EACf,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAwB,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAE9E;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,aAAa,CAAC;IAC7B,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,eAAe,EAAE,eAAe,CAAC;IACjC,kEAAkE;IAClE,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACjD;oDACgD;IAChD,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBACa,mBAAmB;IAC9B;;;OAGG;IACG,OAAO,CACX,IAAI,EAAE,qBAAqB,EAC3B,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,mBAAmB,CAAC;IAsE/B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,cAAc;CAmBvB;AAGD,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC5D,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC"}
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: Object.getOwnPropertyDescriptor(all, name).get
9
+ });
10
+ }
11
+ _export(exports, {
12
+ get JobStatus () {
13
+ return _status.JobStatus;
14
+ },
15
+ get StepStatus () {
16
+ return _status.StepStatus;
17
+ },
18
+ get TaskletStepExecutor () {
19
+ return TaskletStepExecutor;
20
+ }
21
+ });
22
+ const _common = require("@nestjs/common");
23
+ const _ir = require("../core/ir");
24
+ const _status = require("../core/status");
25
+ const _refresolver = require("./ref-resolver");
26
+ function _ts_decorate(decorators, target, key, desc) {
27
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
28
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
29
+ 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;
30
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
31
+ }
32
+ let TaskletStepExecutor = class TaskletStepExecutor {
33
+ /**
34
+ * Execute a tasklet step. Returns the step execution result.
35
+ * The caller (JobExecutor, Task 20) handles persistence of the StepExecution.
36
+ */ async execute(step, context) {
37
+ // Build the TaskletContext the tasklet will see.
38
+ //
39
+ // `stepExecutionId` is a placeholder here — the JobExecutor knows the real
40
+ // ID (it created the StepExecution) and will patch this object before the
41
+ // tasklet uses it. The placeholder keeps the contract explicit.
42
+ //
43
+ // `getExecutionContext` / `saveExecutionContext` are also stubbed here;
44
+ // they become real once the JobExecutor wires the stepExecutionId in.
45
+ // (For Wave 3 tests we do not exercise these methods.)
46
+ const taskletCtx = {
47
+ jobExecutionId: context.jobExecutionId,
48
+ stepExecutionId: '<pending>',
49
+ getExecutionContext: async ()=>({
50
+ data: null,
51
+ version: 0
52
+ }),
53
+ saveExecutionContext: async (_ctx)=>{
54
+ // wired by JobExecutor (Task 20) once stepExecutionId is known
55
+ }
56
+ };
57
+ // 1. before-step listeners
58
+ await context.listenerInvoker.invokeBeforeStep(context.listenerResolvers, {
59
+ jobExecutionId: context.jobExecutionId,
60
+ stepExecutionId: taskletCtx.stepExecutionId
61
+ });
62
+ let result;
63
+ try {
64
+ // 2. withTransaction wrap
65
+ const taskletInstance = this.resolveTasklet(step.tasklet, context);
66
+ const txResult = await context.transactionManager.withTransaction(async (_txCtx)=>{
67
+ return taskletInstance.execute(taskletCtx);
68
+ });
69
+ result = {
70
+ status: _status.StepStatus.COMPLETED,
71
+ exitCode: 'COMPLETED',
72
+ exitMessage: txResult === undefined ? '' : String(txResult),
73
+ readCount: 0,
74
+ writeCount: 0,
75
+ skipCount: 0
76
+ };
77
+ } catch (err) {
78
+ // 3. on-step-error listeners (best-effort: rethrow their failures too)
79
+ await context.listenerInvoker.invokeOnErrorStep(context.listenerResolvers, {
80
+ jobExecutionId: context.jobExecutionId,
81
+ stepExecutionId: taskletCtx.stepExecutionId
82
+ }, err);
83
+ result = {
84
+ status: _status.StepStatus.FAILED,
85
+ exitCode: 'FAILED',
86
+ exitMessage: err instanceof Error ? err.message : String(err),
87
+ readCount: 0,
88
+ writeCount: 0,
89
+ skipCount: 0
90
+ };
91
+ }
92
+ // 4. after-step listeners (always run, even on failure).
93
+ // Pass the LIVE `result` (not a snapshot) so an `after-step`
94
+ // listener can mutate `result.status` and steer the flow into a
95
+ // different branch — transition evaluation runs AFTER this call.
96
+ await context.listenerInvoker.invokeAfterStep(context.listenerResolvers, {
97
+ jobExecutionId: context.jobExecutionId,
98
+ stepExecutionId: taskletCtx.stepExecutionId
99
+ }, result);
100
+ return result;
101
+ }
102
+ /**
103
+ * Resolve a `TaskletRef` to a `Tasklet` instance.
104
+ *
105
+ * Supported kinds:
106
+ * - `builder-lambda` — `taskletRef.fn` is the bound tasklet function.
107
+ * - `provider-token` — looked up in `context.providerResolvers` against
108
+ * `taskletRef.token`. The bound instance must
109
+ * expose an `execute(ctx)` method.
110
+ *
111
+ * Method refs are pre-resolved by the caller and wrapped in a
112
+ * `builder-lambda` ref before reaching this executor.
113
+ */ resolveTasklet(taskletRef, context) {
114
+ if (taskletRef.kind === _ir.RefKind.BuilderLambda && taskletRef.fn) {
115
+ const result = taskletRef.fn();
116
+ if (typeof result === 'function') {
117
+ return {
118
+ execute: result
119
+ };
120
+ }
121
+ if (result !== null && typeof result === 'object' && typeof result.execute === 'function') {
122
+ return result;
123
+ }
124
+ return {
125
+ execute: taskletRef.fn
126
+ };
127
+ }
128
+ if (taskletRef.kind === _ir.RefKind.ProviderToken) {
129
+ return (0, _refresolver.resolveProviderToken)('tasklet', taskletRef, context.providerResolvers);
130
+ }
131
+ throw new Error(`Tasklet resolution not supported for ref kind: ${taskletRef.kind}`);
132
+ }
133
+ };
134
+ TaskletStepExecutor = _ts_decorate([
135
+ (0, _common.Injectable)()
136
+ ], TaskletStepExecutor);
137
+
138
+ //# sourceMappingURL=tasklet-step-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/execution/tasklet-step-executor.ts"],"sourcesContent":["import { Injectable } from '@nestjs/common';\nimport type { TaskletStepDefinition, ListenerDefinition } from '../core/ir';\nimport { RefKind } from '../core/ir';\nimport type { Tasklet, TaskletContext } from '../core/item';\nimport type {\n JobRepository,\n ExecutionContext,\n StepExecution,\n ExecutionScope,\n} from '../core/repository';\nimport type { TransactionManager } from '../core/transaction';\nimport { StepStatus, JobStatus } from '../core/status';\nimport { ListenerInvoker, type ListenerResolver } from './listener-invoker';\nimport { resolveProviderToken, type ProviderResolvers } from './ref-resolver';\n\n/**\n * Bundled dependencies + state for a single `TaskletStepExecutor.execute()` call.\n * The caller (JobExecutor, Task 20) owns lifecycle and persistence.\n */\nexport interface TaskletExecutionContext {\n jobExecutionId: string;\n jobRepository: JobRepository;\n transactionManager: TransactionManager;\n listenerInvoker: ListenerInvoker;\n /** Map from ListenerRef key (`phase:name`) to actual function. */\n listenerResolvers: Map<string, ListenerResolver>;\n /** Optional map of provider-token id → already-resolved provider instance\n * for `RefKind.ProviderToken` tasklet refs. */\n providerResolvers?: ProviderResolvers;\n}\n\n/**\n * Result of a single tasklet step. Mirrors the subset of `StepExecutionPatch`\n * that the executor can fill in BEFORE the JobExecutor persists it.\n *\n * - `status` — `COMPLETED` if the tasklet returned, `FAILED` if it threw\n * - `exitCode` — short string label (`COMPLETED` / `FAILED`)\n * - `exitMessage` — tasklet's return value (on success) or error message (on failure)\n * - `readCount`/`writeCount`/`skipCount` — always 0 for tasklets (no chunk loop)\n */\nexport interface StepExecutionResult {\n status: StepStatus;\n exitCode: string;\n exitMessage: string;\n readCount: number;\n writeCount: number;\n skipCount: number;\n}\n\n/**\n * TaskletStepExecutor — runs a single tasklet step.\n *\n * Orchestration contract (in order):\n * 1. `before-step:*` listeners (always run; failures bubble up)\n * 2. `transactionManager.withTransaction(tasklet.execute, ctx)`\n * 3a. On success → result `{ status: COMPLETED, exitCode: 'COMPLETED', exitMessage: <return> }`\n * 3b. On error → `on-step-error:*` listeners → result `{ status: FAILED, exitCode: 'FAILED', exitMessage: <err> }`\n * 4. `after-step:*` listeners (always run, receives the result)\n *\n * Persistence of the StepExecution is the caller's responsibility —\n * this executor returns a `StepExecutionResult` and the JobExecutor (Task 20)\n * applies it via `jobRepository.updateStepExecution()`.\n *\n * Read/write counts are always 0 for tasklets; the chunk executor (Task 18)\n * produces non-zero counts.\n */\n@Injectable()\nexport class TaskletStepExecutor {\n /**\n * Execute a tasklet step. Returns the step execution result.\n * The caller (JobExecutor, Task 20) handles persistence of the StepExecution.\n */\n async execute(\n step: TaskletStepDefinition,\n context: TaskletExecutionContext,\n ): Promise<StepExecutionResult> {\n // Build the TaskletContext the tasklet will see.\n //\n // `stepExecutionId` is a placeholder here — the JobExecutor knows the real\n // ID (it created the StepExecution) and will patch this object before the\n // tasklet uses it. The placeholder keeps the contract explicit.\n //\n // `getExecutionContext` / `saveExecutionContext` are also stubbed here;\n // they become real once the JobExecutor wires the stepExecutionId in.\n // (For Wave 3 tests we do not exercise these methods.)\n const taskletCtx: TaskletContext = {\n jobExecutionId: context.jobExecutionId,\n stepExecutionId: '<pending>',\n getExecutionContext: async () => ({ data: null, version: 0 }),\n saveExecutionContext: async (_ctx: ExecutionContext) => {\n // wired by JobExecutor (Task 20) once stepExecutionId is known\n },\n };\n\n // 1. before-step listeners\n await context.listenerInvoker.invokeBeforeStep(context.listenerResolvers, {\n jobExecutionId: context.jobExecutionId,\n stepExecutionId: taskletCtx.stepExecutionId,\n });\n\n let result: StepExecutionResult;\n try {\n // 2. withTransaction wrap\n const taskletInstance = this.resolveTasklet(step.tasklet, context);\n const txResult = await context.transactionManager.withTransaction(async (_txCtx) => {\n return taskletInstance.execute(taskletCtx);\n });\n result = {\n status: StepStatus.COMPLETED,\n exitCode: 'COMPLETED',\n exitMessage: txResult === undefined ? '' : String(txResult),\n readCount: 0,\n writeCount: 0,\n skipCount: 0,\n };\n } catch (err) {\n // 3. on-step-error listeners (best-effort: rethrow their failures too)\n await context.listenerInvoker.invokeOnErrorStep(\n context.listenerResolvers,\n { jobExecutionId: context.jobExecutionId, stepExecutionId: taskletCtx.stepExecutionId },\n err,\n );\n result = {\n status: StepStatus.FAILED,\n exitCode: 'FAILED',\n exitMessage: err instanceof Error ? err.message : String(err),\n readCount: 0,\n writeCount: 0,\n skipCount: 0,\n };\n }\n\n // 4. after-step listeners (always run, even on failure).\n // Pass the LIVE `result` (not a snapshot) so an `after-step`\n // listener can mutate `result.status` and steer the flow into a\n // different branch — transition evaluation runs AFTER this call.\n await context.listenerInvoker.invokeAfterStep(\n context.listenerResolvers,\n { jobExecutionId: context.jobExecutionId, stepExecutionId: taskletCtx.stepExecutionId },\n result,\n );\n\n return result;\n }\n\n /**\n * Resolve a `TaskletRef` to a `Tasklet` instance.\n *\n * Supported kinds:\n * - `builder-lambda` — `taskletRef.fn` is the bound tasklet function.\n * - `provider-token` — looked up in `context.providerResolvers` against\n * `taskletRef.token`. The bound instance must\n * expose an `execute(ctx)` method.\n *\n * Method refs are pre-resolved by the caller and wrapped in a\n * `builder-lambda` ref before reaching this executor.\n */\n private resolveTasklet(\n taskletRef: { kind: string; token?: string; fn?: ListenerResolver; classToken?: string; methodName?: string },\n context: TaskletExecutionContext,\n ): Tasklet {\n if (taskletRef.kind === RefKind.BuilderLambda && taskletRef.fn) {\n const result = taskletRef.fn();\n if (typeof result === 'function') {\n return { execute: result as Tasklet['execute'] };\n }\n if (result !== null && typeof result === 'object' && typeof (result as Tasklet).execute === 'function') {\n return result as Tasklet;\n }\n return { execute: taskletRef.fn as Tasklet['execute'] };\n }\n if (taskletRef.kind === RefKind.ProviderToken) {\n return resolveProviderToken<Tasklet>('tasklet', taskletRef, context.providerResolvers);\n }\n throw new Error(`Tasklet resolution not supported for ref kind: ${taskletRef.kind}`);\n }\n}\n\n// Re-exports for convenience — callers may import types from the executor module.\nexport type { Tasklet, TaskletContext } from '../core/item';\nexport type { StepExecution, ExecutionScope };\nexport { StepStatus, JobStatus };\n"],"names":["JobStatus","StepStatus","TaskletStepExecutor","execute","step","context","taskletCtx","jobExecutionId","stepExecutionId","getExecutionContext","data","version","saveExecutionContext","_ctx","listenerInvoker","invokeBeforeStep","listenerResolvers","result","taskletInstance","resolveTasklet","tasklet","txResult","transactionManager","withTransaction","_txCtx","status","COMPLETED","exitCode","exitMessage","undefined","String","readCount","writeCount","skipCount","err","invokeOnErrorStep","FAILED","Error","message","invokeAfterStep","taskletRef","kind","RefKind","BuilderLambda","fn","ProviderToken","resolveProviderToken","providerResolvers"],"mappings":";;;;;;;;;;;QAqLqBA;eAAAA,iBAAS;;QAArBC;eAAAA,kBAAU;;QAlHNC;eAAAA;;;wBAnEc;oBAEH;wBASc;6BAEuB;;;;;;;AAsDtD,IAAA,AAAMA,sBAAN,MAAMA;IACX;;;GAGC,GACD,MAAMC,QACJC,IAA2B,EAC3BC,OAAgC,EACF;QAC9B,iDAAiD;QACjD,EAAE;QACF,2EAA2E;QAC3E,0EAA0E;QAC1E,gEAAgE;QAChE,EAAE;QACF,wEAAwE;QACxE,sEAAsE;QACtE,uDAAuD;QACvD,MAAMC,aAA6B;YACjCC,gBAAgBF,QAAQE,cAAc;YACtCC,iBAAiB;YACjBC,qBAAqB,UAAa,CAAA;oBAAEC,MAAM;oBAAMC,SAAS;gBAAE,CAAA;YAC3DC,sBAAsB,OAAOC;YAC3B,+DAA+D;YACjE;QACF;QAEA,2BAA2B;QAC3B,MAAMR,QAAQS,eAAe,CAACC,gBAAgB,CAACV,QAAQW,iBAAiB,EAAE;YACxET,gBAAgBF,QAAQE,cAAc;YACtCC,iBAAiBF,WAAWE,eAAe;QAC7C;QAEA,IAAIS;QACJ,IAAI;YACF,0BAA0B;YAC1B,MAAMC,kBAAkB,IAAI,CAACC,cAAc,CAACf,KAAKgB,OAAO,EAAEf;YAC1D,MAAMgB,WAAW,MAAMhB,QAAQiB,kBAAkB,CAACC,eAAe,CAAC,OAAOC;gBACvE,OAAON,gBAAgBf,OAAO,CAACG;YACjC;YACAW,SAAS;gBACPQ,QAAQxB,kBAAU,CAACyB,SAAS;gBAC5BC,UAAU;gBACVC,aAAaP,aAAaQ,YAAY,KAAKC,OAAOT;gBAClDU,WAAW;gBACXC,YAAY;gBACZC,WAAW;YACb;QACF,EAAE,OAAOC,KAAK;YACZ,uEAAuE;YACvE,MAAM7B,QAAQS,eAAe,CAACqB,iBAAiB,CAC7C9B,QAAQW,iBAAiB,EACzB;gBAAET,gBAAgBF,QAAQE,cAAc;gBAAEC,iBAAiBF,WAAWE,eAAe;YAAC,GACtF0B;YAEFjB,SAAS;gBACPQ,QAAQxB,kBAAU,CAACmC,MAAM;gBACzBT,UAAU;gBACVC,aAAaM,eAAeG,QAAQH,IAAII,OAAO,GAAGR,OAAOI;gBACzDH,WAAW;gBACXC,YAAY;gBACZC,WAAW;YACb;QACF;QAEA,yDAAyD;QACzD,6DAA6D;QAC7D,gEAAgE;QAChE,iEAAiE;QACjE,MAAM5B,QAAQS,eAAe,CAACyB,eAAe,CAC3ClC,QAAQW,iBAAiB,EACzB;YAAET,gBAAgBF,QAAQE,cAAc;YAAEC,iBAAiBF,WAAWE,eAAe;QAAC,GACtFS;QAGF,OAAOA;IACT;IAEA;;;;;;;;;;;GAWC,GACD,AAAQE,eACNqB,UAA6G,EAC7GnC,OAAgC,EACvB;QACT,IAAImC,WAAWC,IAAI,KAAKC,WAAO,CAACC,aAAa,IAAIH,WAAWI,EAAE,EAAE;YAC9D,MAAM3B,SAASuB,WAAWI,EAAE;YAC5B,IAAI,OAAO3B,WAAW,YAAY;gBAChC,OAAO;oBAAEd,SAASc;gBAA6B;YACjD;YACA,IAAIA,WAAW,QAAQ,OAAOA,WAAW,YAAY,OAAO,AAACA,OAAmBd,OAAO,KAAK,YAAY;gBACtG,OAAOc;YACT;YACA,OAAO;gBAAEd,SAASqC,WAAWI,EAAE;YAAuB;QACxD;QACA,IAAIJ,WAAWC,IAAI,KAAKC,WAAO,CAACG,aAAa,EAAE;YAC7C,OAAOC,IAAAA,iCAAoB,EAAU,WAAWN,YAAYnC,QAAQ0C,iBAAiB;QACvF;QACA,MAAM,IAAIV,MAAM,CAAC,+CAA+C,EAAEG,WAAWC,IAAI,EAAE;IACrF;AACF"}
@@ -0,0 +1,138 @@
1
+ import { OnModuleInit } from '@nestjs/common';
2
+ import { DiscoveryService } from '@nestjs/core';
3
+ import 'reflect-metadata';
4
+ import type { JobableOptions, StepableOptions } from '../decorators';
5
+ import type { ListenerKind, ListenerPhase } from '../core/ir/listener-definition';
6
+ /**
7
+ * Raw shape of a discovered batch job, as it appears immediately after the
8
+ * explorer walks the Nest provider tree. The {@link DiscoveredJob} contains
9
+ * only metadata + class reference + (optionally) the resolved DI instance.
10
+ *
11
+ * It is intentionally NOT a `JobDefinition` yet — the {@link DefinitionCompiler}
12
+ * (Task 8) is responsible for resolving the prototype methods into concrete
13
+ * `ListenerRef` / `TaskletRef` / `ReaderRef` / `ProcessorRef` / `WriterRef` /
14
+ * `TransitionRef` records and for choosing a start step.
15
+ */
16
+ export interface DiscoveredJob {
17
+ /** The @Jobable-decorated class reference. */
18
+ classRef: Function;
19
+ /** The Nest-resolved DI instance, when available. May be `undefined` for
20
+ * factories or providers that have not been instantiated yet. */
21
+ instance?: unknown;
22
+ /** Raw options passed to `@Jobable(...)`. */
23
+ jobOptions: JobableOptions;
24
+ /** Every `@Stepable` method on the class prototype, in declaration order. */
25
+ stepMethods: DiscoveredStep[];
26
+ /** Every listener-decorated method on the class prototype, in declaration order. */
27
+ listenerMethods: DiscoveredListener[];
28
+ /** Every `@OnTransition` method on the class prototype, in declaration order. */
29
+ transitionMethods: DiscoveredTransition[];
30
+ }
31
+ /** A `@Stepable` method. `isTasklet` is true if `@Tasklet` was also applied. */
32
+ export interface DiscoveredStep {
33
+ methodName: string;
34
+ options: StepableOptions;
35
+ isTasklet: boolean;
36
+ }
37
+ /** A listener-decorated method (any of the 7 kinds). */
38
+ export interface DiscoveredListener {
39
+ methodName: string;
40
+ kind: ListenerKind;
41
+ phase: ListenerPhase;
42
+ nonCritical?: boolean;
43
+ }
44
+ /**
45
+ * A `@OnTransition` method. `onStatus` is the string name of a
46
+ * `FlowExecutionStatus` (e.g. `'COMPLETED'`, `'FAILED'`, `'STOPPED'`).
47
+ * `toStep === null` means the transition ends the flow.
48
+ */
49
+ export interface DiscoveredTransition {
50
+ methodName: string;
51
+ fromStep: string;
52
+ onStatus: string;
53
+ toStep: string | null;
54
+ }
55
+ /**
56
+ * Minimal shape required from an `InstanceWrapper`-like object. We accept
57
+ * this loose shape (rather than requiring the full Nest `InstanceWrapper`
58
+ * class) so that:
59
+ * 1. tests can pass plain `{ metatype, instance }` objects without booting
60
+ * a Nest application, and
61
+ * 2. future Nest versions that change the wrapper's internal shape will
62
+ * still work as long as `metatype` + `instance` are preserved.
63
+ */
64
+ export interface ProviderLike {
65
+ metatype?: Function;
66
+ instance?: unknown;
67
+ }
68
+ /**
69
+ * `BatchExplorer` is a Nest `OnModuleInit` provider that walks every
70
+ * provider registered in the application, looks for classes carrying
71
+ * `@Jobable(...)` metadata, and records every `@Stepable` / `@Tasklet` /
72
+ * listener / `@OnTransition` method on each discovered class.
73
+ *
74
+ * The actual `JobDefinition` IR is produced downstream by the
75
+ * `DefinitionCompiler` (Task 8). The explorer only collects the raw
76
+ * metadata; it does not validate it, compile references, or register jobs.
77
+ *
78
+ * Mirrors the pattern used by `@nestjs/schedule` (`SchedulerExplorer`) and
79
+ * `@nestjs/cqrs` (`Explorer`).
80
+ */
81
+ export declare class BatchExplorer implements OnModuleInit {
82
+ private readonly discovery;
83
+ private readonly logger;
84
+ private discovered;
85
+ constructor(discovery: DiscoveryService);
86
+ /** Hook called by Nest once the DI container is ready. */
87
+ onModuleInit(): void;
88
+ /**
89
+ * Returns the snapshot of jobs collected at `onModuleInit` time. The
90
+ * returned array is `readonly` — callers MUST NOT mutate it.
91
+ */
92
+ getDiscovered(): readonly DiscoveredJob[];
93
+ /**
94
+ * Pure provider-walk: given an array of `InstanceWrapper`-like objects,
95
+ * returns the list of `DiscoveredJob`s. Does not require a Nest container.
96
+ *
97
+ * The `onModuleInit` hook delegates here. Tests call this directly.
98
+ */
99
+ discoverFromProviders(providers: ProviderLike[]): DiscoveredJob[];
100
+ /**
101
+ * Walks the class prototype chain and returns every method that carries
102
+ * `BATCH_STEP_METADATA`. Each entry's `isTasklet` is true when the same
103
+ * method also carries `BATCH_TASKLET_METADATA`.
104
+ *
105
+ * Walks the full prototype chain (not just `Object.getOwnPropertyNames`
106
+ * on the top-level prototype) so that inherited `@Stepable` methods are
107
+ * also picked up.
108
+ */
109
+ private collectStepMethods;
110
+ /**
111
+ * Walks the prototype chain and returns every method decorated with one
112
+ * of the 7 listener kinds (job / step / chunk / item-read / item-process /
113
+ * item-write / skip). The metadata shape is uniform — `{ kind, phase,
114
+ * nonCritical? }` — because every listener decorator funnels through
115
+ * the same internal `defineListener` helper.
116
+ */
117
+ private collectListenerMethods;
118
+ /**
119
+ * Walks the prototype chain and returns every method carrying
120
+ * `BATCH_TRANSITION_METADATA` (written by the `@OnTransition` decorator
121
+ * added in Task 31). Until Task 31 lands, this method simply returns
122
+ * an empty array.
123
+ *
124
+ * `onStatus` is the *string name* of a `FlowExecutionStatus` value
125
+ * (e.g. `'COMPLETED'`, `'FAILED'`, `'STOPPED'`). It is stored as a string
126
+ * to avoid a circular import from `core/ir` → `core/status` and to keep
127
+ * the metadata JSON-serializable.
128
+ */
129
+ private collectTransitionMethods;
130
+ /**
131
+ * Returns every own method name (excluding `constructor`) on the given
132
+ * prototype and all of its ancestors up to (but not including)
133
+ * `Object.prototype`. Order is undefined, so callers that need a stable
134
+ * order should sort afterwards.
135
+ */
136
+ private allMethodNames;
137
+ }
138
+ //# sourceMappingURL=batch-explorer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch-explorer.d.ts","sourceRoot":"","sources":["../../../src/explorer/batch-explorer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,YAAY,EAAU,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,kBAAkB,CAAC;AAQ1B,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAElF;;;;;;;;;GASG;AACH,MAAM,WAAW,aAAa;IAC5B,8CAA8C;IAC9C,QAAQ,EAAE,QAAQ,CAAC;IACnB;sEACkE;IAClE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6CAA6C;IAC7C,UAAU,EAAE,cAAc,CAAC;IAC3B,6EAA6E;IAC7E,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,oFAAoF;IACpF,eAAe,EAAE,kBAAkB,EAAE,CAAC;IACtC,iFAAiF;IACjF,iBAAiB,EAAE,oBAAoB,EAAE,CAAC;CAC3C;AAED,gFAAgF;AAChF,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,eAAe,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wDAAwD;AACxD,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,aAAa,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;GAYG;AACH,qBACa,aAAc,YAAW,YAAY;IAIpC,OAAO,CAAC,QAAQ,CAAC,SAAS;IAHtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkC;IACzD,OAAO,CAAC,UAAU,CAAuB;gBAEZ,SAAS,EAAE,gBAAgB;IAExD,0DAA0D;IAC1D,YAAY,IAAI,IAAI;IAKpB;;;OAGG;IACH,aAAa,IAAI,SAAS,aAAa,EAAE;IAIzC;;;;;OAKG;IACH,qBAAqB,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,aAAa,EAAE;IA6BjE;;;;;;;;OAQG;IACH,OAAO,CAAC,kBAAkB;IAkB1B;;;;;;OAMG;IACH,OAAO,CAAC,sBAAsB;IAqB9B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,wBAAwB;IAgBhC;;;;;OAKG;IACH,OAAO,CAAC,cAAc;CAYvB"}
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "BatchExplorer", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return BatchExplorer;
9
+ }
10
+ });
11
+ const _common = require("@nestjs/common");
12
+ const _core = require("@nestjs/core");
13
+ require("reflect-metadata");
14
+ const _constants = require("../decorators/constants");
15
+ function _ts_decorate(decorators, target, key, desc) {
16
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
17
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
18
+ 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;
19
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
20
+ }
21
+ function _ts_metadata(k, v) {
22
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
23
+ }
24
+ let BatchExplorer = class BatchExplorer {
25
+ discovery;
26
+ logger = new _common.Logger(BatchExplorer.name);
27
+ discovered = [];
28
+ constructor(discovery){
29
+ this.discovery = discovery;
30
+ }
31
+ /** Hook called by Nest once the DI container is ready. */ onModuleInit() {
32
+ const providers = this.discovery.getProviders();
33
+ this.discovered = this.discoverFromProviders(providers);
34
+ }
35
+ /**
36
+ * Returns the snapshot of jobs collected at `onModuleInit` time. The
37
+ * returned array is `readonly` — callers MUST NOT mutate it.
38
+ */ getDiscovered() {
39
+ return this.discovered;
40
+ }
41
+ /**
42
+ * Pure provider-walk: given an array of `InstanceWrapper`-like objects,
43
+ * returns the list of `DiscoveredJob`s. Does not require a Nest container.
44
+ *
45
+ * The `onModuleInit` hook delegates here. Tests call this directly.
46
+ */ discoverFromProviders(providers) {
47
+ const out = [];
48
+ for (const wrapper of providers){
49
+ const metatype = wrapper.metatype;
50
+ if (!metatype) continue;
51
+ const jobOptions = Reflect.getMetadata(_constants.BATCH_JOB_METADATA, metatype);
52
+ if (!jobOptions) continue;
53
+ out.push({
54
+ classRef: metatype,
55
+ instance: wrapper.instance,
56
+ jobOptions,
57
+ stepMethods: this.collectStepMethods(metatype.prototype),
58
+ listenerMethods: this.collectListenerMethods(metatype.prototype),
59
+ transitionMethods: this.collectTransitionMethods(metatype.prototype)
60
+ });
61
+ this.logger.log(`Discovered job: ${jobOptions.id}`);
62
+ }
63
+ return out;
64
+ }
65
+ // -------------------------------------------------------------------------
66
+ // Step methods
67
+ // -------------------------------------------------------------------------
68
+ /**
69
+ * Walks the class prototype chain and returns every method that carries
70
+ * `BATCH_STEP_METADATA`. Each entry's `isTasklet` is true when the same
71
+ * method also carries `BATCH_TASKLET_METADATA`.
72
+ *
73
+ * Walks the full prototype chain (not just `Object.getOwnPropertyNames`
74
+ * on the top-level prototype) so that inherited `@Stepable` methods are
75
+ * also picked up.
76
+ */ collectStepMethods(prototype) {
77
+ const result = [];
78
+ for (const name of this.allMethodNames(prototype)){
79
+ const opts = Reflect.getMetadata(_constants.BATCH_STEP_METADATA, prototype, name);
80
+ if (!opts) continue;
81
+ const isTasklet = Reflect.getMetadata(_constants.BATCH_TASKLET_METADATA, prototype, name) === true;
82
+ result.push({
83
+ methodName: name,
84
+ options: opts,
85
+ isTasklet
86
+ });
87
+ }
88
+ return result;
89
+ }
90
+ // -------------------------------------------------------------------------
91
+ // Listener methods
92
+ // -------------------------------------------------------------------------
93
+ /**
94
+ * Walks the prototype chain and returns every method decorated with one
95
+ * of the 7 listener kinds (job / step / chunk / item-read / item-process /
96
+ * item-write / skip). The metadata shape is uniform — `{ kind, phase,
97
+ * nonCritical? }` — because every listener decorator funnels through
98
+ * the same internal `defineListener` helper.
99
+ */ collectListenerMethods(prototype) {
100
+ const result = [];
101
+ for (const name of this.allMethodNames(prototype)){
102
+ const opts = Reflect.getMetadata(_constants.BATCH_LISTENER_METADATA, prototype, name);
103
+ if (!opts) continue;
104
+ result.push({
105
+ methodName: name,
106
+ kind: opts.kind,
107
+ phase: opts.phase,
108
+ nonCritical: opts.nonCritical
109
+ });
110
+ }
111
+ return result;
112
+ }
113
+ // -------------------------------------------------------------------------
114
+ // Transition methods
115
+ // -------------------------------------------------------------------------
116
+ /**
117
+ * Walks the prototype chain and returns every method carrying
118
+ * `BATCH_TRANSITION_METADATA` (written by the `@OnTransition` decorator
119
+ * added in Task 31). Until Task 31 lands, this method simply returns
120
+ * an empty array.
121
+ *
122
+ * `onStatus` is the *string name* of a `FlowExecutionStatus` value
123
+ * (e.g. `'COMPLETED'`, `'FAILED'`, `'STOPPED'`). It is stored as a string
124
+ * to avoid a circular import from `core/ir` → `core/status` and to keep
125
+ * the metadata JSON-serializable.
126
+ */ collectTransitionMethods(prototype) {
127
+ const result = [];
128
+ for (const name of this.allMethodNames(prototype)){
129
+ const opts = Reflect.getMetadata(_constants.BATCH_TRANSITION_METADATA, prototype, name);
130
+ if (!opts) continue;
131
+ result.push({
132
+ methodName: name,
133
+ ...opts
134
+ });
135
+ }
136
+ return result;
137
+ }
138
+ // -------------------------------------------------------------------------
139
+ // Prototype walker
140
+ // -------------------------------------------------------------------------
141
+ /**
142
+ * Returns every own method name (excluding `constructor`) on the given
143
+ * prototype and all of its ancestors up to (but not including)
144
+ * `Object.prototype`. Order is undefined, so callers that need a stable
145
+ * order should sort afterwards.
146
+ */ allMethodNames(prototype) {
147
+ const names = new Set();
148
+ let proto = prototype;
149
+ while(proto && proto !== Object.prototype){
150
+ for (const name of Object.getOwnPropertyNames(proto)){
151
+ if (name === 'constructor') continue;
152
+ names.add(name);
153
+ }
154
+ proto = Object.getPrototypeOf(proto);
155
+ }
156
+ return names;
157
+ }
158
+ };
159
+ BatchExplorer = _ts_decorate([
160
+ (0, _common.Injectable)(),
161
+ _ts_metadata("design:type", Function),
162
+ _ts_metadata("design:paramtypes", [
163
+ typeof _core.DiscoveryService === "undefined" ? Object : _core.DiscoveryService
164
+ ])
165
+ ], BatchExplorer);
166
+
167
+ //# sourceMappingURL=batch-explorer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/explorer/batch-explorer.ts"],"sourcesContent":["import { Injectable, OnModuleInit, Logger } from '@nestjs/common';\nimport { DiscoveryService } from '@nestjs/core';\nimport type { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper';\nimport 'reflect-metadata';\nimport {\n BATCH_JOB_METADATA,\n BATCH_STEP_METADATA,\n BATCH_TASKLET_METADATA,\n BATCH_LISTENER_METADATA,\n BATCH_TRANSITION_METADATA,\n} from '../decorators/constants';\nimport type { JobableOptions, StepableOptions } from '../decorators';\nimport type { ListenerKind, ListenerPhase } from '../core/ir/listener-definition';\n\n/**\n * Raw shape of a discovered batch job, as it appears immediately after the\n * explorer walks the Nest provider tree. The {@link DiscoveredJob} contains\n * only metadata + class reference + (optionally) the resolved DI instance.\n *\n * It is intentionally NOT a `JobDefinition` yet — the {@link DefinitionCompiler}\n * (Task 8) is responsible for resolving the prototype methods into concrete\n * `ListenerRef` / `TaskletRef` / `ReaderRef` / `ProcessorRef` / `WriterRef` /\n * `TransitionRef` records and for choosing a start step.\n */\nexport interface DiscoveredJob {\n /** The @Jobable-decorated class reference. */\n classRef: Function;\n /** The Nest-resolved DI instance, when available. May be `undefined` for\n * factories or providers that have not been instantiated yet. */\n instance?: unknown;\n /** Raw options passed to `@Jobable(...)`. */\n jobOptions: JobableOptions;\n /** Every `@Stepable` method on the class prototype, in declaration order. */\n stepMethods: DiscoveredStep[];\n /** Every listener-decorated method on the class prototype, in declaration order. */\n listenerMethods: DiscoveredListener[];\n /** Every `@OnTransition` method on the class prototype, in declaration order. */\n transitionMethods: DiscoveredTransition[];\n}\n\n/** A `@Stepable` method. `isTasklet` is true if `@Tasklet` was also applied. */\nexport interface DiscoveredStep {\n methodName: string;\n options: StepableOptions;\n isTasklet: boolean;\n}\n\n/** A listener-decorated method (any of the 7 kinds). */\nexport interface DiscoveredListener {\n methodName: string;\n kind: ListenerKind;\n phase: ListenerPhase;\n nonCritical?: boolean;\n}\n\n/**\n * A `@OnTransition` method. `onStatus` is the string name of a\n * `FlowExecutionStatus` (e.g. `'COMPLETED'`, `'FAILED'`, `'STOPPED'`).\n * `toStep === null` means the transition ends the flow.\n */\nexport interface DiscoveredTransition {\n methodName: string;\n fromStep: string;\n onStatus: string;\n toStep: string | null;\n}\n\n/**\n * Minimal shape required from an `InstanceWrapper`-like object. We accept\n * this loose shape (rather than requiring the full Nest `InstanceWrapper`\n * class) so that:\n * 1. tests can pass plain `{ metatype, instance }` objects without booting\n * a Nest application, and\n * 2. future Nest versions that change the wrapper's internal shape will\n * still work as long as `metatype` + `instance` are preserved.\n */\nexport interface ProviderLike {\n metatype?: Function;\n instance?: unknown;\n}\n\n/**\n * `BatchExplorer` is a Nest `OnModuleInit` provider that walks every\n * provider registered in the application, looks for classes carrying\n * `@Jobable(...)` metadata, and records every `@Stepable` / `@Tasklet` /\n * listener / `@OnTransition` method on each discovered class.\n *\n * The actual `JobDefinition` IR is produced downstream by the\n * `DefinitionCompiler` (Task 8). The explorer only collects the raw\n * metadata; it does not validate it, compile references, or register jobs.\n *\n * Mirrors the pattern used by `@nestjs/schedule` (`SchedulerExplorer`) and\n * `@nestjs/cqrs` (`Explorer`).\n */\n@Injectable()\nexport class BatchExplorer implements OnModuleInit {\n private readonly logger = new Logger(BatchExplorer.name);\n private discovered: DiscoveredJob[] = [];\n\n constructor(private readonly discovery: DiscoveryService) {}\n\n /** Hook called by Nest once the DI container is ready. */\n onModuleInit(): void {\n const providers = this.discovery.getProviders();\n this.discovered = this.discoverFromProviders(providers as ProviderLike[]);\n }\n\n /**\n * Returns the snapshot of jobs collected at `onModuleInit` time. The\n * returned array is `readonly` — callers MUST NOT mutate it.\n */\n getDiscovered(): readonly DiscoveredJob[] {\n return this.discovered;\n }\n\n /**\n * Pure provider-walk: given an array of `InstanceWrapper`-like objects,\n * returns the list of `DiscoveredJob`s. Does not require a Nest container.\n *\n * The `onModuleInit` hook delegates here. Tests call this directly.\n */\n discoverFromProviders(providers: ProviderLike[]): DiscoveredJob[] {\n const out: DiscoveredJob[] = [];\n for (const wrapper of providers) {\n const metatype = wrapper.metatype;\n if (!metatype) continue;\n\n const jobOptions = Reflect.getMetadata(BATCH_JOB_METADATA, metatype) as\n | JobableOptions\n | undefined;\n if (!jobOptions) continue;\n\n out.push({\n classRef: metatype,\n instance: wrapper.instance,\n jobOptions,\n stepMethods: this.collectStepMethods(metatype.prototype),\n listenerMethods: this.collectListenerMethods(metatype.prototype),\n transitionMethods: this.collectTransitionMethods(metatype.prototype),\n });\n\n this.logger.log(`Discovered job: ${jobOptions.id}`);\n }\n return out;\n }\n\n // -------------------------------------------------------------------------\n // Step methods\n // -------------------------------------------------------------------------\n\n /**\n * Walks the class prototype chain and returns every method that carries\n * `BATCH_STEP_METADATA`. Each entry's `isTasklet` is true when the same\n * method also carries `BATCH_TASKLET_METADATA`.\n *\n * Walks the full prototype chain (not just `Object.getOwnPropertyNames`\n * on the top-level prototype) so that inherited `@Stepable` methods are\n * also picked up.\n */\n private collectStepMethods(prototype: object): DiscoveredStep[] {\n const result: DiscoveredStep[] = [];\n for (const name of this.allMethodNames(prototype)) {\n const opts = Reflect.getMetadata(BATCH_STEP_METADATA, prototype, name) as\n | StepableOptions\n | undefined;\n if (!opts) continue;\n const isTasklet =\n Reflect.getMetadata(BATCH_TASKLET_METADATA, prototype, name) === true;\n result.push({ methodName: name, options: opts, isTasklet });\n }\n return result;\n }\n\n // -------------------------------------------------------------------------\n // Listener methods\n // -------------------------------------------------------------------------\n\n /**\n * Walks the prototype chain and returns every method decorated with one\n * of the 7 listener kinds (job / step / chunk / item-read / item-process /\n * item-write / skip). The metadata shape is uniform — `{ kind, phase,\n * nonCritical? }` — because every listener decorator funnels through\n * the same internal `defineListener` helper.\n */\n private collectListenerMethods(prototype: object): DiscoveredListener[] {\n const result: DiscoveredListener[] = [];\n for (const name of this.allMethodNames(prototype)) {\n const opts = Reflect.getMetadata(BATCH_LISTENER_METADATA, prototype, name) as\n | { kind: ListenerKind; phase: ListenerPhase; nonCritical?: boolean }\n | undefined;\n if (!opts) continue;\n result.push({\n methodName: name,\n kind: opts.kind,\n phase: opts.phase,\n nonCritical: opts.nonCritical,\n });\n }\n return result;\n }\n\n // -------------------------------------------------------------------------\n // Transition methods\n // -------------------------------------------------------------------------\n\n /**\n * Walks the prototype chain and returns every method carrying\n * `BATCH_TRANSITION_METADATA` (written by the `@OnTransition` decorator\n * added in Task 31). Until Task 31 lands, this method simply returns\n * an empty array.\n *\n * `onStatus` is the *string name* of a `FlowExecutionStatus` value\n * (e.g. `'COMPLETED'`, `'FAILED'`, `'STOPPED'`). It is stored as a string\n * to avoid a circular import from `core/ir` → `core/status` and to keep\n * the metadata JSON-serializable.\n */\n private collectTransitionMethods(prototype: object): DiscoveredTransition[] {\n const result: DiscoveredTransition[] = [];\n for (const name of this.allMethodNames(prototype)) {\n const opts = Reflect.getMetadata(BATCH_TRANSITION_METADATA, prototype, name) as\n | { fromStep: string; onStatus: string; toStep: string | null }\n | undefined;\n if (!opts) continue;\n result.push({ methodName: name, ...opts });\n }\n return result;\n }\n\n // -------------------------------------------------------------------------\n // Prototype walker\n // -------------------------------------------------------------------------\n\n /**\n * Returns every own method name (excluding `constructor`) on the given\n * prototype and all of its ancestors up to (but not including)\n * `Object.prototype`. Order is undefined, so callers that need a stable\n * order should sort afterwards.\n */\n private allMethodNames(prototype: object): Set<string> {\n const names = new Set<string>();\n let proto: object | null = prototype;\n while (proto && proto !== Object.prototype) {\n for (const name of Object.getOwnPropertyNames(proto)) {\n if (name === 'constructor') continue;\n names.add(name);\n }\n proto = Object.getPrototypeOf(proto);\n }\n return names;\n }\n}\n"],"names":["BatchExplorer","logger","Logger","name","discovered","discovery","onModuleInit","providers","getProviders","discoverFromProviders","getDiscovered","out","wrapper","metatype","jobOptions","Reflect","getMetadata","BATCH_JOB_METADATA","push","classRef","instance","stepMethods","collectStepMethods","prototype","listenerMethods","collectListenerMethods","transitionMethods","collectTransitionMethods","log","id","result","allMethodNames","opts","BATCH_STEP_METADATA","isTasklet","BATCH_TASKLET_METADATA","methodName","options","BATCH_LISTENER_METADATA","kind","phase","nonCritical","BATCH_TRANSITION_METADATA","names","Set","proto","Object","getOwnPropertyNames","add","getPrototypeOf"],"mappings":";;;;+BA+FaA;;;eAAAA;;;wBA/FoC;sBAChB;QAE1B;2BAOA;;;;;;;;;;AAqFA,IAAA,AAAMA,gBAAN,MAAMA;;IACMC,SAAS,IAAIC,cAAM,CAACF,cAAcG,IAAI,EAAE;IACjDC,aAA8B,EAAE,CAAC;IAEzC,YAAY,AAAiBC,SAA2B,CAAE;aAA7BA,YAAAA;IAA8B;IAE3D,wDAAwD,GACxDC,eAAqB;QACnB,MAAMC,YAAY,IAAI,CAACF,SAAS,CAACG,YAAY;QAC7C,IAAI,CAACJ,UAAU,GAAG,IAAI,CAACK,qBAAqB,CAACF;IAC/C;IAEA;;;GAGC,GACDG,gBAA0C;QACxC,OAAO,IAAI,CAACN,UAAU;IACxB;IAEA;;;;;GAKC,GACDK,sBAAsBF,SAAyB,EAAmB;QAChE,MAAMI,MAAuB,EAAE;QAC/B,KAAK,MAAMC,WAAWL,UAAW;YAC/B,MAAMM,WAAWD,QAAQC,QAAQ;YACjC,IAAI,CAACA,UAAU;YAEf,MAAMC,aAAaC,QAAQC,WAAW,CAACC,6BAAkB,EAAEJ;YAG3D,IAAI,CAACC,YAAY;YAEjBH,IAAIO,IAAI,CAAC;gBACPC,UAAUN;gBACVO,UAAUR,QAAQQ,QAAQ;gBAC1BN;gBACAO,aAAa,IAAI,CAACC,kBAAkB,CAACT,SAASU,SAAS;gBACvDC,iBAAiB,IAAI,CAACC,sBAAsB,CAACZ,SAASU,SAAS;gBAC/DG,mBAAmB,IAAI,CAACC,wBAAwB,CAACd,SAASU,SAAS;YACrE;YAEA,IAAI,CAACtB,MAAM,CAAC2B,GAAG,CAAC,CAAC,gBAAgB,EAAEd,WAAWe,EAAE,EAAE;QACpD;QACA,OAAOlB;IACT;IAEA,4EAA4E;IAC5E,eAAe;IACf,4EAA4E;IAE5E;;;;;;;;GAQC,GACD,AAAQW,mBAAmBC,SAAiB,EAAoB;QAC9D,MAAMO,SAA2B,EAAE;QACnC,KAAK,MAAM3B,QAAQ,IAAI,CAAC4B,cAAc,CAACR,WAAY;YACjD,MAAMS,OAAOjB,QAAQC,WAAW,CAACiB,8BAAmB,EAAEV,WAAWpB;YAGjE,IAAI,CAAC6B,MAAM;YACX,MAAME,YACJnB,QAAQC,WAAW,CAACmB,iCAAsB,EAAEZ,WAAWpB,UAAU;YACnE2B,OAAOZ,IAAI,CAAC;gBAAEkB,YAAYjC;gBAAMkC,SAASL;gBAAME;YAAU;QAC3D;QACA,OAAOJ;IACT;IAEA,4EAA4E;IAC5E,mBAAmB;IACnB,4EAA4E;IAE5E;;;;;;GAMC,GACD,AAAQL,uBAAuBF,SAAiB,EAAwB;QACtE,MAAMO,SAA+B,EAAE;QACvC,KAAK,MAAM3B,QAAQ,IAAI,CAAC4B,cAAc,CAACR,WAAY;YACjD,MAAMS,OAAOjB,QAAQC,WAAW,CAACsB,kCAAuB,EAAEf,WAAWpB;YAGrE,IAAI,CAAC6B,MAAM;YACXF,OAAOZ,IAAI,CAAC;gBACVkB,YAAYjC;gBACZoC,MAAMP,KAAKO,IAAI;gBACfC,OAAOR,KAAKQ,KAAK;gBACjBC,aAAaT,KAAKS,WAAW;YAC/B;QACF;QACA,OAAOX;IACT;IAEA,4EAA4E;IAC5E,qBAAqB;IACrB,4EAA4E;IAE5E;;;;;;;;;;GAUC,GACD,AAAQH,yBAAyBJ,SAAiB,EAA0B;QAC1E,MAAMO,SAAiC,EAAE;QACzC,KAAK,MAAM3B,QAAQ,IAAI,CAAC4B,cAAc,CAACR,WAAY;YACjD,MAAMS,OAAOjB,QAAQC,WAAW,CAAC0B,oCAAyB,EAAEnB,WAAWpB;YAGvE,IAAI,CAAC6B,MAAM;YACXF,OAAOZ,IAAI,CAAC;gBAAEkB,YAAYjC;gBAAM,GAAG6B,IAAI;YAAC;QAC1C;QACA,OAAOF;IACT;IAEA,4EAA4E;IAC5E,mBAAmB;IACnB,4EAA4E;IAE5E;;;;;GAKC,GACD,AAAQC,eAAeR,SAAiB,EAAe;QACrD,MAAMoB,QAAQ,IAAIC;QAClB,IAAIC,QAAuBtB;QAC3B,MAAOsB,SAASA,UAAUC,OAAOvB,SAAS,CAAE;YAC1C,KAAK,MAAMpB,QAAQ2C,OAAOC,mBAAmB,CAACF,OAAQ;gBACpD,IAAI1C,SAAS,eAAe;gBAC5BwC,MAAMK,GAAG,CAAC7C;YACZ;YACA0C,QAAQC,OAAOG,cAAc,CAACJ;QAChC;QACA,OAAOF;IACT;AACF"}
@@ -0,0 +1,2 @@
1
+ export * from './batch-explorer';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/explorer/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ _export_star(require("./batch-explorer"), exports);
6
+ function _export_star(from, to) {
7
+ Object.keys(from).forEach(function(k) {
8
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
9
+ Object.defineProperty(to, k, {
10
+ enumerable: true,
11
+ get: function() {
12
+ return from[k];
13
+ }
14
+ });
15
+ }
16
+ });
17
+ return from;
18
+ }
19
+
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/explorer/index.ts"],"sourcesContent":["export * from './batch-explorer';\n"],"names":[],"mappings":";;;;qBAAc"}
@@ -0,0 +1,30 @@
1
+ import type { TransitionDefinition } from '../core/ir';
2
+ /**
3
+ * FlowEvaluator resolves the next step in a flow graph given the current step
4
+ * and its exit status. It is a pure, side-effect-free decision function:
5
+ * given the same inputs it always returns the same next step (or END).
6
+ *
7
+ * Per ORACLE verdict 3c, the API is uniformly async — even though the current
8
+ * implementation is synchronous internally, returning a Promise keeps the
9
+ * caller contract identical to future evaluators that may need to consult
10
+ * remote state (e.g. conditional / data-driven transitions).
11
+ */
12
+ export declare class FlowEvaluator {
13
+ /**
14
+ * Evaluate the next step ID given the current step and exit status.
15
+ *
16
+ * - Returns `null` if the job should END — either no transition matches
17
+ * the (fromStepId, onStatus) pair, or the matching transition's
18
+ * `toStepId` is `null` (explicit END).
19
+ * - Supports `*` and `?` wildcards in `onStatus`. Exact matches win
20
+ * over wildcard matches. If multiple matches have the same
21
+ * specificity, the graph is ambiguous and the caller must fix it.
22
+ *
23
+ * @param transitions All transitions in the job's flow graph.
24
+ * @param fromStepId The current step's ID.
25
+ * @param status The current step's exit status.
26
+ */
27
+ evaluate(transitions: TransitionDefinition[], fromStepId: string, status: string): Promise<string | null>;
28
+ matches(transition: TransitionDefinition, fromStepId: string, status: string): boolean;
29
+ }
30
+ //# sourceMappingURL=flow-evaluator.d.ts.map