Skip to content

Commit 6f33d26

Browse files
committed
Rework README
Signed-off-by: paulhenri-l <25308170+paulhenri-l@users.noreply.github.com>
1 parent b35cfcb commit 6f33d26

File tree

2 files changed

+42
-233
lines changed

2 files changed

+42
-233
lines changed

packages/world-postgres/HOW_IT_WORKS.md

Lines changed: 0 additions & 50 deletions
This file was deleted.

packages/world-postgres/README.md

Lines changed: 42 additions & 183 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# @workflow/world-postgres
22

3-
A PostgreSQL-backed workflow runtime for durable, long-running workflows in JavaScript/TypeScript. Designed for multi-host self-hosted solutions with flexible queue and execution strategies.
3+
An embedded worker/workflow system backed by PostgreSQL for multi-host self-hosted solutions
44

55
## Installation
66

@@ -12,52 +12,54 @@ pnpm add @workflow/world-postgres
1212
yarn add @workflow/world-postgres
1313
```
1414

15-
## Quick Start (Next.js)
15+
## Usage
1616

17-
Get started in seconds by adding this to your Next.js project:
17+
### Basic Setup
1818

19-
```typescript
20-
// instrumentation.ts
21-
export async function register() {
22-
if (process.env.NEXT_RUNTIME !== 'edge') {
23-
const { createWorld } = await import("@workflow/world-postgres");
19+
The postgres world can be configured by setting the WORKFLOW_TARGET_WORLD environment variable to the package name.
2420

25-
const world = createWorld();
26-
await world.start();
27-
}
28-
}
21+
```bash
22+
WORKFLOW_TARGET_WORLD="@workflow/world-postgres"
2923
```
3024

31-
Set these environment variables:
25+
### Configuration
26+
27+
Configure the PostgreSQL world using environment variables:
3228

3329
```bash
34-
export WORKFLOW_TARGET_WORLD="@workflow/world-postgres"
35-
export WORKFLOW_POSTGRES_URL="postgres://username:password@localhost:5432/database"
36-
export WORKFLOW_POSTGRES_SECURITY_TOKEN="your-secret-token-here"
37-
export WORKFLOW_POSTGRES_APP_URL="http://localhost:3000"
30+
WORKFLOW_POSTGRES_URL="postgres://username:password@localhost:5432/database"
31+
WORKFLOW_POSTGRES_SECURITY_TOKEN="your-secret-token-here"
32+
WORKFLOW_POSTGRES_APP_URL="http://localhost:3000"
3833
```
3934

40-
**⚠️ IMPORTANT**: Always set a strong `WORKFLOW_POSTGRES_SECURITY_TOKEN` in production. This token authenticates queue workers when they call your workflow endpoints and prevents unauthorized access.
35+
### Programmatic Usage
4136

42-
That's it! The world will automatically use pg-boss for queuing and HTTP proxy for executing workflows.
37+
You can also create a PostgreSQL world directly in your code:
4338

44-
## Architecture
39+
```typescript
40+
import { createWorld, createPgBossQueue } from "@workflow/world-postgres";
4541

46-
This package provides a layered architecture with three key components:
42+
const world = createWorld({
43+
connectionString: "postgres://username:password@localhost:5432/database",
44+
securityToken: "your-secret-token-here",
45+
queueFactorya: createPgBossHttpProxyQueue({
46+
jobPrefix: "my-app",
47+
queueConcurrency: 10,
48+
})
49+
});
50+
```
4751

48-
- **Storage**: Persists workflow state in PostgreSQL (runs, events, steps, hooks, streaming chunks). All tables are isolated in their own PostgreSQL schema.
49-
- **Queue Driver**: Manages job queuing and worker orchestration (default: pg-boss, or bring your own)
50-
- **Proxy Strategy**: Determines how jobs are executed (HTTP calls or direct function invocation)
52+
**⚠️ IMPORTANT**: Always set a strong `WORKFLOW_POSTGRES_SECURITY_TOKEN` in production. This token authenticates queue workers when they call your workflow endpoints and prevents unauthorized access.
5153

52-
## Execution Patterns
54+
## Architecture
5355

54-
The package supports flexible execution patterns based on two dimensions:
56+
The package supports flexible queues and execution patterns, letting you choose how jobs are queued and where the steps and workflows execution will be happen.
5557

