indexeddbshim 17.0.0 → 17.2.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.
Files changed (58) hide show
  1. package/README.md +62 -0
  2. package/badges/licenses-badge-dev.svg +1 -1
  3. package/badges/licenses-badge.svg +1 -1
  4. package/dist/CFG.d.ts +1 -0
  5. package/dist/CFG.d.ts.map +1 -1
  6. package/dist/DOMException.d.ts.map +1 -1
  7. package/dist/IDBCursor.d.ts +25 -18
  8. package/dist/IDBCursor.d.ts.map +1 -1
  9. package/dist/IDBFactory.d.ts +19 -19
  10. package/dist/IDBFactory.d.ts.map +1 -1
  11. package/dist/IDBIndex.d.ts.map +1 -1
  12. package/dist/IDBKeyRange.d.ts +5 -5
  13. package/dist/IDBKeyRange.d.ts.map +1 -1
  14. package/dist/IDBTransaction.d.ts +24 -3
  15. package/dist/IDBTransaction.d.ts.map +1 -1
  16. package/dist/Key.d.ts +41 -41
  17. package/dist/Key.d.ts.map +1 -1
  18. package/dist/indexeddbshim-Key.js +88 -69
  19. package/dist/indexeddbshim-Key.js.map +1 -1
  20. package/dist/indexeddbshim-Key.min.js +2 -2
  21. package/dist/indexeddbshim-Key.min.js.map +1 -1
  22. package/dist/indexeddbshim-UnicodeIdentifiers-node.cjs +1682 -1056
  23. package/dist/indexeddbshim-UnicodeIdentifiers-node.cjs.map +1 -1
  24. package/dist/indexeddbshim-UnicodeIdentifiers.js +886 -663
  25. package/dist/indexeddbshim-UnicodeIdentifiers.js.map +1 -1
  26. package/dist/indexeddbshim-UnicodeIdentifiers.min.js +4 -4
  27. package/dist/indexeddbshim-UnicodeIdentifiers.min.js.map +1 -1
  28. package/dist/indexeddbshim-node.cjs +1682 -1056
  29. package/dist/indexeddbshim-node.cjs.map +1 -1
  30. package/dist/indexeddbshim-noninvasive.js +886 -663
  31. package/dist/indexeddbshim-noninvasive.js.map +1 -1
  32. package/dist/indexeddbshim-noninvasive.min.js +4 -4
  33. package/dist/indexeddbshim-noninvasive.min.js.map +1 -1
  34. package/dist/indexeddbshim.js +890 -660
  35. package/dist/indexeddbshim.js.map +1 -1
  36. package/dist/indexeddbshim.min.js +4 -4
  37. package/dist/indexeddbshim.min.js.map +1 -1
  38. package/dist/node-UnicodeIdentifiers.d.ts.map +1 -1
  39. package/dist/node.d.ts.map +1 -1
  40. package/dist/nodeSQLiteDatabase.d.ts +65 -0
  41. package/dist/nodeSQLiteDatabase.d.ts.map +1 -0
  42. package/dist/nodeWebSQL.d.ts.map +1 -1
  43. package/dist/util.d.ts +5 -0
  44. package/dist/util.d.ts.map +1 -1
  45. package/package.json +22 -18
  46. package/src/CFG.js +3 -0
  47. package/src/DOMException.js +10 -10
  48. package/src/IDBCursor.js +152 -102
  49. package/src/IDBFactory.js +30 -26
  50. package/src/IDBIndex.js +1 -2
  51. package/src/IDBKeyRange.js +5 -5
  52. package/src/IDBTransaction.js +35 -5
  53. package/src/Key.js +63 -55
  54. package/src/node-UnicodeIdentifiers.js +5 -1
  55. package/src/node.js +5 -1
  56. package/src/nodeSQLiteDatabase.js +174 -0
  57. package/src/nodeWebSQL.js +1 -3
  58. package/src/util.js +62 -3
