@ewhauser/world-celld 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/README.md +47 -19
- package/celld-worker/README.md +5 -3
- package/celld-worker/worker.ts +10 -1
- package/celld-worker/wrangler.jsonc +15 -4
- package/dist/index.d.ts +163 -60
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +524 -197
- package/dist/index.js.map +1 -1
- package/dist/testing.d.ts +47 -0
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +1874 -582
- package/dist/testing.js.map +1 -1
- package/dist/util-DmO0XkFw.js +545 -0
- package/dist/util-DmO0XkFw.js.map +1 -0
- package/dist/worker.d.ts +223 -111
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +1960 -551
- package/dist/worker.js.map +1 -1
- package/package.json +7 -5
- package/dist/retention-bLY1vcOu.js +0 -164
- package/dist/retention-bLY1vcOu.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## 0.3.1 (2026-08-19)
|
|
6
|
+
|
|
7
|
+
## What's Changed
|
|
8
|
+
* perf: reduce runs.list RPC fanout by @ewhauser in https://github.com/ewhauser/world-celld/pull/21
|
|
9
|
+
* perf: remove unused correlation index by @ewhauser in https://github.com/ewhauser/world-celld/pull/23
|
|
10
|
+
* perf: bound QueueDO inflight deadline work by @ewhauser in https://github.com/ewhauser/world-celld/pull/24
|
|
11
|
+
* chore(deps-dev): bump @types/node from 22.20.1 to 26.1.2 by @dependabot[bot] in https://github.com/ewhauser/world-celld/pull/4
|
|
12
|
+
* chore(deps-dev): bump the development-dependencies group across 1 directory with 2 updates by @dependabot[bot] in https://github.com/ewhauser/world-celld/pull/25
|
|
13
|
+
* perf: batch and long-poll stream I/O by @ewhauser in https://github.com/ewhauser/world-celld/pull/26
|
|
14
|
+
* perf: bound cleanup and batch Durable Object storage by @ewhauser in https://github.com/ewhauser/world-celld/pull/27
|
|
15
|
+
* perf: shard workflow indexes by @ewhauser in https://github.com/ewhauser/world-celld/pull/28
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
**Full Changelog**: https://github.com/ewhauser/world-celld/compare/v0.3.0...v0.3.1
|
|
19
|
+
|
|
20
|
+
## 0.3.0 (2026-08-16)
|
|
21
|
+
|
|
22
|
+
## What's Changed
|
|
23
|
+
* fix: split Release Please release and PR phases by @ewhauser in https://github.com/ewhauser/world-celld/pull/16
|
|
24
|
+
* feat: target Workflow 5 beta by @ewhauser in https://github.com/ewhauser/world-celld/pull/17
|
|
25
|
+
* fix: enforce Workflow 5 storage contracts by @ewhauser in https://github.com/ewhauser/world-celld/pull/19
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
**Full Changelog**: https://github.com/ewhauser/world-celld/compare/v0.2.0...v0.3.0
|
|
29
|
+
|
|
5
30
|
## 0.2.0 (2026-08-16)
|
|
6
31
|
|
|
7
32
|
## What's Changed
|
package/README.md
CHANGED
|
@@ -115,39 +115,60 @@ More deployment detail is in [`celld-worker/README.md`](./celld-worker/README.md
|
|
|
115
115
|
```text
|
|
116
116
|
Workflow application
|
|
117
117
|
|
|
|
118
|
-
| authenticated HTTP RPC
|
|
118
|
+
| authenticated HTTP RPC + binary stream batches
|
|
119
119
|
v
|
|
120
120
|
celld worker router
|
|
121
121
|
|-- WorkflowRunDO one cell per workflow run
|
|
122
|
+
|-- RunCatalogDO 16 stable run-id shards; merged ordered listing
|
|
123
|
+
|-- RunFenceDO one lifecycle fence cell per workflow run
|
|
124
|
+
|-- HookTokenDO 32 stable token-ownership shards
|
|
125
|
+
|-- HookIdDO 32 stable hook-id lookup shards
|
|
122
126
|
|-- StreamDO stream chunks and run/stream indexes
|
|
123
|
-
|-- IndexDO run and hook lookup indexes
|
|
124
127
|
`-- QueueDO delayed delivery, retries, and dead letters
|
|
125
128
|
|
|
|
126
129
|
| HTTP callbacks
|
|
127
130
|
v
|
|
128
|
-
Workflow application /.well-known/workflow/v1/
|
|
131
|
+
Workflow application /.well-known/workflow/v1/flow
|
|
129
132
|
```
|
|
130
133
|
|
|
131
134
|
The application-side package implements the Workflow `World` interface and
|
|
132
|
-
translates its storage
|
|
133
|
-
|
|
134
|
-
|
|
135
|
+
translates its storage and queue operations into JSON RPC calls. Stream chunk
|
|
136
|
+
writes and bounded long-poll reads use a binary batch route; stream control and
|
|
137
|
+
retention operations remain fixed, authenticated RPC methods. The worker routes
|
|
138
|
+
each request to the named cell that owns the data.
|
|
139
|
+
|
|
140
|
+
Index routing is a versioned hard-cutover protocol. Run catalog writes hash the
|
|
141
|
+
`runId` across 16 shards, while hook ownership and hook-ID lookup hash their
|
|
142
|
+
natural keys across 32 shards each. A single stateless worker request queries
|
|
143
|
+
all 16 catalog shards in parallel and merges their lexicographic pages before
|
|
144
|
+
authoritative RunDO reads. A terminal or expired run is hidden through its own
|
|
145
|
+
`RunFenceDO`, so no global fence cell remains. Token and hook-ID admission are
|
|
146
|
+
each transactional inside their natural-key shards. The RunDO remains the
|
|
147
|
+
authoritative commit domain, and exact claim IDs plus a serialized cancellation
|
|
148
|
+
fence resolve ambiguous delivery without pretending the two ownership shards
|
|
149
|
+
form a cross-Durable-Object transaction. Stateless cohesive index routes keep
|
|
150
|
+
catalog listing, terminal commits, hook finalization, and hook release to one
|
|
151
|
+
public request each while exposing the internal shard work in measurements.
|
|
152
|
+
|
|
153
|
+
The routing rationale and before/after RPC, storage, latency, and contention
|
|
154
|
+
evidence are recorded in [`docs/index-sharding.md`](./docs/index-sharding.md).
|
|
135
155
|
|
|
136
156
|
## Configuration
|
|
137
157
|
|
|
138
158
|
Application options can be passed to `createCelldWorld()` unless an environment
|
|
139
159
|
variable is shown below.
|
|
140
160
|
|
|
141
|
-
| Option
|
|
142
|
-
|
|
|
143
|
-
| `fleetUrl`
|
|
144
|
-
| `secret`
|
|
145
|
-
| `baseUrl`
|
|
146
|
-
| `deploymentId`
|
|
147
|
-
| `queueShards`
|
|
148
|
-
| `runRetentionMs`
|
|
149
|
-
| `
|
|
150
|
-
| `
|
|
161
|
+
| Option | Environment variable | Default |
|
|
162
|
+
| ----------------------- | ------------------------ | ------------------------ |
|
|
163
|
+
| `fleetUrl` | `CELLD_FLEET_URL` | required |
|
|
164
|
+
| `secret` | `CELLD_WORLD_SECRET` | required with `fleetUrl` |
|
|
165
|
+
| `baseUrl` | `WORKFLOW_BASE_URL` | `http://localhost:$PORT` |
|
|
166
|
+
| `deploymentId` | `CELLD_DEPLOYMENT_ID` | `celld-default` |
|
|
167
|
+
| `queueShards` | — | `1` |
|
|
168
|
+
| `runRetentionMs` | `CELLD_RUN_RETENTION_MS` | `0` (disabled) |
|
|
169
|
+
| `streamLongPollMs` | — | `20000` |
|
|
170
|
+
| `streamFlushIntervalMs` | — | `0` |
|
|
171
|
+
| `rpcTimeoutMs` | — | `30000` |
|
|
151
172
|
|
|
152
173
|
The deployed worker also accepts these celld variables:
|
|
153
174
|
|
|
@@ -156,7 +177,7 @@ The deployed worker also accepts these celld variables:
|
|
|
156
177
|
| `WORLD_SECRET` | none | Required bearer secret for RPC routes |
|
|
157
178
|
| `WORKFLOW_CALLBACK_SECRET` | none | Sent with deliveries as `x-workflow-callback-secret` |
|
|
158
179
|
| `QUEUE_MAX_ATTEMPTS` | `5` | Attempts before a message is dead-lettered |
|
|
159
|
-
| `QUEUE_MAX_INFLIGHT` | `5` | Concurrent deliveries per queue cell
|
|
180
|
+
| `QUEUE_MAX_INFLIGHT` | `5` | Concurrent deliveries per queue cell (maximum `128`) |
|
|
160
181
|
| `QUEUE_DELIVERY_TIMEOUT_MS` | `300000` | Timeout for an application callback |
|
|
161
182
|
|
|
162
183
|
`queueShards` is part of queue placement and is pinned when a queue cell is
|
|
@@ -171,8 +192,13 @@ pending runs are never eligible for automatic cleanup.
|
|
|
171
192
|
|
|
172
193
|
At expiration, the run cell fences new writes and removes the run's derived
|
|
173
194
|
indexes, stream chunks, pending and dead-letter queue messages, and durable run
|
|
174
|
-
payloads. Cleanup is a persisted, idempotent state machine
|
|
175
|
-
|
|
195
|
+
payloads. Cleanup is a persisted, idempotent state machine. Each alarm processes
|
|
196
|
+
one bounded page, persists its progress, and re-arms the next alarm; an
|
|
197
|
+
interrupted phase records its error and retries with capped backoff.
|
|
198
|
+
|
|
199
|
+
Terminal hook and wait disposal uses the same alarm mechanism even when run
|
|
200
|
+
retention is disabled, so a terminal event never performs an unbounded storage
|
|
201
|
+
transaction.
|
|
176
202
|
|
|
177
203
|
The final state is a metadata-only tombstone, not an empty cell. It prevents a
|
|
178
204
|
delayed queue delivery or stale RPC from recreating an expired run. Reads and
|
|
@@ -199,6 +225,8 @@ an existing terminal run that has no cleanup record.
|
|
|
199
225
|
must be idempotent.
|
|
200
226
|
- Queue cells expose `stats`, `listDeadLetters`, `redriveDeadLetter`,
|
|
201
227
|
`purgeDeadLetters`, and `rearmAlarm` through the authenticated RPC endpoint.
|
|
228
|
+
`purgeDeadLetters` deletes at most 128 entries per call; repeat it while its
|
|
229
|
+
result reports `hasMore`.
|
|
202
230
|
- Run cells expose retention status, scheduling, immediate cleanup, and alarm
|
|
203
231
|
recovery through `world.retention`.
|
|
204
232
|
- A new application URL applies to newly enqueued messages. Existing messages
|
package/celld-worker/README.md
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# world-celld worker
|
|
2
2
|
|
|
3
|
-
The celld-deployable half of `@ewhauser/world-celld`:
|
|
4
|
-
(WorkflowRunDO,
|
|
5
|
-
router.
|
|
3
|
+
The celld-deployable half of `@ewhauser/world-celld`: seven cell classes
|
|
4
|
+
(WorkflowRunDO, RunCatalogDO, RunFenceDO, HookTokenDO, HookIdDO, StreamDO, and
|
|
5
|
+
QueueDO) behind an authenticated HTTP router.
|
|
6
|
+
Storage, control, and queue methods use fixed JSON RPC routes; stream chunks use
|
|
7
|
+
bounded binary batch writes and binary long-poll reads.
|
|
6
8
|
|
|
7
9
|
## Deploy
|
|
8
10
|
|
package/celld-worker/worker.ts
CHANGED
|
@@ -2,4 +2,13 @@
|
|
|
2
2
|
// project directory; this one-liner resolves the real worker through the
|
|
3
3
|
// application's node_modules so the deployed bundle stays in step with the
|
|
4
4
|
// installed @ewhauser/world-celld version.
|
|
5
|
-
export {
|
|
5
|
+
export {
|
|
6
|
+
HookIdDO,
|
|
7
|
+
HookTokenDO,
|
|
8
|
+
QueueDO,
|
|
9
|
+
RunCatalogDO,
|
|
10
|
+
RunFenceDO,
|
|
11
|
+
StreamDO,
|
|
12
|
+
WorkflowRunDO,
|
|
13
|
+
default,
|
|
14
|
+
} from '@ewhauser/world-celld/worker';
|
|
@@ -9,19 +9,30 @@
|
|
|
9
9
|
"bindings": [
|
|
10
10
|
{ "name": "WORKFLOW_DB", "class_name": "WorkflowRunDO" },
|
|
11
11
|
{ "name": "WORKFLOW_STREAMS", "class_name": "StreamDO" },
|
|
12
|
-
{ "name": "
|
|
12
|
+
{ "name": "WORKFLOW_RUN_CATALOG", "class_name": "RunCatalogDO" },
|
|
13
|
+
{ "name": "WORKFLOW_RUN_FENCES", "class_name": "RunFenceDO" },
|
|
14
|
+
{ "name": "WORKFLOW_HOOK_TOKENS", "class_name": "HookTokenDO" },
|
|
15
|
+
{ "name": "WORKFLOW_HOOK_IDS", "class_name": "HookIdDO" },
|
|
13
16
|
{ "name": "WORKFLOW_QUEUE", "class_name": "QueueDO" },
|
|
14
17
|
],
|
|
15
18
|
},
|
|
16
19
|
"migrations": [
|
|
17
20
|
{
|
|
18
21
|
"tag": "v1",
|
|
19
|
-
"new_sqlite_classes": [
|
|
22
|
+
"new_sqlite_classes": [
|
|
23
|
+
"WorkflowRunDO",
|
|
24
|
+
"StreamDO",
|
|
25
|
+
"RunCatalogDO",
|
|
26
|
+
"RunFenceDO",
|
|
27
|
+
"HookTokenDO",
|
|
28
|
+
"HookIdDO",
|
|
29
|
+
"QueueDO",
|
|
30
|
+
],
|
|
20
31
|
},
|
|
21
32
|
],
|
|
22
33
|
"vars": {
|
|
23
|
-
// REQUIRED: bearer secret for the world's RPC surface.
|
|
24
|
-
// routes fail closed with 503 while this is empty. Inject the real value
|
|
34
|
+
// REQUIRED: bearer secret for the world's RPC and binary stream surface.
|
|
35
|
+
// Authenticated routes fail closed with 503 while this is empty. Inject the real value
|
|
25
36
|
// at the node level with CELLD_VAR_WORLD_SECRET instead of committing it.
|
|
26
37
|
"WORLD_SECRET": "",
|
|
27
38
|
// Optional: forwarded as x-workflow-callback-secret on queue deliveries.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CreateEventRequest, Event, Hook, RunCreatedEventRequest, Step, TerminalWorkflowRunStatus, ValidQueueName, WorkflowRun, World } from "@workflow/world";
|
|
1
|
+
import { CreateEventParams, CreateEventRequest, Event, GetChunksOptions, Hook, RunCreatedEventRequest, Step, StreamChunksResponse, StreamInfoResponse, Streamer, TerminalWorkflowRunStatus, ValidQueueName, Wait, WorkflowRun, World } from "@workflow/world";
|
|
2
2
|
//#region src/retention.d.ts
|
|
3
3
|
type CleanupPhase = 'retained' | 'index' | 'streams' | 'queues' | 'payload' | 'tombstoned';
|
|
4
4
|
interface CleanupRecord {
|
|
@@ -11,6 +11,8 @@ interface CleanupRecord {
|
|
|
11
11
|
dueAt: Date;
|
|
12
12
|
queueShards: number;
|
|
13
13
|
phase: CleanupPhase;
|
|
14
|
+
/** Optimistic-concurrency token for alarm/RPC work that awaits another cell. */
|
|
15
|
+
generation: number;
|
|
14
16
|
attempts: number;
|
|
15
17
|
lastError?: string;
|
|
16
18
|
lastAttemptAt?: Date;
|
|
@@ -40,6 +42,15 @@ interface HookIndexReference {
|
|
|
40
42
|
hookId: string;
|
|
41
43
|
token: string;
|
|
42
44
|
}
|
|
45
|
+
interface ReleaseHookIndexesRequest {
|
|
46
|
+
runId: string;
|
|
47
|
+
hooks: HookIndexReference[];
|
|
48
|
+
/** Install a fence that prevents delayed hook finalization after terminal state. */
|
|
49
|
+
terminal: boolean;
|
|
50
|
+
}
|
|
51
|
+
interface ReleaseHookIndexesResult {
|
|
52
|
+
deleted: number;
|
|
53
|
+
}
|
|
43
54
|
interface ExpireRunIndexesRequest {
|
|
44
55
|
runId: string;
|
|
45
56
|
keys: string[];
|
|
@@ -52,12 +63,24 @@ interface ExpireRunIndexesResult {
|
|
|
52
63
|
interface ExpireRunStreamsResult {
|
|
53
64
|
streams: string[];
|
|
54
65
|
}
|
|
66
|
+
interface FinalizeRunStreamsResult {
|
|
67
|
+
/** Cumulative registry entries removed for this run. */
|
|
68
|
+
deleted: number;
|
|
69
|
+
done: boolean;
|
|
70
|
+
}
|
|
55
71
|
interface ExpireStreamResult {
|
|
72
|
+
/** True only when this call installed the stream's expiration fence. */
|
|
56
73
|
deleted: boolean;
|
|
74
|
+
/** Chunk rows removed by this bounded call. */
|
|
57
75
|
chunks: number;
|
|
76
|
+
/** Payload bytes represented by the removed chunk rows. */
|
|
77
|
+
bytes: number;
|
|
78
|
+
done: boolean;
|
|
58
79
|
}
|
|
59
80
|
interface ExpireQueueRunResult {
|
|
81
|
+
/** Cumulative messages removed for this run in this queue shard. */
|
|
60
82
|
deleted: number;
|
|
83
|
+
done: boolean;
|
|
61
84
|
}
|
|
62
85
|
interface ScheduleCleanupRequest {
|
|
63
86
|
retentionMs: number;
|
|
@@ -69,18 +92,22 @@ interface ApplyEventRequest {
|
|
|
69
92
|
/** The effective run id (already resolved / generated by the caller). */
|
|
70
93
|
runId: string;
|
|
71
94
|
data: CreateEventRequest | RunCreatedEventRequest;
|
|
95
|
+
/** Workflow 5 event-log position and preload options. */
|
|
96
|
+
params?: CreateEventParams;
|
|
72
97
|
/**
|
|
73
|
-
* Current holder of the hook token per the
|
|
98
|
+
* Current holder of the hook token per the sharded token-ownership index
|
|
74
99
|
* (hook_created only). `null` means the token is unclaimed.
|
|
75
100
|
*/
|
|
76
101
|
tokenHolder?: {
|
|
77
102
|
runId: string;
|
|
78
103
|
hookId: string;
|
|
79
104
|
} | null;
|
|
105
|
+
/** Exact token/ID reservation fenced on ambiguous-delivery resolution. */
|
|
106
|
+
hookClaimId?: string;
|
|
80
107
|
/** Internal world-celld retention policy captured with the event. */
|
|
81
108
|
cleanup?: ScheduleCleanupRequest;
|
|
82
109
|
}
|
|
83
|
-
type ApplyEventErrorCode = 'RUN_NOT_FOUND' | 'STEP_NOT_FOUND' | 'HOOK_NOT_FOUND' | 'ENTITY_CONFLICT' | '
|
|
110
|
+
type ApplyEventErrorCode = 'RUN_NOT_FOUND' | 'STEP_NOT_FOUND' | 'HOOK_NOT_FOUND' | 'WAIT_NOT_FOUND' | 'ENTITY_CONFLICT' | 'HOOK_CLAIM_CANCELLED' | 'RUN_EXPIRED' | 'TOO_EARLY' | 'RUN_NOT_SUPPORTED';
|
|
84
111
|
interface ApplyEventFailure {
|
|
85
112
|
ok: false;
|
|
86
113
|
code: ApplyEventErrorCode;
|
|
@@ -97,7 +124,10 @@ interface ApplyEventSuccess {
|
|
|
97
124
|
run?: WorkflowRun;
|
|
98
125
|
step?: Step;
|
|
99
126
|
hook?: Hook;
|
|
100
|
-
|
|
127
|
+
wait?: Wait;
|
|
128
|
+
/** True when a lazy step_started atomically created its step. */
|
|
129
|
+
stepCreated?: true;
|
|
130
|
+
/** Hooks whose token and ID indexes must be released. */
|
|
101
131
|
releasedHooks: Array<{
|
|
102
132
|
hookId: string;
|
|
103
133
|
token: string;
|
|
@@ -107,10 +137,15 @@ interface ApplyEventSuccess {
|
|
|
107
137
|
workflowName: string;
|
|
108
138
|
createdAt: Date;
|
|
109
139
|
};
|
|
110
|
-
/** Set when the
|
|
140
|
+
/** Set when the sharded hook indexes must be (re)written. */
|
|
111
141
|
hookToIndex?: Hook;
|
|
112
142
|
/** All events (ascending), preloaded for run_started responses. */
|
|
113
143
|
events?: Event[];
|
|
144
|
+
/** Pagination metadata required whenever events are returned. */
|
|
145
|
+
cursor?: string | null;
|
|
146
|
+
hasMore?: boolean;
|
|
147
|
+
/** Server-owned event ceiling advertised on run lifecycle writes. */
|
|
148
|
+
maxEvents?: number;
|
|
114
149
|
}
|
|
115
150
|
type ApplyEventOutcome = ApplyEventSuccess | ApplyEventFailure;
|
|
116
151
|
//#endregion
|
|
@@ -121,6 +156,13 @@ type ApplyEventOutcome = ApplyEventSuccess | ApplyEventFailure;
|
|
|
121
156
|
*/
|
|
122
157
|
interface WorkflowRunDOStub {
|
|
123
158
|
applyEvent(request: ApplyEventRequest): Promise<ApplyEventOutcome>;
|
|
159
|
+
resolveHookTokenClaim(request: {
|
|
160
|
+
hookId: string;
|
|
161
|
+
token: string;
|
|
162
|
+
claimId: string;
|
|
163
|
+
}): Promise<{
|
|
164
|
+
committed: boolean;
|
|
165
|
+
}>;
|
|
124
166
|
getRun(): Promise<RunReadOutcome<WorkflowRun | null>>;
|
|
125
167
|
getStep(stepId: string): Promise<RunReadOutcome<Step | null>>;
|
|
126
168
|
getEvent(eventId: string): Promise<RunReadOutcome<Event | null>>;
|
|
@@ -164,32 +206,74 @@ interface DurableObjectIdLike {
|
|
|
164
206
|
toString(): string;
|
|
165
207
|
}
|
|
166
208
|
//#endregion
|
|
209
|
+
//#region src/stream-protocol.d.ts
|
|
210
|
+
/** Metadata plus payload and size-index entries remain below the 128-key platform limit. */
|
|
211
|
+
declare const MAX_STREAM_WRITE_CHUNKS = 32;
|
|
212
|
+
/** A chunk remains below the 2 MiB SQLite-backed DO key/value limit. */
|
|
213
|
+
declare const MAX_STREAM_CHUNK_BYTES: number;
|
|
214
|
+
/** Keeps serialized RPC bodies well below the 32 MiB Workers RPC limit. */
|
|
215
|
+
declare const MAX_STREAM_BATCH_BYTES: number;
|
|
216
|
+
declare const MAX_STREAM_READ_CHUNKS = 32;
|
|
217
|
+
declare const MAX_STREAM_READ_BYTES: number;
|
|
218
|
+
declare const MAX_STREAM_ERROR_BYTES: number;
|
|
219
|
+
/** Must remain below the default 30 second fleet request deadline. */
|
|
220
|
+
declare const MAX_STREAM_LONG_POLL_MS = 20000;
|
|
221
|
+
type StreamTerminalState = 'open' | 'closed' | 'errored' | 'expired';
|
|
222
|
+
interface StreamErrorData {
|
|
223
|
+
name: string;
|
|
224
|
+
message: string;
|
|
225
|
+
}
|
|
226
|
+
interface StreamWriteResult {
|
|
227
|
+
startIndex: number;
|
|
228
|
+
count: number;
|
|
229
|
+
tailIndex: number;
|
|
230
|
+
}
|
|
231
|
+
interface StreamReadRequest {
|
|
232
|
+
runId: string;
|
|
233
|
+
startIndex: number;
|
|
234
|
+
maxChunks: number;
|
|
235
|
+
maxBytes: number;
|
|
236
|
+
waitMs: number;
|
|
237
|
+
}
|
|
238
|
+
interface StreamReadResult {
|
|
239
|
+
startIndex: number;
|
|
240
|
+
tailIndex: number;
|
|
241
|
+
chunks: Uint8Array[];
|
|
242
|
+
state: StreamTerminalState;
|
|
243
|
+
timedOut: boolean;
|
|
244
|
+
error?: StreamErrorData;
|
|
245
|
+
}
|
|
246
|
+
//#endregion
|
|
167
247
|
//#region src/streamer.d.ts
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
248
|
+
interface CelldStreamer extends Omit<Streamer, 'streams'> {
|
|
249
|
+
streams: Streamer['streams'] & {
|
|
250
|
+
fail(runId: string, name: string, error: StreamErrorData | string): Promise<void>;
|
|
251
|
+
};
|
|
252
|
+
writeToStream(name: string, runId: string | Promise<string>, chunk: string | Uint8Array): Promise<void>;
|
|
253
|
+
writeChunksToStream(name: string, runId: string | Promise<string>, chunks: readonly (string | Uint8Array)[]): Promise<void>;
|
|
254
|
+
closeStream(name: string, runId: string | Promise<string>): Promise<void>;
|
|
255
|
+
errorStream(name: string, runId: string | Promise<string>, error: StreamErrorData | string): Promise<void>;
|
|
256
|
+
readFromStream(name: string, runId: string, startIndex?: number): Promise<ReadableStream<Uint8Array>>;
|
|
257
|
+
listStreamsByRunId(runId: string): Promise<string[]>;
|
|
258
|
+
getStreamChunks(name: string, runId: string, options?: GetChunksOptions): Promise<StreamChunksResponse>;
|
|
259
|
+
getStreamInfo(name: string, runId: string): Promise<StreamInfoResponse>;
|
|
260
|
+
}
|
|
261
|
+
/** Direct StreamDO RPC surface. Remote stubs specialize read/write as binary HTTP. */
|
|
173
262
|
interface StreamDOStub {
|
|
174
|
-
|
|
263
|
+
writeChunks(runId: string, chunks: Uint8Array[]): Promise<StreamWriteResult>;
|
|
264
|
+
readChunks(request: StreamReadRequest, signal?: AbortSignal): Promise<StreamReadResult>;
|
|
175
265
|
closeStream(runId: string): Promise<void>;
|
|
176
|
-
|
|
177
|
-
startIndex: number;
|
|
178
|
-
limit: number;
|
|
179
|
-
}): Promise<{
|
|
180
|
-
chunks: Uint8Array[];
|
|
181
|
-
done: boolean;
|
|
182
|
-
tailIndex: number;
|
|
183
|
-
}>;
|
|
184
|
-
getInfo(): Promise<{
|
|
185
|
-
tailIndex: number;
|
|
186
|
-
done: boolean;
|
|
187
|
-
}>;
|
|
266
|
+
failStream(runId: string, error: StreamErrorData | string): Promise<void>;
|
|
188
267
|
registerStream(runId: string, name: string): Promise<void>;
|
|
189
268
|
listStreams(): Promise<string[]>;
|
|
190
|
-
expireRegistry(runId: string, expiredAt: number
|
|
191
|
-
|
|
192
|
-
|
|
269
|
+
expireRegistry(runId: string, expiredAt: number, options?: {
|
|
270
|
+
limit?: number;
|
|
271
|
+
}): Promise<ExpireRunStreamsResult>;
|
|
272
|
+
finalizeRegistry(runId: string, streams: string[]): Promise<FinalizeRunStreamsResult>;
|
|
273
|
+
expireStream(runId: string, expiredAt: number, options?: {
|
|
274
|
+
limit?: number;
|
|
275
|
+
byteLimit?: number;
|
|
276
|
+
}): Promise<ExpireStreamResult>;
|
|
193
277
|
}
|
|
194
278
|
interface StreamDONamespace {
|
|
195
279
|
idFromName(name: string): StreamDOId;
|
|
@@ -200,7 +284,7 @@ interface StreamDOId {
|
|
|
200
284
|
}
|
|
201
285
|
//#endregion
|
|
202
286
|
//#region src/queue.d.ts
|
|
203
|
-
type Pathname = 'flow'
|
|
287
|
+
type Pathname = 'flow';
|
|
204
288
|
/**
|
|
205
289
|
* Enqueue request accepted by a QueueDO cell. The message payload travels
|
|
206
290
|
* pre-encoded with the shared tagged-JSON codec (`body`), so the cell can
|
|
@@ -223,7 +307,7 @@ interface EnqueueRequest {
|
|
|
223
307
|
config: QueueCellConfig;
|
|
224
308
|
}
|
|
225
309
|
interface QueueCellConfig {
|
|
226
|
-
/** Base URL of the app; deliveries POST to `${baseUrl}/.well-known/workflow/v1/
|
|
310
|
+
/** Base URL of the app; deliveries POST to `${baseUrl}/.well-known/workflow/v1/flow`. */
|
|
227
311
|
targetBaseUrl: string;
|
|
228
312
|
queueShards: number;
|
|
229
313
|
}
|
|
@@ -239,7 +323,9 @@ type EnqueueOutcome = {
|
|
|
239
323
|
/** RPC surface of QueueDO used by the queue producer. */
|
|
240
324
|
interface QueueCellStub {
|
|
241
325
|
enqueue(request: EnqueueRequest): Promise<EnqueueOutcome>;
|
|
242
|
-
expireRun(runId: string, expiredAt: number
|
|
326
|
+
expireRun(runId: string, expiredAt: number, options?: {
|
|
327
|
+
limit?: number;
|
|
328
|
+
}): Promise<ExpireQueueRunResult>;
|
|
243
329
|
}
|
|
244
330
|
interface QueueCellNamespace {
|
|
245
331
|
idFromName(name: string): {
|
|
@@ -250,36 +336,51 @@ interface QueueCellNamespace {
|
|
|
250
336
|
}): QueueCellStub;
|
|
251
337
|
}
|
|
252
338
|
//#endregion
|
|
253
|
-
//#region src/
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
339
|
+
//#region src/indexes.d.ts
|
|
340
|
+
interface IndexListOptions {
|
|
341
|
+
prefix?: string;
|
|
342
|
+
cursor?: string;
|
|
343
|
+
limit?: number;
|
|
344
|
+
reverse?: boolean;
|
|
345
|
+
}
|
|
346
|
+
interface IndexListPage {
|
|
347
|
+
keys: Array<{
|
|
348
|
+
name: string;
|
|
349
|
+
value: string;
|
|
350
|
+
}>;
|
|
351
|
+
list_complete: boolean;
|
|
352
|
+
cursor?: string;
|
|
353
|
+
}
|
|
354
|
+
interface HookReservation {
|
|
355
|
+
claimId: string;
|
|
356
|
+
tokenClaimId?: string;
|
|
357
|
+
hookIdClaimId?: string;
|
|
358
|
+
}
|
|
359
|
+
type HookReservationResult = {
|
|
360
|
+
admitted: true;
|
|
361
|
+
reservation: HookReservation;
|
|
362
|
+
} | {
|
|
363
|
+
admitted: false;
|
|
364
|
+
holder: HookTokenOwner;
|
|
365
|
+
};
|
|
366
|
+
/** High-level client used by the World storage layer and retention coordinator. */
|
|
367
|
+
interface WorkflowIndex {
|
|
368
|
+
commitRun(run: WorkflowRun, serializedMetadata: string): Promise<{
|
|
260
369
|
stored: boolean;
|
|
261
370
|
}>;
|
|
371
|
+
listRuns(options?: IndexListOptions): Promise<IndexListPage>;
|
|
372
|
+
getHookByToken(token: string): Promise<string | null>;
|
|
373
|
+
getHookById(hookId: string): Promise<string | null>;
|
|
374
|
+
reserveHook(token: string, owner: HookTokenOwner): Promise<HookReservationResult>;
|
|
375
|
+
finalizeHookIndexes(token: string, hookId: string, serializedHook: string, owner: HookTokenOwner, reservation?: HookReservation): Promise<void>;
|
|
376
|
+
releaseHookReservation(token: string, owner: HookTokenOwner, reservation: HookReservation): Promise<void>;
|
|
377
|
+
releaseHookIndexes(request: ReleaseHookIndexesRequest): Promise<ReleaseHookIndexesResult>;
|
|
262
378
|
expireRun(request: ExpireRunIndexesRequest): Promise<ExpireRunIndexesResult>;
|
|
263
|
-
list(options?: {
|
|
264
|
-
prefix?: string;
|
|
265
|
-
cursor?: string;
|
|
266
|
-
limit?: number;
|
|
267
|
-
reverse?: boolean;
|
|
268
|
-
}): Promise<{
|
|
269
|
-
keys: Array<{
|
|
270
|
-
name: string;
|
|
271
|
-
}>;
|
|
272
|
-
list_complete: boolean;
|
|
273
|
-
cursor?: string;
|
|
274
|
-
}>;
|
|
275
|
-
reserveHookToken(token: string, owner: HookTokenOwner): Promise<{
|
|
276
|
-
claimed: boolean;
|
|
277
|
-
holder?: HookTokenOwner;
|
|
278
|
-
}>;
|
|
279
|
-
finalizeHookIndexes(token: string, hookId: string, serializedHook: string, owner: HookTokenOwner): Promise<void>;
|
|
280
|
-
releaseHookToken(token: string, owner: HookTokenOwner): Promise<void>;
|
|
281
|
-
deleteHookIndexes(token: string, hookId: string, owner: HookTokenOwner): Promise<void>;
|
|
282
379
|
}
|
|
380
|
+
//#endregion
|
|
381
|
+
//#region src/config.d.ts
|
|
382
|
+
/** Public alias retained for custom in-process environments. */
|
|
383
|
+
type IndexNamespace = WorkflowIndex;
|
|
283
384
|
interface HookTokenOwner {
|
|
284
385
|
runId: string;
|
|
285
386
|
hookId: string;
|
|
@@ -312,7 +413,7 @@ interface CelldWorldConfig {
|
|
|
312
413
|
deploymentId?: string;
|
|
313
414
|
/**
|
|
314
415
|
* Base URL the app's workflow endpoints are mounted on; QueueDO cells
|
|
315
|
-
* deliver to `${baseUrl}/.well-known/workflow/v1/
|
|
416
|
+
* deliver to `${baseUrl}/.well-known/workflow/v1/flow`.
|
|
316
417
|
* Default: process.env.WORKFLOW_BASE_URL || `http://localhost:${PORT ?? 3000}`
|
|
317
418
|
*/
|
|
318
419
|
baseUrl?: string;
|
|
@@ -324,8 +425,10 @@ interface CelldWorldConfig {
|
|
|
324
425
|
* Default: process.env.CELLD_RUN_RETENTION_MS || 0
|
|
325
426
|
*/
|
|
326
427
|
runRetentionMs?: number;
|
|
327
|
-
/**
|
|
328
|
-
|
|
428
|
+
/** Duration of one bounded idle stream read. Default: 20000 */
|
|
429
|
+
streamLongPollMs?: number;
|
|
430
|
+
/** Runtime stream batching delay. Default: 0 */
|
|
431
|
+
streamFlushIntervalMs?: number;
|
|
329
432
|
/** Per-attempt fleet RPC deadline in milliseconds. Default: 30000 */
|
|
330
433
|
rpcTimeoutMs?: number;
|
|
331
434
|
}
|
|
@@ -337,10 +440,10 @@ interface CelldRetentionAdmin {
|
|
|
337
440
|
cleanupNow(runId: string): Promise<CleanupRecord | null>;
|
|
338
441
|
rearm(runId: string): Promise<CleanupRecord | null>;
|
|
339
442
|
}
|
|
340
|
-
type CelldWorld = World & {
|
|
443
|
+
type CelldWorld = World & CelldStreamer & {
|
|
341
444
|
retention: CelldRetentionAdmin;
|
|
342
445
|
};
|
|
343
446
|
declare function createCelldWorld(config?: CelldWorldConfig): CelldWorld;
|
|
344
447
|
//#endregion
|
|
345
|
-
export { CelldRetentionAdmin, CelldWorld, type CelldWorldConfig, type CelldWorldEnv, type CleanupPhase, type CleanupRecord, type EnqueueOutcome, type EnqueueRequest, type IndexNamespace, type QueueCellConfig, type QueueCellNamespace, type QueueCellStub, type RunTombstone, type StreamDONamespace, type StreamDOStub, type WorkflowRunDONamespace, type WorkflowRunDOStub, createCelldWorld, createCelldWorld as createWorld };
|
|
448
|
+
export { CelldRetentionAdmin, CelldWorld, type CelldWorldConfig, type CelldWorldEnv, type CleanupPhase, type CleanupRecord, type EnqueueOutcome, type EnqueueRequest, type IndexNamespace, MAX_STREAM_BATCH_BYTES, MAX_STREAM_CHUNK_BYTES, MAX_STREAM_ERROR_BYTES, MAX_STREAM_LONG_POLL_MS, MAX_STREAM_READ_BYTES, MAX_STREAM_READ_CHUNKS, MAX_STREAM_WRITE_CHUNKS, type QueueCellConfig, type QueueCellNamespace, type QueueCellStub, type RunTombstone, type StreamDONamespace, type StreamDOStub, type StreamErrorData, type StreamReadRequest, type StreamReadResult, type StreamTerminalState, type StreamWriteResult, type WorkflowRunDONamespace, type WorkflowRunDOStub, createCelldWorld, createCelldWorld as createWorld };
|
|
346
449
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/retention.ts","../src/apply-event.ts","../src/storage.ts","../src/streamer.ts","../src/queue.ts","../src/config.ts","../src/index.ts"],"mappings":";;KAOY;UAEK;EACf;EACA;EACA;EACA,WAAW;EACX,aAAa;EACb,gBAAgB;EAChB,OAAO;EACP;EACA,OAAO;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/retention.ts","../src/apply-event.ts","../src/storage.ts","../src/stream-protocol.ts","../src/streamer.ts","../src/queue.ts","../src/indexes.ts","../src/config.ts","../src/index.ts"],"mappings":"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"}
|