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 (factory) {
4
4
  typeof define === 'function' && define.amd ? define(factory) :
@@ -3541,6 +3541,32 @@
3541
3541
  }
3542
3542
 
3543
3543
  var _templateObject, _templateObject2;
3544
+ /**
3545
+ * @param {unknown[]} arr
3546
+ * @param {number} index
3547
+ * @param {unknown} val
3548
+ * @returns {void}
3549
+ */
3550
+ var setArrayValue = function setArrayValue(arr, index, val) {
3551
+ if (Reflect.has(Array.prototype, index)) {
3552
+ Object.defineProperty(arr, index, {
3553
+ value: val,
3554
+ enumerable: true,
3555
+ writable: true,
3556
+ configurable: true
3557
+ });
3558
+ } else {
3559
+ arr[index] = val;
3560
+ }
3561
+ };
3562
+ /**
3563
+ * @param {unknown[]} arr
3564
+ * @param {unknown} val
3565
+ * @returns {void}
3566
+ */
3567
+ var safePush = function safePush(arr, val) {
3568
+ return setArrayValue(arr, arr.length, val);
3569
+ };
3544
3570
 
3545
3571
  /**
3546
3572
  * @typedef {NodeJS.TypedArray|DataView} ArrayBufferView
@@ -3804,6 +3830,7 @@
3804
3830
  * @returns {string}
3805
3831
  */
3806
3832
  encode: function encode(key) {
3833
+ /** @type {(string|null)[]} */
3807
3834
  var encoded = [];
3808
3835
  var _iterator = _createForOfIteratorHelper(key.entries()),
3809
3836
  _step;
@@ -3813,14 +3840,14 @@
3813
3840
  i = _step$value[0],
3814
3841
  item = _step$value[1];
3815
3842
  var encodedItem = _encode(item, true); // encode the array item
3816
- encoded[i] = encodedItem;
3843
+ setArrayValue(encoded, i, encodedItem);
3817
3844
  }
3818
3845
  } catch (err) {
3819
3846
  _iterator.e(err);
3820
3847
  } finally {
3821
3848
  _iterator.f();
3822
3849
  }
3823
- encoded.push(keyTypeToEncodedChar.invalid + '-'); // append an extra item, so empty arrays sort correctly
3850
+ safePush(encoded, keyTypeToEncodedChar.invalid + '-'); // append an extra item, so empty arrays sort correctly
3824
3851
  var encodedKey = JSON.stringify(encoded);
3825
3852
  if (CFG.escapeNULForSQLiteStatements === false) {
3826
3853
  encodedKey = encodedKey.replaceAll(String.raw(_templateObject || (_templateObject = _taggedTemplateLiteral(["\0"], ["\\u0000"]))), '\0');
@@ -3841,7 +3868,7 @@
3841
3868
  for (var i = 0; i < decoded.length; i++) {
3842
3869
  var item = decoded[i];
3843
3870
  var decodedItem = _decode(item, true); // decode the item
3844
- decoded[i] = decodedItem;
3871
+ setArrayValue(decoded, i, decodedItem);
3845
3872
  }
3846
3873
  return decoded;
3847
3874
  }
@@ -4139,7 +4166,7 @@
4139
4166
  // May throw (from binary)
4140
4167
  var arr = /** @type {Array<any>} */input;
4141
4168
  var len = arr.length;
4142
- seen.push(input);
4169
+ safePush(seen, input);
4143
4170
 
4144
4171
  /** @type {(KeyValueObject|Value)[]} */
4145
4172
  var keys = [];
@@ -4174,7 +4201,7 @@
4174
4201
  }) || fullKeys && keys.every(function (k) {
4175
4202
  return cmp(k, key) !== 0;
4176
4203
  })) {
4177
- keys.push(fullKeys ? key : key.value);
4204
+ safePush(keys, fullKeys ? key : key.value);
4178
4205
  }
