pg-workflows 0.9.0 → 0.11.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.
@@ -66,6 +66,8 @@ var exports_client_entry = {};
66
66
  __export(exports_client_entry, {
67
67
  createWorkflowRef: () => createWorkflowRef,
68
68
  WorkflowStatus: () => WorkflowStatus,
69
+ WorkflowRunNotFoundError: () => WorkflowRunNotFoundError,
70
+ WorkflowEngineError: () => WorkflowEngineError,
69
71
  WorkflowClient: () => WorkflowClient
70
72
  });
71
73
  module.exports = __toCommonJS(exports_client_entry);
@@ -82,10 +84,15 @@ var WORKFLOW_RUN_DLQ_QUEUE_NAME = "workflow_run_dlq";
82
84
  var DEFAULT_PGBOSS_SCHEMA = "pgboss_v12_pgworkflow";
83
85
  var MAX_WORKFLOW_ID_LENGTH = 256;
84
86
  var MAX_RESOURCE_ID_LENGTH = 256;
87
+ var INVOKE_CHILD_WORKFLOW_TIMELINE_SUFFIX = "invoke-child-workflow";
88
+ var WAIT_FOR_TIMELINE_SUFFIX = "wait-for";
89
+ var invokeChildWorkflowTimelineKey = (stepId) => `${stepId}-${INVOKE_CHILD_WORKFLOW_TIMELINE_SUFFIX}`;
90
+ var waitForTimelineKey = (stepId) => `${stepId}-${WAIT_FOR_TIMELINE_SUFFIX}`;
91
+ var isInvokeChildWorkflowTimelineEntry = (entry) => !!entry && typeof entry === "object" && ("invokeChildWorkflow" in entry);
85
92
 
86
93
  // src/db/migration.ts
87
94
  var MIGRATION_LOCK_ID = 738291645;
