@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.
- package/LICENSE +21 -0
- package/README.md +368 -0
- package/dist/src/adapters/in-process.adapter.d.ts +140 -0
- package/dist/src/adapters/in-process.adapter.d.ts.map +1 -0
- package/dist/src/adapters/in-process.adapter.js +86 -0
- package/dist/src/adapters/in-process.adapter.js.map +1 -0
- package/dist/src/adapters/index.d.ts +18 -0
- package/dist/src/adapters/index.d.ts.map +1 -0
- package/dist/src/adapters/index.js +35 -0
- package/dist/src/adapters/index.js.map +1 -0
- package/dist/src/builder/batch-builder.d.ts +26 -0
- package/dist/src/builder/batch-builder.d.ts.map +1 -0
- package/dist/src/builder/batch-builder.js +25 -0
- package/dist/src/builder/batch-builder.js.map +1 -0
- package/dist/src/builder/flow-builder.d.ts +59 -0
- package/dist/src/builder/flow-builder.d.ts.map +1 -0
- package/dist/src/builder/flow-builder.js +115 -0
- package/dist/src/builder/flow-builder.js.map +1 -0
- package/dist/src/builder/index.d.ts +5 -0
- package/dist/src/builder/index.d.ts.map +1 -0
- package/dist/src/builder/index.js +23 -0
- package/dist/src/builder/index.js.map +1 -0
- package/dist/src/builder/job-builder.d.ts +76 -0
- package/dist/src/builder/job-builder.d.ts.map +1 -0
- package/dist/src/builder/job-builder.js +166 -0
- package/dist/src/builder/job-builder.js.map +1 -0
- package/dist/src/builder/step-builder.d.ts +74 -0
- package/dist/src/builder/step-builder.d.ts.map +1 -0
- package/dist/src/builder/step-builder.js +144 -0
- package/dist/src/builder/step-builder.js.map +1 -0
- package/dist/src/compiler/builder-types.d.ts +20 -0
- package/dist/src/compiler/builder-types.d.ts.map +1 -0
- package/dist/src/compiler/builder-types.js +6 -0
- package/dist/src/compiler/builder-types.js.map +1 -0
- package/dist/src/compiler/definition-compiler.d.ts +99 -0
- package/dist/src/compiler/definition-compiler.d.ts.map +1 -0
- package/dist/src/compiler/definition-compiler.js +257 -0
- package/dist/src/compiler/definition-compiler.js.map +1 -0
- package/dist/src/compiler/index.d.ts +3 -0
- package/dist/src/compiler/index.d.ts.map +1 -0
- package/dist/src/compiler/index.js +21 -0
- package/dist/src/compiler/index.js.map +1 -0
- package/dist/src/core/errors.d.ts +77 -0
- package/dist/src/core/errors.d.ts.map +1 -0
- package/dist/src/core/errors.js +170 -0
- package/dist/src/core/errors.js.map +1 -0
- package/dist/src/core/execution-context/index.d.ts +4 -0
- package/dist/src/core/execution-context/index.d.ts.map +1 -0
- package/dist/src/core/execution-context/index.js +22 -0
- package/dist/src/core/execution-context/index.js.map +1 -0
- package/dist/src/core/execution-context/json-value.d.ts +5 -0
- package/dist/src/core/execution-context/json-value.d.ts.map +1 -0
- package/dist/src/core/execution-context/json-value.js +6 -0
- package/dist/src/core/execution-context/json-value.js.map +1 -0
- package/dist/src/core/execution-context/serializer.d.ts +4 -0
- package/dist/src/core/execution-context/serializer.d.ts.map +1 -0
- package/dist/src/core/execution-context/serializer.js +34 -0
- package/dist/src/core/execution-context/serializer.js.map +1 -0
- package/dist/src/core/execution-context/validator.d.ts +18 -0
- package/dist/src/core/execution-context/validator.d.ts.map +1 -0
- package/dist/src/core/execution-context/validator.js +90 -0
- package/dist/src/core/execution-context/validator.js.map +1 -0
- package/dist/src/core/index.d.ts +8 -0
- package/dist/src/core/index.d.ts.map +1 -0
- package/dist/src/core/index.js +26 -0
- package/dist/src/core/index.js.map +1 -0
- package/dist/src/core/ir/decider-definition.d.ts +20 -0
- package/dist/src/core/ir/decider-definition.d.ts.map +1 -0
- package/dist/src/core/ir/decider-definition.js +6 -0
- package/dist/src/core/ir/decider-definition.js.map +1 -0
- package/dist/src/core/ir/index.d.ts +8 -0
- package/dist/src/core/ir/index.d.ts.map +1 -0
- package/dist/src/core/ir/index.js +26 -0
- package/dist/src/core/ir/index.js.map +1 -0
- package/dist/src/core/ir/job-definition.d.ts +15 -0
- package/dist/src/core/ir/job-definition.d.ts.map +1 -0
- package/dist/src/core/ir/job-definition.js +6 -0
- package/dist/src/core/ir/job-definition.js.map +1 -0
- package/dist/src/core/ir/listener-definition.d.ts +10 -0
- package/dist/src/core/ir/listener-definition.d.ts.map +1 -0
- package/dist/src/core/ir/listener-definition.js +6 -0
- package/dist/src/core/ir/listener-definition.js.map +1 -0
- package/dist/src/core/ir/policy-config.d.ts +24 -0
- package/dist/src/core/ir/policy-config.d.ts.map +1 -0
- package/dist/src/core/ir/policy-config.js +6 -0
- package/dist/src/core/ir/policy-config.js.map +1 -0
- package/dist/src/core/ir/refs.d.ts +42 -0
- package/dist/src/core/ir/refs.d.ts.map +1 -0
- package/dist/src/core/ir/refs.js +18 -0
- package/dist/src/core/ir/refs.js.map +1 -0
- package/dist/src/core/ir/step-definition.d.ts +59 -0
- package/dist/src/core/ir/step-definition.d.ts.map +1 -0
- package/dist/src/core/ir/step-definition.js +6 -0
- package/dist/src/core/ir/step-definition.js.map +1 -0
- package/dist/src/core/ir/transition-definition.d.ts +8 -0
- package/dist/src/core/ir/transition-definition.d.ts.map +1 -0
- package/dist/src/core/ir/transition-definition.js +6 -0
- package/dist/src/core/ir/transition-definition.js.map +1 -0
- package/dist/src/core/item/index.d.ts +2 -0
- package/dist/src/core/item/index.d.ts.map +1 -0
- package/dist/src/core/item/index.js +20 -0
- package/dist/src/core/item/index.js.map +1 -0
- package/dist/src/core/item/interfaces.d.ts +64 -0
- package/dist/src/core/item/interfaces.d.ts.map +1 -0
- package/dist/src/core/item/interfaces.js +6 -0
- package/dist/src/core/item/interfaces.js.map +1 -0
- package/dist/src/core/repository/index.d.ts +3 -0
- package/dist/src/core/repository/index.d.ts.map +1 -0
- package/dist/src/core/repository/index.js +21 -0
- package/dist/src/core/repository/index.js.map +1 -0
- package/dist/src/core/repository/job-repository.d.ts +60 -0
- package/dist/src/core/repository/job-repository.d.ts.map +1 -0
- package/dist/src/core/repository/job-repository.js +27 -0
- package/dist/src/core/repository/job-repository.js.map +1 -0
- package/dist/src/core/repository/types.d.ts +84 -0
- package/dist/src/core/repository/types.d.ts.map +1 -0
- package/dist/src/core/repository/types.js +6 -0
- package/dist/src/core/repository/types.js.map +1 -0
- package/dist/src/core/status.d.ts +29 -0
- package/dist/src/core/status.d.ts.map +1 -0
- package/dist/src/core/status.js +58 -0
- package/dist/src/core/status.js.map +1 -0
- package/dist/src/core/transaction/index.d.ts +2 -0
- package/dist/src/core/transaction/index.d.ts.map +1 -0
- package/dist/src/core/transaction/index.js +20 -0
- package/dist/src/core/transaction/index.js.map +1 -0
- package/dist/src/core/transaction/transaction-manager.d.ts +8 -0
- package/dist/src/core/transaction/transaction-manager.d.ts.map +1 -0
- package/dist/src/core/transaction/transaction-manager.js +14 -0
- package/dist/src/core/transaction/transaction-manager.js.map +1 -0
- package/dist/src/core/validation/definition-validator.d.ts +46 -0
- package/dist/src/core/validation/definition-validator.d.ts.map +1 -0
- package/dist/src/core/validation/definition-validator.js +177 -0
- package/dist/src/core/validation/definition-validator.js.map +1 -0
- package/dist/src/core/validation/index.d.ts +2 -0
- package/dist/src/core/validation/index.d.ts.map +1 -0
- package/dist/src/core/validation/index.js +20 -0
- package/dist/src/core/validation/index.js.map +1 -0
- package/dist/src/decorators/constants.d.ts +10 -0
- package/dist/src/decorators/constants.d.ts.map +1 -0
- package/dist/src/decorators/constants.js +50 -0
- package/dist/src/decorators/constants.js.map +1 -0
- package/dist/src/decorators/flow.decorator.d.ts +25 -0
- package/dist/src/decorators/flow.decorator.d.ts.map +1 -0
- package/dist/src/decorators/flow.decorator.js +19 -0
- package/dist/src/decorators/flow.decorator.js.map +1 -0
- package/dist/src/decorators/index.d.ts +8 -0
- package/dist/src/decorators/index.d.ts.map +1 -0
- package/dist/src/decorators/index.js +26 -0
- package/dist/src/decorators/index.js.map +1 -0
- package/dist/src/decorators/item.decorators.d.ts +32 -0
- package/dist/src/decorators/item.decorators.d.ts.map +1 -0
- package/dist/src/decorators/item.decorators.js +40 -0
- package/dist/src/decorators/item.decorators.js.map +1 -0
- package/dist/src/decorators/job.decorator.d.ts +11 -0
- package/dist/src/decorators/job.decorator.d.ts.map +1 -0
- package/dist/src/decorators/job.decorator.js +17 -0
- package/dist/src/decorators/job.decorator.js.map +1 -0
- package/dist/src/decorators/listener.decorators.d.ts +56 -0
- package/dist/src/decorators/listener.decorators.d.ts.map +1 -0
- package/dist/src/decorators/listener.decorators.js +157 -0
- package/dist/src/decorators/listener.decorators.js.map +1 -0
- package/dist/src/decorators/step.decorator.d.ts +25 -0
- package/dist/src/decorators/step.decorator.d.ts.map +1 -0
- package/dist/src/decorators/step.decorator.js +21 -0
- package/dist/src/decorators/step.decorator.js.map +1 -0
- package/dist/src/decorators/tasklet.decorator.d.ts +7 -0
- package/dist/src/decorators/tasklet.decorator.d.ts.map +1 -0
- package/dist/src/decorators/tasklet.decorator.js +21 -0
- package/dist/src/decorators/tasklet.decorator.js.map +1 -0
- package/dist/src/execution/batch-worker-runner.d.ts +27 -0
- package/dist/src/execution/batch-worker-runner.d.ts.map +1 -0
- package/dist/src/execution/batch-worker-runner.js +147 -0
- package/dist/src/execution/batch-worker-runner.js.map +1 -0
- package/dist/src/execution/chunk-step-executor.d.ts +86 -0
- package/dist/src/execution/chunk-step-executor.d.ts.map +1 -0
- package/dist/src/execution/chunk-step-executor.js +482 -0
- package/dist/src/execution/chunk-step-executor.js.map +1 -0
- package/dist/src/execution/execution-strategy.d.ts +110 -0
- package/dist/src/execution/execution-strategy.d.ts.map +1 -0
- package/dist/src/execution/execution-strategy.js +13 -0
- package/dist/src/execution/execution-strategy.js.map +1 -0
- package/dist/src/execution/external-task-execution-strategy.d.ts +36 -0
- package/dist/src/execution/external-task-execution-strategy.d.ts.map +1 -0
- package/dist/src/execution/external-task-execution-strategy.js +97 -0
- package/dist/src/execution/external-task-execution-strategy.js.map +1 -0
- package/dist/src/execution/in-process-execution-strategy.d.ts +129 -0
- package/dist/src/execution/in-process-execution-strategy.d.ts.map +1 -0
- package/dist/src/execution/in-process-execution-strategy.js +141 -0
- package/dist/src/execution/in-process-execution-strategy.js.map +1 -0
- package/dist/src/execution/index.d.ts +14 -0
- package/dist/src/execution/index.d.ts.map +1 -0
- package/dist/src/execution/index.js +32 -0
- package/dist/src/execution/index.js.map +1 -0
- package/dist/src/execution/job-executor.d.ts +145 -0
- package/dist/src/execution/job-executor.d.ts.map +1 -0
- package/dist/src/execution/job-executor.js +475 -0
- package/dist/src/execution/job-executor.js.map +1 -0
- package/dist/src/execution/job-explorer.d.ts +15 -0
- package/dist/src/execution/job-explorer.d.ts.map +1 -0
- package/dist/src/execution/job-explorer.js +84 -0
- package/dist/src/execution/job-explorer.js.map +1 -0
- package/dist/src/execution/job-key.d.ts +3 -0
- package/dist/src/execution/job-key.d.ts.map +1 -0
- package/dist/src/execution/job-key.js +43 -0
- package/dist/src/execution/job-key.js.map +1 -0
- package/dist/src/execution/job-launcher.d.ts +75 -0
- package/dist/src/execution/job-launcher.d.ts.map +1 -0
- package/dist/src/execution/job-launcher.js +112 -0
- package/dist/src/execution/job-launcher.js.map +1 -0
- package/dist/src/execution/job-operator.d.ts +22 -0
- package/dist/src/execution/job-operator.d.ts.map +1 -0
- package/dist/src/execution/job-operator.js +125 -0
- package/dist/src/execution/job-operator.js.map +1 -0
- package/dist/src/execution/listener-invoker.d.ts +164 -0
- package/dist/src/execution/listener-invoker.d.ts.map +1 -0
- package/dist/src/execution/listener-invoker.js +246 -0
- package/dist/src/execution/listener-invoker.js.map +1 -0
- package/dist/src/execution/ref-resolver.d.ts +40 -0
- package/dist/src/execution/ref-resolver.d.ts.map +1 -0
- package/dist/src/execution/ref-resolver.js +41 -0
- package/dist/src/execution/ref-resolver.js.map +1 -0
- package/dist/src/execution/tasklet-step-executor.d.ts +79 -0
- package/dist/src/execution/tasklet-step-executor.d.ts.map +1 -0
- package/dist/src/execution/tasklet-step-executor.js +138 -0
- package/dist/src/execution/tasklet-step-executor.js.map +1 -0
- package/dist/src/explorer/batch-explorer.d.ts +138 -0
- package/dist/src/explorer/batch-explorer.d.ts.map +1 -0
- package/dist/src/explorer/batch-explorer.js +167 -0
- package/dist/src/explorer/batch-explorer.js.map +1 -0
- package/dist/src/explorer/index.d.ts +2 -0
- package/dist/src/explorer/index.d.ts.map +1 -0
- package/dist/src/explorer/index.js +20 -0
- package/dist/src/explorer/index.js.map +1 -0
- package/dist/src/flow/flow-evaluator.d.ts +30 -0
- package/dist/src/flow/flow-evaluator.d.ts.map +1 -0
- package/dist/src/flow/flow-evaluator.js +80 -0
- package/dist/src/flow/flow-evaluator.js.map +1 -0
- package/dist/src/flow/index.d.ts +2 -0
- package/dist/src/flow/index.d.ts.map +1 -0
- package/dist/src/flow/index.js +20 -0
- package/dist/src/flow/index.js.map +1 -0
- package/dist/src/index.d.ts +18 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +90 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/io/checkpoint.d.ts +7 -0
- package/dist/src/io/checkpoint.d.ts.map +1 -0
- package/dist/src/io/checkpoint.js +56 -0
- package/dist/src/io/checkpoint.js.map +1 -0
- package/dist/src/io/database.d.ts +50 -0
- package/dist/src/io/database.d.ts.map +1 -0
- package/dist/src/io/database.js +108 -0
- package/dist/src/io/database.js.map +1 -0
- package/dist/src/io/file-readers.d.ts +54 -0
- package/dist/src/io/file-readers.d.ts.map +1 -0
- package/dist/src/io/file-readers.js +167 -0
- package/dist/src/io/file-readers.js.map +1 -0
- package/dist/src/io/file-writers.d.ts +31 -0
- package/dist/src/io/file-writers.d.ts.map +1 -0
- package/dist/src/io/file-writers.js +80 -0
- package/dist/src/io/file-writers.js.map +1 -0
- package/dist/src/io/index.d.ts +6 -0
- package/dist/src/io/index.d.ts.map +1 -0
- package/dist/src/io/index.js +24 -0
- package/dist/src/io/index.js.map +1 -0
- package/dist/src/io/s3.d.ts +50 -0
- package/dist/src/io/s3.d.ts.map +1 -0
- package/dist/src/io/s3.js +96 -0
- package/dist/src/io/s3.js.map +1 -0
- package/dist/src/listeners/builtin-listeners.d.ts +77 -0
- package/dist/src/listeners/builtin-listeners.d.ts.map +1 -0
- package/dist/src/listeners/builtin-listeners.js +108 -0
- package/dist/src/listeners/builtin-listeners.js.map +1 -0
- package/dist/src/listeners/index.d.ts +8 -0
- package/dist/src/listeners/index.d.ts.map +1 -0
- package/dist/src/listeners/index.js +25 -0
- package/dist/src/listeners/index.js.map +1 -0
- package/dist/src/module/adapter-options.d.ts +39 -0
- package/dist/src/module/adapter-options.d.ts.map +1 -0
- package/dist/src/module/adapter-options.js +34 -0
- package/dist/src/module/adapter-options.js.map +1 -0
- package/dist/src/module/adapter.d.ts +157 -0
- package/dist/src/module/adapter.d.ts.map +1 -0
- package/dist/src/module/adapter.js +80 -0
- package/dist/src/module/adapter.js.map +1 -0
- package/dist/src/module/batch-schedule-registry.d.ts +110 -0
- package/dist/src/module/batch-schedule-registry.d.ts.map +1 -0
- package/dist/src/module/batch-schedule-registry.js +0 -0
- package/dist/src/module/batch-schedule-registry.js.map +1 -0
- package/dist/src/module/index.d.ts +14 -0
- package/dist/src/module/index.d.ts.map +1 -0
- package/dist/src/module/index.js +31 -0
- package/dist/src/module/index.js.map +1 -0
- package/dist/src/module/nest-batch.module.d.ts +236 -0
- package/dist/src/module/nest-batch.module.d.ts.map +1 -0
- package/dist/src/module/nest-batch.module.js +475 -0
- package/dist/src/module/nest-batch.module.js.map +1 -0
- package/dist/src/module/tokens.d.ts +83 -0
- package/dist/src/module/tokens.d.ts.map +1 -0
- package/dist/src/module/tokens.js +58 -0
- package/dist/src/module/tokens.js.map +1 -0
- package/dist/src/observability/event-types.d.ts +55 -0
- package/dist/src/observability/event-types.d.ts.map +1 -0
- package/dist/src/observability/event-types.js +36 -0
- package/dist/src/observability/event-types.js.map +1 -0
- package/dist/src/observability/exporters.d.ts +35 -0
- package/dist/src/observability/exporters.d.ts.map +1 -0
- package/dist/src/observability/exporters.js +93 -0
- package/dist/src/observability/exporters.js.map +1 -0
- package/dist/src/observability/index.d.ts +3 -0
- package/dist/src/observability/index.d.ts.map +1 -0
- package/dist/src/observability/index.js +21 -0
- package/dist/src/observability/index.js.map +1 -0
- package/dist/src/partition-helpers.d.ts +127 -0
- package/dist/src/partition-helpers.d.ts.map +1 -0
- package/dist/src/partition-helpers.js +136 -0
- package/dist/src/partition-helpers.js.map +1 -0
- package/dist/src/policies/backoff.d.ts +3 -0
- package/dist/src/policies/backoff.d.ts.map +1 -0
- package/dist/src/policies/backoff.js +34 -0
- package/dist/src/policies/backoff.js.map +1 -0
- package/dist/src/policies/index.d.ts +4 -0
- package/dist/src/policies/index.d.ts.map +1 -0
- package/dist/src/policies/index.js +22 -0
- package/dist/src/policies/index.js.map +1 -0
- package/dist/src/policies/retry-policy.d.ts +13 -0
- package/dist/src/policies/retry-policy.d.ts.map +1 -0
- package/dist/src/policies/retry-policy.js +55 -0
- package/dist/src/policies/retry-policy.js.map +1 -0
- package/dist/src/policies/skip-policy.d.ts +12 -0
- package/dist/src/policies/skip-policy.d.ts.map +1 -0
- package/dist/src/policies/skip-policy.js +44 -0
- package/dist/src/policies/skip-policy.js.map +1 -0
- package/dist/src/registry/index.d.ts +2 -0
- package/dist/src/registry/index.d.ts.map +1 -0
- package/dist/src/registry/index.js +20 -0
- package/dist/src/registry/index.js.map +1 -0
- package/dist/src/registry/job-registry.d.ts +16 -0
- package/dist/src/registry/job-registry.d.ts.map +1 -0
- package/dist/src/registry/job-registry.js +50 -0
- package/dist/src/registry/job-registry.js.map +1 -0
- package/dist/src/repository/id-generator.d.ts +18 -0
- package/dist/src/repository/id-generator.d.ts.map +1 -0
- package/dist/src/repository/id-generator.js +37 -0
- package/dist/src/repository/id-generator.js.map +1 -0
- package/dist/src/repository/in-memory/in-memory-job-repository.d.ts +49 -0
- package/dist/src/repository/in-memory/in-memory-job-repository.d.ts.map +1 -0
- package/dist/src/repository/in-memory/in-memory-job-repository.js +291 -0
- package/dist/src/repository/in-memory/in-memory-job-repository.js.map +1 -0
- package/dist/src/repository/in-memory/index.d.ts +2 -0
- package/dist/src/repository/in-memory/index.d.ts.map +1 -0
- package/dist/src/repository/in-memory/index.js +20 -0
- package/dist/src/repository/in-memory/index.js.map +1 -0
- package/dist/src/repository/index.d.ts +4 -0
- package/dist/src/repository/index.d.ts.map +1 -0
- package/dist/src/repository/index.js +22 -0
- package/dist/src/repository/index.js.map +1 -0
- package/dist/src/repository/uuid-v7.d.ts +20 -0
- package/dist/src/repository/uuid-v7.d.ts.map +1 -0
- package/dist/src/repository/uuid-v7.js +31 -0
- package/dist/src/repository/uuid-v7.js.map +1 -0
- package/dist/src/scheduling/batch-scheduled.d.ts +87 -0
- package/dist/src/scheduling/batch-scheduled.d.ts.map +1 -0
- package/dist/src/scheduling/batch-scheduled.js +170 -0
- package/dist/src/scheduling/batch-scheduled.js.map +1 -0
- package/dist/src/transaction/in-memory-transaction-manager.d.ts +16 -0
- package/dist/src/transaction/in-memory-transaction-manager.d.ts.map +1 -0
- package/dist/src/transaction/in-memory-transaction-manager.js +33 -0
- package/dist/src/transaction/in-memory-transaction-manager.js.map +1 -0
- package/dist/src/transaction/index.d.ts +2 -0
- package/dist/src/transaction/index.d.ts.map +1 -0
- package/dist/src/transaction/index.js +20 -0
- package/dist/src/transaction/index.js.map +1 -0
- package/dist/tests/contracts/index.d.ts +26 -0
- package/dist/tests/contracts/index.d.ts.map +1 -0
- package/dist/tests/contracts/index.js +37 -0
- package/dist/tests/contracts/index.js.map +1 -0
- package/dist/tests/contracts/job-repository.contract.d.ts +46 -0
- package/dist/tests/contracts/job-repository.contract.d.ts.map +1 -0
- package/dist/tests/contracts/job-repository.contract.js +644 -0
- package/dist/tests/contracts/job-repository.contract.js.map +1 -0
- package/package.json +80 -0
- package/src/adapters/in-process.adapter.ts +182 -0
- package/src/adapters/index.ts +17 -0
- package/src/builder/batch-builder.ts +32 -0
- package/src/builder/flow-builder.ts +141 -0
- package/src/builder/index.ts +4 -0
- package/src/builder/job-builder.ts +206 -0
- package/src/builder/step-builder.ts +190 -0
- package/src/compiler/builder-types.ts +27 -0
- package/src/compiler/definition-compiler.ts +325 -0
- package/src/compiler/index.ts +2 -0
- package/src/core/errors.ts +125 -0
- package/src/core/execution-context/index.ts +3 -0
- package/src/core/execution-context/json-value.ts +3 -0
- package/src/core/execution-context/serializer.ts +21 -0
- package/src/core/execution-context/validator.ts +103 -0
- package/src/core/index.ts +7 -0
- package/src/core/ir/decider-definition.ts +25 -0
- package/src/core/ir/index.ts +7 -0
- package/src/core/ir/job-definition.ts +15 -0
- package/src/core/ir/listener-definition.ts +19 -0
- package/src/core/ir/policy-config.ts +19 -0
- package/src/core/ir/refs.ts +42 -0
- package/src/core/ir/step-definition.ts +62 -0
- package/src/core/ir/transition-definition.ts +9 -0
- package/src/core/item/index.ts +1 -0
- package/src/core/item/interfaces.ts +70 -0
- package/src/core/repository/index.ts +2 -0
- package/src/core/repository/job-repository.ts +100 -0
- package/src/core/repository/types.ts +91 -0
- package/src/core/status.ts +31 -0
- package/src/core/transaction/index.ts +1 -0
- package/src/core/transaction/transaction-manager.ts +8 -0
- package/src/core/validation/definition-validator.ts +215 -0
- package/src/core/validation/index.ts +1 -0
- package/src/decorators/constants.ts +9 -0
- package/src/decorators/flow.decorator.ts +31 -0
- package/src/decorators/index.ts +7 -0
- package/src/decorators/item.decorators.ts +51 -0
- package/src/decorators/job.decorator.ts +16 -0
- package/src/decorators/listener.decorators.ts +142 -0
- package/src/decorators/step.decorator.ts +33 -0
- package/src/decorators/tasklet.decorator.ts +14 -0
- package/src/execution/batch-worker-runner.ts +142 -0
- package/src/execution/chunk-step-executor.ts +594 -0
- package/src/execution/execution-strategy.ts +115 -0
- package/src/execution/external-task-execution-strategy.ts +104 -0
- package/src/execution/in-process-execution-strategy.ts +207 -0
- package/src/execution/index.ts +13 -0
- package/src/execution/job-executor.ts +553 -0
- package/src/execution/job-explorer.ts +73 -0
- package/src/execution/job-key.ts +35 -0
- package/src/execution/job-launcher.ts +132 -0
- package/src/execution/job-operator.ts +127 -0
- package/src/execution/listener-invoker.ts +389 -0
- package/src/execution/ref-resolver.ts +64 -0
- package/src/execution/tasklet-step-executor.ts +182 -0
- package/src/explorer/batch-explorer.ts +251 -0
- package/src/explorer/index.ts +1 -0
- package/src/flow/flow-evaluator.ts +89 -0
- package/src/flow/index.ts +1 -0
- package/src/index.ts +24 -0
- package/src/io/checkpoint.ts +47 -0
- package/src/io/database.ts +114 -0
- package/src/io/file-readers.ts +191 -0
- package/src/io/file-writers.ts +99 -0
- package/src/io/index.ts +5 -0
- package/src/io/s3.ts +117 -0
- package/src/listeners/builtin-listeners.ts +151 -0
- package/src/listeners/index.ts +7 -0
- package/src/module/adapter-options.ts +38 -0
- package/src/module/adapter.ts +160 -0
- package/src/module/batch-schedule-registry.ts +0 -0
- package/src/module/index.ts +13 -0
- package/src/module/nest-batch.module.ts +674 -0
- package/src/module/tokens.ts +95 -0
- package/src/observability/event-types.ts +61 -0
- package/src/observability/exporters.ts +96 -0
- package/src/observability/index.ts +2 -0
- package/src/partition-helpers.ts +204 -0
- package/src/policies/backoff.ts +22 -0
- package/src/policies/index.ts +3 -0
- package/src/policies/retry-policy.ts +57 -0
- package/src/policies/skip-policy.ts +51 -0
- package/src/registry/index.ts +1 -0
- package/src/registry/job-registry.ts +42 -0
- package/src/repository/id-generator.ts +25 -0
- package/src/repository/in-memory/in-memory-job-repository.ts +334 -0
- package/src/repository/in-memory/index.ts +1 -0
- package/src/repository/index.ts +3 -0
- package/src/repository/uuid-v7.ts +40 -0
- package/src/scheduling/batch-scheduled.ts +257 -0
- package/src/transaction/in-memory-transaction-manager.ts +23 -0
- package/src/transaction/index.ts +1 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { StepDefinition, ReaderRef, ProcessorRef, WriterRef, TaskletRef, ListenerRef, SkipPolicyConfig, RetryPolicyConfig, ListenerKind, ListenerPhase } from '../core/ir';
|
|
2
|
+
/**
|
|
3
|
+
* Fluent builder for a single step (`chunk` or `tasklet`).
|
|
4
|
+
*
|
|
5
|
+
* Typical usage via `JobBuilder.addStep` callback:
|
|
6
|
+
*
|
|
7
|
+
* .addStep((b) => b
|
|
8
|
+
* .chunk('read-csv', 100, {
|
|
9
|
+
* reader: { kind: BuilderLambda, fn: readCsv },
|
|
10
|
+
* processor: { kind: BuilderLambda, fn: transform },
|
|
11
|
+
* writer: { kind: BuilderLambda, fn: writeRows },
|
|
12
|
+
* }))
|
|
13
|
+
*
|
|
14
|
+
* .addStep((b) => b
|
|
15
|
+
* .tasklet('cleanup', { kind: BuilderLambda, fn: cleanup }))
|
|
16
|
+
*
|
|
17
|
+
* The builder is single-use: call `.build()` once to produce the
|
|
18
|
+
* `StepDefinition` IR.
|
|
19
|
+
*/
|
|
20
|
+
export declare class StepBuilder {
|
|
21
|
+
private _chunkSize?;
|
|
22
|
+
private _reader?;
|
|
23
|
+
private _processor?;
|
|
24
|
+
private _writer?;
|
|
25
|
+
private _tasklet?;
|
|
26
|
+
private _id?;
|
|
27
|
+
private _skipPolicy?;
|
|
28
|
+
private _retryPolicy?;
|
|
29
|
+
private readonly itemListeners;
|
|
30
|
+
private readonly listenerDefs;
|
|
31
|
+
/**
|
|
32
|
+
* Start a chunk step. Sets the step id and chunk size; optionally
|
|
33
|
+
* accepts reader/processor/writer/policies in a single call.
|
|
34
|
+
*
|
|
35
|
+
* .chunk('s1', 100, { reader, processor, writer })
|
|
36
|
+
* .chunk('s2', 50, { reader, writer, skipPolicy })
|
|
37
|
+
*
|
|
38
|
+
* Throws if `size` is not a positive integer.
|
|
39
|
+
*/
|
|
40
|
+
chunk(id: string, size: number, config?: {
|
|
41
|
+
reader: ReaderRef;
|
|
42
|
+
processor?: ProcessorRef;
|
|
43
|
+
writer: WriterRef;
|
|
44
|
+
skipPolicy?: SkipPolicyConfig;
|
|
45
|
+
retryPolicy?: RetryPolicyConfig;
|
|
46
|
+
}): this;
|
|
47
|
+
/**
|
|
48
|
+
* Start a tasklet step. Sets the step id and the tasklet ref.
|
|
49
|
+
*
|
|
50
|
+
* .tasklet('cleanup', { kind: BuilderLambda, fn: cleanup })
|
|
51
|
+
*/
|
|
52
|
+
tasklet(id: string, ref: TaskletRef): this;
|
|
53
|
+
reader(ref: ReaderRef): this;
|
|
54
|
+
processor(ref: ProcessorRef): this;
|
|
55
|
+
writer(ref: WriterRef): this;
|
|
56
|
+
skipPolicy(p: SkipPolicyConfig): this;
|
|
57
|
+
retryPolicy(p: RetryPolicyConfig): this;
|
|
58
|
+
/**
|
|
59
|
+
* Attach an item-level listener ref to this step. Listener metadata
|
|
60
|
+
* is also recorded internally so it can be re-emitted via `.build()`.
|
|
61
|
+
*
|
|
62
|
+
* (The step IR's `listeners: ItemListenerRef[]` field is the source of
|
|
63
|
+
* truth at runtime; the `ListenerDefinition[]` aggregate lives on the
|
|
64
|
+
* job. We keep both in sync here for downstream consumer convenience.)
|
|
65
|
+
*/
|
|
66
|
+
addListener(ref: ListenerRef, kind: ListenerKind, phase: ListenerPhase, nonCritical?: boolean): this;
|
|
67
|
+
/**
|
|
68
|
+
* Produce the `StepDefinition` IR. Throws if the step is missing an
|
|
69
|
+
* id, or is neither a configured tasklet nor a configured chunk
|
|
70
|
+
* (chunk requires both `reader` and `writer`).
|
|
71
|
+
*/
|
|
72
|
+
build(): StepDefinition;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=step-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-builder.d.ts","sourceRoot":"","sources":["../../../src/builder/step-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EAGd,SAAS,EACT,YAAY,EACZ,SAAS,EACT,UAAU,EACV,WAAW,EAEX,gBAAgB,EAChB,iBAAiB,EAEjB,YAAY,EACZ,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,WAAW;IAQtB,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,OAAO,CAAC,CAAY;IAC5B,OAAO,CAAC,UAAU,CAAC,CAAe;IAClC,OAAO,CAAC,OAAO,CAAC,CAAY;IAC5B,OAAO,CAAC,QAAQ,CAAC,CAAa;IAC9B,OAAO,CAAC,GAAG,CAAC,CAAS;IACrB,OAAO,CAAC,WAAW,CAAC,CAAmB;IACvC,OAAO,CAAC,YAAY,CAAC,CAAoB;IACzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyB;IACvD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA4B;IAIzD;;;;;;;;OAQG;IACH,KAAK,CACH,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE;QACP,MAAM,EAAE,SAAS,CAAC;QAClB,SAAS,CAAC,EAAE,YAAY,CAAC;QACzB,MAAM,EAAE,SAAS,CAAC;QAClB,UAAU,CAAC,EAAE,gBAAgB,CAAC;QAC9B,WAAW,CAAC,EAAE,iBAAiB,CAAC;KACjC,GACA,IAAI;IAgBP;;;;OAIG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,IAAI;IAQ1C,MAAM,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI;IAK5B,SAAS,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI;IAKlC,MAAM,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI;IAK5B,UAAU,CAAC,CAAC,EAAE,gBAAgB,GAAG,IAAI;IAKrC,WAAW,CAAC,CAAC,EAAE,iBAAiB,GAAG,IAAI;IAKvC;;;;;;;OAOG;IACH,WAAW,CACT,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,aAAa,EACpB,WAAW,CAAC,EAAE,OAAO,GACpB,IAAI;IAaP;;;;OAIG;IACH,KAAK,IAAI,cAAc;CA6BxB"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "StepBuilder", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return StepBuilder;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
let StepBuilder = class StepBuilder {
|
|
12
|
+
// Field names use a `_` prefix to avoid colliding with the same-named
|
|
13
|
+
// setter methods (`reader` / `processor` / `writer` / `tasklet` /
|
|
14
|
+
// `skipPolicy` / `retryPolicy`). With `useDefineForClassFields: false`
|
|
15
|
+
// (project tsconfig), a class field shadows any prototype method of
|
|
16
|
+
// the same name — which would make the fluent setters unreachable and
|
|
17
|
+
// (more subtly) make `if (this.tasklet)` in `build()` accidentally
|
|
18
|
+
// find the method via the prototype chain.
|
|
19
|
+
_chunkSize;
|
|
20
|
+
_reader;
|
|
21
|
+
_processor;
|
|
22
|
+
_writer;
|
|
23
|
+
_tasklet;
|
|
24
|
+
_id;
|
|
25
|
+
_skipPolicy;
|
|
26
|
+
_retryPolicy;
|
|
27
|
+
itemListeners = [];
|
|
28
|
+
listenerDefs = [];
|
|
29
|
+
// --- step-kind entry points ------------------------------------------
|
|
30
|
+
/**
|
|
31
|
+
* Start a chunk step. Sets the step id and chunk size; optionally
|
|
32
|
+
* accepts reader/processor/writer/policies in a single call.
|
|
33
|
+
*
|
|
34
|
+
* .chunk('s1', 100, { reader, processor, writer })
|
|
35
|
+
* .chunk('s2', 50, { reader, writer, skipPolicy })
|
|
36
|
+
*
|
|
37
|
+
* Throws if `size` is not a positive integer.
|
|
38
|
+
*/ chunk(id, size, config) {
|
|
39
|
+
if (!Number.isInteger(size) || size <= 0) {
|
|
40
|
+
throw new Error('chunkSize must be a positive integer');
|
|
41
|
+
}
|
|
42
|
+
this._id = id;
|
|
43
|
+
this._chunkSize = size;
|
|
44
|
+
if (config) {
|
|
45
|
+
this._reader = config.reader;
|
|
46
|
+
this._processor = config.processor;
|
|
47
|
+
this._writer = config.writer;
|
|
48
|
+
this._skipPolicy = config.skipPolicy;
|
|
49
|
+
this._retryPolicy = config.retryPolicy;
|
|
50
|
+
}
|
|
51
|
+
return this;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Start a tasklet step. Sets the step id and the tasklet ref.
|
|
55
|
+
*
|
|
56
|
+
* .tasklet('cleanup', { kind: BuilderLambda, fn: cleanup })
|
|
57
|
+
*/ tasklet(id, ref) {
|
|
58
|
+
this._id = id;
|
|
59
|
+
this._tasklet = ref;
|
|
60
|
+
return this;
|
|
61
|
+
}
|
|
62
|
+
// --- fine-grained setters (used after `.chunk(id, size)`) -----------
|
|
63
|
+
reader(ref) {
|
|
64
|
+
this._reader = ref;
|
|
65
|
+
return this;
|
|
66
|
+
}
|
|
67
|
+
processor(ref) {
|
|
68
|
+
this._processor = ref;
|
|
69
|
+
return this;
|
|
70
|
+
}
|
|
71
|
+
writer(ref) {
|
|
72
|
+
this._writer = ref;
|
|
73
|
+
return this;
|
|
74
|
+
}
|
|
75
|
+
skipPolicy(p) {
|
|
76
|
+
this._skipPolicy = p;
|
|
77
|
+
return this;
|
|
78
|
+
}
|
|
79
|
+
retryPolicy(p) {
|
|
80
|
+
this._retryPolicy = p;
|
|
81
|
+
return this;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Attach an item-level listener ref to this step. Listener metadata
|
|
85
|
+
* is also recorded internally so it can be re-emitted via `.build()`.
|
|
86
|
+
*
|
|
87
|
+
* (The step IR's `listeners: ItemListenerRef[]` field is the source of
|
|
88
|
+
* truth at runtime; the `ListenerDefinition[]` aggregate lives on the
|
|
89
|
+
* job. We keep both in sync here for downstream consumer convenience.)
|
|
90
|
+
*/ addListener(ref, kind, phase, nonCritical) {
|
|
91
|
+
this.itemListeners.push(ref);
|
|
92
|
+
this.listenerDefs.push({
|
|
93
|
+
ref,
|
|
94
|
+
kind,
|
|
95
|
+
phase,
|
|
96
|
+
...nonCritical !== undefined ? {
|
|
97
|
+
nonCritical
|
|
98
|
+
} : {}
|
|
99
|
+
});
|
|
100
|
+
return this;
|
|
101
|
+
}
|
|
102
|
+
// --- build -----------------------------------------------------------
|
|
103
|
+
/**
|
|
104
|
+
* Produce the `StepDefinition` IR. Throws if the step is missing an
|
|
105
|
+
* id, or is neither a configured tasklet nor a configured chunk
|
|
106
|
+
* (chunk requires both `reader` and `writer`).
|
|
107
|
+
*/ build() {
|
|
108
|
+
if (!this._id) {
|
|
109
|
+
throw new Error('Step must have an id (call .chunk() or .tasklet() first)');
|
|
110
|
+
}
|
|
111
|
+
if (this._tasklet) {
|
|
112
|
+
const def = {
|
|
113
|
+
kind: 'tasklet',
|
|
114
|
+
id: this._id,
|
|
115
|
+
tasklet: this._tasklet,
|
|
116
|
+
listeners: this.itemListeners
|
|
117
|
+
};
|
|
118
|
+
return def;
|
|
119
|
+
}
|
|
120
|
+
if (this._chunkSize !== undefined && this._reader && this._writer) {
|
|
121
|
+
const def = {
|
|
122
|
+
kind: 'chunk',
|
|
123
|
+
id: this._id,
|
|
124
|
+
chunkSize: this._chunkSize,
|
|
125
|
+
reader: this._reader,
|
|
126
|
+
writer: this._writer,
|
|
127
|
+
listeners: this.itemListeners,
|
|
128
|
+
...this._processor ? {
|
|
129
|
+
processor: this._processor
|
|
130
|
+
} : {},
|
|
131
|
+
...this._skipPolicy ? {
|
|
132
|
+
skipPolicy: this._skipPolicy
|
|
133
|
+
} : {},
|
|
134
|
+
...this._retryPolicy ? {
|
|
135
|
+
retryPolicy: this._retryPolicy
|
|
136
|
+
} : {}
|
|
137
|
+
};
|
|
138
|
+
return def;
|
|
139
|
+
}
|
|
140
|
+
throw new Error('Step must be either tasklet or chunk with reader+writer');
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
//# sourceMappingURL=step-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/builder/step-builder.ts"],"sourcesContent":["import type {\n StepDefinition,\n ChunkStepDefinition,\n TaskletStepDefinition,\n ReaderRef,\n ProcessorRef,\n WriterRef,\n TaskletRef,\n ListenerRef,\n ItemListenerRef,\n SkipPolicyConfig,\n RetryPolicyConfig,\n ListenerDefinition,\n ListenerKind,\n ListenerPhase,\n} from '../core/ir';\n\n/**\n * Fluent builder for a single step (`chunk` or `tasklet`).\n *\n * Typical usage via `JobBuilder.addStep` callback:\n *\n * .addStep((b) => b\n * .chunk('read-csv', 100, {\n * reader: { kind: BuilderLambda, fn: readCsv },\n * processor: { kind: BuilderLambda, fn: transform },\n * writer: { kind: BuilderLambda, fn: writeRows },\n * }))\n *\n * .addStep((b) => b\n * .tasklet('cleanup', { kind: BuilderLambda, fn: cleanup }))\n *\n * The builder is single-use: call `.build()` once to produce the\n * `StepDefinition` IR.\n */\nexport class StepBuilder {\n // Field names use a `_` prefix to avoid colliding with the same-named\n // setter methods (`reader` / `processor` / `writer` / `tasklet` /\n // `skipPolicy` / `retryPolicy`). With `useDefineForClassFields: false`\n // (project tsconfig), a class field shadows any prototype method of\n // the same name — which would make the fluent setters unreachable and\n // (more subtly) make `if (this.tasklet)` in `build()` accidentally\n // find the method via the prototype chain.\n private _chunkSize?: number;\n private _reader?: ReaderRef;\n private _processor?: ProcessorRef;\n private _writer?: WriterRef;\n private _tasklet?: TaskletRef;\n private _id?: string;\n private _skipPolicy?: SkipPolicyConfig;\n private _retryPolicy?: RetryPolicyConfig;\n private readonly itemListeners: ItemListenerRef[] = [];\n private readonly listenerDefs: ListenerDefinition[] = [];\n\n // --- step-kind entry points ------------------------------------------\n\n /**\n * Start a chunk step. Sets the step id and chunk size; optionally\n * accepts reader/processor/writer/policies in a single call.\n *\n * .chunk('s1', 100, { reader, processor, writer })\n * .chunk('s2', 50, { reader, writer, skipPolicy })\n *\n * Throws if `size` is not a positive integer.\n */\n chunk(\n id: string,\n size: number,\n config?: {\n reader: ReaderRef;\n processor?: ProcessorRef;\n writer: WriterRef;\n skipPolicy?: SkipPolicyConfig;\n retryPolicy?: RetryPolicyConfig;\n },\n ): this {\n if (!Number.isInteger(size) || size <= 0) {\n throw new Error('chunkSize must be a positive integer');\n }\n this._id = id;\n this._chunkSize = size;\n if (config) {\n this._reader = config.reader;\n this._processor = config.processor;\n this._writer = config.writer;\n this._skipPolicy = config.skipPolicy;\n this._retryPolicy = config.retryPolicy;\n }\n return this;\n }\n\n /**\n * Start a tasklet step. Sets the step id and the tasklet ref.\n *\n * .tasklet('cleanup', { kind: BuilderLambda, fn: cleanup })\n */\n tasklet(id: string, ref: TaskletRef): this {\n this._id = id;\n this._tasklet = ref;\n return this;\n }\n\n // --- fine-grained setters (used after `.chunk(id, size)`) -----------\n\n reader(ref: ReaderRef): this {\n this._reader = ref;\n return this;\n }\n\n processor(ref: ProcessorRef): this {\n this._processor = ref;\n return this;\n }\n\n writer(ref: WriterRef): this {\n this._writer = ref;\n return this;\n }\n\n skipPolicy(p: SkipPolicyConfig): this {\n this._skipPolicy = p;\n return this;\n }\n\n retryPolicy(p: RetryPolicyConfig): this {\n this._retryPolicy = p;\n return this;\n }\n\n /**\n * Attach an item-level listener ref to this step. Listener metadata\n * is also recorded internally so it can be re-emitted via `.build()`.\n *\n * (The step IR's `listeners: ItemListenerRef[]` field is the source of\n * truth at runtime; the `ListenerDefinition[]` aggregate lives on the\n * job. We keep both in sync here for downstream consumer convenience.)\n */\n addListener(\n ref: ListenerRef,\n kind: ListenerKind,\n phase: ListenerPhase,\n nonCritical?: boolean,\n ): this {\n this.itemListeners.push(ref);\n this.listenerDefs.push({\n ref,\n kind,\n phase,\n ...(nonCritical !== undefined ? { nonCritical } : {}),\n });\n return this;\n }\n\n // --- build -----------------------------------------------------------\n\n /**\n * Produce the `StepDefinition` IR. Throws if the step is missing an\n * id, or is neither a configured tasklet nor a configured chunk\n * (chunk requires both `reader` and `writer`).\n */\n build(): StepDefinition {\n if (!this._id) {\n throw new Error('Step must have an id (call .chunk() or .tasklet() first)');\n }\n if (this._tasklet) {\n const def: TaskletStepDefinition = {\n kind: 'tasklet',\n id: this._id,\n tasklet: this._tasklet,\n listeners: this.itemListeners,\n };\n return def;\n }\n if (this._chunkSize !== undefined && this._reader && this._writer) {\n const def: ChunkStepDefinition = {\n kind: 'chunk',\n id: this._id,\n chunkSize: this._chunkSize,\n reader: this._reader,\n writer: this._writer,\n listeners: this.itemListeners,\n ...(this._processor ? { processor: this._processor } : {}),\n ...(this._skipPolicy ? { skipPolicy: this._skipPolicy } : {}),\n ...(this._retryPolicy ? { retryPolicy: this._retryPolicy } : {}),\n };\n return def;\n }\n throw new Error('Step must be either tasklet or chunk with reader+writer');\n }\n}\n"],"names":["StepBuilder","_chunkSize","_reader","_processor","_writer","_tasklet","_id","_skipPolicy","_retryPolicy","itemListeners","listenerDefs","chunk","id","size","config","Number","isInteger","Error","reader","processor","writer","skipPolicy","retryPolicy","tasklet","ref","p","addListener","kind","phase","nonCritical","push","undefined","build","def","listeners","chunkSize"],"mappings":";;;;+BAmCaA;;;eAAAA;;;AAAN,IAAA,AAAMA,cAAN,MAAMA;IACX,sEAAsE;IACtE,kEAAkE;IAClE,uEAAuE;IACvE,oEAAoE;IACpE,sEAAsE;IACtE,mEAAmE;IACnE,2CAA2C;IACnCC,WAAoB;IACpBC,QAAoB;IACpBC,WAA0B;IAC1BC,QAAoB;IACpBC,SAAsB;IACtBC,IAAa;IACbC,YAA+B;IAC/BC,aAAiC;IACxBC,gBAAmC,EAAE,CAAC;IACtCC,eAAqC,EAAE,CAAC;IAEzD,wEAAwE;IAExE;;;;;;;;GAQC,GACDC,MACEC,EAAU,EACVC,IAAY,EACZC,MAMC,EACK;QACN,IAAI,CAACC,OAAOC,SAAS,CAACH,SAASA,QAAQ,GAAG;YACxC,MAAM,IAAII,MAAM;QAClB;QACA,IAAI,CAACX,GAAG,GAAGM;QACX,IAAI,CAACX,UAAU,GAAGY;QAClB,IAAIC,QAAQ;YACV,IAAI,CAACZ,OAAO,GAAGY,OAAOI,MAAM;YAC5B,IAAI,CAACf,UAAU,GAAGW,OAAOK,SAAS;YAClC,IAAI,CAACf,OAAO,GAAGU,OAAOM,MAAM;YAC5B,IAAI,CAACb,WAAW,GAAGO,OAAOO,UAAU;YACpC,IAAI,CAACb,YAAY,GAAGM,OAAOQ,WAAW;QACxC;QACA,OAAO,IAAI;IACb;IAEA;;;;GAIC,GACDC,QAAQX,EAAU,EAAEY,GAAe,EAAQ;QACzC,IAAI,CAAClB,GAAG,GAAGM;QACX,IAAI,CAACP,QAAQ,GAAGmB;QAChB,OAAO,IAAI;IACb;IAEA,uEAAuE;IAEvEN,OAAOM,GAAc,EAAQ;QAC3B,IAAI,CAACtB,OAAO,GAAGsB;QACf,OAAO,IAAI;IACb;IAEAL,UAAUK,GAAiB,EAAQ;QACjC,IAAI,CAACrB,UAAU,GAAGqB;QAClB,OAAO,IAAI;IACb;IAEAJ,OAAOI,GAAc,EAAQ;QAC3B,IAAI,CAACpB,OAAO,GAAGoB;QACf,OAAO,IAAI;IACb;IAEAH,WAAWI,CAAmB,EAAQ;QACpC,IAAI,CAAClB,WAAW,GAAGkB;QACnB,OAAO,IAAI;IACb;IAEAH,YAAYG,CAAoB,EAAQ;QACtC,IAAI,CAACjB,YAAY,GAAGiB;QACpB,OAAO,IAAI;IACb;IAEA;;;;;;;GAOC,GACDC,YACEF,GAAgB,EAChBG,IAAkB,EAClBC,KAAoB,EACpBC,WAAqB,EACf;QACN,IAAI,CAACpB,aAAa,CAACqB,IAAI,CAACN;QACxB,IAAI,CAACd,YAAY,CAACoB,IAAI,CAAC;YACrBN;YACAG;YACAC;YACA,GAAIC,gBAAgBE,YAAY;gBAAEF;YAAY,IAAI,CAAC,CAAC;QACtD;QACA,OAAO,IAAI;IACb;IAEA,wEAAwE;IAExE;;;;GAIC,GACDG,QAAwB;QACtB,IAAI,CAAC,IAAI,CAAC1B,GAAG,EAAE;YACb,MAAM,IAAIW,MAAM;QAClB;QACA,IAAI,IAAI,CAACZ,QAAQ,EAAE;YACjB,MAAM4B,MAA6B;gBACjCN,MAAM;gBACNf,IAAI,IAAI,CAACN,GAAG;gBACZiB,SAAS,IAAI,CAAClB,QAAQ;gBACtB6B,WAAW,IAAI,CAACzB,aAAa;YAC/B;YACA,OAAOwB;QACT;QACA,IAAI,IAAI,CAAChC,UAAU,KAAK8B,aAAa,IAAI,CAAC7B,OAAO,IAAI,IAAI,CAACE,OAAO,EAAE;YACjE,MAAM6B,MAA2B;gBAC/BN,MAAM;gBACNf,IAAI,IAAI,CAACN,GAAG;gBACZ6B,WAAW,IAAI,CAAClC,UAAU;gBAC1BiB,QAAQ,IAAI,CAAChB,OAAO;gBACpBkB,QAAQ,IAAI,CAAChB,OAAO;gBACpB8B,WAAW,IAAI,CAACzB,aAAa;gBAC7B,GAAI,IAAI,CAACN,UAAU,GAAG;oBAAEgB,WAAW,IAAI,CAAChB,UAAU;gBAAC,IAAI,CAAC,CAAC;gBACzD,GAAI,IAAI,CAACI,WAAW,GAAG;oBAAEc,YAAY,IAAI,CAACd,WAAW;gBAAC,IAAI,CAAC,CAAC;gBAC5D,GAAI,IAAI,CAACC,YAAY,GAAG;oBAAEc,aAAa,IAAI,CAACd,YAAY;gBAAC,IAAI,CAAC,CAAC;YACjE;YACA,OAAOyB;QACT;QACA,MAAM,IAAIhB,MAAM;IAClB;AACF"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { StepDefinition, ListenerDefinition, TransitionDefinition, DeciderDefinition } from '../core/ir';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration shape for the Builder API. The builder returns this from `build()`.
|
|
4
|
+
* `DefinitionCompiler.compileFromBuilderConfig` consumes it and produces a
|
|
5
|
+
* fully-validated `JobDefinition` IR.
|
|
6
|
+
*
|
|
7
|
+
* This is a *plain-data* shape — no methods, no Nest DI references — so a builder
|
|
8
|
+
* can be assembled in unit tests without booting a Nest container.
|
|
9
|
+
*/
|
|
10
|
+
export interface JobBuilderConfig {
|
|
11
|
+
id: string;
|
|
12
|
+
restartable: boolean;
|
|
13
|
+
allowDuplicateInstances: boolean;
|
|
14
|
+
steps: StepDefinition[];
|
|
15
|
+
startStepId: string;
|
|
16
|
+
transitions: TransitionDefinition[];
|
|
17
|
+
deciders?: DeciderDefinition[];
|
|
18
|
+
listeners: ListenerDefinition[];
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=builder-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builder-types.d.ts","sourceRoot":"","sources":["../../../src/compiler/builder-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAGpB;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,OAAO,CAAC;IACrB,uBAAuB,EAAE,OAAO,CAAC;IACjC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,oBAAoB,EAAE,CAAC;IACpC,QAAQ,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC/B,SAAS,EAAE,kBAAkB,EAAE,CAAC;CACjC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/compiler/builder-types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { type JobDefinition } from '../core/ir';
|
|
3
|
+
import { BatchError } from '../core/errors';
|
|
4
|
+
import type { DiscoveredJob } from '../explorer/batch-explorer';
|
|
5
|
+
import type { JobBuilderConfig } from './builder-types';
|
|
6
|
+
/**
|
|
7
|
+
* Thrown when a chunk step on a discovered class cannot resolve a required
|
|
8
|
+
* item handler method (`@ItemReader` or `@ItemWriter`) on the class prototype.
|
|
9
|
+
*
|
|
10
|
+
* Distinct from `InvalidFlowGraphError` because this is a *static* class-shape
|
|
11
|
+
* problem (the class is missing a decorator), not a flow-graph problem
|
|
12
|
+
* (transitions, start, reachability). The `code` is stable for callers
|
|
13
|
+
* that want to switch on it.
|
|
14
|
+
*/
|
|
15
|
+
export declare class ProviderNotFoundError extends BatchError {
|
|
16
|
+
readonly code = "PROVIDER_NOT_FOUND";
|
|
17
|
+
constructor(token: string);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* `DefinitionCompiler` is the bridge between metadata-rich sources
|
|
21
|
+
* (decorator-discovered classes, fluent builder configs) and the
|
|
22
|
+
* `JobDefinition` IR consumed by the rest of the runtime.
|
|
23
|
+
*
|
|
24
|
+
* Two compilation paths share the same output type:
|
|
25
|
+
*
|
|
26
|
+
* - `compileFromDiscovered(discovered)` walks the class prototype
|
|
27
|
+
* (resolved by `BatchExplorer` in Task 7) and binds reader /
|
|
28
|
+
* processor / writer / tasklet / listener methods into `Ref`s.
|
|
29
|
+
* - `compileFromBuilderConfig(config)` accepts a plain-data config
|
|
30
|
+
* from the builder API and copies it into a `JobDefinition`.
|
|
31
|
+
*
|
|
32
|
+
* Both paths run the same `DefinitionValidator` before returning, so
|
|
33
|
+
* downstream consumers can assume the IR is structurally sound.
|
|
34
|
+
*
|
|
35
|
+
* The compiler does NOT register the job — that is `JobRegistry`'s job
|
|
36
|
+
* (Task 9). The compiler is pure: it produces IR, nothing else.
|
|
37
|
+
*/
|
|
38
|
+
export declare class DefinitionCompiler {
|
|
39
|
+
private readonly logger;
|
|
40
|
+
private readonly validator;
|
|
41
|
+
/**
|
|
42
|
+
* Compile from a discovered class. Resolves reader/processor/writer methods
|
|
43
|
+
* on the class prototype and assembles StepDefinitions. Validates before returning.
|
|
44
|
+
*/
|
|
45
|
+
compileFromDiscovered(discovered: DiscoveredJob): JobDefinition;
|
|
46
|
+
/**
|
|
47
|
+
* Compile from a builder config. Used by the fluent Builder API.
|
|
48
|
+
* Same validation as `compileFromDiscovered`.
|
|
49
|
+
*/
|
|
50
|
+
compileFromBuilderConfig(config: JobBuilderConfig): JobDefinition;
|
|
51
|
+
/**
|
|
52
|
+
* Resolve a listener method on a discovered class to a callable
|
|
53
|
+
* `ListenerRef`. Mirrors the tasklet-ref resolution in
|
|
54
|
+
* `buildTaskletStep`: if the DI container has already instantiated
|
|
55
|
+
* the class (which is the case by the time the explorer walks
|
|
56
|
+
* providers at `onModuleInit`), the method is pre-bound to the
|
|
57
|
+
* instance and the returned ref is a `BuilderLambda` carrying the
|
|
58
|
+
* bound function. This lets the runtime resolver map call the
|
|
59
|
+
* listener directly without holding onto the instance or a
|
|
60
|
+
* `ModuleRef`.
|
|
61
|
+
*
|
|
62
|
+
* When the instance is not yet available (factory providers that
|
|
63
|
+
* have not been instantiated, late-bound providers, etc.) the ref
|
|
64
|
+
* stays as a `Method` and the runtime resolver will throw a
|
|
65
|
+
* deterministic error if it cannot resolve the class. The
|
|
66
|
+
* pre-binding is a pure optimisation for the common
|
|
67
|
+
* `providers: [MyClass]` case — the test suite exercises that path.
|
|
68
|
+
*/
|
|
69
|
+
private buildListenerRef;
|
|
70
|
+
/**
|
|
71
|
+
* Build a `TaskletStepDefinition` for a `@Stepable` + `@Tasklet` method.
|
|
72
|
+
*
|
|
73
|
+
* If a DI-resolved instance is available on the `DiscoveredJob`, the
|
|
74
|
+
* tasklet ref is a `BuilderLambda` (bound function) so the executor
|
|
75
|
+
* can call it directly. Otherwise we fall back to a `Method` ref that
|
|
76
|
+
* the executor resolves at runtime against the DI container.
|
|
77
|
+
*/
|
|
78
|
+
private buildTaskletStep;
|
|
79
|
+
/**
|
|
80
|
+
* Build a `ChunkStepDefinition` for a `@Stepable` (no `@Tasklet`) method.
|
|
81
|
+
* Requires `@ItemReader` and `@ItemWriter` on the class; `@ItemProcessor`
|
|
82
|
+
* is optional.
|
|
83
|
+
*
|
|
84
|
+
* Throws `ProviderNotFoundError` if a required handler is missing.
|
|
85
|
+
*/
|
|
86
|
+
private buildChunkStep;
|
|
87
|
+
private buildItemMethodRef;
|
|
88
|
+
/**
|
|
89
|
+
* Walks the prototype chain (including inherited prototypes, stopping
|
|
90
|
+
* at `Object.prototype`) looking for a method carrying the given
|
|
91
|
+
* `BATCH_ITEM_*` metadata key.
|
|
92
|
+
*
|
|
93
|
+
* Returns the method name or `undefined`. The explorer only records
|
|
94
|
+
* `@Stepable` / listener / transition methods; item handlers are
|
|
95
|
+
* resolved here at compile time.
|
|
96
|
+
*/
|
|
97
|
+
private findItemMethod;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=definition-compiler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"definition-compiler.d.ts","sourceRoot":"","sources":["../../../src/compiler/definition-compiler.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAE1B,OAAO,EAEL,KAAK,aAAa,EAWnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,UAAU,EAAyB,MAAM,gBAAgB,CAAC;AAGnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAMhE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAExD;;;;;;;;GAQG;AACH,qBAAa,qBAAsB,SAAQ,UAAU;IACnD,QAAQ,CAAC,IAAI,wBAAwB;gBACzB,KAAK,EAAE,MAAM;CAG1B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBACa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAC9D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA6B;IAEvD;;;OAGG;IACH,qBAAqB,CAAC,UAAU,EAAE,aAAa,GAAG,aAAa;IAiD/D;;;OAGG;IACH,wBAAwB,CAAC,MAAM,EAAE,gBAAgB,GAAG,aAAa;IAqBjE;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,gBAAgB;IAkBxB;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB;IAoBxB;;;;;;OAMG;IACH,OAAO,CAAC,cAAc;IA+DtB,OAAO,CAAC,kBAAkB;IAsB1B;;;;;;;;OAQG;IACH,OAAO,CAAC,cAAc;CAavB"}
|
|
@@ -0,0 +1,257 @@
|
|
|
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 DefinitionCompiler () {
|
|
13
|
+
return DefinitionCompiler;
|
|
14
|
+
},
|
|
15
|
+
get ProviderNotFoundError () {
|
|
16
|
+
return ProviderNotFoundError;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
require("reflect-metadata");
|
|
20
|
+
const _common = require("@nestjs/common");
|
|
21
|
+
const _ir = require("../core/ir");
|
|
22
|
+
const _status = require("../core/status");
|
|
23
|
+
const _errors = require("../core/errors");
|
|
24
|
+
const _definitionvalidator = require("../core/validation/definition-validator");
|
|
25
|
+
const _partitionhelpers = require("../partition-helpers");
|
|
26
|
+
const _constants = require("../decorators/constants");
|
|
27
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
28
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
29
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
30
|
+
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;
|
|
31
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
32
|
+
}
|
|
33
|
+
let ProviderNotFoundError = class ProviderNotFoundError extends _errors.BatchError {
|
|
34
|
+
code = 'PROVIDER_NOT_FOUND';
|
|
35
|
+
constructor(token){
|
|
36
|
+
super(`Provider not found: ${token}`, {
|
|
37
|
+
token
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
let DefinitionCompiler = class DefinitionCompiler {
|
|
42
|
+
logger = new _common.Logger(DefinitionCompiler.name);
|
|
43
|
+
validator = new _definitionvalidator.DefinitionValidator();
|
|
44
|
+
/**
|
|
45
|
+
* Compile from a discovered class. Resolves reader/processor/writer methods
|
|
46
|
+
* on the class prototype and assembles StepDefinitions. Validates before returning.
|
|
47
|
+
*/ compileFromDiscovered(discovered) {
|
|
48
|
+
const steps = {};
|
|
49
|
+
const startStepId = discovered.stepMethods[0]?.options.id ?? '';
|
|
50
|
+
const classToken = discovered.classRef.name;
|
|
51
|
+
for (const step of discovered.stepMethods){
|
|
52
|
+
if (step.isTasklet) {
|
|
53
|
+
steps[step.options.id] = this.buildTaskletStep(discovered, classToken, step);
|
|
54
|
+
} else {
|
|
55
|
+
steps[step.options.id] = this.buildChunkStep(discovered, classToken, step);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const listenerDefs = discovered.listenerMethods.map((l)=>({
|
|
59
|
+
kind: l.kind,
|
|
60
|
+
phase: l.phase,
|
|
61
|
+
nonCritical: l.nonCritical,
|
|
62
|
+
ref: this.buildListenerRef(discovered, classToken, l.methodName)
|
|
63
|
+
}));
|
|
64
|
+
const transitions = discovered.transitionMethods.map((t)=>({
|
|
65
|
+
fromStepId: t.fromStep,
|
|
66
|
+
onStatus: _status.FlowExecutionStatus[t.onStatus] ?? _status.FlowExecutionStatus.UNKNOWN,
|
|
67
|
+
toStepId: t.toStep
|
|
68
|
+
}));
|
|
69
|
+
const job = {
|
|
70
|
+
id: discovered.jobOptions.id,
|
|
71
|
+
steps,
|
|
72
|
+
startStepId,
|
|
73
|
+
transitions,
|
|
74
|
+
deciders: [],
|
|
75
|
+
listeners: listenerDefs,
|
|
76
|
+
restartable: discovered.jobOptions.restartable ?? false,
|
|
77
|
+
allowDuplicateInstances: discovered.jobOptions.allowDuplicateInstances ?? false
|
|
78
|
+
};
|
|
79
|
+
this.logger.log(`Compiled job "${job.id}" from "${classToken}": ${Object.keys(steps).length} step(s), ${listenerDefs.length} listener(s), ${transitions.length} transition(s)`);
|
|
80
|
+
this.validator.validate(job);
|
|
81
|
+
return job;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Compile from a builder config. Used by the fluent Builder API.
|
|
85
|
+
* Same validation as `compileFromDiscovered`.
|
|
86
|
+
*/ compileFromBuilderConfig(config) {
|
|
87
|
+
const steps = {};
|
|
88
|
+
for (const s of config.steps){
|
|
89
|
+
steps[s.id] = s;
|
|
90
|
+
}
|
|
91
|
+
const job = {
|
|
92
|
+
id: config.id,
|
|
93
|
+
steps,
|
|
94
|
+
startStepId: config.startStepId,
|
|
95
|
+
transitions: config.transitions,
|
|
96
|
+
deciders: config.deciders ?? [],
|
|
97
|
+
listeners: config.listeners,
|
|
98
|
+
restartable: config.restartable,
|
|
99
|
+
allowDuplicateInstances: config.allowDuplicateInstances
|
|
100
|
+
};
|
|
101
|
+
this.validator.validate(job);
|
|
102
|
+
return job;
|
|
103
|
+
}
|
|
104
|
+
// --- private helpers --------------------------------------------------
|
|
105
|
+
/**
|
|
106
|
+
* Resolve a listener method on a discovered class to a callable
|
|
107
|
+
* `ListenerRef`. Mirrors the tasklet-ref resolution in
|
|
108
|
+
* `buildTaskletStep`: if the DI container has already instantiated
|
|
109
|
+
* the class (which is the case by the time the explorer walks
|
|
110
|
+
* providers at `onModuleInit`), the method is pre-bound to the
|
|
111
|
+
* instance and the returned ref is a `BuilderLambda` carrying the
|
|
112
|
+
* bound function. This lets the runtime resolver map call the
|
|
113
|
+
* listener directly without holding onto the instance or a
|
|
114
|
+
* `ModuleRef`.
|
|
115
|
+
*
|
|
116
|
+
* When the instance is not yet available (factory providers that
|
|
117
|
+
* have not been instantiated, late-bound providers, etc.) the ref
|
|
118
|
+
* stays as a `Method` and the runtime resolver will throw a
|
|
119
|
+
* deterministic error if it cannot resolve the class. The
|
|
120
|
+
* pre-binding is a pure optimisation for the common
|
|
121
|
+
* `providers: [MyClass]` case — the test suite exercises that path.
|
|
122
|
+
*/ buildListenerRef(discovered, classToken, methodName) {
|
|
123
|
+
const instance = discovered.instance;
|
|
124
|
+
const method = instance?.[methodName];
|
|
125
|
+
if (method) {
|
|
126
|
+
return {
|
|
127
|
+
kind: _ir.RefKind.BuilderLambda,
|
|
128
|
+
fn: method.bind(discovered.instance)
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
kind: _ir.RefKind.Method,
|
|
133
|
+
classToken,
|
|
134
|
+
methodName
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Build a `TaskletStepDefinition` for a `@Stepable` + `@Tasklet` method.
|
|
139
|
+
*
|
|
140
|
+
* If a DI-resolved instance is available on the `DiscoveredJob`, the
|
|
141
|
+
* tasklet ref is a `BuilderLambda` (bound function) so the executor
|
|
142
|
+
* can call it directly. Otherwise we fall back to a `Method` ref that
|
|
143
|
+
* the executor resolves at runtime against the DI container.
|
|
144
|
+
*/ buildTaskletStep(discovered, classToken, step) {
|
|
145
|
+
const instance = discovered.instance;
|
|
146
|
+
const method = instance?.[step.methodName];
|
|
147
|
+
const taskletRef = method ? {
|
|
148
|
+
kind: _ir.RefKind.BuilderLambda,
|
|
149
|
+
fn: ()=>method.bind(discovered.instance)
|
|
150
|
+
} : {
|
|
151
|
+
kind: _ir.RefKind.Method,
|
|
152
|
+
classToken,
|
|
153
|
+
methodName: step.methodName
|
|
154
|
+
};
|
|
155
|
+
return {
|
|
156
|
+
kind: 'tasklet',
|
|
157
|
+
id: step.options.id,
|
|
158
|
+
tasklet: taskletRef,
|
|
159
|
+
listeners: []
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Build a `ChunkStepDefinition` for a `@Stepable` (no `@Tasklet`) method.
|
|
164
|
+
* Requires `@ItemReader` and `@ItemWriter` on the class; `@ItemProcessor`
|
|
165
|
+
* is optional.
|
|
166
|
+
*
|
|
167
|
+
* Throws `ProviderNotFoundError` if a required handler is missing.
|
|
168
|
+
*/ buildChunkStep(discovered, classToken, step) {
|
|
169
|
+
const reader = this.findItemMethod(discovered, _constants.BATCH_ITEM_READER_METADATA);
|
|
170
|
+
const processor = this.findItemMethod(discovered, _constants.BATCH_ITEM_PROCESSOR_METADATA);
|
|
171
|
+
const writer = this.findItemMethod(discovered, _constants.BATCH_ITEM_WRITER_METADATA);
|
|
172
|
+
if (!reader) {
|
|
173
|
+
throw new ProviderNotFoundError(`@ItemReader for job ${discovered.jobOptions.id} (step ${step.options.id})`);
|
|
174
|
+
}
|
|
175
|
+
if (!writer) {
|
|
176
|
+
throw new ProviderNotFoundError(`@ItemWriter for job ${discovered.jobOptions.id} (step ${step.options.id})`);
|
|
177
|
+
}
|
|
178
|
+
const readerRef = this.buildItemMethodRef(discovered, classToken, reader);
|
|
179
|
+
const writerRef = this.buildItemMethodRef(discovered, classToken, writer);
|
|
180
|
+
// Validate the partition config at compile time so a typo
|
|
181
|
+
// (e.g. `count: 0`) fails at module load rather than at
|
|
182
|
+
// runtime when the launcher pre-creates the execution.
|
|
183
|
+
// `DefinitionValidator.validate` does the same check later
|
|
184
|
+
// (the IR is the source of truth), but the compiler is the
|
|
185
|
+
// first place we have the value in hand and we want the
|
|
186
|
+
// earliest possible failure for a decorator-discovered job.
|
|
187
|
+
try {
|
|
188
|
+
(0, _partitionhelpers.validatePartitions)(step.options.partitions);
|
|
189
|
+
} catch (err) {
|
|
190
|
+
if (err instanceof _partitionhelpers.InvalidPartitionsError) {
|
|
191
|
+
throw new _errors.InvalidFlowGraphError('INVALID_PARTITIONS', `Step "${step.options.id}" has invalid partitions: ${err.message}`, {
|
|
192
|
+
jobId: discovered.jobOptions.id,
|
|
193
|
+
stepId: step.options.id,
|
|
194
|
+
partitions: step.options.partitions
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
throw err;
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
kind: 'chunk',
|
|
201
|
+
id: step.options.id,
|
|
202
|
+
chunkSize: step.options.chunkSize ?? 100,
|
|
203
|
+
reader: readerRef,
|
|
204
|
+
writer: writerRef,
|
|
205
|
+
skipPolicy: step.options.skipPolicy,
|
|
206
|
+
retryPolicy: step.options.retryPolicy,
|
|
207
|
+
listeners: [],
|
|
208
|
+
...step.options.partitions !== undefined ? {
|
|
209
|
+
partitions: step.options.partitions
|
|
210
|
+
} : {},
|
|
211
|
+
...processor ? {
|
|
212
|
+
processor: this.buildItemMethodRef(discovered, classToken, processor)
|
|
213
|
+
} : {}
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
buildItemMethodRef(discovered, classToken, methodName) {
|
|
217
|
+
const instance = discovered.instance;
|
|
218
|
+
const method = instance?.[methodName];
|
|
219
|
+
if (method) {
|
|
220
|
+
return {
|
|
221
|
+
kind: _ir.RefKind.BuilderLambda,
|
|
222
|
+
fn: ()=>method.bind(discovered.instance)
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
return {
|
|
226
|
+
kind: _ir.RefKind.Method,
|
|
227
|
+
classToken,
|
|
228
|
+
methodName
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Walks the prototype chain (including inherited prototypes, stopping
|
|
233
|
+
* at `Object.prototype`) looking for a method carrying the given
|
|
234
|
+
* `BATCH_ITEM_*` metadata key.
|
|
235
|
+
*
|
|
236
|
+
* Returns the method name or `undefined`. The explorer only records
|
|
237
|
+
* `@Stepable` / listener / transition methods; item handlers are
|
|
238
|
+
* resolved here at compile time.
|
|
239
|
+
*/ findItemMethod(discovered, metadataKey) {
|
|
240
|
+
const proto = discovered.classRef.prototype;
|
|
241
|
+
if (!proto) return undefined;
|
|
242
|
+
let p = proto;
|
|
243
|
+
while(p && p !== Object.prototype){
|
|
244
|
+
for (const name of Object.getOwnPropertyNames(p)){
|
|
245
|
+
if (name === 'constructor') continue;
|
|
246
|
+
if (Reflect.getMetadata(metadataKey, p, name) === true) return name;
|
|
247
|
+
}
|
|
248
|
+
p = Object.getPrototypeOf(p);
|
|
249
|
+
}
|
|
250
|
+
return undefined;
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
DefinitionCompiler = _ts_decorate([
|
|
254
|
+
(0, _common.Injectable)()
|
|
255
|
+
], DefinitionCompiler);
|
|
256
|
+
|
|
257
|
+
//# sourceMappingURL=definition-compiler.js.map
|