openworkflow 0.4.1 → 0.5.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 (193) hide show
  1. package/README.md +53 -48
  2. package/dist/backend-postgres/index.d.ts +44 -0
  3. package/dist/backend-postgres/index.d.ts.map +1 -0
  4. package/dist/backend-postgres/index.js +535 -0
  5. package/dist/backend-postgres/index.js.map +1 -0
  6. package/dist/backend-postgres/postgres.d.ts +42 -0
  7. package/dist/backend-postgres/postgres.d.ts.map +1 -0
  8. package/dist/backend-postgres/postgres.js +234 -0
  9. package/dist/backend-postgres/postgres.js.map +1 -0
  10. package/dist/backend-sqlite/index.d.ts +41 -1
  11. package/dist/backend-sqlite/index.d.ts.map +1 -1
  12. package/dist/backend-sqlite/index.js +654 -1
  13. package/dist/backend-sqlite/index.js.map +1 -1
  14. package/dist/backend-sqlite/sqlite.d.ts +18 -2
  15. package/dist/backend-sqlite/sqlite.d.ts.map +1 -1
  16. package/dist/backend-sqlite/sqlite.js +20 -2
  17. package/dist/backend-sqlite/sqlite.js.map +1 -1
  18. package/dist/{core/backend.d.ts → backend.d.ts} +7 -5
  19. package/dist/backend.d.ts.map +1 -0
  20. package/dist/backend.js.map +1 -0
  21. package/dist/bin/openworkflow.d.ts +3 -0
  22. package/dist/bin/openworkflow.d.ts.map +1 -0
  23. package/dist/bin/openworkflow.js +44 -0
  24. package/dist/bin/openworkflow.js.map +1 -0
  25. package/dist/client.d.ts +141 -0
  26. package/dist/client.d.ts.map +1 -0
  27. package/dist/{sdk/sdk.js → client.js} +44 -71
  28. package/dist/client.js.map +1 -0
  29. package/dist/config.d.ts +27 -21
  30. package/dist/config.d.ts.map +1 -1
  31. package/dist/config.js +44 -36
  32. package/dist/config.js.map +1 -1
  33. package/dist/core/duration.d.ts +4 -2
  34. package/dist/core/duration.d.ts.map +1 -1
  35. package/dist/core/duration.js +3 -1
  36. package/dist/core/duration.js.map +1 -1
  37. package/dist/core/error.d.ts +14 -0
  38. package/dist/core/error.d.ts.map +1 -0
  39. package/dist/core/error.js +18 -0
  40. package/dist/core/error.js.map +1 -0
  41. package/dist/core/result.d.ts +14 -4
  42. package/dist/core/result.d.ts.map +1 -1
  43. package/dist/core/result.js +10 -0
  44. package/dist/core/result.js.map +1 -1
  45. package/dist/core/retry.d.ts +0 -9
  46. package/dist/core/retry.d.ts.map +1 -1
  47. package/dist/core/retry.js +0 -14
  48. package/dist/core/retry.js.map +1 -1
  49. package/dist/core/step.d.ts +1 -32
  50. package/dist/core/step.d.ts.map +1 -1
  51. package/dist/core/step.js +0 -35
  52. package/dist/core/step.js.map +1 -1
  53. package/dist/core/workflow.d.ts +2 -47
  54. package/dist/core/workflow.d.ts.map +1 -1
  55. package/dist/core/workflow.js +0 -44
  56. package/dist/core/workflow.js.map +1 -1
  57. package/dist/{execution/execution.d.ts → execution.d.ts} +4 -26
  58. package/dist/execution.d.ts.map +1 -0
  59. package/dist/{execution/execution.js → execution.js} +4 -4
  60. package/dist/execution.js.map +1 -0
  61. package/dist/index.d.ts +6 -9
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +4 -4
  64. package/dist/index.js.map +1 -1
  65. package/dist/internal.d.ts +8 -0
  66. package/dist/internal.d.ts.map +1 -0
  67. package/dist/internal.js +5 -0
  68. package/dist/internal.js.map +1 -0
  69. package/dist/pg/backend.d.ts +42 -0
  70. package/dist/pg/backend.d.ts.map +1 -0
  71. package/dist/pg/backend.js +534 -0
  72. package/dist/pg/backend.js.map +1 -0
  73. package/dist/pg/index.d.ts +3 -0
  74. package/dist/pg/index.d.ts.map +1 -0
  75. package/dist/pg/index.js +3 -0
  76. package/dist/pg/index.js.map +1 -0
  77. package/dist/pg/postgres.d.ts +42 -0
  78. package/dist/pg/postgres.d.ts.map +1 -0
  79. package/dist/pg/postgres.js +234 -0
  80. package/dist/pg/postgres.js.map +1 -0
  81. package/dist/pg/scripts/db-migrate.d.ts +2 -0
  82. package/dist/pg/scripts/db-migrate.d.ts.map +1 -0
  83. package/dist/pg/scripts/db-migrate.js +5 -0
  84. package/dist/pg/scripts/db-migrate.js.map +1 -0
  85. package/dist/pg/scripts/db-reset.d.ts +2 -0
  86. package/dist/pg/scripts/db-reset.d.ts.map +1 -0
  87. package/dist/pg/scripts/db-reset.js +6 -0
  88. package/dist/pg/scripts/db-reset.js.map +1 -0
  89. package/dist/pg/scripts/squawk.d.ts +2 -0
  90. package/dist/pg/scripts/squawk.d.ts.map +1 -0
  91. package/dist/pg/scripts/squawk.js +17 -0
  92. package/dist/pg/scripts/squawk.js.map +1 -0
  93. package/dist/pg/vitest.global-setup.d.ts +3 -0
  94. package/dist/pg/vitest.global-setup.d.ts.map +1 -0
  95. package/dist/pg/vitest.global-setup.js +8 -0
  96. package/dist/pg/vitest.global-setup.js.map +1 -0
  97. package/dist/registry.d.ts +27 -0
  98. package/dist/registry.d.ts.map +1 -0
  99. package/dist/registry.js +49 -0
  100. package/dist/registry.js.map +1 -0
  101. package/dist/{backend-sqlite → sqlite}/backend.d.ts +6 -4
  102. package/dist/sqlite/backend.d.ts.map +1 -0
  103. package/dist/{backend-sqlite → sqlite}/backend.js +31 -5
  104. package/dist/sqlite/backend.js.map +1 -0
  105. package/dist/sqlite/index.d.ts +3 -0
  106. package/dist/sqlite/index.d.ts.map +1 -0
  107. package/dist/sqlite/index.js +3 -0
  108. package/dist/sqlite/index.js.map +1 -0
  109. package/dist/sqlite/sqlite.d.ts +61 -0
  110. package/dist/sqlite/sqlite.d.ts.map +1 -0
  111. package/dist/sqlite/sqlite.js +247 -0
  112. package/dist/sqlite/sqlite.js.map +1 -0
  113. package/dist/testing/backend.testsuite.d.ts +20 -0
  114. package/dist/testing/backend.testsuite.d.ts.map +1 -0
  115. package/dist/{core → testing}/backend.testsuite.js +186 -53
  116. package/dist/testing/backend.testsuite.js.map +1 -0
  117. package/dist/testing/index.d.ts +2 -0
  118. package/dist/testing/index.d.ts.map +1 -0
  119. package/dist/testing/index.js +2 -0
  120. package/dist/testing/index.js.map +1 -0
  121. package/dist/tsconfig.tsbuildinfo +1 -1
  122. package/dist/{worker/worker.d.ts → worker.d.ts} +11 -4
  123. package/dist/worker.d.ts.map +1 -0
  124. package/dist/{worker/worker.js → worker.js} +20 -10
  125. package/dist/worker.js.map +1 -0
  126. package/dist/workflow.d.ts +60 -0
  127. package/dist/workflow.d.ts.map +1 -0
  128. package/dist/workflow.js +49 -0
  129. package/dist/workflow.js.map +1 -0
  130. package/package.json +13 -3
  131. package/dist/backend-sqlite/backend.d.ts.map +0 -1
  132. package/dist/backend-sqlite/backend.js.map +0 -1
  133. package/dist/config/config.d.ts +0 -102
  134. package/dist/config/config.d.ts.map +0 -1
  135. package/dist/config/config.js +0 -29
  136. package/dist/config/config.js.map +0 -1
  137. package/dist/config/index.d.ts +0 -3
  138. package/dist/config/index.d.ts.map +0 -1
  139. package/dist/config/index.js +0 -2
  140. package/dist/config/index.js.map +0 -1
  141. package/dist/core/backend-test-suite.d.ts +0 -22
  142. package/dist/core/backend-test-suite.d.ts.map +0 -1
  143. package/dist/core/backend-test-suite.js +0 -960
  144. package/dist/core/backend-test-suite.js.map +0 -1
  145. package/dist/core/backend.d.ts.map +0 -1
  146. package/dist/core/backend.js.map +0 -1
  147. package/dist/core/backend.testsuite.d.ts +0 -21
  148. package/dist/core/backend.testsuite.d.ts.map +0 -1
  149. package/dist/core/backend.testsuite.js.map +0 -1
  150. package/dist/core/duration.test.d.ts +0 -2
  151. package/dist/core/duration.test.d.ts.map +0 -1
  152. package/dist/core/duration.test.js +0 -264
  153. package/dist/core/duration.test.js.map +0 -1
  154. package/dist/core/result.test.d.ts +0 -2
  155. package/dist/core/result.test.d.ts.map +0 -1
  156. package/dist/core/result.test.js +0 -11
  157. package/dist/core/result.test.js.map +0 -1
  158. package/dist/core/retry.test.d.ts +0 -2
  159. package/dist/core/retry.test.d.ts.map +0 -1
  160. package/dist/core/retry.test.js +0 -36
  161. package/dist/core/retry.test.js.map +0 -1
  162. package/dist/core/step.test.d.ts +0 -2
  163. package/dist/core/step.test.d.ts.map +0 -1
  164. package/dist/core/step.test.js +0 -340
  165. package/dist/core/step.test.js.map +0 -1
  166. package/dist/core/workflow.test.d.ts +0 -2
  167. package/dist/core/workflow.test.d.ts.map +0 -1
  168. package/dist/core/workflow.test.js +0 -216
  169. package/dist/core/workflow.test.js.map +0 -1
  170. package/dist/execution/execution.d.ts.map +0 -1
  171. package/dist/execution/execution.js.map +0 -1
  172. package/dist/execution/execution.test.d.ts +0 -2
  173. package/dist/execution/execution.test.d.ts.map +0 -1
  174. package/dist/execution/execution.test.js +0 -382
  175. package/dist/execution/execution.test.js.map +0 -1
  176. package/dist/global.d.ts +0 -62
  177. package/dist/global.d.ts.map +0 -1
  178. package/dist/global.js +0 -78
  179. package/dist/global.js.map +0 -1
  180. package/dist/sdk/sdk.d.ts +0 -182
  181. package/dist/sdk/sdk.d.ts.map +0 -1
  182. package/dist/sdk/sdk.js.map +0 -1
  183. package/dist/sdk/sdk.test.d.ts +0 -2
  184. package/dist/sdk/sdk.test.d.ts.map +0 -1
  185. package/dist/sdk/sdk.test.js +0 -195
  186. package/dist/sdk/sdk.test.js.map +0 -1
  187. package/dist/worker/worker.d.ts.map +0 -1
  188. package/dist/worker/worker.js.map +0 -1
  189. package/dist/worker/worker.test.d.ts +0 -2
  190. package/dist/worker/worker.test.d.ts.map +0 -1
  191. package/dist/worker/worker.test.js +0 -786
  192. package/dist/worker/worker.test.js.map +0 -1
  193. /package/dist/{core/backend.js → backend.js} +0 -0