88
- var CURRENT_SCHEMA_VERSION = 3;
95
+ var CURRENT_SCHEMA_VERSION = 4;
89
96
  async function runMigrations(db) {
90
97
  if (await isSchemaUpToDate(db)) {
91
98
  return;
@@ -143,6 +150,11 @@ async function runMigrations(db) {
143
150
  commands.push("ALTER TABLE workflow_runs ALTER COLUMN resource_id TYPE varchar(256)");
144
151
  commands.push("ALTER TABLE workflow_runs ALTER COLUMN workflow_id TYPE varchar(256)");
145
152
  }
153
+ if (currentVersion < 4) {
154
+ commands.push("ALTER TABLE workflow_runs ADD COLUMN IF NOT EXISTS parent_run_id varchar(32)");
155
+ commands.push("ALTER TABLE workflow_runs ADD COLUMN IF NOT EXISTS parent_step_id varchar(256)");
156
+ commands.push("ALTER TABLE workflow_runs ADD COLUMN IF NOT EXISTS parent_resource_id varchar(256)");
157
+ }
146
158
  if (currentVersion === 0) {
147
159
  commands.push(`INSERT INTO workflow_schema_version (version) VALUES (${CURRENT_SCHEMA_VERSION})`);
148
160
  } else {
@@ -205,7 +217,10 @@ function mapRowToWorkflowRun(row) {
205
217
  retryCount: row.retry_count,
206
218
  maxRetries: row.max_retries,
207
219
  jobId: row.job_id,
208
- idempotencyKey: row.idempotency_key
220
+ idempotencyKey: row.idempotency_key,
221
+ parentRunId: row.parent_run_id,
222
+ parentStepId: row.parent_step_id,
223
+ parentResourceId: row.parent_resource_id
209
224
  };
210
225
  }
211
226
  async function insertWorkflowRun({
@@ -216,7 +231,10 @@ async function insertWorkflowRun({
216
231
  input,
217
232
  maxRetries,
218
233
  timeoutAt,
219
- idempotencyKey
234
+ idempotencyKey,
235
+ parentRunId,
236
+ parentStepId,
237
+ parentResourceId
220
238
  }, db) {
221
239
  const runId = generateKSUID("run");
222
240
  const now = new Date;
@@ -233,9 +251,12 @@ async function insertWorkflowRun({
233
251
  updated_at,
234
252
  timeline,
235
253
  retry_count,
236
- idempotency_key
254
+ idempotency_key,
255
+ parent_run_id,
256
+ parent_step_id,
257
+ parent_resource_id
237
258
  )
238
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)
259
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)
239
260
  ON CONFLICT (idempotency_key) WHERE idempotency_key IS NOT NULL DO NOTHING
240
261
  RETURNING *`, [
241
262
  runId,
@@ -250,7 +271,10 @@ async function insertWorkflowRun({
250
271
  now,
251
272
  "{}",
252
273
  0,
253
- idempotencyKey ?? null
274
+ idempotencyKey ?? null,
275
+ parentRunId ?? null,
276
+ parentStepId ?? null,
277
+ parentResourceId ?? null
254
278
  ]);
255
279
  if (result.rows[0]) {
256
280
  return { run: mapRowToWorkflowRun(result.rows[0]), created: true };
@@ -513,15 +537,6 @@ var WorkflowStatus;
513
537
  WorkflowStatus2["FAILED"] = "failed";
514
538
  WorkflowStatus2["CANCELLED"] = "cancelled";
515
539
  })(WorkflowStatus ||= {});
516
- var StepType;
517
- ((StepType2) => {
518
- StepType2["PAUSE"] = "pause";
519
- StepType2["RUN"] = "run";
520
- StepType2["WAIT_FOR"] = "waitFor";
521
- StepType2["WAIT_UNTIL"] = "waitUntil";
522
- StepType2["DELAY"] = "delay";
523
- StepType2["POLL"] = "poll";
524
- })(StepType ||= {});
525
540
 
526
541
  // src/client.ts
527
542
  var LOG_PREFIX = "[WorkflowClient]";
@@ -628,7 +643,8 @@ class WorkflowClient {
628
643
  };
629
644
  await this.boss.send(WORKFLOW_RUN_QUEUE_NAME, job, {
630
645
  startAfter: new Date,
631
- expireInSeconds: options?.expireInSeconds ?? defaultExpireInSeconds
646
+ expireInSeconds: options?.expireInSeconds ?? defaultExpireInSeconds,
647
+ db: _db
632
648
  });
633
649
  }
634
650
  return insertedRun;
@@ -691,6 +707,11 @@ class WorkflowClient {
691
707
  if (current.status !== "paused" /* PAUSED */) {
692
708
  throw new WorkflowEngineError(`Cannot resume workflow run in '${current.status}' status, must be 'paused'`, current.workflowId, runId);
693
709
  }
710
+ const currentStepId = current.currentStepId;
711
+ const currentStepTimelineEntry = current.timeline[invokeChildWorkflowTimelineKey(currentStepId)];
712
+ if (isInvokeChildWorkflowTimelineEntry(currentStepTimelineEntry)) {
713
+ return current;
714
+ }
694
715
  return this.triggerEvent({
695
716
  runId,
696
717
  resourceId,
@@ -709,8 +730,12 @@ class WorkflowClient {
709
730
  if (run.status !== "paused" /* PAUSED */) {
710
731
  return run;
711
732
  }
712
- const stepId = run.currentStepId;
713
- const waitForEntry = run.timeline[`${stepId}-wait-for`];
733
+ const currentStepId = run.currentStepId;
734
+ const currentStepTimelineEntry = run.timeline[invokeChildWorkflowTimelineKey(currentStepId)];
735
+ if (isInvokeChildWorkflowTimelineEntry(currentStepTimelineEntry)) {
736
+ return run;
737
+ }
738
+ const waitForEntry = run.timeline[waitForTimelineKey(currentStepId)];
714
739
  if (!waitForEntry || typeof waitForEntry !== "object" || !("waitFor" in waitForEntry)) {
715
740
  return run;
716
741
  }
@@ -728,7 +753,7 @@ class WorkflowClient {
728
753
  resourceId,
729
754
  data: {
730
755
  timeline: import_es_toolkit.merge(freshRun.timeline, {
731
- [stepId]: {
756
+ [currentStepId]: {
732
757
  output: data ?? {},
733
758
  timestamp: new Date
734
759
  }
@@ -828,7 +853,10 @@ function createWorkflowRef(id, options) {
828
853
  retries: defineOptions?.retries
829
854
  });
830
855
  Object.defineProperty(ref, "id", { value: id, enumerable: true });
831
- Object.defineProperty(ref, "inputSchema", { value: options?.inputSchema, enumerable: true });
856
+ Object.defineProperty(ref, "inputSchema", {
857
+ value: options?.inputSchema,
858
+ enumerable: true
859
+ });
832
860
  return ref;
833
861
  }
834
862
  function createWorkflowFactory(plugins = []) {
@@ -849,5 +877,5 @@ function createWorkflowFactory(plugins = []) {
849
877
  }
850
878
  var workflow = createWorkflowFactory();
851
879
 
852
- //# debugId=5A9A3072C311C6E064756E2164756E21
880
+ //# debugId=AA7D4CB0B3AC99D364756E2164756E21
853
881
  //# sourceMappingURL=client.entry.js.map
@@ -20,6 +20,9 @@ type WorkflowRun = {
20
20
  maxRetries: number;
21
21
  jobId: string | null;
22
22
  idempotencyKey: string | null;
23
+ parentRunId: string | null;
24
+ parentStepId: string | null;
25
+ parentResourceId: string | null;
23
26
  };
24
27
  import { StandardSchemaV1 } from "@standard-schema/spec";
25
28
  type DurationObject = {
@@ -40,6 +43,13 @@ declare enum WorkflowStatus {
40
43
  }
41
44
  type InputParameters = StandardSchemaV1;
42
45
  type InferInputParameters<P extends InputParameters> = StandardSchemaV1.InferOutput<P>;
46
+ type StartWorkflowOptions = {
47
+ resourceId?: string;
48
+ timeout?: number;
49
+ retries?: number;
50
+ expireInSeconds?: number;
51
+ idempotencyKey?: string;
52
+ };
43
53
  type WorkflowOptions<I extends InputParameters> = {
44
54
  timeout?: number;
45
55
  retries?: number;
@@ -79,6 +89,23 @@ type StepBaseContext = {
79
89
  } | {
80
90
  timedOut: true;
81
91
  }>;
92
+ /**
93
+ * Invoke a child workflow from inside the current workflow and pause until
94
+ * the child run reaches a terminal state.
95
+ */
96
+ invokeChildWorkflow: {
97
+ <
98
+ TInput extends InputParameters,
99
+ TOutput = unknown
100
+ >(stepId: string, ref: WorkflowRef<TInput, TOutput>, input: InferInputParameters<TInput>, options?: StartWorkflowOptions): Promise<TOutput>;
101
+ <TOutput = unknown>(stepId: string, params: {
102
+ workflowId: string;
103
+ input: unknown;
104
+ resourceId?: string;
105
+ idempotencyKey?: string;
106
+ options?: StartWorkflowOptions;
107
+ }): Promise<TOutput>;
108
+ };
82
109
  };
83
110
  /**
84
111
  * Plugin that extends the workflow step API with extra methods.
@@ -119,7 +146,10 @@ type WorkflowDefinition<TInput extends InputParameters = InputParameters> = {
119
146
  *
120
147
  * Callable: pass a handler to create a full WorkflowDefinition.
121
148
  */
122
- interface WorkflowRef<TInput extends InputParameters = InputParameters> {
149
+ interface WorkflowRef<
150
+ TInput extends InputParameters = InputParameters,
151
+ TOutput = unknown
152
+ > {
123
153
  (handler: (context: WorkflowContext<TInput, StepBaseContext>) => Promise<unknown>, options?: Omit<WorkflowOptions<TInput>, "inputSchema">): WorkflowDefinition<TInput>;
124
154
  readonly id: string;
125
155
  readonly inputSchema?: TInput;
@@ -149,13 +179,6 @@ type WorkflowClientOptions = {
149
179
  connectionString: string;
150
180
  pool?: never;
151
181
  });
152
- type StartWorkflowOptions = {
153
- resourceId?: string;
154
- timeout?: number;
155
- retries?: number;
156
- expireInSeconds?: number;
157
- idempotencyKey?: string;
158
- };
159
182
  declare class WorkflowClient {
160
183
  private boss;
161
184
  private db;
@@ -231,7 +254,21 @@ declare class WorkflowClient {
231
254
  * Create a lightweight workflow reference.
232
255
  * Safe to import from `pg-workflows/client` - no engine or handler code.
233
256
  */
234
- declare function createWorkflowRef<TInput extends InputParameters = InputParameters>(id: string, options?: {
257
+ declare function createWorkflowRef<
258
+ TOutput = unknown,
259
+ TInput extends InputParameters = InputParameters
260
+ >(id: string, options?: {
235
261
  inputSchema?: TInput;
236
- }): WorkflowRef<TInput>;
237
- export { createWorkflowRef, WorkflowStatus, WorkflowRunProgress, WorkflowRun, WorkflowRef, WorkflowLogger, WorkflowClientOptions, WorkflowClient, StartWorkflowOptions, InputParameters, InferInputParameters };
262
+ }): WorkflowRef<TInput, TOutput>;
263
+ import { StandardSchemaV1 as StandardSchemaV12 } from "@standard-schema/spec";
264
+ declare class WorkflowEngineError extends Error {
265
+ readonly workflowId?: string | undefined;
266
+ readonly runId?: string | undefined;
267
+ readonly cause: Error | undefined;
268
+ readonly issues?: StandardSchemaV12.FailureResult["issues"] | undefined;
269
+ constructor(message: string, workflowId?: string | undefined, runId?: string | undefined, cause?: Error | undefined, issues?: StandardSchemaV12.FailureResult["issues"] | undefined);
270
+ }
271
+ declare class WorkflowRunNotFoundError extends WorkflowEngineError {
272
+ constructor(runId?: string, workflowId?: string);
273
+ }
274
+ export { createWorkflowRef, WorkflowStatus, WorkflowRunProgress, WorkflowRunNotFoundError, WorkflowRun, WorkflowRef, WorkflowLogger, WorkflowEngineError, WorkflowClientOptions, WorkflowClient, StartWorkflowOptions, InputParameters, InferInputParameters };
@@ -20,6 +20,9 @@ type WorkflowRun = {
20
20
  maxRetries: number;
21
21
  jobId: string | null;
22
22
  idempotencyKey: string | null;
23
+ parentRunId: string | null;
24
+ parentStepId: string | null;
25
+ parentResourceId: string | null;
23
26
  };
24
27
  import { StandardSchemaV1 } from "@standard-schema/spec";
25
28
  type DurationObject = {
@@ -40,6 +43,13 @@ declare enum WorkflowStatus {
40
43
  }
41
44
  type InputParameters = StandardSchemaV1;
42
45
  type InferInputParameters<P extends InputParameters> = StandardSchemaV1.InferOutput<P>;
46
+ type StartWorkflowOptions = {
47
+ resourceId?: string;
48
+ timeout?: number;
49
+ retries?: number;
50
+ expireInSeconds?: number;
51
+ idempotencyKey?: string;
52
+ };
43
53
  type WorkflowOptions<I extends InputParameters> = {
44
54
  timeout?: number;
45
55
  retries?: number;
@@ -79,6 +89,23 @@ type StepBaseContext = {
79
89
  } | {
80
90
  timedOut: true;
81
91
  }>;
92
+ /**
93
+ * Invoke a child workflow from inside the current workflow and pause until
94
+ * the child run reaches a terminal state.
95
+ */
96
+ invokeChildWorkflow: {
97
+ <
98
+ TInput extends InputParameters,
99
+ TOutput = unknown
100
+ >(stepId: string, ref: WorkflowRef<TInput, TOutput>, input: InferInputParameters<TInput>, options?: StartWorkflowOptions): Promise<TOutput>;
101
+ <TOutput = unknown>(stepId: string, params: {
102
+ workflowId: string;
103
+ input: unknown;
104
+ resourceId?: string;
105
+ idempotencyKey?: string;
106
+ options?: StartWorkflowOptions;
107
+ }): Promise<TOutput>;
108
+ };
82
109
  };
83
110
  /**
84
111
  * Plugin that extends the workflow step API with extra methods.
@@ -119,7 +146,10 @@ type WorkflowDefinition<TInput extends InputParameters = InputParameters> = {
119
146
  *
120
147
  * Callable: pass a handler to create a full WorkflowDefinition.
121
148
  */
122
- interface WorkflowRef<TInput extends InputParameters = InputParameters> {
149
+ interface WorkflowRef<
150
+ TInput extends InputParameters = InputParameters,
151
+ TOutput = unknown
152
+ > {
123
153
  (handler: (context: WorkflowContext<TInput, StepBaseContext>) => Promise<unknown>, options?: Omit<WorkflowOptions<TInput>, "inputSchema">): WorkflowDefinition<TInput>;
124
154
  readonly id: string;
125
155
  readonly inputSchema?: TInput;
@@ -149,13 +179,6 @@ type WorkflowClientOptions = {
149
179
  connectionString: string;
150
180
  pool?: never;
151
181
  });
152
- type StartWorkflowOptions = {
153
- resourceId?: string;
154
- timeout?: number;
155
- retries?: number;
156
- expireInSeconds?: number;
157
- idempotencyKey?: string;
158
- };
159
182
  declare class WorkflowClient {
160
183
  private boss;
161
184
  private db;
@@ -231,7 +254,21 @@ declare class WorkflowClient {
231
254
  * Create a lightweight workflow reference.
232
255
  * Safe to import from `pg-workflows/client` - no engine or handler code.
233
256
  */
234
- declare function createWorkflowRef<TInput extends InputParameters = InputParameters>(id: string, options?: {
257
+ declare function createWorkflowRef<
258
+ TOutput = unknown,
259
+ TInput extends InputParameters = InputParameters
260
+ >(id: string, options?: {
235
261
  inputSchema?: TInput;
236
- }): WorkflowRef<TInput>;
237
- export { createWorkflowRef, WorkflowStatus, WorkflowRunProgress, WorkflowRun, WorkflowRef, WorkflowLogger, WorkflowClientOptions, WorkflowClient, StartWorkflowOptions, InputParameters, InferInputParameters };
262
+ }): WorkflowRef<TInput, TOutput>;
263
+ import { StandardSchemaV1 as StandardSchemaV12 } from "@standard-schema/spec";
264
+ declare class WorkflowEngineError extends Error {
265
+ readonly workflowId?: string | undefined;
266
+ readonly runId?: string | undefined;
267
+ readonly cause: Error | undefined;
268
+ readonly issues?: StandardSchemaV12.FailureResult["issues"] | undefined;
269
+ constructor(message: string, workflowId?: string | undefined, runId?: string | undefined, cause?: Error | undefined, issues?: StandardSchemaV12.FailureResult["issues"] | undefined);
270
+ }
271
+ declare class WorkflowRunNotFoundError extends WorkflowEngineError {
272
+ constructor(runId?: string, workflowId?: string);
273
+ }
274
+ export { createWorkflowRef, WorkflowStatus, WorkflowRunProgress, WorkflowRunNotFoundError, WorkflowRun, WorkflowRef, WorkflowLogger, WorkflowEngineError, WorkflowClientOptions, WorkflowClient, StartWorkflowOptions, InputParameters, InferInputParameters };
@@ -1,13 +1,17 @@
1
1
  import {
2
2
  WorkflowClient,
3
+ WorkflowEngineError,
4
+ WorkflowRunNotFoundError,
3
5
  WorkflowStatus,
4
6
  createWorkflowRef
5
- } from "./shared/chunk-fr76gdwj.js";
7
+ } from "./shared/chunk-ahxqsytt.js";
6
8
  export {
7
9
  createWorkflowRef,
8
10
  WorkflowStatus,
11
+ WorkflowRunNotFoundError,
12
+ WorkflowEngineError,
9
13
  WorkflowClient
10
14
  };
11
15
 
12
- //# debugId=B0186153DBB6496064756E2164756E21
16
+ //# debugId=64DD8F1F4DBCBD8C64756E2164756E21
13
17
  //# sourceMappingURL=client.entry.js.map