@homeofthings/sqlite3 6.3.1 → 6.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -20,7 +20,7 @@ Asynchronous, non-blocking [SQLite3](https://sqlite.org/) bindings for [Node.js]
20
20
  - [Extension support](https://github.com/gms1/node-sqlite3/wiki/API#databaseloadextensionpath-callback), including bundled support for the [json1 extension](https://www.sqlite.org/json1.html)
21
21
  - Big test suite
22
22
  - Written in modern C++ and tested for memory leaks
23
- - Bundles SQLite v3.51.3, or you can build using a local SQLite
23
+ - Bundles SQLite v3.53.0, or you can build using a local SQLite
24
24
 
25
25
  # Installing
26
26
 
@@ -245,6 +245,34 @@ npm install @homeofthings/sqlite3 --build-from-source --sqlite_libname=sqlcipher
245
245
  npm test
246
246
  ```
247
247
 
248
+ # Benchmarks
249
+
250
+ ## Driver Comparison
251
+
252
+ The `tools/benchmark-drivers` directory contains a comprehensive benchmark suite comparing different SQLite drivers for Node.js:
253
+
254
+ ```bash
255
+ cd tools/benchmark-drivers
256
+ npm install
257
+ node index.js
258
+ ```
259
+
260
+ This compares `@homeofthings/sqlite3` against other popular SQLite drivers:
261
+ - `better-sqlite3` - Synchronous, high-performance
262
+ - `node:sqlite` - Built-in Node.js SQLite (v22.6.0+)
263
+
264
+ See [tools/benchmark-drivers/README.md](tools/benchmark-drivers/README.md) for details.
265
+
266
+ **Key insight**: Async drivers like `@homeofthings/sqlite3` show lower raw throughput but provide better event loop availability, allowing other operations to proceed concurrently. Sync drivers block the event loop completely.
267
+
268
+ ## Internal Benchmarks
269
+
270
+ Internal performance benchmarks are available in `tools/benchmark-internal`:
271
+
272
+ ```bash
273
+ node tools/benchmark-internal/run.js
274
+ ```
275
+
248
276
  # Contributors
249
277
 
250
278
  * [Daniel Lockyer](https://github.com/daniellockyer)
@@ -269,7 +297,9 @@ Thanks to [Orlando Vazquez](https://github.com/orlandov),
269
297
  [Eric Fredricksen](https://github.com/grumdrig) and
270
298
  [Ryan Dahl](https://github.com/ry) for their SQLite bindings for node, and to mraleph on Freenode's #v8 for answering questions.
271
299
 
272
- This module was originally created by [Mapbox](https://mapbox.com/) & is now maintained by [Ghost](https://ghost.org).
300
+ This module was originally created by [Mapbox](https://mapbox.com/), then it was taken over by [Ghost](https://ghost.org), but was then deprecated without prior notice, so that the original is no longer maintained. See [TryGhost/node-sqlite3](https://github.com/TryGhost/node-sqlite3)
301
+
302
+ I still hope that it will eventually be taken over by a larger organization, but in the meantime, I'm trying to maintain this fork here.
273
303
 
274
304
  # Changelog
275
305
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  'variables': {
3
- 'sqlite_version%':'3510300',
3
+ 'sqlite_version%':'3530000',
4
4
  "toolset%":'',
5
5
  },
6
6
  'target_defaults': {
@@ -324,9 +324,18 @@ class SqliteDatabase {
324
324
  /**
325
325
  * Run callback inside a database transaction
326
326
  *
327
+ * IMPORTANT: SQLite provides isolation between different database connections,
328
+ * but NOT between operations on the same connection. If you need concurrent
329
+ * transactions with proper isolation, use separate SqliteDatabase instances.
330
+ *
331
+ * Note: This uses BEGIN IMMEDIATE TRANSACTION which acquires a write lock
332
+ * immediately. If another connection holds a write lock, this will fail
333
+ * with SQLITE_BUSY error.
334
+ *
327
335
  * @template T
328
336
  * @param {() => Promise<T>} callback - The callback to run in transaction
329
337
  * @returns {Promise<T>} A promise that resolves to the callback result
338
+ * @see https://www.sqlite.org/isolation.html
330
339
  */
331
340
  async transactionalize(callback) {
332
341
  await this.beginTransaction();
@@ -341,7 +350,10 @@ class SqliteDatabase {
341
350
  }
342
351
 
343
352
  /**
344
- * Begin a transaction
353
+ * Begin a transaction using BEGIN IMMEDIATE TRANSACTION
354
+ *
355
+ * This acquires a write lock immediately, preventing deadlocks by
356
+ * failing fast if another connection holds the lock (SQLITE_BUSY).
345
357
  *
346
358
  * @returns {Promise<SqlRunResult>}
347
359
  */
@@ -60,6 +60,10 @@ class SqliteStatement {
60
60
  /**
61
61
  * Finalizes a prepared statement (freeing any resource used by this statement)
62
62
  *
63
+ * IMPORTANT: You MUST finalize all prepared statements before closing the database.
64
+ * If you attempt to close a database with unfinalized statements, you will get:
65
+ * SQLITE_BUSY: unable to close due to unfinalised statements
66
+ *
63
67
  * @returns {Promise<void>}
64
68
  */
65
69
  finalize() {
package/lib/sqlite3.d.ts CHANGED
@@ -265,7 +265,22 @@ export class SqliteDatabase {
265
265
  serialize(callback?: () => void): void;
266
266
  parallelize(callback?: () => void): void;
267
267
 
268
+ /**
269
+ * Run callback inside a database transaction.
270
+ *
271
+ * IMPORTANT: SQLite provides isolation between different database connections,
272
+ * but NOT between operations on the same connection. For concurrent transactions
273
+ * with proper isolation, use separate SqliteDatabase instances.
274
+ *
275
+ * Uses BEGIN IMMEDIATE TRANSACTION which acquires a write lock immediately.
276
+ * @see https://www.sqlite.org/isolation.html
277
+ */
268
278
  transactionalize<T>(callback: () => Promise<T>): Promise<T>;
279
+
280
+ /**
281
+ * Begin a transaction using BEGIN IMMEDIATE TRANSACTION.
282
+ * Acquires write lock immediately - fails with SQLITE_BUSY if lock unavailable.
283
+ */
269
284
  beginTransaction(): Promise<void>;
270
285
  commitTransaction(): Promise<void>;
271
286
  rollbackTransaction(): Promise<void>;
@@ -300,6 +315,11 @@ export class SqliteStatement {
300
315
  callback?: (err: Error | null, row: T) => void,
301
316
  ): Promise<number>;
302
317
 
318
+ /**
319
+ * Finalizes the statement.
320
+ * IMPORTANT: You MUST finalize all prepared statements before closing the database.
321
+ * Otherwise you will get SQLITE_BUSY: unable to close due to unfinalised statements
322
+ */
303
323
  finalize(): Promise<void>;
304
324
  }
305
325
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@homeofthings/sqlite3",
3
3
  "description": "Asynchronous, non-blocking SQLite3 bindings",
4
- "version": "6.3.1",
4
+ "version": "6.4.0",
5
5
  "homepage": "https://github.com/gms1/node-sqlite3",
6
6
  "author": {
7
7
  "name": "Mapbox",
@@ -52,7 +52,7 @@
52
52
  "devDependencies": {
53
53
  "@eslint/js": "^10.0.1",
54
54
  "eslint": "^10.2.0",
55
- "globals": "^17.4.0",
55
+ "globals": "^17.5.0",
56
56
  "mocha": "11.7.5",
57
57
  "nyc": "^18.0.0",
58
58
  "prebuild": "13.0.1",
Binary file