indexeddbshim 19.0.3 → 19.0.5

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 (35) hide show
  1. package/README.md +1 -6
  2. package/badges/coverage-badge.svg +1 -1
  3. package/badges/tests-badge.svg +1 -1
  4. package/dist/IDBTransaction.d.ts +15 -0
  5. package/dist/IDBTransaction.d.ts.map +1 -1
  6. package/dist/indexeddbshim-Key.js +2 -2
  7. package/dist/indexeddbshim-Key.js.map +1 -1
  8. package/dist/indexeddbshim-Key.min.js +1 -1
  9. package/dist/indexeddbshim-Key.min.js.map +1 -1
  10. package/dist/indexeddbshim-UnicodeIdentifiers-node.cjs +91 -25
  11. package/dist/indexeddbshim-UnicodeIdentifiers-node.cjs.map +1 -1
  12. package/dist/indexeddbshim-UnicodeIdentifiers.js +89 -24
  13. package/dist/indexeddbshim-UnicodeIdentifiers.js.map +1 -1
  14. package/dist/indexeddbshim-UnicodeIdentifiers.min.js +3 -3
  15. package/dist/indexeddbshim-UnicodeIdentifiers.min.js.map +1 -1
  16. package/dist/indexeddbshim-node.cjs +89 -24
  17. package/dist/indexeddbshim-node.cjs.map +1 -1
  18. package/dist/indexeddbshim-noninvasive.js +89 -24
  19. package/dist/indexeddbshim-noninvasive.js.map +1 -1
  20. package/dist/indexeddbshim-noninvasive.min.js +2 -2
  21. package/dist/indexeddbshim-noninvasive.min.js.map +1 -1
  22. package/dist/indexeddbshim.js +89 -24
  23. package/dist/indexeddbshim.js.map +1 -1
  24. package/dist/indexeddbshim.min.js +2 -2
  25. package/dist/indexeddbshim.min.js.map +1 -1
  26. package/dist/node-UnicodeIdentifiers.d.ts.map +1 -1
  27. package/dist/setGlobalVars.d.ts.map +1 -1
  28. package/dist/util.d.ts +0 -6
  29. package/dist/util.d.ts.map +1 -1
  30. package/package.json +22 -18
  31. package/src/CFG.js +1 -1
  32. package/src/IDBTransaction.js +87 -23
  33. package/src/node-UnicodeIdentifiers.js +2 -1
  34. package/src/setGlobalVars.js +2 -1
  35. package/src/util.js +1 -11
@@ -1,4 +1,4 @@
1
- /*! indexeddbshim - v19.0.3 - 9/15/2026 */
1
+ /*! indexeddbshim - v19.0.5 - 9/17/2026 */
2
2
 
3
3
  'use strict';
4
4
 
@@ -1446,7 +1446,7 @@ const CFG = /** @type {ConfigValues} */{};
1446
1446
  'UnicodeIDStart',
1447
1447
  // In the non-Unicode builds, defaults to /[$0-9A-Z_a-z]/
1448
1448
  'UnicodeIDContinue',
1449
- // Used by SCA.js for optional restructuring of typeson-registry
1449
+ // Used by Sca.js for optional restructuring of typeson-registry
1450
1450
  // Structured Cloning Algorithm; should only be needed for ensuring data
1451
1451
  // created in 3.* versions of IndexedDBShim continue to work; see the
1452
1452
  // library `typeson-registry-sca-reverter` to get a function to do this
