duron 0.3.0-beta.9 → 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.
Files changed (91) hide show
  1. package/dist/action-job.d.ts +33 -2
  2. package/dist/action-job.d.ts.map +1 -1
  3. package/dist/action-job.js +88 -23
  4. package/dist/action-manager.d.ts +44 -2
  5. package/dist/action-manager.d.ts.map +1 -1
  6. package/dist/action-manager.js +64 -3
  7. package/dist/action.d.ts +388 -7
  8. package/dist/action.d.ts.map +1 -1
  9. package/dist/action.js +44 -23
  10. package/dist/adapters/adapter.d.ts +365 -8
  11. package/dist/adapters/adapter.d.ts.map +1 -1
  12. package/dist/adapters/adapter.js +221 -15
  13. package/dist/adapters/postgres/base.d.ts +184 -6
  14. package/dist/adapters/postgres/base.d.ts.map +1 -1
  15. package/dist/adapters/postgres/base.js +436 -75
  16. package/dist/adapters/postgres/pglite.d.ts +37 -0
  17. package/dist/adapters/postgres/pglite.d.ts.map +1 -1
  18. package/dist/adapters/postgres/pglite.js +38 -0
  19. package/dist/adapters/postgres/postgres.d.ts +35 -0
  20. package/dist/adapters/postgres/postgres.d.ts.map +1 -1
  21. package/dist/adapters/postgres/postgres.js +42 -0
  22. package/dist/adapters/postgres/schema.d.ts +150 -37
  23. package/dist/adapters/postgres/schema.d.ts.map +1 -1
  24. package/dist/adapters/postgres/schema.default.d.ts +151 -38
  25. package/dist/adapters/postgres/schema.default.d.ts.map +1 -1
  26. package/dist/adapters/postgres/schema.default.js +2 -2
  27. package/dist/adapters/postgres/schema.js +60 -23
  28. package/dist/adapters/schemas.d.ts +124 -80
  29. package/dist/adapters/schemas.d.ts.map +1 -1
  30. package/dist/adapters/schemas.js +139 -26
  31. package/dist/client.d.ts +426 -22
  32. package/dist/client.d.ts.map +1 -1
  33. package/dist/client.js +370 -20
  34. package/dist/constants.js +6 -0
  35. package/dist/errors.d.ts +140 -3
  36. package/dist/errors.d.ts.map +1 -1
  37. package/dist/errors.js +152 -9
  38. package/dist/index.d.ts +2 -1
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/server.d.ts +99 -37
  41. package/dist/server.d.ts.map +1 -1
  42. package/dist/server.js +84 -25
  43. package/dist/step-manager.d.ts +111 -4
  44. package/dist/step-manager.d.ts.map +1 -1
  45. package/dist/step-manager.js +403 -75
  46. package/dist/telemetry/index.d.ts +1 -4
  47. package/dist/telemetry/index.d.ts.map +1 -1
  48. package/dist/telemetry/index.js +2 -4
  49. package/dist/telemetry/local-span-exporter.d.ts +56 -0
  50. package/dist/telemetry/local-span-exporter.d.ts.map +1 -0
  51. package/dist/telemetry/local-span-exporter.js +118 -0
  52. package/dist/utils/p-retry.d.ts +5 -0
  53. package/dist/utils/p-retry.d.ts.map +1 -1
  54. package/dist/utils/p-retry.js +8 -0
  55. package/dist/utils/wait-for-abort.d.ts +1 -0
  56. package/dist/utils/wait-for-abort.d.ts.map +1 -1
  57. package/dist/utils/wait-for-abort.js +1 -0
  58. package/migrations/postgres/{20260119153838_flimsy_thor_girl → 20260121160012_normal_bloodstrike}/migration.sql +32 -20
  59. package/migrations/postgres/{20260119153838_flimsy_thor_girl → 20260121160012_normal_bloodstrike}/snapshot.json +241 -66
  60. package/package.json +42 -26
  61. package/src/action-job.ts +33 -29
  62. package/src/action-manager.ts +5 -5
  63. package/src/action.ts +317 -149
  64. package/src/adapters/adapter.ts +54 -54
  65. package/src/adapters/postgres/base.ts +266 -86
  66. package/src/adapters/postgres/schema.default.ts +2 -2
  67. package/src/adapters/postgres/schema.ts +52 -24
  68. package/src/adapters/schemas.ts +91 -36
  69. package/src/client.ts +322 -68
  70. package/src/errors.ts +84 -12
  71. package/src/index.ts +2 -0
  72. package/src/server.ts +39 -37
  73. package/src/step-manager.ts +246 -95
  74. package/src/telemetry/index.ts +2 -20
  75. package/src/telemetry/local-span-exporter.ts +148 -0
  76. package/dist/telemetry/adapter.d.ts +0 -107
  77. package/dist/telemetry/adapter.d.ts.map +0 -1
  78. package/dist/telemetry/adapter.js +0 -134
  79. package/dist/telemetry/local.d.ts +0 -22
  80. package/dist/telemetry/local.d.ts.map +0 -1
  81. package/dist/telemetry/local.js +0 -243
  82. package/dist/telemetry/noop.d.ts +0 -17
  83. package/dist/telemetry/noop.d.ts.map +0 -1
  84. package/dist/telemetry/noop.js +0 -66
  85. package/dist/telemetry/opentelemetry.d.ts +0 -25
  86. package/dist/telemetry/opentelemetry.d.ts.map +0 -1
  87. package/dist/telemetry/opentelemetry.js +0 -312
  88. package/src/telemetry/adapter.ts +0 -642
  89. package/src/telemetry/local.ts +0 -429
  90. package/src/telemetry/noop.ts +0 -141
  91. package/src/telemetry/opentelemetry.ts +0 -453
