dexie 4.3.0 → 4.4.1

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.1, Wed Mar 25 2026
8
8
  *
9
9
  * https://dexie.org
10
10
  *
@@ -222,12 +222,6 @@ function cloneSimpleObjectTree(o) {
222
222
  }
223
223
  return rv;
224
224
  }
225
- function objectIsEmpty(o) {
226
- for (var k in o)
227
- if (hasOwn(o, k))
228
- return false;
229
- return true;
230
- }
231
225
  var circularRefs = null;
232
226
  function deepClone(any) {
233
227
  circularRefs = new WeakMap();
@@ -1138,12 +1132,12 @@ function tempTransaction(db, mode, storeNames, fn) {
1138
1132
  }
1139
1133
  }
1140
1134
 
1141
- var DEXIE_VERSION = '4.3.0';
1135
+ var DEXIE_VERSION = '4.4.1';
1142
1136
  var maxString = String.fromCharCode(65535);
1143
1137
  var minKey = -Infinity;
1144
1138
  var INVALID_KEY_ARGUMENT = "Invalid key provided. Keys must be of type string, number, Date or Array<string | number | Date>.";
1145
1139
  var STRING_EXPECTED = "String expected.";
1146
- var connections = [];
1140
+ var DEFAULT_MAX_CONNECTIONS = 1000;
1147
1141
  var DBNAMES_DB = '__dbnames';
1148
1142
  var READONLY = 'readonly';
1149
1143
  var READWRITE = 'readwrite';