@@ -4941,6 +4941,7 @@ const readonlyProperties$4 = ['objectStoreNames', 'mode', 'durability', 'db', 'e
4941
4941
  * __requestsFinished: boolean,
4942
4942
  * __transFinishedCb: (err: boolean, cb: ((bool?: boolean) => void)) => void,
4943
4943
  * __callTransFinishedCb: (err: boolean, cb: ((bool?: boolean) => void)) => void,
4944
+ * __usesStandardDriver: () => boolean,
4944
4945
  * __transactionEndCallback: (() => void)|undefined,
4945
4946
  * __transactionFinished: boolean,
4946
4947
  * __completed: boolean,
@@ -5078,6 +5079,27 @@ IDBTransaction.prototype.__transFinishedCb = function (err, cb) {
5078
5079
  cb(Boolean(err));
5079
5080
  };
5080
5081
 
5082
+ /**
5083
+ * A standard (3-argument) `transaction()`/`readTransaction()` implementation
5084
+ * (browser WebSQL, `cordova-plugin-sqlite-2`, etc.) never invokes the
5085
+ * non-standard 4th callback that installs the real `__transFinishedCb`,
5086
+ * and finalizes its own underlying SQL transaction synchronously, as soon
5087
+ * as it sees no further `executeSql` call already in flight or queued --
5088
+ * with no way for it to know a JS-level continuation (e.g. an
5089
+ * `await`-deferred follow-up request) is still coming. Detected via
5090
+ * arity, checking whichever of the two methods this transaction's own
5091
+ * mode actually uses.
5092
+ * @this {IDBTransactionFull}
5093
+ * @returns {boolean}
5094
+ */
5095
+ IDBTransaction.prototype.__usesStandardDriver = function () {
5096
+ const me = this;
5097
+ const dbConn = me.db && me.db.__db;
5098
+ const dbMethodName = me.mode === 'readonly' ? 'readTransaction' : 'transaction';
5099
+ const supportsNonstandardTransCb = Boolean(dbConn && typeof dbConn[dbMethodName] === 'function' && dbConn[dbMethodName].length >= 4);
5100
+ return !supportsNonstandardTransCb;
5101
+ };
5102
+
5081
5103
  /**
5082
5104
  * In Node, the real (SQL-commit-capable) `__transFinishedCb` is only
5083
5105
  * installed once the underlying WebSQL driver's own SQL-queue-idle check
@@ -5112,17 +5134,11 @@ IDBTransaction.prototype.__callTransFinishedCb = function (err, cb) {
5112
5134
  return;
5113
5135
  }
5114
5136
  if (me.__transFinishedCb === IDBTransaction.prototype.__transFinishedCb) {
5115
- // Standard (3-argument) `transaction()`/`readTransaction()` implementations
5116
- // (browser WebSQL, `cordova-plugin-sqlite-2`, etc.) never invoke the
5117
- // non-standard 4th callback that installs the real `__transFinishedCb`,
5118
- // so waiting for it here would defer forever. Detect that via arity
5119
- // (checking whichever of the two methods this transaction's own mode
5120
- // actually uses -- see `__executeRequests`) and, if it's not supported,
5121
- // just call the default (the driver auto-commits on its own).
5122
- const dbConn = me.db && me.db.__db;
5123
- const dbMethodName = me.mode === 'readonly' ? 'readTransaction' : 'transaction';
5124
- const supportsNonstandardTransCb = Boolean(dbConn && typeof dbConn[dbMethodName] === 'function' && dbConn[dbMethodName].length >= 4);
5125
- if (!supportsNonstandardTransCb) {
5137
+ // Waiting here for the non-standard 4th callback to install the real
5138
+ // `__transFinishedCb` would defer forever on a standard driver, which
5139
+ // never invokes it -- call the default instead (the driver auto-commits
5140
+ // on its own).
5141
+ if (me.__usesStandardDriver()) {
5126
5142
  me.__transFinishedCbFired = true;
5127
5143
  me.__transFinishedCb(err, cb);
5128
5144
  return;
@@ -5161,10 +5177,56 @@ IDBTransaction.prototype.__executeRequests = function () {
5161
5177
  // `readTransaction` is optimized, at least in `node-websql`
5162
5178
  function executeRequests(tx) {
5163
5179
  me.__tx = tx;
5180
+ const isStandardDriver = me.__usesStandardDriver();
5164
5181
  /** @type {RequestInfo} */
5165
5182
  let q,
5166
5183
  i = -1;
5167
5184
 
5185
+ // On a standard driver, `keepAliveAndWait` issues a SQL query, which
5186
+ // is a macrotask. Otherwise it issues ten microtasks.
5187
+ const keepAliveAttempts = isStandardDriver ? 1 : 10;
5188
+
5189
+ /**
5190
+ * A continuation that must still be able to observe the
5191
+ * transaction as safe to extend (e.g., re-checking whether an
5192
+ * `await`-based follow-up request has arrived yet, or giving a
5193
+ * same-tick microtask scheduled from a handler a chance to run
5194
+ * first) can normally just be deferred via `queueMicrotask`.
5195
+ * That alone isn't safe on a standard (3-argument) driver,
5196
+ * though: it finalizes its own underlying SQL transaction
5197
+ * synchronously, as soon as it sees no further `executeSql`
5198
+ * call already in flight or queued, and a microtask hop by
5199
+ * itself never issues one -- so the driver already considers
5200
+ * the transaction done by the time the deferred continuation
5201
+ * runs, silently dropping whatever it tries to do next. Issuing
5202
+ * a harmless `SELECT 1` instead keeps the driver's own queue
5203
+ * non-empty across that same gap, at the cost of a real SQL
5204
+ * round trip; Node's driver doesn't need this since its real
5205
+ * commit/rollback is already deferred separately, via
5206
+ * `nonstandardTransCb`.
5207
+ * @param {() => void} cb
5208
+ * @returns {void}
5209
+ */
5210
+ function keepAliveAndWait(cb) {
5211
+ if (!isStandardDriver) {
5212
+ queueMicrotask(cb);
5213
+ return;
5214
+ }
5215
+ try {
5216
+ tx.executeSql('SELECT 1', [], function () {
5217
+ cb();
5218
+ }, function () {
5219
+ cb();
5220
+ return false; // Don't roll back the transaction over a keep-alive no-op
5221
+ });
5222
+ } catch (err) {
5223
+ // The driver has already finalized the transaction (or otherwise
5224
+ // rejected the call) -- nothing left to hold open. We explicitly
5225
+ // abort the transaction here.
5226
+ me.__abortTransaction(/** @type {Error|DOMException} */err);
5227
+ }
5228
+ }
5229
+
5168
5230
  /**
5169
5231
  * @typedef {unknown} IDBRequestResult
5170
5232
  */
@@ -5353,9 +5415,9 @@ IDBTransaction.prototype.__executeRequests = function () {
5353
5415
  * from a microtask -- so if the JS-level queue is merely found
5354
5416
  * empty here, that doesn't yet mean no more work is coming, only
5355
5417
  * that none has been queued *yet*. Re-check across a small, bounded
5356
- * number of further microtask turns (letting a typical `await`
5357
- * chain like `await store.put(...); await store.get(...)` catch
5358
- * up) before finally concluding the transaction is genuinely done.
5418
+ * number of further turns (see `keepAliveAndWait`, letting a typical
5419
+ * `await` chain like `await store.put(...); await store.get(...)`
5420
+ * catch up) before finally concluding the transaction is genuinely done.
5359
5421
  * Applies to `readonly` transactions too, not just `readwrite`/
5360
5422
  * `versionchange`: a `readonly` transaction's `complete` event
5361
5423
  * can otherwise fire synchronously, immediately after its last
@@ -5363,9 +5425,11 @@ IDBTransaction.prototype.__executeRequests = function () {
5363
5425
  * consumer of that same handler (e.g. one that resolves a
5364
5426
  * promise from within `onsuccess` and only attaches `oncomplete`
5365
5427
  * afterward) ever gets a turn to run, so it can miss `complete`
5366
- * entirely. `readonly` requests don't hold a real SQL
5367
- * transaction open, though, so there's no file-lock/connection
5368
- * collision risk in waiting the same bounded amount here.
5428
+ * afterward) ever gets a turn to run, so it can miss `complete`
5429
+ * entirely. On a non-standard driver, `readonly` requests don't hold
5430
+ * a real SQL transaction open, so there's no file-lock/connection
5431
+ * collision risk. On a standard driver, the wait now issues real SQL
5432
+ * inside the read transaction, so this does carry a slight risk.
5369
5433
  * @param {number} attemptsLeft
5370
5434
  * @returns {void}
5371
5435
  */
@@ -5385,7 +5449,7 @@ IDBTransaction.prototype.__executeRequests = function () {
5385
5449
  }
5386
5450
  return;
5387
5451
  }
5388
- queueMicrotask(() => {
5452
+ keepAliveAndWait(() => {
5389
5453
  checkQueueEntry(attemptsLeft - 1);
5390
5454
  });
5391
5455
  }
@@ -5400,7 +5464,7 @@ IDBTransaction.prototype.__executeRequests = function () {
5400
5464
  }
5401
5465
  i++;
5402
5466
  if (i >= me.__requests.length) {
5403
- checkQueueEntry(10);
5467
+ checkQueueEntry(keepAliveAttempts);
5404
5468
  return;
5405
5469
  }
5406
5470
  runQueuedRequest();
@@ -5437,10 +5501,10 @@ IDBTransaction.prototype.__executeRequests = function () {
5437
5501
  }
5438
5502
  i++;
5439
5503
  if (i >= me.__requests.length) {
5440
- checkQueueEntry(10);
5504
+ checkQueueEntry(keepAliveAttempts);
5441
5505
  return;
5442
5506
  }
5443
- queueMicrotask(() => {
5507
+ keepAliveAndWait(() => {
5444
5508
  if (me.__errored || me.__requestsFinished) {
5445
5509
  return;
5446
5510
  }
@@ -13054,10 +13118,11 @@ function setGlobalVars(idb, initialConfig) {
13054
13118
  setNonIDBGlobals();
13055
13119
  }
13056
13120
  }
13057
- /* istanbul ignore next -- TS guard */
13121
+ /* c8 ignore start -- TS guard */
13058
13122
  if (!IDB.shimIndexedDB) {
13059
13123
  return;
13060
13124
  }
13125
+ /* c8 ignore stop -- TS guard */
13061
13126
  IDB.shimIndexedDB.__setConnectionQueueOrigin();
13062
13127
  }
13063
13128
  };
@@ -13224,10 +13289,11 @@ const __setGlobalVars = function (idb, initialConfig = {}) {
13224
13289
  escapeNULForSQLiteStatements: false,
13225
13290
  ...initialConfig
13226
13291
  });
13227
- /* istanbul ignore next -- TS guard */
13292
+ /* c8 ignore start -- TS guard */
13228
13293
  if (!obj.shimIndexedDB) {
13229
13294
  return obj;
13230
13295
  }
13296
+ /* c8 ignore stop -- TS guard */
13231
13297
  obj.shimIndexedDB.__setUnicodeIdentifiers(UnicodeIdentifiers);
13232
13298
  return obj;
13233
13299
  };