@tursodatabase/serverless 1.1.1 → 1.1.2-pre.1

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,5 +1,516 @@
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';
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
+ * Configuration options for a session.
44
+ */
45
+ interface SessionConfig {
46
+ /** Database URL */
47
+ url: string;
48
+ /** Authentication token (optional for local development with turso dev) */
49
+ authToken?: string;
50
+ /**
51
+ * Encryption key for the remote database (base64 encoded)
52
+ * to enable access to encrypted Turso Cloud databases.
53
+ */
54
+ remoteEncryptionKey?: string;
55
+ /** Default maximum query execution time in milliseconds before interruption. */
56
+ defaultQueryTimeout?: number;
57
+ }
58
+ /**
59
+ * A database session that manages the connection state and baton.
60
+ *
61
+ * Each session maintains its own connection state and can execute SQL statements
62
+ * independently without interfering with other sessions.
63
+ */
64
+ declare class Session {
65
+ private config;
66
+ private baton;
67
+ private baseUrl;
68
+ constructor(config: SessionConfig);
69
+ private createAbortSignal;
70
+ /**
71
+ * Describe a SQL statement to get its column metadata.
72
+ *
73
+ * @param sql - The SQL statement to describe
74
+ * @returns Promise resolving to the statement description
75
+ */
76
+ describe(sql: string, queryOptions?: QueryOptions): Promise<DescribeResult>;
77
+ /**
78
+ * Execute a SQL statement and return all results.
79
+ *
80
+ * @param sql - The SQL statement to execute
81
+ * @param args - Optional array of parameter values or object with named parameters
82
+ * @param safeIntegers - Whether to return integers as BigInt
83
+ * @returns Promise resolving to the complete result set
84
+ */
85
+ execute(sql: string, args?: any[] | Record<string, any>, safeIntegers?: boolean, queryOptions?: QueryOptions): Promise<any>;
86
+ /**
87
+ * Execute a SQL statement and return the raw response and entries.
88
+ *
89
+ * @param sql - The SQL statement to execute
90
+ * @param args - Optional array of parameter values or object with named parameters
91
+ * @returns Promise resolving to the raw response and cursor entries
92
+ */
93
+ executeRaw(sql: string, args?: any[] | Record<string, any>, queryOptions?: QueryOptions): Promise<{
94
+ response: CursorResponse;
95
+ entries: AsyncGenerator<CursorEntry>;
96
+ }>;
97
+ /**
98
+ * Process cursor entries into a structured result.
99
+ *
100
+ * @param entries - Async generator of cursor entries
101
+ * @returns Promise resolving to the processed result
102
+ */
103
+ processCursorEntries(entries: AsyncGenerator<CursorEntry>, safeIntegers?: boolean): Promise<any>;
104
+ /**
105
+ * Create a row object with both array and named property access.
106
+ *
107
+ * @param values - Array of column values
108
+ * @param columns - Array of column names
109
+ * @returns Row object with dual access patterns
110
+ */
111
+ createRowObject(values: any[], columns: string[]): any;
112
+ /**
113
+ * Execute multiple SQL statements in a batch.
114
+ *
115
+ * @param statements - Array of SQL statements to execute
116
+ * @returns Promise resolving to batch execution results
117
+ */
118
+ batch(statements: string[], queryOptions?: QueryOptions): Promise<any>;
119
+ /**
120
+ * Execute a sequence of SQL statements separated by semicolons.
121
+ *
122
+ * @param sql - SQL string containing multiple statements separated by semicolons
123
+ * @returns Promise resolving when all statements are executed
124
+ */
125
+ sequence(sql: string, queryOptions?: QueryOptions): Promise<void>;
126
+ /**
127
+ * Close the session.
128
+ *
129
+ * This sends a close request to the server to properly clean up the stream
130
+ * before resetting the local state.
131
+ */
132
+ close(): Promise<void>;
133
+ }
134
+
135
+ declare class AsyncLock {
136
+ private locked;
137
+ private queue;
138
+ acquire(): Promise<void>;
139
+ release(): void;
140
+ }
141
+
142
+ /**
143
+ * A prepared SQL statement that can be executed in multiple ways.
144
+ *
145
+ * Statements may either own a dedicated session or share a connection session to preserve transaction boundaries.
146
+ * Provides three execution modes:
147
+ * - `get(args?)`: Returns the first row or null
148
+ * - `all(args?)`: Returns all rows as an array
149
+ * - `iterate(args?)`: Returns an async iterator for streaming results
150
+ */
151
+ declare class Statement {
152
+ private session;
153
+ private sql;
154
+ private presentationMode;
155
+ private safeIntegerMode;
156
+ private columnMetadata;
157
+ private execLock?;
158
+ constructor(sessionConfig: SessionConfig, sql: string, columns?: Column[]);
159
+ /**
160
+ * Create a Statement that shares an existing session and serializes execution
161
+ * through the given lock. Used by Connection.prepare() so prepared statements
162
+ * participate in the connection's transaction scope.
163
+ */
164
+ static fromSession(session: Session, sql: string, columns: Column[] | undefined, execLock: AsyncLock): Statement;
165
+ /**
166
+ * Whether the prepared statement returns data.
167
+ *
168
+ * This is `true` for SELECT queries and statements with RETURNING clause,
169
+ * and `false` for INSERT, UPDATE, DELETE statements without RETURNING.
170
+ *
171
+ * @example
172
+ * ```typescript
173
+ * const stmt = await conn.prepare(sql);
174
+ * if (stmt.reader) {
175
+ * return stmt.all(args); // SELECT-like query
176
+ * } else {
177
+ * return stmt.run(args); // INSERT/UPDATE/DELETE
178
+ * }
179
+ * ```
180
+ */
181
+ get reader(): boolean;
182
+ /**
183
+ * Enable raw mode to return arrays instead of objects.
184
+ *
185
+ * @param raw Enable or disable raw mode. If you don't pass the parameter, raw mode is enabled.
186
+ * @returns This statement instance for chaining
187
+ *
188
+ * @example
189
+ * ```typescript
190
+ * const stmt = client.prepare("SELECT * FROM users WHERE id = ?");
191
+ * const row = await stmt.raw().get([1]);
192
+ * console.log(row); // [1, "Alice", "alice@example.org"]
193
+ * ```
194
+ */
195
+ raw(raw?: boolean): Statement;
196
+ /**
197
+ * Enable pluck mode to return only the first column value from each row.
198
+ *
199
+ * @param pluck Enable or disable pluck mode. If you don't pass the parameter, pluck mode is enabled.
200
+ * @returns This statement instance for chaining
201
+ *
202
+ * @example
203
+ * ```typescript
204
+ * const stmt = client.prepare("SELECT id FROM users");
205
+ * const ids = await stmt.pluck().all();
206
+ * console.log(ids); // [1, 2, 3, ...]
207
+ * ```
208
+ */
209
+ pluck(pluck?: boolean): Statement;
210
+ /**
211
+ * Sets safe integers mode for this statement.
212
+ *
213
+ * @param toggle Whether to use safe integers. If you don't pass the parameter, safe integers mode is enabled.
214
+ * @returns This statement instance for chaining
215
+ */
216
+ safeIntegers(toggle?: boolean): Statement;
217
+ /**
218
+ * Get column information for this statement.
219
+ *
220
+ * @returns Array of column metadata objects matching the native bindings format
221
+ *
222
+ * @example
223
+ * ```typescript
224
+ * const stmt = await client.prepare("SELECT id, name, email FROM users");
225
+ * const columns = stmt.columns();
226
+ * console.log(columns); // [{ name: 'id', type: 'INTEGER', column: null, database: null, table: null }, ...]
227
+ * ```
228
+ */
229
+ columns(): any[];
230
+ private withLock;
231
+ /**
232
+ * Executes the prepared statement.
233
+ *
234
+ * @param args - Optional array of parameter values or object with named parameters
235
+ * @returns Promise resolving to the result of the statement
236
+ *
237
+ * @example
238
+ * ```typescript
239
+ * const stmt = client.prepare("INSERT INTO users (name, email) VALUES (?, ?)");
240
+ * const result = await stmt.run(['John Doe', 'john.doe@example.com']);
241
+ * console.log(`Inserted user with ID ${result.lastInsertRowid}`);
242
+ * ```
243
+ */
244
+ run(args?: any, queryOptions?: QueryOptions): Promise<any>;
245
+ /**
246
+ * Execute the statement and return the first row.
247
+ *
248
+ * @param args - Optional array of parameter values or object with named parameters
249
+ * @returns Promise resolving to the first row or undefined if no results
250
+ *
251
+ * @example
252
+ * ```typescript
253
+ * const stmt = client.prepare("SELECT * FROM users WHERE id = ?");
254
+ * const user = await stmt.get([123]);
255
+ * if (user) {
256
+ * console.log(user.name);
257
+ * }
258
+ * ```
259
+ */
260
+ get(args?: any, queryOptions?: QueryOptions): Promise<any>;
261
+ /**
262
+ * Execute the statement and return all rows.
263
+ *
264
+ * @param args - Optional array of parameter values or object with named parameters
265
+ * @returns Promise resolving to an array of all result rows
266
+ *
267
+ * @example
268
+ * ```typescript
269
+ * const stmt = client.prepare("SELECT * FROM users WHERE active = ?");
270
+ * const activeUsers = await stmt.all([true]);
271
+ * console.log(`Found ${activeUsers.length} active users`);
272
+ * ```
273
+ */
274
+ all(args?: any, queryOptions?: QueryOptions): Promise<any[]>;
275
+ /**
276
+ * Execute the statement and return an async iterator for streaming results.
277
+ *
278
+ * This method provides memory-efficient processing of large result sets
279
+ * by streaming rows one at a time instead of loading everything into memory.
280
+ *
281
+ * @param args - Optional array of parameter values or object with named parameters
282
+ * @returns AsyncGenerator that yields individual rows
283
+ *
284
+ * @example
285
+ * ```typescript
286
+ * const stmt = client.prepare("SELECT * FROM large_table WHERE category = ?");
287
+ * for await (const row of stmt.iterate(['electronics'])) {
288
+ * // Process each row individually
289
+ * console.log(row.id, row.name);
290
+ * }
291
+ * ```
292
+ */
293
+ iterate(args?: any, queryOptions?: QueryOptions): AsyncGenerator<any>;
294
+ /**
295
+ * Normalize arguments to handle both single values and arrays.
296
+ * Matches the behavior of the native bindings.
297
+ */
298
+ private normalizeArgs;
299
+ }
300
+
301
+ /**
302
+ * Configuration options for connecting to a Turso database.
303
+ */
304
+ interface Config extends SessionConfig {
305
+ }
306
+ /**
307
+ * A connection to a Turso database.
308
+ *
309
+ * Provides methods for executing SQL statements and managing prepared statements.
310
+ * Uses the SQL over HTTP protocol with streaming cursor support.
311
+ *
312
+ * ## Concurrency model
313
+ *
314
+ * A Connection is **single-stream**: it can only run one statement at a time.
315
+ * This is not an implementation quirk — it follows from the SQL over HTTP protocol,
316
+ * where each request carries a baton from the previous response to sequence operations
317
+ * on the server. Concurrent calls on the same connection would race on that baton
318
+ * and corrupt the stream. This is the same model as SQLite itself (one execution
319
+ * at a time per connection).
320
+ *
321
+ * If you call `execute()` while another is in flight, the call automatically
322
+ * waits for the previous one to finish — just like the native
323
+ * `@tursodatabase/database` binding.
324
+ *
325
+ * ## Parallel queries
326
+ *
327
+ * For parallelism, create multiple connections. `connect()` is cheap — it just
328
+ * allocates a config object. No TCP connection is opened until the first `execute()`,
329
+ * and the underlying `fetch()` runtime automatically pools and reuses TCP/TLS
330
+ * connections to the same origin.
331
+ *
332
+ * ```typescript
333
+ * import { connect } from "@tursodatabase/serverless";
334
+ *
335
+ * const config = { url: process.env.TURSO_URL, authToken: process.env.TURSO_TOKEN };
336
+ *
337
+ * // Option 1: one connection per parallel query
338
+ * const [users, orders] = await Promise.all([
339
+ * connect(config).execute("SELECT * FROM users WHERE active = 1"),
340
+ * connect(config).execute("SELECT * FROM orders WHERE status = 'pending'"),
341
+ * ]);
342
+ *
343
+ * // Option 2: reusable pool for repeated parallel work
344
+ * const pool = Array.from({ length: 4 }, () => connect(config));
345
+ * const results = await Promise.all(
346
+ * queries.map((sql, i) => pool[i % pool.length].execute(sql))
347
+ * );
348
+ * ```
349
+ */
350
+ declare class Connection {
351
+ private config;
352
+ private session;
353
+ private isOpen;
354
+ private defaultSafeIntegerMode;
355
+ private _inTransaction;
356
+ private execLock;
357
+ constructor(config: Config);
358
+ /**
359
+ * Whether the database is currently in a transaction.
360
+ */
361
+ get inTransaction(): boolean;
362
+ /**
363
+ * Prepare a SQL statement for execution.
364
+ *
365
+ * Prepared statements created from a Connection use the same underlying session so transaction boundaries are preserved.
366
+ * This method fetches column metadata using the describe functionality.
367
+ *
368
+ * @param sql - The SQL statement to prepare
369
+ * @returns A Promise that resolves to a Statement object with column metadata
370
+ *
371
+ * @example
372
+ * ```typescript
373
+ * const stmt = await client.prepare("SELECT * FROM users WHERE id = ?");
374
+ * const columns = stmt.columns();
375
+ * const user = await stmt.get([123]);
376
+ * ```
377
+ */
378
+ prepare(sql: string): Promise<Statement>;
379
+ /**
380
+ * Execute a SQL statement and return all results.
381
+ *
382
+ * @param sql - The SQL statement to execute
383
+ * @param args - Optional array of parameter values
384
+ * @returns Promise resolving to the complete result set
385
+ *
386
+ * @example
387
+ * ```typescript
388
+ * const result = await client.execute("SELECT * FROM users WHERE id = ?", [123]);
389
+ * console.log(result.rows);
390
+ * ```
391
+ */
392
+ execute(sql: string, args?: any[], queryOptions?: QueryOptions): Promise<any>;
393
+ /**
394
+ * Execute a SQL statement and return all results.
395
+ *
396
+ * @param sql - The SQL statement to execute
397
+ * @returns Promise resolving to the complete result set
398
+ *
399
+ * @example
400
+ * ```typescript
401
+ * const result = await client.exec("SELECT * FROM users");
402
+ * console.log(result.rows);
403
+ * ```
404
+ */
405
+ exec(sql: string, queryOptions?: QueryOptions): Promise<any>;
406
+ /**
407
+ * Execute multiple SQL statements in a batch.
408
+ *
409
+ * @param statements - Array of SQL statements to execute
410
+ * @param mode - Optional transaction mode (currently unused)
411
+ * @returns Promise resolving to batch execution results
412
+ *
413
+ * @example
414
+ * ```typescript
415
+ * await client.batch([
416
+ * "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)",
417
+ * "INSERT INTO users (name) VALUES ('Alice')",
418
+ * "INSERT INTO users (name) VALUES ('Bob')"
419
+ * ]);
420
+ * ```
421
+ */
422
+ batch(statements: string[], mode?: string, queryOptions?: QueryOptions): Promise<any>;
423
+ /**
424
+ * Execute a pragma.
425
+ *
426
+ * @param pragma - The pragma to execute
427
+ * @returns Promise resolving to the result of the pragma
428
+ */
429
+ pragma(pragma: string, queryOptions?: QueryOptions): Promise<any>;
430
+ /**
431
+ * Sets the default safe integers mode for all statements from this connection.
432
+ *
433
+ * @param toggle - Whether to use safe integers by default.
434
+ */
435
+ defaultSafeIntegers(toggle?: boolean): void;
436
+ /**
437
+ * Returns a function that executes the given function in a transaction.
438
+ *
439
+ * @param fn - The function to wrap in a transaction
440
+ * @returns A function that will execute fn within a transaction
441
+ *
442
+ * @example
443
+ * ```typescript
444
+ * const insert = await client.prepare("INSERT INTO users (name) VALUES (?)");
445
+ * const insertMany = client.transaction((users) => {
446
+ * for (const user of users) {
447
+ * insert.run([user]);
448
+ * }
449
+ * });
450
+ *
451
+ * await insertMany(['Alice', 'Bob', 'Charlie']);
452
+ * ```
453
+ */
454
+ transaction(fn: (...args: any[]) => any): any;
455
+ /**
456
+ * Close the connection.
457
+ *
458
+ * This sends a close request to the server to properly clean up the stream.
459
+ */
460
+ close(): Promise<void>;
461
+ reconnect(): Promise<void>;
462
+ }
463
+ /**
464
+ * Create a new connection to a Turso database.
465
+ *
466
+ * This is a lightweight operation — it only allocates a config object. No network
467
+ * I/O happens until the first query. The underlying `fetch()` implementation
468
+ * automatically pools TCP/TLS connections to the same origin, so creating many
469
+ * connections is cheap.
470
+ *
471
+ * Each connection is single-stream: concurrent calls on the same connection are
472
+ * automatically serialized. For true parallelism, create multiple connections:
473
+ *
474
+ * ```typescript
475
+ * import { connect } from "@tursodatabase/serverless";
476
+ *
477
+ * const config = { url: process.env.TURSO_URL, authToken: process.env.TURSO_TOKEN };
478
+ *
479
+ * // Sequential (single connection is fine)
480
+ * const conn = connect(config);
481
+ * const a = await conn.execute("SELECT 1");
482
+ * const b = await conn.execute("SELECT 2");
483
+ *
484
+ * // Parallel (use separate connections)
485
+ * const [x, y] = await Promise.all([
486
+ * connect(config).execute("SELECT 1"),
487
+ * connect(config).execute("SELECT 2"),
488
+ * ]);
489
+ * ```
490
+ *
491
+ * @param config - Configuration object with database URL and auth token
492
+ * @returns A new Connection instance
493
+ */
494
+ declare function connect(config: Config): Connection;
495
+
496
+ declare class DatabaseError extends Error {
497
+ /** Machine-readable error code (e.g., "SQLITE_CONSTRAINT") */
498
+ code?: string;
499
+ /** Raw numeric error code */
500
+ rawCode?: number;
501
+ /** Original error that caused this error */
502
+ cause?: Error;
503
+ constructor(message: string, code?: string, rawCode?: number, cause?: Error);
504
+ }
505
+ /**
506
+ * Error thrown when a query exceeds the configured timeout.
507
+ *
508
+ * This is a subclass of `DatabaseError` with `code` set to `"TIMEOUT"`.
509
+ * Catch this type to distinguish timeouts from other database errors
510
+ * and decide whether to retry or fail gracefully.
511
+ */
512
+ declare class TimeoutError extends DatabaseError {
513
+ constructor(message?: string, cause?: Error);
514
+ }
515
+
516
+ export { type Column, type Config, Connection, DatabaseError, ENCRYPTION_KEY_HEADER, type QueryOptions, Session, type SessionConfig, Statement, TimeoutError, connect };