@voyant-travel/workflows-orchestrator 0.108.0 → 0.109.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/README.md +13 -11
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +5 -4
  5. package/dist/node/core.d.ts +9 -0
  6. package/dist/node/core.d.ts.map +1 -0
  7. package/dist/node/core.js +8 -0
  8. package/dist/node/dashboard-chunks.d.ts +17 -0
  9. package/dist/node/dashboard-chunks.d.ts.map +1 -0
  10. package/dist/node/dashboard-chunks.js +19 -0
  11. package/dist/node/dashboard-http-server.d.ts +6 -0
  12. package/dist/node/dashboard-http-server.d.ts.map +1 -0
  13. package/dist/node/dashboard-http-server.js +99 -0
  14. package/dist/node/dashboard-metrics.d.ts +3 -0
  15. package/dist/node/dashboard-metrics.d.ts.map +1 -0
  16. package/dist/node/dashboard-metrics.js +26 -0
  17. package/dist/node/dashboard-request.d.ts +7 -0
  18. package/dist/node/dashboard-request.d.ts.map +1 -0
  19. package/dist/node/dashboard-request.js +436 -0
  20. package/dist/node/dashboard-server.d.ts +10 -0
  21. package/dist/node/dashboard-server.d.ts.map +1 -0
  22. package/dist/node/dashboard-server.js +7 -0
  23. package/dist/node/dashboard-sse.d.ts +7 -0
  24. package/dist/node/dashboard-sse.d.ts.map +1 -0
  25. package/dist/node/dashboard-sse.js +134 -0
  26. package/dist/node/dashboard-static.d.ts +7 -0
  27. package/dist/node/dashboard-static.d.ts.map +1 -0
  28. package/dist/node/dashboard-static.js +89 -0
  29. package/dist/node/dashboard-types.d.ts +134 -0
  30. package/dist/node/dashboard-types.d.ts.map +1 -0
  31. package/dist/node/dashboard-types.js +1 -0
  32. package/dist/node/entry-loader.d.ts +8 -0
  33. package/dist/node/entry-loader.d.ts.map +1 -0
  34. package/dist/node/entry-loader.js +19 -0
  35. package/dist/node/fs-run-record-store.d.ts +12 -0
  36. package/dist/node/fs-run-record-store.d.ts.map +1 -0
  37. package/dist/node/fs-run-record-store.js +101 -0
  38. package/dist/node/index.d.ts +23 -0
  39. package/dist/node/index.d.ts.map +1 -0
  40. package/dist/node/index.js +22 -0
  41. package/dist/node/local-runtime.d.ts +3 -0
  42. package/dist/node/local-runtime.d.ts.map +1 -0
  43. package/dist/node/local-runtime.js +35 -0
  44. package/dist/node/migrate.d.ts +17 -0
  45. package/dist/node/migrate.d.ts.map +1 -0
  46. package/dist/node/migrate.js +75 -0
  47. package/dist/node/node-selfhost-defaults.d.ts +7 -0
  48. package/dist/node/node-selfhost-defaults.d.ts.map +1 -0
  49. package/dist/node/node-selfhost-defaults.js +8 -0
  50. package/dist/node/node-selfhost-deps.d.ts +4 -0
  51. package/dist/node/node-selfhost-deps.d.ts.map +1 -0
  52. package/dist/node/node-selfhost-deps.js +402 -0
  53. package/dist/node/node-selfhost-resume-input.d.ts +4 -0
  54. package/dist/node/node-selfhost-resume-input.d.ts.map +1 -0
  55. package/dist/node/node-selfhost-resume-input.js +20 -0
  56. package/dist/node/node-standalone-driver.d.ts +76 -0
  57. package/dist/node/node-standalone-driver.d.ts.map +1 -0
  58. package/dist/node/node-standalone-driver.js +507 -0
  59. package/dist/node/persistent-wakeup-manager.d.ts +16 -0
  60. package/dist/node/persistent-wakeup-manager.d.ts.map +1 -0
  61. package/dist/node/persistent-wakeup-manager.js +27 -0
  62. package/dist/node/postgres-manifest-store.d.ts +35 -0
  63. package/dist/node/postgres-manifest-store.d.ts.map +1 -0
  64. package/dist/node/postgres-manifest-store.js +86 -0
  65. package/dist/node/postgres-run-record-store.d.ts +9 -0
  66. package/dist/node/postgres-run-record-store.d.ts.map +1 -0
  67. package/dist/node/postgres-run-record-store.js +161 -0
  68. package/dist/node/postgres-schema.d.ts +450 -0
  69. package/dist/node/postgres-schema.d.ts.map +1 -0
  70. package/dist/node/postgres-schema.js +70 -0
  71. package/dist/node/postgres-snapshot-run-store.d.ts +31 -0
  72. package/dist/node/postgres-snapshot-run-store.d.ts.map +1 -0
  73. package/dist/node/postgres-snapshot-run-store.js +134 -0
  74. package/dist/node/postgres-wakeup-store.d.ts +22 -0
  75. package/dist/node/postgres-wakeup-store.d.ts.map +1 -0
  76. package/dist/node/postgres-wakeup-store.js +118 -0
  77. package/dist/node/postgres.d.ts +12 -0
  78. package/dist/node/postgres.d.ts.map +1 -0
  79. package/dist/node/postgres.js +21 -0
  80. package/dist/node/resume-run.d.ts +2 -0
  81. package/dist/node/resume-run.d.ts.map +1 -0
  82. package/dist/node/resume-run.js +1 -0
  83. package/dist/node/run-record-snapshot.d.ts +23 -0
  84. package/dist/node/run-record-snapshot.d.ts.map +1 -0
  85. package/dist/node/run-record-snapshot.js +116 -0
  86. package/dist/node/scheduler.d.ts +2 -0
  87. package/dist/node/scheduler.d.ts.map +1 -0
  88. package/dist/node/scheduler.js +1 -0
  89. package/dist/node/selfhost-client.d.ts +32 -0
  90. package/dist/node/selfhost-client.d.ts.map +1 -0
  91. package/dist/node/selfhost-client.js +32 -0
  92. package/dist/node/sleep-alarm-manager.d.ts +32 -0
  93. package/dist/node/sleep-alarm-manager.d.ts.map +1 -0
  94. package/dist/node/sleep-alarm-manager.js +100 -0
  95. package/dist/node/snapshot-run-store.d.ts +38 -0
  96. package/dist/node/snapshot-run-store.d.ts.map +1 -0
  97. package/dist/node/snapshot-run-store.js +109 -0
  98. package/dist/node/store-stream.d.ts +29 -0
  99. package/dist/node/store-stream.d.ts.map +1 -0
  100. package/dist/node/store-stream.js +93 -0
  101. package/dist/node/wakeup-poller.d.ts +35 -0
  102. package/dist/node/wakeup-poller.d.ts.map +1 -0
  103. package/dist/node/wakeup-poller.js +95 -0
  104. package/dist/node/wakeup-store.d.ts +31 -0
  105. package/dist/node/wakeup-store.d.ts.map +1 -0
  106. package/dist/node/wakeup-store.js +131 -0
  107. package/dist/testing/driver-compliance.js +1 -1
  108. package/drizzle/0000_init.sql +26 -0
  109. package/drizzle/0001_persist_run_record.sql +1 -0
  110. package/drizzle/0002_allow_null_input.sql +1 -0
  111. package/drizzle/0003_idempotency_key.sql +2 -0
  112. package/drizzle/0004_workflow_manifests.sql +10 -0
  113. package/drizzle/0005_wakeup_priority.sql +3 -0
  114. package/drizzle/meta/0000_snapshot.json +215 -0
  115. package/drizzle/meta/0001_snapshot.json +221 -0
  116. package/drizzle/meta/0002_snapshot.json +221 -0
  117. package/drizzle/meta/_journal.json +48 -0
  118. package/package.json +23 -5
  119. package/src/index.ts +5 -4
  120. package/src/node/core.ts +43 -0
  121. package/src/node/dashboard-chunks.ts +35 -0
  122. package/src/node/dashboard-http-server.ts +118 -0
  123. package/src/node/dashboard-metrics.ts +39 -0
  124. package/src/node/dashboard-request.ts +488 -0
  125. package/src/node/dashboard-server.ts +17 -0
  126. package/src/node/dashboard-sse.ts +150 -0
  127. package/src/node/dashboard-static.ts +88 -0
  128. package/src/node/dashboard-types.ts +106 -0
  129. package/src/node/entry-loader.ts +32 -0
  130. package/src/node/fs-run-record-store.ts +107 -0
  131. package/src/node/index.ts +149 -0
  132. package/src/node/local-runtime.ts +35 -0
  133. package/src/node/migrate.ts +103 -0
  134. package/src/node/node-selfhost-defaults.ts +9 -0
  135. package/src/node/node-selfhost-deps.ts +492 -0
  136. package/src/node/node-selfhost-resume-input.ts +27 -0
  137. package/src/node/node-standalone-driver.ts +706 -0
  138. package/src/node/persistent-wakeup-manager.ts +52 -0
  139. package/src/node/postgres-manifest-store.ts +146 -0
  140. package/src/node/postgres-run-record-store.ts +183 -0
  141. package/src/node/postgres-schema.ts +102 -0
  142. package/src/node/postgres-snapshot-run-store.ts +167 -0
  143. package/src/node/postgres-wakeup-store.ts +156 -0
  144. package/src/node/postgres.ts +35 -0
  145. package/src/node/resume-run.ts +7 -0
  146. package/src/node/run-record-snapshot.ts +154 -0
  147. package/src/node/scheduler.ts +13 -0
  148. package/src/node/selfhost-client.ts +77 -0
  149. package/src/node/sleep-alarm-manager.ts +144 -0
  150. package/src/node/snapshot-run-store.ts +149 -0
  151. package/src/node/store-stream.ts +128 -0
  152. package/src/node/wakeup-poller.ts +142 -0
  153. package/src/node/wakeup-store.ts +162 -0
  154. package/src/testing/driver-compliance.ts +1 -1
