@shipfox/api-workflows 12.6.0 → 13.0.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.
Files changed (117) hide show
  1. package/.turbo/turbo-build.log +8 -8
  2. package/CHANGELOG.md +23 -0
  3. package/dist/core/entities/workflow-run.d.ts +3 -0
  4. package/dist/core/entities/workflow-run.d.ts.map +1 -1
  5. package/dist/core/entities/workflow-run.js.map +1 -1
  6. package/dist/db/index.d.ts +1 -1
  7. package/dist/db/index.d.ts.map +1 -1
  8. package/dist/db/index.js +1 -1
  9. package/dist/db/index.js.map +1 -1
  10. package/dist/db/job-listeners.d.ts.map +1 -1
  11. package/dist/db/job-listeners.js +17 -1
  12. package/dist/db/job-listeners.js.map +1 -1
  13. package/dist/db/workflow-runs/job-executions.d.ts +2 -3
  14. package/dist/db/workflow-runs/job-executions.d.ts.map +1 -1
  15. package/dist/db/workflow-runs/job-executions.js +48 -20
  16. package/dist/db/workflow-runs/job-executions.js.map +1 -1
  17. package/dist/db/workflow-runs/outbox.d.ts +15 -0
  18. package/dist/db/workflow-runs/outbox.d.ts.map +1 -1
  19. package/dist/db/workflow-runs/outbox.js +35 -1
  20. package/dist/db/workflow-runs/outbox.js.map +1 -1
  21. package/dist/db/workflow-runs/queries.d.ts +5 -3
  22. package/dist/db/workflow-runs/queries.d.ts.map +1 -1
  23. package/dist/db/workflow-runs/queries.js +20 -6
  24. package/dist/db/workflow-runs/queries.js.map +1 -1
  25. package/dist/db/workflow-runs/run-graph.d.ts.map +1 -1
  26. package/dist/db/workflow-runs/run-graph.js +12 -0
  27. package/dist/db/workflow-runs/run-graph.js.map +1 -1
  28. package/dist/db/workflow-runs/run-status.d.ts.map +1 -1
  29. package/dist/db/workflow-runs/run-status.js +13 -1
  30. package/dist/db/workflow-runs/run-status.js.map +1 -1
  31. package/dist/db/workflow-runs.d.ts +2 -2
  32. package/dist/db/workflow-runs.d.ts.map +1 -1
  33. package/dist/db/workflow-runs.js +2 -2
  34. package/dist/db/workflow-runs.js.map +1 -1
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +2 -4
  37. package/dist/index.js.map +1 -1
  38. package/dist/presentation/dto/workflow-run.d.ts.map +1 -1
  39. package/dist/presentation/dto/workflow-run.js +4 -2
  40. package/dist/presentation/dto/workflow-run.js.map +1 -1
  41. package/dist/presentation/index.d.ts +1 -1
  42. package/dist/presentation/index.d.ts.map +1 -1
  43. package/dist/presentation/index.js +1 -1
  44. package/dist/presentation/index.js.map +1 -1
  45. package/dist/presentation/routes/get-run.d.ts.map +1 -1
  46. package/dist/presentation/routes/get-run.js +2 -1
  47. package/dist/presentation/routes/get-run.js.map +1 -1
  48. package/dist/presentation/subscribers/index.d.ts +0 -1
  49. package/dist/presentation/subscribers/index.d.ts.map +1 -1
  50. package/dist/presentation/subscribers/index.js +0 -1
  51. package/dist/presentation/subscribers/index.js.map +1 -1
  52. package/dist/temporal/activities/index.d.ts +2 -18
  53. package/dist/temporal/activities/index.d.ts.map +1 -1
  54. package/dist/temporal/activities/index.js +3 -5
  55. package/dist/temporal/activities/index.js.map +1 -1
  56. package/dist/temporal/activities/orchestration-activities.d.ts +5 -14
  57. package/dist/temporal/activities/orchestration-activities.d.ts.map +1 -1
  58. package/dist/temporal/activities/orchestration-activities.js +13 -34
  59. package/dist/temporal/activities/orchestration-activities.js.map +1 -1
  60. package/dist/temporal/workflows/index.bundle.js +20 -68
  61. package/dist/temporal/workflows/job-execution-orchestration.d.ts +0 -3
  62. package/dist/temporal/workflows/job-execution-orchestration.d.ts.map +1 -1
  63. package/dist/temporal/workflows/job-execution-orchestration.js +17 -41
  64. package/dist/temporal/workflows/job-execution-orchestration.js.map +1 -1
  65. package/dist/temporal/workflows/job-listener-orchestration.d.ts +0 -3
  66. package/dist/temporal/workflows/job-listener-orchestration.d.ts.map +1 -1
  67. package/dist/temporal/workflows/job-listener-orchestration.js +1 -9
  68. package/dist/temporal/workflows/job-listener-orchestration.js.map +1 -1
  69. package/dist/temporal/workflows/run-orchestration.d.ts.map +1 -1
  70. package/dist/temporal/workflows/run-orchestration.js +2 -18
  71. package/dist/temporal/workflows/run-orchestration.js.map +1 -1
  72. package/dist/temporal/workflows/test-env.d.ts +4 -6
  73. package/dist/temporal/workflows/test-env.d.ts.map +1 -1
  74. package/dist/temporal/workflows/test-env.js +13 -24
  75. package/dist/temporal/workflows/test-env.js.map +1 -1
  76. package/dist/tsconfig.test.tsbuildinfo +1 -1
  77. package/package.json +3 -3
  78. package/src/core/entities/workflow-run.ts +3 -0
  79. package/src/db/index.ts +1 -1
  80. package/src/db/job-listeners.test.ts +21 -0
  81. package/src/db/job-listeners.ts +18 -0
  82. package/src/db/workflow-runs/job-executions.test.ts +110 -12
  83. package/src/db/workflow-runs/job-executions.ts +54 -29
  84. package/src/db/workflow-runs/outbox.ts +63 -0
  85. package/src/db/workflow-runs/queries.test.ts +27 -0
  86. package/src/db/workflow-runs/queries.ts +31 -5
  87. package/src/db/workflow-runs/run-graph.ts +17 -0
  88. package/src/db/workflow-runs/run-status.test.ts +13 -0
  89. package/src/db/workflow-runs/run-status.ts +15 -1
  90. package/src/db/workflow-runs.ts +3 -1
  91. package/src/index.ts +1 -5
  92. package/src/presentation/dto/workflow-run.ts +7 -1
  93. package/src/presentation/index.ts +0 -1
  94. package/src/presentation/routes/get-run.test.ts +31 -0
  95. package/src/presentation/routes/get-run.ts +1 -0
  96. package/src/presentation/routes/list-runs.test.ts +5 -1
  97. package/src/presentation/subscribers/index.ts +0 -1
  98. package/src/temporal/activities/index.ts +2 -8
  99. package/src/temporal/activities/orchestration-activities.test.ts +17 -1
  100. package/src/temporal/activities/orchestration-activities.ts +13 -46
  101. package/src/temporal/workflows/job-execution-orchestration.test.ts +6 -25
  102. package/src/temporal/workflows/job-execution-orchestration.ts +17 -43
  103. package/src/temporal/workflows/job-listener-orchestration-continuation.test.ts +0 -3
  104. package/src/temporal/workflows/job-listener-orchestration.test.ts +9 -12
  105. package/src/temporal/workflows/job-listener-orchestration.ts +0 -8
  106. package/src/temporal/workflows/run-orchestration.test.ts +22 -33
  107. package/src/temporal/workflows/run-orchestration.ts +4 -28
  108. package/src/temporal/workflows/test-env.ts +14 -34
  109. package/test/fixtures/runners-inter-module.ts +0 -3
  110. package/test/helpers/workflow-runs.ts +25 -0
  111. package/tsconfig.build.tsbuildinfo +1 -1
  112. package/dist/presentation/subscribers/on-runner-job-queued.d.ts +0 -3
  113. package/dist/presentation/subscribers/on-runner-job-queued.d.ts.map +0 -1
  114. package/dist/presentation/subscribers/on-runner-job-queued.js +0 -20
  115. package/dist/presentation/subscribers/on-runner-job-queued.js.map +0 -1
  116. package/src/presentation/subscribers/on-runner-job-queued.test.ts +0 -57
  117. package/src/presentation/subscribers/on-runner-job-queued.ts +0 -23
@@ -1,12 +1,12 @@
1
1
  $ shipfox-swc && shipfox-temporal-bundle dist/temporal/workflows/index.js
2
- Successfully compiled: 124 files with swc (791.43ms)
3
- 2026-08-10T11:40:58.465Z [INFO] asset workflow-bundle-a5487a6112facdf4dd9d.js 3.32 MiB [emitted] [immutable] (name: main)
2
+ Successfully compiled: 123 files with swc (608.14ms)
3
+ 2026-08-14T18:57:06.620Z [INFO] asset workflow-bundle-4d88ac6c229f6c77759a.js 3.31 MiB [emitted] [immutable] (name: main)
4
4
  orphan modules 33.5 KiB [orphan] 21 modules
5
5
  runtime modules 1.13 KiB 5 modules
6
6
  modules by path ../../../node_modules/.pnpm/ 970 KiB 196 modules
7
- modules by path ./dist/ 41.2 KiB
8
- modules by path ./dist/temporal/ 36.1 KiB
9
- modules by path ./dist/temporal/workflows/*.js 34.8 KiB 5 modules
7
+ modules by path ./dist/ 39.3 KiB
8
+ modules by path ./dist/temporal/ 34.2 KiB
9
+ modules by path ./dist/temporal/workflows/*.js 32.9 KiB 5 modules
10
10
  + 2 modules
11
11
  modules by path ./dist/core/ 5.11 KiB
12
12
  ./dist/core/job-execution-outcome.js 1010 bytes [built] [code generated]
@@ -16,6 +16,6 @@ optional modules 30 bytes [optional]
16
16
  __temporal_custom_payload_converter (ignored) 15 bytes [optional] [built] [code generated]
17
17
  __temporal_custom_failure_converter (ignored) 15 bytes [optional] [built] [code generated]
18
18
  ../../shared/node/temporal/dist/workflow-error-interceptor.js 1.21 KiB [built] [code generated]
19
- webpack 5.107.2 compiled successfully in 8919 ms
20
- 2026-08-10T11:40:58.506Z [INFO] Workflow bundle created { size: '3.32MB' }
21
- /home/runner/work/shipfox/shipfox/libs/api/workflows/dist/temporal/workflows/index.js: 3476109 bytes
19
+ webpack 5.107.2 compiled successfully in 5769 ms
20
+ 2026-08-14T18:57:06.649Z [INFO] Workflow bundle created { size: '3.31MB' }
21
+ /home/runner/work/shipfox/shipfox/libs/api/workflows/dist/temporal/workflows/index.js: 3469609 bytes
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # @shipfox/api-workflows
2
2
 
3
+ ## 13.0.0
4
+
5
+ ### Patch Changes
6
+
7
+ - af6b31e: Expose ordered queued and terminal workflow job-execution facts, and release terminal runner reservations once no uncancelled lease remains.
8
+ - Updated dependencies [af6b31e]
9
+ - @shipfox/api-runners-dto@13.0.0
10
+ - @shipfox/api-workflows-dto@13.0.0
11
+
12
+ ## 12.7.0
13
+
14
+ ### Minor Changes
15
+
16
+ - 4df5e37: Workflow run list items and run detail now carry `has_started_job_execution`, reporting whether any
17
+ job execution of the attempt reached a runner. Run surfaces no longer show a client-derived `Queued`
18
+ state: the run list and run detail present the API attempt status and duration, and read the new
19
+ field to label a finished run's duration as run or elapsed time.
20
+
21
+ ### Patch Changes
22
+
23
+ - Updated dependencies [4df5e37]
24
+ - @shipfox/api-workflows-dto@12.7.0
25
+
3
26
  ## 12.6.0
4
27
 
5
28
  ### Minor Changes
@@ -79,5 +79,8 @@ export interface WorkflowRunDetail extends WorkflowRun {
79
79
  runAttempt: WorkflowRunAttempt;
80
80
  latestAttempt: number;
81
81
  jobs: WorkflowJobDetail[];
82
+ /** Whether any job execution of this attempt reached its runner, decided here so the detail
83
+ * and the list cannot answer it differently. */
84
+ hasStartedJobExecution: boolean;
82
85
  }
