How the RankCheckWorkflow Class Enables Cross-Script Binding Between Main and Auxiliary Workers
The RankCheckWorkflow class enables cross-script binding by extending Cloudflare's WorkflowEntrypoint base class, allowing the same TypeScript implementation to be registered as a callable binding in both the main (open_seo) and auxiliary (open_seo_audit) workers through coordinated Wrangler configuration and a lean-worker bundler plugin.
The every-app/open-seo repository implements a distributed architecture on Cloudflare Workers where heavy rank-checking operations are offloaded to auxiliary workers to keep the main script lightweight. Cross-script binding allows the main worker to invoke methods on the RankCheckWorkflow class as if it were local code, even when the actual execution occurs within the open_seo_audit auxiliary worker, enabling seamless distribution of computational load.
Extending WorkflowEntrypoint for Cross-Script Registration
The foundation of cross-script binding lies in the WorkflowEntrypoint base class provided by Cloudflare Workers. In src/server/workflows/RankCheckWorkflow.ts at lines 62-66, the class is exported with the following declaration:
export class RankCheckWorkflow extends WorkflowEntrypoint<Env, RankCheckParams> {
// Implementation details...
}
By extending WorkflowEntrypoint, the class automatically registers itself under a specific script name within the Cloudflare runtime. This registration exposes a canonical run method that the system can invoke from any worker possessing a binding to that script. The generic type parameters ensure that both the main and auxiliary workers share the same environment (Env) and payload types, maintaining type safety across worker boundaries.
Configuring the Auxiliary Worker Binding
Cross-script binding requires explicit declaration of the auxiliary worker relationship within the build system. The project defines the open_seo_audit auxiliary worker in vite.config.ts within the auxiliaryWorkers array at lines 58-62:
auxiliaryWorkers: [{ configPath: "./wrangler.audit.jsonc" }],
This configuration instructs Wrangler to compile the source tree into a separate script while exposing its exports as bindings that the main worker can import. The wrangler.audit.jsonc file provides the specific Wrangler configuration for the audit worker, ensuring that its exported symbols—including RankCheckWorkflow—are available as callable bindings to other workers in the project.
Lean-Worker Bundling and Import Resolution
The actual mechanism that enables the main worker to import auxiliary worker code resides in vite-plugin-lean-worker-bundle.ts. At line 112, the plugin handles the generation of lean bundles for both the main worker (referenced as "ssr") and the auxiliary worker ("open_seo_audit").
The plugin ensures that shared code, including the RankCheckWorkflow class definition, remains identical across both bundles. It then rewrites import paths so that the main worker can access the auxiliary worker's exports through a generated binding object, using the special workers: protocol namespace.
Executing Workflows Across Worker Boundaries
Invoking from the Main Worker
Because the bundler compiles the same source file into both workers, the main script can instantiate and execute the workflow using standard syntax. The Cloudflare runtime automatically routes the call to the auxiliary worker:
// Inside the main worker (open_seo)
import { RankCheckWorkflow } from "workers:open_seo_audit";
async function startRankCheck(payload: RankCheckParams) {
const wf = new RankCheckWorkflow();
// Runtime routes this call to the auxiliary worker
await wf.run({ payload, scheduledTime: Date.now() } as any, {} as any);
}
Updates to RankCheckWorkflow logic—such as changes to prepareRankCheckKeywords or database step handling—automatically propagate to both contexts without code duplication, ensuring the binding remains synchronized.
Execution Context in the Auxiliary Worker
The workflow itself remains agnostic to which worker actually executes the code. When running inside the open_seo_audit auxiliary worker, the same class definition handles the heavy lifting:
// Inside the auxiliary worker (open_seo_audit)
export class RankCheckWorkflow extends WorkflowEntrypoint<Env, RankCheckParams> {
async run(event: WorkflowEvent<RankCheckParams>, step: WorkflowStep) {
// Database operations and API calls execute here
await step.do("fetch-rankings", async () => {
// Implementation using withPgClient
});
}
}
The workflow retains access to shared utilities such as withPgClient, pgStep, and the DataForSEO client regardless of execution context. This architecture delegates resource-intensive operations to the auxiliary worker while presenting a unified interface to the main application.
Summary
- The
RankCheckWorkflowclass extendsWorkflowEntrypointinsrc/server/workflows/RankCheckWorkflow.ts(lines 62-66) to register a callable entry point accessible from any bound worker script. - The
vite.config.tsfile declares theopen_seo_auditauxiliary worker via theauxiliaryWorkersarray (lines 58-62), enabling Wrangler to expose auxiliary exports as bindings. - The
vite-plugin-lean-worker-bundle.tsplugin (line 112) compiles shared code into both workers and generates binding objects that allow import via theworkers:open_seo_auditprotocol. - Cross-script calls use standard instantiation and method invocation (
new RankCheckWorkflow().run()), with the Cloudflare runtime automatically routing execution to the appropriate worker script while preserving the sharedEnvand utility functions.
Frequently Asked Questions
What is cross-script binding in Cloudflare Workers?
Cross-script binding is a mechanism that allows one worker script to call code exported by another worker script as if it were a local function. In the every-app/open-seo project, this enables the main worker to invoke the RankCheckWorkflow class that physically resides in the open_seo_audit auxiliary worker bundle, facilitating distributed execution of heavy computational tasks without blocking the main application thread.
Why does RankCheckWorkflow extend WorkflowEntrypoint?
Extending WorkflowEntrypoint registers the class with Cloudflare's workflow runtime and exposes a standardized run method that can be invoked across worker boundaries. This base class handles the underlying protocol for cross-script communication, allowing the RankCheckWorkflow to execute in either the main or auxiliary context without modification to its core logic or database access patterns.
How does the main worker import classes from the auxiliary worker?
The main worker imports auxiliary worker exports using the workers: protocol followed by the worker name, specifically import { RankCheckWorkflow } from "workers:open_seo_audit". This import is made possible by the lean-worker bundler plugin, which generates the necessary binding objects during the build process defined in vite.config.ts, allowing TypeScript to resolve the module path at compile time while the runtime handles the cross-worker dispatch.
Where is the auxiliary worker configuration defined?
The auxiliary worker configuration is defined in two locations: the vite.config.ts file contains the auxiliaryWorkers array referencing ./wrangler.audit.jsonc (lines 58-62), while the actual Wrangler-specific settings for the audit worker reside in wrangler.audit.jsonc. Together, these files instruct the build system to compile the auxiliary script and expose its exports for cross-script binding with the main open_seo worker.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →