@coji/durably 0.10.0 → 0.12.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/README.md +2 -2
- package/dist/{index-BjlCb0gP.d.ts → index-hM7-oiyj.d.ts} +88 -63
- package/dist/index.d.ts +46 -96
- package/dist/index.js +516 -415
- package/dist/index.js.map +1 -1
- package/dist/plugins/index.d.ts +1 -1
- package/docs/llms.md +179 -61
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ Step-oriented resumable batch execution for Node.js and browsers using SQLite.
|
|
|
12
12
|
npm install @coji/durably kysely zod better-sqlite3
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
See the [
|
|
15
|
+
See the [Quick Start](https://coji.github.io/durably/guide/quick-start) for other SQLite backends (libsql, SQLocal for browsers).
|
|
16
16
|
|
|
17
17
|
## Quick Start
|
|
18
18
|
|
|
@@ -30,7 +30,7 @@ const myJob = defineJob({
|
|
|
30
30
|
},
|
|
31
31
|
})
|
|
32
32
|
|
|
33
|
-
const durably = createDurably({ dialect
|
|
33
|
+
const durably = createDurably({ dialect, jobs: { myJob } })
|
|
34
34
|
|
|
35
35
|
await durably.init() // migrate + start
|
|
36
36
|
await durably.jobs.myJob.trigger({ id: '123' })
|
|
@@ -70,13 +70,12 @@ interface RunDeleteEvent extends BaseEvent {
|
|
|
70
70
|
labels: Record<string, string>;
|
|
71
71
|
}
|
|
72
72
|
/**
|
|
73
|
-
*
|
|
73
|
+
* Progress data reported by step.progress()
|
|
74
74
|
*/
|
|
75
|
-
interface
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
labels: Record<string, string>;
|
|
75
|
+
interface ProgressData {
|
|
76
|
+
current: number;
|
|
77
|
+
total?: number;
|
|
78
|
+
message?: string;
|
|
80
79
|
}
|
|
81
80
|
/**
|
|
82
81
|
* Run progress event
|
|
@@ -85,11 +84,7 @@ interface RunProgressEvent extends BaseEvent {
|
|
|
85
84
|
type: 'run:progress';
|
|
86
85
|
runId: string;
|
|
87
86
|
jobName: string;
|
|
88
|
-
progress:
|
|
89
|
-
current: number;
|
|
90
|
-
total?: number;
|
|
91
|
-
message?: string;
|
|
92
|
-
};
|
|
87
|
+
progress: ProgressData;
|
|
93
88
|
labels: Record<string, string>;
|
|
94
89
|
}
|
|
95
90
|
/**
|
|
@@ -136,17 +131,24 @@ interface StepCancelEvent extends BaseEvent {
|
|
|
136
131
|
stepIndex: number;
|
|
137
132
|
labels: Record<string, string>;
|
|
138
133
|
}
|
|
134
|
+
/**
|
|
135
|
+
* Log data reported by step.log
|
|
136
|
+
*/
|
|
137
|
+
interface LogData {
|
|
138
|
+
level: 'info' | 'warn' | 'error';
|
|
139
|
+
message: string;
|
|
140
|
+
data?: unknown;
|
|
141
|
+
stepName?: string | null;
|
|
142
|
+
}
|
|
139
143
|
/**
|
|
140
144
|
* Log write event
|
|
141
145
|
*/
|
|
142
|
-
interface LogWriteEvent extends BaseEvent {
|
|
146
|
+
interface LogWriteEvent extends BaseEvent, LogData {
|
|
143
147
|
type: 'log:write';
|
|
144
148
|
runId: string;
|
|
145
149
|
jobName: string;
|
|
146
150
|
labels: Record<string, string>;
|
|
147
151
|
stepName: string | null;
|
|
148
|
-
level: 'info' | 'warn' | 'error';
|
|
149
|
-
message: string;
|
|
150
152
|
data: unknown;
|
|
151
153
|
}
|
|
152
154
|
/**
|
|
@@ -161,7 +163,7 @@ interface WorkerErrorEvent extends BaseEvent {
|
|
|
161
163
|
/**
|
|
162
164
|
* All event types as discriminated union
|
|
163
165
|
*/
|
|
164
|
-
type DurablyEvent = RunTriggerEvent | RunStartEvent | RunCompleteEvent | RunFailEvent | RunCancelEvent | RunDeleteEvent |
|
|
166
|
+
type DurablyEvent = RunTriggerEvent | RunStartEvent | RunCompleteEvent | RunFailEvent | RunCancelEvent | RunDeleteEvent | RunProgressEvent | StepStartEvent | StepCompleteEvent | StepFailEvent | StepCancelEvent | LogWriteEvent | WorkerErrorEvent;
|
|
165
167
|
/**
|
|
166
168
|
* Event types for type-safe event names
|
|
167
169
|
*/
|
|
@@ -179,7 +181,7 @@ type EventInput<T extends EventType> = Omit<EventByType<T>, 'timestamp' | 'seque
|
|
|
179
181
|
/**
|
|
180
182
|
* All possible event inputs as a union (properly distributed)
|
|
181
183
|
*/
|
|
182
|
-
type AnyEventInput = EventInput<'run:trigger'> | EventInput<'run:start'> | EventInput<'run:complete'> | EventInput<'run:fail'> | EventInput<'run:cancel'> | EventInput<'run:delete'> | EventInput<'run:
|
|
184
|
+
type AnyEventInput = EventInput<'run:trigger'> | EventInput<'run:start'> | EventInput<'run:complete'> | EventInput<'run:fail'> | EventInput<'run:cancel'> | EventInput<'run:delete'> | EventInput<'run:progress'> | EventInput<'step:start'> | EventInput<'step:complete'> | EventInput<'step:fail'> | EventInput<'step:cancel'> | EventInput<'log:write'> | EventInput<'worker:error'>;
|
|
183
185
|
/**
|
|
184
186
|
* Event listener function
|
|
185
187
|
*/
|
|
@@ -248,17 +250,17 @@ interface Database {
|
|
|
248
250
|
/**
|
|
249
251
|
* Run data for creating a new run
|
|
250
252
|
*/
|
|
251
|
-
interface CreateRunInput {
|
|
253
|
+
interface CreateRunInput<TLabels extends Record<string, string> = Record<string, string>> {
|
|
252
254
|
jobName: string;
|
|
253
255
|
input: unknown;
|
|
254
256
|
idempotencyKey?: string;
|
|
255
257
|
concurrencyKey?: string;
|
|
256
|
-
labels?:
|
|
258
|
+
labels?: TLabels;
|
|
257
259
|
}
|
|
258
260
|
/**
|
|
259
261
|
* Run data returned from storage
|
|
260
262
|
*/
|
|
261
|
-
interface Run {
|
|
263
|
+
interface Run<TLabels extends Record<string, string> = Record<string, string>> {
|
|
262
264
|
id: string;
|
|
263
265
|
jobName: string;
|
|
264
266
|
input: unknown;
|
|
@@ -274,7 +276,7 @@ interface Run {
|
|
|
274
276
|
} | null;
|
|
275
277
|
output: unknown | null;
|
|
276
278
|
error: string | null;
|
|
277
|
-
labels:
|
|
279
|
+
labels: TLabels;
|
|
278
280
|
heartbeatAt: string;
|
|
279
281
|
startedAt: string | null;
|
|
280
282
|
completedAt: string | null;
|
|
@@ -301,10 +303,14 @@ interface UpdateRunInput {
|
|
|
301
303
|
/**
|
|
302
304
|
* Run filter options
|
|
303
305
|
*/
|
|
304
|
-
interface RunFilter
|
|
306
|
+
interface RunFilter<TLabels extends Record<string, string> = Record<string, string>> {
|
|
305
307
|
status?: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
|
|
306
|
-
|
|
307
|
-
|
|
308
|
+
/** Filter by job name(s). Pass a string for one, or an array for multiple (OR). */
|
|
309
|
+
jobName?: string | string[];
|
|
310
|
+
/** Filter by labels (all specified labels must match) */
|
|
311
|
+
labels?: {
|
|
312
|
+
[K in keyof TLabels]?: TLabels[K];
|
|
313
|
+
};
|
|
308
314
|
/** Maximum number of runs to return */
|
|
309
315
|
limit?: number;
|
|
310
316
|
/** Number of runs to skip (for pagination) */
|
|
@@ -362,11 +368,11 @@ interface Log {
|
|
|
362
368
|
* A client-safe subset of Run, excluding internal fields like
|
|
363
369
|
* heartbeatAt, idempotencyKey, concurrencyKey, and updatedAt.
|
|
364
370
|
*/
|
|
365
|
-
type ClientRun = Omit<Run
|
|
371
|
+
type ClientRun<TLabels extends Record<string, string> = Record<string, string>> = Omit<Run<TLabels>, 'idempotencyKey' | 'concurrencyKey' | 'heartbeatAt' | 'updatedAt'>;
|
|
366
372
|
/**
|
|
367
373
|
* Project a full Run to a ClientRun by stripping internal fields.
|
|
368
374
|
*/
|
|
369
|
-
declare function toClientRun(run: Run): ClientRun
|
|
375
|
+
declare function toClientRun<TLabels extends Record<string, string> = Record<string, string>>(run: Run<TLabels>): ClientRun<TLabels>;
|
|
370
376
|
/**
|
|
371
377
|
* Storage interface for database operations
|
|
372
378
|
*/
|
|
@@ -376,9 +382,10 @@ interface Storage {
|
|
|
376
382
|
updateRun(runId: string, data: UpdateRunInput): Promise<void>;
|
|
377
383
|
deleteRun(runId: string): Promise<void>;
|
|
378
384
|
getRun<T extends Run = Run>(runId: string): Promise<T | null>;
|
|
379
|
-
getRuns<T extends Run = Run>(filter?: RunFilter
|
|
385
|
+
getRuns<T extends Run = Run>(filter?: RunFilter): Promise<T[]>;
|
|
380
386
|
claimNextPendingRun(excludeConcurrencyKeys: string[]): Promise<Run | null>;
|
|
381
387
|
createStep(input: CreateStepInput): Promise<Step>;
|
|
388
|
+
deleteSteps(runId: string): Promise<void>;
|
|
382
389
|
getSteps(runId: string): Promise<Step[]>;
|
|
383
390
|
getCompletedStep(runId: string, name: string): Promise<Step | null>;
|
|
384
391
|
createLog(input: CreateLogInput): Promise<Log>;
|
|
@@ -411,39 +418,36 @@ interface StepContext {
|
|
|
411
418
|
};
|
|
412
419
|
}
|
|
413
420
|
/**
|
|
414
|
-
* Trigger options
|
|
421
|
+
* Trigger options for trigger() and batchTrigger()
|
|
415
422
|
*/
|
|
416
|
-
interface TriggerOptions {
|
|
423
|
+
interface TriggerOptions<TLabels extends Record<string, string> = Record<string, string>> {
|
|
417
424
|
idempotencyKey?: string;
|
|
418
425
|
concurrencyKey?: string;
|
|
419
|
-
labels?:
|
|
420
|
-
/** Timeout in milliseconds for triggerAndWait() */
|
|
421
|
-
timeout?: number;
|
|
426
|
+
labels?: TLabels;
|
|
422
427
|
}
|
|
423
428
|
/**
|
|
424
|
-
*
|
|
429
|
+
* Options for triggerAndWait() (extends TriggerOptions with wait-specific options)
|
|
425
430
|
*/
|
|
426
|
-
interface
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
offset?: number;
|
|
431
|
+
interface TriggerAndWaitOptions<TLabels extends Record<string, string> = Record<string, string>> extends TriggerOptions<TLabels> {
|
|
432
|
+
/** Timeout in milliseconds */
|
|
433
|
+
timeout?: number;
|
|
434
|
+
/** Called when step.progress() is invoked during execution */
|
|
435
|
+
onProgress?: (progress: ProgressData) => void | Promise<void>;
|
|
436
|
+
/** Called when step.log is invoked during execution */
|
|
437
|
+
onLog?: (log: LogData) => void | Promise<void>;
|
|
434
438
|
}
|
|
435
439
|
/**
|
|
436
440
|
* Typed run with output type
|
|
437
441
|
*/
|
|
438
|
-
interface TypedRun<TOutput> extends Omit<Run
|
|
442
|
+
interface TypedRun<TOutput, TLabels extends Record<string, string> = Record<string, string>> extends Omit<Run<TLabels>, 'output'> {
|
|
439
443
|
output: TOutput | null;
|
|
440
444
|
}
|
|
441
445
|
/**
|
|
442
446
|
* Batch trigger input - either just the input or input with options
|
|
443
447
|
*/
|
|
444
|
-
type BatchTriggerInput<TInput> = TInput | {
|
|
448
|
+
type BatchTriggerInput<TInput, TLabels extends Record<string, string> = Record<string, string>> = TInput | {
|
|
445
449
|
input: TInput;
|
|
446
|
-
options?: TriggerOptions
|
|
450
|
+
options?: TriggerOptions<TLabels>;
|
|
447
451
|
};
|
|
448
452
|
/**
|
|
449
453
|
* Result of triggerAndWait
|
|
@@ -455,30 +459,30 @@ interface TriggerAndWaitResult<TOutput> {
|
|
|
455
459
|
/**
|
|
456
460
|
* Job handle returned by defineJob
|
|
457
461
|
*/
|
|
458
|
-
interface JobHandle<TName extends string, TInput, TOutput> {
|
|
462
|
+
interface JobHandle<TName extends string, TInput, TOutput, TLabels extends Record<string, string> = Record<string, string>> {
|
|
459
463
|
readonly name: TName;
|
|
460
464
|
/**
|
|
461
465
|
* Trigger a new run
|
|
462
466
|
*/
|
|
463
|
-
trigger(input: TInput, options?: TriggerOptions): Promise<TypedRun<TOutput>>;
|
|
467
|
+
trigger(input: TInput, options?: TriggerOptions<TLabels>): Promise<TypedRun<TOutput, TLabels>>;
|
|
464
468
|
/**
|
|
465
469
|
* Trigger a new run and wait for completion
|
|
466
470
|
* Returns the output directly, throws if the run fails
|
|
467
471
|
*/
|
|
468
|
-
triggerAndWait(input: TInput, options?:
|
|
472
|
+
triggerAndWait(input: TInput, options?: TriggerAndWaitOptions<TLabels>): Promise<TriggerAndWaitResult<TOutput>>;
|
|
469
473
|
/**
|
|
470
474
|
* Trigger multiple runs in a batch
|
|
471
475
|
* All inputs are validated before any runs are created
|
|
472
476
|
*/
|
|
473
|
-
batchTrigger(inputs: BatchTriggerInput<TInput>[]): Promise<TypedRun<TOutput>[]>;
|
|
477
|
+
batchTrigger(inputs: BatchTriggerInput<TInput, TLabels>[]): Promise<TypedRun<TOutput, TLabels>[]>;
|
|
474
478
|
/**
|
|
475
479
|
* Get a run by ID
|
|
476
480
|
*/
|
|
477
|
-
getRun(id: string): Promise<TypedRun<TOutput> | null>;
|
|
481
|
+
getRun(id: string): Promise<TypedRun<TOutput, TLabels> | null>;
|
|
478
482
|
/**
|
|
479
483
|
* Get runs with optional filter
|
|
480
484
|
*/
|
|
481
|
-
getRuns(filter?: Omit<RunFilter
|
|
485
|
+
getRuns(filter?: Omit<RunFilter<TLabels>, 'jobName'>): Promise<TypedRun<TOutput, TLabels>[]>;
|
|
482
486
|
}
|
|
483
487
|
|
|
484
488
|
/**
|
|
@@ -544,29 +548,47 @@ declare function defineJob<TName extends string, TInputSchema extends z.ZodType,
|
|
|
544
548
|
/**
|
|
545
549
|
* Options for creating a Durably instance
|
|
546
550
|
*/
|
|
547
|
-
interface DurablyOptions {
|
|
551
|
+
interface DurablyOptions<TLabels extends Record<string, string> = Record<string, string>, TJobs extends Record<string, JobDefinition<string, any, any>> = Record<string, never>> {
|
|
548
552
|
dialect: Dialect;
|
|
549
553
|
pollingInterval?: number;
|
|
550
554
|
heartbeatInterval?: number;
|
|
551
555
|
staleThreshold?: number;
|
|
556
|
+
cleanupSteps?: boolean;
|
|
557
|
+
/**
|
|
558
|
+
* Zod schema for labels. When provided:
|
|
559
|
+
* - Labels are type-checked at compile time
|
|
560
|
+
* - Labels are validated at runtime on trigger()
|
|
561
|
+
*/
|
|
562
|
+
labels?: z.ZodType<TLabels>;
|
|
563
|
+
/**
|
|
564
|
+
* Job definitions to register. Shorthand for calling .register() after creation.
|
|
565
|
+
* @example
|
|
566
|
+
* ```ts
|
|
567
|
+
* const durably = createDurably({
|
|
568
|
+
* dialect,
|
|
569
|
+
* jobs: { importCsv: importCsvJob, syncUsers: syncUsersJob },
|
|
570
|
+
* })
|
|
571
|
+
* ```
|
|
572
|
+
*/
|
|
573
|
+
jobs?: TJobs;
|
|
552
574
|
}
|
|
553
575
|
/**
|
|
554
576
|
* Plugin interface for extending Durably
|
|
555
577
|
*/
|
|
556
578
|
interface DurablyPlugin {
|
|
557
579
|
name: string;
|
|
558
|
-
install(durably: Durably<any>): void;
|
|
580
|
+
install(durably: Durably<any, any>): void;
|
|
559
581
|
}
|
|
560
582
|
/**
|
|
561
583
|
* Helper type to transform JobDefinition record to JobHandle record
|
|
562
584
|
*/
|
|
563
|
-
type TransformToHandles<TJobs extends Record<string, JobDefinition<string, unknown, unknown
|
|
564
|
-
[K in keyof TJobs]: TJobs[K] extends JobDefinition<infer TName, infer TInput, infer TOutput> ? JobHandle<TName & string, TInput, TOutput> : never;
|
|
585
|
+
type TransformToHandles<TJobs extends Record<string, JobDefinition<string, unknown, unknown>>, TLabels extends Record<string, string> = Record<string, string>> = {
|
|
586
|
+
[K in keyof TJobs]: TJobs[K] extends JobDefinition<infer TName, infer TInput, infer TOutput> ? JobHandle<TName & string, TInput, TOutput, TLabels> : never;
|
|
565
587
|
};
|
|
566
588
|
/**
|
|
567
589
|
* Durably instance with type-safe jobs
|
|
568
590
|
*/
|
|
569
|
-
interface Durably<TJobs extends Record<string, JobHandle<string, unknown, unknown
|
|
591
|
+
interface Durably<TJobs extends Record<string, JobHandle<string, unknown, unknown, Record<string, string>>> = Record<string, never>, TLabels extends Record<string, string> = Record<string, string>> {
|
|
570
592
|
/**
|
|
571
593
|
* Registered job handles (type-safe)
|
|
572
594
|
*/
|
|
@@ -622,7 +644,7 @@ interface Durably<TJobs extends Record<string, JobHandle<string, unknown, unknow
|
|
|
622
644
|
* // Usage: durably.jobs.importCsv.trigger({ rows: [...] })
|
|
623
645
|
* ```
|
|
624
646
|
*/
|
|
625
|
-
register<TNewJobs extends Record<string, JobDefinition<string, any, any>>>(jobDefs: TNewJobs): Durably<TJobs & TransformToHandles<TNewJobs
|
|
647
|
+
register<TNewJobs extends Record<string, JobDefinition<string, any, any>>>(jobDefs: TNewJobs): Durably<TJobs & TransformToHandles<TNewJobs, TLabels>, TLabels>;
|
|
626
648
|
/**
|
|
627
649
|
* Start the worker polling loop
|
|
628
650
|
*/
|
|
@@ -632,10 +654,10 @@ interface Durably<TJobs extends Record<string, JobHandle<string, unknown, unknow
|
|
|
632
654
|
*/
|
|
633
655
|
stop(): Promise<void>;
|
|
634
656
|
/**
|
|
635
|
-
*
|
|
636
|
-
* @throws Error if run is
|
|
657
|
+
* Create a fresh run from a completed, failed, or cancelled run
|
|
658
|
+
* @throws Error if run is pending, running, or does not exist
|
|
637
659
|
*/
|
|
638
|
-
|
|
660
|
+
retrigger(runId: string): Promise<Run<TLabels>>;
|
|
639
661
|
/**
|
|
640
662
|
* Cancel a pending or running run
|
|
641
663
|
* @throws Error if run is already completed, failed, or cancelled
|
|
@@ -658,7 +680,7 @@ interface Durably<TJobs extends Record<string, JobHandle<string, unknown, unknow
|
|
|
658
680
|
* const typedRun = await durably.getRun<MyRun>(runId)
|
|
659
681
|
* ```
|
|
660
682
|
*/
|
|
661
|
-
getRun<T extends Run = Run
|
|
683
|
+
getRun<T extends Run<TLabels> = Run<TLabels>>(runId: string): Promise<T | null>;
|
|
662
684
|
/**
|
|
663
685
|
* Get runs with optional filtering
|
|
664
686
|
* @example
|
|
@@ -671,7 +693,7 @@ interface Durably<TJobs extends Record<string, JobHandle<string, unknown, unknow
|
|
|
671
693
|
* const typedRuns = await durably.getRuns<MyRun>({ jobName: 'my-job' })
|
|
672
694
|
* ```
|
|
673
695
|
*/
|
|
674
|
-
getRuns<T extends Run = Run
|
|
696
|
+
getRuns<T extends Run<TLabels> = Run<TLabels>>(filter?: RunFilter<TLabels>): Promise<T[]>;
|
|
675
697
|
/**
|
|
676
698
|
* Register a plugin
|
|
677
699
|
*/
|
|
@@ -680,7 +702,7 @@ interface Durably<TJobs extends Record<string, JobHandle<string, unknown, unknow
|
|
|
680
702
|
* Get a registered job handle by name
|
|
681
703
|
* Returns undefined if job is not registered
|
|
682
704
|
*/
|
|
683
|
-
getJob<TName extends string = string>(name: TName): JobHandle<TName, Record<string, unknown>, unknown> | undefined;
|
|
705
|
+
getJob<TName extends string = string>(name: TName): JobHandle<TName, Record<string, unknown>, unknown, TLabels> | undefined;
|
|
684
706
|
/**
|
|
685
707
|
* Subscribe to events for a specific run
|
|
686
708
|
* Returns a ReadableStream that can be used for SSE
|
|
@@ -690,11 +712,14 @@ interface Durably<TJobs extends Record<string, JobHandle<string, unknown, unknow
|
|
|
690
712
|
/**
|
|
691
713
|
* Create a Durably instance
|
|
692
714
|
*/
|
|
693
|
-
declare function createDurably
|
|
715
|
+
declare function createDurably<TLabels extends Record<string, string> = Record<string, string>, TJobs extends Record<string, JobDefinition<string, any, any>> = Record<string, never>>(options: DurablyOptions<TLabels, TJobs> & {
|
|
716
|
+
jobs: TJobs;
|
|
717
|
+
}): Durably<TransformToHandles<TJobs, TLabels>, TLabels>;
|
|
718
|
+
declare function createDurably<TLabels extends Record<string, string> = Record<string, string>>(options: DurablyOptions<TLabels>): Durably<Record<string, never>, TLabels>;
|
|
694
719
|
|
|
695
720
|
/**
|
|
696
721
|
* Plugin that persists log events to the database
|
|
697
722
|
*/
|
|
698
723
|
declare function withLogPersistence(): DurablyPlugin;
|
|
699
724
|
|
|
700
|
-
export { type StepsTable as A,
|
|
725
|
+
export { type StepsTable as A, type BatchTriggerInput as B, type ClientRun as C, type Durably as D, type ErrorHandler as E, type TriggerAndWaitResult as F, type TriggerOptions as G, createDurably as H, defineJob as I, type JobDefinition as J, toClientRun as K, type Log as L, withLogPersistence as M, type ProgressData as P, type Run as R, type SchemaVersionsTable as S, type TriggerAndWaitOptions as T, type WorkerErrorEvent as W, type RunFilter as a, type Database as b, type DurablyEvent as c, type DurablyOptions as d, type DurablyPlugin as e, type EventType as f, type JobHandle as g, type JobInput as h, type JobOutput as i, type LogData as j, type LogWriteEvent as k, type LogsTable as l, type RunCancelEvent as m, type RunCompleteEvent as n, type RunDeleteEvent as o, type RunFailEvent as p, type RunProgressEvent as q, type RunStartEvent as r, type RunTriggerEvent as s, type RunsTable as t, type Step as u, type StepCancelEvent as v, type StepCompleteEvent as w, type StepContext as x, type StepFailEvent as y, type StepStartEvent as z };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { D as Durably } from './index-
|
|
2
|
-
export { C as ClientRun,
|
|
1
|
+
import { R as Run, a as RunFilter, D as Durably } from './index-hM7-oiyj.js';
|
|
2
|
+
export { B as BatchTriggerInput, C as ClientRun, b as Database, c as DurablyEvent, d as DurablyOptions, e as DurablyPlugin, E as ErrorHandler, f as EventType, J as JobDefinition, g as JobHandle, h as JobInput, i as JobOutput, L as Log, j as LogData, k as LogWriteEvent, l as LogsTable, P as ProgressData, m as RunCancelEvent, n as RunCompleteEvent, o as RunDeleteEvent, p as RunFailEvent, q as RunProgressEvent, r as RunStartEvent, s as RunTriggerEvent, t as RunsTable, S as SchemaVersionsTable, u as Step, v as StepCancelEvent, w as StepCompleteEvent, x as StepContext, y as StepFailEvent, z as StepStartEvent, A as StepsTable, T as TriggerAndWaitOptions, F as TriggerAndWaitResult, G as TriggerOptions, W as WorkerErrorEvent, H as createDurably, I as defineJob, K as toClientRun, M as withLogPersistence } from './index-hM7-oiyj.js';
|
|
3
3
|
import 'kysely';
|
|
4
4
|
import 'zod';
|
|
5
5
|
|
|
@@ -12,15 +12,23 @@ declare class CancelledError extends Error {
|
|
|
12
12
|
constructor(runId: string);
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Run operation types for onRunAccess
|
|
17
|
+
*/
|
|
18
|
+
type RunOperation = 'read' | 'subscribe' | 'steps' | 'retrigger' | 'cancel' | 'delete';
|
|
19
|
+
/**
|
|
20
|
+
* Subscription filter — only fields that SSE subscriptions actually support.
|
|
21
|
+
*/
|
|
22
|
+
type RunsSubscribeFilter<TLabels extends Record<string, string> = Record<string, string>> = Pick<RunFilter<TLabels>, 'jobName' | 'labels'>;
|
|
15
23
|
/**
|
|
16
24
|
* Request body for triggering a job
|
|
17
25
|
*/
|
|
18
|
-
interface TriggerRequest {
|
|
26
|
+
interface TriggerRequest<TLabels extends Record<string, string> = Record<string, string>> {
|
|
19
27
|
jobName: string;
|
|
20
|
-
input:
|
|
28
|
+
input: unknown;
|
|
21
29
|
idempotencyKey?: string;
|
|
22
30
|
concurrencyKey?: string;
|
|
23
|
-
labels?:
|
|
31
|
+
labels?: TLabels;
|
|
24
32
|
}
|
|
25
33
|
/**
|
|
26
34
|
* Response for trigger endpoint
|
|
@@ -28,127 +36,69 @@ interface TriggerRequest {
|
|
|
28
36
|
interface TriggerResponse {
|
|
29
37
|
runId: string;
|
|
30
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Auth middleware configuration.
|
|
41
|
+
* When `auth` is set, `authenticate` is required.
|
|
42
|
+
* TContext is inferred from authenticate's return type.
|
|
43
|
+
* TLabels is inferred from the Durably instance.
|
|
44
|
+
*/
|
|
45
|
+
interface AuthConfig<TContext, TLabels extends Record<string, string> = Record<string, string>> {
|
|
46
|
+
/** Authenticate every request. Return context or throw Response to reject. */
|
|
47
|
+
authenticate: (request: Request) => Promise<TContext> | TContext;
|
|
48
|
+
/** Guard before trigger. Called after body validation and job resolution. */
|
|
49
|
+
onTrigger?: (ctx: TContext, trigger: TriggerRequest<TLabels>) => Promise<void> | void;
|
|
50
|
+
/** Guard before run-level operations. Run is pre-fetched. */
|
|
51
|
+
onRunAccess?: (ctx: TContext, run: Run<TLabels>, info: {
|
|
52
|
+
operation: RunOperation;
|
|
53
|
+
}) => Promise<void> | void;
|
|
54
|
+
/** Scope runs list queries (GET /runs). */
|
|
55
|
+
scopeRuns?: (ctx: TContext, filter: RunFilter<TLabels>) => RunFilter<TLabels> | Promise<RunFilter<TLabels>>;
|
|
56
|
+
/** Scope runs subscribe stream (GET /runs/subscribe). Falls back to scopeRuns if not set. */
|
|
57
|
+
scopeRunsSubscribe?: (ctx: TContext, filter: RunsSubscribeFilter<TLabels>) => RunsSubscribeFilter<TLabels> | Promise<RunsSubscribeFilter<TLabels>>;
|
|
58
|
+
}
|
|
31
59
|
/**
|
|
32
60
|
* Handler interface for HTTP endpoints
|
|
33
61
|
*/
|
|
34
62
|
interface DurablyHandler {
|
|
35
63
|
/**
|
|
36
|
-
* Handle all Durably HTTP requests with automatic routing
|
|
64
|
+
* Handle all Durably HTTP requests with automatic routing + auth
|
|
37
65
|
*
|
|
38
66
|
* Routes:
|
|
39
67
|
* - GET {basePath}/subscribe?runId=xxx - SSE stream
|
|
40
68
|
* - GET {basePath}/runs - List runs
|
|
69
|
+
* - GET {basePath}/runs/subscribe - SSE stream of run updates
|
|
41
70
|
* - GET {basePath}/run?runId=xxx - Get single run
|
|
71
|
+
* - GET {basePath}/steps?runId=xxx - Get steps
|
|
42
72
|
* - POST {basePath}/trigger - Trigger a job
|
|
43
|
-
* - POST {basePath}/
|
|
73
|
+
* - POST {basePath}/retrigger?runId=xxx - Create a fresh run from a terminal run
|
|
44
74
|
* - POST {basePath}/cancel?runId=xxx - Cancel a run
|
|
45
|
-
*
|
|
46
|
-
* @param request - The incoming HTTP request
|
|
47
|
-
* @param basePath - The base path to strip from the URL (e.g., '/api/durably')
|
|
48
|
-
* @returns Response or null if route not matched
|
|
49
|
-
*
|
|
50
|
-
* @example
|
|
51
|
-
* ```ts
|
|
52
|
-
* // React Router / Remix
|
|
53
|
-
* export async function loader({ request }) {
|
|
54
|
-
* return durablyHandler.handle(request, '/api/durably')
|
|
55
|
-
* }
|
|
56
|
-
* export async function action({ request }) {
|
|
57
|
-
* return durablyHandler.handle(request, '/api/durably')
|
|
58
|
-
* }
|
|
59
|
-
* ```
|
|
75
|
+
* - DELETE {basePath}/run?runId=xxx - Delete a run
|
|
60
76
|
*/
|
|
61
77
|
handle(request: Request, basePath: string): Promise<Response>;
|
|
62
|
-
/**
|
|
63
|
-
* Handle job trigger request
|
|
64
|
-
* Expects POST with JSON body: { jobName, input, idempotencyKey?, concurrencyKey? }
|
|
65
|
-
* Returns JSON: { runId }
|
|
66
|
-
*/
|
|
67
|
-
trigger(request: Request): Promise<Response>;
|
|
68
|
-
/**
|
|
69
|
-
* Handle subscription request
|
|
70
|
-
* Expects GET with query param: runId
|
|
71
|
-
* Returns SSE stream of events
|
|
72
|
-
*/
|
|
73
|
-
subscribe(request: Request): Response;
|
|
74
|
-
/**
|
|
75
|
-
* Handle runs list request
|
|
76
|
-
* Expects GET with optional query params: jobName, status, limit, offset
|
|
77
|
-
* Returns JSON array of runs
|
|
78
|
-
*/
|
|
79
|
-
runs(request: Request): Promise<Response>;
|
|
80
|
-
/**
|
|
81
|
-
* Handle single run request
|
|
82
|
-
* Expects GET with query param: runId
|
|
83
|
-
* Returns JSON run object or 404
|
|
84
|
-
*/
|
|
85
|
-
run(request: Request): Promise<Response>;
|
|
86
|
-
/**
|
|
87
|
-
* Handle retry request
|
|
88
|
-
* Expects POST with query param: runId
|
|
89
|
-
* Returns JSON: { success: true }
|
|
90
|
-
*/
|
|
91
|
-
retry(request: Request): Promise<Response>;
|
|
92
|
-
/**
|
|
93
|
-
* Handle cancel request
|
|
94
|
-
* Expects POST with query param: runId
|
|
95
|
-
* Returns JSON: { success: true }
|
|
96
|
-
*/
|
|
97
|
-
cancel(request: Request): Promise<Response>;
|
|
98
|
-
/**
|
|
99
|
-
* Handle delete request
|
|
100
|
-
* Expects DELETE with query param: runId
|
|
101
|
-
* Returns JSON: { success: true }
|
|
102
|
-
*/
|
|
103
|
-
delete(request: Request): Promise<Response>;
|
|
104
|
-
/**
|
|
105
|
-
* Handle steps request
|
|
106
|
-
* Expects GET with query param: runId
|
|
107
|
-
* Returns JSON array of steps
|
|
108
|
-
*/
|
|
109
|
-
steps(request: Request): Promise<Response>;
|
|
110
|
-
/**
|
|
111
|
-
* Handle runs subscription request
|
|
112
|
-
* Expects GET with optional query param: jobName
|
|
113
|
-
* Returns SSE stream of run update notifications
|
|
114
|
-
*/
|
|
115
|
-
runsSubscribe(request: Request): Response;
|
|
116
78
|
}
|
|
117
79
|
/**
|
|
118
80
|
* Options for createDurablyHandler
|
|
119
81
|
*/
|
|
120
|
-
interface CreateDurablyHandlerOptions {
|
|
82
|
+
interface CreateDurablyHandlerOptions<TContext = undefined, TLabels extends Record<string, string> = Record<string, string>> {
|
|
121
83
|
/**
|
|
122
|
-
* Called before handling each request.
|
|
84
|
+
* Called before handling each request (after authentication).
|
|
123
85
|
* Use this to initialize Durably (migrate, start worker, etc.)
|
|
124
|
-
*
|
|
125
|
-
* @example
|
|
126
|
-
* ```ts
|
|
127
|
-
* const durablyHandler = createDurablyHandler(durably, {
|
|
128
|
-
* onRequest: async () => {
|
|
129
|
-
* await durably.migrate()
|
|
130
|
-
* durably.start()
|
|
131
|
-
* }
|
|
132
|
-
* })
|
|
133
|
-
* ```
|
|
134
86
|
*/
|
|
135
87
|
onRequest?: () => Promise<void> | void;
|
|
136
88
|
/**
|
|
137
89
|
* Throttle interval in milliseconds for SSE progress events.
|
|
138
|
-
* When set, `run:progress` events are throttled per run so the client
|
|
139
|
-
* receives at most one progress update per throttle window.
|
|
140
|
-
* The first and last progress events are always delivered.
|
|
141
|
-
* Non-progress events are never throttled.
|
|
142
|
-
*
|
|
143
|
-
* Set to 0 to disable throttling.
|
|
144
90
|
* @default 100
|
|
145
91
|
*/
|
|
146
92
|
sseThrottleMs?: number;
|
|
93
|
+
/**
|
|
94
|
+
* Auth middleware. When set, authenticate is required and auth applies to ALL endpoints.
|
|
95
|
+
*/
|
|
96
|
+
auth?: AuthConfig<TContext, TLabels>;
|
|
147
97
|
}
|
|
148
98
|
/**
|
|
149
99
|
* Create HTTP handlers for Durably
|
|
150
100
|
* Uses Web Standard Request/Response for framework-agnostic usage
|
|
151
101
|
*/
|
|
152
|
-
declare function createDurablyHandler(durably: Durably, options?: CreateDurablyHandlerOptions): DurablyHandler;
|
|
102
|
+
declare function createDurablyHandler<TContext = undefined, TLabels extends Record<string, string> = Record<string, string>>(durably: Durably<any, TLabels>, options?: CreateDurablyHandlerOptions<TContext, TLabels>): DurablyHandler;
|
|
153
103
|
|
|
154
|
-
export { CancelledError, type CreateDurablyHandlerOptions, Durably, type DurablyHandler, type TriggerRequest, type TriggerResponse, createDurablyHandler };
|
|
104
|
+
export { type AuthConfig, CancelledError, type CreateDurablyHandlerOptions, Durably, type DurablyHandler, Run, RunFilter, type RunOperation, type RunsSubscribeFilter, type TriggerRequest, type TriggerResponse, createDurablyHandler };
|