4179
4206
  } catch (err) {
4180
4207
  if (!multiEntry) {
@@ -4334,7 +4361,7 @@
4334
4361
  if (key.failure) {
4335
4362
  return true;
4336
4363
  }
4337
- result.push(key.value);
4364
+ safePush(result, key.value);
4338
4365
  return false;
4339
4366
  }) ? {
4340
4367
  failure: true
@@ -4395,11 +4422,21 @@
4395
4422
  identifiers.forEach(function (identifier) {
4396
4423
  var hop = Object.hasOwn(value, identifier);
4397
4424
  if (!hop) {
4398
- value[identifier] = {};
4425
+ Object.defineProperty(value, identifier, {
4426
+ value: {},
4427
+ enumerable: true,
4428
+ writable: true,
4429
+ configurable: true
4430
+ });
4399
4431
  }
4400
4432
  value = value[identifier];
4401
4433
  });
4402
- value[(/** @type {string} */last)] = key; // key is already a `keyValue` in our processing so no need to convert
4434
+ Object.defineProperty(value, /** @type {string} */last, {
4435
+ value: key,
4436
+ enumerable: true,
4437
+ writable: true,
4438
+ configurable: true
4439
+ }); // key is already a `keyValue` in our processing so no need to convert
4403
4440
  }
4404
4441
 
4405
4442
  /**
@@ -4477,6 +4514,7 @@
4477
4514
  * @returns {Key[]}
4478
4515
  */
4479
4516
  function findMultiEntryMatches(keyEntry, range) {
4517
+ /** @type {unknown[]} */
4480
4518
  var matches = [];
4481
4519
  if (Array.isArray(keyEntry)) {
4482
4520
  var _iterator4 = _createForOfIteratorHelper(keyEntry),
@@ -4493,13 +4531,13 @@
4493
4531
  } else {
4494
4532
  var nested = findMultiEntryMatches(key, range);
4495
4533
  if (nested.length > 0) {
4496
- matches.push(key);
4534
+ safePush(matches, key);
4497
4535
  }
4498
4536
  continue;
4499
4537
  }
4500
4538
  }
4501
4539
  if (isNullish(range) || isKeyInRange(key, range, true)) {
4502
- matches.push(key);
4540
+ safePush(matches, key);
4503
4541
  }
4504
4542
  }
4505
4543
  } catch (err) {
@@ -4508,7 +4546,7 @@
4508
4546
  _iterator4.f();
4509
4547
  }
4510
4548
  } else if (isNullish(range) || isKeyInRange(keyEntry, range, true)) {
4511
- matches.push(keyEntry);
4549
+ safePush(matches, keyEntry);
4512
4550
  }
4513
4551
  return matches;
4514
4552
  }
@@ -4530,12 +4568,13 @@
4530
4568
  }
4531
4569
  case 'array':
4532
4570
  {
4571
+ /** @type {ValueType[]} */
4533
4572
  var array = [];
4534
4573
  var len = value.length;
4535
4574
  var index = 0;
4536
4575
  while (index < len) {
4537
4576
  var entry = convertKeyToValue(value[index]);
4538
- array[index] = entry;
4577
+ setArrayValue(array, index, entry);
4539
4578
  index++;
4540
4579
  }
4541
4580
  return array;
@@ -5295,6 +5334,7 @@
5295
5334
  }
5296
5335
 
5297
5336
  var uniqueID = 0;
5337
+ var activeTransactions = new Set();
5298
5338
  var listeners$1 = ['onabort', 'oncomplete', 'onerror'];
5299
5339
  var readonlyProperties$4 = ['objectStoreNames', 'mode', 'durability', 'db', 'error'];
5300
5340
 
@@ -5426,6 +5466,7 @@
5426
5466
  me.__mode = mode;
5427
5467
  me.__durability = durability;
5428
5468
  me.__db = db;
5469
+ activeTransactions.add(me);
5429
5470
  me.__error = null;
5430
5471
  // @ts-expect-error Part of `ShimEventTarget`
5431
5472
  me.__setOptions({
@@ -5938,6 +5979,7 @@
5938
5979
  me.__errored = true;
5939
5980
  throw e;
5940
5981
  } finally {
5982
+ activeTransactions.delete(me);
5941
5983
  me.__storeHandles = {};
5942
5984
  }
5943
5985
  }
