indexeddbshim 17.3.3 → 17.3.4

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.
@@ -1,4 +1,4 @@
1
- /*! indexeddbshim - v17.3.3 - 8/25/2026 */
1
+ /*! indexeddbshim - v17.3.4 - 8/25/2026 */
2
2
 
3
3
  (function (global, factory) {
4
4
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
@@ -3549,6 +3549,32 @@
3549
3549
  }
3550
3550
 
3551
3551
  var _templateObject, _templateObject2;
3552
+ /**
3553
+ * @param {unknown[]} arr
3554
+ * @param {number} index
3555
+ * @param {unknown} val
3556
+ * @returns {void}
3557
+ */
3558
+ var setArrayValue = function setArrayValue(arr, index, val) {
3559
+ if (Reflect.has(Array.prototype, index)) {
3560
+ Object.defineProperty(arr, index, {
3561
+ value: val,
3562
+ enumerable: true,
3563
+ writable: true,
3564
+ configurable: true
3565
+ });
3566
+ } else {
3567
+ arr[index] = val;
3568
+ }
3569
+ };
3570
+ /**
3571
+ * @param {unknown[]} arr
3572
+ * @param {unknown} val
3573
+ * @returns {void}
3574
+ */
3575
+ var safePush = function safePush(arr, val) {
3576
+ return setArrayValue(arr, arr.length, val);
3577
+ };
3552
3578
 
3553
3579
  /**
3554
3580
  * @typedef {NodeJS.TypedArray|DataView} ArrayBufferView
@@ -3812,6 +3838,7 @@
3812
3838
  * @returns {string}
3813
3839
  */
3814
3840
  encode: function encode(key) {
3841
+ /** @type {(string|null)[]} */
3815
3842
  var encoded = [];
3816
3843
  var _iterator = _createForOfIteratorHelper(key.entries()),
3817
3844
  _step;
@@ -3821,14 +3848,14 @@
3821
3848
  i = _step$value[0],
3822
3849
  item = _step$value[1];
3823
3850
  var encodedItem = _encode(item, true); // encode the array item
3824
- encoded[i] = encodedItem;
3851
+ setArrayValue(encoded, i, encodedItem);
3825
3852
  }
3826
3853
  } catch (err) {
3827
3854
  _iterator.e(err);
3828
3855
  } finally {
3829
3856
  _iterator.f();
3830
3857
  }
3831
- encoded.push(keyTypeToEncodedChar.invalid + '-'); // append an extra item, so empty arrays sort correctly
3858
+ safePush(encoded, keyTypeToEncodedChar.invalid + '-'); // append an extra item, so empty arrays sort correctly
3832
3859
  var encodedKey = JSON.stringify(encoded);
3833
3860
  if (CFG.escapeNULForSQLiteStatements === false) {
3834
3861
  encodedKey = encodedKey.replaceAll(String.raw(_templateObject || (_templateObject = _taggedTemplateLiteral(["\0"], ["\\u0000"]))), '\0');
@@ -3849,7 +3876,7 @@
3849
3876
  for (var i = 0; i < decoded.length; i++) {
3850
3877
  var item = decoded[i];
3851
3878
  var decodedItem = _decode(item, true); // decode the item
3852
- decoded[i] = decodedItem;
3879
+ setArrayValue(decoded, i, decodedItem);
3853
3880
  }
3854
3881
  return decoded;
3855
3882
  }
@@ -4147,7 +4174,7 @@
4147
4174
  // May throw (from binary)
4148
4175
  var arr = /** @type {Array<any>} */input;
4149
4176
  var len = arr.length;
4150
- seen.push(input);
4177
+ safePush(seen, input);
4151
4178
 
4152
4179
  /** @type {(KeyValueObject|Value)[]} */
4153
4180
  var keys = [];
@@ -4182,7 +4209,7 @@
4182
4209
  }) || fullKeys && keys.every(function (k) {
4183
4210
  return cmp(k, key) !== 0;
4184
4211
  })) {
4185
- keys.push(fullKeys ? key : key.value);
4212
+ safePush(keys, fullKeys ? key : key.value);
4186
4213
  }