@@ -1,642 +0,0 @@
1
- import type { Logger } from 'pino'
2
-
3
- import type { Adapter } from '../adapters/adapter.js'
4
-
5
- // ============================================================================
6
- // Types
7
- // ============================================================================
8
-
9
- /**
10
- * Interface representing the minimal Duron client required by telemetry adapters.
11
- * This avoids circular dependencies by using a minimal interface.
12
- */
13
- export interface TelemetryClient {
14
- /**
15
- * The database adapter instance.
16
- */
17
- database: Adapter
18
- }
19
-
20
- /**
21
- * Span represents a trace span for job or step execution.
22
- */
23
- export interface Span {
24
- /**
25
- * Unique identifier for this span.
26
- */
27
- id: string
28
-
29
- /**
30
- * The job ID this span belongs to.
31
- */
32
- jobId: string
33
-
34
- /**
35
- * The step ID this span belongs to (null for job spans).
36
- */
37
- stepId: string | null
38
-
39
- /**
40
- * Parent span ID for nested spans.
41
- */
42
- parentSpanId: string | null
43
- }
44
-
45
- /**
46
- * Options for starting a job span.
47
- */
48
- export interface StartJobSpanOptions {
49
- jobId: string
50
- actionName: string
51
- groupKey: string
52
- input?: any
53
- }
54
-
55
- /**
56
- * Options for starting a step span.
57
- */
58
- export interface StartStepSpanOptions {
59
- jobId: string
60
- stepId: string
61
- stepName: string
62
- parentSpan?: Span
63
- parentStepId: string | null
64
- }
65
-
66
- /**
67
- * Options for ending a span.
68
- */
69
- export interface EndSpanOptions {
70
- status: 'ok' | 'error' | 'cancelled'
71
- error?: any
72
- }
73
-
74
- /**
75
- * Options for starting a database span.
76
- */
77
- export interface StartDatabaseSpanOptions {
78
- operation: string
79
- query?: string
80
- }
81
-
82
- /**
83
- * Options for recording a metric.
84
- */
85
- export interface RecordMetricOptions {
86
- jobId: string
87
- stepId?: string
88
- name: string
89
- value: number
90
- attributes?: Record<string, any>
91
- }
92
-
93
- /**
94
- * Options for adding a span event.
95
- */
96
- export interface AddSpanEventOptions {
97
- span: Span
98
- name: string
99
- attributes?: Record<string, any>
100
- }
101
-
102
- /**
103
- * Options for adding a span attribute.
104
- */
105
- export interface AddSpanAttributeOptions {
106
- span: Span
107
- key: string
108
- value: string | number | boolean
109
- }
110
-
111
- /**
112
- * Options for starting a custom span with the tracer.
113
- */
114
- export interface StartSpanOptions {
115
- /**
116
- * Span kind (internal, client, server, producer, consumer).
117
- * @default 'internal'
118
- */
119
- kind?: 'internal' | 'client' | 'server' | 'producer' | 'consumer'
120
-
121
- /**
122
- * Initial attributes for the span.
123
- */
124
- attributes?: Record<string, string | number | boolean>
125
-
126
- /**
127
- * Parent span to use for context propagation.
128
- * If not provided, uses the current active context.
129
- */
130
- parentSpan?: TracerSpan
131
- }
132
-
133
- /**
134
- * A span created by the Tracer for manual instrumentation.
135
- */
136
- export interface TracerSpan {
137
- /**
138
- * Set an attribute on the span.
139
- *
140
- * @param key - The attribute key
141
- * @param value - The attribute value
142
- */
143
- setAttribute(key: string, value: string | number | boolean): void
144
-
145
- /**
146
- * Set multiple attributes on the span.
147
- *
148
- * @param attributes - The attributes to set
149
- */
150
- setAttributes(attributes: Record<string, string | number | boolean>): void
151
-
152
- /**
153
- * Add an event to the span.
154
- *
155
- * @param name - The event name
156
- * @param attributes - Optional event attributes
157
- */
158
- addEvent(name: string, attributes?: Record<string, string | number | boolean>): void
159
-
160
- /**
161
- * Record an exception on the span.
162
- *
163
- * @param error - The error to record
164
- */
165
- recordException(error: Error): void
166
-
167
- /**
168
- * Set the span status to OK.
169
- */
170
- setStatusOk(): void
171
-
172
- /**
173
- * Set the span status to error.
174
- *
175
- * @param message - Optional error message
176
- */
177
- setStatusError(message?: string): void
178
-
179
- /**
180
- * End the span.
181
- * After calling this, no more operations can be performed on the span.
182
- */
183
- end(): void
184
-
185
- /**
186
- * Check if this span is recording.
187
- */
188
- isRecording(): boolean
189
- }
190
-
191
- /**
192
- * A Tracer provides methods for creating spans.
193
- * Similar to OpenTelemetry's Tracer interface.
194
- */
195
- export interface Tracer {
196
- /**
197
- * The name of this tracer.
198
- */
199
- readonly name: string
200
-
201
- /**
202
- * Start a new span.
203
- *
204
- * @param name - The name of the span
205
- * @param options - Optional span configuration
206
- * @returns A TracerSpan for manual instrumentation
207
- */
208
- startSpan(name: string, options?: StartSpanOptions): TracerSpan
209
- }
210
-
211
- /**
212
- * Observe context provided to action and step handlers.
213
- */
214
- export interface ObserveContext {
215
- /**
216
- * Record a custom metric.
217
- *
218
- * @param name - The metric name (e.g., 'ai.tokens.total', 'processing.duration_ms')
219
- * @param value - The metric value
220
- * @param attributes - Optional attributes for the metric
221
- */
222
- recordMetric(name: string, value: number, attributes?: Record<string, any>): void
223
-
224
- /**
225
- * Add an attribute to the current span.
226
- *
227
- * @param key - The attribute key
228
- * @param value - The attribute value
229
- */
230
- addSpanAttribute(key: string, value: string | number | boolean): void
231
-
232
- /**
233
- * Add an event to the current span.
234
- *
235
- * @param name - The event name
236
- * @param attributes - Optional event attributes
237
- */
238
- addSpanEvent(name: string, attributes?: Record<string, any>): void
239
-
240
- /**
241
- * Get a tracer for manual instrumentation.
242
- * Similar to OpenTelemetry's `trace.getTracer()` method.
243
- *
244
- * @param name - The name of the tracer (typically your service or library name)
245
- * @returns A Tracer for creating custom spans
246
- *
247
- * @example
248
- * ```typescript
249
- * const tracer = ctx.observe.getTracer('my-service')
250
- *
251
- * const span = tracer.startSpan('external-api-call', {
252
- * kind: 'client',
253
- * attributes: { 'api.endpoint': '/users' }
254
- * })
255
- *
256
- * try {
257
- * const result = await fetch('https://api.example.com/users')
258
- * span.setStatusOk()
259
- * return result
260
- * } catch (error) {
261
- * span.recordException(error)
262
- * span.setStatusError(error.message)
263
- * throw error
264
- * } finally {
265
- * span.end()
266
- * }
267
- * ```
268
- */
269
- getTracer(name: string): Tracer
270
- }
271
-
272
- // ============================================================================
273
- // Abstract Telemetry Adapter
274
- // ============================================================================
275
-
276
- /**
277
- * Abstract base class for telemetry adapters.
278
- * All telemetry adapters must extend this class and implement its abstract methods.
279
- */
280
- export abstract class TelemetryAdapter {
281
- #logger: Logger | null = null
282
- #client: TelemetryClient | null = null
283
- #started: boolean = false
284
- #stopped: boolean = false
285
- #starting: Promise<boolean> | null = null
286
- #stopping: Promise<boolean> | null = null
287
-
288
- // ============================================================================
289
- // Lifecycle Methods
290
- // ============================================================================
291
-
292
- /**
293
- * Start the telemetry adapter.
294
- * Performs any necessary initialization.
295
- *
296
- * @returns Promise resolving to `true` if started successfully, `false` otherwise
297
- */
298
- async start(): Promise<boolean> {
299
- try {
300
- if (this.#stopping || this.#stopped) {
301
- return false
302
- }
303
-
304
- if (this.#started) {
305
- return true
306
- }
307
-
308
- if (this.#starting) {
309
- return this.#starting
310
- }
311
-
312
- this.#starting = (async () => {
313
- await this._start()
314
- this.#started = true
315
- this.#starting = null
316
- return true
317
- })()
318
-
319
- return this.#starting
320
- } catch (error) {
321
- this.#logger?.error(error, 'Error in TelemetryAdapter.start()')
322
- throw error
323
- }
324
- }
325
-
326
- /**
327
- * Stop the telemetry adapter.
328
- * Performs cleanup.
329
- *
330
- * @returns Promise resolving to `true` if stopped successfully, `false` otherwise
331
- */
332
- async stop(): Promise<boolean> {
333
- try {
334
- if (this.#stopped) {
335
- return true
336
- }
337
-
338
- if (this.#stopping) {
339
- return this.#stopping
340
- }
341
-
342
- this.#stopping = (async () => {
343
- await this._stop()
344
- this.#stopped = true
345
- this.#stopping = null
346
- return true
347
- })()
348
-
349
- return this.#stopping
350
- } catch (error) {
351
- this.#logger?.error(error, 'Error in TelemetryAdapter.stop()')
352
- throw error
353
- }
354
- }
355
-
356
- // ============================================================================
357
- // Configuration Methods
358
- // ============================================================================
359
-
360
- /**
361
- * Set the logger instance for this adapter.
362
- *
363
- * @param logger - The logger instance to use for logging
364
- */
365
- setLogger(logger: Logger): void {
366
- this.#logger = logger
367
- }
368
-
369
- /**
370
- * Get the logger instance for this adapter.
371
- *
372
- * @returns The logger instance, or `null` if not set
373
- */
374
- get logger(): Logger | null {
375
- return this.#logger
376
- }
377
-
378
- /**
379
- * Set the Duron client instance for this adapter.
380
- * This is called automatically by the Duron client during initialization.
381
- *
382
- * @param client - The Duron client instance
383
- */
384
- setClient(client: TelemetryClient): void {
385
- this.#client = client
386
- }
387
-
388
- /**
389
- * Get the Duron client instance.
390
- * Available to subclasses for accessing the database adapter.
391
- *
392
- * @returns The Duron client instance, or `null` if not set
393
- */
394
- protected get client(): TelemetryClient | null {
395
- return this.#client
396
- }
397
-
398
- // ============================================================================
399
- // Span Methods
400
- // ============================================================================
401
-
402
- /**
403
- * Start a span for job execution.
404
- *
405
- * @param options - Options for the job span
406
- * @returns The created span
407
- */
408
- async startJobSpan(options: StartJobSpanOptions): Promise<Span> {
409
- await this.start()
410
- return this._startJobSpan(options)
411
- }
412
-
413
- /**
414
- * End a job span.
415
- *
416
- * @param span - The span to end
417
- * @param options - End options including status and error
418
- */
419
- async endJobSpan(span: Span, options: EndSpanOptions): Promise<void> {
420
- await this.start()
421
- return this._endJobSpan(span, options)
422
- }
423
-
424
- /**
425
- * Start a span for step execution.
426
- *
427
- * @param options - Options for the step span
428
- * @returns The created span
429
- */
430
- async startStepSpan(options: StartStepSpanOptions): Promise<Span> {
431
- await this.start()
432
- return this._startStepSpan(options)
433
- }
434
-
435
- /**
436
- * End a step span.
437
- *
438
- * @param span - The span to end
439
- * @param options - End options including status and error
440
- */
441
- async endStepSpan(span: Span, options: EndSpanOptions): Promise<void> {
442
- await this.start()
443
- return this._endStepSpan(span, options)
444
- }
445
-
446
- /**
447
- * Start a span for database operation (optional tracing).
448
- *
449
- * @param options - Options for the database span
450
- * @returns The created span, or null if database tracing is disabled
451
- */
452
- async startDatabaseSpan(options: StartDatabaseSpanOptions): Promise<Span | null> {
453
- await this.start()
454
- return this._startDatabaseSpan(options)
455
- }
456
-
457
- /**
458
- * End a database span.
459
- *
460
- * @param span - The span to end
461
- * @param options - End options including status and error
462
- */
463
- async endDatabaseSpan(span: Span | null, options: EndSpanOptions): Promise<void> {
464
- if (!span) return
465
- await this.start()
466
- return this._endDatabaseSpan(span, options)
467
- }
468
-
469
- // ============================================================================
470
- // Metrics Methods
471
- // ============================================================================
472
-
473
- /**
474
- * Record a metric.
475
- *
476
- * @param options - Options for recording the metric
477
- */
478
- async recordMetric(options: RecordMetricOptions): Promise<void> {
479
- await this.start()
480
- return this._recordMetric(options)
481
- }
482
-
483
- /**
484
- * Add an event to a span.
485
- *
486
- * @param options - Options for the span event
487
- */
488
- async addSpanEvent(options: AddSpanEventOptions): Promise<void> {
489
- await this.start()
490
- return this._addSpanEvent(options)
491
- }
492
-
493
- /**
494
- * Add an attribute to a span.
495
- *
496
- * @param options - Options for the span attribute
497
- */
498
- async addSpanAttribute(options: AddSpanAttributeOptions): Promise<void> {
499
- await this.start()
500
- return this._addSpanAttribute(options)
501
- }
502
-
503
- // ============================================================================
504
- // Tracer Methods
505
- // ============================================================================
506
-
507
- /**
508
- * Get a tracer for manual instrumentation.
509
- * Similar to OpenTelemetry's `trace.getTracer()` method.
510
- *
511
- * @param name - The name of the tracer (typically your service or library name)
512
- * @returns A Tracer for creating custom spans
513
- *
514
- * @example
515
- * ```typescript
516
- * const tracer = telemetry.getTracer('my-service')
517
- *
518
- * const span = tracer.startSpan('process-order', {
519
- * attributes: { 'order.id': orderId }
520
- * })
521
- *
522
- * try {
523
- * // Do some work
524
- * span.addEvent('order.validated')
525
- * span.setStatusOk()
526
- * } catch (error) {
527
- * span.recordException(error)
528
- * span.setStatusError(error.message)
529
- * } finally {
530
- * span.end()
531
- * }
532
- * ```
533
- */
534
- getTracer(name: string): Tracer {
535
- return this._getTracer(name)
536
- }
537
-
538
- // ============================================================================
539
- // Context Methods
540
- // ============================================================================
541
-
542
- /**
543
- * Create an observe context for action/step handlers.
544
- *
545
- * @param jobId - The job ID
546
- * @param stepId - The step ID (optional)
547
- * @param span - The current span
548
- * @returns ObserveContext for use in handlers
549
- */
550
- createObserveContext(jobId: string, stepId: string | null, span: Span): ObserveContext {
551
- return {
552
- recordMetric: (name: string, value: number, attributes?: Record<string, any>) => {
553
- this.recordMetric({
554
- jobId,
555
- stepId: stepId ?? undefined,
556
- name,
557
- value,
558
- attributes,
559
- }).catch((err) => {
560
- this.#logger?.error(err, 'Error recording metric')
561
- })
562
- },
563
- addSpanAttribute: (key: string, value: string | number | boolean) => {
564
- this.addSpanAttribute({ span, key, value }).catch((err) => {
565
- this.#logger?.error(err, 'Error adding span attribute')
566
- })
567
- },
568
- addSpanEvent: (name: string, attributes?: Record<string, any>) => {
569
- this.addSpanEvent({ span, name, attributes }).catch((err) => {
570
- this.#logger?.error(err, 'Error adding span event')
571
- })
572
- },
573
- getTracer: (name: string) => {
574
- return this.getTracer(name)
575
- },
576
- }
577
- }
578
-
579
- // ============================================================================
580
- // Protected Abstract Methods (to be implemented by adapters)
581
- // ============================================================================
582
-
583
- /**
584
- * Start the adapter.
585
- */
586
- protected abstract _start(): Promise<void>
587
-
588
- /**
589
- * Stop the adapter.
590
- */
591
- protected abstract _stop(): Promise<void>
592
-
593
- /**
594
- * Internal method to start a job span.
595
- */
596
- protected abstract _startJobSpan(options: StartJobSpanOptions): Promise<Span>
597
-
598
- /**
599
- * Internal method to end a job span.
600
- */
601
- protected abstract _endJobSpan(span: Span, options: EndSpanOptions): Promise<void>
602
-
603
- /**
604
- * Internal method to start a step span.
605
- */
606
- protected abstract _startStepSpan(options: StartStepSpanOptions): Promise<Span>
607
-
608
- /**
609
- * Internal method to end a step span.
610
- */
611
- protected abstract _endStepSpan(span: Span, options: EndSpanOptions): Promise<void>
612
-
613
- /**
614
- * Internal method to start a database span.
615
- */
616
- protected abstract _startDatabaseSpan(options: StartDatabaseSpanOptions): Promise<Span | null>
617
-
618
- /**
619
- * Internal method to end a database span.
620
- */
621
- protected abstract _endDatabaseSpan(span: Span, options: EndSpanOptions): Promise<void>
622
-
623
- /**
624
- * Internal method to record a metric.
625
- */
626
- protected abstract _recordMetric(options: RecordMetricOptions): Promise<void>
627
-
628
- /**
629
- * Internal method to add a span event.
630
- */
631
- protected abstract _addSpanEvent(options: AddSpanEventOptions): Promise<void>
632
-
633
- /**
634
- * Internal method to add a span attribute.
635
- */
636
- protected abstract _addSpanAttribute(options: AddSpanAttributeOptions): Promise<void>
637
-
638
- /**
639
- * Internal method to get a tracer for manual instrumentation.
640
- */
641
- protected abstract _getTracer(name: string): Tracer
642
- }