83
86
  //# sourceMappingURL=workflow-run.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-run.d.ts","sourceRoot":"","sources":["../../../src/core/entities/workflow-run.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workflow-run.d.ts","sourceRoot":"","sources":["../../../src/core/entities/workflow-run.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/entities/workflow-run.ts"],"sourcesContent":["import type {Job} from './job.js';\nimport type {JobExecution} from './job-execution.js';\nimport type {Step, StepAttempt} from './step.js';\nimport type {WorkflowRunAttempt} from './workflow-run-attempt.js';\n\nexport type WorkflowRunStatus = 'pending' | 'running' | 'succeeded' | 'failed' | 'cancelled';\n\nexport type TerminalWorkflowRunStatus = Extract<\n WorkflowRunStatus,\n 'succeeded' | 'failed' | 'cancelled'\n>;\n\nconst TERMINAL_WORKFLOW_RUN_STATUSES = new Set<WorkflowRunStatus>([\n 'succeeded',\n 'failed',\n 'cancelled',\n]);\n\nexport function isWorkflowRunTerminal(\n status: WorkflowRunStatus,\n): status is TerminalWorkflowRunStatus {\n return TERMINAL_WORKFLOW_RUN_STATUSES.has(status);\n}\n\nexport interface WorkflowRunTriggerReference {\n project: {id: string} | null;\n repository: string | null;\n ref: string | null;\n commit: string | null;\n actor: string | null;\n}\n\nexport interface WorkflowSourceSnapshot {\n content: string;\n format: 'yaml';\n}\n\nexport type TriggerPayload =\n | {\n source: 'manual';\n provider?: 'manual' | undefined;\n event: 'fire';\n subscriptionId: string;\n userId: string;\n }\n | {\n source: 'cron';\n provider?: 'cron' | undefined;\n event: 'tick';\n scheduleId: string;\n }\n // Integration sources (github, gitlab, sentry, …) flow through opaquely: the\n // run records what fired it and carries the raw event payload, without the\n // triggers module having to know each source's shape.\n | {\n source: string;\n provider?: string | undefined;\n event: string;\n deliveryId: string;\n data: unknown;\n };\n\nexport interface WorkflowRun {\n id: string;\n workspaceId: string;\n projectId: string;\n definitionId: string;\n number: number;\n /** Effective runtime name: the resolved override, or workflowName when absent. */\n name: string;\n /** Static workflow-name snapshot preserved from the definition at creation. */\n workflowName: string;\n /** Nullable resolved override retained for rerun fidelity. */\n nameOverride: string | null;\n status: WorkflowRunStatus;\n currentAttempt: number;\n triggerProvider: string | null;\n triggerSource: string;\n triggerEvent: string;\n triggerPayload: TriggerPayload;\n /** Provider-neutral trigger facts captured at run creation, when available. */\n triggerReference?: WorkflowRunTriggerReference | null | undefined;\n inputs: Record<string, unknown> | null;\n sourceSnapshot: WorkflowSourceSnapshot | null;\n triggerIdempotencyKey: string | null;\n timeoutMs: number;\n version: number;\n createdAt: Date;\n updatedAt: Date;\n startedAt: Date | null;\n finishedAt: Date | null;\n}\n\nexport interface StepDetail extends Step {\n attempts: StepAttempt[];\n}\n\nexport interface JobExecutionDetail extends JobExecution {\n steps: StepDetail[];\n}\n\nexport interface WorkflowJobDetail extends Job {\n jobExecutions: JobExecutionDetail[];\n}\n\nexport interface WorkflowRunDetail extends WorkflowRun {\n runAttempt: WorkflowRunAttempt;\n latestAttempt: number;\n jobs: WorkflowJobDetail[];\n}\n"],"names":["TERMINAL_WORKFLOW_RUN_STATUSES","Set","isWorkflowRunTerminal","status","has"],"mappings":"AAYA,MAAMA,iCAAiC,IAAIC,IAAuB;IAChE;IACA;IACA;CACD;AAED,OAAO,SAASC,sBACdC,MAAyB;IAEzB,OAAOH,+BAA+BI,GAAG,CAACD;AAC5C"}
