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) :
@@ -6161,9 +6161,15 @@
6161
6161
  if (err !== null) {
6162
6162
  me.__error = err;
6163
6163
  }
6164
- if (me.__requestsFinished) {
6164
+ if (me.__requestsFinished && err !== null) {
6165
6165
  // The transaction has already completed, so we can't call "onerror" or "onabort".
6166
- // So throw the error instead.
6166
+ // So throw the error instead. `err` is only ever `null` here via
6167
+ // `IDBTransaction.prototype.abort`'s own `__abortTransaction(null)`
6168
+ // call, which now checks `__requestsFinished` itself first and
6169
+ // throws `InvalidStateError` synchronously before ever reaching
6170
+ // this point -- so this guard is just defense in depth against
6171
+ // `err` somehow being `null` some other way, not something this
6172
+ // path should see in practice.
6167
6173
  setTimeout(function () {
6168
6174
  throw err;
6169
6175
  }, 0);
@@ -6283,6 +6289,14 @@
6283
6289
  if (me.__committed) {
6284
6290
  throw createDOMException('InvalidStateError', 'The transaction has already been committed');
6285
6291
  }
6292
+ if (me.__requestsFinished) {
6293
+ // All requests have already finished and the transaction is
6294
+ // auto-committing (the async SQL commit round trip just hasn't
6295
+ // resolved yet) -- too late to abort per spec, even though
6296
+ // `__committed` itself isn't set until that round trip actually
6297
+ // finishes.
6298
+ throw createDOMException('InvalidStateError', 'The transaction is already committing');
6299
+ }
6286
6300
  me.__abortTransaction(null);
6287
6301
  };
6288
6302
 
@@ -6607,22 +6621,22 @@
6607
6621
  sync: true
6608
6622
  }, this.options), s),
6609
6623
  c = i.sync,
6610
- y = {},
6611
- u = [],
6624
+ u = {},
6625
+ y = [],
6612
6626
  l = [],
6613
6627
  p = [],
6614
6628
  f = !("cyclic" in i) || i.cyclic,
6615
6629
  d = i.encapsulateObserver,
6616
6630
  m = i.encapsulateError,
