@shipfox/api-triggers 4.0.0 → 6.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.
- package/.turbo/turbo-build.log +4 -4
- package/CHANGELOG.md +65 -0
- package/README.md +23 -3
- package/dist/core/dispatch-integration-event.d.ts +2 -0
- package/dist/core/dispatch-integration-event.d.ts.map +1 -1
- package/dist/core/dispatch-integration-event.js +9 -5
- package/dist/core/dispatch-integration-event.js.map +1 -1
- package/dist/core/drain-cron-schedules.d.ts +2 -0
- package/dist/core/drain-cron-schedules.d.ts.map +1 -1
- package/dist/core/drain-cron-schedules.js +1 -0
- package/dist/core/drain-cron-schedules.js.map +1 -1
- package/dist/core/fire-cron.d.ts +6 -2
- package/dist/core/fire-cron.d.ts.map +1 -1
- package/dist/core/fire-cron.js +8 -5
- package/dist/core/fire-cron.js.map +1 -1
- package/dist/core/fire-manual.d.ts +6 -2
- package/dist/core/fire-manual.d.ts.map +1 -1
- package/dist/core/fire-manual.js +8 -4
- package/dist/core/fire-manual.js.map +1 -1
- package/dist/core/route-event-to-job-listeners.d.ts +2 -0
- package/dist/core/route-event-to-job-listeners.d.ts.map +1 -1
- package/dist/core/route-event-to-job-listeners.js +2 -3
- package/dist/core/route-event-to-job-listeners.js.map +1 -1
- package/dist/core/workflows-client.d.ts +69 -0
- package/dist/core/workflows-client.d.ts.map +1 -0
- package/dist/core/workflows-client.js +20 -0
- package/dist/core/workflows-client.js.map +1 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +52 -50
- package/dist/index.js.map +1 -1
- package/dist/presentation/index.d.ts +2 -2
- package/dist/presentation/index.d.ts.map +1 -1
- package/dist/presentation/index.js +2 -2
- package/dist/presentation/index.js.map +1 -1
- package/dist/presentation/routes/fire-manual.d.ts +2 -1
- package/dist/presentation/routes/fire-manual.d.ts.map +1 -1
- package/dist/presentation/routes/fire-manual.js +61 -58
- package/dist/presentation/routes/fire-manual.js.map +1 -1
- package/dist/presentation/routes/index.d.ts +2 -1
- package/dist/presentation/routes/index.d.ts.map +1 -1
- package/dist/presentation/routes/index.js +23 -21
- package/dist/presentation/routes/index.js.map +1 -1
- package/dist/presentation/subscribers/index.d.ts +1 -1
- package/dist/presentation/subscribers/index.d.ts.map +1 -1
- package/dist/presentation/subscribers/index.js +1 -1
- package/dist/presentation/subscribers/index.js.map +1 -1
- package/dist/presentation/subscribers/on-integration-event-received.d.ts +2 -1
- package/dist/presentation/subscribers/on-integration-event-received.d.ts.map +1 -1
- package/dist/presentation/subscribers/on-integration-event-received.js +16 -13
- package/dist/presentation/subscribers/on-integration-event-received.js.map +1 -1
- package/dist/temporal/activities/drain-cron-batch.d.ts +2 -1
- package/dist/temporal/activities/drain-cron-batch.d.ts.map +1 -1
- package/dist/temporal/activities/drain-cron-batch.js +2 -1
- package/dist/temporal/activities/drain-cron-batch.js.map +1 -1
- package/dist/temporal/activities/index.d.ts +4 -3
- package/dist/temporal/activities/index.d.ts.map +1 -1
- package/dist/temporal/activities/index.js +2 -2
- package/dist/temporal/activities/index.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +27 -35
- package/src/core/dispatch-integration-event.history-failure.test.ts +11 -6
- package/src/core/dispatch-integration-event.test.ts +50 -36
- package/src/core/dispatch-integration-event.ts +8 -5
- package/src/core/drain-cron-schedules.test.ts +30 -29
- package/src/core/drain-cron-schedules.ts +3 -0
- package/src/core/fire-cron.test.ts +35 -24
- package/src/core/fire-cron.ts +9 -7
- package/src/core/fire-manual.test.ts +19 -22
- package/src/core/fire-manual.ts +9 -6
- package/src/core/record-trigger-history.test.ts +3 -5
- package/src/core/route-event-to-job-listeners.test.ts +5 -4
- package/src/core/route-event-to-job-listeners.ts +5 -4
- package/src/core/workflows-client.test.ts +73 -0
- package/src/core/workflows-client.ts +32 -0
- package/src/index.ts +49 -42
- package/src/presentation/index.ts +2 -2
- package/src/presentation/routes/fire-manual.test.ts +14 -30
- package/src/presentation/routes/fire-manual.ts +62 -54
- package/src/presentation/routes/index.ts +18 -15
- package/src/presentation/subscribers/index.ts +1 -1
- package/src/presentation/subscribers/on-integration-event-received.test.ts +6 -3
- package/src/presentation/subscribers/on-integration-event-received.ts +20 -16
- package/src/temporal/activities/drain-cron-batch.ts +5 -1
- package/src/temporal/activities/index.ts +3 -2
- package/tsconfig.build.tsbuildinfo +1 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
$ shipfox-swc && shipfox-temporal-bundle dist/temporal/workflows/index.js
|
|
2
|
-
Successfully compiled:
|
|
3
|
-
2026-07-
|
|
2
|
+
Successfully compiled: 57 files with swc (584.37ms)
|
|
3
|
+
2026-07-21T08:10:32.735Z [INFO] asset workflow-bundle-c6357fb5676e5edf087a.js 1.45 MiB [emitted] [immutable] (name: main)
|
|
4
4
|
runtime modules 670 bytes 3 modules
|
|
5
5
|
modules by path ../../../node_modules/.pnpm/ 424 KiB
|
|
6
6
|
modules by path ../../../node_modules/.pnpm/@temporalio+common@1.18.1/node_modules/@temporal...(truncated) 155 KiB 34 modules
|
|
@@ -16,6 +16,6 @@ modules by path ./dist/temporal/workflows/ 3.72 KiB
|
|
|
16
16
|
optional modules 30 bytes [optional]
|
|
17
17
|
__temporal_custom_payload_converter (ignored) 15 bytes [optional] [built] [code generated]
|
|
18
18
|
__temporal_custom_failure_converter (ignored) 15 bytes [optional] [built] [code generated]
|
|
19
|
-
webpack 5.107.2 compiled successfully in
|
|
20
|
-
2026-07-
|
|
19
|
+
webpack 5.107.2 compiled successfully in 4048 ms
|
|
20
|
+
2026-07-21T08:10:32.755Z [INFO] Workflow bundle created { size: '1.45MB' }
|
|
21
21
|
/home/runner/work/shipfox/shipfox/libs/api/triggers/dist/temporal/workflows/index.js: 1524360 bytes
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,70 @@
|
|
|
1
1
|
# @shipfox/api-triggers
|
|
2
2
|
|
|
3
|
+
## 6.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 23563de: Moves Triggers to the injected Workflows inter-module contract with stable run idempotency and listener delivery commands.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- f73da5d: Enforces bounded API context imports and routes inter-module consumers through producer contracts.
|
|
12
|
+
- Updated dependencies [a8f0545]
|
|
13
|
+
- Updated dependencies [0bb82a4]
|
|
14
|
+
- Updated dependencies [23563de]
|
|
15
|
+
- Updated dependencies [54ce48b]
|
|
16
|
+
- Updated dependencies [f4bc2eb]
|
|
17
|
+
- Updated dependencies [c0162b0]
|
|
18
|
+
- Updated dependencies [7ac43a4]
|
|
19
|
+
- Updated dependencies [f262539]
|
|
20
|
+
- Updated dependencies [a01e917]
|
|
21
|
+
- Updated dependencies [3bb4e26]
|
|
22
|
+
- Updated dependencies [8bdc149]
|
|
23
|
+
- Updated dependencies [f73da5d]
|
|
24
|
+
- Updated dependencies [3810996]
|
|
25
|
+
- Updated dependencies [23a4dc2]
|
|
26
|
+
- Updated dependencies [b00ed29]
|
|
27
|
+
- Updated dependencies [8aa7cd3]
|
|
28
|
+
- Updated dependencies [81f9544]
|
|
29
|
+
- Updated dependencies [4604a06]
|
|
30
|
+
- @shipfox/api-definitions-dto@6.0.0
|
|
31
|
+
- @shipfox/api-integration-core-dto@6.0.0
|
|
32
|
+
- @shipfox/api-projects@6.0.0
|
|
33
|
+
- @shipfox/api-workflows-dto@6.0.0
|
|
34
|
+
- @shipfox/node-module@0.4.0
|
|
35
|
+
- @shipfox/node-temporal@0.3.2
|
|
36
|
+
- @shipfox/node-drizzle@0.3.2
|
|
37
|
+
- @shipfox/node-outbox@0.2.4
|
|
38
|
+
- @shipfox/api-auth-context@6.0.0
|
|
39
|
+
- @shipfox/node-fastify@0.2.4
|
|
40
|
+
- @shipfox/inter-module@0.2.0
|
|
41
|
+
|
|
42
|
+
## 5.0.0
|
|
43
|
+
|
|
44
|
+
### Patch Changes
|
|
45
|
+
|
|
46
|
+
- bb037af: Resolves workspace packages from source during development while published consumers continue to use compiled output.
|
|
47
|
+
- Updated dependencies [2875241]
|
|
48
|
+
- Updated dependencies [bb037af]
|
|
49
|
+
- Updated dependencies [fb70438]
|
|
50
|
+
- @shipfox/api-integration-core-dto@5.0.0
|
|
51
|
+
- @shipfox/api-auth-context@5.0.0
|
|
52
|
+
- @shipfox/api-definitions-dto@5.0.0
|
|
53
|
+
- @shipfox/api-projects@5.0.0
|
|
54
|
+
- @shipfox/api-triggers-dto@5.0.0
|
|
55
|
+
- @shipfox/api-workflows@5.0.0
|
|
56
|
+
- @shipfox/api-workflows-dto@5.0.0
|
|
57
|
+
- @shipfox/config@1.2.2
|
|
58
|
+
- @shipfox/expression@1.1.3
|
|
59
|
+
- @shipfox/node-drizzle@0.3.1
|
|
60
|
+
- @shipfox/node-fastify@0.2.3
|
|
61
|
+
- @shipfox/node-module@0.3.2
|
|
62
|
+
- @shipfox/node-opentelemetry@0.5.2
|
|
63
|
+
- @shipfox/node-outbox@0.2.3
|
|
64
|
+
- @shipfox/node-postgres@0.4.2
|
|
65
|
+
- @shipfox/node-temporal@0.3.1
|
|
66
|
+
- @shipfox/workflow-document@2.1.1
|
|
67
|
+
|
|
3
68
|
## 4.0.0
|
|
4
69
|
|
|
5
70
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -11,12 +11,22 @@ runs and inspect received trigger events.
|
|
|
11
11
|
Register the module with the API module runner:
|
|
12
12
|
|
|
13
13
|
```ts
|
|
14
|
-
import {
|
|
14
|
+
import {createTriggersModule} from '@shipfox/api-triggers';
|
|
15
|
+
import {workflowsInterModuleContract} from '@shipfox/api-workflows-dto/inter-module';
|
|
15
16
|
import {createApp, listen} from '@shipfox/node-fastify';
|
|
16
17
|
import {initializeModules, startModuleWorkers} from '@shipfox/node-module';
|
|
17
|
-
|
|
18
|
+
import {
|
|
19
|
+
createInMemoryInterModuleTransport,
|
|
20
|
+
registerInterModulePresentations,
|
|
21
|
+
} from '@shipfox/node-module/inter-module';
|
|
22
|
+
|
|
23
|
+
const transport = createInMemoryInterModuleTransport();
|
|
24
|
+
const workflows = transport.createClient(workflowsInterModuleContract);
|
|
25
|
+
const modules = [createTriggersModule({workflows}) /* and other modules */];
|
|
26
|
+
registerInterModulePresentations({transport, modules});
|
|
27
|
+
transport.seal();
|
|
18
28
|
const {auth, routes, workers} = await initializeModules({
|
|
19
|
-
modules
|
|
29
|
+
modules,
|
|
20
30
|
});
|
|
21
31
|
|
|
22
32
|
await createApp({auth, routes});
|
|
@@ -24,6 +34,16 @@ await startModuleWorkers({workers});
|
|
|
24
34
|
await listen();
|
|
25
35
|
```
|
|
26
36
|
|
|
37
|
+
### Migration from `triggersModule`
|
|
38
|
+
|
|
39
|
+
`triggersModule` is replaced by `createTriggersModule({workflows})`. The API
|
|
40
|
+
composition root creates the Workflows client from
|
|
41
|
+
`@shipfox/api-workflows-dto/inter-module`, passes it to Triggers, registers the
|
|
42
|
+
Workflows presentation, and seals the transport before the server starts. Cron
|
|
43
|
+
activities, integration subscribers, and the manual route use that one injected
|
|
44
|
+
client. Callers must keep the deterministic cron or integration key when they
|
|
45
|
+
retry a trigger command. The manual route creates one new key for each request.
|
|
46
|
+
|
|
27
47
|
This adds:
|
|
28
48
|
|
|
29
49
|
- triggers database migrations from `libs/api/triggers/drizzle`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch-integration-event.d.ts","sourceRoot":"","sources":["../../src/core/dispatch-integration-event.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dispatch-integration-event.d.ts","sourceRoot":"","sources":["../../src/core/dispatch-integration-event.ts"],"names":[],"mappings":"AASA,OAAO,EAA2B,KAAK,qBAAqB,EAAC,MAAM,uBAAuB,CAAC;AAE3F,MAAM,WAAW,8BAA8B;IAC7C,SAAS,EAAE,qBAAqB,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,IAAI,CAAC;CAClB;AAcD,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,8BAA8B,GACrC,OAAO,CAAC,IAAI,CAAC,CAiHf"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { isPermanentRunWorkflowError, runWorkflow } from '@shipfox/api-workflows';
|
|
2
1
|
import { findMatchingSubscriptions } from '#db/subscriptions.js';
|
|
3
2
|
import { eventOutcomeCount, eventReceivedCount, subscriptionTriggeredCount } from '#metrics/instance.js';
|
|
4
3
|
import { evaluateTriggerFilter, readConfigInputs } from './config.js';
|
|
5
4
|
import { beginTriggerHistory, toReason } from './record-trigger-history.js';
|
|
6
5
|
import { routeEventToJobListeners } from './route-event-to-job-listeners.js';
|
|
6
|
+
import { isPermanentStartRunError } from './workflows-client.js';
|
|
7
7
|
// Source-agnostic dispatcher: any inbound integration event fans out to every
|
|
8
8
|
// workspace subscription registered for its (source, event) and to every listening
|
|
9
9
|
// job subscribed to it, passing the raw payload through untouched. The module knows
|
|
@@ -56,8 +56,9 @@ export async function dispatchIntegrationEvent(params) {
|
|
|
56
56
|
continue;
|
|
57
57
|
}
|
|
58
58
|
triggerEngagedCount += 1;
|
|
59
|
+
const inputs = readConfigInputs(subscription);
|
|
59
60
|
try {
|
|
60
|
-
const run = await
|
|
61
|
+
const run = await params.workflows.startRunFromTrigger({
|
|
61
62
|
workspaceId: subscription.workspaceId,
|
|
62
63
|
projectId: subscription.projectId,
|
|
63
64
|
definitionId: subscription.workflowDefinitionId,
|
|
@@ -68,8 +69,10 @@ export async function dispatchIntegrationEvent(params) {
|
|
|
68
69
|
deliveryId: params.deliveryId,
|
|
69
70
|
data: params.payload
|
|
70
71
|
},
|
|
71
|
-
inputs:
|
|
72
|
-
|
|
72
|
+
...inputs === undefined ? {} : {
|
|
73
|
+
inputs
|
|
74
|
+
},
|
|
75
|
+
idempotencyKey: `${subscription.id}:${params.eventRef}`
|
|
73
76
|
});
|
|
74
77
|
await history.triggered(subscription, run);
|
|
75
78
|
triggeredCount += 1;
|
|
@@ -80,13 +83,14 @@ export async function dispatchIntegrationEvent(params) {
|
|
|
80
83
|
await history.dispatchErrored(subscription, toReason(error));
|
|
81
84
|
// Track presence with a flag, not `firstTransientError === undefined`: a thrown
|
|
82
85
|
// value of `undefined` is still a transient failure and must drive the replay.
|
|
83
|
-
if (!
|
|
86
|
+
if (!isPermanentStartRunError(error) && !sawTransientError) {
|
|
84
87
|
sawTransientError = true;
|
|
85
88
|
firstTransientError = error;
|
|
86
89
|
}
|
|
87
90
|
}
|
|
88
91
|
}
|
|
89
92
|
const listenerResult = await routeEventToJobListeners({
|
|
93
|
+
workflows: params.workflows,
|
|
90
94
|
history,
|
|
91
95
|
eventRef: params.eventRef,
|
|
92
96
|
workspaceId: params.workspaceId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/dispatch-integration-event.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../../src/core/dispatch-integration-event.ts"],"sourcesContent":["import {findMatchingSubscriptions} from '#db/subscriptions.js';\nimport {\n eventOutcomeCount,\n eventReceivedCount,\n subscriptionTriggeredCount,\n} from '#metrics/instance.js';\nimport {evaluateTriggerFilter, readConfigInputs} from './config.js';\nimport {beginTriggerHistory, toReason} from './record-trigger-history.js';\nimport {routeEventToJobListeners} from './route-event-to-job-listeners.js';\nimport {isPermanentStartRunError, type WorkflowsModuleClient} from './workflows-client.js';\n\nexport interface DispatchIntegrationEventParams {\n workflows: WorkflowsModuleClient;\n eventRef: string;\n workspaceId: string;\n provider: string;\n source: string;\n event: string;\n deliveryId: string;\n connectionId: string;\n connectionName: string | null;\n payload: unknown;\n receivedAt: Date;\n}\n\n// Source-agnostic dispatcher: any inbound integration event fans out to every\n// workspace subscription registered for its (source, event) and to every listening\n// job subscribed to it, passing the raw payload through untouched. The module knows\n// nothing about github, gitlab, etc.\n//\n// Continue-on-error: every matched subscription and listener is attempted so one broken\n// subscription cannot starve its siblings. A permanent failure (deleted definition, project\n// mismatch) is recorded and skipped; a transient one is recorded and re-thrown so the outbox\n// replays the whole event and converges (succeeded siblings dedup on the idempotency key). The\n// event reaches a terminal outcome only when no transient error remains: `routed` if any run\n// was created or any listening job matched, `discarded` if nothing matched, otherwise `errored`.\n// History is best-effort; the thrown transient error, not the recorded outcome, drives the retry.\nexport async function dispatchIntegrationEvent(\n params: DispatchIntegrationEventParams,\n): Promise<void> {\n eventReceivedCount.add(1, {provider: params.provider});\n\n const history = await beginTriggerHistory({\n eventRef: params.eventRef,\n origin: 'integration',\n workspaceId: params.workspaceId,\n provider: params.provider,\n source: params.source,\n event: params.event,\n deliveryId: params.deliveryId,\n connectionId: params.connectionId,\n connectionName: params.connectionName,\n payload: (params.payload ?? null) as Record<string, unknown> | null,\n receivedAt: params.receivedAt,\n });\n\n const subscriptions = await findMatchingSubscriptions({\n workspaceId: params.workspaceId,\n source: params.source,\n event: params.event,\n });\n\n let triggeredCount = 0;\n let triggerEngagedCount = 0;\n let sawTransientError = false;\n let firstTransientError: unknown;\n\n for (const subscription of subscriptions) {\n const filterResult = evaluateTriggerFilter({\n subscription,\n source: params.source,\n event: params.event,\n payload: params.payload,\n });\n if (filterResult.kind === 'filtered') continue;\n if (filterResult.kind === 'filter-error') {\n triggerEngagedCount += 1;\n await history.filterErrored(subscription, filterResult.reason);\n continue;\n }\n triggerEngagedCount += 1;\n\n const inputs = readConfigInputs(subscription);\n try {\n const run = await params.workflows.startRunFromTrigger({\n workspaceId: subscription.workspaceId,\n projectId: subscription.projectId,\n definitionId: subscription.workflowDefinitionId,\n triggerPayload: {\n provider: params.provider,\n source: params.source,\n event: params.event,\n deliveryId: params.deliveryId,\n data: params.payload,\n },\n ...(inputs === undefined ? {} : {inputs}),\n idempotencyKey: `${subscription.id}:${params.eventRef}`,\n });\n await history.triggered(subscription, run);\n triggeredCount += 1;\n subscriptionTriggeredCount.add(1, {provider: params.provider});\n } catch (error) {\n await history.dispatchErrored(subscription, toReason(error));\n // Track presence with a flag, not `firstTransientError === undefined`: a thrown\n // value of `undefined` is still a transient failure and must drive the replay.\n if (!isPermanentStartRunError(error) && !sawTransientError) {\n sawTransientError = true;\n firstTransientError = error;\n }\n }\n }\n\n const listenerResult = await routeEventToJobListeners({\n workflows: params.workflows,\n history,\n eventRef: params.eventRef,\n workspaceId: params.workspaceId,\n provider: params.provider,\n source: params.source,\n event: params.event,\n deliveryId: params.deliveryId,\n payload: params.payload,\n receivedAt: params.receivedAt,\n });\n\n if (listenerResult.transientErrored && !sawTransientError) {\n sawTransientError = true;\n firstTransientError = listenerResult.transientError;\n }\n\n const totalMatchedCount = triggerEngagedCount + listenerResult.engagedCount;\n\n if (sawTransientError) {\n eventOutcomeCount.add(1, {provider: params.provider, outcome: 'failed'});\n await history.failed(totalMatchedCount);\n throw firstTransientError;\n }\n\n if (triggeredCount > 0 || listenerResult.acceptedJobCount > 0) {\n eventOutcomeCount.add(1, {provider: params.provider, outcome: 'routed'});\n await history.routed(totalMatchedCount);\n return;\n }\n\n if (totalMatchedCount === 0) {\n eventOutcomeCount.add(1, {provider: params.provider, outcome: 'discarded'});\n await history.discarded();\n return;\n }\n\n eventOutcomeCount.add(1, {provider: params.provider, outcome: 'errored'});\n await history.allErrored(totalMatchedCount);\n}\n"],"names":["findMatchingSubscriptions","eventOutcomeCount","eventReceivedCount","subscriptionTriggeredCount","evaluateTriggerFilter","readConfigInputs","beginTriggerHistory","toReason","routeEventToJobListeners","isPermanentStartRunError","dispatchIntegrationEvent","params","add","provider","history","eventRef","origin","workspaceId","source","event","deliveryId","connectionId","connectionName","payload","receivedAt","subscriptions","triggeredCount","triggerEngagedCount","sawTransientError","firstTransientError","subscription","filterResult","kind","filterErrored","reason","inputs","run","workflows","startRunFromTrigger","projectId","definitionId","workflowDefinitionId","triggerPayload","data","undefined","idempotencyKey","id","triggered","error","dispatchErrored","listenerResult","transientErrored","transientError","totalMatchedCount","engagedCount","outcome","failed","acceptedJobCount","routed","discarded","allErrored"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drain-cron-schedules.d.ts","sourceRoot":"","sources":["../../src/core/drain-cron-schedules.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"drain-cron-schedules.d.ts","sourceRoot":"","sources":["../../src/core/drain-cron-schedules.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,uBAAuB,CAAC;AAEjE,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,SAAS,EAAE,qBAAqB,CAAC;IAC1C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC;;;;OAIG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;CACzD;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,2BAA2B,GAClC,OAAO,CAAC,gBAAgB,CAAC,CAoD3B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/drain-cron-schedules.ts"],"sourcesContent":["import {logger} from '@shipfox/node-opentelemetry';\nimport {advanceCronSchedule, claimDueCronSchedules, selectDbNow} from '#db/cron-schedules.js';\nimport {db} from '#db/db.js';\nimport {computeNextFireAt} from './compute-next-fire-at.js';\nimport {fireCronSubscription} from './fire-cron.js';\n\nexport interface DrainDueCronSchedulesParams {\n readonly batchSize: number;\n readonly jitterWindowSeconds: number;\n /**\n * Liveness signal invoked once per processed schedule (e.g. the Temporal activity\n * heartbeat), so a batch stuck on a slow `runWorkflow` is visible rather than\n * looking hung until the start-to-close timeout fires.\n */\n readonly onScheduleProcessed?: (() => void) | undefined;\n}\n\nexport interface CronDrainSummary {\n readonly claimed: number;\n readonly fired: number;\n readonly errored: number;\n readonly retried: number;\n}\n\n/**\n * Claims one bounded batch of due cron schedules and, per row, advances the schedule\n * and fires the workflow. There is no internal drain loop, so the per-activity ceiling\n * stays a hard `batchSize`.\n *\n * The batch is claimed and processed inside a single transaction, so its `FOR UPDATE\n * SKIP LOCKED` locks are held until commit and concurrent activities/pods claim disjoint\n * rows. Each row runs in a nested savepoint that advances `next_fire_at` before firing:\n * on a transient failure the savepoint rolls back only that row's advance, leaving it due\n * for retry, without blocking the rest of the batch. Firing before the advance commits\n * makes a crash between the two re-fire the (idempotent) occurrence rather than skip it.\n */\nexport async function drainDueCronSchedules(\n params: DrainDueCronSchedulesParams,\n): Promise<CronDrainSummary> {\n let claimed = 0;\n let fired = 0;\n let errored = 0;\n let retried = 0;\n\n await db().transaction(async (tx) => {\n // One database-clock reading shared by the due check and every advance, so the two\n // never disagree under application/database clock skew.\n const now = await selectDbNow(tx);\n const due = await claimDueCronSchedules({tx, limit: params.batchSize, now});\n claimed = due.length;\n\n for (const schedule of due) {\n const scheduledSlot = schedule.nextFireAt;\n try {\n const result = await tx.transaction(async (rowTx) => {\n const nextFireAt = computeNextFireAt({\n cronExpression: schedule.cronExpression,\n timezone: schedule.timezone,\n from: now,\n subscriptionId: schedule.subscriptionId,\n jitterWindowSeconds: params.jitterWindowSeconds,\n });\n await advanceCronSchedule({\n tx: rowTx,\n subscriptionId: schedule.subscriptionId,\n nextFireAt,\n lastFiredAt: scheduledSlot,\n });\n return await fireCronSubscription({\n subscriptionId: schedule.subscriptionId,\n scheduledSlot,\n });\n });\n if (result.outcome === 'fired') fired += 1;\n else errored += 1;\n } catch (error) {\n // Transient failure: the savepoint rolled back the advance, so the schedule\n // stays due and the next tick (or an activity retry) re-claims it.\n retried += 1;\n logger().warn(\n {err: error, subscriptionId: schedule.subscriptionId},\n 'cron drain: transient fire failure; schedule left due for retry',\n );\n }\n params.onScheduleProcessed?.();\n }\n });\n\n return {claimed, fired, errored, retried};\n}\n"],"names":["logger","advanceCronSchedule","claimDueCronSchedules","selectDbNow","db","computeNextFireAt","fireCronSubscription","drainDueCronSchedules","params","claimed","fired","errored","retried","transaction","tx","now","due","limit","batchSize","length","schedule","scheduledSlot","nextFireAt","result","rowTx","cronExpression","timezone","from","subscriptionId","jitterWindowSeconds","lastFiredAt","outcome","error","warn","err","onScheduleProcessed"],"mappings":"AAAA,SAAQA,MAAM,QAAO,8BAA8B;AACnD,SAAQC,mBAAmB,EAAEC,qBAAqB,EAAEC,WAAW,QAAO,wBAAwB;AAC9F,SAAQC,EAAE,QAAO,YAAY;AAC7B,SAAQC,iBAAiB,QAAO,4BAA4B;AAC5D,SAAQC,oBAAoB,QAAO,iBAAiB;
|
|
1
|
+
{"version":3,"sources":["../../src/core/drain-cron-schedules.ts"],"sourcesContent":["import {logger} from '@shipfox/node-opentelemetry';\nimport {advanceCronSchedule, claimDueCronSchedules, selectDbNow} from '#db/cron-schedules.js';\nimport {db} from '#db/db.js';\nimport {computeNextFireAt} from './compute-next-fire-at.js';\nimport {fireCronSubscription} from './fire-cron.js';\nimport type {WorkflowsModuleClient} from './workflows-client.js';\n\nexport interface DrainDueCronSchedulesParams {\n readonly workflows: WorkflowsModuleClient;\n readonly batchSize: number;\n readonly jitterWindowSeconds: number;\n /**\n * Liveness signal invoked once per processed schedule (e.g. the Temporal activity\n * heartbeat), so a batch stuck on a slow `runWorkflow` is visible rather than\n * looking hung until the start-to-close timeout fires.\n */\n readonly onScheduleProcessed?: (() => void) | undefined;\n}\n\nexport interface CronDrainSummary {\n readonly claimed: number;\n readonly fired: number;\n readonly errored: number;\n readonly retried: number;\n}\n\n/**\n * Claims one bounded batch of due cron schedules and, per row, advances the schedule\n * and fires the workflow. There is no internal drain loop, so the per-activity ceiling\n * stays a hard `batchSize`.\n *\n * The batch is claimed and processed inside a single transaction, so its `FOR UPDATE\n * SKIP LOCKED` locks are held until commit and concurrent activities/pods claim disjoint\n * rows. Each row runs in a nested savepoint that advances `next_fire_at` before firing:\n * on a transient failure the savepoint rolls back only that row's advance, leaving it due\n * for retry, without blocking the rest of the batch. Firing before the advance commits\n * makes a crash between the two re-fire the (idempotent) occurrence rather than skip it.\n */\nexport async function drainDueCronSchedules(\n params: DrainDueCronSchedulesParams,\n): Promise<CronDrainSummary> {\n let claimed = 0;\n let fired = 0;\n let errored = 0;\n let retried = 0;\n\n await db().transaction(async (tx) => {\n // One database-clock reading shared by the due check and every advance, so the two\n // never disagree under application/database clock skew.\n const now = await selectDbNow(tx);\n const due = await claimDueCronSchedules({tx, limit: params.batchSize, now});\n claimed = due.length;\n\n for (const schedule of due) {\n const scheduledSlot = schedule.nextFireAt;\n try {\n const result = await tx.transaction(async (rowTx) => {\n const nextFireAt = computeNextFireAt({\n cronExpression: schedule.cronExpression,\n timezone: schedule.timezone,\n from: now,\n subscriptionId: schedule.subscriptionId,\n jitterWindowSeconds: params.jitterWindowSeconds,\n });\n await advanceCronSchedule({\n tx: rowTx,\n subscriptionId: schedule.subscriptionId,\n nextFireAt,\n lastFiredAt: scheduledSlot,\n });\n return await fireCronSubscription({\n workflows: params.workflows,\n subscriptionId: schedule.subscriptionId,\n scheduledSlot,\n });\n });\n if (result.outcome === 'fired') fired += 1;\n else errored += 1;\n } catch (error) {\n // Transient failure: the savepoint rolled back the advance, so the schedule\n // stays due and the next tick (or an activity retry) re-claims it.\n retried += 1;\n logger().warn(\n {err: error, subscriptionId: schedule.subscriptionId},\n 'cron drain: transient fire failure; schedule left due for retry',\n );\n }\n params.onScheduleProcessed?.();\n }\n });\n\n return {claimed, fired, errored, retried};\n}\n"],"names":["logger","advanceCronSchedule","claimDueCronSchedules","selectDbNow","db","computeNextFireAt","fireCronSubscription","drainDueCronSchedules","params","claimed","fired","errored","retried","transaction","tx","now","due","limit","batchSize","length","schedule","scheduledSlot","nextFireAt","result","rowTx","cronExpression","timezone","from","subscriptionId","jitterWindowSeconds","lastFiredAt","workflows","outcome","error","warn","err","onScheduleProcessed"],"mappings":"AAAA,SAAQA,MAAM,QAAO,8BAA8B;AACnD,SAAQC,mBAAmB,EAAEC,qBAAqB,EAAEC,WAAW,QAAO,wBAAwB;AAC9F,SAAQC,EAAE,QAAO,YAAY;AAC7B,SAAQC,iBAAiB,QAAO,4BAA4B;AAC5D,SAAQC,oBAAoB,QAAO,iBAAiB;AAsBpD;;;;;;;;;;;CAWC,GACD,OAAO,eAAeC,sBACpBC,MAAmC;IAEnC,IAAIC,UAAU;IACd,IAAIC,QAAQ;IACZ,IAAIC,UAAU;IACd,IAAIC,UAAU;IAEd,MAAMR,KAAKS,WAAW,CAAC,OAAOC;QAC5B,mFAAmF;QACnF,wDAAwD;QACxD,MAAMC,MAAM,MAAMZ,YAAYW;QAC9B,MAAME,MAAM,MAAMd,sBAAsB;YAACY;YAAIG,OAAOT,OAAOU,SAAS;YAAEH;QAAG;QACzEN,UAAUO,IAAIG,MAAM;QAEpB,KAAK,MAAMC,YAAYJ,IAAK;YAC1B,MAAMK,gBAAgBD,SAASE,UAAU;YACzC,IAAI;gBACF,MAAMC,SAAS,MAAMT,GAAGD,WAAW,CAAC,OAAOW;oBACzC,MAAMF,aAAajB,kBAAkB;wBACnCoB,gBAAgBL,SAASK,cAAc;wBACvCC,UAAUN,SAASM,QAAQ;wBAC3BC,MAAMZ;wBACNa,gBAAgBR,SAASQ,cAAc;wBACvCC,qBAAqBrB,OAAOqB,mBAAmB;oBACjD;oBACA,MAAM5B,oBAAoB;wBACxBa,IAAIU;wBACJI,gBAAgBR,SAASQ,cAAc;wBACvCN;wBACAQ,aAAaT;oBACf;oBACA,OAAO,MAAMf,qBAAqB;wBAChCyB,WAAWvB,OAAOuB,SAAS;wBAC3BH,gBAAgBR,SAASQ,cAAc;wBACvCP;oBACF;gBACF;gBACA,IAAIE,OAAOS,OAAO,KAAK,SAAStB,SAAS;qBACpCC,WAAW;YAClB,EAAE,OAAOsB,OAAO;gBACd,4EAA4E;gBAC5E,mEAAmE;gBACnErB,WAAW;gBACXZ,SAASkC,IAAI,CACX;oBAACC,KAAKF;oBAAOL,gBAAgBR,SAASQ,cAAc;gBAAA,GACpD;YAEJ;YACApB,OAAO4B,mBAAmB;QAC5B;IACF;IAEA,OAAO;QAAC3B;QAASC;QAAOC;QAASC;IAAO;AAC1C"}
|
package/dist/core/fire-cron.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type WorkflowsModuleClient } from './workflows-client.js';
|
|
2
2
|
export interface FireCronSubscriptionParams {
|
|
3
|
+
workflows: WorkflowsModuleClient;
|
|
3
4
|
subscriptionId: string;
|
|
4
5
|
/**
|
|
5
6
|
* The `next_fire_at` value the schedule held when it was claimed. Anchoring the
|
|
@@ -10,7 +11,10 @@ export interface FireCronSubscriptionParams {
|
|
|
10
11
|
}
|
|
11
12
|
export type FireCronSubscriptionResult = {
|
|
12
13
|
outcome: 'fired';
|
|
13
|
-
run:
|
|
14
|
+
run: {
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
};
|
|
14
18
|
} | {
|
|
15
19
|
outcome: 'errored';
|
|
16
20
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fire-cron.d.ts","sourceRoot":"","sources":["../../src/core/fire-cron.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fire-cron.d.ts","sourceRoot":"","sources":["../../src/core/fire-cron.ts"],"names":[],"mappings":"AAKA,OAAO,EAA2B,KAAK,qBAAqB,EAAC,MAAM,uBAAuB,CAAC;AAE3F,MAAM,WAAW,0BAA0B;IACzC,SAAS,EAAE,qBAAqB,CAAC;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,aAAa,EAAE,IAAI,CAAC;CACrB;AAED,MAAM,MAAM,0BAA0B,GAClC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,CAAA;CAAC,GACnD;IAAC,OAAO,EAAE,SAAS,CAAA;CAAC,CAAC;AAEzB;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,0BAA0B,GACjC,OAAO,CAAC,0BAA0B,CAAC,CA4DrC"}
|
package/dist/core/fire-cron.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { isPermanentRunWorkflowError, runWorkflow } from '@shipfox/api-workflows';
|
|
2
1
|
import { getTriggerSubscriptionById } from '#db/subscriptions.js';
|
|
3
2
|
import { cronFiredCount, cronFireLag } from '#metrics/instance.js';
|
|
4
3
|
import { readConfigInputs } from './config.js';
|
|
5
4
|
import { TriggerSubscriptionNotCronError, TriggerSubscriptionNotFoundError } from './errors.js';
|
|
6
5
|
import { beginTriggerHistory, toReason } from './record-trigger-history.js';
|
|
6
|
+
import { isPermanentStartRunError } from './workflows-client.js';
|
|
7
7
|
/**
|
|
8
8
|
* Fires one cron schedule occurrence. Mirrors `fireManualSubscription`, but is driven
|
|
9
9
|
* by the drain activity rather than an HTTP route, and reports the outcome instead of
|
|
@@ -36,9 +36,10 @@ import { beginTriggerHistory, toReason } from './record-trigger-history.js';
|
|
|
36
36
|
receivedAt: params.scheduledSlot,
|
|
37
37
|
eventRef
|
|
38
38
|
};
|
|
39
|
+
const inputs = readConfigInputs(subscription);
|
|
39
40
|
let run;
|
|
40
41
|
try {
|
|
41
|
-
run = await
|
|
42
|
+
run = await params.workflows.startRunFromTrigger({
|
|
42
43
|
workspaceId: subscription.workspaceId,
|
|
43
44
|
projectId: subscription.projectId,
|
|
44
45
|
definitionId: subscription.workflowDefinitionId,
|
|
@@ -48,13 +49,15 @@ import { beginTriggerHistory, toReason } from './record-trigger-history.js';
|
|
|
48
49
|
event: 'tick',
|
|
49
50
|
scheduleId: subscription.id
|
|
50
51
|
},
|
|
51
|
-
inputs:
|
|
52
|
-
|
|
52
|
+
...inputs === undefined ? {} : {
|
|
53
|
+
inputs
|
|
54
|
+
},
|
|
55
|
+
idempotencyKey: eventRef
|
|
53
56
|
});
|
|
54
57
|
} catch (error) {
|
|
55
58
|
const failure = await beginTriggerHistory(historyBase);
|
|
56
59
|
await failure.dispatchErrored(subscription, toReason(error));
|
|
57
|
-
if (
|
|
60
|
+
if (isPermanentStartRunError(error)) {
|
|
58
61
|
recordFire('errored', params.scheduledSlot);
|
|
59
62
|
await failure.allErrored(1);
|
|
60
63
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/fire-cron.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../../src/core/fire-cron.ts"],"sourcesContent":["import {getTriggerSubscriptionById} from '#db/subscriptions.js';\nimport {cronFiredCount, cronFireLag} from '#metrics/instance.js';\nimport {readConfigInputs} from './config.js';\nimport {TriggerSubscriptionNotCronError, TriggerSubscriptionNotFoundError} from './errors.js';\nimport {beginTriggerHistory, toReason} from './record-trigger-history.js';\nimport {isPermanentStartRunError, type WorkflowsModuleClient} from './workflows-client.js';\n\nexport interface FireCronSubscriptionParams {\n workflows: WorkflowsModuleClient;\n subscriptionId: string;\n /**\n * The `next_fire_at` value the schedule held when it was claimed. Anchoring the\n * idempotency key and history `event_ref` on this slot, rather than wall-clock\n * time, makes a retry of the same occurrence a deterministic no-op.\n */\n scheduledSlot: Date;\n}\n\nexport type FireCronSubscriptionResult =\n | {outcome: 'fired'; run: {id: string; name: string}}\n | {outcome: 'errored'};\n\n/**\n * Fires one cron schedule occurrence. Mirrors `fireManualSubscription`, but is driven\n * by the drain activity rather than an HTTP route, and reports the outcome instead of\n * throwing on a permanent failure so the caller can advance the schedule past a\n * permanently broken definition:\n *\n * - `{outcome: 'fired'}` on success (or an idempotent replay of an already-created run),\n * - `{outcome: 'errored'}` on a permanent `runWorkflow` failure (recorded, schedule advances),\n * - throws on a transient failure so the caller rolls back the advance and retries.\n */\nexport async function fireCronSubscription(\n params: FireCronSubscriptionParams,\n): Promise<FireCronSubscriptionResult> {\n const subscription = await getTriggerSubscriptionById(params.subscriptionId);\n if (!subscription) throw new TriggerSubscriptionNotFoundError(params.subscriptionId);\n if (subscription.source !== 'cron') {\n throw new TriggerSubscriptionNotCronError(params.subscriptionId, subscription.source);\n }\n\n // Deterministic per-occurrence identity: unique across (subscription, slot), stable\n // across retries. Used for both the run idempotency key and the received-event ref.\n const eventRef = `${subscription.id}:${params.scheduledSlot.toISOString()}`;\n const historyBase = {\n origin: 'cron' as const,\n workspaceId: subscription.workspaceId,\n provider: null,\n source: subscription.source,\n event: subscription.event,\n deliveryId: null,\n connectionId: null,\n connectionName: null,\n payload: null,\n // The scheduled occurrence is the logical arrival time of the tick event.\n receivedAt: params.scheduledSlot,\n eventRef,\n };\n\n const inputs = readConfigInputs(subscription);\n let run: {id: string; name: string};\n try {\n run = await params.workflows.startRunFromTrigger({\n workspaceId: subscription.workspaceId,\n projectId: subscription.projectId,\n definitionId: subscription.workflowDefinitionId,\n triggerPayload: {\n provider: 'cron',\n source: 'cron',\n event: 'tick',\n scheduleId: subscription.id,\n },\n ...(inputs === undefined ? {} : {inputs}),\n idempotencyKey: eventRef,\n });\n } catch (error) {\n const failure = await beginTriggerHistory(historyBase);\n await failure.dispatchErrored(subscription, toReason(error));\n if (isPermanentStartRunError(error)) {\n recordFire('errored', params.scheduledSlot);\n await failure.allErrored(1);\n return {outcome: 'errored'};\n }\n // Transient: leave the event non-terminal and re-throw so the caller rolls back\n // the advance and the schedule stays due for the next tick.\n await failure.failed(1);\n throw error;\n }\n\n const history = await beginTriggerHistory(historyBase);\n await history.triggered(subscription, run);\n recordFire('fired', params.scheduledSlot);\n await history.routed(1);\n return {outcome: 'fired', run};\n}\n\nfunction recordFire(outcome: 'fired' | 'errored', scheduledSlot: Date): void {\n cronFiredCount.add(1, {outcome});\n cronFireLag.record(Math.max(0, Date.now() - scheduledSlot.getTime()));\n}\n"],"names":["getTriggerSubscriptionById","cronFiredCount","cronFireLag","readConfigInputs","TriggerSubscriptionNotCronError","TriggerSubscriptionNotFoundError","beginTriggerHistory","toReason","isPermanentStartRunError","fireCronSubscription","params","subscription","subscriptionId","source","eventRef","id","scheduledSlot","toISOString","historyBase","origin","workspaceId","provider","event","deliveryId","connectionId","connectionName","payload","receivedAt","inputs","run","workflows","startRunFromTrigger","projectId","definitionId","workflowDefinitionId","triggerPayload","scheduleId","undefined","idempotencyKey","error","failure","dispatchErrored","recordFire","allErrored","outcome","failed","history","triggered","routed","add","record","Math","max","Date","now","getTime"],"mappings":"AAAA,SAAQA,0BAA0B,QAAO,uBAAuB;AAChE,SAAQC,cAAc,EAAEC,WAAW,QAAO,uBAAuB;AACjE,SAAQC,gBAAgB,QAAO,cAAc;AAC7C,SAAQC,+BAA+B,EAAEC,gCAAgC,QAAO,cAAc;AAC9F,SAAQC,mBAAmB,EAAEC,QAAQ,QAAO,8BAA8B;AAC1E,SAAQC,wBAAwB,QAAmC,wBAAwB;AAiB3F;;;;;;;;;CASC,GACD,OAAO,eAAeC,qBACpBC,MAAkC;IAElC,MAAMC,eAAe,MAAMX,2BAA2BU,OAAOE,cAAc;IAC3E,IAAI,CAACD,cAAc,MAAM,IAAIN,iCAAiCK,OAAOE,cAAc;IACnF,IAAID,aAAaE,MAAM,KAAK,QAAQ;QAClC,MAAM,IAAIT,gCAAgCM,OAAOE,cAAc,EAAED,aAAaE,MAAM;IACtF;IAEA,oFAAoF;IACpF,oFAAoF;IACpF,MAAMC,WAAW,GAAGH,aAAaI,EAAE,CAAC,CAAC,EAAEL,OAAOM,aAAa,CAACC,WAAW,IAAI;IAC3E,MAAMC,cAAc;QAClBC,QAAQ;QACRC,aAAaT,aAAaS,WAAW;QACrCC,UAAU;QACVR,QAAQF,aAAaE,MAAM;QAC3BS,OAAOX,aAAaW,KAAK;QACzBC,YAAY;QACZC,cAAc;QACdC,gBAAgB;QAChBC,SAAS;QACT,0EAA0E;QAC1EC,YAAYjB,OAAOM,aAAa;QAChCF;IACF;IAEA,MAAMc,SAASzB,iBAAiBQ;IAChC,IAAIkB;IACJ,IAAI;QACFA,MAAM,MAAMnB,OAAOoB,SAAS,CAACC,mBAAmB,CAAC;YAC/CX,aAAaT,aAAaS,WAAW;YACrCY,WAAWrB,aAAaqB,SAAS;YACjCC,cAActB,aAAauB,oBAAoB;YAC/CC,gBAAgB;gBACdd,UAAU;gBACVR,QAAQ;gBACRS,OAAO;gBACPc,YAAYzB,aAAaI,EAAE;YAC7B;YACA,GAAIa,WAAWS,YAAY,CAAC,IAAI;gBAACT;YAAM,CAAC;YACxCU,gBAAgBxB;QAClB;IACF,EAAE,OAAOyB,OAAO;QACd,MAAMC,UAAU,MAAMlC,oBAAoBY;QAC1C,MAAMsB,QAAQC,eAAe,CAAC9B,cAAcJ,SAASgC;QACrD,IAAI/B,yBAAyB+B,QAAQ;YACnCG,WAAW,WAAWhC,OAAOM,aAAa;YAC1C,MAAMwB,QAAQG,UAAU,CAAC;YACzB,OAAO;gBAACC,SAAS;YAAS;QAC5B;QACA,gFAAgF;QAChF,4DAA4D;QAC5D,MAAMJ,QAAQK,MAAM,CAAC;QACrB,MAAMN;IACR;IAEA,MAAMO,UAAU,MAAMxC,oBAAoBY;IAC1C,MAAM4B,QAAQC,SAAS,CAACpC,cAAckB;IACtCa,WAAW,SAAShC,OAAOM,aAAa;IACxC,MAAM8B,QAAQE,MAAM,CAAC;IACrB,OAAO;QAACJ,SAAS;QAASf;IAAG;AAC/B;AAEA,SAASa,WAAWE,OAA4B,EAAE5B,aAAmB;IACnEf,eAAegD,GAAG,CAAC,GAAG;QAACL;IAAO;IAC9B1C,YAAYgD,MAAM,CAACC,KAAKC,GAAG,CAAC,GAAGC,KAAKC,GAAG,KAAKtC,cAAcuC,OAAO;AACnE"}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type WorkflowsModuleClient } from './workflows-client.js';
|
|
2
2
|
export interface FireManualSubscriptionParams {
|
|
3
|
+
workflows: WorkflowsModuleClient;
|
|
3
4
|
subscriptionId: string;
|
|
4
5
|
callerWorkspaceId: string;
|
|
5
6
|
userId: string;
|
|
6
7
|
inputs?: Record<string, unknown> | undefined;
|
|
7
8
|
}
|
|
8
|
-
export declare function fireManualSubscription(params: FireManualSubscriptionParams): Promise<
|
|
9
|
+
export declare function fireManualSubscription(params: FireManualSubscriptionParams): Promise<{
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
}>;
|
|
9
13
|
//# sourceMappingURL=fire-manual.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fire-manual.d.ts","sourceRoot":"","sources":["../../src/core/fire-manual.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fire-manual.d.ts","sourceRoot":"","sources":["../../src/core/fire-manual.ts"],"names":[],"mappings":"AAcA,OAAO,EAA2B,KAAK,qBAAqB,EAAC,MAAM,uBAAuB,CAAC;AAE3F,MAAM,WAAW,4BAA4B;IAC3C,SAAS,EAAE,qBAAqB,CAAC;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;CAC9C;AAED,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,4BAA4B,GACnC,OAAO,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,CAAC,CAoErC"}
|
package/dist/core/fire-manual.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import { isPermanentRunWorkflowError, runWorkflow } from '@shipfox/api-workflows';
|
|
3
2
|
import { getTriggerSubscriptionById } from '#db/subscriptions.js';
|
|
4
3
|
import { eventOutcomeCount, eventReceivedCount, subscriptionTriggeredCount } from '#metrics/instance.js';
|
|
5
4
|
import { readConfigInputs } from './config.js';
|
|
6
5
|
import { TriggerSubscriptionNotFoundError, TriggerSubscriptionNotManualError, TriggerWorkspaceMismatchError } from './errors.js';
|
|
7
6
|
import { beginTriggerHistory, toReason } from './record-trigger-history.js';
|
|
7
|
+
import { isPermanentStartRunError } from './workflows-client.js';
|
|
8
8
|
export async function fireManualSubscription(params) {
|
|
9
9
|
const subscription = await getTriggerSubscriptionById(params.subscriptionId);
|
|
10
10
|
if (!subscription) throw new TriggerSubscriptionNotFoundError(params.subscriptionId);
|
|
@@ -32,9 +32,10 @@ export async function fireManualSubscription(params) {
|
|
|
32
32
|
eventReceivedCount.add(1, {
|
|
33
33
|
provider: 'manual'
|
|
34
34
|
});
|
|
35
|
+
const inputs = params.inputs ?? readConfigInputs(subscription);
|
|
35
36
|
let run;
|
|
36
37
|
try {
|
|
37
|
-
run = await
|
|
38
|
+
run = await params.workflows.startRunFromTrigger({
|
|
38
39
|
workspaceId: subscription.workspaceId,
|
|
39
40
|
projectId: subscription.projectId,
|
|
40
41
|
definitionId: subscription.workflowDefinitionId,
|
|
@@ -45,7 +46,10 @@ export async function fireManualSubscription(params) {
|
|
|
45
46
|
subscriptionId: subscription.id,
|
|
46
47
|
userId: params.userId
|
|
47
48
|
},
|
|
48
|
-
inputs
|
|
49
|
+
...inputs === undefined ? {} : {
|
|
50
|
+
inputs
|
|
51
|
+
},
|
|
52
|
+
idempotencyKey: randomUUID()
|
|
49
53
|
});
|
|
50
54
|
} catch (error) {
|
|
51
55
|
const failure = await beginTriggerHistory({
|
|
@@ -53,7 +57,7 @@ export async function fireManualSubscription(params) {
|
|
|
53
57
|
eventRef: randomUUID()
|
|
54
58
|
});
|
|
55
59
|
await failure.dispatchErrored(subscription, toReason(error));
|
|
56
|
-
if (
|
|
60
|
+
if (isPermanentStartRunError(error)) {
|
|
57
61
|
eventOutcomeCount.add(1, {
|
|
58
62
|
provider: 'manual',
|
|
59
63
|
outcome: 'errored'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/fire-manual.ts"],"sourcesContent":["import {randomUUID} from 'node:crypto';\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/core/fire-manual.ts"],"sourcesContent":["import {randomUUID} from 'node:crypto';\nimport {getTriggerSubscriptionById} from '#db/subscriptions.js';\nimport {\n eventOutcomeCount,\n eventReceivedCount,\n subscriptionTriggeredCount,\n} from '#metrics/instance.js';\nimport {readConfigInputs} from './config.js';\nimport {\n TriggerSubscriptionNotFoundError,\n TriggerSubscriptionNotManualError,\n TriggerWorkspaceMismatchError,\n} from './errors.js';\nimport {beginTriggerHistory, toReason} from './record-trigger-history.js';\nimport {isPermanentStartRunError, type WorkflowsModuleClient} from './workflows-client.js';\n\nexport interface FireManualSubscriptionParams {\n workflows: WorkflowsModuleClient;\n subscriptionId: string;\n callerWorkspaceId: string;\n userId: string;\n inputs?: Record<string, unknown> | undefined;\n}\n\nexport async function fireManualSubscription(\n params: FireManualSubscriptionParams,\n): Promise<{id: string; name: string}> {\n const subscription = await getTriggerSubscriptionById(params.subscriptionId);\n if (!subscription) throw new TriggerSubscriptionNotFoundError(params.subscriptionId);\n if (subscription.source !== 'manual') {\n throw new TriggerSubscriptionNotManualError(params.subscriptionId, subscription.source);\n }\n // Defence in depth: unreachable from the HTTP route, but required for any direct caller.\n if (subscription.workspaceId !== params.callerWorkspaceId) {\n throw new TriggerWorkspaceMismatchError(\n params.subscriptionId,\n subscription.workspaceId,\n params.callerWorkspaceId,\n );\n }\n\n // Manual fires have no upstream event id. Use the run id after success; failed\n // attempts need a synthesized ref because there is no run to key on.\n const historyBase = {\n origin: 'manual' as const,\n workspaceId: subscription.workspaceId,\n provider: null,\n source: subscription.source,\n event: subscription.event,\n deliveryId: null,\n connectionId: null,\n connectionName: null,\n payload: null,\n receivedAt: new Date(),\n };\n\n eventReceivedCount.add(1, {provider: 'manual'});\n\n const inputs = params.inputs ?? readConfigInputs(subscription);\n let run: {id: string; name: string};\n try {\n run = await params.workflows.startRunFromTrigger({\n workspaceId: subscription.workspaceId,\n projectId: subscription.projectId,\n definitionId: subscription.workflowDefinitionId,\n triggerPayload: {\n provider: 'manual',\n source: 'manual',\n event: 'fire',\n subscriptionId: subscription.id,\n userId: params.userId,\n },\n ...(inputs === undefined ? {} : {inputs}),\n idempotencyKey: randomUUID(),\n });\n } catch (error) {\n const failure = await beginTriggerHistory({...historyBase, eventRef: randomUUID()});\n await failure.dispatchErrored(subscription, toReason(error));\n if (isPermanentStartRunError(error)) {\n eventOutcomeCount.add(1, {provider: 'manual', outcome: 'errored'});\n await failure.allErrored(1);\n } else {\n eventOutcomeCount.add(1, {provider: 'manual', outcome: 'failed'});\n await failure.failed(1);\n }\n throw error;\n }\n\n const history = await beginTriggerHistory({...historyBase, eventRef: run.id});\n await history.triggered(subscription, run);\n subscriptionTriggeredCount.add(1, {provider: 'manual'});\n eventOutcomeCount.add(1, {provider: 'manual', outcome: 'routed'});\n await history.routed(1);\n return run;\n}\n"],"names":["randomUUID","getTriggerSubscriptionById","eventOutcomeCount","eventReceivedCount","subscriptionTriggeredCount","readConfigInputs","TriggerSubscriptionNotFoundError","TriggerSubscriptionNotManualError","TriggerWorkspaceMismatchError","beginTriggerHistory","toReason","isPermanentStartRunError","fireManualSubscription","params","subscription","subscriptionId","source","workspaceId","callerWorkspaceId","historyBase","origin","provider","event","deliveryId","connectionId","connectionName","payload","receivedAt","Date","add","inputs","run","workflows","startRunFromTrigger","projectId","definitionId","workflowDefinitionId","triggerPayload","id","userId","undefined","idempotencyKey","error","failure","eventRef","dispatchErrored","outcome","allErrored","failed","history","triggered","routed"],"mappings":"AAAA,SAAQA,UAAU,QAAO,cAAc;AACvC,SAAQC,0BAA0B,QAAO,uBAAuB;AAChE,SACEC,iBAAiB,EACjBC,kBAAkB,EAClBC,0BAA0B,QACrB,uBAAuB;AAC9B,SAAQC,gBAAgB,QAAO,cAAc;AAC7C,SACEC,gCAAgC,EAChCC,iCAAiC,EACjCC,6BAA6B,QACxB,cAAc;AACrB,SAAQC,mBAAmB,EAAEC,QAAQ,QAAO,8BAA8B;AAC1E,SAAQC,wBAAwB,QAAmC,wBAAwB;AAU3F,OAAO,eAAeC,uBACpBC,MAAoC;IAEpC,MAAMC,eAAe,MAAMb,2BAA2BY,OAAOE,cAAc;IAC3E,IAAI,CAACD,cAAc,MAAM,IAAIR,iCAAiCO,OAAOE,cAAc;IACnF,IAAID,aAAaE,MAAM,KAAK,UAAU;QACpC,MAAM,IAAIT,kCAAkCM,OAAOE,cAAc,EAAED,aAAaE,MAAM;IACxF;IACA,yFAAyF;IACzF,IAAIF,aAAaG,WAAW,KAAKJ,OAAOK,iBAAiB,EAAE;QACzD,MAAM,IAAIV,8BACRK,OAAOE,cAAc,EACrBD,aAAaG,WAAW,EACxBJ,OAAOK,iBAAiB;IAE5B;IAEA,+EAA+E;IAC/E,qEAAqE;IACrE,MAAMC,cAAc;QAClBC,QAAQ;QACRH,aAAaH,aAAaG,WAAW;QACrCI,UAAU;QACVL,QAAQF,aAAaE,MAAM;QAC3BM,OAAOR,aAAaQ,KAAK;QACzBC,YAAY;QACZC,cAAc;QACdC,gBAAgB;QAChBC,SAAS;QACTC,YAAY,IAAIC;IAClB;IAEAzB,mBAAmB0B,GAAG,CAAC,GAAG;QAACR,UAAU;IAAQ;IAE7C,MAAMS,SAASjB,OAAOiB,MAAM,IAAIzB,iBAAiBS;IACjD,IAAIiB;IACJ,IAAI;QACFA,MAAM,MAAMlB,OAAOmB,SAAS,CAACC,mBAAmB,CAAC;YAC/ChB,aAAaH,aAAaG,WAAW;YACrCiB,WAAWpB,aAAaoB,SAAS;YACjCC,cAAcrB,aAAasB,oBAAoB;YAC/CC,gBAAgB;gBACdhB,UAAU;gBACVL,QAAQ;gBACRM,OAAO;gBACPP,gBAAgBD,aAAawB,EAAE;gBAC/BC,QAAQ1B,OAAO0B,MAAM;YACvB;YACA,GAAIT,WAAWU,YAAY,CAAC,IAAI;gBAACV;YAAM,CAAC;YACxCW,gBAAgBzC;QAClB;IACF,EAAE,OAAO0C,OAAO;QACd,MAAMC,UAAU,MAAMlC,oBAAoB;YAAC,GAAGU,WAAW;YAAEyB,UAAU5C;QAAY;QACjF,MAAM2C,QAAQE,eAAe,CAAC/B,cAAcJ,SAASgC;QACrD,IAAI/B,yBAAyB+B,QAAQ;YACnCxC,kBAAkB2B,GAAG,CAAC,GAAG;gBAACR,UAAU;gBAAUyB,SAAS;YAAS;YAChE,MAAMH,QAAQI,UAAU,CAAC;QAC3B,OAAO;YACL7C,kBAAkB2B,GAAG,CAAC,GAAG;gBAACR,UAAU;gBAAUyB,SAAS;YAAQ;YAC/D,MAAMH,QAAQK,MAAM,CAAC;QACvB;QACA,MAAMN;IACR;IAEA,MAAMO,UAAU,MAAMxC,oBAAoB;QAAC,GAAGU,WAAW;QAAEyB,UAAUb,IAAIO,EAAE;IAAA;IAC3E,MAAMW,QAAQC,SAAS,CAACpC,cAAciB;IACtC3B,2BAA2ByB,GAAG,CAAC,GAAG;QAACR,UAAU;IAAQ;IACrDnB,kBAAkB2B,GAAG,CAAC,GAAG;QAACR,UAAU;QAAUyB,SAAS;IAAQ;IAC/D,MAAMG,QAAQE,MAAM,CAAC;IACrB,OAAOpB;AACT"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { type TriggerHistoryRecorder } from './record-trigger-history.js';
|
|
2
|
+
import type { WorkflowsModuleClient } from './workflows-client.js';
|
|
2
3
|
export interface RouteEventToJobListenersParams {
|
|
4
|
+
workflows: WorkflowsModuleClient;
|
|
3
5
|
history: TriggerHistoryRecorder;
|
|
4
6
|
eventRef: string;
|
|
5
7
|
workspaceId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-event-to-job-listeners.d.ts","sourceRoot":"","sources":["../../src/core/route-event-to-job-listeners.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"route-event-to-job-listeners.d.ts","sourceRoot":"","sources":["../../src/core/route-event-to-job-listeners.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,KAAK,sBAAsB,EAAW,MAAM,6BAA6B,CAAC;AAClF,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,uBAAuB,CAAC;AAEjE,MAAM,WAAW,8BAA8B;IAC7C,SAAS,EAAE,qBAAqB,CAAC;IACjC,OAAO,EAAE,sBAAsB,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,8BAA8B;IAC7C;;;;OAIG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,8BAA8B,GACrC,OAAO,CAAC,8BAA8B,CAAC,CAmEzC"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { deliverEventToListener } from '@shipfox/api-workflows';
|
|
2
1
|
import { logger } from '@shipfox/node-opentelemetry';
|
|
3
2
|
import { findMatchingJobListenerSubscriptions } from '#db/job-listener-subscriptions.js';
|
|
4
3
|
import { evaluateStoredFilter } from './config.js';
|
|
@@ -35,7 +34,7 @@ export async function routeEventToJobListeners(params) {
|
|
|
35
34
|
for (const subscription of effectiveMatchByJobId.values()){
|
|
36
35
|
const disposition = listenerDisposition(subscription);
|
|
37
36
|
try {
|
|
38
|
-
const result = await
|
|
37
|
+
const result = await params.workflows.deliverEventToJobListener({
|
|
39
38
|
jobId: subscription.jobId,
|
|
40
39
|
disposition,
|
|
41
40
|
eventRef: params.eventRef,
|
|
@@ -44,7 +43,7 @@ export async function routeEventToJobListeners(params) {
|
|
|
44
43
|
event: params.event,
|
|
45
44
|
provider: params.provider,
|
|
46
45
|
payload: params.payload,
|
|
47
|
-
receivedAt: params.receivedAt
|
|
46
|
+
receivedAt: params.receivedAt.toISOString()
|
|
48
47
|
});
|
|
49
48
|
if (!result.skipped) {
|
|
50
49
|
acceptedJobCount += 1;
|