@photostructure/sqlite 0.0.1 → 0.2.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.
Files changed (57) hide show
  1. package/CHANGELOG.md +38 -2
  2. package/README.md +47 -483
  3. package/SECURITY.md +27 -83
  4. package/binding.gyp +69 -22
  5. package/dist/index.cjs +185 -18
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.d.cts +552 -100
  8. package/dist/index.d.mts +552 -100
  9. package/dist/index.d.ts +552 -100
  10. package/dist/index.mjs +183 -18
  11. package/dist/index.mjs.map +1 -1
  12. package/package.json +51 -41
  13. package/prebuilds/darwin-arm64/@photostructure+sqlite.glibc.node +0 -0
  14. package/prebuilds/darwin-x64/@photostructure+sqlite.glibc.node +0 -0
  15. package/prebuilds/linux-arm64/@photostructure+sqlite.glibc.node +0 -0
  16. package/prebuilds/linux-arm64/@photostructure+sqlite.musl.node +0 -0
  17. package/prebuilds/linux-x64/@photostructure+sqlite.glibc.node +0 -0
  18. package/prebuilds/linux-x64/@photostructure+sqlite.musl.node +0 -0
  19. package/prebuilds/test_extension.so +0 -0
  20. package/prebuilds/win32-arm64/@photostructure+sqlite.glibc.node +0 -0
  21. package/prebuilds/win32-x64/@photostructure+sqlite.glibc.node +0 -0
  22. package/src/aggregate_function.cpp +503 -235
  23. package/src/aggregate_function.h +57 -42
  24. package/src/binding.cpp +117 -14
  25. package/src/dirname.ts +1 -1
  26. package/src/index.ts +122 -332
  27. package/src/lru-cache.ts +84 -0
  28. package/src/shims/env-inl.h +6 -15
  29. package/src/shims/node_errors.h +7 -1
  30. package/src/shims/sqlite_errors.h +168 -0
  31. package/src/shims/util.h +29 -4
  32. package/src/sql-tag-store.ts +140 -0
  33. package/src/sqlite_exception.h +49 -0
  34. package/src/sqlite_impl.cpp +736 -129
  35. package/src/sqlite_impl.h +84 -6
  36. package/src/{stack_path.ts → stack-path.ts} +7 -1
  37. package/src/types/aggregate-options.ts +22 -0
  38. package/src/types/changeset-apply-options.ts +18 -0
  39. package/src/types/database-sync-instance.ts +203 -0
  40. package/src/types/database-sync-options.ts +69 -0
  41. package/src/types/session-options.ts +10 -0
  42. package/src/types/sql-tag-store-instance.ts +51 -0
  43. package/src/types/sqlite-authorization-actions.ts +77 -0
  44. package/src/types/sqlite-authorization-results.ts +15 -0
  45. package/src/types/sqlite-changeset-conflict-types.ts +19 -0
  46. package/src/types/sqlite-changeset-resolution.ts +15 -0
  47. package/src/types/sqlite-open-flags.ts +50 -0
  48. package/src/types/statement-sync-instance.ts +73 -0
  49. package/src/types/user-functions-options.ts +14 -0
  50. package/src/upstream/node_sqlite.cc +960 -259
  51. package/src/upstream/node_sqlite.h +127 -2
  52. package/src/upstream/sqlite.js +1 -14
  53. package/src/upstream/sqlite3.c +4510 -1411
  54. package/src/upstream/sqlite3.h +390 -195
  55. package/src/upstream/sqlite3ext.h +7 -0
  56. package/src/user_function.cpp +88 -36
  57. package/src/user_function.h +2 -1
package/CHANGELOG.md CHANGED
@@ -2,7 +2,41 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
- ## [0.1.0] - 2025-01-06
5
+ ## [0.2.1] (2025-12-01)
6
+
7
+ ### Added
8
+
9
+ - Windows ARM64 prebuilt binaries
10
+
11
+ ### Fixed
12
+
13
+ - Error message handling on Windows ARM64 (ABI compatibility)
14
+ - Error handling consistency across platforms
15
+
16
+ ## [0.2.0] (2025-12-01)
17
+
18
+ ### Added
19
+
20
+ - **Node.js v25 API sync**: SQLite 3.51.1, native `Symbol.dispose` in C++, Session class exposed in public API
21
+ - **New database open options**: `readBigInts`, `returnArrays`, `allowBareNamedParameters`, `allowUnknownNamedParameters`, `defensive`, `open`
22
+ - **Defensive mode**: `enableDefensive()` method to prevent SQL from deliberately corrupting the database
23
+ - **Statement enhancements**: `setAllowUnknownNamedParameters()` method, `finalized` property
24
+ - **Type identification**: `sqlite-type` symbol property on DatabaseSync (Node.js PR #59405)
25
+ - **Enhanced SQLite errors**: New properties `sqliteCode`, `sqliteExtendedCode`, `code`, `sqliteErrorString`, `systemErrno`
26
+ - **ARM64 prebuilds**: macOS Apple Silicon and Windows ARM64 binaries
27
+ - **Tagged template literals**: `db.createTagStore()` for cached prepared statements (Node.js PR #58748)
28
+ - **Authorization API**: `db.setAuthorizer()` for security callbacks (Node.js PR #59928)
29
+ - **Standalone backup**: `backup(srcDb, destFile, options?)` for one-liner database backups with progress callbacks
30
+
31
+ ### Fixed
32
+
33
+ - DataView parameter binding (previously returned garbage data)
34
+ - DataView and TypedArray return values in user-defined functions
35
+ - RETURNING clause metadata handling
36
+ - Null and empty values in user function return value conversion
37
+ - Native stability: N-API reference cleanup in aggregates/destructors, thread-local napi_env storage, statement-to-database reference tracking, deferred exception handling in authorizers
38
+
39
+ ## [0.0.1] - 2025-06-13
6
40
 
7
41
  ### Added
8
42
 
@@ -30,6 +64,7 @@ All notable changes to this project will be documented in this file.
30
64
  - **Safe integer handling**: JavaScript-safe integer conversion with overflow detection
31
65
  - **Multi-process support**: Safe concurrent access from multiple Node.js processes
32
66
  - **Worker thread support**: Full functionality in worker threads
67
+ - **URI filename support**: Full SQLite URI syntax support for advanced database configuration
33
68
  - **Strict tables**: Support for SQLite's strict table mode
34
69
  - **Double-quoted strings**: Configurable SQL syntax compatibility
35
70
 
@@ -40,4 +75,5 @@ All notable changes to this project will be documented in this file.
40
75
  - macOS (x64, ARM64)
41
76
  - Linux (x64, ARM64), (glibc 2.28+, musl)
42
77
 
43
- [0.1.0]: https://github.com/PhotoStructure/node-sqlite/releases/tag/v0.1.0
78
+ [0.2.0]: https://github.com/PhotoStructure/node-sqlite/releases/tag/v0.2.0
79
+ [0.0.1]: https://github.com/PhotoStructure/node-sqlite/releases/tag/v0.0.1
package/README.md CHANGED
@@ -1,32 +1,9 @@
1
- ![PhotoStructure SQLite Logo](https://raw.githubusercontent.com/photostructure/node-sqlite/main/doc/logo.svg)
1
+ # @photostructure/sqlite
2
2
 
3
- ## 🚀 Drop-in Replacement for node:sqlite
3
+ [![npm version](https://img.shields.io/npm/v/@photostructure/sqlite.svg)](https://www.npmjs.com/package/@photostructure/sqlite)
4
+ [![CI](https://github.com/photostructure/node-sqlite/actions/workflows/build.yml/badge.svg)](https://github.com/photostructure/node-sqlite/actions/workflows/build.yml)
4
5
 
5
- This package provides **100% API compatibility** with Node.js v24 built-in SQLite module (`node:sqlite`). You can seamlessly switch between this package and the built-in module without changing any code.
6
-
7
- ```javascript
8
- // Using Node.js built-in SQLite (requires Node.js 22.5.0+ and --experimental-sqlite flag)
9
- const { DatabaseSync } = require("node:sqlite");
10
-
11
- // Using @photostructure/sqlite (works on Node.js 20+ without any flags)
12
- const { DatabaseSync } = require("@photostructure/sqlite");
13
-
14
- // The API is identical - no code changes needed!
15
- ```
16
-
17
- ## Overview
18
-
19
- Node.js has an [experimental built-in SQLite module](https://nodejs.org/docs/latest/api/sqlite.html) that provides synchronous database operations with excellent performance. However, it's only available in the newest Node.js versions, and requires the `--experimental-sqlite` flag.
20
-
21
- This package extracts that implementation into a standalone library that:
22
-
23
- - **Works everywhere**: Compatible with Node.js 20+ without experimental flags
24
- - **Drop-in replacement**: 100% API compatible with `node:sqlite` - no code changes needed
25
- - **Full-featured**: Includes all SQLite extensions (FTS, JSON, math functions, etc.)
26
- - **High performance**: Direct SQLite C library integration with minimal overhead
27
- - **Type-safe**: Complete TypeScript definitions matching Node.js exactly
28
- - **Worker thread support**: Full support for Node.js worker threads with proper isolation
29
- - **Future-proof**: When `node:sqlite` becomes stable, switching back requires zero code changes
6
+ Native SQLite for Node.js 20+ without the experimental flag. Drop-in replacement for `node:sqlite`. Updated to Node.js v25 for latest features and native Symbol.dispose resource management.
30
7
 
31
8
  ## Installation
32
9
 
@@ -36,486 +13,73 @@ npm install @photostructure/sqlite
36
13
 
37
14
  ## Quick Start
38
15
 
39
- ### As a Drop-in Replacement
40
-
41
16
  ```javascript
42
- // If you have code using node:sqlite:
43
- const { DatabaseSync } = require("node:sqlite");
44
-
45
- // Simply replace with:
46
- const { DatabaseSync } = require("@photostructure/sqlite");
47
- // That's it! No other changes needed.
48
- ```
49
-
50
- ### Basic Example
51
-
52
- ```typescript
53
17
  import { DatabaseSync } from "@photostructure/sqlite";
54
18
 
55
- // Create an in-memory database
56
19
  const db = new DatabaseSync(":memory:");
57
-
58
- // Create a table
59
- db.exec(`
60
- CREATE TABLE users (
61
- id INTEGER PRIMARY KEY AUTOINCREMENT,
62
- name TEXT NOT NULL,
63
- email TEXT UNIQUE
64
- )
65
- `);
66
-
67
- // Insert data
68
- const insertStmt = db.prepare("INSERT INTO users (name, email) VALUES (?, ?)");
69
- const result = insertStmt.run("Alice Johnson", "alice@example.com");
70
- console.log("Inserted user with ID:", result.lastInsertRowid);
71
-
72
- // Query data
73
- const selectStmt = db.prepare("SELECT * FROM users WHERE id = ?");
74
- const user = selectStmt.get(result.lastInsertRowid);
75
- console.log("User:", user);
76
-
77
- // Clean up
78
- db.close();
79
- ```
80
-
81
- ## API Reference
82
-
83
- ### Database Configuration Options
84
-
85
- ### Custom Functions
86
-
87
- ```typescript
88
- // Register a simple custom SQL function
89
- db.function("multiply", (a, b) => a * b);
90
-
91
- // With options
92
- db.function(
93
- "hash",
94
- {
95
- deterministic: true, // Same inputs always produce same output
96
- directOnly: true, // Cannot be called from triggers/views
97
- },
98
- (value) => {
99
- return crypto.createHash("sha256").update(String(value)).digest("hex");
100
- },
101
- );
102
-
103
- // Aggregate function
104
- db.aggregate("custom_sum", {
105
- start: 0,
106
- step: (sum, value) => sum + value,
107
- result: (sum) => sum,
108
- });
109
-
110
- // Use in SQL
111
- const result = db
112
- .prepare("SELECT custom_sum(price) as total FROM products")
113
- .get();
114
- console.log(result.total);
115
- ```
116
-
117
- ### Database Backup
118
-
119
- ```typescript
120
- // Simple backup
121
- await db.backup("./backup.db");
122
-
123
- // Backup with progress monitoring
124
- await db.backup("./backup.db", {
125
- rate: 10, // Copy 10 pages per iteration
126
- progress: ({ totalPages, remainingPages }) => {
127
- const percent = (
128
- ((totalPages - remainingPages) / totalPages) *
129
- 100
130
- ).toFixed(1);
131
- console.log(`Backup progress: ${percent}%`);
132
- },
133
- });
134
-
135
- // Backup specific attached database
136
- db.exec("ATTACH DATABASE 'other.db' AS other");
137
- await db.backup("./other-backup.db", {
138
- source: "other", // Backup the attached database instead of main
139
- });
140
- ```
141
-
142
- ### Database Restoration
143
-
144
- ```typescript
145
- // Restore from a backup file
146
- import * as fs from "fs";
147
-
148
- // Close the current database
20
+ db.exec("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)");
21
+ const insert = db.prepare("INSERT INTO users (name) VALUES (?)");
22
+ insert.run("Alice");
23
+ const users = db.prepare("SELECT * FROM users").all();
24
+ console.log(users); // [{ id: 1, name: 'Alice' }]
149
25
  db.close();
150
-
151
- // Copy the backup file over the current database file
152
- fs.copyFileSync("./backup.db", "./mydata.db");
153
-
154
- // Reopen the database with the restored data
155
- const restoredDb = new DatabaseSync("./mydata.db");
156
-
157
- // Verify restoration
158
- const count = restoredDb.prepare("SELECT COUNT(*) as count FROM users").get();
159
- console.log(`Restored database has ${count.count} users`);
160
- ```
161
-
162
- ### Worker Thread Support
163
-
164
- This package has full support for Node.js worker threads. Each worker thread gets its own isolated SQLite environment.
165
-
166
- ```javascript
167
- // main.js
168
- const { Worker } = require("worker_threads");
169
-
170
- // Spawn multiple workers to handle database operations
171
- const worker1 = new Worker("./db-worker.js");
172
- const worker2 = new Worker("./db-worker.js");
173
-
174
- // Send queries to workers
175
- worker1.postMessage({
176
- sql: "SELECT * FROM users WHERE active = ?",
177
- params: [true],
178
- });
179
-
180
- // db-worker.js
181
- const { parentPort } = require("worker_threads");
182
- const { DatabaseSync } = require("@photostructure/sqlite");
183
-
184
- // Each worker creates its own database connection
185
- const db = new DatabaseSync("./app.db");
186
-
187
- parentPort.on("message", ({ sql, params }) => {
188
- try {
189
- const stmt = db.prepare(sql);
190
- const results = stmt.all(...params);
191
- stmt.finalize();
192
- parentPort.postMessage({ success: true, results });
193
- } catch (error) {
194
- parentPort.postMessage({ success: false, error: error.message });
195
- }
196
- });
197
- ```
198
-
199
- Key points:
200
-
201
- - Each worker thread must create its own `DatabaseSync` instance
202
- - Database connections cannot be shared between threads
203
- - SQLite's built-in thread safety (multi-thread mode) ensures data integrity
204
- - No special initialization required - just use normally in each worker
205
-
206
- ### Extension Loading
207
-
208
- SQLite extensions can be loaded to add custom functionality. Extension loading requires explicit permission for security.
209
-
210
- ```javascript
211
- // Enable extension loading at database creation
212
- const db = new DatabaseSync("./mydb.sqlite", {
213
- allowExtension: true,
214
- });
215
-
216
- // Enable extension loading (required before loading)
217
- db.enableLoadExtension(true);
218
-
219
- // Load an extension
220
- db.loadExtension("./extensions/vector.so");
221
-
222
- // Optionally specify an entry point
223
- db.loadExtension("./extensions/custom.so", "sqlite3_custom_init");
224
-
225
- // Disable extension loading when done for security
226
- db.enableLoadExtension(false);
227
- ```
228
-
229
- ### Session-based Change Tracking
230
-
231
- SQLite's session extension allows you to record changes and apply them to other databases - perfect for synchronization, replication, or undo/redo functionality. This feature is available in both `node:sqlite` and `@photostructure/sqlite`, but not in better-sqlite3.
232
-
233
- ```typescript
234
- // Create a session to track changes
235
- const session = db.createSession({ table: "users" });
236
-
237
- // Make some changes
238
- db.prepare("UPDATE users SET name = ? WHERE id = ?").run("Alice Smith", 1);
239
- db.prepare("INSERT INTO users (name, email) VALUES (?, ?)").run(
240
- "Bob",
241
- "bob@example.com",
242
- );
243
-
244
- // Get the changes as a changeset
245
- const changeset = session.changeset();
246
- session.close();
247
-
248
- // Apply changes to another database
249
- const otherDb = new DatabaseSync("./replica.db");
250
- const applied = otherDb.applyChangeset(changeset, {
251
- onConflict: (conflict) => {
252
- console.log(`Conflict on table ${conflict.table}`);
253
- return constants.SQLITE_CHANGESET_REPLACE; // Resolve by replacing
254
- },
255
- });
256
26
  ```
257
27
 
258
- ### Parameter Binding
28
+ ## Features
259
29
 
260
- ```typescript
261
- const stmt = db.prepare("SELECT * FROM users WHERE name = ? AND age > ?");
30
+ - 100% compatible with Node.js v25 built-in `node:sqlite` module\*
31
+ - Zero dependencies - native SQLite implementation
32
+ - Synchronous API - no async overhead
33
+ - Performance matches leading SQLite libraries
34
+ - Full SQLite feature set ([details](./doc/features.md))
35
+ - TypeScript support with complete type definitions
36
+ - Cross-platform prebuilt binaries (Windows/macOS/Linux, x64/ARM64)
37
+ - User-defined functions and aggregates
38
+ - Database backups and session/changeset support
39
+ - Session class exposed for advanced replication workflows
40
+ - Native Symbol.dispose for improved resource management
41
+ - URI filename support for advanced configuration
42
+ - Worker thread safe
43
+ - [Compare with other libraries →](./doc/library-comparison.md)
262
44
 
263
- // Positional parameters
264
- const users1 = stmt.all("Alice", 25);
45
+ ## Note
265
46
 
266
- // Named parameters (with object)
267
- const stmt2 = db.prepare(
268
- "SELECT * FROM users WHERE name = $name AND age > $age",
269
- );
270
- const users2 = stmt2.all({ name: "Alice", age: 25 });
271
- ```
47
+ \*API-compatible with Node.js SQLite, but this library adopts SQLite-recommended features and security-enhancing build flags. See [build configuration details](./doc/build-flags.md).
272
48
 
273
- ### Using with TypeScript
274
-
275
- ```typescript
276
- interface User {
277
- id: number;
278
- name: string;
279
- email: string;
280
- created_at: string;
281
- }
282
-
283
- const db = new DatabaseSync("users.db");
284
- const stmt = db.prepare("SELECT * FROM users WHERE id = ?");
285
-
286
- const user = stmt.get(1) as User;
287
- console.log(`User: ${user.name} <${user.email}>`);
288
- ```
49
+ - DataView parameter binding is not currently supported. Use Buffer instead for binary data.
289
50
 
290
- ## Performance
51
+ ## Documentation
291
52
 
292
- This package provides performance comparable to Node.js's built-in SQLite and better-sqlite3, with:
53
+ **Getting Started**
293
54
 
294
- - **Synchronous operations** - No async/await overhead
295
- - **Direct C library access** - Minimal JavaScript ↔ native boundary crossings
296
- - **Full SQLite features** - FTS5, JSON functions, R\*Tree indexes, math functions, session extension (including changesets)
55
+ - [Installation & Setup](./doc/getting-started.md)
56
+ - [Migrating from node:sqlite](./doc/migrating-from-node-sqlite.md)
57
+ - [Migrating from better-sqlite3](./doc/migrating-from-better-sqlite3.md)
297
58
 
298
- Performance is quite similar to node:sqlite and better-sqlite3, while significantly faster than async sqlite3 due to synchronous operations.
59
+ **Using SQLite**
299
60
 
300
- ## Platform Support
61
+ - [Working with Data](./doc/working-with-data.md)
62
+ - [Extending SQLite](./doc/extending-sqlite.md)
63
+ - [Advanced Patterns](./doc/advanced-patterns.md)
301
64
 
302
- | Platform | x64 | ARM64 | Notes |
303
- | -------- | --- | ----- | ------------------------------------------------ |
304
- | Linux | ✅ | ✅ | GLIBC 2.31+ (Ubuntu 20.04+, Debian 11+, RHEL 8+) |
305
- | Alpine | ✅ | ✅ | Alpine 3.21+ (musl libc) |
306
- | macOS | ✅ | ✅ | macOS 10.15+ |
307
- | Windows | ✅ | ✅ | Windows 10+ |
65
+ **Reference**
308
66
 
309
- ### Linux Distribution Requirements
310
-
311
- **Supported distributions** (with prebuilt binaries):
312
-
313
- - Ubuntu 20.04 LTS and newer
314
- - Debian 11 (Bullseye) and newer
315
- - RHEL/CentOS/Rocky/Alma Linux 8 and newer
316
- - Fedora 32 and newer
317
- - Alpine Linux 3.21 and newer (musl libc)
318
- - Any distribution with GLIBC 2.31 or newer
319
-
320
- **Not supported** (GLIBC too old):
321
-
322
- - Debian 10 (Buster) - GLIBC 2.28
323
- - Ubuntu 18.04 LTS - GLIBC 2.27
324
- - CentOS 7 - GLIBC 2.17
325
- - Amazon Linux 2 - GLIBC 2.26
326
-
327
- > **Note**: While Node.js 20 itself supports these older distributions, our prebuilt binaries require GLIBC 2.31+ due to toolchain requirements. Users on older distributions can still compile from source if they have a compatible compiler (GCC 10+ with C++20 support).
328
-
329
- Prebuilt binaries are provided for all supported platforms. If a prebuilt binary isn't available, the package will compile from source using node-gyp.
330
-
331
- ## Development Requirements
332
-
333
- - **Node.js**: v20 or higher
334
- - **Build tools** (if compiling from source):
335
- - Linux: `build-essential`, `python3` (3.8+), GCC 10+ or Clang 10+
336
- - macOS: Xcode command line tools
337
- - Windows: Visual Studio Build Tools 2019 or newer
338
- - **Python**: 3.8 or higher (required by node-gyp v11)
339
-
340
- ## Alternatives
341
-
342
- When choosing a SQLite library for Node.js, you have several excellent options. Here's how **`@photostructure/sqlite`** compares to the alternatives:
343
-
344
- ### 🏷️ [`node:sqlite`](https://nodejs.org/docs/latest/api/sqlite.html) — Node.js Built-in Module
345
-
346
- _The official SQLite module included with Node.js 22.5.0+ (experimental)_
347
-
348
- **✨ Pros:**
349
-
350
- - **Zero dependencies** — Built directly into Node.js
351
- - **Official support** — Maintained by the Node.js core team
352
- - **Clean synchronous API** — Simple, predictable blocking operations
353
- - **Full SQLite power** — FTS5, JSON functions, R\*Tree, sessions/changesets, and more
354
-
355
- **⚠️ Cons:**
356
-
357
- - **Experimental status** — Not yet stable for production use
358
- - **Requires Node.js 22.5.0+** — Won't work on older versions
359
- - **Flag required** — Must use `--experimental-sqlite` to enable
360
- - **API may change** — Breaking changes possible before stable release
361
- - **Limited real-world usage** — Few production deployments to learn from
362
-
363
- **🎯 Best for:** Experimental projects, early adopters, and preparing for the future when it becomes stable.
364
-
365
- ---
366
-
367
- ### 🚀 [`better-sqlite3`](https://github.com/WiseLibs/better-sqlite3) — The Performance Champion
368
-
369
- _The most popular high-performance synchronous SQLite library_
370
-
371
- **✨ Pros:**
372
-
373
- - **Blazing fast** — 2-15x faster than async alternatives
374
- - **Rock-solid stability** — Battle-tested in thousands of production apps
375
- - **Rich feature set** — User functions, aggregates, virtual tables, extensions
376
- - **Extensive community** — Large ecosystem with many resources
377
-
378
- **⚠️ Cons:**
379
-
380
- - **Different API** — Not compatible with Node.js built-in SQLite
381
- - **V8-specific** — Requires separate builds for each Node.js version
382
- - **Synchronous only** — No async operations (usually a feature, not a bug)
383
- - **Migration effort** — Switching from other libraries requires code changes
384
- - **No session support** — Doesn't expose SQLite's session/changeset functionality
385
-
386
- **🎯 Best for:** High-performance applications where you want maximum speed and control over the API.
387
-
388
- ---
389
-
390
- ### 📦 [`sqlite3`](https://github.com/TryGhost/node-sqlite3) — The Async Classic
391
-
392
- _The original asynchronous SQLite binding for Node.js_
393
-
394
- **✨ Pros:**
395
-
396
- - **Battle-tested legacy** — 10+ years of production use
397
- - **Massive ecosystem** — 4000+ dependent packages
398
- - **Truly asynchronous** — Non-blocking operations won't freeze your app
399
- - **Extensive resources** — Countless tutorials and Stack Overflow answers
400
- - **Extension support** — Works with SQLCipher for encryption
401
- - **Node-API stable** — One build works across Node.js versions
402
-
403
- **⚠️ Cons:**
404
-
405
- - **Significantly slower** — 2-15x performance penalty vs synchronous libs
406
- - **Callback complexity** — Prone to callback hell without careful design
407
- - **Unnecessary overhead** — SQLite is inherently synchronous anyway
408
- - **Memory management quirks** — Exposes low-level C concerns to JavaScript
409
- - **Concurrency issues** — Mutex contention under heavy load
410
-
411
- **🎯 Best for:** Legacy codebases, apps requiring true async operations, or when you need SQLCipher encryption.
412
-
413
- ---
414
-
415
- ## 🎯 Quick Decision Guide
416
-
417
- ### Choose **`@photostructure/sqlite`** when you want:
418
-
419
- - ✅ **Future-proof code** that works with both this package AND `node:sqlite`
420
- - ✅ **Node.js API compatibility** without waiting for stable release
421
- - ✅ **Broad Node.js support** (v20+) without experimental flags
422
- - ✅ **Synchronous performance** with a clean, official API
423
- - ✅ **Node-API stability** — one build works across Node.js versions
424
- - ✅ **Zero migration path** when `node:sqlite` becomes stable
425
- - ✅ **Session/changeset support** for replication and synchronization
426
-
427
- ### Choose **`better-sqlite3`** when you want:
428
-
429
- - ✅ The most mature and feature-rich synchronous SQLite library
430
- - ✅ Maximum performance above all else
431
- - ✅ A specific API design that differs from Node.js
432
-
433
- ### Choose **`sqlite3`** when you have:
434
-
435
- - ✅ Legacy code using async/callback patterns
436
- - ✅ Hard requirement for non-blocking operations
437
- - ✅ Need for SQLCipher encryption
438
-
439
- ### Choose **`node:sqlite`** when you're:
440
-
441
- - ✅ Experimenting with bleeding-edge Node.js features
442
- - ✅ Building proof-of-concepts for future migration
443
- - ✅ Working in environments where you control the Node.js version
444
-
445
- ## Contributing
446
-
447
- Contributions are welcome! This project maintains 100% API compatibility with Node.js's built-in SQLite module. Please run tests with `npm test` and ensure code passes linting with `npm run lint` before submitting changes. When adding new features, include corresponding tests and ensure they match Node.js SQLite behavior exactly.
448
-
449
- The project includes automated sync scripts to keep up-to-date with:
450
-
451
- - **Node.js SQLite implementation** via `npm run sync:node`
452
- - **SQLite library updates** via `npm run sync:sqlite`
453
-
454
- ## Security
455
-
456
- This project takes security seriously and employs multiple layers of protection:
457
-
458
- - **Automated scanning**: npm audit, Snyk, OSV Scanner, CodeQL (JS/TS and C++), and TruffleHog
459
- - **Weekly security scans**: Automated checks for new vulnerabilities
460
- - **Rapid patching**: Security fixes are prioritized and released quickly
461
- - **Memory safety**: Validated through ASAN, valgrind, and comprehensive testing
462
-
463
- ### Running Security Scans Locally
464
-
465
- ```bash
466
- # Install security tools (OSV Scanner, etc.)
467
- ./scripts/setup-security-tools.sh
468
-
469
- # Run all security scans
470
- npm run security
471
- ```
472
-
473
- For details, see our [Security Policy](./SECURITY.md). To report vulnerabilities, please email security@photostructure.com.
474
-
475
- ## License
476
-
477
- MIT License - see [LICENSE](./LICENSE) for details.
478
-
479
- This package includes SQLite, which is in the public domain, as well as code from the Node.js project, which is MIT licensed.
67
+ - [API Reference](./doc/api-reference.md)
68
+ - [All Features](./doc/features.md)
69
+ - [Build Flags & Configuration](./doc/build-flags.md)
70
+ - [Library Comparison](./doc/library-comparison.md)
480
71
 
481
72
  ## Support
482
73
 
483
- - 🐛 **Bug reports**: [GitHub Issues](https://github.com/photostructure/node-sqlite/issues)
484
- - 💬 **Questions**: [GitHub Discussions](https://github.com/photostructure/node-sqlite/discussions)
485
- - 📧 **Security issues**: see [SECURITY.md](./SECURITY.md)
74
+ - 🐛 [Issues](https://github.com/photostructure/node-sqlite/issues)
75
+ - 💬 [Discussions](https://github.com/photostructure/node-sqlite/discussions)
76
+ - 📧 [Security](./SECURITY.md)
486
77
 
487
- ---
488
-
489
- ## Development
490
-
491
- This project was built with substantial assistance from [Claude Code](https://claude.ai/referral/gM3vgw7pfA), an AI coding assistant.
492
-
493
- Note that all changes are human-reviewed before merging.
494
-
495
- ### Project Timeline
496
-
497
- - <details>
498
- <summary>900+ lines of C++</summary>
499
- `find . -name "*.cpp" -o -name "*.h" -not -path "./node_modules/*" -not -path "./vendored/*" -not -path "*/upstream/*" -exec wc -l {} +`
500
- </details>
501
- - <details>
502
- <summary>17,000 lines of comprehensive TypeScript tests
503
- </summary>
504
- `find . -name "*.ts" -not -path "./node_modules/*" -not -path "./vendored/*" -not -path "*/upstream/*" -exec wc -l {} +`
505
- </details>
506
- - **400+ tests** with full API compliance running in both ESM and CJS modes
507
- - **Multi-platform CI/CD** with automated builds
508
- - **Security scanning** and memory leak detection
509
- - **Automated sync** from Node.js and SQLite upstream
510
- - **Robust [benchmarking suite](./benchmark/README.md)** including all popular Node.js SQLite libraries
511
-
512
- ### Development Cost
78
+ ## License
513
79
 
514
- - **API usage**: ~$1400 in Claude API tokens
515
- - **Actual cost**: $200/month MAX 20x plan subscription
516
- - **Time saved**: At least a month of setup, analysis, porting and testing
80
+ MIT - see [LICENSE](./LICENSE) for details.
517
81
 
518
- This project demonstrates how AI-assisted development can accelerate complex system programming while maintaining high code quality through comprehensive testing and human oversight.
82
+ This package includes SQLite (public domain) and code from Node.js (MIT licensed).
519
83
 
520
84
  ---
521
85