6617
6631
  finish = function finish(e) {
6618
- var t = Object.values(y);
6632
+ var t = Object.values(u);
6619
6633
  if (i.iterateNone) return t.length ? t[0] : getJSONType(e);
6620
6634
  if (t.length) {
6621
6635
  if (i.returnTypeNames) return _toConsumableArray(new Set(t));
6622
- e && isPlainObject(e) && !n(e, "$types") ? e.$types = y : e = {
6636
+ e && isPlainObject(e) && !n(e, "$types") ? e.$types = u : e = {
6623
6637
  $: e,
6624
6638
  $types: {
6625
- $: y
6639
+ $: u
6626
6640
  }
6627
6641
  };
6628
6642
  } else isObject(e) && n(e, "$types") && (e = {
@@ -6646,18 +6660,18 @@
6646
6660
  _context2.n = 2;
6647
6661
  return Promise.all(r.map(/*#__PURE__*/function () {
6648
6662
  var _ref = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(r) {
6649
- var n, _t$splice, _t$splice2, a, _a, o, s, i, c, y, u, l, p, _t, _t2, _t3, _t4;
6663
+ var n, _t$splice, _t$splice2, a, _a, o, s, i, c, u, y, l, p, _t, _t2, _t3, _t4;
6650
6664
  return _regenerator().w(function (_context) {
6651
6665
  while (1) switch (_context.n) {
6652
6666
  case 0:
6653
- 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);
6667
+ 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);
6654
6668
  if (!(o && p)) {
6655
6669
  _context.n = 2;
6656
6670
  break;
6657
6671
  }
6658
6672
  _t2 = setOwnEnumerable;
6659
6673
  _t3 = c;
6660
- _t4 = y;
6674
+ _t4 = u;
6661
6675
  _context.n = 1;
6662
6676
  return l.p;
6663
6677
  case 1:
@@ -6666,7 +6680,7 @@
6666
6680
  _context.n = 3;
6667
6681
  break;
6668
6682
  case 2:
6669
- _t = (o ? setOwnEnumerable(c, y, l) : e = p ? l.p : l, _checkPromises(e, n));
6683
+ _t = (o ? setOwnEnumerable(c, u, l) : e = p ? l.p : l, _checkPromises(e, n));
6670
6684
  case 3:
6671
6685
  return _context.a(2, _t);
6672
6686
  }
@@ -6745,11 +6759,11 @@
6745
6759
  })) : h = t, b && b(), h;
6746
6760
  if (null === t) return b && b(), t;
6747
6761
  if (o && t && "object" == _typeof(t) && !s.iterateIn && !s.iterateUnsetNumeric) {
6748
- var _r2 = u.indexOf(t);
6749
- if (-1 !== _r2) return y[e] = "#", b && b({
6762
+ var _r2 = y.indexOf(t);
6763
+ if (-1 !== _r2) return u[e] = "#", b && b({
6750
6764
  cyclicKeypath: l[_r2]
6751
6765
  }), "#" + l[_r2];
6752
- true === o && (u.push(t), l.push(e));
6766
+ true === o && (y.push(t), l.push(e));
6753
6767
  }
6754
6768
  var v = isPlainObject(t),
6755
6769
  w = a(t),
@@ -6819,14 +6833,14 @@
6819
6833
  },
6820
6834
  replace = function replace(e, t, r, n, a, o, s) {
6821
6835
  var i = a ? _this2.plainObjectReplacers : _this2.nonplainObjectReplacers;
6822
- var u = i.length;
6823
- for (; u--;) {
6824
- var _a3 = i[u];
6836
+ var y = i.length;
6837
+ for (; y--;) {
6838
+ var _a3 = i[y];
6825
6839
  if (_a3.test(t, r)) {
6826
6840
  var _i2 = _a3.type;
6827
6841
  if (Object.hasOwn(_this2.revivers, _i2)) {
6828
- var _t5 = y[e];
6829
- y[e] = _t5 ? [_i2].concat(_t5) : _i2;
6842
+ var _t5 = u[e];
6843
+ u[e] = _t5 ? [_i2].concat(_t5) : _i2;
6830
6844
  }
6831
6845
  if (Object.assign(r, {
6832
6846
  type: _i2,
@@ -6834,14 +6848,14 @@
6834
6848
  }), (c || !_a3.replaceAsync) && !_a3.replace) return s && s({
6835
6849
  typeDetected: true
6836
6850
  }), _encapsulate2(e, t, f && "readonly", r, n, o, _i2);
6837
- var _u = void 0;
6851
+ var _y = void 0;
6838
6852
  if (s && s({
6839
6853
  replacing: true
6840
6854
  }), c || !_a3.replaceAsync) {
6841
6855
  if (void 0 === _a3.replace) throw new TypeError("Missing replacer");
6842
- _u = _a3.replace(t, r);
6843
- } else _u = _a3.replaceAsync(t, r);
6844
- return _encapsulate2(e, _u, f && "readonly", r, n, o, _i2);
6856
+ _y = _a3.replace(t, r);
6857
+ } else _y = _a3.replaceAsync(t, r);
6858
+ return _encapsulate2(e, _y, f && "readonly", r, n, o, _i2);
6845
6859
  }
6846
6860
  }
6847
6861
  return t;
@@ -6889,8 +6903,8 @@
6889
6903
  if (true === i) return finishRevival(e.$);
6890
6904
  if (!i || "object" != _typeof(i) || Array.isArray(i)) return finishRevival(e);
6891
6905
  var c = [],
6892
- y = Object.create(null),
6893
- u = {};
6906
+ u = Object.create(null),
6907
+ y = {};
6894
6908
  var l = true;
6895
6909
  i.$ && isPlainObject(i.$) && (e = e.$, i = i.$, l = false);
6896
6910
  var executeReviver = function executeReviver(e, t) {
@@ -6900,8 +6914,8 @@
6900
6914
  r = _ref5[0];
6901
6915
  if (!r) throw new Error("Unregistered type: " + e);
6902
6916
  if (s && !("revive" in r)) return t;
6903
- if (!s && r.reviveAsync) return r.reviveAsync(t, u);
6904
- if (r.revive) return r.revive(t, u);
6917
+ if (!s && r.reviveAsync) return r.reviveAsync(t, y);
6918
+ if (r.revive) return r.revive(t, y);
6905
6919
  throw new Error("Missing reviver");
6906
6920
  },
6907
6921
  p = [];
@@ -6946,7 +6960,7 @@
6946
6960
  var d;
6947
6961
  return hasConstructorOf(f, TypesonPromise) ? d = f.then(function () {
6948
6962
  return e;
6949
- }) : (d = function _revive(e, t, o, u, f) {
6963
+ }) : (d = function _revive(e, t, o, y, f) {
6950
6964
  if (l && "$types" === e) return;
6951
6965
  var d = p.length,
6952
6966
  m = n(i, e) ? i[e] : void 0,
@@ -6967,18 +6981,18 @@
6967
6981
  _t6 = _c$[1],
6968
6982
  _r5 = _c$[2],
6969
6983
  _a5 = _c$[3],
6970
- _o2 = n(y, _t6),
6971
- _s = _o2 ? y[_t6] : getByKeyPath(_e2, _t6);
6984
+ _o2 = n(u, _t6),
6985
+ _s = _o2 ? u[_t6] : getByKeyPath(_e2, _t6);
6972
6986
  if (!_o2 && void 0 === _s) break;
6973
6987
  setOwnEnumerable(_r5, _a5, _s), c.shift();
6974
6988
  }
6975
6989
  }
6976
- if (!m) return y[e] = t, t;
6990
+ if (!m) return u[e] = t, t;
6977
6991
  if ("#" === m) {
6978
6992
  var _e3 = t.slice(1),
6979
- _r6 = n(y, _e3),
6980
- _a6 = _r6 ? y[_e3] : getByKeyPath(o, _e3);
6981
- return _r6 || void 0 !== _a6 || c.push([o, _e3, u, f]), _a6;
6993
+ _r6 = n(u, _e3),
6994
+ _a6 = _r6 ? u[_e3] : getByKeyPath(o, _e3);
6995
+ return _r6 || void 0 !== _a6 || c.push([o, _e3, y, f]), _a6;
6982
6996
  }
6983
6997
  var applyType = function applyType(t) {
6984
6998
  var r = [].concat(m).reduce(function reducer(e, t) {
@@ -6989,8 +7003,8 @@
6989
7003
  return executeReviver(t, e);
6990
7004
  }, t);
6991
7005
  return hasConstructorOf(r, TypesonPromise) ? r.then(function (t) {
6992
- return y[e] = t, t;
6993
- }) : (y[e] = r, r);
7006
+ return u[e] = t, t;
7007
+ }) : (u[e] = r, r);
6994
7008
  };
6995
7009
  return !s && p.length > d ? TypesonPromise.all(p.slice(d)).then(function () {
6996
7010
  return applyType(t);
@@ -7095,8 +7109,8 @@
7095
7109
  });
7096
7110
  Undefined.__typeson__type__ = "TypesonUndefined";
7097
7111
  var s = ["null", "boolean", "number", "string", "array", "object"];
7098
- for (var i = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", c = new Uint8Array(256), y = 0; y < 64; y++) c[i.codePointAt(y)] = y;
7099
- var u = function encode(e, t, r) {
7112
+ for (var i = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", c = new Uint8Array(256), u = 0; u < 64; u++) c[i.codePointAt(u)] = u;
7113
+ var y = function encode(e, t, r) {
7100
7114
  null == r && (r = e.byteLength);
7101
7115
  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]];
7102
7116
  return a % 3 == 2 ? o = o.slice(0, -1) + "=" : a % 3 == 1 && (o = o.slice(0, -2) + "=="), o;
@@ -7109,10 +7123,10 @@
7109
7123
  o,
7110
7124
  s,
7111
7125
  i = .75 * e.length,
7112
- y = 0;
7126
+ u = 0;
7113
7127
  "=" === e[e.length - 1] && (i--, "=" === e[e.length - 2] && i--);
7114
- 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;
7115
- return u;
7128
+ 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;
7129
+ return y;
7116
7130
  };
7117
7131
  var p = {
7118
7132
  arraybuffer: {
@@ -7125,7 +7139,7 @@
7125
7139
  return -1 !== r ? {
7126
7140
  index: r
7127
7141
  } : (t.buffers.push(e), {
7128
- s: u(e),
7142
+ s: y(e),
7129
7143
  maxByteLength: e.maxByteLength,
7130
7144
  resizable: e.resizable
7131
7145
  });
@@ -7159,13 +7173,13 @@
7159
7173
  });
7160
7174
  i.push(_r0), c += _r0;
7161
7175
  }
7162
- var y = new ArrayBuffer(c);
7163
- var u = 0;
7176
+ var u = new ArrayBuffer(c);
7177
+ var y = 0;
7164
7178
  for (var _t9 = 0; _t9 < s; _t9++) {
7165
- var _r1 = new Uint8Array(y, u, i[_t9]);
7179
+ var _r1 = new Uint8Array(u, y, i[_t9]);
7166
7180
  e.copyTo(_r1, {
7167
7181
  planeIndex: _t9
7168
- }), u += i[_t9];
7182
+ }), y += i[_t9];
7169
7183
  }
7170
7184
  return {
7171
7185
  format: t,
@@ -7173,7 +7187,7 @@
7173
7187
  numberOfFrames: n,
7174
7188
  numberOfChannels: a,
7175
7189
  timestamp: o,
7176
- data: y
7190
+ data: u
7177
7191
  };
7178
7192
  },
7179
7193
  revive: function revive(_ref11) {
@@ -7324,7 +7338,7 @@
7324
7338
  byteOffset: t,
7325
7339
  byteLength: r
7326
7340
  } : (n.buffers.push(e), {
7327
- encoded: u(e),
7341
+ encoded: y(e),
7328
7342
  maxByteLength: e.maxByteLength,
7329
7343
  resizable: e.resizable,
7330
7344
  byteOffset: t,
@@ -7956,7 +7970,7 @@
7956
7970
  } : (n.buffers.push(e), {
7957
7971
  maxByteLength: e.maxByteLength,
7958
7972
  resizable: e.resizable,
7959
- encoded: u(e),
7973
+ encoded: y(e),
7960
7974
  byteOffset: t,
7961
7975
  length: r
7962
7976
  });
@@ -7969,10 +7983,10 @@
7969
7983
  s = t.index,
7970
7984
  i = t.maxByteLength,
7971
7985
  c = t.resizable;
7972
- var y;
7973
- return "index" in t ? y = r.buffers[s] : (y = l(o, c ? {
7986
+ var u;
7987
+ return "index" in t ? u = r.buffers[s] : (u = l(o, c ? {
7974
7988
  maxByteLength: i
7975
- } : void 0), r.buffers.push(y)), new e(y, n, a);
7989
+ } : void 0), r.buffers.push(u)), new e(u, n, a);
7976
7990
  }
7977
7991
  };
7978
7992
  }(e);