@@ -6144,7 +6186,7 @@
6144
6186
  });
6145
6187
  }
6146
6188
  me.__active = false; // Setting here and in requestsFinished for https://github.com/w3c/IndexedDB/issues/87
6147
-
6189
+ activeTransactions.delete(me);
6148
6190
  if (err !== null) {
6149
6191
  me.__error = err;
6150
6192
  }
@@ -6365,7 +6407,7 @@
6365
6407
  * @returns {void}
6366
6408
  */
6367
6409
  IDBTransaction.__assertActive = function (tx) {
6368
- if (!tx || !tx.__active || tx.__committed) {
6410
+ if (!tx || !tx.__active || !tx.__handlerActive || tx.__committed) {
6369
6411
  throw createDOMException('TransactionInactiveError', 'A request was placed against a transaction which is currently not active, or which is finished');
6370
6412
  }
6371
6413
  };
@@ -6392,6 +6434,9 @@
6392
6434
  Object.defineProperty(IDBTransaction, 'prototype', {
6393
6435
  writable: false
6394
6436
  });
6437
+ /* eslint-enable unicorn/no-top-level-side-effects -- Would be good */
6438
+
6439
+ IDBTransaction.activeTransactions = activeTransactions;
6395
6440
 
6396
6441
  var TypesonPromise = /*#__PURE__*/_createClass(function TypesonPromise(e) {
6397
6442
  _classCallCheck(this, TypesonPromise);
@@ -7778,7 +7823,7 @@
7778
7823
  }
7779
7824
  }
7780
7825
  },
7781
- k = {
7826
+ D = {
7782
7827
  map: {
7783
7828
  test: function test(e) {
7784
7829
  return "Map" === toStringTag(e);
@@ -7791,7 +7836,7 @@
7791
7836
  }
7792
7837
  }
7793
7838
  },
7794
- D = {
7839
+ R = {
7795
7840
  nan: {
7796
7841
  test: function test(e) {
7797
7842
  return Number.isNaN(e);
@@ -8140,8 +8185,8 @@
8140
8185
  revive: function revive() {}
8141
8186
  }
8142
8187
  }],
8143
- ne = [D, M, L, F],
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 : []);
8188
+ ne = [R, M, L, F],
8189
+ 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 : []);
8145
8190
  var ue = ce.concat({
8146
8191
  checkDataCloneException: {
8147
8192
  test: function test(e) {
@@ -8158,11 +8203,56 @@
8158
8203
  return false;
8159
8204
  }
8160
8205
  }
8206
+ }),
8207
+ ye = ue.concat({
8208
+ checkSharedArrayBufferException: {
8209
+ test: function test(e) {
8210
+ if ("SharedArrayBuffer" === {}.toString.call(e).slice(8, -1)) throw new DOMException("The object cannot be cloned.", "DataCloneError");
8211
+ return false;
8212
+ }
8213
+ }
8161
8214
  });
8162
8215
 
8163
8216
  // See: https://stackoverflow.com/questions/42170826/categories-for-rejection-by-the-structured-cloning-algorithm
8164
8217
 
