# How the RankCheckWorkflow Class Enables Cross-Script Binding Between Main and Auxiliary Workers

> Learn how the RankCheckWorkflow class enables cross-script binding between main and auxiliary workers using Cloudflare's WorkflowEntrypoint for seamless TypeScript integration.

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: internals
- Published: 2026-09-12

---

**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`](https://github.com/every-app/open-seo/blob/main/src/server/workflows/RankCheckWorkflow.ts) at lines 62-66, the class is exported with the following declaration:

```typescript
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`](https://github.com/every-app/open-seo/blob/main/vite.config.ts) within the `auxiliaryWorkers` array at lines 58-62:

```typescript
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`](https://github.com/every-app/open-seo/blob/main/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:

```typescript
// 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:

```typescript
// 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 `RankCheckWorkflow` class extends `WorkflowEntrypoint` in [`src/server/workflows/RankCheckWorkflow.ts`](https://github.com/every-app/open-seo/blob/main/src/server/workflows/RankCheckWorkflow.ts) (lines 62-66) to register a callable entry point accessible from any bound worker script.
- The [`vite.config.ts`](https://github.com/every-app/open-seo/blob/main/vite.config.ts) file declares the `open_seo_audit` auxiliary worker via the `auxiliaryWorkers` array (lines 58-62), enabling Wrangler to expose auxiliary exports as bindings.
- The [`vite-plugin-lean-worker-bundle.ts`](https://github.com/every-app/open-seo/blob/main/vite-plugin-lean-worker-bundle.ts) plugin (line 112) compiles shared code into both workers and generates binding objects that allow import via the `workers:open_seo_audit` protocol.
- 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 shared `Env` and 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`](https://github.com/every-app/open-seo/blob/main/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`](https://github.com/every-app/open-seo/blob/main/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.