@@ -8011,12 +8025,12 @@
8011
8025
  replaceAsync: function replaceAsync(e) {
8012
8026
  return new TypesonPromise(/*#__PURE__*/function () {
8013
8027
  var _ref29 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6(t, r) {
8014
- var _r12, _n3, _a7, _o3, _s2, _i3, _c, _y, _u2, _l, _t14;
8028
+ var _r12, _n3, _a7, _o3, _s2, _i3, _c, _u, _y2, _l, _t14;
8015
8029
  return _regenerator().w(function (_context6) {
8016
8030
  while (1) switch (_context6.p = _context6.n) {
8017
8031
  case 0:
8018
8032
  _context6.p = 0;
8019
- _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());
8033
+ _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());
8020
8034
  _context6.n = 1;
8021
8035
  return e.copyTo(_l);
8022
8036
  case 1:
@@ -8033,12 +8047,12 @@
8033
8047
  height: _i3.height
8034
8048
  },
8035
8049
  displayWidth: _c,
8036
- displayHeight: _y,
8050
+ displayHeight: _u,
8037
8051
  colorSpace: {
8038
- primaries: _u2.primaries,
8039
- transfer: _u2.transfer,
8040
- matrix: _u2.matrix,
8041
- fullRange: _u2.fullRange
8052
+ primaries: _y2.primaries,
8053
+ transfer: _y2.transfer,
8054
+ matrix: _y2.matrix,
8055
+ fullRange: _y2.fullRange
8042
8056
  },
8043
8057
  data: _l
8044
8058
  });
@@ -8068,8 +8082,8 @@
8068
8082
  s = _ref30.displayWidth,
8069
8083
  i = _ref30.displayHeight,
8070
8084
  c = _ref30.colorSpace,
8071
- y = _ref30.data;
8072
- return new VideoFrame(new Uint8Array(y), {
8085
+ u = _ref30.data;
8086
+ return new VideoFrame(new Uint8Array(u), {
8073
8087
  format: e,
8074
8088
  codedWidth: t,
8075
8089
  codedHeight: r,
@@ -8141,11 +8155,11 @@
8141
8155
  }],
8142
8156
  ne = [D, M, L, F],
8143
8157
  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 : []);
8144
- var ye = ce.concat({
8158
+ var ue = ce.concat({
8145
8159
  checkDataCloneException: {
8146
8160
  test: function test(e) {
8147
8161
  var t = {}.toString.call(e).slice(8, -1);
8148
- 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) {
8162
+ 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) {
8149
8163
  if ("boolean" == typeof e.detached) return e.detached;
8150
8164
  if (0 !== e.byteLength) return false;
8151
8165
  try {
@@ -8161,7 +8175,7 @@
8161
8175
 
8162
8176
  // See: https://stackoverflow.com/questions/42170826/categories-for-rejection-by-the-structured-cloning-algorithm
8163
8177
 
8164
- var typeson = new Typeson().register(ye);
8178
+ var typeson = new Typeson().register(ue);
8165
8179
 
8166
8180
  /**
8167
8181
  * @param {(preset: import('typeson-registry').Preset) =>
@@ -8170,7 +8184,7 @@
8170
8184
  */
8171
8185
  function register(func) {
8172
8186
  // eslint-disable-next-line unicorn/no-top-level-assignment-in-function -- Should be one-time cache
8173
- typeson = new Typeson().register(func(ye));
8187
+ typeson = new Typeson().register(func(ue));
8174
8188
  }
8175
8189
 
8176
8190
  /**
@@ -9233,6 +9247,11 @@
9233
9247
  * success: (key: import('./Key.js').Key, cn?: Integer) => void,
9234
9248
  * failCb: import('./Key.js').SQLFailureCallback
9235
9249
  * ) => void,
9250
+ * __checkIndexConstraints: (
9251
+ * tx: WebSQLTransaction,
9252
+ * value: import('./Key.js').Value,
9253
+ * excludeKey: import('./Key.js').Key|Integer|undefined
9254
+ * ) => SyncPromise,
9236
9255
  * __insertData: (
9237
9256
  * tx: WebSQLTransaction,
9238
9257
  * encoded: string,
@@ -9651,6 +9670,69 @@
9651
9670
  }
9652
9671
  };
9653
9672
 
9673
+ /**
9674
+ * Validates `value`'s unique index entries against the table's *current*
9675
+ * state without mutating anything -- used by `__storingRecordObjectStore`
9676
+ * to check a `put()`'s constraints *before* `__overwrite` deletes the
9677
+ * existing row for that key, so a rejected `put()` can't end up losing
9678
+ * the record it was trying to replace (see
9679
+ * `idbobjectstore-put-unique-index-constraint-is-atomic.any.js`).
9680
+ * `excludeKey`, when given, treats a conflicting record as a non-conflict
9681
+ * if it's the very record being overwritten (its own current entry would
9682
+ * otherwise self-conflict on every no-op `put()` of an unchanged value).
9683
+ * `__insertData` below still runs its own (now redundant, but harmless --
9684
+ * the old row is gone by then) equivalent check as its first step; this
9685
+ * isn't merged into it because `__insertData` also performs the actual
9686
+ * `INSERT`, which cannot safely run before `__overwrite`'s `DELETE` when
9687
+ * overwriting an existing key.
9688
+ * @param {WebSQLTransaction} tx
9689
+ * @param {import('./Key.js').Value} value
9690
+ * @param {import('./Key.js').Key|Integer|undefined} excludeKey
9691
+ * @this {IDBObjectStoreFull}
9692
+ * @returns {SyncPromise}
9693
+ */
9694
+ IDBObjectStore.prototype.__checkIndexConstraints = function (tx, value, excludeKey) {
9695
+ var me = this;
9696
+ var indexPromises = Object.keys(me.__indexes).map(function (indexName) {
9697
+ return new SyncPromise(function (resolve, reject) {
9698
+ var index = me.__indexes[indexName];
9699
+ if (index.__pendingCreate || index.__deleted || !index.unique) {
9700
+ resolve(undefined);
9701
+ return;
9702
+ }
9703
+ /**
9704
+ * @type {import('./Key.js').KeyValueObject|
9705
+ * import('./Key.js').KeyPathEvaluateValue}
9706
+ */
9707
+ var indexKey;
9708
+ try {
9709
+ indexKey = extractKeyValueDecodedFromValueUsingKeyPath(value, index.keyPath, index.multiEntry);
9710
+ if ('invalid' in indexKey && indexKey.invalid || 'failure' in indexKey && indexKey.failure) {
9711
+ throw new Error('Go to catch');
9712
+ }
9713
+ } catch (err) {
9714
+ resolve(undefined);
9715
+ return;
9716
+ }
9717
+ indexKey = indexKey.value;
9718
+ if (indexKey === undefined) {
9719
+ resolve(undefined);
9720
+ return;
9721
+ }
9722
+ var multiCheck = index.multiEntry && Array.isArray(indexKey);
9723
+ var fetchArgs = buildFetchIndexDataSQL(true, index, indexKey, 'key', multiCheck);
9724
+ executeFetchIndexData.apply(void 0, [null].concat(_toConsumableArray(fetchArgs), [tx, null, function success(key) {
9725
+ if (key === undefined || excludeKey !== undefined && cmp(key, excludeKey) === 0) {
9726
+ resolve(undefined);
9727
+ return;
9728
+ }
9729
+ reject(createDOMException('ConstraintError', 'Index already contains a record equal to ' + (multiCheck ? 'one of the subkeys of' : '') + '`indexKey`'));
9730
+ }, reject]));
9731
+ });
9732
+ });
9733
+ return SyncPromise.all(indexPromises);
9734
+ };
9735
+
9654
9736
  /**
9655
9737
  *
9656
9738
  * @param {WebSQLTransaction} tx
@@ -9912,7 +9994,32 @@
9912
9994
  }, error);
9913
9995
  }
9914
9996
  if (!noOverwrite) {
9915
- store.__overwrite(tx, clonedKeyOrCurrentNumber, insert, error);
9997
+ // Validate unique index constraints *before* `__overwrite`
9998
+ // deletes the existing row at this key -- otherwise a
9999
+ // `put()` that ends up rejected still permanently loses
10000
+ // the record it was trying to replace (see
10001
+ // `idbobjectstore-put-unique-index-constraint-is-atomic.any.js`).
10002
+ store.__checkIndexConstraints(tx, value, clonedKeyOrCurrentNumber).then(function () {
10003
+ store.__overwrite(tx, clonedKeyOrCurrentNumber, insert, error);
10004
+ return undefined;
10005
+ /**
10006
+ * @param {Error|DOMException} err
10007
+ * @returns {null}
10008
+ */
10009
+ }).catch(function (err) {
10010
+ /**
10011
+ * @returns {void}
10012
+ */
10013
+ function fail() {
10014
+ error(err);
10015
+ }
10016
+ if (typeof oldCn === 'number') {
10017
+ assignCurrentNumber(tx, store, oldCn, fail, fail);
10018
+ return null;
10019
+ }
10020
+ fail();
10021
+ return null;
10022
+ });
9916
10023
  return;
9917
10024
  }
9918
10025
  insert(tx);
@@ -11004,7 +11111,29 @@
11004
11111
  return new SyncPromise(function (resolve) {
11005
11112
  setTimeout(function () {
11006
11113
  entry.dispatchEvent(e); // No need to catch errors
11007
- resolve(undefined);
11114
+ // Unlike a native `Promise`, `SyncPromise#then` chains
11115
+ // synchronously off `resolve()` (verified directly:
11116
+ // `SyncPromise.resolve().then(cb)` runs `cb` before
11117
+ // even the calling code below it finishes) -- so
11118
+ // resolving immediately here would let the
11119
+ // `connectionsClosed()` check below run before a
11120
+ // same-task-but-microtask-later continuation of a
11121
+ // `versionchange` listener above (e.g. an `await`-
11122
+ // based one that then calls `db.close()`, as in
11123
+ // `transaction-lifetime.any.js`) ever gets a turn,
11124
+ // incorrectly firing `blocked` even though the
11125
+ // connection was about to close in time. Give real
11126
+ // microtask-deferred continuations a small, bounded
11127
+ // number of turns first -- same pattern as
11128
+ // `IDBTransaction.js`'s `checkQueueEntry`.
11129
+ var attemptsLeft = 10;
11130
+ (function wait() {
11131
+ if (attemptsLeft-- <= 0) {
11132
+ resolve(undefined);
11133
+ return;
11134
+ }
11135
+ queueMicrotask(wait);
11136
+ })();
11008
11137
  }, 0);
11009
11138
  });
11010
11139
  });
@@ -11064,6 +11193,23 @@
11064
11193
  */
11065
11194
  var websqlDBCache = {};
11066
11195
 
11196
+ /**
11197
+ * Tracks databases with a creation/upgrade currently in flight but not yet
11198
+ * committed or aborted -- keyed by (unescaped) database name. The
11199
+ * `dbVersions` row in `sysdb` these entries shadow is written *before*
11200
+ * `upgradeneeded` is even dispatched to user code (as the success
11201
+ * callback of that very `INSERT`/`UPDATE`), on the same shared `sysdb`
11202
+ * connection `databases()` itself reads from -- so, absent this, a
11203
+ * `databases()` call made while an upgrade is still pending would see
11204
+ * the new row (or new version) immediately, rather than only once the
11205
+ * corresponding `versionchange` transaction has genuinely committed, as
11206
+ * required by `get-databases.any.js`'s "doesn't pick up changes that
11207
+ * haven't committed" test. `IDBFactory.prototype.databases` filters
11208
+ * its SQL results against this map.
11209
+ * @type {Map<string, {oldVersion: Integer, newVersion: Integer}>}
11210
+ */
11211
+ var pendingVersionChanges = new Map();
11212
+
11067
11213
  /** @type {import('websql-configurable/lib/websql/WebSQLDatabase.js').default} */
11068
11214
  var sysdb;
11069
11215
  var nameCounter = 0;
@@ -11366,6 +11512,19 @@
11366
11512
  if (calledDbCreateError) {
11367
11513
  return false;
11368
11514
  }
11515
+ // Defensive cleanup: `pendingVersionChanges.set(name, ...)` (see
11516
+ // below) runs *before* the `dbVersions` `INSERT`/`UPDATE` it
11517
+ // guards is even attempted, but only `versionSet`'s own
11518
+ // `on__beforecomplete`/`on__preabort` handlers ever clear it --
11519
+ // and `versionSet` never runs at all if that `INSERT`/`UPDATE`,
11520
+ // or an earlier step in this same `open()` flow, fails first.
11521
+ // Without this, such a failure would leave the entry orphaned
11522
+ // forever, silently corrupting `databases()` for any *other*,
11523
+ // unrelated later `open()` call that happens to reuse the same
11524
+ // database name (common in WPT tests, e.g. generic names like
11525
+ // "DB1"/"TestDatabase" reused across different test files in
11526
+ // the same process). A no-op if no entry was ever set.
11527
+ pendingVersionChanges.delete(name);
11369
11528
  var er = err ? webSQLErrback(err) : (/** @type {Error} */tx);
11370
11529
  calledDbCreateError = true;
11371
11530
  // Re: why bubbling here (and how cancelable is only really relevant for `window.onerror`) see: https://github.com/w3c/IndexedDB/issues/86
@@ -11477,22 +11636,43 @@
11477
11636
  // open/close the transaction's active-handler window itself.
11478
11637
  req.transaction.__handlerActive = true;
11479
11638
  req.dispatchEvent(e);
11480
- // Give any same-tick microtask scheduled from within the
11639
+ // Give any microtask-scheduled continuation of the
11481
11640
  // `upgradeneeded` handler (e.g. a plain
11482
- // `Promise.resolve().then(...)`) a chance to run -- and still
11483
- // observe the transaction as active -- before we deactivate it
11484
- // again, per https://github.com/w3c/IndexedDB/issues/87. Only
11485
- // the flag reset itself is deferred here -- unlike
11486
- // `IDBTransaction.js`'s `advanceAfterDispatch`, `finished()`
11487
- // (this transaction's own queue-advancement/completion signal)
11488
- // still runs synchronously, at exactly its previous timing: an
11489
- // earlier attempt at deferring `finished()` too raced against
11490
- // unrelated test setup that assumed a freshly deleted/created
11491
- // database's upgrade transaction had already fully completed by
11492
- // the time this function returns.
11493
- queueMicrotask(function () {
11494
- req.transaction.__handlerActive = false;
11495
- });
11641
+ // `Promise.resolve().then(...)`, or an `await`-based
11642
+ // continuation of a promise resolved from within the handler,
11643
+ // such as testharness.js's own `EventWatcher`) a chance to
11644
+ // run -- and still observe the transaction as active -- before
11645
+ // we deactivate it again, per
11646
+ // https://github.com/w3c/IndexedDB/issues/87. A single deferred
11647
+ // tick isn't always enough: an `await`-based continuation can
11648
+ // take more than one microtask turn to resume (e.g.
11649
+ // `transaction-lifetime.any.js`'s `EventWatcher`-based
11650
+ // `await eventWatcher.wait_for('upgradeneeded')`), so retry a
11651
+ // small, bounded number of times first -- same pattern as
11652
+ // `IDBTransaction.js`'s `checkQueueEntry` -- rather than
11653
+ // resetting after only one. Only the flag reset itself is
11654
+ // deferred here -- unlike `IDBTransaction.js`'s
11655
+ // `advanceAfterDispatch`, `finished()` (this transaction's own
11656
+ // queue-advancement/completion signal) still runs
11657
+ // synchronously, at exactly its previous timing: an earlier
11658
+ // attempt at deferring `finished()` too raced against unrelated
11659
+ // test setup that assumed a freshly deleted/created database's
11660
+ // upgrade transaction had already fully completed by the time
11661
+ // this function returns.
11662
+ /**
11663
+ * @param {Integer} attemptsLeft
11664
+ * @returns {void}
11665
+ */
11666
+ function deferHandlerActiveReset(attemptsLeft) {
11667
+ if (attemptsLeft <= 0) {
11668
+ req.transaction.__handlerActive = false;
11669
+ return;
11670
+ }
11671
+ queueMicrotask(function () {
11672
+ deferHandlerActiveReset(attemptsLeft - 1);
11673
+ });
11674
+ }
11675
+ deferHandlerActiveReset(10);
11496
11676
  if (e.__legacyOutputDidListenersThrowError) {
11497
11677
  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
11498
11678
  req.transaction.__abortTransaction(createDOMException('AbortError', 'A request was aborted.'));
@@ -11508,6 +11688,7 @@
11508
11688
  * @returns {void}
11509
11689
  */
11510
11690
  function (ev) {
11691
+ pendingVersionChanges.delete(name);
11511
11692
  connection.__upgradeTransaction = null;
11512
11693
  /** @type {import('./IDBDatabase.js').IDBDatabaseFull} */
11513
11694
  req.__result.__versionTransaction = null;
@@ -11522,6 +11703,7 @@
11522
11703
 
11523
11704
  // eslint-disable-next-line camelcase -- Clear API
11524
11705
  req.transaction.on__preabort = function () {
11706
+ pendingVersionChanges.delete(name);
11525
11707
  connection.__upgradeTransaction = null;
11526
11708
  // We ensure any cache is deleted before any request error events fire and try to reopen
11527
11709
  if (useDatabaseCache) {
@@ -11584,6 +11766,10 @@
11584
11766
  // });
11585
11767
  };
11586
11768
  }
11769
+ pendingVersionChanges.set(name, {
11770
+ oldVersion: oldVersion,
11771
+ newVersion: version
11772
+ });
11587
11773
  if (oldVersion === 0) {
11588
11774
  systx.executeSql('INSERT INTO dbVersions VALUES (?,?)', [sqlSafeName, version], versionSet, dbCreateError);
11589
11775
  } else {
@@ -11886,6 +12072,15 @@
11886
12072
  IDBFactory.prototype.databases = function () {
11887
12073
  var me = this;
11888
12074
  var calledDbCreateError = false;
12075
+ // Snapshotted *now*, synchronously, at call time -- not read later
12076
+ // from inside the SQL query's callback below, which runs on a
12077
+ // deferred macrotask (see `nodeSQLiteDatabase.js`'s `exec`) and so
12078
+ // could otherwise race against (and lose to) an in-flight upgrade's
12079
+ // own commit/abort handler clearing its `pendingVersionChanges`
12080
+ // entry in the meantime -- which would make this method incorrectly
12081
+ // reflect a since-committed change that hadn't committed yet when
12082
+ // it was actually called.
12083
+ var pendingVersionChangesSnapshot = new Map(pendingVersionChanges);
11889
12084
  return new Promise(function (resolve, reject) {
11890
12085
  // eslint-disable-line promise/avoid-new -- Own polyfill
11891
12086
  if (!(me instanceof IDBFactory)) {
@@ -11915,10 +12110,29 @@
11915
12110
  var dbNames = [];
11916
12111
  for (var i = 0; i < data.rows.length; i++) {
11917
12112
  var _data$rows$item2 = /** @type {{name: string, version: Integer}} */data.rows.item(i),
11918
- name = _data$rows$item2.name,
12113
+ encodedName = _data$rows$item2.name,
11919
12114
  version = _data$rows$item2.version;
12115
+ var name = unescapeSQLiteResponse(encodedName);
12116
+ // A row for a database whose creation/upgrade hasn't
12117
+ // committed yet (see `pendingVersionChanges`) must
12118
+ // not reflect that in-flight change: a brand new
12119
+ // database (`oldVersion === 0`) isn't reported at
12120
+ // all until its creation commits, and an existing
12121
+ // database being upgraded is still reported, but
12122
+ // with its pre-upgrade version.
12123
+ var pending = pendingVersionChangesSnapshot.get(name);
12124
+ if (pending) {
12125
+ if (pending.oldVersion === 0) {
12126
+ continue;
12127
+ }
12128
+ dbNames.push({
12129
+ name: name,
12130
+ version: pending.oldVersion
12131
+ });
12132
+ continue;
12133
+ }
11920
12134
  dbNames.push({
11921
- name: unescapeSQLiteResponse(name),
12135
+ name: name,
11922
12136
  version: version
11923
12137
  });
11924
12138
  }
@@ -12063,6 +12277,14 @@
12063
12277
  // We must resort to this to get "get <name>" as the function `name` for
12064
12278
  // proper IDL.
12065
12279
  var o = _defineAccessor("get", {}, prop, function () {
12280
+ // This is defined on the *shared* prototype (see above), so,
12281
+ // unlike a per-instance getter, it's reachable by calling it
12282
+ // directly on `IDBRecord.prototype` itself (not a real
12283
+ // instance) -- WebIDL requires that to throw.
12284
+ if (!(this instanceof IDBRecordAlias)) {
12285
+ throw new TypeError('Illegal invocation');
12286
+ }
12287
+ // @ts-ignore `this` is a real instance past the check above (not an issue in TS7)
12066
12288
  return this['__' + prop];
12067
12289
  });
12068
12290
  var desc = /** @type {PropertyDescriptor} */
@@ -12330,9 +12552,26 @@
12330
12552
  // Key.convertValueToKey(key); // Already checked by `continue` or `continuePrimaryKey`
12331
12553
  sqlValues.push(/** @type {string} */_encode(key));
12332
12554
  } else if (continueCall && me.__key !== undefined) {
12333
- sql.push('AND', quotedKeyColumnName, op + ' ?');
12334
12555
  // Key.convertValueToKey(me.__key); // Already checked when stored
12335
- sqlValues.push(/** @type {string} */_encode(me.__key));
12556
+ if (!me.__unique && me.__keyColumnName !== 'key' && me.__primaryKey !== undefined) {
12557
+ // A plain `continue()` on a non-unique index cursor must find
12558
+ // the next record strictly after the (key, primaryKey) pair
12559
+ // this cursor last returned -- a scalar `key > lastKey` alone
12560
+ // would wrongly exclude a *different*, not-yet-visited record
12561
+ // that's still tied on key with the last one (e.g. another
12562
+ // record that always had that same indexed value), and would
12563
+ // also wrongly re-admit the *same* record forever if a
12564
+ // same-transaction `update()` bumped its own key back above
12565
+ // the threshold, since a scalar comparison can't distinguish
12566
+ // "some other record newly tied" from "this record moved
12567
+ // past its own last position." Comparing the full tuple (via
12568
+ // this OR) against both key and primary key resolves both.
12569
+ sql.push('AND (', quotedKeyColumnName, op, '?', 'OR (', quotedKeyColumnName, '= ?', 'AND', quotedKey, op, '?))');
12570
+ sqlValues.push(/** @type {string} */_encode(me.__key), /** @type {string} */_encode(me.__key), /** @type {string} */_encode(me.__primaryKey));
12571
+ } else {
12572
+ sql.push('AND', quotedKeyColumnName, op + ' ?');
12573
+ sqlValues.push(/** @type {string} */_encode(me.__key));
12574
+ }
12336
12575
  }
12337
12576
  if (!me.__count) {
12338
12577
  // 1. Sort by key
@@ -12962,9 +13201,15 @@
12962
13201
  * @returns {void}
12963
13202
  */
12964
13203
  function addToQueue(clonedValue) {
12965
- // We set the `invalidateCache` argument to `false` since the old value shouldn't be accessed
13204
+ // `invalidateCache: true` so any cursor on this store (including
13205
+ // this one) drops its prefetched row batch, forcing its next
13206
+ // `continue()` to re-query live rather than serve rows snapshotted
13207
+ // before this update -- needed for the compound-tuple
13208
+ // continuation logic in `__findBasic` to see this update's
13209
+ // effect on ordering (see "Modify records during cursor
13210
+ // iteration" in idbcursor_update_index.any.js).
12966
13211
  // @ts-ignore -- API (not erring in TS 6)
12967
- IDBObjectStore.__storingRecordObjectStore(request, me.__store, false, clonedValue, false, key);
13212
+ IDBObjectStore.__storingRecordObjectStore(request, me.__store, true, clonedValue, false, key);
12968
13213
  }
12969
13214
  if (me.__store.keyPath !== null) {
12970
13215
  var _me$__store$__validat = me.__store.__validateKeyAndValueAndCloneValue(valueToUpdate, undefined, true),