@voyantjs/workflows-orchestrator-cloudflare 0.28.3 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +23 -11
  2. package/dist/cloudflare-edge-driver.d.ts +49 -0
  3. package/dist/cloudflare-edge-driver.d.ts.map +1 -0
  4. package/dist/cloudflare-edge-driver.js +317 -0
  5. package/dist/dispatchers.d.ts +87 -0
  6. package/dist/dispatchers.d.ts.map +1 -0
  7. package/dist/dispatchers.js +83 -0
  8. package/dist/do-store.d.ts.map +1 -1
  9. package/dist/do-store.js +12 -0
  10. package/dist/durable-object.d.ts +13 -6
  11. package/dist/durable-object.d.ts.map +1 -1
  12. package/dist/durable-object.js +13 -4
  13. package/dist/event-handler.d.ts +23 -0
  14. package/dist/event-handler.d.ts.map +1 -0
  15. package/dist/event-handler.js +241 -0
  16. package/dist/index.d.ts +3 -1
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +14 -6
  19. package/dist/manifest-handler.d.ts +16 -0
  20. package/dist/manifest-handler.d.ts.map +1 -0
  21. package/dist/manifest-handler.js +92 -0
  22. package/dist/manifest-kv-store.d.ts +59 -0
  23. package/dist/manifest-kv-store.d.ts.map +1 -0
  24. package/dist/manifest-kv-store.js +134 -0
  25. package/dist/types.d.ts +7 -15
  26. package/dist/types.d.ts.map +1 -1
  27. package/dist/worker.d.ts +19 -0
  28. package/dist/worker.d.ts.map +1 -1
  29. package/dist/worker.js +41 -0
  30. package/package.json +3 -3
  31. package/src/cloudflare-edge-driver.ts +435 -0
  32. package/src/dispatchers.ts +162 -0
  33. package/src/do-store.ts +13 -0
  34. package/src/durable-object.ts +30 -9
  35. package/src/event-handler.ts +302 -0
  36. package/src/index.ts +32 -8
  37. package/src/manifest-handler.ts +113 -0
  38. package/src/manifest-kv-store.ts +186 -0
  39. package/src/types.ts +7 -19
  40. package/src/worker.ts +64 -0
  41. package/dist/dispatch-handler.d.ts +0 -20
  42. package/dist/dispatch-handler.d.ts.map +0 -1
  43. package/dist/dispatch-handler.js +0 -31
  44. package/src/dispatch-handler.ts +0 -51
package/src/types.ts CHANGED
@@ -27,20 +27,6 @@ export interface DurableObjectStorageLike {
27
27
  deleteAlarm?(): Promise<void>
28
28
  }
29
29
 
30
- /**
31
- * Subset of a Workers-for-Platforms dispatch namespace. `get(name)`
32
- * returns a binding whose `fetch` delivers to the tenant Worker
33
- * registered under that name.
34
- */
35
- export interface DispatchNamespaceLike {
36
- get(
37
- name: string,
38
- args?: Record<string, unknown>,
39
- ): {
40
- fetch(request: Request): Promise<Response>
41
- }
42
- }
43
-
44
30
  /** Args the Worker passes when routing to a run DO. */
