{"_id":"@ataylorme/workflow-world-cloudflare","name":"@ataylorme/workflow-world-cloudflare","dist-tags":{"beta":"1.0.0-beta1","latest":"1.0.0-beta1"},"versions":{"1.0.0-beta1":{"name":"@ataylorme/workflow-world-cloudflare","version":"1.0.0-beta1","description":"Cloudflare Workers world implementation for Workflow DevKit using Durable Objects, D1, and Cloudflare Queues","type":"module","main":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./durable-object":{"types":"./dist/durable-object.d.ts","default":"./dist/durable-object.js"},"./d1":{"types":"./dist/d1.d.ts","default":"./dist/d1.js"}},"publishConfig":{"access":"public"},"license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/ataylorme/workflow-world-cloudflare.git"},"engines":{"node":">=24"},"scripts":{"build":"bash scripts/build.sh","dev":"tsc --watch","check":"biome check .","check:fix":"biome check --write .","test":"vitest run","typecheck":"tsc --noEmit","prepublishOnly":"npm run check && npm run test && npm run build"},"devDependencies":{"@biomejs/biome":"^2.4.8","@cloudflare/workers-types":"^4.20260317.1","@types/node":"^24.0.0","@vercel/ncc":"^0.38.4","@workflow/errors":"^4.1.0-beta.18","@workflow/world":"^4.1.0-beta.13","@workflow/world-local":"^4.1.0-beta.44","typescript":"^5.9.3","ulid":"^2.4.0","vitest":"^4.1.0","zod":"^4.3.6"},"keywords":["cloudflare","workers","durable-objects","workflow","vercel-workflow"],"gitHead":"94c13a59dc62e8a03c28589ed9c1124b0f7a6226","types":"./dist/index.d.ts","_id":"@ataylorme/workflow-world-cloudflare@1.0.0-beta1","bugs":{"url":"https://github.com/ataylorme/workflow-world-cloudflare/issues"},"homepage":"https://github.com/ataylorme/workflow-world-cloudflare#readme","_nodeVersion":"25.2.1","_npmVersion":"11.6.2","dist":{"integrity":"sha512-x6akbihRQuklg3g8ltSLnYHyiV5b/N7TiPbaaPQRuVxR12rIHOUQb9z6Mb0JeQLNS3MwO2P0NNBOGM98jYxR2g==","shasum":"2d65d0b71347fd98efe863498a4ca6cf2b34abb9","tarball":"https://registry.npmjs.org/@ataylorme/workflow-world-cloudflare/-/workflow-world-cloudflare-1.0.0-beta1.tgz","fileCount":24,"unpackedSize":2862348,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCBd06uC/bmouU2657pZ2F53/5E2nP4AgXRVWMMpWjpdwIgLYOFt6RPynm305a4qBOhd6HdRu7gMCpVaZrYGIw6mBE="}]},"_npmUser":{"name":"ataylorme","email":"andrew@ataylor.me"},"directories":{},"maintainers":[{"name":"ataylorme","email":"andrew@ataylor.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/workflow-world-cloudflare_1.0.0-beta1_1774072514323_0.4837759831073003"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-21T05:55:14.217Z","1.0.0-beta1":"2026-03-21T05:55:14.481Z","modified":"2026-03-21T05:55:14.689Z"},"maintainers":[{"name":"ataylorme","email":"andrew@ataylor.me"}],"description":"Cloudflare Workers world implementation for Workflow DevKit using Durable Objects, D1, and Cloudflare Queues","homepage":"https://github.com/ataylorme/workflow-world-cloudflare#readme","keywords":["cloudflare","workers","durable-objects","workflow","vercel-workflow"],"repository":{"type":"git","url":"git+https://github.com/ataylorme/workflow-world-cloudflare.git"},"bugs":{"url":"https://github.com/ataylorme/workflow-world-cloudflare/issues"},"license":"Apache-2.0","readme":"# @ataylorme/workflow-world-cloudflare\n\nA [Workflow DevKit](https://useworkflow.dev) world implementation for Cloudflare Workers, using **Durable Objects** for per-run state, **D1** for cross-run queries, and **Cloudflare Queues** for message dispatch.\n\n## Architecture\n\n- **Durable Objects**: Each workflow run maps to a single Durable Object instance. All run state (events, steps, hooks, waits, stream chunks) lives in the DO's transactional storage.\n- **D1 (SQLite)**: A lightweight global index enables cross-run queries like `runs.list()` and `hooks.getByToken()`. The DO writes index updates to D1 after each mutation.\n- **Cloudflare Queues**: Workflow and step invocations are dispatched through Cloudflare Queues for reliable, at-least-once delivery.\n\n## Setup\n\n### 1. Install\n\n```bash\nnpm add @ataylorme/workflow-world-cloudflare\n```\n\n### 2. Configure bindings\n\nCopy `wrangler.example.toml` and configure your D1 database ID:\n\n```toml\n[durable_objects]\nbindings = [{ name = \"WORKFLOW_RUNS\", class_name = \"WorkflowRunDO\" }]\n\n[[d1_databases]]\nbinding = \"WORKFLOW_DB\"\ndatabase_name = \"workflow\"\ndatabase_id = \"<your-d1-database-id>\"\n\n[[queues.producers]]\nbinding = \"WORKFLOW_QUEUE\"\nqueue = \"workflow-jobs\"\n\n[[queues.consumers]]\nqueue = \"workflow-jobs\"\nmax_batch_size = 10\nmax_retries = 3\n```\n\n### 3. Run D1 migration\n\n```ts\nimport { migrate } from '@ataylorme/workflow-world-cloudflare/d1';\n\n// Run once during setup or in a migration script\nawait migrate(env.WORKFLOW_DB);\n```\n\n### 4. Create the world\n\n```ts\nimport { createWorld, WorkflowRunDO } from '@ataylorme/workflow-world-cloudflare';\n\n// Re-export the DO class so Cloudflare can instantiate it\nexport { WorkflowRunDO };\n\nexport default {\n  async fetch(request, env) {\n    const world = createWorld({\n      db: env.WORKFLOW_DB,\n      runs: env.WORKFLOW_RUNS,\n      queue: env.WORKFLOW_QUEUE,\n    });\n    // Use world with your workflow runtime...\n  },\n\n  async queue(batch, env) {\n    const world = createWorld({\n      db: env.WORKFLOW_DB,\n      runs: env.WORKFLOW_RUNS,\n      queue: env.WORKFLOW_QUEUE,\n    });\n    await world.handleQueueBatch(batch);\n  },\n};\n```\n\n## Limitations\n\n- `events.listByCorrelationId()` requires the `runId` context (inherent to DO-per-run architecture)\n- `steps.get()` requires `runId` (cannot look up steps without knowing which DO to query)\n- `readFromStream()` expects stream names in `runId:streamName` format\n\n## License\n\nApache-2.0\n","readmeFilename":"README.md","_rev":"1-41bdcb1f6a17b15baca4a3fb6f3041c0"}