4187
4214
  } catch (err) {
4188
4215
  if (!multiEntry) {
@@ -4342,7 +4369,7 @@
4342
4369
  if (key.failure) {
4343
4370
  return true;
4344
4371
  }
4345
- result.push(key.value);
4372
+ safePush(result, key.value);
4346
4373
  return false;
4347
4374
  }) ? {
4348
4375
  failure: true
@@ -4403,11 +4430,21 @@
4403
4430
  identifiers.forEach(function (identifier) {
4404
4431
  var hop = Object.hasOwn(value, identifier);
4405
4432
  if (!hop) {
4406
- value[identifier] = {};
4433
+ Object.defineProperty(value, identifier, {
4434
+ value: {},
4435
+ enumerable: true,
4436
+ writable: true,
4437
+ configurable: true
4438
+ });
4407
4439
  }
4408
4440
  value = value[identifier];
4409
4441
  });
4410
- value[(/** @type {string} */last)] = key; // key is already a `keyValue` in our processing so no need to convert
4442
+ Object.defineProperty(value, /** @type {string} */last, {
4443
+ value: key,
4444
+ enumerable: true,
4445
+ writable: true,
4446
+ configurable: true
4447
+ }); // key is already a `keyValue` in our processing so no need to convert
4411
4448
  }
4412
4449
 
4413
4450
  /**
@@ -4485,6 +4522,7 @@
4485
4522
  * @returns {Key[]}
4486
4523
  */
4487
4524
  function findMultiEntryMatches(keyEntry, range) {
4525
+ /** @type {unknown[]} */
4488
4526
  var matches = [];
4489
4527
  if (Array.isArray(keyEntry)) {
4490
4528
  var _iterator4 = _createForOfIteratorHelper(keyEntry),
@@ -4501,13 +4539,13 @@
4501
4539
  } else {
4502
4540
  var nested = findMultiEntryMatches(key, range);
4503
4541
  if (nested.length > 0) {
4504
- matches.push(key);
4542
+ safePush(matches, key);
4505
4543
  }
4506
4544
  continue;
4507
4545
  }
4508
4546
  }
4509
4547
  if (isNullish(range) || isKeyInRange(key, range, true)) {
4510
- matches.push(key);
4548
+ safePush(matches, key);
4511
4549
  }
4512
4550
  }
4513
4551
  } catch (err) {
@@ -4516,7 +4554,7 @@
4516
4554
  _iterator4.f();
4517
4555
  }
4518
4556
  } else if (isNullish(range) || isKeyInRange(keyEntry, range, true)) {
4519
- matches.push(keyEntry);
4557
+ safePush(matches, keyEntry);
4520
4558
  }
4521
4559
  return matches;
4522
4560
  }
@@ -4538,12 +4576,13 @@
4538
4576
  }
4539
4577
  case 'array':
4540
4578
  {
4579
+ /** @type {ValueType[]} */
4541
4580
  var array = [];
4542
4581
  var len = value.length;
4543
4582
  var index = 0;
4544
4583
  while (index < len) {
4545
4584
  var entry = convertKeyToValue(value[index]);
4546
- array[index] = entry;
4585
+ setArrayValue(array, index, entry);
4547
4586
  index++;
4548
4587
  }
4549
4588
  return array;
@@ -5303,6 +5342,7 @@
5303
5342
  }
5304
5343
 
5305
5344
  var uniqueID = 0;
5345
+ var activeTransactions = new Set();
5306
5346
  var listeners$1 = ['onabort', 'oncomplete', 'onerror'];
5307
5347
  var readonlyProperties$4 = ['objectStoreNames', 'mode', 'durability', 'db', 'error'];
5308
5348
 
@@ -5434,6 +5474,7 @@
5434
5474
  me.__mode = mode;
5435
5475
  me.__durability = durability;
5436
5476
  me.__db = db;
5477
+ activeTransactions.add(me);
5437
5478
  me.__error = null;
5438
5479
  // @ts-expect-error Part of `ShimEventTarget`
