@smithers-orchestrator/db 0.21.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smithers-orchestrator/db",
3
- "version": "0.21.0",
3
+ "version": "0.22.0",
4
4
  "description": "SQLite and Drizzle persistence adapter for Smithers workflows",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -26,10 +26,10 @@
26
26
  "drizzle-zod": "^0.8.3",
27
27
  "effect": "^3.21.1",
28
28
  "zod": "^4.3.6",
29
- "@smithers-orchestrator/errors": "0.21.0",
30
- "@smithers-orchestrator/graph": "0.21.0",
31
- "@smithers-orchestrator/scheduler": "0.21.0",
32
- "@smithers-orchestrator/observability": "0.21.0"
29
+ "@smithers-orchestrator/errors": "0.22.0",
30
+ "@smithers-orchestrator/observability": "0.22.0",
31
+ "@smithers-orchestrator/scheduler": "0.22.0",
32
+ "@smithers-orchestrator/graph": "0.22.0"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@types/bun": "latest",
package/src/adapter.js CHANGED
@@ -10,7 +10,7 @@
10
10
  /** @typedef {import("./adapter/StaleRunRecord.ts").StaleRunRecord} StaleRunRecord */
11
11
  // @smithers-type-exports-end
12
12
 
13
- import { getTableName, sql } from "drizzle-orm";
13
+ import { getTableName } from "drizzle-orm";
14
14
  import { Effect, Exit, FiberId, Metric } from "effect";
15
15
  import { toSmithersError } from "@smithers-orchestrator/errors/toSmithersError";
16
16
  import { getSqlMessageStorage } from "./sql-message-storage.js";
@@ -1111,9 +1111,11 @@ export class SmithersDb {
1111
1111
  */
1112
1112
  getRawNodeOutput(tableName, runId, nodeId) {
1113
1113
  return runnableEffect(this.read(`get raw node output ${tableName}`, () => {
1114
- const query = sql.raw(`SELECT * FROM "${tableName}" WHERE run_id = '${runId}' AND node_id = '${nodeId}' ORDER BY iteration DESC LIMIT 1`);
1115
- const res = this.db.get(query);
1116
- return Promise.resolve(res ?? null);
1114
+ const escaped = tableName.replaceAll(`"`, `""`);
1115
+ const client = this.db.session.client;
1116
+ const stmt = client.query(`SELECT * FROM "${escaped}" WHERE run_id = ? AND node_id = ? ORDER BY iteration DESC LIMIT 1`);
1117
+ const row = stmt.get(runId, nodeId);
1118
+ return Promise.resolve(row ?? null);
1117
1119
  }).pipe(Effect.catchAll(() => Effect.succeed(null))));
1118
1120
  }
1119
1121
  /**
@@ -13,16 +13,18 @@ import { SmithersError } from "@smithers-orchestrator/errors/SmithersError";
13
13
  * @returns {Effect.Effect<Record<string, unknown> | undefined, SmithersError>}
14
14
  */
15
15
  export function loadInput(db, inputTable, runId) {
16
- const cols = getTableColumns(inputTable);
17
- const runIdCol = cols.runId;
18
- if (!runIdCol) {
19
- throw new SmithersError("DB_MISSING_COLUMNS", "schema.input must include runId column");
20
- }
21
- return Effect.tryPromise({
22
- try: () => db.select().from(inputTable).where(eq(runIdCol, runId)).limit(1),
23
- catch: (cause) => toSmithersError(cause, "load input", {
24
- code: "DB_QUERY_FAILED",
25
- details: { runId },
26
- }),
27
- }).pipe(Effect.map((rows) => rows[0]), Effect.annotateLogs({ runId }), Effect.withLogSpan("db:load-input"));
16
+ return Effect.suspend(() => {
17
+ const cols = getTableColumns(inputTable);
18
+ const runIdCol = cols.runId;
19
+ if (!runIdCol) {
20
+ return Effect.fail(new SmithersError("DB_MISSING_COLUMNS", "schema.input must include runId column"));
21
+ }
22
+ return Effect.tryPromise({
23
+ try: () => db.select().from(inputTable).where(eq(runIdCol, runId)).limit(1),
24
+ catch: (cause) => toSmithersError(cause, "load input", {
25
+ code: "DB_QUERY_FAILED",
26
+ details: { runId },
27
+ }),
28
+ }).pipe(Effect.map((rows) => rows[0]));
29
+ }).pipe(Effect.annotateLogs({ runId }), Effect.withLogSpan("db:load-input"));
28
30
  }
package/src/snapshot.js CHANGED
@@ -53,18 +53,20 @@ function coerceBooleanColumns(rows, boolKeys) {
53
53
  * @returns {Effect.Effect<Record<string, unknown> | undefined, SmithersError>}
54
54
  */
55
55
  export function loadInputEffect(db, inputTable, runId) {
56
- const cols = getTableColumns(inputTable);
57
- const runIdCol = cols.runId;
58
- if (!runIdCol) {
59
- throw new SmithersError("DB_MISSING_COLUMNS", "schema.input must include runId column");
60
- }
61
- return Effect.tryPromise({
62
- try: () => db.select().from(inputTable).where(eq(runIdCol, runId)).limit(1),
63
- catch: (cause) => toSmithersError(cause, "load input", {
64
- code: "DB_QUERY_FAILED",
65
- details: { runId },
66
- }),
67
- }).pipe(Effect.map((rows) => rows[0]), Effect.annotateLogs({ runId }), Effect.withLogSpan("db:load-input"));
56
+ return Effect.suspend(() => {
57
+ const cols = getTableColumns(inputTable);
58
+ const runIdCol = cols.runId;
59
+ if (!runIdCol) {
60
+ return Effect.fail(new SmithersError("DB_MISSING_COLUMNS", "schema.input must include runId column"));
61
+ }
62
+ return Effect.tryPromise({
63
+ try: () => db.select().from(inputTable).where(eq(runIdCol, runId)).limit(1),
64
+ catch: (cause) => toSmithersError(cause, "load input", {
65
+ code: "DB_QUERY_FAILED",
66
+ details: { runId },
67
+ }),
68
+ }).pipe(Effect.map((rows) => rows[0]));
69
+ }).pipe(Effect.annotateLogs({ runId }), Effect.withLogSpan("db:load-input"));
68
70
  }
69
71
  /**
70
72
  * @param {BunSQLiteDatabase<Record<string, unknown>>} db
@@ -3,7 +3,7 @@ import * as SqlClient from "@effect/sql/SqlClient";
3
3
  import { SqlError } from "@effect/sql/SqlError";
4
4
  import * as Statement from "@effect/sql/Statement";
5
5
  import { Database } from "bun:sqlite";
6
- import { Context, Effect, Layer, ManagedRuntime, Scope } from "effect";
6
+ import { Context, Effect, Layer, ManagedRuntime, Scope, Stream } from "effect";
7
7
  import { runSmithersSchemaMigrations } from "./schema-migrations.js";
8
8
  import { camelToSnake } from "./utils/camelToSnake.js";
9
9
  /** @typedef {import("drizzle-orm/bun-sqlite").BunSQLiteDatabase} BunSQLiteDatabase */
@@ -494,7 +494,7 @@ function createConnection(sqlite) {
494
494
  }
495
495
  }),
496
496
  executeUnprepared: (statement, params, transformRows) => execute(statement, params, transformRows),
497
- executeStream: () => Effect.dieMessage("executeStream not implemented"),
497
+ executeStream: (statement, params, transformRows) => Stream.fromIterableEffect(execute(statement, params, transformRows)),
498
498
  };
499
499
  }
500
500
  /**