indexeddbshim 17.3.1 → 17.3.3

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 (33) hide show
  1. package/dist/IDBCursor.d.ts.map +1 -1
  2. package/dist/IDBFactory.d.ts.map +1 -1
  3. package/dist/IDBObjectStore.d.ts +28 -0
  4. package/dist/IDBObjectStore.d.ts.map +1 -1
  5. package/dist/IDBTransaction.d.ts.map +1 -1
  6. package/dist/indexeddbshim-Key.js +1 -1
  7. package/dist/indexeddbshim-Key.min.js +1 -1
  8. package/dist/indexeddbshim-UnicodeIdentifiers-node.cjs +507 -150
  9. package/dist/indexeddbshim-UnicodeIdentifiers-node.cjs.map +1 -1
  10. package/dist/indexeddbshim-UnicodeIdentifiers.js +334 -89
  11. package/dist/indexeddbshim-UnicodeIdentifiers.js.map +1 -1
  12. package/dist/indexeddbshim-UnicodeIdentifiers.min.js +3 -3
  13. package/dist/indexeddbshim-UnicodeIdentifiers.min.js.map +1 -1
  14. package/dist/indexeddbshim-node.cjs +507 -150
  15. package/dist/indexeddbshim-node.cjs.map +1 -1
  16. package/dist/indexeddbshim-noninvasive.js +334 -89
  17. package/dist/indexeddbshim-noninvasive.js.map +1 -1
  18. package/dist/indexeddbshim-noninvasive.min.js +3 -3
  19. package/dist/indexeddbshim-noninvasive.min.js.map +1 -1
  20. package/dist/indexeddbshim.js +334 -89
  21. package/dist/indexeddbshim.js.map +1 -1
  22. package/dist/indexeddbshim.min.js +3 -3
  23. package/dist/indexeddbshim.min.js.map +1 -1
  24. package/dist/nodeSQLiteDatabase.d.ts.map +1 -1
  25. package/dist/nodeWebSQL.d.ts.map +1 -1
  26. package/package.json +4 -3
  27. package/src/IDBCursor.js +34 -4
  28. package/src/IDBFactory.js +119 -21
  29. package/src/IDBObjectStore.js +103 -1
  30. package/src/IDBRecord.js +8 -0
  31. package/src/IDBTransaction.js +16 -2
  32. package/src/nodeSQLiteDatabase.js +92 -26
  33. package/src/nodeWebSQL.js +8 -1
@@ -1,4 +1,4 @@
1
- /*! indexeddbshim - v17.3.1 - 8/24/2026 */
1
+ /*! indexeddbshim - v17.3.3 - 8/25/2026 */
2
2
 
3
3
  (function (factory) {
4
4
  typeof define === 'function' && define.amd ? define(factory) :
@@ -6148,9 +6148,15 @@
6148
6148
  if (err !== null) {
6149
6149
  me.__error = err;
6150
6150
  }
6151
- if (me.__requestsFinished) {
6151
+ if (me.__requestsFinished && err !== null) {
6152
6152
  // The transaction has already completed, so we can't call "onerror" or "onabort".
6153
- // So throw the error instead.
6153
+ // So throw the error instead. `err` is only ever `null` here via
6154
+ // `IDBTransaction.prototype.abort`'s own `__abortTransaction(null)`
6155
+ // call, which now checks `__requestsFinished` itself first and
6156
+ // throws `InvalidStateError` synchronously before ever reaching
6157
+ // this point -- so this guard is just defense in depth against
6158
+ // `err` somehow being `null` some other way, not something this
6159
+ // path should see in practice.
6154
6160
  setTimeout(function () {
6155
6161
  throw err;
6156
6162
  }, 0);
@@ -6270,6 +6276,14 @@
6270
6276
  if (me.__committed) {
6271
6277
  throw createDOMException('InvalidStateError', 'The transaction has already been committed');
6272
6278
  }
6279
+ if (me.__requestsFinished) {
6280
+ // All requests have already finished and the transaction is
6281
+ // auto-committing (the async SQL commit round trip just hasn't
6282
+ // resolved yet) -- too late to abort per spec, even though
6283
+ // `__committed` itself isn't set until that round trip actually
6284
+ // finishes.
6285
+ throw createDOMException('InvalidStateError', 'The transaction is already committing');
6286
+ }
6273
6287
  me.__abortTransaction(null);
6274
6288
  };
6275
6289
 
@@ -6594,22 +6608,22 @@
6594
6608
  sync: true
6595
6609
  }, this.options), s),
6596
6610
  c = i.sync,
6597
- y = {},
6598
- u = [],
6611
+ u = {},
6612
+ y = [],
6599
6613
  l = [],
6600
6614
  p = [],
6601
6615
  f = !("cyclic" in i) || i.cyclic,
6602
6616
  d = i.encapsulateObserver,
6603
6617
  m = i.encapsulateError,