5439
5480
  me.__setOptions({
@@ -5946,6 +5987,7 @@
5946
5987
  me.__errored = true;
5947
5988
  throw e;
5948
5989
  } finally {
5990
+ activeTransactions.delete(me);
5949
5991
  me.__storeHandles = {};
5950
5992
  }
5951
5993
  }
@@ -6152,7 +6194,7 @@
6152
6194
  });
6153
6195
  }
6154
6196
  me.__active = false; // Setting here and in requestsFinished for https://github.com/w3c/IndexedDB/issues/87
6155
-
6197
+ activeTransactions.delete(me);
6156
6198
  if (err !== null) {
6157
6199
  me.__error = err;
6158
6200
  }
@@ -6373,7 +6415,7 @@
6373
6415
  * @returns {void}
6374
6416
  */
6375
6417
  IDBTransaction.__assertActive = function (tx) {
6376
- if (!tx || !tx.__active || tx.__committed) {
6418
+ if (!tx || !tx.__active || !tx.__handlerActive || tx.__committed) {
6377
6419
  throw createDOMException('TransactionInactiveError', 'A request was placed against a transaction which is currently not active, or which is finished');
6378
6420
  }
6379
6421
  };
@@ -6400,6 +6442,9 @@
6400
6442
  Object.defineProperty(IDBTransaction, 'prototype', {
6401
6443
  writable: false
6402
6444
  });
6445
+ /* eslint-enable unicorn/no-top-level-side-effects -- Would be good */
6446
+
6447
+ IDBTransaction.activeTransactions = activeTransactions;
6403
6448
 
6404
6449
  var TypesonPromise = /*#__PURE__*/_createClass(function TypesonPromise(e) {
6405
6450
  _classCallCheck(this, TypesonPromise);
@@ -7786,7 +7831,7 @@
7786
7831
  }
7787
7832
  }
7788
7833
  },
