@absurd-sqlite/bun-worker 0.2.2-alpha.1 → 0.3.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/sqlite.d.ts CHANGED
@@ -1,15 +1,7 @@
1
1
  import { Database } from "bun:sqlite";
2
- import type { Queryable } from "@absurd-sqlite/sdk";
3
- import type { SQLiteRestBindParams } from "@absurd-sqlite/sdk";
4
- export declare class BunSqliteConnection implements Queryable {
5
- private readonly db;
6
- private readonly maxRetries;
7
- private readonly baseRetryDelayMs;
8
- constructor(db: Database);
9
- query<R extends object = Record<string, any>>(sql: string, params?: SQLiteRestBindParams): Promise<{
10
- rows: R[];
11
- }>;
12
- exec(sql: string, params?: SQLiteRestBindParams): Promise<void>;
13
- private runWithRetry;
2
+ import type { SQLiteConnectionOptions } from "@absurd-sqlite/sdk";
3
+ import { SQLiteConnection } from "@absurd-sqlite/sdk";
4
+ export declare class BunSqliteConnection extends SQLiteConnection {
5
+ constructor(db: Database, options?: SQLiteConnectionOptions);
14
6
  }
15
7
  //# sourceMappingURL=sqlite.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../src/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAGV,oBAAoB,EACrB,MAAM,oBAAoB,CAAC;AAE5B,qBAAa,mBAAoB,YAAW,SAAS;IACnD,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAW;IAC9B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAK;IAChC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAM;gBAE3B,EAAE,EAAE,QAAQ;IAIlB,KAAK,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAChD,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,oBAAoB,GAC5B,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,EAAE,CAAA;KAAE,CAAC;IAiBnB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;YAWvD,YAAY;CAc3B"}
1
+ {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../src/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,KAAK,EAGV,uBAAuB,EAIxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,qBAAa,mBAAoB,SAAQ,gBAAgB;gBAC3C,EAAE,EAAE,QAAQ,EAAE,OAAO,GAAE,uBAA4B;CAIhE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absurd-sqlite/bun-worker",
3
- "version": "0.2.2-alpha.1",
3
+ "version": "0.3.0-alpha.0",
4
4
  "description": "Bun worker utilities for Absurd-SQLite",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -39,11 +39,10 @@
39
39
  "homepage": "https://github.com/b4fun/absurd-sqlite#readme",
40
40
  "dependencies": {
41
41
  "@absurd-sqlite/sdk": "next",
42
- "absurd-sdk": "~0.0.7",
43
42
  "cac": "^6.7.14"
44
43
  },
45
44
  "devDependencies": {
46
- "bun-types": "^1.3.5",
45
+ "bun-types": "^1.3.6",
47
46
  "typescript": "^5.9.3"
48
47
  },
49
48
  "engines": {
package/src/index.ts CHANGED
@@ -1,12 +1,15 @@
1
- import { Absurd, type WorkerOptions } from "absurd-sdk";
2
1
  import { Database } from "bun:sqlite";
3
- import type { AbsurdClient } from "@absurd-sqlite/sdk";
2
+ import {
3
+ Absurd,
4
+ type AbsurdClient,
5
+ type WorkerOptions,
6
+ } from "@absurd-sqlite/sdk";
4
7
  import { cac } from "cac";
5
8
 
6
9
  import { BunSqliteConnection } from "./sqlite";
7
10
 
8
11
  export type { AbsurdClient } from "@absurd-sqlite/sdk";
9
- export type { WorkerOptions } from "absurd-sdk";
12
+ export type { WorkerOptions } from "@absurd-sqlite/sdk";
10
13
 
11
14
  export {
12
15
  downloadExtension,
@@ -101,12 +104,10 @@ export default async function run(setupFunction: SetupFunction): Promise<void> {
101
104
  }
102
105
 
103
106
  const db = new Database(dbPath);
104
- (db as unknown as { loadExtension(path: string): void }).loadExtension(
105
- extensionPath
106
- );
107
+ db.loadExtension(extensionPath);
107
108
 
108
109
  const conn = new BunSqliteConnection(db);
109
- const absurd = new Absurd({ db: conn });
110
+ const absurd = new Absurd(conn);
110
111
 
111
112
  await setupFunction(absurd);
112
113
 
package/src/sqlite.ts CHANGED
@@ -1,112 +1,138 @@
1
1
  import { Database } from "bun:sqlite";
2
2
 
3
- import type { Queryable } from "@absurd-sqlite/sdk";
4
3
  import type {
5
- SQLiteBindParams,
6
4
  SQLiteBindValue,
7
- SQLiteRestBindParams,
5
+ SQLiteColumnDefinition,
6
+ SQLiteConnectionOptions,
7
+ SQLiteDatabase,
8
+ SQLiteStatement,
9
+ SQLiteValueCodec,
8
10
  } from "@absurd-sqlite/sdk";
11
+ import { SQLiteConnection } from "@absurd-sqlite/sdk";
9
12
 
10
- export class BunSqliteConnection implements Queryable {
11
- private readonly db: Database;
12
- private readonly maxRetries = 5;
13
- private readonly baseRetryDelayMs = 50;
13
+ export class BunSqliteConnection extends SQLiteConnection {
14
+ constructor(db: Database, options: SQLiteConnectionOptions = {}) {
15
+ const valueCodec = buildValueCodec(options.valueCodec);
16
+ super(new BunSqliteDatabase(db), { ...options, valueCodec });
17
+ }
18
+ }
19
+
20
+ class BunSqliteDatabase implements SQLiteDatabase {
21
+ constructor(private readonly db: Database) {}
14
22
 
15
- constructor(db: Database) {
16
- this.db = db;
23
+ prepare<Result extends object = Record<string, any>>(
24
+ sql: string
25
+ ): SQLiteStatement<Result> {
26
+ const statement = this.db.prepare(sql);
27
+ return new BunSqliteStatement(statement, isReadonlyQuery(sql));
17
28
  }
18
29
 
19
- async query<R extends object = Record<string, any>>(
20
- sql: string,
21
- params?: SQLiteRestBindParams
22
- ): Promise<{ rows: R[] }> {
23
- const { sql: sqliteQuery, paramOrder } = rewritePostgresQuery(sql);
24
- const sqliteParams = rewritePostgresParams(
25
- normalizeParams(params),
26
- paramOrder
27
- );
30
+ close(): void {
31
+ this.db.close();
32
+ }
28
33
 
29
- const statement = this.db.query(sqliteQuery);
30
- const rows = await this.runWithRetry(() =>
31
- statement.all(...sqliteParams).map((row) =>
32
- decodeRowValues(row as Record<string, unknown>)
33
- )
34
+ loadExtension(path: string): void {
35
+ (this.db as unknown as { loadExtension(path: string): void }).loadExtension(
36
+ path
34
37
  );
38
+ }
39
+ }
40
+
41
+ class BunSqliteStatement<Result extends object = Record<string, any>>
42
+ implements SQLiteStatement<Result>
43
+ {
44
+ readonly readonly: boolean;
35
45
 
36
- return { rows: rows as R[] };
46
+ constructor(
47
+ private readonly stmt: ReturnType<Database["prepare"]>,
48
+ readonlyFlag: boolean
49
+ ) {
50
+ this.readonly = readonlyFlag;
37
51
  }
38
52
 
39
- async exec(sql: string, params?: SQLiteRestBindParams): Promise<void> {
40
- const { sql: sqliteQuery, paramOrder } = rewritePostgresQuery(sql);
41
- const sqliteParams = rewritePostgresParams(
42
- normalizeParams(params),
43
- paramOrder
44
- );
53
+ columns(): SQLiteColumnDefinition[] {
54
+ const columnNames = this.stmt.columnNames ?? [];
55
+ const declaredTypes = this.stmt.declaredTypes ?? [];
56
+ return columnNames.map((name, index) => ({
57
+ name,
58
+ column: null,
59
+ table: null,
60
+ database: null,
61
+ type: normalizeColumnType(declaredTypes[index] ?? null),
62
+ }));
63
+ }
45
64
 
46
- const statement = this.db.query(sqliteQuery);
47
- await this.runWithRetry(() => statement.run(...sqliteParams));
48
- }
49
-
50
- private async runWithRetry<T>(operation: () => T): Promise<T> {
51
- let attempt = 0;
52
- while (true) {
53
- try {
54
- return operation();
55
- } catch (err) {
56
- if (!isRetryableSQLiteError(err) || attempt >= this.maxRetries) {
57
- throw err;
58
- }
59
- attempt++;
60
- await delay(this.baseRetryDelayMs * attempt);
61
- }
62
- }
65
+ all(...args: any[]): Result[] {
66
+ const normalizedArgs = normalizeStatementArgs(args);
67
+ return this.stmt.all(...normalizedArgs) as Result[];
68
+ }
69
+
70
+ run(...args: any[]): unknown {
71
+ const normalizedArgs = normalizeStatementArgs(args);
72
+ return this.stmt.run(...normalizedArgs);
63
73
  }
64
74
  }
65
75
 
66
- function rewritePostgresQuery(text: string): {
67
- sql: string;
68
- paramOrder: number[];
69
- } {
70
- const paramOrder: number[] = [];
71
- const sql = text
72
- .replace(/\$(\d+)/g, (_, index) => {
73
- paramOrder.push(Number(index));
74
- return "?";
75
- })
76
- .replace(/absurd\.(\w+)/g, "absurd_$1");
77
-
78
- return { sql, paramOrder };
76
+ function buildValueCodec(
77
+ overrides?: SQLiteValueCodec
78
+ ): SQLiteValueCodec {
79
+ return {
80
+ encodeParam: overrides?.encodeParam ?? encodeColumnValue,
81
+ decodeColumn: overrides?.decodeColumn ?? decodeColumnValue,
82
+ decodeRow: overrides?.decodeRow ?? decodeRowValues,
83
+ };
79
84
  }
80
85
 
81
- function rewritePostgresParams<I = any>(
82
- params: SQLiteBindValue[],
83
- paramOrder: number[]
84
- ): I[] {
85
- if (paramOrder.length === 0) {
86
- return params.map((value) => encodeColumnValue(value)) as I[];
86
+ function normalizeStatementArgs(args: any[]): any[] {
87
+ if (args.length !== 1) {
88
+ return args;
89
+ }
90
+ const params = args[0];
91
+ if (!params || typeof params !== "object" || Array.isArray(params)) {
92
+ return args;
87
93
  }
94
+ const normalized: Record<string, unknown> = {};
95
+ for (const [key, value] of Object.entries(params)) {
96
+ normalized[normalizeParamKey(key)] = value;
97
+ }
98
+ return [normalized];
99
+ }
88
100
 
89
- return paramOrder.map((index) => {
90
- const value = params[index - 1];
91
- return encodeColumnValue(value) as I;
92
- });
101
+ function normalizeParamKey(key: string): string {
102
+ if (key.startsWith("$") || key.startsWith(":") || key.startsWith("@")) {
103
+ return key;
104
+ }
105
+ return `:${key}`;
93
106
  }
94
107
 
95
- function decodeRowValues<R extends object = any>(
96
- row: Record<string, unknown>
97
- ): R {
108
+ function decodeRowValues<R extends object = any>(args: {
109
+ row: Record<string, unknown>;
110
+ columns?: SQLiteColumnDefinition[];
111
+ decodeColumn?: (args: {
112
+ value: unknown;
113
+ columnName: string;
114
+ columnType: string | null;
115
+ }) => unknown;
116
+ }): R {
98
117
  const decodedRow: any = {};
99
- for (const [columnName, rawValue] of Object.entries(row)) {
100
- decodedRow[columnName] = decodeColumnValue(rawValue, columnName);
118
+ for (const [columnName, rawValue] of Object.entries(args.row)) {
119
+ decodedRow[columnName] = decodeColumnValue({
120
+ value: rawValue,
121
+ columnName,
122
+ columnType: null,
123
+ });
101
124
  }
102
125
 
103
126
  return decodedRow as R;
104
127
  }
105
128
 
106
- function decodeColumnValue<V = any>(
107
- value: unknown | V,
108
- columnName: string
109
- ): V | null {
129
+ function decodeColumnValue<V = any>(args: {
130
+ value: unknown | V;
131
+ columnName: string;
132
+ columnType: string | null;
133
+ verbose?: (...args: any[]) => void;
134
+ }): V | null {
135
+ const { value, columnName } = args;
110
136
  if (value === null || value === undefined) {
111
137
  return null;
112
138
  }
@@ -128,8 +154,7 @@ function decodeColumnValue<V = any>(
128
154
  }
129
155
 
130
156
  if (value instanceof Uint8Array || value instanceof ArrayBuffer) {
131
- const bytes =
132
- value instanceof Uint8Array ? value : new Uint8Array(value);
157
+ const bytes = value instanceof Uint8Array ? value : new Uint8Array(value);
133
158
  const decoded = new TextDecoder().decode(bytes);
134
159
  return tryDecodeJson(decoded) ?? (value as V);
135
160
  }
@@ -145,7 +170,7 @@ function tryDecodeJson<V = any>(value: string): V | null {
145
170
  }
146
171
  }
147
172
 
148
- function encodeColumnValue(value: any): any {
173
+ function encodeColumnValue(value: SQLiteBindValue): SQLiteBindValue {
149
174
  if (value instanceof Date) {
150
175
  return value.toISOString();
151
176
  }
@@ -159,60 +184,23 @@ function isTimestampColumn(columnName: string): boolean {
159
184
  return columnName.endsWith("_at");
160
185
  }
161
186
 
162
- function normalizeParams(
163
- params?: SQLiteRestBindParams
164
- ): SQLiteBindValue[] {
165
- if (!params) {
166
- return [];
167
- }
168
-
169
- if (params.length === 1 && isBindParams(params[0])) {
170
- const inner = params[0];
171
- if (Array.isArray(inner)) {
172
- return inner;
173
- }
174
- return Object.values(inner);
175
- }
176
-
177
- return params as SQLiteBindValue[];
178
- }
179
-
180
- function isBindParams(value: unknown): value is SQLiteBindParams {
181
- if (Array.isArray(value)) {
182
- return true;
183
- }
184
- if (!value || typeof value !== "object") {
185
- return false;
186
- }
187
- const tag = Object.prototype.toString.call(value);
188
- return tag === "[object Object]";
187
+ function isReadonlyQuery(sql: string): boolean {
188
+ const trimmed = sql.trim().toLowerCase();
189
+ return (
190
+ trimmed.startsWith("select") ||
191
+ trimmed.startsWith("with") ||
192
+ trimmed.startsWith("pragma") ||
193
+ trimmed.startsWith("explain")
194
+ );
189
195
  }
190
196
 
191
- const sqliteRetryableErrorCodes = new Set(["SQLITE_BUSY", "SQLITE_LOCKED"]);
192
- const sqliteRetryableErrnos = new Set([5, 6]);
193
-
194
- function isRetryableSQLiteError(err: unknown): boolean {
195
- if (!err || typeof err !== "object") {
196
- return false;
197
- }
198
-
199
- const code = (err as any).code;
200
- if (typeof code === "string") {
201
- for (const retryableCode of sqliteRetryableErrorCodes) {
202
- if (code.startsWith(retryableCode)) {
203
- return true;
204
- }
205
- }
197
+ function normalizeColumnType(value: string | null): string | null {
198
+ if (!value) {
199
+ return null;
206
200
  }
207
-
208
- const errno = (err as any).errno;
209
- if (typeof errno === "number" && sqliteRetryableErrnos.has(errno)) {
210
- return true;
201
+ const lowered = value.toLowerCase();
202
+ if (lowered === "null") {
203
+ return null;
211
204
  }
212
-
213
- return false;
214
- }
215
-
216
- function delay(ms: number): Promise<void> {
217
- return new Promise((resolve) => setTimeout(resolve, ms));
205
+ return lowered;
218
206
  }
@@ -4,9 +4,10 @@ import {
4
4
  expect,
5
5
  beforeAll,
6
6
  afterEach,
7
+ jest,
7
8
  } from "bun:test";
8
9
  import assert from "node:assert/strict";
9
- import type { Absurd } from "absurd-sdk";
10
+ import type { Absurd } from "@absurd-sqlite/sdk";
10
11
  import { createTestAbsurd, randomName, type TestContext } from "./setup";
11
12
  import { EventEmitter, once } from "events";
12
13
  import { waitFor } from "./wait-for";
@@ -501,5 +502,56 @@ describe("Basic SDK Operations", () => {
501
502
  );
502
503
  });
503
504
  });
505
+
506
+ test("heartbeat keeps task alive past original claim timeout", async () => {
507
+ const claimTimeout = 1;
508
+ const extension = 10;
509
+ const longWorkMs = claimTimeout * 2000 + 100;
510
+ let heartbeatFired = false;
511
+
512
+ absurd.registerTask(
513
+ { name: "heartbeat-long-task" },
514
+ async (_params, taskCtx) => {
515
+ await taskCtx.heartbeat(extension);
516
+ heartbeatFired = true;
517
+ await ctx.sleep(longWorkMs);
518
+ return { ok: true };
519
+ },
520
+ );
521
+
522
+ const { taskID } = await absurd.spawn("heartbeat-long-task", {});
523
+
524
+ const exitSpy = jest
525
+ .spyOn(process, "exit")
526
+ .mockImplementation(() => undefined as never);
527
+
528
+ const worker = await absurd.startWorker({
529
+ claimTimeout,
530
+ concurrency: 1,
531
+ pollInterval: 0.01,
532
+ fatalOnLeaseTimeout: true,
533
+ });
534
+
535
+ try {
536
+ await waitFor(() => expect(heartbeatFired).toBe(true), {
537
+ timeout: 500,
538
+ });
539
+
540
+ await waitFor(async () => {
541
+ const task = await ctx.getTask(taskID);
542
+ expect(task?.state).toBe("completed");
543
+ }, {
544
+ timeout: longWorkMs + 2000,
545
+ });
546
+
547
+ const runs = await ctx.getRuns(taskID);
548
+ expect(runs).toHaveLength(1);
549
+ expect(runs[0]?.state).toBe("completed");
550
+ expect(exitSpy).not.toHaveBeenCalled();
551
+ } finally {
552
+ await worker.close();
553
+ exitSpy.mockRestore();
554
+ }
555
+ });
504
556
  });
505
557
  });
@@ -1,7 +1,7 @@
1
1
  import { describe, test, expect, beforeAll, afterEach } from "bun:test";
2
- import type { Absurd } from "absurd-sdk";
2
+ import type { Absurd } from "@absurd-sqlite/sdk";
3
3
  import { createTestAbsurd, randomName, type TestContext } from "./setup";
4
- import { TimeoutError } from "absurd-sdk";
4
+ import { TimeoutError } from "@absurd-sqlite/sdk";
5
5
 
6
6
  describe("Event system", () => {
7
7
  let ctx: TestContext;
@@ -1,6 +1,6 @@
1
1
  import { describe, test, expect, beforeAll, afterEach } from "bun:test";
2
2
  import { AsyncLocalStorage } from "node:async_hooks";
3
- import type { Absurd, SpawnOptions } from "absurd-sdk";
3
+ import type { Absurd, SpawnOptions } from "@absurd-sqlite/sdk";
4
4
  import { createTestAbsurd, randomName, type TestContext } from "./setup";
5
5
 
6
6
  describe("Hooks", () => {
@@ -1,5 +1,5 @@
1
1
  import { describe, test, expect, beforeAll, afterEach } from "bun:test";
2
- import type { Absurd } from "absurd-sdk";
2
+ import type { Absurd } from "@absurd-sqlite/sdk";
3
3
  import { createTestAbsurd, randomName, type TestContext } from "./setup";
4
4
 
5
5
  describe("Idempotent Task Spawning", () => {
@@ -3,7 +3,7 @@ import { mkdtempSync, rmSync } from "node:fs";
3
3
  import { tmpdir } from "node:os";
4
4
  import { join } from "node:path";
5
5
  import { afterEach, describe, expect, it } from "bun:test";
6
- import { Absurd } from "absurd-sdk";
6
+ import { Absurd } from "@absurd-sqlite/sdk";
7
7
 
8
8
  import { BunSqliteConnection } from "../src/sqlite";
9
9
  import { loadExtension } from "./setup";
@@ -29,7 +29,7 @@ describe("Absurd", () => {
29
29
  it("creates and lists queues using the sqlite extension", async () => {
30
30
  const db = createDatabaseWithMigrations();
31
31
  const conn = new BunSqliteConnection(db);
32
- const absurd = new Absurd({ db: conn });
32
+ const absurd = new Absurd(conn);
33
33
 
34
34
  await absurd.createQueue("alpha");
35
35
  await absurd.createQueue("beta");
@@ -52,7 +52,7 @@ describe("Absurd", () => {
52
52
  it("closes workers without affecting the sqlite database", async () => {
53
53
  const db = createDatabaseWithMigrations();
54
54
  const conn = new BunSqliteConnection(db);
55
- const absurd = new Absurd({ db: conn });
55
+ const absurd = new Absurd(conn);
56
56
 
57
57
  await absurd.close();
58
58
 
@@ -1,5 +1,5 @@
1
1
  import { describe, test, expect, beforeAll, afterEach } from "bun:test";
2
- import type { Absurd } from "absurd-sdk";
2
+ import type { Absurd } from "@absurd-sqlite/sdk";
3
3
  import { createTestAbsurd, randomName, type TestContext } from "./setup";
4
4
 
5
5
  describe("Retry and cancellation", () => {
package/test/setup.ts CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  Absurd,
9
9
  type AbsurdHooks,
10
10
  type JsonValue,
11
- } from "absurd-sdk";
11
+ } from "@absurd-sqlite/sdk";
12
12
 
13
13
  import { BunSqliteConnection } from "../src/sqlite";
14
14
 
@@ -263,10 +263,7 @@ export async function createTestAbsurd(
263
263
  queueName: string = "default"
264
264
  ): Promise<TestContext> {
265
265
  const fixture = createFixture();
266
- const absurd = new Absurd({
267
- db: fixture.conn,
268
- queueName,
269
- });
266
+ const absurd = new Absurd(fixture.conn, { queueName });
270
267
 
271
268
  await absurd.createQueue(queueName);
272
269
 
@@ -335,8 +332,7 @@ export async function createTestAbsurd(
335
332
  expectCancelledError: (promise: Promise<unknown>) =>
336
333
  expectCancelledError(promise),
337
334
  createClient: (options) => {
338
- const client = new Absurd({
339
- db: fixture.conn,
335
+ const client = new Absurd(fixture.conn, {
340
336
  queueName: options?.queueName ?? queueName,
341
337
  hooks: options?.hooks,
342
338
  });
@@ -26,12 +26,14 @@ describe("BunSqliteConnection", () => {
26
26
  db.close();
27
27
  });
28
28
 
29
- it("returns empty rows for non-reader statements", async () => {
29
+ it("throws when query is used for non-reader statements", async () => {
30
30
  const db = new Database(":memory:");
31
31
  const conn = new BunSqliteConnection(db);
32
32
 
33
- const { rows } = await conn.query("CREATE TABLE t (id)");
34
- expect(rows).toEqual([]);
33
+ await expect(conn.query("CREATE TABLE t (id)")).rejects.toThrow(
34
+ "only statements that return data"
35
+ );
36
+ await conn.exec("CREATE TABLE t (id)");
35
37
 
36
38
  await conn.exec("INSERT INTO t (id) VALUES ($1)", [1]);
37
39
  const { rows: inserted } = await conn.query<{ id: number }>(
@@ -146,14 +148,14 @@ describe("BunSqliteConnection", () => {
146
148
  }),
147
149
  };
148
150
 
149
- const querySpy = jest.fn().mockReturnValue(statement as any);
150
- const db = { query: querySpy } as unknown as Database;
151
+ const prepareSpy = jest.fn().mockReturnValue(statement as any);
152
+ const db = { prepare: prepareSpy } as unknown as Database;
151
153
  const conn = new BunSqliteConnection(db);
152
154
 
153
155
  await expect(
154
156
  conn.exec("UPDATE locked_table SET value = $1 WHERE id = $2", [1, 1])
155
157
  ).resolves.toBeUndefined();
156
158
  expect(statement.run).toHaveBeenCalledTimes(2);
157
- expect(querySpy).toHaveBeenCalledTimes(1);
159
+ expect(prepareSpy).toHaveBeenCalledTimes(1);
158
160
  });
159
161
  });
package/test/step.test.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { describe, test, expect, beforeAll, afterEach, jest } from "bun:test";
2
- import type { Absurd } from "absurd-sdk";
2
+ import type { Absurd } from "@absurd-sqlite/sdk";
3
3
  import { createTestAbsurd, randomName, type TestContext } from "./setup";
4
4
 
5
5
  describe("Step functionality", () => {
@@ -2,7 +2,7 @@ import { describe, it, expect, beforeAll, afterEach, jest } from "bun:test";
2
2
  import { EventEmitter, once } from "events";
3
3
  import type { TestContext } from "./setup";
4
4
  import { createTestAbsurd, randomName } from "./setup";
5
- import type { Absurd } from "absurd-sdk";
5
+ import type { Absurd } from "@absurd-sqlite/sdk";
6
6
  import { waitFor } from "./wait-for";
7
7
 
8
8
  describe("Worker", () => {