pg-workflows 0.15.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.cjs CHANGED
@@ -65,7 +65,7 @@ var __export = (target, all) => {
65
65
  var exports_src = {};
66
66
  __export(exports_src, {
67
67
  workflow: () => workflow,
68
- otelPlugin: () => otelPlugin,
68
+ isStepCached: () => isStepCached,
69
69
  createWorkflowRef: () => createWorkflowRef,
70
70
  WorkflowStatus: () => WorkflowStatus,
71
71
  WorkflowRunNotFoundError: () => WorkflowRunNotFoundError,
@@ -95,6 +95,7 @@ var WAIT_FOR_TIMELINE_SUFFIX = "wait-for";
95
95
  var invokeChildWorkflowTimelineKey = (stepId) => `${stepId}-${INVOKE_CHILD_WORKFLOW_TIMELINE_SUFFIX}`;
96
96
  var waitForTimelineKey = (stepId) => `${stepId}-${WAIT_FOR_TIMELINE_SUFFIX}`;
97
97
  var isInvokeChildWorkflowTimelineEntry = (entry) => !!entry && typeof entry === "object" && ("invokeChildWorkflow" in entry);
98
+ var isStepCached = (timeline, stepId) => timeline[stepId]?.output !== undefined || isInvokeChildWorkflowTimelineEntry(timeline[invokeChildWorkflowTimelineKey(stepId)]);
98
99
 
99
100
  // src/db/migration.ts
100
101
  var MIGRATION_LOCK_ID = 738291645;
@@ -269,7 +270,37 @@ class WorkflowRunInProgressError extends WorkflowEngineError {
269
270
  }
270
271
  }
271
272
 
273
+ // src/types.ts
274
+ var WorkflowStatus;
275
+ ((WorkflowStatus2) => {
276
+ WorkflowStatus2["PENDING"] = "pending";
277
+ WorkflowStatus2["RUNNING"] = "running";
278
+ WorkflowStatus2["PAUSED"] = "paused";
279
+ WorkflowStatus2["COMPLETED"] = "completed";
280
+ WorkflowStatus2["FAILED"] = "failed";
281
+ WorkflowStatus2["CANCELLED"] = "cancelled";
282
+ })(WorkflowStatus ||= {});
283
+ var _STEP_BASE_METHOD_TO_TYPE = {
284
+ run: "run" /* RUN */,
285
+ waitFor: "waitFor" /* WAIT_FOR */,
286
+ waitUntil: "waitUntil" /* WAIT_UNTIL */,
287
+ delay: "delay" /* DELAY */,
288
+ sleep: "delay" /* DELAY */,
289
+ pause: "pause" /* PAUSE */,
290
+ poll: "poll" /* POLL */,
291
+ invokeChildWorkflow: "invokeChildWorkflow" /* INVOKE_CHILD_WORKFLOW */
292
+ };
293
+ var STEP_BASE_METHOD_TYPES = new Map(Object.entries(_STEP_BASE_METHOD_TO_TYPE));
294
+
272
295
  // src/db/queries.ts
296
+ var EMPTY_RUN_STATS = {
297
+ ["pending" /* PENDING */]: 0,
298
+ ["running" /* RUNNING */]: 0,
299
+ ["paused" /* PAUSED */]: 0,
300
+ ["completed" /* COMPLETED */]: 0,
301
+ ["failed" /* FAILED */]: 0,
302
+ ["cancelled" /* CANCELLED */]: 0
303
+ };
273
304
  function generateKSUID(prefix) {
274
305
  return `${prefix ? `${prefix}_` : ""}${import_ksuid.default.randomSync().string}`;
275
306
  }
@@ -617,6 +648,32 @@ async function getWorkflowRuns({
617
648
  const prevCursor = hasPrev && items.length > 0 ? items[0]?.id ?? null : null;
618
649
  return { items, nextCursor, prevCursor, hasMore, hasPrev };
619
650
  }
651
+ async function getWorkflowRunStats({
652
+ resourceId,
653
+ workflowId
654
+ }, db) {
655
+ const conditions = [];
656
+ const values = [];
657
+ let paramIndex = 1;
658
+ if (resourceId) {
659
+ conditions.push(`resource_id = $${paramIndex}`);
660
+ values.push(resourceId);
661
+ paramIndex++;
662
+ }
663
+ if (workflowId) {
664
+ conditions.push(`workflow_id = $${paramIndex}`);
665
+ values.push(workflowId);
666
+ }
667
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
668
+ const result = await db.executeSql(`SELECT status, COUNT(*)::int AS count FROM workflow_runs ${whereClause} GROUP BY status`, values);
669
+ const stats = { ...EMPTY_RUN_STATS };
670
+ for (const row of result.rows) {
671
+ if (row.status in stats) {
672
+ stats[row.status] = Number(row.count);
673
+ }
674
+ }
675
+ return stats;
676
+ }
620
677
  async function withPostgresTransaction(db, callback, pool) {
621
678
  let txDb;
622
679
  let release;
@@ -666,28 +723,6 @@ function resolvePriority(...candidates) {
666
723
  return PRIORITY_LEVELS.normal;
667
724
  }
668
725
 
669
- // src/types.ts
670
- var WorkflowStatus;
671
- ((WorkflowStatus2) => {
672
- WorkflowStatus2["PENDING"] = "pending";
673
- WorkflowStatus2["RUNNING"] = "running";
674
- WorkflowStatus2["PAUSED"] = "paused";
675
- WorkflowStatus2["COMPLETED"] = "completed";
676
- WorkflowStatus2["FAILED"] = "failed";
677
- WorkflowStatus2["CANCELLED"] = "cancelled";
678
- })(WorkflowStatus ||= {});
679
- var _STEP_BASE_METHOD_TO_TYPE = {
680
- run: "run" /* RUN */,
681
- waitFor: "waitFor" /* WAIT_FOR */,
682
- waitUntil: "waitUntil" /* WAIT_UNTIL */,
683
- delay: "delay" /* DELAY */,
684
- sleep: "delay" /* DELAY */,
685
- pause: "pause" /* PAUSE */,
686
- poll: "poll" /* POLL */,
687
- invokeChildWorkflow: "invokeChildWorkflow" /* INVOKE_CHILD_WORKFLOW */
688
- };
689
- var STEP_BASE_METHOD_TYPES = new Map(Object.entries(_STEP_BASE_METHOD_TO_TYPE));
690
-
691
726
  // src/client.ts
692
727
  var LOG_PREFIX = "[WorkflowClient]";
693
728
  var defaultLogger = {
@@ -996,6 +1031,16 @@ class WorkflowClient {
996
1031
  workflowId
997
1032
  }, this.db);
998
1033
  }
1034
+ async getStats({
1035
+ resourceId,
1036
+ workflowId
1037
+ } = {}) {
1038
+ await this.ensureStarted();
1039
+ if (workflowId)
1040
+ validateWorkflowId(workflowId);
1041
+ validateResourceId(resourceId);
1042
+ return getWorkflowRunStats({ resourceId, workflowId }, this.db);
1043
+ }
999
1044
  async ensureStarted() {
1000
1045
  if (!this._started) {
1001
1046
  await this.start();
@@ -2425,177 +2470,16 @@ ${error.stack}` : String(error)
2425
2470
  workflowId
2426
2471
  }, this.db);
2427
2472
  }
2428
- }
2429
- // src/plugins/otel.ts
2430
- var import_api = require("@opentelemetry/api");
2431
- var DEFAULT_PREFIX = "pg_workflows";
2432
- function isCachedHit(timeline, stepId, kind) {
2433
- const entry = timeline[stepId];
2434
- if (entry && typeof entry === "object" && "output" in entry && entry.output !== undefined) {
2435
- return true;
2436
- }
2437
- if (kind === "invokeChildWorkflow" && timeline[invokeChildWorkflowTimelineKey(stepId)]) {
2438
- return true;
2473
+ async getStats({
2474
+ resourceId,
2475
+ workflowId
2476
+ } = {}) {
2477
+ if (workflowId)
2478
+ validateWorkflowId(workflowId);
2479
+ validateResourceId(resourceId);
2480
+ return getWorkflowRunStats({ resourceId, workflowId }, this.db);
2439
2481
  }
2440
- return false;
2441
- }
2442
- function otelPlugin(options = {}) {
2443
- const tracer = options.tracer ?? import_api.trace.getTracer("pg-workflows");
2444
- const prefix = options.spanNamePrefix ?? DEFAULT_PREFIX;
2445
- const extraAttrs = options.attributes;
2446
- return {
2447
- name: "opentelemetry",
2448
- methods: (step, context) => {
2449
- const wrapVoidish = (kind, base) => {
2450
- return async (stepId, ...args) => {
2451
- if (isCachedHit(context.timeline, stepId, kind)) {
2452
- return base(stepId, ...args);
2453
- }
2454
- const capturedCtx = import_api.context.active();
2455
- const startTime = new Date;
2456
- let result;
2457
- let originalErr;
2458
- let thrownError;
2459
- try {
2460
- result = await base(stepId, ...args);
2461
- } catch (err) {
2462
- originalErr = err;
2463
- thrownError = err instanceof Error ? err : new Error(String(err));
2464
- }
2465
- const span = tracer.startSpan(`${prefix}.step.${kind}`, {
2466
- startTime,
2467
- attributes: { "step.id": stepId, "step.type": kind }
2468
- }, capturedCtx);
2469
- if (thrownError) {
2470
- span.recordException(thrownError);
2471
- span.setStatus({ code: import_api.SpanStatusCode.ERROR, message: thrownError.message });
2472
- span.end();
2473
- throw originalErr;
2474
- }
2475
- span.setStatus({ code: import_api.SpanStatusCode.OK });
2476
- span.end();
2477
- return result;
2478
- };
2479
- };
2480
- return {
2481
- run: async (stepId, handler) => {
2482
- if (isCachedHit(context.timeline, stepId, "run")) {
2483
- return step.run(stepId, handler);
2484
- }
2485
- const capturedCtx = import_api.context.active();
2486
- const startTime = new Date;
2487
- let result;
2488
- let originalErr;
2489
- let thrownError;
2490
- try {
2491
- result = await step.run(stepId, handler);
2492
- } catch (err) {
2493
- originalErr = err;
2494
- thrownError = err instanceof Error ? err : new Error(String(err));
2495
- }
2496
- if (result === undefined && !thrownError) {
2497
- return;
2498
- }
2499
- const span = tracer.startSpan(`${prefix}.step.run`, {
2500
- startTime,
2501
- attributes: { "step.id": stepId, "step.type": "run" }
2502
- }, capturedCtx);
2503
- if (thrownError) {
2504
- span.recordException(thrownError);
2505
- span.setStatus({ code: import_api.SpanStatusCode.ERROR, message: thrownError.message });
2506
- span.end();
2507
- throw originalErr;
2508
- }
2509
- span.setStatus({ code: import_api.SpanStatusCode.OK });
2510
- span.end();
2511
- return result;
2512
- },
2513
- waitFor: wrapVoidish("waitFor", step.waitFor),
2514
- delay: wrapVoidish("delay", step.delay),
2515
- sleep: wrapVoidish("delay", step.delay),
2516
- waitUntil: wrapVoidish("waitUntil", step.waitUntil),
2517
- pause: wrapVoidish("pause", step.pause),
2518
- poll: async (stepId, conditionFn, pollOptions) => {
2519
- const capturedCtx = import_api.context.active();
2520
- const startTime = new Date;
2521
- let result;
2522
- let originalErr;
2523
- let thrownError;
2524
- try {
2525
- result = await step.poll(stepId, conditionFn, pollOptions);
2526
- } catch (err) {
2527
- originalErr = err;
2528
- thrownError = err instanceof Error ? err : new Error(String(err));
2529
- }
2530
- const span = tracer.startSpan(`${prefix}.step.poll`, {
2531
- startTime,
2532
- attributes: { "step.id": stepId, "step.type": "poll" }
2533
- }, capturedCtx);
2534
- if (thrownError) {
2535
- span.recordException(thrownError);
2536
- span.setStatus({ code: import_api.SpanStatusCode.ERROR, message: thrownError.message });
2537
- span.end();
2538
- throw originalErr;
2539
- }
2540
- span.setStatus({ code: import_api.SpanStatusCode.OK });
2541
- span.end();
2542
- return result;
2543
- },
2544
- invokeChildWorkflow: async (stepId, refOrParams, inputArg, optionsArg) => {
2545
- if (isCachedHit(context.timeline, stepId, "invokeChildWorkflow")) {
2546
- return step.invokeChildWorkflow(stepId, refOrParams, inputArg, optionsArg);
2547
- }
2548
- const capturedCtx = import_api.context.active();
2549
- const startTime = new Date;
2550
- let result;
2551
- let originalErr;
2552
- let thrownError;
2553
- try {
2554
- result = await step.invokeChildWorkflow(stepId, refOrParams, inputArg, optionsArg);
2555
- } catch (err) {
2556
- originalErr = err;
2557
- thrownError = err instanceof Error ? err : new Error(String(err));
2558
- }
2559
- const span = tracer.startSpan(`${prefix}.step.invokeChildWorkflow`, {
2560
- startTime,
2561
- attributes: { "step.id": stepId, "step.type": "invokeChildWorkflow" }
2562
- }, capturedCtx);
2563
- if (thrownError) {
2564
- span.recordException(thrownError);
2565
- span.setStatus({ code: import_api.SpanStatusCode.ERROR, message: thrownError.message });
2566
- span.end();
2567
- throw originalErr;
2568
- }
2569
- span.setStatus({ code: import_api.SpanStatusCode.OK });
2570
- span.end();
2571
- return result;
2572
- }
2573
- };
2574
- },
2575
- wrap: (context, next) => tracer.startActiveSpan(`${prefix}.workflow.run`, {
2576
- attributes: {
2577
- "workflow.id": context.workflowId,
2578
- "workflow.run_id": context.runId,
2579
- "workflow.attempt": context.attempt,
2580
- ...context.resourceId ? { "workflow.resource_id": context.resourceId } : {},
2581
- ...extraAttrs ? extraAttrs(context) : {}
2582
- }
2583
- }, async (span) => {
2584
- try {
2585
- const result = await next();
2586
- span.setStatus({ code: import_api.SpanStatusCode.OK });
2587
- return result;
2588
- } catch (err) {
2589
- const error = err instanceof Error ? err : new Error(String(err));
2590
- span.recordException(error);
2591
- span.setStatus({ code: import_api.SpanStatusCode.ERROR, message: error.message });
2592
- throw err;
2593
- } finally {
2594
- span.end();
2595
- }
2596
- })
2597
- };
2598
2482
  }
2599
2483
 
2600
- //# debugId=0BBC9686D69E329D64756E2164756E21
2484
+ //# debugId=B101AE54CEFCC2C064756E2164756E21
2601
2485
  //# sourceMappingURL=index.js.map
package/dist/index.d.cts CHANGED
@@ -65,6 +65,7 @@ declare enum WorkflowStatus {
65
65
  FAILED = "failed",
66
66
  CANCELLED = "cancelled"
67
67
  }
68
+ type WorkflowRunStats = Record<WorkflowStatus, number>;
68
69
  declare enum StepType {
69
70
  PAUSE = "pause",
70
71
  RUN = "run",
@@ -349,9 +350,21 @@ declare class WorkflowClient {
349
350
  hasMore: boolean;
350
351
  hasPrev: boolean;
351
352
  }>;
353
+ getStats({ resourceId, workflowId }?: {
354
+ resourceId?: string;
355
+ workflowId?: string;
356
+ }): Promise<WorkflowRunStats>;
352
357
  private ensureStarted;
353
358
  }
354
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
+ /**
355
368
  * Create a lightweight workflow reference.
356
369
  * Safe to import from `pg-workflows/client` - no engine or handler code.
357
370
  */
@@ -522,6 +535,10 @@ declare class WorkflowEngine {
522
535
  hasMore: boolean;
523
536
  hasPrev: boolean;
524
537
  }>;
538
+ getStats({ resourceId, workflowId }?: {
539
+ resourceId?: string;
540
+ workflowId?: string;
541
+ }): Promise<WorkflowRunStats>;
525
542
  }
526
543
  import { StandardSchemaV1 as StandardSchemaV12 } from "@standard-schema/spec";
527
544
  declare class WorkflowEngineError extends Error {
@@ -537,14 +554,4 @@ declare class WorkflowRunNotFoundError extends WorkflowEngineError {
537
554
  declare class WorkflowRunInProgressError extends WorkflowEngineError {
538
555
  constructor(workflowId: string, runId?: string);
539
556
  }
540
- import { AttributeValue, Tracer } from "@opentelemetry/api";
541
- type OtelPluginOptions = {
542
- /** Tracer to use. Defaults to `trace.getTracer('pg-workflows')`. */
543
- tracer?: Tracer;
544
- /** Prefix for all span names. Defaults to `pg_workflows`. */
545
- spanNamePrefix?: string;
546
- /** Extra attributes merged onto the workflow.run span. */
547
- attributes?: (context: WorkflowContext) => Record<string, AttributeValue>;
548
- };
549
- declare function otelPlugin(options?: OtelPluginOptions): WorkflowPlugin<StepBaseContext, object>;
550
- export { workflow, otelPlugin, createWorkflowRef, WorkflowStatus, WorkflowRunProgress, WorkflowRunNotFoundError, WorkflowRunInProgressError, WorkflowRun, WorkflowRef, WorkflowPriority, WorkflowPlugin, WorkflowOptions, WorkflowLogger, WorkflowEngineOptions, WorkflowEngineError, WorkflowEngine, WorkflowDefinition, WorkflowContext, WorkflowClientOptions, WorkflowClient, StepBaseContext, StartWorkflowOptions, ScheduleContext, Schedule, OtelPluginOptions, InputParameters, InferInputParameters, Duration };
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
@@ -65,6 +65,7 @@ declare enum WorkflowStatus {
65
65
  FAILED = "failed",
66
66
  CANCELLED = "cancelled"
67
67
  }
68
+ type WorkflowRunStats = Record<WorkflowStatus, number>;
68
69
  declare enum StepType {
69
70
  PAUSE = "pause",
70
71
  RUN = "run",
@@ -349,9 +350,21 @@ declare class WorkflowClient {
349
350
  hasMore: boolean;
350
351
  hasPrev: boolean;
351
352
  }>;
353
+ getStats({ resourceId, workflowId }?: {
354
+ resourceId?: string;
355
+ workflowId?: string;
356
+ }): Promise<WorkflowRunStats>;
352
357
  private ensureStarted;
353
358
  }
354
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
+ /**
355
368
  * Create a lightweight workflow reference.
356
369
  * Safe to import from `pg-workflows/client` - no engine or handler code.
357
370
  */
@@ -522,6 +535,10 @@ declare class WorkflowEngine {
522
535
  hasMore: boolean;
523
536
  hasPrev: boolean;
524
537
  }>;
538
+ getStats({ resourceId, workflowId }?: {
539
+ resourceId?: string;
540
+ workflowId?: string;
541
+ }): Promise<WorkflowRunStats>;
525
542
  }
526
543
  import { StandardSchemaV1 as StandardSchemaV12 } from "@standard-schema/spec";
527
544
  declare class WorkflowEngineError extends Error {
@@ -537,14 +554,4 @@ declare class WorkflowRunNotFoundError extends WorkflowEngineError {
537
554
  declare class WorkflowRunInProgressError extends WorkflowEngineError {
538
555
  constructor(workflowId: string, runId?: string);
539
556
  }
540
- import { AttributeValue, Tracer } from "@opentelemetry/api";
541
- type OtelPluginOptions = {
542
- /** Tracer to use. Defaults to `trace.getTracer('pg-workflows')`. */
543
- tracer?: Tracer;
544
- /** Prefix for all span names. Defaults to `pg_workflows`. */
545
- spanNamePrefix?: string;
546
- /** Extra attributes merged onto the workflow.run span. */
547
- attributes?: (context: WorkflowContext) => Record<string, AttributeValue>;
548
- };
549
- declare function otelPlugin(options?: OtelPluginOptions): WorkflowPlugin<StepBaseContext, object>;
550
- export { workflow, otelPlugin, createWorkflowRef, WorkflowStatus, WorkflowRunProgress, WorkflowRunNotFoundError, WorkflowRunInProgressError, WorkflowRun, WorkflowRef, WorkflowPriority, WorkflowPlugin, WorkflowOptions, WorkflowLogger, WorkflowEngineOptions, WorkflowEngineError, WorkflowEngine, WorkflowDefinition, WorkflowContext, WorkflowClientOptions, WorkflowClient, StepBaseContext, StartWorkflowOptions, ScheduleContext, Schedule, OtelPluginOptions, InputParameters, InferInputParameters, Duration };
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
@@ -13,10 +13,12 @@ import {
13
13
  createWorkflowRef,
14
14
  getWorkflowLastRun,
15
15
  getWorkflowRun,
16
+ getWorkflowRunStats,
16
17
  getWorkflowRuns,
17
18
  insertWorkflowRun,
18
19
  invokeChildWorkflowTimelineKey,
19
20
  isInvokeChildWorkflowTimelineEntry,
21
+ isStepCached,
20
22
  resolvePriority,
21
23
  runMigrations,
22
24
  scheduleQueueNameFor,
@@ -26,7 +28,7 @@ import {
26
28
  waitForTimelineKey,
27
29
  withPostgresTransaction,
28
30
  workflow
29
- } from "./shared/chunk-n0f7hd40.js";
31
+ } from "./shared/chunk-d204nxd5.js";
30
32
  // src/engine.ts
31
33
  import { merge } from "es-toolkit";
32
34
  import pg from "pg";
@@ -1397,184 +1399,19 @@ ${error.stack}` : String(error)
1397
1399
  workflowId
1398
1400
  }, this.db);
1399
1401
  }
1400
- }
1401
- // src/plugins/otel.ts
1402
- import {
1403
- context as otelContext,
1404
- SpanStatusCode,
1405
- trace
1406
- } from "@opentelemetry/api";
1407
- var DEFAULT_PREFIX = "pg_workflows";
1408
- function isCachedHit(timeline, stepId, kind) {
1409
- const entry = timeline[stepId];
1410
- if (entry && typeof entry === "object" && "output" in entry && entry.output !== undefined) {
1411
- return true;
1412
- }
1413
- if (kind === "invokeChildWorkflow" && timeline[invokeChildWorkflowTimelineKey(stepId)]) {
1414
- 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);
1415
1410
  }
1416
- return false;
1417
- }
1418
- function otelPlugin(options = {}) {
1419
- const tracer = options.tracer ?? trace.getTracer("pg-workflows");
1420
- const prefix = options.spanNamePrefix ?? DEFAULT_PREFIX;
1421
- const extraAttrs = options.attributes;
1422
- return {
1423
- name: "opentelemetry",
1424
- methods: (step, context) => {
1425
- const wrapVoidish = (kind, base) => {
1426
- return async (stepId, ...args) => {
1427
- if (isCachedHit(context.timeline, stepId, kind)) {
1428
- return base(stepId, ...args);
1429
- }
1430
- const capturedCtx = otelContext.active();
1431
- const startTime = new Date;
1432
- let result;
1433
- let originalErr;
1434
- let thrownError;
1435
- try {
1436
- result = await base(stepId, ...args);
1437
- } catch (err) {
1438
- originalErr = err;
1439
- thrownError = err instanceof Error ? err : new Error(String(err));
1440
- }
1441
- const span = tracer.startSpan(`${prefix}.step.${kind}`, {
1442
- startTime,
1443
- attributes: { "step.id": stepId, "step.type": kind }
1444
- }, capturedCtx);
1445
- if (thrownError) {
1446
- span.recordException(thrownError);
1447
- span.setStatus({ code: SpanStatusCode.ERROR, message: thrownError.message });
1448
- span.end();
1449
- throw originalErr;
1450
- }
1451
- span.setStatus({ code: SpanStatusCode.OK });
1452
- span.end();
1453
- return result;
1454
- };
1455
- };
1456
- return {
1457
- run: async (stepId, handler) => {
1458
- if (isCachedHit(context.timeline, stepId, "run")) {
1459
- return step.run(stepId, handler);
1460
- }
1461
- const capturedCtx = otelContext.active();
1462
- const startTime = new Date;
1463
- let result;
1464
- let originalErr;
1465
- let thrownError;
1466
- try {
1467
- result = await step.run(stepId, handler);
1468
- } catch (err) {
1469
- originalErr = err;
1470
- thrownError = err instanceof Error ? err : new Error(String(err));
1471
- }
1472
- if (result === undefined && !thrownError) {
1473
- return;
1474
- }
1475
- const span = tracer.startSpan(`${prefix}.step.run`, {
1476
- startTime,
1477
- attributes: { "step.id": stepId, "step.type": "run" }
1478
- }, capturedCtx);
1479
- if (thrownError) {
1480
- span.recordException(thrownError);
1481
- span.setStatus({ code: SpanStatusCode.ERROR, message: thrownError.message });
1482
- span.end();
1483
- throw originalErr;
1484
- }
1485
- span.setStatus({ code: SpanStatusCode.OK });
1486
- span.end();
1487
- return result;
1488
- },
1489
- waitFor: wrapVoidish("waitFor", step.waitFor),
1490
- delay: wrapVoidish("delay", step.delay),
1491
- sleep: wrapVoidish("delay", step.delay),
1492
- waitUntil: wrapVoidish("waitUntil", step.waitUntil),
1493
- pause: wrapVoidish("pause", step.pause),
1494
- poll: async (stepId, conditionFn, pollOptions) => {
1495
- const capturedCtx = otelContext.active();
1496
- const startTime = new Date;
1497
- let result;
1498
- let originalErr;
1499
- let thrownError;
1500
- try {
1501
- result = await step.poll(stepId, conditionFn, pollOptions);
1502
- } catch (err) {
1503
- originalErr = err;
1504
- thrownError = err instanceof Error ? err : new Error(String(err));
1505
- }
1506
- const span = tracer.startSpan(`${prefix}.step.poll`, {
1507
- startTime,
1508
- attributes: { "step.id": stepId, "step.type": "poll" }
1509
- }, capturedCtx);
1510
- if (thrownError) {
1511
- span.recordException(thrownError);
1512
- span.setStatus({ code: SpanStatusCode.ERROR, message: thrownError.message });
1513
- span.end();
1514
- throw originalErr;
1515
- }
1516
- span.setStatus({ code: SpanStatusCode.OK });
1517
- span.end();
1518
- return result;
1519
- },
1520
- invokeChildWorkflow: async (stepId, refOrParams, inputArg, optionsArg) => {
1521
- if (isCachedHit(context.timeline, stepId, "invokeChildWorkflow")) {
1522
- return step.invokeChildWorkflow(stepId, refOrParams, inputArg, optionsArg);
1523
- }
1524
- const capturedCtx = otelContext.active();
1525
- const startTime = new Date;
1526
- let result;
1527
- let originalErr;
1528
- let thrownError;
1529
- try {
1530
- result = await step.invokeChildWorkflow(stepId, refOrParams, inputArg, optionsArg);
1531
- } catch (err) {
1532
- originalErr = err;
1533
- thrownError = err instanceof Error ? err : new Error(String(err));
1534
- }
1535
- const span = tracer.startSpan(`${prefix}.step.invokeChildWorkflow`, {
1536
- startTime,
1537
- attributes: { "step.id": stepId, "step.type": "invokeChildWorkflow" }
1538
- }, capturedCtx);
1539
- if (thrownError) {
1540
- span.recordException(thrownError);
1541
- span.setStatus({ code: SpanStatusCode.ERROR, message: thrownError.message });
1542
- span.end();
1543
- throw originalErr;
1544
- }
1545
- span.setStatus({ code: SpanStatusCode.OK });
1546
- span.end();
1547
- return result;
1548
- }
1549
- };
1550
- },
1551
- wrap: (context, next) => tracer.startActiveSpan(`${prefix}.workflow.run`, {
1552
- attributes: {
1553
- "workflow.id": context.workflowId,
1554
- "workflow.run_id": context.runId,
1555
- "workflow.attempt": context.attempt,
1556
- ...context.resourceId ? { "workflow.resource_id": context.resourceId } : {},
1557
- ...extraAttrs ? extraAttrs(context) : {}
1558
- }
1559
- }, async (span) => {
1560
- try {
1561
- const result = await next();
1562
- span.setStatus({ code: SpanStatusCode.OK });
1563
- return result;
1564
- } catch (err) {
1565
- const error = err instanceof Error ? err : new Error(String(err));
1566
- span.recordException(error);
1567
- span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
1568
- throw err;
1569
- } finally {
1570
- span.end();
1571
- }
1572
- })
1573
- };
1574
1411
  }
1575
1412
  export {
1576
1413
  workflow,
1577
- otelPlugin,
1414
+ isStepCached,
1578
1415
  createWorkflowRef,
1579
1416
  WorkflowStatus,
1580
1417
  WorkflowRunNotFoundError,
@@ -1584,5 +1421,5 @@ export {
1584
1421
  WorkflowClient
1585
1422
  };
1586
1423
 
1587
- //# debugId=4EA8624FFA9819BE64756E2164756E21
1424
+ //# debugId=5FDB649CAAD8594E64756E2164756E21
1588
1425
  //# sourceMappingURL=index.js.map