@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,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reference built-in listeners — drop-in `Injectable` classes that mirror common
|
|
3
|
+
* batch lifecycle conventions (logging, metrics, timing). Each listener exposes
|
|
4
|
+
* the lifecycle methods consumed by `ListenerInvoker` and uses the canonical
|
|
5
|
+
* `ResolverMap` key format (`${phase}:${kind}:${name}`), so a user can simply
|
|
6
|
+
* instantiate one of these classes and register the bound methods under the
|
|
7
|
+
* desired phase/kind pairs.
|
|
8
|
+
*
|
|
9
|
+
* The classes are intentionally framework-agnostic — they do not depend on
|
|
10
|
+
* the execution pipeline, the `ResolverMap` shape, or any module wiring. They
|
|
11
|
+
* only depend on `@nestjs/common` for `Logger` / `Injectable`.
|
|
12
|
+
*/ "use strict";
|
|
13
|
+
Object.defineProperty(exports, "__esModule", {
|
|
14
|
+
value: true
|
|
15
|
+
});
|
|
16
|
+
function _export(target, all) {
|
|
17
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
_export(exports, {
|
|
23
|
+
get LoggingListener () {
|
|
24
|
+
return LoggingListener;
|
|
25
|
+
},
|
|
26
|
+
get MetricsListener () {
|
|
27
|
+
return MetricsListener;
|
|
28
|
+
},
|
|
29
|
+
get TimingListener () {
|
|
30
|
+
return TimingListener;
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
const _common = require("@nestjs/common");
|
|
34
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
35
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
36
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
37
|
+
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;
|
|
38
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
39
|
+
}
|
|
40
|
+
let LoggingListener = class LoggingListener {
|
|
41
|
+
logger = new _common.Logger(LoggingListener.name);
|
|
42
|
+
// -- Job -----------------------------------------------------------------
|
|
43
|
+
async beforeJob(ctx) {
|
|
44
|
+
this.logger.log(`Job ${ctx.jobExecutionId} starting`);
|
|
45
|
+
}
|
|
46
|
+
async afterJob(ctx, result) {
|
|
47
|
+
this.logger.log(`Job ${ctx.jobExecutionId} ${result.status}`);
|
|
48
|
+
}
|
|
49
|
+
// -- Step ----------------------------------------------------------------
|
|
50
|
+
async beforeStep(ctx) {
|
|
51
|
+
this.logger.log(`Step ${ctx.stepExecutionId} starting`);
|
|
52
|
+
}
|
|
53
|
+
async afterStep(ctx, result) {
|
|
54
|
+
this.logger.log(`Step ${ctx.stepExecutionId} ${result.status} (${result.exitCode})`);
|
|
55
|
+
}
|
|
56
|
+
// -- Skip ----------------------------------------------------------------
|
|
57
|
+
async onSkipInRead(err, item) {
|
|
58
|
+
this.logger.warn(`Skipped read: ${err.message} (item=${String(item)})`);
|
|
59
|
+
}
|
|
60
|
+
async onSkipInProcess(item, err) {
|
|
61
|
+
this.logger.warn(`Skipped process: ${err.message} (item=${String(item)})`);
|
|
62
|
+
}
|
|
63
|
+
async onSkipInWrite(items, err) {
|
|
64
|
+
this.logger.warn(`Skipped write of ${items.length} items: ${err.message}`);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
LoggingListener = _ts_decorate([
|
|
68
|
+
(0, _common.Injectable)()
|
|
69
|
+
], LoggingListener);
|
|
70
|
+
let MetricsListener = class MetricsListener {
|
|
71
|
+
stepCounts = new Map();
|
|
72
|
+
/**
|
|
73
|
+
* Store the counts reported by the step result. Missing fields default to 0
|
|
74
|
+
* so a partial result (e.g. a tasklet step that has no read/write/skip
|
|
75
|
+
* counts) does not pollute the metric with `NaN`/`undefined`.
|
|
76
|
+
*/ async afterStep(ctx, result) {
|
|
77
|
+
this.stepCounts.set(ctx.stepExecutionId, {
|
|
78
|
+
read: result.readCount ?? 0,
|
|
79
|
+
write: result.writeCount ?? 0,
|
|
80
|
+
skip: result.skipCount ?? 0
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
/** Returns the latest recorded counts for the given step, or `undefined` if
|
|
84
|
+
* the step has not been observed yet. */ getCounts(stepExecutionId) {
|
|
85
|
+
return this.stepCounts.get(stepExecutionId);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
MetricsListener = _ts_decorate([
|
|
89
|
+
(0, _common.Injectable)()
|
|
90
|
+
], MetricsListener);
|
|
91
|
+
let TimingListener = class TimingListener {
|
|
92
|
+
startTimes = new Map();
|
|
93
|
+
async beforeStep(ctx) {
|
|
94
|
+
this.startTimes.set(ctx.stepExecutionId, Date.now());
|
|
95
|
+
}
|
|
96
|
+
async afterStep(ctx) {
|
|
97
|
+
const start = this.startTimes.get(ctx.stepExecutionId);
|
|
98
|
+
if (start !== undefined) {
|
|
99
|
+
return Date.now() - start;
|
|
100
|
+
}
|
|
101
|
+
return 0;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
TimingListener = _ts_decorate([
|
|
105
|
+
(0, _common.Injectable)()
|
|
106
|
+
], TimingListener);
|
|
107
|
+
|
|
108
|
+
//# sourceMappingURL=builtin-listeners.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/listeners/builtin-listeners.ts"],"sourcesContent":["/**\n * Reference built-in listeners — drop-in `Injectable` classes that mirror common\n * batch lifecycle conventions (logging, metrics, timing). Each listener exposes\n * the lifecycle methods consumed by `ListenerInvoker` and uses the canonical\n * `ResolverMap` key format (`${phase}:${kind}:${name}`), so a user can simply\n * instantiate one of these classes and register the bound methods under the\n * desired phase/kind pairs.\n *\n * The classes are intentionally framework-agnostic — they do not depend on\n * the execution pipeline, the `ResolverMap` shape, or any module wiring. They\n * only depend on `@nestjs/common` for `Logger` / `Injectable`.\n */\nimport { Injectable, Logger } from '@nestjs/common';\n\n// ---------------------------------------------------------------------------\n// LoggingListener\n// ---------------------------------------------------------------------------\n\n/**\n * Emits a one-line `log` / `warn` entry for every lifecycle event. The method\n * names match the 7 `LifecyclePhaseKind` values plus the 3 `SkipSubKind`\n * variants, so callers can register any of them under a `ResolverMap` key\n * like `before:step:LoggingListener` and the invoker will dispatch correctly.\n */\n@Injectable()\nexport class LoggingListener {\n private readonly logger = new Logger(LoggingListener.name);\n\n // -- Job -----------------------------------------------------------------\n async beforeJob(ctx: { jobExecutionId: string }): Promise<void> {\n this.logger.log(`Job ${ctx.jobExecutionId} starting`);\n }\n\n async afterJob(\n ctx: { jobExecutionId: string },\n result: { status: string },\n ): Promise<void> {\n this.logger.log(`Job ${ctx.jobExecutionId} ${result.status}`);\n }\n\n // -- Step ----------------------------------------------------------------\n async beforeStep(ctx: {\n jobExecutionId: string;\n stepExecutionId: string;\n }): Promise<void> {\n this.logger.log(`Step ${ctx.stepExecutionId} starting`);\n }\n\n async afterStep(\n ctx: { jobExecutionId: string; stepExecutionId: string },\n result: { status: string; exitCode: string },\n ): Promise<void> {\n this.logger.log(\n `Step ${ctx.stepExecutionId} ${result.status} (${result.exitCode})`,\n );\n }\n\n // -- Skip ----------------------------------------------------------------\n async onSkipInRead(err: unknown, item: unknown): Promise<void> {\n this.logger.warn(\n `Skipped read: ${(err as Error).message} (item=${String(item)})`,\n );\n }\n\n async onSkipInProcess(item: unknown, err: unknown): Promise<void> {\n this.logger.warn(\n `Skipped process: ${(err as Error).message} (item=${String(item)})`,\n );\n }\n\n async onSkipInWrite(items: unknown[], err: unknown): Promise<void> {\n this.logger.warn(\n `Skipped write of ${items.length} items: ${(err as Error).message}`,\n );\n }\n}\n\n// ---------------------------------------------------------------------------\n// MetricsListener\n// ---------------------------------------------------------------------------\n\n/**\n * Per-step read / write / skip counters. The counts are keyed by\n * `stepExecutionId`, so multiple step executions within the same job are\n * tracked independently. Callers can read the latest counts via\n * `getCounts(stepExecutionId)`.\n */\n@Injectable()\nexport class MetricsListener {\n private readonly stepCounts = new Map<\n string,\n { read: number; write: number; skip: number }\n >();\n\n /**\n * Store the counts reported by the step result. Missing fields default to 0\n * so a partial result (e.g. a tasklet step that has no read/write/skip\n * counts) does not pollute the metric with `NaN`/`undefined`.\n */\n async afterStep(\n ctx: { stepExecutionId: string },\n result: {\n readCount?: number;\n writeCount?: number;\n skipCount?: number;\n status: string;\n },\n ): Promise<void> {\n this.stepCounts.set(ctx.stepExecutionId, {\n read: result.readCount ?? 0,\n write: result.writeCount ?? 0,\n skip: result.skipCount ?? 0,\n });\n }\n\n /** Returns the latest recorded counts for the given step, or `undefined` if\n * the step has not been observed yet. */\n getCounts(\n stepExecutionId: string,\n ): { read: number; write: number; skip: number } | undefined {\n return this.stepCounts.get(stepExecutionId);\n }\n}\n\n// ---------------------------------------------------------------------------\n// TimingListener\n// ---------------------------------------------------------------------------\n\n/**\n * Records the wall-clock duration of each step. `beforeStep` captures\n * `Date.now()`; `afterStep` returns the elapsed milliseconds (or 0 if no\n * matching `beforeStep` was observed — this keeps the listener idempotent\n * even when invoked out of order, e.g. after a process restart that replayed\n * a partial log).\n */\n@Injectable()\nexport class TimingListener {\n private readonly startTimes = new Map<string, number>();\n\n async beforeStep(ctx: { stepExecutionId: string }): Promise<void> {\n this.startTimes.set(ctx.stepExecutionId, Date.now());\n }\n\n async afterStep(ctx: { stepExecutionId: string }): Promise<number> {\n const start = this.startTimes.get(ctx.stepExecutionId);\n if (start !== undefined) {\n return Date.now() - start;\n }\n return 0;\n }\n}\n"],"names":["LoggingListener","MetricsListener","TimingListener","logger","Logger","name","beforeJob","ctx","log","jobExecutionId","afterJob","result","status","beforeStep","stepExecutionId","afterStep","exitCode","onSkipInRead","err","item","warn","message","String","onSkipInProcess","onSkipInWrite","items","length","stepCounts","Map","set","read","readCount","write","writeCount","skip","skipCount","getCounts","get","startTimes","Date","now","start","undefined"],"mappings":"AAAA;;;;;;;;;;;CAWC;;;;;;;;;;;QAcYA;eAAAA;;QA+DAC;eAAAA;;QAgDAC;eAAAA;;;wBA5HsB;;;;;;;AAa5B,IAAA,AAAMF,kBAAN,MAAMA;IACMG,SAAS,IAAIC,cAAM,CAACJ,gBAAgBK,IAAI,EAAE;IAE3D,2EAA2E;IAC3E,MAAMC,UAAUC,GAA+B,EAAiB;QAC9D,IAAI,CAACJ,MAAM,CAACK,GAAG,CAAC,CAAC,IAAI,EAAED,IAAIE,cAAc,CAAC,SAAS,CAAC;IACtD;IAEA,MAAMC,SACJH,GAA+B,EAC/BI,MAA0B,EACX;QACf,IAAI,CAACR,MAAM,CAACK,GAAG,CAAC,CAAC,IAAI,EAAED,IAAIE,cAAc,CAAC,CAAC,EAAEE,OAAOC,MAAM,EAAE;IAC9D;IAEA,2EAA2E;IAC3E,MAAMC,WAAWN,GAGhB,EAAiB;QAChB,IAAI,CAACJ,MAAM,CAACK,GAAG,CAAC,CAAC,KAAK,EAAED,IAAIO,eAAe,CAAC,SAAS,CAAC;IACxD;IAEA,MAAMC,UACJR,GAAwD,EACxDI,MAA4C,EAC7B;QACf,IAAI,CAACR,MAAM,CAACK,GAAG,CACb,CAAC,KAAK,EAAED,IAAIO,eAAe,CAAC,CAAC,EAAEH,OAAOC,MAAM,CAAC,EAAE,EAAED,OAAOK,QAAQ,CAAC,CAAC,CAAC;IAEvE;IAEA,2EAA2E;IAC3E,MAAMC,aAAaC,GAAY,EAAEC,IAAa,EAAiB;QAC7D,IAAI,CAAChB,MAAM,CAACiB,IAAI,CACd,CAAC,cAAc,EAAE,AAACF,IAAcG,OAAO,CAAC,OAAO,EAAEC,OAAOH,MAAM,CAAC,CAAC;IAEpE;IAEA,MAAMI,gBAAgBJ,IAAa,EAAED,GAAY,EAAiB;QAChE,IAAI,CAACf,MAAM,CAACiB,IAAI,CACd,CAAC,iBAAiB,EAAE,AAACF,IAAcG,OAAO,CAAC,OAAO,EAAEC,OAAOH,MAAM,CAAC,CAAC;IAEvE;IAEA,MAAMK,cAAcC,KAAgB,EAAEP,GAAY,EAAiB;QACjE,IAAI,CAACf,MAAM,CAACiB,IAAI,CACd,CAAC,iBAAiB,EAAEK,MAAMC,MAAM,CAAC,QAAQ,EAAE,AAACR,IAAcG,OAAO,EAAE;IAEvE;AACF;;;;AAaO,IAAA,AAAMpB,kBAAN,MAAMA;IACM0B,aAAa,IAAIC,MAG9B;IAEJ;;;;GAIC,GACD,MAAMb,UACJR,GAAgC,EAChCI,MAKC,EACc;QACf,IAAI,CAACgB,UAAU,CAACE,GAAG,CAACtB,IAAIO,eAAe,EAAE;YACvCgB,MAAMnB,OAAOoB,SAAS,IAAI;YAC1BC,OAAOrB,OAAOsB,UAAU,IAAI;YAC5BC,MAAMvB,OAAOwB,SAAS,IAAI;QAC5B;IACF;IAEA;0CACwC,GACxCC,UACEtB,eAAuB,EACoC;QAC3D,OAAO,IAAI,CAACa,UAAU,CAACU,GAAG,CAACvB;IAC7B;AACF;;;;AAcO,IAAA,AAAMZ,iBAAN,MAAMA;IACMoC,aAAa,IAAIV,MAAsB;IAExD,MAAMf,WAAWN,GAAgC,EAAiB;QAChE,IAAI,CAAC+B,UAAU,CAACT,GAAG,CAACtB,IAAIO,eAAe,EAAEyB,KAAKC,GAAG;IACnD;IAEA,MAAMzB,UAAUR,GAAgC,EAAmB;QACjE,MAAMkC,QAAQ,IAAI,CAACH,UAAU,CAACD,GAAG,CAAC9B,IAAIO,eAAe;QACrD,IAAI2B,UAAUC,WAAW;YACvB,OAAOH,KAAKC,GAAG,KAAKC;QACtB;QACA,OAAO;IACT;AACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public surface for the reference built-in listeners.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports `LoggingListener`, `MetricsListener`, and `TimingListener` so
|
|
5
|
+
* consumers can do `import { LoggingListener } from '@nest-batch/core'`.
|
|
6
|
+
*/
|
|
7
|
+
export * from './builtin-listeners';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/listeners/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public surface for the reference built-in listeners.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports `LoggingListener`, `MetricsListener`, and `TimingListener` so
|
|
5
|
+
* consumers can do `import { LoggingListener } from '@nest-batch/core'`.
|
|
6
|
+
*/ "use strict";
|
|
7
|
+
Object.defineProperty(exports, "__esModule", {
|
|
8
|
+
value: true
|
|
9
|
+
});
|
|
10
|
+
_export_star(require("./builtin-listeners"), exports);
|
|
11
|
+
function _export_star(from, to) {
|
|
12
|
+
Object.keys(from).forEach(function(k) {
|
|
13
|
+
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
|
|
14
|
+
Object.defineProperty(to, k, {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function() {
|
|
17
|
+
return from[k];
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
return from;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/listeners/index.ts"],"sourcesContent":["/**\n * Public surface for the reference built-in listeners.\n *\n * Re-exports `LoggingListener`, `MetricsListener`, and `TimingListener` so\n * consumers can do `import { LoggingListener } from '@nest-batch/core'`.\n */\nexport * from './builtin-listeners';\n"],"names":[],"mappings":"AAAA;;;;;CAKC;;;;qBACa"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `AdapterOptions` — the common options bag that sibling adapter
|
|
3
|
+
* packages extend.
|
|
4
|
+
*
|
|
5
|
+
* Sibling packages (e.g. `@nest-batch/mikro-orm`, `@nest-batch/typeorm`,
|
|
6
|
+
* `@nest-batch/bullmq`) extend this interface with their own fields:
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* // in @nest-batch/mikro-orm
|
|
10
|
+
* export interface MikroOrmAdapterOptions extends AdapterOptions {
|
|
11
|
+
* contextName?: string;
|
|
12
|
+
* entities?: EntityClass[];
|
|
13
|
+
* }
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* The host app then passes the union into `NestBatchModule.forRoot({ ...
|
|
17
|
+
* <adapterFields> })`. The core module preserves every field in the
|
|
18
|
+
* `MODULE_OPTIONS_TOKEN` provider so the adapter can read it back out
|
|
19
|
+
* via `Inject(MODULE_OPTIONS_TOKEN)`.
|
|
20
|
+
*
|
|
21
|
+
* Why a structural shape (`Record<string, unknown>`) and not a closed
|
|
22
|
+
* interface with no fields?
|
|
23
|
+
* - Lets adapters extend with their own fields without forcing core
|
|
24
|
+
* to ship a `Pick<...>` per adapter.
|
|
25
|
+
* - The runtime check is intentionally permissive: core is
|
|
26
|
+
* dependency-light and does not know which adapters exist.
|
|
27
|
+
* - TypeScript users still get end-to-end type safety through
|
|
28
|
+
* declaration merging / interface extension on the adapter side.
|
|
29
|
+
*/
|
|
30
|
+
export interface AdapterOptions {
|
|
31
|
+
/**
|
|
32
|
+
* Reserved for forward compatibility. Concrete adapters are
|
|
33
|
+
* encouraged to declare their own extension interface and re-declare
|
|
34
|
+
* this with a more specific type so `useFactory` return values are
|
|
35
|
+
* type-checked end-to-end.
|
|
36
|
+
*/
|
|
37
|
+
readonly [key: string]: unknown;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=adapter-options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-options.d.ts","sourceRoot":"","sources":["../../../src/module/adapter-options.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;OAKG;IACH,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `AdapterOptions` — the common options bag that sibling adapter
|
|
3
|
+
* packages extend.
|
|
4
|
+
*
|
|
5
|
+
* Sibling packages (e.g. `@nest-batch/mikro-orm`, `@nest-batch/typeorm`,
|
|
6
|
+
* `@nest-batch/bullmq`) extend this interface with their own fields:
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* // in @nest-batch/mikro-orm
|
|
10
|
+
* export interface MikroOrmAdapterOptions extends AdapterOptions {
|
|
11
|
+
* contextName?: string;
|
|
12
|
+
* entities?: EntityClass[];
|
|
13
|
+
* }
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* The host app then passes the union into `NestBatchModule.forRoot({ ...
|
|
17
|
+
* <adapterFields> })`. The core module preserves every field in the
|
|
18
|
+
* `MODULE_OPTIONS_TOKEN` provider so the adapter can read it back out
|
|
19
|
+
* via `Inject(MODULE_OPTIONS_TOKEN)`.
|
|
20
|
+
*
|
|
21
|
+
* Why a structural shape (`Record<string, unknown>`) and not a closed
|
|
22
|
+
* interface with no fields?
|
|
23
|
+
* - Lets adapters extend with their own fields without forcing core
|
|
24
|
+
* to ship a `Pick<...>` per adapter.
|
|
25
|
+
* - The runtime check is intentionally permissive: core is
|
|
26
|
+
* dependency-light and does not know which adapters exist.
|
|
27
|
+
* - TypeScript users still get end-to-end type safety through
|
|
28
|
+
* declaration merging / interface extension on the adapter side.
|
|
29
|
+
*/ "use strict";
|
|
30
|
+
Object.defineProperty(exports, "__esModule", {
|
|
31
|
+
value: true
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=adapter-options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/module/adapter-options.ts"],"sourcesContent":["/**\n * `AdapterOptions` — the common options bag that sibling adapter\n * packages extend.\n *\n * Sibling packages (e.g. `@nest-batch/mikro-orm`, `@nest-batch/typeorm`,\n * `@nest-batch/bullmq`) extend this interface with their own fields:\n *\n * ```ts\n * // in @nest-batch/mikro-orm\n * export interface MikroOrmAdapterOptions extends AdapterOptions {\n * contextName?: string;\n * entities?: EntityClass[];\n * }\n * ```\n *\n * The host app then passes the union into `NestBatchModule.forRoot({ ...\n * <adapterFields> })`. The core module preserves every field in the\n * `MODULE_OPTIONS_TOKEN` provider so the adapter can read it back out\n * via `Inject(MODULE_OPTIONS_TOKEN)`.\n *\n * Why a structural shape (`Record<string, unknown>`) and not a closed\n * interface with no fields?\n * - Lets adapters extend with their own fields without forcing core\n * to ship a `Pick<...>` per adapter.\n * - The runtime check is intentionally permissive: core is\n * dependency-light and does not know which adapters exist.\n * - TypeScript users still get end-to-end type safety through\n * declaration merging / interface extension on the adapter side.\n */\nexport interface AdapterOptions {\n /**\n * Reserved for forward compatibility. Concrete adapters are\n * encouraged to declare their own extension interface and re-declare\n * this with a more specific type so `useFactory` return values are\n * type-checked end-to-end.\n */\n readonly [key: string]: unknown;\n}\n"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BC"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `BatchAdapter` — the type contract every sibling adapter package
|
|
3
|
+
* implements to plug into `@nest-batch/core`.
|
|
4
|
+
*
|
|
5
|
+
* An adapter is a *self-contained* bundle of Nest providers for one of
|
|
6
|
+
* the two concerns core delegates:
|
|
7
|
+
*
|
|
8
|
+
* - `persistence` — the `JobRepository` + `TransactionManager`
|
|
9
|
+
* bindings plus the storage meta tables (e.g.
|
|
10
|
+
* `@nest-batch/mikro-orm`, `@nest-batch/typeorm`).
|
|
11
|
+
* - `transport` — the `IExecutionStrategy` binding for a queue
|
|
12
|
+
* runtime plus the transport's lifecycle (workers, schedulers,
|
|
13
|
+
* event bridges — e.g. `@nest-batch/bullmq`).
|
|
14
|
+
*
|
|
15
|
+
* The two slots are required (the type encodes that), and core
|
|
16
|
+
* imports both at module-build time — adapters never talk to each
|
|
17
|
+
* other directly, they go through core.
|
|
18
|
+
*
|
|
19
|
+
* Shape contract:
|
|
20
|
+
*
|
|
21
|
+
* - `name` — a stable, human-readable identifier
|
|
22
|
+
* (`'mikro-orm'`, `'bullmq'`, ...). Used in logs, in the
|
|
23
|
+
* resolved options bag under `MODULE_OPTIONS_TOKEN`, and as the
|
|
24
|
+
* key for any per-adapter DI registration. Treat it as the
|
|
25
|
+
* package's public name; changing it is a breaking change.
|
|
26
|
+
*
|
|
27
|
+
* - `module` — a Nest `DynamicModule` that core will
|
|
28
|
+
* `import` as part of building `NestBatchModule`. The adapter
|
|
29
|
+
* owns the module — it can be a class with a static factory
|
|
30
|
+
* (e.g. `MikroOrmAdapter.forRoot({ ... })`) or a plain
|
|
31
|
+
* `DynamicModule` literal. Core treats it as opaque and only
|
|
32
|
+
* forwards it to the `imports` array. The adapter is responsible
|
|
33
|
+
* for the module being self-contained (its own `imports`,
|
|
34
|
+
* `providers`, and `exports`).
|
|
35
|
+
*
|
|
36
|
+
* - `globalProviders` — *optional* list of Nest `Provider` records
|
|
37
|
+
* core will register into its own DI scope and re-export. The
|
|
38
|
+
* use case is runtime classes (e.g. `JobExecutor`,
|
|
39
|
+
* `InProcessExecutionStrategy`) that the adapter's own module
|
|
40
|
+
* needs to inject but that the host app should also be able to
|
|
41
|
+
* inject. Without this re-export, Nest's module encapsulation
|
|
42
|
+
* hides those providers from anyone outside the adapter's
|
|
43
|
+
* module. If the adapter does not need any host-visible
|
|
44
|
+
* providers, omit the field — core treats `undefined` and `[]`
|
|
45
|
+
* identically.
|
|
46
|
+
*
|
|
47
|
+
* The adapter is *purely* a DI bundle. It does not run any code at
|
|
48
|
+
* module-build time (other than what Nest does when it processes the
|
|
49
|
+
* `DynamicModule`). Wiring, lifecycle, and runtime behaviour are
|
|
50
|
+
* the adapter's responsibility — core's job is to import the
|
|
51
|
+
* `module` and merge the `globalProviders` into its own provider
|
|
52
|
+
* list.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* // packages/mikro-orm — typical persistence adapter
|
|
57
|
+
* export class MikroOrmAdapter {
|
|
58
|
+
* static forRoot(): BatchAdapter {
|
|
59
|
+
* return {
|
|
60
|
+
* name: 'mikro-orm' as const,
|
|
61
|
+
* module: {
|
|
62
|
+
* module: MikroOrmBatchModule,
|
|
63
|
+
* global: true,
|
|
64
|
+
* providers: [MikroORMJobRepository, MikroORMTransactionManager],
|
|
65
|
+
* exports: [JOB_REPOSITORY_TOKEN, TRANSACTION_MANAGER_TOKEN],
|
|
66
|
+
* },
|
|
67
|
+
* globalProviders: [
|
|
68
|
+
* { provide: JOB_REPOSITORY_TOKEN, useClass: MikroORMJobRepository },
|
|
69
|
+
* { provide: TRANSACTION_MANAGER_TOKEN, useClass: MikroORMTransactionManager },
|
|
70
|
+
* ],
|
|
71
|
+
* };
|
|
72
|
+
* }
|
|
73
|
+
* }
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
import type { DynamicModule, Provider } from '@nestjs/common';
|
|
77
|
+
/**
|
|
78
|
+
* A single adapter bundle.
|
|
79
|
+
*
|
|
80
|
+
* See the {@link BatchAdapter} module-level JSDoc for the full
|
|
81
|
+
* contract. The interface is closed (no `[key: string]: unknown`
|
|
82
|
+
* index signature) because every adapter is a deliberate
|
|
83
|
+
* implementation of one of the two well-known roles
|
|
84
|
+
* (`persistence` / `transport`); sibling packages cannot extend it
|
|
85
|
+
* with extra fields.
|
|
86
|
+
*/
|
|
87
|
+
export interface BatchAdapter {
|
|
88
|
+
/** Stable identifier for the adapter (e.g. `'mikro-orm'`, `'bullmq'`). */
|
|
89
|
+
readonly name: string;
|
|
90
|
+
/**
|
|
91
|
+
* The `DynamicModule` core will import when building
|
|
92
|
+
* `NestBatchModule`. The adapter owns this module — it can be a
|
|
93
|
+
* `forRoot({ ... })` result, a `forRootAsync({ ... })` result, or
|
|
94
|
+
* a plain `DynamicModule` literal.
|
|
95
|
+
*/
|
|
96
|
+
readonly module: DynamicModule;
|
|
97
|
+
/**
|
|
98
|
+
* Optional list of Nest `Provider` records core will register
|
|
99
|
+
* into its own DI scope and re-export. Use this for runtime
|
|
100
|
+
* classes the adapter's own module needs to inject but that the
|
|
101
|
+
* host app should also be able to inject. Omit (or return `[]`)
|
|
102
|
+
* when the adapter has no host-visible providers.
|
|
103
|
+
*/
|
|
104
|
+
readonly globalProviders?: readonly Provider[];
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* The full adapter configuration core requires to build a working
|
|
108
|
+
* batch engine.
|
|
109
|
+
*
|
|
110
|
+
* Both keys are **required**: every deployment must pick one
|
|
111
|
+
* persistence adapter and one transport adapter. There is no
|
|
112
|
+
* implicit default — even the in-process transport ships as a
|
|
113
|
+
* dedicated `BatchAdapter` (T4) so the choice is explicit at the
|
|
114
|
+
* call site and the host's `AppModule` reads as a complete wiring
|
|
115
|
+
* recipe.
|
|
116
|
+
*
|
|
117
|
+
* Why is the shape closed (`persistence` + `transport` and nothing
|
|
118
|
+
* else) and not an open record?
|
|
119
|
+
* - The two slots are the only concerns core delegates. There is
|
|
120
|
+
* no third concern today, and adding one would be a breaking
|
|
121
|
+
* change by design.
|
|
122
|
+
* - A closed shape lets the compiler catch a missing adapter at
|
|
123
|
+
* `forRoot({ adapters: { ... } })` time — the host cannot
|
|
124
|
+
* accidentally boot a `NestBatchModule` without a persistence
|
|
125
|
+
* binding or a transport binding.
|
|
126
|
+
* - The `as const satisfies` pattern keeps the adapter's
|
|
127
|
+
* `name` narrowed to a literal type when the adapter defines
|
|
128
|
+
* it inline, which simplifies log filtering and config
|
|
129
|
+
* round-tripping.
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```ts
|
|
133
|
+
* @Module({
|
|
134
|
+
* imports: [
|
|
135
|
+
* MikroOrmModule.forRoot({
|
|
136
|
+
* entities: [ProductEntity, ...BATCH_META_ENTITIES],
|
|
137
|
+
* dbName: process.env.DB_NAME,
|
|
138
|
+
* // ...host-owned MikroORM options
|
|
139
|
+
* }),
|
|
140
|
+
* NestBatchModule.forRoot({
|
|
141
|
+
* adapters: {
|
|
142
|
+
* persistence: MikroOrmAdapter.forRoot(),
|
|
143
|
+
* transport: InProcessAdapter.forRoot(),
|
|
144
|
+
* },
|
|
145
|
+
* }),
|
|
146
|
+
* ],
|
|
147
|
+
* })
|
|
148
|
+
* class AppModule {}
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
export type BatchAdaptersConfig = {
|
|
152
|
+
/** Adapter that owns the `JobRepository` + `TransactionManager` bindings. */
|
|
153
|
+
readonly persistence: BatchAdapter;
|
|
154
|
+
/** Adapter that owns the `IExecutionStrategy` (transport) binding. */
|
|
155
|
+
readonly transport: BatchAdapter;
|
|
156
|
+
};
|
|
157
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/module/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0EG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE9D;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAY;IAC3B,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAE/B;;;;;;OAMG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;CAChD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,6EAA6E;IAC7E,QAAQ,CAAC,WAAW,EAAE,YAAY,CAAC;IACnC,sEAAsE;IACtE,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;CAClC,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `BatchAdapter` — the type contract every sibling adapter package
|
|
3
|
+
* implements to plug into `@nest-batch/core`.
|
|
4
|
+
*
|
|
5
|
+
* An adapter is a *self-contained* bundle of Nest providers for one of
|
|
6
|
+
* the two concerns core delegates:
|
|
7
|
+
*
|
|
8
|
+
* - `persistence` — the `JobRepository` + `TransactionManager`
|
|
9
|
+
* bindings plus the storage meta tables (e.g.
|
|
10
|
+
* `@nest-batch/mikro-orm`, `@nest-batch/typeorm`).
|
|
11
|
+
* - `transport` — the `IExecutionStrategy` binding for a queue
|
|
12
|
+
* runtime plus the transport's lifecycle (workers, schedulers,
|
|
13
|
+
* event bridges — e.g. `@nest-batch/bullmq`).
|
|
14
|
+
*
|
|
15
|
+
* The two slots are required (the type encodes that), and core
|
|
16
|
+
* imports both at module-build time — adapters never talk to each
|
|
17
|
+
* other directly, they go through core.
|
|
18
|
+
*
|
|
19
|
+
* Shape contract:
|
|
20
|
+
*
|
|
21
|
+
* - `name` — a stable, human-readable identifier
|
|
22
|
+
* (`'mikro-orm'`, `'bullmq'`, ...). Used in logs, in the
|
|
23
|
+
* resolved options bag under `MODULE_OPTIONS_TOKEN`, and as the
|
|
24
|
+
* key for any per-adapter DI registration. Treat it as the
|
|
25
|
+
* package's public name; changing it is a breaking change.
|
|
26
|
+
*
|
|
27
|
+
* - `module` — a Nest `DynamicModule` that core will
|
|
28
|
+
* `import` as part of building `NestBatchModule`. The adapter
|
|
29
|
+
* owns the module — it can be a class with a static factory
|
|
30
|
+
* (e.g. `MikroOrmAdapter.forRoot({ ... })`) or a plain
|
|
31
|
+
* `DynamicModule` literal. Core treats it as opaque and only
|
|
32
|
+
* forwards it to the `imports` array. The adapter is responsible
|
|
33
|
+
* for the module being self-contained (its own `imports`,
|
|
34
|
+
* `providers`, and `exports`).
|
|
35
|
+
*
|
|
36
|
+
* - `globalProviders` — *optional* list of Nest `Provider` records
|
|
37
|
+
* core will register into its own DI scope and re-export. The
|
|
38
|
+
* use case is runtime classes (e.g. `JobExecutor`,
|
|
39
|
+
* `InProcessExecutionStrategy`) that the adapter's own module
|
|
40
|
+
* needs to inject but that the host app should also be able to
|
|
41
|
+
* inject. Without this re-export, Nest's module encapsulation
|
|
42
|
+
* hides those providers from anyone outside the adapter's
|
|
43
|
+
* module. If the adapter does not need any host-visible
|
|
44
|
+
* providers, omit the field — core treats `undefined` and `[]`
|
|
45
|
+
* identically.
|
|
46
|
+
*
|
|
47
|
+
* The adapter is *purely* a DI bundle. It does not run any code at
|
|
48
|
+
* module-build time (other than what Nest does when it processes the
|
|
49
|
+
* `DynamicModule`). Wiring, lifecycle, and runtime behaviour are
|
|
50
|
+
* the adapter's responsibility — core's job is to import the
|
|
51
|
+
* `module` and merge the `globalProviders` into its own provider
|
|
52
|
+
* list.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* // packages/mikro-orm — typical persistence adapter
|
|
57
|
+
* export class MikroOrmAdapter {
|
|
58
|
+
* static forRoot(): BatchAdapter {
|
|
59
|
+
* return {
|
|
60
|
+
* name: 'mikro-orm' as const,
|
|
61
|
+
* module: {
|
|
62
|
+
* module: MikroOrmBatchModule,
|
|
63
|
+
* global: true,
|
|
64
|
+
* providers: [MikroORMJobRepository, MikroORMTransactionManager],
|
|
65
|
+
* exports: [JOB_REPOSITORY_TOKEN, TRANSACTION_MANAGER_TOKEN],
|
|
66
|
+
* },
|
|
67
|
+
* globalProviders: [
|
|
68
|
+
* { provide: JOB_REPOSITORY_TOKEN, useClass: MikroORMJobRepository },
|
|
69
|
+
* { provide: TRANSACTION_MANAGER_TOKEN, useClass: MikroORMTransactionManager },
|
|
70
|
+
* ],
|
|
71
|
+
* };
|
|
72
|
+
* }
|
|
73
|
+
* }
|
|
74
|
+
* ```
|
|
75
|
+
*/ "use strict";
|
|
76
|
+
Object.defineProperty(exports, "__esModule", {
|
|
77
|
+
value: true
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/module/adapter.ts"],"sourcesContent":["/**\n * `BatchAdapter` — the type contract every sibling adapter package\n * implements to plug into `@nest-batch/core`.\n *\n * An adapter is a *self-contained* bundle of Nest providers for one of\n * the two concerns core delegates:\n *\n * - `persistence` — the `JobRepository` + `TransactionManager`\n * bindings plus the storage meta tables (e.g.\n * `@nest-batch/mikro-orm`, `@nest-batch/typeorm`).\n * - `transport` — the `IExecutionStrategy` binding for a queue\n * runtime plus the transport's lifecycle (workers, schedulers,\n * event bridges — e.g. `@nest-batch/bullmq`).\n *\n * The two slots are required (the type encodes that), and core\n * imports both at module-build time — adapters never talk to each\n * other directly, they go through core.\n *\n * Shape contract:\n *\n * - `name` — a stable, human-readable identifier\n * (`'mikro-orm'`, `'bullmq'`, ...). Used in logs, in the\n * resolved options bag under `MODULE_OPTIONS_TOKEN`, and as the\n * key for any per-adapter DI registration. Treat it as the\n * package's public name; changing it is a breaking change.\n *\n * - `module` — a Nest `DynamicModule` that core will\n * `import` as part of building `NestBatchModule`. The adapter\n * owns the module — it can be a class with a static factory\n * (e.g. `MikroOrmAdapter.forRoot({ ... })`) or a plain\n * `DynamicModule` literal. Core treats it as opaque and only\n * forwards it to the `imports` array. The adapter is responsible\n * for the module being self-contained (its own `imports`,\n * `providers`, and `exports`).\n *\n * - `globalProviders` — *optional* list of Nest `Provider` records\n * core will register into its own DI scope and re-export. The\n * use case is runtime classes (e.g. `JobExecutor`,\n * `InProcessExecutionStrategy`) that the adapter's own module\n * needs to inject but that the host app should also be able to\n * inject. Without this re-export, Nest's module encapsulation\n * hides those providers from anyone outside the adapter's\n * module. If the adapter does not need any host-visible\n * providers, omit the field — core treats `undefined` and `[]`\n * identically.\n *\n * The adapter is *purely* a DI bundle. It does not run any code at\n * module-build time (other than what Nest does when it processes the\n * `DynamicModule`). Wiring, lifecycle, and runtime behaviour are\n * the adapter's responsibility — core's job is to import the\n * `module` and merge the `globalProviders` into its own provider\n * list.\n *\n * @example\n * ```ts\n * // packages/mikro-orm — typical persistence adapter\n * export class MikroOrmAdapter {\n * static forRoot(): BatchAdapter {\n * return {\n * name: 'mikro-orm' as const,\n * module: {\n * module: MikroOrmBatchModule,\n * global: true,\n * providers: [MikroORMJobRepository, MikroORMTransactionManager],\n * exports: [JOB_REPOSITORY_TOKEN, TRANSACTION_MANAGER_TOKEN],\n * },\n * globalProviders: [\n * { provide: JOB_REPOSITORY_TOKEN, useClass: MikroORMJobRepository },\n * { provide: TRANSACTION_MANAGER_TOKEN, useClass: MikroORMTransactionManager },\n * ],\n * };\n * }\n * }\n * ```\n */\nimport type { DynamicModule, Provider } from '@nestjs/common';\n\n/**\n * A single adapter bundle.\n *\n * See the {@link BatchAdapter} module-level JSDoc for the full\n * contract. The interface is closed (no `[key: string]: unknown`\n * index signature) because every adapter is a deliberate\n * implementation of one of the two well-known roles\n * (`persistence` / `transport`); sibling packages cannot extend it\n * with extra fields.\n */\nexport interface BatchAdapter {\n /** Stable identifier for the adapter (e.g. `'mikro-orm'`, `'bullmq'`). */\n readonly name: string;\n\n /**\n * The `DynamicModule` core will import when building\n * `NestBatchModule`. The adapter owns this module — it can be a\n * `forRoot({ ... })` result, a `forRootAsync({ ... })` result, or\n * a plain `DynamicModule` literal.\n */\n readonly module: DynamicModule;\n\n /**\n * Optional list of Nest `Provider` records core will register\n * into its own DI scope and re-export. Use this for runtime\n * classes the adapter's own module needs to inject but that the\n * host app should also be able to inject. Omit (or return `[]`)\n * when the adapter has no host-visible providers.\n */\n readonly globalProviders?: readonly Provider[];\n}\n\n/**\n * The full adapter configuration core requires to build a working\n * batch engine.\n *\n * Both keys are **required**: every deployment must pick one\n * persistence adapter and one transport adapter. There is no\n * implicit default — even the in-process transport ships as a\n * dedicated `BatchAdapter` (T4) so the choice is explicit at the\n * call site and the host's `AppModule` reads as a complete wiring\n * recipe.\n *\n * Why is the shape closed (`persistence` + `transport` and nothing\n * else) and not an open record?\n * - The two slots are the only concerns core delegates. There is\n * no third concern today, and adding one would be a breaking\n * change by design.\n * - A closed shape lets the compiler catch a missing adapter at\n * `forRoot({ adapters: { ... } })` time — the host cannot\n * accidentally boot a `NestBatchModule` without a persistence\n * binding or a transport binding.\n * - The `as const satisfies` pattern keeps the adapter's\n * `name` narrowed to a literal type when the adapter defines\n * it inline, which simplifies log filtering and config\n * round-tripping.\n *\n * @example\n * ```ts\n * @Module({\n * imports: [\n * MikroOrmModule.forRoot({\n * entities: [ProductEntity, ...BATCH_META_ENTITIES],\n * dbName: process.env.DB_NAME,\n * // ...host-owned MikroORM options\n * }),\n * NestBatchModule.forRoot({\n * adapters: {\n * persistence: MikroOrmAdapter.forRoot(),\n * transport: InProcessAdapter.forRoot(),\n * },\n * }),\n * ],\n * })\n * class AppModule {}\n * ```\n */\nexport type BatchAdaptersConfig = {\n /** Adapter that owns the `JobRepository` + `TransactionManager` bindings. */\n readonly persistence: BatchAdapter;\n /** Adapter that owns the `IExecutionStrategy` (transport) binding. */\n readonly transport: BatchAdapter;\n};\n"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0EC"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { BatchOverlapPolicy } from '../scheduling/batch-scheduled';
|
|
2
|
+
/**
|
|
3
|
+
* A single entry recorded in the `BatchScheduleRegistry`.
|
|
4
|
+
*
|
|
5
|
+
* The registry is the contract surface between the
|
|
6
|
+
* discovery-time metadata (stamped by the `@BatchScheduled` decorator
|
|
7
|
+
* and collected by `BatchExplorer`) and the future runtime scheduler
|
|
8
|
+
* (the `@nest-batch/bullmq` cron strategy, or a sibling scheduling
|
|
9
|
+
* package). Today the registry is populated by the explorer; tomorrow
|
|
10
|
+
* the runtime scheduler reads from it.
|
|
11
|
+
*
|
|
12
|
+
* `inert` is captured at decoration time from
|
|
13
|
+
* `process.env.BATCH_SCHEDULED_DISABLE` and is preserved on the entry
|
|
14
|
+
* verbatim so the runtime scheduler can decide whether to install a
|
|
15
|
+
* real timer. The decorator does NOT inspect the env at runtime
|
|
16
|
+
* scheduling time — the registry carries the resolved value.
|
|
17
|
+
*/
|
|
18
|
+
export interface BatchScheduleEntry {
|
|
19
|
+
/** The `@Jobable({ id })` value of the host class. */
|
|
20
|
+
readonly jobId: string;
|
|
21
|
+
/** The method name on the host class that carries `@BatchScheduled`. */
|
|
22
|
+
readonly methodName: string;
|
|
23
|
+
/** The cron expression supplied to the decorator, verbatim. */
|
|
24
|
+
readonly cron: string;
|
|
25
|
+
/** IANA timezone, as supplied to the decorator. */
|
|
26
|
+
readonly timezone: string;
|
|
27
|
+
/** Overlap policy. `undefined` means the runtime applies its default. */
|
|
28
|
+
readonly overlap?: BatchOverlapPolicy;
|
|
29
|
+
/** Absolute lower bound (optional). */
|
|
30
|
+
readonly startAt?: Date;
|
|
31
|
+
/** Absolute upper bound (optional). */
|
|
32
|
+
readonly endAt?: Date;
|
|
33
|
+
/**
|
|
34
|
+
* Captured at decoration time from
|
|
35
|
+
* `process.env.BATCH_SCHEDULED_DISABLE`. `true` is a hint to the
|
|
36
|
+
* runtime scheduler to skip installing a real timer.
|
|
37
|
+
*/
|
|
38
|
+
readonly inert: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* `BatchScheduleRegistry` — in-memory map of `@BatchScheduled`
|
|
42
|
+
* metadata discovered at bootstrap.
|
|
43
|
+
*
|
|
44
|
+
* Lifecycle:
|
|
45
|
+
* 1. The registry is constructed once at module init (Nest DI
|
|
46
|
+
* singleton).
|
|
47
|
+
* 2. `BatchExplorer.onModuleInit` walks every provider, and
|
|
48
|
+
* `BatchBootstrapper.onApplicationBootstrap` walks the discovered
|
|
49
|
+
* jobs, calling `register(entry)` once per `@BatchScheduled`
|
|
50
|
+
* method.
|
|
51
|
+
* 3. A future runtime scheduler (e.g. a BullMQ adapter) reads from
|
|
52
|
+
* the registry at app start to install the actual timers.
|
|
53
|
+
*
|
|
54
|
+
* The registry is intentionally metadata-only: it never installs a
|
|
55
|
+
* timer, never reads the env, never resolves the cron expression. It
|
|
56
|
+
* is a pure data structure.
|
|
57
|
+
*/
|
|
58
|
+
export declare class BatchScheduleRegistry {
|
|
59
|
+
private readonly entries;
|
|
60
|
+
/**
|
|
61
|
+
* Number of registered entries. Exposed for diagnostics / health
|
|
62
|
+
* endpoints; the future runtime scheduler also uses it to detect
|
|
63
|
+
* "no schedules" without paying for `getAll().length`.
|
|
64
|
+
*/
|
|
65
|
+
size(): number;
|
|
66
|
+
/**
|
|
67
|
+
* Register a single `@BatchScheduled` entry.
|
|
68
|
+
*
|
|
69
|
+
* Throws `DuplicateBatchScheduleError` if a `(jobId, methodName)`
|
|
70
|
+
* pair is registered twice. This is deterministic: the explorer
|
|
71
|
+
* should never see the same method twice for a given class, so a
|
|
72
|
+
* duplicate is always a programmer / wiring error.
|
|
73
|
+
*/
|
|
74
|
+
register(entry: BatchScheduleEntry): void;
|
|
75
|
+
/**
|
|
76
|
+
* Look up a registered entry. Returns `undefined` if no entry exists
|
|
77
|
+
* for the given `(jobId, methodName)` pair. The lookup is O(1).
|
|
78
|
+
*/
|
|
79
|
+
get(jobId: string, methodName: string): BatchScheduleEntry | undefined;
|
|
80
|
+
/**
|
|
81
|
+
* Boolean variant of `get` — useful for guards and tests where the
|
|
82
|
+
* caller does not need the entry value.
|
|
83
|
+
*/
|
|
84
|
+
has(jobId: string, methodName: string): boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Snapshot of every registered entry. Order is insertion order
|
|
87
|
+
* (because the underlying `Map` preserves insertion order); callers
|
|
88
|
+
* that need a stable sort MUST sort the returned array themselves.
|
|
89
|
+
*/
|
|
90
|
+
getAll(): BatchScheduleEntry[];
|
|
91
|
+
/**
|
|
92
|
+
* Remove every entry. Primarily useful in tests; production code
|
|
93
|
+
* should treat the registry as append-only for the lifetime of the
|
|
94
|
+
* Nest application.
|
|
95
|
+
*/
|
|
96
|
+
clear(): void;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Thrown when the explorer (or any other code path) attempts to
|
|
100
|
+
* register a duplicate `@BatchScheduled` entry for the same
|
|
101
|
+
* `(jobId, methodName)` pair.
|
|
102
|
+
*
|
|
103
|
+
* This is a `BatchError` so the existing `core/errors.ts` hierarchy
|
|
104
|
+
* applies. It is exported from the module barrel so adapter code can
|
|
105
|
+
* `instanceof`-check it without reaching into a deep import.
|
|
106
|
+
*/
|
|
107
|
+
export declare class DuplicateBatchScheduleError extends Error {
|
|
108
|
+
constructor(jobId: string, methodName: string);
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=batch-schedule-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-schedule-registry.d.ts","sourceRoot":"","sources":["../../../src/module/batch-schedule-registry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAExE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,kBAAkB;IACjC,sDAAsD;IACtD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,wEAAwE;IACxE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,yEAAyE;IACzE,QAAQ,CAAC,OAAO,CAAC,EAAE,kBAAkB,CAAC;IACtC,uCAAuC;IACvC,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC;IACxB,uCAAuC;IACvC,QAAQ,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAcD;;;;;;;;;;;;;;;;;GAiBG;AACH,qBACa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyC;IAEjE;;;;OAIG;IACH,IAAI,IAAI,MAAM;IAId;;;;;;;OAOG;IACH,QAAQ,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI;IAQzC;;;OAGG;IACH,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAItE;;;OAGG;IACH,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO;IAI/C;;;;OAIG;IACH,MAAM,IAAI,kBAAkB,EAAE;IAI9B;;;;OAIG;IACH,KAAK,IAAI,IAAI;CAGd;AAED;;;;;;;;GAQG;AACH,qBAAa,2BAA4B,SAAQ,KAAK;gBACxC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;CAQ9C"}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/module/batch-schedule-registry.ts"],"sourcesContent":["import { Injectable } from '@nestjs/common';\n\nimport type { BatchOverlapPolicy } from '../scheduling/batch-scheduled';\n\n/**\n * A single entry recorded in the `BatchScheduleRegistry`.\n *\n * The registry is the contract surface between the\n * discovery-time metadata (stamped by the `@BatchScheduled` decorator\n * and collected by `BatchExplorer`) and the future runtime scheduler\n * (the `@nest-batch/bullmq` cron strategy, or a sibling scheduling\n * package). Today the registry is populated by the explorer; tomorrow\n * the runtime scheduler reads from it.\n *\n * `inert` is captured at decoration time from\n * `process.env.BATCH_SCHEDULED_DISABLE` and is preserved on the entry\n * verbatim so the runtime scheduler can decide whether to install a\n * real timer. The decorator does NOT inspect the env at runtime\n * scheduling time — the registry carries the resolved value.\n */\nexport interface BatchScheduleEntry {\n /** The `@Jobable({ id })` value of the host class. */\n readonly jobId: string;\n /** The method name on the host class that carries `@BatchScheduled`. */\n readonly methodName: string;\n /** The cron expression supplied to the decorator, verbatim. */\n readonly cron: string;\n /** IANA timezone, as supplied to the decorator. */\n readonly timezone: string;\n /** Overlap policy. `undefined` means the runtime applies its default. */\n readonly overlap?: BatchOverlapPolicy;\n /** Absolute lower bound (optional). */\n readonly startAt?: Date;\n /** Absolute upper bound (optional). */\n readonly endAt?: Date;\n /**\n * Captured at decoration time from\n * `process.env.BATCH_SCHEDULED_DISABLE`. `true` is a hint to the\n * runtime scheduler to skip installing a real timer.\n */\n readonly inert: boolean;\n}\n\n/**\n * Internal composite key used by the registry's `Map`. We intentionally\n * avoid the `Symbol`/`string` debate by using a stable string form\n * `${jobId}\u0000${methodName}`. There is no risk of collision because\n * `jobId` and `methodName` are both required to be unique within a\n * given scope (`jobId` is unique across the whole registry, and\n * `methodName` is unique within a class).\n */\nfunction registryKey(jobId: string, methodName: string): string {\n return `${jobId}\u0000${methodName}`;\n}\n\n/**\n * `BatchScheduleRegistry` — in-memory map of `@BatchScheduled`\n * metadata discovered at bootstrap.\n *\n * Lifecycle:\n * 1. The registry is constructed once at module init (Nest DI\n * singleton).\n * 2. `BatchExplorer.onModuleInit` walks every provider, and\n * `BatchBootstrapper.onApplicationBootstrap` walks the discovered\n * jobs, calling `register(entry)` once per `@BatchScheduled`\n * method.\n * 3. A future runtime scheduler (e.g. a BullMQ adapter) reads from\n * the registry at app start to install the actual timers.\n *\n * The registry is intentionally metadata-only: it never installs a\n * timer, never reads the env, never resolves the cron expression. It\n * is a pure data structure.\n */\n@Injectable()\nexport class BatchScheduleRegistry {\n private readonly entries = new Map<string, BatchScheduleEntry>();\n\n /**\n * Number of registered entries. Exposed for diagnostics / health\n * endpoints; the future runtime scheduler also uses it to detect\n * \"no schedules\" without paying for `getAll().length`.\n */\n size(): number {\n return this.entries.size;\n }\n\n /**\n * Register a single `@BatchScheduled` entry.\n *\n * Throws `DuplicateBatchScheduleError` if a `(jobId, methodName)`\n * pair is registered twice. This is deterministic: the explorer\n * should never see the same method twice for a given class, so a\n * duplicate is always a programmer / wiring error.\n */\n register(entry: BatchScheduleEntry): void {\n const key = registryKey(entry.jobId, entry.methodName);\n if (this.entries.has(key)) {\n throw new DuplicateBatchScheduleError(entry.jobId, entry.methodName);\n }\n this.entries.set(key, entry);\n }\n\n /**\n * Look up a registered entry. Returns `undefined` if no entry exists\n * for the given `(jobId, methodName)` pair. The lookup is O(1).\n */\n get(jobId: string, methodName: string): BatchScheduleEntry | undefined {\n return this.entries.get(registryKey(jobId, methodName));\n }\n\n /**\n * Boolean variant of `get` — useful for guards and tests where the\n * caller does not need the entry value.\n */\n has(jobId: string, methodName: string): boolean {\n return this.entries.has(registryKey(jobId, methodName));\n }\n\n /**\n * Snapshot of every registered entry. Order is insertion order\n * (because the underlying `Map` preserves insertion order); callers\n * that need a stable sort MUST sort the returned array themselves.\n */\n getAll(): BatchScheduleEntry[] {\n return Array.from(this.entries.values());\n }\n\n /**\n * Remove every entry. Primarily useful in tests; production code\n * should treat the registry as append-only for the lifetime of the\n * Nest application.\n */\n clear(): void {\n this.entries.clear();\n }\n}\n\n/**\n * Thrown when the explorer (or any other code path) attempts to\n * register a duplicate `@BatchScheduled` entry for the same\n * `(jobId, methodName)` pair.\n *\n * This is a `BatchError` so the existing `core/errors.ts` hierarchy\n * applies. It is exported from the module barrel so adapter code can\n * `instanceof`-check it without reaching into a deep import.\n */\nexport class DuplicateBatchScheduleError extends Error {\n constructor(jobId: string, methodName: string) {\n super(\n `Duplicate @BatchScheduled entry for jobId=\"${jobId}\", method=\"${methodName}\". ` +\n `A method can only be scheduled once per jobId. ` +\n `If you want two schedules for the same job, declare them on distinct methods.`,\n );\n this.name = 'DuplicateBatchScheduleError';\n }\n}\n"],"names":["BatchScheduleRegistry","DuplicateBatchScheduleError","registryKey","jobId","methodName","entries","Map","size","register","entry","key","has","set","get","getAll","Array","from","values","clear","Error","name"],"mappings":";;;;;;;;;;;QA0EaA;eAAAA;;QAwEAC;eAAAA;;;wBAlJc;;;;;;;AA2C3B;;;;;;;CAOC,GACD,SAASC,YAAYC,KAAa,EAAEC,UAAkB;IACpD,OAAO,GAAGD,MAAM,CAAC,EAAEC,YAAY;AACjC;AAqBO,IAAA,AAAMJ,wBAAN,MAAMA;IACMK,UAAU,IAAIC,MAAkC;IAEjE;;;;GAIC,GACDC,OAAe;QACb,OAAO,IAAI,CAACF,OAAO,CAACE,IAAI;IAC1B;IAEA;;;;;;;GAOC,GACDC,SAASC,KAAyB,EAAQ;QACxC,MAAMC,MAAMR,YAAYO,MAAMN,KAAK,EAAEM,MAAML,UAAU;QACrD,IAAI,IAAI,CAACC,OAAO,CAACM,GAAG,CAACD,MAAM;YACzB,MAAM,IAAIT,4BAA4BQ,MAAMN,KAAK,EAAEM,MAAML,UAAU;QACrE;QACA,IAAI,CAACC,OAAO,CAACO,GAAG,CAACF,KAAKD;IACxB;IAEA;;;GAGC,GACDI,IAAIV,KAAa,EAAEC,UAAkB,EAAkC;QACrE,OAAO,IAAI,CAACC,OAAO,CAACQ,GAAG,CAACX,YAAYC,OAAOC;IAC7C;IAEA;;;GAGC,GACDO,IAAIR,KAAa,EAAEC,UAAkB,EAAW;QAC9C,OAAO,IAAI,CAACC,OAAO,CAACM,GAAG,CAACT,YAAYC,OAAOC;IAC7C;IAEA;;;;GAIC,GACDU,SAA+B;QAC7B,OAAOC,MAAMC,IAAI,CAAC,IAAI,CAACX,OAAO,CAACY,MAAM;IACvC;IAEA;;;;GAIC,GACDC,QAAc;QACZ,IAAI,CAACb,OAAO,CAACa,KAAK;IACpB;AACF;;;;AAWO,IAAA,AAAMjB,8BAAN,MAAMA,oCAAoCkB;IAC/C,YAAYhB,KAAa,EAAEC,UAAkB,CAAE;QAC7C,KAAK,CACH,CAAC,2CAA2C,EAAED,MAAM,WAAW,EAAEC,WAAW,GAAG,CAAC,GAC9E,CAAC,+CAA+C,CAAC,GACjD,CAAC,6EAA6E,CAAC;QAEnF,IAAI,CAACgB,IAAI,GAAG;IACd;AACF"}
|