@@ -0,0 +1,535 @@
1
+ import { DEFAULT_NAMESPACE_ID } from "../backend.js";
2
+ import { DEFAULT_RETRY_POLICY } from "../core/retry.js";
3
+ import { DEFAULT_SCHEMA, migrate, newPostgres, newPostgresMaxOne, } from "./postgres.js";
4
+ const DEFAULT_PAGINATION_PAGE_SIZE = 100;
5
+ /**
6
+ * Manages a connection to a Postgres database for workflow operations.
7
+ */
8
+ export class BackendPostgres {
9
+ pg;
10
+ namespaceId;
11
+ constructor(pg, namespaceId) {
12
+ this.pg = pg;
13
+ this.namespaceId = namespaceId;
14
+ }
15
+ /**
16
+ * Create and initialize a new BackendPostgres instance. This will
17
+ * automatically run migrations on startup unless `runMigrations` is set to
18
+ * false.
19
+ * @param url - Postgres connection URL
20
+ * @param options - Backend options
21
+ * @returns A connected backend instance
22
+ */
23
+ static async connect(url, options) {
24
+ const { namespaceId, runMigrations } = {
25
+ namespaceId: DEFAULT_NAMESPACE_ID,
26
+ runMigrations: true,
27
+ ...options,
28
+ };
29
+ if (runMigrations) {
30
+ const pgForMigrate = newPostgresMaxOne(url);
31
+ await migrate(pgForMigrate, DEFAULT_SCHEMA);
32
+ await pgForMigrate.end();
33
+ }
34
+ const pg = newPostgres(url);
35
+ return new BackendPostgres(pg, namespaceId);
36
+ }
37
+ async stop() {
38
+ await this.pg.end();
39
+ }
40
+ async createWorkflowRun(params) {
41
+ const [workflowRun] = await this.pg `
42
+ INSERT INTO "openworkflow"."workflow_runs" (
43
+ "namespace_id",
44
+ "id",
45
+ "workflow_name",
46
+ "version",
47
+ "status",
48
+ "idempotency_key",
49
+ "config",
50
+ "context",
51
+ "input",
52
+ "attempts",
53
+ "available_at",
54
+ "deadline_at",
55
+ "created_at",
56
+ "updated_at"
57
+ )
58
+ VALUES (
59
+ ${this.namespaceId},
60
+ gen_random_uuid(),
61
+ ${params.workflowName},
62
+ ${params.version},
63
+ 'pending',
64
+ ${params.idempotencyKey},
65
+ ${this.pg.json(params.config)},
66
+ ${this.pg.json(params.context)},
67
+ ${this.pg.json(params.input)},
68
+ 0,
69
+ ${sqlDateDefaultNow(this.pg, params.availableAt)},
70
+ ${params.deadlineAt},
71
+ date_trunc('milliseconds', NOW()),
72
+ NOW()
73
+ )
74
+ RETURNING *
75
+ `;
76
+ if (!workflowRun)
77
+ throw new Error("Failed to create workflow run");
78
+ return workflowRun;
79
+ }
80
+ async getWorkflowRun(params) {
81
+ const [workflowRun] = await this.pg `
82
+ SELECT *
83
+ FROM "openworkflow"."workflow_runs"
84
+ WHERE "namespace_id" = ${this.namespaceId}
85
+ AND "id" = ${params.workflowRunId}
86
+ LIMIT 1
87
+ `;
88
+ return workflowRun ?? null;
89
+ }
90
+ async listWorkflowRuns(params) {
91
+ const limit = params.limit ?? DEFAULT_PAGINATION_PAGE_SIZE;
92
+ const { after, before } = params;
93
+ let cursor = null;
94
+ if (after) {
95
+ cursor = decodeCursor(after);
96
+ }
97
+ else if (before) {
98
+ cursor = decodeCursor(before);
99
+ }
100
+ const whereClause = this.buildListWorkflowRunsWhere(params, cursor);
101
+ const order = before
102
+ ? this.pg `ORDER BY "created_at" DESC, "id" DESC`
103
+ : this.pg `ORDER BY "created_at" ASC, "id" ASC`;
104
+ const rows = await this.pg `
105
+ SELECT *
106
+ FROM "openworkflow"."workflow_runs"
107
+ WHERE ${whereClause}
108
+ ${order}
109
+ LIMIT ${limit + 1}
110
+ `;
111
+ return this.processPaginationResults(rows, limit, !!after, !!before);
112
+ }
113
+ buildListWorkflowRunsWhere(params, cursor) {
114
+ const { after } = params;
115
+ const conditions = [this.pg `"namespace_id" = ${this.namespaceId}`];
116
+ if (cursor) {
117
+ const op = after ? this.pg `>` : this.pg `<`;
118
+ conditions.push(this.pg `("created_at", "id") ${op} (${cursor.createdAt}, ${cursor.id})`);
119
+ }
120
+ let whereClause = conditions[0];
121
+ if (!whereClause)
122
+ throw new Error("No conditions");
123
+ for (let i = 1; i < conditions.length; i++) {
124
+ const condition = conditions[i];
125
+ if (condition) {
126
+ whereClause = this.pg `${whereClause} AND ${condition}`;
127
+ }
128
+ }
129
+ return whereClause;
130
+ }
131
+ async claimWorkflowRun(params) {
132
+ // 1. mark any deadline-expired workflow runs as failed
133
+ // 2. find an available workflow run to claim
134
+ // 3. claim the workflow run
135
+ const [claimed] = await this.pg `
136
+ WITH expired AS (
137
+ UPDATE "openworkflow"."workflow_runs"
138
+ SET
139
+ "status" = 'failed',
140
+ "error" = ${this.pg.json({ message: "Workflow run deadline exceeded" })},
141
+ "worker_id" = NULL,
142
+ "available_at" = NULL,
143
+ "finished_at" = NOW(),
144
+ "updated_at" = NOW()
145
+ WHERE "namespace_id" = ${this.namespaceId}
146
+ AND "status" IN ('pending', 'running', 'sleeping')
147
+ AND "deadline_at" IS NOT NULL
148
+ AND "deadline_at" <= NOW()
149
+ RETURNING "id"
150
+ ),
151
+ candidate AS (
152
+ SELECT "id"
153
+ FROM "openworkflow"."workflow_runs"
154
+ WHERE "namespace_id" = ${this.namespaceId}
155
+ AND "status" IN ('pending', 'running', 'sleeping')
156
+ AND "available_at" <= NOW()
157
+ AND ("deadline_at" IS NULL OR "deadline_at" > NOW())
158
+ ORDER BY
159
+ CASE WHEN "status" = 'pending' THEN 0 ELSE 1 END,
160
+ "available_at",
161
+ "created_at"
162
+ LIMIT 1
163
+ FOR UPDATE SKIP LOCKED
164
+ )
165
+ UPDATE "openworkflow"."workflow_runs" AS wr
166
+ SET
167
+ "status" = 'running',
168
+ "attempts" = "attempts" + 1,
169
+ "worker_id" = ${params.workerId},
170
+ "available_at" = NOW() + ${params.leaseDurationMs} * INTERVAL '1 millisecond',
171
+ "started_at" = COALESCE("started_at", NOW()),
172
+ "updated_at" = NOW()
173
+ FROM candidate
174
+ WHERE wr."id" = candidate."id"
175
+ AND wr."namespace_id" = ${this.namespaceId}
176
+ RETURNING wr.*;
177
+ `;
178
+ return claimed ?? null;
179
+ }
180
+ async extendWorkflowRunLease(params) {
181
+ const [updated] = await this.pg `
182
+ UPDATE "openworkflow"."workflow_runs"
183
+ SET
184
+ "available_at" = ${this.pg `NOW() + ${params.leaseDurationMs} * INTERVAL '1 millisecond'`},
185
+ "updated_at" = NOW()
186
+ WHERE "namespace_id" = ${this.namespaceId}
187
+ AND "id" = ${params.workflowRunId}
188
+ AND "status" = 'running'
189
+ AND "worker_id" = ${params.workerId}
190
+ RETURNING *
191
+ `;
192
+ if (!updated)
193
+ throw new Error("Failed to extend lease for workflow run");
194
+ return updated;
195
+ }
196
+ async sleepWorkflowRun(params) {
197
+ // 'succeeded' status is deprecated
198
+ const [updated] = await this.pg `
199
+ UPDATE "openworkflow"."workflow_runs"
200
+ SET
201
+ "status" = 'sleeping',
202
+ "available_at" = ${params.availableAt},
203
+ "worker_id" = NULL,
204
+ "updated_at" = NOW()
205
+ WHERE "namespace_id" = ${this.namespaceId}
206
+ AND "id" = ${params.workflowRunId}
207
+ AND "status" != 'succeeded'
208
+ AND "status" != 'completed'
209
+ AND "status" != 'failed'
210
+ AND "status" != 'canceled'
211
+ AND "worker_id" = ${params.workerId}
212
+ RETURNING *
213
+ `;
214
+ if (!updated)
215
+ throw new Error("Failed to sleep workflow run");
216
+ return updated;
217
+ }
218
+ async completeWorkflowRun(params) {
219
+ const [updated] = await this.pg `
220
+ UPDATE "openworkflow"."workflow_runs"
221
+ SET
222
+ "status" = 'completed',
223
+ "output" = ${this.pg.json(params.output)},
224
+ "error" = NULL,
225
+ "worker_id" = ${params.workerId},
226
+ "available_at" = NULL,
227
+ "finished_at" = NOW(),
228
+ "updated_at" = NOW()
229
+ WHERE "namespace_id" = ${this.namespaceId}
230
+ AND "id" = ${params.workflowRunId}
231
+ AND "status" = 'running'
232
+ AND "worker_id" = ${params.workerId}
233
+ RETURNING *
234
+ `;
235
+ if (!updated)
236
+ throw new Error("Failed to mark workflow run completed");
237
+ return updated;
238
+ }
239
+ async failWorkflowRun(params) {
240
+ const { workflowRunId, error } = params;
241
+ const { initialIntervalMs, backoffCoefficient, maximumIntervalMs } = DEFAULT_RETRY_POLICY;
242
+ // this beefy query updates a workflow's status, available_at, and
243
+ // finished_at based on the workflow's deadline and retry policy
244
+ //
245
+ // if the next retry would exceed the deadline, the run is marked as
246
+ // 'failed' and finalized, otherwise, the run is rescheduled with an updated
247
+ // 'available_at' timestamp for the next retry
248
+ const [updated] = await this.pg `
249
+ UPDATE "openworkflow"."workflow_runs"
250
+ SET
251
+ "status" = CASE
252
+ WHEN "deadline_at" IS NOT NULL AND NOW() + (
253
+ LEAST(
254
+ ${initialIntervalMs} * POWER(${backoffCoefficient}, "attempts" - 1),
255
+ ${maximumIntervalMs}
256
+ ) * INTERVAL '1 millisecond'
257
+ ) >= "deadline_at" THEN 'failed'
258
+ ELSE 'pending'
259
+ END,
260
+
261
+ "available_at" = CASE
262
+ WHEN "deadline_at" IS NOT NULL AND NOW() + (
263
+ LEAST(
264
+ ${initialIntervalMs} * POWER(${backoffCoefficient}, "attempts" - 1),
265
+ ${maximumIntervalMs}
266
+ ) * INTERVAL '1 millisecond'
267
+ ) >= "deadline_at" THEN NULL
268
+ ELSE NOW() + (
269
+ LEAST(
270
+ ${initialIntervalMs} * POWER(${backoffCoefficient}, "attempts" - 1),
271
+ ${maximumIntervalMs}
272
+ ) * INTERVAL '1 millisecond'
273
+ )
274
+ END,
275
+
276
+ "finished_at" = CASE
277
+ WHEN "deadline_at" IS NOT NULL AND NOW() + (
278
+ LEAST(
279
+ ${initialIntervalMs} * POWER(${backoffCoefficient}, "attempts" - 1),
280
+ ${maximumIntervalMs}
281
+ ) * INTERVAL '1 millisecond'
282
+ ) >= "deadline_at" THEN NOW()
283
+ ELSE NULL
284
+ END,
285
+ "error" = ${this.pg.json(error)},
286
+ "worker_id" = NULL,
287
+ "started_at" = NULL,
288
+ "updated_at" = NOW()
289
+ WHERE "namespace_id" = ${this.namespaceId}
290
+ AND "id" = ${workflowRunId}
291
+ AND "status" = 'running'
292
+ AND "worker_id" = ${params.workerId}
293
+ RETURNING *
294
+ `;
295
+ if (!updated)
296
+ throw new Error("Failed to mark workflow run failed");
297
+ return updated;
298
+ }
299
+ async cancelWorkflowRun(params) {
300
+ const [updated] = await this.pg `
301
+ UPDATE "openworkflow"."workflow_runs"
302
+ SET
303
+ "status" = 'canceled',
304
+ "worker_id" = NULL,
305
+ "available_at" = NULL,
306
+ "finished_at" = NOW(),
307
+ "updated_at" = NOW()
308
+ WHERE "namespace_id" = ${this.namespaceId}
309
+ AND "id" = ${params.workflowRunId}
310
+ AND "status" IN ('pending', 'running', 'sleeping')
311
+ RETURNING *
312
+ `;
313
+ if (!updated) {
314
+ // workflow may already be in a terminal state
315
+ const existing = await this.getWorkflowRun({
316
+ workflowRunId: params.workflowRunId,
317
+ });
318
+ if (!existing) {
319
+ throw new Error(`Workflow run ${params.workflowRunId} does not exist`);
320
+ }
321
+ // if already canceled, just return it
322
+ if (existing.status === "canceled") {
323
+ return existing;
324
+ }
325
+ // throw error for completed/failed workflows
326
+ // 'succeeded' status is deprecated
327
+ if (["succeeded", "completed", "failed"].includes(existing.status)) {
328
+ throw new Error(`Cannot cancel workflow run ${params.workflowRunId} with status ${existing.status}`);
329
+ }
330
+ throw new Error("Failed to cancel workflow run");
331
+ }
332
+ return updated;
333
+ }
334
+ async createStepAttempt(params) {
335
+ const [stepAttempt] = await this.pg `
336
+ INSERT INTO "openworkflow"."step_attempts" (
337
+ "namespace_id",
338
+ "id",
339
+ "workflow_run_id",
340
+ "step_name",
341
+ "kind",
342
+ "status",
343
+ "config",
344
+ "context",
345
+ "started_at",
346
+ "created_at",
347
+ "updated_at"
348
+ )
349
+ VALUES (
350
+ ${this.namespaceId},
351
+ gen_random_uuid(),
352
+ ${params.workflowRunId},
353
+ ${params.stepName},
354
+ ${params.kind},
355
+ 'running',
356
+ ${this.pg.json(params.config)},
357
+ ${this.pg.json(params.context)},
358
+ NOW(),
359
+ date_trunc('milliseconds', NOW()),
360
+ NOW()
361
+ )
362
+ RETURNING *
363
+ `;
364
+ if (!stepAttempt)
365
+ throw new Error("Failed to create step attempt");
366
+ return stepAttempt;
367
+ }
368
+ async getStepAttempt(params) {
369
+ const [stepAttempt] = await this.pg `
370
+ SELECT *
371
+ FROM "openworkflow"."step_attempts"
372
+ WHERE "namespace_id" = ${this.namespaceId}
373
+ AND "id" = ${params.stepAttemptId}
374
+ LIMIT 1
375
+ `;
376
+ return stepAttempt ?? null;
377
+ }
378
+ async listStepAttempts(params) {
379
+ const limit = params.limit ?? DEFAULT_PAGINATION_PAGE_SIZE;
380
+ const { after, before } = params;
381
+ let cursor = null;
382
+ if (after) {
383
+ cursor = decodeCursor(after);
384
+ }
385
+ else if (before) {
386
+ cursor = decodeCursor(before);
387
+ }
388
+ const whereClause = this.buildListStepAttemptsWhere(params, cursor);
389
+ const order = before
390
+ ? this.pg `ORDER BY "created_at" DESC, "id" DESC`
391
+ : this.pg `ORDER BY "created_at" ASC, "id" ASC`;
392
+ const rows = await this.pg `
393
+ SELECT *
394
+ FROM "openworkflow"."step_attempts"
395
+ WHERE ${whereClause}
396
+ ${order}
397
+ LIMIT ${limit + 1}
398
+ `;
399
+ return this.processPaginationResults(rows, limit, !!after, !!before);
400
+ }
401
+ buildListStepAttemptsWhere(params, cursor) {
402
+ const { after } = params;
403
+ const conditions = [
404
+ this.pg `"namespace_id" = ${this.namespaceId}`,
405
+ this.pg `"workflow_run_id" = ${params.workflowRunId}`,
406
+ ];
407
+ if (cursor) {
408
+ const op = after ? this.pg `>` : this.pg `<`;
409
+ conditions.push(this.pg `("created_at", "id") ${op} (${cursor.createdAt}, ${cursor.id})`);
410
+ }
411
+ let whereClause = conditions[0];
412
+ if (!whereClause)
413
+ throw new Error("No conditions");
414
+ for (let i = 1; i < conditions.length; i++) {
415
+ const condition = conditions[i];
416
+ if (condition) {
417
+ whereClause = this.pg `${whereClause} AND ${condition}`;
418
+ }
419
+ }
420
+ return whereClause;
421
+ }
422
+ processPaginationResults(rows, limit, hasAfter, hasBefore) {
423
+ const data = rows;
424
+ let hasNext = false;
425
+ let hasPrev = false;
426
+ if (hasBefore) {
427
+ data.reverse();
428
+ if (data.length > limit) {
429
+ hasPrev = true;
430
+ data.shift();
431
+ }
432
+ hasNext = true;
433
+ }
434
+ else {
435
+ if (data.length > limit) {
436
+ hasNext = true;
437
+ data.pop();
438
+ }
439
+ if (hasAfter) {
440
+ hasPrev = true;
441
+ }
442
+ }
443
+ const lastItem = data.at(-1);
444
+ const nextCursor = hasNext && lastItem ? encodeCursor(lastItem) : null;
445
+ const firstItem = data[0];
446
+ const prevCursor = hasPrev && firstItem ? encodeCursor(firstItem) : null;
447
+ return {
448
+ data,
449
+ pagination: {
450
+ next: nextCursor,
451
+ prev: prevCursor,
452
+ },
453
+ };
454
+ }
455
+ async completeStepAttempt(params) {
456
+ const [updated] = await this.pg `
457
+ UPDATE "openworkflow"."step_attempts" sa
458
+ SET
459
+ "status" = 'completed',
460
+ "output" = ${this.pg.json(params.output)},
461
+ "error" = NULL,
462
+ "finished_at" = NOW(),
463
+ "updated_at" = NOW()
464
+ FROM "openworkflow"."workflow_runs" wr
465
+ WHERE sa."namespace_id" = ${this.namespaceId}
466
+ AND sa."workflow_run_id" = ${params.workflowRunId}
467
+ AND sa."id" = ${params.stepAttemptId}
468
+ AND sa."status" = 'running'
469
+ AND wr."namespace_id" = sa."namespace_id"
470
+ AND wr."id" = sa."workflow_run_id"
471
+ AND wr."status" = 'running'
472
+ AND wr."worker_id" = ${params.workerId}
473
+ RETURNING sa.*
474
+ `;
475
+ if (!updated)
476
+ throw new Error("Failed to mark step attempt completed");
477
+ return updated;
478
+ }
479
+ async failStepAttempt(params) {
480
+ const [updated] = await this.pg `
481
+ UPDATE "openworkflow"."step_attempts" sa
482
+ SET
483
+ "status" = 'failed',
484
+ "output" = NULL,
485
+ "error" = ${this.pg.json(params.error)},
486
+ "finished_at" = NOW(),
487
+ "updated_at" = NOW()
488
+ FROM "openworkflow"."workflow_runs" wr
489
+ WHERE sa."namespace_id" = ${this.namespaceId}
490
+ AND sa."workflow_run_id" = ${params.workflowRunId}
491
+ AND sa."id" = ${params.stepAttemptId}
492
+ AND sa."status" = 'running'
493
+ AND wr."namespace_id" = sa."namespace_id"
494
+ AND wr."id" = sa."workflow_run_id"
495
+ AND wr."status" = 'running'
496
+ AND wr."worker_id" = ${params.workerId}
497
+ RETURNING sa.*
498
+ `;
499
+ if (!updated)
500
+ throw new Error("Failed to mark step attempt failed");
501
+ return updated;
502
+ }
503
+ }
504
+ /**
505
+ * sqlDateDefaultNow returns the provided date or `NOW()` if not.
506
+ * This is needed so we don't have to disable the eslint rule for every query.
507
+ * @param pg - Postgres client
508
+ * @param date - Date to use (or null)
509
+ * @returns The provided date or a NOW() expression
510
+ */
511
+ function sqlDateDefaultNow(pg, date) {
512
+ return date ?? pg `NOW()`;
513
+ }
514
+ /**
515
+ * Encode a pagination cursor to a string.
516
+ * @param item - Cursor data
517
+ * @returns Encoded cursor
518
+ */
519
+ function encodeCursor(item) {
520
+ return Buffer.from(JSON.stringify({ createdAt: item.createdAt, id: item.id })).toString("base64");
521
+ }
522
+ /**
523
+ * Decode a pagination cursor from a string.
524
+ * @param cursor - Encoded cursor
525
+ * @returns Cursor data
526
+ */
527
+ function decodeCursor(cursor) {
528
+ const decoded = Buffer.from(cursor, "base64").toString("utf8");
529
+ const parsed = JSON.parse(decoded);
530
+ return {
531
+ createdAt: new Date(parsed.createdAt),
532
+ id: parsed.id,
533
+ };
534
+ }
535
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/backend-postgres/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import postgres from "postgres";
2
+ export declare const DEFAULT_POSTGRES_URL = "postgresql://postgres:postgres@localhost:5432/postgres";
3
+ export declare const DEFAULT_SCHEMA = "openworkflow";
4
+ export type Postgres = ReturnType<typeof postgres>;
5
+ export type PostgresOptions = Parameters<typeof postgres>[1];
6
+ /**
7
+ * newPostgres creates a new Postgres client.
8
+ * @param url - Database connection URL
9
+ * @param options - Postgres client options
10
+ * @returns A Postgres client
11
+ */
12
+ export declare function newPostgres(url: string, options?: PostgresOptions): postgres.Sql<{}>;
13
+ /**
14
+ * newPostgresMaxOne creates a new Postgres client with a maximum pool size of
15
+ * one, which is useful for migrations.
16
+ * @param url - Database connection URL
17
+ * @param options - Postgres client options
18
+ * @returns A Postgres client
19
+ */
20
+ export declare function newPostgresMaxOne(url: string, options?: PostgresOptions): postgres.Sql<{}>;
21
+ /**
22
+ * migrations returns the list of migration SQL statements.
23
+ * @param schema - Schema name
24
+ * @returns Migration SQL statements
25
+ */
26
+ export declare function migrations(schema: string): string[];
27
+ /**
28
+ * migrate applies pending migrations to the database. Does nothing if the
29
+ * database is already up to date.
30
+ * @param pg - Postgres client
31
+ * @param schema - Schema name
32
+ * @returns Promise resolved when migrations complete
33
+ */
34
+ export declare function migrate(pg: Postgres, schema: string): Promise<void>;
35
+ /**
36
+ * dropSchema drops the specified schema from the database.
37
+ * @param pg - Postgres client
38
+ * @param schema - Schema name
39
+ * @returns Promise resolved when the schema is dropped
40
+ */
41
+ export declare function dropSchema(pg: Postgres, schema: string): Promise<void>;
42
+ //# sourceMappingURL=postgres.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../src/backend-postgres/postgres.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAEhC,eAAO,MAAM,oBAAoB,2DACyB,CAAC;AAO3D,eAAO,MAAM,cAAc,iBAAiB,CAAC;AAE7C,MAAM,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AACnD,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AAE7D;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,oBAEjE;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,oBAEvE;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CA+JnD;AAED;;;;;;GAMG;AACH,wBAAsB,OAAO,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,iBAQzD;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,iBAE5D"}