@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,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public injection tokens for the `@nest-batch/core` module surface.
|
|
3
|
+
*
|
|
4
|
+
* These tokens are the stable, package-scoped identifiers sibling packages
|
|
5
|
+
* (e.g. `@nest-batch/mikro-orm`, `@nest-batch/typeorm`, `@nest-batch/bullmq`)
|
|
6
|
+
* use to bind their own providers into the core DI graph. They are
|
|
7
|
+
* registered in the global `Symbol.for` registry under stable, package-
|
|
8
|
+
* scoped keys so they are unique across the host process even if the
|
|
9
|
+
* package is loaded multiple times.
|
|
10
|
+
*
|
|
11
|
+
* Why symbols and not string tokens?
|
|
12
|
+
* - Symbols cannot collide with a user string by accident.
|
|
13
|
+
* - `Symbol.for(key)` gives us cross-realm uniqueness without the
|
|
14
|
+
* caller having to thread the token through `import` chains — a
|
|
15
|
+
* host can resolve any of these tokens by reaching into
|
|
16
|
+
* `Symbol.for('...description...')` and getting the same value.
|
|
17
|
+
* - Symbols are erased from emitted JavaScript, so they do not
|
|
18
|
+
* pollute production bundles with debug strings.
|
|
19
|
+
*
|
|
20
|
+
* Why a stable description (not `Symbol(description)`)?
|
|
21
|
+
* - `Symbol.for('k')` only works if the *same* string is passed both
|
|
22
|
+
* times. Hard-coding a `description` lets future sibling packages
|
|
23
|
+
* resolve the token without importing this file (useful for tooling
|
|
24
|
+
* and for ad-hoc cross-package debugging).
|
|
25
|
+
*/ "use strict";
|
|
26
|
+
Object.defineProperty(exports, "__esModule", {
|
|
27
|
+
value: true
|
|
28
|
+
});
|
|
29
|
+
function _export(target, all) {
|
|
30
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
_export(exports, {
|
|
36
|
+
get BATCH_SCHEDULE_REGISTRY () {
|
|
37
|
+
return BATCH_SCHEDULE_REGISTRY;
|
|
38
|
+
},
|
|
39
|
+
get EXECUTION_STRATEGY () {
|
|
40
|
+
return _executionstrategy.EXECUTION_STRATEGY;
|
|
41
|
+
},
|
|
42
|
+
get JOB_REPOSITORY_TOKEN () {
|
|
43
|
+
return JOB_REPOSITORY_TOKEN;
|
|
44
|
+
},
|
|
45
|
+
get MODULE_OPTIONS_TOKEN () {
|
|
46
|
+
return MODULE_OPTIONS_TOKEN;
|
|
47
|
+
},
|
|
48
|
+
get TRANSACTION_MANAGER_TOKEN () {
|
|
49
|
+
return TRANSACTION_MANAGER_TOKEN;
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
const _executionstrategy = require("../execution/execution-strategy");
|
|
53
|
+
const JOB_REPOSITORY_TOKEN = Symbol.for('@nest-batch/core/JOB_REPOSITORY');
|
|
54
|
+
const TRANSACTION_MANAGER_TOKEN = Symbol.for('@nest-batch/core/TRANSACTION_MANAGER');
|
|
55
|
+
const BATCH_SCHEDULE_REGISTRY = Symbol.for('@nest-batch/core/BATCH_SCHEDULE_REGISTRY');
|
|
56
|
+
const MODULE_OPTIONS_TOKEN = Symbol.for('@nest-batch/core/MODULE_OPTIONS');
|
|
57
|
+
|
|
58
|
+
//# sourceMappingURL=tokens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/module/tokens.ts"],"sourcesContent":["/**\n * Public injection tokens for the `@nest-batch/core` module surface.\n *\n * These tokens are the stable, package-scoped identifiers sibling packages\n * (e.g. `@nest-batch/mikro-orm`, `@nest-batch/typeorm`, `@nest-batch/bullmq`)\n * use to bind their own providers into the core DI graph. They are\n * registered in the global `Symbol.for` registry under stable, package-\n * scoped keys so they are unique across the host process even if the\n * package is loaded multiple times.\n *\n * Why symbols and not string tokens?\n * - Symbols cannot collide with a user string by accident.\n * - `Symbol.for(key)` gives us cross-realm uniqueness without the\n * caller having to thread the token through `import` chains — a\n * host can resolve any of these tokens by reaching into\n * `Symbol.for('...description...')` and getting the same value.\n * - Symbols are erased from emitted JavaScript, so they do not\n * pollute production bundles with debug strings.\n *\n * Why a stable description (not `Symbol(description)`)?\n * - `Symbol.for('k')` only works if the *same* string is passed both\n * times. Hard-coding a `description` lets future sibling packages\n * resolve the token without importing this file (useful for tooling\n * and for ad-hoc cross-package debugging).\n */\nimport { EXECUTION_STRATEGY } from '../execution/execution-strategy';\n\n/**\n * Injection token for the `JobRepository` implementation.\n *\n * Adapter packages (`@nest-batch/mikro-orm`, `@nest-batch/typeorm`, ...)\n * bind their `JobRepository` subclass to this token. By default the host\n * app is expected to register its own `JobRepository` provider — core\n * does NOT ship a default binding because the choice of persistence\n * backend is the host's decision.\n */\nexport const JOB_REPOSITORY_TOKEN: symbol = Symbol.for(\n '@nest-batch/core/JOB_REPOSITORY',\n);\n\n/**\n * Injection token for the `TransactionManager` implementation.\n *\n * Adapter packages bind their transaction manager to this token. The\n * `JobRepository` implementation is expected to participate in the same\n * transaction (e.g. share the same `EntityManager` / `DataSource`).\n */\nexport const TRANSACTION_MANAGER_TOKEN: symbol = Symbol.for(\n '@nest-batch/core/TRANSACTION_MANAGER',\n);\n\n/**\n * Injection token for the `BatchScheduleRegistry` provider.\n *\n * The `BatchExplorer` populates this registry with `@BatchScheduled`\n * metadata it discovers on `@Jobable` classes. The future runtime\n * scheduler (the `@nest-batch/bullmq` cron strategy, or a sibling\n * scheduling package) reads from this registry to install the actual\n * timers. Keeping the registry as a stable token means adapters can\n * inject it (for introspection / health checks) without depending on\n * the explorer's internal state.\n */\nexport const BATCH_SCHEDULE_REGISTRY: symbol = Symbol.for(\n '@nest-batch/core/BATCH_SCHEDULE_REGISTRY',\n);\n\n/**\n * Injection token for the module's resolved options bag.\n *\n * Backs the post-`useFactory` options read (T2 will wire the async\n * factory provider to write into this slot). Sibling packages and the\n * host app can read the resolved options by injecting this token. The\n * shape is the union of `NestBatchModuleOptions` plus whatever an\n * adapter's own config contributed, so the value is a\n * `Record<string, unknown>` at runtime.\n *\n * The previous `'BATCH_OPTIONS'` string alias was removed in the\n * T1 type-contract refactor — hosts that need the options bag should\n * inject `MODULE_OPTIONS_TOKEN` instead.\n */\nexport const MODULE_OPTIONS_TOKEN: symbol = Symbol.for(\n '@nest-batch/core/MODULE_OPTIONS',\n);\n\n/**\n * Polymorphic execution strategy token.\n *\n * Re-exported here from `execution/execution-strategy.ts` so that the\n * module surface is the single import path for downstream packages.\n * Apps that want the default in-process strategy wire up\n * `IN_PROCESS_EXECUTION_STRATEGY_PROVIDER`; sibling packages (e.g.\n * `@nest-batch/bullmq`) provide a custom binding under this same\n * token.\n */\nexport { EXECUTION_STRATEGY };\n"],"names":["BATCH_SCHEDULE_REGISTRY","EXECUTION_STRATEGY","JOB_REPOSITORY_TOKEN","MODULE_OPTIONS_TOKEN","TRANSACTION_MANAGER_TOKEN","Symbol","for"],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;CAwBC;;;;;;;;;;;QAsCYA;eAAAA;;QAgCJC;eAAAA,qCAAkB;;QA1DdC;eAAAA;;QA4CAC;eAAAA;;QAjCAC;eAAAA;;;mCAtBsB;AAW5B,MAAMF,uBAA+BG,OAAOC,GAAG,CACpD;AAUK,MAAMF,4BAAoCC,OAAOC,GAAG,CACzD;AAcK,MAAMN,0BAAkCK,OAAOC,GAAG,CACvD;AAiBK,MAAMH,uBAA+BE,OAAOC,GAAG,CACpD"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { JsonValue } from '../core/execution-context/json-value';
|
|
2
|
+
/**
|
|
3
|
+
* Event type constants emitted by the JobExecutor / step executors.
|
|
4
|
+
*
|
|
5
|
+
* Naming follows `<domain>.<entity>.<verb-past-tense>` so downstream
|
|
6
|
+
* consumers can subscribe via dot-separated filter strings.
|
|
7
|
+
*/
|
|
8
|
+
export declare const BATCH_EVENT: {
|
|
9
|
+
readonly JOB_STARTED: "nest-batch.job.started";
|
|
10
|
+
readonly JOB_COMPLETED: "nest-batch.job.completed";
|
|
11
|
+
readonly JOB_FAILED: "nest-batch.job.failed";
|
|
12
|
+
readonly STEP_STARTED: "nest-batch.step.started";
|
|
13
|
+
readonly STEP_COMPLETED: "nest-batch.step.completed";
|
|
14
|
+
readonly STEP_FAILED: "nest-batch.step.failed";
|
|
15
|
+
readonly CHUNK_PROCESSED: "nest-batch.chunk.processed";
|
|
16
|
+
readonly ITEM_SKIPPED: "nest-batch.item.skipped";
|
|
17
|
+
readonly ITEM_RETRIED: "nest-batch.item.retried";
|
|
18
|
+
};
|
|
19
|
+
export type BatchEventType = (typeof BATCH_EVENT)[keyof typeof BATCH_EVENT];
|
|
20
|
+
/**
|
|
21
|
+
* Single, normalized event payload. `data` is intentionally typed as
|
|
22
|
+
* `JsonValue` so observers can ship events over any transport (HTTP,
|
|
23
|
+
* JSON log line, message queue) without further conversion.
|
|
24
|
+
*
|
|
25
|
+
* - `jobExecutionId` is always present.
|
|
26
|
+
* - `stepExecutionId` is present for STEP_*, CHUNK_*, and ITEM_*
|
|
27
|
+
* events; absent for JOB_* events that fire outside a step context
|
|
28
|
+
* (currently the JOB_STARTED / JOB_COMPLETED / JOB_FAILED trio).
|
|
29
|
+
*/
|
|
30
|
+
export interface BatchEvent {
|
|
31
|
+
type: BatchEventType;
|
|
32
|
+
timestamp: Date;
|
|
33
|
+
jobExecutionId: string;
|
|
34
|
+
stepExecutionId?: string;
|
|
35
|
+
data: JsonValue;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Observer contract for batch lifecycle events. Implementations may
|
|
39
|
+
* emit logs, push to a queue, or aggregate metrics. The executor
|
|
40
|
+
* awaits `onEvent` so a slow observer blocks step transitions — this
|
|
41
|
+
* is intentional: per the plan, exporters are out of scope, and the
|
|
42
|
+
* default observer is a no-op.
|
|
43
|
+
*/
|
|
44
|
+
export interface BatchObserver {
|
|
45
|
+
onEvent(event: BatchEvent): void | Promise<void>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Default observer used when none is supplied. Discards every event.
|
|
49
|
+
* Useful as a sentinel default that satisfies the interface without
|
|
50
|
+
* doing any I/O.
|
|
51
|
+
*/
|
|
52
|
+
export declare class NoopBatchObserver implements BatchObserver {
|
|
53
|
+
onEvent(_event: BatchEvent): Promise<void>;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=event-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-types.d.ts","sourceRoot":"","sources":["../../../src/observability/event-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AAEtE;;;;;GAKG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;CAUd,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,WAAW,CAAC,CAAC;AAE5E;;;;;;;;;GASG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,IAAI,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,IAAI,EAAE,SAAS,CAAC;CACjB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClD;AAED;;;;GAIG;AACH,qBAAa,iBAAkB,YAAW,aAAa;IAC/C,OAAO,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAGjD"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get BATCH_EVENT () {
|
|
13
|
+
return BATCH_EVENT;
|
|
14
|
+
},
|
|
15
|
+
get NoopBatchObserver () {
|
|
16
|
+
return NoopBatchObserver;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
const BATCH_EVENT = {
|
|
20
|
+
JOB_STARTED: 'nest-batch.job.started',
|
|
21
|
+
JOB_COMPLETED: 'nest-batch.job.completed',
|
|
22
|
+
JOB_FAILED: 'nest-batch.job.failed',
|
|
23
|
+
STEP_STARTED: 'nest-batch.step.started',
|
|
24
|
+
STEP_COMPLETED: 'nest-batch.step.completed',
|
|
25
|
+
STEP_FAILED: 'nest-batch.step.failed',
|
|
26
|
+
CHUNK_PROCESSED: 'nest-batch.chunk.processed',
|
|
27
|
+
ITEM_SKIPPED: 'nest-batch.item.skipped',
|
|
28
|
+
ITEM_RETRIED: 'nest-batch.item.retried'
|
|
29
|
+
};
|
|
30
|
+
let NoopBatchObserver = class NoopBatchObserver {
|
|
31
|
+
async onEvent(_event) {
|
|
32
|
+
// intentional no-op
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
//# sourceMappingURL=event-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/observability/event-types.ts"],"sourcesContent":["import type { JsonValue } from '../core/execution-context/json-value';\n\n/**\n * Event type constants emitted by the JobExecutor / step executors.\n *\n * Naming follows `<domain>.<entity>.<verb-past-tense>` so downstream\n * consumers can subscribe via dot-separated filter strings.\n */\nexport const BATCH_EVENT = {\n JOB_STARTED: 'nest-batch.job.started',\n JOB_COMPLETED: 'nest-batch.job.completed',\n JOB_FAILED: 'nest-batch.job.failed',\n STEP_STARTED: 'nest-batch.step.started',\n STEP_COMPLETED: 'nest-batch.step.completed',\n STEP_FAILED: 'nest-batch.step.failed',\n CHUNK_PROCESSED: 'nest-batch.chunk.processed',\n ITEM_SKIPPED: 'nest-batch.item.skipped',\n ITEM_RETRIED: 'nest-batch.item.retried',\n} as const;\n\nexport type BatchEventType = (typeof BATCH_EVENT)[keyof typeof BATCH_EVENT];\n\n/**\n * Single, normalized event payload. `data` is intentionally typed as\n * `JsonValue` so observers can ship events over any transport (HTTP,\n * JSON log line, message queue) without further conversion.\n *\n * - `jobExecutionId` is always present.\n * - `stepExecutionId` is present for STEP_*, CHUNK_*, and ITEM_*\n * events; absent for JOB_* events that fire outside a step context\n * (currently the JOB_STARTED / JOB_COMPLETED / JOB_FAILED trio).\n */\nexport interface BatchEvent {\n type: BatchEventType;\n timestamp: Date;\n jobExecutionId: string;\n stepExecutionId?: string;\n data: JsonValue;\n}\n\n/**\n * Observer contract for batch lifecycle events. Implementations may\n * emit logs, push to a queue, or aggregate metrics. The executor\n * awaits `onEvent` so a slow observer blocks step transitions — this\n * is intentional: per the plan, exporters are out of scope, and the\n * default observer is a no-op.\n */\nexport interface BatchObserver {\n onEvent(event: BatchEvent): void | Promise<void>;\n}\n\n/**\n * Default observer used when none is supplied. Discards every event.\n * Useful as a sentinel default that satisfies the interface without\n * doing any I/O.\n */\nexport class NoopBatchObserver implements BatchObserver {\n async onEvent(_event: BatchEvent): Promise<void> {\n // intentional no-op\n }\n}\n"],"names":["BATCH_EVENT","NoopBatchObserver","JOB_STARTED","JOB_COMPLETED","JOB_FAILED","STEP_STARTED","STEP_COMPLETED","STEP_FAILED","CHUNK_PROCESSED","ITEM_SKIPPED","ITEM_RETRIED","onEvent","_event"],"mappings":";;;;;;;;;;;QAQaA;eAAAA;;QAgDAC;eAAAA;;;AAhDN,MAAMD,cAAc;IACzBE,aAAa;IACbC,eAAe;IACfC,YAAY;IACZC,cAAc;IACdC,gBAAgB;IAChBC,aAAa;IACbC,iBAAiB;IACjBC,cAAc;IACdC,cAAc;AAChB;AAsCO,IAAA,AAAMT,oBAAN,MAAMA;IACX,MAAMU,QAAQC,MAAkB,EAAiB;IAC/C,oBAAoB;IACtB;AACF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type BatchEvent, type BatchObserver } from './event-types';
|
|
2
|
+
export declare class CompositeBatchObserver implements BatchObserver {
|
|
3
|
+
private readonly observers;
|
|
4
|
+
constructor(observers: readonly BatchObserver[]);
|
|
5
|
+
onEvent(event: BatchEvent): Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
export interface JsonLogBatchObserverOptions {
|
|
8
|
+
readonly write?: (line: string) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare class JsonLogBatchObserver implements BatchObserver {
|
|
11
|
+
private readonly write;
|
|
12
|
+
constructor(options?: JsonLogBatchObserverOptions);
|
|
13
|
+
onEvent(event: BatchEvent): void;
|
|
14
|
+
}
|
|
15
|
+
export interface BatchMetricsSnapshot {
|
|
16
|
+
readonly eventsTotal: Readonly<Record<string, number>>;
|
|
17
|
+
readonly jobsStarted: number;
|
|
18
|
+
readonly jobsCompleted: number;
|
|
19
|
+
readonly jobsFailed: number;
|
|
20
|
+
readonly stepsStarted: number;
|
|
21
|
+
readonly stepsCompleted: number;
|
|
22
|
+
readonly stepsFailed: number;
|
|
23
|
+
readonly chunksProcessed: number;
|
|
24
|
+
readonly itemsSkipped: number;
|
|
25
|
+
readonly itemsRetried: number;
|
|
26
|
+
}
|
|
27
|
+
export declare class PrometheusBatchMetricsObserver implements BatchObserver {
|
|
28
|
+
private readonly eventsTotal;
|
|
29
|
+
onEvent(event: BatchEvent): void;
|
|
30
|
+
snapshot(): BatchMetricsSnapshot;
|
|
31
|
+
renderPrometheus(): string;
|
|
32
|
+
private increment;
|
|
33
|
+
private count;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=exporters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exporters.d.ts","sourceRoot":"","sources":["../../../src/observability/exporters.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAEjF,qBAAa,sBAAuB,YAAW,aAAa;IAC9C,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,SAAS,aAAa,EAAE;IAE1D,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAGhD;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAED,qBAAa,oBAAqB,YAAW,aAAa;IACxD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAyB;gBAEnC,OAAO,GAAE,2BAAgC;IAIrD,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;CAQjC;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACvD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,qBAAa,8BAA+B,YAAW,aAAa;IAClE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6B;IAEzD,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAIhC,QAAQ,IAAI,oBAAoB;IAehC,gBAAgB,IAAI,MAAM;IAkB1B,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,KAAK;CAGd"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get CompositeBatchObserver () {
|
|
13
|
+
return CompositeBatchObserver;
|
|
14
|
+
},
|
|
15
|
+
get JsonLogBatchObserver () {
|
|
16
|
+
return JsonLogBatchObserver;
|
|
17
|
+
},
|
|
18
|
+
get PrometheusBatchMetricsObserver () {
|
|
19
|
+
return PrometheusBatchMetricsObserver;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
const _eventtypes = require("./event-types");
|
|
23
|
+
let CompositeBatchObserver = class CompositeBatchObserver {
|
|
24
|
+
observers;
|
|
25
|
+
constructor(observers){
|
|
26
|
+
this.observers = observers;
|
|
27
|
+
}
|
|
28
|
+
async onEvent(event) {
|
|
29
|
+
await Promise.all(this.observers.map((observer)=>observer.onEvent(event)));
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
let JsonLogBatchObserver = class JsonLogBatchObserver {
|
|
33
|
+
write;
|
|
34
|
+
constructor(options = {}){
|
|
35
|
+
this.write = options.write ?? ((line)=>console.log(line));
|
|
36
|
+
}
|
|
37
|
+
onEvent(event) {
|
|
38
|
+
this.write(JSON.stringify({
|
|
39
|
+
...event,
|
|
40
|
+
timestamp: event.timestamp.toISOString()
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
let PrometheusBatchMetricsObserver = class PrometheusBatchMetricsObserver {
|
|
45
|
+
eventsTotal = new Map();
|
|
46
|
+
onEvent(event) {
|
|
47
|
+
this.increment(event.type);
|
|
48
|
+
}
|
|
49
|
+
snapshot() {
|
|
50
|
+
return {
|
|
51
|
+
eventsTotal: Object.fromEntries(this.eventsTotal.entries()),
|
|
52
|
+
jobsStarted: this.count(_eventtypes.BATCH_EVENT.JOB_STARTED),
|
|
53
|
+
jobsCompleted: this.count(_eventtypes.BATCH_EVENT.JOB_COMPLETED),
|
|
54
|
+
jobsFailed: this.count(_eventtypes.BATCH_EVENT.JOB_FAILED),
|
|
55
|
+
stepsStarted: this.count(_eventtypes.BATCH_EVENT.STEP_STARTED),
|
|
56
|
+
stepsCompleted: this.count(_eventtypes.BATCH_EVENT.STEP_COMPLETED),
|
|
57
|
+
stepsFailed: this.count(_eventtypes.BATCH_EVENT.STEP_FAILED),
|
|
58
|
+
chunksProcessed: this.count(_eventtypes.BATCH_EVENT.CHUNK_PROCESSED),
|
|
59
|
+
itemsSkipped: this.count(_eventtypes.BATCH_EVENT.ITEM_SKIPPED),
|
|
60
|
+
itemsRetried: this.count(_eventtypes.BATCH_EVENT.ITEM_RETRIED)
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
renderPrometheus() {
|
|
64
|
+
const lines = [
|
|
65
|
+
'# HELP nest_batch_events_total Total batch lifecycle events.',
|
|
66
|
+
'# TYPE nest_batch_events_total counter'
|
|
67
|
+
];
|
|
68
|
+
for (const [type, count] of [
|
|
69
|
+
...this.eventsTotal.entries()
|
|
70
|
+
].sort()){
|
|
71
|
+
lines.push(`nest_batch_events_total{type="${escapeLabel(type)}"} ${count}`);
|
|
72
|
+
}
|
|
73
|
+
const snapshot = this.snapshot();
|
|
74
|
+
lines.push('# HELP nest_batch_jobs_completed_total Completed jobs.');
|
|
75
|
+
lines.push('# TYPE nest_batch_jobs_completed_total counter');
|
|
76
|
+
lines.push(`nest_batch_jobs_completed_total ${snapshot.jobsCompleted}`);
|
|
77
|
+
lines.push('# HELP nest_batch_jobs_failed_total Failed jobs.');
|
|
78
|
+
lines.push('# TYPE nest_batch_jobs_failed_total counter');
|
|
79
|
+
lines.push(`nest_batch_jobs_failed_total ${snapshot.jobsFailed}`);
|
|
80
|
+
return `${lines.join('\n')}\n`;
|
|
81
|
+
}
|
|
82
|
+
increment(type) {
|
|
83
|
+
this.eventsTotal.set(type, this.count(type) + 1);
|
|
84
|
+
}
|
|
85
|
+
count(type) {
|
|
86
|
+
return this.eventsTotal.get(type) ?? 0;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
function escapeLabel(value) {
|
|
90
|
+
return value.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
//# sourceMappingURL=exporters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/observability/exporters.ts"],"sourcesContent":["import { BATCH_EVENT, type BatchEvent, type BatchObserver } from './event-types';\n\nexport class CompositeBatchObserver implements BatchObserver {\n constructor(private readonly observers: readonly BatchObserver[]) {}\n\n async onEvent(event: BatchEvent): Promise<void> {\n await Promise.all(this.observers.map((observer) => observer.onEvent(event)));\n }\n}\n\nexport interface JsonLogBatchObserverOptions {\n readonly write?: (line: string) => void;\n}\n\nexport class JsonLogBatchObserver implements BatchObserver {\n private readonly write: (line: string) => void;\n\n constructor(options: JsonLogBatchObserverOptions = {}) {\n this.write = options.write ?? ((line) => console.log(line));\n }\n\n onEvent(event: BatchEvent): void {\n this.write(\n JSON.stringify({\n ...event,\n timestamp: event.timestamp.toISOString(),\n }),\n );\n }\n}\n\nexport interface BatchMetricsSnapshot {\n readonly eventsTotal: Readonly<Record<string, number>>;\n readonly jobsStarted: number;\n readonly jobsCompleted: number;\n readonly jobsFailed: number;\n readonly stepsStarted: number;\n readonly stepsCompleted: number;\n readonly stepsFailed: number;\n readonly chunksProcessed: number;\n readonly itemsSkipped: number;\n readonly itemsRetried: number;\n}\n\nexport class PrometheusBatchMetricsObserver implements BatchObserver {\n private readonly eventsTotal = new Map<string, number>();\n\n onEvent(event: BatchEvent): void {\n this.increment(event.type);\n }\n\n snapshot(): BatchMetricsSnapshot {\n return {\n eventsTotal: Object.fromEntries(this.eventsTotal.entries()),\n jobsStarted: this.count(BATCH_EVENT.JOB_STARTED),\n jobsCompleted: this.count(BATCH_EVENT.JOB_COMPLETED),\n jobsFailed: this.count(BATCH_EVENT.JOB_FAILED),\n stepsStarted: this.count(BATCH_EVENT.STEP_STARTED),\n stepsCompleted: this.count(BATCH_EVENT.STEP_COMPLETED),\n stepsFailed: this.count(BATCH_EVENT.STEP_FAILED),\n chunksProcessed: this.count(BATCH_EVENT.CHUNK_PROCESSED),\n itemsSkipped: this.count(BATCH_EVENT.ITEM_SKIPPED),\n itemsRetried: this.count(BATCH_EVENT.ITEM_RETRIED),\n };\n }\n\n renderPrometheus(): string {\n const lines = [\n '# HELP nest_batch_events_total Total batch lifecycle events.',\n '# TYPE nest_batch_events_total counter',\n ];\n for (const [type, count] of [...this.eventsTotal.entries()].sort()) {\n lines.push(`nest_batch_events_total{type=\"${escapeLabel(type)}\"} ${count}`);\n }\n const snapshot = this.snapshot();\n lines.push('# HELP nest_batch_jobs_completed_total Completed jobs.');\n lines.push('# TYPE nest_batch_jobs_completed_total counter');\n lines.push(`nest_batch_jobs_completed_total ${snapshot.jobsCompleted}`);\n lines.push('# HELP nest_batch_jobs_failed_total Failed jobs.');\n lines.push('# TYPE nest_batch_jobs_failed_total counter');\n lines.push(`nest_batch_jobs_failed_total ${snapshot.jobsFailed}`);\n return `${lines.join('\\n')}\\n`;\n }\n\n private increment(type: string): void {\n this.eventsTotal.set(type, this.count(type) + 1);\n }\n\n private count(type: string): number {\n return this.eventsTotal.get(type) ?? 0;\n }\n}\n\nfunction escapeLabel(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').replace(/\\n/g, '\\\\n');\n}\n"],"names":["CompositeBatchObserver","JsonLogBatchObserver","PrometheusBatchMetricsObserver","observers","onEvent","event","Promise","all","map","observer","write","options","line","console","log","JSON","stringify","timestamp","toISOString","eventsTotal","Map","increment","type","snapshot","Object","fromEntries","entries","jobsStarted","count","BATCH_EVENT","JOB_STARTED","jobsCompleted","JOB_COMPLETED","jobsFailed","JOB_FAILED","stepsStarted","STEP_STARTED","stepsCompleted","STEP_COMPLETED","stepsFailed","STEP_FAILED","chunksProcessed","CHUNK_PROCESSED","itemsSkipped","ITEM_SKIPPED","itemsRetried","ITEM_RETRIED","renderPrometheus","lines","sort","push","escapeLabel","join","set","get","value","replace"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/observability/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
_export_star(require("./event-types"), exports);
|
|
6
|
+
_export_star(require("./exporters"), exports);
|
|
7
|
+
function _export_star(from, to) {
|
|
8
|
+
Object.keys(from).forEach(function(k) {
|
|
9
|
+
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
|
|
10
|
+
Object.defineProperty(to, k, {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: function() {
|
|
13
|
+
return from[k];
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
return from;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/observability/index.ts"],"sourcesContent":["export * from './event-types';\nexport * from './exporters';\n"],"names":[],"mappings":";;;;qBAAc;qBACA"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure partition helpers for chunked steps.
|
|
3
|
+
*
|
|
4
|
+
* This module is the single source of truth for partition validation
|
|
5
|
+
* and the default partition-range shape. It is deliberately
|
|
6
|
+
* dependency-light: no `@nest-batch/bullmq`, no `@nest-batch/kafka`,
|
|
7
|
+
* no ORMs, no cron — verified by
|
|
8
|
+
* `packages/core/tests/core/boundary/no-forbidden-imports.test.ts`.
|
|
9
|
+
*
|
|
10
|
+
* The helpers are consumed by:
|
|
11
|
+
* - `packages/core/src/compiler/definition-compiler.ts` (validation
|
|
12
|
+
* at compile time),
|
|
13
|
+
* - `packages/core/src/core/validation/definition-validator.ts`
|
|
14
|
+
* (cross-checks the resolved `JobDefinition`),
|
|
15
|
+
* - `packages/core/src/execution/in-process-execution-strategy.ts`
|
|
16
|
+
* (the in-process adapter's partition guard),
|
|
17
|
+
* - `packages/bullmq/src/bullmq-runtime.service.ts` (the BullMQ
|
|
18
|
+
* strategy's enqueue fan-out + the worker's `partitionIndex`
|
|
19
|
+
* enforcement),
|
|
20
|
+
* - `packages/kafka/src/kafka-runtime.service.ts` (the Kafka
|
|
21
|
+
* mirror — T9).
|
|
22
|
+
*
|
|
23
|
+
* Pinned by:
|
|
24
|
+
* - `docs/RELEASE-0.2.0.md §6` — the v1 partition contract.
|
|
25
|
+
* - `packages/bullmq/tests/partition-invariant.test.ts` — T-AC-3
|
|
26
|
+
* first half (the BullMQ side).
|
|
27
|
+
* - `packages/kafka/tests/partition-invariant.test.ts` — T-AC-3
|
|
28
|
+
* second half (the Kafka side, T9).
|
|
29
|
+
*/
|
|
30
|
+
import type { ChunkPartitionConfig } from './core/ir/step-definition';
|
|
31
|
+
/**
|
|
32
|
+
* Error code returned / thrown by the partition helpers. Stable for
|
|
33
|
+
* callers that want to switch on it (the BullMQ / Kafka workers
|
|
34
|
+
* surface this in their `exitMessage` when a partition payload is
|
|
35
|
+
* out of range).
|
|
36
|
+
*/
|
|
37
|
+
export declare const INVALID_PARTITION_INDEX = "INVALID_PARTITION_INDEX";
|
|
38
|
+
/**
|
|
39
|
+
* Thrown when a partition's `count` is not a positive integer, or
|
|
40
|
+
* when a runtime-resolved `partitionIndex` falls outside `[0, count)`.
|
|
41
|
+
*
|
|
42
|
+
* Distinct from `InvalidFlowGraphError` because this is a *value*
|
|
43
|
+
* problem (the input is out of range) rather than a *graph*
|
|
44
|
+
* problem (the step graph is malformed). The `code` is stable.
|
|
45
|
+
*/
|
|
46
|
+
export declare class InvalidPartitionsError extends Error {
|
|
47
|
+
readonly details?: unknown | undefined;
|
|
48
|
+
readonly code: string;
|
|
49
|
+
constructor(message: string, details?: unknown | undefined);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Validate a `ChunkPartitionConfig` at compile time. Throws
|
|
53
|
+
* `InvalidPartitionsError` when the config is structurally invalid:
|
|
54
|
+
*
|
|
55
|
+
* - `count` is not a finite integer
|
|
56
|
+
* - `count <= 0` (a partition count of zero is meaningless)
|
|
57
|
+
* - `range` is set but is not a function
|
|
58
|
+
*
|
|
59
|
+
* `count === 1` is allowed but the runtime short-circuits it to
|
|
60
|
+
* the non-partitioned path; we still validate it here so a typo
|
|
61
|
+
* (`count: 0` vs `count: 1`) fails loudly at the compiler.
|
|
62
|
+
*/
|
|
63
|
+
export declare function validatePartitions(partitions: ChunkPartitionConfig | undefined): void;
|
|
64
|
+
/**
|
|
65
|
+
* The default even-split partition range, given a known total item
|
|
66
|
+
* count. The formula mirrors the v1 contract in
|
|
67
|
+
* `docs/RELEASE-0.2.0.md §6.1`:
|
|
68
|
+
*
|
|
69
|
+
* partition `i` of `n` over `total` items:
|
|
70
|
+
* [floor(i * total / n), floor((i+1) * total / n))
|
|
71
|
+
*
|
|
72
|
+
* Pure function. Exported so hosts that want the "even split"
|
|
73
|
+
* behaviour without re-implementing the math can reuse it:
|
|
74
|
+
*
|
|
75
|
+
* const r = defaultRange(i, n, total);
|
|
76
|
+
* partitions: { count: n, range: (i, n) => defaultRange(i, n, total) }
|
|
77
|
+
*
|
|
78
|
+
* `total` is required because the runtime has no generic way to
|
|
79
|
+
* count the input — only the host's reader knows. The math is
|
|
80
|
+
* robust to `total === 0` (returns `[0, 0)` for every partition).
|
|
81
|
+
*/
|
|
82
|
+
export declare function defaultRange(i: number, n: number, total: number): readonly [from: number, to: number];
|
|
83
|
+
/**
|
|
84
|
+
* Runtime check that a `partitionIndex` on a job payload is in
|
|
85
|
+
* range for the configured `count`. Throws
|
|
86
|
+
* `InvalidPartitionsError` when the index is undefined, not an
|
|
87
|
+
* integer, negative, or `>= count`.
|
|
88
|
+
*
|
|
89
|
+
* The BullMQ / Kafka worker's `processJob` calls this with the
|
|
90
|
+
* payload's `partitionIndex` and the step's `partitions.count` so
|
|
91
|
+
* an out-of-range index becomes a hard step failure (the runtime
|
|
92
|
+
* surfaces it as `FAILED` with the invariant violation in the
|
|
93
|
+
* `exitMessage`).
|
|
94
|
+
*/
|
|
95
|
+
export declare function enforcePartitionIndex(partitionIndex: number | undefined, count: number): void;
|
|
96
|
+
/**
|
|
97
|
+
* Resolved partition info passed through the runtime. Built from
|
|
98
|
+
* the step's `partitions` config and the BullMQ / Kafka payload's
|
|
99
|
+
* `partitionIndex`. The runtime uses this to:
|
|
100
|
+
* - bound the chunk executor's read loop (when the host provided
|
|
101
|
+
* a `range` resolver),
|
|
102
|
+
* - tag the persisted `StepExecution` for diagnostics (a future
|
|
103
|
+
* task; the v1 contract only requires the chunk executor to
|
|
104
|
+
* honour the range).
|
|
105
|
+
*/
|
|
106
|
+
export interface ResolvedPartition {
|
|
107
|
+
readonly count: number;
|
|
108
|
+
readonly index: number;
|
|
109
|
+
/** The partition's resolved `[from, to)` range, or `undefined`
|
|
110
|
+
* when the step did not provide a `range` resolver (the default
|
|
111
|
+
* behaviour is "read until EOF"). */
|
|
112
|
+
readonly range?: readonly [from: number, to: number];
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Resolve a partition's metadata from the step's `partitions`
|
|
116
|
+
* config and the transport's `partitionIndex`. Calls
|
|
117
|
+
* `enforcePartitionIndex` to fail loudly on out-of-range indices.
|
|
118
|
+
*
|
|
119
|
+
* The `range` is computed only when the step provides a resolver;
|
|
120
|
+
* otherwise the returned `ResolvedPartition` is `count` + `index`
|
|
121
|
+
* with no `range`, and the chunk executor reads until EOF.
|
|
122
|
+
*/
|
|
123
|
+
export declare function resolvePartition(args: {
|
|
124
|
+
partitions: ChunkPartitionConfig;
|
|
125
|
+
partitionIndex: number | undefined;
|
|
126
|
+
}): ResolvedPartition;
|
|
127
|
+
//# sourceMappingURL=partition-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"partition-helpers.d.ts","sourceRoot":"","sources":["../../src/partition-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEtE;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,4BAA4B,CAAC;AAEjE;;;;;;;GAOG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;aAEF,OAAO,CAAC,EAAE,OAAO;IAD9D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBACV,OAAO,EAAE,MAAM,EAAkB,OAAO,CAAC,EAAE,OAAO,YAAA;CAK/D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,oBAAoB,GAAG,SAAS,GAAG,IAAI,CAgBrF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,YAAY,CAC1B,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,KAAK,EAAE,MAAM,GACZ,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,CAmBrC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,KAAK,EAAE,MAAM,GACZ,IAAI,CAiBN;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;0CAEsC;IACtC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;CACtD;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,UAAU,EAAE,oBAAoB,CAAC;IACjC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC,GAAG,iBAAiB,CAQpB"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure partition helpers for chunked steps.
|
|
3
|
+
*
|
|
4
|
+
* This module is the single source of truth for partition validation
|
|
5
|
+
* and the default partition-range shape. It is deliberately
|
|
6
|
+
* dependency-light: no `@nest-batch/bullmq`, no `@nest-batch/kafka`,
|
|
7
|
+
* no ORMs, no cron — verified by
|
|
8
|
+
* `packages/core/tests/core/boundary/no-forbidden-imports.test.ts`.
|
|
9
|
+
*
|
|
10
|
+
* The helpers are consumed by:
|
|
11
|
+
* - `packages/core/src/compiler/definition-compiler.ts` (validation
|
|
12
|
+
* at compile time),
|
|
13
|
+
* - `packages/core/src/core/validation/definition-validator.ts`
|
|
14
|
+
* (cross-checks the resolved `JobDefinition`),
|
|
15
|
+
* - `packages/core/src/execution/in-process-execution-strategy.ts`
|
|
16
|
+
* (the in-process adapter's partition guard),
|
|
17
|
+
* - `packages/bullmq/src/bullmq-runtime.service.ts` (the BullMQ
|
|
18
|
+
* strategy's enqueue fan-out + the worker's `partitionIndex`
|
|
19
|
+
* enforcement),
|
|
20
|
+
* - `packages/kafka/src/kafka-runtime.service.ts` (the Kafka
|
|
21
|
+
* mirror — T9).
|
|
22
|
+
*
|
|
23
|
+
* Pinned by:
|
|
24
|
+
* - `docs/RELEASE-0.2.0.md §6` — the v1 partition contract.
|
|
25
|
+
* - `packages/bullmq/tests/partition-invariant.test.ts` — T-AC-3
|
|
26
|
+
* first half (the BullMQ side).
|
|
27
|
+
* - `packages/kafka/tests/partition-invariant.test.ts` — T-AC-3
|
|
28
|
+
* second half (the Kafka side, T9).
|
|
29
|
+
*/ "use strict";
|
|
30
|
+
Object.defineProperty(exports, "__esModule", {
|
|
31
|
+
value: true
|
|
32
|
+
});
|
|
33
|
+
function _export(target, all) {
|
|
34
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
35
|
+
enumerable: true,
|
|
36
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
_export(exports, {
|
|
40
|
+
get INVALID_PARTITION_INDEX () {
|
|
41
|
+
return INVALID_PARTITION_INDEX;
|
|
42
|
+
},
|
|
43
|
+
get InvalidPartitionsError () {
|
|
44
|
+
return InvalidPartitionsError;
|
|
45
|
+
},
|
|
46
|
+
get defaultRange () {
|
|
47
|
+
return defaultRange;
|
|
48
|
+
},
|
|
49
|
+
get enforcePartitionIndex () {
|
|
50
|
+
return enforcePartitionIndex;
|
|
51
|
+
},
|
|
52
|
+
get resolvePartition () {
|
|
53
|
+
return resolvePartition;
|
|
54
|
+
},
|
|
55
|
+
get validatePartitions () {
|
|
56
|
+
return validatePartitions;
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
const INVALID_PARTITION_INDEX = 'INVALID_PARTITION_INDEX';
|
|
60
|
+
let InvalidPartitionsError = class InvalidPartitionsError extends Error {
|
|
61
|
+
details;
|
|
62
|
+
code;
|
|
63
|
+
constructor(message, details){
|
|
64
|
+
super(message), this.details = details;
|
|
65
|
+
this.name = 'InvalidPartitionsError';
|
|
66
|
+
this.code = 'INVALID_PARTITIONS';
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
function validatePartitions(partitions) {
|
|
70
|
+
if (partitions === undefined) return;
|
|
71
|
+
if (!Number.isInteger(partitions.count) || partitions.count <= 0) {
|
|
72
|
+
throw new InvalidPartitionsError(`ChunkStepDefinition.partitions.count must be a positive integer, got ${String(partitions.count)}`, {
|
|
73
|
+
count: partitions.count
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
if (partitions.range !== undefined && typeof partitions.range !== 'function') {
|
|
77
|
+
throw new InvalidPartitionsError(`ChunkStepDefinition.partitions.range must be a function when present, got ${typeof partitions.range}`, {
|
|
78
|
+
rangeType: typeof partitions.range
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function defaultRange(i, n, total) {
|
|
83
|
+
if (!Number.isInteger(i) || i < 0 || i >= n) {
|
|
84
|
+
throw new InvalidPartitionsError(`defaultRange: partition index ${i} out of range [0, ${n})`, {
|
|
85
|
+
i,
|
|
86
|
+
n
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
if (!Number.isInteger(n) || n <= 0) {
|
|
90
|
+
throw new InvalidPartitionsError(`defaultRange: count ${n} must be a positive integer`, {
|
|
91
|
+
n
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
if (!Number.isFinite(total) || total < 0) {
|
|
95
|
+
throw new InvalidPartitionsError(`defaultRange: total ${total} must be a non-negative finite number`, {
|
|
96
|
+
total
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
const from = Math.floor(i * total / n);
|
|
100
|
+
const to = Math.floor((i + 1) * total / n);
|
|
101
|
+
return [
|
|
102
|
+
from,
|
|
103
|
+
to
|
|
104
|
+
];
|
|
105
|
+
}
|
|
106
|
+
function enforcePartitionIndex(partitionIndex, count) {
|
|
107
|
+
if (partitionIndex === undefined) {
|
|
108
|
+
throw new InvalidPartitionsError(`partitionIndex is required for a partitioned step (count=${count})`, {
|
|
109
|
+
count
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
if (!Number.isInteger(partitionIndex) || partitionIndex < 0 || partitionIndex >= count) {
|
|
113
|
+
throw new InvalidPartitionsError(`partitionIndex ${partitionIndex} is out of range [0, ${count})`, {
|
|
114
|
+
partitionIndex,
|
|
115
|
+
count
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function resolvePartition(args) {
|
|
120
|
+
enforcePartitionIndex(args.partitionIndex, args.partitions.count);
|
|
121
|
+
const index = args.partitionIndex;
|
|
122
|
+
if (args.partitions.range === undefined) {
|
|
123
|
+
return {
|
|
124
|
+
count: args.partitions.count,
|
|
125
|
+
index
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
const range = args.partitions.range(index, args.partitions.count);
|
|
129
|
+
return {
|
|
130
|
+
count: args.partitions.count,
|
|
131
|
+
index,
|
|
132
|
+
range
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
//# sourceMappingURL=partition-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/partition-helpers.ts"],"sourcesContent":["/**\n * Pure partition helpers for chunked steps.\n *\n * This module is the single source of truth for partition validation\n * and the default partition-range shape. It is deliberately\n * dependency-light: no `@nest-batch/bullmq`, no `@nest-batch/kafka`,\n * no ORMs, no cron — verified by\n * `packages/core/tests/core/boundary/no-forbidden-imports.test.ts`.\n *\n * The helpers are consumed by:\n * - `packages/core/src/compiler/definition-compiler.ts` (validation\n * at compile time),\n * - `packages/core/src/core/validation/definition-validator.ts`\n * (cross-checks the resolved `JobDefinition`),\n * - `packages/core/src/execution/in-process-execution-strategy.ts`\n * (the in-process adapter's partition guard),\n * - `packages/bullmq/src/bullmq-runtime.service.ts` (the BullMQ\n * strategy's enqueue fan-out + the worker's `partitionIndex`\n * enforcement),\n * - `packages/kafka/src/kafka-runtime.service.ts` (the Kafka\n * mirror — T9).\n *\n * Pinned by:\n * - `docs/RELEASE-0.2.0.md §6` — the v1 partition contract.\n * - `packages/bullmq/tests/partition-invariant.test.ts` — T-AC-3\n * first half (the BullMQ side).\n * - `packages/kafka/tests/partition-invariant.test.ts` — T-AC-3\n * second half (the Kafka side, T9).\n */\n\nimport type { ChunkPartitionConfig } from './core/ir/step-definition';\n\n/**\n * Error code returned / thrown by the partition helpers. Stable for\n * callers that want to switch on it (the BullMQ / Kafka workers\n * surface this in their `exitMessage` when a partition payload is\n * out of range).\n */\nexport const INVALID_PARTITION_INDEX = 'INVALID_PARTITION_INDEX';\n\n/**\n * Thrown when a partition's `count` is not a positive integer, or\n * when a runtime-resolved `partitionIndex` falls outside `[0, count)`.\n *\n * Distinct from `InvalidFlowGraphError` because this is a *value*\n * problem (the input is out of range) rather than a *graph*\n * problem (the step graph is malformed). The `code` is stable.\n */\nexport class InvalidPartitionsError extends Error {\n readonly code: string;\n constructor(message: string, public readonly details?: unknown) {\n super(message);\n this.name = 'InvalidPartitionsError';\n this.code = 'INVALID_PARTITIONS';\n }\n}\n\n/**\n * Validate a `ChunkPartitionConfig` at compile time. Throws\n * `InvalidPartitionsError` when the config is structurally invalid:\n *\n * - `count` is not a finite integer\n * - `count <= 0` (a partition count of zero is meaningless)\n * - `range` is set but is not a function\n *\n * `count === 1` is allowed but the runtime short-circuits it to\n * the non-partitioned path; we still validate it here so a typo\n * (`count: 0` vs `count: 1`) fails loudly at the compiler.\n */\nexport function validatePartitions(partitions: ChunkPartitionConfig | undefined): void {\n if (partitions === undefined) return;\n if (!Number.isInteger(partitions.count) || partitions.count <= 0) {\n throw new InvalidPartitionsError(\n `ChunkStepDefinition.partitions.count must be a positive integer, got ${String(\n partitions.count,\n )}`,\n { count: partitions.count },\n );\n }\n if (partitions.range !== undefined && typeof partitions.range !== 'function') {\n throw new InvalidPartitionsError(\n `ChunkStepDefinition.partitions.range must be a function when present, got ${typeof partitions.range}`,\n { rangeType: typeof partitions.range },\n );\n }\n}\n\n/**\n * The default even-split partition range, given a known total item\n * count. The formula mirrors the v1 contract in\n * `docs/RELEASE-0.2.0.md §6.1`:\n *\n * partition `i` of `n` over `total` items:\n * [floor(i * total / n), floor((i+1) * total / n))\n *\n * Pure function. Exported so hosts that want the \"even split\"\n * behaviour without re-implementing the math can reuse it:\n *\n * const r = defaultRange(i, n, total);\n * partitions: { count: n, range: (i, n) => defaultRange(i, n, total) }\n *\n * `total` is required because the runtime has no generic way to\n * count the input — only the host's reader knows. The math is\n * robust to `total === 0` (returns `[0, 0)` for every partition).\n */\nexport function defaultRange(\n i: number,\n n: number,\n total: number,\n): readonly [from: number, to: number] {\n if (!Number.isInteger(i) || i < 0 || i >= n) {\n throw new InvalidPartitionsError(\n `defaultRange: partition index ${i} out of range [0, ${n})`,\n { i, n },\n );\n }\n if (!Number.isInteger(n) || n <= 0) {\n throw new InvalidPartitionsError(`defaultRange: count ${n} must be a positive integer`, { n });\n }\n if (!Number.isFinite(total) || total < 0) {\n throw new InvalidPartitionsError(\n `defaultRange: total ${total} must be a non-negative finite number`,\n { total },\n );\n }\n const from = Math.floor((i * total) / n);\n const to = Math.floor(((i + 1) * total) / n);\n return [from, to] as const;\n}\n\n/**\n * Runtime check that a `partitionIndex` on a job payload is in\n * range for the configured `count`. Throws\n * `InvalidPartitionsError` when the index is undefined, not an\n * integer, negative, or `>= count`.\n *\n * The BullMQ / Kafka worker's `processJob` calls this with the\n * payload's `partitionIndex` and the step's `partitions.count` so\n * an out-of-range index becomes a hard step failure (the runtime\n * surfaces it as `FAILED` with the invariant violation in the\n * `exitMessage`).\n */\nexport function enforcePartitionIndex(\n partitionIndex: number | undefined,\n count: number,\n): void {\n if (partitionIndex === undefined) {\n throw new InvalidPartitionsError(\n `partitionIndex is required for a partitioned step (count=${count})`,\n { count },\n );\n }\n if (\n !Number.isInteger(partitionIndex) ||\n partitionIndex < 0 ||\n partitionIndex >= count\n ) {\n throw new InvalidPartitionsError(\n `partitionIndex ${partitionIndex} is out of range [0, ${count})`,\n { partitionIndex, count },\n );\n }\n}\n\n/**\n * Resolved partition info passed through the runtime. Built from\n * the step's `partitions` config and the BullMQ / Kafka payload's\n * `partitionIndex`. The runtime uses this to:\n * - bound the chunk executor's read loop (when the host provided\n * a `range` resolver),\n * - tag the persisted `StepExecution` for diagnostics (a future\n * task; the v1 contract only requires the chunk executor to\n * honour the range).\n */\nexport interface ResolvedPartition {\n readonly count: number;\n readonly index: number;\n /** The partition's resolved `[from, to)` range, or `undefined`\n * when the step did not provide a `range` resolver (the default\n * behaviour is \"read until EOF\"). */\n readonly range?: readonly [from: number, to: number];\n}\n\n/**\n * Resolve a partition's metadata from the step's `partitions`\n * config and the transport's `partitionIndex`. Calls\n * `enforcePartitionIndex` to fail loudly on out-of-range indices.\n *\n * The `range` is computed only when the step provides a resolver;\n * otherwise the returned `ResolvedPartition` is `count` + `index`\n * with no `range`, and the chunk executor reads until EOF.\n */\nexport function resolvePartition(args: {\n partitions: ChunkPartitionConfig;\n partitionIndex: number | undefined;\n}): ResolvedPartition {\n enforcePartitionIndex(args.partitionIndex, args.partitions.count);\n const index = args.partitionIndex as number;\n if (args.partitions.range === undefined) {\n return { count: args.partitions.count, index };\n }\n const range = args.partitions.range(index, args.partitions.count);\n return { count: args.partitions.count, index, range };\n}\n"],"names":["INVALID_PARTITION_INDEX","InvalidPartitionsError","defaultRange","enforcePartitionIndex","resolvePartition","validatePartitions","Error","code","message","details","name","partitions","undefined","Number","isInteger","count","String","range","rangeType","i","n","total","isFinite","from","Math","floor","to","partitionIndex","args","index"],"mappings":"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"}
|