@coji/durably 0.4.0 → 0.6.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/README.md +15 -44
- package/dist/chunk-UCUP6NMJ.js +22 -0
- package/dist/chunk-UCUP6NMJ.js.map +1 -0
- package/dist/index-CHQw-b_O.d.ts +632 -0
- package/dist/index.d.ts +98 -499
- package/dist/index.js +591 -75
- package/dist/index.js.map +1 -1
- package/dist/plugins/index.d.ts +3 -8
- package/dist/plugins/index.js +3 -6
- package/dist/plugins/index.js.map +1 -1
- package/docs/llms.md +129 -17
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,543 +1,142 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { D as Durably } from './index-CHQw-b_O.js';
|
|
2
|
+
export { p as Database, g as DurablyEvent, a as DurablyOptions, b as DurablyPlugin, E as ErrorHandler, h as EventType, J as JobDefinition, n as JobHandle, e as JobInput, f as JobOutput, u as Log, L as LogWriteEvent, q as LogsTable, v as Run, R as RunCompleteEvent, i as RunFailEvent, x as RunFilter, j as RunProgressEvent, k as RunStartEvent, r as RunsTable, s as SchemaVersionsTable, y as Step, S as StepCompleteEvent, o as StepContext, l as StepFailEvent, m as StepStartEvent, t as StepsTable, T as TriggerAndWaitResult, W as WorkerErrorEvent, c as createDurably, d as defineJob, w as withLogPersistence } from './index-CHQw-b_O.js';
|
|
3
|
+
import 'kysely';
|
|
4
|
+
import 'zod';
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
|
-
*
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
type: string;
|
|
9
|
-
timestamp: string;
|
|
10
|
-
sequence: number;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Run start event
|
|
14
|
-
*/
|
|
15
|
-
interface RunStartEvent extends BaseEvent {
|
|
16
|
-
type: 'run:start';
|
|
17
|
-
runId: string;
|
|
18
|
-
jobName: string;
|
|
19
|
-
payload: unknown;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Run complete event
|
|
23
|
-
*/
|
|
24
|
-
interface RunCompleteEvent extends BaseEvent {
|
|
25
|
-
type: 'run:complete';
|
|
26
|
-
runId: string;
|
|
27
|
-
jobName: string;
|
|
28
|
-
output: unknown;
|
|
29
|
-
duration: number;
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Run fail event
|
|
33
|
-
*/
|
|
34
|
-
interface RunFailEvent extends BaseEvent {
|
|
35
|
-
type: 'run:fail';
|
|
36
|
-
runId: string;
|
|
37
|
-
jobName: string;
|
|
38
|
-
error: string;
|
|
39
|
-
failedStepName: string;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Step start event
|
|
43
|
-
*/
|
|
44
|
-
interface StepStartEvent extends BaseEvent {
|
|
45
|
-
type: 'step:start';
|
|
46
|
-
runId: string;
|
|
47
|
-
jobName: string;
|
|
48
|
-
stepName: string;
|
|
49
|
-
stepIndex: number;
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Step complete event
|
|
53
|
-
*/
|
|
54
|
-
interface StepCompleteEvent extends BaseEvent {
|
|
55
|
-
type: 'step:complete';
|
|
56
|
-
runId: string;
|
|
57
|
-
jobName: string;
|
|
58
|
-
stepName: string;
|
|
59
|
-
stepIndex: number;
|
|
60
|
-
output: unknown;
|
|
61
|
-
duration: number;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Step fail event
|
|
65
|
-
*/
|
|
66
|
-
interface StepFailEvent extends BaseEvent {
|
|
67
|
-
type: 'step:fail';
|
|
68
|
-
runId: string;
|
|
69
|
-
jobName: string;
|
|
70
|
-
stepName: string;
|
|
71
|
-
stepIndex: number;
|
|
72
|
-
error: string;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Log write event
|
|
76
|
-
*/
|
|
77
|
-
interface LogWriteEvent extends BaseEvent {
|
|
78
|
-
type: 'log:write';
|
|
79
|
-
runId: string;
|
|
80
|
-
stepName: string | null;
|
|
81
|
-
level: 'info' | 'warn' | 'error';
|
|
82
|
-
message: string;
|
|
83
|
-
data: unknown;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Worker error event (internal errors like heartbeat failures)
|
|
87
|
-
*/
|
|
88
|
-
interface WorkerErrorEvent extends BaseEvent {
|
|
89
|
-
type: 'worker:error';
|
|
90
|
-
error: string;
|
|
91
|
-
context: string;
|
|
92
|
-
runId?: string;
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* All event types as discriminated union
|
|
96
|
-
*/
|
|
97
|
-
type DurablyEvent = RunStartEvent | RunCompleteEvent | RunFailEvent | StepStartEvent | StepCompleteEvent | StepFailEvent | LogWriteEvent | WorkerErrorEvent;
|
|
98
|
-
/**
|
|
99
|
-
* Event types for type-safe event names
|
|
100
|
-
*/
|
|
101
|
-
type EventType = DurablyEvent['type'];
|
|
102
|
-
/**
|
|
103
|
-
* Extract event by type
|
|
104
|
-
*/
|
|
105
|
-
type EventByType<T extends EventType> = Extract<DurablyEvent, {
|
|
106
|
-
type: T;
|
|
107
|
-
}>;
|
|
108
|
-
/**
|
|
109
|
-
* Event input (without auto-generated fields)
|
|
110
|
-
*/
|
|
111
|
-
type EventInput<T extends EventType> = Omit<EventByType<T>, 'timestamp' | 'sequence'>;
|
|
112
|
-
/**
|
|
113
|
-
* All possible event inputs as a union (properly distributed)
|
|
114
|
-
*/
|
|
115
|
-
type AnyEventInput = EventInput<'run:start'> | EventInput<'run:complete'> | EventInput<'run:fail'> | EventInput<'step:start'> | EventInput<'step:complete'> | EventInput<'step:fail'> | EventInput<'log:write'> | EventInput<'worker:error'>;
|
|
116
|
-
/**
|
|
117
|
-
* Event listener function
|
|
118
|
-
*/
|
|
119
|
-
type EventListener<T extends EventType> = (event: EventByType<T>) => void;
|
|
120
|
-
/**
|
|
121
|
-
* Unsubscribe function returned by on()
|
|
122
|
-
*/
|
|
123
|
-
type Unsubscribe = () => void;
|
|
124
|
-
/**
|
|
125
|
-
* Error handler function for listener exceptions
|
|
126
|
-
*/
|
|
127
|
-
type ErrorHandler = (error: Error, event: DurablyEvent) => void;
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Database schema types for Durably
|
|
7
|
+
* Error thrown when a run is cancelled during execution.
|
|
8
|
+
* The worker catches this error and treats it specially - it does not
|
|
9
|
+
* mark the run as failed, as the run status is already 'cancelled'.
|
|
131
10
|
*/
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
job_name: string;
|
|
135
|
-
payload: string;
|
|
136
|
-
status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
|
|
137
|
-
idempotency_key: string | null;
|
|
138
|
-
concurrency_key: string | null;
|
|
139
|
-
current_step_index: number;
|
|
140
|
-
progress: string | null;
|
|
141
|
-
output: string | null;
|
|
142
|
-
error: string | null;
|
|
143
|
-
heartbeat_at: string;
|
|
144
|
-
created_at: string;
|
|
145
|
-
updated_at: string;
|
|
146
|
-
}
|
|
147
|
-
interface StepsTable {
|
|
148
|
-
id: string;
|
|
149
|
-
run_id: string;
|
|
150
|
-
name: string;
|
|
151
|
-
index: number;
|
|
152
|
-
status: 'completed' | 'failed';
|
|
153
|
-
output: string | null;
|
|
154
|
-
error: string | null;
|
|
155
|
-
started_at: string;
|
|
156
|
-
completed_at: string | null;
|
|
157
|
-
}
|
|
158
|
-
interface LogsTable {
|
|
159
|
-
id: string;
|
|
160
|
-
run_id: string;
|
|
161
|
-
step_name: string | null;
|
|
162
|
-
level: 'info' | 'warn' | 'error';
|
|
163
|
-
message: string;
|
|
164
|
-
data: string | null;
|
|
165
|
-
created_at: string;
|
|
166
|
-
}
|
|
167
|
-
interface SchemaVersionsTable {
|
|
168
|
-
version: number;
|
|
169
|
-
applied_at: string;
|
|
170
|
-
}
|
|
171
|
-
interface Database {
|
|
172
|
-
durably_runs: RunsTable;
|
|
173
|
-
durably_steps: StepsTable;
|
|
174
|
-
durably_logs: LogsTable;
|
|
175
|
-
durably_schema_versions: SchemaVersionsTable;
|
|
11
|
+
declare class CancelledError extends Error {
|
|
12
|
+
constructor(runId: string);
|
|
176
13
|
}
|
|
177
14
|
|
|
178
15
|
/**
|
|
179
|
-
*
|
|
16
|
+
* Request body for triggering a job
|
|
180
17
|
*/
|
|
181
|
-
interface
|
|
18
|
+
interface TriggerRequest {
|
|
182
19
|
jobName: string;
|
|
183
|
-
|
|
20
|
+
input: Record<string, unknown>;
|
|
184
21
|
idempotencyKey?: string;
|
|
185
22
|
concurrencyKey?: string;
|
|
186
23
|
}
|
|
187
24
|
/**
|
|
188
|
-
*
|
|
189
|
-
*/
|
|
190
|
-
interface Run {
|
|
191
|
-
id: string;
|
|
192
|
-
jobName: string;
|
|
193
|
-
payload: unknown;
|
|
194
|
-
status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
|
|
195
|
-
idempotencyKey: string | null;
|
|
196
|
-
concurrencyKey: string | null;
|
|
197
|
-
currentStepIndex: number;
|
|
198
|
-
progress: {
|
|
199
|
-
current: number;
|
|
200
|
-
total?: number;
|
|
201
|
-
message?: string;
|
|
202
|
-
} | null;
|
|
203
|
-
output: unknown | null;
|
|
204
|
-
error: string | null;
|
|
205
|
-
heartbeatAt: string;
|
|
206
|
-
createdAt: string;
|
|
207
|
-
updatedAt: string;
|
|
208
|
-
}
|
|
209
|
-
/**
|
|
210
|
-
* Run update data
|
|
211
|
-
*/
|
|
212
|
-
interface UpdateRunInput {
|
|
213
|
-
status?: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
|
|
214
|
-
currentStepIndex?: number;
|
|
215
|
-
progress?: {
|
|
216
|
-
current: number;
|
|
217
|
-
total?: number;
|
|
218
|
-
message?: string;
|
|
219
|
-
} | null;
|
|
220
|
-
output?: unknown;
|
|
221
|
-
error?: string | null;
|
|
222
|
-
heartbeatAt?: string;
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* Run filter options
|
|
226
|
-
*/
|
|
227
|
-
interface RunFilter$1 {
|
|
228
|
-
status?: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
|
|
229
|
-
jobName?: string;
|
|
230
|
-
/** Maximum number of runs to return */
|
|
231
|
-
limit?: number;
|
|
232
|
-
/** Number of runs to skip (for pagination) */
|
|
233
|
-
offset?: number;
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* Step data for creating a new step
|
|
25
|
+
* Response for trigger endpoint
|
|
237
26
|
*/
|
|
238
|
-
interface
|
|
27
|
+
interface TriggerResponse {
|
|
239
28
|
runId: string;
|
|
240
|
-
name: string;
|
|
241
|
-
index: number;
|
|
242
|
-
status: 'completed' | 'failed';
|
|
243
|
-
output?: unknown;
|
|
244
|
-
error?: string;
|
|
245
|
-
startedAt: string;
|
|
246
29
|
}
|
|
247
30
|
/**
|
|
248
|
-
*
|
|
31
|
+
* Handler interface for HTTP endpoints
|
|
249
32
|
*/
|
|
250
|
-
interface
|
|
251
|
-
id: string;
|
|
252
|
-
runId: string;
|
|
253
|
-
name: string;
|
|
254
|
-
index: number;
|
|
255
|
-
status: 'completed' | 'failed';
|
|
256
|
-
output: unknown | null;
|
|
257
|
-
error: string | null;
|
|
258
|
-
startedAt: string;
|
|
259
|
-
completedAt: string | null;
|
|
260
|
-
}
|
|
261
|
-
/**
|
|
262
|
-
* Log data for creating a new log
|
|
263
|
-
*/
|
|
264
|
-
interface CreateLogInput {
|
|
265
|
-
runId: string;
|
|
266
|
-
stepName: string | null;
|
|
267
|
-
level: 'info' | 'warn' | 'error';
|
|
268
|
-
message: string;
|
|
269
|
-
data?: unknown;
|
|
270
|
-
}
|
|
271
|
-
/**
|
|
272
|
-
* Log data returned from storage
|
|
273
|
-
*/
|
|
274
|
-
interface Log {
|
|
275
|
-
id: string;
|
|
276
|
-
runId: string;
|
|
277
|
-
stepName: string | null;
|
|
278
|
-
level: 'info' | 'warn' | 'error';
|
|
279
|
-
message: string;
|
|
280
|
-
data: unknown | null;
|
|
281
|
-
createdAt: string;
|
|
282
|
-
}
|
|
283
|
-
/**
|
|
284
|
-
* Storage interface for database operations
|
|
285
|
-
*/
|
|
286
|
-
interface Storage {
|
|
287
|
-
createRun(input: CreateRunInput): Promise<Run>;
|
|
288
|
-
batchCreateRuns(inputs: CreateRunInput[]): Promise<Run[]>;
|
|
289
|
-
updateRun(runId: string, data: UpdateRunInput): Promise<void>;
|
|
290
|
-
deleteRun(runId: string): Promise<void>;
|
|
291
|
-
getRun(runId: string): Promise<Run | null>;
|
|
292
|
-
getRuns(filter?: RunFilter$1): Promise<Run[]>;
|
|
293
|
-
getNextPendingRun(excludeConcurrencyKeys: string[]): Promise<Run | null>;
|
|
294
|
-
createStep(input: CreateStepInput): Promise<Step>;
|
|
295
|
-
getSteps(runId: string): Promise<Step[]>;
|
|
296
|
-
getCompletedStep(runId: string, name: string): Promise<Step | null>;
|
|
297
|
-
createLog(input: CreateLogInput): Promise<Log>;
|
|
298
|
-
getLogs(runId: string): Promise<Log[]>;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Step context passed to the job function
|
|
303
|
-
*/
|
|
304
|
-
interface StepContext {
|
|
33
|
+
interface DurablyHandler {
|
|
305
34
|
/**
|
|
306
|
-
*
|
|
35
|
+
* Handle all Durably HTTP requests with automatic routing
|
|
36
|
+
*
|
|
37
|
+
* Routes:
|
|
38
|
+
* - GET {basePath}/subscribe?runId=xxx - SSE stream
|
|
39
|
+
* - GET {basePath}/runs - List runs
|
|
40
|
+
* - GET {basePath}/run?runId=xxx - Get single run
|
|
41
|
+
* - POST {basePath}/trigger - Trigger a job
|
|
42
|
+
* - POST {basePath}/retry?runId=xxx - Retry a failed run
|
|
43
|
+
* - POST {basePath}/cancel?runId=xxx - Cancel a run
|
|
44
|
+
*
|
|
45
|
+
* @param request - The incoming HTTP request
|
|
46
|
+
* @param basePath - The base path to strip from the URL (e.g., '/api/durably')
|
|
47
|
+
* @returns Response or null if route not matched
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* // React Router / Remix
|
|
52
|
+
* export async function loader({ request }) {
|
|
53
|
+
* return durablyHandler.handle(request, '/api/durably')
|
|
54
|
+
* }
|
|
55
|
+
* export async function action({ request }) {
|
|
56
|
+
* return durablyHandler.handle(request, '/api/durably')
|
|
57
|
+
* }
|
|
58
|
+
* ```
|
|
307
59
|
*/
|
|
308
|
-
|
|
60
|
+
handle(request: Request, basePath: string): Promise<Response>;
|
|
309
61
|
/**
|
|
310
|
-
*
|
|
62
|
+
* Handle job trigger request
|
|
63
|
+
* Expects POST with JSON body: { jobName, input, idempotencyKey?, concurrencyKey? }
|
|
64
|
+
* Returns JSON: { runId }
|
|
311
65
|
*/
|
|
312
|
-
|
|
66
|
+
trigger(request: Request): Promise<Response>;
|
|
313
67
|
/**
|
|
314
|
-
*
|
|
68
|
+
* Handle subscription request
|
|
69
|
+
* Expects GET with query param: runId
|
|
70
|
+
* Returns SSE stream of events
|
|
315
71
|
*/
|
|
316
|
-
|
|
72
|
+
subscribe(request: Request): Response;
|
|
317
73
|
/**
|
|
318
|
-
*
|
|
74
|
+
* Handle runs list request
|
|
75
|
+
* Expects GET with optional query params: jobName, status, limit, offset
|
|
76
|
+
* Returns JSON array of runs
|
|
319
77
|
*/
|
|
320
|
-
|
|
321
|
-
info(message: string, data?: unknown): void;
|
|
322
|
-
warn(message: string, data?: unknown): void;
|
|
323
|
-
error(message: string, data?: unknown): void;
|
|
324
|
-
};
|
|
325
|
-
}
|
|
326
|
-
/**
|
|
327
|
-
* Trigger options
|
|
328
|
-
*/
|
|
329
|
-
interface TriggerOptions {
|
|
330
|
-
idempotencyKey?: string;
|
|
331
|
-
concurrencyKey?: string;
|
|
332
|
-
/** Timeout in milliseconds for triggerAndWait() */
|
|
333
|
-
timeout?: number;
|
|
334
|
-
}
|
|
335
|
-
/**
|
|
336
|
-
* Run filter options
|
|
337
|
-
*/
|
|
338
|
-
interface RunFilter {
|
|
339
|
-
status?: 'pending' | 'running' | 'completed' | 'failed';
|
|
340
|
-
jobName?: string;
|
|
341
|
-
}
|
|
342
|
-
/**
|
|
343
|
-
* Typed run with output type
|
|
344
|
-
*/
|
|
345
|
-
interface TypedRun<TOutput> extends Omit<Run, 'output'> {
|
|
346
|
-
output: TOutput | null;
|
|
347
|
-
}
|
|
348
|
-
/**
|
|
349
|
-
* Batch trigger input - either just the input or input with options
|
|
350
|
-
*/
|
|
351
|
-
type BatchTriggerInput<TInput> = TInput | {
|
|
352
|
-
input: TInput;
|
|
353
|
-
options?: TriggerOptions;
|
|
354
|
-
};
|
|
355
|
-
/**
|
|
356
|
-
* Result of triggerAndWait
|
|
357
|
-
*/
|
|
358
|
-
interface TriggerAndWaitResult<TOutput> {
|
|
359
|
-
id: string;
|
|
360
|
-
output: TOutput;
|
|
361
|
-
}
|
|
362
|
-
/**
|
|
363
|
-
* Job handle returned by defineJob
|
|
364
|
-
*/
|
|
365
|
-
interface JobHandle<TName extends string, TInput, TOutput> {
|
|
366
|
-
readonly name: TName;
|
|
78
|
+
runs(request: Request): Promise<Response>;
|
|
367
79
|
/**
|
|
368
|
-
*
|
|
80
|
+
* Handle single run request
|
|
81
|
+
* Expects GET with query param: runId
|
|
82
|
+
* Returns JSON run object or 404
|
|
369
83
|
*/
|
|
370
|
-
|
|
84
|
+
run(request: Request): Promise<Response>;
|
|
371
85
|
/**
|
|
372
|
-
*
|
|
373
|
-
*
|
|
86
|
+
* Handle retry request
|
|
87
|
+
* Expects POST with query param: runId
|
|
88
|
+
* Returns JSON: { success: true }
|
|
374
89
|
*/
|
|
375
|
-
|
|
90
|
+
retry(request: Request): Promise<Response>;
|
|
376
91
|
/**
|
|
377
|
-
*
|
|
378
|
-
*
|
|
92
|
+
* Handle cancel request
|
|
93
|
+
* Expects POST with query param: runId
|
|
94
|
+
* Returns JSON: { success: true }
|
|
379
95
|
*/
|
|
380
|
-
|
|
96
|
+
cancel(request: Request): Promise<Response>;
|
|
381
97
|
/**
|
|
382
|
-
*
|
|
98
|
+
* Handle delete request
|
|
99
|
+
* Expects DELETE with query param: runId
|
|
100
|
+
* Returns JSON: { success: true }
|
|
383
101
|
*/
|
|
384
|
-
|
|
102
|
+
delete(request: Request): Promise<Response>;
|
|
385
103
|
/**
|
|
386
|
-
*
|
|
104
|
+
* Handle steps request
|
|
105
|
+
* Expects GET with query param: runId
|
|
106
|
+
* Returns JSON array of steps
|
|
387
107
|
*/
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
/**
|
|
396
|
-
* Job definition - a standalone description of a job
|
|
397
|
-
* This is the result of calling defineJob() and can be passed to durably.register()
|
|
398
|
-
*/
|
|
399
|
-
interface JobDefinition<TName extends string, TInput, TOutput> {
|
|
400
|
-
readonly name: TName;
|
|
401
|
-
readonly input: z.ZodType<TInput>;
|
|
402
|
-
readonly output: z.ZodType<TOutput> | undefined;
|
|
403
|
-
readonly run: JobRunFunction<TInput, TOutput>;
|
|
404
|
-
}
|
|
405
|
-
/**
|
|
406
|
-
* Configuration for defining a job
|
|
407
|
-
*/
|
|
408
|
-
interface DefineJobConfig<TName extends string, TInputSchema extends z.ZodType, TOutputSchema extends z.ZodType | undefined> {
|
|
409
|
-
name: TName;
|
|
410
|
-
input: TInputSchema;
|
|
411
|
-
output?: TOutputSchema;
|
|
412
|
-
run: JobRunFunction<z.infer<TInputSchema>, TOutputSchema extends z.ZodType ? z.infer<TOutputSchema> : void>;
|
|
413
|
-
}
|
|
414
|
-
/**
|
|
415
|
-
* Define a job - creates a JobDefinition that can be registered with durably.register()
|
|
416
|
-
*
|
|
417
|
-
* @example
|
|
418
|
-
* ```ts
|
|
419
|
-
* import { defineJob } from '@coji/durably'
|
|
420
|
-
* import { z } from 'zod'
|
|
421
|
-
*
|
|
422
|
-
* export const syncUsers = defineJob({
|
|
423
|
-
* name: 'sync-users',
|
|
424
|
-
* input: z.object({ orgId: z.string() }),
|
|
425
|
-
* output: z.object({ syncedCount: z.number() }),
|
|
426
|
-
* run: async (step, payload) => {
|
|
427
|
-
* const users = await step.run('fetch-users', () => fetchUsers(payload.orgId))
|
|
428
|
-
* return { syncedCount: users.length }
|
|
429
|
-
* },
|
|
430
|
-
* })
|
|
431
|
-
* ```
|
|
432
|
-
*/
|
|
433
|
-
declare function defineJob<TName extends string, TInputSchema extends z.ZodType, TOutputSchema extends z.ZodType | undefined = undefined>(config: DefineJobConfig<TName, TInputSchema, TOutputSchema>): JobDefinition<TName, z.infer<TInputSchema>, TOutputSchema extends z.ZodType ? z.infer<TOutputSchema> : void>;
|
|
434
|
-
|
|
435
|
-
/**
|
|
436
|
-
* Options for creating a Durably instance
|
|
437
|
-
*/
|
|
438
|
-
interface DurablyOptions {
|
|
439
|
-
dialect: Dialect;
|
|
440
|
-
pollingInterval?: number;
|
|
441
|
-
heartbeatInterval?: number;
|
|
442
|
-
staleThreshold?: number;
|
|
443
|
-
}
|
|
444
|
-
/**
|
|
445
|
-
* Plugin interface for extending Durably
|
|
446
|
-
*/
|
|
447
|
-
interface DurablyPlugin {
|
|
448
|
-
name: string;
|
|
449
|
-
install(durably: Durably): void;
|
|
108
|
+
steps(request: Request): Promise<Response>;
|
|
109
|
+
/**
|
|
110
|
+
* Handle runs subscription request
|
|
111
|
+
* Expects GET with optional query param: jobName
|
|
112
|
+
* Returns SSE stream of run update notifications
|
|
113
|
+
*/
|
|
114
|
+
runsSubscribe(request: Request): Response;
|
|
450
115
|
}
|
|
451
116
|
/**
|
|
452
|
-
*
|
|
117
|
+
* Options for createDurablyHandler
|
|
453
118
|
*/
|
|
454
|
-
interface
|
|
455
|
-
/**
|
|
456
|
-
* Run database migrations
|
|
457
|
-
* This is idempotent and safe to call multiple times
|
|
458
|
-
*/
|
|
459
|
-
migrate(): Promise<void>;
|
|
460
|
-
/**
|
|
461
|
-
* Get the underlying Kysely database instance
|
|
462
|
-
* Useful for testing and advanced use cases
|
|
463
|
-
*/
|
|
464
|
-
readonly db: Kysely<Database>;
|
|
465
|
-
/**
|
|
466
|
-
* Storage layer for database operations
|
|
467
|
-
*/
|
|
468
|
-
readonly storage: Storage;
|
|
469
|
-
/**
|
|
470
|
-
* Register an event listener
|
|
471
|
-
* @returns Unsubscribe function
|
|
472
|
-
*/
|
|
473
|
-
on<T extends EventType>(type: T, listener: EventListener<T>): Unsubscribe;
|
|
474
|
-
/**
|
|
475
|
-
* Emit an event (auto-assigns timestamp and sequence)
|
|
476
|
-
*/
|
|
477
|
-
emit(event: AnyEventInput): void;
|
|
478
|
-
/**
|
|
479
|
-
* Register an error handler for listener exceptions
|
|
480
|
-
*/
|
|
481
|
-
onError(handler: ErrorHandler): void;
|
|
482
|
-
/**
|
|
483
|
-
* Register a job definition and return a job handle
|
|
484
|
-
* Same JobDefinition can be registered multiple times (idempotent)
|
|
485
|
-
* Different JobDefinitions with the same name will throw an error
|
|
486
|
-
*/
|
|
487
|
-
register<TName extends string, TInput, TOutput>(jobDef: JobDefinition<TName, TInput, TOutput>): JobHandle<TName, TInput, TOutput>;
|
|
488
|
-
/**
|
|
489
|
-
* Start the worker polling loop
|
|
490
|
-
*/
|
|
491
|
-
start(): void;
|
|
492
|
-
/**
|
|
493
|
-
* Stop the worker after current run completes
|
|
494
|
-
*/
|
|
495
|
-
stop(): Promise<void>;
|
|
496
|
-
/**
|
|
497
|
-
* Retry a failed run by resetting it to pending
|
|
498
|
-
* @throws Error if run is not in failed status
|
|
499
|
-
*/
|
|
500
|
-
retry(runId: string): Promise<void>;
|
|
501
|
-
/**
|
|
502
|
-
* Cancel a pending or running run
|
|
503
|
-
* @throws Error if run is already completed, failed, or cancelled
|
|
504
|
-
*/
|
|
505
|
-
cancel(runId: string): Promise<void>;
|
|
119
|
+
interface CreateDurablyHandlerOptions {
|
|
506
120
|
/**
|
|
507
|
-
*
|
|
508
|
-
*
|
|
121
|
+
* Called before handling each request.
|
|
122
|
+
* Use this to initialize Durably (migrate, start worker, etc.)
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```ts
|
|
126
|
+
* const durablyHandler = createDurablyHandler(durably, {
|
|
127
|
+
* onRequest: async () => {
|
|
128
|
+
* await durably.migrate()
|
|
129
|
+
* durably.start()
|
|
130
|
+
* }
|
|
131
|
+
* })
|
|
132
|
+
* ```
|
|
509
133
|
*/
|
|
510
|
-
|
|
511
|
-
/**
|
|
512
|
-
* Get a run by ID (returns unknown output type)
|
|
513
|
-
*/
|
|
514
|
-
getRun(runId: string): Promise<Run | null>;
|
|
515
|
-
/**
|
|
516
|
-
* Get runs with optional filtering
|
|
517
|
-
*/
|
|
518
|
-
getRuns(filter?: RunFilter$1): Promise<Run[]>;
|
|
519
|
-
/**
|
|
520
|
-
* Register a plugin
|
|
521
|
-
*/
|
|
522
|
-
use(plugin: DurablyPlugin): void;
|
|
134
|
+
onRequest?: () => Promise<void> | void;
|
|
523
135
|
}
|
|
524
136
|
/**
|
|
525
|
-
* Create
|
|
137
|
+
* Create HTTP handlers for Durably
|
|
138
|
+
* Uses Web Standard Request/Response for framework-agnostic usage
|
|
526
139
|
*/
|
|
527
|
-
declare function
|
|
528
|
-
|
|
529
|
-
/**
|
|
530
|
-
* Plugin that persists log events to the database
|
|
531
|
-
*/
|
|
532
|
-
declare function withLogPersistence(): DurablyPlugin;
|
|
533
|
-
|
|
534
|
-
/**
|
|
535
|
-
* Error thrown when a run is cancelled during execution.
|
|
536
|
-
* The worker catches this error and treats it specially - it does not
|
|
537
|
-
* mark the run as failed, as the run status is already 'cancelled'.
|
|
538
|
-
*/
|
|
539
|
-
declare class CancelledError extends Error {
|
|
540
|
-
constructor(runId: string);
|
|
541
|
-
}
|
|
140
|
+
declare function createDurablyHandler(durably: Durably, options?: CreateDurablyHandlerOptions): DurablyHandler;
|
|
542
141
|
|
|
543
|
-
export { CancelledError,
|
|
142
|
+
export { CancelledError, Durably, type DurablyHandler, type TriggerRequest, type TriggerResponse, createDurablyHandler };
|