@coji/durably 0.8.0 → 0.9.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 CHANGED
@@ -23,7 +23,7 @@ import { z } from 'zod'
23
23
  const myJob = defineJob({
24
24
  name: 'my-job',
25
25
  input: z.object({ id: z.string() }),
26
- run: async (step, payload) => {
26
+ run: async (step, input) => {
27
27
  await step.run('step-1', async () => {
28
28
  /* ... */
29
29
  })
@@ -1,4 +1,4 @@
1
- import { Dialect, Kysely } from 'kysely';
1
+ import { Kysely, Dialect } from 'kysely';
2
2
  import { z } from 'zod';
3
3
 
4
4
  /**
@@ -16,7 +16,8 @@ interface RunTriggerEvent extends BaseEvent {
16
16
  type: 'run:trigger';
17
17
  runId: string;
18
18
  jobName: string;
19
- payload: unknown;
19
+ input: unknown;
20
+ labels: Record<string, string>;
20
21
  }
21
22
  /**
22
23
  * Run start event
@@ -25,7 +26,8 @@ interface RunStartEvent extends BaseEvent {
25
26
  type: 'run:start';
26
27
  runId: string;
27
28
  jobName: string;
28
- payload: unknown;
29
+ input: unknown;
30
+ labels: Record<string, string>;
29
31
  }
30
32
  /**
31
33
  * Run complete event
@@ -36,6 +38,7 @@ interface RunCompleteEvent extends BaseEvent {
36
38
  jobName: string;
37
39
  output: unknown;
38
40
  duration: number;
41
+ labels: Record<string, string>;
39
42
  }
40
43
  /**
41
44
  * Run fail event
@@ -46,6 +49,7 @@ interface RunFailEvent extends BaseEvent {
46
49
  jobName: string;
47
50
  error: string;
48
51
  failedStepName: string;
52
+ labels: Record<string, string>;
49
53
  }
50
54
  /**
51
55
  * Run cancel event
@@ -54,6 +58,16 @@ interface RunCancelEvent extends BaseEvent {
54
58
  type: 'run:cancel';
55
59
  runId: string;
56
60
  jobName: string;
61
+ labels: Record<string, string>;
62
+ }
63
+ /**
64
+ * Run delete event (emitted when a run is deleted)
65
+ */
66
+ interface RunDeleteEvent extends BaseEvent {
67
+ type: 'run:delete';
68
+ runId: string;
69
+ jobName: string;
70
+ labels: Record<string, string>;
57
71
  }
58
72
  /**
59
73
  * Run retry event (emitted when a failed run is retried)
@@ -62,6 +76,7 @@ interface RunRetryEvent extends BaseEvent {
62
76
  type: 'run:retry';
63
77
  runId: string;
64
78
  jobName: string;
79
+ labels: Record<string, string>;
65
80
  }
66
81
  /**
67
82
  * Run progress event
@@ -75,6 +90,7 @@ interface RunProgressEvent extends BaseEvent {
75
90
  total?: number;
76
91
  message?: string;
77
92
  };
93
+ labels: Record<string, string>;
78
94
  }
79
95
  /**
80
96
  * Step start event
@@ -85,6 +101,7 @@ interface StepStartEvent extends BaseEvent {
85
101
  jobName: string;
86
102
  stepName: string;
87
103
  stepIndex: number;
104
+ labels: Record<string, string>;
88
105
  }
89
106
  /**
90
107
  * Step complete event
@@ -97,6 +114,7 @@ interface StepCompleteEvent extends BaseEvent {
97
114
  stepIndex: number;
98
115
  output: unknown;
99
116
  duration: number;
117
+ labels: Record<string, string>;
100
118
  }
101
119
  /**
102
120
  * Step fail event
@@ -108,6 +126,15 @@ interface StepFailEvent extends BaseEvent {
108
126
  stepName: string;
109
127
  stepIndex: number;
110
128
  error: string;
129
+ labels: Record<string, string>;
130
+ }
131
+ interface StepCancelEvent extends BaseEvent {
132
+ type: 'step:cancel';
133
+ runId: string;
134
+ jobName: string;
135
+ stepName: string;
136
+ stepIndex: number;
137
+ labels: Record<string, string>;
111
138
  }
112
139
  /**
113
140
  * Log write event
@@ -115,6 +142,8 @@ interface StepFailEvent extends BaseEvent {
115
142
  interface LogWriteEvent extends BaseEvent {
116
143
  type: 'log:write';
117
144
  runId: string;
145
+ jobName: string;
146
+ labels: Record<string, string>;
118
147
  stepName: string | null;
119
148
  level: 'info' | 'warn' | 'error';
120
149
  message: string;
@@ -132,7 +161,7 @@ interface WorkerErrorEvent extends BaseEvent {
132
161
  /**
133
162
  * All event types as discriminated union
134
163
  */
135
- type DurablyEvent = RunTriggerEvent | RunStartEvent | RunCompleteEvent | RunFailEvent | RunCancelEvent | RunRetryEvent | RunProgressEvent | StepStartEvent | StepCompleteEvent | StepFailEvent | LogWriteEvent | WorkerErrorEvent;
164
+ type DurablyEvent = RunTriggerEvent | RunStartEvent | RunCompleteEvent | RunFailEvent | RunCancelEvent | RunDeleteEvent | RunRetryEvent | RunProgressEvent | StepStartEvent | StepCompleteEvent | StepFailEvent | StepCancelEvent | LogWriteEvent | WorkerErrorEvent;
136
165
  /**
137
166
  * Event types for type-safe event names
138
167
  */
@@ -150,7 +179,7 @@ type EventInput<T extends EventType> = Omit<EventByType<T>, 'timestamp' | 'seque
150
179
  /**
151
180
  * All possible event inputs as a union (properly distributed)
152
181
  */
153
- type AnyEventInput = EventInput<'run:trigger'> | EventInput<'run:start'> | EventInput<'run:complete'> | EventInput<'run:fail'> | EventInput<'run:cancel'> | EventInput<'run:retry'> | EventInput<'run:progress'> | EventInput<'step:start'> | EventInput<'step:complete'> | EventInput<'step:fail'> | EventInput<'log:write'> | EventInput<'worker:error'>;
182
+ type AnyEventInput = EventInput<'run:trigger'> | EventInput<'run:start'> | EventInput<'run:complete'> | EventInput<'run:fail'> | EventInput<'run:cancel'> | EventInput<'run:delete'> | EventInput<'run:retry'> | EventInput<'run:progress'> | EventInput<'step:start'> | EventInput<'step:complete'> | EventInput<'step:fail'> | EventInput<'step:cancel'> | EventInput<'log:write'> | EventInput<'worker:error'>;
154
183
  /**
155
184
  * Event listener function
156
185
  */
@@ -170,7 +199,7 @@ type ErrorHandler = (error: Error, event: DurablyEvent) => void;
170
199
  interface RunsTable {
171
200
  id: string;
172
201
  job_name: string;
173
- payload: string;
202
+ input: string;
174
203
  status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
175
204
  idempotency_key: string | null;
176
205
  concurrency_key: string | null;
@@ -178,7 +207,10 @@ interface RunsTable {
178
207
  progress: string | null;
179
208
  output: string | null;
180
209
  error: string | null;
210
+ labels: string;
181
211
  heartbeat_at: string;
212
+ started_at: string | null;
213
+ completed_at: string | null;
182
214
  created_at: string;
183
215
  updated_at: string;
184
216
  }
@@ -187,7 +219,7 @@ interface StepsTable {
187
219
  run_id: string;
188
220
  name: string;
189
221
  index: number;
190
- status: 'completed' | 'failed';
222
+ status: 'completed' | 'failed' | 'cancelled';
191
223
  output: string | null;
192
224
  error: string | null;
193
225
  started_at: string;
@@ -218,9 +250,10 @@ interface Database {
218
250
  */
219
251
  interface CreateRunInput {
220
252
  jobName: string;
221
- payload: unknown;
253
+ input: unknown;
222
254
  idempotencyKey?: string;
223
255
  concurrencyKey?: string;
256
+ labels?: Record<string, string>;
224
257
  }
225
258
  /**
226
259
  * Run data returned from storage
@@ -228,7 +261,7 @@ interface CreateRunInput {
228
261
  interface Run {
229
262
  id: string;
230
263
  jobName: string;
231
- payload: unknown;
264
+ input: unknown;
232
265
  status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
233
266
  idempotencyKey: string | null;
234
267
  concurrencyKey: string | null;
@@ -241,7 +274,10 @@ interface Run {
241
274
  } | null;
242
275
  output: unknown | null;
243
276
  error: string | null;
277
+ labels: Record<string, string>;
244
278
  heartbeatAt: string;
279
+ startedAt: string | null;
280
+ completedAt: string | null;
245
281
  createdAt: string;
246
282
  updatedAt: string;
247
283
  }
@@ -259,6 +295,8 @@ interface UpdateRunInput {
259
295
  output?: unknown;
260
296
  error?: string | null;
261
297
  heartbeatAt?: string;
298
+ startedAt?: string;
299
+ completedAt?: string;
262
300
  }
263
301
  /**
264
302
  * Run filter options
@@ -266,6 +304,7 @@ interface UpdateRunInput {
266
304
  interface RunFilter$1 {
267
305
  status?: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
268
306
  jobName?: string;
307
+ labels?: Record<string, string>;
269
308
  /** Maximum number of runs to return */
270
309
  limit?: number;
271
310
  /** Number of runs to skip (for pagination) */
@@ -278,7 +317,7 @@ interface CreateStepInput {
278
317
  runId: string;
279
318
  name: string;
280
319
  index: number;
281
- status: 'completed' | 'failed';
320
+ status: 'completed' | 'failed' | 'cancelled';
282
321
  output?: unknown;
283
322
  error?: string;
284
323
  startedAt: string;
@@ -291,7 +330,7 @@ interface Step {
291
330
  runId: string;
292
331
  name: string;
293
332
  index: number;
294
- status: 'completed' | 'failed';
333
+ status: 'completed' | 'failed' | 'cancelled';
295
334
  output: unknown | null;
296
335
  error: string | null;
297
336
  startedAt: string;
@@ -319,6 +358,15 @@ interface Log {
319
358
  data: unknown | null;
320
359
  createdAt: string;
321
360
  }
361
+ /**
362
+ * A client-safe subset of Run, excluding internal fields like
363
+ * heartbeatAt, idempotencyKey, concurrencyKey, and updatedAt.
364
+ */
365
+ type ClientRun = Omit<Run, 'idempotencyKey' | 'concurrencyKey' | 'heartbeatAt' | 'updatedAt'>;
366
+ /**
367
+ * Project a full Run to a ClientRun by stripping internal fields.
368
+ */
369
+ declare function toClientRun(run: Run): ClientRun;
322
370
  /**
323
371
  * Storage interface for database operations
324
372
  */
@@ -329,7 +377,7 @@ interface Storage {
329
377
  deleteRun(runId: string): Promise<void>;
330
378
  getRun<T extends Run = Run>(runId: string): Promise<T | null>;
331
379
  getRuns<T extends Run = Run>(filter?: RunFilter$1): Promise<T[]>;
332
- getNextPendingRun(excludeConcurrencyKeys: string[]): Promise<Run | null>;
380
+ claimNextPendingRun(excludeConcurrencyKeys: string[]): Promise<Run | null>;
333
381
  createStep(input: CreateStepInput): Promise<Step>;
334
382
  getSteps(runId: string): Promise<Step[]>;
335
383
  getCompletedStep(runId: string, name: string): Promise<Step | null>;
@@ -348,7 +396,7 @@ interface StepContext {
348
396
  /**
349
397
  * Execute a step with automatic persistence and replay
350
398
  */
351
- run<T>(name: string, fn: () => T | Promise<T>): Promise<T>;
399
+ run<T>(name: string, fn: (signal: AbortSignal) => T | Promise<T>): Promise<T>;
352
400
  /**
353
401
  * Report progress for the current run
354
402
  */
@@ -368,6 +416,7 @@ interface StepContext {
368
416
  interface TriggerOptions {
369
417
  idempotencyKey?: string;
370
418
  concurrencyKey?: string;
419
+ labels?: Record<string, string>;
371
420
  /** Timeout in milliseconds for triggerAndWait() */
372
421
  timeout?: number;
373
422
  }
@@ -377,6 +426,7 @@ interface TriggerOptions {
377
426
  interface RunFilter {
378
427
  status?: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
379
428
  jobName?: string;
429
+ labels?: Record<string, string>;
380
430
  /** Maximum number of runs to return */
381
431
  limit?: number;
382
432
  /** Number of runs to skip (for pagination) */
@@ -434,7 +484,7 @@ interface JobHandle<TName extends string, TInput, TOutput> {
434
484
  /**
435
485
  * Job run function type
436
486
  */
437
- type JobRunFunction<TInput, TOutput> = (step: StepContext, payload: TInput) => Promise<TOutput>;
487
+ type JobRunFunction<TInput, TOutput> = (step: StepContext, input: TInput) => Promise<TOutput>;
438
488
  /**
439
489
  * Job definition - a standalone description of a job
440
490
  * This is the result of calling defineJob() and can be passed to durably.register()
@@ -482,8 +532,8 @@ interface DefineJobConfig<TName extends string, TInputSchema extends z.ZodType,
482
532
  * name: 'sync-users',
483
533
  * input: z.object({ orgId: z.string() }),
484
534
  * output: z.object({ syncedCount: z.number() }),
485
- * run: async (step, payload) => {
486
- * const users = await step.run('fetch-users', () => fetchUsers(payload.orgId))
535
+ * run: async (step, input) => {
536
+ * const users = await step.run('fetch-users', () => fetchUsers(input.orgId))
487
537
  * return { syncedCount: users.length }
488
538
  * },
489
539
  * })
@@ -604,7 +654,7 @@ interface Durably<TJobs extends Record<string, JobHandle<string, unknown, unknow
604
654
  * const run = await durably.getRun(runId)
605
655
  *
606
656
  * // Typed (returns custom type)
607
- * type MyRun = Run & { payload: { userId: string }; output: { count: number } | null }
657
+ * type MyRun = Run & { input: { userId: string }; output: { count: number } | null }
608
658
  * const typedRun = await durably.getRun<MyRun>(runId)
609
659
  * ```
610
660
  */
@@ -617,7 +667,7 @@ interface Durably<TJobs extends Record<string, JobHandle<string, unknown, unknow
617
667
  * const runs = await durably.getRuns({ status: 'completed' })
618
668
  *
619
669
  * // Typed (returns custom type[])
620
- * type MyRun = Run & { payload: { userId: string }; output: { count: number } | null }
670
+ * type MyRun = Run & { input: { userId: string }; output: { count: number } | null }
621
671
  * const typedRuns = await durably.getRuns<MyRun>({ jobName: 'my-job' })
622
672
  * ```
623
673
  */
@@ -647,4 +697,4 @@ declare function createDurably(options: DurablyOptions): Durably<Record<string,
647
697
  */
648
698
  declare function withLogPersistence(): DurablyPlugin;
649
699
 
650
- export { type Durably as D, type ErrorHandler as E, type JobDefinition as J, type LogWriteEvent as L, type RunCompleteEvent as R, type StepCompleteEvent as S, type TriggerAndWaitResult as T, type WorkerErrorEvent as W, type DurablyOptions as a, type DurablyPlugin as b, createDurably as c, defineJob as d, type JobInput as e, type JobOutput as f, type DurablyEvent as g, type EventType as h, type RunFailEvent as i, type RunProgressEvent as j, type RunStartEvent as k, type StepFailEvent as l, type StepStartEvent as m, type JobHandle as n, type StepContext as o, type Database as p, type LogsTable as q, type RunsTable as r, type SchemaVersionsTable as s, type StepsTable as t, type Log as u, type Run as v, withLogPersistence as w, type RunFilter$1 as x, type Step as y };
700
+ export { type StepsTable as A, createDurably as B, type ClientRun as C, type Durably as D, type ErrorHandler as E, defineJob as F, toClientRun as G, withLogPersistence as H, type JobDefinition as J, type Log as L, type Run as R, type SchemaVersionsTable as S, type TriggerAndWaitResult as T, type WorkerErrorEvent as W, type Database as a, type DurablyEvent as b, type DurablyOptions as c, type DurablyPlugin as d, type EventType as e, type JobHandle as f, type JobInput as g, type JobOutput as h, type LogWriteEvent as i, type LogsTable as j, type RunCancelEvent as k, type RunCompleteEvent as l, type RunDeleteEvent as m, type RunFailEvent as n, type RunFilter$1 as o, type RunProgressEvent as p, type RunRetryEvent 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-4aPZWn8r.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-4aPZWn8r.js';
1
+ import { D as Durably } from './index-BjlCb0gP.js';
2
+ export { C as ClientRun, a as Database, b as DurablyEvent, c as DurablyOptions, d as DurablyPlugin, E as ErrorHandler, e as EventType, J as JobDefinition, f as JobHandle, g as JobInput, h as JobOutput, L as Log, i as LogWriteEvent, j as LogsTable, R as Run, k as RunCancelEvent, l as RunCompleteEvent, m as RunDeleteEvent, n as RunFailEvent, o as RunFilter, p as RunProgressEvent, q as RunRetryEvent, 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 TriggerAndWaitResult, W as WorkerErrorEvent, B as createDurably, F as defineJob, G as toClientRun, H as withLogPersistence } from './index-BjlCb0gP.js';
3
3
  import 'kysely';
4
4
  import 'zod';
5
5
 
@@ -20,6 +20,7 @@ interface TriggerRequest {
20
20
  input: Record<string, unknown>;
21
21
  idempotencyKey?: string;
22
22
  concurrencyKey?: string;
23
+ labels?: Record<string, string>;
23
24
  }
24
25
  /**
25
26
  * Response for trigger endpoint