pg-workflows 0.14.0 → 0.16.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/dist/index.d.cts CHANGED
@@ -20,6 +20,13 @@ type WorkflowRun = {
20
20
  maxRetries: number;
21
21
  /** Resolved scheduling priority (pg-boss integer; higher runs first). */
22
22
  priority: number;
23
+ /**
24
+ * When true, this run participates in the per-workflow-ID uniqueness
25
+ * constraint: no other pending or running singleton run of the same
26
+ * workflow ID may exist at the same time. Paused, completed, failed, and
27
+ * cancelled runs release the slot.
28
+ */
29
+ singleton: boolean;
23
30
  jobId: string | null;
24
31
  idempotencyKey: string | null;
25
32
  parentRunId: string | null;
@@ -58,6 +65,7 @@ declare enum WorkflowStatus {
58
65
  FAILED = "failed",
59
66
  CANCELLED = "cancelled"
60
67
  }
68
+ type WorkflowRunStats = Record<WorkflowStatus, number>;
61
69
  declare enum StepType {
62
70
  PAUSE = "pause",
63
71
  RUN = "run",
@@ -76,6 +84,12 @@ type StartWorkflowOptions = {
76
84
  expireInSeconds?: number;
77
85
  idempotencyKey?: string;
78
86
  priority?: WorkflowPriority;
87
+ /**
88
+ * Client-side counterpart of `workflow(..., { singleton: true })`.
89
+ * The engine reads this from the registered definition; pass it here when
90
+ * starting from `WorkflowClient` so the uniqueness constraint applies.
91
+ */
92
+ singleton?: boolean;
79
93
  };
80
94
  type WorkflowOptions<I extends InputParameters> = {
81
95
  timeout?: number;
@@ -83,6 +97,12 @@ type WorkflowOptions<I extends InputParameters> = {
83
97
  inputSchema?: I;
84
98
  priority?: WorkflowPriority;
85
99
  /**
100
+ * When true, at most one pending or running run of this workflow ID may exist.
101
+ * A second `startWorkflow` throws `WorkflowRunInProgressError` until the
102
+ * current run pauses, completes, fails, or is cancelled.
103
+ */
104
+ singleton?: boolean;
105
+ /**
86
106
  * Recurring schedule. Accepts a cron expression (`'0 9 * * 1-5'`),
87
107
  * a duration string (`'5m'`, `'1 hour'`), or a `DurationObject`.
88
108
  */
@@ -190,6 +210,7 @@ type WorkflowDefinition<TInput extends InputParameters = InputParameters> = {
190
210
  timeout?: number;
191
211
  retries?: number;
192
212
  priority?: WorkflowPriority;
213
+ singleton?: boolean;
193
214
  schedule?: Schedule;
194
215
  timezone?: string;
195
216
  plugins?: WorkflowPlugin[];
@@ -216,6 +237,7 @@ interface WorkflowFactory<TStepExt = object> {
216
237
  TOutput = unknown
217
238
  >(id: string, options?: {
218
239
  inputSchema?: TInput;
240
+ singleton?: boolean;
219
241
  }): WorkflowRef<TInput, TOutput>;
220
242
  }
221
243
  /**
@@ -232,6 +254,7 @@ interface WorkflowRef<
232
254
  (handler: (context: WorkflowContext<TInput, StepBaseContext>) => Promise<unknown>, options?: Omit<WorkflowOptions<TInput>, "inputSchema">): WorkflowDefinition<TInput>;
233
255
  readonly id: string;
234
256
  readonly inputSchema?: TInput;
257
+ readonly singleton?: boolean;
235
258
  }
236
259
  type WorkflowRunProgress = WorkflowRun & {
237
260
  completionPercentage: number;
@@ -327,9 +350,21 @@ declare class WorkflowClient {
327
350
  hasMore: boolean;
328
351
  hasPrev: boolean;
329
352
  }>;
353
+ getStats({ resourceId, workflowId }?: {
354
+ resourceId?: string;
355
+ workflowId?: string;
356
+ }): Promise<WorkflowRunStats>;
330
357
  private ensureStarted;
331
358
  }
332
359
  /**
360
+ * True when a re-executed handler will replay `stepId` from `timeline` instead
361
+ * of running it: the step has a recorded output, or it is an
362
+ * `invokeChildWorkflow` step whose child is already bound. Public so plugins
363
+ * (e.g. tracing) can tell replays from real executions without depending on
364
+ * the timeline shape.
365
+ */
366
+ declare const isStepCached: (timeline: Record<string, unknown>, stepId: string) => boolean;
367
+ /**
333
368
  * Create a lightweight workflow reference.
334
369
  * Safe to import from `pg-workflows/client` - no engine or handler code.
335
370
  */
@@ -338,6 +373,7 @@ declare function createWorkflowRef<
338
373
  TInput extends InputParameters = InputParameters
339
374
  >(id: string, options?: {
340
375
  inputSchema?: TInput;
376
+ singleton?: boolean;
341
377
  }): WorkflowRef<TInput, TOutput>;
342
378
  declare const workflow: WorkflowFactory;
343
379
  import pg2 from "pg";
@@ -499,6 +535,10 @@ declare class WorkflowEngine {
499
535
  hasMore: boolean;
500
536
  hasPrev: boolean;
501
537
  }>;
538
+ getStats({ resourceId, workflowId }?: {
539
+ resourceId?: string;
540
+ workflowId?: string;
541
+ }): Promise<WorkflowRunStats>;
502
542
  }
503
543
  import { StandardSchemaV1 as StandardSchemaV12 } from "@standard-schema/spec";
504
544
  declare class WorkflowEngineError extends Error {
@@ -511,14 +551,7 @@ declare class WorkflowEngineError extends Error {
511
551
  declare class WorkflowRunNotFoundError extends WorkflowEngineError {
512
552
  constructor(runId?: string, workflowId?: string);
513
553
  }
514
- import { AttributeValue, Tracer } from "@opentelemetry/api";
515
- type OtelPluginOptions = {
516
- /** Tracer to use. Defaults to `trace.getTracer('pg-workflows')`. */
517
- tracer?: Tracer;
518
- /** Prefix for all span names. Defaults to `pg_workflows`. */
519
- spanNamePrefix?: string;
520
- /** Extra attributes merged onto the workflow.run span. */
521
- attributes?: (context: WorkflowContext) => Record<string, AttributeValue>;
522
- };
523
- declare function otelPlugin(options?: OtelPluginOptions): WorkflowPlugin<StepBaseContext, object>;
524
- export { workflow, otelPlugin, createWorkflowRef, WorkflowStatus, WorkflowRunProgress, WorkflowRunNotFoundError, WorkflowRun, WorkflowRef, WorkflowPriority, WorkflowPlugin, WorkflowOptions, WorkflowLogger, WorkflowEngineOptions, WorkflowEngineError, WorkflowEngine, WorkflowDefinition, WorkflowContext, WorkflowClientOptions, WorkflowClient, StepBaseContext, StartWorkflowOptions, ScheduleContext, Schedule, OtelPluginOptions, InputParameters, InferInputParameters, Duration };
554
+ declare class WorkflowRunInProgressError extends WorkflowEngineError {
555
+ constructor(workflowId: string, runId?: string);
556
+ }
557
+ export { workflow, isStepCached, createWorkflowRef, WorkflowStatus, WorkflowRunStats, WorkflowRunProgress, WorkflowRunNotFoundError, WorkflowRunInProgressError, WorkflowRun, WorkflowRef, WorkflowPriority, WorkflowPlugin, WorkflowOptions, WorkflowLogger, WorkflowEngineOptions, WorkflowEngineError, WorkflowEngine, WorkflowDefinition, WorkflowContext, WorkflowClientOptions, WorkflowClient, StepBaseContext, StartWorkflowOptions, ScheduleContext, Schedule, InputParameters, InferInputParameters, Duration };
package/dist/index.d.ts CHANGED
@@ -20,6 +20,13 @@ type WorkflowRun = {
20
20
  maxRetries: number;
21
21
  /** Resolved scheduling priority (pg-boss integer; higher runs first). */
22
22
  priority: number;
23
+ /**
24
+ * When true, this run participates in the per-workflow-ID uniqueness
25
+ * constraint: no other pending or running singleton run of the same
26
+ * workflow ID may exist at the same time. Paused, completed, failed, and
27
+ * cancelled runs release the slot.
28
+ */
29
+ singleton: boolean;
23
30
  jobId: string | null;
24
31
  idempotencyKey: string | null;
25
32
  parentRunId: string | null;
@@ -58,6 +65,7 @@ declare enum WorkflowStatus {
58
65
  FAILED = "failed",
59
66
  CANCELLED = "cancelled"
60
67
  }
68
+ type WorkflowRunStats = Record<WorkflowStatus, number>;
61
69
  declare enum StepType {
62
70
  PAUSE = "pause",
63
71
  RUN = "run",
@@ -76,6 +84,12 @@ type StartWorkflowOptions = {
76
84
  expireInSeconds?: number;
77
85
  idempotencyKey?: string;
78
86
  priority?: WorkflowPriority;
87
+ /**
88
+ * Client-side counterpart of `workflow(..., { singleton: true })`.
89
+ * The engine reads this from the registered definition; pass it here when
90
+ * starting from `WorkflowClient` so the uniqueness constraint applies.
91
+ */
92
+ singleton?: boolean;
79
93
  };
80
94
  type WorkflowOptions<I extends InputParameters> = {
81
95
  timeout?: number;
@@ -83,6 +97,12 @@ type WorkflowOptions<I extends InputParameters> = {
83
97
  inputSchema?: I;
84
98
  priority?: WorkflowPriority;
85
99
  /**
100
+ * When true, at most one pending or running run of this workflow ID may exist.
101
+ * A second `startWorkflow` throws `WorkflowRunInProgressError` until the
102
+ * current run pauses, completes, fails, or is cancelled.
103
+ */
104
+ singleton?: boolean;
105
+ /**
86
106
  * Recurring schedule. Accepts a cron expression (`'0 9 * * 1-5'`),
87
107
  * a duration string (`'5m'`, `'1 hour'`), or a `DurationObject`.
88
108
  */
@@ -190,6 +210,7 @@ type WorkflowDefinition<TInput extends InputParameters = InputParameters> = {
190
210
  timeout?: number;
191
211
  retries?: number;
192
212
  priority?: WorkflowPriority;
213
+ singleton?: boolean;
193
214
  schedule?: Schedule;
194
215
  timezone?: string;
195
216
  plugins?: WorkflowPlugin[];
@@ -216,6 +237,7 @@ interface WorkflowFactory<TStepExt = object> {
216
237
  TOutput = unknown
217
238
  >(id: string, options?: {
218
239
  inputSchema?: TInput;
240
+ singleton?: boolean;
219
241
  }): WorkflowRef<TInput, TOutput>;
220
242
  }
221
243
  /**
@@ -232,6 +254,7 @@ interface WorkflowRef<
232
254
  (handler: (context: WorkflowContext<TInput, StepBaseContext>) => Promise<unknown>, options?: Omit<WorkflowOptions<TInput>, "inputSchema">): WorkflowDefinition<TInput>;
233
255
  readonly id: string;
234
256
  readonly inputSchema?: TInput;
257
+ readonly singleton?: boolean;
235
258
  }
236
259
  type WorkflowRunProgress = WorkflowRun & {
237
260
  completionPercentage: number;
@@ -327,9 +350,21 @@ declare class WorkflowClient {
327
350
  hasMore: boolean;
328
351
  hasPrev: boolean;
329
352
  }>;
353
+ getStats({ resourceId, workflowId }?: {
354
+ resourceId?: string;
355
+ workflowId?: string;
356
+ }): Promise<WorkflowRunStats>;
330
357
  private ensureStarted;
331
358
  }
332
359
  /**
360
+ * True when a re-executed handler will replay `stepId` from `timeline` instead
361
+ * of running it: the step has a recorded output, or it is an
362
+ * `invokeChildWorkflow` step whose child is already bound. Public so plugins
363
+ * (e.g. tracing) can tell replays from real executions without depending on
364
+ * the timeline shape.
365
+ */
366
+ declare const isStepCached: (timeline: Record<string, unknown>, stepId: string) => boolean;
367
+ /**
333
368
  * Create a lightweight workflow reference.
334
369
  * Safe to import from `pg-workflows/client` - no engine or handler code.
335
370
  */
@@ -338,6 +373,7 @@ declare function createWorkflowRef<
338
373
  TInput extends InputParameters = InputParameters
339
374
  >(id: string, options?: {
340
375
  inputSchema?: TInput;
376
+ singleton?: boolean;
341
377
  }): WorkflowRef<TInput, TOutput>;
342
378
  declare const workflow: WorkflowFactory;
343
379
  import pg2 from "pg";
@@ -499,6 +535,10 @@ declare class WorkflowEngine {
499
535
  hasMore: boolean;
500
536
  hasPrev: boolean;
501
537
  }>;
538
+ getStats({ resourceId, workflowId }?: {
539
+ resourceId?: string;
540
+ workflowId?: string;
541
+ }): Promise<WorkflowRunStats>;
502
542
  }
503
543
  import { StandardSchemaV1 as StandardSchemaV12 } from "@standard-schema/spec";
504
544
  declare class WorkflowEngineError extends Error {
@@ -511,14 +551,7 @@ declare class WorkflowEngineError extends Error {
511
551
  declare class WorkflowRunNotFoundError extends WorkflowEngineError {
512
552
  constructor(runId?: string, workflowId?: string);
513
553
  }
514
- import { AttributeValue, Tracer } from "@opentelemetry/api";
515
- type OtelPluginOptions = {
516
- /** Tracer to use. Defaults to `trace.getTracer('pg-workflows')`. */
517
- tracer?: Tracer;
518
- /** Prefix for all span names. Defaults to `pg_workflows`. */
519
- spanNamePrefix?: string;
520
- /** Extra attributes merged onto the workflow.run span. */
521
- attributes?: (context: WorkflowContext) => Record<string, AttributeValue>;
522
- };
523
- declare function otelPlugin(options?: OtelPluginOptions): WorkflowPlugin<StepBaseContext, object>;
524
- export { workflow, otelPlugin, createWorkflowRef, WorkflowStatus, WorkflowRunProgress, WorkflowRunNotFoundError, WorkflowRun, WorkflowRef, WorkflowPriority, WorkflowPlugin, WorkflowOptions, WorkflowLogger, WorkflowEngineOptions, WorkflowEngineError, WorkflowEngine, WorkflowDefinition, WorkflowContext, WorkflowClientOptions, WorkflowClient, StepBaseContext, StartWorkflowOptions, ScheduleContext, Schedule, OtelPluginOptions, InputParameters, InferInputParameters, Duration };
554
+ declare class WorkflowRunInProgressError extends WorkflowEngineError {
555
+ constructor(workflowId: string, runId?: string);
556
+ }
557
+ export { workflow, isStepCached, createWorkflowRef, WorkflowStatus, WorkflowRunStats, WorkflowRunProgress, WorkflowRunNotFoundError, WorkflowRunInProgressError, WorkflowRun, WorkflowRef, WorkflowPriority, WorkflowPlugin, WorkflowOptions, WorkflowLogger, WorkflowEngineOptions, WorkflowEngineError, WorkflowEngine, WorkflowDefinition, WorkflowContext, WorkflowClientOptions, WorkflowClient, StepBaseContext, StartWorkflowOptions, ScheduleContext, Schedule, InputParameters, InferInputParameters, Duration };
package/dist/index.js CHANGED
@@ -6,15 +6,19 @@ import {
6
6
  WORKFLOW_RUN_QUEUE_NAME,
7
7
  WorkflowClient,
8
8
  WorkflowEngineError,
9
+ WorkflowRunInProgressError,
9
10
  WorkflowRunNotFoundError,
10
11
  WorkflowStatus,
12
+ assertSingletonSlotAvailable,
11
13
  createWorkflowRef,
12
14
  getWorkflowLastRun,
13
15
  getWorkflowRun,
16
+ getWorkflowRunStats,
14
17
  getWorkflowRuns,
15
18
  insertWorkflowRun,
16
19
  invokeChildWorkflowTimelineKey,
17
20
  isInvokeChildWorkflowTimelineEntry,
21
+ isStepCached,
18
22
  resolvePriority,
19
23
  runMigrations,
20
24
  scheduleQueueNameFor,
@@ -24,7 +28,7 @@ import {
24
28
  waitForTimelineKey,
25
29
  withPostgresTransaction,
26
30
  workflow
27
- } from "./shared/chunk-w3qcrrwx.js";
31
+ } from "./shared/chunk-d204nxd5.js";
28
32
  // src/engine.ts
29
33
  import { merge } from "es-toolkit";
30
34
  import pg from "pg";
@@ -225,11 +229,10 @@ class WorkflowEngine {
225
229
  const db = {
226
230
  executeSql: (text, values) => this.pool.query(text, values)
227
231
  };
228
- if (boss) {
229
- this.boss = boss;
230
- } else {
231
- this.boss = new PgBoss({ db, schema: DEFAULT_PGBOSS_SCHEMA });
232
- }
232
+ this.boss = boss ?? new PgBoss({ db, schema: DEFAULT_PGBOSS_SCHEMA });
233
+ this.boss.on("error", (error) => {
234
+ this.logger.error("pg-boss error", error);
235
+ });
233
236
  this.db = this.boss.getDb();
234
237
  }
235
238
  async start(asEngine = true, {
@@ -283,6 +286,10 @@ class WorkflowEngine {
283
286
  try {
284
287
  await this.createWorkflowRun({ workflowId, input: {}, scheduledAt });
285
288
  } catch (error) {
289
+ if (error instanceof WorkflowRunInProgressError) {
290
+ this.logger.log(`Skipping schedule fire for "${workflowId}": a run is already in progress`, { workflowId, runId: error.runId });
291
+ return;
292
+ }
286
293
  this.logger.error(`Schedule fire failed to start a run for workflow "${workflowId}"`, error instanceof Error ? error : new Error(String(error)), { workflowId });
287
294
  throw error;
288
295
  }
@@ -432,7 +439,8 @@ class WorkflowEngine {
432
439
  parentRunId,
433
440
  parentStepId,
434
441
  parentResourceId,
435
- scheduledAt
442
+ scheduledAt,
443
+ singleton: workflow2.singleton === true || options?.singleton === true
436
444
  }, targetDb);
437
445
  const insertAndEnqueue = async (targetDb) => {
438
446
  const result = await insertRun(targetDb);
@@ -591,6 +599,9 @@ class WorkflowEngine {
591
599
  }) {
592
600
  await this.checkIfHasStarted();
593
601
  const run = await this.getRun({ runId, resourceId });
602
+ if (run.singleton) {
603
+ await assertSingletonSlotAvailable({ workflowId: run.workflowId, exceptRunId: run.id }, this.db);
604
+ }
594
605
  const jobResourceId = resourceId ?? run.resourceId ?? undefined;
595
606
  const job = {
596
607
  runId: run.id,
@@ -1388,191 +1399,27 @@ ${error.stack}` : String(error)
1388
1399
  workflowId
1389
1400
  }, this.db);
1390
1401
  }
1391
- }
1392
- // src/plugins/otel.ts
1393
- import {
1394
- context as otelContext,
1395
- SpanStatusCode,
1396
- trace
1397
- } from "@opentelemetry/api";
1398
- var DEFAULT_PREFIX = "pg_workflows";
1399
- function isCachedHit(timeline, stepId, kind) {
1400
- const entry = timeline[stepId];
1401
- if (entry && typeof entry === "object" && "output" in entry && entry.output !== undefined) {
1402
- return true;
1403
- }
1404
- if (kind === "invokeChildWorkflow" && timeline[invokeChildWorkflowTimelineKey(stepId)]) {
1405
- return true;
1402
+ async getStats({
1403
+ resourceId,
1404
+ workflowId
1405
+ } = {}) {
1406
+ if (workflowId)
1407
+ validateWorkflowId(workflowId);
1408
+ validateResourceId(resourceId);
1409
+ return getWorkflowRunStats({ resourceId, workflowId }, this.db);
1406
1410
  }
1407
- return false;
1408
- }
1409
- function otelPlugin(options = {}) {
1410
- const tracer = options.tracer ?? trace.getTracer("pg-workflows");
1411
- const prefix = options.spanNamePrefix ?? DEFAULT_PREFIX;
1412
- const extraAttrs = options.attributes;
1413
- return {
1414
- name: "opentelemetry",
1415
- methods: (step, context) => {
1416
- const wrapVoidish = (kind, base) => {
1417
- return async (stepId, ...args) => {
1418
- if (isCachedHit(context.timeline, stepId, kind)) {
1419
- return base(stepId, ...args);
1420
- }
1421
- const capturedCtx = otelContext.active();
1422
- const startTime = new Date;
1423
- let result;
1424
- let originalErr;
1425
- let thrownError;
1426
- try {
1427
- result = await base(stepId, ...args);
1428
- } catch (err) {
1429
- originalErr = err;
1430
- thrownError = err instanceof Error ? err : new Error(String(err));
1431
- }
1432
- const span = tracer.startSpan(`${prefix}.step.${kind}`, {
1433
- startTime,
1434
- attributes: { "step.id": stepId, "step.type": kind }
1435
- }, capturedCtx);
1436
- if (thrownError) {
1437
- span.recordException(thrownError);
1438
- span.setStatus({ code: SpanStatusCode.ERROR, message: thrownError.message });
1439
- span.end();
1440
- throw originalErr;
1441
- }
1442
- span.setStatus({ code: SpanStatusCode.OK });
1443
- span.end();
1444
- return result;
1445
- };
1446
- };
1447
- return {
1448
- run: async (stepId, handler) => {
1449
- if (isCachedHit(context.timeline, stepId, "run")) {
1450
- return step.run(stepId, handler);
1451
- }
1452
- const capturedCtx = otelContext.active();
1453
- const startTime = new Date;
1454
- let result;
1455
- let originalErr;
1456
- let thrownError;
1457
- try {
1458
- result = await step.run(stepId, handler);
1459
- } catch (err) {
1460
- originalErr = err;
1461
- thrownError = err instanceof Error ? err : new Error(String(err));
1462
- }
1463
- if (result === undefined && !thrownError) {
1464
- return;
1465
- }
1466
- const span = tracer.startSpan(`${prefix}.step.run`, {
1467
- startTime,
1468
- attributes: { "step.id": stepId, "step.type": "run" }
1469
- }, capturedCtx);
1470
- if (thrownError) {
1471
- span.recordException(thrownError);
1472
- span.setStatus({ code: SpanStatusCode.ERROR, message: thrownError.message });
1473
- span.end();
1474
- throw originalErr;
1475
- }
1476
- span.setStatus({ code: SpanStatusCode.OK });
1477
- span.end();
1478
- return result;
1479
- },
1480
- waitFor: wrapVoidish("waitFor", step.waitFor),
1481
- delay: wrapVoidish("delay", step.delay),
1482
- sleep: wrapVoidish("delay", step.delay),
1483
- waitUntil: wrapVoidish("waitUntil", step.waitUntil),
1484
- pause: wrapVoidish("pause", step.pause),
1485
- poll: async (stepId, conditionFn, pollOptions) => {
1486
- const capturedCtx = otelContext.active();
1487
- const startTime = new Date;
1488
- let result;
1489
- let originalErr;
1490
- let thrownError;
1491
- try {
1492
- result = await step.poll(stepId, conditionFn, pollOptions);
1493
- } catch (err) {
1494
- originalErr = err;
1495
- thrownError = err instanceof Error ? err : new Error(String(err));
1496
- }
1497
- const span = tracer.startSpan(`${prefix}.step.poll`, {
1498
- startTime,
1499
- attributes: { "step.id": stepId, "step.type": "poll" }
1500
- }, capturedCtx);
1501
- if (thrownError) {
1502
- span.recordException(thrownError);
1503
- span.setStatus({ code: SpanStatusCode.ERROR, message: thrownError.message });
1504
- span.end();
1505
- throw originalErr;
1506
- }
1507
- span.setStatus({ code: SpanStatusCode.OK });
1508
- span.end();
1509
- return result;
1510
- },
1511
- invokeChildWorkflow: async (stepId, refOrParams, inputArg, optionsArg) => {
1512
- if (isCachedHit(context.timeline, stepId, "invokeChildWorkflow")) {
1513
- return step.invokeChildWorkflow(stepId, refOrParams, inputArg, optionsArg);
1514
- }
1515
- const capturedCtx = otelContext.active();
1516
- const startTime = new Date;
1517
- let result;
1518
- let originalErr;
1519
- let thrownError;
1520
- try {
1521
- result = await step.invokeChildWorkflow(stepId, refOrParams, inputArg, optionsArg);
1522
- } catch (err) {
1523
- originalErr = err;
1524
- thrownError = err instanceof Error ? err : new Error(String(err));
1525
- }
1526
- const span = tracer.startSpan(`${prefix}.step.invokeChildWorkflow`, {
1527
- startTime,
1528
- attributes: { "step.id": stepId, "step.type": "invokeChildWorkflow" }
1529
- }, capturedCtx);
1530
- if (thrownError) {
1531
- span.recordException(thrownError);
1532
- span.setStatus({ code: SpanStatusCode.ERROR, message: thrownError.message });
1533
- span.end();
1534
- throw originalErr;
1535
- }
1536
- span.setStatus({ code: SpanStatusCode.OK });
1537
- span.end();
1538
- return result;
1539
- }
1540
- };
1541
- },
1542
- wrap: (context, next) => tracer.startActiveSpan(`${prefix}.workflow.run`, {
1543
- attributes: {
1544
- "workflow.id": context.workflowId,
1545
- "workflow.run_id": context.runId,
1546
- "workflow.attempt": context.attempt,
1547
- ...context.resourceId ? { "workflow.resource_id": context.resourceId } : {},
1548
- ...extraAttrs ? extraAttrs(context) : {}
1549
- }
1550
- }, async (span) => {
1551
- try {
1552
- const result = await next();
1553
- span.setStatus({ code: SpanStatusCode.OK });
1554
- return result;
1555
- } catch (err) {
1556
- const error = err instanceof Error ? err : new Error(String(err));
1557
- span.recordException(error);
1558
- span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
1559
- throw err;
1560
- } finally {
1561
- span.end();
1562
- }
1563
- })
1564
- };
1565
1411
  }
1566
1412
  export {
1567
1413
  workflow,
1568
- otelPlugin,
1414
+ isStepCached,
1569
1415
  createWorkflowRef,
1570
1416
  WorkflowStatus,
1571
1417
  WorkflowRunNotFoundError,
1418
+ WorkflowRunInProgressError,
1572
1419
  WorkflowEngineError,
1573
1420
  WorkflowEngine,
1574
1421
  WorkflowClient
1575
1422
  };
1576
1423
 
1577
- //# debugId=A6C8F39FA22E601264756E2164756E21
1424
+ //# debugId=5FDB649CAAD8594E64756E2164756E21
1578
1425
  //# sourceMappingURL=index.js.map