45
31
  export interface RunOperation {
46
32
  op: "trigger" | "resume" | "cancel" | "get"
@@ -61,8 +47,12 @@ export interface TriggerPayload {
61
47
  tenantId: string
62
48
  projectId: string
63
49
  organizationId: string
64
- /** Dispatch-namespace name to forward step requests to. */
65
- tenantScript: string
50
+ /**
51
+ * Adapter-specific tenant identifier. Opaque to the OSS runtime —
52
+ * surfaces on `StepDispatcherContext` so custom dispatchers can
53
+ * use it as a routing key.
54
+ */
55
+ tenantScript?: string
66
56
  }
67
57
  environment?: "production" | "preview" | "development"
68
58
  tags?: string[]
@@ -78,9 +68,7 @@ export interface CancelPayload {
78
68
  * The Worker runtime env the adapter expects. Callers provide their
79
69
  * own wrangler config; this interface documents what we read.
80
70
  */
81
- export interface AdapterEnv<DONamespace = unknown, DispatchNS = DispatchNamespaceLike> {
71
+ export interface AdapterEnv<DONamespace = unknown> {
82
72
  /** Durable Object namespace holding one DO per run. Typed loosely to avoid a CF types dep. */
83
73
  WORKFLOW_RUN_DO: DONamespace
84
- /** Dispatch namespace containing tenant Workers. */
85
- DISPATCHER: DispatchNS
86
74
  }
package/src/worker.ts CHANGED
@@ -13,6 +13,10 @@
13
13
 
14
14
  import type { WaitpointInjection } from "@voyantjs/workflows-orchestrator"
15
15
 
16
+ import { handleIngestEvent } from "./event-handler.js"
17
+ import { handleGetManifest, handleRegisterManifest } from "./manifest-handler.js"
18
+ import type { CfManifestStore } from "./manifest-kv-store.js"
19
+
16
20
  /**
17
21
  * Minimal shape of a DO namespace. `idFromName` returns an opaque id;
18
22
  * `get(id)` returns a stub with `fetch` (matching the CF DO API).
@@ -36,6 +40,24 @@ export interface WorkerFetchDeps<Id = unknown> {
36
40
  idGenerator?: () => string
37
41
  /** Injectable clock for id generation. */
38
42
  now?: () => number
43
+ /**
44
+ * Optional KV-backed manifest store. When set, the worker also serves
45
+ * `/api/manifests` and `/api/events`. When unset, those routes 404 —
46
+ * useful for orchestrators that only expose the run surface.
47
+ */
48
+ manifestStore?: CfManifestStore
49
+ /**
50
+ * Tenant metadata stamped on event-triggered runs. Defaults to
51
+ * `{ tenantId: "default", projectId: "default", organizationId: "default" }`.
52
+ * Voyant Cloud's wrapper layer overrides this with per-org values via
53
+ * the request-routing layer.
54
+ */
55
+ tenantMeta?: {
56
+ tenantId: string
57
+ projectId: string
58
+ organizationId: string
59
+ tenantScript?: string
60
+ }
39
61
  }
40
62
 
41
63
  export async function handleWorkerRequest<Id>(
@@ -60,6 +82,48 @@ export async function handleWorkerRequest<Id>(
60
82
  })
61
83
  }
62
84
 
85
+ // POST /api/manifests — register a manifest for an environment.
86
+ if (req.method === "POST" && url.pathname === "/api/manifests") {
87
+ if (!deps.manifestStore) {
88
+ return json(404, { error: "manifests_not_configured" })
89
+ }
90
+ return handleRegisterManifest(req, {
91
+ manifestStore: deps.manifestStore,
92
+ logger: deps.logger,
93
+ })
94
+ }
95
+
96
+ // GET /api/manifests/:env — read the current manifest.
97
+ if (req.method === "GET") {
98
+ const manifestMatch = url.pathname.match(/^\/api\/manifests\/([^/]+)$/)
99
+ if (manifestMatch) {
100
+ if (!deps.manifestStore) {
101
+ return json(404, { error: "manifests_not_configured" })
102
+ }
103
+ const env = decodeURIComponent(manifestMatch[1] ?? "")
104
+ return handleGetManifest(env, {
105
+ manifestStore: deps.manifestStore,
106
+ logger: deps.logger,
107
+ })
108
+ }
109
+ }
110
+
111
+ // POST /api/events — synchronous event ingest. Loads the manifest,
112
+ // routes filters, forwards each match to the run-DO trigger flow.
113
+ if (req.method === "POST" && url.pathname === "/api/events") {
114
+ if (!deps.manifestStore) {
115
+ return json(404, { error: "events_not_configured" })
116
+ }
117
+ return handleIngestEvent(req, {
118
+ manifestStore: deps.manifestStore,
119
+ runDO: deps.runDO,
120
+ idGenerator: deps.idGenerator,
121
+ now: deps.now,
122
+ tenantMeta: deps.tenantMeta,
123
+ logger: deps.logger,
124
+ })
125
+ }
126
+
63
127
  // POST /api/runs — trigger a new run.
64
128
  if (req.method === "POST" && url.pathname === "/api/runs") {
65
129
  let payload: Record<string, unknown>
@@ -1,20 +0,0 @@
1
- import { type StepHandler } from "@voyantjs/workflows-orchestrator";
2
- import type { DispatchNamespaceLike } from "./types.js";
3
- export interface DispatchHandlerDeps {
4
- dispatcher: DispatchNamespaceLike;
5
- /** Optional HMAC signer for the X-Voyant-Dispatch-Auth header. */
6
- sign?: (body: string) => Promise<string> | string;
7
- /** Optional logger for step-level observability. */
8
- logger?: (level: "info" | "warn" | "error", msg: string, data?: object) => void;
9
- /** Base URL to present to the tenant. Defaults to `https://tenant.voyant.internal`. */
10
- baseUrl?: string;
11
- }
12
- /**
13
- * The dispatcher binding expects a name corresponding to the tenant
14
- * script slot. `createDispatchStepHandler` binds the step handler to
15
- * a specific tenant script; different tenants need different handlers
16
- * (trivial via `createDispatchStepHandler(...)` with the script name
17
- * resolved from the run's tenantMeta).
18
- */
19
- export declare function createDispatchStepHandler(tenantScript: string, deps: DispatchHandlerDeps): StepHandler;
20
- //# sourceMappingURL=dispatch-handler.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dispatch-handler.d.ts","sourceRoot":"","sources":["../src/dispatch-handler.ts"],"names":[],"mappings":"AAOA,OAAO,EAEL,KAAK,WAAW,EAEjB,MAAM,kCAAkC,CAAA;AACzC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAEvD,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,qBAAqB,CAAA;IACjC,kEAAkE;IAClE,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAA;IACjD,oDAAoD;IACpD,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/E,uFAAuF;IACvF,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,mBAAmB,GACxB,WAAW,CAgBb"}
@@ -1,31 +0,0 @@
1
- // Builds a `StepHandler` (the thing the orchestrator calls on every
2
- // invocation) by routing the request through a Workers-for-Platforms
3
- // dispatch namespace to the tenant's bundled Worker.
4
- //
5
- // The tenant Worker is expected to mount `@voyantjs/workflows/handler`
6
- // at `POST /__voyant/workflow-step` (see docs/runtime-protocol.md §2.1).
7
- import { createHttpStepHandler, } from "@voyantjs/workflows-orchestrator";
8
- /**
9
- * The dispatcher binding expects a name corresponding to the tenant
10
- * script slot. `createDispatchStepHandler` binds the step handler to
11
- * a specific tenant script; different tenants need different handlers
12
- * (trivial via `createDispatchStepHandler(...)` with the script name
13
- * resolved from the run's tenantMeta).
14
- */
15
- export function createDispatchStepHandler(tenantScript, deps) {
16
- const baseUrl = deps.baseUrl ?? "https://tenant.voyant.internal";
17
- return createHttpStepHandler({
18
- sign: deps.sign ? (body) => deps.sign(body) : undefined,
19
- logger: deps.logger,
20
- resolveTarget(_req) {
21
- const binding = deps.dispatcher.get(tenantScript);
22
- return {
23
- url: `${baseUrl}/__voyant/workflow-step`,
24
- label: tenantScript,
25
- fetch(request) {
26
- return binding.fetch(request);
27
- },
28
- };
29
- },
30
- });
31
- }
@@ -1,51 +0,0 @@
1
- // Builds a `StepHandler` (the thing the orchestrator calls on every
2
- // invocation) by routing the request through a Workers-for-Platforms
3
- // dispatch namespace to the tenant's bundled Worker.
4
- //
5
- // The tenant Worker is expected to mount `@voyantjs/workflows/handler`
6
- // at `POST /__voyant/workflow-step` (see docs/runtime-protocol.md §2.1).
7
-
8
- import {
9
- createHttpStepHandler,
10
- type StepHandler,
11
- type WorkflowStepRequest,
12
- } from "@voyantjs/workflows-orchestrator"
13
- import type { DispatchNamespaceLike } from "./types.js"
14
-
15
- export interface DispatchHandlerDeps {
16
- dispatcher: DispatchNamespaceLike
17
- /** Optional HMAC signer for the X-Voyant-Dispatch-Auth header. */
18
- sign?: (body: string) => Promise<string> | string
19
- /** Optional logger for step-level observability. */
20
- logger?: (level: "info" | "warn" | "error", msg: string, data?: object) => void
21
- /** Base URL to present to the tenant. Defaults to `https://tenant.voyant.internal`. */
22
- baseUrl?: string
23
- }
24
-
25
- /**
26
- * The dispatcher binding expects a name corresponding to the tenant
27
- * script slot. `createDispatchStepHandler` binds the step handler to
28
- * a specific tenant script; different tenants need different handlers
29
- * (trivial via `createDispatchStepHandler(...)` with the script name
30
- * resolved from the run's tenantMeta).
31
- */
32
- export function createDispatchStepHandler(
33
- tenantScript: string,
34
- deps: DispatchHandlerDeps,
35
- ): StepHandler {
36
- const baseUrl = deps.baseUrl ?? "https://tenant.voyant.internal"
37
- return createHttpStepHandler({
38
- sign: deps.sign ? (body) => deps.sign!(body) : undefined,
39
- logger: deps.logger,
40
- resolveTarget(_req: WorkflowStepRequest) {
41
- const binding = deps.dispatcher.get(tenantScript)
42
- return {
43
- url: `${baseUrl}/__voyant/workflow-step`,
44
- label: tenantScript,
45
- fetch(request: Request) {
46
- return binding.fetch(request)
47
- },
48
- }
49
- },
50
- })
51
- }