8165
- var typeson = new Typeson().register(ue);
8218
+ // Although typeson-registry already has a FileList type in its structured cloning presets,
8219
+ // we need to override it so it works with our tests
8220
+
8221
+ var specSet = ye.flatMap(function (preset) {
8222
+ return Array.isArray(preset) ? preset : [preset];
8223
+ }).find(function (preset) {
8224
+ return preset && !Array.isArray(preset) && 'filelist' in preset;
8225
+ });
8226
+ var origFileList = specSet && !Array.isArray(specSet) && 'filelist' in specSet ? specSet.filelist : undefined;
8227
+ var origTest = origFileList && _typeof(origFileList) === 'object' && 'test' in origFileList && typeof origFileList.test === 'function' ? origFileList.test : undefined;
8228
+ var origRevive = origFileList && _typeof(origFileList) === 'object' && 'revive' in origFileList && typeof origFileList.revive === 'function' ? origFileList.revive : undefined;
8229
+ var customFileList = origFileList ? _objectSpread2(_objectSpread2({}, origFileList), {}, {
8230
+ /**
8231
+ * @param {unknown} x
8232
+ * @param {import('typeson').StateObject} state
8233
+ * @returns {boolean}
8234
+ */
8235
+ test: function test(x, state) {
8236
+ if (typeof FileList !== 'undefined') {
8237
+ return x instanceof FileList;
8238
+ }
8239
+ return typeof origTest === 'function' ? origTest(x, state) : false;
8240
+ },
8241
+ /**
8242
+ * @param {unknown} x
8243
+ * @param {import('typeson').StateObject} state
8244
+ * @returns {unknown}
8245
+ */
8246
+ revive: function revive(x, state) {
8247
+ if (typeof FileList !== 'undefined') {
8248
+ return Reflect.construct(FileList, [x]);
8249
+ }
8250
+ return typeof origRevive === 'function' ? origRevive(x, state) : undefined;
8251
+ }
8252
+ }) : undefined;
8253
+ var typeson = new Typeson().register([ye, customFileList ? {
8254
+ filelist: customFileList
8255
+ } : {}]);
8166
8256
 
8167
8257
  /**
8168
8258
  * @param {(preset: import('typeson-registry').Preset) =>
@@ -8171,7 +8261,7 @@
8171
8261
  */
8172
8262
  function register(func) {
8173
8263
  // eslint-disable-next-line unicorn/no-top-level-assignment-in-function -- Should be one-time cache
8174
- typeson = new Typeson().register(func(ue));
8264
+ typeson = new Typeson().register(func(ye));
8175
8265
  }
8176
8266
 
8177
8267
  /**
@@ -11470,6 +11560,7 @@
11470
11560
  }
11471
11561
  var req = IDBOpenDBRequest.__createInstance();
11472
11562
  var calledDbCreateError = false;
11563
+ var isRevertingSysdb = false;
11473
11564
  if (CFG.autoName && name === '') {
11474
11565
  // eslint-disable-next-line unicorn/no-top-level-assignment-in-function -- Necessary?
11475
11566
  name = 'autoNamedDatabase_' + nameCounter++;
@@ -11496,7 +11587,7 @@
11496
11587
  * @returns {boolean}
11497
11588
  */
