diff --git a/alchemy-web/docs/providers/cloudflare/workflow.md b/alchemy-web/docs/providers/cloudflare/workflow.md index eef061aa0..2cb25d15f 100644 --- a/alchemy-web/docs/providers/cloudflare/workflow.md +++ b/alchemy-web/docs/providers/cloudflare/workflow.md @@ -20,6 +20,20 @@ const workflow = await Workflow("my-workflow", { }); ``` +## Use a Workflow Defined in Another Script + +Reference a workflow implemented in a different worker script using `scriptName`. + +```ts +import { Workflow } from "alchemy/cloudflare"; + +const workflow = await Workflow("shared-workflow", { + workflowName: "my-workflow", + className: "MyWorkflow", + scriptName: "shared-worker" +}); +``` + ## Bind to a Worker Bind a workflow to a Worker to use its functionality. diff --git a/alchemy/src/cloudflare/worker-metadata.ts b/alchemy/src/cloudflare/worker-metadata.ts index 48384e664..56285c52b 100644 --- a/alchemy/src/cloudflare/worker-metadata.ts +++ b/alchemy/src/cloudflare/worker-metadata.ts @@ -403,8 +403,7 @@ export async function prepareWorkerMetadata( name: bindingName, workflow_name: binding.workflowName, class_name: binding.className, - // this should be set if the Workflow is in another script ... - // script_name: ??, + script_name: binding.scriptName, }); // it's unclear whether this is needed, but it works both ways // configureClassMigration(binding, binding.id, binding.className); diff --git a/alchemy/src/cloudflare/worker.ts b/alchemy/src/cloudflare/worker.ts index 0522bfcac..2c37442f9 100644 --- a/alchemy/src/cloudflare/worker.ts +++ b/alchemy/src/cloudflare/worker.ts @@ -805,7 +805,7 @@ export const _Worker = Resource( await upsertWorkflow(api, { workflowName: workflow.workflowName, className: workflow.className, - scriptName: workerName, + scriptName: workflow.scriptName ?? workerName, }); } diff --git a/alchemy/src/cloudflare/workflow.ts b/alchemy/src/cloudflare/workflow.ts index ae4e6bbc3..d0590daba 100644 --- a/alchemy/src/cloudflare/workflow.ts +++ b/alchemy/src/cloudflare/workflow.ts @@ -19,6 +19,13 @@ export interface WorkflowProps { * @default - workflowName if provided, otherwise id */ className?: string; + + /** + * Name of the script containing the workflow implementation + * + * @default - bound worker script + */ + scriptName?: string; } export function isWorkflow(binding: Binding): binding is Workflow { @@ -36,6 +43,7 @@ export class Workflow { public readonly workflowName: string; public readonly className: string; + public readonly scriptName?: string; constructor( public readonly id: string, @@ -43,6 +51,7 @@ export class Workflow { ) { this.workflowName = props.workflowName ?? props.className ?? id; this.className = props.className ?? this.workflowName; + this.scriptName = props.scriptName; } } diff --git a/alchemy/src/cloudflare/wrangler.json.ts b/alchemy/src/cloudflare/wrangler.json.ts index e07afcba9..dbe19e1a4 100644 --- a/alchemy/src/cloudflare/wrangler.json.ts +++ b/alchemy/src/cloudflare/wrangler.json.ts @@ -261,6 +261,7 @@ export interface WranglerJsonSpec { name: string; binding: string; class_name: string; + script_name?: string; }[]; /** @@ -366,7 +367,12 @@ function processBindings( const services: { binding: string; service: string; environment?: string }[] = []; const secrets: string[] = []; - const workflows: { name: string; binding: string; class_name: string }[] = []; + const workflows: { + name: string; + binding: string; + class_name: string; + script_name?: string; + }[] = []; const d1Databases: { binding: string; database_id: string; @@ -481,6 +487,7 @@ function processBindings( name: binding.workflowName, binding: bindingName, class_name: binding.className, + script_name: binding.scriptName, }); } else if (binding.type === "d1") { d1Databases.push({ diff --git a/alchemy/test/cloudflare/wrangler-json.test.ts b/alchemy/test/cloudflare/wrangler-json.test.ts index 7e2fee161..6a0c7e970 100644 --- a/alchemy/test/cloudflare/wrangler-json.test.ts +++ b/alchemy/test/cloudflare/wrangler-json.test.ts @@ -325,6 +325,7 @@ describe("WranglerJson Resource", () => { const workflow = new Workflow("test-workflow", { className: "TestWorkflow", workflowName: "test-workflow", + scriptName: "other-script", }); const worker = await Worker(name, { @@ -345,6 +346,7 @@ describe("WranglerJson Resource", () => { expect(spec.workflows?.[0].name).toEqual("test-workflow"); expect(spec.workflows?.[0].binding).toEqual("WF"); expect(spec.workflows?.[0].class_name).toEqual("TestWorkflow"); + expect(spec.workflows?.[0].script_name).toEqual("other-script"); } finally { await fs.rm(tempDir, { recursive: true, force: true }); await destroy(scope);