@pattern-stack/codegen 0.16.1 → 0.17.1
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/CHANGELOG.md +121 -0
- package/consumer-skills/entities/families-and-queries.md +5 -3
- package/consumer-skills/integration/audit-and-detection.md +29 -4
- package/dist/{chunk-H6FO2ZDJ.js → chunk-4PFF3ED4.js} +4 -4
- package/dist/{chunk-CO6LUM72.js → chunk-7P5ODGLA.js} +34 -2
- package/dist/chunk-7P5ODGLA.js.map +1 -0
- package/dist/{chunk-QSJ3J4HE.js → chunk-BHZP6LOV.js} +7 -7
- package/dist/{chunk-RUSUZZAF.js → chunk-BK5ICA2F.js} +4 -4
- package/dist/{chunk-T4YJRD22.js → chunk-DUMI2J5M.js} +45 -14
- package/dist/chunk-DUMI2J5M.js.map +1 -0
- package/dist/{chunk-TKVTEUBD.js → chunk-EJBK7I4F.js} +2 -2
- package/dist/{chunk-IT6FRTEW.js → chunk-FVNAU7VO.js} +39 -18
- package/dist/chunk-FVNAU7VO.js.map +1 -0
- package/dist/{chunk-JM3T27ZW.js → chunk-FWRL7BZ5.js} +7 -7
- package/dist/{chunk-DGYTSCKN.js → chunk-HOIRY5XP.js} +14 -14
- package/dist/{chunk-AYC2HEAL.js → chunk-HPS554L4.js} +9 -9
- package/dist/{chunk-2WDX6I7T.js → chunk-IOQMMH6C.js} +16 -6
- package/dist/{chunk-2WDX6I7T.js.map → chunk-IOQMMH6C.js.map} +1 -1
- package/dist/{chunk-24WXSC3C.js → chunk-JA7GJDNI.js} +15 -9
- package/dist/chunk-JA7GJDNI.js.map +1 -0
- package/dist/{chunk-36U5UGIO.js → chunk-JEINYUJH.js} +8 -5
- package/dist/chunk-JEINYUJH.js.map +1 -0
- package/dist/{chunk-BOPZWRJK.js → chunk-JYBFPNBJ.js} +8 -8
- package/dist/chunk-JYBFPNBJ.js.map +1 -0
- package/dist/{chunk-K2I6XIK5.js → chunk-KSTZIULO.js} +4 -4
- package/dist/chunk-MKWQKKK7.js +72 -0
- package/dist/chunk-MKWQKKK7.js.map +1 -0
- package/dist/{chunk-CRBVI4GE.js → chunk-PSDVGPQR.js} +5 -5
- package/dist/{chunk-DLG62MQY.js → chunk-SFQRETXJ.js} +7 -7
- package/dist/{chunk-NXNVTXKG.js → chunk-SGSWVNNB.js} +5 -5
- package/dist/{chunk-5LXOJGO2.js → chunk-VNBC3VXM.js} +6 -6
- package/dist/{job-orchestrator.protocol-DubMVbm9.d.ts → job-orchestrator.protocol-ZuJ3ow-O.d.ts} +77 -3
- package/dist/runtime/base-classes/activity-entity-repository.d.ts +39 -7
- package/dist/runtime/base-classes/activity-entity-repository.js +1 -1
- package/dist/runtime/base-classes/activity-entity-service.d.ts +12 -10
- package/dist/runtime/base-classes/activity-entity-service.js +1 -1
- package/dist/runtime/base-classes/index.js +18 -18
- package/dist/runtime/shared/openapi/index.js +3 -3
- package/dist/runtime/subsystems/auth/index.js +3 -3
- package/dist/runtime/subsystems/bridge/bridge-delivery-handler.d.ts +1 -1
- package/dist/runtime/subsystems/bridge/bridge-delivery-handler.js +2 -2
- package/dist/runtime/subsystems/bridge/bridge-delivery.drizzle-backend.js +2 -2
- package/dist/runtime/subsystems/bridge/bridge-outbox-drain-hook.js +6 -6
- package/dist/runtime/subsystems/bridge/bridge.module.d.ts +1 -1
- package/dist/runtime/subsystems/bridge/bridge.module.js +19 -19
- package/dist/runtime/subsystems/bridge/event-flow.service.d.ts +1 -1
- package/dist/runtime/subsystems/bridge/index.d.ts +1 -1
- package/dist/runtime/subsystems/bridge/index.js +21 -21
- package/dist/runtime/subsystems/cache/cache.module.js +1 -1
- package/dist/runtime/subsystems/cache/index.js +3 -3
- package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js +2 -2
- package/dist/runtime/subsystems/events/events.module.js +3 -3
- package/dist/runtime/subsystems/events/index.js +3 -3
- package/dist/runtime/subsystems/index.d.ts +1 -1
- package/dist/runtime/subsystems/index.js +50 -50
- package/dist/runtime/subsystems/integration/deep-equal.differ.d.ts +19 -0
- package/dist/runtime/subsystems/integration/deep-equal.differ.js +1 -1
- package/dist/runtime/subsystems/integration/index.js +22 -22
- package/dist/runtime/subsystems/integration/integration.module.d.ts +20 -0
- package/dist/runtime/subsystems/integration/integration.module.js +4 -4
- package/dist/runtime/subsystems/jobs/index.d.ts +1 -1
- package/dist/runtime/subsystems/jobs/index.js +43 -43
- package/dist/runtime/subsystems/jobs/job-handler.base.d.ts +1 -1
- package/dist/runtime/subsystems/jobs/job-handler.base.js +11 -3
- package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.d.ts +1 -1
- package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js +7 -6
- package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-orchestrator.drizzle-backend.d.ts +1 -1
- package/dist/runtime/subsystems/jobs/job-orchestrator.drizzle-backend.js +4 -3
- package/dist/runtime/subsystems/jobs/job-orchestrator.memory-backend.d.ts +11 -1
- package/dist/runtime/subsystems/jobs/job-orchestrator.memory-backend.js +3 -3
- package/dist/runtime/subsystems/jobs/job-orchestrator.protocol.d.ts +1 -1
- package/dist/runtime/subsystems/jobs/job-run-keyset-cursor.d.ts +1 -1
- package/dist/runtime/subsystems/jobs/job-run-service.drizzle-backend.d.ts +1 -1
- package/dist/runtime/subsystems/jobs/job-run-service.drizzle-backend.js +3 -3
- package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.d.ts +1 -1
- package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.js +3 -3
- package/dist/runtime/subsystems/jobs/job-run-service.protocol.d.ts +1 -1
- package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.d.ts +1 -1
- package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js +3 -3
- package/dist/runtime/subsystems/jobs/job-worker.d.ts +1 -1
- package/dist/runtime/subsystems/jobs/job-worker.js +3 -3
- package/dist/runtime/subsystems/jobs/job-worker.module.d.ts +1 -1
- package/dist/runtime/subsystems/jobs/job-worker.module.js +13 -13
- package/dist/runtime/subsystems/jobs/jobs-domain.module.js +11 -11
- package/dist/runtime/subsystems/jobs/jobs-errors.d.ts +1 -1
- package/dist/runtime/subsystems/observability/index.d.ts +1 -1
- package/dist/runtime/subsystems/observability/observability.protocol.d.ts +1 -1
- package/dist/runtime/subsystems/observability/observability.service.d.ts +1 -1
- package/dist/runtime/subsystems/observability/reporters/bridge-metrics.reporter.d.ts +1 -1
- package/dist/runtime/subsystems/observability/reporters/index.d.ts +1 -1
- package/dist/runtime/subsystems/storage/index.js +4 -4
- package/dist/runtime/subsystems/storage/storage.module.js +2 -2
- package/dist/src/cli/index.js +34 -12
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/index.d.ts +23 -8
- package/dist/src/index.js +7 -7
- package/package.json +2 -1
- package/runtime/base-classes/activity-entity-repository.ts +72 -13
- package/runtime/base-classes/activity-entity-service.ts +14 -12
- package/runtime/subsystems/integration/deep-equal.differ.ts +34 -5
- package/runtime/subsystems/integration/integration.module.ts +26 -2
- package/runtime/subsystems/jobs/job-handler.base.ts +115 -2
- package/runtime/subsystems/jobs/job-orchestrator.drizzle-backend.ts +43 -16
- package/runtime/subsystems/jobs/job-orchestrator.memory-backend.ts +58 -18
- package/src/patterns/library/activity.pattern.ts +40 -10
- package/templates/subsystem/integration-config/codegen-config-integration-block.ejs.t +17 -0
- package/dist/chunk-24WXSC3C.js.map +0 -1
- package/dist/chunk-36U5UGIO.js.map +0 -1
- package/dist/chunk-BOPZWRJK.js.map +0 -1
- package/dist/chunk-CO6LUM72.js.map +0 -1
- package/dist/chunk-IT6FRTEW.js.map +0 -1
- package/dist/chunk-T4YJRD22.js.map +0 -1
- package/dist/chunk-XCEI7NUH.js +0 -41
- package/dist/chunk-XCEI7NUH.js.map +0 -1
- /package/dist/{chunk-H6FO2ZDJ.js.map → chunk-4PFF3ED4.js.map} +0 -0
- /package/dist/{chunk-QSJ3J4HE.js.map → chunk-BHZP6LOV.js.map} +0 -0
- /package/dist/{chunk-RUSUZZAF.js.map → chunk-BK5ICA2F.js.map} +0 -0
- /package/dist/{chunk-TKVTEUBD.js.map → chunk-EJBK7I4F.js.map} +0 -0
- /package/dist/{chunk-JM3T27ZW.js.map → chunk-FWRL7BZ5.js.map} +0 -0
- /package/dist/{chunk-DGYTSCKN.js.map → chunk-HOIRY5XP.js.map} +0 -0
- /package/dist/{chunk-AYC2HEAL.js.map → chunk-HPS554L4.js.map} +0 -0
- /package/dist/{chunk-K2I6XIK5.js.map → chunk-KSTZIULO.js.map} +0 -0
- /package/dist/{chunk-CRBVI4GE.js.map → chunk-PSDVGPQR.js.map} +0 -0
- /package/dist/{chunk-DLG62MQY.js.map → chunk-SFQRETXJ.js.map} +0 -0
- /package/dist/{chunk-NXNVTXKG.js.map → chunk-SGSWVNNB.js.map} +0 -0
- /package/dist/{chunk-5LXOJGO2.js.map → chunk-VNBC3VXM.js.map} +0 -0
|
@@ -1,36 +1,23 @@
|
|
|
1
1
|
import "../../../chunk-KVOWSC5S.js";
|
|
2
2
|
import {
|
|
3
3
|
IntegrationModule
|
|
4
|
-
} from "../../../chunk-
|
|
5
|
-
import {
|
|
6
|
-
MemoryRunRecorder
|
|
7
|
-
} from "../../../chunk-EO2QPOKH.js";
|
|
4
|
+
} from "../../../chunk-JA7GJDNI.js";
|
|
8
5
|
import {
|
|
9
6
|
createLoopbackMiddleware
|
|
10
7
|
} from "../../../chunk-PRWIX6UW.js";
|
|
11
|
-
import {
|
|
12
|
-
PostgresCursorStore
|
|
13
|
-
} from "../../../chunk-XWBK3XJK.js";
|
|
14
8
|
import {
|
|
15
9
|
MemoryCursorStore
|
|
16
10
|
} from "../../../chunk-AHV4GDYM.js";
|
|
17
11
|
import {
|
|
18
12
|
DrizzleIntegrationRunRecorder
|
|
19
13
|
} from "../../../chunk-YK5JEVLX.js";
|
|
14
|
+
import {
|
|
15
|
+
MemoryRunRecorder
|
|
16
|
+
} from "../../../chunk-EO2QPOKH.js";
|
|
20
17
|
import {
|
|
21
18
|
FieldDiffSchema,
|
|
22
19
|
FieldDiffValueSchema
|
|
23
20
|
} from "../../../chunk-SQDOBLBP.js";
|
|
24
|
-
import {
|
|
25
|
-
CURSOR_DIVISIBILITY,
|
|
26
|
-
CursorStrategySchema,
|
|
27
|
-
DetectionConfigSchema,
|
|
28
|
-
FieldMappingSchema,
|
|
29
|
-
PollDetectionSchema,
|
|
30
|
-
ResolvedFilterSchema,
|
|
31
|
-
WebhookDetectionSchema,
|
|
32
|
-
isDivisibleCursor
|
|
33
|
-
} from "../../../chunk-5TK7MEN4.js";
|
|
34
21
|
import {
|
|
35
22
|
MemoryEntityChangeSourceRegistry
|
|
36
23
|
} from "../../../chunk-4KNXX6TI.js";
|
|
@@ -40,6 +27,13 @@ import {
|
|
|
40
27
|
import {
|
|
41
28
|
ExecuteIntegrationUseCase
|
|
42
29
|
} from "../../../chunk-TDEHU73T.js";
|
|
30
|
+
import {
|
|
31
|
+
IncrementalReadBase,
|
|
32
|
+
mapConcurrent
|
|
33
|
+
} from "../../../chunk-LG57S2SC.js";
|
|
34
|
+
import {
|
|
35
|
+
PostgresCursorStore
|
|
36
|
+
} from "../../../chunk-XWBK3XJK.js";
|
|
43
37
|
import {
|
|
44
38
|
ENTITY_CHANGE_SOURCE_REGISTRY,
|
|
45
39
|
INTEGRATION_CHANGE_SOURCE,
|
|
@@ -54,10 +48,6 @@ import {
|
|
|
54
48
|
MissingTenantIdError,
|
|
55
49
|
assertTenantId
|
|
56
50
|
} from "../../../chunk-MZ6GV4YF.js";
|
|
57
|
-
import {
|
|
58
|
-
IncrementalReadBase,
|
|
59
|
-
mapConcurrent
|
|
60
|
-
} from "../../../chunk-LG57S2SC.js";
|
|
61
51
|
import {
|
|
62
52
|
integrationRunActionEnum,
|
|
63
53
|
integrationRunDirectionEnum,
|
|
@@ -79,7 +69,17 @@ import {
|
|
|
79
69
|
} from "../../../chunk-TIZXQU26.js";
|
|
80
70
|
import {
|
|
81
71
|
DeepEqualDiffer
|
|
82
|
-
} from "../../../chunk-
|
|
72
|
+
} from "../../../chunk-JEINYUJH.js";
|
|
73
|
+
import {
|
|
74
|
+
CURSOR_DIVISIBILITY,
|
|
75
|
+
CursorStrategySchema,
|
|
76
|
+
DetectionConfigSchema,
|
|
77
|
+
FieldMappingSchema,
|
|
78
|
+
PollDetectionSchema,
|
|
79
|
+
ResolvedFilterSchema,
|
|
80
|
+
WebhookDetectionSchema,
|
|
81
|
+
isDivisibleCursor
|
|
82
|
+
} from "../../../chunk-5TK7MEN4.js";
|
|
83
83
|
import "../../../chunk-U64T4YZE.js";
|
|
84
84
|
import "../../../chunk-2E224ZSN.js";
|
|
85
85
|
export {
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { DynamicModule } from '@nestjs/common';
|
|
2
|
+
import { DeepEqualDifferOptions } from './deep-equal.differ.js';
|
|
3
|
+
import './integration-field-diff.protocol.js';
|
|
4
|
+
import 'zod';
|
|
2
5
|
|
|
3
6
|
/**
|
|
4
7
|
* IntegrationModule — `DynamicModule.forRoot({ backend, multiTenant? })` factory
|
|
@@ -88,6 +91,23 @@ interface IntegrationModuleOptions {
|
|
|
88
91
|
* Defaults to `false`.
|
|
89
92
|
*/
|
|
90
93
|
multiTenant?: boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Default-differ configuration (DIFFER-UNIGNORE, 0.17.1). Threaded into the
|
|
96
|
+
* `DeepEqualDiffer` bound to `INTEGRATION_FIELD_DIFFER`. Omit for the
|
|
97
|
+
* historical behaviour (the default ignore list, unchanged).
|
|
98
|
+
*
|
|
99
|
+
* Mirrors `DeepEqualDifferOptions`:
|
|
100
|
+
* - `ignore` — extra field names to ignore (merged with the defaults).
|
|
101
|
+
* - `unignore` — default-ignored field names to RE-include as domain data
|
|
102
|
+
* (e.g. `['deletedAt']` for an entity whose `deletedAt` is a
|
|
103
|
+
* vendor-observed retraction tombstone, not row metadata — swe-brain
|
|
104
|
+
* ADR-0008 §1). Subtracted after the merge, so it wins.
|
|
105
|
+
*
|
|
106
|
+
* A feature module that binds its own `IFieldDiffer<T>` to
|
|
107
|
+
* `INTEGRATION_FIELD_DIFFER` overrides this entirely (per-entity escape hatch
|
|
108
|
+
* unchanged).
|
|
109
|
+
*/
|
|
110
|
+
differ?: DeepEqualDifferOptions;
|
|
91
111
|
}
|
|
92
112
|
declare class IntegrationModule {
|
|
93
113
|
static forRoot(options: IntegrationModuleOptions): DynamicModule;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
IntegrationModule
|
|
3
|
-
} from "../../../chunk-
|
|
4
|
-
import "../../../chunk-EO2QPOKH.js";
|
|
5
|
-
import "../../../chunk-XWBK3XJK.js";
|
|
3
|
+
} from "../../../chunk-JA7GJDNI.js";
|
|
6
4
|
import "../../../chunk-AHV4GDYM.js";
|
|
7
5
|
import "../../../chunk-YK5JEVLX.js";
|
|
6
|
+
import "../../../chunk-EO2QPOKH.js";
|
|
8
7
|
import "../../../chunk-SQDOBLBP.js";
|
|
8
|
+
import "../../../chunk-XWBK3XJK.js";
|
|
9
9
|
import "../../../chunk-S7C6TIIF.js";
|
|
10
10
|
import "../../../chunk-MZ6GV4YF.js";
|
|
11
11
|
import "../../../chunk-HNWZFNKP.js";
|
|
12
|
-
import "../../../chunk-
|
|
12
|
+
import "../../../chunk-JEINYUJH.js";
|
|
13
13
|
import "../../../chunk-U64T4YZE.js";
|
|
14
14
|
import "../../../chunk-2E224ZSN.js";
|
|
15
15
|
export {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { JobDefinitionRow, JobRunRow, JobStepRow, collisionModeEnum, jobRunStatusEnum, jobRuns, jobStepKindEnum, jobStepStatusEnum, jobSteps, jobs, parentClosePolicyEnum, replayFromEnum, triggerSourceEnum, waitKindEnum } from './job-orchestration.schema.js';
|
|
2
2
|
export { JOBS_LISTEN_NOTIFY, JOBS_MULTI_TENANT, JOB_ORCHESTRATOR, JOB_RUN_SERVICE, JOB_STEP_SERVICE } from './jobs-domain.tokens.js';
|
|
3
|
-
export { C as CancelOptions, a as ConcurrencyPolicy, D as DedupePolicy, H as HandlerRegistry, b as HandlerRegistryEntry, I as IJobOrchestrator, J as JOB_HANDLER_METADATA_KEY, c as JOB_HANDLER_REGISTRY, d as JobContext, e as JobHandler, f as JobHandlerBase, g as JobHandlerMeta, h as JobPoolDef, i as JobRun, j as JobUpsertEntry, P as ParentClosePolicy, R as RetryPolicy, S as ScopeRef, k as SpawnChildOptions, l as StartOptions, m as StepOptions } from '../../../job-orchestrator.protocol-
|
|
3
|
+
export { C as CancelOptions, a as ConcurrencyPolicy, D as DedupePolicy, H as HandlerRegistry, b as HandlerRegistryEntry, I as IJobOrchestrator, J as JOB_HANDLER_METADATA_KEY, c as JOB_HANDLER_REGISTRY, d as JobContext, e as JobHandler, f as JobHandlerBase, g as JobHandlerMeta, h as JobPoolDef, i as JobRun, j as JobUpsertEntry, P as ParentClosePolicy, R as RetryPolicy, S as ScopeRef, k as SpawnChildOptions, l as StartOptions, m as StepOptions } from '../../../job-orchestrator.protocol-ZuJ3ow-O.js';
|
|
4
4
|
export { CancelForScopeOptions, IJobRunService, JobRunFailure, JobRunPage, JobRunSummary, ListForScopeOptions, ListJobRunsQuery, PoolStatusCount, RescheduleForScopeOptions } from './job-run-service.protocol.js';
|
|
5
5
|
export { IJobStepService, JobStep, RecordStepInput } from './job-step-service.protocol.js';
|
|
6
6
|
export { DrizzleJobOrchestrator } from './job-orchestrator.drizzle-backend.js';
|
|
@@ -2,7 +2,7 @@ import "../../../chunk-W4HOHZVF.js";
|
|
|
2
2
|
import {
|
|
3
3
|
JobWorkerModule,
|
|
4
4
|
JobWorkerOrchestrator
|
|
5
|
-
} from "../../../chunk-
|
|
5
|
+
} from "../../../chunk-HPS554L4.js";
|
|
6
6
|
import {
|
|
7
7
|
JOB_WORKER_OPTIONS,
|
|
8
8
|
JobWorker,
|
|
@@ -10,20 +10,41 @@ import {
|
|
|
10
10
|
buildStaleSweepQuery,
|
|
11
11
|
classifyError,
|
|
12
12
|
computeBackoff
|
|
13
|
-
} from "../../../chunk-
|
|
13
|
+
} from "../../../chunk-FWRL7BZ5.js";
|
|
14
14
|
import {
|
|
15
15
|
JobsDomainModule
|
|
16
|
-
} from "../../../chunk-
|
|
16
|
+
} from "../../../chunk-HOIRY5XP.js";
|
|
17
|
+
import {
|
|
18
|
+
DrizzleJobStepService
|
|
19
|
+
} from "../../../chunk-DV4RV2DC.js";
|
|
20
|
+
import {
|
|
21
|
+
DrizzleJobOrchestrator
|
|
22
|
+
} from "../../../chunk-FVNAU7VO.js";
|
|
23
|
+
import {
|
|
24
|
+
MemoryJobOrchestrator
|
|
25
|
+
} from "../../../chunk-DUMI2J5M.js";
|
|
26
|
+
import {
|
|
27
|
+
MemoryJobStepService
|
|
28
|
+
} from "../../../chunk-PNZSGAB2.js";
|
|
17
29
|
import {
|
|
18
30
|
DrizzleJobRunService
|
|
19
|
-
} from "../../../chunk-
|
|
31
|
+
} from "../../../chunk-VNBC3VXM.js";
|
|
20
32
|
import {
|
|
21
33
|
MemoryJobRunService
|
|
22
|
-
} from "../../../chunk-
|
|
23
|
-
import "../../../chunk-L3LZWWSX.js";
|
|
34
|
+
} from "../../../chunk-BHZP6LOV.js";
|
|
24
35
|
import {
|
|
25
|
-
|
|
26
|
-
} from "../../../chunk-
|
|
36
|
+
MemoryJobStore
|
|
37
|
+
} from "../../../chunk-SNQ3TOWP.js";
|
|
38
|
+
import {
|
|
39
|
+
BootValidationError,
|
|
40
|
+
JobCollisionError,
|
|
41
|
+
JobNotReplayableError,
|
|
42
|
+
JobTemplateFieldMissingError,
|
|
43
|
+
JobTypeNotFoundError,
|
|
44
|
+
MissingTenantIdError,
|
|
45
|
+
ReservedPoolViolationError
|
|
46
|
+
} from "../../../chunk-T4BIIU5E.js";
|
|
47
|
+
import "../../../chunk-L3LZWWSX.js";
|
|
27
48
|
import {
|
|
28
49
|
BULLMQ_CONNECTION,
|
|
29
50
|
BULLMQ_RESOLVED_CONFIG,
|
|
@@ -38,8 +59,20 @@ import {
|
|
|
38
59
|
loadPoolConfig
|
|
39
60
|
} from "../../../chunk-RHVN6NA7.js";
|
|
40
61
|
import {
|
|
41
|
-
|
|
42
|
-
|
|
62
|
+
JOBS_LISTEN_NOTIFY,
|
|
63
|
+
JOBS_MULTI_TENANT,
|
|
64
|
+
JOB_ORCHESTRATOR,
|
|
65
|
+
JOB_RUN_SERVICE,
|
|
66
|
+
JOB_STEP_SERVICE
|
|
67
|
+
} from "../../../chunk-ZPL74UQN.js";
|
|
68
|
+
import {
|
|
69
|
+
HandlerRegistry,
|
|
70
|
+
JOB_HANDLER_METADATA_KEY,
|
|
71
|
+
JOB_HANDLER_REGISTRY,
|
|
72
|
+
JobHandler,
|
|
73
|
+
JobHandlerBase,
|
|
74
|
+
ParentClosePolicy
|
|
75
|
+
} from "../../../chunk-7P5ODGLA.js";
|
|
43
76
|
import {
|
|
44
77
|
collisionModeEnum,
|
|
45
78
|
jobRunStatusEnum,
|
|
@@ -53,39 +86,6 @@ import {
|
|
|
53
86
|
triggerSourceEnum,
|
|
54
87
|
waitKindEnum
|
|
55
88
|
} from "../../../chunk-OKXZ63IA.js";
|
|
56
|
-
import {
|
|
57
|
-
MemoryJobOrchestrator
|
|
58
|
-
} from "../../../chunk-T4YJRD22.js";
|
|
59
|
-
import {
|
|
60
|
-
MemoryJobStepService
|
|
61
|
-
} from "../../../chunk-PNZSGAB2.js";
|
|
62
|
-
import {
|
|
63
|
-
MemoryJobStore
|
|
64
|
-
} from "../../../chunk-SNQ3TOWP.js";
|
|
65
|
-
import {
|
|
66
|
-
HandlerRegistry,
|
|
67
|
-
JOB_HANDLER_METADATA_KEY,
|
|
68
|
-
JOB_HANDLER_REGISTRY,
|
|
69
|
-
JobHandler,
|
|
70
|
-
JobHandlerBase,
|
|
71
|
-
ParentClosePolicy
|
|
72
|
-
} from "../../../chunk-CO6LUM72.js";
|
|
73
|
-
import {
|
|
74
|
-
JOBS_LISTEN_NOTIFY,
|
|
75
|
-
JOBS_MULTI_TENANT,
|
|
76
|
-
JOB_ORCHESTRATOR,
|
|
77
|
-
JOB_RUN_SERVICE,
|
|
78
|
-
JOB_STEP_SERVICE
|
|
79
|
-
} from "../../../chunk-ZPL74UQN.js";
|
|
80
|
-
import {
|
|
81
|
-
BootValidationError,
|
|
82
|
-
JobCollisionError,
|
|
83
|
-
JobNotReplayableError,
|
|
84
|
-
JobTemplateFieldMissingError,
|
|
85
|
-
JobTypeNotFoundError,
|
|
86
|
-
MissingTenantIdError,
|
|
87
|
-
ReservedPoolViolationError
|
|
88
|
-
} from "../../../chunk-T4BIIU5E.js";
|
|
89
89
|
import {
|
|
90
90
|
EVENTS_WAKE_CHANNEL,
|
|
91
91
|
JOBS_WAKE_CHANNEL,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import '@nestjs/common';
|
|
2
2
|
import '../events/event-registry.js';
|
|
3
|
-
export { a as ConcurrencyPolicy, D as DedupePolicy, H as HandlerRegistry, b as HandlerRegistryEntry, J as JOB_HANDLER_METADATA_KEY, c as JOB_HANDLER_REGISTRY, d as JobContext, e as JobHandler, f as JobHandlerBase, g as JobHandlerMeta, n as JobTrigger, P as ParentClosePolicy, R as RetryPolicy, S as ScopeRef, k as SpawnChildOptions, m as StepOptions } from '../../../job-orchestrator.protocol-
|
|
3
|
+
export { a as ConcurrencyPolicy, D as DedupePolicy, F as FN_KEY_SENTINEL, H as HandlerRegistry, b as HandlerRegistryEntry, J as JOB_HANDLER_METADATA_KEY, c as JOB_HANDLER_REGISTRY, d as JobContext, e as JobHandler, f as JobHandlerBase, g as JobHandlerMeta, n as JobKeyFunctionUnavailableError, o as JobKeySelector, p as JobTrigger, K as KeyKind, P as ParentClosePolicy, R as RetryPolicy, S as ScopeRef, k as SpawnChildOptions, m as StepOptions, q as keySelectorToTemplate, r as resolveJobKey } from '../../../job-orchestrator.protocol-ZuJ3ow-O.js';
|
|
4
4
|
import '../events/event-bus.protocol.js';
|
|
5
5
|
import '../../types/drizzle.js';
|
|
6
6
|
import 'drizzle-orm/node-postgres';
|
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
import {
|
|
2
|
+
FN_KEY_SENTINEL,
|
|
2
3
|
HandlerRegistry,
|
|
3
4
|
JOB_HANDLER_METADATA_KEY,
|
|
4
5
|
JOB_HANDLER_REGISTRY,
|
|
5
6
|
JobHandler,
|
|
6
7
|
JobHandlerBase,
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
JobKeyFunctionUnavailableError,
|
|
9
|
+
ParentClosePolicy,
|
|
10
|
+
keySelectorToTemplate,
|
|
11
|
+
resolveJobKey
|
|
12
|
+
} from "../../../chunk-7P5ODGLA.js";
|
|
9
13
|
import "../../../chunk-GYGNEQSC.js";
|
|
10
14
|
import "../../../chunk-2E224ZSN.js";
|
|
11
15
|
export {
|
|
16
|
+
FN_KEY_SENTINEL,
|
|
12
17
|
HandlerRegistry,
|
|
13
18
|
JOB_HANDLER_METADATA_KEY,
|
|
14
19
|
JOB_HANDLER_REGISTRY,
|
|
15
20
|
JobHandler,
|
|
16
21
|
JobHandlerBase,
|
|
17
|
-
|
|
22
|
+
JobKeyFunctionUnavailableError,
|
|
23
|
+
ParentClosePolicy,
|
|
24
|
+
keySelectorToTemplate,
|
|
25
|
+
resolveJobKey
|
|
18
26
|
};
|
|
19
27
|
//# sourceMappingURL=job-handler.base.js.map
|
|
@@ -2,7 +2,7 @@ import { ConnectionOptions, FlowProducer } from 'bullmq';
|
|
|
2
2
|
import { DrizzleClient } from '../../types/drizzle.js';
|
|
3
3
|
import { DrizzleTransaction } from '../events/event-bus.protocol.js';
|
|
4
4
|
import { DrizzleJobOrchestrator } from './job-orchestrator.drizzle-backend.js';
|
|
5
|
-
import { l as StartOptions, i as JobRun, C as CancelOptions } from '../../../job-orchestrator.protocol-
|
|
5
|
+
import { l as StartOptions, i as JobRun, C as CancelOptions } from '../../../job-orchestrator.protocol-ZuJ3ow-O.js';
|
|
6
6
|
import { BullMqResolvedConfig } from './bullmq.config.js';
|
|
7
7
|
import 'drizzle-orm/node-postgres';
|
|
8
8
|
import './job-orchestration.schema.js';
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DrizzleJobOrchestrator
|
|
3
|
+
} from "../../../chunk-FVNAU7VO.js";
|
|
4
|
+
import "../../../chunk-T4BIIU5E.js";
|
|
1
5
|
import {
|
|
2
6
|
BULLMQ_CONNECTION,
|
|
3
7
|
BULLMQ_RESOLVED_CONFIG,
|
|
@@ -5,16 +9,13 @@ import {
|
|
|
5
9
|
} from "../../../chunk-I6MVCB5A.js";
|
|
6
10
|
import "../../../chunk-RHVN6NA7.js";
|
|
7
11
|
import {
|
|
8
|
-
|
|
9
|
-
} from "../../../chunk-
|
|
12
|
+
JOBS_MULTI_TENANT
|
|
13
|
+
} from "../../../chunk-ZPL74UQN.js";
|
|
14
|
+
import "../../../chunk-7P5ODGLA.js";
|
|
10
15
|
import {
|
|
11
16
|
jobRuns,
|
|
12
17
|
jobs
|
|
13
18
|
} from "../../../chunk-OKXZ63IA.js";
|
|
14
|
-
import {
|
|
15
|
-
JOBS_MULTI_TENANT
|
|
16
|
-
} from "../../../chunk-ZPL74UQN.js";
|
|
17
|
-
import "../../../chunk-T4BIIU5E.js";
|
|
18
19
|
import "../../../chunk-MYQIQ27N.js";
|
|
19
20
|
import "../../../chunk-GYGNEQSC.js";
|
|
20
21
|
import {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../runtime/subsystems/jobs/job-orchestrator.bullmq-backend.ts"],"sourcesContent":["/**\n * BullMQJobOrchestrator — BullMQ-backed implementation of `IJobOrchestrator`\n * (BULLMQ-1, ADR-022 §58 — the reserved \"Phase 6+\" backend, now built).\n *\n * Split-of-responsibility (spec §\"Postgres + BullMQ coordination\"):\n * - Postgres `job_run` stays the **domain source of truth** — scoping,\n * hierarchy (`parent_run_id`/`root_run_id`), dedupe/concurrency state,\n * `listForScope`. All of that is the Drizzle backend's job and is reused\n * verbatim by extending `DrizzleJobOrchestrator`.\n * - BullMQ owns the **claim/dispatch** half. `start` adds a job to the\n * pool's queue (or to a FlowProducer flow when parented); the BullMQ\n * `Worker` (see `job-worker.bullmq-backend.ts`) consumes it and runs the\n * handler through the existing `JobHandlerBase` path. `cancel` removes\n * the queued job; `replay` re-adds it after the shared DB reset.\n *\n * This is **additive**: the Drizzle backend, the core protocol, and app code\n * are untouched. Consumers flip `jobs.backend: bullmq` with no code change —\n * the same `IJobOrchestrator` surface is satisfied.\n *\n * `jobId` (spec §Gotcha 1): BullMQ treats `:` as a Redis key separator and\n * consumers use `vendor:externalId`-shaped idempotency keys, so we derive the\n * `jobId` as `sha1(idempotencyKey)` — colon-safe and stable (same logical key\n * → same id → BullMQ-native dedup). When no dedupe key is configured we fall\n * back to the `job_run.id` (a fresh UUID), which is already colon-safe.\n */\nimport { createHash } from 'node:crypto';\nimport { Inject, Injectable, Logger, Optional } from '@nestjs/common';\nimport { eq } from 'drizzle-orm';\n// `bullmq` is an OPTIONAL peer dependency. Only TYPE imports here — types are\n// erased at compile time and never resolve `'bullmq'` at runtime, so a\n// `drizzle`-only consumer who didn't install bullmq can still load this file\n// (it is statically imported by `jobs-domain.module.ts`). The VALUE\n// constructors (`Queue`, `FlowProducer`) are loaded lazily via `await\n// import('bullmq')` in `loadBullMq()` — mirrors\n// `event-bus.redis-backend.ts:createRedisClient`. See BULLMQ-1 §Lazy import.\nimport type { ConnectionOptions, FlowProducer, Queue } from 'bullmq';\nimport type { DrizzleClient } from '../../types/drizzle';\nimport type { DrizzleTransaction } from '../events/event-bus.protocol';\nimport { DRIZZLE } from '../../constants/tokens';\nimport { jobRuns, jobs, type JobDefinitionRow } from './job-orchestration.schema';\nimport { DrizzleJobOrchestrator } from './job-orchestrator.drizzle-backend';\nimport type {\n CancelOptions,\n JobRun,\n StartOptions,\n} from './job-orchestrator.protocol';\nimport { JOBS_MULTI_TENANT } from './jobs-domain.tokens';\nimport {\n BULLMQ_CONNECTION,\n resolvePoolQueueName,\n type BullMqResolvedConfig,\n BULLMQ_RESOLVED_CONFIG,\n} from './bullmq.config';\n\n/**\n * Derive a colon-safe, stable BullMQ `jobId` from a logical idempotency key.\n *\n * SHA-1 over the raw key. Collision analysis (spec §Gotcha 1, resolved during\n * implementation): SHA-1's 160-bit space makes an accidental collision between\n * two *distinct* logical keys astronomically unlikely at any realistic job\n * volume (the birthday bound is ~2^80 keys before a 50% collision chance —\n * orders of magnitude beyond any job throughput). SHA-1's cryptographic\n * weakness is irrelevant here: there is no adversary forging idempotency keys,\n * and even a forged collision only deduplicates two jobs that the caller chose\n * to key identically. We therefore accept SHA-1 with no mitigation. The *same*\n * logical key intentionally maps to the *same* jobId — that is the dedup\n * mechanism, not a collision.\n */\nexport function sha1JobId(idempotencyKey: string): string {\n return createHash('sha1').update(idempotencyKey).digest('hex');\n}\n\n// Constructor types for the lazily-loaded `bullmq` value exports. Typed via\n// `typeof` the type-only imports so the cached ctors stay strongly typed\n// without a runtime `import`.\ntype QueueCtor = typeof import('bullmq').Queue;\ntype FlowProducerCtor = typeof import('bullmq').FlowProducer;\n\n@Injectable()\nexport class BullMQJobOrchestrator extends DrizzleJobOrchestrator {\n // TODO(logging-subsystem): swap to ILogger once ADR-028 lands\n private readonly bullLogger = new Logger(BullMQJobOrchestrator.name);\n\n /** Lazily-opened `Queue` handles, one per pool. */\n private readonly queues = new Map<string, Queue>();\n /** Single FlowProducer for parent/child hierarchies. Lazily opened. */\n private _flow: FlowProducer | null = null;\n\n /**\n * Cached `bullmq` value constructors, populated by `loadBullMq()` on first\n * use (the `start`/`cancel`/`replay` entrypoints `await` it before touching\n * a queue). Kept off the import graph so a `drizzle`-only consumer never\n * resolves the optional `'bullmq'` package.\n */\n private QueueCtor: QueueCtor | null = null;\n private FlowProducerCtor: FlowProducerCtor | null = null;\n private bullMqLoad: Promise<void> | null = null;\n\n /**\n * Own reference to the Drizzle client. `DrizzleJobOrchestrator.db` is\n * `private` (can't be redeclared even privately in a subclass), and the\n * spec forbids touching that file — so the subclass keeps its own handle\n * under a distinct name (same instance, passed through to `super`) for the\n * cancel-cascade snapshot + definition/run loads below.\n */\n private readonly bullDb: DrizzleClient;\n\n constructor(\n @Inject(DRIZZLE) db: DrizzleClient,\n @Inject(JOBS_MULTI_TENANT) multiTenant: boolean,\n @Inject(BULLMQ_CONNECTION) private readonly connection: ConnectionOptions,\n @Optional()\n @Inject(BULLMQ_RESOLVED_CONFIG)\n private readonly bullConfig: BullMqResolvedConfig | null = null,\n ) {\n super(db, multiTenant);\n this.bullDb = db;\n }\n\n /**\n * Lazily load the optional `bullmq` package and cache its value\n * constructors. Idempotent (single in-flight promise). Throws a friendly,\n * actionable error when the consumer selected `backend: 'bullmq'` but did\n * not install the package — mirrors `createRedisClient` in the redis event\n * backend. Must be `await`ed before any `queueFor`/`flow` access.\n */\n private async loadBullMq(): Promise<void> {\n if (this.QueueCtor && this.FlowProducerCtor) return;\n if (!this.bullMqLoad) {\n this.bullMqLoad = (async () => {\n try {\n const mod = await import('bullmq');\n this.QueueCtor = mod.Queue;\n this.FlowProducerCtor = mod.FlowProducer;\n } catch {\n throw new Error(\n 'BullMQ backend requires the \"bullmq\" package. Install it with: npm install bullmq',\n );\n }\n })();\n }\n await this.bullMqLoad;\n }\n\n /**\n * Open (or reuse) the `Queue` for a pool. Synchronous — callers `await\n * loadBullMq()` first so `QueueCtor` is populated.\n */\n private queueFor(pool: string): Queue {\n if (!this.QueueCtor) {\n throw new Error('BullMQJobOrchestrator: queueFor called before loadBullMq()');\n }\n const name = resolvePoolQueueName(pool, this.bullConfig);\n let q = this.queues.get(name);\n if (!q) {\n q = new this.QueueCtor(name, { connection: this.connection });\n this.queues.set(name, q);\n }\n return q;\n }\n\n private flow(): FlowProducer {\n if (!this.FlowProducerCtor) {\n throw new Error('BullMQJobOrchestrator: flow called before loadBullMq()');\n }\n if (!this._flow) {\n this._flow = new this.FlowProducerCtor({ connection: this.connection });\n }\n return this._flow;\n }\n\n // ==========================================================================\n // start — Postgres insert (super) + BullMQ dispatch\n // ==========================================================================\n\n override async start(\n type: string,\n input: unknown,\n opts: StartOptions = {},\n tx?: DrizzleTransaction,\n ): Promise<JobRun> {\n // (1) Postgres remains source of truth — the Drizzle backend handles the\n // job-definition lookup, dedupe short-circuit, concurrency collision,\n // parent/root resolution, and the `job_run` INSERT. If dedupe\n // short-circuited it returns the incumbent row whose dispatch already\n // happened on the original start; we must not enqueue again.\n const run = await super.start(type, input, opts, tx);\n\n // Dedupe returned an existing run (its createdAt predates this call) —\n // BullMQ-native dedup already covered the dispatch. Skip re-enqueue.\n // We detect this by checking the run was freshly created in THIS call:\n // a brand-new run has status 'pending' and zero attempts AND its id is\n // not yet known to BullMQ. The cheapest reliable signal is the dedupe\n // path's contract: super.start returns the incumbent unchanged. Since we\n // cannot distinguish purely from the row, we rely on `jobId` idempotency\n // — re-adding with the same jobId is a no-op in BullMQ, so the enqueue is\n // safe to attempt unconditionally.\n\n await this.dispatch(run, type);\n return run;\n }\n\n /**\n * Map a `job_run` row onto a BullMQ job via `queue.add`. When the run has a\n * `parentRunId` we attach it to the parent's existing BullMQ job through the\n * `parent: { id, queue }` opt — BullMQ then tracks the parent/child link in\n * its own graph. (The FlowProducer is reserved for whole-tree atomic\n * submits, exposed as an opt-in extension via `flowProducer()`; runtime\n * `ctx.spawnChild` is incremental, so `queue.add` with a parent ref is the\n * correct primitive here.)\n *\n * The `jobId` is colon-safe + stable: `sha1(dedupeKey)` when a dedupe key is\n * present (so the same logical key dedups), else the `job_run.id` UUID\n * (already colon-free).\n *\n * The domain `parentClosePolicy` cascade is still enforced in Postgres by\n * the shared `cancel` path — BullMQ's parent link is dispatch bookkeeping,\n * not the authority.\n */\n private async dispatch(run: JobRun, type: string): Promise<void> {\n await this.loadBullMq();\n const def = await this.loadDefinition(type);\n const jobId = run.dedupeKey ? sha1JobId(run.dedupeKey) : run.id;\n\n const jobOpts: Record<string, unknown> = {\n jobId,\n ...this.retryOpts(def),\n ...this.dedupeOpts(run, def),\n };\n\n if (run.parentRunId) {\n const parentRow = await this.loadRun(run.parentRunId);\n if (parentRow) {\n const parentJobId = parentRow.dedupeKey\n ? sha1JobId(parentRow.dedupeKey)\n : parentRow.id;\n jobOpts.parent = {\n id: parentJobId,\n queue: resolvePoolQueueName(parentRow.pool, this.bullConfig),\n };\n }\n }\n\n // The processor reads the authoritative input from `job_run`; the payload\n // carries the runId so it can load the row, plus type/input for logging.\n const payload = { runId: run.id, type, input: run.input };\n await this.queueFor(run.pool).add(type, payload, jobOpts);\n }\n\n /**\n * Opt-in extension (spec §Extensions): expose the FlowProducer for\n * consumers that want to submit a whole parent/child DAG atomically up\n * front, rather than incrementally via `ctx.spawnChild`. Backend-specific —\n * code using it is not portable to the Drizzle backend. Async because it\n * lazily loads the optional `bullmq` package on first use.\n */\n async flowProducer(): Promise<FlowProducer> {\n await this.loadBullMq();\n return this.flow();\n }\n\n private retryOpts(def: JobDefinitionRow): {\n attempts?: number;\n backoff?: { type: 'fixed' | 'exponential'; delay: number };\n } {\n const policy = def.retryPolicy;\n if (!policy) return {};\n return {\n attempts: policy.attempts,\n backoff: {\n type: policy.backoff === 'exponential' ? 'exponential' : 'fixed',\n delay: policy.baseMs,\n },\n };\n }\n\n private dedupeOpts(\n run: JobRun,\n def: JobDefinitionRow,\n ): { deduplication?: { id: string; ttl?: number } } {\n if (!run.dedupeKey || !def.dedupeWindowMs) return {};\n return {\n deduplication: {\n id: sha1JobId(run.dedupeKey),\n ttl: def.dedupeWindowMs,\n },\n };\n }\n\n // ==========================================================================\n // cancel — Postgres cascade (super) + remove from queue\n // ==========================================================================\n\n override async cancel(runId: string, opts: CancelOptions = {}): Promise<void> {\n // Snapshot the subtree BEFORE the DB cascade flips rows to canceled, so we\n // can remove every affected BullMQ job. We read the target's rootRunId and\n // the non-terminal descendants the same way the Drizzle cascade does.\n const target = await this.loadRun(runId);\n\n await super.cancel(runId, opts);\n\n if (!target) return;\n await this.loadBullMq();\n // Remove the target's own queued job.\n await this.removeFromQueue(target);\n\n if (opts.cascade === false) return;\n\n // Remove descendants' queued jobs (the DB rows were just canceled by\n // super.cancel; we mirror that into BullMQ so workers don't pick them up).\n const descendants = await this.bullDb\n .select()\n .from(jobRuns)\n .where(eq(jobRuns.rootRunId, target.rootRunId));\n for (const child of descendants) {\n if (child.id === runId) continue;\n await this.removeFromQueue(child as JobRun);\n }\n }\n\n private async removeFromQueue(run: JobRun): Promise<void> {\n const jobId = run.dedupeKey ? sha1JobId(run.dedupeKey) : run.id;\n try {\n const job = await this.queueFor(run.pool).getJob(jobId);\n if (job) await job.remove();\n } catch (err) {\n // A job already moved to active/completed cannot always be removed;\n // the Postgres cancel is authoritative either way.\n this.bullLogger.warn(\n `cancel: could not remove BullMQ job ${jobId} (pool=${run.pool}): ${(err as Error).message}`,\n );\n }\n }\n\n // ==========================================================================\n // replay — Postgres reset (super) + re-enqueue\n // ==========================================================================\n\n override async replay(runId: string): Promise<JobRun> {\n const run = await super.replay(runId);\n await this.dispatch(run, run.jobType);\n return run;\n }\n\n // ==========================================================================\n // Internals\n // ==========================================================================\n\n private async loadDefinition(type: string): Promise<JobDefinitionRow> {\n const [def] = await this.bullDb\n .select()\n .from(jobs)\n .where(eq(jobs.type, type))\n .limit(1);\n if (!def) {\n throw new Error(`BullMQJobOrchestrator: no job definition for '${type}'`);\n }\n return def as JobDefinitionRow;\n }\n\n private async loadRun(id: string): Promise<JobRun | null> {\n const [row] = await this.bullDb\n .select()\n .from(jobRuns)\n .where(eq(jobRuns.id, id))\n .limit(1);\n return (row as JobRun) ?? null;\n }\n\n /** Close all open queue + flow connections. Called on module destroy. */\n async closeConnections(): Promise<void> {\n for (const q of this.queues.values()) {\n await q.close().catch(() => undefined);\n }\n this.queues.clear();\n if (this._flow) {\n await this._flow.close().catch(() => undefined);\n this._flow = null;\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../runtime/subsystems/jobs/job-orchestrator.bullmq-backend.ts"],"sourcesContent":["/**\n * BullMQJobOrchestrator — BullMQ-backed implementation of `IJobOrchestrator`\n * (BULLMQ-1, ADR-022 §58 — the reserved \"Phase 6+\" backend, now built).\n *\n * Split-of-responsibility (spec §\"Postgres + BullMQ coordination\"):\n * - Postgres `job_run` stays the **domain source of truth** — scoping,\n * hierarchy (`parent_run_id`/`root_run_id`), dedupe/concurrency state,\n * `listForScope`. All of that is the Drizzle backend's job and is reused\n * verbatim by extending `DrizzleJobOrchestrator`.\n * - BullMQ owns the **claim/dispatch** half. `start` adds a job to the\n * pool's queue (or to a FlowProducer flow when parented); the BullMQ\n * `Worker` (see `job-worker.bullmq-backend.ts`) consumes it and runs the\n * handler through the existing `JobHandlerBase` path. `cancel` removes\n * the queued job; `replay` re-adds it after the shared DB reset.\n *\n * This is **additive**: the Drizzle backend, the core protocol, and app code\n * are untouched. Consumers flip `jobs.backend: bullmq` with no code change —\n * the same `IJobOrchestrator` surface is satisfied.\n *\n * `jobId` (spec §Gotcha 1): BullMQ treats `:` as a Redis key separator and\n * consumers use `vendor:externalId`-shaped idempotency keys, so we derive the\n * `jobId` as `sha1(idempotencyKey)` — colon-safe and stable (same logical key\n * → same id → BullMQ-native dedup). When no dedupe key is configured we fall\n * back to the `job_run.id` (a fresh UUID), which is already colon-safe.\n */\nimport { createHash } from 'node:crypto';\nimport { Inject, Injectable, Logger, Optional } from '@nestjs/common';\nimport { eq } from 'drizzle-orm';\n// `bullmq` is an OPTIONAL peer dependency. Only TYPE imports here — types are\n// erased at compile time and never resolve `'bullmq'` at runtime, so a\n// `drizzle`-only consumer who didn't install bullmq can still load this file\n// (it is statically imported by `jobs-domain.module.ts`). The VALUE\n// constructors (`Queue`, `FlowProducer`) are loaded lazily via `await\n// import('bullmq')` in `loadBullMq()` — mirrors\n// `event-bus.redis-backend.ts:createRedisClient`. See BULLMQ-1 §Lazy import.\nimport type { ConnectionOptions, FlowProducer, Queue } from 'bullmq';\nimport type { DrizzleClient } from '../../types/drizzle';\nimport type { DrizzleTransaction } from '../events/event-bus.protocol';\nimport { DRIZZLE } from '../../constants/tokens';\nimport { jobRuns, jobs, type JobDefinitionRow } from './job-orchestration.schema';\nimport { DrizzleJobOrchestrator } from './job-orchestrator.drizzle-backend';\nimport type {\n CancelOptions,\n JobRun,\n StartOptions,\n} from './job-orchestrator.protocol';\nimport { JOBS_MULTI_TENANT } from './jobs-domain.tokens';\nimport {\n BULLMQ_CONNECTION,\n resolvePoolQueueName,\n type BullMqResolvedConfig,\n BULLMQ_RESOLVED_CONFIG,\n} from './bullmq.config';\n\n/**\n * Derive a colon-safe, stable BullMQ `jobId` from a logical idempotency key.\n *\n * SHA-1 over the raw key. Collision analysis (spec §Gotcha 1, resolved during\n * implementation): SHA-1's 160-bit space makes an accidental collision between\n * two *distinct* logical keys astronomically unlikely at any realistic job\n * volume (the birthday bound is ~2^80 keys before a 50% collision chance —\n * orders of magnitude beyond any job throughput). SHA-1's cryptographic\n * weakness is irrelevant here: there is no adversary forging idempotency keys,\n * and even a forged collision only deduplicates two jobs that the caller chose\n * to key identically. We therefore accept SHA-1 with no mitigation. The *same*\n * logical key intentionally maps to the *same* jobId — that is the dedup\n * mechanism, not a collision.\n */\nexport function sha1JobId(idempotencyKey: string): string {\n return createHash('sha1').update(idempotencyKey).digest('hex');\n}\n\n// Constructor types for the lazily-loaded `bullmq` value exports. Typed via\n// `typeof` the type-only imports so the cached ctors stay strongly typed\n// without a runtime `import`.\ntype QueueCtor = typeof import('bullmq').Queue;\ntype FlowProducerCtor = typeof import('bullmq').FlowProducer;\n\n@Injectable()\nexport class BullMQJobOrchestrator extends DrizzleJobOrchestrator {\n // TODO(logging-subsystem): swap to ILogger once ADR-028 lands\n private readonly bullLogger = new Logger(BullMQJobOrchestrator.name);\n\n /** Lazily-opened `Queue` handles, one per pool. */\n private readonly queues = new Map<string, Queue>();\n /** Single FlowProducer for parent/child hierarchies. Lazily opened. */\n private _flow: FlowProducer | null = null;\n\n /**\n * Cached `bullmq` value constructors, populated by `loadBullMq()` on first\n * use (the `start`/`cancel`/`replay` entrypoints `await` it before touching\n * a queue). Kept off the import graph so a `drizzle`-only consumer never\n * resolves the optional `'bullmq'` package.\n */\n private QueueCtor: QueueCtor | null = null;\n private FlowProducerCtor: FlowProducerCtor | null = null;\n private bullMqLoad: Promise<void> | null = null;\n\n /**\n * Own reference to the Drizzle client. `DrizzleJobOrchestrator.db` is\n * `private` (can't be redeclared even privately in a subclass), and the\n * spec forbids touching that file — so the subclass keeps its own handle\n * under a distinct name (same instance, passed through to `super`) for the\n * cancel-cascade snapshot + definition/run loads below.\n */\n private readonly bullDb: DrizzleClient;\n\n constructor(\n @Inject(DRIZZLE) db: DrizzleClient,\n @Inject(JOBS_MULTI_TENANT) multiTenant: boolean,\n @Inject(BULLMQ_CONNECTION) private readonly connection: ConnectionOptions,\n @Optional()\n @Inject(BULLMQ_RESOLVED_CONFIG)\n private readonly bullConfig: BullMqResolvedConfig | null = null,\n ) {\n super(db, multiTenant);\n this.bullDb = db;\n }\n\n /**\n * Lazily load the optional `bullmq` package and cache its value\n * constructors. Idempotent (single in-flight promise). Throws a friendly,\n * actionable error when the consumer selected `backend: 'bullmq'` but did\n * not install the package — mirrors `createRedisClient` in the redis event\n * backend. Must be `await`ed before any `queueFor`/`flow` access.\n */\n private async loadBullMq(): Promise<void> {\n if (this.QueueCtor && this.FlowProducerCtor) return;\n if (!this.bullMqLoad) {\n this.bullMqLoad = (async () => {\n try {\n const mod = await import('bullmq');\n this.QueueCtor = mod.Queue;\n this.FlowProducerCtor = mod.FlowProducer;\n } catch {\n throw new Error(\n 'BullMQ backend requires the \"bullmq\" package. Install it with: npm install bullmq',\n );\n }\n })();\n }\n await this.bullMqLoad;\n }\n\n /**\n * Open (or reuse) the `Queue` for a pool. Synchronous — callers `await\n * loadBullMq()` first so `QueueCtor` is populated.\n */\n private queueFor(pool: string): Queue {\n if (!this.QueueCtor) {\n throw new Error('BullMQJobOrchestrator: queueFor called before loadBullMq()');\n }\n const name = resolvePoolQueueName(pool, this.bullConfig);\n let q = this.queues.get(name);\n if (!q) {\n q = new this.QueueCtor(name, { connection: this.connection });\n this.queues.set(name, q);\n }\n return q;\n }\n\n private flow(): FlowProducer {\n if (!this.FlowProducerCtor) {\n throw new Error('BullMQJobOrchestrator: flow called before loadBullMq()');\n }\n if (!this._flow) {\n this._flow = new this.FlowProducerCtor({ connection: this.connection });\n }\n return this._flow;\n }\n\n // ==========================================================================\n // start — Postgres insert (super) + BullMQ dispatch\n // ==========================================================================\n\n override async start(\n type: string,\n input: unknown,\n opts: StartOptions = {},\n tx?: DrizzleTransaction,\n ): Promise<JobRun> {\n // (1) Postgres remains source of truth — the Drizzle backend handles the\n // job-definition lookup, dedupe short-circuit, concurrency collision,\n // parent/root resolution, and the `job_run` INSERT. If dedupe\n // short-circuited it returns the incumbent row whose dispatch already\n // happened on the original start; we must not enqueue again.\n const run = await super.start(type, input, opts, tx);\n\n // Dedupe returned an existing run (its createdAt predates this call) —\n // BullMQ-native dedup already covered the dispatch. Skip re-enqueue.\n // We detect this by checking the run was freshly created in THIS call:\n // a brand-new run has status 'pending' and zero attempts AND its id is\n // not yet known to BullMQ. The cheapest reliable signal is the dedupe\n // path's contract: super.start returns the incumbent unchanged. Since we\n // cannot distinguish purely from the row, we rely on `jobId` idempotency\n // — re-adding with the same jobId is a no-op in BullMQ, so the enqueue is\n // safe to attempt unconditionally.\n\n await this.dispatch(run, type);\n return run;\n }\n\n /**\n * Map a `job_run` row onto a BullMQ job via `queue.add`. When the run has a\n * `parentRunId` we attach it to the parent's existing BullMQ job through the\n * `parent: { id, queue }` opt — BullMQ then tracks the parent/child link in\n * its own graph. (The FlowProducer is reserved for whole-tree atomic\n * submits, exposed as an opt-in extension via `flowProducer()`; runtime\n * `ctx.spawnChild` is incremental, so `queue.add` with a parent ref is the\n * correct primitive here.)\n *\n * The `jobId` is colon-safe + stable: `sha1(dedupeKey)` when a dedupe key is\n * present (so the same logical key dedups), else the `job_run.id` UUID\n * (already colon-free).\n *\n * The domain `parentClosePolicy` cascade is still enforced in Postgres by\n * the shared `cancel` path — BullMQ's parent link is dispatch bookkeeping,\n * not the authority.\n */\n private async dispatch(run: JobRun, type: string): Promise<void> {\n await this.loadBullMq();\n const def = await this.loadDefinition(type);\n const jobId = run.dedupeKey ? sha1JobId(run.dedupeKey) : run.id;\n\n const jobOpts: Record<string, unknown> = {\n jobId,\n ...this.retryOpts(def),\n ...this.dedupeOpts(run, def),\n };\n\n if (run.parentRunId) {\n const parentRow = await this.loadRun(run.parentRunId);\n if (parentRow) {\n const parentJobId = parentRow.dedupeKey\n ? sha1JobId(parentRow.dedupeKey)\n : parentRow.id;\n jobOpts.parent = {\n id: parentJobId,\n queue: resolvePoolQueueName(parentRow.pool, this.bullConfig),\n };\n }\n }\n\n // The processor reads the authoritative input from `job_run`; the payload\n // carries the runId so it can load the row, plus type/input for logging.\n const payload = { runId: run.id, type, input: run.input };\n await this.queueFor(run.pool).add(type, payload, jobOpts);\n }\n\n /**\n * Opt-in extension (spec §Extensions): expose the FlowProducer for\n * consumers that want to submit a whole parent/child DAG atomically up\n * front, rather than incrementally via `ctx.spawnChild`. Backend-specific —\n * code using it is not portable to the Drizzle backend. Async because it\n * lazily loads the optional `bullmq` package on first use.\n */\n async flowProducer(): Promise<FlowProducer> {\n await this.loadBullMq();\n return this.flow();\n }\n\n private retryOpts(def: JobDefinitionRow): {\n attempts?: number;\n backoff?: { type: 'fixed' | 'exponential'; delay: number };\n } {\n const policy = def.retryPolicy;\n if (!policy) return {};\n return {\n attempts: policy.attempts,\n backoff: {\n type: policy.backoff === 'exponential' ? 'exponential' : 'fixed',\n delay: policy.baseMs,\n },\n };\n }\n\n private dedupeOpts(\n run: JobRun,\n def: JobDefinitionRow,\n ): { deduplication?: { id: string; ttl?: number } } {\n if (!run.dedupeKey || !def.dedupeWindowMs) return {};\n return {\n deduplication: {\n id: sha1JobId(run.dedupeKey),\n ttl: def.dedupeWindowMs,\n },\n };\n }\n\n // ==========================================================================\n // cancel — Postgres cascade (super) + remove from queue\n // ==========================================================================\n\n override async cancel(runId: string, opts: CancelOptions = {}): Promise<void> {\n // Snapshot the subtree BEFORE the DB cascade flips rows to canceled, so we\n // can remove every affected BullMQ job. We read the target's rootRunId and\n // the non-terminal descendants the same way the Drizzle cascade does.\n const target = await this.loadRun(runId);\n\n await super.cancel(runId, opts);\n\n if (!target) return;\n await this.loadBullMq();\n // Remove the target's own queued job.\n await this.removeFromQueue(target);\n\n if (opts.cascade === false) return;\n\n // Remove descendants' queued jobs (the DB rows were just canceled by\n // super.cancel; we mirror that into BullMQ so workers don't pick them up).\n const descendants = await this.bullDb\n .select()\n .from(jobRuns)\n .where(eq(jobRuns.rootRunId, target.rootRunId));\n for (const child of descendants) {\n if (child.id === runId) continue;\n await this.removeFromQueue(child as JobRun);\n }\n }\n\n private async removeFromQueue(run: JobRun): Promise<void> {\n const jobId = run.dedupeKey ? sha1JobId(run.dedupeKey) : run.id;\n try {\n const job = await this.queueFor(run.pool).getJob(jobId);\n if (job) await job.remove();\n } catch (err) {\n // A job already moved to active/completed cannot always be removed;\n // the Postgres cancel is authoritative either way.\n this.bullLogger.warn(\n `cancel: could not remove BullMQ job ${jobId} (pool=${run.pool}): ${(err as Error).message}`,\n );\n }\n }\n\n // ==========================================================================\n // replay — Postgres reset (super) + re-enqueue\n // ==========================================================================\n\n override async replay(runId: string): Promise<JobRun> {\n const run = await super.replay(runId);\n await this.dispatch(run, run.jobType);\n return run;\n }\n\n // ==========================================================================\n // Internals\n // ==========================================================================\n\n private async loadDefinition(type: string): Promise<JobDefinitionRow> {\n const [def] = await this.bullDb\n .select()\n .from(jobs)\n .where(eq(jobs.type, type))\n .limit(1);\n if (!def) {\n throw new Error(`BullMQJobOrchestrator: no job definition for '${type}'`);\n }\n return def as JobDefinitionRow;\n }\n\n private async loadRun(id: string): Promise<JobRun | null> {\n const [row] = await this.bullDb\n .select()\n .from(jobRuns)\n .where(eq(jobRuns.id, id))\n .limit(1);\n return (row as JobRun) ?? null;\n }\n\n /** Close all open queue + flow connections. Called on module destroy. */\n async closeConnections(): Promise<void> {\n for (const q of this.queues.values()) {\n await q.close().catch(() => undefined);\n }\n this.queues.clear();\n if (this._flow) {\n await this._flow.close().catch(() => undefined);\n this._flow = null;\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DrizzleClient } from '../../types/drizzle.js';
|
|
2
2
|
import { DrizzleTransaction } from '../events/event-bus.protocol.js';
|
|
3
|
-
import { I as IJobOrchestrator, l as StartOptions, i as JobRun, C as CancelOptions, j as JobUpsertEntry, h as JobPoolDef } from '../../../job-orchestrator.protocol-
|
|
3
|
+
import { I as IJobOrchestrator, l as StartOptions, i as JobRun, C as CancelOptions, j as JobUpsertEntry, h as JobPoolDef } from '../../../job-orchestrator.protocol-ZuJ3ow-O.js';
|
|
4
4
|
import 'drizzle-orm/node-postgres';
|
|
5
5
|
import './job-orchestration.schema.js';
|
|
6
6
|
import 'drizzle-orm/pg-core';
|
|
@@ -2,10 +2,11 @@ import {
|
|
|
2
2
|
DrizzleJobOrchestrator,
|
|
3
3
|
TERMINAL_STATUSES,
|
|
4
4
|
evaluateKeyTemplate
|
|
5
|
-
} from "../../../chunk-
|
|
6
|
-
import "../../../chunk-OKXZ63IA.js";
|
|
7
|
-
import "../../../chunk-ZPL74UQN.js";
|
|
5
|
+
} from "../../../chunk-FVNAU7VO.js";
|
|
8
6
|
import "../../../chunk-T4BIIU5E.js";
|
|
7
|
+
import "../../../chunk-ZPL74UQN.js";
|
|
8
|
+
import "../../../chunk-7P5ODGLA.js";
|
|
9
|
+
import "../../../chunk-OKXZ63IA.js";
|
|
9
10
|
import "../../../chunk-MYQIQ27N.js";
|
|
10
11
|
import "../../../chunk-GYGNEQSC.js";
|
|
11
12
|
import "../../../chunk-U64T4YZE.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ModuleRef } from '@nestjs/core';
|
|
2
2
|
import { JobRunRow } from './job-orchestration.schema.js';
|
|
3
|
-
import { I as IJobOrchestrator, g as JobHandlerMeta, f as JobHandlerBase, j as JobUpsertEntry, h as JobPoolDef, l as StartOptions, i as JobRun, C as CancelOptions } from '../../../job-orchestrator.protocol-
|
|
3
|
+
import { I as IJobOrchestrator, g as JobHandlerMeta, f as JobHandlerBase, j as JobUpsertEntry, h as JobPoolDef, l as StartOptions, i as JobRun, C as CancelOptions } from '../../../job-orchestrator.protocol-ZuJ3ow-O.js';
|
|
4
4
|
import { MemoryJobStore } from './memory-job-store.js';
|
|
5
5
|
import { MemoryJobStepService } from './job-step-service.memory-backend.js';
|
|
6
6
|
import 'drizzle-orm/pg-core';
|
|
@@ -48,6 +48,16 @@ declare class MemoryJobOrchestrator implements IJobOrchestrator {
|
|
|
48
48
|
registerHandler<TInput>(type: string, meta: JobHandlerMeta<TInput>, handlerClass: new (...args: unknown[]) => JobHandlerBase<TInput>): void;
|
|
49
49
|
/** Test helper — look up a registered handler without exposing the map. */
|
|
50
50
|
getHandlerRegistration(type: string): HandlerRegistration | undefined;
|
|
51
|
+
/**
|
|
52
|
+
* JOB-FN-KEY (0.16.2): resolve a persisted key template against the payload.
|
|
53
|
+
* Delegates to the shared `resolveJobKey`, but binds the FUNCTION-sentinel
|
|
54
|
+
* lookup to THIS backend's local `handlerRegistry` (the memory backend keeps
|
|
55
|
+
* its own meta map seeded by `registerHandler`, distinct from the global
|
|
56
|
+
* `JOB_HANDLER_REGISTRY` that the Drizzle/worker path uses — memory tests
|
|
57
|
+
* register handlers directly, never via the `@JobHandler` decorator). The
|
|
58
|
+
* `evaluateTemplate` callback handles the ordinary `{{field}}` path.
|
|
59
|
+
*/
|
|
60
|
+
private resolveKey;
|
|
51
61
|
/**
|
|
52
62
|
* Boot-time upsert per `IJobOrchestrator.upsertJobRows`. Memory backend
|
|
53
63
|
* just funnels each entry through `registerHandler`. The validator is
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MemoryJobOrchestrator
|
|
3
|
-
} from "../../../chunk-
|
|
3
|
+
} from "../../../chunk-DUMI2J5M.js";
|
|
4
4
|
import "../../../chunk-PNZSGAB2.js";
|
|
5
5
|
import "../../../chunk-SNQ3TOWP.js";
|
|
6
|
-
import "../../../chunk-CO6LUM72.js";
|
|
7
|
-
import "../../../chunk-ZPL74UQN.js";
|
|
8
6
|
import "../../../chunk-T4BIIU5E.js";
|
|
7
|
+
import "../../../chunk-ZPL74UQN.js";
|
|
8
|
+
import "../../../chunk-7P5ODGLA.js";
|
|
9
9
|
import "../../../chunk-GYGNEQSC.js";
|
|
10
10
|
import "../../../chunk-2E224ZSN.js";
|
|
11
11
|
export {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import '../events/event-bus.protocol.js';
|
|
2
2
|
import './job-orchestration.schema.js';
|
|
3
|
-
export { C as CancelOptions, I as IJobOrchestrator, h as JobPoolDef, i as JobRun, j as JobUpsertEntry, l as StartOptions } from '../../../job-orchestrator.protocol-
|
|
3
|
+
export { C as CancelOptions, I as IJobOrchestrator, h as JobPoolDef, i as JobRun, j as JobUpsertEntry, l as StartOptions } from '../../../job-orchestrator.protocol-ZuJ3ow-O.js';
|
|
4
4
|
import '../../types/drizzle.js';
|
|
5
5
|
import 'drizzle-orm/node-postgres';
|
|
6
6
|
import 'drizzle-orm/pg-core';
|
|
@@ -2,7 +2,7 @@ import { JobRunRow } from './job-orchestration.schema.js';
|
|
|
2
2
|
import { JobRunSummary } from './job-run-service.protocol.js';
|
|
3
3
|
import 'drizzle-orm/pg-core';
|
|
4
4
|
import 'drizzle-orm';
|
|
5
|
-
import '../../../job-orchestrator.protocol-
|
|
5
|
+
import '../../../job-orchestrator.protocol-ZuJ3ow-O.js';
|
|
6
6
|
import '../events/event-bus.protocol.js';
|
|
7
7
|
import '../../types/drizzle.js';
|
|
8
8
|
import 'drizzle-orm/node-postgres';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DrizzleClient } from '../../types/drizzle.js';
|
|
2
|
-
import { I as IJobOrchestrator, i as JobRun } from '../../../job-orchestrator.protocol-
|
|
2
|
+
import { I as IJobOrchestrator, i as JobRun } from '../../../job-orchestrator.protocol-ZuJ3ow-O.js';
|
|
3
3
|
import { IJobRunService, ListForScopeOptions, CancelForScopeOptions, RescheduleForScopeOptions, PoolStatusCount, JobRunFailure, ListJobRunsQuery, JobRunPage } from './job-run-service.protocol.js';
|
|
4
4
|
import 'drizzle-orm/node-postgres';
|
|
5
5
|
import '../events/event-bus.protocol.js';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DrizzleJobRunService
|
|
3
|
-
} from "../../../chunk-
|
|
3
|
+
} from "../../../chunk-VNBC3VXM.js";
|
|
4
|
+
import "../../../chunk-T4BIIU5E.js";
|
|
4
5
|
import "../../../chunk-L3LZWWSX.js";
|
|
5
|
-
import "../../../chunk-OKXZ63IA.js";
|
|
6
6
|
import "../../../chunk-ZPL74UQN.js";
|
|
7
|
-
import "../../../chunk-
|
|
7
|
+
import "../../../chunk-OKXZ63IA.js";
|
|
8
8
|
import "../../../chunk-GYGNEQSC.js";
|
|
9
9
|
import "../../../chunk-U64T4YZE.js";
|
|
10
10
|
import "../../../chunk-2E224ZSN.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { I as IJobOrchestrator, i as JobRun } from '../../../job-orchestrator.protocol-
|
|
1
|
+
import { I as IJobOrchestrator, i as JobRun } from '../../../job-orchestrator.protocol-ZuJ3ow-O.js';
|
|
2
2
|
import { IJobRunService, ListForScopeOptions, CancelForScopeOptions, RescheduleForScopeOptions, PoolStatusCount, JobRunFailure, ListJobRunsQuery, JobRunPage } from './job-run-service.protocol.js';
|
|
3
3
|
import { MemoryJobStore } from './memory-job-store.js';
|
|
4
4
|
import '../events/event-bus.protocol.js';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MemoryJobRunService
|
|
3
|
-
} from "../../../chunk-
|
|
4
|
-
import "../../../chunk-L3LZWWSX.js";
|
|
3
|
+
} from "../../../chunk-BHZP6LOV.js";
|
|
5
4
|
import "../../../chunk-SNQ3TOWP.js";
|
|
6
|
-
import "../../../chunk-ZPL74UQN.js";
|
|
7
5
|
import "../../../chunk-T4BIIU5E.js";
|
|
6
|
+
import "../../../chunk-L3LZWWSX.js";
|
|
7
|
+
import "../../../chunk-ZPL74UQN.js";
|
|
8
8
|
import "../../../chunk-GYGNEQSC.js";
|
|
9
9
|
import "../../../chunk-2E224ZSN.js";
|
|
10
10
|
export {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as JobRun } from '../../../job-orchestrator.protocol-
|
|
1
|
+
import { i as JobRun } from '../../../job-orchestrator.protocol-ZuJ3ow-O.js';
|
|
2
2
|
import '../events/event-bus.protocol.js';
|
|
3
3
|
import '../../types/drizzle.js';
|
|
4
4
|
import 'drizzle-orm/node-postgres';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ModuleRef } from '@nestjs/core';
|
|
2
2
|
import { ConnectionOptions } from 'bullmq';
|
|
3
3
|
import { DrizzleClient } from '../../types/drizzle.js';
|
|
4
|
-
import { I as IJobOrchestrator } from '../../../job-orchestrator.protocol-
|
|
4
|
+
import { I as IJobOrchestrator } from '../../../job-orchestrator.protocol-ZuJ3ow-O.js';
|
|
5
5
|
import { IJobStepService } from './job-step-service.protocol.js';
|
|
6
6
|
import 'drizzle-orm/node-postgres';
|
|
7
7
|
import '../events/event-bus.protocol.js';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
JOB_HANDLER_REGISTRY
|
|
3
|
+
} from "../../../chunk-7P5ODGLA.js";
|
|
1
4
|
import {
|
|
2
5
|
jobRuns
|
|
3
6
|
} from "../../../chunk-OKXZ63IA.js";
|
|
4
|
-
import {
|
|
5
|
-
JOB_HANDLER_REGISTRY
|
|
6
|
-
} from "../../../chunk-CO6LUM72.js";
|
|
7
7
|
import "../../../chunk-GYGNEQSC.js";
|
|
8
8
|
import "../../../chunk-2E224ZSN.js";
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ import { OnModuleInit, OnModuleDestroy } from '@nestjs/common';
|
|
|
3
3
|
import { ModuleRef } from '@nestjs/core';
|
|
4
4
|
import { DrizzleClient } from '../../types/drizzle.js';
|
|
5
5
|
import { JobRunRow } from './job-orchestration.schema.js';
|
|
6
|
-
import { I as IJobOrchestrator, R as RetryPolicy } from '../../../job-orchestrator.protocol-
|
|
6
|
+
import { I as IJobOrchestrator, R as RetryPolicy } from '../../../job-orchestrator.protocol-ZuJ3ow-O.js';
|
|
7
7
|
import { IJobRunService } from './job-run-service.protocol.js';
|
|
8
8
|
import { IJobStepService } from './job-step-service.protocol.js';
|
|
9
9
|
import 'drizzle-orm/node-postgres';
|
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
buildStaleSweepQuery,
|
|
7
7
|
classifyError,
|
|
8
8
|
computeBackoff
|
|
9
|
-
} from "../../../chunk-
|
|
10
|
-
import "../../../chunk-OKXZ63IA.js";
|
|
11
|
-
import "../../../chunk-CO6LUM72.js";
|
|
9
|
+
} from "../../../chunk-FWRL7BZ5.js";
|
|
12
10
|
import "../../../chunk-ZPL74UQN.js";
|
|
11
|
+
import "../../../chunk-7P5ODGLA.js";
|
|
12
|
+
import "../../../chunk-OKXZ63IA.js";
|
|
13
13
|
import "../../../chunk-MYQIQ27N.js";
|
|
14
14
|
import "../../../chunk-GYGNEQSC.js";
|
|
15
15
|
import "../../../chunk-U64T4YZE.js";
|