5658
### Queue Strategy
5759
- **Built-in pg-boss** (default): Reliable PostgreSQL-backed job queue
5860
- **Custom queue**: Implement your own queue system (Redis, SQS, RabbitMQ, etc.)
5961

60-
### Proxy Strategy
62+
### Execution Proxy Strategy
6163
- **HTTP Proxy**: Workers call workflow endpoints over HTTP (`/.well-known/workflow/v1/flow` and `/.well-known/workflow/v1/step`)
6264
- **Function Proxy**: Workers invoke workflow/step functions directly in-process
6365

@@ -66,11 +68,11 @@ The package supports flexible execution patterns based on two dimensions:
6668
- **Separate Process**: Dedicated worker process(es) for better isolation and scaling
6769
- **Serverless**: Receive messages from your queue and call a proxy to execute workflows
6870

69-
## Configuration Patterns
71+
## Advanced Usage
7072

71-
### Pattern 1: pg-boss + HTTP Proxy (Default)
73+
### pg-boss + HTTP Proxy (Default)
7274

73-
The simplest setup - workers make HTTP calls to your application:
75+
The simplest setup - jobs are queued usning pg-boss and workers make HTTP calls to your application:
7476

7577
```typescript
7678
import { createWorld } from "@workflow/world-postgres";
@@ -100,14 +102,15 @@ const world = createWorld({
100102
});
101103
```
102104

103-
### Pattern 2: pg-boss + Function Proxy
105+
### pg-boss + Function Proxy
104106

105-
Workers call workflow functions directly in the same process - better performance, simpler deployment:
107+
Jobs are using pg-boss and workers directly call workflow functions in the same process
106108

107109
```typescript
110+
const { setWorld } = await import('workflow/runtime');
108111
import { createWorld, createPgBossFunctionProxyQueue } from "@workflow/world-postgres";
109112

110-
// Import entrypoints from your Next.js API routes
113+
// Import entrypoints from your framework API routes
111114
import { __wkf_entrypoint as workflowEntrypoint } from './app/.well-known/workflow/v1/flow/route';
112115
import { __wkf_entrypoint as stepEntrypoint } from './app/.well-known/workflow/v1/step/route';
113116

@@ -119,34 +122,17 @@ const world = createWorld({
119122
}),
120123
});
121124

122-
await world.start();
123-
```
125+
setWorld(world);
124126

125-
**Required Environment Variables:**
126-
```bash
127-
WORKFLOW_POSTGRES_URL="postgres://username:password@localhost:5432/database"
128-
WORKFLOW_POSTGRES_SECURITY_TOKEN="your-secret-token-here"
129-
```
130-
131-
**Optional:**
132-
All configuration can be passed programmatically:
133-
134-
```typescript
135-
createPgBossFunctionProxyQueue({
136-
stepEntrypoint,
137-
workflowEntrypoint,
138-
connectionString: "postgres://...",
139-
securityToken: "your-secret-token",
140-
jobPrefix: "myapp_",
141-
queueConcurrency: 10,
142-
})
127+
await world.start();
143128
```
144129

145-
### Pattern 3: Custom Queue Driver
130+
### Custom Queue Driver + HTTP Proxy
146131

147132
Implement your own queue system for maximum flexibility:
148133

149134
```typescript
135+
const { setWorld } = await import('workflow/runtime');
150136
import { createWorld } from "@workflow/world-postgres";
151137
import type { QueueDriver, MessageData } from "@workflow/world-postgres/queue-drivers/types";
152138

@@ -182,67 +168,12 @@ const world = createWorld({
182168
queueFactory: () => myCustomQueue,
183169
});
184170

185-
await world.start();
186-
```
187-
188-
You can use the helper proxies:
189-
- `createHttpProxy({ baseUrl, securityToken })` - for HTTP execution
190-
- `createFunctionProxy({ stepEntrypoint, workflowEntrypoint, securityToken })` - for in-process execution
191-
192-
See `src/queue-drivers/types.ts` for the full `QueueDriver` interface and `MessageData` structure.
193-
194-
## Execution Environment Examples
195-
196-
### Same Process (Next.js instrumentation.ts)
197-
198-
Run workers in the same process as your Next.js application:
199-
200-
```typescript
201-
// instrumentation.ts
202-
export async function register() {
203-
if (process.env.NEXT_RUNTIME !== 'edge') {
204-
const { createWorld, createPgBossFunctionProxyQueue } =
205-
await import("@workflow/world-postgres");
206-
207-
const { __wkf_entrypoint: workflowEntrypoint } =
208-
await import('./app/.well-known/workflow/v1/flow/route');
209-
const { __wkf_entrypoint: stepEntrypoint } =
210-
await import('./app/.well-known/workflow/v1/step/route');
211-
212-
const world = createWorld({
213-
queueFactory: () =>
214-
createPgBossFunctionProxyQueue({
215-
stepEntrypoint,
216-
workflowEntrypoint,
217-
}),
218-
});
219-
220-
await world.start();
221-
}
222-
}
223-
```
224-
225-
### Separate Worker Process
226-
227-
Run workers in a dedicated process for better isolation:
228-
229-
```typescript
230-
// worker.ts
231-
import { createWorld, createPgBossHttpProxyQueue } from "@workflow/world-postgres";
232-
233-
const world = createWorld({
234-
queueFactory: () =>
235-
createPgBossHttpProxyQueue({
236-
baseUrl: "http://localhost:3000", // Your app URL
237-
}),
238-
});
171+
setWorld(world);
239172

240173
await world.start();
241174
```
242175

