@adonis-agora/durable 0.49.1 → 0.50.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/CHANGELOG.md +251 -0
- package/README.md +53 -22
- package/dist/assets/spa/assets/index-DupjrK7N.js +16 -0
- package/dist/assets/spa/assets/index-DupjrK7N.js.map +1 -0
- package/dist/assets/spa/index.html +1 -1
- package/dist/commands/durable_worker.d.ts.map +1 -1
- package/dist/commands/durable_worker.js +9 -8
- package/dist/commands/durable_worker.js.map +1 -1
- package/dist/configure.d.ts.map +1 -1
- package/dist/configure.js +1 -0
- package/dist/configure.js.map +1 -1
- package/dist/providers/dashboard_provider.d.ts +2 -0
- package/dist/providers/dashboard_provider.d.ts.map +1 -1
- package/dist/providers/dashboard_provider.js +50 -6
- package/dist/providers/dashboard_provider.js.map +1 -1
- package/dist/providers/durable_provider.d.ts.map +1 -1
- package/dist/providers/durable_provider.js +143 -34
- package/dist/providers/durable_provider.js.map +1 -1
- package/dist/src/admission-redis/redis-admission-backend.d.ts.map +1 -1
- package/dist/src/admission-redis/redis-admission-backend.js +3 -1
- package/dist/src/admission-redis/redis-admission-backend.js.map +1 -1
- package/dist/src/ambient-step.d.ts +24 -0
- package/dist/src/ambient-step.d.ts.map +1 -0
- package/dist/src/ambient-step.js +42 -0
- package/dist/src/ambient-step.js.map +1 -0
- package/dist/src/base-workflow.d.ts +10 -1
- package/dist/src/base-workflow.d.ts.map +1 -1
- package/dist/src/base-workflow.js.map +1 -1
- package/dist/src/codec-state-store.d.ts +28 -2
- package/dist/src/codec-state-store.d.ts.map +1 -1
- package/dist/src/codec-state-store.js +61 -3
- package/dist/src/codec-state-store.js.map +1 -1
- package/dist/src/commands/worker.d.ts +4 -1
- package/dist/src/commands/worker.d.ts.map +1 -1
- package/dist/src/commands/worker.js +27 -3
- package/dist/src/commands/worker.js.map +1 -1
- package/dist/src/config_types.d.ts +6 -0
- package/dist/src/config_types.d.ts.map +1 -1
- package/dist/src/control-plane-redis/redis-control-plane.d.ts.map +1 -1
- package/dist/src/control-plane-redis/redis-control-plane.js +22 -6
- package/dist/src/control-plane-redis/redis-control-plane.js.map +1 -1
- package/dist/src/control-planes/factory.d.ts +6 -0
- package/dist/src/control-planes/factory.d.ts.map +1 -1
- package/dist/src/control-planes/factory.js +1 -0
- package/dist/src/control-planes/factory.js.map +1 -1
- package/dist/src/dashboard/gateway-adapter.d.ts +15 -5
- package/dist/src/dashboard/gateway-adapter.d.ts.map +1 -1
- package/dist/src/dashboard/gateway-adapter.js +71 -7
- package/dist/src/dashboard/gateway-adapter.js.map +1 -1
- package/dist/src/dashboard/handlers.d.ts +53 -1
- package/dist/src/dashboard/handlers.d.ts.map +1 -1
- package/dist/src/dashboard/handlers.js +200 -20
- package/dist/src/dashboard/handlers.js.map +1 -1
- package/dist/src/dashboard/index.d.ts +2 -2
- package/dist/src/dashboard/index.d.ts.map +1 -1
- package/dist/src/dashboard/index.js +2 -2
- package/dist/src/dashboard/index.js.map +1 -1
- package/dist/src/dashboard/openapi.d.ts.map +1 -1
- package/dist/src/dashboard/openapi.js +71 -1
- package/dist/src/dashboard/openapi.js.map +1 -1
- package/dist/src/define_config.d.ts +122 -8
- package/dist/src/define_config.d.ts.map +1 -1
- package/dist/src/define_config.js.map +1 -1
- package/dist/src/diagnostics-bridge.d.ts +16 -3
- package/dist/src/diagnostics-bridge.d.ts.map +1 -1
- package/dist/src/diagnostics-bridge.js +9 -3
- package/dist/src/diagnostics-bridge.js.map +1 -1
- package/dist/src/discovery-roots.d.ts +92 -0
- package/dist/src/discovery-roots.d.ts.map +1 -0
- package/dist/src/discovery-roots.js +150 -0
- package/dist/src/discovery-roots.js.map +1 -0
- package/dist/src/engine.d.ts +418 -20
- package/dist/src/engine.d.ts.map +1 -1
- package/dist/src/engine.js +1523 -159
- package/dist/src/engine.js.map +1 -1
- package/dist/src/entities.d.ts +36 -1
- package/dist/src/entities.d.ts.map +1 -1
- package/dist/src/entities.js +65 -4
- package/dist/src/entities.js.map +1 -1
- package/dist/src/errors.d.ts +36 -0
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/errors.js +44 -0
- package/dist/src/errors.js.map +1 -1
- package/dist/src/event-trigger-bridge.d.ts +8 -0
- package/dist/src/event-trigger-bridge.d.ts.map +1 -1
- package/dist/src/event-trigger-bridge.js +24 -3
- package/dist/src/event-trigger-bridge.js.map +1 -1
- package/dist/src/handshake/announced.d.ts +27 -0
- package/dist/src/handshake/announced.d.ts.map +1 -1
- package/dist/src/handshake/announced.js +62 -0
- package/dist/src/handshake/announced.js.map +1 -1
- package/dist/src/handshake/directory.d.ts +92 -0
- package/dist/src/handshake/directory.d.ts.map +1 -0
- package/dist/src/handshake/directory.js +139 -0
- package/dist/src/handshake/directory.js.map +1 -0
- package/dist/src/hooks/barrel-sources.d.ts +28 -0
- package/dist/src/hooks/barrel-sources.d.ts.map +1 -0
- package/dist/src/hooks/barrel-sources.js +92 -0
- package/dist/src/hooks/barrel-sources.js.map +1 -0
- package/dist/src/hooks/steps.d.ts +12 -3
- package/dist/src/hooks/steps.d.ts.map +1 -1
- package/dist/src/hooks/steps.js +7 -11
- package/dist/src/hooks/steps.js.map +1 -1
- package/dist/src/hooks/workflows.d.ts +12 -3
- package/dist/src/hooks/workflows.d.ts.map +1 -1
- package/dist/src/hooks/workflows.js +7 -13
- package/dist/src/hooks/workflows.js.map +1 -1
- package/dist/src/index.d.ts +12 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +12 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/interfaces.d.ts +309 -21
- package/dist/src/interfaces.d.ts.map +1 -1
- package/dist/src/interfaces.js +10 -0
- package/dist/src/interfaces.js.map +1 -1
- package/dist/src/metrics.d.ts.map +1 -1
- package/dist/src/metrics.js +5 -0
- package/dist/src/metrics.js.map +1 -1
- package/dist/src/namespaces.d.ts +17 -0
- package/dist/src/namespaces.d.ts.map +1 -0
- package/dist/src/namespaces.js +24 -0
- package/dist/src/namespaces.js.map +1 -0
- package/dist/src/otel/durable-metrics.d.ts.map +1 -1
- package/dist/src/otel/durable-metrics.js +5 -0
- package/dist/src/otel/durable-metrics.js.map +1 -1
- package/dist/src/otel/durable-otel.d.ts.map +1 -1
- package/dist/src/otel/durable-otel.js +5 -0
- package/dist/src/otel/durable-otel.js.map +1 -1
- package/dist/src/pollers.d.ts +10 -1
- package/dist/src/pollers.d.ts.map +1 -1
- package/dist/src/pollers.js +15 -5
- package/dist/src/pollers.js.map +1 -1
- package/dist/src/protocol.d.ts +12 -0
- package/dist/src/protocol.d.ts.map +1 -1
- package/dist/src/protocol.js +27 -1
- package/dist/src/protocol.js.map +1 -1
- package/dist/src/remote-event.d.ts +6 -0
- package/dist/src/remote-event.d.ts.map +1 -0
- package/dist/src/remote-event.js +19 -0
- package/dist/src/remote-event.js.map +1 -0
- package/dist/src/remote-workflow-executor.d.ts +34 -12
- package/dist/src/remote-workflow-executor.d.ts.map +1 -1
- package/dist/src/remote-workflow-executor.js +42 -40
- package/dist/src/remote-workflow-executor.js.map +1 -1
- package/dist/src/run-detail-summary.d.ts +90 -3
- package/dist/src/run-detail-summary.d.ts.map +1 -1
- package/dist/src/run-detail-summary.js +360 -2
- package/dist/src/run-detail-summary.js.map +1 -1
- package/dist/src/run-facets.d.ts +48 -0
- package/dist/src/run-facets.d.ts.map +1 -0
- package/dist/src/run-facets.js +100 -0
- package/dist/src/run-facets.js.map +1 -0
- package/dist/src/run-gateway/interface.d.ts +27 -1
- package/dist/src/run-gateway/interface.d.ts.map +1 -1
- package/dist/src/run-gateway/proxy-run-gateway.d.ts +32 -4
- package/dist/src/run-gateway/proxy-run-gateway.d.ts.map +1 -1
- package/dist/src/run-gateway/proxy-run-gateway.js +101 -5
- package/dist/src/run-gateway/proxy-run-gateway.js.map +1 -1
- package/dist/src/run-gateway/run-request-responder.d.ts +18 -5
- package/dist/src/run-gateway/run-request-responder.d.ts.map +1 -1
- package/dist/src/run-gateway/run-request-responder.js +155 -32
- package/dist/src/run-gateway/run-request-responder.js.map +1 -1
- package/dist/src/run-gateway/store-run-gateway.d.ts +23 -1
- package/dist/src/run-gateway/store-run-gateway.d.ts.map +1 -1
- package/dist/src/run-gateway/store-run-gateway.js +38 -0
- package/dist/src/run-gateway/store-run-gateway.js.map +1 -1
- package/dist/src/search-attributes-schema.d.ts +44 -0
- package/dist/src/search-attributes-schema.d.ts.map +1 -0
- package/dist/src/search-attributes-schema.js +51 -0
- package/dist/src/search-attributes-schema.js.map +1 -0
- package/dist/src/singleton-admission.d.ts +75 -0
- package/dist/src/singleton-admission.d.ts.map +1 -0
- package/dist/src/singleton-admission.js +156 -0
- package/dist/src/singleton-admission.js.map +1 -0
- package/dist/src/singleton-gate.d.ts +23 -8
- package/dist/src/singleton-gate.d.ts.map +1 -1
- package/dist/src/singleton-gate.js +59 -12
- package/dist/src/singleton-gate.js.map +1 -1
- package/dist/src/standard-schema.d.ts +83 -0
- package/dist/src/standard-schema.d.ts.map +1 -0
- package/dist/src/standard-schema.js +31 -0
- package/dist/src/standard-schema.js.map +1 -0
- package/dist/src/step-discovery.d.ts +21 -11
- package/dist/src/step-discovery.d.ts.map +1 -1
- package/dist/src/step-discovery.js +86 -45
- package/dist/src/step-discovery.js.map +1 -1
- package/dist/src/step-ref.d.ts +38 -12
- package/dist/src/step-ref.d.ts.map +1 -1
- package/dist/src/step-ref.js +5 -13
- package/dist/src/step-ref.js.map +1 -1
- package/dist/src/stores/factory.d.ts +6 -0
- package/dist/src/stores/factory.d.ts.map +1 -1
- package/dist/src/stores/factory.js +4 -1
- package/dist/src/stores/factory.js.map +1 -1
- package/dist/src/stores/lucid-helpers.d.ts +2 -0
- package/dist/src/stores/lucid-helpers.d.ts.map +1 -1
- package/dist/src/stores/lucid-helpers.js +7 -0
- package/dist/src/stores/lucid-helpers.js.map +1 -1
- package/dist/src/stores/lucid-mappers.d.ts +25 -0
- package/dist/src/stores/lucid-mappers.d.ts.map +1 -1
- package/dist/src/stores/lucid-mappers.js +81 -18
- package/dist/src/stores/lucid-mappers.js.map +1 -1
- package/dist/src/stores/lucid-schema.d.ts +59 -1
- package/dist/src/stores/lucid-schema.d.ts.map +1 -1
- package/dist/src/stores/lucid-schema.js +271 -25
- package/dist/src/stores/lucid-schema.js.map +1 -1
- package/dist/src/stores/lucid.d.ts +61 -2
- package/dist/src/stores/lucid.d.ts.map +1 -1
- package/dist/src/stores/lucid.js +346 -41
- package/dist/src/stores/lucid.js.map +1 -1
- package/dist/src/telescope/dashboard.d.ts.map +1 -1
- package/dist/src/telescope/dashboard.js +30 -1
- package/dist/src/telescope/dashboard.js.map +1 -1
- package/dist/src/telescope/data-providers.d.ts +19 -1
- package/dist/src/telescope/data-providers.d.ts.map +1 -1
- package/dist/src/telescope/data-providers.js +119 -3
- package/dist/src/telescope/data-providers.js.map +1 -1
- package/dist/src/telescope/extension.d.ts.map +1 -1
- package/dist/src/telescope/extension.js +2 -1
- package/dist/src/telescope/extension.js.map +1 -1
- package/dist/src/telescope/index.d.ts +1 -1
- package/dist/src/telescope/index.d.ts.map +1 -1
- package/dist/src/telescope/index.js +1 -1
- package/dist/src/telescope/index.js.map +1 -1
- package/dist/src/testing/in-memory-state-store.d.ts +44 -15
- package/dist/src/testing/in-memory-state-store.d.ts.map +1 -1
- package/dist/src/testing/in-memory-state-store.js +204 -41
- package/dist/src/testing/in-memory-state-store.js.map +1 -1
- package/dist/src/testing-kit/checkpoint-aggregation-contract.d.ts +16 -0
- package/dist/src/testing-kit/checkpoint-aggregation-contract.d.ts.map +1 -0
- package/dist/src/testing-kit/checkpoint-aggregation-contract.js +228 -0
- package/dist/src/testing-kit/checkpoint-aggregation-contract.js.map +1 -0
- package/dist/src/testing-kit/state-store-conformance.d.ts.map +1 -1
- package/dist/src/testing-kit/state-store-conformance.js +355 -3
- package/dist/src/testing-kit/state-store-conformance.js.map +1 -1
- package/dist/src/transport-pool.d.ts +15 -1
- package/dist/src/transport-pool.d.ts.map +1 -1
- package/dist/src/transport-pool.js +50 -4
- package/dist/src/transport-pool.js.map +1 -1
- package/dist/src/transports/adaptive-concurrency.d.ts +168 -0
- package/dist/src/transports/adaptive-concurrency.d.ts.map +1 -0
- package/dist/src/transports/adaptive-concurrency.js +353 -0
- package/dist/src/transports/adaptive-concurrency.js.map +1 -0
- package/dist/src/transports/bullmq/adaptive-concurrency.d.ts +1 -165
- package/dist/src/transports/bullmq/adaptive-concurrency.d.ts.map +1 -1
- package/dist/src/transports/bullmq/adaptive-concurrency.js +3 -351
- package/dist/src/transports/bullmq/adaptive-concurrency.js.map +1 -1
- package/dist/src/transports/bullmq/bullmq-transport.d.ts +49 -1
- package/dist/src/transports/bullmq/bullmq-transport.d.ts.map +1 -1
- package/dist/src/transports/bullmq/bullmq-transport.js +330 -38
- package/dist/src/transports/bullmq/bullmq-transport.js.map +1 -1
- package/dist/src/transports/bullmq/deps.d.ts +18 -2
- package/dist/src/transports/bullmq/deps.d.ts.map +1 -1
- package/dist/src/transports/bullmq/deps.js +44 -2
- package/dist/src/transports/bullmq/deps.js.map +1 -1
- package/dist/src/transports/db-helpers.d.ts +39 -0
- package/dist/src/transports/db-helpers.d.ts.map +1 -1
- package/dist/src/transports/db-helpers.js +73 -0
- package/dist/src/transports/db-helpers.js.map +1 -1
- package/dist/src/transports/db-remote.d.ts +53 -0
- package/dist/src/transports/db-remote.d.ts.map +1 -0
- package/dist/src/transports/db-remote.js +147 -0
- package/dist/src/transports/db-remote.js.map +1 -0
- package/dist/src/transports/db-schema.d.ts +44 -1
- package/dist/src/transports/db-schema.d.ts.map +1 -1
- package/dist/src/transports/db-schema.js +227 -88
- package/dist/src/transports/db-schema.js.map +1 -1
- package/dist/src/transports/db.d.ts +189 -6
- package/dist/src/transports/db.d.ts.map +1 -1
- package/dist/src/transports/db.js +1291 -137
- package/dist/src/transports/db.js.map +1 -1
- package/dist/src/transports/event-emitter.d.ts +8 -0
- package/dist/src/transports/event-emitter.d.ts.map +1 -1
- package/dist/src/transports/event-emitter.js +36 -3
- package/dist/src/transports/event-emitter.js.map +1 -1
- package/dist/src/transports/factory.d.ts +110 -5
- package/dist/src/transports/factory.d.ts.map +1 -1
- package/dist/src/transports/factory.js +56 -9
- package/dist/src/transports/factory.js.map +1 -1
- package/dist/src/transports/queue-mock-adapter.d.ts +7 -2
- package/dist/src/transports/queue-mock-adapter.d.ts.map +1 -1
- package/dist/src/transports/queue-mock-adapter.js +18 -2
- package/dist/src/transports/queue-mock-adapter.js.map +1 -1
- package/dist/src/transports/queue-remote.d.ts +146 -0
- package/dist/src/transports/queue-remote.d.ts.map +1 -0
- package/dist/src/transports/queue-remote.js +398 -0
- package/dist/src/transports/queue-remote.js.map +1 -0
- package/dist/src/transports/queue.d.ts +159 -6
- package/dist/src/transports/queue.d.ts.map +1 -1
- package/dist/src/transports/queue.js +747 -37
- package/dist/src/transports/queue.js.map +1 -1
- package/dist/src/transports/task-failure.d.ts +31 -0
- package/dist/src/transports/task-failure.d.ts.map +1 -0
- package/dist/src/transports/task-failure.js +50 -0
- package/dist/src/transports/task-failure.js.map +1 -0
- package/dist/src/workflow-als.d.ts +1 -1
- package/dist/src/workflow-als.d.ts.map +1 -1
- package/dist/src/workflow-ctx.d.ts +10 -0
- package/dist/src/workflow-ctx.d.ts.map +1 -1
- package/dist/src/workflow-ctx.js +97 -15
- package/dist/src/workflow-ctx.js.map +1 -1
- package/dist/src/workflow-discovery.d.ts +32 -41
- package/dist/src/workflow-discovery.d.ts.map +1 -1
- package/dist/src/workflow-discovery.js +65 -88
- package/dist/src/workflow-discovery.js.map +1 -1
- package/dist/src/workflow-ref.d.ts +24 -0
- package/dist/src/workflow-ref.d.ts.map +1 -1
- package/dist/src/workflow-ref.js.map +1 -1
- package/dist/stubs/config/durable.stub +6 -0
- package/dist/stubs/config/durable_dashboard.stub +7 -3
- package/dist/stubs/database/migrations/create_durable_tables.stub +2 -1
- package/dist/stubs/database/migrations/create_durable_transport_messages.stub +43 -0
- package/dist/stubs/database/migrations/create_durable_transport_tables.stub +12 -9
- package/dist/stubs/database/migrations/create_durable_transport_worker_keys.stub +1 -1
- package/dist/stubs/make/workflow/main.stub +1 -1
- package/package.json +6 -4
- package/skills/durable-cluster/SKILL.md +80 -11
- package/skills/durable-determinism/SKILL.md +11 -5
- package/skills/durable-reliability/SKILL.md +77 -37
- package/skills/durable-setup/SKILL.md +51 -22
- package/skills/durable-transports-stores/SKILL.md +128 -18
- package/skills/durable-workflows/SKILL.md +71 -18
- package/dist/assets/spa/assets/index-DdB9zxuX.js +0 -16
- package/dist/assets/spa/assets/index-DdB9zxuX.js.map +0 -1
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { DURABLE_RUN_GATEWAY } from '../role_bindings.js';
|
|
2
|
+
import { UNSUPPORTED_RUN_REQUEST } from '../run-gateway/run-request-responder.js';
|
|
3
|
+
import { scanRunValueFacets } from '../run-value-facets.js';
|
|
2
4
|
/**
|
|
3
5
|
* Adapt a store-backed {@link import('../engine.js').WorkflowEngine} to the {@link DashboardEngine}
|
|
4
6
|
* port — an explicit wrapper (not a raw `as DashboardEngine` cast) because two verbs need shape
|
|
@@ -17,6 +19,16 @@ export function storeDashboardEngine(engine) {
|
|
|
17
19
|
listRuns: (query) => engine.listRuns(query),
|
|
18
20
|
listCheckpoints: (runId) => engine.listCheckpoints(runId),
|
|
19
21
|
getRunChildren: (runId) => engine.getRunChildren(runId),
|
|
22
|
+
...(engine.getRunDetail
|
|
23
|
+
? {
|
|
24
|
+
getRunDetail: (runId, options) => engine.getRunDetail(runId, options),
|
|
25
|
+
}
|
|
26
|
+
: {}),
|
|
27
|
+
...(engine.getFanMembers
|
|
28
|
+
? {
|
|
29
|
+
getFanMembers: (runId, group, query) => engine.getFanMembers(runId, group, query),
|
|
30
|
+
}
|
|
31
|
+
: {}),
|
|
20
32
|
requeue: (runId) => engine.requeue(runId),
|
|
21
33
|
redispatchPending: (runId) => engine.redispatchPending?.(runId) ?? Promise.resolve(null),
|
|
22
34
|
cancel: (runId, opts) => engine.cancel(runId, opts),
|
|
@@ -34,6 +46,16 @@ export function storeDashboardEngine(engine) {
|
|
|
34
46
|
if (event.runId === runId)
|
|
35
47
|
onEvent(event);
|
|
36
48
|
}),
|
|
49
|
+
...(engine.countRuns
|
|
50
|
+
? {
|
|
51
|
+
countRuns: (query) => engine.countRuns(query),
|
|
52
|
+
}
|
|
53
|
+
: {}),
|
|
54
|
+
...(engine.getEvent
|
|
55
|
+
? {
|
|
56
|
+
getEvent: (runId, key) => engine.getEvent(runId, key),
|
|
57
|
+
}
|
|
58
|
+
: {}),
|
|
37
59
|
...(engine.listSignalWaiters
|
|
38
60
|
? {
|
|
39
61
|
listSignalWaiters: (prefix) => engine.listSignalWaiters?.(prefix),
|
|
@@ -68,10 +90,13 @@ export function storeDashboardEngine(engine) {
|
|
|
68
90
|
* `RunRequestKind` verb), so a store-less tenant pod's run detail view lists children round-tripped over
|
|
69
91
|
* the wire — the responder enforces the tenant-ownership check before answering (anti-IDOR).
|
|
70
92
|
*
|
|
71
|
-
* `
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
93
|
+
* `retry`, `continue`, `retryWithInput`, `runValueFacets` and `waitingFor` ride the wire too (aviary's
|
|
94
|
+
* verbs), so a tenant pod's console retries in place, continues a breakpoint, fixes and replays,
|
|
95
|
+
* fills its value pickers and names what a suspended run waits on. Against a control plane that
|
|
96
|
+
* predates them (it answers `unsupported-request` or an unknown-verb error) each degrades the way it
|
|
97
|
+
* did before those verbs existed: `requeue` re-dispatches the run's pending steps, `continue` and
|
|
98
|
+
* `retryWithInput` answer `null` (the handlers 404), the pickers count a bounded `listRuns` scan,
|
|
99
|
+
* and the list rows carry no `waiting` stamp.
|
|
75
100
|
*/
|
|
76
101
|
export function gatewayDashboardEngine(gateway) {
|
|
77
102
|
return {
|
|
@@ -89,15 +114,54 @@ export function gatewayDashboardEngine(gateway) {
|
|
|
89
114
|
getFanMembers: (runId, group, query) => gateway.getFanMembers(runId, group, query),
|
|
90
115
|
}
|
|
91
116
|
: {}),
|
|
92
|
-
requeue: (runId) => gateway.
|
|
117
|
+
requeue: (runId) => gateway.retry
|
|
118
|
+
? orOlder(gateway.retry(runId), () => gateway.redispatchPending(runId))
|
|
119
|
+
: gateway.redispatchPending(runId),
|
|
93
120
|
redispatchPending: (runId) => gateway.redispatchPending(runId),
|
|
94
121
|
cancel: (runId, opts) => gateway.cancel(runId, opts),
|
|
95
122
|
workerHealth: () => gateway.workerHealth(),
|
|
96
|
-
retryWithInput: () =>
|
|
97
|
-
|
|
123
|
+
retryWithInput: (runId, input) => gateway.retryWithInput
|
|
124
|
+
? orOlder(gateway.retryWithInput(runId, input), () => Promise.resolve(null))
|
|
125
|
+
: Promise.resolve(null),
|
|
126
|
+
continue: (runId) => gateway.continue
|
|
127
|
+
? orOlder(gateway.continue(runId), () => Promise.resolve(null))
|
|
128
|
+
: Promise.resolve(null),
|
|
129
|
+
...(gateway.runValueFacets
|
|
130
|
+
? {
|
|
131
|
+
runValueFacets: (axis, query, opts) => orOlder(gateway.runValueFacets(axis, query, opts), () => scanRunValueFacets({ listRuns: (q) => gateway.listRuns(q) }, axis, query, opts)),
|
|
132
|
+
}
|
|
133
|
+
: {}),
|
|
134
|
+
...(gateway.runFacets
|
|
135
|
+
? {
|
|
136
|
+
// The metrics backlog gauges, scoped to the tenant by the control plane.
|
|
137
|
+
countRuns: async ({ status, statuses, ...rest }) => {
|
|
138
|
+
const wanted = new Set(statuses ?? (status ? [status] : []));
|
|
139
|
+
const cells = await gateway.runFacets(rest);
|
|
140
|
+
return cells
|
|
141
|
+
.filter((c) => wanted.size === 0 || wanted.has(c.status))
|
|
142
|
+
.reduce((n, c) => n + c.count, 0);
|
|
143
|
+
},
|
|
144
|
+
}
|
|
145
|
+
: {}),
|
|
146
|
+
...(gateway.waitingFor
|
|
147
|
+
? {
|
|
148
|
+
waitingFor: (runIds) => orOlder(gateway.waitingFor(runIds), () => Promise.resolve({})),
|
|
149
|
+
}
|
|
150
|
+
: {}),
|
|
98
151
|
subscribe: (runId, onEvent) => gateway.subscribe(runId, onEvent),
|
|
99
152
|
};
|
|
100
153
|
}
|
|
154
|
+
/** `work`, or `older()` when the control plane answered that it does not know the verb. */
|
|
155
|
+
async function orOlder(work, older) {
|
|
156
|
+
try {
|
|
157
|
+
return await work;
|
|
158
|
+
}
|
|
159
|
+
catch (err) {
|
|
160
|
+
if (err?.code === UNSUPPORTED_RUN_REQUEST)
|
|
161
|
+
return older();
|
|
162
|
+
throw err;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
101
165
|
/**
|
|
102
166
|
* Resolve the dashboard's read/control port for the active durable `role` (design §5) — the single seam
|
|
103
167
|
* that makes the dashboard store-agnostic:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gateway-adapter.js","sourceRoot":"","sources":["../../../src/dashboard/gateway-adapter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"gateway-adapter.js","sourceRoot":"","sources":["../../../src/dashboard/gateway-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ScheduleInfo } from '../engine.js';
|
|
2
|
-
import type { EngineEvent, GroupHealth, RunFacetQuery, RunQuery, RunResult, RunValueAxis, RunValueFacetOptions, RunValueFacetRow, SignalWaiter, StepCheckpoint, UpdateResult, WorkflowRun } from '../index.js';
|
|
2
|
+
import type { EngineEvent, GroupHealth, RunFacetQuery, RunQuery, RunResult, RunValueAxis, RunValueFacetOptions, RunValueFacetRow, RunWaiting, SignalWaiter, StepCheckpoint, UpdateResult, WorkflowRun } from '../index.js';
|
|
3
3
|
import { type FanPage, type FanPageQuery, type RunDetail, type RunDetailOptions } from '../run-detail-summary.js';
|
|
4
4
|
/**
|
|
5
5
|
* Framework-light JSON handlers over a {@link DashboardEngine}.
|
|
@@ -96,6 +96,18 @@ export interface DashboardEngine {
|
|
|
96
96
|
* full `listSignalWaiters('')` scan above.
|
|
97
97
|
*/
|
|
98
98
|
listSignalWaitersByRunIds?(runIds: string[]): Promise<SignalWaiter[]>;
|
|
99
|
+
/**
|
|
100
|
+
* Already-resolved {@link RunWaiting} for the given runs — what a store-less `tenant` pod's
|
|
101
|
+
* gateway answers instead of raw waiter rows. Used by `listRuns` only when neither waiter scan
|
|
102
|
+
* above is available.
|
|
103
|
+
*/
|
|
104
|
+
waitingFor?(runIds: string[]): Promise<Record<string, RunWaiting>>;
|
|
105
|
+
/** How many runs match `query` — the backlog gauges of `GET /metrics`. Optional: without it the
|
|
106
|
+
* gauges are left out of the scrape. */
|
|
107
|
+
countRuns?(query: Omit<RunQuery, 'page' | 'size'>): Promise<number>;
|
|
108
|
+
/** The latest value a run published for `key` via `ctx.setEvent` (a side-effect-free live query).
|
|
109
|
+
* Optional: absent on a store-less `tenant` pod, where `GET /runs/:id/events/:key` answers 404. */
|
|
110
|
+
getEvent?(runId: string, key: string): Promise<unknown>;
|
|
99
111
|
/**
|
|
100
112
|
* The distinct values of ONE filter axis over the runs matching `query`, with counts — what a
|
|
101
113
|
* console's pickers list. Optional: absent on a port that can't do the scan yet (a store-less
|
|
@@ -107,6 +119,10 @@ export interface DashboardEngine {
|
|
|
107
119
|
/** The read/control port the handlers operate over (a store engine or a tenant gateway adapter). */
|
|
108
120
|
export interface Deps {
|
|
109
121
|
engine: DashboardEngine;
|
|
122
|
+
/** This process's event counters (`collectMetrics`), prepended to `GET /metrics`. */
|
|
123
|
+
metrics?: {
|
|
124
|
+
prometheus(): string;
|
|
125
|
+
} | undefined;
|
|
110
126
|
/** Host redaction hooks over the SERIALIZED run/checkpoint shapes (see the config's `redact`). */
|
|
111
127
|
redact?: {
|
|
112
128
|
run?: (run: Record<string, unknown>) => Record<string, unknown>;
|
|
@@ -122,11 +138,15 @@ export interface ApiRequest {
|
|
|
122
138
|
query: Record<string, unknown>;
|
|
123
139
|
/** Parsed JSON body (for POST actions). */
|
|
124
140
|
body?: unknown;
|
|
141
|
+
/** Request headers, lower-cased names. Read by the run-detail routes for `If-None-Match`. */
|
|
142
|
+
headers?: Record<string, string | undefined>;
|
|
125
143
|
}
|
|
126
144
|
/** A plain JSON response: an HTTP status and a serializable body. */
|
|
127
145
|
export interface ApiResponse {
|
|
128
146
|
status: number;
|
|
129
147
|
body: unknown;
|
|
148
|
+
/** Extra response headers (the run-detail routes' `ETag` / `Cache-Control`). */
|
|
149
|
+
headers?: Record<string, string>;
|
|
130
150
|
}
|
|
131
151
|
/** A `200 OK` JSON response. Exported so sibling handlers (e.g. `compat`) share one convention. */
|
|
132
152
|
export declare const ok: (body: unknown) => ApiResponse;
|
|
@@ -239,4 +259,36 @@ export declare function workers(deps: Deps): Promise<ApiResponse>;
|
|
|
239
259
|
/** `GET /topology` — this deployment's durable role, for the header badge. Pure/local (no engine
|
|
240
260
|
* round-trip): the role is already known by `dashboard_provider.ts` from `config/durable.ts`. */
|
|
241
261
|
export declare function topology(role: 'standalone' | 'control-plane' | 'tenant', tenant?: string): ApiResponse;
|
|
262
|
+
/**
|
|
263
|
+
* `GET /metrics` — Prometheus text exposition: this process's event counters (runs and steps by
|
|
264
|
+
* outcome, per-workflow counts, step durations; see `collectMetrics`) plus gauges read at scrape
|
|
265
|
+
* time: `durable_pending_runs` (the dispatch backlog), `durable_running_runs`, `durable_dead_runs`
|
|
266
|
+
* (the dead-letter queue) and, per worker group, `durable_group_queue_depth` and
|
|
267
|
+
* `durable_group_live_workers` (`depth > 0` with zero live workers is the alert). The counters only
|
|
268
|
+
* count the events this process produced, so summing a scrape of every pod counts each event once.
|
|
269
|
+
* Returns the text body; the route sets the `text/plain; version=0.0.4` content type.
|
|
270
|
+
*/
|
|
271
|
+
export declare function metricsText(deps: Deps): Promise<string>;
|
|
272
|
+
/**
|
|
273
|
+
* `GET /runs/:id/events/:key` — the latest value run `id` published for `key` via `ctx.setEvent`:
|
|
274
|
+
* a side-effect-free query of a live (or finished) run. `{ value }`, with `value` absent when the
|
|
275
|
+
* run never published that key. 404 for an unknown run, and on a topology without the read (a
|
|
276
|
+
* store-less `tenant` pod). The value passes through the `checkpoint` redaction hook as the
|
|
277
|
+
* `event:<key>` checkpoint's `output`, since that is where it is stored.
|
|
278
|
+
*/
|
|
279
|
+
export declare function getRunEvent(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
|
|
280
|
+
/**
|
|
281
|
+
* `POST /webhooks/:token` — deliver a `ctx.webhook()` callback: the body resumes the run parked on
|
|
282
|
+
* that webhook. Only webhook tokens (`wh:<runId>:<seq>`) are accepted, so this is not a generic
|
|
283
|
+
* signal endpoint. A callback for a run waiting on that token resumes it (200). One that lands
|
|
284
|
+
* before the run reaches `wait()` is buffered (202) when the run exists, is not terminal and has not
|
|
285
|
+
* consumed this webhook yet, and the later `wait()` consumes it; anything else — an unknown run, a
|
|
286
|
+
* terminal one, a duplicate — answers 404 and buffers nothing.
|
|
287
|
+
*
|
|
288
|
+
* The route sits behind the console's own guard (`authorize`, CSRF, roles), like every other
|
|
289
|
+
* route: a webhook token embeds the run id, which a caller may know, so it is not a secret to rest
|
|
290
|
+
* on. Let your callers through in `authorize` (a shared header, an IP range, a signature check), or
|
|
291
|
+
* mount your own public route that verifies the sender and calls `engine.signal(token, body)`.
|
|
292
|
+
*/
|
|
293
|
+
export declare function deliverWebhook(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
|
|
242
294
|
//# sourceMappingURL=handlers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../../src/dashboard/handlers.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../../src/dashboard/handlers.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,6 +9,19 @@ import { runValueAdapter } from './run-values.js';
|
|
|
9
9
|
function redacted(hook, row) {
|
|
10
10
|
return hook ? hook(row) : row;
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Revalidation headers for a versioned run detail or fan page: `no-cache` makes the browser ask on
|
|
14
|
+
* every poll and send the `ETag` back as `If-None-Match`, so an unchanged run costs a 304.
|
|
15
|
+
*/
|
|
16
|
+
function etagHeaders(etag) {
|
|
17
|
+
return { etag, 'cache-control': 'private, no-cache' };
|
|
18
|
+
}
|
|
19
|
+
/** A bare `304 Not Modified` carrying its validator. */
|
|
20
|
+
const notModified = (etag) => ({
|
|
21
|
+
status: 304,
|
|
22
|
+
body: null,
|
|
23
|
+
headers: etagHeaders(etag),
|
|
24
|
+
});
|
|
12
25
|
/** A `200 OK` JSON response. Exported so sibling handlers (e.g. `compat`) share one convention. */
|
|
13
26
|
export const ok = (body) => ({ status: 200, body });
|
|
14
27
|
const notFound = (message) => ({
|
|
@@ -187,12 +200,9 @@ export async function listRuns(deps, req) {
|
|
|
187
200
|
// (...)`, indexed) over the legacy full-table waiter scan; absent on a topology that can't do
|
|
188
201
|
// either yet (see `DashboardEngine.listSignalWaiters`'s doc), where the `waiting` stamp is
|
|
189
202
|
// simply skipped, same as `@dudousxd/nestjs-durable-dashboard`.
|
|
190
|
-
const
|
|
191
|
-
? await engine.listSignalWaitersByRunIds(runs.map((r) => r.id))
|
|
192
|
-
: await (engine.listSignalWaiters?.('') ?? Promise.resolve(undefined));
|
|
193
|
-
const waiterByRun = waiters ? indexWaitersByRun(waiters) : undefined;
|
|
203
|
+
const waitingOf = await waitingResolver(engine, runs);
|
|
194
204
|
return ok({
|
|
195
|
-
runs: runs.map((run) => redacted(deps.redact?.run, summarizeRun(run,
|
|
205
|
+
runs: runs.map((run) => redacted(deps.redact?.run, summarizeRun(run, waitingOf))),
|
|
196
206
|
meta: { page, size, count: runs.length },
|
|
197
207
|
statuses: RUN_STATUSES,
|
|
198
208
|
});
|
|
@@ -212,20 +222,28 @@ export async function getRun(deps, req) {
|
|
|
212
222
|
const full = readFlag(req, 'full');
|
|
213
223
|
if (full === INVALID_FLAG)
|
|
214
224
|
return badRequest('full must be a boolean');
|
|
215
|
-
const
|
|
225
|
+
const ifNoneMatch = req.headers?.['if-none-match'];
|
|
226
|
+
const options = full
|
|
227
|
+
? undefined
|
|
228
|
+
: { summarizeFansOver: SUMMARIZE_FANS_OVER, ...(ifNoneMatch ? { ifNoneMatch } : {}) };
|
|
216
229
|
const detail = engine.getRunDetail
|
|
217
230
|
? await engine.getRunDetail(id, options)
|
|
218
231
|
: await loadRunDetail(engine, id, options);
|
|
219
232
|
if (!detail)
|
|
220
233
|
return notFound(`run ${id} not found`);
|
|
234
|
+
if (detail.etag && detail.notModified)
|
|
235
|
+
return notModified(detail.etag);
|
|
221
236
|
const checkpoint = (cp) => redacted(deps.redact?.checkpoint, summarizeCheckpoint(cp));
|
|
222
|
-
return
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
237
|
+
return {
|
|
238
|
+
...ok({
|
|
239
|
+
run: redacted(deps.redact?.run, detailRun(detail.run)),
|
|
240
|
+
timeline: detail.timeline.map(checkpoint),
|
|
241
|
+
children: detail.children,
|
|
242
|
+
...(detail.fans ? { fans: detail.fans.map((fan) => serializeFan(fan, checkpoint)) } : {}),
|
|
243
|
+
...(detail.childCount !== undefined ? { childCount: detail.childCount } : {}),
|
|
244
|
+
}),
|
|
245
|
+
...(detail.etag ? { headers: etagHeaders(detail.etag) } : {}),
|
|
246
|
+
};
|
|
229
247
|
}
|
|
230
248
|
/**
|
|
231
249
|
* `GET /runs/:id/fans/:group` — one page of a summarized fan's members, in seq order, with the
|
|
@@ -244,20 +262,27 @@ export async function getFanMembers(deps, req) {
|
|
|
244
262
|
const raw = firstQuery(req.query[key]);
|
|
245
263
|
return raw === undefined ? undefined : Number(raw);
|
|
246
264
|
};
|
|
265
|
+
const ifNoneMatch = req.headers?.['if-none-match'];
|
|
247
266
|
const query = {
|
|
248
267
|
offset: number('offset'),
|
|
249
268
|
limit: number('limit'),
|
|
250
269
|
failedOnly: failed,
|
|
270
|
+
...(ifNoneMatch ? { ifNoneMatch } : {}),
|
|
251
271
|
};
|
|
252
272
|
const page = engine.getFanMembers
|
|
253
273
|
? await engine.getFanMembers(id, group, query)
|
|
254
274
|
: await loadFanMembers(engine, id, group, query);
|
|
255
275
|
if (!page)
|
|
256
276
|
return notFound(`run ${id} not found`);
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
277
|
+
if (page.etag && page.notModified)
|
|
278
|
+
return notModified(page.etag);
|
|
279
|
+
return {
|
|
280
|
+
...ok({
|
|
281
|
+
items: page.items.map((cp) => redacted(deps.redact?.checkpoint, summarizeCheckpoint(cp))),
|
|
282
|
+
total: page.total,
|
|
283
|
+
}),
|
|
284
|
+
...(page.etag ? { headers: etagHeaders(page.etag) } : {}),
|
|
285
|
+
};
|
|
261
286
|
}
|
|
262
287
|
/** A {@link FanSummary} on the wire: ISO dates, and its failure sample shaped like timeline steps. */
|
|
263
288
|
function serializeFan(fan, checkpoint) {
|
|
@@ -554,10 +579,31 @@ export async function workers(deps) {
|
|
|
554
579
|
export function topology(role, tenant) {
|
|
555
580
|
return ok(tenant !== undefined ? { role, tenant } : { role });
|
|
556
581
|
}
|
|
557
|
-
/**
|
|
582
|
+
/**
|
|
583
|
+
* How `listRuns` names what each run on a page is parked on: from the store's waiter rows (the
|
|
584
|
+
* targeted per-page lookup, else the full scan), or from a gateway's resolved `waitingFor`. Undefined
|
|
585
|
+
* when the port can do neither, and the `waiting` stamp is skipped.
|
|
586
|
+
*/
|
|
587
|
+
async function waitingResolver(engine, runs) {
|
|
588
|
+
const ids = runs.map((r) => r.id);
|
|
589
|
+
const waiters = engine.listSignalWaitersByRunIds
|
|
590
|
+
? await engine.listSignalWaitersByRunIds(ids)
|
|
591
|
+
: await (engine.listSignalWaiters?.('') ?? Promise.resolve(undefined));
|
|
592
|
+
if (waiters) {
|
|
593
|
+
const waiterByRun = indexWaitersByRun(waiters);
|
|
594
|
+
return (run) => resolveRunWaiting(run, waiterByRun);
|
|
595
|
+
}
|
|
596
|
+
if (engine.waitingFor) {
|
|
597
|
+
const suspended = runs.filter((r) => r.status === 'suspended').map((r) => r.id);
|
|
598
|
+
const byRun = suspended.length > 0 ? await engine.waitingFor(suspended) : {};
|
|
599
|
+
return (run) => byRun[run.id];
|
|
600
|
+
}
|
|
601
|
+
return undefined;
|
|
602
|
+
}
|
|
603
|
+
/** Compact run shape for the list view. `waitingOf`, when given, stamps `waiting` on a `suspended`
|
|
558
604
|
* run parked on a signal/webhook/child/breakpoint (see `listRuns`' bulk waiter scan). */
|
|
559
|
-
function summarizeRun(run,
|
|
560
|
-
const waiting =
|
|
605
|
+
function summarizeRun(run, waitingOf) {
|
|
606
|
+
const waiting = waitingOf ? waitingOf(run) : undefined;
|
|
561
607
|
return {
|
|
562
608
|
id: run.id,
|
|
563
609
|
workflow: run.workflow,
|
|
@@ -616,4 +662,138 @@ function summarizeCheckpoint(cp) {
|
|
|
616
662
|
queueMs: queueMs >= 0 ? queueMs : 0,
|
|
617
663
|
};
|
|
618
664
|
}
|
|
665
|
+
/** Escape a Prometheus label value (backslash, double quote, newline). */
|
|
666
|
+
function promLabel(value) {
|
|
667
|
+
return value.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n');
|
|
668
|
+
}
|
|
669
|
+
/**
|
|
670
|
+
* `GET /metrics` — Prometheus text exposition: this process's event counters (runs and steps by
|
|
671
|
+
* outcome, per-workflow counts, step durations; see `collectMetrics`) plus gauges read at scrape
|
|
672
|
+
* time: `durable_pending_runs` (the dispatch backlog), `durable_running_runs`, `durable_dead_runs`
|
|
673
|
+
* (the dead-letter queue) and, per worker group, `durable_group_queue_depth` and
|
|
674
|
+
* `durable_group_live_workers` (`depth > 0` with zero live workers is the alert). The counters only
|
|
675
|
+
* count the events this process produced, so summing a scrape of every pod counts each event once.
|
|
676
|
+
* Returns the text body; the route sets the `text/plain; version=0.0.4` content type.
|
|
677
|
+
*/
|
|
678
|
+
export async function metricsText(deps) {
|
|
679
|
+
const { engine } = deps;
|
|
680
|
+
const gauges = [];
|
|
681
|
+
const count = engine.countRuns?.bind(engine);
|
|
682
|
+
// A count that fails (a control plane too old to answer it, from a tenant pod) leaves the backlog
|
|
683
|
+
// gauges out rather than reporting a backlog of 0.
|
|
684
|
+
const counts = count
|
|
685
|
+
? await Promise.all([
|
|
686
|
+
count({ status: 'pending' }),
|
|
687
|
+
count({ status: 'running' }),
|
|
688
|
+
count({ status: 'dead' }),
|
|
689
|
+
]).catch(() => undefined)
|
|
690
|
+
: undefined;
|
|
691
|
+
if (counts) {
|
|
692
|
+
const [pending, running, dead] = counts;
|
|
693
|
+
gauges.push('# TYPE durable_pending_runs gauge', `durable_pending_runs ${pending}`, '# TYPE durable_running_runs gauge', `durable_running_runs ${running}`, '# TYPE durable_dead_runs gauge', `durable_dead_runs ${dead}`);
|
|
694
|
+
}
|
|
695
|
+
const health = await engine.workerHealth();
|
|
696
|
+
if (health.length > 0) {
|
|
697
|
+
gauges.push('# TYPE durable_group_queue_depth gauge');
|
|
698
|
+
for (const h of health) {
|
|
699
|
+
gauges.push(`durable_group_queue_depth{group="${promLabel(h.group)}"} ${h.depth}`);
|
|
700
|
+
}
|
|
701
|
+
gauges.push('# TYPE durable_group_live_workers gauge');
|
|
702
|
+
for (const h of health) {
|
|
703
|
+
gauges.push(`durable_group_live_workers{group="${promLabel(h.group)}"} ${h.liveWorkers.length}`);
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
const counters = deps.metrics?.prometheus() ?? '';
|
|
707
|
+
return `${counters}${gauges.length > 0 ? `${gauges.join('\n')}\n` : ''}`;
|
|
708
|
+
}
|
|
709
|
+
/**
|
|
710
|
+
* `GET /runs/:id/events/:key` — the latest value run `id` published for `key` via `ctx.setEvent`:
|
|
711
|
+
* a side-effect-free query of a live (or finished) run. `{ value }`, with `value` absent when the
|
|
712
|
+
* run never published that key. 404 for an unknown run, and on a topology without the read (a
|
|
713
|
+
* store-less `tenant` pod). The value passes through the `checkpoint` redaction hook as the
|
|
714
|
+
* `event:<key>` checkpoint's `output`, since that is where it is stored.
|
|
715
|
+
*/
|
|
716
|
+
export async function getRunEvent(deps, req) {
|
|
717
|
+
const { engine } = deps;
|
|
718
|
+
const id = req.params.id;
|
|
719
|
+
const key = req.params.key;
|
|
720
|
+
if (!id)
|
|
721
|
+
return notFound('run id is required');
|
|
722
|
+
if (!key)
|
|
723
|
+
return notFound('event key is required');
|
|
724
|
+
if (!engine.getEvent)
|
|
725
|
+
return notFound('run events are not available on this topology');
|
|
726
|
+
if (!(await engine.getRun(id)))
|
|
727
|
+
return notFound(`run ${id} not found`);
|
|
728
|
+
const value = await engine.getEvent(id, key);
|
|
729
|
+
if (value === undefined)
|
|
730
|
+
return ok({});
|
|
731
|
+
const hook = deps.redact?.checkpoint;
|
|
732
|
+
if (!hook)
|
|
733
|
+
return ok({ value });
|
|
734
|
+
return ok({ value: hook({ name: `event:${key}`, output: value }).output });
|
|
735
|
+
}
|
|
736
|
+
/** The run a `ctx.webhook()` token belongs to: `wh:<runId>:<seq>`. */
|
|
737
|
+
function webhookRunId(token) {
|
|
738
|
+
if (!token.startsWith('wh:'))
|
|
739
|
+
return undefined;
|
|
740
|
+
const rest = token.slice(3);
|
|
741
|
+
const sep = rest.lastIndexOf(':');
|
|
742
|
+
if (sep <= 0 || !/^\d+$/.test(rest.slice(sep + 1)))
|
|
743
|
+
return undefined;
|
|
744
|
+
return rest.slice(0, sep);
|
|
745
|
+
}
|
|
746
|
+
/**
|
|
747
|
+
* `POST /webhooks/:token` — deliver a `ctx.webhook()` callback: the body resumes the run parked on
|
|
748
|
+
* that webhook. Only webhook tokens (`wh:<runId>:<seq>`) are accepted, so this is not a generic
|
|
749
|
+
* signal endpoint. A callback for a run waiting on that token resumes it (200). One that lands
|
|
750
|
+
* before the run reaches `wait()` is buffered (202) when the run exists, is not terminal and has not
|
|
751
|
+
* consumed this webhook yet, and the later `wait()` consumes it; anything else — an unknown run, a
|
|
752
|
+
* terminal one, a duplicate — answers 404 and buffers nothing.
|
|
753
|
+
*
|
|
754
|
+
* The route sits behind the console's own guard (`authorize`, CSRF, roles), like every other
|
|
755
|
+
* route: a webhook token embeds the run id, which a caller may know, so it is not a secret to rest
|
|
756
|
+
* on. Let your callers through in `authorize` (a shared header, an IP range, a signature check), or
|
|
757
|
+
* mount your own public route that verifies the sender and calls `engine.signal(token, body)`.
|
|
758
|
+
*/
|
|
759
|
+
export async function deliverWebhook(deps, req) {
|
|
760
|
+
const { engine } = deps;
|
|
761
|
+
const token = req.params.token;
|
|
762
|
+
if (!token)
|
|
763
|
+
return notFound('webhook token is required');
|
|
764
|
+
const runId = webhookRunId(token);
|
|
765
|
+
if (runId === undefined)
|
|
766
|
+
return notFound(`${token} is not a webhook token`);
|
|
767
|
+
if (!engine.signal)
|
|
768
|
+
return notFound('webhooks are not available on this topology');
|
|
769
|
+
const tooLarge = payloadTooLarge(req.body);
|
|
770
|
+
if (tooLarge)
|
|
771
|
+
return tooLarge;
|
|
772
|
+
const waiters = engine.listSignalWaitersByRunIds
|
|
773
|
+
? await engine.listSignalWaitersByRunIds([runId])
|
|
774
|
+
: await engine.listSignalWaiters?.(token);
|
|
775
|
+
if (!waiters?.some((w) => w.token === token)) {
|
|
776
|
+
// Nothing waits on it YET: a callback may legitimately land before the run reaches `wait()`
|
|
777
|
+
// (the url was handed out, then the run kept going). Buffer it like `engine.signal` does — but
|
|
778
|
+
// only for a run that exists, is not terminal, and has not already consumed this webhook, so a
|
|
779
|
+
// guessed, stale or duplicate token buffers nothing.
|
|
780
|
+
const run = await engine.getRun(runId);
|
|
781
|
+
if (!run || TERMINAL_STATUSES.has(run.status)) {
|
|
782
|
+
return notFound(`no live run is waiting on webhook ${token}`);
|
|
783
|
+
}
|
|
784
|
+
const seq = Number(token.slice(token.lastIndexOf(':') + 1));
|
|
785
|
+
const delivered = (await engine.listCheckpoints(runId)).some((cp) => cp.seq === seq && cp.status === 'completed');
|
|
786
|
+
if (delivered)
|
|
787
|
+
return notFound(`webhook ${token} was already delivered`);
|
|
788
|
+
const result = await engine.signal(token, req.body);
|
|
789
|
+
if (result)
|
|
790
|
+
return ok({ result });
|
|
791
|
+
return { status: 202, body: { buffered: true } };
|
|
792
|
+
}
|
|
793
|
+
const result = await engine.signal(token, req.body);
|
|
794
|
+
if (!result)
|
|
795
|
+
return notFound(`no run is waiting on webhook ${token}`);
|
|
796
|
+
return ok({ result });
|
|
797
|
+
}
|
|
798
|
+
const TERMINAL_STATUSES = new Set(['completed', 'failed', 'cancelled', 'dead']);
|
|
619
799
|
//# sourceMappingURL=handlers.js.map
|