@tursodatabase/serverless 1.2.0-pre.2 → 1.2.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/index.d.ts CHANGED
@@ -1,593 +1,5 @@
1
- interface Value {
2
- type: 'null' | 'integer' | 'float' | 'text' | 'blob';
3
- value?: string | number;
4
- base64?: string;
5
- }
6
- interface Column {
7
- name: string;
8
- decltype: string;
9
- }
10
- interface DescribeResult {
11
- params: Array<{
12
- name?: string;
13
- }>;
14
- cols: Column[];
15
- is_explain: boolean;
16
- is_readonly: boolean;
17
- }
18
- interface CursorResponse {
19
- baton: string | null;
20
- base_url: string | null;
21
- }
22
- interface CursorEntry {
23
- type: 'step_begin' | 'step_end' | 'step_error' | 'row' | 'error';
24
- step?: number;
25
- cols?: Column[];
26
- row?: Value[];
27
- affected_row_count?: number;
28
- last_insert_rowid?: string | number;
29
- error?: {
30
- message: string;
31
- code: string;
32
- };
33
- }
34
- /** HTTP header key for the encryption key */
35
- declare const ENCRYPTION_KEY_HEADER = "x-turso-encryption-key";
36
- /** Per-query timeout options. Overrides defaultQueryTimeout for this call. */
37
- interface QueryOptions {
38
- /** Per-query timeout in milliseconds. Overrides defaultQueryTimeout for this call. */
39
- queryTimeout?: number;
40
- }
41
-
42
- /**
43
- * Locking mode for atomic `batch()` execution. Accepts the same values
44
- * as the variants of `Connection.transaction(...)`.
45
- */
46
- type BatchMode = 'deferred' | 'immediate' | 'exclusive' | 'concurrent';
47
- /**
48
- * Configuration options for a session.
49
- */
50
- interface SessionConfig {
51
- /** Database URL */
52
- url: string;
53
- /** Authentication token (optional for local development with turso dev) */
54
- authToken?: string;
55
- /**
56
- * Encryption key for the remote database (base64 encoded)
57
- * to enable access to encrypted Turso Cloud databases.
58
- */
59
- remoteEncryptionKey?: string;
60
- /** Default maximum query execution time in milliseconds before interruption. */
61
- defaultQueryTimeout?: number;
62
- }
63
- /**
64
- * A database session that manages the connection state and baton.
65
- *
66
- * Each session maintains its own connection state and can execute SQL statements
67
- * independently without interfering with other sessions.
68
- */
69
- declare class Session {
70
- private config;
71
- private baton;
72
- private baseUrl;
73
- constructor(config: SessionConfig);
74
- private createAbortSignal;
75
- /**
76
- * Describe a SQL statement to get its column metadata.
77
- *
78
- * @param sql - The SQL statement to describe
79
- * @returns Promise resolving to the statement description
80
- */
81
- describe(sql: string, queryOptions?: QueryOptions): Promise<DescribeResult>;
82
- /**
83
- * Execute a SQL statement and return all results.
84
- *
85
- * @param sql - The SQL statement to execute
86
- * @param args - Optional array of parameter values or object with named parameters
87
- * @param safeIntegers - Whether to return integers as BigInt
88
- * @returns Promise resolving to the complete result set
89
- */
90
- execute(sql: string, args?: any[] | Record<string, any>, safeIntegers?: boolean, queryOptions?: QueryOptions): Promise<any>;
91
- /**
92
- * Execute a SQL statement and return the raw response and entries.
93
- *
94
- * @param sql - The SQL statement to execute
95
- * @param args - Optional array of parameter values or object with named parameters
96
- * @returns Promise resolving to the raw response and cursor entries
97
- */
98
- executeRaw(sql: string, args?: any[] | Record<string, any>, queryOptions?: QueryOptions): Promise<{
99
- response: CursorResponse;
100
- entries: AsyncGenerator<CursorEntry>;
101
- }>;
102
- /**
103
- * Process cursor entries into a structured result.
104
- *
105
- * @param entries - Async generator of cursor entries
106
- * @returns Promise resolving to the processed result
107
- */
108
- processCursorEntries(entries: AsyncGenerator<CursorEntry>, safeIntegers?: boolean): Promise<any>;
109
- /**
110
- * Create a row object with both array and named property access.
111
- *
112
- * @param values - Array of column values
113
- * @param columns - Array of column names
114
- * @returns Row object with dual access patterns
115
- */
116
- createRowObject(values: any[], columns: string[]): any;
117
- /**
118
- * Execute multiple SQL statements in a batch.
119
- *
120
- * When `mode` is set, the batch is sent as a single Hrana request that
121
- * also carries `BEGIN <mode>` / `COMMIT` / `ROLLBACK` steps using the
122
- * server-side condition chain, giving atomic execution in one round-trip.
123
- * When `mode` is omitted, the user statements are sent as-is and run
124
- * under autocommit (or whatever transaction is already active on this
125
- * stream).
126
- *
127
- * @param statements - Array of SQL statements to execute.
128
- * @param mode - Optional locking mode; when set, the batch executes
129
- * atomically. Accepts the same values as `Database.transaction(...)`
130
- * variants: `"deferred"`, `"immediate"`, `"exclusive"`, `"concurrent"`.
131
- * @returns Promise resolving to batch execution results.
132
- */
133
- batch(statements: Array<string | {
134
- sql: string;
135
- args?: any[] | Record<string, any>;
136
- }>, mode?: BatchMode, queryOptions?: QueryOptions): Promise<any>;
137
- /**
138
- * Execute a sequence of SQL statements separated by semicolons.
139
- *
140
- * @param sql - SQL string containing multiple statements separated by semicolons
141
- * @returns Promise resolving when all statements are executed
142
- */
143
- sequence(sql: string, queryOptions?: QueryOptions): Promise<void>;
144
- /**
145
- * Close the session.
146
- *
147
- * This sends a close request to the server to properly clean up the stream
148
- * before resetting the local state.
149
- */
150
- close(): Promise<void>;
151
- }
152
-
153
- declare class AsyncLock {
154
- private locked;
155
- private queue;
156
- acquire(): Promise<void>;
157
- release(): void;
158
- }
159
-
160
- /**
161
- * A prepared SQL statement that can be executed in multiple ways.
162
- *
163
- * Statements may either own a dedicated session or share a connection session to preserve transaction boundaries.
164
- * Provides three execution modes:
165
- * - `get(args?)`: Returns the first row or null
166
- * - `all(args?)`: Returns all rows as an array
167
- * - `iterate(args?)`: Returns an async iterator for streaming results
168
- */
169
- declare class Statement {
170
- private session;
171
- private sql;
172
- private presentationMode;
173
- private safeIntegerMode;
174
- private columnMetadata;
175
- private execLock?;
176
- constructor(sessionConfig: SessionConfig, sql: string, columns?: Column[]);
177
- /**
178
- * Create a Statement that shares an existing session and serializes execution
179
- * through the given lock. Used by Connection.prepare() so prepared statements
180
- * participate in the connection's transaction scope.
181
- */
182
- static fromSession(session: Session, sql: string, columns: Column[] | undefined, execLock: AsyncLock): Statement;
183
- /**
184
- * Whether the prepared statement returns data.
185
- *
186
- * This is `true` for SELECT queries and statements with RETURNING clause,
187
- * and `false` for INSERT, UPDATE, DELETE statements without RETURNING.
188
- *
189
- * @example
190
- * ```typescript
191
- * const stmt = await conn.prepare(sql);
192
- * if (stmt.reader) {
193
- * return stmt.all(args); // SELECT-like query
194
- * } else {
195
- * return stmt.run(args); // INSERT/UPDATE/DELETE
196
- * }
197
- * ```
198
- */
199
- get reader(): boolean;
200
- /**
201
- * Enable raw mode to return arrays instead of objects.
202
- *
203
- * @param raw Enable or disable raw mode. If you don't pass the parameter, raw mode is enabled.
204
- * @returns This statement instance for chaining
205
- *
206
- * @example
207
- * ```typescript
208
- * const stmt = client.prepare("SELECT * FROM users WHERE id = ?");
209
- * const row = await stmt.raw().get([1]);
210
- * console.log(row); // [1, "Alice", "alice@example.org"]
211
- * ```
212
- */
213
- raw(raw?: boolean): Statement;
214
- /**
215
- * Enable pluck mode to return only the first column value from each row.
216
- *
217
- * @param pluck Enable or disable pluck mode. If you don't pass the parameter, pluck mode is enabled.
218
- * @returns This statement instance for chaining
219
- *
220
- * @example
221
- * ```typescript
222
- * const stmt = client.prepare("SELECT id FROM users");
223
- * const ids = await stmt.pluck().all();
224
- * console.log(ids); // [1, 2, 3, ...]
225
- * ```
226
- */
227
- pluck(pluck?: boolean): Statement;
228
- /**
229
- * Sets safe integers mode for this statement.
230
- *
231
- * @param toggle Whether to use safe integers. If you don't pass the parameter, safe integers mode is enabled.
232
- * @returns This statement instance for chaining
233
- */
234
- safeIntegers(toggle?: boolean): Statement;
235
- /**
236
- * Get column information for this statement.
237
- *
238
- * @returns Array of column metadata objects matching the native bindings format
239
- *
240
- * @example
241
- * ```typescript
242
- * const stmt = await client.prepare("SELECT id, name, email FROM users");
243
- * const columns = stmt.columns();
244
- * console.log(columns); // [{ name: 'id', type: 'INTEGER', column: null, database: null, table: null }, ...]
245
- * ```
246
- */
247
- columns(): any[];
248
- private withLock;
249
- /**
250
- * Executes the prepared statement.
251
- *
252
- * @param args - Optional array of parameter values or object with named parameters
253
- * @returns Promise resolving to the result of the statement
254
- *
255
- * @example
256
- * ```typescript
257
- * const stmt = client.prepare("INSERT INTO users (name, email) VALUES (?, ?)");
258
- * const result = await stmt.run(['John Doe', 'john.doe@example.com']);
259
- * console.log(`Inserted user with ID ${result.lastInsertRowid}`);
260
- * ```
261
- */
262
- run(args?: any, queryOptions?: QueryOptions): Promise<any>;
263
- /**
264
- * Execute the statement and return the first row.
265
- *
266
- * @param args - Optional array of parameter values or object with named parameters
267
- * @returns Promise resolving to the first row or undefined if no results
268
- *
269
- * @example
270
- * ```typescript
271
- * const stmt = client.prepare("SELECT * FROM users WHERE id = ?");
272
- * const user = await stmt.get([123]);
273
- * if (user) {
274
- * console.log(user.name);
275
- * }
276
- * ```
277
- */
278
- get(args?: any, queryOptions?: QueryOptions): Promise<any>;
279
- /**
280
- * Execute the statement and return all rows.
281
- *
282
- * @param args - Optional array of parameter values or object with named parameters
283
- * @returns Promise resolving to an array of all result rows
284
- *
285
- * @example
286
- * ```typescript
287
- * const stmt = client.prepare("SELECT * FROM users WHERE active = ?");
288
- * const activeUsers = await stmt.all([true]);
289
- * console.log(`Found ${activeUsers.length} active users`);
290
- * ```
291
- */
292
- all(args?: any, queryOptions?: QueryOptions): Promise<any[]>;
293
- /**
294
- * Execute the statement and return an async iterator for streaming results.
295
- *
296
- * This method provides memory-efficient processing of large result sets
297
- * by streaming rows one at a time instead of loading everything into memory.
298
- *
299
- * @param args - Optional array of parameter values or object with named parameters
300
- * @returns AsyncGenerator that yields individual rows
301
- *
302
- * @example
303
- * ```typescript
304
- * const stmt = client.prepare("SELECT * FROM large_table WHERE category = ?");
305
- * for await (const row of stmt.iterate(['electronics'])) {
306
- * // Process each row individually
307
- * console.log(row.id, row.name);
308
- * }
309
- * ```
310
- */
311
- iterate(args?: any, queryOptions?: QueryOptions): AsyncGenerator<any>;
312
- }
313
-
314
- /**
315
- * Configuration options for connecting to a Turso database.
316
- */
317
- interface Config extends SessionConfig {
318
- }
319
- type BatchStatement = string | {
320
- sql: string;
321
- args?: any[] | Record<string, any>;
322
- };
323
- /**
324
- * A connection to a Turso database.
325
- *
326
- * Provides methods for executing SQL statements and managing prepared statements.
327
- * Uses the SQL over HTTP protocol with streaming cursor support.
328
- *
329
- * ## Concurrency model
330
- *
331
- * A Connection is **single-stream**: it can only run one statement at a time.
332
- * This is not an implementation quirk — it follows from the SQL over HTTP protocol,
333
- * where each request carries a baton from the previous response to sequence operations
334
- * on the server. Concurrent calls on the same connection would race on that baton
335
- * and corrupt the stream. This is the same model as SQLite itself (one execution
336
- * at a time per connection).
337
- *
338
- * If you call `execute()` while another is in flight, the call automatically
339
- * waits for the previous one to finish — just like the native
340
- * `@tursodatabase/database` binding.
341
- *
342
- * ## Parallel queries
343
- *
344
- * For parallelism, create multiple connections. `connect()` is cheap — it just
345
- * allocates a config object. No TCP connection is opened until the first `execute()`,
346
- * and the underlying `fetch()` runtime automatically pools and reuses TCP/TLS
347
- * connections to the same origin.
348
- *
349
- * ```typescript
350
- * import { connect } from "@tursodatabase/serverless";
351
- *
352
- * const config = { url: process.env.TURSO_URL, authToken: process.env.TURSO_TOKEN };
353
- *
354
- * // Option 1: one connection per parallel query
355
- * const [users, orders] = await Promise.all([
356
- * connect(config).execute("SELECT * FROM users WHERE active = 1"),
357
- * connect(config).execute("SELECT * FROM orders WHERE status = 'pending'"),
358
- * ]);
359
- *
360
- * // Option 2: reusable pool for repeated parallel work
361
- * const pool = Array.from({ length: 4 }, () => connect(config));
362
- * const results = await Promise.all(
363
- * queries.map((sql, i) => pool[i % pool.length].execute(sql))
364
- * );
365
- * ```
366
- */
367
- declare class Connection {
368
- private config;
369
- private session;
370
- private isOpen;
371
- private defaultSafeIntegerMode;
372
- private _inTransaction;
373
- private execLock;
374
- constructor(config: Config);
375
- /**
376
- * Whether the database is currently in a transaction.
377
- */
378
- get inTransaction(): boolean;
379
- /**
380
- * Prepare a SQL statement for execution.
381
- *
382
- * Prepared statements created from a Connection use the same underlying session so transaction boundaries are preserved.
383
- * This method fetches column metadata using the describe functionality.
384
- *
385
- * @param sql - The SQL statement to prepare
386
- * @returns A Promise that resolves to a Statement object with column metadata
387
- *
388
- * @example
389
- * ```typescript
390
- * const stmt = await client.prepare("SELECT * FROM users WHERE id = ?");
391
- * const columns = stmt.columns();
392
- * const user = await stmt.get([123]);
393
- * ```
394
- */
395
- prepare(sql: string): Promise<Statement>;
396
- /**
397
- * Like `prepare(sql).run(args)` but in a single round trip — skips `describe`
398
- * since run() does not need column metadata.
399
- */
400
- run(sql: string, ...bindParameters: any[]): Promise<any>;
401
- /**
402
- * Like `prepare(sql).get(args)` but in a single round trip.
403
- */
404
- get(sql: string, ...bindParameters: any[]): Promise<any>;
405
- /**
406
- * Like `prepare(sql).all(args)` but in a single round trip.
407
- */
408
- all(sql: string, ...bindParameters: any[]): Promise<any[]>;
409
- /**
410
- * Like `prepare(sql).iterate(args)` but in a single round trip. Buffers the
411
- * result set — the connection lock cannot be held across `yield` points
412
- * without risking deadlock on nested calls.
413
- */
414
- iterate(sql: string, ...bindParameters: any[]): AsyncGenerator<any>;
415
- /**
416
- * Execute a SQL statement and return all results.
417
- *
418
- * @param sql - The SQL statement to execute
419
- * @param args - Optional array of parameter values
420
- * @returns Promise resolving to the complete result set
421
- *
422
- * @example
423
- * ```typescript
424
- * const result = await client.execute("SELECT * FROM users WHERE id = ?", [123]);
425
- * console.log(result.rows);
426
- * ```
427
- */
428
- execute(sql: string, args?: any[], queryOptions?: QueryOptions): Promise<any>;
429
- /**
430
- * Execute a SQL statement and return all results.
431
- *
432
- * @param sql - The SQL statement to execute
433
- * @returns Promise resolving to the complete result set
434
- *
435
- * @example
436
- * ```typescript
437
- * const result = await client.exec("SELECT * FROM users");
438
- * console.log(result.rows);
439
- * ```
440
- */
441
- exec(sql: string, queryOptions?: QueryOptions): Promise<any>;
442
- /**
443
- * Executes a batch of SQL statements over this connection.
444
- *
445
- * By default, batch() is not transactional: each statement runs in its
446
- * own autocommit step, so a failure mid-batch leaves earlier successful
447
- * statements committed. Pass a `mode` to make the batch atomic — the
448
- * statements are wrapped in `BEGIN <mode>` / `COMMIT` (with `ROLLBACK`
449
- * on failure) and dispatched as a single Hrana request, so the whole
450
- * batch completes in one round-trip. When called from inside a
451
- * `connection.transaction(...)` callback the `mode` argument is ignored
452
- * and the surrounding transaction is reused.
453
- *
454
- * When `mode` is set, `batch()` owns the surrounding
455
- * `BEGIN`/`COMMIT`/`ROLLBACK`, so the `statements` array must not
456
- * contain its own transaction-control SQL (`BEGIN`, `COMMIT`,
457
- * `ROLLBACK`, `SAVEPOINT`, `RELEASE`). The input is not validated
458
- * for that — a user-supplied `COMMIT` will close the wrapper
459
- * transaction mid-batch and leave earlier statements committed,
460
- * defeating the all-or-nothing contract.
461
- *
462
- * @param statements - An array of SQL strings or `{ sql, args }` objects.
463
- * @param mode - When set, makes the batch atomic. Accepts the same
464
- * values as `connection.transaction(...)` variants: `"deferred"`,
465
- * `"immediate"`, `"exclusive"`, `"concurrent"`. Ignored when already
466
- * inside a transaction.
467
- * @returns An object with `rowsAffected` (sum of affected rows) and
468
- * `lastInsertRowid` (rowid of the last successful insert).
469
- *
470
- * @example
471
- * // Plain SQL strings (non-atomic).
472
- * await db.batch([
473
- * "INSERT INTO users(name) VALUES ('Alice')",
474
- * "INSERT INTO users(name) VALUES ('Bob')",
475
- * ]);
476
- *
477
- * @example
478
- * // Positional and named bind parameters.
479
- * await db.batch([
480
- * { sql: "INSERT INTO users(name, email) VALUES (?, ?)", args: ["Carol", "carol@example.net"] },
481
- * { sql: "INSERT INTO users(name, email) VALUES (:name, :email)", args: { name: "Dave", email: "dave@example.net" } },
482
- * ]);
483
- *
484
- * @example
485
- * // Atomic via the mode parameter.
486
- * await db.batch([
487
- * { sql: "INSERT INTO users(name) VALUES (?)", args: ["Eve"] },
488
- * { sql: "INSERT INTO users(name) VALUES (?)", args: ["Frank"] },
489
- * ], "immediate");
490
- *
491
- * @example
492
- * // Atomic via the transaction() API for mixed workloads.
493
- * const txn = db.transaction(async () => {
494
- * await db.batch([{ sql: "INSERT INTO users(name) VALUES (?)", args: ["Eve"] }]);
495
- * await db.execute("UPDATE counters SET n = n + 1");
496
- * });
497
- * await txn.immediate();
498
- */
499
- batch(statements: BatchStatement[], mode?: BatchMode, queryOptions?: QueryOptions): Promise<any>;
500
- /**
501
- * Execute a pragma.
502
- *
503
- * @param pragma - The pragma to execute
504
- * @returns Promise resolving to the result of the pragma
505
- */
506
- pragma(pragma: string, queryOptions?: QueryOptions): Promise<any>;
507
- /**
508
- * Sets the default safe integers mode for all statements from this connection.
509
- *
510
- * @param toggle - Whether to use safe integers by default.
511
- */
512
- defaultSafeIntegers(toggle?: boolean): void;
513
- /**
514
- * Returns a function that executes the given function in a transaction.
515
- *
516
- * @param fn - The function to wrap in a transaction
517
- * @returns A function that will execute fn within a transaction
518
- *
519
- * @example
520
- * ```typescript
521
- * const insert = await client.prepare("INSERT INTO users (name) VALUES (?)");
522
- * const insertMany = client.transaction((users) => {
523
- * for (const user of users) {
524
- * insert.run([user]);
525
- * }
526
- * });
527
- *
528
- * await insertMany(['Alice', 'Bob', 'Charlie']);
529
- * ```
530
- */
531
- transaction(fn: (...args: any[]) => any): any;
532
- /**
533
- * Close the connection.
534
- *
535
- * This sends a close request to the server to properly clean up the stream.
536
- */
537
- close(): Promise<void>;
538
- reconnect(): Promise<void>;
539
- }
540
- /**
541
- * Create a new connection to a Turso database.
542
- *
543
- * This is a lightweight operation — it only allocates a config object. No network
544
- * I/O happens until the first query. The underlying `fetch()` implementation
545
- * automatically pools TCP/TLS connections to the same origin, so creating many
546
- * connections is cheap.
547
- *
548
- * Each connection is single-stream: concurrent calls on the same connection are
549
- * automatically serialized. For true parallelism, create multiple connections:
550
- *
551
- * ```typescript
552
- * import { connect } from "@tursodatabase/serverless";
553
- *
554
- * const config = { url: process.env.TURSO_URL, authToken: process.env.TURSO_TOKEN };
555
- *
556
- * // Sequential (single connection is fine)
557
- * const conn = connect(config);
558
- * const a = await conn.execute("SELECT 1");
559
- * const b = await conn.execute("SELECT 2");
560
- *
561
- * // Parallel (use separate connections)
562
- * const [x, y] = await Promise.all([
563
- * connect(config).execute("SELECT 1"),
564
- * connect(config).execute("SELECT 2"),
565
- * ]);
566
- * ```
567
- *
568
- * @param config - Configuration object with database URL and auth token
569
- * @returns A new Connection instance
570
- */
571
- declare function connect(config: Config): Connection;
572
-
573
- declare class DatabaseError extends Error {
574
- /** Machine-readable error code (e.g., "SQLITE_CONSTRAINT") */
575
- code?: string;
576
- /** Raw numeric error code */
577
- rawCode?: number;
578
- /** Original error that caused this error */
579
- cause?: Error;
580
- constructor(message: string, code?: string, rawCode?: number, cause?: Error);
581
- }
582
- /**
583
- * Error thrown when a query exceeds the configured timeout.
584
- *
585
- * This is a subclass of `DatabaseError` with `code` set to `"TIMEOUT"`.
586
- * Catch this type to distinguish timeouts from other database errors
587
- * and decide whether to retry or fail gracefully.
588
- */
589
- declare class TimeoutError extends DatabaseError {
590
- constructor(message?: string, cause?: Error);
591
- }
592
-
593
- export { type BatchStatement, type Column, type Config, Connection, DatabaseError, ENCRYPTION_KEY_HEADER, type QueryOptions, Session, type SessionConfig, Statement, TimeoutError, connect };
1
+ export { Connection, connect, type Config } from './connection.js';
2
+ export { Statement } from './statement.js';
3
+ export { Session, type SessionConfig } from './session.js';
4
+ export { DatabaseError, TimeoutError } from './error.js';
5
+ export { type Column, type QueryOptions, ENCRYPTION_KEY_HEADER } from './protocol.js';