@workflow-worlds/starter
v0.1.0
Published
Starter template for building Workflow DevKit Worlds
Maintainers
Readme
@workflow-worlds/starter
A complete in-memory World implementation that serves as a starting point for building custom Worlds.
Features
- In-Memory Storage - Runs, steps, events, and hooks stored in Maps
- setTimeout Queue - Simple queue processing via HTTP callbacks
- In-Memory Streamer - Real-time output streaming with event emitters
- Full Test Coverage - Passes all
@workflow/world-testingsuites - Well-Documented - TODO markers show where to add your implementation
Installation
npm install @workflow-worlds/starter
# or
pnpm add @workflow-worlds/starterQuick Start
import { createWorld } from '@workflow-worlds/starter';
const world = createWorld();
// Start queue processing
await world.start();Building Your Own World
The starter is designed to be copied and modified:
1. Copy the starter
cp -r packages/starter my-world
cd my-world2. Update package.json
{
"name": "@myorg/world-custom",
"description": "My custom World implementation"
}3. Verify tests pass
pnpm install
pnpm build
pnpm test4. Replace implementations
Each component has TODO markers showing where to add your backend:
| File | Replace With |
|------|--------------|
| src/storage.ts | Database (MongoDB, PostgreSQL, etc.) |
| src/queue.ts | Job queue (BullMQ, SQS, etc.) |
| src/streamer.ts | Streaming (Redis Streams, WebSockets, etc.) |
5. Test incrementally
Run tests after each change to catch issues early:
pnpm testProject Structure
src/
├── index.ts # World factory and exports
├── storage.ts # Storage implementation (runs, steps, events, hooks)
├── queue.ts # Queue implementation with HTTP callbacks
├── streamer.ts # Output streaming implementation
└── utils.ts # Shared utilities (ID generation, cloning)Configuration
interface StarterWorldConfig {
// Base URL for HTTP callbacks
// Default: http://localhost:${PORT}
baseUrl?: string;
// Port for HTTP callbacks
// Default: process.env.PORT ?? 3000
port?: number;
}Usage with Workflow DevKit
Set the WORKFLOW_TARGET_WORLD environment variable:
WORKFLOW_TARGET_WORLD=@workflow-worlds/starter pnpm devOr export the factory function:
// world.ts
import { createWorld } from '@workflow-worlds/starter';
export default createWorld;Test Suites
The starter passes all five test suites from @workflow/world-testing:
| Suite | Description | Duration | |-------|-------------|----------| | addition | Basic workflow execution | ~12s | | idempotency | State reconstruction with 110 steps | ~30s | | hooks | Hook/resume mechanism | ~15s | | errors | Retry semantics | ~30s | | nullByte | Binary data handling | ~5s |
Run tests:
pnpm testImportant Patterns
Deep Cloning
The starter uses structuredClone() for all returned objects to prevent mutation issues:
// storage.ts
return deepClone(run); // Not the original objectQueue Buffering
Messages queued before start() are buffered and processed once started:
const world = createWorld();
await world.queue(...); // Buffered
await world.start(); // Now processedID Generation
Uses monotonic ULIDs with prefixes for all entities:
const runId = `wrun_${generateUlid()}`;
const stepId = `wstep_${generateUlid()}`;License
MIT
