@ewhauser/world-celld 0.1.1 → 0.3.0
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 +27 -0
- package/README.md +61 -23
- package/dist/index.d.ts +126 -20
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +206 -135
- package/dist/index.js.map +1 -1
- package/dist/{util-BvWlkqgV.js → retention-bLY1vcOu.js} +44 -2
- package/dist/retention-bLY1vcOu.js.map +1 -0
- package/dist/testing.d.ts +2 -0
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +802 -174
- package/dist/testing.js.map +1 -1
- package/dist/worker.d.ts +133 -62
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +829 -170
- package/dist/worker.js.map +1 -1
- package/package.json +7 -7
- package/dist/util-BvWlkqgV.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## 0.3.0 (2026-08-16)
|
|
6
|
+
|
|
7
|
+
## What's Changed
|
|
8
|
+
* fix: split Release Please release and PR phases by @ewhauser in https://github.com/ewhauser/world-celld/pull/16
|
|
9
|
+
* feat: target Workflow 5 beta by @ewhauser in https://github.com/ewhauser/world-celld/pull/17
|
|
10
|
+
* fix: enforce Workflow 5 storage contracts by @ewhauser in https://github.com/ewhauser/world-celld/pull/19
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
**Full Changelog**: https://github.com/ewhauser/world-celld/compare/v0.2.0...v0.3.0
|
|
14
|
+
|
|
15
|
+
## 0.2.0 (2026-08-16)
|
|
16
|
+
|
|
17
|
+
## What's Changed
|
|
18
|
+
* Patch vulnerable Hono test dependencies by @ewhauser in https://github.com/ewhauser/world-celld/pull/8
|
|
19
|
+
* chore(deps-dev): bump typescript from 5.9.3 to 7.0.2 by @dependabot[bot] in https://github.com/ewhauser/world-celld/pull/3
|
|
20
|
+
* Fix flaky harness teardown by @ewhauser in https://github.com/ewhauser/world-celld/pull/10
|
|
21
|
+
* Add terminal workflow retention by @ewhauser in https://github.com/ewhauser/world-celld/pull/11
|
|
22
|
+
* chore(deps): bump the production-dependencies group across 1 directory with 3 updates by @dependabot[bot] in https://github.com/ewhauser/world-celld/pull/1
|
|
23
|
+
* ci: automate releases with Release Please by @ewhauser in https://github.com/ewhauser/world-celld/pull/13
|
|
24
|
+
* 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/12
|
|
25
|
+
* fix: exclude generated changelog from formatting by @ewhauser in https://github.com/ewhauser/world-celld/pull/15
|
|
26
|
+
|
|
27
|
+
## New Contributors
|
|
28
|
+
* @dependabot[bot] made their first contribution in https://github.com/ewhauser/world-celld/pull/3
|
|
29
|
+
|
|
30
|
+
**Full Changelog**: https://github.com/ewhauser/world-celld/compare/v0.1.1...v0.2.0
|
|
31
|
+
|
|
5
32
|
## 0.1.1 - 2026-08-15
|
|
6
33
|
|
|
7
34
|
- Publish through npm trusted publishing with OIDC provenance.
|
package/README.md
CHANGED
|
@@ -16,6 +16,7 @@ self-hosted alternative to platform-specific Workflow backends.
|
|
|
16
16
|
- Workflow run, step, event, and hook persistence
|
|
17
17
|
- Durable streams
|
|
18
18
|
- Delayed work, retries, deduplication, and dead-letter storage
|
|
19
|
+
- Configurable cleanup of terminal workflow payloads
|
|
19
20
|
- An authenticated HTTP connection between a Node application and a celld fleet
|
|
20
21
|
- An in-process fleet for local development and conformance testing
|
|
21
22
|
|
|
@@ -64,6 +65,8 @@ const world = createCelldWorld({
|
|
|
64
65
|
fleetUrl: 'http://fleet.internal:8080',
|
|
65
66
|
secret: process.env.CELLD_WORLD_SECRET!,
|
|
66
67
|
baseUrl: 'https://workflow.example.com',
|
|
68
|
+
// Keep completed, failed, and cancelled run payloads for 30 days.
|
|
69
|
+
runRetentionMs: 30 * 24 * 60 * 60 * 1000,
|
|
67
70
|
});
|
|
68
71
|
```
|
|
69
72
|
|
|
@@ -122,7 +125,7 @@ celld worker router
|
|
|
122
125
|
|
|
|
123
126
|
| HTTP callbacks
|
|
124
127
|
v
|
|
125
|
-
Workflow application /.well-known/workflow/v1/
|
|
128
|
+
Workflow application /.well-known/workflow/v1/flow
|
|
126
129
|
```
|
|
127
130
|
|
|
128
131
|
The application-side package implements the Workflow `World` interface and
|
|
@@ -135,15 +138,16 @@ cell that owns the data.
|
|
|
135
138
|
Application options can be passed to `createCelldWorld()` unless an environment
|
|
136
139
|
variable is shown below.
|
|
137
140
|
|
|
138
|
-
| Option
|
|
139
|
-
|
|
|
140
|
-
| `fleetUrl`
|
|
141
|
-
| `secret`
|
|
142
|
-
| `baseUrl`
|
|
143
|
-
| `deploymentId`
|
|
144
|
-
| `queueShards`
|
|
145
|
-
| `
|
|
146
|
-
| `
|
|
141
|
+
| Option | Environment variable | Default |
|
|
142
|
+
| ---------------- | ------------------------ | ------------------------ |
|
|
143
|
+
| `fleetUrl` | `CELLD_FLEET_URL` | required |
|
|
144
|
+
| `secret` | `CELLD_WORLD_SECRET` | required with `fleetUrl` |
|
|
145
|
+
| `baseUrl` | `WORKFLOW_BASE_URL` | `http://localhost:$PORT` |
|
|
146
|
+
| `deploymentId` | `CELLD_DEPLOYMENT_ID` | `celld-default` |
|
|
147
|
+
| `queueShards` | — | `1` |
|
|
148
|
+
| `runRetentionMs` | `CELLD_RUN_RETENTION_MS` | `0` (disabled) |
|
|
149
|
+
| `readPollMs` | — | `250` |
|
|
150
|
+
| `rpcTimeoutMs` | — | `30000` |
|
|
147
151
|
|
|
148
152
|
The deployed worker also accepts these celld variables:
|
|
149
153
|
|
|
@@ -158,12 +162,45 @@ The deployed worker also accepts these celld variables:
|
|
|
158
162
|
`queueShards` is part of queue placement and is pinned when a queue cell is
|
|
159
163
|
first used. Drain pending work before changing it.
|
|
160
164
|
|
|
165
|
+
## Terminal run retention
|
|
166
|
+
|
|
167
|
+
When `runRetentionMs` is greater than zero, a terminal transition atomically
|
|
168
|
+
records the run's `expiredAt` and arms its cell alarm. The complete run, event,
|
|
169
|
+
step, hook, and stream data remains readable until that deadline. Active and
|
|
170
|
+
pending runs are never eligible for automatic cleanup.
|
|
171
|
+
|
|
172
|
+
At expiration, the run cell fences new writes and removes the run's derived
|
|
173
|
+
indexes, stream chunks, pending and dead-letter queue messages, and durable run
|
|
174
|
+
payloads. Cleanup is a persisted, idempotent state machine: an interrupted
|
|
175
|
+
phase records its error and re-arms itself with capped backoff.
|
|
176
|
+
|
|
177
|
+
The final state is a metadata-only tombstone, not an empty cell. It prevents a
|
|
178
|
+
delayed queue delivery or stale RPC from recreating an expired run. Reads and
|
|
179
|
+
writes against that run return `RunExpiredError`, and the run no longer appears
|
|
180
|
+
in listings. Tombstones contain no workflow input, output, event, step, hook,
|
|
181
|
+
stream, or queue payload.
|
|
182
|
+
|
|
183
|
+
The returned World exposes authenticated operational methods:
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
const status = await world.retention.getStatus(runId);
|
|
187
|
+
await world.retention.schedule(runId); // requires runRetentionMs > 0
|
|
188
|
+
await world.retention.cleanupNow(runId);
|
|
189
|
+
await world.retention.rearm(runId); // recover a missed or abandoned alarm
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
The retention deadline is pinned when the run becomes terminal. Changing the
|
|
193
|
+
configuration affects newly terminal runs; call `schedule()` explicitly for
|
|
194
|
+
an existing terminal run that has no cleanup record.
|
|
195
|
+
|
|
161
196
|
## Operational notes
|
|
162
197
|
|
|
163
198
|
- Delivery is at least once. Workflow steps and other external side effects
|
|
164
199
|
must be idempotent.
|
|
165
200
|
- Queue cells expose `stats`, `listDeadLetters`, `redriveDeadLetter`,
|
|
166
201
|
`purgeDeadLetters`, and `rearmAlarm` through the authenticated RPC endpoint.
|
|
202
|
+
- Run cells expose retention status, scheduling, immediate cleanup, and alarm
|
|
203
|
+
recovery through `world.retention`.
|
|
167
204
|
- A new application URL applies to newly enqueued messages. Existing messages
|
|
168
205
|
retain the callback URL with which they were created.
|
|
169
206
|
- Fleet restarts can interrupt in-flight callbacks; expired claims are
|
|
@@ -176,7 +213,7 @@ pnpm format
|
|
|
176
213
|
pnpm check
|
|
177
214
|
```
|
|
178
215
|
|
|
179
|
-
`pnpm check` runs formatting, linting, type checking,
|
|
216
|
+
`pnpm check` runs formatting, linting, type checking, the build, tests, and the
|
|
180
217
|
worker and npm-package checks. The package check inspects the exact tarball and
|
|
181
218
|
installs it in a clean temporary consumer with lifecycle scripts disabled.
|
|
182
219
|
Oxlint runs its correctness, suspicious, and performance categories with
|
|
@@ -193,12 +230,12 @@ pnpm test:integration
|
|
|
193
230
|
### Local MinIO performance and loss test
|
|
194
231
|
|
|
195
232
|
The opt-in performance harness starts a fresh MinIO bucket and a single celld
|
|
196
|
-
node with Docker Compose
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
233
|
+
node with Docker Compose. Its queue workload verifies that every accepted
|
|
234
|
+
message reaches a successful callback, including forced `503` redeliveries. A
|
|
235
|
+
second workload creates terminal runs with streams and delayed queue messages,
|
|
236
|
+
then verifies complete payload cleanup without resurrection. Results include
|
|
237
|
+
queue and cleanup throughput plus p50, p95, p99, and maximum latency and are
|
|
238
|
+
saved under `.perf-results/`.
|
|
202
239
|
|
|
203
240
|
> MinIO Community is **not a supported celld production store**. It does not
|
|
204
241
|
> implement the conditional writes celld needs for ownership fencing. This
|
|
@@ -275,12 +312,13 @@ job needs. Third-party actions are pinned to verified release commits. Release
|
|
|
275
312
|
builds do not use caches, and the exact npm tarball is checksummed, clean-room
|
|
276
313
|
installed, and verified again before publication.
|
|
277
314
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
315
|
+
Release Please maintains version and changelog pull requests. Releases publish
|
|
316
|
+
from GitHub-hosted runners through npm trusted publishing (OIDC), without a
|
|
317
|
+
long-lived npm token. npm records provenance for public releases. A draft
|
|
318
|
+
GitHub release holds the release notes while the package is verified; the Git
|
|
319
|
+
tag and public release are created only after npm accepts the matching tarball.
|
|
320
|
+
Published GitHub releases are immutable. Dependency updates use cooldowns, and
|
|
321
|
+
pnpm permits lifecycle scripts only for an explicit allowlist.
|
|
284
322
|
|
|
285
323
|
See [`SECURITY.md`](./SECURITY.md) to report a vulnerability and
|
|
286
324
|
[`RELEASING.md`](./RELEASING.md) for the release procedure.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,76 @@
|
|
|
1
|
-
import { CreateEventRequest, Event, Hook, RunCreatedEventRequest, Step, ValidQueueName, WorkflowRun, World } from "@workflow/world";
|
|
1
|
+
import { CreateEventParams, CreateEventRequest, Event, Hook, RunCreatedEventRequest, Step, TerminalWorkflowRunStatus, ValidQueueName, Wait, WorkflowRun, World } from "@workflow/world";
|
|
2
|
+
//#region src/retention.d.ts
|
|
3
|
+
type CleanupPhase = 'retained' | 'index' | 'streams' | 'queues' | 'payload' | 'tombstoned';
|
|
4
|
+
interface CleanupRecord {
|
|
5
|
+
version: 1;
|
|
6
|
+
runId: string;
|
|
7
|
+
workflowName: string;
|
|
8
|
+
createdAt: Date;
|
|
9
|
+
completedAt: Date;
|
|
10
|
+
terminalStatus: TerminalWorkflowRunStatus;
|
|
11
|
+
dueAt: Date;
|
|
12
|
+
queueShards: number;
|
|
13
|
+
phase: CleanupPhase;
|
|
14
|
+
attempts: number;
|
|
15
|
+
lastError?: string;
|
|
16
|
+
lastAttemptAt?: Date;
|
|
17
|
+
tombstonedAt?: Date;
|
|
18
|
+
deletedPayloadKeys: number;
|
|
19
|
+
deletedStreams: number;
|
|
20
|
+
deletedQueueMessages: number;
|
|
21
|
+
}
|
|
22
|
+
interface RunTombstone {
|
|
23
|
+
version: 1;
|
|
24
|
+
runId: string;
|
|
25
|
+
terminalStatus: TerminalWorkflowRunStatus;
|
|
26
|
+
completedAt: Date;
|
|
27
|
+
expiredAt: Date;
|
|
28
|
+
tombstonedAt: Date;
|
|
29
|
+
}
|
|
30
|
+
type RunReadOutcome<T> = {
|
|
31
|
+
ok: true;
|
|
32
|
+
value: T;
|
|
33
|
+
} | {
|
|
34
|
+
ok: false;
|
|
35
|
+
code: 'RUN_EXPIRED';
|
|
36
|
+
message: string;
|
|
37
|
+
tombstone: RunTombstone;
|
|
38
|
+
};
|
|
39
|
+
interface HookIndexReference {
|
|
40
|
+
hookId: string;
|
|
41
|
+
token: string;
|
|
42
|
+
}
|
|
43
|
+
interface ExpireRunIndexesRequest {
|
|
44
|
+
runId: string;
|
|
45
|
+
keys: string[];
|
|
46
|
+
hooks: HookIndexReference[];
|
|
47
|
+
expiredAt: number;
|
|
48
|
+
}
|
|
49
|
+
interface ExpireRunIndexesResult {
|
|
50
|
+
deleted: number;
|
|
51
|
+
}
|
|
52
|
+
interface ExpireRunStreamsResult {
|
|
53
|
+
streams: string[];
|
|
54
|
+
}
|
|
55
|
+
interface ExpireStreamResult {
|
|
56
|
+
deleted: boolean;
|
|
57
|
+
chunks: number;
|
|
58
|
+
}
|
|
59
|
+
interface ExpireQueueRunResult {
|
|
60
|
+
deleted: number;
|
|
61
|
+
}
|
|
62
|
+
interface ScheduleCleanupRequest {
|
|
63
|
+
retentionMs: number;
|
|
64
|
+
queueShards: number;
|
|
65
|
+
}
|
|
66
|
+
//#endregion
|
|
2
67
|
//#region src/apply-event.d.ts
|
|
3
68
|
interface ApplyEventRequest {
|
|
4
69
|
/** The effective run id (already resolved / generated by the caller). */
|
|
5
70
|
runId: string;
|
|
6
71
|
data: CreateEventRequest | RunCreatedEventRequest;
|
|
72
|
+
/** Workflow 5 event-log position and preload options. */
|
|
73
|
+
params?: CreateEventParams;
|
|
7
74
|
/**
|
|
8
75
|
* Current holder of the hook token per the global KV token index
|
|
9
76
|
* (hook_created only). `null` means the token is unclaimed.
|
|
@@ -12,8 +79,10 @@ interface ApplyEventRequest {
|
|
|
12
79
|
runId: string;
|
|
13
80
|
hookId: string;
|
|
14
81
|
} | null;
|
|
82
|
+
/** Internal world-celld retention policy captured with the event. */
|
|
83
|
+
cleanup?: ScheduleCleanupRequest;
|
|
15
84
|
}
|
|
16
|
-
type ApplyEventErrorCode = 'RUN_NOT_FOUND' | 'STEP_NOT_FOUND' | 'HOOK_NOT_FOUND' | '
|
|
85
|
+
type ApplyEventErrorCode = 'RUN_NOT_FOUND' | 'STEP_NOT_FOUND' | 'HOOK_NOT_FOUND' | 'WAIT_NOT_FOUND' | 'ENTITY_CONFLICT' | 'RUN_EXPIRED' | 'TOO_EARLY' | 'RUN_NOT_SUPPORTED';
|
|
17
86
|
interface ApplyEventFailure {
|
|
18
87
|
ok: false;
|
|
19
88
|
code: ApplyEventErrorCode;
|
|
@@ -30,6 +99,9 @@ interface ApplyEventSuccess {
|
|
|
30
99
|
run?: WorkflowRun;
|
|
31
100
|
step?: Step;
|
|
32
101
|
hook?: Hook;
|
|
102
|
+
wait?: Wait;
|
|
103
|
+
/** True when a lazy step_started atomically created its step. */
|
|
104
|
+
stepCreated?: true;
|
|
33
105
|
/** Hooks whose tokens must be released from the global KV index. */
|
|
34
106
|
releasedHooks: Array<{
|
|
35
107
|
hookId: string;
|
|
@@ -44,6 +116,11 @@ interface ApplyEventSuccess {
|
|
|
44
116
|
hookToIndex?: Hook;
|
|
45
117
|
/** All events (ascending), preloaded for run_started responses. */
|
|
46
118
|
events?: Event[];
|
|
119
|
+
/** Pagination metadata required whenever events are returned. */
|
|
120
|
+
cursor?: string | null;
|
|
121
|
+
hasMore?: boolean;
|
|
122
|
+
/** Server-owned event ceiling advertised on run lifecycle writes. */
|
|
123
|
+
maxEvents?: number;
|
|
47
124
|
}
|
|
48
125
|
type ApplyEventOutcome = ApplyEventSuccess | ApplyEventFailure;
|
|
49
126
|
//#endregion
|
|
@@ -54,36 +131,40 @@ type ApplyEventOutcome = ApplyEventSuccess | ApplyEventFailure;
|
|
|
54
131
|
*/
|
|
55
132
|
interface WorkflowRunDOStub {
|
|
56
133
|
applyEvent(request: ApplyEventRequest): Promise<ApplyEventOutcome>;
|
|
57
|
-
getRun(): Promise<WorkflowRun | null
|
|
58
|
-
getStep(stepId: string): Promise<Step | null
|
|
59
|
-
getEvent(eventId: string): Promise<Event | null
|
|
134
|
+
getRun(): Promise<RunReadOutcome<WorkflowRun | null>>;
|
|
135
|
+
getStep(stepId: string): Promise<RunReadOutcome<Step | null>>;
|
|
136
|
+
getEvent(eventId: string): Promise<RunReadOutcome<Event | null>>;
|
|
60
137
|
listEvents(params?: {
|
|
61
138
|
limit?: number;
|
|
62
139
|
cursor?: string;
|
|
63
140
|
sortOrder?: 'asc' | 'desc';
|
|
64
|
-
}): Promise<{
|
|
141
|
+
}): Promise<RunReadOutcome<{
|
|
65
142
|
data: Event[];
|
|
66
143
|
cursor: string | null;
|
|
67
144
|
hasMore: boolean;
|
|
68
|
-
}
|
|
145
|
+
}>>;
|
|
69
146
|
listSteps(params?: {
|
|
70
147
|
limit?: number;
|
|
71
148
|
cursor?: string;
|
|
72
149
|
sortOrder?: 'asc' | 'desc';
|
|
73
|
-
}): Promise<{
|
|
150
|
+
}): Promise<RunReadOutcome<{
|
|
74
151
|
data: Step[];
|
|
75
152
|
cursor: string | null;
|
|
76
153
|
hasMore: boolean;
|
|
77
|
-
}
|
|
154
|
+
}>>;
|
|
78
155
|
listHooks(params?: {
|
|
79
156
|
limit?: number;
|
|
80
157
|
cursor?: string;
|
|
81
158
|
sortOrder?: 'asc' | 'desc';
|
|
82
|
-
}): Promise<{
|
|
159
|
+
}): Promise<RunReadOutcome<{
|
|
83
160
|
data: Hook[];
|
|
84
161
|
cursor: string | null;
|
|
85
162
|
hasMore: boolean;
|
|
86
|
-
}
|
|
163
|
+
}>>;
|
|
164
|
+
getCleanupStatus(): Promise<CleanupRecord | null>;
|
|
165
|
+
scheduleCleanup(request: ScheduleCleanupRequest): Promise<CleanupRecord | null>;
|
|
166
|
+
cleanupNow(request: ScheduleCleanupRequest): Promise<CleanupRecord | null>;
|
|
167
|
+
rearmCleanup(): Promise<CleanupRecord | null>;
|
|
87
168
|
}
|
|
88
169
|
interface WorkflowRunDONamespace {
|
|
89
170
|
idFromName(name: string): DurableObjectIdLike;
|
|
@@ -100,8 +181,8 @@ interface DurableObjectIdLike {
|
|
|
100
181
|
* protocol.
|
|
101
182
|
*/
|
|
102
183
|
interface StreamDOStub {
|
|
103
|
-
writeChunk(data: Uint8Array): Promise<number>;
|
|
104
|
-
closeStream(): Promise<void>;
|
|
184
|
+
writeChunk(runId: string, data: Uint8Array): Promise<number>;
|
|
185
|
+
closeStream(runId: string): Promise<void>;
|
|
105
186
|
getChunks(params: {
|
|
106
187
|
startIndex: number;
|
|
107
188
|
limit: number;
|
|
@@ -114,8 +195,11 @@ interface StreamDOStub {
|
|
|
114
195
|
tailIndex: number;
|
|
115
196
|
done: boolean;
|
|
116
197
|
}>;
|
|
117
|
-
registerStream(name: string): Promise<void>;
|
|
198
|
+
registerStream(runId: string, name: string): Promise<void>;
|
|
118
199
|
listStreams(): Promise<string[]>;
|
|
200
|
+
expireRegistry(runId: string, expiredAt: number): Promise<ExpireRunStreamsResult>;
|
|
201
|
+
finalizeRegistry(runId: string): Promise<void>;
|
|
202
|
+
expireStream(runId: string, expiredAt: number): Promise<ExpireStreamResult>;
|
|
119
203
|
}
|
|
120
204
|
interface StreamDONamespace {
|
|
121
205
|
idFromName(name: string): StreamDOId;
|
|
@@ -126,7 +210,7 @@ interface StreamDOId {
|
|
|
126
210
|
}
|
|
127
211
|
//#endregion
|
|
128
212
|
//#region src/queue.d.ts
|
|
129
|
-
type Pathname = 'flow'
|
|
213
|
+
type Pathname = 'flow';
|
|
130
214
|
/**
|
|
131
215
|
* Enqueue request accepted by a QueueDO cell. The message payload travels
|
|
132
216
|
* pre-encoded with the shared tagged-JSON codec (`body`), so the cell can
|
|
@@ -138,6 +222,8 @@ interface EnqueueRequest {
|
|
|
138
222
|
pathname: Pathname;
|
|
139
223
|
/** `stringify(message)` — the exact bytes POSTed to the app on delivery. */
|
|
140
224
|
body: string;
|
|
225
|
+
/** Owning workflow run; absent only for health-check messages. */
|
|
226
|
+
runId?: string;
|
|
141
227
|
idempotencyKey?: string;
|
|
142
228
|
delaySeconds?: number;
|
|
143
229
|
/**
|
|
@@ -147,7 +233,7 @@ interface EnqueueRequest {
|
|
|
147
233
|
config: QueueCellConfig;
|
|
148
234
|
}
|
|
149
235
|
interface QueueCellConfig {
|
|
150
|
-
/** Base URL of the app; deliveries POST to `${baseUrl}/.well-known/workflow/v1/
|
|
236
|
+
/** Base URL of the app; deliveries POST to `${baseUrl}/.well-known/workflow/v1/flow`. */
|
|
151
237
|
targetBaseUrl: string;
|
|
152
238
|
queueShards: number;
|
|
153
239
|
}
|
|
@@ -157,12 +243,13 @@ type EnqueueOutcome = {
|
|
|
157
243
|
deduped: boolean;
|
|
158
244
|
} | {
|
|
159
245
|
ok: false;
|
|
160
|
-
code: 'CONFIG_MISMATCH';
|
|
246
|
+
code: 'CONFIG_MISMATCH' | 'RUN_EXPIRED';
|
|
161
247
|
message: string;
|
|
162
248
|
};
|
|
163
249
|
/** RPC surface of QueueDO used by the queue producer. */
|
|
164
250
|
interface QueueCellStub {
|
|
165
251
|
enqueue(request: EnqueueRequest): Promise<EnqueueOutcome>;
|
|
252
|
+
expireRun(runId: string, expiredAt: number): Promise<ExpireQueueRunResult>;
|
|
166
253
|
}
|
|
167
254
|
interface QueueCellNamespace {
|
|
168
255
|
idFromName(name: string): {
|
|
@@ -179,6 +266,10 @@ interface IndexNamespace {
|
|
|
179
266
|
get(key: string): Promise<string | null>;
|
|
180
267
|
put(key: string, value: string): Promise<void>;
|
|
181
268
|
delete(key: string): Promise<void>;
|
|
269
|
+
putOwned(runId: string, key: string, value: string): Promise<{
|
|
270
|
+
stored: boolean;
|
|
271
|
+
}>;
|
|
272
|
+
expireRun(request: ExpireRunIndexesRequest): Promise<ExpireRunIndexesResult>;
|
|
182
273
|
list(options?: {
|
|
183
274
|
prefix?: string;
|
|
184
275
|
cursor?: string;
|
|
@@ -231,12 +322,18 @@ interface CelldWorldConfig {
|
|
|
231
322
|
deploymentId?: string;
|
|
232
323
|
/**
|
|
233
324
|
* Base URL the app's workflow endpoints are mounted on; QueueDO cells
|
|
234
|
-
* deliver to `${baseUrl}/.well-known/workflow/v1/
|
|
325
|
+
* deliver to `${baseUrl}/.well-known/workflow/v1/flow`.
|
|
235
326
|
* Default: process.env.WORKFLOW_BASE_URL || `http://localhost:${PORT ?? 3000}`
|
|
236
327
|
*/
|
|
237
328
|
baseUrl?: string;
|
|
238
329
|
/** Number of queue cells to spread enqueues over. Default: 1 */
|
|
239
330
|
queueShards?: number;
|
|
331
|
+
/**
|
|
332
|
+
* Keep terminal run payloads for this many milliseconds before replacing
|
|
333
|
+
* them with metadata-only tombstones. Zero disables automatic cleanup.
|
|
334
|
+
* Default: process.env.CELLD_RUN_RETENTION_MS || 0
|
|
335
|
+
*/
|
|
336
|
+
runRetentionMs?: number;
|
|
240
337
|
/** Poll interval (ms) while waiting for new chunks on a live stream. Default: 250 */
|
|
241
338
|
readPollMs?: number;
|
|
242
339
|
/** Per-attempt fleet RPC deadline in milliseconds. Default: 30000 */
|
|
@@ -244,7 +341,16 @@ interface CelldWorldConfig {
|
|
|
244
341
|
}
|
|
245
342
|
//#endregion
|
|
246
343
|
//#region src/index.d.ts
|
|
247
|
-
|
|
344
|
+
interface CelldRetentionAdmin {
|
|
345
|
+
getStatus(runId: string): Promise<CleanupRecord | null>;
|
|
346
|
+
schedule(runId: string): Promise<CleanupRecord | null>;
|
|
347
|
+
cleanupNow(runId: string): Promise<CleanupRecord | null>;
|
|
348
|
+
rearm(runId: string): Promise<CleanupRecord | null>;
|
|
349
|
+
}
|
|
350
|
+
type CelldWorld = World & {
|
|
351
|
+
retention: CelldRetentionAdmin;
|
|
352
|
+
};
|
|
353
|
+
declare function createCelldWorld(config?: CelldWorldConfig): CelldWorld;
|
|
248
354
|
//#endregion
|
|
249
|
-
export { type CelldWorldConfig, type CelldWorldEnv, type EnqueueOutcome, type EnqueueRequest, type IndexNamespace, type QueueCellConfig, type QueueCellNamespace, type QueueCellStub, type StreamDONamespace, type StreamDOStub, type WorkflowRunDONamespace, type WorkflowRunDOStub, createCelldWorld, createCelldWorld as createWorld };
|
|
355
|
+
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 };
|
|
250
356
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/apply-event.ts","../src/storage.ts","../src/streamer.ts","../src/queue.ts","../src/config.ts","../src/index.ts"],"mappings":";;
|
|
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":"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"}
|