@ewhauser/world-celld 0.1.1 → 0.2.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 +17 -0
- package/README.md +60 -22
- package/dist/index.d.ts +112 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +93 -39
- 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 +557 -78
- package/dist/testing.js.map +1 -1
- package/dist/worker.d.ts +120 -57
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +585 -75
- package/dist/worker.js.map +1 -1
- package/package.json +6 -6
- package/dist/util-BvWlkqgV.js.map +0 -1
package/dist/worker.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CreateEventRequest, Event, Hook, RunCreatedEventRequest, Step, ValidQueueName, WorkflowRun } from "@workflow/world";
|
|
1
|
+
import { CreateEventRequest, Event, Hook, RunCreatedEventRequest, Step, TerminalWorkflowRunStatus, ValidQueueName, WorkflowRun } from "@workflow/world";
|
|
2
2
|
//#region src/worker/router.d.ts
|
|
3
3
|
/** Minimal structural DO namespace type (celld provides the real thing). */
|
|
4
4
|
interface DONamespaceLike {
|
|
@@ -18,6 +18,71 @@ interface WorkerEnv {
|
|
|
18
18
|
}
|
|
19
19
|
declare function createRouter(env: WorkerEnv): (request: Request) => Promise<Response>;
|
|
20
20
|
//#endregion
|
|
21
|
+
//#region src/retention.d.ts
|
|
22
|
+
type CleanupPhase = 'retained' | 'index' | 'streams' | 'queues' | 'payload' | 'tombstoned';
|
|
23
|
+
interface CleanupRecord {
|
|
24
|
+
version: 1;
|
|
25
|
+
runId: string;
|
|
26
|
+
workflowName: string;
|
|
27
|
+
createdAt: Date;
|
|
28
|
+
completedAt: Date;
|
|
29
|
+
terminalStatus: TerminalWorkflowRunStatus;
|
|
30
|
+
dueAt: Date;
|
|
31
|
+
queueShards: number;
|
|
32
|
+
phase: CleanupPhase;
|
|
33
|
+
attempts: number;
|
|
34
|
+
lastError?: string;
|
|
35
|
+
lastAttemptAt?: Date;
|
|
36
|
+
tombstonedAt?: Date;
|
|
37
|
+
deletedPayloadKeys: number;
|
|
38
|
+
deletedStreams: number;
|
|
39
|
+
deletedQueueMessages: number;
|
|
40
|
+
}
|
|
41
|
+
interface RunTombstone {
|
|
42
|
+
version: 1;
|
|
43
|
+
runId: string;
|
|
44
|
+
terminalStatus: TerminalWorkflowRunStatus;
|
|
45
|
+
completedAt: Date;
|
|
46
|
+
expiredAt: Date;
|
|
47
|
+
tombstonedAt: Date;
|
|
48
|
+
}
|
|
49
|
+
type RunReadOutcome<T> = {
|
|
50
|
+
ok: true;
|
|
51
|
+
value: T;
|
|
52
|
+
} | {
|
|
53
|
+
ok: false;
|
|
54
|
+
code: 'RUN_EXPIRED';
|
|
55
|
+
message: string;
|
|
56
|
+
tombstone: RunTombstone;
|
|
57
|
+
};
|
|
58
|
+
interface HookIndexReference {
|
|
59
|
+
hookId: string;
|
|
60
|
+
token: string;
|
|
61
|
+
}
|
|
62
|
+
interface ExpireRunIndexesRequest {
|
|
63
|
+
runId: string;
|
|
64
|
+
keys: string[];
|
|
65
|
+
hooks: HookIndexReference[];
|
|
66
|
+
expiredAt: number;
|
|
67
|
+
}
|
|
68
|
+
interface ExpireRunIndexesResult {
|
|
69
|
+
deleted: number;
|
|
70
|
+
}
|
|
71
|
+
interface ExpireRunStreamsResult {
|
|
72
|
+
streams: string[];
|
|
73
|
+
}
|
|
74
|
+
interface ExpireStreamResult {
|
|
75
|
+
deleted: boolean;
|
|
76
|
+
chunks: number;
|
|
77
|
+
}
|
|
78
|
+
interface ExpireQueueRunResult {
|
|
79
|
+
deleted: number;
|
|
80
|
+
}
|
|
81
|
+
interface ScheduleCleanupRequest {
|
|
82
|
+
retentionMs: number;
|
|
83
|
+
queueShards: number;
|
|
84
|
+
}
|
|
85
|
+
//#endregion
|
|
21
86
|
//#region src/apply-event.d.ts
|
|
22
87
|
interface ApplyEventRequest {
|
|
23
88
|
/** The effective run id (already resolved / generated by the caller). */
|
|
@@ -31,6 +96,8 @@ interface ApplyEventRequest {
|
|
|
31
96
|
runId: string;
|
|
32
97
|
hookId: string;
|
|
33
98
|
} | null;
|
|
99
|
+
/** Internal world-celld retention policy captured with the event. */
|
|
100
|
+
cleanup?: ScheduleCleanupRequest;
|
|
34
101
|
}
|
|
35
102
|
type ApplyEventErrorCode = 'RUN_NOT_FOUND' | 'STEP_NOT_FOUND' | 'HOOK_NOT_FOUND' | 'ENTITY_CONFLICT' | 'RUN_EXPIRED' | 'TOO_EARLY' | 'RUN_NOT_SUPPORTED' | 'LEGACY_RUN_NOT_SUPPORTED';
|
|
36
103
|
interface ApplyEventFailure {
|
|
@@ -79,6 +146,8 @@ interface EnqueueRequest {
|
|
|
79
146
|
pathname: Pathname;
|
|
80
147
|
/** `stringify(message)` — the exact bytes POSTed to the app on delivery. */
|
|
81
148
|
body: string;
|
|
149
|
+
/** Owning workflow run; absent only for health-check messages. */
|
|
150
|
+
runId?: string;
|
|
82
151
|
idempotencyKey?: string;
|
|
83
152
|
delaySeconds?: number;
|
|
84
153
|
/**
|
|
@@ -98,7 +167,7 @@ type EnqueueOutcome = {
|
|
|
98
167
|
deduped: boolean;
|
|
99
168
|
} | {
|
|
100
169
|
ok: false;
|
|
101
|
-
code: 'CONFIG_MISMATCH';
|
|
170
|
+
code: 'CONFIG_MISMATCH' | 'RUN_EXPIRED';
|
|
102
171
|
message: string;
|
|
103
172
|
};
|
|
104
173
|
//#endregion
|
|
@@ -141,6 +210,10 @@ declare class DurableObject<TEnv = unknown> {
|
|
|
141
210
|
declare class IndexDO extends DurableObject {
|
|
142
211
|
get(key: string): Promise<string | null>;
|
|
143
212
|
put(key: string, value: string): Promise<void>;
|
|
213
|
+
/** Publish a derived index only while its owning run is not expired. */
|
|
214
|
+
putOwned(runId: string, key: string, value: string): Promise<{
|
|
215
|
+
stored: boolean;
|
|
216
|
+
}>;
|
|
144
217
|
delete(key: string): Promise<void>;
|
|
145
218
|
list(options?: {
|
|
146
219
|
prefix?: string;
|
|
@@ -161,6 +234,12 @@ declare class IndexDO extends DurableObject {
|
|
|
161
234
|
finalizeHookIndexes(token: string, hookId: string, serializedHook: string, owner: HookTokenOwner): Promise<void>;
|
|
162
235
|
releaseHookToken(token: string, owner: HookTokenOwner): Promise<void>;
|
|
163
236
|
deleteHookIndexes(token: string, hookId: string, owner: HookTokenOwner): Promise<void>;
|
|
237
|
+
/**
|
|
238
|
+
* Fence a run and remove all of its known derived indexes atomically.
|
|
239
|
+
* Once the fence exists, putOwned() and hook finalization cannot resurrect
|
|
240
|
+
* entries from a delayed request.
|
|
241
|
+
*/
|
|
242
|
+
expireRun(request: ExpireRunIndexesRequest): Promise<ExpireRunIndexesResult>;
|
|
164
243
|
}
|
|
165
244
|
//#endregion
|
|
166
245
|
//#region src/worker/durable-objects/QueueDO.d.ts
|
|
@@ -179,6 +258,8 @@ declare class IndexDO extends DurableObject {
|
|
|
179
258
|
* inflight:<messageId> crash-recovery deadline (epoch ms)
|
|
180
259
|
* key:<idempotencyKey> active dedup claim -> messageId
|
|
181
260
|
* dlq:<paddedMs>:<messageId> DeadLetterRow
|
|
261
|
+
* run:<runId>:<messageId> QueueRunReference for retention cleanup
|
|
262
|
+
* expired-run:<runId> run fence preventing delayed enqueue
|
|
182
263
|
*
|
|
183
264
|
* celld gotchas designed around:
|
|
184
265
|
* - celld#144 (alarm handlers can overlap): the storage-only claim phase runs
|
|
@@ -196,6 +277,7 @@ interface MessageRow {
|
|
|
196
277
|
pathname: 'flow' | 'step';
|
|
197
278
|
/** Pre-encoded tagged-JSON payload — forwarded byte-identical. */
|
|
198
279
|
body: string;
|
|
280
|
+
runId?: string;
|
|
199
281
|
/**
|
|
200
282
|
* Delivery target captured at enqueue time. Carried per message (not
|
|
201
283
|
* pinned on the cell) so an app redeploy at a new URL never bricks the
|
|
@@ -245,6 +327,8 @@ declare class QueueDO extends DurableObject {
|
|
|
245
327
|
rearmAlarm(): Promise<{
|
|
246
328
|
alarmAt: number | null;
|
|
247
329
|
}>;
|
|
330
|
+
/** Fence a run and purge every live, inflight, and dead-letter message it owns. */
|
|
331
|
+
expireRun(runId: string, expiredAt: number): Promise<ExpireQueueRunResult>;
|
|
248
332
|
}
|
|
249
333
|
//#endregion
|
|
250
334
|
//#region src/worker/durable-objects/StreamDO.d.ts
|
|
@@ -260,16 +344,17 @@ declare class QueueDO extends DurableObject {
|
|
|
260
344
|
*/
|
|
261
345
|
declare class StreamDO extends DurableObject {
|
|
262
346
|
private getMeta;
|
|
347
|
+
private assertOwner;
|
|
263
348
|
/**
|
|
264
349
|
* Append a chunk. The index is allocated inside the transaction, so
|
|
265
350
|
* concurrent writers can never collide or skip.
|
|
266
351
|
*/
|
|
267
|
-
writeChunk(data: Uint8Array): Promise<number>;
|
|
352
|
+
writeChunk(runId: string, data: Uint8Array): Promise<number>;
|
|
268
353
|
/**
|
|
269
354
|
* Close the stream (idempotent). Readers observe `done: true` once all
|
|
270
355
|
* previously written chunks have been consumed.
|
|
271
356
|
*/
|
|
272
|
-
closeStream(): Promise<void>;
|
|
357
|
+
closeStream(runId: string): Promise<void>;
|
|
273
358
|
/**
|
|
274
359
|
* Read up to `limit` chunks starting at `startIndex` (0-based, inclusive).
|
|
275
360
|
*/
|
|
@@ -293,11 +378,17 @@ declare class StreamDO extends DurableObject {
|
|
|
293
378
|
/**
|
|
294
379
|
* Register a stream name against this per-run registry instance.
|
|
295
380
|
*/
|
|
296
|
-
registerStream(name: string): Promise<void>;
|
|
381
|
+
registerStream(runId: string, name: string): Promise<void>;
|
|
297
382
|
/**
|
|
298
383
|
* List stream names registered against this per-run registry instance.
|
|
299
384
|
*/
|
|
300
385
|
listStreams(): Promise<string[]>;
|
|
386
|
+
/** Fence a run's registry before any stream cells are removed. */
|
|
387
|
+
expireRegistry(runId: string, expiredAt: number): Promise<ExpireRunStreamsResult>;
|
|
388
|
+
/** Remove the registry payload after every referenced stream was fenced. */
|
|
389
|
+
finalizeRegistry(runId: string): Promise<void>;
|
|
390
|
+
/** Delete stream payload while leaving a small ownership tombstone. */
|
|
391
|
+
expireStream(runId: string, expiredAt: number): Promise<ExpireStreamResult>;
|
|
301
392
|
}
|
|
302
393
|
//#endregion
|
|
303
394
|
//#region src/worker/durable-objects/WorkflowRunDO.d.ts
|
|
@@ -313,87 +404,59 @@ declare class StreamDO extends DurableObject {
|
|
|
313
404
|
*/
|
|
314
405
|
declare class WorkflowRunDO extends DurableObject {
|
|
315
406
|
private schemaReady;
|
|
316
|
-
|
|
317
|
-
* Lazily ensure schema migrations have run.
|
|
318
|
-
* Memoized so it only runs once per DO instantiation.
|
|
319
|
-
*/
|
|
407
|
+
private now;
|
|
320
408
|
private ensureSchema;
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
* outcomes (not thrown) because typed errors do not survive the RPC
|
|
325
|
-
* boundary with their `name` intact.
|
|
326
|
-
*/
|
|
409
|
+
private expiredTombstone;
|
|
410
|
+
private read;
|
|
411
|
+
/** Apply an event and capture all retention metadata in the same transaction. */
|
|
327
412
|
applyEvent(request: ApplyEventRequest): Promise<ApplyEventOutcome>;
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
*/
|
|
331
|
-
getRun(): Promise<WorkflowRun | null>;
|
|
332
|
-
/**
|
|
333
|
-
* Get a specific step
|
|
334
|
-
*/
|
|
335
|
-
getStep(stepId: string): Promise<Step | null>;
|
|
336
|
-
/**
|
|
337
|
-
* List steps with real limit/cursor pagination (cursor = last stepId).
|
|
338
|
-
*/
|
|
413
|
+
getRun(): Promise<RunReadOutcome<WorkflowRun | null>>;
|
|
414
|
+
getStep(stepId: string): Promise<RunReadOutcome<Step | null>>;
|
|
339
415
|
listSteps(params?: {
|
|
340
416
|
limit?: number;
|
|
341
417
|
cursor?: string;
|
|
342
418
|
sortOrder?: 'asc' | 'desc';
|
|
343
|
-
}): Promise<{
|
|
419
|
+
}): Promise<RunReadOutcome<{
|
|
344
420
|
data: Step[];
|
|
345
421
|
cursor: string | null;
|
|
346
422
|
hasMore: boolean;
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
* Get a specific event
|
|
350
|
-
*/
|
|
351
|
-
getEvent(eventId: string): Promise<Event | null>;
|
|
352
|
-
/**
|
|
353
|
-
* List events with real limit/cursor pagination. Events are keyed by their
|
|
354
|
-
* monotonic ULID eventId, so storage order == event order.
|
|
355
|
-
*/
|
|
423
|
+
}>>;
|
|
424
|
+
getEvent(eventId: string): Promise<RunReadOutcome<Event | null>>;
|
|
356
425
|
listEvents(params?: {
|
|
357
426
|
limit?: number;
|
|
358
427
|
cursor?: string;
|
|
359
428
|
sortOrder?: 'asc' | 'desc';
|
|
360
|
-
}): Promise<{
|
|
429
|
+
}): Promise<RunReadOutcome<{
|
|
361
430
|
data: Event[];
|
|
362
431
|
cursor: string | null;
|
|
363
432
|
hasMore: boolean;
|
|
364
|
-
}
|
|
365
|
-
/**
|
|
366
|
-
* List hooks with real limit/cursor pagination (cursor = last hookId).
|
|
367
|
-
*/
|
|
433
|
+
}>>;
|
|
368
434
|
listHooks(params?: {
|
|
369
435
|
limit?: number;
|
|
370
436
|
cursor?: string;
|
|
371
437
|
sortOrder?: 'asc' | 'desc';
|
|
372
|
-
}): Promise<{
|
|
438
|
+
}): Promise<RunReadOutcome<{
|
|
373
439
|
data: Hook[];
|
|
374
440
|
cursor: string | null;
|
|
375
441
|
hasMore: boolean;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
442
|
+
}>>;
|
|
443
|
+
getCleanupStatus(): Promise<CleanupRecord | null>;
|
|
444
|
+
/** Explicitly schedule an existing terminal run, used for opt-in backfills. */
|
|
445
|
+
scheduleCleanup(request: ScheduleCleanupRequest): Promise<CleanupRecord | null>;
|
|
446
|
+
cleanupNow(request: ScheduleCleanupRequest): Promise<CleanupRecord | null>;
|
|
447
|
+
rearmCleanup(): Promise<CleanupRecord | null>;
|
|
448
|
+
alarm(): Promise<void>;
|
|
449
|
+
private namespace;
|
|
450
|
+
private setCleanupPhase;
|
|
451
|
+
private executeCleanup;
|
|
452
|
+
private deletePayloadBatch;
|
|
453
|
+
private recordCleanupFailure;
|
|
388
454
|
claimInflight(params: {
|
|
389
455
|
messageId: string;
|
|
390
456
|
staleMs: number;
|
|
391
457
|
}): Promise<{
|
|
392
458
|
claimed: boolean;
|
|
393
459
|
}>;
|
|
394
|
-
/**
|
|
395
|
-
* Release a queue-message dedup claim after the message was fully handled.
|
|
396
|
-
*/
|
|
397
460
|
releaseInflight(): Promise<void>;
|
|
398
461
|
}
|
|
399
462
|
//#endregion
|
package/dist/worker.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.d.ts","names":[],"sources":["../src/worker/router.ts","../src/apply-event.ts","../src/queue.ts","../src/config.ts","../src/worker/do-base.ts","../src/worker/durable-objects/IndexDO.ts","../src/worker/durable-objects/QueueDO.ts","../src/worker/durable-objects/StreamDO.ts","../src/worker/durable-objects/WorkflowRunDO.ts","../src/worker/worker.ts"],"mappings":";;;UAmBiB;EACf,WAAW;IAAiB;;EAC5B,IAAI;IAAM;;;UAGK;EACf,aAAa;EACb,kBAAkB;EAClB,gBAAgB;EAChB,gBAAgB;EAChB;;
|
|
1
|
+
{"version":3,"file":"worker.d.ts","names":[],"sources":["../src/worker/router.ts","../src/retention.ts","../src/apply-event.ts","../src/queue.ts","../src/config.ts","../src/worker/do-base.ts","../src/worker/durable-objects/IndexDO.ts","../src/worker/durable-objects/QueueDO.ts","../src/worker/durable-objects/StreamDO.ts","../src/worker/durable-objects/WorkflowRunDO.ts","../src/worker/worker.ts"],"mappings":"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"}
|