@sonamu-kit/tasks 0.1.0 → 0.1.2

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 (51) hide show
  1. package/dist/client.d.ts +0 -1
  2. package/dist/client.d.ts.map +1 -1
  3. package/dist/client.js +0 -1
  4. package/dist/client.js.map +1 -1
  5. package/dist/client.test.js +2 -1
  6. package/dist/client.test.js.map +1 -1
  7. package/dist/core/duration.d.ts +1 -1
  8. package/dist/core/duration.js +1 -1
  9. package/dist/core/duration.js.map +1 -1
  10. package/dist/core/workflow.d.ts +2 -1
  11. package/dist/core/workflow.d.ts.map +1 -1
  12. package/dist/core/workflow.js +2 -1
  13. package/dist/core/workflow.js.map +1 -1
  14. package/dist/database/backend.d.ts +7 -8
  15. package/dist/database/backend.d.ts.map +1 -1
  16. package/dist/database/backend.js +134 -39
  17. package/dist/database/backend.js.map +1 -1
  18. package/dist/database/backend.test.js +3 -1
  19. package/dist/database/backend.test.js.map +1 -1
  20. package/dist/database/base.d.ts +2 -2
  21. package/dist/database/base.d.ts.map +1 -1
  22. package/dist/database/base.js +17 -5
  23. package/dist/database/base.js.map +1 -1
  24. package/dist/database/pubsub.d.ts.map +1 -1
  25. package/dist/database/pubsub.js +9 -3
  26. package/dist/database/pubsub.js.map +1 -1
  27. package/dist/execution.test.js +4 -2
  28. package/dist/execution.test.js.map +1 -1
  29. package/dist/practices/01-remote-workflow.js +2 -1
  30. package/dist/practices/01-remote-workflow.js.map +1 -1
  31. package/dist/testing/connection.d.ts +1 -1
  32. package/dist/testing/connection.d.ts.map +1 -1
  33. package/dist/testing/connection.js +5 -4
  34. package/dist/testing/connection.js.map +1 -1
  35. package/dist/worker.test.js +2 -1
  36. package/dist/worker.test.js.map +1 -1
  37. package/package.json +7 -5
  38. package/scripts/migrate.ts +1 -4
  39. package/src/client.test.ts +2 -1
  40. package/src/client.ts +0 -1
  41. package/src/core/duration.ts +1 -1
  42. package/src/core/workflow.ts +2 -1
  43. package/src/database/backend.test.ts +3 -1
  44. package/src/database/backend.ts +140 -45
  45. package/src/database/base.ts +12 -7
  46. package/src/database/pubsub.ts +9 -3
  47. package/src/execution.test.ts +4 -2
  48. package/src/practices/01-remote-workflow.ts +2 -1
  49. package/src/testing/connection.ts +5 -3
  50. package/src/worker.test.ts +2 -1
  51. package/templates/openworkflow.config.ts +1 -1
@@ -1,3 +1,4 @@
1
+ import { getLogger } from "@logtape/logtape";
1
2
  import { camelize } from "inflection";
2
3
  import knex from "knex";
3
4
  import { DEFAULT_NAMESPACE_ID } from "../backend.js";
@@ -6,19 +7,70 @@ import { DEFAULT_SCHEMA, migrate } from "./base.js";
6
7
  import { PostgresPubSub } from "./pubsub.js";
7
8
  export const DEFAULT_LISTEN_CHANNEL = "new_tasks";
8
9
  const DEFAULT_PAGINATION_PAGE_SIZE = 100;