6604
6618
  finish = function finish(e) {
6605
- var t = Object.values(y);
6619
+ var t = Object.values(u);
6606
6620
  if (i.iterateNone) return t.length ? t[0] : getJSONType(e);
6607
6621
  if (t.length) {
6608
6622
  if (i.returnTypeNames) return _toConsumableArray(new Set(t));
6609
- e && isPlainObject(e) && !n(e, "$types") ? e.$types = y : e = {
6623
+ e && isPlainObject(e) && !n(e, "$types") ? e.$types = u : e = {
6610
6624
  $: e,
6611
6625
  $types: {
6612
- $: y
6626
+ $: u
6613
6627
  }
6614
6628
  };
6615
6629
  } else isObject(e) && n(e, "$types") && (e = {
@@ -6633,18 +6647,18 @@
6633
6647
  _context2.n = 2;
6634
6648
  return Promise.all(r.map(/*#__PURE__*/function () {
6635
6649
  var _ref = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(r) {
6636
- var n, _t$splice, _t$splice2, a, _a, o, s, i, c, y, u, l, p, _t, _t2, _t3, _t4;
6650
+ var n, _t$splice, _t$splice2, a, _a, o, s, i, c, u, y, l, p, _t, _t2, _t3, _t4;
6637
6651
  return _regenerator().w(function (_context) {
6638
6652
  while (1) switch (_context.n) {
6639
6653
  case 0:
6640
- n = [], _t$splice = t.splice(0, 1), _t$splice2 = _slicedToArray(_t$splice, 1), a = _t$splice2[0], _a = _slicedToArray(a, 7), o = _a[0], s = _a[2], i = _a[3], c = _a[4], y = _a[5], u = _a[6], l = _encapsulate2(o, r, s, i, n, true, u), p = hasConstructorOf(l, TypesonPromise);
6654
+ n = [], _t$splice = t.splice(0, 1), _t$splice2 = _slicedToArray(_t$splice, 1), a = _t$splice2[0], _a = _slicedToArray(a, 7), o = _a[0], s = _a[2], i = _a[3], c = _a[4], u = _a[5], y = _a[6], l = _encapsulate2(o, r, s, i, n, true, y), p = hasConstructorOf(l, TypesonPromise);
6641
6655
  if (!(o && p)) {
6642
6656
  _context.n = 2;
6643
6657
  break;
6644
6658
  }
6645
6659
  _t2 = setOwnEnumerable;
6646
6660
  _t3 = c;
6647
- _t4 = y;
6661
+ _t4 = u;
6648
6662
  _context.n = 1;
6649
6663
  return l.p;
6650
6664
  case 1:
@@ -6653,7 +6667,7 @@
6653
6667
  _context.n = 3;
6654
6668
  break;
6655
6669
  case 2:
6656
- _t = (o ? setOwnEnumerable(c, y, l) : e = p ? l.p : l, _checkPromises(e, n));
6670
+ _t = (o ? setOwnEnumerable(c, u, l) : e = p ? l.p : l, _checkPromises(e, n));
6657
6671
  case 3:
6658
6672
  return _context.a(2, _t);
6659
6673
  }
@@ -6732,11 +6746,11 @@
6732
6746
  })) : h = t, b && b(), h;
6733
6747
  if (null === t) return b && b(), t;
6734
6748
  if (o && t && "object" == _typeof(t) && !s.iterateIn && !s.iterateUnsetNumeric) {
6735
- var _r2 = u.indexOf(t);
6736
- if (-1 !== _r2) return y[e] = "#", b && b({
6749
+ var _r2 = y.indexOf(t);
6750
+ if (-1 !== _r2) return u[e] = "#", b && b({
6737
6751
  cyclicKeypath: l[_r2]
6738
6752
  }), "#" + l[_r2];
6739
- true === o && (u.push(t), l.push(e));
6753
+ true === o && (y.push(t), l.push(e));
6740
6754
  }
6741
6755
  var v = isPlainObject(t),
6742
6756
  w = a(t),
@@ -6806,14 +6820,14 @@
6806
6820
  },
6807
6821
  replace = function replace(e, t, r, n, a, o, s) {
6808
6822
  var i = a ? _this2.plainObjectReplacers : _this2.nonplainObjectReplacers;
6809
- var u = i.length;
6810
- for (; u--;) {
6811
- var _a3 = i[u];
6823
+ var y = i.length;
6824
+ for (; y--;) {
6825
+ var _a3 = i[y];
6812
6826
  if (_a3.test(t, r)) {
6813
6827
  var _i2 = _a3.type;
6814
6828
  if (Object.hasOwn(_this2.revivers, _i2)) {
6815
- var _t5 = y[e];
6816
- y[e] = _t5 ? [_i2].concat(_t5) : _i2;
6829
+ var _t5 = u[e];
6830
+ u[e] = _t5 ? [_i2].concat(_t5) : _i2;
6817
6831
  }
6818
6832
  if (Object.assign(r, {
6819
6833
  type: _i2,
@@ -6821,14 +6835,14 @@
6821
6835
  }), (c || !_a3.replaceAsync) && !_a3.replace) return s && s({
6822
6836
  typeDetected: true
6823
6837
  }), _encapsulate2(e, t, f && "readonly", r, n, o, _i2);
6824
- var _u = void 0;
6838
+ var _y = void 0;
6825
6839
  if (s && s({
6826
6840
  replacing: true
6827
6841
  }), c || !_a3.replaceAsync) {
6828
6842
  if (void 0 === _a3.replace) throw new TypeError("Missing replacer");
6829
- _u = _a3.replace(t, r);
6830
- } else _u = _a3.replaceAsync(t, r);
6831
- return _encapsulate2(e, _u, f && "readonly", r, n, o, _i2);
6843
+ _y = _a3.replace(t, r);
6844
+ } else _y = _a3.replaceAsync(t, r);
6845
+ return _encapsulate2(e, _y, f && "readonly", r, n, o, _i2);
6832
6846
  }
6833
6847
  }
6834
6848
  return t;
@@ -6876,8 +6890,8 @@
6876
6890
  if (true === i) return finishRevival(e.$);
6877
6891
  if (!i || "object" != _typeof(i) || Array.isArray(i)) return finishRevival(e);
6878
6892
  var c = [],
6879
- y = Object.create(null),
6880
- u = {};
6893
+ u = Object.create(null),
6894
+ y = {};
6881
6895
  var l = true;
6882
6896
  i.$ && isPlainObject(i.$) && (e = e.$, i = i.$, l = false);
6883
6897
  var executeReviver = function executeReviver(e, t) {
@@ -6887,8 +6901,8 @@
6887
6901
  r = _ref5[0];
6888
6902
  if (!r) throw new Error("Unregistered type: " + e);
6889
6903
  if (s && !("revive" in r)) return t;
6890
- if (!s && r.reviveAsync) return r.reviveAsync(t, u);
6891
- if (r.revive) return r.revive(t, u);
6904
+ if (!s && r.reviveAsync) return r.reviveAsync(t, y);
6905
+ if (r.revive) return r.revive(t, y);
6892
6906
  throw new Error("Missing reviver");
6893
6907
  },
6894
6908
  p = [];
@@ -6933,7 +6947,7 @@
6933
6947
  var d;
6934
6948
  return hasConstructorOf(f, TypesonPromise) ? d = f.then(function () {
6935
6949
  return e;
6936
- }) : (d = function _revive(e, t, o, u, f) {
6950
+ }) : (d = function _revive(e, t, o, y, f) {
6937
6951
  if (l && "$types" === e) return;
6938
6952
  var d = p.length,
6939
6953
  m = n(i, e) ? i[e] : void 0,
@@ -6954,18 +6968,18 @@
6954
6968
  _t6 = _c$[1],
6955
6969
  _r5 = _c$[2],
6956
6970
  _a5 = _c$[3],
6957
- _o2 = n(y, _t6),
6958
- _s = _o2 ? y[_t6] : getByKeyPath(_e2, _t6);
6971
+ _o2 = n(u, _t6),
6972
+ _s = _o2 ? u[_t6] : getByKeyPath(_e2, _t6);
6959
6973
  if (!_o2 && void 0 === _s) break;
6960
6974
  setOwnEnumerable(_r5, _a5, _s), c.shift();
6961
6975
  }
6962
6976
  }
6963
- if (!m) return y[e] = t, t;
6977
+ if (!m) return u[e] = t, t;
6964
6978
  if ("#" === m) {
6965
6979
  var _e3 = t.slice(1),
6966
- _r6 = n(y, _e3),
6967
- _a6 = _r6 ? y[_e3] : getByKeyPath(o, _e3);
6968
- return _r6 || void 0 !== _a6 || c.push([o, _e3, u, f]), _a6;
6980
+ _r6 = n(u, _e3),
6981
+ _a6 = _r6 ? u[_e3] : getByKeyPath(o, _e3);
6982
+ return _r6 || void 0 !== _a6 || c.push([o, _e3, y, f]), _a6;
6969
6983
  }
6970
6984
  var applyType = function applyType(t) {
6971
6985
  var r = [].concat(m).reduce(function reducer(e, t) {
@@ -6976,8 +6990,8 @@
6976
6990
  return executeReviver(t, e);
6977
6991
  }, t);
6978
6992
  return hasConstructorOf(r, TypesonPromise) ? r.then(function (t) {
6979
- return y[e] = t, t;
6980
- }) : (y[e] = r, r);
6993
+ return u[e] = t, t;
6994
+ }) : (u[e] = r, r);
6981
6995
  };
6982
6996
  return !s && p.length > d ? TypesonPromise.all(p.slice(d)).then(function () {
6983
6997
  return applyType(t);
@@ -7082,8 +7096,8 @@
7082
7096
  });
7083
7097
  Undefined.__typeson__type__ = "TypesonUndefined";
7084
7098
  var s = ["null", "boolean", "number", "string", "array", "object"];
7085
- for (var i = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", c = new Uint8Array(256), y = 0; y < 64; y++) c[i.codePointAt(y)] = y;
7086
- var u = function encode(e, t, r) {
7099
+ for (var i = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", c = new Uint8Array(256), u = 0; u < 64; u++) c[i.codePointAt(u)] = u;
7100
+ var y = function encode(e, t, r) {
7087
7101
  null == r && (r = e.byteLength);
7088
7102
  for (var n = new Uint8Array(e, 0, r), a = n.length, o = "", s = 0; s < a; s += 3) o += i[n[s] >> 2], o += i[(3 & n[s]) << 4 | n[s + 1] >> 4], o += i[(15 & n[s + 1]) << 2 | n[s + 2] >> 6], o += i[63 & n[s + 2]];
7089
7103
  return a % 3 == 2 ? o = o.slice(0, -1) + "=" : a % 3 == 1 && (o = o.slice(0, -2) + "=="), o;
@@ -7096,10 +7110,10 @@
7096
7110
  o,
7097
7111
  s,
7098
7112
  i = .75 * e.length,
7099
- y = 0;
7113
+ u = 0;
7100
7114
  "=" === e[e.length - 1] && (i--, "=" === e[e.length - 2] && i--);
7101
- for (var u = new ArrayBuffer(i, t), l = new Uint8Array(u), p = 0; p < r; p += 4) n = c[e.codePointAt(p)], a = c[e.codePointAt(p + 1)], o = c[e.codePointAt(p + 2)], s = c[e.codePointAt(p + 3)], l[y++] = n << 2 | a >> 4, l[y++] = (15 & a) << 4 | o >> 2, l[y++] = (3 & o) << 6 | 63 & s;
7102
- return u;
7115
+ for (var y = new ArrayBuffer(i, t), l = new Uint8Array(y), p = 0; p < r; p += 4) n = c[e.codePointAt(p)], a = c[e.codePointAt(p + 1)], o = c[e.codePointAt(p + 2)], s = c[e.codePointAt(p + 3)], l[u++] = n << 2 | a >> 4, l[u++] = (15 & a) << 4 | o >> 2, l[u++] = (3 & o) << 6 | 63 & s;
7116
+ return y;
7103
7117
  };
7104
7118
  var p = {
7105
7119
  arraybuffer: {
@@ -7112,7 +7126,7 @@
7112
7126
  return -1 !== r ? {
7113
7127
  index: r
7114
7128
  } : (t.buffers.push(e), {
7115
- s: u(e),
7129
+ s: y(e),
7116
7130
  maxByteLength: e.maxByteLength,
7117
7131
  resizable: e.resizable
7118
7132
  });
@@ -7146,13 +7160,13 @@
7146
7160
  });
7147
7161
  i.push(_r0), c += _r0;
7148
7162
  }
7149
- var y = new ArrayBuffer(c);
7150
- var u = 0;
7163
+ var u = new ArrayBuffer(c);
7164
+ var y = 0;
7151
7165
  for (var _t9 = 0; _t9 < s; _t9++) {
7152
- var _r1 = new Uint8Array(y, u, i[_t9]);
7166
+ var _r1 = new Uint8Array(u, y, i[_t9]);
7153
7167
  e.copyTo(_r1, {
7154
7168
  planeIndex: _t9
7155
- }), u += i[_t9];
7169
+ }), y += i[_t9];
7156
7170
  }
7157
7171
  return {
7158
7172
  format: t,
@@ -7160,7 +7174,7 @@
7160
7174
  numberOfFrames: n,
7161
7175
  numberOfChannels: a,
7162
7176
  timestamp: o,
7163
- data: y
7177
+ data: u
7164
7178
  };
7165
7179
  },
7166
7180
  revive: function revive(_ref11) {
@@ -7311,7 +7325,7 @@
7311
7325
  byteOffset: t,
7312
7326
  byteLength: r
7313
7327
  } : (n.buffers.push(e), {
7314
- encoded: u(e),
7328
+ encoded: y(e),
7315
7329
  maxByteLength: e.maxByteLength,
7316
7330
  resizable: e.resizable,
7317
7331
  byteOffset: t,
@@ -7943,7 +7957,7 @@
7943
7957
  } : (n.buffers.push(e), {
7944
7958
  maxByteLength: e.maxByteLength,
7945
7959
  resizable: e.resizable,
7946
- encoded: u(e),
7960
+ encoded: y(e),
7947
7961
  byteOffset: t,
7948
7962
  length: r
7949
7963
  });
@@ -7956,10 +7970,10 @@
7956
7970
  s = t.index,
7957
7971
  i = t.maxByteLength,
7958
7972
  c = t.resizable;
7959
- var y;
7960
- return "index" in t ? y = r.buffers[s] : (y = l(o, c ? {
7973
+ var u;
7974
+ return "index" in t ? u = r.buffers[s] : (u = l(o, c ? {
7961
7975
  maxByteLength: i
7962
- } : void 0), r.buffers.push(y)), new e(y, n, a);
7976
+ } : void 0), r.buffers.push(u)), new e(u, n, a);
7963
7977
  }
7964
7978
  };
7965
7979
  }(e);
@@ -7998,12 +8012,12 @@
7998
8012
  replaceAsync: function replaceAsync(e) {
7999
8013
  return new TypesonPromise(/*#__PURE__*/function () {
8000
8014
  var _ref29 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6(t, r) {
8001
- var _r12, _n3, _a7, _o3, _s2, _i3, _c, _y, _u2, _l, _t14;
8015
+ var _r12, _n3, _a7, _o3, _s2, _i3, _c, _u, _y2, _l, _t14;
8002
8016
  return _regenerator().w(function (_context6) {
8003
8017
  while (1) switch (_context6.p = _context6.n) {
8004
8018
  case 0:
8005
8019
  _context6.p = 0;
8006
- _r12 = e.format, _n3 = e.codedWidth, _a7 = e.codedHeight, _o3 = e.timestamp, _s2 = e.duration, _i3 = e.visibleRect, _c = e.displayWidth, _y = e.displayHeight, _u2 = e.colorSpace, _l = new ArrayBuffer(e.allocationSize());
8020
+ _r12 = e.format, _n3 = e.codedWidth, _a7 = e.codedHeight, _o3 = e.timestamp, _s2 = e.duration, _i3 = e.visibleRect, _c = e.displayWidth, _u = e.displayHeight, _y2 = e.colorSpace, _l = new ArrayBuffer(e.allocationSize());
8007
8021
  _context6.n = 1;
8008
8022
  return e.copyTo(_l);
8009
8023
  case 1:
@@ -8020,12 +8034,12 @@
8020
8034
  height: _i3.height
8021
8035
  },
8022
8036
  displayWidth: _c,
8023
- displayHeight: _y,
8037
+ displayHeight: _u,
8024
8038
  colorSpace: {
8025
- primaries: _u2.primaries,
8026
- transfer: _u2.transfer,
8027
- matrix: _u2.matrix,
8028
- fullRange: _u2.fullRange
8039
+ primaries: _y2.primaries,
8040
+ transfer: _y2.transfer,
8041
+ matrix: _y2.matrix,
8042
+ fullRange: _y2.fullRange
8029
8043
  },
8030
8044
  data: _l
8031
8045
  });
@@ -8055,8 +8069,8 @@
8055
8069
  s = _ref30.displayWidth,
8056
8070
  i = _ref30.displayHeight,
8057
8071
  c = _ref30.colorSpace,
8058
- y = _ref30.data;
8059
- return new VideoFrame(new Uint8Array(y), {
8072
+ u = _ref30.data;
8073
+ return new VideoFrame(new Uint8Array(u), {
8060
8074
  format: e,
8061
8075
  codedWidth: t,
8062
8076
  codedHeight: r,
@@ -8128,11 +8142,11 @@
8128
8142
  }],
8129
8143
  ne = [D, M, L, F],
8130
8144
  ce = [Z, Y, re, K, ne, O, z, U, _, B, I, h, N, C].concat("function" == typeof Map ? k : [], "function" == typeof Set ? H : [], "function" == typeof ArrayBuffer ? p : [], "function" == typeof Uint8Array ? X : [], "function" == typeof DataView ? w : [], "undefined" != typeof crypto ? v : [], "undefined" != typeof BigInt ? [m, d] : [], "undefined" != typeof DOMException ? A : [], "undefined" != typeof QuotaExceededError ? W : [], "undefined" != typeof WebTransportError ? te : [], "undefined" != typeof DOMRect ? x : [], "undefined" != typeof DOMPoint ? S : [], "undefined" != typeof DOMQuad ? P : [], "undefined" != typeof DOMMatrix ? T : [], "undefined" != typeof AudioData ? f : [], "undefined" != typeof EncodedAudioChunk ? E : [], "undefined" != typeof EncodedVideoChunk ? j : [], "undefined" != typeof VideoFrame ? ee : []);
8131
- var ye = ce.concat({
8145
+ var ue = ce.concat({
8132
8146
  checkDataCloneException: {
8133
8147
  test: function test(e) {
8134
8148
  var t = {}.toString.call(e).slice(8, -1);
8135
- if (["symbol", "function"].includes(_typeof(e)) || ["Arguments", "Module", "Promise", "WeakMap", "WeakSet", "Event", "MessageChannel"].includes(t) || ["ArrayBuffer", "DataView", "Int8Array", "Uint8Array", "Uint8ClampedArray", "Int16Array", "Uint16Array", "Int32Array", "Uint32Array", "Float32Array", "Float64Array", "BigInt64Array", "BigUint64Array"].includes(t) && function isBufferDetached(e) {
8149
+ if (["symbol", "function"].includes(_typeof(e)) || ["Arguments", "Module", "Promise", "WeakMap", "WeakSet", "Event", "MessageChannel", "MessagePort"].includes(t) || e && e.constructor && ["MessageChannel", "MessagePort"].includes(e.constructor.name) || ["ArrayBuffer", "DataView", "Int8Array", "Uint8Array", "Uint8ClampedArray", "Int16Array", "Uint16Array", "Int32Array", "Uint32Array", "Float32Array", "Float64Array", "BigInt64Array", "BigUint64Array"].includes(t) && function isBufferDetached(e) {
8136
8150
  if ("boolean" == typeof e.detached) return e.detached;
8137
8151
  if (0 !== e.byteLength) return false;
8138
8152
  try {
@@ -8148,7 +8162,7 @@
8148
8162
 
8149
8163
  // See: https://stackoverflow.com/questions/42170826/categories-for-rejection-by-the-structured-cloning-algorithm
8150
8164
 
8151
- var typeson = new Typeson().register(ye);
8165
+ var typeson = new Typeson().register(ue);
8152
8166
 
8153
8167
  /**
8154
8168
  * @param {(preset: import('typeson-registry').Preset) =>
@@ -8157,7 +8171,7 @@
8157
8171
  */
8158
8172
  function register(func) {
8159
8173
  // eslint-disable-next-line unicorn/no-top-level-assignment-in-function -- Should be one-time cache
8160
- typeson = new Typeson().register(func(ye));
8174
+ typeson = new Typeson().register(func(ue));
8161
8175
  }
8162
8176
 
8163
8177
  /**
@@ -9220,6 +9234,11 @@
9220
9234
  * success: (key: import('./Key.js').Key, cn?: Integer) => void,
9221
9235
  * failCb: import('./Key.js').SQLFailureCallback
9222
9236
  * ) => void,
9237
+ * __checkIndexConstraints: (
9238
+ * tx: WebSQLTransaction,
9239
+ * value: import('./Key.js').Value,
9240
+ * excludeKey: import('./Key.js').Key|Integer|undefined
9241
+ * ) => SyncPromise,
9223
9242
  * __insertData: (
9224
9243
  * tx: WebSQLTransaction,
9225
9244
  * encoded: string,
@@ -9638,6 +9657,69 @@
9638
9657
  }
9639
9658
  };
9640
9659
 
9660
+ /**
9661
+ * Validates `value`'s unique index entries against the table's *current*
9662
+ * state without mutating anything -- used by `__storingRecordObjectStore`
9663
+ * to check a `put()`'s constraints *before* `__overwrite` deletes the
9664
+ * existing row for that key, so a rejected `put()` can't end up losing
9665
+ * the record it was trying to replace (see
9666
+ * `idbobjectstore-put-unique-index-constraint-is-atomic.any.js`).
9667
+ * `excludeKey`, when given, treats a conflicting record as a non-conflict
9668
+ * if it's the very record being overwritten (its own current entry would
9669
+ * otherwise self-conflict on every no-op `put()` of an unchanged value).
9670
+ * `__insertData` below still runs its own (now redundant, but harmless --
9671
+ * the old row is gone by then) equivalent check as its first step; this
9672
+ * isn't merged into it because `__insertData` also performs the actual
9673
+ * `INSERT`, which cannot safely run before `__overwrite`'s `DELETE` when
9674
+ * overwriting an existing key.
9675
+ * @param {WebSQLTransaction} tx
9676
+ * @param {import('./Key.js').Value} value
9677
+ * @param {import('./Key.js').Key|Integer|undefined} excludeKey
9678
+ * @this {IDBObjectStoreFull}
9679
+ * @returns {SyncPromise}
9680
+ */
9681
+ IDBObjectStore.prototype.__checkIndexConstraints = function (tx, value, excludeKey) {
9682
+ var me = this;
9683
+ var indexPromises = Object.keys(me.__indexes).map(function (indexName) {
9684
+ return new SyncPromise(function (resolve, reject) {
9685
+ var index = me.__indexes[indexName];
9686
+ if (index.__pendingCreate || index.__deleted || !index.unique) {
9687
+ resolve(undefined);
9688
+ return;
9689
+ }
9690
+ /**
9691
+ * @type {import('./Key.js').KeyValueObject|
9692
+ * import('./Key.js').KeyPathEvaluateValue}
9693
+ */
9694
+ var indexKey;
9695
+ try {
9696
+ indexKey = extractKeyValueDecodedFromValueUsingKeyPath(value, index.keyPath, index.multiEntry);
9697
+ if ('invalid' in indexKey && indexKey.invalid || 'failure' in indexKey && indexKey.failure) {
9698
+ throw new Error('Go to catch');
9699
+ }
9700
+ } catch (err) {
9701
+ resolve(undefined);
9702
+ return;
9703
+ }
9704
+ indexKey = indexKey.value;
9705
+ if (indexKey === undefined) {
9706
+ resolve(undefined);
9707
+ return;
9708
+ }
9709
+ var multiCheck = index.multiEntry && Array.isArray(indexKey);
9710
+ var fetchArgs = buildFetchIndexDataSQL(true, index, indexKey, 'key', multiCheck);
9711
+ executeFetchIndexData.apply(void 0, [null].concat(_toConsumableArray(fetchArgs), [tx, null, function success(key) {
9712
+ if (key === undefined || excludeKey !== undefined && cmp(key, excludeKey) === 0) {
9713
+ resolve(undefined);
9714
+ return;
9715
+ }
9716
+ reject(createDOMException('ConstraintError', 'Index already contains a record equal to ' + (multiCheck ? 'one of the subkeys of' : '') + '`indexKey`'));
9717
+ }, reject]));
9718
+ });
9719
+ });
9720
+ return SyncPromise.all(indexPromises);
9721
+ };
9722
+
9641
9723
  /**
9642
9724
  *
9643
9725
  * @param {WebSQLTransaction} tx
@@ -9899,7 +9981,32 @@
9899
9981
  }, error);
9900
9982
  }
9901
9983
  if (!noOverwrite) {
9902
- store.__overwrite(tx, clonedKeyOrCurrentNumber, insert, error);
9984
+ // Validate unique index constraints *before* `__overwrite`
9985
+ // deletes the existing row at this key -- otherwise a
9986
+ // `put()` that ends up rejected still permanently loses
9987
+ // the record it was trying to replace (see
9988
+ // `idbobjectstore-put-unique-index-constraint-is-atomic.any.js`).
9989
+ store.__checkIndexConstraints(tx, value, clonedKeyOrCurrentNumber).then(function () {
9990
+ store.__overwrite(tx, clonedKeyOrCurrentNumber, insert, error);
9991
+ return undefined;
9992
+ /**
9993
+ * @param {Error|DOMException} err
9994
+ * @returns {null}
9995
+ */
9996
+ }).catch(function (err) {
9997
+ /**
9998
+ * @returns {void}
9999
+ */
10000
+ function fail() {
10001
+ error(err);
10002
+ }
10003
+ if (typeof oldCn === 'number') {
10004
+ assignCurrentNumber(tx, store, oldCn, fail, fail);
10005
+ return null;
10006
+ }
10007
+ fail();
10008
+ return null;
10009
+ });
9903
10010
  return;
9904
10011
  }
9905
10012
  insert(tx);
@@ -10991,7 +11098,29 @@
10991
11098
  return new SyncPromise(function (resolve) {
10992
11099
  setTimeout(function () {
10993
11100
  entry.dispatchEvent(e); // No need to catch errors
10994
- resolve(undefined);
11101
+ // Unlike a native `Promise`, `SyncPromise#then` chains
11102
+ // synchronously off `resolve()` (verified directly:
11103
+ // `SyncPromise.resolve().then(cb)` runs `cb` before
11104
+ // even the calling code below it finishes) -- so
11105
+ // resolving immediately here would let the
11106
+ // `connectionsClosed()` check below run before a
11107
+ // same-task-but-microtask-later continuation of a
11108
+ // `versionchange` listener above (e.g. an `await`-
11109
+ // based one that then calls `db.close()`, as in
11110
+ // `transaction-lifetime.any.js`) ever gets a turn,
11111
+ // incorrectly firing `blocked` even though the
11112
+ // connection was about to close in time. Give real
11113
+ // microtask-deferred continuations a small, bounded
11114
+ // number of turns first -- same pattern as
11115
+ // `IDBTransaction.js`'s `checkQueueEntry`.
11116
+ var attemptsLeft = 10;
11117
+ (function wait() {
11118
+ if (attemptsLeft-- <= 0) {
11119
+ resolve(undefined);
11120
+ return;
11121
+ }
11122
+ queueMicrotask(wait);
11123
+ })();
10995
11124
  }, 0);
10996
11125
  });
10997
11126
  });
@@ -11051,6 +11180,23 @@
11051
11180
  */
11052
11181
  var websqlDBCache = {};
11053
11182
 
11183
+ /**
11184
+ * Tracks databases with a creation/upgrade currently in flight but not yet
11185
+ * committed or aborted -- keyed by (unescaped) database name. The
11186
+ * `dbVersions` row in `sysdb` these entries shadow is written *before*
11187
+ * `upgradeneeded` is even dispatched to user code (as the success
11188
+ * callback of that very `INSERT`/`UPDATE`), on the same shared `sysdb`
11189
+ * connection `databases()` itself reads from -- so, absent this, a
11190
+ * `databases()` call made while an upgrade is still pending would see
11191
+ * the new row (or new version) immediately, rather than only once the
11192
+ * corresponding `versionchange` transaction has genuinely committed, as
11193
+ * required by `get-databases.any.js`'s "doesn't pick up changes that
11194
+ * haven't committed" test. `IDBFactory.prototype.databases` filters
11195
+ * its SQL results against this map.
11196
+ * @type {Map<string, {oldVersion: Integer, newVersion: Integer}>}
11197
+ */
11198
+ var pendingVersionChanges = new Map();
11199
+
11054
11200
  /** @type {import('websql-configurable/lib/websql/WebSQLDatabase.js').default} */
11055
11201
  var sysdb;
11056
11202
  var nameCounter = 0;
@@ -11353,6 +11499,19 @@
11353
11499
  if (calledDbCreateError) {
11354
11500
  return false;
11355
11501
  }
11502
+ // Defensive cleanup: `pendingVersionChanges.set(name, ...)` (see
11503
+ // below) runs *before* the `dbVersions` `INSERT`/`UPDATE` it
11504
+ // guards is even attempted, but only `versionSet`'s own
11505
+ // `on__beforecomplete`/`on__preabort` handlers ever clear it --
11506
+ // and `versionSet` never runs at all if that `INSERT`/`UPDATE`,
11507
+ // or an earlier step in this same `open()` flow, fails first.
11508
+ // Without this, such a failure would leave the entry orphaned
11509
+ // forever, silently corrupting `databases()` for any *other*,
11510
+ // unrelated later `open()` call that happens to reuse the same
11511
+ // database name (common in WPT tests, e.g. generic names like
11512
+ // "DB1"/"TestDatabase" reused across different test files in
11513
+ // the same process). A no-op if no entry was ever set.
11514
+ pendingVersionChanges.delete(name);
11356
11515
  var er = err ? webSQLErrback(err) : (/** @type {Error} */tx);
11357
11516
  calledDbCreateError = true;
11358
11517
  // Re: why bubbling here (and how cancelable is only really relevant for `window.onerror`) see: https://github.com/w3c/IndexedDB/issues/86
@@ -11464,22 +11623,43 @@
11464
11623
  // open/close the transaction's active-handler window itself.
11465
11624
  req.transaction.__handlerActive = true;
11466
11625
  req.dispatchEvent(e);
11467
- // Give any same-tick microtask scheduled from within the
11626
+ // Give any microtask-scheduled continuation of the
11468
11627
  // `upgradeneeded` handler (e.g. a plain
11469
- // `Promise.resolve().then(...)`) a chance to run -- and still
11470
- // observe the transaction as active -- before we deactivate it
11471
- // again, per https://github.com/w3c/IndexedDB/issues/87. Only
11472
- // the flag reset itself is deferred here -- unlike
11473
- // `IDBTransaction.js`'s `advanceAfterDispatch`, `finished()`
11474
- // (this transaction's own queue-advancement/completion signal)
11475
- // still runs synchronously, at exactly its previous timing: an
11476
- // earlier attempt at deferring `finished()` too raced against
11477
- // unrelated test setup that assumed a freshly deleted/created
11478
- // database's upgrade transaction had already fully completed by
11479
- // the time this function returns.
11480
- queueMicrotask(function () {
11481
- req.transaction.__handlerActive = false;
11482
- });
11628
+ // `Promise.resolve().then(...)`, or an `await`-based
11629
+ // continuation of a promise resolved from within the handler,
11630
+ // such as testharness.js's own `EventWatcher`) a chance to
11631
+ // run -- and still observe the transaction as active -- before
11632
+ // we deactivate it again, per
11633
+ // https://github.com/w3c/IndexedDB/issues/87. A single deferred
11634
+ // tick isn't always enough: an `await`-based continuation can
11635
+ // take more than one microtask turn to resume (e.g.
11636
+ // `transaction-lifetime.any.js`'s `EventWatcher`-based
11637
+ // `await eventWatcher.wait_for('upgradeneeded')`), so retry a
11638
+ // small, bounded number of times first -- same pattern as
11639
+ // `IDBTransaction.js`'s `checkQueueEntry` -- rather than
11640
+ // resetting after only one. Only the flag reset itself is
11641
+ // deferred here -- unlike `IDBTransaction.js`'s
11642
+ // `advanceAfterDispatch`, `finished()` (this transaction's own
11643
+ // queue-advancement/completion signal) still runs
11644
+ // synchronously, at exactly its previous timing: an earlier
11645
+ // attempt at deferring `finished()` too raced against unrelated
11646
+ // test setup that assumed a freshly deleted/created database's
11647
+ // upgrade transaction had already fully completed by the time
11648
+ // this function returns.
11649
+ /**
11650
+ * @param {Integer} attemptsLeft
11651
+ * @returns {void}
11652
+ */
11653
+ function deferHandlerActiveReset(attemptsLeft) {
11654
+ if (attemptsLeft <= 0) {
11655
+ req.transaction.__handlerActive = false;
11656
+ return;
11657
+ }
11658
+ queueMicrotask(function () {
11659
+ deferHandlerActiveReset(attemptsLeft - 1);
11660
+ });
11661
+ }
11662
+ deferHandlerActiveReset(10);
11483
11663
  if (e.__legacyOutputDidListenersThrowError) {
11484
11664
  logError('Error', 'An error occurred in an upgradeneeded handler attached to request chain', /** @type {Error} */e.__legacyOutputDidListenersThrowError); // We do nothing else with this error as per spec
11485
11665
  req.transaction.__abortTransaction(createDOMException('AbortError', 'A request was aborted.'));
@@ -11495,6 +11675,7 @@
11495
11675
  * @returns {void}
11496
11676
  */
11497
11677
  function (ev) {
11678
+ pendingVersionChanges.delete(name);
11498
11679
  connection.__upgradeTransaction = null;
11499
11680
  /** @type {import('./IDBDatabase.js').IDBDatabaseFull} */
11500
11681
  req.__result.__versionTransaction = null;
@@ -11509,6 +11690,7 @@
11509
11690
 
11510
11691
  // eslint-disable-next-line camelcase -- Clear API
11511
11692
  req.transaction.on__preabort = function () {
11693
+ pendingVersionChanges.delete(name);
11512
11694
  connection.__upgradeTransaction = null;
11513
11695
  // We ensure any cache is deleted before any request error events fire and try to reopen
11514
11696
  if (useDatabaseCache) {
@@ -11571,6 +11753,10 @@
11571
11753
  // });
11572
11754
  };
11573
11755
  }
11756
+ pendingVersionChanges.set(name, {
11757
+ oldVersion: oldVersion,
11758
+ newVersion: version
11759
+ });
11574
11760
  if (oldVersion === 0) {
11575
11761
  systx.executeSql('INSERT INTO dbVersions VALUES (?,?)', [sqlSafeName, version], versionSet, dbCreateError);
11576
11762
  } else {
@@ -11873,6 +12059,15 @@
11873
12059
  IDBFactory.prototype.databases = function () {
11874
12060
  var me = this;
11875
12061
  var calledDbCreateError = false;
12062
+ // Snapshotted *now*, synchronously, at call time -- not read later
12063
+ // from inside the SQL query's callback below, which runs on a
12064
+ // deferred macrotask (see `nodeSQLiteDatabase.js`'s `exec`) and so
12065
+ // could otherwise race against (and lose to) an in-flight upgrade's
12066
+ // own commit/abort handler clearing its `pendingVersionChanges`
12067
+ // entry in the meantime -- which would make this method incorrectly
12068
+ // reflect a since-committed change that hadn't committed yet when
12069
+ // it was actually called.
12070
+ var pendingVersionChangesSnapshot = new Map(pendingVersionChanges);
11876
12071
  return new Promise(function (resolve, reject) {
11877
12072
  // eslint-disable-line promise/avoid-new -- Own polyfill
11878
12073
  if (!(me instanceof IDBFactory)) {
@@ -11902,10 +12097,29 @@
11902
12097
  var dbNames = [];
11903
12098
  for (var i = 0; i < data.rows.length; i++) {
11904
12099
  var _data$rows$item2 = /** @type {{name: string, version: Integer}} */data.rows.item(i),
11905
- name = _data$rows$item2.name,
12100
+ encodedName = _data$rows$item2.name,
11906
12101
  version = _data$rows$item2.version;
12102
+ var name = unescapeSQLiteResponse(encodedName);
12103
+ // A row for a database whose creation/upgrade hasn't
12104
+ // committed yet (see `pendingVersionChanges`) must
12105
+ // not reflect that in-flight change: a brand new
12106
+ // database (`oldVersion === 0`) isn't reported at
12107
+ // all until its creation commits, and an existing
12108
+ // database being upgraded is still reported, but
12109
+ // with its pre-upgrade version.
12110
+ var pending = pendingVersionChangesSnapshot.get(name);
12111
+ if (pending) {
12112
+ if (pending.oldVersion === 0) {
12113
+ continue;
12114
+ }
12115
+ dbNames.push({
12116
+ name: name,
12117
+ version: pending.oldVersion
12118
+ });
12119
+ continue;
12120
+ }
11907
12121
  dbNames.push({
11908
- name: unescapeSQLiteResponse(name),
12122
+ name: name,
11909
12123
  version: version
11910
12124
  });
11911
12125
  }
@@ -12050,6 +12264,14 @@
12050
12264
  // We must resort to this to get "get <name>" as the function `name` for
12051
12265
  // proper IDL.
12052
12266
  var o = _defineAccessor("get", {}, prop, function () {
12267
+ // This is defined on the *shared* prototype (see above), so,
12268
+ // unlike a per-instance getter, it's reachable by calling it
12269
+ // directly on `IDBRecord.prototype` itself (not a real
12270
+ // instance) -- WebIDL requires that to throw.
12271
+ if (!(this instanceof IDBRecordAlias)) {
12272
+ throw new TypeError('Illegal invocation');
12273
+ }
12274
+ // @ts-ignore `this` is a real instance past the check above (not an issue in TS7)
12053
12275
  return this['__' + prop];
12054
12276
  });
12055
12277
  var desc = /** @type {PropertyDescriptor} */
@@ -12317,9 +12539,26 @@
12317
12539
  // Key.convertValueToKey(key); // Already checked by `continue` or `continuePrimaryKey`
12318
12540
  sqlValues.push(/** @type {string} */_encode(key));
12319
12541
  } else if (continueCall && me.__key !== undefined) {
12320
- sql.push('AND', quotedKeyColumnName, op + ' ?');
12321
12542
  // Key.convertValueToKey(me.__key); // Already checked when stored
12322
- sqlValues.push(/** @type {string} */_encode(me.__key));
12543
+ if (!me.__unique && me.__keyColumnName !== 'key' && me.__primaryKey !== undefined) {
12544
+ // A plain `continue()` on a non-unique index cursor must find
12545
+ // the next record strictly after the (key, primaryKey) pair
12546
+ // this cursor last returned -- a scalar `key > lastKey` alone
12547
+ // would wrongly exclude a *different*, not-yet-visited record
12548
+ // that's still tied on key with the last one (e.g. another
12549
+ // record that always had that same indexed value), and would
12550
+ // also wrongly re-admit the *same* record forever if a
12551
+ // same-transaction `update()` bumped its own key back above
12552
+ // the threshold, since a scalar comparison can't distinguish
12553
+ // "some other record newly tied" from "this record moved
12554
+ // past its own last position." Comparing the full tuple (via
12555
+ // this OR) against both key and primary key resolves both.
12556
+ sql.push('AND (', quotedKeyColumnName, op, '?', 'OR (', quotedKeyColumnName, '= ?', 'AND', quotedKey, op, '?))');
12557
+ sqlValues.push(/** @type {string} */_encode(me.__key), /** @type {string} */_encode(me.__key), /** @type {string} */_encode(me.__primaryKey));
12558
+ } else {
12559
+ sql.push('AND', quotedKeyColumnName, op + ' ?');
12560
+ sqlValues.push(/** @type {string} */_encode(me.__key));
12561
+ }
12323
12562
  }
12324
12563
  if (!me.__count) {
12325
12564
  // 1. Sort by key
@@ -12949,9 +13188,15 @@
12949
13188
  * @returns {void}
12950
13189
  */
12951
13190
  function addToQueue(clonedValue) {
12952
- // We set the `invalidateCache` argument to `false` since the old value shouldn't be accessed
13191
+ // `invalidateCache: true` so any cursor on this store (including
13192
+ // this one) drops its prefetched row batch, forcing its next
13193
+ // `continue()` to re-query live rather than serve rows snapshotted
13194
+ // before this update -- needed for the compound-tuple
13195
+ // continuation logic in `__findBasic` to see this update's
13196
+ // effect on ordering (see "Modify records during cursor
13197
+ // iteration" in idbcursor_update_index.any.js).
12953
13198
  // @ts-ignore -- API (not erring in TS 6)
12954
- IDBObjectStore.__storingRecordObjectStore(request, me.__store, false, clonedValue, false, key);
13199
+ IDBObjectStore.__storingRecordObjectStore(request, me.__store, true, clonedValue, false, key);
12955
13200
  }
12956
13201
  if (me.__store.keyPath !== null) {
12957
13202
  var _me$__store$__validat = me.__store.__validateKeyAndValueAndCloneValue(valueToUpdate, undefined, true),