@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,674 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DynamicModule,
|
|
3
|
+
Injectable,
|
|
4
|
+
Logger,
|
|
5
|
+
Module,
|
|
6
|
+
OnApplicationBootstrap,
|
|
7
|
+
Provider,
|
|
8
|
+
} from '@nestjs/common';
|
|
9
|
+
import { DiscoveryModule } from '@nestjs/core';
|
|
10
|
+
|
|
11
|
+
import type { BatchAdaptersConfig } from './adapter';
|
|
12
|
+
import { DefinitionCompiler } from '../compiler/definition-compiler';
|
|
13
|
+
import { BatchExplorer } from '../explorer/batch-explorer';
|
|
14
|
+
import { JobRegistry } from '../registry/job-registry';
|
|
15
|
+
import { JobExecutor } from '../execution/job-executor';
|
|
16
|
+
import { ChunkStepExecutor } from '../execution/chunk-step-executor';
|
|
17
|
+
import { TaskletStepExecutor } from '../execution/tasklet-step-executor';
|
|
18
|
+
import { ListenerInvoker } from '../execution/listener-invoker';
|
|
19
|
+
import { JobLauncher } from '../execution/job-launcher';
|
|
20
|
+
import { JobExplorer } from '../execution/job-explorer';
|
|
21
|
+
import { JobOperator } from '../execution/job-operator';
|
|
22
|
+
import { BatchWorkerRunner } from '../execution/batch-worker-runner';
|
|
23
|
+
import {
|
|
24
|
+
InProcessExecutionStrategy,
|
|
25
|
+
IN_PROCESS_EXECUTION_STRATEGY_PROVIDER,
|
|
26
|
+
} from '../execution/in-process-execution-strategy';
|
|
27
|
+
import { FlowEvaluator } from '../flow/flow-evaluator';
|
|
28
|
+
import { BATCH_SCHEDULED_OPTIONS } from '../decorators/constants';
|
|
29
|
+
import type { BatchScheduledMetadata } from '../scheduling/batch-scheduled';
|
|
30
|
+
import {
|
|
31
|
+
BatchScheduleRegistry,
|
|
32
|
+
type BatchScheduleEntry,
|
|
33
|
+
} from './batch-schedule-registry';
|
|
34
|
+
import {
|
|
35
|
+
BATCH_SCHEDULE_REGISTRY,
|
|
36
|
+
JOB_REPOSITORY_TOKEN,
|
|
37
|
+
MODULE_OPTIONS_TOKEN,
|
|
38
|
+
TRANSACTION_MANAGER_TOKEN,
|
|
39
|
+
} from './tokens';
|
|
40
|
+
import { JobRepository } from '../core/repository/job-repository';
|
|
41
|
+
import { TransactionManager } from '../core/transaction/transaction-manager';
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Re-export the default in-process strategy and its token binding so
|
|
45
|
+
* the host app can wire them up alongside the rest of the batch
|
|
46
|
+
* engine. The strategy is *not* auto-registered by
|
|
47
|
+
* `NestBatchModule.forRoot()` because its constructor requires
|
|
48
|
+
* `JobRepository` and `JobExecutor` — runtime deps the host
|
|
49
|
+
* supplies. The T4 `InProcessAdapter` factory does the wiring through
|
|
50
|
+
* the adapter's own `DynamicModule.exports` so the runtime
|
|
51
|
+
* resolution chain works without the core module having to know which
|
|
52
|
+
* adapter is active.
|
|
53
|
+
*
|
|
54
|
+
* ```ts
|
|
55
|
+
* import { InProcessAdapter, MikroOrmAdapter, NestBatchModule } from '@nest-batch/core';
|
|
56
|
+
*
|
|
57
|
+
* @Module({
|
|
58
|
+
* imports: [
|
|
59
|
+
* NestBatchModule.forRoot({
|
|
60
|
+
* adapters: {
|
|
61
|
+
* persistence: MikroOrmAdapter,
|
|
62
|
+
* transport: InProcessAdapter,
|
|
63
|
+
* },
|
|
64
|
+
* }),
|
|
65
|
+
* ],
|
|
66
|
+
* })
|
|
67
|
+
* class AppModule {}
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export { InProcessExecutionStrategy, IN_PROCESS_EXECUTION_STRATEGY_PROVIDER };
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Options for `NestBatchModule.forRoot()`.
|
|
74
|
+
*
|
|
75
|
+
* The whole configuration is the pair of adapters (persistence +
|
|
76
|
+
* transport) the host picked. Both are required — the compiler
|
|
77
|
+
* will reject an `adapters` bag that is missing one — and each
|
|
78
|
+
* adapter is a self-contained `DynamicModule` core will import.
|
|
79
|
+
* Sibling packages can no longer extend the options shape via
|
|
80
|
+
* interface merging: the old `AdapterOptions` extension point is
|
|
81
|
+
* gone because every adapter now owns its own `DynamicModule`
|
|
82
|
+
* (and therefore its own config). Adapter authors that want
|
|
83
|
+
* type-safe factory arguments should expose them on their own
|
|
84
|
+
* adapter factory (e.g. `MikroOrmAdapter.forRoot({ ... })`).
|
|
85
|
+
*
|
|
86
|
+
* - `adapters.persistence` — the adapter that owns the
|
|
87
|
+
* `JobRepository` + `TransactionManager` bindings (e.g.
|
|
88
|
+
* `MikroOrmAdapter`, `TypeOrmAdapter`).
|
|
89
|
+
* - `adapters.transport` — the adapter that owns the
|
|
90
|
+
* `IExecutionStrategy` binding (e.g. `InProcessAdapter`,
|
|
91
|
+
* `BullmqAdapter`).
|
|
92
|
+
*/
|
|
93
|
+
export interface NestBatchModuleOptions {
|
|
94
|
+
readonly adapters: BatchAdaptersConfig;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Options for `NestBatchModule.forRootAsync()`.
|
|
99
|
+
*
|
|
100
|
+
* `imports` + `inject` + `useFactory` mirror the standard
|
|
101
|
+
* `ConfigurableModuleBuilder` shape. The factory is registered as a
|
|
102
|
+
* sentinel provider under `OPTIONS_FACTORY` (a `Symbol.for` token
|
|
103
|
+
* stable across module boundaries), and `MODULE_OPTIONS_TOKEN` is
|
|
104
|
+
* bound to its resolved `BatchAdaptersConfig` via a follow-up
|
|
105
|
+
* `useFactory` provider.
|
|
106
|
+
*
|
|
107
|
+
* **Note on adapter module merging.** NestJS cannot dynamically
|
|
108
|
+
* import a `DynamicModule` at module-build time, so the
|
|
109
|
+
* `forRootAsync` path does NOT auto-merge the adapter modules'
|
|
110
|
+
* `globalProviders` into the core module's `providers` list the way
|
|
111
|
+
* `forRoot` does. Two consequences for the async path:
|
|
112
|
+
*
|
|
113
|
+
* 1. The adapter `DynamicModule`s must be passed in the caller's
|
|
114
|
+
* `imports` array directly (e.g.
|
|
115
|
+
* `imports: [MikroOrmAdapter.module, InProcessAdapter.module]`)
|
|
116
|
+
* so Nest sees them in the module graph.
|
|
117
|
+
* 2. The factory's return value is used only for the
|
|
118
|
+
* `MODULE_OPTIONS_TOKEN` binding (adapters introspection);
|
|
119
|
+
* sibling packages and the host can read the resolved config
|
|
120
|
+
* via `@Inject(MODULE_OPTIONS_TOKEN)`.
|
|
121
|
+
*
|
|
122
|
+
* For the full auto-merge (adapter modules + `globalProviders`
|
|
123
|
+
* registered into core's own DI scope), prefer `forRoot` with a
|
|
124
|
+
* pre-resolved `BatchAdaptersConfig`. The async path is for
|
|
125
|
+
* adapters whose factory needs to consult a config service or
|
|
126
|
+
* another async provider to decide which adapter to plug in.
|
|
127
|
+
*/
|
|
128
|
+
export interface NestBatchModuleAsyncOptions {
|
|
129
|
+
imports?: DynamicModule['imports'];
|
|
130
|
+
useFactory: (
|
|
131
|
+
...args: unknown[]
|
|
132
|
+
) => Promise<BatchAdaptersConfig> | BatchAdaptersConfig;
|
|
133
|
+
inject?: readonly unknown[];
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Sentinel provider token used by `forRootAsync` to plumb the user's
|
|
138
|
+
* `useFactory` through DI. The factory is registered under this
|
|
139
|
+
* token, and `MODULE_OPTIONS_TOKEN` resolves to its output via a
|
|
140
|
+
* follow-up `useFactory` provider.
|
|
141
|
+
*
|
|
142
|
+
* `Symbol.for(...)` makes the token stable across module boundaries:
|
|
143
|
+
* tooling or sibling packages that know the description string can
|
|
144
|
+
* resolve the same symbol without importing this file. Matches the
|
|
145
|
+
* convention used by `BATCH_SCHEDULE_REGISTRY`, `MODULE_OPTIONS_TOKEN`,
|
|
146
|
+
* `JOB_REPOSITORY_TOKEN`, etc. in `./tokens.ts`.
|
|
147
|
+
*/
|
|
148
|
+
const OPTIONS_FACTORY: symbol = Symbol.for('@nest-batch/core/OPTIONS_FACTORY');
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Hook that runs on `OnApplicationBootstrap` to wire together the
|
|
152
|
+
* discovery → compile → register pipeline.
|
|
153
|
+
*
|
|
154
|
+
* Why a separate provider and not a method on `JobRegistry` or
|
|
155
|
+
* `DefinitionCompiler`?
|
|
156
|
+
* - `BatchExplorer.onModuleInit` populates the discovered
|
|
157
|
+
* list once the DI container is ready. Compilation needs every
|
|
158
|
+
* `@Jobable` provider to be instantiated, so it must run *after*
|
|
159
|
+
* `onModuleInit`.
|
|
160
|
+
* - `OnApplicationBootstrap` is the latest point in Nest's lifecycle
|
|
161
|
+
* before the app actually starts handling requests, so all of:
|
|
162
|
+
* `forRoot` / `forRootAsync` providers, custom `useFactory` results,
|
|
163
|
+
* and user-supplied job classes, are guaranteed to be live.
|
|
164
|
+
* - Keeping the wire-up in a dedicated `BatchBootstrapper` means the
|
|
165
|
+
* explorer/compiler/registry stay pure (no `onApplicationBootstrap`
|
|
166
|
+
* coupling) and are independently testable.
|
|
167
|
+
*
|
|
168
|
+
* The bootstrapper also walks every discovered job for
|
|
169
|
+
* `@BatchScheduled` metadata and registers the corresponding entries
|
|
170
|
+
* into the `BatchScheduleRegistry` so the (future) runtime scheduler
|
|
171
|
+
* has a single, stable place to read them from. Today, the registry is
|
|
172
|
+
* metadata-only — no timers are installed.
|
|
173
|
+
*/
|
|
174
|
+
@Injectable()
|
|
175
|
+
export class BatchBootstrapper implements OnApplicationBootstrap {
|
|
176
|
+
private readonly logger = new Logger(BatchBootstrapper.name);
|
|
177
|
+
|
|
178
|
+
constructor(
|
|
179
|
+
private readonly explorer: BatchExplorer,
|
|
180
|
+
private readonly compiler: DefinitionCompiler,
|
|
181
|
+
private readonly registry: JobRegistry,
|
|
182
|
+
private readonly scheduleRegistry: BatchScheduleRegistry,
|
|
183
|
+
) {}
|
|
184
|
+
|
|
185
|
+
onApplicationBootstrap(): void {
|
|
186
|
+
// 1. Compile + register every discovered job.
|
|
187
|
+
for (const discovered of this.explorer.getDiscovered()) {
|
|
188
|
+
const jobId = discovered.jobOptions.id;
|
|
189
|
+
try {
|
|
190
|
+
const def = this.compiler.compileFromDiscovered(discovered);
|
|
191
|
+
this.registry.register(def);
|
|
192
|
+
this.logger.log(`Registered job "${jobId}"`);
|
|
193
|
+
} catch (err) {
|
|
194
|
+
this.logger.error(
|
|
195
|
+
`Failed to register job "${jobId}": ${(err as Error).message}`,
|
|
196
|
+
);
|
|
197
|
+
throw err;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// 2. Walk the same discovered set for @BatchScheduled metadata
|
|
202
|
+
// and populate BatchScheduleRegistry. The metadata is stamped
|
|
203
|
+
// by the decorator via `SetMetadata(KEY, value)`, which Nest
|
|
204
|
+
// writes to the *function reference* of the decorated method
|
|
205
|
+
// (not to the prototype+name slot). We therefore read it from
|
|
206
|
+
// `prototype[name]` (the function), not from the (proto, name)
|
|
207
|
+
// tuple.
|
|
208
|
+
for (const discovered of this.explorer.getDiscovered()) {
|
|
209
|
+
const jobId = discovered.jobOptions.id;
|
|
210
|
+
const prototype = discovered.classRef.prototype as Record<string, unknown>;
|
|
211
|
+
for (const name of this.allMethodNames(prototype)) {
|
|
212
|
+
const fn = prototype[name];
|
|
213
|
+
if (typeof fn !== 'function') continue;
|
|
214
|
+
const meta = Reflect.getMetadata(
|
|
215
|
+
BATCH_SCHEDULED_OPTIONS,
|
|
216
|
+
fn,
|
|
217
|
+
) as BatchScheduledMetadata | undefined;
|
|
218
|
+
if (!meta) continue;
|
|
219
|
+
const entry: BatchScheduleEntry = {
|
|
220
|
+
jobId,
|
|
221
|
+
methodName: name,
|
|
222
|
+
cron: meta.cron,
|
|
223
|
+
timezone: meta.options.timezone,
|
|
224
|
+
overlap: meta.options.overlap,
|
|
225
|
+
startAt: meta.options.startAt,
|
|
226
|
+
endAt: meta.options.endAt,
|
|
227
|
+
inert: meta.inert,
|
|
228
|
+
};
|
|
229
|
+
try {
|
|
230
|
+
this.scheduleRegistry.register(entry);
|
|
231
|
+
this.logger.log(
|
|
232
|
+
`Registered schedule for job "${jobId}"::${name} (cron="${meta.cron}", tz="${meta.options.timezone}")`,
|
|
233
|
+
);
|
|
234
|
+
} catch (err) {
|
|
235
|
+
this.logger.error(
|
|
236
|
+
`Failed to register schedule for job "${jobId}"::${name}: ${
|
|
237
|
+
(err as Error).message
|
|
238
|
+
}`,
|
|
239
|
+
);
|
|
240
|
+
throw err;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Walk the prototype chain and return every own method name
|
|
248
|
+
* (excluding `constructor`) up to (but not including)
|
|
249
|
+
* `Object.prototype`. Same shape as `BatchExplorer.allMethodNames` —
|
|
250
|
+
* we duplicate the walker here so the bootstrapper remains
|
|
251
|
+
* independent of the explorer's internals.
|
|
252
|
+
*/
|
|
253
|
+
private allMethodNames(prototype: object): Set<string> {
|
|
254
|
+
const names = new Set<string>();
|
|
255
|
+
let proto: object | null = prototype;
|
|
256
|
+
while (proto && proto !== Object.prototype) {
|
|
257
|
+
for (const name of Object.getOwnPropertyNames(proto)) {
|
|
258
|
+
if (name === 'constructor') continue;
|
|
259
|
+
names.add(name);
|
|
260
|
+
}
|
|
261
|
+
proto = Object.getPrototypeOf(proto);
|
|
262
|
+
}
|
|
263
|
+
return names;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Public Nest module that wires up the @nest-batch/core library.
|
|
269
|
+
*
|
|
270
|
+
* The module is a `global: true` `DynamicModule` whose `imports`,
|
|
271
|
+
* `providers`, and `exports` are assembled at the call site by
|
|
272
|
+
* `forRoot` (synchronous) or `forRootAsync` (sentinel-factory
|
|
273
|
+
* pattern). In both paths the core providers and the executor
|
|
274
|
+
* subgraph are auto-registered so the host does not have to wire
|
|
275
|
+
* them by hand; adapter modules are imported as part of the same
|
|
276
|
+
* `DynamicModule` so Nest's discovery phase sees every job class.
|
|
277
|
+
*
|
|
278
|
+
* @see {@link NestBatchModuleOptions} for the synchronous options shape
|
|
279
|
+
* @see {@link NestBatchModuleAsyncOptions} for the async options shape
|
|
280
|
+
* @see {@link BatchAdaptersConfig} for the adapter contract
|
|
281
|
+
*/
|
|
282
|
+
@Module({})
|
|
283
|
+
export class NestBatchModule {
|
|
284
|
+
/**
|
|
285
|
+
* Build a provider list from an adapter's `globalProviders`,
|
|
286
|
+
* automatically aliasing the abstract `JobRepository` class to
|
|
287
|
+
* `JOB_REPOSITORY_TOKEN` when the symbol is present but the class
|
|
288
|
+
* itself is not directly provided.
|
|
289
|
+
*
|
|
290
|
+
* This fixes the NestJS DI resolution gap: `JobExecutor`,
|
|
291
|
+
* `JobLauncher`, and `InProcessExecutionStrategy` all inject the
|
|
292
|
+
* abstract `JobRepository`, but adapters typically bind their
|
|
293
|
+
* concrete implementation to `JOB_REPOSITORY_TOKEN`. NestJS cannot
|
|
294
|
+
* resolve abstract class → concrete subclass automatically, so we
|
|
295
|
+
* inject the alias here.
|
|
296
|
+
*
|
|
297
|
+
* Idempotent: if `JobRepository` is already directly provided (e.g.
|
|
298
|
+
* `{ provide: JobRepository, useClass: MyRepo }`), no extra alias is
|
|
299
|
+
* added.
|
|
300
|
+
*/
|
|
301
|
+
private static buildProviders(adapterGlobalProviders: readonly Provider[]): Provider[] {
|
|
302
|
+
const providers = [...adapterGlobalProviders];
|
|
303
|
+
|
|
304
|
+
const hasJobRepositoryToken = providers.some(
|
|
305
|
+
(p) =>
|
|
306
|
+
typeof p === 'object' &&
|
|
307
|
+
p !== null &&
|
|
308
|
+
'provide' in p &&
|
|
309
|
+
p.provide === JOB_REPOSITORY_TOKEN,
|
|
310
|
+
);
|
|
311
|
+
|
|
312
|
+
const hasJobRepositoryClass = providers.some(
|
|
313
|
+
(p) =>
|
|
314
|
+
p === JobRepository ||
|
|
315
|
+
(typeof p === 'object' &&
|
|
316
|
+
p !== null &&
|
|
317
|
+
'provide' in p &&
|
|
318
|
+
p.provide === JobRepository),
|
|
319
|
+
);
|
|
320
|
+
|
|
321
|
+
if (hasJobRepositoryToken && !hasJobRepositoryClass) {
|
|
322
|
+
providers.push({
|
|
323
|
+
provide: JobRepository,
|
|
324
|
+
useExisting: JOB_REPOSITORY_TOKEN,
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const hasTransactionManagerToken = providers.some(
|
|
329
|
+
(p) =>
|
|
330
|
+
typeof p === 'object' &&
|
|
331
|
+
p !== null &&
|
|
332
|
+
'provide' in p &&
|
|
333
|
+
p.provide === TRANSACTION_MANAGER_TOKEN,
|
|
334
|
+
);
|
|
335
|
+
|
|
336
|
+
const hasTransactionManagerClass = providers.some(
|
|
337
|
+
(p) =>
|
|
338
|
+
p === TransactionManager ||
|
|
339
|
+
(typeof p === 'object' &&
|
|
340
|
+
p !== null &&
|
|
341
|
+
'provide' in p &&
|
|
342
|
+
p.provide === TransactionManager),
|
|
343
|
+
);
|
|
344
|
+
|
|
345
|
+
if (hasTransactionManagerToken && !hasTransactionManagerClass) {
|
|
346
|
+
providers.push({
|
|
347
|
+
provide: TransactionManager,
|
|
348
|
+
useExisting: TRANSACTION_MANAGER_TOKEN,
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
return providers;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Best-effort resolution of `inject` tokens by reading the
|
|
357
|
+
* `providers` metadata of modules listed in `imports`. This lets
|
|
358
|
+
* `forRootAsync` evaluate a synchronous `useFactory` even when it
|
|
359
|
+
* declares `inject` deps, provided those deps are `useValue`
|
|
360
|
+
* providers exported by an imported module.
|
|
361
|
+
*
|
|
362
|
+
* Only `useValue` providers can be resolved this way — `useClass`
|
|
363
|
+
* and `useFactory` providers need Nest's DI container and are
|
|
364
|
+
* skipped.
|
|
365
|
+
*/
|
|
366
|
+
private static resolveInjectValues(
|
|
367
|
+
imports: NestBatchModuleAsyncOptions['imports'],
|
|
368
|
+
inject: readonly unknown[],
|
|
369
|
+
): unknown[] {
|
|
370
|
+
if (!inject || inject.length === 0) return [];
|
|
371
|
+
|
|
372
|
+
const values: unknown[] = [];
|
|
373
|
+
for (const token of inject) {
|
|
374
|
+
let resolved: unknown = undefined;
|
|
375
|
+
for (const mod of imports ?? []) {
|
|
376
|
+
if (!mod) continue;
|
|
377
|
+
|
|
378
|
+
let providers: Provider[] | undefined;
|
|
379
|
+
|
|
380
|
+
if (typeof mod === 'object' && 'module' in mod) {
|
|
381
|
+
const dynamicMod = mod as DynamicModule;
|
|
382
|
+
providers = dynamicMod.providers;
|
|
383
|
+
if (!providers && dynamicMod.module) {
|
|
384
|
+
try {
|
|
385
|
+
providers = Reflect.getMetadata('providers', dynamicMod.module);
|
|
386
|
+
} catch {
|
|
387
|
+
/* ignore metadata read failures */
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
} else if (typeof mod === 'function') {
|
|
391
|
+
try {
|
|
392
|
+
providers = Reflect.getMetadata('providers', mod);
|
|
393
|
+
} catch {
|
|
394
|
+
/* ignore metadata read failures */
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
for (const p of providers ?? []) {
|
|
399
|
+
if (
|
|
400
|
+
typeof p === 'object' &&
|
|
401
|
+
p !== null &&
|
|
402
|
+
'provide' in p &&
|
|
403
|
+
p.provide === token &&
|
|
404
|
+
'useValue' in p
|
|
405
|
+
) {
|
|
406
|
+
resolved = p.useValue;
|
|
407
|
+
break;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
if (resolved !== undefined) break;
|
|
411
|
+
}
|
|
412
|
+
values.push(resolved);
|
|
413
|
+
}
|
|
414
|
+
return values;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Static (synchronous) configuration.
|
|
419
|
+
*
|
|
420
|
+
* Takes the resolved `BatchAdaptersConfig` and builds a
|
|
421
|
+
* `global: true` `DynamicModule` that:
|
|
422
|
+
*
|
|
423
|
+
* 1. imports each adapter's `DynamicModule`
|
|
424
|
+
* (`adapters.persistence.module` and `adapters.transport.module`);
|
|
425
|
+
* 2. imports `DiscoveryModule` from `@nestjs/core` so the explorer
|
|
426
|
+
* can use Nest's `DiscoveryService`;
|
|
427
|
+
* 3. registers core's own providers — `JobRegistry`,
|
|
428
|
+
* `DefinitionCompiler`, `BatchExplorer`, `FlowEvaluator`,
|
|
429
|
+
* `BatchScheduleRegistry`, `BatchBootstrapper` — and the
|
|
430
|
+
* executor subgraph (`JobExecutor`, `ChunkStepExecutor`,
|
|
431
|
+
* `TaskletStepExecutor`, `ListenerInvoker`) so the host
|
|
432
|
+
* does not have to wire them by hand;
|
|
433
|
+
* 4. registers each adapter's `globalProviders` (e.g. the
|
|
434
|
+
* `JobRepository` / `TransactionManager` implementations
|
|
435
|
+
* from a persistence adapter) so the host can inject them
|
|
436
|
+
* too;
|
|
437
|
+
* 5. binds the `BatchAdaptersConfig` to `MODULE_OPTIONS_TOKEN`
|
|
438
|
+
* via a value provider for adapter introspection.
|
|
439
|
+
*/
|
|
440
|
+
static forRoot(options: NestBatchModuleOptions): DynamicModule {
|
|
441
|
+
const { adapters } = options;
|
|
442
|
+
const persistenceProviders = NestBatchModule.buildProviders(
|
|
443
|
+
adapters.persistence.globalProviders ?? [],
|
|
444
|
+
);
|
|
445
|
+
const transportProviders = NestBatchModule.buildProviders(
|
|
446
|
+
adapters.transport.globalProviders ?? [],
|
|
447
|
+
);
|
|
448
|
+
|
|
449
|
+
return {
|
|
450
|
+
module: NestBatchModule,
|
|
451
|
+
global: true,
|
|
452
|
+
imports: [
|
|
453
|
+
adapters.persistence.module,
|
|
454
|
+
adapters.transport.module,
|
|
455
|
+
DiscoveryModule,
|
|
456
|
+
],
|
|
457
|
+
providers: [
|
|
458
|
+
// Core classes (discovery + compile + register).
|
|
459
|
+
JobRegistry,
|
|
460
|
+
DefinitionCompiler,
|
|
461
|
+
BatchExplorer,
|
|
462
|
+
FlowEvaluator,
|
|
463
|
+
BatchScheduleRegistry,
|
|
464
|
+
BatchBootstrapper,
|
|
465
|
+
// Executor subgraph (JobExecutor → Chunk/Tasklet/Listener).
|
|
466
|
+
JobExecutor,
|
|
467
|
+
ChunkStepExecutor,
|
|
468
|
+
TaskletStepExecutor,
|
|
469
|
+
ListenerInvoker,
|
|
470
|
+
JobLauncher,
|
|
471
|
+
JobExplorer,
|
|
472
|
+
JobOperator,
|
|
473
|
+
BatchWorkerRunner,
|
|
474
|
+
// Resolved options bag for adapter introspection.
|
|
475
|
+
{
|
|
476
|
+
provide: MODULE_OPTIONS_TOKEN,
|
|
477
|
+
useValue: adapters,
|
|
478
|
+
},
|
|
479
|
+
// Schedule registry symbol alias — the symbol itself
|
|
480
|
+
// must be a provider (not just a class export) so the
|
|
481
|
+
// `exports` entry below resolves through Nest's DI
|
|
482
|
+
// validation.
|
|
483
|
+
{
|
|
484
|
+
provide: BATCH_SCHEDULE_REGISTRY,
|
|
485
|
+
useExisting: BatchScheduleRegistry,
|
|
486
|
+
},
|
|
487
|
+
// Adapter-supplied global providers (e.g. JobRepository
|
|
488
|
+
// / TransactionManager implementations).
|
|
489
|
+
...persistenceProviders,
|
|
490
|
+
...transportProviders,
|
|
491
|
+
],
|
|
492
|
+
exports: [
|
|
493
|
+
// Core classes — exported so sibling packages and the
|
|
494
|
+
// host app can resolve them from the global module chain.
|
|
495
|
+
JobRegistry,
|
|
496
|
+
DefinitionCompiler,
|
|
497
|
+
BatchExplorer,
|
|
498
|
+
FlowEvaluator,
|
|
499
|
+
BatchScheduleRegistry,
|
|
500
|
+
BatchBootstrapper,
|
|
501
|
+
// Tokens — exported so adapters can bind to them via
|
|
502
|
+
// `@Inject(MODULE_OPTIONS_TOKEN)` and host code can read
|
|
503
|
+
// the schedule registry by its stable symbol.
|
|
504
|
+
BATCH_SCHEDULE_REGISTRY,
|
|
505
|
+
MODULE_OPTIONS_TOKEN,
|
|
506
|
+
// Executor subgraph — exported so adapters (e.g. the
|
|
507
|
+
// `InProcessExecutionStrategy`) and host code can inject
|
|
508
|
+
// them.
|
|
509
|
+
JobExecutor,
|
|
510
|
+
ChunkStepExecutor,
|
|
511
|
+
TaskletStepExecutor,
|
|
512
|
+
ListenerInvoker,
|
|
513
|
+
JobLauncher,
|
|
514
|
+
JobExplorer,
|
|
515
|
+
JobOperator,
|
|
516
|
+
BatchWorkerRunner,
|
|
517
|
+
// Adapter-supplied global providers — re-exported so the
|
|
518
|
+
// host can resolve the persistence + transport bindings
|
|
519
|
+
// from the global module chain.
|
|
520
|
+
...persistenceProviders,
|
|
521
|
+
...transportProviders,
|
|
522
|
+
],
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* Async configuration — useful when the adapter set comes from a
|
|
528
|
+
* config service or another async source.
|
|
529
|
+
*
|
|
530
|
+
* Mirrors the `BullmqBatchModule.forRootAsync` pattern: the user's
|
|
531
|
+
* `useFactory` is registered as a sentinel provider under
|
|
532
|
+
* `OPTIONS_FACTORY`, and `MODULE_OPTIONS_TOKEN` is bound to its
|
|
533
|
+
* resolved `BatchAdaptersConfig` via a follow-up `useFactory`
|
|
534
|
+
* provider. The user's `imports` + `inject` are forwarded as-is
|
|
535
|
+
* so the factory can pull from `ConfigService` or any other
|
|
536
|
+
* DI-bound dependency.
|
|
537
|
+
*
|
|
538
|
+
* See the `NestBatchModuleAsyncOptions` JSDoc for the adapter
|
|
539
|
+
* module merging caveat — the async path does not auto-merge
|
|
540
|
+
* the adapter modules' `globalProviders`. The adapter
|
|
541
|
+
* `DynamicModule`s must be passed in the caller's `imports`
|
|
542
|
+
* array so Nest sees them in the module graph; the factory's
|
|
543
|
+
* return value is used only for `MODULE_OPTIONS_TOKEN`.
|
|
544
|
+
*/
|
|
545
|
+
static forRootAsync(
|
|
546
|
+
options: NestBatchModuleAsyncOptions,
|
|
547
|
+
): DynamicModule | Promise<DynamicModule> {
|
|
548
|
+
const { imports = [], inject = [], useFactory } = options;
|
|
549
|
+
|
|
550
|
+
// Try to evaluate the factory synchronously so we can merge
|
|
551
|
+
// adapter `globalProviders` at module-build time (mirroring
|
|
552
|
+
// what `forRoot` does). If the factory is async or needs
|
|
553
|
+
// injected deps we can't resolve, fall back to the pure
|
|
554
|
+
// sentinel-factory path.
|
|
555
|
+
const injectValues = NestBatchModule.resolveInjectValues(imports, inject);
|
|
556
|
+
const factoryResult = useFactory(...injectValues);
|
|
557
|
+
|
|
558
|
+
if (factoryResult instanceof Promise) {
|
|
559
|
+
return factoryResult.then((adapters) =>
|
|
560
|
+
NestBatchModule.buildAsyncModule(options, adapters),
|
|
561
|
+
);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
return NestBatchModule.buildAsyncModule(options, factoryResult);
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Shared module builder used by both the sync and async branches
|
|
569
|
+
* of `forRootAsync`. When the factory result is available
|
|
570
|
+
* synchronously we merge adapter `globalProviders` (plus the
|
|
571
|
+
* `JobRepository` alias) into core's own provider list, exactly
|
|
572
|
+
* like `forRoot` does.
|
|
573
|
+
*/
|
|
574
|
+
private static buildAsyncModule(
|
|
575
|
+
options: NestBatchModuleAsyncOptions,
|
|
576
|
+
adapters: BatchAdaptersConfig,
|
|
577
|
+
): DynamicModule {
|
|
578
|
+
const { imports = [], inject = [], useFactory } = options;
|
|
579
|
+
|
|
580
|
+
const persistenceProviders = NestBatchModule.buildProviders(
|
|
581
|
+
adapters.persistence.globalProviders ?? [],
|
|
582
|
+
);
|
|
583
|
+
const transportProviders = NestBatchModule.buildProviders(
|
|
584
|
+
adapters.transport.globalProviders ?? [],
|
|
585
|
+
);
|
|
586
|
+
|
|
587
|
+
// Sentinel factory provider: holds the user's `useFactory` and
|
|
588
|
+
// any `inject` deps. Other providers can pull the resolved
|
|
589
|
+
// `BatchAdaptersConfig` via `@Inject(OPTIONS_FACTORY)` if they
|
|
590
|
+
// need to.
|
|
591
|
+
const factoryProvider: Provider = {
|
|
592
|
+
provide: OPTIONS_FACTORY,
|
|
593
|
+
useFactory: useFactory as (...args: unknown[]) => unknown,
|
|
594
|
+
inject: [...inject] as Array<string | symbol | Function>,
|
|
595
|
+
};
|
|
596
|
+
|
|
597
|
+
// Options provider: bridges the sentinel factory to the
|
|
598
|
+
// canonical `MODULE_OPTIONS_TOKEN` so adapters + host code can
|
|
599
|
+
// read the resolved config by its stable symbol.
|
|
600
|
+
const optionsProvider: Provider = {
|
|
601
|
+
provide: MODULE_OPTIONS_TOKEN,
|
|
602
|
+
useFactory: (
|
|
603
|
+
fromFactory: BatchAdaptersConfig | undefined,
|
|
604
|
+
): BatchAdaptersConfig | undefined => fromFactory,
|
|
605
|
+
inject: [OPTIONS_FACTORY],
|
|
606
|
+
};
|
|
607
|
+
|
|
608
|
+
return {
|
|
609
|
+
module: NestBatchModule,
|
|
610
|
+
global: true,
|
|
611
|
+
imports: [
|
|
612
|
+
...imports,
|
|
613
|
+
adapters.persistence.module,
|
|
614
|
+
adapters.transport.module,
|
|
615
|
+
DiscoveryModule,
|
|
616
|
+
],
|
|
617
|
+
providers: [
|
|
618
|
+
// Core classes (discovery + compile + register).
|
|
619
|
+
JobRegistry,
|
|
620
|
+
DefinitionCompiler,
|
|
621
|
+
BatchExplorer,
|
|
622
|
+
FlowEvaluator,
|
|
623
|
+
BatchScheduleRegistry,
|
|
624
|
+
BatchBootstrapper,
|
|
625
|
+
// Executor subgraph (JobExecutor → Chunk/Tasklet/Listener).
|
|
626
|
+
JobExecutor,
|
|
627
|
+
ChunkStepExecutor,
|
|
628
|
+
TaskletStepExecutor,
|
|
629
|
+
ListenerInvoker,
|
|
630
|
+
JobLauncher,
|
|
631
|
+
JobExplorer,
|
|
632
|
+
JobOperator,
|
|
633
|
+
BatchWorkerRunner,
|
|
634
|
+
{
|
|
635
|
+
provide: BATCH_SCHEDULE_REGISTRY,
|
|
636
|
+
useExisting: BatchScheduleRegistry,
|
|
637
|
+
},
|
|
638
|
+
// Adapter-supplied global providers (e.g. JobRepository
|
|
639
|
+
// / TransactionManager implementations).
|
|
640
|
+
...persistenceProviders,
|
|
641
|
+
...transportProviders,
|
|
642
|
+
// Sentinel factory + options provider (the async path).
|
|
643
|
+
factoryProvider,
|
|
644
|
+
optionsProvider,
|
|
645
|
+
],
|
|
646
|
+
exports: [
|
|
647
|
+
// Core classes.
|
|
648
|
+
JobRegistry,
|
|
649
|
+
DefinitionCompiler,
|
|
650
|
+
BatchExplorer,
|
|
651
|
+
FlowEvaluator,
|
|
652
|
+
BatchScheduleRegistry,
|
|
653
|
+
BatchBootstrapper,
|
|
654
|
+
// Tokens.
|
|
655
|
+
BATCH_SCHEDULE_REGISTRY,
|
|
656
|
+
MODULE_OPTIONS_TOKEN,
|
|
657
|
+
// Executor subgraph.
|
|
658
|
+
JobExecutor,
|
|
659
|
+
ChunkStepExecutor,
|
|
660
|
+
TaskletStepExecutor,
|
|
661
|
+
ListenerInvoker,
|
|
662
|
+
JobLauncher,
|
|
663
|
+
JobExplorer,
|
|
664
|
+
JobOperator,
|
|
665
|
+
BatchWorkerRunner,
|
|
666
|
+
// Adapter-supplied global providers — re-exported so the
|
|
667
|
+
// host can resolve the persistence + transport bindings
|
|
668
|
+
// from the global module chain.
|
|
669
|
+
...persistenceProviders,
|
|
670
|
+
...transportProviders,
|
|
671
|
+
],
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
}
|