dexie 4.3.0 → 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/dexie.mjs CHANGED
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * By David Fahlander, david.fahlander@gmail.com
6
6
  *
7
- * Version 4.3.0, Sat Dec 20 2025
7
+ * Version 4.4.0, Wed Mar 18 2026
8
8
  *
9
9
  * https://dexie.org
10
10
  *
@@ -1138,12 +1138,12 @@ function tempTransaction(db, mode, storeNames, fn) {
1138
1138
  }
1139
1139
  }
1140
1140
 
1141
- var DEXIE_VERSION = '4.3.0';
1141
+ var DEXIE_VERSION = '4.4.0';
1142
1142
  var maxString = String.fromCharCode(65535);
1143
1143
  var minKey = -Infinity;
1144
1144
  var INVALID_KEY_ARGUMENT = "Invalid key provided. Keys must be of type string, number, Date or Array<string | number | Date>.";
1145
1145
  var STRING_EXPECTED = "String expected.";
1146
- var connections = [];
1146
+ var DEFAULT_MAX_CONNECTIONS = 1000;
1147
1147
  var DBNAMES_DB = '__dbnames';
1148
1148
  var READONLY = 'readonly';
1149
1149
  var READWRITE = 'readwrite';
@@ -1975,13 +1975,14 @@ var Collection = (function () {
1975
1975
  var _this = this;
1976
1976
  return this._read(function (trans) {
1977
1977
  var ctx = _this._ctx;
1978
- if (ctx.dir === 'next' && isPlainKeyRange(ctx, true) && ctx.limit > 0) {
1978
+ if (isPlainKeyRange(ctx, true) && ctx.limit > 0) {
1979
1979
  var valueMapper_1 = ctx.valueMapper;
1980
1980
  var index = getIndexOrStore(ctx, ctx.table.core.schema);
1981
1981
  return ctx.table.core.query({
1982
1982
  trans: trans,
1983
1983
  limit: ctx.limit,
1984
1984
  values: true,
1985
+ direction: ctx.dir === 'prev' ? 'prev' : undefined,
1985
1986
  query: {
1986
1987
  index: index,
1987
1988
  range: ctx.range
@@ -2106,13 +2107,14 @@ var Collection = (function () {
2106
2107
  };
2107
2108
  Collection.prototype.primaryKeys = function (cb) {
2108
2109
  var ctx = this._ctx;
2109
- if (ctx.dir === 'next' && isPlainKeyRange(ctx, true) && ctx.limit > 0) {
2110
+ if (isPlainKeyRange(ctx, true) && ctx.limit > 0) {
2110
2111
  return this._read(function (trans) {
2111
2112
  var index = getIndexOrStore(ctx, ctx.table.core.schema);
2112
2113
  return ctx.table.core.query({
2113
2114
  trans: trans,
2114
2115
  values: false,
2115
2116
  limit: ctx.limit,
2117
+ direction: ctx.dir === 'prev' ? 'prev' : undefined,
2116
2118
  query: {
2117
2119
  index: index,
2118
2120
  range: ctx.range
@@ -3002,6 +3004,9 @@ function getKeyPathAlias(keyPath) {
3002
3004
  function createDBCore(db, IdbKeyRange, tmpTrans) {
3003
3005
  function extractSchema(db, trans) {
3004
3006
  var tables = arrayify(db.objectStoreNames);
3007
+ var tempStore = tables.length > 0
3008
+ ? trans.objectStore(tables[0])
3009
+ : {};
3005
3010
  return {
3006
3011
  schema: {
3007
3012
  name: db.name,
@@ -3046,10 +3051,11 @@ function createDBCore(db, IdbKeyRange, tmpTrans) {
3046
3051
  return result;
3047
3052
  })
3048
3053
  },
3049
- hasGetAll: tables.length > 0 && ('getAll' in trans.objectStore(tables[0])) &&
3054
+ hasGetAll: tables.length > 0 && ('getAll' in tempStore) &&
3050
3055
  !(typeof navigator !== 'undefined' && /Safari/.test(navigator.userAgent) &&
3051
3056
  !/(Chrome\/|Edge\/)/.test(navigator.userAgent) &&
3052
- [].concat(navigator.userAgent.match(/Safari\/(\d*)/))[1] < 604)
3057
+ [].concat(navigator.userAgent.match(/Safari\/(\d*)/))[1] < 604),
3058
+ hasIdb3Features: 'getAllRecords' in tempStore
3053
3059
  };
3054
3060
  }
3055
3061
  function makeIDBKeyRange(range) {
@@ -3220,11 +3226,13 @@ function createDBCore(db, IdbKeyRange, tmpTrans) {
3220
3226
  }, reject);
3221
3227
  });
3222
3228
  }
3223
- function query(hasGetAll) {
3229
+ function query(hasGetAll, hasIdb3Features) {
3224
3230
  return function (request) {
3225
3231
  return new Promise(function (resolve, reject) {
3232
+ var _a;
3226
3233
  resolve = wrap(resolve);
3227
3234
  var trans = request.trans, values = request.values, limit = request.limit, query = request.query;
3235
+ var direction = (_a = request.direction) !== null && _a !== void 0 ? _a : 'next';
3228
3236
  var nonInfinitLimit = limit === Infinity ? undefined : limit;
3229
3237
  var index = query.index, range = query.range;
3230
3238
  var store = trans.objectStore(tableName);
@@ -3232,7 +3240,19 @@ function createDBCore(db, IdbKeyRange, tmpTrans) {
3232
3240
  var idbKeyRange = makeIDBKeyRange(range);
3233
3241
  if (limit === 0)
3234
3242
  return resolve({ result: [] });
3235
- if (hasGetAll) {
3243
+ if (hasIdb3Features) {
3244
+ var options = {
3245
+ query: idbKeyRange,
3246
+ count: nonInfinitLimit,
3247
+ direction: direction
3248
+ };
3249
+ var req = values ?
3250
+ source.getAll(options) :
3251
+ source.getAllKeys(options);
3252
+ req.onsuccess = function (event) { return resolve({ result: event.target.result }); };
3253
+ req.onerror = eventRejectHandler(reject);
3254
+ }
3255
+ else if (hasGetAll && direction === 'next') {
3236
3256
  var req = values ?
3237
3257
  source.getAll(idbKeyRange, nonInfinitLimit) :
3238
3258
  source.getAllKeys(idbKeyRange, nonInfinitLimit);
@@ -3242,10 +3262,10 @@ function createDBCore(db, IdbKeyRange, tmpTrans) {
3242
3262
  else {
3243
3263
  var count_1 = 0;
3244
3264
  var req_1 = values || !('openKeyCursor' in source) ?
3245
- source.openCursor(idbKeyRange) :
3246
- source.openKeyCursor(idbKeyRange);
3265
+ source.openCursor(idbKeyRange, direction) :
3266
+ source.openKeyCursor(idbKeyRange, direction);
3247
3267
  var result_1 = [];
3248
- req_1.onsuccess = function (event) {
3268
+ req_1.onsuccess = function () {
3249
3269
  var cursor = req_1.result;
3250
3270
  if (!cursor)
3251
3271
  return resolve({ result: result_1 });
@@ -3305,7 +3325,7 @@ function createDBCore(db, IdbKeyRange, tmpTrans) {
3305
3325
  req.onerror = eventRejectHandler(reject);
3306
3326
  });
3307
3327
  },
3308
- query: query(hasGetAll),
3328
+ query: query(hasGetAll, hasIdb3Features),
3309
3329
  openCursor: openCursor,
3310
3330
  count: function (_a) {
3311
3331
  var query = _a.query, trans = _a.trans;
@@ -3321,7 +3341,7 @@ function createDBCore(db, IdbKeyRange, tmpTrans) {
3321
3341
  }
3322
3342
  };
3323
3343
  }
3324
- var _a = extractSchema(db, tmpTrans), schema = _a.schema, hasGetAll = _a.hasGetAll;
3344
+ var _a = extractSchema(db, tmpTrans), schema = _a.schema, hasGetAll = _a.hasGetAll, hasIdb3Features = _a.hasIdb3Features;
3325
3345
  var tables = schema.tables.map(function (tableSchema) { return createDbCoreTable(tableSchema); });
3326
3346
  var tableMap = {};
3327
3347
  tables.forEach(function (table) { return tableMap[table.name] = table; });
@@ -3773,6 +3793,63 @@ function createVersionConstructor(db) {
3773
3793
  });
3774
3794
  }
3775
3795
 
3796
+ var connections = createConnectionsManager();
3797
+ function createConnectionsManager() {
3798
+ if (typeof FinalizationRegistry !== 'undefined' && typeof WeakRef !== 'undefined') {
3799
+ var _refs_1 = new Set();
3800
+ var _registry_1 = new FinalizationRegistry(function (ref) {
3801
+ _refs_1.delete(ref);
3802
+ });
3803
+ var toArray = function () {
3804
+ return Array.from(_refs_1)
3805
+ .map(function (ref) { return ref.deref(); })
3806
+ .filter(function (db) { return db !== undefined; });
3807
+ };
3808
+ var add = function (db) {
3809
+ var ref = new WeakRef(db._novip);
3810
+ _refs_1.add(ref);
3811
+ _registry_1.register(db._novip, ref, ref);
3812
+ if (_refs_1.size > db._options.maxConnections) {
3813
+ var oldestRef = _refs_1.values().next().value;
3814
+ _refs_1.delete(oldestRef);
3815
+ _registry_1.unregister(oldestRef);
3816
+ }
3817
+ };
3818
+ var remove = function (db) {
3819
+ if (!db)
3820
+ return;
3821
+ var iterator = _refs_1.values();
3822
+ var result = iterator.next();
3823
+ while (!result.done) {
3824
+ var ref = result.value;
3825
+ if (ref.deref() === db._novip) {
3826
+ _refs_1.delete(ref);
3827
+ _registry_1.unregister(ref);
3828
+ return;
3829
+ }
3830
+ result = iterator.next();
3831
+ }
3832
+ };
3833
+ return { toArray: toArray, add: add, remove: remove };
3834
+ }
3835
+ else {
3836
+ var connections_1 = [];
3837
+ var toArray = function () { return connections_1; };
3838
+ var add = function (db) {
3839
+ connections_1.push(db._novip);
3840
+ };
3841
+ var remove = function (db) {
3842
+ if (!db)
3843
+ return;
3844
+ var index = connections_1.indexOf(db._novip);
3845
+ if (index !== -1) {
3846
+ connections_1.splice(index, 1);
3847
+ }
3848
+ };
3849
+ return { toArray: toArray, add: add, remove: remove };
3850
+ }
3851
+ }
3852
+
3776
3853
  function getDbNamesTable(indexedDB, IDBKeyRange) {
3777
3854
  var dbNamesDB = indexedDB["_dbNamesDB"];
3778
3855
  if (!dbNamesDB) {
@@ -4151,7 +4228,7 @@ function dexieOpen(db) {
4151
4228
  }
4152
4229
  catch (e) {
4153
4230
  }
4154
- connections.push(db);
4231
+ connections.add(db);
4155
4232
  idbdb.onversionchange = wrap(function (ev) {
4156
4233
  state.vcFired = true;
4157
4234
  db.on("versionchange").fire(ev);
@@ -4996,10 +5073,13 @@ function applyOptimisticOps(result, req, ops, table, cacheEntry, immutable) {
4996
5073
  }, result);
4997
5074
  if (finalResult === result)
4998
5075
  return result;
4999
- finalResult.sort(function (a, b) {
5076
+ var sorter = function (a, b) {
5000
5077
  return cmp(extractLowLevelIndex(a), extractLowLevelIndex(b)) ||
5001
5078
  cmp(extractPrimKey(a), extractPrimKey(b));
5002
- });
5079
+ };
5080
+ finalResult.sort(req.direction === 'prev' || req.direction === 'prevunique'
5081
+ ? function (a, b) { return sorter(b, a); }
5082
+ : sorter);
5003
5083
  if (req.limit && req.limit < Infinity) {
5004
5084
  if (finalResult.length > req.limit) {
5005
5085
  finalResult.length = req.limit;
@@ -5056,6 +5136,7 @@ function isSuperRange(r1, r2) {
5056
5136
  }
5057
5137
 
5058
5138
  function findCompatibleQuery(dbName, tableName, type, req) {
5139
+ var _a;
5059
5140
  var tblCache = cache["idb://".concat(dbName, "/").concat(tableName)];
5060
5141
  if (!tblCache)
5061
5142
  return [];
@@ -5068,9 +5149,12 @@ function findCompatibleQuery(dbName, tableName, type, req) {
5068
5149
  return [null, false, tblCache, null];
5069
5150
  switch (type) {
5070
5151
  case 'query':
5152
+ var reqDirection_1 = (_a = req.direction) !== null && _a !== void 0 ? _a : 'next';
5071
5153
  var equalEntry = entries.find(function (entry) {
5154
+ var _a;
5072
5155
  return entry.req.limit === req.limit &&
5073
5156
  entry.req.values === req.values &&
5157
+ ((_a = entry.req.direction) !== null && _a !== void 0 ? _a : 'next') === reqDirection_1 &&
5074
5158
  areRangesEqual(entry.req.query.range, req.query.range);
5075
5159
  });
5076
5160
  if (equalEntry)
@@ -5081,8 +5165,10 @@ function findCompatibleQuery(dbName, tableName, type, req) {
5081
5165
  entries,
5082
5166
  ];
5083
5167
  var superEntry = entries.find(function (entry) {
5168
+ var _a;
5084
5169
  var limit = 'limit' in entry.req ? entry.req.limit : Infinity;
5085
5170
  return (limit >= req.limit &&
5171
+ ((_a = entry.req.direction) !== null && _a !== void 0 ? _a : 'next') === reqDirection_1 &&
5086
5172
  (req.values ? entry.req.values : true) &&
5087
5173
  isSuperRange(entry.req.query.range, req.query.range));
5088
5174
  });
@@ -5332,7 +5418,7 @@ var Dexie$1 = (function () {
5332
5418
  var deps = Dexie.dependencies;
5333
5419
  this._options = options = __assign({
5334
5420
  addons: Dexie.addons, autoOpen: true,
5335
- indexedDB: deps.indexedDB, IDBKeyRange: deps.IDBKeyRange, cache: 'cloned' }, options);
5421
+ indexedDB: deps.indexedDB, IDBKeyRange: deps.IDBKeyRange, cache: 'cloned', maxConnections: DEFAULT_MAX_CONNECTIONS }, options);
5336
5422
  this._deps = {
5337
5423
  indexedDB: options.indexedDB,
5338
5424
  IDBKeyRange: options.IDBKeyRange
@@ -5426,7 +5512,7 @@ var Dexie$1 = (function () {
5426
5512
  this._createTransaction = function (mode, storeNames, dbschema, parentTransaction) { return new _this.Transaction(mode, storeNames, dbschema, _this._options.chromeTransactionDurability, parentTransaction); };
5427
5513
  this._fireOnBlocked = function (ev) {
5428
5514
  _this.on("blocked").fire(ev);
5429
- connections
5515
+ connections.toArray()
5430
5516
  .filter(function (c) { return c.name === _this.name && c !== _this && !c._state.vcFired; })
5431
5517
  .map(function (c) { return c.on("versionchange").fire(ev); });
5432
5518
  };
@@ -5519,9 +5605,7 @@ var Dexie$1 = (function () {
5519
5605
  Dexie.prototype._close = function () {
5520
5606
  this.on.close.fire(new CustomEvent('close'));
5521
5607
  var state = this._state;
5522
- var idx = connections.indexOf(this);
5523
- if (idx >= 0)
5524
- connections.splice(idx, 1);
5608
+ connections.remove(this);
5525
5609
  if (this.idbdb) {
5526
5610
  try {
5527
5611
  this.idbdb.close();
@@ -5883,7 +5967,9 @@ props(Dexie, __assign(__assign({}, fullNameExceptions), {
5883
5967
  getByKeyPath: getByKeyPath, setByKeyPath: setByKeyPath, delByKeyPath: delByKeyPath, shallowClone: shallowClone, deepClone: deepClone, getObjectDiff: getObjectDiff, cmp: cmp, asap: asap$1,
5884
5968
  minKey: minKey,
5885
5969
  addons: [],
5886
- connections: connections,
5970
+ connections: {
5971
+ get: connections.toArray
5972
+ },
5887
5973
  errnames: errnames,
5888
5974
  dependencies: domDeps, cache: cache,
5889
5975
  semVer: DEXIE_VERSION, version: DEXIE_VERSION.split('.')
@@ -5947,8 +6033,8 @@ if (typeof addEventListener !== 'undefined') {
5947
6033
  if (debug)
5948
6034
  console.debug('Dexie: handling persisted pagehide');
5949
6035
  bc === null || bc === void 0 ? void 0 : bc.close();
5950
- for (var _i = 0, connections_1 = connections; _i < connections_1.length; _i++) {
5951
- var db = connections_1[_i];
6036
+ for (var _i = 0, _a = connections.toArray(); _i < _a.length; _i++) {
6037
+ var db = _a[_i];
5952
6038
  db.close({ disableAutoOpen: false });
5953
6039
  }
5954
6040
  }
@@ -5978,5 +6064,5 @@ function replacePrefix(a, b) {
5978
6064
  DexiePromise.rejectionMapper = mapError;
5979
6065
  setDebug(debug);
5980
6066
 
5981
- export { Dexie$1 as Dexie, Entity, PropModification, RangeSet, add, cmp, Dexie$1 as default, liveQuery, mergeRanges, rangesOverlap, remove, replacePrefix };
6067
+ export { DEFAULT_MAX_CONNECTIONS, Dexie$1 as Dexie, Entity, PropModification, RangeSet, add, cmp, Dexie$1 as default, liveQuery, mergeRanges, rangesOverlap, remove, replacePrefix };
5982
6068
  //# sourceMappingURL=dexie.mjs.map