243-
Then run: `node worker.ts`
244-
245-
### Serverless
176+
### Serverless execution
246177

247178
In a serverless environment, receive messages from your queue and execute them via proxy:
248179

@@ -333,78 +264,6 @@ All environment variables can be overridden by passing configuration programmati
333264
- **Configurable Concurrency**: Adjustable worker concurrency for queue processing
334265
- **Type-Safe**: Full TypeScript support with exported types
335266

336-
## API Reference
337-
338-
### `createWorld(options)`
339-
340-
Creates a workflow world instance with PostgreSQL storage.
341-
342-
**Options:**
343-
- `connectionString?: string` - PostgreSQL connection string (default: `process.env.WORKFLOW_POSTGRES_URL`)
344-
- `securityToken?: string` - Token for authenticating queue workers (default: `process.env.WORKFLOW_POSTGRES_SECURITY_TOKEN`)
345-
- `queueFactory?: () => QueueDriver` - Factory function to create queue driver (default: `createPgBossHttpProxyQueue()`)
346-
347-
**Returns:** World instance with `start()` method
348-
349-
### Built-in Queue Factories
350-
351-
#### `createPgBossHttpProxyQueue(options)`
352-
353-
Creates a pg-boss queue driver with HTTP proxy execution.
354-
355-
**Options:**
356-
- `connectionString?: string`
357-
- `securityToken?: string`
358-
- `jobPrefix?: string`
359-
- `queueConcurrency?: number`
360-
- `port?: number`
361-
- `baseUrl?: string`
362-
363-
#### `createPgBossFunctionProxyQueue(options)`
364-
365-
Creates a pg-boss queue driver with direct function call execution.
366-
367-
**Options:**
368-
- `stepEntrypoint: (request: Request) => Promise<Response>` - Required
369-
- `workflowEntrypoint: (request: Request) => Promise<Response>` - Required
370-
- `connectionString?: string`
371-
- `securityToken?: string`
372-
- `jobPrefix?: string`
373-
- `queueConcurrency?: number`
374-
375-
### Proxy Helpers
376-
377-
#### `createHttpProxy(options)`
378-
379-
Creates an HTTP proxy for executing workflows via HTTP calls.
380-
381-
**Options:**
382-
- `baseUrl?: string` - Base URL of your application
383-
- `port?: number` - Port (if baseUrl not provided)
384-
- `securityToken: string` - Security token for authentication
385-
386-
#### `createFunctionProxy(options)`
387-
388-
Creates a function proxy for executing workflows via direct function calls.
389-
390-
**Options:**
391-
- `stepEntrypoint: (request: Request) => Promise<Response>` - Required
392-
- `workflowEntrypoint: (request: Request) => Promise<Response>` - Required
393-
- `securityToken: string` - Security token for authentication
394-
395-
## TypeScript Support
396-
397-
All public APIs are fully typed. Import types from the package:
398-
399-
```typescript
400-
import type {
401-
QueueDriver,
402-
MessageData,
403-
WkfProxy,
404-
PostgresWorldConfig
405-
} from "@workflow/world-postgres";
406-
```
407-
408267
## Development
409268

410269
For local development, you can use the included Docker Compose configuration:

0 commit comments

Comments
 (0)