@@ -1975,13 +1969,14 @@ var Collection = (function () {
1975
1969
  var _this = this;
1976
1970
  return this._read(function (trans) {
1977
1971
  var ctx = _this._ctx;
1978
- if (ctx.dir === 'next' && isPlainKeyRange(ctx, true) && ctx.limit > 0) {
1972
+ if (isPlainKeyRange(ctx, true) && ctx.limit > 0) {
1979
1973
  var valueMapper_1 = ctx.valueMapper;
1980
1974
  var index = getIndexOrStore(ctx, ctx.table.core.schema);
1981
1975
  return ctx.table.core.query({
1982
1976
  trans: trans,
1983
1977
  limit: ctx.limit,
1984
1978
  values: true,
1979
+ direction: ctx.dir === 'prev' ? 'prev' : undefined,
1985
1980
  query: {
1986
1981
  index: index,
1987
1982
  range: ctx.range
@@ -2106,13 +2101,14 @@ var Collection = (function () {
2106
2101
  };
2107
2102
  Collection.prototype.primaryKeys = function (cb) {
2108
2103
  var ctx = this._ctx;
2109
- if (ctx.dir === 'next' && isPlainKeyRange(ctx, true) && ctx.limit > 0) {
2104
+ if (isPlainKeyRange(ctx, true) && ctx.limit > 0) {
2110
2105
  return this._read(function (trans) {
2111
2106
  var index = getIndexOrStore(ctx, ctx.table.core.schema);
2112
2107
  return ctx.table.core.query({
2113
2108
  trans: trans,
2114
2109
  values: false,
2115
2110
  limit: ctx.limit,
2111
+ direction: ctx.dir === 'prev' ? 'prev' : undefined,
2116
2112
  query: {
2117
2113
  index: index,
2118
2114
  range: ctx.range
@@ -3002,6 +2998,9 @@ function getKeyPathAlias(keyPath) {
3002
2998
  function createDBCore(db, IdbKeyRange, tmpTrans) {
3003
2999
  function extractSchema(db, trans) {
3004
3000
  var tables = arrayify(db.objectStoreNames);
3001
+ var tempStore = tables.length > 0
3002
+ ? trans.objectStore(tables[0])
3003
+ : {};
3005
3004
  return {
3006
3005
  schema: {
3007
3006
  name: db.name,
@@ -3046,10 +3045,11 @@ function createDBCore(db, IdbKeyRange, tmpTrans) {
3046
3045
  return result;
3047
3046
  })
3048
3047
  },
3049
- hasGetAll: tables.length > 0 && ('getAll' in trans.objectStore(tables[0])) &&
3048
+ hasGetAll: tables.length > 0 && ('getAll' in tempStore) &&
3050
3049
  !(typeof navigator !== 'undefined' && /Safari/.test(navigator.userAgent) &&
3051
3050
  !/(Chrome\/|Edge\/)/.test(navigator.userAgent) &&
3052
- [].concat(navigator.userAgent.match(/Safari\/(\d*)/))[1] < 604)
3051
+ [].concat(navigator.userAgent.match(/Safari\/(\d*)/))[1] < 604),
3052
+ hasIdb3Features: 'getAllRecords' in tempStore
3053
3053
  };
3054
3054
  }
3055
3055
  function makeIDBKeyRange(range) {
@@ -3220,11 +3220,13 @@ function createDBCore(db, IdbKeyRange, tmpTrans) {
3220
3220
  }, reject);
3221
3221
  });
3222
3222
  }
3223
- function query(hasGetAll) {
3223
+ function query(hasGetAll, hasIdb3Features) {
3224
3224
  return function (request) {
3225
3225
  return new Promise(function (resolve, reject) {
3226
+ var _a;
3226
3227
  resolve = wrap(resolve);
3227
3228
  var trans = request.trans, values = request.values, limit = request.limit, query = request.query;
3229
+ var direction = (_a = request.direction) !== null && _a !== void 0 ? _a : 'next';
3228
3230
  var nonInfinitLimit = limit === Infinity ? undefined : limit;
3229
3231
  var index = query.index, range = query.range;
3230
3232
  var store = trans.objectStore(tableName);
@@ -3232,7 +3234,19 @@ function createDBCore(db, IdbKeyRange, tmpTrans) {
3232
3234
  var idbKeyRange = makeIDBKeyRange(range);
3233
3235
  if (limit === 0)
3234
3236
  return resolve({ result: [] });
3235
- if (hasGetAll) {
3237
+ if (hasIdb3Features) {
3238
+ var options = {
3239
+ query: idbKeyRange,
3240
+ count: nonInfinitLimit,
3241
+ direction: direction
3242
+ };
3243
+ var req = values ?
3244
+ source.getAll(options) :
3245
+ source.getAllKeys(options);
3246
+ req.onsuccess = function (event) { return resolve({ result: event.target.result }); };
3247
+ req.onerror = eventRejectHandler(reject);
3248
+ }
3249
+ else if (hasGetAll && direction === 'next') {
3236
3250
  var req = values ?
3237
3251
  source.getAll(idbKeyRange, nonInfinitLimit) :
3238
3252
  source.getAllKeys(idbKeyRange, nonInfinitLimit);
@@ -3242,10 +3256,10 @@ function createDBCore(db, IdbKeyRange, tmpTrans) {
3242
3256
  else {
3243
3257
  var count_1 = 0;
3244
3258
  var req_1 = values || !('openKeyCursor' in source) ?
3245
- source.openCursor(idbKeyRange) :
3246
- source.openKeyCursor(idbKeyRange);
3259
+ source.openCursor(idbKeyRange, direction) :
3260
+ source.openKeyCursor(idbKeyRange, direction);
3247
3261
  var result_1 = [];
3248
- req_1.onsuccess = function (event) {
3262
+ req_1.onsuccess = function () {
3249
3263
  var cursor = req_1.result;
3250
3264
  if (!cursor)
3251
3265
  return resolve({ result: result_1 });
@@ -3305,7 +3319,7 @@ function createDBCore(db, IdbKeyRange, tmpTrans) {
3305
3319
  req.onerror = eventRejectHandler(reject);
3306
3320
  });
3307
3321
  },
3308
- query: query(hasGetAll),
3322
+ query: query(hasGetAll, hasIdb3Features),
3309
3323
  openCursor: openCursor,
3310
3324
  count: function (_a) {
3311
3325
  var query = _a.query, trans = _a.trans;
@@ -3321,7 +3335,7 @@ function createDBCore(db, IdbKeyRange, tmpTrans) {
3321
3335
  }
3322
3336
  };
3323
3337
  }
3324
- var _a = extractSchema(db, tmpTrans), schema = _a.schema, hasGetAll = _a.hasGetAll;
3338
+ var _a = extractSchema(db, tmpTrans), schema = _a.schema, hasGetAll = _a.hasGetAll, hasIdb3Features = _a.hasIdb3Features;
3325
3339
  var tables = schema.tables.map(function (tableSchema) { return createDbCoreTable(tableSchema); });
3326
3340
  var tableMap = {};
3327
3341
  tables.forEach(function (table) { return tableMap[table.name] = table; });
@@ -3773,6 +3787,63 @@ function createVersionConstructor(db) {
3773
3787
  });
3774
3788
  }
3775
3789
 
3790
+ var connections = createConnectionsManager();
3791
+ function createConnectionsManager() {
3792
+ if (typeof FinalizationRegistry !== 'undefined' && typeof WeakRef !== 'undefined') {
3793
+ var _refs_1 = new Set();
3794
+ var _registry_1 = new FinalizationRegistry(function (ref) {
3795
+ _refs_1.delete(ref);
3796
+ });
3797
+ var toArray = function () {
3798
+ return Array.from(_refs_1)
3799
+ .map(function (ref) { return ref.deref(); })
3800
+ .filter(function (db) { return db !== undefined; });
3801
+ };
3802
+ var add = function (db) {
3803
+ var ref = new WeakRef(db._novip);
3804
+ _refs_1.add(ref);
3805
+ _registry_1.register(db._novip, ref, ref);
3806
+ if (_refs_1.size > db._options.maxConnections) {
3807
+ var oldestRef = _refs_1.values().next().value;
3808
+ _refs_1.delete(oldestRef);
3809
+ _registry_1.unregister(oldestRef);
3810
+ }
3811
+ };
3812
+ var remove = function (db) {
3813
+ if (!db)
3814
+ return;
3815
+ var iterator = _refs_1.values();
3816
+ var result = iterator.next();
3817
+ while (!result.done) {
3818
+ var ref = result.value;
3819
+ if (ref.deref() === db._novip) {
3820
+ _refs_1.delete(ref);
3821
+ _registry_1.unregister(ref);
3822
+ return;
3823
+ }
3824
+ result = iterator.next();
3825
+ }
3826
+ };
3827
+ return { toArray: toArray, add: add, remove: remove };
3828
+ }
3829
+ else {
3830
+ var connections_1 = [];
3831
+ var toArray = function () { return connections_1; };
3832
+ var add = function (db) {
3833
+ connections_1.push(db._novip);
3834
+ };
3835
+ var remove = function (db) {
3836
+ if (!db)
3837
+ return;
3838
+ var index = connections_1.indexOf(db._novip);
3839
+ if (index !== -1) {
3840
+ connections_1.splice(index, 1);
3841
+ }
3842
+ };
3843
+ return { toArray: toArray, add: add, remove: remove };
3844
+ }
3845
+ }
3846
+
3776
3847
  function getDbNamesTable(indexedDB, IDBKeyRange) {
3777
3848
  var dbNamesDB = indexedDB["_dbNamesDB"];
3778
3849
  if (!dbNamesDB) {
@@ -4151,7 +4222,7 @@ function dexieOpen(db) {
4151
4222
  }
4152
4223
  catch (e) {
4153
4224
  }
4154
- connections.push(db);
4225
+ connections.add(db);
4155
4226
  idbdb.onversionchange = wrap(function (ev) {
4156
4227
  state.vcFired = true;
4157
4228
  db.on("versionchange").fire(ev);
@@ -4996,10 +5067,13 @@ function applyOptimisticOps(result, req, ops, table, cacheEntry, immutable) {
4996
5067
  }, result);
4997
5068
  if (finalResult === result)
4998
5069
  return result;
4999
- finalResult.sort(function (a, b) {
5070
+ var sorter = function (a, b) {
5000
5071
  return cmp(extractLowLevelIndex(a), extractLowLevelIndex(b)) ||
5001
5072
  cmp(extractPrimKey(a), extractPrimKey(b));
5002
- });
5073
+ };
5074
+ finalResult.sort(req.direction === 'prev' || req.direction === 'prevunique'
5075
+ ? function (a, b) { return sorter(b, a); }
5076
+ : sorter);
5003
5077
  if (req.limit && req.limit < Infinity) {
5004
5078
  if (finalResult.length > req.limit) {
5005
5079
  finalResult.length = req.limit;
@@ -5056,6 +5130,7 @@ function isSuperRange(r1, r2) {
5056
5130
  }
5057
5131
 
5058
5132
  function findCompatibleQuery(dbName, tableName, type, req) {
5133
+ var _a;
5059
5134
  var tblCache = cache["idb://".concat(dbName, "/").concat(tableName)];
5060
5135
  if (!tblCache)
5061
5136
  return [];
@@ -5068,9 +5143,12 @@ function findCompatibleQuery(dbName, tableName, type, req) {
5068
5143
  return [null, false, tblCache, null];
5069
5144
  switch (type) {
5070
5145
  case 'query':
5146
+ var reqDirection_1 = (_a = req.direction) !== null && _a !== void 0 ? _a : 'next';
5071
5147
  var equalEntry = entries.find(function (entry) {
5148
+ var _a;
5072
5149
  return entry.req.limit === req.limit &&
5073
5150
  entry.req.values === req.values &&
5151
+ ((_a = entry.req.direction) !== null && _a !== void 0 ? _a : 'next') === reqDirection_1 &&
5074
5152
  areRangesEqual(entry.req.query.range, req.query.range);
5075
5153
  });
5076
5154
  if (equalEntry)
@@ -5081,8 +5159,10 @@ function findCompatibleQuery(dbName, tableName, type, req) {
5081
5159
  entries,
5082
5160
  ];
5083
5161
  var superEntry = entries.find(function (entry) {
5162
+ var _a;
5084
5163
  var limit = 'limit' in entry.req ? entry.req.limit : Infinity;
5085
5164
  return (limit >= req.limit &&
5165
+ ((_a = entry.req.direction) !== null && _a !== void 0 ? _a : 'next') === reqDirection_1 &&
5086
5166
  (req.values ? entry.req.values : true) &&
5087
5167
  isSuperRange(entry.req.query.range, req.query.range));
5088
5168
  });
@@ -5332,7 +5412,7 @@ var Dexie$1 = (function () {
5332
5412
  var deps = Dexie.dependencies;
5333
5413
  this._options = options = __assign({
5334
5414
  addons: Dexie.addons, autoOpen: true,
5335
- indexedDB: deps.indexedDB, IDBKeyRange: deps.IDBKeyRange, cache: 'cloned' }, options);
5415
+ indexedDB: deps.indexedDB, IDBKeyRange: deps.IDBKeyRange, cache: 'cloned', maxConnections: DEFAULT_MAX_CONNECTIONS }, options);
5336
5416
  this._deps = {
5337
5417
  indexedDB: options.indexedDB,
5338
5418
  IDBKeyRange: options.IDBKeyRange
@@ -5426,7 +5506,7 @@ var Dexie$1 = (function () {
5426
5506
  this._createTransaction = function (mode, storeNames, dbschema, parentTransaction) { return new _this.Transaction(mode, storeNames, dbschema, _this._options.chromeTransactionDurability, parentTransaction); };
5427
5507
  this._fireOnBlocked = function (ev) {
5428
5508
  _this.on("blocked").fire(ev);
5429
- connections
5509
+ connections.toArray()
5430
5510
  .filter(function (c) { return c.name === _this.name && c !== _this && !c._state.vcFired; })
5431
5511
  .map(function (c) { return c.on("versionchange").fire(ev); });
5432
5512
  };
@@ -5519,9 +5599,7 @@ var Dexie$1 = (function () {
5519
5599
  Dexie.prototype._close = function () {
5520
5600
  this.on.close.fire(new CustomEvent('close'));
5521
5601
  var state = this._state;
5522
- var idx = connections.indexOf(this);
5523
- if (idx >= 0)
5524
- connections.splice(idx, 1);
5602
+ connections.remove(this);
5525
5603
  if (this.idbdb) {
5526
5604
  try {
5527
5605
  this.idbdb.close();
@@ -5772,22 +5850,32 @@ function liveQuery(querier) {
5772
5850
  signal: abortController.signal,
5773
5851
  requery: doQuery,
5774
5852
  querier: querier,
5775
- trans: null
5853
+ trans: null,
5776
5854
  };
5777
5855
  var ret = execute(ctx);
5856
+ if (!startedListening) {
5857
+ globalEvents(DEXIE_STORAGE_MUTATED_EVENT_NAME, mutationListener);
5858
+ startedListening = true;
5859
+ }
5778
5860
  Promise.resolve(ret).then(function (result) {
5779
5861
  hasValue = true;
5780
5862
  currentValue = result;
5781
5863
  if (closed || ctx.signal.aborted) {
5782
5864
  return;
5783
5865
  }
5784
- accumMuts = {};
5785
- currentObs = subscr;
5786
- if (!objectIsEmpty(currentObs) && !startedListening) {
5787
- globalEvents(DEXIE_STORAGE_MUTATED_EVENT_NAME, mutationListener);
5788
- startedListening = true;
5866
+ if (shouldNotify()) {
5867
+ doQuery();
5868
+ }
5869
+ else {
5870
+ currentObs = subscr;
5871
+ if (shouldNotify()) {
5872
+ doQuery();
5873
+ }
5874
+ else {
5875
+ accumMuts = {};
5876
+ execInGlobalContext(function () { return !closed && observer.next && observer.next(result); });
5877
+ }
5789
5878
  }
5790
- execInGlobalContext(function () { return !closed && observer.next && observer.next(result); });
5791
5879
  }, function (err) {
5792
5880
  hasValue = false;
5793
5881
  if (!['DatabaseClosedError', 'AbortError'].includes(err === null || err === void 0 ? void 0 : err.name)) {
@@ -5883,7 +5971,9 @@ props(Dexie, __assign(__assign({}, fullNameExceptions), {
5883
5971
  getByKeyPath: getByKeyPath, setByKeyPath: setByKeyPath, delByKeyPath: delByKeyPath, shallowClone: shallowClone, deepClone: deepClone, getObjectDiff: getObjectDiff, cmp: cmp, asap: asap$1,
5884
5972
  minKey: minKey,
5885
5973
  addons: [],
5886
- connections: connections,
5974
+ connections: {
5975
+ get: connections.toArray
5976
+ },
5887
5977
  errnames: errnames,
5888
5978
  dependencies: domDeps, cache: cache,
5889
5979
  semVer: DEXIE_VERSION, version: DEXIE_VERSION.split('.')
@@ -5947,8 +6037,8 @@ if (typeof addEventListener !== 'undefined') {
5947
6037
  if (debug)
5948
6038
  console.debug('Dexie: handling persisted pagehide');
5949
6039
  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];
6040
+ for (var _i = 0, _a = connections.toArray(); _i < _a.length; _i++) {
6041
+ var db = _a[_i];
5952
6042
  db.close({ disableAutoOpen: false });
5953
6043
  }
5954
6044
  }
@@ -5978,5 +6068,5 @@ function replacePrefix(a, b) {
5978
6068
  DexiePromise.rejectionMapper = mapError;
5979
6069
  setDebug(debug);
5980
6070
 
5981
- export { Dexie$1 as Dexie, Entity, PropModification, RangeSet, add, cmp, Dexie$1 as default, liveQuery, mergeRanges, rangesOverlap, remove, replacePrefix };
6071
+ export { DEFAULT_MAX_CONNECTIONS, Dexie$1 as Dexie, Entity, PropModification, RangeSet, add, cmp, Dexie$1 as default, liveQuery, mergeRanges, rangesOverlap, remove, replacePrefix };
5982
6072
  //# sourceMappingURL=dexie.mjs.map