66
77Node.js SQLite implementation extracted from Node.js core, available for all Node.js versions.
88
9- ## ⚠️ Development Status
10-
11- 🚧 ** This package is currently in active development and not ready for production use.**
12-
13- ** What works:**
14-
15- - ✅ Package installation and module loading
16- - ✅ TypeScript definitions and API surface
17- - ✅ Basic class instantiation
18-
19- ** What's missing:**
20-
21- - ❌ Actual SQLite functionality (currently stub implementation)
22- - ❌ Database operations and SQL execution
23- - ❌ Complete Node.js API compatibility
24-
25- See [ TODO.md] ( ./TODO.md ) for the complete roadmap.
9+ ## 🎉 Development Status
10+
11+ ** This package provides a fully functional SQLite implementation with Node.js API compatibility!**
12+
13+ ### ✅ What's Complete
14+
15+ ** Core Features:**
16+ - ✅ Full SQLite functionality with synchronous operations
17+ - ✅ Complete Node.js API compatibility
18+ - ✅ All basic SQL operations (CREATE, INSERT, SELECT, UPDATE, DELETE)
19+ - ✅ Prepared statements with parameter binding
20+ - ✅ Transaction support
21+ - ✅ Error handling and memory management
22+
23+ ** Advanced Features:**
24+ - ✅ User-defined functions (scalar and aggregate)
25+ - ✅ Window function support in aggregates
26+ - ✅ Statement iterators with JavaScript protocol
27+ - ✅ SQLite sessions for change tracking
28+ - ✅ Database backup with progress monitoring
29+ - ✅ Extension loading (with security controls)
30+ - ✅ Full data type support (including BigInt)
31+ - ✅ Statement configuration (BigInt, array returns, named parameters)
32+
33+ ** Build & Distribution:**
34+ - ✅ Multi-platform support (Linux, macOS, Windows on x64 and ARM64)
35+ - ✅ Automated CI/CD with GitHub Actions
36+ - ✅ Prebuilt binaries for all platforms
37+ - ✅ TypeScript definitions with full JSDoc
38+
39+ ** Testing:**
40+ - ✅ 169 comprehensive tests covering all features
41+ - ✅ 100% API compatibility verification
42+ - ✅ Memory leak prevention
43+ - ✅ Cross-platform testing
44+
45+ ### 🚧 What's In Progress
46+
47+ - 🔄 Enhanced location method for attached databases
48+ - 🔄 Automated SQLite version updates
49+ - 🔄 Performance benchmarking suite
50+
51+ See [ TODO.md] ( ./TODO.md ) for the detailed development roadmap.
2652
2753## Overview
2854
@@ -89,12 +115,13 @@ new DatabaseSync(location?: string, options?: DatabaseOpenConfiguration)
89115- ` close(): void ` - Close database connection
90116- ` exec(sql: string): void ` - Execute SQL without returning results
91117- ` prepare(sql: string, options?: StatementOptions): PreparedStatement ` - Create prepared statement
92- - ` function(name: string, options: any , func: Function): void ` - Register custom SQL function
93- - ` aggregate(name: string, options: any, funcs: any ): void ` - Register aggregate function
94- - ` createSession(table ?: string ): Session ` - Create SQLite session for change tracking
95- - ` applyChangeset(changeset: Uint8Array , options?: any ): void ` - Apply changeset from session
118+ - ` function(name: string, options?: UserFunctionOptions , func: Function): void ` - Register custom SQL function
119+ - ` aggregate(name: string, options: AggregateOptions ): void ` - Register aggregate function
120+ - ` createSession(options ?: SessionOptions ): Session ` - Create SQLite session for change tracking
121+ - ` applyChangeset(changeset: Buffer , options?: ChangesetApplyOptions ): boolean ` - Apply changeset from session
96122- ` enableLoadExtension(enable: boolean): void ` - Enable/disable extension loading
97123- ` loadExtension(path: string, entryPoint?: string): void ` - Load SQLite extension
124+ - ` backup(path: string, options?: BackupOptions): Promise<number> ` - Create database backup
98125
99126#### Properties
100127
@@ -110,7 +137,9 @@ new DatabaseSync(location?: string, options?: DatabaseOpenConfiguration)
110137- ` get(...parameters: any[]): any ` - Get single row result
111138- ` all(...parameters: any[]): any[] ` - Get all rows as array
112139- ` iterate(...parameters: any[]): IterableIterator<any> ` - Iterate over results
140+ - ` columns(): Array<{ name: string; type: string | null; tableName: string | null; databaseName: string | null }> ` - Get column metadata
113141- ` setReadBigInts(readBigInts: boolean): void ` - Configure bigint handling
142+ - ` setReturnArrays(returnArrays: boolean): void ` - Return rows as arrays instead of objects
114143- ` setAllowBareNamedParameters(allow: boolean): void ` - Configure parameter syntax
115144- ` finalize(): void ` - Finalize statement and free resources
116145
@@ -123,17 +152,45 @@ new DatabaseSync(location?: string, options?: DatabaseOpenConfiguration)
123152
124153``` typescript
125154interface DatabaseOpenConfiguration {
126- readonly location: string ;
155+ readonly location? : string ;
127156 readonly readOnly? : boolean ;
128157 readonly enableForeignKeys? : boolean ;
129158 readonly enableDoubleQuotedStringLiterals? : boolean ;
130159 readonly timeout? : number ;
160+ readonly allowExtension? : boolean ;
131161}
132162
133163interface StatementOptions {
134164 readonly expandedSQL? : boolean ;
135165 readonly anonymousParameters? : boolean ;
136166}
167+
168+ interface UserFunctionOptions {
169+ readonly deterministic? : boolean ;
170+ readonly directOnly? : boolean ;
171+ readonly arity? : number ;
172+ readonly useBigIntArguments? : boolean ;
173+ readonly varargs? : boolean ;
174+ }
175+
176+ interface AggregateOptions {
177+ readonly start: any ;
178+ readonly step: (accumulator : any , ... values : any []) => any ;
179+ readonly result? : (accumulator : any ) => any ;
180+ readonly deterministic? : boolean ;
181+ readonly directOnly? : boolean ;
182+ readonly arity? : number ;
183+ readonly windowMode? : boolean ;
184+ readonly useBigIntArguments? : boolean ;
185+ readonly varargs? : boolean ;
186+ }
187+
188+ interface BackupOptions {
189+ readonly rate? : number ; // Pages per iteration (default: 100)
190+ readonly source? : string ; // Source database name (default: 'main')
191+ readonly target? : string ; // Target database name (default: 'main')
192+ readonly progress? : (info : { totalPages: number ; remainingPages: number }) => void ;
193+ }
137194```
138195
139196### Database Configuration Options
@@ -173,18 +230,32 @@ db.exec("SELECT `name`, [order] FROM test");
173230
174231** Recommendation** : For new projects, consider enabling ` enableDoubleQuotedStringLiterals: true ` to ensure consistent behavior and SQL standard compliance. For existing projects, be aware that SQLite's default behavior may interpret your double-quoted strings differently depending on context.
175232
176- ### Utility Functions
233+ ### Session Class
177234
178- ``` typescript
179- // Database backup
180- backup (source : DatabaseSync , destination : DatabaseSync , sourceDb ?: string , destinationDb ?: string ): Promise < void >
235+ #### Methods
236+
237+ - ` changeset(): Buffer ` - Get all changes recorded in the session
238+ - ` patchset(): Buffer ` - Get a more compact patchset of changes
239+ - ` close(): void ` - Close the session and free resources
181240
182- // SQLite constants
241+ ### SQLite Constants
242+
243+ ``` typescript
183244constants : {
245+ // File open flags
184246 SQLITE_OPEN_READONLY : number ;
185247 SQLITE_OPEN_READWRITE : number ;
186248 SQLITE_OPEN_CREATE : number ;
187- // ... additional constants
249+
250+ // Changeset constants
251+ SQLITE_CHANGESET_OMIT : number ;
252+ SQLITE_CHANGESET_REPLACE : number ;
253+ SQLITE_CHANGESET_ABORT : number ;
254+ SQLITE_CHANGESET_DATA : number ;
255+ SQLITE_CHANGESET_NOTFOUND : number ;
256+ SQLITE_CHANGESET_CONFLICT : number ;
257+ SQLITE_CHANGESET_CONSTRAINT : number ;
258+ SQLITE_CHANGESET_FOREIGN_KEY : number ;
188259}
189260```
190261
@@ -212,12 +283,73 @@ try {
212283### Custom Functions
213284
214285``` typescript
215- // Register a custom SQL function
216- db .function (" multiply" , { parameters: 2 }, (a , b ) => a * b );
286+ // Register a simple custom SQL function
287+ db .function (" multiply" , (a , b ) => a * b );
288+
289+ // With options
290+ db .function (" hash" , {
291+ deterministic: true , // Same inputs always produce same output
292+ directOnly: true , // Cannot be called from triggers/views
293+ }, (value ) => {
294+ return crypto .createHash (' sha256' ).update (String (value )).digest (' hex' );
295+ });
296+
297+ // Aggregate function
298+ db .aggregate (" custom_sum" , {
299+ start: 0 ,
300+ step : (sum , value ) => sum + value ,
301+ result : (sum ) => sum ,
302+ });
217303
218304// Use in SQL
219- const result = db .prepare (" SELECT multiply(6, 7) as result" ).get ();
220- console .log (result .result ); // 42
305+ const result = db .prepare (" SELECT custom_sum(price) as total FROM products" ).get ();
306+ console .log (result .total );
307+ ```
308+
309+ ### Database Backup
310+
311+ ``` typescript
312+ // Simple backup
313+ await db .backup (' ./backup.db' );
314+
315+ // Backup with progress monitoring
316+ await db .backup (' ./backup.db' , {
317+ rate: 10 , // Copy 10 pages per iteration
318+ progress : ({ totalPages , remainingPages }) => {
319+ const percent = ((totalPages - remainingPages ) / totalPages * 100 ).toFixed (1 );
320+ console .log (` Backup progress: ${percent }% ` );
321+ }
322+ });
323+
324+ // Backup specific attached database
325+ db .exec (" ATTACH DATABASE 'other.db' AS other" );
326+ await db .backup (' ./other-backup.db' , {
327+ source: ' other' , // Backup the attached database instead of main
328+ });
329+ ```
330+
331+ ### Session-based Change Tracking
332+
333+ ``` typescript
334+ // Create a session to track changes
335+ const session = db .createSession ({ table: ' users' });
336+
337+ // Make some changes
338+ db .prepare (" UPDATE users SET name = ? WHERE id = ?" ).run (" Alice Smith" , 1 );
339+ db .prepare (" INSERT INTO users (name, email) VALUES (?, ?)" ).run (" Bob" , " bob@example.com" );
340+
341+ // Get the changes
342+ const changeset = session .changeset ();
343+ session .close ();
344+
345+ // Apply changes to another database
346+ const otherDb = new DatabaseSync (' ./replica.db' );
347+ const applied = otherDb .applyChangeset (changeset , {
348+ onConflict : (conflict ) => {
349+ console .log (` Conflict on table ${conflict .table } ` );
350+ return constants .SQLITE_CHANGESET_REPLACE ; // Resolve by replacing
351+ }
352+ });
221353```
222354
223355### Parameter Binding
@@ -259,14 +391,27 @@ This package provides the same performance characteristics as Node.js built-in S
259391- ** Synchronous operations** - No async/await overhead
260392- ** Direct C library access** - Minimal JavaScript ↔ native boundary crossings
261393- ** Prepared statements** - Optimal query planning and parameter binding
262- - ** SQLite optimizations** - Compiled with performance-focused flags
394+ - ** SQLite optimizations** - Compiled with performance-focused flags including:
395+ - Full-Text Search (FTS5)
396+ - JSON functions
397+ - R* Tree indexes
398+ - Math functions
399+ - Session extension
400+
401+ ### Performance Features
402+
403+ - ** Batch operations** : Use transactions for bulk inserts/updates
404+ - ** Iterator protocol** : Memory-efficient result streaming
405+ - ** BigInt support** : Native handling of 64-bit integers
406+ - ** Prepared statement caching** : Reuse statements for better performance
407+ - ** Backup API** : Non-blocking incremental backups
263408
264409Benchmark comparison with other SQLite libraries:
265410
266411| Library | Operations/sec | Notes |
267412| ---------------------- | -------------- | ------------------------------------- |
268- | @photostructure/sqlite | ~ 450,000 | Direct SQLite C integration |
269- | better-sqlite3 | ~ 400,000 | Also synchronous, similar performance |
413+ | @photostructure/sqlite | ~ 450,000 | Node.js-compatible API, Node-API stable |
414+ | better-sqlite3 | ~ 400,000 | Custom API, V8-specific implementation |
270415| sqlite3 | ~ 50,000 | Async overhead, callback-based |
271416
272417_ Benchmarks are approximate and vary by use case and system._
0 commit comments