package/src/util.js CHANGED
@@ -51,7 +51,12 @@ function escapeNameForSQLiteIdentifier (arg) {
51
51
  * @returns {string}
52
52
  */
53
53
  function escapeSQLiteStatement (arg) {
54
- return escapeUnmatchedSurrogates(arg.replaceAll('^', '^^').replaceAll('\0', '^0'));
54
+ const escaped = arg.replaceAll('^', '^^');
55
+ return escapeUnmatchedSurrogates(
56
+ CFG.escapeNULForSQLiteStatements === false
57
+ ? escaped
58
+ : escaped.replaceAll('\0', '^0')
59
+ );
55
60
  }
56
61
 
57
62
  /**
@@ -59,7 +64,11 @@ function escapeSQLiteStatement (arg) {
59
64
  * @returns {string}
60
65
  */
61
66
  function unescapeSQLiteResponse (arg) {
62
- return unescapeUnmatchedSurrogates(arg)
67
+ const unescaped = unescapeUnmatchedSurrogates(arg);
68
+ if (CFG.escapeNULForSQLiteStatements === false) {
69
+ return unescaped.replaceAll('^^', '^');
70
+ }
71
+ return unescaped
63
72
  .replaceAll(/(\^+)0/gu, (_, esc) => {
64
73
  return esc.length % 2
65
74
  ? esc.slice(1) + '\0'
@@ -548,6 +557,56 @@ function isNullish (v) {
548
557
  return v === null || v === undefined;
549
558
  }
550
559
 
560
+ /**
561
+ * Cursor/request continuation chains can call each other synchronously
562
+ * (e.g. walking a large prefetched buffer, or advancing many interleaved
563
+ * cursors in one transaction) which, for large enough record counts, can
564
+ * exceed the JS engine's call stack ("Maximum call stack size exceeded").
565
+ *
566
+ * This can't be fixed by deferring continuations to a microtask/macrotask:
567
+ * the transaction machinery synchronously checks (once the current call
568
+ * stack unwinds) whether there are any pending requests left in order to
569
+ * decide it's safe to commit; deferring a continuation opens a real gap in
570
+ * which that check runs first and the transaction completes prematurely,
571
+ * with the deferred continuation then acting on an already-finished
572
+ * transaction (a hang, since it can never resolve).
573
+ *
574
+ * Instead, this implements a true trampoline: the first call starts a
575
+ * synchronous work queue and drains it in a flat loop; any call made while
576
+ * already draining (i.e. a continuation triggering another continuation)
577
+ * is simply appended to that same queue and returns immediately instead of
578
+ * recursing. This keeps everything synchronous (so no completion-check
579
+ * race is introduced) while preventing the call stack from growing with
580
+ * each successive continuation.
581
+ */
582
+ const continuationState = {
583
+ /** @type {Array<() => void>|null} */
584
+ queue: null
585
+ };
586
+
587
+ /**
588
+ * @param {() => void} fn
589
+ * @returns {void}
590
+ */
591
+ function runContinuationSafely (fn) {
592
+ if (continuationState.queue) {
593
+ continuationState.queue.push(fn);
594
+ return;
595
+ }
596
+ const queue = [fn];
597
+ continuationState.queue = queue;
598
+ try {
599
+ while (queue.length) {
600
+ const next = /** @type {() => void} */ (queue.shift());
601
+ next();
602
+ }
603
+ } finally {
604
+ // Ensure a thrown exception can't leave the queue permanently
605
+ // stuck (which would silently swallow all future continuations).
606
+ continuationState.queue = null;
607
+ }
608
+ }
609
+
551
610
  export {escapeSQLiteStatement, unescapeSQLiteResponse,
552
611
  escapeDatabaseNameForSQLAndFiles, unescapeDatabaseNameForSQLAndFiles,
553
612
  escapeStoreNameForSQL, escapeIndexNameForSQL, escapeIndexNameForSQLKeyColumn,
@@ -558,4 +617,4 @@ export {escapeSQLiteStatement, unescapeSQLiteResponse,
558
617
  defineListenerProperties, defineReadonlyProperties,
559
618
  isValidKeyPath, enforceRange,
560
619
  convertToDOMString, convertToSequenceDOMString,
561
- isNullish};
620
+ isNullish, runContinuationSafely};