11498
11589
  function dbCreateError(tx, err) {
11499
- if (calledDbCreateError) {
11590
+ if (calledDbCreateError || isRevertingSysdb) {
11500
11591
  return false;
11501
11592
  }
11502
11593
  // Defensive cleanup: `pendingVersionChanges.set(name, ...)` (see
@@ -11560,36 +11651,46 @@
11560
11651
  */
11561
11652
  var sysdbFinishedCb = function sysdbFinishedCb(systx, err, cb) {
11562
11653
  if (err) {
11563
- try {
11564
- systx.executeSql('ROLLBACK', [], cb, cb);
11565
- } catch (err) {
11566
- // Browser may fail with expired transaction above so
11567
- // no choice but to manually revert
11654
+ /**
11655
+ * @param {any} [errorToShow]
11656
+ * @returns {void}
11657
+ */
11658
+ var manualRevert = function manualRevert(errorToShow) {
11659
+ /**
11660
+ * @param {string} [msg]
11661
+ * @throws {Error}
11662
+ * @returns {never}
11663
+ */
11664
+ function reportError(msg) {
11665
+ throw new Error('Unable to roll back upgrade transaction!' + (msg || ''));
11666
+ }
11568
11667
  sysdb.transaction(function (systx) {
11569
- /**
11570
- *
11571
- * @param {string} msg
11572
- * @throws {Error}
11573
- * @returns {never}
11574
- */
11575
- function reportError(msg) {
11576
- throw new Error('Unable to roll back upgrade transaction!' + (msg || ''));
11577
- }
11578
-
11579
11668
  // Attempt to revert
11580
11669
  if (oldVersion === 0) {
11581
- systx.executeSql('DELETE FROM dbVersions WHERE "name" = ?', [sqlSafeName], function () {
11582
- // @ts-expect-error Force to work
11583
- cb(reportError); // eslint-disable-line promise/no-callback-in-promise -- Convenient
11584
- },
11585
- // @ts-expect-error Force to work
11586
- reportError);
11670
+ systx.executeSql('DELETE FROM dbVersions WHERE "name" = ?', [sqlSafeName]);
11587
11671
  } else {
11588
- systx.executeSql('UPDATE dbVersions SET "version" = ? WHERE "name" = ?', [oldVersion, sqlSafeName], cb,
11589
- // @ts-expect-error Force to work
11590
- reportError);
11672
+ systx.executeSql('UPDATE dbVersions SET "version" = ? WHERE "name" = ?', [oldVersion, sqlSafeName]);
11591
11673
  }
11674
+ }, function (sqlErr) {
11675
+ isRevertingSysdb = false;
11676
+ cb(sqlErr); // eslint-disable-line promise/no-callback-in-promise -- Convenient
11677
+ }, function () {
11678
+ isRevertingSysdb = false;
11679
+ cb(errorToShow || reportError); // eslint-disable-line promise/no-callback-in-promise -- Convenient
11680
+ });
11681
+ };
11682
+ try {
11683
+ systx.executeSql('ROLLBACK', [], function () {
11684
+ cb(); // eslint-disable-line promise/no-callback-in-promise -- Convenient
11685
+ }, function (tx, sqlErr) {
11686
+ // Browser/Node may fail with expired transaction, so manually revert
11687
+ manualRevert(sqlErr);
11688
+ return false;
11592
11689
  });
11690
+ } catch (e) {
11691
+ // Browser may fail with expired transaction above so
11692
+ // no choice but to manually revert
11693
+ manualRevert(e);
11593
11694
  }
11594
11695
  return;
11595
11696
  }
@@ -11690,6 +11791,7 @@
11690
11791
 
11691
11792
  // eslint-disable-next-line camelcase -- Clear API
11692
11793
  req.transaction.on__preabort = function () {
11794
+ isRevertingSysdb = true;
11693
11795
  pendingVersionChanges.delete(name);
11694
11796
  connection.__upgradeTransaction = null;
11695
11797
  // We ensure any cache is deleted before any request error events fire and try to reopen
@@ -11707,6 +11809,7 @@
11707
11809
  req.__result = undefined;
11708
11810
  req.__done = false;
11709
11811
  connection.close();
11812
+ isRevertingSysdb = true;
11710
11813
  setTimeout(function () {
11711
11814
  var err = createDOMException('AbortError', 'The upgrade transaction was aborted.');
11712
11815
  sysdbFinishedCb(systx, err, function (reportError) {
@@ -11768,7 +11871,26 @@
11768
11871
  }
11769
11872
  sysdbFinishedCb = function sysdbFinishedCb(systx, err, cb) {
11770
11873
  if (err) {
11771
- rollback(err, cb);
11874
+ rollback(err,
11875
+ /**
11876
+ * @param {Error} [reportError]
11877
+ * @returns {void}
11878
+ */
11879
+ function (reportError) {
11880
+ sysdb.transaction(function (systx) {
11881
+ if (oldVersion === 0) {
11882
+ systx.executeSql('DELETE FROM dbVersions WHERE "name" = ?', [sqlSafeName]);
11883
+ } else {
11884
+ systx.executeSql('UPDATE dbVersions SET "version" = ? WHERE "name" = ?', [oldVersion, sqlSafeName]);
11885
+ }
11886
+ }, function (sqlErr) {
11887
+ isRevertingSysdb = false;
11888
+ cb(sqlErr); // eslint-disable-line promise/no-callback-in-promise -- Convenient
11889
+ }, function () {
11890
+ isRevertingSysdb = false;
11891
+ cb(reportError); // eslint-disable-line promise/no-callback-in-promise -- Convenient
11892
+ });
11893
+ });
11772
11894
  } else {
11773
11895
  commit(cb);
11774
11896
  }