10
+ const logger = getLogger([
11
+ "sonamu",
12
+ "internal",
13
+ "tasks"
14
+ ]);
9
15
  /**
10
16
  * Manages a connection to a Postgres database for workflow operations.
11
17
  */ export class BackendPostgres {
12
- knex;
18
+ config;
13
19
  namespaceId;
14
20
  usePubSub;
15
21
  pubsub = null;
16
- constructor(knex, namespaceId, usePubSub){
17
- this.knex = knex;
22
+ initialized = false;
23
+ runMigrations;
24
+ _knex = null;
25
+ get knex() {
26
+ if (!this._knex) {
27
+ this._knex = knex(this.config);
28
+ }
29
+ return this._knex;
30
+ }
31
+ constructor(config, options){
32
+ this.config = {
33
+ ...config,
34
+ postProcessResponse: (result, _queryContext)=>{
35
+ if (result === null || result === undefined) {
36
+ return result;
37
+ }
38
+ if (config?.postProcessResponse) {
39
+ result = config.postProcessResponse(result, _queryContext);
40
+ }
41
+ const camelizeRow = (row)=>Object.fromEntries(Object.entries(row).map(([key, value])=>[
42
+ camelize(key, true),
43
+ value
44
+ ]));
45
+ if (Array.isArray(result)) {
46
+ return result.map(camelizeRow);
47
+ }
48
+ return camelizeRow(result);
49
+ }
50
+ };
51
+ const { namespaceId, usePubSub, runMigrations } = {
52
+ namespaceId: DEFAULT_NAMESPACE_ID,
53
+ usePubSub: true,
54
+ runMigrations: true,
55
+ ...options
56
+ };
18
57
  this.namespaceId = namespaceId;
19
58
  this.usePubSub = usePubSub;
59
+ this.runMigrations = runMigrations;
60
+ }
61
+ async initialize() {
62
+ if (this.initialized) {
63
+ return;
64
+ }
65
+ if (this.runMigrations) {
66
+ await migrate(this.config, DEFAULT_SCHEMA);
67
+ }
68
+ this.initialized = true;
20
69
  }
21
70
  async subscribe(callback) {
71
+ if (!this.initialized) {
72
+ throw new Error("Backend not initialized");
73
+ }
22
74
  if (!this.usePubSub) {
23
75
  return;
24
76
  }
@@ -28,53 +80,26 @@ const DEFAULT_PAGINATION_PAGE_SIZE = 100;
28
80
  this.pubsub.listenEvent(DEFAULT_LISTEN_CHANNEL, callback);
29
81
  }
30
82
  async publish(payload) {
83
+ if (!this.initialized) {
84
+ throw new Error("Backend not initialized");
85
+ }
31
86
  if (!this.usePubSub) {
32
87
  return;
33
88
  }
34
89
  await this.knex.raw(payload ? `NOTIFY ${DEFAULT_LISTEN_CHANNEL}, '${payload}'` : `NOTIFY ${DEFAULT_LISTEN_CHANNEL}`);
35
90
  }
36
- /**
37
- * Create and initialize a new BackendPostgres instance. This will
38
- * automatically run migrations on startup unless `runMigrations` is set to
39
- * false.
40
- */ static async connect(dbConf, options) {
41
- const postProcessResponse = (result, _queryContext)=>{
42
- if (result === null || result === undefined) {
43
- return result;
44
- }
45
- if (dbConf?.postProcessResponse) {
46
- result = dbConf.postProcessResponse(result, _queryContext);
47
- }
48
- const camelizeRow = (row)=>Object.fromEntries(Object.entries(row).map(([key, value])=>[
49
- camelize(key, true),
50
- value
51
- ]));
52
- if (Array.isArray(result)) {
53
- return result.map(camelizeRow);
54
- }
55
- return camelizeRow(result);
56
- };
57
- const { namespaceId, runMigrations, usePubSub } = {
58
- namespaceId: DEFAULT_NAMESPACE_ID,
59
- runMigrations: true,
60
- usePubSub: true,
61
- ...options
62
- };
63
- const knexInstance = knex({
64
- ...dbConf,
65
- postProcessResponse
66
- });
67
- if (runMigrations) {
68
- await migrate(knexInstance, DEFAULT_SCHEMA);
69
- }
70
- return new BackendPostgres(knexInstance, namespaceId, usePubSub);
71
- }
72
91
  async stop() {
92
+ if (!this.initialized) {
93
+ return;
94
+ }
73
95
  await this.pubsub?.destroy();
74
96
  this.pubsub = null;
75
97
  await this.knex.destroy();
76
98
  }
77
99
  async createWorkflowRun(params) {
100
+ if (!this.initialized) {
101
+ throw new Error("Backend not initialized");
102
+ }
78
103
  const qb = this.knex.withSchema(DEFAULT_SCHEMA).table("workflow_runs").insert({
79
104
  namespace_id: this.namespaceId,
80
105
  id: crypto.randomUUID(),
@@ -93,15 +118,24 @@ const DEFAULT_PAGINATION_PAGE_SIZE = 100;
93
118
  }).returning("*");
94
119
  const workflowRun = await qb;
95
120
  if (!workflowRun[0]) {
121
+ logger.error("Failed to create workflow run: {params}", {
122
+ params
123
+ });
96
124
  throw new Error("Failed to create workflow run");
97
125
  }
98
126
  return workflowRun[0];
99
127
  }
100
128
  async getWorkflowRun(params) {
129
+ if (!this.initialized) {
130
+ throw new Error("Backend not initialized");
131
+ }
101
132
  const workflowRun = await this.knex.withSchema(DEFAULT_SCHEMA).table("workflow_runs").where("namespace_id", this.namespaceId).where("id", params.workflowRunId).select("namespace_id", "id", "workflow_name", "version", "status", "idempotency_key", "config", "context", "input", "output", "error", "attempts", "parent_step_attempt_namespace_id", "parent_step_attempt_id", "worker_id", "available_at", "deadline_at", "started_at", "finished_at", "created_at", "updated_at").first();
102
133
  return workflowRun ?? null;
103
134
  }
104
135
  async listWorkflowRuns(params) {
136
+ if (!this.initialized) {
137
+ throw new Error("Backend not initialized");
138
+ }
105
139
  const limit = params.limit ?? DEFAULT_PAGINATION_PAGE_SIZE;
106
140
  const { after, before } = params;
107
141
  let cursor = null;
@@ -127,6 +161,9 @@ const DEFAULT_PAGINATION_PAGE_SIZE = 100;
127
161
  return qb;
128
162
  }
129
163
  async claimWorkflowRun(params) {
164
+ if (!this.initialized) {
165
+ throw new Error("Backend not initialized");
166
+ }
130
167
  const claimed = await this.knex.with("expired", (qb)=>qb.withSchema(DEFAULT_SCHEMA).table("workflow_runs").update({
131
168
  status: "failed",
132
169
  error: JSON.stringify({
@@ -157,16 +194,25 @@ const DEFAULT_PAGINATION_PAGE_SIZE = 100;
157
194
  return claimed[0] ?? null;
158
195
  }
159
196
  async extendWorkflowRunLease(params) {
197
+ if (!this.initialized) {
198
+ throw new Error("Backend not initialized");
199
+ }
160
200
  const [updated] = await this.knex.withSchema(DEFAULT_SCHEMA).table("workflow_runs").where("namespace_id", this.namespaceId).where("id", params.workflowRunId).where("status", "running").where("worker_id", params.workerId).update({
161
201
  available_at: this.knex.raw(`NOW() + ${params.leaseDurationMs} * INTERVAL '1 millisecond'`),
162
202
  updated_at: this.knex.fn.now()
163
203
  }).returning("*");
164
204
  if (!updated) {
205
+ logger.error("Failed to extend lease for workflow run: {params}", {
206
+ params
207
+ });
165
208
  throw new Error("Failed to extend lease for workflow run");
166
209
  }
167
210
  return updated;
168
211
  }
169
212
  async sleepWorkflowRun(params) {
213
+ if (!this.initialized) {
214
+ throw new Error("Backend not initialized");
215
+ }
170
216
  // 'succeeded' status is deprecated
171
217
  const [updated] = await this.knex.withSchema(DEFAULT_SCHEMA).table("workflow_runs").where("namespace_id", this.namespaceId).where("id", params.workflowRunId).whereNotIn("status", [
172
218
  "succeeded",
@@ -180,11 +226,17 @@ const DEFAULT_PAGINATION_PAGE_SIZE = 100;
180
226
  updated_at: this.knex.fn.now()
181
227
  }).returning("*");
182
228
  if (!updated) {
229
+ logger.error("Failed to sleep workflow run: {params}", {
230
+ params
231
+ });
183
232
  throw new Error("Failed to sleep workflow run");
184
233
  }
185
234
  return updated;
186
235
  }
187
236
  async completeWorkflowRun(params) {
237
+ if (!this.initialized) {
238
+ throw new Error("Backend not initialized");
239
+ }
188
240
  const [updated] = await this.knex.withSchema(DEFAULT_SCHEMA).table("workflow_runs").where("namespace_id", this.namespaceId).where("id", params.workflowRunId).where("status", "running").where("worker_id", params.workerId).update({
189
241
  status: "completed",
190
242
  output: JSON.stringify(params.output),
@@ -195,11 +247,17 @@ const DEFAULT_PAGINATION_PAGE_SIZE = 100;
195
247
  updated_at: this.knex.fn.now()
196
248
  }).returning("*");
197
249
  if (!updated) {
250
+ logger.error("Failed to complete workflow run: {params}", {
251
+ params
252
+ });
198
253
  throw new Error("Failed to complete workflow run");
199
254
  }
200
255
  return updated;
201
256
  }
202
257
  async failWorkflowRun(params) {
258
+ if (!this.initialized) {
259
+ throw new Error("Backend not initialized");
260
+ }
203
261
  const { workflowRunId, error } = params;
204
262
  const { initialIntervalMs, backoffCoefficient, maximumIntervalMs } = DEFAULT_RETRY_POLICY;
205
263
  // this beefy query updates a workflow's status, available_at, and
@@ -220,11 +278,17 @@ const DEFAULT_PAGINATION_PAGE_SIZE = 100;
220
278
  updated_at: this.knex.fn.now()
221
279
  }).returning("*");
222
280
  if (!updated) {
281
+ logger.error("Failed to mark workflow run failed: {params}", {
282
+ params
283
+ });
223
284
  throw new Error("Failed to mark workflow run failed");
224
285
  }
225
286
  return updated;
226
287
  }
227
288
  async cancelWorkflowRun(params) {
289
+ if (!this.initialized) {
290
+ throw new Error("Backend not initialized");
291
+ }
228
292
  const [updated] = await this.knex.withSchema(DEFAULT_SCHEMA).table("workflow_runs").where("namespace_id", this.namespaceId).where("id", params.workflowRunId).whereIn("status", [
229
293
  "pending",
230
294
  "running",
@@ -255,13 +319,23 @@ const DEFAULT_PAGINATION_PAGE_SIZE = 100;
255
319
  "completed",
256
320
  "failed"
257
321
  ].includes(existing.status)) {
322
+ logger.error("Cannot cancel workflow run: {params} with status {status}", {
323
+ params,
324
+ status: existing.status
325
+ });
258
326
  throw new Error(`Cannot cancel workflow run ${params.workflowRunId} with status ${existing.status}`);
259
327
  }
328
+ logger.error("Failed to cancel workflow run: {params}", {
329
+ params
330
+ });
260
331
  throw new Error("Failed to cancel workflow run");
261
332
  }
262
333
  return updated;
263
334
  }
264
335
  async createStepAttempt(params) {
336
+ if (!this.initialized) {
337
+ throw new Error("Backend not initialized");
338
+ }
265
339
  const [stepAttempt] = await this.knex.withSchema(DEFAULT_SCHEMA).table("step_attempts").insert({
266
340
  namespace_id: this.namespaceId,
267
341
  id: crypto.randomUUID(),
@@ -276,15 +350,24 @@ const DEFAULT_PAGINATION_PAGE_SIZE = 100;
276
350
  updated_at: this.knex.fn.now()
277
351
  }).returning("*");
278
352
  if (!stepAttempt) {
353
+ logger.error("Failed to create step attempt: {params}", {
354
+ params
355
+ });
279
356
  throw new Error("Failed to create step attempt");
280
357
  }
281
358
  return stepAttempt;
282
359
  }
283
360
  async getStepAttempt(params) {
361
+ if (!this.initialized) {
362
+ throw new Error("Backend not initialized");
363
+ }
284
364
  const stepAttempt = await this.knex.withSchema(DEFAULT_SCHEMA).table("step_attempts").where("namespace_id", this.namespaceId).where("id", params.stepAttemptId).first();
285
365
  return stepAttempt ?? null;
286
366
  }
287
367
  async listStepAttempts(params) {
368
+ if (!this.initialized) {
369
+ throw new Error("Backend not initialized");
370
+ }
288
371
  const limit = params.limit ?? DEFAULT_PAGINATION_PAGE_SIZE;
289
372
  const { after, before } = params;
290
373
  let cursor = null;
@@ -342,6 +425,9 @@ const DEFAULT_PAGINATION_PAGE_SIZE = 100;
342
425
  };
343
426
  }
344
427
  async completeStepAttempt(params) {
428
+ if (!this.initialized) {
429
+ throw new Error("Backend not initialized");
430
+ }
345
431
  const [updated] = await this.knex.withSchema(DEFAULT_SCHEMA).table("step_attempts as sa").update({
346
432
  status: "completed",
347
433
  output: JSON.stringify(params.output),
@@ -350,11 +436,17 @@ const DEFAULT_PAGINATION_PAGE_SIZE = 100;
350
436
  updated_at: this.knex.fn.now()
351
437
  }).updateFrom(`${DEFAULT_SCHEMA}.workflow_runs as wr`).where("sa.namespace_id", this.namespaceId).where("sa.workflow_run_id", params.workflowRunId).where("sa.id", params.stepAttemptId).where("sa.status", "running").where("wr.namespace_id", this.knex.ref("sa.namespace_id")).where("wr.id", this.knex.ref("sa.workflow_run_id")).where("wr.status", "running").where("wr.worker_id", params.workerId).returning("sa.*");
352
438
  if (!updated) {
439
+ logger.error("Failed to mark step attempt completed: {params}", {
440
+ params
441
+ });
353
442
  throw new Error("Failed to mark step attempt completed");
354
443
  }
355
444
  return updated;
356
445
  }
357
446
  async failStepAttempt(params) {
447
+ if (!this.initialized) {
448
+ throw new Error("Backend not initialized");
449
+ }
358
450
  const [updated] = await this.knex.withSchema(DEFAULT_SCHEMA).table("step_attempts as sa").update({
359
451
  status: "failed",
360
452
  output: null,
@@ -363,6 +455,9 @@ const DEFAULT_PAGINATION_PAGE_SIZE = 100;
363
455
  updated_at: this.knex.fn.now()
364
456
  }).updateFrom(`${DEFAULT_SCHEMA}.workflow_runs as wr`).where("sa.namespace_id", this.namespaceId).where("sa.workflow_run_id", params.workflowRunId).where("sa.id", params.stepAttemptId).where("sa.status", "running").where("wr.namespace_id", this.knex.ref("sa.namespace_id")).where("wr.id", this.knex.ref("sa.workflow_run_id")).where("wr.status", "running").where("wr.worker_id", params.workerId).returning("sa.*");
365
457
  if (!updated) {
458
+ logger.error("Failed to mark step attempt failed: {params}", {
459
+ params
460
+ });
366
461
  throw new Error("Failed to mark step attempt failed");
367
462
  }
368
463
  return updated;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/database/backend.ts"],"sourcesContent":["import { camelize } from \"inflection\";\nimport knex, { type Knex } from \"knex\";\nimport {\n type Backend,\n type CancelWorkflowRunParams,\n type ClaimWorkflowRunParams,\n type CompleteStepAttemptParams,\n type CompleteWorkflowRunParams,\n type CreateStepAttemptParams,\n type CreateWorkflowRunParams,\n DEFAULT_NAMESPACE_ID,\n type ExtendWorkflowRunLeaseParams,\n type FailStepAttemptParams,\n type FailWorkflowRunParams,\n type GetStepAttemptParams,\n type GetWorkflowRunParams,\n type ListStepAttemptsParams,\n type ListWorkflowRunsParams,\n type PaginatedResponse,\n type SleepWorkflowRunParams,\n} from \"../backend\";\nimport { DEFAULT_RETRY_POLICY } from \"../core/retry\";\nimport type { StepAttempt } from \"../core/step\";\nimport type { WorkflowRun } from \"../core/workflow\";\nimport { DEFAULT_SCHEMA, migrate } from \"./base\";\nimport { type OnSubscribed, PostgresPubSub } from \"./pubsub\";\n\nexport const DEFAULT_LISTEN_CHANNEL = \"new_tasks\" as const;\nconst DEFAULT_PAGINATION_PAGE_SIZE = 100 as const;\n\ninterface BackendPostgresOptions {\n namespaceId?: string;\n runMigrations?: boolean;\n\n // default: true\n usePubSub?: boolean;\n}\n\n/**\n * Manages a connection to a Postgres database for workflow operations.\n */\nexport class BackendPostgres implements Backend {\n private knex: Knex;\n private namespaceId: string;\n private usePubSub: boolean;\n private pubsub: PostgresPubSub | null = null;\n\n private constructor(knex: Knex, namespaceId: string, usePubSub: boolean) {\n this.knex = knex;\n this.namespaceId = namespaceId;\n this.usePubSub = usePubSub;\n }\n\n async subscribe(callback: OnSubscribed) {\n if (!this.usePubSub) {\n return;\n }\n\n if (!this.pubsub) {\n this.pubsub = await PostgresPubSub.create(this.knex);\n }\n\n this.pubsub.listenEvent(DEFAULT_LISTEN_CHANNEL, callback);\n }\n\n async publish(payload?: string): Promise<void> {\n if (!this.usePubSub) {\n return;\n }\n\n await this.knex.raw(\n payload\n ? `NOTIFY ${DEFAULT_LISTEN_CHANNEL}, '${payload}'`\n : `NOTIFY ${DEFAULT_LISTEN_CHANNEL}`,\n );\n }\n\n /**\n * Create and initialize a new BackendPostgres instance. This will\n * automatically run migrations on startup unless `runMigrations` is set to\n * false.\n */\n static async connect(\n dbConf: Knex.Config,\n options?: BackendPostgresOptions,\n ): Promise<BackendPostgres> {\n const postProcessResponse: Knex.Config[\"postProcessResponse\"] = (result, _queryContext) => {\n if (result === null || result === undefined) {\n return result;\n }\n\n if (dbConf?.postProcessResponse) {\n result = dbConf.postProcessResponse(result, _queryContext);\n }\n\n const camelizeRow = (row: Record<string, unknown>) =>\n Object.fromEntries(Object.entries(row).map(([key, value]) => [camelize(key, true), value]));\n\n if (Array.isArray(result)) {\n return result.map(camelizeRow);\n }\n\n return camelizeRow(result);\n };\n\n const { namespaceId, runMigrations, usePubSub } = {\n namespaceId: DEFAULT_NAMESPACE_ID,\n runMigrations: true,\n usePubSub: true,\n ...options,\n };\n\n const knexInstance = knex({ ...dbConf, postProcessResponse });\n if (runMigrations) {\n await migrate(knexInstance, DEFAULT_SCHEMA);\n }\n\n return new BackendPostgres(knexInstance, namespaceId, usePubSub);\n }\n\n async stop(): Promise<void> {\n await this.pubsub?.destroy();\n this.pubsub = null;\n await this.knex.destroy();\n }\n\n async createWorkflowRun(params: CreateWorkflowRunParams): Promise<WorkflowRun> {\n const qb = this.knex\n .withSchema(DEFAULT_SCHEMA)\n .table(\"workflow_runs\")\n .insert({\n namespace_id: this.namespaceId,\n id: crypto.randomUUID(),\n workflow_name: params.workflowName,\n version: params.version,\n status: \"pending\",\n idempotency_key: params.idempotencyKey,\n config: params.config,\n context: params.context,\n input: params.input,\n attempts: 0,\n available_at: params.availableAt ?? this.knex.fn.now(),\n deadline_at: params.deadlineAt,\n created_at: this.knex.fn.now(),\n updated_at: this.knex.fn.now(),\n })\n .returning(\"*\");\n\n const workflowRun = await qb;\n if (!workflowRun[0]) {\n throw new Error(\"Failed to create workflow run\");\n }\n\n return workflowRun[0];\n }\n\n async getWorkflowRun(params: GetWorkflowRunParams): Promise<WorkflowRun | null> {\n const workflowRun = await this.knex\n .withSchema(DEFAULT_SCHEMA)\n .table(\"workflow_runs\")\n .where(\"namespace_id\", this.namespaceId)\n .where(\"id\", params.workflowRunId)\n .select(\n \"namespace_id\",\n \"id\",\n \"workflow_name\",\n \"version\",\n \"status\",\n \"idempotency_key\",\n \"config\",\n \"context\",\n \"input\",\n \"output\",\n \"error\",\n \"attempts\",\n \"parent_step_attempt_namespace_id\",\n \"parent_step_attempt_id\",\n \"worker_id\",\n \"available_at\",\n \"deadline_at\",\n \"started_at\",\n \"finished_at\",\n \"created_at\",\n \"updated_at\",\n )\n .first();\n\n return workflowRun ?? null;\n }\n\n async listWorkflowRuns(params: ListWorkflowRunsParams): Promise<PaginatedResponse<WorkflowRun>> {\n const limit = params.limit ?? DEFAULT_PAGINATION_PAGE_SIZE;\n const { after, before } = params;\n\n let cursor: Cursor | null = null;\n if (after) {\n cursor = decodeCursor(after);\n } else if (before) {\n cursor = decodeCursor(before);\n }\n\n const qb = this.buildListWorkflowRunsWhere(params, cursor);\n const rows = await qb\n .orderBy(\"created_at\", before ? \"desc\" : \"asc\")\n .orderBy(\"id\", before ? \"desc\" : \"asc\")\n .limit(limit + 1);\n\n return this.processPaginationResults(\n rows,\n limit,\n typeof after === \"string\",\n typeof before === \"string\",\n );\n }\n\n private buildListWorkflowRunsWhere(params: ListWorkflowRunsParams, cursor: Cursor | null) {\n const { after } = params;\n const qb = this.knex\n .withSchema(DEFAULT_SCHEMA)\n .table(\"workflow_runs\")\n .where(\"namespace_id\", this.namespaceId);\n\n if (cursor) {\n const operator = after ? \">\" : \"<\";\n return qb.whereRaw(`(\"created_at\", \"id\") ${operator} (?, ?)`, [\n cursor.createdAt.toISOString(),\n cursor.id,\n ]);\n }\n\n return qb;\n }\n\n async claimWorkflowRun(params: ClaimWorkflowRunParams): Promise<WorkflowRun | null> {\n const claimed = await this.knex\n .with(\"expired\", (qb) =>\n qb\n .withSchema(DEFAULT_SCHEMA)\n .table(\"workflow_runs\")\n .update({\n status: \"failed\",\n error: JSON.stringify({ message: \"Workflow run deadline exceeded\" }),\n worker_id: null,\n available_at: null,\n finished_at: this.knex.raw(\"NOW()\"),\n updated_at: this.knex.raw(\"NOW()\"),\n })\n .where(\"namespace_id\", this.namespaceId)\n .whereIn(\"status\", [\"pending\", \"running\", \"sleeping\"])\n .whereNotNull(\"deadline_at\")\n .where(\"deadline_at\", \"<=\", this.knex.raw(\"NOW()\"))\n .returning(\"id\"),\n )\n .with(\"candidate\", (qb) =>\n qb\n .withSchema(DEFAULT_SCHEMA)\n .select(\"id\")\n .from(\"workflow_runs\")\n .where(\"namespace_id\", this.namespaceId)\n .whereIn(\"status\", [\"pending\", \"running\", \"sleeping\"])\n .where(\"available_at\", \"<=\", this.knex.raw(\"NOW()\"))\n .where((qb2) => {\n qb2.whereNull(\"deadline_at\").orWhere(\"deadline_at\", \">\", this.knex.raw(\"NOW()\"));\n })\n .orderByRaw(\"CASE WHEN status = 'pending' THEN 0 ELSE 1 END\")\n .orderBy(\"available_at\", \"asc\")\n .orderBy(\"created_at\", \"asc\")\n .limit(1)\n .forUpdate()\n .skipLocked(),\n )\n .withSchema(DEFAULT_SCHEMA)\n .table(\"workflow_runs as wr\")\n .where(\"wr.namespace_id\", this.namespaceId)\n .where(\"wr.id\", this.knex.ref(\"candidate.id\"))\n .update({\n status: \"running\",\n attempts: this.knex.raw(\"wr.attempts + 1\"),\n worker_id: params.workerId,\n available_at: this.knex.raw(`NOW() + ${params.leaseDurationMs} * INTERVAL '1 millisecond'`),\n started_at: this.knex.raw(\"COALESCE(wr.started_at, NOW())\"),\n updated_at: this.knex.raw(\"NOW()\"),\n })\n .updateFrom(\"candidate\")\n .returning(\"wr.*\");\n\n return claimed[0] ?? null;\n }\n\n async extendWorkflowRunLease(params: ExtendWorkflowRunLeaseParams): Promise<WorkflowRun> {\n const [updated] = await this.knex\n .withSchema(DEFAULT_SCHEMA)\n .table(\"workflow_runs\")\n .where(\"namespace_id\", this.namespaceId)\n .where(\"id\", params.workflowRunId)\n .where(\"status\", \"running\")\n .where(\"worker_id\", params.workerId)\n .update({\n available_at: this.knex.raw(`NOW() + ${params.leaseDurationMs} * INTERVAL '1 millisecond'`),\n updated_at: this.knex.fn.now(),\n })\n .returning(\"*\");\n\n if (!updated) {\n throw new Error(\"Failed to extend lease for workflow run\");\n }\n\n return updated;\n }\n\n async sleepWorkflowRun(params: SleepWorkflowRunParams): Promise<WorkflowRun> {\n // 'succeeded' status is deprecated\n const [updated] = await this.knex\n .withSchema(DEFAULT_SCHEMA)\n .table(\"workflow_runs\")\n .where(\"namespace_id\", this.namespaceId)\n .where(\"id\", params.workflowRunId)\n .whereNotIn(\"status\", [\"succeeded\", \"completed\", \"failed\", \"canceled\"])\n .where(\"worker_id\", params.workerId)\n .update({\n status: \"sleeping\",\n available_at: params.availableAt,\n worker_id: null,\n updated_at: this.knex.fn.now(),\n })\n .returning(\"*\");\n\n if (!updated) {\n throw new Error(\"Failed to sleep workflow run\");\n }\n\n return updated;\n }\n\n async completeWorkflowRun(params: CompleteWorkflowRunParams): Promise<WorkflowRun> {\n const [updated] = await this.knex\n .withSchema(DEFAULT_SCHEMA)\n .table(\"workflow_runs\")\n .where(\"namespace_id\", this.namespaceId)\n .where(\"id\", params.workflowRunId)\n .where(\"status\", \"running\")\n .where(\"worker_id\", params.workerId)\n .update({\n status: \"completed\",\n output: JSON.stringify(params.output),\n error: null,\n worker_id: params.workerId,\n available_at: null,\n finished_at: this.knex.fn.now(),\n updated_at: this.knex.fn.now(),\n })\n .returning(\"*\");\n\n if (!updated) {\n throw new Error(\"Failed to complete workflow run\");\n }\n\n return updated;\n }\n\n async failWorkflowRun(params: FailWorkflowRunParams): Promise<WorkflowRun> {\n const { workflowRunId, error } = params;\n const { initialIntervalMs, backoffCoefficient, maximumIntervalMs } = DEFAULT_RETRY_POLICY;\n\n // this beefy query updates a workflow's status, available_at, and\n // finished_at based on the workflow's deadline and retry policy\n //\n // if the next retry would exceed the deadline, the run is marked as\n // 'failed' and finalized, otherwise, the run is rescheduled with an updated\n // 'available_at' timestamp for the next retry\n const retryIntervalExpr = `LEAST(${initialIntervalMs} * POWER(${backoffCoefficient}, \"attempts\" - 1), ${maximumIntervalMs}) * INTERVAL '1 millisecond'`;\n const deadlineExceededCondition = `\"deadline_at\" IS NOT NULL AND NOW() + (${retryIntervalExpr}) >= \"deadline_at\"`;\n\n const [updated] = await this.knex\n .withSchema(DEFAULT_SCHEMA)\n .table(\"workflow_runs\")\n .where(\"namespace_id\", this.namespaceId)\n .where(\"id\", workflowRunId)\n .where(\"status\", \"running\")\n .where(\"worker_id\", params.workerId)\n .update({\n status: this.knex.raw(\n `CASE WHEN ${deadlineExceededCondition} THEN 'failed' ELSE 'pending' END`,\n ),\n available_at: this.knex.raw(\n `CASE WHEN ${deadlineExceededCondition} THEN NULL ELSE NOW() + (${retryIntervalExpr}) END`,\n ),\n finished_at: this.knex.raw(\n `CASE WHEN ${deadlineExceededCondition} THEN NOW() ELSE NULL END`,\n ),\n error: JSON.stringify(error),\n worker_id: null,\n started_at: null,\n updated_at: this.knex.fn.now(),\n })\n .returning(\"*\");\n\n if (!updated) {\n throw new Error(\"Failed to mark workflow run failed\");\n }\n\n return updated;\n }\n\n async cancelWorkflowRun(params: CancelWorkflowRunParams): Promise<WorkflowRun> {\n const [updated] = await this.knex\n .withSchema(DEFAULT_SCHEMA)\n .table(\"workflow_runs\")\n .where(\"namespace_id\", this.namespaceId)\n .where(\"id\", params.workflowRunId)\n .whereIn(\"status\", [\"pending\", \"running\", \"sleeping\"])\n .update({\n status: \"canceled\",\n worker_id: null,\n available_at: null,\n finished_at: this.knex.fn.now(),\n updated_at: this.knex.fn.now(),\n })\n .returning(\"*\");\n\n if (!updated) {\n // workflow may already be in a terminal state\n const existing = await this.getWorkflowRun({\n workflowRunId: params.workflowRunId,\n });\n if (!existing) {\n throw new Error(`Workflow run ${params.workflowRunId} does not exist`);\n }\n\n // if already canceled, just return it\n if (existing.status === \"canceled\") {\n return existing;\n }\n\n // throw error for completed/failed workflows\n // 'succeeded' status is deprecated\n if ([\"succeeded\", \"completed\", \"failed\"].includes(existing.status)) {\n throw new Error(\n `Cannot cancel workflow run ${params.workflowRunId} with status ${existing.status}`,\n );\n }\n\n throw new Error(\"Failed to cancel workflow run\");\n }\n\n return updated;\n }\n\n async createStepAttempt(params: CreateStepAttemptParams): Promise<StepAttempt> {\n const [stepAttempt] = await this.knex\n .withSchema(DEFAULT_SCHEMA)\n .table(\"step_attempts\")\n .insert({\n namespace_id: this.namespaceId,\n id: crypto.randomUUID(),\n workflow_run_id: params.workflowRunId,\n step_name: params.stepName,\n kind: params.kind,\n status: \"running\",\n config: JSON.stringify(params.config),\n context: JSON.stringify(params.context),\n started_at: this.knex.fn.now(),\n created_at: this.knex.raw(\"date_trunc('milliseconds', NOW())\"),\n updated_at: this.knex.fn.now(),\n })\n .returning(\"*\");\n\n if (!stepAttempt) {\n throw new Error(\"Failed to create step attempt\");\n }\n\n return stepAttempt;\n }\n\n async getStepAttempt(params: GetStepAttemptParams): Promise<StepAttempt | null> {\n const stepAttempt = await this.knex\n .withSchema(DEFAULT_SCHEMA)\n .table(\"step_attempts\")\n .where(\"namespace_id\", this.namespaceId)\n .where(\"id\", params.stepAttemptId)\n .first();\n\n return stepAttempt ?? null;\n }\n\n async listStepAttempts(params: ListStepAttemptsParams): Promise<PaginatedResponse<StepAttempt>> {\n const limit = params.limit ?? DEFAULT_PAGINATION_PAGE_SIZE;\n const { after, before } = params;\n\n let cursor: Cursor | null = null;\n if (after) {\n cursor = decodeCursor(after);\n } else if (before) {\n cursor = decodeCursor(before);\n }\n\n const qb = this.buildListStepAttemptsWhere(params, cursor);\n const rows = await qb\n .orderBy(\"created_at\", before ? \"desc\" : \"asc\")\n .orderBy(\"id\", before ? \"desc\" : \"asc\")\n .limit(limit + 1);\n\n return this.processPaginationResults(\n rows,\n limit,\n typeof after === \"string\",\n typeof before === \"string\",\n );\n }\n\n private buildListStepAttemptsWhere(params: ListStepAttemptsParams, cursor: Cursor | null) {\n const { after } = params;\n const qb = this.knex\n .withSchema(DEFAULT_SCHEMA)\n .table(\"step_attempts\")\n .where(\"namespace_id\", this.namespaceId)\n .where(\"workflow_run_id\", params.workflowRunId);\n\n if (cursor) {\n const operator = after ? \">\" : \"<\";\n return qb.whereRaw(`(\"created_at\", \"id\") ${operator} (?, ?)`, [\n cursor.createdAt.toISOString(),\n cursor.id,\n ]);\n }\n\n return qb;\n }\n\n private processPaginationResults<T extends Cursor>(\n rows: T[],\n limit: number,\n hasAfter: boolean,\n hasBefore: boolean,\n ): PaginatedResponse<T> {\n const data = rows;\n let hasNext = false;\n let hasPrev = false;\n\n if (hasBefore) {\n data.reverse();\n if (data.length > limit) {\n hasPrev = true;\n data.shift();\n }\n hasNext = true;\n } else {\n if (data.length > limit) {\n hasNext = true;\n data.pop();\n }\n if (hasAfter) {\n hasPrev = true;\n }\n }\n\n const lastItem = data.at(-1);\n const nextCursor = hasNext && lastItem ? encodeCursor(lastItem) : null;\n const firstItem = data[0];\n const prevCursor = hasPrev && firstItem ? encodeCursor(firstItem) : null;\n\n return {\n data,\n pagination: {\n next: nextCursor,\n prev: prevCursor,\n },\n };\n }\n\n async completeStepAttempt(params: CompleteStepAttemptParams): Promise<StepAttempt> {\n const [updated] = await this.knex\n .withSchema(DEFAULT_SCHEMA)\n .table(\"step_attempts as sa\")\n .update({\n status: \"completed\",\n output: JSON.stringify(params.output),\n error: null,\n finished_at: this.knex.fn.now(),\n updated_at: this.knex.fn.now(),\n })\n .updateFrom(`${DEFAULT_SCHEMA}.workflow_runs as wr`)\n .where(\"sa.namespace_id\", this.namespaceId)\n .where(\"sa.workflow_run_id\", params.workflowRunId)\n .where(\"sa.id\", params.stepAttemptId)\n .where(\"sa.status\", \"running\")\n .where(\"wr.namespace_id\", this.knex.ref(\"sa.namespace_id\"))\n .where(\"wr.id\", this.knex.ref(\"sa.workflow_run_id\"))\n .where(\"wr.status\", \"running\")\n .where(\"wr.worker_id\", params.workerId)\n .returning(\"sa.*\");\n\n if (!updated) {\n throw new Error(\"Failed to mark step attempt completed\");\n }\n\n return updated;\n }\n\n async failStepAttempt(params: FailStepAttemptParams): Promise<StepAttempt> {\n const [updated] = await this.knex\n .withSchema(DEFAULT_SCHEMA)\n .table(\"step_attempts as sa\")\n .update({\n status: \"failed\",\n output: null,\n error: JSON.stringify(params.error),\n finished_at: this.knex.fn.now(),\n updated_at: this.knex.fn.now(),\n })\n .updateFrom(`${DEFAULT_SCHEMA}.workflow_runs as wr`)\n .where(\"sa.namespace_id\", this.namespaceId)\n .where(\"sa.workflow_run_id\", params.workflowRunId)\n .where(\"sa.id\", params.stepAttemptId)\n .where(\"sa.status\", \"running\")\n .where(\"wr.namespace_id\", this.knex.ref(\"sa.namespace_id\"))\n .where(\"wr.id\", this.knex.ref(\"sa.workflow_run_id\"))\n .where(\"wr.status\", \"running\")\n .where(\"wr.worker_id\", params.workerId)\n .returning(\"sa.*\");\n\n if (!updated) {\n throw new Error(\"Failed to mark step attempt failed\");\n }\n\n return updated;\n }\n}\n\n/**\n * Cursor used for pagination. Requires created_at and id fields. Because JS\n * Date does not natively support microsecond precision dates, created_at should\n * be stored with millisecond precision in paginated tables to avoid issues with\n * cursor comparisons.\n */\ninterface Cursor {\n createdAt: Date;\n id: string;\n}\n\nfunction encodeCursor(item: Cursor): string {\n const encoded = Buffer.from(\n JSON.stringify({ createdAt: item.createdAt.toISOString(), id: item.id }),\n ).toString(\"base64\");\n return encoded;\n}\n\nexport function decodeCursor(cursor: string): Cursor {\n const decoded = Buffer.from(cursor, \"base64\").toString(\"utf8\");\n const parsed = JSON.parse(decoded) as { createdAt: string; id: string };\n return {\n createdAt: new Date(parsed.createdAt),\n id: parsed.id,\n };\n}\n"],"names":["camelize","knex","DEFAULT_NAMESPACE_ID","DEFAULT_RETRY_POLICY","DEFAULT_SCHEMA","migrate","PostgresPubSub","DEFAULT_LISTEN_CHANNEL","DEFAULT_PAGINATION_PAGE_SIZE","BackendPostgres","namespaceId","usePubSub","pubsub","subscribe","callback","create","listenEvent","publish","payload","raw","connect","dbConf","options","postProcessResponse","result","_queryContext","undefined","camelizeRow","row","Object","fromEntries","entries","map","key","value","Array","isArray","runMigrations","knexInstance","stop","destroy","createWorkflowRun","params","qb","withSchema","table","insert","namespace_id","id","crypto","randomUUID","workflow_name","workflowName","version","status","idempotency_key","idempotencyKey","config","context","input","attempts","available_at","availableAt","fn","now","deadline_at","deadlineAt","created_at","updated_at","returning","workflowRun","Error","getWorkflowRun","where","workflowRunId","select","first","listWorkflowRuns","limit","after","before","cursor","decodeCursor","buildListWorkflowRunsWhere","rows","orderBy","processPaginationResults","operator","whereRaw","createdAt","toISOString","claimWorkflowRun","claimed","with","update","error","JSON","stringify","message","worker_id","finished_at","whereIn","whereNotNull","from","qb2","whereNull","orWhere","orderByRaw","forUpdate","skipLocked","ref","workerId","leaseDurationMs","started_at","updateFrom","extendWorkflowRunLease","updated","sleepWorkflowRun","whereNotIn","completeWorkflowRun","output","failWorkflowRun","initialIntervalMs","backoffCoefficient","maximumIntervalMs","retryIntervalExpr","deadlineExceededCondition","cancelWorkflowRun","existing","includes","createStepAttempt","stepAttempt","workflow_run_id","step_name","stepName","kind","getStepAttempt","stepAttemptId","listStepAttempts","buildListStepAttemptsWhere","hasAfter","hasBefore","data","hasNext","hasPrev","reverse","length","shift","pop","lastItem","at","nextCursor","encodeCursor","firstItem","prevCursor","pagination","next","prev","completeStepAttempt","failStepAttempt","item","encoded","Buffer","toString","decoded","parsed","parse","Date"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/database/backend.ts"],"sourcesContent":["import { getLogger } from \"@logtape/logtape\";\nimport { camelize } from \"inflection\";\nimport knex, { type Knex } from \"knex\";\nimport {\n type Backend,\n type CancelWorkflowRunParams,\n type ClaimWorkflowRunParams,\n type CompleteStepAttemptParams,\n type CompleteWorkflowRunParams,\n type CreateStepAttemptParams,\n type CreateWorkflowRunParams,\n DEFAULT_NAMESPACE_ID,\n type ExtendWorkflowRunLeaseParams,\n type FailStepAttemptParams,\n type FailWorkflowRunParams,\n type GetStepAttemptParams,\n type GetWorkflowRunParams,\n type ListStepAttemptsParams,\n type ListWorkflowRunsParams,\n type PaginatedResponse,\n type SleepWorkflowRunParams,\n} from \"../backend\";\nimport { DEFAULT_RETRY_POLICY } from \"../core/retry\";\nimport type { StepAttempt } from \"../core/step\";\nimport type { WorkflowRun } from \"../core/workflow\";\nimport { DEFAULT_SCHEMA, migrate } from \"./base\";\nimport { type OnSubscribed, PostgresPubSub } from \"./pubsub\";\n\nexport const DEFAULT_LISTEN_CHANNEL = \"new_tasks\" as const;\nconst DEFAULT_PAGINATION_PAGE_SIZE = 100 as const;\n\ninterface BackendPostgresOptions {\n namespaceId?: string;\n runMigrations?: boolean;\n\n // default: true\n usePubSub?: boolean;\n}\n\nconst logger = getLogger([\"sonamu\", \"internal\", \"tasks\"]);\n\n/**\n * Manages a connection to a Postgres database for workflow operations.\n */\nexport class BackendPostgres implements Backend {\n private config: Knex.Config;\n private namespaceId: string;\n private usePubSub: boolean;\n private pubsub: PostgresPubSub | null = null;\n private initialized: boolean = false;\n private runMigrations: boolean;\n\n private _knex: Knex | null = null;\n private get knex(): Knex {\n if (!this._knex) {\n this._knex = knex(this.config);\n }\n\n return this._knex;\n }\n\n constructor(config: Knex.Config, options?: BackendPostgresOptions) {\n this.config = {\n ...config,\n postProcessResponse: (result, _queryContext) => {\n if (result === null || result === undefined) {\n return result;\n }\n\n if (config?.postProcessResponse) {\n result = config.postProcessResponse(result, _queryContext);\n }\n\n const camelizeRow = (row: Record<string, unknown>) =>\n Object.fromEntries(\n Object.entries(row).map(([key, value]) => [camelize(key, true), value]),\n );\n\n if (Array.isArray(result)) {\n return result.map(camelizeRow);\n }\n\n return camelizeRow(result);\n },\n };\n\n const { namespaceId, usePubSub, runMigrations } = {\n namespaceId: DEFAULT_NAMESPACE_ID,\n usePubSub: true,\n runMigrations: true,\n ...options,\n };\n\n this.namespaceId = namespaceId;\n this.usePubSub = usePubSub;\n this.runMigrations = runMigrations;\n }\n\n async initialize() {\n if (this.initialized) {\n return;\n }\n\n if (this.runMigrations) {\n await migrate(this.config, DEFAULT_SCHEMA);\n }\n\n this.initialized = true;\n }\n\n async subscribe(callback: OnSubscribed) {\n if (!this.initialized) {\n throw new Error(\"Backend not initialized\");\n }\n\n if (!this.usePubSub) {\n return;\n }\n\n if (!this.pubsub) {\n this.pubsub = await PostgresPubSub.create(this.knex);\n }\n\n this.pubsub.listenEvent(DEFAULT_LISTEN_CHANNEL, callback);\n }\n\n async publish(payload?: string): Promise<void> {\n if (!this.initialized) {\n throw new Error(\"Backend not initialized\");\n }\n\n if (!this.usePubSub) {\n return;\n }\n\n await this.knex.raw(\n payload\n ? `NOTIFY ${DEFAULT_LISTEN_CHANNEL}, '${payload}'`\n : `NOTIFY ${DEFAULT_LISTEN_CHANNEL}`,\n );\n }\n\n async stop(): Promise<void> {\n if (!this.initialized) {\n return;\n }\n\n await this.pubsub?.destroy();\n this.pubsub = null;\n await this.knex.destroy();\n }\n\n async createWorkflowRun(params: CreateWorkflowRunParams): Promise<WorkflowRun> {\n if (!this.initialized) {\n throw new Error(\"Backend not initialized\");\n }\n\n const qb = this.knex\n .withSchema(DEFAULT_SCHEMA)\n .table(\"workflow_runs\")\n .insert({\n namespace_id: this.namespaceId,\n id: crypto.randomUUID(),\n workflow_name: params.workflowName,\n version: params.version,\n status: \"pending\",\n idempotency_key: params.idempotencyKey,\n config: params.config,\n context: params.context,\n input: params.input,\n attempts: 0,\n available_at: params.availableAt ?? this.knex.fn.now(),\n deadline_at: params.deadlineAt,\n created_at: this.knex.fn.now(),\n updated_at: this.knex.fn.now(),\n })\n .returning(\"*\");\n\n const workflowRun = await qb;\n if (!workflowRun[0]) {\n logger.error(\"Failed to create workflow run: {params}\", { params });\n throw new Error(\"Failed to create workflow run\");\n }\n\n return workflowRun[0];\n }\n\n async getWorkflowRun(params: GetWorkflowRunParams): Promise<WorkflowRun | null> {\n if (!this.initialized) {\n throw new Error(\"Backend not initialized\");\n }\n\n const workflowRun = await this.knex\n .withSchema(DEFAULT_SCHEMA)\n .table(\"workflow_runs\")\n .where(\"namespace_id\", this.namespaceId)\n .where(\"id\", params.workflowRunId)\n .select(\n \"namespace_id\",\n \"id\",\n \"workflow_name\",\n \"version\",\n \"status\",\n \"idempotency_key\",\n \"config\",\n \"context\",\n \"input\",\n \"output\",\n \"error\",\n \"attempts\",\n \"parent_step_attempt_namespace_id\",\n \"parent_step_attempt_id\",\n \"worker_id\",\n \"available_at\",\n \"deadline_at\",\n \"started_at\",\n \"finished_at\",\n \"created_at\",\n \"updated_at\",\n )\n .first();\n\n return workflowRun ?? null;\n }\n\n async listWorkflowRuns(params: ListWorkflowRunsParams): Promise<PaginatedResponse<WorkflowRun>> {\n if (!this.initialized) {\n throw new Error(\"Backend not initialized\");\n }\n\n const limit = params.limit ?? DEFAULT_PAGINATION_PAGE_SIZE;\n const { after, before } = params;\n\n let cursor: Cursor | null = null;\n if (after) {\n cursor = decodeCursor(after);\n } else if (before) {\n cursor = decodeCursor(before);\n }\n\n const qb = this.buildListWorkflowRunsWhere(params, cursor);\n const rows = await qb\n .orderBy(\"created_at\", before ? \"desc\" : \"asc\")\n .orderBy(\"id\", before ? \"desc\" : \"asc\")\n .limit(limit + 1);\n\n return this.processPaginationResults(\n rows,\n limit,\n typeof after === \"string\",\n typeof before === \"string\",\n );\n }\n\n private buildListWorkflowRunsWhere(params: ListWorkflowRunsParams, cursor: Cursor | null) {\n const { after } = params;\n const qb = this.knex\n .withSchema(DEFAULT_SCHEMA)\n .table(\"workflow_runs\")\n .where(\"namespace_id\", this.namespaceId);\n\n if (cursor) {\n const operator = after ? \">\" : \"<\";\n return qb.whereRaw(`(\"created_at\", \"id\") ${operator} (?, ?)`, [\n cursor.createdAt.toISOString(),\n cursor.id,\n ]);\n }\n\n return qb;\n }\n\n async claimWorkflowRun(params: ClaimWorkflowRunParams): Promise<WorkflowRun | null> {\n if (!this.initialized) {\n throw new Error(\"Backend not initialized\");\n }\n\n const claimed = await this.knex\n .with(\"expired\", (qb) =>\n qb\n .withSchema(DEFAULT_SCHEMA)\n .table(\"workflow_runs\")\n .update({\n status: \"failed\",\n error: JSON.stringify({ message: \"Workflow run deadline exceeded\" }),\n worker_id: null,\n available_at: null,\n finished_at: this.knex.raw(\"NOW()\"),\n updated_at: this.knex.raw(\"NOW()\"),\n })\n .where(\"namespace_id\", this.namespaceId)\n .whereIn(\"status\", [\"pending\", \"running\", \"sleeping\"])\n .whereNotNull(\"deadline_at\")\n .where(\"deadline_at\", \"<=\", this.knex.raw(\"NOW()\"))\n .returning(\"id\"),\n )\n .with(\"candidate\", (qb) =>\n qb\n .withSchema(DEFAULT_SCHEMA)\n .select(\"id\")\n .from(\"workflow_runs\")\n .where(\"namespace_id\", this.namespaceId)\n .whereIn(\"status\", [\"pending\", \"running\", \"sleeping\"])\n .where(\"available_at\", \"<=\", this.knex.raw(\"NOW()\"))\n .where((qb2) => {\n qb2.whereNull(\"deadline_at\").orWhere(\"deadline_at\", \">\", this.knex.raw(\"NOW()\"));\n })\n .orderByRaw(\"CASE WHEN status = 'pending' THEN 0 ELSE 1 END\")\n .orderBy(\"available_at\", \"asc\")\n .orderBy(\"created_at\", \"asc\")\n .limit(1)\n .forUpdate()\n .skipLocked(),\n )\n .withSchema(DEFAULT_SCHEMA)\n .table(\"workflow_runs as wr\")\n .where(\"wr.namespace_id\", this.namespaceId)\n .where(\"wr.id\", this.knex.ref(\"candidate.id\"))\n .update({\n status: \"running\",\n attempts: this.knex.raw(\"wr.attempts + 1\"),\n worker_id: params.workerId,\n available_at: this.knex.raw(`NOW() + ${params.leaseDurationMs} * INTERVAL '1 millisecond'`),\n started_at: this.knex.raw(\"COALESCE(wr.started_at, NOW())\"),\n updated_at: this.knex.raw(\"NOW()\"),\n })\n .updateFrom(\"candidate\")\n .returning(\"wr.*\");\n\n return claimed[0] ?? null;\n }\n\n async extendWorkflowRunLease(params: ExtendWorkflowRunLeaseParams): Promise<WorkflowRun> {\n if (!this.initialized) {\n throw new Error(\"Backend not initialized\");\n }\n\n const [updated] = await this.knex\n .withSchema(DEFAULT_SCHEMA)\n .table(\"workflow_runs\")\n .where(\"namespace_id\", this.namespaceId)\n .where(\"id\", params.workflowRunId)\n .where(\"status\", \"running\")\n .where(\"worker_id\", params.workerId)\n .update({\n available_at: this.knex.raw(`NOW() + ${params.leaseDurationMs} * INTERVAL '1 millisecond'`),\n updated_at: this.knex.fn.now(),\n })\n .returning(\"*\");\n\n if (!updated) {\n logger.error(\"Failed to extend lease for workflow run: {params}\", { params });\n throw new Error(\"Failed to extend lease for workflow run\");\n }\n\n return updated;\n }\n\n async sleepWorkflowRun(params: SleepWorkflowRunParams): Promise<WorkflowRun> {\n if (!this.initialized) {\n throw new Error(\"Backend not initialized\");\n }\n\n // 'succeeded' status is deprecated\n const [updated] = await this.knex\n .withSchema(DEFAULT_SCHEMA)\n .table(\"workflow_runs\")\n .where(\"namespace_id\", this.namespaceId)\n .where(\"id\", params.workflowRunId)\n .whereNotIn(\"status\", [\"succeeded\", \"completed\", \"failed\", \"canceled\"])\n .where(\"worker_id\", params.workerId)\n .update({\n status: \"sleeping\",\n available_at: params.availableAt,\n worker_id: null,\n updated_at: this.knex.fn.now(),\n })\n .returning(\"*\");\n\n if (!updated) {\n logger.error(\"Failed to sleep workflow run: {params}\", { params });\n throw new Error(\"Failed to sleep workflow run\");\n }\n\n return updated;\n }\n\n async completeWorkflowRun(params: CompleteWorkflowRunParams): Promise<WorkflowRun> {\n if (!this.initialized) {\n throw new Error(\"Backend not initialized\");\n }\n\n const [updated] = await this.knex\n .withSchema(DEFAULT_SCHEMA)\n .table(\"workflow_runs\")\n .where(\"namespace_id\", this.namespaceId)\n .where(\"id\", params.workflowRunId)\n .where(\"status\", \"running\")\n .where(\"worker_id\", params.workerId)\n .update({\n status: \"completed\",\n output: JSON.stringify(params.output),\n error: null,\n worker_id: params.workerId,\n available_at: null,\n finished_at: this.knex.fn.now(),\n updated_at: this.knex.fn.now(),\n })\n .returning(\"*\");\n\n if (!updated) {\n logger.error(\"Failed to complete workflow run: {params}\", { params });\n throw new Error(\"Failed to complete workflow run\");\n }\n\n return updated;\n }\n\n async failWorkflowRun(params: FailWorkflowRunParams): Promise<WorkflowRun> {\n if (!this.initialized) {\n throw new Error(\"Backend not initialized\");\n }\n\n const { workflowRunId, error } = params;\n const { initialIntervalMs, backoffCoefficient, maximumIntervalMs } = DEFAULT_RETRY_POLICY;\n\n // this beefy query updates a workflow's status, available_at, and\n // finished_at based on the workflow's deadline and retry policy\n //\n // if the next retry would exceed the deadline, the run is marked as\n // 'failed' and finalized, otherwise, the run is rescheduled with an updated\n // 'available_at' timestamp for the next retry\n const retryIntervalExpr = `LEAST(${initialIntervalMs} * POWER(${backoffCoefficient}, \"attempts\" - 1), ${maximumIntervalMs}) * INTERVAL '1 millisecond'`;\n const deadlineExceededCondition = `\"deadline_at\" IS NOT NULL AND NOW() + (${retryIntervalExpr}) >= \"deadline_at\"`;\n\n const [updated] = await this.knex\n .withSchema(DEFAULT_SCHEMA)\n .table(\"workflow_runs\")\n .where(\"namespace_id\", this.namespaceId)\n .where(\"id\", workflowRunId)\n .where(\"status\", \"running\")\n .where(\"worker_id\", params.workerId)\n .update({\n status: this.knex.raw(\n `CASE WHEN ${deadlineExceededCondition} THEN 'failed' ELSE 'pending' END`,\n ),\n available_at: this.knex.raw(\n `CASE WHEN ${deadlineExceededCondition} THEN NULL ELSE NOW() + (${retryIntervalExpr}) END`,\n ),\n finished_at: this.knex.raw(\n `CASE WHEN ${deadlineExceededCondition} THEN NOW() ELSE NULL END`,\n ),\n error: JSON.stringify(error),\n worker_id: null,\n started_at: null,\n updated_at: this.knex.fn.now(),\n })\n .returning(\"*\");\n\n if (!updated) {\n logger.error(\"Failed to mark workflow run failed: {params}\", { params });\n throw new Error(\"Failed to mark workflow run failed\");\n }\n\n return updated;\n }\n\n async cancelWorkflowRun(params: CancelWorkflowRunParams): Promise<WorkflowRun> {\n if (!this.initialized) {\n throw new Error(\"Backend not initialized\");\n }\n\n const [updated] = await this.knex\n .withSchema(DEFAULT_SCHEMA)\n .table(\"workflow_runs\")\n .where(\"namespace_id\", this.namespaceId)\n .where(\"id\", params.workflowRunId)\n .whereIn(\"status\", [\"pending\", \"running\", \"sleeping\"])\n .update({\n status: \"canceled\",\n worker_id: null,\n available_at: null,\n finished_at: this.knex.fn.now(),\n updated_at: this.knex.fn.now(),\n })\n .returning(\"*\");\n\n if (!updated) {\n // workflow may already be in a terminal state\n const existing = await this.getWorkflowRun({\n workflowRunId: params.workflowRunId,\n });\n if (!existing) {\n throw new Error(`Workflow run ${params.workflowRunId} does not exist`);\n }\n\n // if already canceled, just return it\n if (existing.status === \"canceled\") {\n return existing;\n }\n\n // throw error for completed/failed workflows\n // 'succeeded' status is deprecated\n if ([\"succeeded\", \"completed\", \"failed\"].includes(existing.status)) {\n logger.error(\"Cannot cancel workflow run: {params} with status {status}\", {\n params,\n status: existing.status,\n });\n throw new Error(\n `Cannot cancel workflow run ${params.workflowRunId} with status ${existing.status}`,\n );\n }\n\n logger.error(\"Failed to cancel workflow run: {params}\", { params });\n throw new Error(\"Failed to cancel workflow run\");\n }\n\n return updated;\n }\n\n async createStepAttempt(params: CreateStepAttemptParams): Promise<StepAttempt> {\n if (!this.initialized) {\n throw new Error(\"Backend not initialized\");\n }\n\n const [stepAttempt] = await this.knex\n .withSchema(DEFAULT_SCHEMA)\n .table(\"step_attempts\")\n .insert({\n namespace_id: this.namespaceId,\n id: crypto.randomUUID(),\n workflow_run_id: params.workflowRunId,\n step_name: params.stepName,\n kind: params.kind,\n status: \"running\",\n config: JSON.stringify(params.config),\n context: JSON.stringify(params.context),\n started_at: this.knex.fn.now(),\n created_at: this.knex.raw(\"date_trunc('milliseconds', NOW())\"),\n updated_at: this.knex.fn.now(),\n })\n .returning(\"*\");\n\n if (!stepAttempt) {\n logger.error(\"Failed to create step attempt: {params}\", { params });\n throw new Error(\"Failed to create step attempt\");\n }\n\n return stepAttempt;\n }\n\n async getStepAttempt(params: GetStepAttemptParams): Promise<StepAttempt | null> {\n if (!this.initialized) {\n throw new Error(\"Backend not initialized\");\n }\n\n const stepAttempt = await this.knex\n .withSchema(DEFAULT_SCHEMA)\n .table(\"step_attempts\")\n .where(\"namespace_id\", this.namespaceId)\n .where(\"id\", params.stepAttemptId)\n .first();\n\n return stepAttempt ?? null;\n }\n\n async listStepAttempts(params: ListStepAttemptsParams): Promise<PaginatedResponse<StepAttempt>> {\n if (!this.initialized) {\n throw new Error(\"Backend not initialized\");\n }\n\n const limit = params.limit ?? DEFAULT_PAGINATION_PAGE_SIZE;\n const { after, before } = params;\n\n let cursor: Cursor | null = null;\n if (after) {\n cursor = decodeCursor(after);\n } else if (before) {\n cursor = decodeCursor(before);\n }\n\n const qb = this.buildListStepAttemptsWhere(params, cursor);\n const rows = await qb\n .orderBy(\"created_at\", before ? \"desc\" : \"asc\")\n .orderBy(\"id\", before ? \"desc\" : \"asc\")\n .limit(limit + 1);\n\n return this.processPaginationResults(\n rows,\n limit,\n typeof after === \"string\",\n typeof before === \"string\",\n );\n }\n\n private buildListStepAttemptsWhere(params: ListStepAttemptsParams, cursor: Cursor | null) {\n const { after } = params;\n const qb = this.knex\n .withSchema(DEFAULT_SCHEMA)\n .table(\"step_attempts\")\n .where(\"namespace_id\", this.namespaceId)\n .where(\"workflow_run_id\", params.workflowRunId);\n\n if (cursor) {\n const operator = after ? \">\" : \"<\";\n return qb.whereRaw(`(\"created_at\", \"id\") ${operator} (?, ?)`, [\n cursor.createdAt.toISOString(),\n cursor.id,\n ]);\n }\n\n return qb;\n }\n\n private processPaginationResults<T extends Cursor>(\n rows: T[],\n limit: number,\n hasAfter: boolean,\n hasBefore: boolean,\n ): PaginatedResponse<T> {\n const data = rows;\n let hasNext = false;\n let hasPrev = false;\n\n if (hasBefore) {\n data.reverse();\n if (data.length > limit) {\n hasPrev = true;\n data.shift();\n }\n hasNext = true;\n } else {\n if (data.length > limit) {\n hasNext = true;\n data.pop();\n }\n if (hasAfter) {\n hasPrev = true;\n }\n }\n\n const lastItem = data.at(-1);\n const nextCursor = hasNext && lastItem ? encodeCursor(lastItem) : null;\n const firstItem = data[0];\n const prevCursor = hasPrev && firstItem ? encodeCursor(firstItem) : null;\n\n return {\n data,\n pagination: {\n next: nextCursor,\n prev: prevCursor,\n },\n };\n }\n\n async completeStepAttempt(params: CompleteStepAttemptParams): Promise<StepAttempt> {\n if (!this.initialized) {\n throw new Error(\"Backend not initialized\");\n }\n\n const [updated] = await this.knex\n .withSchema(DEFAULT_SCHEMA)\n .table(\"step_attempts as sa\")\n .update({\n status: \"completed\",\n output: JSON.stringify(params.output),\n error: null,\n finished_at: this.knex.fn.now(),\n updated_at: this.knex.fn.now(),\n })\n .updateFrom(`${DEFAULT_SCHEMA}.workflow_runs as wr`)\n .where(\"sa.namespace_id\", this.namespaceId)\n .where(\"sa.workflow_run_id\", params.workflowRunId)\n .where(\"sa.id\", params.stepAttemptId)\n .where(\"sa.status\", \"running\")\n .where(\"wr.namespace_id\", this.knex.ref(\"sa.namespace_id\"))\n .where(\"wr.id\", this.knex.ref(\"sa.workflow_run_id\"))\n .where(\"wr.status\", \"running\")\n .where(\"wr.worker_id\", params.workerId)\n .returning(\"sa.*\");\n\n if (!updated) {\n logger.error(\"Failed to mark step attempt completed: {params}\", { params });\n throw new Error(\"Failed to mark step attempt completed\");\n }\n\n return updated;\n }\n\n async failStepAttempt(params: FailStepAttemptParams): Promise<StepAttempt> {\n if (!this.initialized) {\n throw new Error(\"Backend not initialized\");\n }\n\n const [updated] = await this.knex\n .withSchema(DEFAULT_SCHEMA)\n .table(\"step_attempts as sa\")\n .update({\n status: \"failed\",\n output: null,\n error: JSON.stringify(params.error),\n finished_at: this.knex.fn.now(),\n updated_at: this.knex.fn.now(),\n })\n .updateFrom(`${DEFAULT_SCHEMA}.workflow_runs as wr`)\n .where(\"sa.namespace_id\", this.namespaceId)\n .where(\"sa.workflow_run_id\", params.workflowRunId)\n .where(\"sa.id\", params.stepAttemptId)\n .where(\"sa.status\", \"running\")\n .where(\"wr.namespace_id\", this.knex.ref(\"sa.namespace_id\"))\n .where(\"wr.id\", this.knex.ref(\"sa.workflow_run_id\"))\n .where(\"wr.status\", \"running\")\n .where(\"wr.worker_id\", params.workerId)\n .returning(\"sa.*\");\n\n if (!updated) {\n logger.error(\"Failed to mark step attempt failed: {params}\", { params });\n throw new Error(\"Failed to mark step attempt failed\");\n }\n\n return updated;\n }\n}\n\n/**\n * Cursor used for pagination. Requires created_at and id fields. Because JS\n * Date does not natively support microsecond precision dates, created_at should\n * be stored with millisecond precision in paginated tables to avoid issues with\n * cursor comparisons.\n */\ninterface Cursor {\n createdAt: Date;\n id: string;\n}\n\nfunction encodeCursor(item: Cursor): string {\n const encoded = Buffer.from(\n JSON.stringify({ createdAt: item.createdAt.toISOString(), id: item.id }),\n ).toString(\"base64\");\n return encoded;\n}\n\nexport function decodeCursor(cursor: string): Cursor {\n const decoded = Buffer.from(cursor, \"base64\").toString(\"utf8\");\n const parsed = JSON.parse(decoded) as { createdAt: string; id: string };\n return {\n createdAt: new Date(parsed.createdAt),\n id: parsed.id,\n };\n}\n"],"names":["getLogger","camelize","knex","DEFAULT_NAMESPACE_ID","DEFAULT_RETRY_POLICY","DEFAULT_SCHEMA","migrate","PostgresPubSub","DEFAULT_LISTEN_CHANNEL","DEFAULT_PAGINATION_PAGE_SIZE","logger","BackendPostgres","config","namespaceId","usePubSub","pubsub","initialized","runMigrations","_knex","options","postProcessResponse","result","_queryContext","undefined","camelizeRow","row","Object","fromEntries","entries","map","key","value","Array","isArray","initialize","subscribe","callback","Error","create","listenEvent","publish","payload","raw","stop","destroy","createWorkflowRun","params","qb","withSchema","table","insert","namespace_id","id","crypto","randomUUID","workflow_name","workflowName","version","status","idempotency_key","idempotencyKey","context","input","attempts","available_at","availableAt","fn","now","deadline_at","deadlineAt","created_at","updated_at","returning","workflowRun","error","getWorkflowRun","where","workflowRunId","select","first","listWorkflowRuns","limit","after","before","cursor","decodeCursor","buildListWorkflowRunsWhere","rows","orderBy","processPaginationResults","operator","whereRaw","createdAt","toISOString","claimWorkflowRun","claimed","with","update","JSON","stringify","message","worker_id","finished_at","whereIn","whereNotNull","from","qb2","whereNull","orWhere","orderByRaw","forUpdate","skipLocked","ref","workerId","leaseDurationMs","started_at","updateFrom","extendWorkflowRunLease","updated","sleepWorkflowRun","whereNotIn","completeWorkflowRun","output","failWorkflowRun","initialIntervalMs","backoffCoefficient","maximumIntervalMs","retryIntervalExpr","deadlineExceededCondition","cancelWorkflowRun","existing","includes","createStepAttempt","stepAttempt","workflow_run_id","step_name","stepName","kind","getStepAttempt","stepAttemptId","listStepAttempts","buildListStepAttemptsWhere","hasAfter","hasBefore","data","hasNext","hasPrev","reverse","length","shift","pop","lastItem","at","nextCursor","encodeCursor","firstItem","prevCursor","pagination","next","prev","completeStepAttempt","failStepAttempt","item","encoded","Buffer","toString","decoded","parsed","parse","Date"],"mappings":"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"}
@@ -4,10 +4,12 @@ import { BackendPostgres } from "./backend.js";
4
4
  import { testBackend } from "./backend.testsuite.js";
5
5
  testBackend({
6
6
  setup: async ()=>{
7
- return await BackendPostgres.connect(KNEX_GLOBAL_CONFIG, {
7
+ const backend = new BackendPostgres(KNEX_GLOBAL_CONFIG, {
8
8
  namespaceId: randomUUID(),
9
9
  runMigrations: false
10
10
  });
11
+ await backend.initialize();
12
+ return backend;
11
13
  },
12
14
  teardown: async (backend)=>{
13
15
  await backend.stop();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/database/backend.test.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { KNEX_GLOBAL_CONFIG } from \"../testing/connection\";\nimport { BackendPostgres } from \"./backend\";\nimport { testBackend } from \"./backend.testsuite\";\n\ntestBackend({\n setup: async () => {\n return await BackendPostgres.connect(KNEX_GLOBAL_CONFIG, {\n namespaceId: randomUUID(),\n runMigrations: false,\n });\n },\n teardown: async (backend) => {\n await (backend as BackendPostgres).stop();\n },\n});\n"],"names":["randomUUID","KNEX_GLOBAL_CONFIG","BackendPostgres","testBackend","setup","connect","namespaceId","runMigrations","teardown","backend","stop"],"mappings":"AAAA,SAASA,UAAU,QAAQ,cAAc;AACzC,SAASC,kBAAkB,QAAQ,2BAAwB;AAC3D,SAASC,eAAe,QAAQ,eAAY;AAC5C,SAASC,WAAW,QAAQ,yBAAsB;AAElDA,YAAY;IACVC,OAAO;QACL,OAAO,MAAMF,gBAAgBG,OAAO,CAACJ,oBAAoB;YACvDK,aAAaN;YACbO,eAAe;QACjB;IACF;IACAC,UAAU,OAAOC;QACf,MAAM,AAACA,QAA4BC,IAAI;IACzC;AACF"}
1
+ {"version":3,"sources":["../../src/database/backend.test.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { KNEX_GLOBAL_CONFIG } from \"../testing/connection\";\nimport { BackendPostgres } from \"./backend\";\nimport { testBackend } from \"./backend.testsuite\";\n\ntestBackend({\n setup: async () => {\n const backend = new BackendPostgres(KNEX_GLOBAL_CONFIG, {\n namespaceId: randomUUID(),\n runMigrations: false,\n });\n await backend.initialize();\n return backend;\n },\n teardown: async (backend) => {\n await (backend as BackendPostgres).stop();\n },\n});\n"],"names":["randomUUID","KNEX_GLOBAL_CONFIG","BackendPostgres","testBackend","setup","backend","namespaceId","runMigrations","initialize","teardown","stop"],"mappings":"AAAA,SAASA,UAAU,QAAQ,cAAc;AACzC,SAASC,kBAAkB,QAAQ,2BAAwB;AAC3D,SAASC,eAAe,QAAQ,eAAY;AAC5C,SAASC,WAAW,QAAQ,yBAAsB;AAElDA,YAAY;IACVC,OAAO;QACL,MAAMC,UAAU,IAAIH,gBAAgBD,oBAAoB;YACtDK,aAAaN;YACbO,eAAe;QACjB;QACA,MAAMF,QAAQG,UAAU;QACxB,OAAOH;IACT;IACAI,UAAU,OAAOJ;QACf,MAAM,AAACA,QAA4BK,IAAI;IACzC;AACF"}
@@ -1,10 +1,10 @@
1
- import type { Knex } from "knex";
1
+ import { type Knex } from "knex";
2
2
  export declare const DEFAULT_SCHEMA = "sonamu_tasks";
3
3
  /**
4
4
  * migrate applies pending migrations to the database. Does nothing if the
5
5
  * database is already up to date.
6
6
  */
7
- export declare function migrate(knex: Knex, schema: string): Promise<void>;
7
+ export declare function migrate(config: Knex.Config, schema: string): Promise<void>;
8
8
  /**
9
9
  * dropSchema drops the specified schema from the database.
10
10
  */
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/database/base.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAEjC,eAAO,MAAM,cAAc,iBAAiB,CAAC;AAE7C;;;GAGG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,iBAMvD;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,iBAE1D"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/database/base.ts"],"names":[],"mappings":"AACA,OAAa,EAAE,KAAK,IAAI,EAAE,MAAM,MAAM,CAAC;AAEvC,eAAO,MAAM,cAAc,iBAAiB,CAAC;AAE7C;;;GAGG;AACH,wBAAsB,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,iBAWhE;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,iBAE1D"}
@@ -1,14 +1,26 @@
1
1
  import path from "node:path";
2
+ import knex from "knex";
2
3
  export const DEFAULT_SCHEMA = "sonamu_tasks";
3
4
  /**
4
5
  * migrate applies pending migrations to the database. Does nothing if the
5
6
  * database is already up to date.
6
- */ export async function migrate(knex, schema) {
7
- await knex.schema.createSchemaIfNotExists(schema);
8
- await knex.migrate.latest({
9
- directory: path.join(import.meta.dirname, "migrations"),
10
- schemaName: schema
7
+ */ export async function migrate(config, schema) {
8
+ const instance = knex({
9
+ ...config,
10
+ pool: {
11
+ min: 1,
12
+ max: 1
13
+ }
11
14
  });
15
+ try {
16
+ await instance.schema.createSchemaIfNotExists(schema);
17
+ await instance.migrate.latest({
18
+ directory: path.join(import.meta.dirname, "migrations"),
19
+ schemaName: schema
20
+ });
21
+ } finally{
22
+ await instance.destroy();
23
+ }
12
24
  }
13
25
  /**
14
26
  * dropSchema drops the specified schema from the database.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/database/base.ts"],"sourcesContent":["import path from \"node:path\";\nimport type { Knex } from \"knex\";\n\nexport const DEFAULT_SCHEMA = \"sonamu_tasks\";\n\n/**\n * migrate applies pending migrations to the database. Does nothing if the\n * database is already up to date.\n */\nexport async function migrate(knex: Knex, schema: string) {\n await knex.schema.createSchemaIfNotExists(schema);\n await knex.migrate.latest({\n directory: path.join(import.meta.dirname, \"migrations\"),\n schemaName: schema,\n });\n}\n\n/**\n * dropSchema drops the specified schema from the database.\n */\nexport async function dropSchema(knex: Knex, schema: string) {\n await knex.schema.dropSchemaIfExists(schema, true);\n}\n"],"names":["path","DEFAULT_SCHEMA","migrate","knex","schema","createSchemaIfNotExists","latest","directory","join","dirname","schemaName","dropSchema","dropSchemaIfExists"],"mappings":"AAAA,OAAOA,UAAU,YAAY;AAG7B,OAAO,MAAMC,iBAAiB,eAAe;AAE7C;;;CAGC,GACD,OAAO,eAAeC,QAAQC,IAAU,EAAEC,MAAc;IACtD,MAAMD,KAAKC,MAAM,CAACC,uBAAuB,CAACD;IAC1C,MAAMD,KAAKD,OAAO,CAACI,MAAM,CAAC;QACxBC,WAAWP,KAAKQ,IAAI,CAAC,YAAYC,OAAO,EAAE;QAC1CC,YAAYN;IACd;AACF;AAEA;;CAEC,GACD,OAAO,eAAeO,WAAWR,IAAU,EAAEC,MAAc;IACzD,MAAMD,KAAKC,MAAM,CAACQ,kBAAkB,CAACR,QAAQ;AAC/C"}
1
+ {"version":3,"sources":["../../src/database/base.ts"],"sourcesContent":["import path from \"node:path\";\nimport knex, { type Knex } from \"knex\";\n\nexport const DEFAULT_SCHEMA = \"sonamu_tasks\";\n\n/**\n * migrate applies pending migrations to the database. Does nothing if the\n * database is already up to date.\n */\nexport async function migrate(config: Knex.Config, schema: string) {\n const instance = knex({ ...config, pool: { min: 1, max: 1 } });\n try {\n await instance.schema.createSchemaIfNotExists(schema);\n await instance.migrate.latest({\n directory: path.join(import.meta.dirname, \"migrations\"),\n schemaName: schema,\n });\n } finally {\n await instance.destroy();\n }\n}\n\n/**\n * dropSchema drops the specified schema from the database.\n */\nexport async function dropSchema(knex: Knex, schema: string) {\n await knex.schema.dropSchemaIfExists(schema, true);\n}\n"],"names":["path","knex","DEFAULT_SCHEMA","migrate","config","schema","instance","pool","min","max","createSchemaIfNotExists","latest","directory","join","dirname","schemaName","destroy","dropSchema","dropSchemaIfExists"],"mappings":"AAAA,OAAOA,UAAU,YAAY;AAC7B,OAAOC,UAAyB,OAAO;AAEvC,OAAO,MAAMC,iBAAiB,eAAe;AAE7C;;;CAGC,GACD,OAAO,eAAeC,QAAQC,MAAmB,EAAEC,MAAc;IAC/D,MAAMC,WAAWL,KAAK;QAAE,GAAGG,MAAM;QAAEG,MAAM;YAAEC,KAAK;YAAGC,KAAK;QAAE;IAAE;IAC5D,IAAI;QACF,MAAMH,SAASD,MAAM,CAACK,uBAAuB,CAACL;QAC9C,MAAMC,SAASH,OAAO,CAACQ,MAAM,CAAC;YAC5BC,WAAWZ,KAAKa,IAAI,CAAC,YAAYC,OAAO,EAAE;YAC1CC,YAAYV;QACd;IACF,SAAU;QACR,MAAMC,SAASU,OAAO;IACxB;AACF;AAEA;;CAEC,GACD,OAAO,eAAeC,WAAWhB,IAAU,EAAEI,MAAc;IACzD,MAAMJ,KAAKI,MAAM,CAACa,kBAAkB,CAACb,QAAQ;AAC/C"}
@@ -1 +1 @@
1
- {"version":3,"file":"pubsub.d.ts","sourceRoot":"","sources":["../../src/database/pubsub.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAEtD,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnF,qBAAa,cAAc;IAQL,OAAO,CAAC,QAAQ,CAAC,IAAI;IAPzC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,UAAU,CAAwC;IAG1D,OAAO,CAAC,WAAW,CAAoB;IAEvC,OAAO;IAWP,IAAI,SAAS,YAEZ;IAGK,OAAO;IAoCP,OAAO;WAOA,MAAM,CAAC,IAAI,EAAE,IAAI;IAO9B,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY;CAWpD"}
1
+ {"version":3,"file":"pubsub.d.ts","sourceRoot":"","sources":["../../src/database/pubsub.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAEtD,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnF,qBAAa,cAAc;IAQL,OAAO,CAAC,QAAQ,CAAC,IAAI;IAPzC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,UAAU,CAAwC;IAG1D,OAAO,CAAC,WAAW,CAAoB;IAEvC,OAAO;IAWP,IAAI,SAAS,YAEZ;IAGK,OAAO;IAoCP,OAAO;WAaA,MAAM,CAAC,IAAI,EAAE,IAAI;IAO9B,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY;CAWpD"}