7789
- k = {
7834
+ D = {
7790
7835
  map: {
7791
7836
  test: function test(e) {
7792
7837
  return "Map" === toStringTag(e);
@@ -7799,7 +7844,7 @@
7799
7844
  }
7800
7845
  }
7801
7846
  },
7802
- D = {
7847
+ R = {
7803
7848
  nan: {
7804
7849
  test: function test(e) {
7805
7850
  return Number.isNaN(e);
@@ -8148,8 +8193,8 @@
8148
8193
  revive: function revive() {}
8149
8194
  }
8150
8195
  }],
8151
- ne = [D, M, L, F],
8152
- 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 : []);
8196
+ ne = [R, M, L, F],
8197
+ ce = [Z, Y, re, K, ne, O, z, U, _, B, I, h, N, C].concat("function" == typeof Map ? D : [], "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 : []);
8153
8198
  var ue = ce.concat({
8154
8199
  checkDataCloneException: {
8155
8200
  test: function test(e) {
@@ -8166,11 +8211,56 @@
8166
8211
  return false;
8167
8212
  }
8168
8213
  }
8214
+ }),
8215
+ ye = ue.concat({
8216
+ checkSharedArrayBufferException: {
8217
+ test: function test(e) {
8218
+ if ("SharedArrayBuffer" === {}.toString.call(e).slice(8, -1)) throw new DOMException("The object cannot be cloned.", "DataCloneError");
8219
+ return false;
8220
+ }
8221
+ }
8169
8222
  });
8170
8223
 
8171
8224
  // See: https://stackoverflow.com/questions/42170826/categories-for-rejection-by-the-structured-cloning-algorithm
8172
8225
 
8173
- var typeson = new Typeson().register(ue);
8226
+ // Although typeson-registry already has a FileList type in its structured cloning presets,
8227
+ // we need to override it so it works with our tests
8228
+
8229
+ var specSet = ye.flatMap(function (preset) {
8230
+ return Array.isArray(preset) ? preset : [preset];
8231
+ }).find(function (preset) {
8232
+ return preset && !Array.isArray(preset) && 'filelist' in preset;
8233
+ });
8234
+ var origFileList = specSet && !Array.isArray(specSet) && 'filelist' in specSet ? specSet.filelist : undefined;
8235
+ var origTest = origFileList && _typeof(origFileList) === 'object' && 'test' in origFileList && typeof origFileList.test === 'function' ? origFileList.test : undefined;
8236
+ var origRevive = origFileList && _typeof(origFileList) === 'object' && 'revive' in origFileList && typeof origFileList.revive === 'function' ? origFileList.revive : undefined;
8237
+ var customFileList = origFileList ? _objectSpread2(_objectSpread2({}, origFileList), {}, {
8238
+ /**
8239
+ * @param {unknown} x
8240
+ * @param {import('typeson').StateObject} state
8241
+ * @returns {boolean}
8242
+ */
8243
+ test: function test(x, state) {
8244
+ if (typeof FileList !== 'undefined') {
8245
+ return x instanceof FileList;
8246
+ }
8247
+ return typeof origTest === 'function' ? origTest(x, state) : false;
8248
+ },
8249
+ /**
8250
+ * @param {unknown} x
8251
+ * @param {import('typeson').StateObject} state
8252
+ * @returns {unknown}
8253
+ */
8254
+ revive: function revive(x, state) {
8255
+ if (typeof FileList !== 'undefined') {
8256
+ return Reflect.construct(FileList, [x]);
8257
+ }
8258
+ return typeof origRevive === 'function' ? origRevive(x, state) : undefined;
8259
+ }
8260
+ }) : undefined;
8261
+ var typeson = new Typeson().register([ye, customFileList ? {
8262
+ filelist: customFileList
8263
+ } : {}]);
8174
8264
 
8175
8265
  /**
8176
8266
  * @param {(preset: import('typeson-registry').Preset) =>
@@ -8179,7 +8269,7 @@
8179
8269
  */
8180
8270
  function register(func) {
8181
8271
  // eslint-disable-next-line unicorn/no-top-level-assignment-in-function -- Should be one-time cache
8182
- typeson = new Typeson().register(func(ue));
8272
+ typeson = new Typeson().register(func(ye));
8183
8273
  }
8184
8274
 
8185
8275
  /**
@@ -11478,6 +11568,7 @@
11478
11568
  }
11479
11569
  var req = IDBOpenDBRequest.__createInstance();
11480
11570
  var calledDbCreateError = false;
11571
+ var isRevertingSysdb = false;
11481
11572
  if (CFG.autoName && name === '') {
11482
11573
  // eslint-disable-next-line unicorn/no-top-level-assignment-in-function -- Necessary?
11483
11574
  name = 'autoNamedDatabase_' + nameCounter++;
@@ -11504,7 +11595,7 @@
11504
11595
  * @returns {boolean}
11505
11596
  */
11506
11597
  function dbCreateError(tx, err) {
11507
- if (calledDbCreateError) {
11598
+ if (calledDbCreateError || isRevertingSysdb) {
11508
11599
  return false;
11509
11600
  }
11510
11601
  // Defensive cleanup: `pendingVersionChanges.set(name, ...)` (see
@@ -11568,36 +11659,46 @@
11568
11659
  */
11569
11660
  var sysdbFinishedCb = function sysdbFinishedCb(systx, err, cb) {
11570
11661
  if (err) {
11571
- try {
11572
- systx.executeSql('ROLLBACK', [], cb, cb);
11573
- } catch (err) {
11574
- // Browser may fail with expired transaction above so
11575
- // no choice but to manually revert
11662
+ /**
11663
+ * @param {any} [errorToShow]
11664
+ * @returns {void}
11665
+ */
11666
+ var manualRevert = function manualRevert(errorToShow) {
11667
+ /**
11668
+ * @param {string} [msg]
11669
+ * @throws {Error}
11670
+ * @returns {never}
11671
+ */
11672
+ function reportError(msg) {
11673
+ throw new Error('Unable to roll back upgrade transaction!' + (msg || ''));
11674
+ }
11576
11675
  sysdb.transaction(function (systx) {
11577
- /**
11578
- *
11579
- * @param {string} msg
11580
- * @throws {Error}
11581
- * @returns {never}
11582
- */
11583
- function reportError(msg) {
11584
- throw new Error('Unable to roll back upgrade transaction!' + (msg || ''));
11585
- }
11586
-
11587
11676
  // Attempt to revert
11588
11677
  if (oldVersion === 0) {
11589
- systx.executeSql('DELETE FROM dbVersions WHERE "name" = ?', [sqlSafeName], function () {
11590
- // @ts-expect-error Force to work
11591
- cb(reportError); // eslint-disable-line promise/no-callback-in-promise -- Convenient
11592
- },
11593
- // @ts-expect-error Force to work
11594
- reportError);
11678
+ systx.executeSql('DELETE FROM dbVersions WHERE "name" = ?', [sqlSafeName]);
11595
11679
  } else {
11596
- systx.executeSql('UPDATE dbVersions SET "version" = ? WHERE "name" = ?', [oldVersion, sqlSafeName], cb,
11597
- // @ts-expect-error Force to work
11598
- reportError);
11680
+ systx.executeSql('UPDATE dbVersions SET "version" = ? WHERE "name" = ?', [oldVersion, sqlSafeName]);
11599
11681
  }
11682
+ }, function (sqlErr) {
11683
+ isRevertingSysdb = false;
11684
+ cb(sqlErr); // eslint-disable-line promise/no-callback-in-promise -- Convenient
11685
+ }, function () {
11686
+ isRevertingSysdb = false;
11687
+ cb(errorToShow || reportError); // eslint-disable-line promise/no-callback-in-promise -- Convenient
11688
+ });
11689
+ };
11690
+ try {
11691
+ systx.executeSql('ROLLBACK', [], function () {
11692
+ cb(); // eslint-disable-line promise/no-callback-in-promise -- Convenient
11693
+ }, function (tx, sqlErr) {
11694
+ // Browser/Node may fail with expired transaction, so manually revert
11695
+ manualRevert(sqlErr);
11696
+ return false;
11600
11697
  });
11698
+ } catch (e) {
11699
+ // Browser may fail with expired transaction above so
11700
+ // no choice but to manually revert
11701
+ manualRevert(e);
11601
11702
  }
11602
11703
  return;
11603
11704
  }
@@ -11698,6 +11799,7 @@
11698
11799
 
11699
11800
  // eslint-disable-next-line camelcase -- Clear API
11700
11801
  req.transaction.on__preabort = function () {
11802
+ isRevertingSysdb = true;
11701
11803
  pendingVersionChanges.delete(name);
11702
11804
  connection.__upgradeTransaction = null;
11703
11805
  // We ensure any cache is deleted before any request error events fire and try to reopen
@@ -11715,6 +11817,7 @@
11715
11817
  req.__result = undefined;
11716
11818
  req.__done = false;
11717
11819
  connection.close();
11820
+ isRevertingSysdb = true;
11718
11821
  setTimeout(function () {
11719
11822
  var err = createDOMException('AbortError', 'The upgrade transaction was aborted.');
11720
11823
  sysdbFinishedCb(systx, err, function (reportError) {
@@ -11776,7 +11879,26 @@
11776
11879
  }
11777
11880
  sysdbFinishedCb = function sysdbFinishedCb(systx, err, cb) {
11778
11881
  if (err) {
11779
- rollback(err, cb);
11882
+ rollback(err,
11883
+ /**
11884
+ * @param {Error} [reportError]
11885
+ * @returns {void}
11886
+ */
11887
+ function (reportError) {
11888
+ sysdb.transaction(function (systx) {
11889
+ if (oldVersion === 0) {
11890
+ systx.executeSql('DELETE FROM dbVersions WHERE "name" = ?', [sqlSafeName]);
11891
+ } else {
11892
+ systx.executeSql('UPDATE dbVersions SET "version" = ? WHERE "name" = ?', [oldVersion, sqlSafeName]);
11893
+ }
11894
+ }, function (sqlErr) {
11895
+ isRevertingSysdb = false;
11896
+ cb(sqlErr); // eslint-disable-line promise/no-callback-in-promise -- Convenient
11897
+ }, function () {
11898
+ isRevertingSysdb = false;
11899
+ cb(reportError); // eslint-disable-line promise/no-callback-in-promise -- Convenient
11900
+ });
11901
+ });
11780
11902
  } else {
11781
11903
  commit(cb);
11782
11904
  }