@cqlite/node 0.3.1-rc1
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/README.md +252 -0
- package/cqlite-node.darwin-arm64.node +0 -0
- package/index.d.ts +0 -0
- package/index.js +318 -0
- package/lib/error-wrapper.js +375 -0
- package/lib/index.d.ts +874 -0
- package/lib/index.js +102 -0
- package/package.json +68 -0
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,874 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CQLite Node.js bindings type definitions.
|
|
3
|
+
*
|
|
4
|
+
* This module provides complete type definitions for the CQLite Node.js
|
|
5
|
+
* bindings, enabling full TypeScript support with accurate CQL-to-JavaScript
|
|
6
|
+
* type mappings.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
* @module @cqlite/node
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/// <reference types="node" />
|
|
13
|
+
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// Value Types
|
|
16
|
+
// ============================================================================
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Duration value representing CQL duration type.
|
|
20
|
+
*
|
|
21
|
+
* CQL durations have three components: months, days, and nanoseconds.
|
|
22
|
+
* Months and days are stored separately because they have variable lengths.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const duration: Duration = { months: 1, days: 15, nanos: 3600000000000n };
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export interface Duration {
|
|
30
|
+
/** Number of months (-2^31 to 2^31-1) */
|
|
31
|
+
months: number;
|
|
32
|
+
/** Number of days (-2^31 to 2^31-1) */
|
|
33
|
+
days: number;
|
|
34
|
+
/** Number of nanoseconds (uses bigint for full i64 precision) */
|
|
35
|
+
nanos: bigint;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* User-Defined Type (UDT) value.
|
|
40
|
+
*
|
|
41
|
+
* UDTs are returned as plain objects with metadata fields:
|
|
42
|
+
* - `_type`: The UDT type name
|
|
43
|
+
* - `_keyspace`: The keyspace containing the UDT definition
|
|
44
|
+
* - Additional properties for each field in the UDT
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* const address: UdtValue = {
|
|
49
|
+
* _type: 'address',
|
|
50
|
+
* _keyspace: 'my_keyspace',
|
|
51
|
+
* street: '123 Main St',
|
|
52
|
+
* city: 'San Francisco',
|
|
53
|
+
* zip: '94102'
|
|
54
|
+
* };
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export interface UdtValue {
|
|
58
|
+
/** UDT type name */
|
|
59
|
+
_type: string;
|
|
60
|
+
/** Keyspace containing the UDT definition */
|
|
61
|
+
_keyspace: string;
|
|
62
|
+
/** UDT fields (additional properties) */
|
|
63
|
+
[field: string]: Value;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* All possible JavaScript values returned from CQL queries.
|
|
68
|
+
*
|
|
69
|
+
* This union type represents the complete mapping from CQL types to JavaScript:
|
|
70
|
+
*
|
|
71
|
+
* | CQL Type | JavaScript Type |
|
|
72
|
+
* |----------|-----------------|
|
|
73
|
+
* | null | `null` |
|
|
74
|
+
* | boolean | `boolean` |
|
|
75
|
+
* | tinyint, smallint, int, float, double | `number` |
|
|
76
|
+
* | bigint, counter, time, varint | `bigint` |
|
|
77
|
+
* | text, varchar, ascii | `string` |
|
|
78
|
+
* | uuid, timeuuid | `string` (formatted UUID) |
|
|
79
|
+
* | decimal | `string` (preserves precision) |
|
|
80
|
+
* | inet | `string` (IP address format) |
|
|
81
|
+
* | blob | `Buffer` |
|
|
82
|
+
* | timestamp, date | `Date` |
|
|
83
|
+
* | duration | `Duration` object |
|
|
84
|
+
* | list, tuple | `Value[]` |
|
|
85
|
+
* | set | `Set<Value>` |
|
|
86
|
+
* | map | `Map<Value, Value>` |
|
|
87
|
+
* | udt | `UdtValue` object |
|
|
88
|
+
* | frozen<T> | unwrapped inner type |
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* // Values from executeNative() are properly typed
|
|
93
|
+
* const result = await db.executeNative('SELECT * FROM users');
|
|
94
|
+
* const row = result.rows[0];
|
|
95
|
+
* const name: Value = row.name; // string
|
|
96
|
+
* const age: Value = row.age; // number
|
|
97
|
+
* const balance: Value = row.balance; // bigint
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
export type Value =
|
|
101
|
+
| null
|
|
102
|
+
| boolean
|
|
103
|
+
| number
|
|
104
|
+
| bigint
|
|
105
|
+
| string
|
|
106
|
+
| Buffer
|
|
107
|
+
| Date
|
|
108
|
+
| Duration
|
|
109
|
+
| Value[]
|
|
110
|
+
| Set<Value>
|
|
111
|
+
| Map<Value, Value>
|
|
112
|
+
| UdtValue;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* A single row from a query result.
|
|
116
|
+
*
|
|
117
|
+
* Rows are plain JavaScript objects with column names as keys
|
|
118
|
+
* and CQL values converted to JavaScript types.
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```typescript
|
|
122
|
+
* const result = await db.executeNative('SELECT id, name, age FROM users');
|
|
123
|
+
* for (const row of result.rows) {
|
|
124
|
+
* console.log(row.id); // string (UUID)
|
|
125
|
+
* console.log(row.name); // string
|
|
126
|
+
* console.log(row.age); // number
|
|
127
|
+
* }
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
export interface Row {
|
|
131
|
+
[column: string]: Value;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// ============================================================================
|
|
135
|
+
// Column Metadata
|
|
136
|
+
// ============================================================================
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Column metadata information.
|
|
140
|
+
*
|
|
141
|
+
* Provides information about a column in the query result set,
|
|
142
|
+
* including name, data type, and nullability.
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```typescript
|
|
146
|
+
* const result = await db.execute('SELECT * FROM users');
|
|
147
|
+
* for (const col of result.columns) {
|
|
148
|
+
* console.log(`${col.name}: ${col.dataType} (nullable: ${col.nullable})`);
|
|
149
|
+
* }
|
|
150
|
+
* ```
|
|
151
|
+
*/
|
|
152
|
+
export interface ColumnInfo {
|
|
153
|
+
/** Column name. */
|
|
154
|
+
name: string;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* CQL data type as a string.
|
|
158
|
+
*
|
|
159
|
+
* Examples: "Text", "Integer", "BigInt", "Uuid", "Timestamp",
|
|
160
|
+
* "List", "Set", "Map", "Tuple", "Udt"
|
|
161
|
+
*/
|
|
162
|
+
dataType: string;
|
|
163
|
+
|
|
164
|
+
/** Whether the column can contain null values. */
|
|
165
|
+
nullable: boolean;
|
|
166
|
+
|
|
167
|
+
/** Column position in the result set (0-indexed). */
|
|
168
|
+
position: number;
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Original table name.
|
|
172
|
+
*
|
|
173
|
+
* Present for queries involving multiple tables (joins).
|
|
174
|
+
* May be null for single-table queries or computed columns.
|
|
175
|
+
*/
|
|
176
|
+
tableName: string | null;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// ============================================================================
|
|
180
|
+
// Query Results
|
|
181
|
+
// ============================================================================
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Query execution result.
|
|
185
|
+
*
|
|
186
|
+
* Contains the query results serialized as JSON values for JavaScript
|
|
187
|
+
* consumption, along with metadata about the execution.
|
|
188
|
+
*
|
|
189
|
+
* For native JavaScript types (BigInt, Buffer, Date, Set, Map),
|
|
190
|
+
* use `Database.executeNative()` instead.
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* ```typescript
|
|
194
|
+
* const result = await db.execute('SELECT * FROM users LIMIT 10');
|
|
195
|
+
* console.log(`Got ${result.rowCount} rows in ${result.executionTimeMs}ms`);
|
|
196
|
+
* for (const row of result.rows) {
|
|
197
|
+
* console.log(row.name);
|
|
198
|
+
* }
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
201
|
+
export interface QueryResult {
|
|
202
|
+
/**
|
|
203
|
+
* Result rows as JSON-serializable objects.
|
|
204
|
+
*
|
|
205
|
+
* Values are JSON-serialized versions of CQL types:
|
|
206
|
+
* - BigInt/Counter: number (may lose precision for values > 2^53)
|
|
207
|
+
* - Blob: base64 string
|
|
208
|
+
* - Timestamp: ISO 8601 string
|
|
209
|
+
* - Set/Map: Array representations
|
|
210
|
+
* - Varint: Hex string `"0x{hex}"` (e.g., `"0x7f"` for 127)
|
|
211
|
+
* - Decimal: String `"decimal:{scale}:0x{hex}"` (e.g., `"decimal:2:0x7b"` for 1.23)
|
|
212
|
+
*
|
|
213
|
+
* For native types with full precision, use `executeNative()`.
|
|
214
|
+
*
|
|
215
|
+
* @deprecated The execute() method uses legacy JSON encoding. Use executeNative() for proper type fidelity.
|
|
216
|
+
*/
|
|
217
|
+
rows: Record<string, unknown>[];
|
|
218
|
+
|
|
219
|
+
/** Number of rows returned. */
|
|
220
|
+
rowCount: number;
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Number of rows returned (M4 spec alias for rowCount).
|
|
224
|
+
*
|
|
225
|
+
* Note: CQLite is read-only. For SELECT queries, this represents
|
|
226
|
+
* the number of rows read, not modified.
|
|
227
|
+
*/
|
|
228
|
+
rowsAffected: number;
|
|
229
|
+
|
|
230
|
+
/** Query execution time in milliseconds. */
|
|
231
|
+
executionTimeMs: number;
|
|
232
|
+
|
|
233
|
+
/** Column metadata for the result set. */
|
|
234
|
+
columns: ColumnInfo[];
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Query result with native JavaScript types.
|
|
239
|
+
*
|
|
240
|
+
* Returned by `Database.executeNative()`. Uses native JavaScript types
|
|
241
|
+
* (BigInt, Buffer, Date, Set, Map) instead of JSON-serializable values.
|
|
242
|
+
*
|
|
243
|
+
* @example
|
|
244
|
+
* ```typescript
|
|
245
|
+
* const result = await db.executeNative('SELECT * FROM users');
|
|
246
|
+
* for (const row of result.rows) {
|
|
247
|
+
* // Proper types preserved
|
|
248
|
+
* if (typeof row.balance === 'bigint') {
|
|
249
|
+
* console.log(`Balance: ${row.balance}`);
|
|
250
|
+
* }
|
|
251
|
+
* }
|
|
252
|
+
* ```
|
|
253
|
+
*/
|
|
254
|
+
export interface NativeQueryResult {
|
|
255
|
+
/**
|
|
256
|
+
* Result rows with native JavaScript types.
|
|
257
|
+
* Each row is an object with column names as keys.
|
|
258
|
+
*/
|
|
259
|
+
rows: Row[];
|
|
260
|
+
|
|
261
|
+
/** Number of rows returned. */
|
|
262
|
+
rowCount: number;
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Number of rows returned (M4 spec alias for rowCount).
|
|
266
|
+
*
|
|
267
|
+
* Note: CQLite is read-only. For SELECT queries, this represents
|
|
268
|
+
* the number of rows read, not modified.
|
|
269
|
+
*/
|
|
270
|
+
rowsAffected: number;
|
|
271
|
+
|
|
272
|
+
/** Query execution time in milliseconds. */
|
|
273
|
+
executionTimeMs: number;
|
|
274
|
+
|
|
275
|
+
/** Column metadata for the result set. */
|
|
276
|
+
columns: ColumnInfo[];
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// ============================================================================
|
|
280
|
+
// Database Statistics
|
|
281
|
+
// ============================================================================
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Database statistics.
|
|
285
|
+
*
|
|
286
|
+
* Provides information about the database state including
|
|
287
|
+
* storage and memory metrics.
|
|
288
|
+
*
|
|
289
|
+
* @example
|
|
290
|
+
* ```typescript
|
|
291
|
+
* const stats = await db.getStats();
|
|
292
|
+
* console.log(`SSTables: ${stats.totalSstables}`);
|
|
293
|
+
* console.log(`Total rows: ${stats.totalRows}`);
|
|
294
|
+
* console.log(`Memory: ${stats.memoryUsedBytes} bytes`);
|
|
295
|
+
* ```
|
|
296
|
+
*/
|
|
297
|
+
export interface DatabaseStats {
|
|
298
|
+
/** Total number of SSTable files. */
|
|
299
|
+
totalSstables: number;
|
|
300
|
+
|
|
301
|
+
/** Total number of rows across all SSTables. */
|
|
302
|
+
totalRows: bigint;
|
|
303
|
+
|
|
304
|
+
/** Memory currently used by the database in bytes. */
|
|
305
|
+
memoryUsedBytes: bigint;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// ============================================================================
|
|
309
|
+
// Configuration
|
|
310
|
+
// ============================================================================
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Database open options.
|
|
314
|
+
*
|
|
315
|
+
* Configuration options for opening a database.
|
|
316
|
+
*
|
|
317
|
+
* @example
|
|
318
|
+
* ```typescript
|
|
319
|
+
* const options: DatabaseOptions = {
|
|
320
|
+
* schema: '/path/to/schema.cql',
|
|
321
|
+
* memoryLimit: 256 * 1024 * 1024, // 256MB
|
|
322
|
+
* cacheEnabled: true
|
|
323
|
+
* };
|
|
324
|
+
* const db = await Database.open('/path/to/data', options);
|
|
325
|
+
* ```
|
|
326
|
+
*/
|
|
327
|
+
export interface DatabaseOptions {
|
|
328
|
+
/**
|
|
329
|
+
* Path to a CQL schema file (.cql).
|
|
330
|
+
* If provided, the schema will be loaded and used for query execution.
|
|
331
|
+
*/
|
|
332
|
+
schema?: string;
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Maximum memory usage in bytes.
|
|
336
|
+
* Minimum: 1 byte. Values less than 1 will be rejected.
|
|
337
|
+
* Default: 1GB (1073741824 bytes).
|
|
338
|
+
* Controls the overall memory budget for caches and internal buffers.
|
|
339
|
+
*
|
|
340
|
+
* @example
|
|
341
|
+
* ```typescript
|
|
342
|
+
* { memoryLimit: 256 * 1024 * 1024 } // 256MB
|
|
343
|
+
* ```
|
|
344
|
+
*/
|
|
345
|
+
memoryLimit?: number;
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Enable or disable all caches (block, row, query).
|
|
349
|
+
* Default: true (caches enabled).
|
|
350
|
+
* Set to false to minimize memory usage at the cost of performance.
|
|
351
|
+
*/
|
|
352
|
+
cacheEnabled?: boolean;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Configuration for streaming query execution.
|
|
357
|
+
*
|
|
358
|
+
* Controls memory usage during large result set iteration.
|
|
359
|
+
* Used with `executeStreaming()` for memory-efficient processing
|
|
360
|
+
* of large result sets.
|
|
361
|
+
*
|
|
362
|
+
* ## Memory Budget
|
|
363
|
+
*
|
|
364
|
+
* Default values (~11MB peak usage):
|
|
365
|
+
* - bufferSize: 1024 rows x ~1KB = ~1MB in flight
|
|
366
|
+
* - chunkSize: 10000 rows x ~1KB = ~10MB per chunk
|
|
367
|
+
*
|
|
368
|
+
* For rows with large blobs, reduce buffer sizes proportionally.
|
|
369
|
+
*
|
|
370
|
+
* @example
|
|
371
|
+
* ```typescript
|
|
372
|
+
* const config: StreamingConfig = { bufferSize: 512, chunkSize: 5000 };
|
|
373
|
+
* for await (const row of db.executeStreaming(query, config)) {
|
|
374
|
+
* console.log(row);
|
|
375
|
+
* }
|
|
376
|
+
* ```
|
|
377
|
+
*/
|
|
378
|
+
export interface StreamingConfig {
|
|
379
|
+
/**
|
|
380
|
+
* Number of rows to buffer in memory during streaming.
|
|
381
|
+
* Controls backpressure. Default: 1024.
|
|
382
|
+
*/
|
|
383
|
+
bufferSize?: number;
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Number of rows per fetch chunk from storage.
|
|
387
|
+
* Larger chunks improve throughput, smaller chunks reduce memory.
|
|
388
|
+
* Default: 10000.
|
|
389
|
+
*/
|
|
390
|
+
chunkSize?: number;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Streaming query result for memory-efficient processing.
|
|
395
|
+
*
|
|
396
|
+
* Implements `AsyncIterable<Row>` for use with `for await...of` loops.
|
|
397
|
+
* Memory stays bounded by StreamingConfig settings (default ~11MB peak).
|
|
398
|
+
*
|
|
399
|
+
* ## Resource Cleanup
|
|
400
|
+
*
|
|
401
|
+
* Resources are automatically cleaned up when:
|
|
402
|
+
* 1. All rows are consumed (iteration completes)
|
|
403
|
+
* 2. `break` exits the loop early (calls `return()` automatically)
|
|
404
|
+
* 3. `close()` is called explicitly
|
|
405
|
+
* 4. An error occurs during iteration
|
|
406
|
+
*
|
|
407
|
+
* @example
|
|
408
|
+
* ```typescript
|
|
409
|
+
* // Basic streaming - no await on executeStreaming
|
|
410
|
+
* const stream = db.executeStreaming('SELECT * FROM large_table');
|
|
411
|
+
* for await (const row of stream) {
|
|
412
|
+
* console.log(row.name);
|
|
413
|
+
* // Memory stays bounded - only bufferSize rows in flight
|
|
414
|
+
* }
|
|
415
|
+
*
|
|
416
|
+
* // Or use directly in for-await loop
|
|
417
|
+
* for await (const row of db.executeStreaming('SELECT * FROM large_table')) {
|
|
418
|
+
* if (row.id === targetId) {
|
|
419
|
+
* break; // Resources cleaned up automatically
|
|
420
|
+
* }
|
|
421
|
+
* }
|
|
422
|
+
*
|
|
423
|
+
* // Access metadata during streaming (available after first iteration)
|
|
424
|
+
* console.log(`Received ${stream.rowsReceived} rows so far`);
|
|
425
|
+
* console.log(`Columns: ${stream.columns.map(c => c.name).join(', ')}`);
|
|
426
|
+
* ```
|
|
427
|
+
*/
|
|
428
|
+
export interface StreamingResult extends AsyncIterable<Row> {
|
|
429
|
+
/**
|
|
430
|
+
* Number of rows received so far.
|
|
431
|
+
*
|
|
432
|
+
* This counter increases as rows are yielded from the stream.
|
|
433
|
+
* Useful for progress tracking and debugging.
|
|
434
|
+
*/
|
|
435
|
+
readonly rowsReceived: number;
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Column metadata for the result set.
|
|
439
|
+
*
|
|
440
|
+
* Contains information about each column's name, type, and nullability.
|
|
441
|
+
* Returns an empty array before iteration begins. Columns are populated
|
|
442
|
+
* after the first row is fetched.
|
|
443
|
+
*
|
|
444
|
+
* @example
|
|
445
|
+
* ```typescript
|
|
446
|
+
* const stream = db.executeStreaming('SELECT * FROM table');
|
|
447
|
+
* console.log(stream.columns); // [] - empty before iteration
|
|
448
|
+
*
|
|
449
|
+
* for await (const row of stream) {
|
|
450
|
+
* console.log(stream.columns); // ColumnInfo[] - populated during iteration
|
|
451
|
+
* break;
|
|
452
|
+
* }
|
|
453
|
+
* ```
|
|
454
|
+
*/
|
|
455
|
+
readonly columns: ColumnInfo[];
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Release resources early.
|
|
459
|
+
*
|
|
460
|
+
* Called automatically when the iterator is exhausted or the loop exits.
|
|
461
|
+
* Call explicitly to release resources before consuming all rows.
|
|
462
|
+
* Safe to call multiple times - subsequent calls are no-ops.
|
|
463
|
+
*/
|
|
464
|
+
close(): void;
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Async iterator protocol implementation.
|
|
468
|
+
*
|
|
469
|
+
* Prefer using `for await...of` over calling this directly.
|
|
470
|
+
*/
|
|
471
|
+
[Symbol.asyncIterator](): AsyncIterator<Row>;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// ============================================================================
|
|
475
|
+
// Error Handling
|
|
476
|
+
// ============================================================================
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* Error codes for CQLite errors.
|
|
480
|
+
*
|
|
481
|
+
* These codes map to the ErrorCategory enum in cqlite-core and can be used
|
|
482
|
+
* for programmatic error handling.
|
|
483
|
+
*
|
|
484
|
+
* @example
|
|
485
|
+
* ```typescript
|
|
486
|
+
* try {
|
|
487
|
+
* await db.execute('INVALID SQL');
|
|
488
|
+
* } catch (e) {
|
|
489
|
+
* const err = e as CqliteError;
|
|
490
|
+
* switch (err.code) {
|
|
491
|
+
* case 'PARSE':
|
|
492
|
+
* console.log('SQL syntax error');
|
|
493
|
+
* break;
|
|
494
|
+
* case 'IO':
|
|
495
|
+
* console.log('I/O error, may be retryable');
|
|
496
|
+
* break;
|
|
497
|
+
* }
|
|
498
|
+
* }
|
|
499
|
+
* ```
|
|
500
|
+
*/
|
|
501
|
+
export type ErrorCode =
|
|
502
|
+
| 'IO' // System-level I/O errors (file access, memory, timeout)
|
|
503
|
+
| 'SCHEMA' // Schema-related errors (table not found, invalid schema)
|
|
504
|
+
| 'QUERY' // Query execution errors (unsupported queries)
|
|
505
|
+
| 'PARSE' // Data/parsing errors (CQL syntax, type conversion)
|
|
506
|
+
| 'CONFIG' // Configuration errors
|
|
507
|
+
| 'STORAGE' // Storage engine errors
|
|
508
|
+
| 'CONCURRENCY' // Concurrency/lock errors
|
|
509
|
+
| 'NOT_FOUND' // Resource not found
|
|
510
|
+
| 'CONFLICT' // Resource conflicts (already exists)
|
|
511
|
+
| 'INVALID_INPUT' // Logic errors (invalid operation, invalid state)
|
|
512
|
+
| 'CONSTRAINT' // Constraint violations
|
|
513
|
+
| 'TRANSACTION' // Transaction errors
|
|
514
|
+
| 'PLATFORM' // Platform-specific errors (WASM)
|
|
515
|
+
| 'INTERNAL'; // Internal errors
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Error category names for CQLite errors.
|
|
519
|
+
*
|
|
520
|
+
* These categories map to the ErrorCategory enum in cqlite-core and
|
|
521
|
+
* provide semantic grouping for error types.
|
|
522
|
+
*/
|
|
523
|
+
export type ErrorCategory =
|
|
524
|
+
| 'System'
|
|
525
|
+
| 'Data'
|
|
526
|
+
| 'Schema'
|
|
527
|
+
| 'Query'
|
|
528
|
+
| 'Configuration'
|
|
529
|
+
| 'Storage'
|
|
530
|
+
| 'Concurrency'
|
|
531
|
+
| 'NotFound'
|
|
532
|
+
| 'Conflict'
|
|
533
|
+
| 'Logic'
|
|
534
|
+
| 'Constraint'
|
|
535
|
+
| 'Transaction'
|
|
536
|
+
| 'Platform'
|
|
537
|
+
| 'Internal';
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* CQLite error interface.
|
|
541
|
+
*
|
|
542
|
+
* All errors thrown by CQLite methods extend the standard Error
|
|
543
|
+
* with additional properties for error categorization and recovery.
|
|
544
|
+
*
|
|
545
|
+
* @example
|
|
546
|
+
* ```typescript
|
|
547
|
+
* try {
|
|
548
|
+
* await db.execute('INVALID SQL');
|
|
549
|
+
* } catch (e) {
|
|
550
|
+
* const err = e as CqliteError;
|
|
551
|
+
* console.log(`Error [${err.code}]: ${err.message}`);
|
|
552
|
+
* console.log(`Category: ${err.category}`);
|
|
553
|
+
* if (err.isRecoverable) {
|
|
554
|
+
* console.log('This error may succeed on retry');
|
|
555
|
+
* }
|
|
556
|
+
* }
|
|
557
|
+
* ```
|
|
558
|
+
*/
|
|
559
|
+
export interface CqliteError extends Error {
|
|
560
|
+
/**
|
|
561
|
+
* Error code identifying the type of error.
|
|
562
|
+
*
|
|
563
|
+
* Use this for programmatic error handling with switch/case.
|
|
564
|
+
*/
|
|
565
|
+
code: ErrorCode;
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Error category name from the Rust ErrorCategory enum.
|
|
569
|
+
*
|
|
570
|
+
* Provides semantic grouping for error types.
|
|
571
|
+
*/
|
|
572
|
+
category: ErrorCategory;
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* Whether the error is potentially recoverable.
|
|
576
|
+
*
|
|
577
|
+
* Recoverable errors (like I/O or concurrency errors) may succeed
|
|
578
|
+
* if retried. Non-recoverable errors (like parse errors) will
|
|
579
|
+
* always fail with the same input.
|
|
580
|
+
*/
|
|
581
|
+
isRecoverable: boolean;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// ============================================================================
|
|
585
|
+
// Prepared Statements
|
|
586
|
+
// ============================================================================
|
|
587
|
+
|
|
588
|
+
/**
|
|
589
|
+
* Statistics about a prepared statement.
|
|
590
|
+
*
|
|
591
|
+
* Contains query plan information useful for optimization
|
|
592
|
+
* and debugging query performance.
|
|
593
|
+
*/
|
|
594
|
+
export interface PreparedStatementStats {
|
|
595
|
+
/** Number of parameters in the query. */
|
|
596
|
+
parameterCount: number;
|
|
597
|
+
|
|
598
|
+
/** Type of execution plan (TableScan, IndexScan, PointLookup). */
|
|
599
|
+
planType: string;
|
|
600
|
+
|
|
601
|
+
/** Estimated execution cost (relative metric for comparing plans). */
|
|
602
|
+
estimatedCost: number;
|
|
603
|
+
|
|
604
|
+
/** Estimated number of rows to be returned. */
|
|
605
|
+
estimatedRows: bigint;
|
|
606
|
+
|
|
607
|
+
/** Whether the query is cache-friendly. */
|
|
608
|
+
cacheFriendly: boolean;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* A prepared CQL statement.
|
|
613
|
+
*
|
|
614
|
+
* PreparedStatement holds a pre-parsed and planned query that can be
|
|
615
|
+
* inspected for metadata and statistics. Created via Database.prepare().
|
|
616
|
+
*/
|
|
617
|
+
export declare class PreparedStatement {
|
|
618
|
+
/** The original CQL query text. */
|
|
619
|
+
readonly query: string;
|
|
620
|
+
|
|
621
|
+
/** Number of parameters in the query. */
|
|
622
|
+
readonly parameterCount: number;
|
|
623
|
+
|
|
624
|
+
/** Get statistics about this prepared statement. */
|
|
625
|
+
stats(): PreparedStatementStats;
|
|
626
|
+
|
|
627
|
+
/** String representation of the prepared statement. */
|
|
628
|
+
toString(): string;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
// ============================================================================
|
|
632
|
+
// Database Class
|
|
633
|
+
// ============================================================================
|
|
634
|
+
|
|
635
|
+
/**
|
|
636
|
+
* A CQLite database handle.
|
|
637
|
+
*
|
|
638
|
+
* Use `Database.open()` to create a Database instance.
|
|
639
|
+
* Always close the database when done to release resources.
|
|
640
|
+
*
|
|
641
|
+
* All methods that can fail throw `CqliteError` with structured
|
|
642
|
+
* error properties (code, category, isRecoverable).
|
|
643
|
+
*
|
|
644
|
+
* ## Thread Safety
|
|
645
|
+
*
|
|
646
|
+
* Database handles are thread-safe and can be shared across worker threads.
|
|
647
|
+
* The `close()` method is idempotent - calling it multiple times is safe.
|
|
648
|
+
*
|
|
649
|
+
* @example
|
|
650
|
+
* ```typescript
|
|
651
|
+
* import { Database, CqliteError } from '@cqlite/node';
|
|
652
|
+
*
|
|
653
|
+
* try {
|
|
654
|
+
* const db = await Database.open('/path/to/data', {
|
|
655
|
+
* schema: '/path/to/schema.cql'
|
|
656
|
+
* });
|
|
657
|
+
*
|
|
658
|
+
* const result = await db.execute('SELECT * FROM users LIMIT 10');
|
|
659
|
+
* console.log(`Got ${result.rowCount} rows`);
|
|
660
|
+
*
|
|
661
|
+
* // For native types (BigInt, Buffer, Date, etc.)
|
|
662
|
+
* const native = await db.executeNative('SELECT * FROM users LIMIT 10');
|
|
663
|
+
* for (const row of native.rows) {
|
|
664
|
+
* console.log(row.name, typeof row.balance);
|
|
665
|
+
* }
|
|
666
|
+
*
|
|
667
|
+
* await db.close();
|
|
668
|
+
* } catch (e) {
|
|
669
|
+
* const err = e as CqliteError;
|
|
670
|
+
* console.log(`Error [${err.code}]: ${err.message}`);
|
|
671
|
+
* }
|
|
672
|
+
* ```
|
|
673
|
+
*/
|
|
674
|
+
export declare class Database {
|
|
675
|
+
/**
|
|
676
|
+
* Opens a database at the specified data directory.
|
|
677
|
+
*
|
|
678
|
+
* @param dataDir - Path to the SSTable data directory
|
|
679
|
+
* @param options - Optional configuration (schema path, etc.)
|
|
680
|
+
* @returns Promise resolving to a Database instance
|
|
681
|
+
* @throws {CqliteError} If the database cannot be opened
|
|
682
|
+
*
|
|
683
|
+
* @example
|
|
684
|
+
* ```typescript
|
|
685
|
+
* // Basic open
|
|
686
|
+
* const db = await Database.open('/path/to/sstables');
|
|
687
|
+
*
|
|
688
|
+
* // With schema file
|
|
689
|
+
* const db = await Database.open('/path/to/sstables', {
|
|
690
|
+
* schema: '/path/to/schema.cql'
|
|
691
|
+
* });
|
|
692
|
+
* ```
|
|
693
|
+
*/
|
|
694
|
+
static open(dataDir: string, options?: DatabaseOptions): Promise<Database>;
|
|
695
|
+
|
|
696
|
+
/**
|
|
697
|
+
* Execute a CQL query and return results as JSON-serializable values.
|
|
698
|
+
*
|
|
699
|
+
* Use this method when you need JSON-compatible output or don't need
|
|
700
|
+
* native JavaScript types. For native types with full precision,
|
|
701
|
+
* use `executeNative()` instead.
|
|
702
|
+
*
|
|
703
|
+
* ## Varint and Decimal Encoding
|
|
704
|
+
*
|
|
705
|
+
* This method uses hex-based encoding for arbitrary precision numbers:
|
|
706
|
+
* - **Varint**: `"0x{hex}"` - Two's complement big-endian hex encoding
|
|
707
|
+
* - Example: 127 -> `"0x7f"`, -1 -> `"0xff"`, 256 -> `"0x0100"`
|
|
708
|
+
* - **Decimal**: `"decimal:{scale}:0x{hex}"` - Scale + hex-encoded unscaled value
|
|
709
|
+
* - Example: 1.23 (scale=2, unscaled=123) -> `"decimal:2:0x7b"`
|
|
710
|
+
*
|
|
711
|
+
* @param query - CQL SELECT statement to execute
|
|
712
|
+
* @returns Promise resolving to QueryResult with rows and metadata
|
|
713
|
+
* @throws {CqliteError} If the query fails
|
|
714
|
+
* @deprecated Since 0.4.0. Use `executeNative()` for proper type fidelity.
|
|
715
|
+
*
|
|
716
|
+
* @example
|
|
717
|
+
* ```typescript
|
|
718
|
+
* // JSON path - hex encoding for varint/decimal
|
|
719
|
+
* const result = await db.execute('SELECT * FROM users LIMIT 10');
|
|
720
|
+
* console.log(`Got ${result.rowCount} rows in ${result.executionTimeMs}ms`);
|
|
721
|
+
* // Varint column: "0x7f" for 127
|
|
722
|
+
* // Decimal column: "decimal:2:0x7b" for 1.23
|
|
723
|
+
*
|
|
724
|
+
* // Native path (recommended) - proper types
|
|
725
|
+
* const native = await db.executeNative('SELECT * FROM users');
|
|
726
|
+
* // Varint: BigInt(127)
|
|
727
|
+
* // Decimal: "1.23"
|
|
728
|
+
* ```
|
|
729
|
+
*/
|
|
730
|
+
execute(query: string): Promise<QueryResult>;
|
|
731
|
+
|
|
732
|
+
/**
|
|
733
|
+
* Execute a CQL query and return results with native JavaScript types.
|
|
734
|
+
*
|
|
735
|
+
* This method returns native JavaScript types instead of JSON-serializable values:
|
|
736
|
+
* - `bigint` for CQL bigint/counter/varint/time (preserves 64-bit precision)
|
|
737
|
+
* - `Buffer` for CQL blob
|
|
738
|
+
* - `Date` for CQL timestamp/date
|
|
739
|
+
* - `Set` for CQL set
|
|
740
|
+
* - `Map` for CQL map
|
|
741
|
+
* - `Duration` object for CQL duration
|
|
742
|
+
*
|
|
743
|
+
* Use this method when you need:
|
|
744
|
+
* - Full precision for large integers (> Number.MAX_SAFE_INTEGER)
|
|
745
|
+
* - Native Buffer handling for binary data
|
|
746
|
+
* - Native Set/Map operations
|
|
747
|
+
*
|
|
748
|
+
* @param query - CQL SELECT statement to execute
|
|
749
|
+
* @returns Promise resolving to NativeQueryResult with native typed rows
|
|
750
|
+
* @throws {CqliteError} If the query fails
|
|
751
|
+
*
|
|
752
|
+
* @example
|
|
753
|
+
* ```typescript
|
|
754
|
+
* const result = await db.executeNative('SELECT * FROM users LIMIT 10');
|
|
755
|
+
* for (const row of result.rows) {
|
|
756
|
+
* // row.id is bigint if column is CQL bigint
|
|
757
|
+
* // row.created_at is Date if column is timestamp
|
|
758
|
+
* // row.data is Buffer if column is blob
|
|
759
|
+
* console.log(row.name, typeof row.id);
|
|
760
|
+
* }
|
|
761
|
+
* ```
|
|
762
|
+
*/
|
|
763
|
+
executeNative(query: string): Promise<NativeQueryResult>;
|
|
764
|
+
|
|
765
|
+
/**
|
|
766
|
+
* Get database statistics.
|
|
767
|
+
*
|
|
768
|
+
* Returns information about storage, memory usage, and other metrics.
|
|
769
|
+
*
|
|
770
|
+
* @returns Promise resolving to DatabaseStats
|
|
771
|
+
* @throws {CqliteError} If statistics cannot be retrieved
|
|
772
|
+
*
|
|
773
|
+
* @example
|
|
774
|
+
* ```typescript
|
|
775
|
+
* const stats = await db.getStats();
|
|
776
|
+
* console.log(`SSTables: ${stats.totalSstables}`);
|
|
777
|
+
* console.log(`Total rows: ${stats.totalRows}`);
|
|
778
|
+
* console.log(`Memory: ${stats.memoryUsedBytes} bytes`);
|
|
779
|
+
* ```
|
|
780
|
+
*/
|
|
781
|
+
getStats(): Promise<DatabaseStats>;
|
|
782
|
+
|
|
783
|
+
/**
|
|
784
|
+
* Close the database and release resources.
|
|
785
|
+
*
|
|
786
|
+
* This method is idempotent - calling it multiple times is safe.
|
|
787
|
+
* After closing, any operations on the database will throw an error.
|
|
788
|
+
*
|
|
789
|
+
* @returns Promise resolving when close is complete
|
|
790
|
+
*
|
|
791
|
+
* @example
|
|
792
|
+
* ```typescript
|
|
793
|
+
* const db = await Database.open('/path/to/data');
|
|
794
|
+
* // ... use database ...
|
|
795
|
+
* await db.close();
|
|
796
|
+
* await db.close(); // Safe to call again
|
|
797
|
+
* ```
|
|
798
|
+
*/
|
|
799
|
+
close(): Promise<void>;
|
|
800
|
+
|
|
801
|
+
/**
|
|
802
|
+
* Check if the database is closed.
|
|
803
|
+
*
|
|
804
|
+
* @returns True if the database has been closed, false otherwise
|
|
805
|
+
*/
|
|
806
|
+
get isClosed(): boolean;
|
|
807
|
+
|
|
808
|
+
/**
|
|
809
|
+
* Execute a CQL query with streaming results.
|
|
810
|
+
*
|
|
811
|
+
* Returns an async iterable that yields rows one at a time, keeping memory
|
|
812
|
+
* usage bounded by the `StreamingConfig` settings. Use with `for await...of`.
|
|
813
|
+
*
|
|
814
|
+
* Memory stays bounded by configuration (default ~11MB peak):
|
|
815
|
+
* - `bufferSize`: 1024 rows in flight (~1MB)
|
|
816
|
+
* - `chunkSize`: 10,000 rows per fetch chunk (~10MB)
|
|
817
|
+
*
|
|
818
|
+
* @param query - CQL SELECT statement to execute
|
|
819
|
+
* @param config - Optional StreamingConfig for buffer/chunk sizes
|
|
820
|
+
* @returns StreamingResult async iterable (iteration triggers query execution)
|
|
821
|
+
* @throws {CqliteError} If the query fails (on first iteration)
|
|
822
|
+
*
|
|
823
|
+
* @example
|
|
824
|
+
* ```typescript
|
|
825
|
+
* // Basic streaming - no await needed on executeStreaming itself
|
|
826
|
+
* for await (const row of db.executeStreaming('SELECT * FROM large_table')) {
|
|
827
|
+
* console.log(row.name);
|
|
828
|
+
* }
|
|
829
|
+
*
|
|
830
|
+
* // With custom config for memory constraints
|
|
831
|
+
* const config: StreamingConfig = { bufferSize: 256, chunkSize: 2500 };
|
|
832
|
+
* for await (const row of db.executeStreaming(query, config)) {
|
|
833
|
+
* process(row);
|
|
834
|
+
* }
|
|
835
|
+
*
|
|
836
|
+
* // Early termination is safe
|
|
837
|
+
* for await (const row of db.executeStreaming('SELECT * FROM huge_table')) {
|
|
838
|
+
* if (row.id === targetId) {
|
|
839
|
+
* break; // Resources cleaned up automatically
|
|
840
|
+
* }
|
|
841
|
+
* }
|
|
842
|
+
* ```
|
|
843
|
+
*/
|
|
844
|
+
executeStreaming(query: string, config?: StreamingConfig): StreamingResult;
|
|
845
|
+
|
|
846
|
+
/**
|
|
847
|
+
* Prepare a CQL query for analysis.
|
|
848
|
+
*
|
|
849
|
+
* Returns a PreparedStatement that can be inspected for query plan
|
|
850
|
+
* information and statistics.
|
|
851
|
+
*
|
|
852
|
+
* @param query - CQL SELECT statement to prepare
|
|
853
|
+
* @returns Promise resolving to PreparedStatement with query plan info
|
|
854
|
+
* @throws {CqliteError} If the query cannot be prepared
|
|
855
|
+
*/
|
|
856
|
+
prepare(query: string): Promise<PreparedStatement>;
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
// ============================================================================
|
|
860
|
+
// Functions
|
|
861
|
+
// ============================================================================
|
|
862
|
+
|
|
863
|
+
/**
|
|
864
|
+
* Returns the version of the cqlite-node binding.
|
|
865
|
+
*
|
|
866
|
+
* @returns The semantic version string (e.g., "0.3.0")
|
|
867
|
+
*
|
|
868
|
+
* @example
|
|
869
|
+
* ```typescript
|
|
870
|
+
* import { version } from '@cqlite/node';
|
|
871
|
+
* console.log(`CQLite version: ${version()}`);
|
|
872
|
+
* ```
|
|
873
|
+
*/
|
|
874
|
+
export declare function version(): string;
|