1
+ {"version":3,"sources":["../../../src/core/entities/workflow-run.ts"],"sourcesContent":["import type {Job} from './job.js';\nimport type {JobExecution} from './job-execution.js';\nimport type {Step, StepAttempt} from './step.js';\nimport type {WorkflowRunAttempt} from './workflow-run-attempt.js';\n\nexport type WorkflowRunStatus = 'pending' | 'running' | 'succeeded' | 'failed' | 'cancelled';\n\nexport type TerminalWorkflowRunStatus = Extract<\n WorkflowRunStatus,\n 'succeeded' | 'failed' | 'cancelled'\n>;\n\nconst TERMINAL_WORKFLOW_RUN_STATUSES = new Set<WorkflowRunStatus>([\n 'succeeded',\n 'failed',\n 'cancelled',\n]);\n\nexport function isWorkflowRunTerminal(\n status: WorkflowRunStatus,\n): status is TerminalWorkflowRunStatus {\n return TERMINAL_WORKFLOW_RUN_STATUSES.has(status);\n}\n\nexport interface WorkflowRunTriggerReference {\n project: {id: string} | null;\n repository: string | null;\n ref: string | null;\n commit: string | null;\n actor: string | null;\n}\n\nexport interface WorkflowSourceSnapshot {\n content: string;\n format: 'yaml';\n}\n\nexport type TriggerPayload =\n | {\n source: 'manual';\n provider?: 'manual' | undefined;\n event: 'fire';\n subscriptionId: string;\n userId: string;\n }\n | {\n source: 'cron';\n provider?: 'cron' | undefined;\n event: 'tick';\n scheduleId: string;\n }\n // Integration sources (github, gitlab, sentry, …) flow through opaquely: the\n // run records what fired it and carries the raw event payload, without the\n // triggers module having to know each source's shape.\n | {\n source: string;\n provider?: string | undefined;\n event: string;\n deliveryId: string;\n data: unknown;\n };\n\nexport interface WorkflowRun {\n id: string;\n workspaceId: string;\n projectId: string;\n definitionId: string;\n number: number;\n /** Effective runtime name: the resolved override, or workflowName when absent. */\n name: string;\n /** Static workflow-name snapshot preserved from the definition at creation. */\n workflowName: string;\n /** Nullable resolved override retained for rerun fidelity. */\n nameOverride: string | null;\n status: WorkflowRunStatus;\n currentAttempt: number;\n triggerProvider: string | null;\n triggerSource: string;\n triggerEvent: string;\n triggerPayload: TriggerPayload;\n /** Provider-neutral trigger facts captured at run creation, when available. */\n triggerReference?: WorkflowRunTriggerReference | null | undefined;\n inputs: Record<string, unknown> | null;\n sourceSnapshot: WorkflowSourceSnapshot | null;\n triggerIdempotencyKey: string | null;\n timeoutMs: number;\n version: number;\n createdAt: Date;\n updatedAt: Date;\n startedAt: Date | null;\n finishedAt: Date | null;\n}\n\nexport interface StepDetail extends Step {\n attempts: StepAttempt[];\n}\n\nexport interface JobExecutionDetail extends JobExecution {\n steps: StepDetail[];\n}\n\nexport interface WorkflowJobDetail extends Job {\n jobExecutions: JobExecutionDetail[];\n}\n\nexport interface WorkflowRunDetail extends WorkflowRun {\n runAttempt: WorkflowRunAttempt;\n latestAttempt: number;\n jobs: WorkflowJobDetail[];\n /** Whether any job execution of this attempt reached its runner, decided here so the detail\n * and the list cannot answer it differently. */\n hasStartedJobExecution: boolean;\n}\n"],"names":["TERMINAL_WORKFLOW_RUN_STATUSES","Set","isWorkflowRunTerminal","status","has"],"mappings":"AAYA,MAAMA,iCAAiC,IAAIC,IAAuB;IAChE;IACA;IACA;CACD;AAED,OAAO,SAASC,sBACdC,MAAyB;IAEzB,OAAOH,+BAA+BI,GAAG,CAACD;AAC5C"}
@@ -5,6 +5,6 @@ export { activateJobListener, countActiveListeners, drainListenerEventsIntoExecu
5
5
  export { workflowsOutbox } from './schema/outbox.js';
6
6
  export { workflowRunCounters } from './schema/workflow-run-counters.js';
7
7
  export type { BulkUpdateStepStatusesParams, CancelWorkflowRunParams, CreateRerunWorkflowRunParams, CreateWorkflowRunParams, EvaluateJobActivationsParams, FailWorkflowRunAsTimedOutParams, JobActivationDecision, ListWorkflowRunsParams, ListWorkflowRunsResult, StepAttemptDetail, UpdateJobExecutionStatusParams, UpdateJobStatusParams, UpdateWorkflowRunStatusParams, WorkflowJobExecutionDepth, WorkflowJobExecutionDepthParams, WorkflowRunAggregates, WorkflowRunFilters, WorkflowRunJobRawStatusCount, WorkflowRunJobStatusCount, WorkflowRunJobSummary, WorkflowRunJobSummaryTarget, WorkflowRunJobsSummary, } from './workflow-runs.js';
8
- export { bulkUpdateStepStatuses, cancelWorkflowRun, createRerunWorkflowRun, createWorkflowRun, evaluateJobActivations, failJobExecutionAsTimedOut, failWorkflowRunAsTimedOut, getFirstJobExecutionByJobId, getJobById, getJobExecutionById, getJobExecutionDetail, getJobExecutionFailureOrigin, getJobExecutionsByJobId, getJobExecutionsByWorkflowRunAttemptId, getJobScope, getJobsByWorkflowRunAttemptId, getJobsByWorkflowRunId, getLatestAttempt, getLatestJobExecutionByJobId, getStepAttemptDetail, getStepAttempts, getStepAttemptsByJobIds, getStepById, getStepByIdForJobExecution, getStepsByJobExecutionId, getStepsByJobExecutionIdForUpdate, getWorkflowJobExecutionDepth, getWorkflowRunAggregates, getWorkflowRunAttemptById, getWorkflowRunByAttemptId, getWorkflowRunById, getWorkflowRunDetail, listRunAttempts, listWorkflowRunJobSummaries, listWorkflowRuns, listWorkflowRunsByProject, recordJobExecutionQueuedAt, recordJobExecutionStartedAt, resolveJobExecutionAfterLeaseExpiry, resolveJobStatusFromJobExecutions, updateJobExecutionStatus, updateJobStatus, updateWorkflowRunStatus, } from './workflow-runs.js';
8
+ export { bulkUpdateStepStatuses, cancelWorkflowRun, createRerunWorkflowRun, createWorkflowRun, evaluateJobActivations, failJobExecutionAsTimedOut, failWorkflowRunAsTimedOut, getFirstJobExecutionByJobId, getJobById, getJobExecutionById, getJobExecutionDetail, getJobExecutionFailureOrigin, getJobExecutionsByJobId, getJobExecutionsByWorkflowRunAttemptId, getJobScope, getJobsByWorkflowRunAttemptId, getJobsByWorkflowRunId, getLatestAttempt, getLatestJobExecutionByJobId, getStepAttemptDetail, getStepAttempts, getStepAttemptsByJobIds, getStepById, getStepByIdForJobExecution, getStepsByJobExecutionId, getStepsByJobExecutionIdForUpdate, getWorkflowJobExecutionDepth, getWorkflowRunAggregates, getWorkflowRunAttemptById, getWorkflowRunByAttemptId, getWorkflowRunById, getWorkflowRunDetail, listRunAttempts, listWorkflowRunJobSummaries, listWorkflowRuns, listWorkflowRunsByProject, queueJobExecution, recordJobExecutionStartedAt, resolveJobExecutionAfterLeaseExpiry, resolveJobStatusFromJobExecutions, updateJobExecutionStatus, updateJobStatus, updateWorkflowRunStatus, } from './workflow-runs.js';
9
9
  export declare const migrationsPath: string;
10
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,OAAO,EAAE,EAAE,EAAE,MAAM,EAAC,MAAM,SAAS,CAAC;AAC5C,OAAO,EACL,KAAK,4BAA4B,EACjC,KAAK,4BAA4B,EACjC,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,EACzB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,gCAAgC,EAChC,kBAAkB,EAClB,kBAAkB,EAClB,0BAA0B,GAC3B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAC,eAAe,EAAC,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAC,mBAAmB,EAAC,MAAM,mCAAmC,CAAC;AACtE,YAAY,EACV,4BAA4B,EAC5B,uBAAuB,EACvB,4BAA4B,EAC5B,uBAAuB,EACvB,4BAA4B,EAC5B,+BAA+B,EAC/B,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACtB,iBAAiB,EACjB,8BAA8B,EAC9B,qBAAqB,EACrB,6BAA6B,EAC7B,yBAAyB,EACzB,+BAA+B,EAC/B,qBAAqB,EACrB,kBAAkB,EAClB,4BAA4B,EAC5B,yBAAyB,EACzB,qBAAqB,EACrB,2BAA2B,EAC3B,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,sBAAsB,EACtB,iBAAiB,EACjB,sBAAsB,EACtB,0BAA0B,EAC1B,yBAAyB,EACzB,2BAA2B,EAC3B,UAAU,EACV,mBAAmB,EACnB,qBAAqB,EACrB,4BAA4B,EAC5B,uBAAuB,EACvB,sCAAsC,EACtC,WAAW,EACX,6BAA6B,EAC7B,sBAAsB,EACtB,gBAAgB,EAChB,4BAA4B,EAC5B,oBAAoB,EACpB,eAAe,EACf,uBAAuB,EACvB,WAAW,EACX,0BAA0B,EAC1B,wBAAwB,EACxB,iCAAiC,EACjC,4BAA4B,EAC5B,wBAAwB,EACxB,yBAAyB,EACzB,yBAAyB,EACzB,kBAAkB,EAClB,oBAAoB,EACpB,eAAe,EACf,2BAA2B,EAC3B,gBAAgB,EAChB,yBAAyB,EACzB,0BAA0B,EAC1B,2BAA2B,EAC3B,mCAAmC,EACnC,iCAAiC,EACjC,wBAAwB,EACxB,eAAe,EACf,uBAAuB,GACxB,MAAM,oBAAoB,CAAC;AAE5B,eAAO,MAAM,cAAc,QAAoE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,OAAO,EAAE,EAAE,EAAE,MAAM,EAAC,MAAM,SAAS,CAAC;AAC5C,OAAO,EACL,KAAK,4BAA4B,EACjC,KAAK,4BAA4B,EACjC,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,EACzB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,gCAAgC,EAChC,kBAAkB,EAClB,kBAAkB,EAClB,0BAA0B,GAC3B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAC,eAAe,EAAC,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAC,mBAAmB,EAAC,MAAM,mCAAmC,CAAC;AACtE,YAAY,EACV,4BAA4B,EAC5B,uBAAuB,EACvB,4BAA4B,EAC5B,uBAAuB,EACvB,4BAA4B,EAC5B,+BAA+B,EAC/B,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACtB,iBAAiB,EACjB,8BAA8B,EAC9B,qBAAqB,EACrB,6BAA6B,EAC7B,yBAAyB,EACzB,+BAA+B,EAC/B,qBAAqB,EACrB,kBAAkB,EAClB,4BAA4B,EAC5B,yBAAyB,EACzB,qBAAqB,EACrB,2BAA2B,EAC3B,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,sBAAsB,EACtB,iBAAiB,EACjB,sBAAsB,EACtB,0BAA0B,EAC1B,yBAAyB,EACzB,2BAA2B,EAC3B,UAAU,EACV,mBAAmB,EACnB,qBAAqB,EACrB,4BAA4B,EAC5B,uBAAuB,EACvB,sCAAsC,EACtC,WAAW,EACX,6BAA6B,EAC7B,sBAAsB,EACtB,gBAAgB,EAChB,4BAA4B,EAC5B,oBAAoB,EACpB,eAAe,EACf,uBAAuB,EACvB,WAAW,EACX,0BAA0B,EAC1B,wBAAwB,EACxB,iCAAiC,EACjC,4BAA4B,EAC5B,wBAAwB,EACxB,yBAAyB,EACzB,yBAAyB,EACzB,kBAAkB,EAClB,oBAAoB,EACpB,eAAe,EACf,2BAA2B,EAC3B,gBAAgB,EAChB,yBAAyB,EACzB,iBAAiB,EACjB,2BAA2B,EAC3B,mCAAmC,EACnC,iCAAiC,EACjC,wBAAwB,EACxB,eAAe,EACf,uBAAuB,GACxB,MAAM,oBAAoB,CAAC;AAE5B,eAAO,MAAM,cAAc,QAAoE,CAAC"}
package/dist/db/index.js CHANGED
@@ -5,7 +5,7 @@ export { deliverEventToListener } from './job-listener-events.js';
5
5
  export { activateJobListener, countActiveListeners, drainListenerEventsIntoExecution, peekListenerBuffer, resolveJobListener, settleListenerJobExecution } from './job-listeners.js';
6
6
  export { workflowsOutbox } from './schema/outbox.js';
7
7
  export { workflowRunCounters } from './schema/workflow-run-counters.js';
8
- export { bulkUpdateStepStatuses, cancelWorkflowRun, createRerunWorkflowRun, createWorkflowRun, evaluateJobActivations, failJobExecutionAsTimedOut, failWorkflowRunAsTimedOut, getFirstJobExecutionByJobId, getJobById, getJobExecutionById, getJobExecutionDetail, getJobExecutionFailureOrigin, getJobExecutionsByJobId, getJobExecutionsByWorkflowRunAttemptId, getJobScope, getJobsByWorkflowRunAttemptId, getJobsByWorkflowRunId, getLatestAttempt, getLatestJobExecutionByJobId, getStepAttemptDetail, getStepAttempts, getStepAttemptsByJobIds, getStepById, getStepByIdForJobExecution, getStepsByJobExecutionId, getStepsByJobExecutionIdForUpdate, getWorkflowJobExecutionDepth, getWorkflowRunAggregates, getWorkflowRunAttemptById, getWorkflowRunByAttemptId, getWorkflowRunById, getWorkflowRunDetail, listRunAttempts, listWorkflowRunJobSummaries, listWorkflowRuns, listWorkflowRunsByProject, recordJobExecutionQueuedAt, recordJobExecutionStartedAt, resolveJobExecutionAfterLeaseExpiry, resolveJobStatusFromJobExecutions, updateJobExecutionStatus, updateJobStatus, updateWorkflowRunStatus } from './workflow-runs.js';
8
+ export { bulkUpdateStepStatuses, cancelWorkflowRun, createRerunWorkflowRun, createWorkflowRun, evaluateJobActivations, failJobExecutionAsTimedOut, failWorkflowRunAsTimedOut, getFirstJobExecutionByJobId, getJobById, getJobExecutionById, getJobExecutionDetail, getJobExecutionFailureOrigin, getJobExecutionsByJobId, getJobExecutionsByWorkflowRunAttemptId, getJobScope, getJobsByWorkflowRunAttemptId, getJobsByWorkflowRunId, getLatestAttempt, getLatestJobExecutionByJobId, getStepAttemptDetail, getStepAttempts, getStepAttemptsByJobIds, getStepById, getStepByIdForJobExecution, getStepsByJobExecutionId, getStepsByJobExecutionIdForUpdate, getWorkflowJobExecutionDepth, getWorkflowRunAggregates, getWorkflowRunAttemptById, getWorkflowRunByAttemptId, getWorkflowRunById, getWorkflowRunDetail, listRunAttempts, listWorkflowRunJobSummaries, listWorkflowRuns, listWorkflowRunsByProject, queueJobExecution, recordJobExecutionStartedAt, resolveJobExecutionAfterLeaseExpiry, resolveJobStatusFromJobExecutions, updateJobExecutionStatus, updateJobStatus, updateWorkflowRunStatus } from './workflow-runs.js';
9
9
  export const migrationsPath = resolve(dirname(fileURLToPath(import.meta.url)), '../../drizzle');
10
10
 
11
11
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/db/index.ts"],"sourcesContent":["import {dirname, resolve} from 'node:path';\nimport {fileURLToPath} from 'node:url';\n\nexport {closeDb, db, schema} from './db.js';\nexport {\n type DeliverEventToListenerParams,\n type DeliverEventToListenerResult,\n deliverEventToListener,\n} from './job-listener-events.js';\nexport type {\n ActivateJobListenerParams,\n ActivateJobListenerResult,\n DrainListenerEventsParams,\n DrainListenerEventsResult,\n ListenerBufferPeek,\n} from './job-listeners.js';\nexport {\n activateJobListener,\n countActiveListeners,\n drainListenerEventsIntoExecution,\n peekListenerBuffer,\n resolveJobListener,\n settleListenerJobExecution,\n} from './job-listeners.js';\nexport {workflowsOutbox} from './schema/outbox.js';\nexport {workflowRunCounters} from './schema/workflow-run-counters.js';\nexport type {\n BulkUpdateStepStatusesParams,\n CancelWorkflowRunParams,\n CreateRerunWorkflowRunParams,\n CreateWorkflowRunParams,\n EvaluateJobActivationsParams,\n FailWorkflowRunAsTimedOutParams,\n JobActivationDecision,\n ListWorkflowRunsParams,\n ListWorkflowRunsResult,\n StepAttemptDetail,\n UpdateJobExecutionStatusParams,\n UpdateJobStatusParams,\n UpdateWorkflowRunStatusParams,\n WorkflowJobExecutionDepth,\n WorkflowJobExecutionDepthParams,\n WorkflowRunAggregates,\n WorkflowRunFilters,\n WorkflowRunJobRawStatusCount,\n WorkflowRunJobStatusCount,\n WorkflowRunJobSummary,\n WorkflowRunJobSummaryTarget,\n WorkflowRunJobsSummary,\n} from './workflow-runs.js';\nexport {\n bulkUpdateStepStatuses,\n cancelWorkflowRun,\n createRerunWorkflowRun,\n createWorkflowRun,\n evaluateJobActivations,\n failJobExecutionAsTimedOut,\n failWorkflowRunAsTimedOut,\n getFirstJobExecutionByJobId,\n getJobById,\n getJobExecutionById,\n getJobExecutionDetail,\n getJobExecutionFailureOrigin,\n getJobExecutionsByJobId,\n getJobExecutionsByWorkflowRunAttemptId,\n getJobScope,\n getJobsByWorkflowRunAttemptId,\n getJobsByWorkflowRunId,\n getLatestAttempt,\n getLatestJobExecutionByJobId,\n getStepAttemptDetail,\n getStepAttempts,\n getStepAttemptsByJobIds,\n getStepById,\n getStepByIdForJobExecution,\n getStepsByJobExecutionId,\n getStepsByJobExecutionIdForUpdate,\n getWorkflowJobExecutionDepth,\n getWorkflowRunAggregates,\n getWorkflowRunAttemptById,\n getWorkflowRunByAttemptId,\n getWorkflowRunById,\n getWorkflowRunDetail,\n listRunAttempts,\n listWorkflowRunJobSummaries,\n listWorkflowRuns,\n listWorkflowRunsByProject,\n recordJobExecutionQueuedAt,\n recordJobExecutionStartedAt,\n resolveJobExecutionAfterLeaseExpiry,\n resolveJobStatusFromJobExecutions,\n updateJobExecutionStatus,\n updateJobStatus,\n updateWorkflowRunStatus,\n} from './workflow-runs.js';\n\nexport const migrationsPath = resolve(dirname(fileURLToPath(import.meta.url)), '../../drizzle');\n"],"names":["dirname","resolve","fileURLToPath","closeDb","db","schema","deliverEventToListener","activateJobListener","countActiveListeners","drainListenerEventsIntoExecution","peekListenerBuffer","resolveJobListener","settleListenerJobExecution","workflowsOutbox","workflowRunCounters","bulkUpdateStepStatuses","cancelWorkflowRun","createRerunWorkflowRun","createWorkflowRun","evaluateJobActivations","failJobExecutionAsTimedOut","failWorkflowRunAsTimedOut","getFirstJobExecutionByJobId","getJobById","getJobExecutionById","getJobExecutionDetail","getJobExecutionFailureOrigin","getJobExecutionsByJobId","getJobExecutionsByWorkflowRunAttemptId","getJobScope","getJobsByWorkflowRunAttemptId","getJobsByWorkflowRunId","getLatestAttempt","getLatestJobExecutionByJobId","getStepAttemptDetail","getStepAttempts","getStepAttemptsByJobIds","getStepById","getStepByIdForJobExecution","getStepsByJobExecutionId","getStepsByJobExecutionIdForUpdate","getWorkflowJobExecutionDepth","getWorkflowRunAggregates","getWorkflowRunAttemptById","getWorkflowRunByAttemptId","getWorkflowRunById","getWorkflowRunDetail","listRunAttempts","listWorkflowRunJobSummaries","listWorkflowRuns","listWorkflowRunsByProject","recordJobExecutionQueuedAt","recordJobExecutionStartedAt","resolveJobExecutionAfterLeaseExpiry","resolveJobStatusFromJobExecutions","updateJobExecutionStatus","updateJobStatus","updateWorkflowRunStatus","migrationsPath","url"],"mappings":"AAAA,SAAQA,OAAO,EAAEC,OAAO,QAAO,YAAY;AAC3C,SAAQC,aAAa,QAAO,WAAW;AAEvC,SAAQC,OAAO,EAAEC,EAAE,EAAEC,MAAM,QAAO,UAAU;AAC5C,SAGEC,sBAAsB,QACjB,2BAA2B;AAQlC,SACEC,mBAAmB,EACnBC,oBAAoB,EACpBC,gCAAgC,EAChCC,kBAAkB,EAClBC,kBAAkB,EAClBC,0BAA0B,QACrB,qBAAqB;AAC5B,SAAQC,eAAe,QAAO,qBAAqB;AACnD,SAAQC,mBAAmB,QAAO,oCAAoC;AAyBtE,SACEC,sBAAsB,EACtBC,iBAAiB,EACjBC,sBAAsB,EACtBC,iBAAiB,EACjBC,sBAAsB,EACtBC,0BAA0B,EAC1BC,yBAAyB,EACzBC,2BAA2B,EAC3BC,UAAU,EACVC,mBAAmB,EACnBC,qBAAqB,EACrBC,4BAA4B,EAC5BC,uBAAuB,EACvBC,sCAAsC,EACtCC,WAAW,EACXC,6BAA6B,EAC7BC,sBAAsB,EACtBC,gBAAgB,EAChBC,4BAA4B,EAC5BC,oBAAoB,EACpBC,eAAe,EACfC,uBAAuB,EACvBC,WAAW,EACXC,0BAA0B,EAC1BC,wBAAwB,EACxBC,iCAAiC,EACjCC,4BAA4B,EAC5BC,wBAAwB,EACxBC,yBAAyB,EACzBC,yBAAyB,EACzBC,kBAAkB,EAClBC,oBAAoB,EACpBC,eAAe,EACfC,2BAA2B,EAC3BC,gBAAgB,EAChBC,yBAAyB,EACzBC,0BAA0B,EAC1BC,2BAA2B,EAC3BC,mCAAmC,EACnCC,iCAAiC,EACjCC,wBAAwB,EACxBC,eAAe,EACfC,uBAAuB,QAClB,qBAAqB;AAE5B,OAAO,MAAMC,iBAAiBzD,QAAQD,QAAQE,cAAc,YAAYyD,GAAG,IAAI,iBAAiB"}
1
+ {"version":3,"sources":["../../src/db/index.ts"],"sourcesContent":["import {dirname, resolve} from 'node:path';\nimport {fileURLToPath} from 'node:url';\n\nexport {closeDb, db, schema} from './db.js';\nexport {\n type DeliverEventToListenerParams,\n type DeliverEventToListenerResult,\n deliverEventToListener,\n} from './job-listener-events.js';\nexport type {\n ActivateJobListenerParams,\n ActivateJobListenerResult,\n DrainListenerEventsParams,\n DrainListenerEventsResult,\n ListenerBufferPeek,\n} from './job-listeners.js';\nexport {\n activateJobListener,\n countActiveListeners,\n drainListenerEventsIntoExecution,\n peekListenerBuffer,\n resolveJobListener,\n settleListenerJobExecution,\n} from './job-listeners.js';\nexport {workflowsOutbox} from './schema/outbox.js';\nexport {workflowRunCounters} from './schema/workflow-run-counters.js';\nexport type {\n BulkUpdateStepStatusesParams,\n CancelWorkflowRunParams,\n CreateRerunWorkflowRunParams,\n CreateWorkflowRunParams,\n EvaluateJobActivationsParams,\n FailWorkflowRunAsTimedOutParams,\n JobActivationDecision,\n ListWorkflowRunsParams,\n ListWorkflowRunsResult,\n StepAttemptDetail,\n UpdateJobExecutionStatusParams,\n UpdateJobStatusParams,\n UpdateWorkflowRunStatusParams,\n WorkflowJobExecutionDepth,\n WorkflowJobExecutionDepthParams,\n WorkflowRunAggregates,\n WorkflowRunFilters,\n WorkflowRunJobRawStatusCount,\n WorkflowRunJobStatusCount,\n WorkflowRunJobSummary,\n WorkflowRunJobSummaryTarget,\n WorkflowRunJobsSummary,\n} from './workflow-runs.js';\nexport {\n bulkUpdateStepStatuses,\n cancelWorkflowRun,\n createRerunWorkflowRun,\n createWorkflowRun,\n evaluateJobActivations,\n failJobExecutionAsTimedOut,\n failWorkflowRunAsTimedOut,\n getFirstJobExecutionByJobId,\n getJobById,\n getJobExecutionById,\n getJobExecutionDetail,\n getJobExecutionFailureOrigin,\n getJobExecutionsByJobId,\n getJobExecutionsByWorkflowRunAttemptId,\n getJobScope,\n getJobsByWorkflowRunAttemptId,\n getJobsByWorkflowRunId,\n getLatestAttempt,\n getLatestJobExecutionByJobId,\n getStepAttemptDetail,\n getStepAttempts,\n getStepAttemptsByJobIds,\n getStepById,\n getStepByIdForJobExecution,\n getStepsByJobExecutionId,\n getStepsByJobExecutionIdForUpdate,\n getWorkflowJobExecutionDepth,\n getWorkflowRunAggregates,\n getWorkflowRunAttemptById,\n getWorkflowRunByAttemptId,\n getWorkflowRunById,\n getWorkflowRunDetail,\n listRunAttempts,\n listWorkflowRunJobSummaries,\n listWorkflowRuns,\n listWorkflowRunsByProject,\n queueJobExecution,\n recordJobExecutionStartedAt,\n resolveJobExecutionAfterLeaseExpiry,\n resolveJobStatusFromJobExecutions,\n updateJobExecutionStatus,\n updateJobStatus,\n updateWorkflowRunStatus,\n} from './workflow-runs.js';\n\nexport const migrationsPath = resolve(dirname(fileURLToPath(import.meta.url)), '../../drizzle');\n"],"names":["dirname","resolve","fileURLToPath","closeDb","db","schema","deliverEventToListener","activateJobListener","countActiveListeners","drainListenerEventsIntoExecution","peekListenerBuffer","resolveJobListener","settleListenerJobExecution","workflowsOutbox","workflowRunCounters","bulkUpdateStepStatuses","cancelWorkflowRun","createRerunWorkflowRun","createWorkflowRun","evaluateJobActivations","failJobExecutionAsTimedOut","failWorkflowRunAsTimedOut","getFirstJobExecutionByJobId","getJobById","getJobExecutionById","getJobExecutionDetail","getJobExecutionFailureOrigin","getJobExecutionsByJobId","getJobExecutionsByWorkflowRunAttemptId","getJobScope","getJobsByWorkflowRunAttemptId","getJobsByWorkflowRunId","getLatestAttempt","getLatestJobExecutionByJobId","getStepAttemptDetail","getStepAttempts","getStepAttemptsByJobIds","getStepById","getStepByIdForJobExecution","getStepsByJobExecutionId","getStepsByJobExecutionIdForUpdate","getWorkflowJobExecutionDepth","getWorkflowRunAggregates","getWorkflowRunAttemptById","getWorkflowRunByAttemptId","getWorkflowRunById","getWorkflowRunDetail","listRunAttempts","listWorkflowRunJobSummaries","listWorkflowRuns","listWorkflowRunsByProject","queueJobExecution","recordJobExecutionStartedAt","resolveJobExecutionAfterLeaseExpiry","resolveJobStatusFromJobExecutions","updateJobExecutionStatus","updateJobStatus","updateWorkflowRunStatus","migrationsPath","url"],"mappings":"AAAA,SAAQA,OAAO,EAAEC,OAAO,QAAO,YAAY;AAC3C,SAAQC,aAAa,QAAO,WAAW;AAEvC,SAAQC,OAAO,EAAEC,EAAE,EAAEC,MAAM,QAAO,UAAU;AAC5C,SAGEC,sBAAsB,QACjB,2BAA2B;AAQlC,SACEC,mBAAmB,EACnBC,oBAAoB,EACpBC,gCAAgC,EAChCC,kBAAkB,EAClBC,kBAAkB,EAClBC,0BAA0B,QACrB,qBAAqB;AAC5B,SAAQC,eAAe,QAAO,qBAAqB;AACnD,SAAQC,mBAAmB,QAAO,oCAAoC;AAyBtE,SACEC,sBAAsB,EACtBC,iBAAiB,EACjBC,sBAAsB,EACtBC,iBAAiB,EACjBC,sBAAsB,EACtBC,0BAA0B,EAC1BC,yBAAyB,EACzBC,2BAA2B,EAC3BC,UAAU,EACVC,mBAAmB,EACnBC,qBAAqB,EACrBC,4BAA4B,EAC5BC,uBAAuB,EACvBC,sCAAsC,EACtCC,WAAW,EACXC,6BAA6B,EAC7BC,sBAAsB,EACtBC,gBAAgB,EAChBC,4BAA4B,EAC5BC,oBAAoB,EACpBC,eAAe,EACfC,uBAAuB,EACvBC,WAAW,EACXC,0BAA0B,EAC1BC,wBAAwB,EACxBC,iCAAiC,EACjCC,4BAA4B,EAC5BC,wBAAwB,EACxBC,yBAAyB,EACzBC,yBAAyB,EACzBC,kBAAkB,EAClBC,oBAAoB,EACpBC,eAAe,EACfC,2BAA2B,EAC3BC,gBAAgB,EAChBC,yBAAyB,EACzBC,iBAAiB,EACjBC,2BAA2B,EAC3BC,mCAAmC,EACnCC,iCAAiC,EACjCC,wBAAwB,EACxBC,eAAe,EACfC,uBAAuB,QAClB,qBAAqB;AAE5B,OAAO,MAAMC,iBAAiBzD,QAAQD,QAAQE,cAAc,YAAYyD,GAAG,IAAI,iBAAiB"}
@@ -1 +1 @@
1
- {"version":3,"file":"job-listeners.d.ts","sourceRoot":"","sources":["../../src/db/job-listeners.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"job-listeners.d.ts","sourceRoot":"","sources":["../../src/db/job-listeners.ts"],"names":[],"mappings":"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"}
@@ -18,7 +18,7 @@ import { jobs, toJob } from './schema/jobs.js';
18
18
  import { steps } from './schema/steps.js';
19
19
  import { workflowRunAttempts } from './schema/workflow-run-attempts.js';
20
20
  import { toWorkflowRun, workflowRuns } from './schema/workflow-runs.js';
21
- import { bulkUpdateStepStatuses, getDirectDependencyJobContexts, loadReferencedVariables, updateJobStatusAtVersion } from './workflow-runs.js';
21
+ import { bulkUpdateStepStatuses, getDirectDependencyJobContexts, loadReferencedVariables, updateJobStatusAtVersion, writeJobExecutionTerminatedOutbox } from './workflow-runs.js';
22
22
  const TERMINAL_EXECUTION_STATUSES = [
23
23
  'succeeded',
24
24
  'failed',
@@ -305,6 +305,13 @@ export async function settleListenerJobExecution(params) {
305
305
  finishedAt: sql`now()`
306
306
  }).where(and(eq(jobExecutions.id, params.jobExecutionId), notInArray(jobExecutions.status, TERMINAL_EXECUTION_STATUSES))).returning();
307
307
  if (!execution) return false;
308
+ await writeJobExecutionTerminatedOutbox(tx, {
309
+ jobId: execution.jobId,
310
+ jobExecutionId: execution.id,
311
+ status: execution.status,
312
+ statusReason: execution.statusReason,
313
+ statusReasonMessage: execution.statusReasonMessage
314
+ });
308
315
  await bulkUpdateStepStatuses({
309
316
  jobExecutionId: params.jobExecutionId,
310
317
  status: params.status
@@ -374,6 +381,15 @@ async function persistMaterializedListenerExecution(tx, params) {
374
381
  } : {}
375
382
  }).returning();
376
383
  if (!execution) throw new Error('Insert returned no rows');
384
+ if (execution.status === 'failed') {
385
+ await writeJobExecutionTerminatedOutbox(tx, {
386
+ jobId: execution.jobId,
387
+ jobExecutionId: execution.id,
388
+ status: execution.status,
389
+ statusReason: execution.statusReason,
390
+ statusReasonMessage: execution.statusReasonMessage
391
+ });
392
+ }
377
393
  await tx.update(jobListenerEvents).set({
378
394
  consumedByExecutionId: execution.id
379
395
  }).where(inArray(jobListenerEvents.id, [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/db/job-listeners.ts"],"sourcesContent":["import type {AgentInterModuleClient} from '@shipfox/api-agent-dto/inter-module';\nimport {readPersistedWorkflowModel} from '@shipfox/api-definitions-dto';\nimport type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto/inter-module';\nimport type {ProjectsModuleClient} from '@shipfox/api-projects-dto/inter-module';\nimport type {SecretsInterModuleClient} from '@shipfox/api-secrets-dto/inter-module';\nimport {\n WORKFLOWS_JOB_ACTIVATED,\n type WorkflowsJobActivatedEventDto,\n} from '@shipfox/api-workflows-dto';\nimport {and, asc, count, eq, inArray, isNull, notInArray, sql} from 'drizzle-orm';\nimport {type AgentDefaultsResolver, createAgentDefaultsResolver} from '#core/agent-defaults.js';\nimport {loadAgentToolMaterializationContext} from '#core/agent-tools.js';\nimport {isJobTerminal, type JobStatus, type ResolutionReason} from '#core/entities/job.js';\nimport type {\n JobExecution,\n JobExecutionStatus,\n WorkflowExecutionEvent,\n} from '#core/entities/job-execution.js';\nimport {normalizeWorkflowExecutionEvent} from '#core/entities/job-execution.js';\nimport {InterpolationUnresolvableError} from '#core/errors.js';\nimport {type DeriveJobSuccessResult, deriveJobSuccess} from '#core/job-transition/index.js';\nimport {\n type MaterializedListenerExecution,\n materializeListenerExecution,\n} from '#core/listener-execution-materialization.js';\nimport {\n applyListenerFilterSnapshots,\n assembleListenerSnapshotContext,\n type ListenerTriggerWithSnapshot,\n listenerFilterOutputTypesForJobs,\n planListenerFilterSnapshots,\n} from '#core/step-config/assemble-run-context.js';\nimport {\n recordListenerEventsCoalesced,\n recordWorkflowJobExecutionStatusChanged,\n recordWorkflowListenerResolved,\n} from '#metrics/instance.js';\nimport {db, type Tx} from './db.js';\nimport {writeWorkflowsOutboxEvent} from './outbox-writes.js';\nimport {type JobExecutionDb, jobExecutions, toJobExecution} from './schema/job-executions.js';\nimport {type JobListenerEventDb, jobListenerEvents} from './schema/job-listener-events.js';\nimport {jobs, toJob} from './schema/jobs.js';\nimport {steps} from './schema/steps.js';\nimport {workflowRunAttempts} from './schema/workflow-run-attempts.js';\nimport {toWorkflowRun, workflowRuns} from './schema/workflow-runs.js';\nimport {\n bulkUpdateStepStatuses,\n getDirectDependencyJobContexts,\n loadReferencedVariables,\n updateJobStatusAtVersion,\n} from './workflow-runs.js';\n\nconst TERMINAL_EXECUTION_STATUSES: JobExecutionStatus[] = ['succeeded', 'failed', 'cancelled'];\nconst MAX_LISTENER_RESOLUTION_ATTEMPTS = 3;\n\nexport interface ActivateJobListenerParams {\n jobId: string;\n expectedVersion: number;\n}\n\nexport interface ActivateJobListenerResult {\n status: 'running' | 'terminal';\n jobStatus: JobStatus;\n jobVersion: number;\n executionCount: number;\n}\n\ntype JobActivatedListenerMatcher = Extract<\n WorkflowsJobActivatedEventDto,\n {mode: 'listening'}\n>['on'][number] &\n ListenerTriggerWithSnapshot;\n\nfunction applyActivatedListenerFilterSnapshots(\n plans: Parameters<typeof applyListenerFilterSnapshots>[0],\n context: Parameters<typeof applyListenerFilterSnapshots>[1],\n outputTypes: Parameters<typeof applyListenerFilterSnapshots>[2],\n): JobActivatedListenerMatcher[] {\n return applyListenerFilterSnapshots(plans, context, outputTypes);\n}\n\nexport async function activateJobListener(\n params: ActivateJobListenerParams,\n): Promise<ActivateJobListenerResult> {\n return await db().transaction(async (tx) => {\n const [target] = await tx\n .select({job: jobs, attempt: workflowRunAttempts, run: workflowRuns})\n .from(jobs)\n .innerJoin(workflowRunAttempts, eq(jobs.workflowRunAttemptId, workflowRunAttempts.id))\n .innerJoin(workflowRuns, eq(workflowRunAttempts.workflowRunId, workflowRuns.id))\n .where(eq(jobs.id, params.jobId))\n .limit(1)\n .for('update');\n if (!target) throw new Error(`Job not found: ${params.jobId}`);\n\n const [{value: executionCount} = {value: 0}] = await tx\n .select({value: count()})\n .from(jobExecutions)\n .where(eq(jobExecutions.jobId, params.jobId));\n\n if (['succeeded', 'failed', 'cancelled', 'skipped'].includes(target.job.status)) {\n return {\n status: 'terminal',\n jobStatus: target.job.status,\n jobVersion: target.job.version,\n executionCount,\n };\n }\n\n let job = toJob(target.job);\n if (target.job.status === 'pending') {\n const updated = await updateJobStatusAtVersion(tx, {\n jobId: params.jobId,\n status: 'running',\n expectedVersion: params.expectedVersion,\n });\n if (!updated) {\n const [existing] = await tx.select().from(jobs).where(eq(jobs.id, params.jobId)).limit(1);\n if (existing?.status !== 'running') {\n throw new Error(\n `Optimistic lock failure activating listener job ${params.jobId} version ${params.expectedVersion}`,\n );\n }\n job = toJob(existing);\n } else {\n job = updated.job;\n }\n }\n\n const listenerRows = await tx\n .update(jobs)\n .set({listenerStatus: 'listening', updatedAt: new Date()})\n .where(and(eq(jobs.id, params.jobId), eq(jobs.listenerStatus, 'inactive')))\n .returning();\n\n if (listenerRows[0]) {\n const matchers = {\n on: target.job.listeningOn ?? [],\n until: target.job.listeningUntil ?? null,\n };\n const snapshotPlan = planListenerFilterSnapshots(matchers);\n const dependencyJobs =\n snapshotPlan.jobKeys.size === 0\n ? []\n : await getDirectDependencyJobContexts(params.jobId, tx);\n const snapshotContext = assembleListenerSnapshotContext({\n job: toJob(target.job),\n run: toWorkflowRun(target.run),\n triggerPayload: target.run.triggerPayload,\n inputs: target.run.inputs,\n vars: target.attempt.vars ?? undefined,\n plan: snapshotPlan,\n dependencyJobs,\n });\n const listenerOutputTypes = listenerFilterOutputTypesForJobs(dependencyJobs);\n\n await writeWorkflowsOutboxEvent(tx, {\n type: WORKFLOWS_JOB_ACTIVATED,\n payload: {\n jobId: params.jobId,\n workflowRunId: target.run.id,\n workspaceId: target.run.workspaceId,\n mode: 'listening',\n on: applyActivatedListenerFilterSnapshots(\n snapshotPlan.on,\n snapshotContext,\n listenerOutputTypes,\n ),\n until:\n matchers.until === null\n ? null\n : applyActivatedListenerFilterSnapshots(\n snapshotPlan.until,\n snapshotContext,\n listenerOutputTypes,\n ),\n },\n });\n }\n\n return {status: 'running', jobStatus: job.status, jobVersion: job.version, executionCount};\n });\n}\n\nexport type DrainListenerEventsResult =\n | {\n kind: 'execution';\n jobExecutionId: string;\n executionVersion: number;\n sequence: number;\n requiredLabels: string[];\n status: JobExecutionStatus;\n }\n | {kind: 'resolve-requested'}\n | {kind: 'empty'};\n\nexport interface DrainListenerEventsParams {\n jobId: string;\n expectedSequence: number;\n maxSize?: number | undefined;\n integrations?: IntegrationsModuleClient | undefined;\n projects?: ProjectsModuleClient | undefined;\n resolveAgentDefaults?: AgentDefaultsResolver | undefined;\n agent?: AgentInterModuleClient | undefined;\n secrets?: Pick<SecretsInterModuleClient, 'getVariablesByNamespace'> | undefined;\n}\n\nexport async function drainListenerEventsIntoExecution(\n params: DrainListenerEventsParams,\n): Promise<DrainListenerEventsResult> {\n const probeResult = await db().transaction(async (tx) => {\n const existing = await findExistingExecution(params, tx);\n if (existing) return existing;\n\n const resolveRequested = await hasPendingResolveEvent(params.jobId, tx);\n if (resolveRequested) return {kind: 'resolve-requested' as const};\n\n const hasBufferedFire = await hasBufferedFireEvent(params.jobId, tx);\n return hasBufferedFire ? null : {kind: 'empty' as const};\n });\n if (probeResult !== null) return probeResult;\n\n // Resolve external state before opening the persistence transaction. The\n // secrets module uses the shared pool and cannot reuse this transaction's\n // connection across the inter-module boundary.\n const materializationTarget = await loadListenerMaterializationTarget(params.jobId);\n const model =\n materializationTarget.attempt.model === null\n ? null\n : readPersistedWorkflowModel(materializationTarget.attempt.model);\n const modelJob = model?.jobs.find((job) => job.key === materializationTarget.job.key);\n let vars: Record<string, string> | undefined;\n let variableResolutionError: InterpolationUnresolvableError | undefined;\n if (model !== null && modelJob !== undefined) {\n try {\n vars = await loadReferencedVariables({\n model,\n jobs: [modelJob],\n workspaceId: materializationTarget.run.workspaceId,\n projectId: materializationTarget.run.projectId,\n definitionId: materializationTarget.run.definitionId,\n secrets: params.secrets,\n });\n } catch (error) {\n if (!(error instanceof InterpolationUnresolvableError)) throw error;\n variableResolutionError = error;\n }\n }\n const agentToolContext =\n materializationTarget.attempt.agentToolMaterialization === null\n ? await loadAgentToolMaterializationContext({\n model,\n workspaceId: materializationTarget.run.workspaceId,\n projectId: materializationTarget.run.projectId,\n integrations: params.integrations,\n projects: params.projects,\n })\n : undefined;\n\n const drained = await db().transaction(async (tx) => {\n const existing = await findExistingExecution(params, tx);\n if (existing) return {result: existing};\n\n const resolveRequested = await hasPendingResolveEvent(params.jobId, tx);\n if (resolveRequested) return {result: {kind: 'resolve-requested' as const}};\n\n const bufferedEvents = await lockBufferedFireEvents(params, tx);\n if (bufferedEvents.length === 0) return {result: {kind: 'empty' as const}};\n\n const target = await loadListenerMaterializationTarget(params.jobId, tx);\n const priorExecutions = await loadListenerPriorExecutions(\n params.jobId,\n target.job.name ?? target.job.key,\n tx,\n );\n const materialized = await materializeListenerExecution({\n model,\n run: toWorkflowRun(target.run),\n job: toJob(target.job),\n vars,\n variableResolutionError,\n sequence: params.expectedSequence,\n triggerEvents: listenerTriggerEvents(bufferedEvents),\n priorExecutions,\n resolveAgentDefaults:\n params.resolveAgentDefaults ??\n (params.agent\n ? createAgentDefaultsResolver(params.agent, target.run.workspaceId)\n : undefined),\n agentToolContext,\n agentToolSnapshot: target.attempt.agentToolMaterialization,\n });\n const execution = await persistMaterializedListenerExecution(tx, {\n jobId: params.jobId,\n sequence: params.expectedSequence,\n bufferedEventIds: bufferedEvents.map((event) => event.id),\n materialized,\n });\n\n if (materialized.status === 'failed') {\n recordWorkflowJobExecutionStatusChanged(materialized.status);\n }\n\n return {\n result: drainExecutionResult(execution),\n batchSize: bufferedEvents.length,\n };\n });\n\n if (drained.result.kind === 'execution' && drained.batchSize !== undefined) {\n recordListenerEventsCoalesced(drained.batchSize);\n }\n\n return drained.result;\n}\n\nexport interface ListenerBufferPeek {\n fireCount: number;\n resolvePending: boolean;\n oldestAgeMs: number;\n newestAgeMs: number;\n}\n\nexport async function peekListenerBuffer(params: {jobId: string}): Promise<ListenerBufferPeek> {\n const [row] = await db()\n .select({\n fireCount: sql<number>`count(*) filter (where ${jobListenerEvents.disposition} = 'fire')::integer`,\n resolvePending: sql<boolean>`coalesce(bool_or(${jobListenerEvents.disposition} = 'resolve'), false)`,\n oldestAgeMs: sql<number>`coalesce(floor(extract(epoch from (statement_timestamp() - min(${jobListenerEvents.receivedAt}) filter (where ${jobListenerEvents.disposition} = 'fire'))) * 1000), 0)::integer`,\n newestAgeMs: sql<number>`coalesce(floor(extract(epoch from (statement_timestamp() - max(${jobListenerEvents.receivedAt}) filter (where ${jobListenerEvents.disposition} = 'fire'))) * 1000), 0)::integer`,\n })\n .from(jobListenerEvents)\n .where(\n and(\n eq(jobListenerEvents.jobId, params.jobId),\n isNull(jobListenerEvents.consumedByExecutionId),\n ),\n );\n\n return {\n fireCount: row?.fireCount ?? 0,\n resolvePending: row?.resolvePending ?? false,\n oldestAgeMs: row?.oldestAgeMs ?? 0,\n newestAgeMs: row?.newestAgeMs ?? 0,\n };\n}\n\nexport async function resolveJobListener(params: {\n jobId: string;\n reason: ResolutionReason;\n}): Promise<{status: 'succeeded' | 'failed'; jobVersion: number}> {\n let result: ApplyJobListenerResolutionResult | undefined;\n for (let attempt = 0; attempt < MAX_LISTENER_RESOLUTION_ATTEMPTS; attempt += 1) {\n const decision = await deriveJobListenerResolutionDecision(params.jobId);\n result = await applyJobListenerResolution(params, decision);\n if (result.kind === 'applied') break;\n }\n\n if (result?.kind !== 'applied') {\n throw new Error(`Optimistic lock failure resolving listener job ${params.jobId}`);\n }\n\n if (result.changed) recordWorkflowListenerResolved(params.reason);\n return {status: result.status, jobVersion: result.jobVersion};\n}\n\ntype JobListenerResolutionDecision = DeriveJobSuccessResult & {\n expectedVersion: number;\n};\n\ntype ApplyJobListenerResolutionResult =\n | {\n kind: 'applied';\n status: 'succeeded' | 'failed';\n jobVersion: number;\n changed: boolean;\n }\n | {kind: 'stale'};\n\nasync function deriveJobListenerResolutionDecision(\n jobId: string,\n): Promise<JobListenerResolutionDecision> {\n const [target] = await db()\n .select({job: jobs, attempt: workflowRunAttempts})\n .from(jobs)\n .innerJoin(workflowRunAttempts, eq(jobs.workflowRunAttemptId, workflowRunAttempts.id))\n .where(eq(jobs.id, jobId))\n .limit(1);\n const jobRow = target?.job;\n if (!jobRow) throw new Error(`Job not found: ${jobId}`);\n\n const [executionRows, dependencyJobs] = await Promise.all([\n db()\n .select()\n .from(jobExecutions)\n .where(eq(jobExecutions.jobId, jobId))\n .orderBy(asc(jobExecutions.sequence), asc(jobExecutions.id)),\n getDirectDependencyJobContexts(jobId),\n ]);\n return {\n expectedVersion: jobRow.version,\n ...deriveJobSuccess({\n success: jobRow.success,\n executions: executionRows.map((execution) =>\n toJobExecution(execution, jobRow.name ?? jobRow.key),\n ),\n jobs: dependencyJobs,\n vars: target.attempt.vars ?? undefined,\n }),\n };\n}\n\nasync function applyJobListenerResolution(\n params: {\n jobId: string;\n reason: ResolutionReason;\n },\n decision: JobListenerResolutionDecision,\n): Promise<ApplyJobListenerResolutionResult> {\n return await db().transaction(async (tx) => {\n const [jobRow] = await tx\n .select()\n .from(jobs)\n .where(eq(jobs.id, params.jobId))\n .limit(1)\n .for('update');\n if (!jobRow) throw new Error(`Job not found: ${params.jobId}`);\n\n if (jobRow.version !== decision.expectedVersion && !isJobTerminal(jobRow.status)) {\n return {kind: 'stale' as const};\n }\n\n const listenerRows = await tx\n .update(jobs)\n .set({\n listenerStatus: 'resolved',\n resolutionReason: params.reason,\n updatedAt: new Date(),\n })\n .where(and(eq(jobs.id, params.jobId), notInArray(jobs.listenerStatus, ['resolved'])))\n .returning({id: jobs.id});\n\n const updated = await updateJobStatusAtVersion(tx, {\n jobId: params.jobId,\n status: decision.status,\n expectedVersion: decision.expectedVersion,\n statusReason: decision.statusReason,\n evaluationTrace: decision.trace,\n });\n const job = updated?.job ?? toJob(jobRow);\n const resolvedStatus: 'succeeded' | 'failed' =\n job.status === 'succeeded' ? 'succeeded' : 'failed';\n return {\n kind: 'applied' as const,\n status: resolvedStatus,\n jobVersion: job.version,\n changed: listenerRows.length > 0 || updated?.changed === true,\n };\n });\n}\n\nexport async function settleListenerJobExecution(params: {\n jobExecutionId: string;\n status: Extract<JobExecutionStatus, 'failed' | 'cancelled'>;\n}): Promise<void> {\n const changed = await db().transaction(async (tx) => {\n const [execution] = await tx\n .update(jobExecutions)\n .set({\n status: params.status,\n statusReason: params.status === 'failed' ? 'step_failed' : 'run_cancelled',\n version: sql`${jobExecutions.version} + 1`,\n updatedAt: new Date(),\n finishedAt: sql`now()`,\n })\n .where(\n and(\n eq(jobExecutions.id, params.jobExecutionId),\n notInArray(jobExecutions.status, TERMINAL_EXECUTION_STATUSES),\n ),\n )\n .returning();\n if (!execution) return false;\n await bulkUpdateStepStatuses(\n {jobExecutionId: params.jobExecutionId, status: params.status},\n tx,\n );\n return true;\n });\n\n if (changed) {\n recordWorkflowJobExecutionStatusChanged(params.status);\n }\n}\n\nexport async function countActiveListeners(): Promise<number> {\n const [row] = await db()\n .select({value: count()})\n .from(jobs)\n .where(eq(jobs.listenerStatus, 'listening'));\n return row?.value ?? 0;\n}\n\nasync function findExistingExecution(\n params: DrainListenerEventsParams,\n tx: Tx,\n): Promise<Extract<DrainListenerEventsResult, {kind: 'execution'}> | undefined> {\n const [existing] = await tx\n .select()\n .from(jobExecutions)\n .where(\n and(\n eq(jobExecutions.jobId, params.jobId),\n eq(jobExecutions.sequence, params.expectedSequence),\n ),\n )\n .limit(1);\n if (!existing) return undefined;\n return drainExecutionResult(existing);\n}\n\nasync function hasPendingResolveEvent(jobId: string, tx: Tx): Promise<boolean> {\n const [resolveEvent] = await tx\n .select({id: jobListenerEvents.id})\n .from(jobListenerEvents)\n .where(\n and(\n eq(jobListenerEvents.jobId, jobId),\n eq(jobListenerEvents.disposition, 'resolve'),\n isNull(jobListenerEvents.consumedByExecutionId),\n ),\n )\n .orderBy(asc(jobListenerEvents.receivedAt), asc(jobListenerEvents.id))\n .limit(1)\n .for('update');\n return resolveEvent !== undefined;\n}\n\nasync function hasBufferedFireEvent(jobId: string, tx: Tx): Promise<boolean> {\n const [fireEvent] = await tx\n .select({id: jobListenerEvents.id})\n .from(jobListenerEvents)\n .where(\n and(\n eq(jobListenerEvents.jobId, jobId),\n eq(jobListenerEvents.disposition, 'fire'),\n isNull(jobListenerEvents.consumedByExecutionId),\n ),\n )\n .limit(1);\n return fireEvent !== undefined;\n}\n\nasync function lockBufferedFireEvents(\n params: DrainListenerEventsParams,\n tx: Tx,\n): Promise<JobListenerEventDb[]> {\n const bufferedQuery = tx\n .select()\n .from(jobListenerEvents)\n .where(\n and(\n eq(jobListenerEvents.jobId, params.jobId),\n eq(jobListenerEvents.disposition, 'fire'),\n isNull(jobListenerEvents.consumedByExecutionId),\n ),\n )\n .orderBy(asc(jobListenerEvents.receivedAt), asc(jobListenerEvents.id));\n return await (params.maxSize === undefined\n ? bufferedQuery\n : bufferedQuery.limit(params.maxSize)\n ).for('update');\n}\n\nfunction listenerTriggerEvents(\n bufferedEvents: readonly JobListenerEventDb[],\n): WorkflowExecutionEvent[] {\n return bufferedEvents.map((event) =>\n normalizeWorkflowExecutionEvent({\n source: event.source,\n event: event.event,\n delivery_id: event.deliveryId,\n received_at: event.receivedAt.toISOString(),\n project: event.triggerReference?.project ?? null,\n repository: event.triggerReference?.repository ?? null,\n ref: event.triggerReference?.ref ?? null,\n commit: event.triggerReference?.commit ?? null,\n data: event.payload,\n }),\n );\n}\n\nasync function persistMaterializedListenerExecution(\n tx: Tx,\n params: {\n readonly jobId: string;\n readonly sequence: number;\n readonly bufferedEventIds: readonly string[];\n readonly materialized: MaterializedListenerExecution;\n },\n): Promise<JobExecutionDb> {\n const [execution] = await tx\n .insert(jobExecutions)\n .values({\n jobId: params.jobId,\n sequence: params.sequence,\n name: params.materialized.nameOverride,\n runner: params.materialized.runner.length === 0 ? null : [...params.materialized.runner],\n status: params.materialized.status,\n statusReason: params.materialized.statusReason,\n triggerEvents: [...params.materialized.triggerEvents],\n evaluationTrace: params.materialized.evaluationTrace,\n ...(params.materialized.status === 'failed' ? {finishedAt: sql`now()`} : {}),\n })\n .returning();\n if (!execution) throw new Error('Insert returned no rows');\n\n await tx\n .update(jobListenerEvents)\n .set({consumedByExecutionId: execution.id})\n .where(inArray(jobListenerEvents.id, [...params.bufferedEventIds]));\n\n if (params.materialized.status === 'pending' && params.materialized.steps.length > 0) {\n await tx.insert(steps).values(\n params.materialized.steps.map((step) => ({\n jobExecutionId: execution.id,\n key: step.key,\n name: step.name,\n sourceLocation: step.sourceLocation,\n status: step.status,\n type: step.type,\n config: step.config,\n configPlan: step.configPlan ?? null,\n authoredConfig: step.authoredConfig,\n condition: step.condition ?? null,\n position: step.position,\n })),\n );\n }\n\n return execution;\n}\n\nfunction drainExecutionResult(\n execution: JobExecutionDb,\n): Extract<DrainListenerEventsResult, {kind: 'execution'}> {\n return {\n kind: 'execution',\n jobExecutionId: execution.id,\n executionVersion: execution.version,\n sequence: execution.sequence,\n requiredLabels: execution.runner ?? [],\n status: execution.status,\n };\n}\n\nasync function loadListenerMaterializationTarget(jobId: string, tx?: Tx) {\n const query = (tx ?? db())\n .select({job: jobs, attempt: workflowRunAttempts, run: workflowRuns})\n .from(jobs)\n .innerJoin(workflowRunAttempts, eq(jobs.workflowRunAttemptId, workflowRunAttempts.id))\n .innerJoin(workflowRuns, eq(workflowRunAttempts.workflowRunId, workflowRuns.id))\n .where(eq(jobs.id, jobId))\n .limit(1);\n const [target] = tx === undefined ? await query : await query.for('update');\n if (!target) throw new Error(`Job not found: ${jobId}`);\n\n return target;\n}\n\nasync function loadListenerPriorExecutions(\n jobId: string,\n fallbackName: string,\n tx: Tx,\n): Promise<JobExecution[]> {\n const priorExecutions = await tx\n .select()\n .from(jobExecutions)\n .where(eq(jobExecutions.jobId, jobId))\n .orderBy(asc(jobExecutions.sequence), asc(jobExecutions.id));\n return priorExecutions.map((execution) => toJobExecution(execution, fallbackName));\n}\n"],"names":["readPersistedWorkflowModel","WORKFLOWS_JOB_ACTIVATED","and","asc","count","eq","inArray","isNull","notInArray","sql","createAgentDefaultsResolver","loadAgentToolMaterializationContext","isJobTerminal","normalizeWorkflowExecutionEvent","InterpolationUnresolvableError","deriveJobSuccess","materializeListenerExecution","applyListenerFilterSnapshots","assembleListenerSnapshotContext","listenerFilterOutputTypesForJobs","planListenerFilterSnapshots","recordListenerEventsCoalesced","recordWorkflowJobExecutionStatusChanged","recordWorkflowListenerResolved","db","writeWorkflowsOutboxEvent","jobExecutions","toJobExecution","jobListenerEvents","jobs","toJob","steps","workflowRunAttempts","toWorkflowRun","workflowRuns","bulkUpdateStepStatuses","getDirectDependencyJobContexts","loadReferencedVariables","updateJobStatusAtVersion","TERMINAL_EXECUTION_STATUSES","MAX_LISTENER_RESOLUTION_ATTEMPTS","applyActivatedListenerFilterSnapshots","plans","context","outputTypes","activateJobListener","params","transaction","tx","target","select","job","attempt","run","from","innerJoin","workflowRunAttemptId","id","workflowRunId","where","jobId","limit","for","Error","value","executionCount","includes","status","jobStatus","jobVersion","version","updated","expectedVersion","existing","listenerRows","update","set","listenerStatus","updatedAt","Date","returning","matchers","on","listeningOn","until","listeningUntil","snapshotPlan","dependencyJobs","jobKeys","size","snapshotContext","triggerPayload","inputs","vars","undefined","plan","listenerOutputTypes","type","payload","workspaceId","mode","drainListenerEventsIntoExecution","probeResult","findExistingExecution","resolveRequested","hasPendingResolveEvent","kind","hasBufferedFire","hasBufferedFireEvent","materializationTarget","loadListenerMaterializationTarget","model","modelJob","find","key","variableResolutionError","projectId","definitionId","secrets","error","agentToolContext","agentToolMaterialization","integrations","projects","drained","result","bufferedEvents","lockBufferedFireEvents","length","priorExecutions","loadListenerPriorExecutions","name","materialized","sequence","expectedSequence","triggerEvents","listenerTriggerEvents","resolveAgentDefaults","agent","agentToolSnapshot","execution","persistMaterializedListenerExecution","bufferedEventIds","map","event","drainExecutionResult","batchSize","peekListenerBuffer","row","fireCount","disposition","resolvePending","oldestAgeMs","receivedAt","newestAgeMs","consumedByExecutionId","resolveJobListener","decision","deriveJobListenerResolutionDecision","applyJobListenerResolution","changed","reason","jobRow","executionRows","Promise","all","orderBy","success","executions","resolutionReason","statusReason","evaluationTrace","trace","resolvedStatus","settleListenerJobExecution","finishedAt","jobExecutionId","countActiveListeners","resolveEvent","fireEvent","bufferedQuery","maxSize","source","delivery_id","deliveryId","received_at","toISOString","project","triggerReference","repository","ref","commit","data","insert","values","nameOverride","runner","step","sourceLocation","config","configPlan","authoredConfig","condition","position","executionVersion","requiredLabels","query","fallbackName"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/db/job-listeners.ts"],"sourcesContent":["import type {AgentInterModuleClient} from '@shipfox/api-agent-dto/inter-module';\nimport {readPersistedWorkflowModel} from '@shipfox/api-definitions-dto';\nimport type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto/inter-module';\nimport type {ProjectsModuleClient} from '@shipfox/api-projects-dto/inter-module';\nimport type {SecretsInterModuleClient} from '@shipfox/api-secrets-dto/inter-module';\nimport {\n WORKFLOWS_JOB_ACTIVATED,\n type WorkflowsJobActivatedEventDto,\n} from '@shipfox/api-workflows-dto';\nimport {and, asc, count, eq, inArray, isNull, notInArray, sql} from 'drizzle-orm';\nimport {type AgentDefaultsResolver, createAgentDefaultsResolver} from '#core/agent-defaults.js';\nimport {loadAgentToolMaterializationContext} from '#core/agent-tools.js';\nimport {isJobTerminal, type JobStatus, type ResolutionReason} from '#core/entities/job.js';\nimport type {\n JobExecution,\n JobExecutionStatus,\n WorkflowExecutionEvent,\n} from '#core/entities/job-execution.js';\nimport {normalizeWorkflowExecutionEvent} from '#core/entities/job-execution.js';\nimport {InterpolationUnresolvableError} from '#core/errors.js';\nimport {type DeriveJobSuccessResult, deriveJobSuccess} from '#core/job-transition/index.js';\nimport {\n type MaterializedListenerExecution,\n materializeListenerExecution,\n} from '#core/listener-execution-materialization.js';\nimport {\n applyListenerFilterSnapshots,\n assembleListenerSnapshotContext,\n type ListenerTriggerWithSnapshot,\n listenerFilterOutputTypesForJobs,\n planListenerFilterSnapshots,\n} from '#core/step-config/assemble-run-context.js';\nimport {\n recordListenerEventsCoalesced,\n recordWorkflowJobExecutionStatusChanged,\n recordWorkflowListenerResolved,\n} from '#metrics/instance.js';\nimport {db, type Tx} from './db.js';\nimport {writeWorkflowsOutboxEvent} from './outbox-writes.js';\nimport {type JobExecutionDb, jobExecutions, toJobExecution} from './schema/job-executions.js';\nimport {type JobListenerEventDb, jobListenerEvents} from './schema/job-listener-events.js';\nimport {jobs, toJob} from './schema/jobs.js';\nimport {steps} from './schema/steps.js';\nimport {workflowRunAttempts} from './schema/workflow-run-attempts.js';\nimport {toWorkflowRun, workflowRuns} from './schema/workflow-runs.js';\nimport {\n bulkUpdateStepStatuses,\n getDirectDependencyJobContexts,\n loadReferencedVariables,\n updateJobStatusAtVersion,\n writeJobExecutionTerminatedOutbox,\n} from './workflow-runs.js';\n\nconst TERMINAL_EXECUTION_STATUSES: JobExecutionStatus[] = ['succeeded', 'failed', 'cancelled'];\nconst MAX_LISTENER_RESOLUTION_ATTEMPTS = 3;\n\nexport interface ActivateJobListenerParams {\n jobId: string;\n expectedVersion: number;\n}\n\nexport interface ActivateJobListenerResult {\n status: 'running' | 'terminal';\n jobStatus: JobStatus;\n jobVersion: number;\n executionCount: number;\n}\n\ntype JobActivatedListenerMatcher = Extract<\n WorkflowsJobActivatedEventDto,\n {mode: 'listening'}\n>['on'][number] &\n ListenerTriggerWithSnapshot;\n\nfunction applyActivatedListenerFilterSnapshots(\n plans: Parameters<typeof applyListenerFilterSnapshots>[0],\n context: Parameters<typeof applyListenerFilterSnapshots>[1],\n outputTypes: Parameters<typeof applyListenerFilterSnapshots>[2],\n): JobActivatedListenerMatcher[] {\n return applyListenerFilterSnapshots(plans, context, outputTypes);\n}\n\nexport async function activateJobListener(\n params: ActivateJobListenerParams,\n): Promise<ActivateJobListenerResult> {\n return await db().transaction(async (tx) => {\n const [target] = await tx\n .select({job: jobs, attempt: workflowRunAttempts, run: workflowRuns})\n .from(jobs)\n .innerJoin(workflowRunAttempts, eq(jobs.workflowRunAttemptId, workflowRunAttempts.id))\n .innerJoin(workflowRuns, eq(workflowRunAttempts.workflowRunId, workflowRuns.id))\n .where(eq(jobs.id, params.jobId))\n .limit(1)\n .for('update');\n if (!target) throw new Error(`Job not found: ${params.jobId}`);\n\n const [{value: executionCount} = {value: 0}] = await tx\n .select({value: count()})\n .from(jobExecutions)\n .where(eq(jobExecutions.jobId, params.jobId));\n\n if (['succeeded', 'failed', 'cancelled', 'skipped'].includes(target.job.status)) {\n return {\n status: 'terminal',\n jobStatus: target.job.status,\n jobVersion: target.job.version,\n executionCount,\n };\n }\n\n let job = toJob(target.job);\n if (target.job.status === 'pending') {\n const updated = await updateJobStatusAtVersion(tx, {\n jobId: params.jobId,\n status: 'running',\n expectedVersion: params.expectedVersion,\n });\n if (!updated) {\n const [existing] = await tx.select().from(jobs).where(eq(jobs.id, params.jobId)).limit(1);\n if (existing?.status !== 'running') {\n throw new Error(\n `Optimistic lock failure activating listener job ${params.jobId} version ${params.expectedVersion}`,\n );\n }\n job = toJob(existing);\n } else {\n job = updated.job;\n }\n }\n\n const listenerRows = await tx\n .update(jobs)\n .set({listenerStatus: 'listening', updatedAt: new Date()})\n .where(and(eq(jobs.id, params.jobId), eq(jobs.listenerStatus, 'inactive')))\n .returning();\n\n if (listenerRows[0]) {\n const matchers = {\n on: target.job.listeningOn ?? [],\n until: target.job.listeningUntil ?? null,\n };\n const snapshotPlan = planListenerFilterSnapshots(matchers);\n const dependencyJobs =\n snapshotPlan.jobKeys.size === 0\n ? []\n : await getDirectDependencyJobContexts(params.jobId, tx);\n const snapshotContext = assembleListenerSnapshotContext({\n job: toJob(target.job),\n run: toWorkflowRun(target.run),\n triggerPayload: target.run.triggerPayload,\n inputs: target.run.inputs,\n vars: target.attempt.vars ?? undefined,\n plan: snapshotPlan,\n dependencyJobs,\n });\n const listenerOutputTypes = listenerFilterOutputTypesForJobs(dependencyJobs);\n\n await writeWorkflowsOutboxEvent(tx, {\n type: WORKFLOWS_JOB_ACTIVATED,\n payload: {\n jobId: params.jobId,\n workflowRunId: target.run.id,\n workspaceId: target.run.workspaceId,\n mode: 'listening',\n on: applyActivatedListenerFilterSnapshots(\n snapshotPlan.on,\n snapshotContext,\n listenerOutputTypes,\n ),\n until:\n matchers.until === null\n ? null\n : applyActivatedListenerFilterSnapshots(\n snapshotPlan.until,\n snapshotContext,\n listenerOutputTypes,\n ),\n },\n });\n }\n\n return {status: 'running', jobStatus: job.status, jobVersion: job.version, executionCount};\n });\n}\n\nexport type DrainListenerEventsResult =\n | {\n kind: 'execution';\n jobExecutionId: string;\n executionVersion: number;\n sequence: number;\n requiredLabels: string[];\n status: JobExecutionStatus;\n }\n | {kind: 'resolve-requested'}\n | {kind: 'empty'};\n\nexport interface DrainListenerEventsParams {\n jobId: string;\n expectedSequence: number;\n maxSize?: number | undefined;\n integrations?: IntegrationsModuleClient | undefined;\n projects?: ProjectsModuleClient | undefined;\n resolveAgentDefaults?: AgentDefaultsResolver | undefined;\n agent?: AgentInterModuleClient | undefined;\n secrets?: Pick<SecretsInterModuleClient, 'getVariablesByNamespace'> | undefined;\n}\n\nexport async function drainListenerEventsIntoExecution(\n params: DrainListenerEventsParams,\n): Promise<DrainListenerEventsResult> {\n const probeResult = await db().transaction(async (tx) => {\n const existing = await findExistingExecution(params, tx);\n if (existing) return existing;\n\n const resolveRequested = await hasPendingResolveEvent(params.jobId, tx);\n if (resolveRequested) return {kind: 'resolve-requested' as const};\n\n const hasBufferedFire = await hasBufferedFireEvent(params.jobId, tx);\n return hasBufferedFire ? null : {kind: 'empty' as const};\n });\n if (probeResult !== null) return probeResult;\n\n // Resolve external state before opening the persistence transaction. The\n // secrets module uses the shared pool and cannot reuse this transaction's\n // connection across the inter-module boundary.\n const materializationTarget = await loadListenerMaterializationTarget(params.jobId);\n const model =\n materializationTarget.attempt.model === null\n ? null\n : readPersistedWorkflowModel(materializationTarget.attempt.model);\n const modelJob = model?.jobs.find((job) => job.key === materializationTarget.job.key);\n let vars: Record<string, string> | undefined;\n let variableResolutionError: InterpolationUnresolvableError | undefined;\n if (model !== null && modelJob !== undefined) {\n try {\n vars = await loadReferencedVariables({\n model,\n jobs: [modelJob],\n workspaceId: materializationTarget.run.workspaceId,\n projectId: materializationTarget.run.projectId,\n definitionId: materializationTarget.run.definitionId,\n secrets: params.secrets,\n });\n } catch (error) {\n if (!(error instanceof InterpolationUnresolvableError)) throw error;\n variableResolutionError = error;\n }\n }\n const agentToolContext =\n materializationTarget.attempt.agentToolMaterialization === null\n ? await loadAgentToolMaterializationContext({\n model,\n workspaceId: materializationTarget.run.workspaceId,\n projectId: materializationTarget.run.projectId,\n integrations: params.integrations,\n projects: params.projects,\n })\n : undefined;\n\n const drained = await db().transaction(async (tx) => {\n const existing = await findExistingExecution(params, tx);\n if (existing) return {result: existing};\n\n const resolveRequested = await hasPendingResolveEvent(params.jobId, tx);\n if (resolveRequested) return {result: {kind: 'resolve-requested' as const}};\n\n const bufferedEvents = await lockBufferedFireEvents(params, tx);\n if (bufferedEvents.length === 0) return {result: {kind: 'empty' as const}};\n\n const target = await loadListenerMaterializationTarget(params.jobId, tx);\n const priorExecutions = await loadListenerPriorExecutions(\n params.jobId,\n target.job.name ?? target.job.key,\n tx,\n );\n const materialized = await materializeListenerExecution({\n model,\n run: toWorkflowRun(target.run),\n job: toJob(target.job),\n vars,\n variableResolutionError,\n sequence: params.expectedSequence,\n triggerEvents: listenerTriggerEvents(bufferedEvents),\n priorExecutions,\n resolveAgentDefaults:\n params.resolveAgentDefaults ??\n (params.agent\n ? createAgentDefaultsResolver(params.agent, target.run.workspaceId)\n : undefined),\n agentToolContext,\n agentToolSnapshot: target.attempt.agentToolMaterialization,\n });\n const execution = await persistMaterializedListenerExecution(tx, {\n jobId: params.jobId,\n sequence: params.expectedSequence,\n bufferedEventIds: bufferedEvents.map((event) => event.id),\n materialized,\n });\n\n if (materialized.status === 'failed') {\n recordWorkflowJobExecutionStatusChanged(materialized.status);\n }\n\n return {\n result: drainExecutionResult(execution),\n batchSize: bufferedEvents.length,\n };\n });\n\n if (drained.result.kind === 'execution' && drained.batchSize !== undefined) {\n recordListenerEventsCoalesced(drained.batchSize);\n }\n\n return drained.result;\n}\n\nexport interface ListenerBufferPeek {\n fireCount: number;\n resolvePending: boolean;\n oldestAgeMs: number;\n newestAgeMs: number;\n}\n\nexport async function peekListenerBuffer(params: {jobId: string}): Promise<ListenerBufferPeek> {\n const [row] = await db()\n .select({\n fireCount: sql<number>`count(*) filter (where ${jobListenerEvents.disposition} = 'fire')::integer`,\n resolvePending: sql<boolean>`coalesce(bool_or(${jobListenerEvents.disposition} = 'resolve'), false)`,\n oldestAgeMs: sql<number>`coalesce(floor(extract(epoch from (statement_timestamp() - min(${jobListenerEvents.receivedAt}) filter (where ${jobListenerEvents.disposition} = 'fire'))) * 1000), 0)::integer`,\n newestAgeMs: sql<number>`coalesce(floor(extract(epoch from (statement_timestamp() - max(${jobListenerEvents.receivedAt}) filter (where ${jobListenerEvents.disposition} = 'fire'))) * 1000), 0)::integer`,\n })\n .from(jobListenerEvents)\n .where(\n and(\n eq(jobListenerEvents.jobId, params.jobId),\n isNull(jobListenerEvents.consumedByExecutionId),\n ),\n );\n\n return {\n fireCount: row?.fireCount ?? 0,\n resolvePending: row?.resolvePending ?? false,\n oldestAgeMs: row?.oldestAgeMs ?? 0,\n newestAgeMs: row?.newestAgeMs ?? 0,\n };\n}\n\nexport async function resolveJobListener(params: {\n jobId: string;\n reason: ResolutionReason;\n}): Promise<{status: 'succeeded' | 'failed'; jobVersion: number}> {\n let result: ApplyJobListenerResolutionResult | undefined;\n for (let attempt = 0; attempt < MAX_LISTENER_RESOLUTION_ATTEMPTS; attempt += 1) {\n const decision = await deriveJobListenerResolutionDecision(params.jobId);\n result = await applyJobListenerResolution(params, decision);\n if (result.kind === 'applied') break;\n }\n\n if (result?.kind !== 'applied') {\n throw new Error(`Optimistic lock failure resolving listener job ${params.jobId}`);\n }\n\n if (result.changed) recordWorkflowListenerResolved(params.reason);\n return {status: result.status, jobVersion: result.jobVersion};\n}\n\ntype JobListenerResolutionDecision = DeriveJobSuccessResult & {\n expectedVersion: number;\n};\n\ntype ApplyJobListenerResolutionResult =\n | {\n kind: 'applied';\n status: 'succeeded' | 'failed';\n jobVersion: number;\n changed: boolean;\n }\n | {kind: 'stale'};\n\nasync function deriveJobListenerResolutionDecision(\n jobId: string,\n): Promise<JobListenerResolutionDecision> {\n const [target] = await db()\n .select({job: jobs, attempt: workflowRunAttempts})\n .from(jobs)\n .innerJoin(workflowRunAttempts, eq(jobs.workflowRunAttemptId, workflowRunAttempts.id))\n .where(eq(jobs.id, jobId))\n .limit(1);\n const jobRow = target?.job;\n if (!jobRow) throw new Error(`Job not found: ${jobId}`);\n\n const [executionRows, dependencyJobs] = await Promise.all([\n db()\n .select()\n .from(jobExecutions)\n .where(eq(jobExecutions.jobId, jobId))\n .orderBy(asc(jobExecutions.sequence), asc(jobExecutions.id)),\n getDirectDependencyJobContexts(jobId),\n ]);\n return {\n expectedVersion: jobRow.version,\n ...deriveJobSuccess({\n success: jobRow.success,\n executions: executionRows.map((execution) =>\n toJobExecution(execution, jobRow.name ?? jobRow.key),\n ),\n jobs: dependencyJobs,\n vars: target.attempt.vars ?? undefined,\n }),\n };\n}\n\nasync function applyJobListenerResolution(\n params: {\n jobId: string;\n reason: ResolutionReason;\n },\n decision: JobListenerResolutionDecision,\n): Promise<ApplyJobListenerResolutionResult> {\n return await db().transaction(async (tx) => {\n const [jobRow] = await tx\n .select()\n .from(jobs)\n .where(eq(jobs.id, params.jobId))\n .limit(1)\n .for('update');\n if (!jobRow) throw new Error(`Job not found: ${params.jobId}`);\n\n if (jobRow.version !== decision.expectedVersion && !isJobTerminal(jobRow.status)) {\n return {kind: 'stale' as const};\n }\n\n const listenerRows = await tx\n .update(jobs)\n .set({\n listenerStatus: 'resolved',\n resolutionReason: params.reason,\n updatedAt: new Date(),\n })\n .where(and(eq(jobs.id, params.jobId), notInArray(jobs.listenerStatus, ['resolved'])))\n .returning({id: jobs.id});\n\n const updated = await updateJobStatusAtVersion(tx, {\n jobId: params.jobId,\n status: decision.status,\n expectedVersion: decision.expectedVersion,\n statusReason: decision.statusReason,\n evaluationTrace: decision.trace,\n });\n const job = updated?.job ?? toJob(jobRow);\n const resolvedStatus: 'succeeded' | 'failed' =\n job.status === 'succeeded' ? 'succeeded' : 'failed';\n return {\n kind: 'applied' as const,\n status: resolvedStatus,\n jobVersion: job.version,\n changed: listenerRows.length > 0 || updated?.changed === true,\n };\n });\n}\n\nexport async function settleListenerJobExecution(params: {\n jobExecutionId: string;\n status: Extract<JobExecutionStatus, 'failed' | 'cancelled'>;\n}): Promise<void> {\n const changed = await db().transaction(async (tx) => {\n const [execution] = await tx\n .update(jobExecutions)\n .set({\n status: params.status,\n statusReason: params.status === 'failed' ? 'step_failed' : 'run_cancelled',\n version: sql`${jobExecutions.version} + 1`,\n updatedAt: new Date(),\n finishedAt: sql`now()`,\n })\n .where(\n and(\n eq(jobExecutions.id, params.jobExecutionId),\n notInArray(jobExecutions.status, TERMINAL_EXECUTION_STATUSES),\n ),\n )\n .returning();\n if (!execution) return false;\n await writeJobExecutionTerminatedOutbox(tx, {\n jobId: execution.jobId,\n jobExecutionId: execution.id,\n status: execution.status,\n statusReason: execution.statusReason,\n statusReasonMessage: execution.statusReasonMessage,\n });\n await bulkUpdateStepStatuses(\n {jobExecutionId: params.jobExecutionId, status: params.status},\n tx,\n );\n return true;\n });\n\n if (changed) {\n recordWorkflowJobExecutionStatusChanged(params.status);\n }\n}\n\nexport async function countActiveListeners(): Promise<number> {\n const [row] = await db()\n .select({value: count()})\n .from(jobs)\n .where(eq(jobs.listenerStatus, 'listening'));\n return row?.value ?? 0;\n}\n\nasync function findExistingExecution(\n params: DrainListenerEventsParams,\n tx: Tx,\n): Promise<Extract<DrainListenerEventsResult, {kind: 'execution'}> | undefined> {\n const [existing] = await tx\n .select()\n .from(jobExecutions)\n .where(\n and(\n eq(jobExecutions.jobId, params.jobId),\n eq(jobExecutions.sequence, params.expectedSequence),\n ),\n )\n .limit(1);\n if (!existing) return undefined;\n return drainExecutionResult(existing);\n}\n\nasync function hasPendingResolveEvent(jobId: string, tx: Tx): Promise<boolean> {\n const [resolveEvent] = await tx\n .select({id: jobListenerEvents.id})\n .from(jobListenerEvents)\n .where(\n and(\n eq(jobListenerEvents.jobId, jobId),\n eq(jobListenerEvents.disposition, 'resolve'),\n isNull(jobListenerEvents.consumedByExecutionId),\n ),\n )\n .orderBy(asc(jobListenerEvents.receivedAt), asc(jobListenerEvents.id))\n .limit(1)\n .for('update');\n return resolveEvent !== undefined;\n}\n\nasync function hasBufferedFireEvent(jobId: string, tx: Tx): Promise<boolean> {\n const [fireEvent] = await tx\n .select({id: jobListenerEvents.id})\n .from(jobListenerEvents)\n .where(\n and(\n eq(jobListenerEvents.jobId, jobId),\n eq(jobListenerEvents.disposition, 'fire'),\n isNull(jobListenerEvents.consumedByExecutionId),\n ),\n )\n .limit(1);\n return fireEvent !== undefined;\n}\n\nasync function lockBufferedFireEvents(\n params: DrainListenerEventsParams,\n tx: Tx,\n): Promise<JobListenerEventDb[]> {\n const bufferedQuery = tx\n .select()\n .from(jobListenerEvents)\n .where(\n and(\n eq(jobListenerEvents.jobId, params.jobId),\n eq(jobListenerEvents.disposition, 'fire'),\n isNull(jobListenerEvents.consumedByExecutionId),\n ),\n )\n .orderBy(asc(jobListenerEvents.receivedAt), asc(jobListenerEvents.id));\n return await (params.maxSize === undefined\n ? bufferedQuery\n : bufferedQuery.limit(params.maxSize)\n ).for('update');\n}\n\nfunction listenerTriggerEvents(\n bufferedEvents: readonly JobListenerEventDb[],\n): WorkflowExecutionEvent[] {\n return bufferedEvents.map((event) =>\n normalizeWorkflowExecutionEvent({\n source: event.source,\n event: event.event,\n delivery_id: event.deliveryId,\n received_at: event.receivedAt.toISOString(),\n project: event.triggerReference?.project ?? null,\n repository: event.triggerReference?.repository ?? null,\n ref: event.triggerReference?.ref ?? null,\n commit: event.triggerReference?.commit ?? null,\n data: event.payload,\n }),\n );\n}\n\nasync function persistMaterializedListenerExecution(\n tx: Tx,\n params: {\n readonly jobId: string;\n readonly sequence: number;\n readonly bufferedEventIds: readonly string[];\n readonly materialized: MaterializedListenerExecution;\n },\n): Promise<JobExecutionDb> {\n const [execution] = await tx\n .insert(jobExecutions)\n .values({\n jobId: params.jobId,\n sequence: params.sequence,\n name: params.materialized.nameOverride,\n runner: params.materialized.runner.length === 0 ? null : [...params.materialized.runner],\n status: params.materialized.status,\n statusReason: params.materialized.statusReason,\n triggerEvents: [...params.materialized.triggerEvents],\n evaluationTrace: params.materialized.evaluationTrace,\n ...(params.materialized.status === 'failed' ? {finishedAt: sql`now()`} : {}),\n })\n .returning();\n if (!execution) throw new Error('Insert returned no rows');\n\n if (execution.status === 'failed') {\n await writeJobExecutionTerminatedOutbox(tx, {\n jobId: execution.jobId,\n jobExecutionId: execution.id,\n status: execution.status,\n statusReason: execution.statusReason,\n statusReasonMessage: execution.statusReasonMessage,\n });\n }\n\n await tx\n .update(jobListenerEvents)\n .set({consumedByExecutionId: execution.id})\n .where(inArray(jobListenerEvents.id, [...params.bufferedEventIds]));\n\n if (params.materialized.status === 'pending' && params.materialized.steps.length > 0) {\n await tx.insert(steps).values(\n params.materialized.steps.map((step) => ({\n jobExecutionId: execution.id,\n key: step.key,\n name: step.name,\n sourceLocation: step.sourceLocation,\n status: step.status,\n type: step.type,\n config: step.config,\n configPlan: step.configPlan ?? null,\n authoredConfig: step.authoredConfig,\n condition: step.condition ?? null,\n position: step.position,\n })),\n );\n }\n\n return execution;\n}\n\nfunction drainExecutionResult(\n execution: JobExecutionDb,\n): Extract<DrainListenerEventsResult, {kind: 'execution'}> {\n return {\n kind: 'execution',\n jobExecutionId: execution.id,\n executionVersion: execution.version,\n sequence: execution.sequence,\n requiredLabels: execution.runner ?? [],\n status: execution.status,\n };\n}\n\nasync function loadListenerMaterializationTarget(jobId: string, tx?: Tx) {\n const query = (tx ?? db())\n .select({job: jobs, attempt: workflowRunAttempts, run: workflowRuns})\n .from(jobs)\n .innerJoin(workflowRunAttempts, eq(jobs.workflowRunAttemptId, workflowRunAttempts.id))\n .innerJoin(workflowRuns, eq(workflowRunAttempts.workflowRunId, workflowRuns.id))\n .where(eq(jobs.id, jobId))\n .limit(1);\n const [target] = tx === undefined ? await query : await query.for('update');\n if (!target) throw new Error(`Job not found: ${jobId}`);\n\n return target;\n}\n\nasync function loadListenerPriorExecutions(\n jobId: string,\n fallbackName: string,\n tx: Tx,\n): Promise<JobExecution[]> {\n const priorExecutions = await tx\n .select()\n .from(jobExecutions)\n .where(eq(jobExecutions.jobId, jobId))\n .orderBy(asc(jobExecutions.sequence), asc(jobExecutions.id));\n return priorExecutions.map((execution) => toJobExecution(execution, fallbackName));\n}\n"],"names":["readPersistedWorkflowModel","WORKFLOWS_JOB_ACTIVATED","and","asc","count","eq","inArray","isNull","notInArray","sql","createAgentDefaultsResolver","loadAgentToolMaterializationContext","isJobTerminal","normalizeWorkflowExecutionEvent","InterpolationUnresolvableError","deriveJobSuccess","materializeListenerExecution","applyListenerFilterSnapshots","assembleListenerSnapshotContext","listenerFilterOutputTypesForJobs","planListenerFilterSnapshots","recordListenerEventsCoalesced","recordWorkflowJobExecutionStatusChanged","recordWorkflowListenerResolved","db","writeWorkflowsOutboxEvent","jobExecutions","toJobExecution","jobListenerEvents","jobs","toJob","steps","workflowRunAttempts","toWorkflowRun","workflowRuns","bulkUpdateStepStatuses","getDirectDependencyJobContexts","loadReferencedVariables","updateJobStatusAtVersion","writeJobExecutionTerminatedOutbox","TERMINAL_EXECUTION_STATUSES","MAX_LISTENER_RESOLUTION_ATTEMPTS","applyActivatedListenerFilterSnapshots","plans","context","outputTypes","activateJobListener","params","transaction","tx","target","select","job","attempt","run","from","innerJoin","workflowRunAttemptId","id","workflowRunId","where","jobId","limit","for","Error","value","executionCount","includes","status","jobStatus","jobVersion","version","updated","expectedVersion","existing","listenerRows","update","set","listenerStatus","updatedAt","Date","returning","matchers","on","listeningOn","until","listeningUntil","snapshotPlan","dependencyJobs","jobKeys","size","snapshotContext","triggerPayload","inputs","vars","undefined","plan","listenerOutputTypes","type","payload","workspaceId","mode","drainListenerEventsIntoExecution","probeResult","findExistingExecution","resolveRequested","hasPendingResolveEvent","kind","hasBufferedFire","hasBufferedFireEvent","materializationTarget","loadListenerMaterializationTarget","model","modelJob","find","key","variableResolutionError","projectId","definitionId","secrets","error","agentToolContext","agentToolMaterialization","integrations","projects","drained","result","bufferedEvents","lockBufferedFireEvents","length","priorExecutions","loadListenerPriorExecutions","name","materialized","sequence","expectedSequence","triggerEvents","listenerTriggerEvents","resolveAgentDefaults","agent","agentToolSnapshot","execution","persistMaterializedListenerExecution","bufferedEventIds","map","event","drainExecutionResult","batchSize","peekListenerBuffer","row","fireCount","disposition","resolvePending","oldestAgeMs","receivedAt","newestAgeMs","consumedByExecutionId","resolveJobListener","decision","deriveJobListenerResolutionDecision","applyJobListenerResolution","changed","reason","jobRow","executionRows","Promise","all","orderBy","success","executions","resolutionReason","statusReason","evaluationTrace","trace","resolvedStatus","settleListenerJobExecution","finishedAt","jobExecutionId","statusReasonMessage","countActiveListeners","resolveEvent","fireEvent","bufferedQuery","maxSize","source","delivery_id","deliveryId","received_at","toISOString","project","triggerReference","repository","ref","commit","data","insert","values","nameOverride","runner","step","sourceLocation","config","configPlan","authoredConfig","condition","position","executionVersion","requiredLabels","query","fallbackName"],"mappings":"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"}
@@ -31,10 +31,9 @@ export interface UpdateJobExecutionStatusParams {
31
31
  secrets?: Pick<SecretsInterModuleClient, 'getVariablesByNamespace'> | undefined;
32
32
  }
33
33
  export declare function updateJobExecutionStatus(params: UpdateJobExecutionStatusParams): Promise<JobExecution>;
34
- export declare function recordJobExecutionQueuedAt(params: {
34
+ export declare function queueJobExecution(params: {
35
35
  jobExecutionId: string;
36
- queuedAt: Date;
37
- }): Promise<void>;
36
+ }): Promise<JobExecution>;
38
37
  export declare function recordJobExecutionStartedAt(params: {
39
38
  jobExecutionId: string;
40
39
  startedAt: Date;
@@ -1 +1 @@
1
- {"version":3,"file":"job-executions.d.ts","sourceRoot":"","sources":["../../../src/db/workflow-runs/job-executions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"job-executions.d.ts","sourceRoot":"","sources":["../../../src/db/workflow-runs/job-executions.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,11 @@
1
1
  import { readPersistedWorkflowModel } from '@shipfox/api-definitions-dto';
2
- import { WORKFLOWS_JOB_EXECUTION_TIMED_OUT } from '@shipfox/api-workflows-dto';
2
+ import { canonicalizeLabels } from '@shipfox/runner-labels';
3
3
  import { and, asc, desc, eq, isNull, notInArray, sql } from 'drizzle-orm';
4
4
  import { InterpolationUnresolvableError, JobNotFoundError, JobOutputNotJsonSafeError, JobOutputTooLargeError, JobOutputTooManyEntriesError } from '#core/errors.js';
5
5
  import { deriveJobExecutionOutputs } from '#core/job-transition/index.js';
6
6
  import { deriveCompletion, isTerminal } from '#core/step-transition/decide-step-transition.js';
7
7
  import { recordWorkflowJobExecutionLeaseExpiryResolved, recordWorkflowJobExecutionQueued, recordWorkflowJobExecutionStarted, recordWorkflowJobExecutionStatusChanged, recordWorkflowJobExecutionTimedOut } from '#metrics/instance.js';
8
8
  import { db } from '../db.js';
9
- import { writeWorkflowsOutboxEvent } from '../outbox-writes.js';
10
9
  import { jobExecutions, toJobExecution } from '../schema/job-executions.js';
11
10
  import { jobs, toJob } from '../schema/jobs.js';
12
11
  import { stepAttempts, toStepAttempt } from '../schema/step-attempts.js';
@@ -14,8 +13,9 @@ import { steps, toStep } from '../schema/steps.js';
14
13
  import { workflowRunAttempts } from '../schema/workflow-run-attempts.js';
15
14
  import { toWorkflowRun, workflowRuns } from '../schema/workflow-runs.js';
16
15
  import { getDirectDependencyJobContexts } from './jobs.js';
16
+ import { writeJobExecutionQueuedOutbox, writeJobExecutionTerminatedOutbox } from './outbox.js';
17
17
  import { loadReferencedVariables } from './runs.js';
18
- import { getWorkflowContextForJob, optimisticLockRetry, TERMINAL_EXECUTION_STATUSES } from './shared.js';
18
+ import { optimisticLockRetry, TERMINAL_EXECUTION_STATUSES } from './shared.js';
19
19
  import { bulkUpdateStepStatuses, getStepsByJobExecutionIdForUpdate } from './steps.js';
20
20
  async function getJobExecutionFallbackName(tx, jobExecutionId) {
21
21
  const [row] = await tx.select({
@@ -169,6 +169,15 @@ async function updateJobExecutionStatusAtVersion(tx, params) {
169
169
  }).where(and(eq(jobExecutions.id, params.jobExecutionId), eq(jobExecutions.version, params.expectedVersion), notInArray(jobExecutions.status, TERMINAL_EXECUTION_STATUSES))).returning();
170
170
  const row = rows[0];
171
171
  if (!row) return null;
172
+ if (TERMINAL_EXECUTION_STATUSES.includes(row.status)) {
173
+ await writeJobExecutionTerminatedOutbox(tx, {
174
+ jobId: row.jobId,
175
+ jobExecutionId: row.id,
176
+ status: row.status,
177
+ statusReason: row.statusReason,
178
+ statusReasonMessage: row.statusReasonMessage
179
+ });
180
+ }
172
181
  return {
173
182
  execution: toJobExecution(row, await getJobExecutionFallbackName(tx, row.id)),
174
183
  changed: true
@@ -200,13 +209,43 @@ export async function updateJobExecutionStatus(params) {
200
209
  if (result.changed) recordWorkflowJobExecutionStatusChanged(result.execution.status);
201
210
  return result.execution;
202
211
  }
203
- export async function recordJobExecutionQueuedAt(params) {
204
- const updated = await db().update(jobExecutions).set({
205
- queuedAt: params.queuedAt
206
- }).where(and(eq(jobExecutions.id, params.jobExecutionId), isNull(jobExecutions.queuedAt))).returning({
207
- id: jobExecutions.id
212
+ export async function queueJobExecution(params) {
213
+ const result = await db().transaction(async (tx)=>{
214
+ const [row] = await tx.select({
215
+ jobExecution: jobExecutions,
216
+ job: jobs
217
+ }).from(jobExecutions).innerJoin(jobs, eq(jobExecutions.jobId, jobs.id)).where(eq(jobExecutions.id, params.jobExecutionId)).limit(1).for('update');
218
+ if (!row) throw new JobNotFoundError(params.jobExecutionId);
219
+ const existing = toJobExecution(row.jobExecution, row.job.name ?? row.job.key);
220
+ if (existing.queuedAt !== null || TERMINAL_EXECUTION_STATUSES.includes(existing.status)) {
221
+ return {
222
+ execution: existing,
223
+ changed: false
224
+ };
225
+ }
226
+ const requiredLabels = [
227
+ ...canonicalizeLabels(existing.runner ?? row.job.runner ?? [])
228
+ ];
229
+ if (requiredLabels.length === 0) {
230
+ throw new Error(`Job execution ${params.jobExecutionId} has no required runner labels`);
231
+ }
232
+ const [queued] = await tx.update(jobExecutions).set({
233
+ queuedAt: sql`now()`
234
+ }).where(eq(jobExecutions.id, params.jobExecutionId)).returning();
235
+ if (!queued?.queuedAt) throw new Error(`Cannot queue job execution ${params.jobExecutionId}`);
236
+ await writeJobExecutionQueuedOutbox(tx, {
237
+ jobId: queued.jobId,
238
+ jobExecutionId: queued.id,
239
+ requiredLabels,
240
+ queuedAt: queued.queuedAt
241
+ });
242
+ return {
243
+ execution: toJobExecution(queued, row.job.name ?? row.job.key),
244
+ changed: true
245
+ };
208
246
  });
209
- if (updated.length > 0) recordWorkflowJobExecutionQueued();
247
+ if (result.changed) recordWorkflowJobExecutionQueued();
248
+ return result.execution;
210
249
  }
211
250
  export async function recordJobExecutionStartedAt(params) {
212
251
  const updated = await db().update(jobExecutions).set({
@@ -237,17 +276,6 @@ export async function failJobExecutionAsTimedOut(params) {
237
276
  } : null,
238
277
  failureMessage: `Optimistic lock failure: job execution ${params.jobExecutionId} version ${params.expectedVersion}`
239
278
  });
240
- if (updated.changed) {
241
- const identity = await getWorkflowContextForJob(updated.execution.jobId, tx);
242
- await writeWorkflowsOutboxEvent(tx, {
243
- type: WORKFLOWS_JOB_EXECUTION_TIMED_OUT,
244
- payload: {
245
- jobId: identity.jobId,
246
- jobExecutionId: params.jobExecutionId,
247
- workflowRunAttemptId: identity.workflowRunAttemptId
248
- }
249
- });
250
- }
251
279
  return updated;
252
280
  });
253
281
  if (result.changed) {