package/README.md CHANGED
@@ -1,10 +1,9 @@
1
1
  # @voyant-travel/workflows-orchestrator
2
2
 
3
- Reference orchestrator for Voyant Workflows. Drives runs through the
4
- tenant step handler over the v1 wire protocol. Transport- and
5
- storage-agnostic: compose with a `RunRecordStore` of your choice
6
- (in-memory for tests, Postgres-backed for production through
7
- [`@voyant-travel/workflows-orchestrator-node`](../workflows-orchestrator-node)).
3
+ Postgres self-host orchestrator runtime for Voyant Workflows. Drives runs through
4
+ the tenant step handler over the v1 wire protocol. The package includes the
5
+ core state machine, in-memory test store, Postgres-backed production stores,
6
+ scheduler/wakeup support, and the self-host server helpers.
8
7
 
9
8
  See [`docs/runtime-protocol.md`](../../docs/runtime-protocol.md) §2 +
10
9
  §5 for the contract this implements.
@@ -20,8 +19,8 @@ import {
20
19
  import { handleStepRequest } from "@voyant-travel/workflows/handler";
21
20
 
22
21
  // A StepHandler calls into the tenant's workflow code. In-process
23
- // here via `handleStepRequest`; production Node deployments normally
24
- // use the node runtime package.
22
+ // here via `handleStepRequest`; production self-host deployments normally
23
+ // use the Postgres-backed driver below.
25
24
  const handler: StepHandler = async (req) => handleStepRequest(req);
26
25
 
27
26
  const store = createInMemoryRunStore();
@@ -54,7 +53,10 @@ const record = await trigger(
54
53
  exposed for advanced composition (e.g. custom scheduling, alarm
55
54
  handlers).
56
55
  - **`createInMemoryRunStore()`** — test-friendly `RunRecordStore`.
57
- Production stores live alongside their transport adapter.
56
+ - **`createStandaloneDriver({ db })`** production Postgres
57
+ workflow driver for `createApp()`.
58
+ - **`startSelfHostServer(options)`** — reference self-host server.
59
+ - **`runPostgresMigrations(options)`** — apply committed runtime migrations.
58
60
 
59
61
  ## Status model
60
62
 
@@ -70,6 +72,6 @@ waitpoint the tenant registered.
70
72
  The authoring SDK (`@voyant-travel/workflows`) describes workflows and
71
73
  provides the in-process executor. The orchestrator consumes that
72
74
  SDK's wire protocol — it doesn't care how the tenant runs the body,
73
- only about the request/response shape. Separating them keeps the
74
- orchestrator transport-neutral and makes it easy to test the full loop
75
- without any network dependency.
75
+ only about the request/response shape. Keeping orchestration outside the
76
+ authoring SDK prevents SDK consumers from taking on Postgres, scheduler, and
77
+ self-host server dependencies unless they are running workflows.
package/dist/index.d.ts CHANGED
@@ -6,6 +6,7 @@ export { type RouteEventArgs, type RouterMatch, routeEvent, } from "./event-rout
6
6
  export { createHttpStepHandler, type HttpStepHandlerDeps, type HttpStepTarget, } from "./http-step-handler.js";
7
7
  export { createInMemoryRunStore } from "./in-memory-store.js";
8
8
  export { emptyJournal } from "./journal-helpers.js";
9
+ export * from "./node/index.js";
9
10
  export { type CancelArgs, cancel, type OrchestratorDeps, type ResumeArgs, type ResumeDueAlarmsArgs, resume, resumeDueAlarms, type TriggerArgs, trigger, } from "./orchestrator.js";
10
11
  export { type BuildResumeJournalInput, type BuildResumeJournalResult, type BuildSeededResumeJournalInput, buildResumeJournal, buildSeededResumeJournal, } from "./resume-run.js";
11
12
  export { type CronSpec, computeNextFire, createScheduler, manifestScheduleSources, nextCronFire, parseCron, type SchedulableDeclaration, type SchedulerDeps, type SchedulerHandle, type ScheduleSource, toMs, } from "./schedule.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,kBAAkB,GACnB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACL,KAAK,mBAAmB,EACxB,qCAAqC,EACrC,KAAK,+BAA+B,EACpC,KAAK,wBAAwB,EAC7B,qBAAqB,EACrB,gCAAgC,GACjC,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,uBAAuB,EAAE,KAAK,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AACzF,OAAO,EACL,oBAAoB,EACpB,KAAK,qBAAqB,GAC3B,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,UAAU,GACX,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,qBAAqB,EACrB,KAAK,mBAAmB,EACxB,KAAK,cAAc,GACpB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACnD,OAAO,EACL,KAAK,UAAU,EACf,MAAM,EACN,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,MAAM,EACN,eAAe,EACf,KAAK,WAAW,EAChB,OAAO,GACR,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC7B,KAAK,6BAA6B,EAClC,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,KAAK,QAAQ,EACb,eAAe,EACf,eAAe,EACf,uBAAuB,EACvB,YAAY,EACZ,SAAS,EACT,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,IAAI,GACL,MAAM,eAAe,CAAA;AACtB,cAAc,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,kBAAkB,GACnB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACL,KAAK,mBAAmB,EACxB,qCAAqC,EACrC,KAAK,+BAA+B,EACpC,KAAK,wBAAwB,EAC7B,qBAAqB,EACrB,gCAAgC,GACjC,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,uBAAuB,EAAE,KAAK,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AACzF,OAAO,EACL,oBAAoB,EACpB,KAAK,qBAAqB,GAC3B,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,UAAU,GACX,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,qBAAqB,EACrB,KAAK,mBAAmB,EACxB,KAAK,cAAc,GACpB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACnD,cAAc,iBAAiB,CAAA;AAC/B,OAAO,EACL,KAAK,UAAU,EACf,MAAM,EACN,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,MAAM,EACN,eAAe,EACf,KAAK,WAAW,EAChB,OAAO,GACR,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC7B,KAAK,6BAA6B,EAClC,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,KAAK,QAAQ,EACb,eAAe,EACf,eAAe,EACf,uBAAuB,EACvB,YAAY,EACZ,SAAS,EACT,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,IAAI,GACL,MAAM,eAAe,CAAA;AACtB,cAAc,YAAY,CAAA"}
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  // @voyant-travel/workflows-orchestrator
2
2
  //
3
- // Reference orchestrator for Voyant Workflows. Drives runs through
4
- // the tenant step handler over the v1 wire protocol. Transport- and
5
- // storage-agnostic: compose with a RunRecordStore of your choice
6
- // (in-memory for tests, Postgres-backed for production).
3
+ // Postgres self-host orchestrator runtime for Voyant Workflows. Drives runs
4
+ // through the tenant step handler over the v1 wire protocol and exports
5
+ // the core engine, in-memory test stores, Postgres stores, scheduler,
6
+ // and self-host server helpers.
7
7
  //
8
8
  // See docs/runtime-protocol.md §2 + §5 for the contract this
9
9
  // implements and docs/design.md §6 for the broader orchestrator
@@ -16,6 +16,7 @@ export { routeEvent, } from "./event-router.js";
16
16
  export { createHttpStepHandler, } from "./http-step-handler.js";
17
17
  export { createInMemoryRunStore } from "./in-memory-store.js";
18
18
  export { emptyJournal } from "./journal-helpers.js";
19
+ export * from "./node/index.js";
19
20
  export { cancel, resume, resumeDueAlarms, trigger, } from "./orchestrator.js";
20
21
  export { buildResumeJournal, buildSeededResumeJournal, } from "./resume-run.js";
21
22
  export { computeNextFire, createScheduler, manifestScheduleSources, nextCronFire, parseCron, toMs, } from "./schedule.js";
@@ -0,0 +1,9 @@
1
+ export { type ConcurrencyRunHooks, createInProcessConcurrencyCoordinator, type InProcessConcurrencyCoordinator, type RuntimeConcurrencyPolicy, resolveConcurrencyKey, WorkflowConcurrencyRejectedError, } from "../concurrency.js";
2
+ export { type RouteEventArgs, type RouterMatch, routeEvent } from "../event-router.js";
3
+ export { createInMemoryRunStore } from "../in-memory-store.js";
4
+ export { emptyJournal } from "../journal-helpers.js";
5
+ export { type CancelArgs, cancel, type OrchestratorDeps, type ResumeArgs, type ResumeDueAlarmsArgs, resume, resumeDueAlarms, type TriggerArgs, trigger, } from "../orchestrator.js";
6
+ export { type BuildResumeJournalInput, type BuildResumeJournalResult, type BuildSeededResumeJournalInput, buildResumeJournal, buildSeededResumeJournal, } from "../resume-run.js";
7
+ export { type CronSpec, computeNextFire, createScheduler, manifestScheduleSources, nextCronFire, parseCron, type SchedulableDeclaration, type SchedulerDeps, type SchedulerHandle, type ScheduleSource, toMs, } from "../schedule.js";
8
+ export * from "../types.js";
9
+ //# sourceMappingURL=core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/node/core.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,mBAAmB,EACxB,qCAAqC,EACrC,KAAK,+BAA+B,EACpC,KAAK,wBAAwB,EAC7B,qBAAqB,EACrB,gCAAgC,GACjC,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AACtF,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACpD,OAAO,EACL,KAAK,UAAU,EACf,MAAM,EACN,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,MAAM,EACN,eAAe,EACf,KAAK,WAAW,EAChB,OAAO,GACR,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC7B,KAAK,6BAA6B,EAClC,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,KAAK,QAAQ,EACb,eAAe,EACf,eAAe,EACf,uBAAuB,EACvB,YAAY,EACZ,SAAS,EACT,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,IAAI,GACL,MAAM,gBAAgB,CAAA;AACvB,cAAc,aAAa,CAAA"}
@@ -0,0 +1,8 @@
1
+ export { createInProcessConcurrencyCoordinator, resolveConcurrencyKey, WorkflowConcurrencyRejectedError, } from "../concurrency.js";
2
+ export { routeEvent } from "../event-router.js";
3
+ export { createInMemoryRunStore } from "../in-memory-store.js";
4
+ export { emptyJournal } from "../journal-helpers.js";
5
+ export { cancel, resume, resumeDueAlarms, trigger, } from "../orchestrator.js";
6
+ export { buildResumeJournal, buildSeededResumeJournal, } from "../resume-run.js";
7
+ export { computeNextFire, createScheduler, manifestScheduleSources, nextCronFire, parseCron, toMs, } from "../schedule.js";
8
+ export * from "../types.js";
@@ -0,0 +1,17 @@
1
+ export interface ChunkEvent {
2
+ runId: string;
3
+ chunk: {
4
+ streamId: string;
5
+ seq: number;
6
+ encoding: "text" | "json" | "base64";
7
+ chunk: unknown;
8
+ final: boolean;
9
+ at: number;
10
+ };
11
+ }
12
+ export interface ChunkBus {
13
+ publish(event: ChunkEvent): void;
14
+ subscribe(fn: (event: ChunkEvent) => void): () => void;
15
+ }
16
+ export declare function createChunkBus(): ChunkBus;
17
+ //# sourceMappingURL=dashboard-chunks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-chunks.d.ts","sourceRoot":"","sources":["../../src/node/dashboard-chunks.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE;QACL,QAAQ,EAAE,MAAM,CAAA;QAChB,GAAG,EAAE,MAAM,CAAA;QACX,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAA;QACpC,KAAK,EAAE,OAAO,CAAA;QACd,KAAK,EAAE,OAAO,CAAA;QACd,EAAE,EAAE,MAAM,CAAA;KACX,CAAA;CACF;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;IAChC,SAAS,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,MAAM,IAAI,CAAA;CACvD;AAED,wBAAgB,cAAc,IAAI,QAAQ,CAiBzC"}
@@ -0,0 +1,19 @@
1
+ export function createChunkBus() {
2
+ const subs = new Set();
3
+ return {
4
+ publish(event) {
5
+ for (const fn of subs) {
6
+ try {
7
+ fn(event);
8
+ }
9
+ catch {
10
+ // Ignore subscriber errors so streaming keeps going.
11
+ }
12
+ }
13
+ },
14
+ subscribe(fn) {
15
+ subs.add(fn);
16
+ return () => subs.delete(fn);
17
+ },
18
+ };
19
+ }
@@ -0,0 +1,6 @@
1
+ import type { ServeDeps, ServeHandle } from "./dashboard-types.js";
2
+ export declare function startServer(options: {
3
+ port: number;
4
+ host: string;
5
+ }, deps: ServeDeps): Promise<ServeHandle>;
6
+ //# sourceMappingURL=dashboard-http-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-http-server.d.ts","sourceRoot":"","sources":["../../src/node/dashboard-http-server.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AASlE,wBAAsB,WAAW,CAC/B,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EACvC,IAAI,EAAE,SAAS,GACd,OAAO,CAAC,WAAW,CAAC,CAiFtB"}
@@ -0,0 +1,99 @@
1
+ import { handleRequest } from "./dashboard-request.js";
2
+ import { handleRunSseStream, handleSseStream } from "./dashboard-sse.js";
3
+ import { createStaticReader, urlPath } from "./dashboard-static.js";
4
+ import { createStoreStream } from "./store-stream.js";
5
+ function closeAllConnections(server) {
6
+ if ("closeAllConnections" in server && typeof server.closeAllConnections === "function") {
7
+ server.closeAllConnections();
8
+ }
9
+ }
10
+ export async function startServer(options, deps) {
11
+ const readStatic = deps.readStatic ?? (deps.staticDir ? createStaticReader(deps.staticDir) : undefined);
12
+ const hasStaticDashboard = Boolean(readStatic);
13
+ let storeStream;
14
+ const getStoreStream = () => {
15
+ if (!storeStream)
16
+ storeStream = createStoreStream(deps.store);
17
+ return storeStream;
18
+ };
19
+ const server = deps.createServer(async (req, res) => {
20
+ const method = (req.method ?? "GET").toUpperCase();
21
+ const url = req.url ?? "/";
22
+ if ((method === "GET" || method === "HEAD") && urlPath(url) === "/api/runs/stream") {
23
+ handleSseStream(res, getStoreStream(), deps.chunkBus);
24
+ return;
25
+ }
26
+ const perRunMatch = urlPath(url).match(/^\/api\/runs\/([^/]+)\/stream$/);
27
+ if ((method === "GET" || method === "HEAD") && perRunMatch) {
28
+ const runId = decodeURIComponent(perRunMatch[1]);
29
+ handleRunSseStream(res, runId, getStoreStream(), deps.chunkBus, deps.store);
30
+ return;
31
+ }
32
+ try {
33
+ const body = method === "POST" ? await readRequestBody(req) : undefined;
34
+ const response = await handleRequest({ method, url, body }, {
35
+ store: deps.store,
36
+ healthCheck: deps.healthCheck,
37
+ readinessCheck: deps.readinessCheck,
38
+ collectMetrics: deps.collectMetrics,
39
+ readStatic,
40
+ hasStaticDashboard,
41
+ triggerRun: deps.triggerRun,
42
+ resumeRun: deps.resumeRun,
43
+ listWorkflows: deps.listWorkflows,
44
+ injectWaitpoint: deps.injectWaitpoint,
45
+ listSchedules: deps.listSchedules,
46
+ cancelRun: deps.cancelRun,
47
+ });
48
+ res.writeHead(response.status, response.headers);
49
+ res.end(response.body);
50
+ }
51
+ catch (err) {
52
+ const message = err instanceof Error ? err.message : String(err);
53
+ res.writeHead(500, { "content-type": "application/json" });
54
+ res.end(JSON.stringify({ error: "internal_error", message }));
55
+ }
56
+ });
57
+ await new Promise((resolve, reject) => {
58
+ server.once("error", reject);
59
+ server.listen(options.port, options.host, () => {
60
+ server.off("error", reject);
61
+ resolve();
62
+ });
63
+ });
64
+ deps.scheduler?.start();
65
+ return {
66
+ url: `http://${options.host}:${options.port}`,
67
+ close: () => new Promise((resolve, reject) => {
68
+ deps.scheduler?.stop();
69
+ storeStream?.stop();
70
+ closeAllConnections(server);
71
+ server.close((err) => {
72
+ if (err) {
73
+ reject(err);
74
+ return;
75
+ }
76
+ Promise.resolve(deps.shutdown?.()).then(() => resolve(), reject);
77
+ });
78
+ }),
79
+ };
80
+ }
81
+ async function readRequestBody(req) {
82
+ const maxBytes = 1_000_000;
83
+ return new Promise((resolve, reject) => {
84
+ let total = 0;
85
+ const chunks = [];
86
+ req.on("data", (chunk) => {
87
+ total += chunk.length;
88
+ if (total > maxBytes) {
89
+ req.destroy(new Error("request body exceeds 1MB"));
90
+ return;
91
+ }
92
+ chunks.push(chunk);
93
+ });
94
+ req.on("end", () => {
95
+ resolve(Buffer.concat(chunks).toString("utf8"));
96
+ });
97
+ req.on("error", reject);
98
+ });
99
+ }
@@ -0,0 +1,3 @@
1
+ import type { MetricsSnapshot } from "./dashboard-types.js";
2
+ export declare function renderMetrics(snapshot: MetricsSnapshot): string;
3
+ //# sourceMappingURL=dashboard-metrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-metrics.d.ts","sourceRoot":"","sources":["../../src/node/dashboard-metrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAE3D,wBAAgB,aAAa,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAgC/D"}
@@ -0,0 +1,26 @@
1
+ export function renderMetrics(snapshot) {
2
+ const lines = [
3
+ "# HELP voyant_selfhost_up Self-host server availability.",
4
+ "# TYPE voyant_selfhost_up gauge",
5
+ "voyant_selfhost_up 1",
6
+ "# HELP voyant_selfhost_workflows_registered Registered workflow count.",
7
+ "# TYPE voyant_selfhost_workflows_registered gauge",
8
+ `voyant_selfhost_workflows_registered ${snapshot.workflowsRegistered}`,
9
+ "# HELP voyant_selfhost_schedules_registered Registered schedule count.",
10
+ "# TYPE voyant_selfhost_schedules_registered gauge",
11
+ `voyant_selfhost_schedules_registered ${snapshot.schedulesRegistered}`,
12
+ "# HELP voyant_selfhost_runs_total Persisted run count.",
13
+ "# TYPE voyant_selfhost_runs_total gauge",
14
+ `voyant_selfhost_runs_total ${snapshot.runsTotal}`,
15
+ "# HELP voyant_selfhost_runs_status Run count by status.",
16
+ "# TYPE voyant_selfhost_runs_status gauge",
17
+ ];
18
+ for (const [status, count] of Object.entries(snapshot.runsByStatus).sort(([a], [b]) => a.localeCompare(b))) {
19
+ lines.push(`voyant_selfhost_runs_status{status="${escapeMetricLabelValue(status)}"} ${count}`);
20
+ }
21
+ lines.push("# HELP voyant_selfhost_wakeups_total Persisted wakeup count.", "# TYPE voyant_selfhost_wakeups_total gauge", `voyant_selfhost_wakeups_total ${snapshot.wakeupsTotal}`, "# HELP voyant_selfhost_metrics_generated_at_seconds Metrics generation timestamp.", "# TYPE voyant_selfhost_metrics_generated_at_seconds gauge", `voyant_selfhost_metrics_generated_at_seconds ${Math.floor(snapshot.generatedAtMs / 1000)}`, "");
22
+ return lines.join("\n");
23
+ }
24
+ function escapeMetricLabelValue(value) {
25
+ return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n");
26
+ }
@@ -0,0 +1,7 @@
1
+ import type { HandlerResponse, RequestHandlerDeps } from "./dashboard-types.js";
2
+ export declare function handleRequest(req: {
3
+ method: string;
4
+ url: string;
5
+ body?: string;
6
+ }, deps: RequestHandlerDeps): Promise<HandlerResponse>;
7
+ //# sourceMappingURL=dashboard-request.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-request.d.ts","sourceRoot":"","sources":["../../src/node/dashboard-request.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAgB,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAG7F,wBAAsB,aAAa,CACjC,GAAG,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,EACnD,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,eAAe,CAAC,CAiT1B"}