dexie 4.0.1-beta.9 → 4.0.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.
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * By David Fahlander, david.fahlander@gmail.com
6
6
  *
7
- * Version 4.0.1-beta.9, Thu Feb 08 2024
7
+ * Version 4.0.1, Tue Mar 26 2024
8
8
  *
9
9
  * https://dexie.org
10
10
  *
@@ -105,7 +105,7 @@ function getByKeyPath(obj, keyPath) {
105
105
  var period = keyPath.indexOf('.');
106
106
  if (period !== -1) {
107
107
  var innerObj = obj[keyPath.substr(0, period)];
108
- return innerObj === undefined ? undefined : getByKeyPath(innerObj, keyPath.substr(period + 1));
108
+ return innerObj == null ? undefined : getByKeyPath(innerObj, keyPath.substr(period + 1));
109
109
  }
110
110
  return undefined;
111
111
  }
@@ -1073,7 +1073,7 @@ function tempTransaction(db, mode, storeNames, fn) {
1073
1073
  catch (ex) {
1074
1074
  if (ex.name === errnames.InvalidState && db.isOpen() && --db._state.PR1398_maxLoop > 0) {
1075
1075
  console.warn('Dexie: Need to reopen db');
1076
- db._close();
1076
+ db.close({ disableAutoOpen: false });
1077
1077
  return db.open().then(() => tempTransaction(db, mode, storeNames, fn));
1078
1078
  }
1079
1079
  return rejection(ex);
@@ -1094,15 +1094,12 @@ function tempTransaction(db, mode, storeNames, fn) {
1094
1094
  }
1095
1095
  }
1096
1096
 
1097
- const DEXIE_VERSION = '4.0.1-beta.9';
1097
+ const DEXIE_VERSION = '4.0.1';
1098
1098
  const maxString = String.fromCharCode(65535);
1099
1099
  const minKey = -Infinity;
1100
1100
  const INVALID_KEY_ARGUMENT = "Invalid key provided. Keys must be of type string, number, Date or Array<string | number | Date>.";
1101
1101
  const STRING_EXPECTED = "String expected.";
1102
1102
  const connections = [];
1103
- const isIEOrEdge = typeof navigator !== 'undefined' && /(MSIE|Trident|Edge)/.test(navigator.userAgent);
1104
- const hasIEDeleteObjectStoreBug = isIEOrEdge;
1105
- const hangsOnDeleteLargeKeyRange = isIEOrEdge;
1106
1103
  const DBNAMES_DB = '__dbnames';
1107
1104
  const READONLY = 'readonly';
1108
1105
  const READWRITE = 'readwrite';
@@ -1720,6 +1717,20 @@ function iterate(cursorPromise, filter, fn, valueMapper) {
1720
1717
  });
1721
1718
  }
1722
1719
 
1720
+ const PropModSymbol = Symbol();
1721
+ class PropModification {
1722
+ execute(value) {
1723
+ const prefixToReplace = this.replacePrefix?.[0];
1724
+ if (prefixToReplace && typeof value === 'string' && value.startsWith(prefixToReplace)) {
1725
+ return this.replacePrefix[1] + value.substring(prefixToReplace.length);
1726
+ }
1727
+ return value;
1728
+ }
1729
+ constructor(spec) {
1730
+ Object.assign(this, spec);
1731
+ }
1732
+ }
1733
+
1723
1734
  class Collection {
1724
1735
  _read(fn, cb) {
1725
1736
  var ctx = this._ctx;
@@ -1978,10 +1989,16 @@ class Collection {
1978
1989
  var keyPaths = keys(changes);
1979
1990
  var numKeys = keyPaths.length;
1980
1991
  modifyer = function (item) {
1981
- var anythingModified = false;
1982
- for (var i = 0; i < numKeys; ++i) {
1983
- var keyPath = keyPaths[i], val = changes[keyPath];
1984
- if (getByKeyPath(item, keyPath) !== val) {
1992
+ let anythingModified = false;
1993
+ for (let i = 0; i < numKeys; ++i) {
1994
+ let keyPath = keyPaths[i];
1995
+ let val = changes[keyPath];
1996
+ let origVal = getByKeyPath(item, keyPath);
1997
+ if (val instanceof PropModification) {
1998
+ setByKeyPath(item, keyPath, val.execute(origVal));
1999
+ anythingModified = true;
2000
+ }
2001
+ else if (origVal !== val) {
1985
2002
  setByKeyPath(item, keyPath, val);
1986
2003
  anythingModified = true;
1987
2004
  }
@@ -2079,7 +2096,7 @@ class Collection {
2079
2096
  delete() {
2080
2097
  var ctx = this._ctx, range = ctx.range;
2081
2098
  if (isPlainKeyRange(ctx) &&
2082
- ((ctx.isPrimKey && !hangsOnDeleteLargeKeyRange) || range.type === 3 ))
2099
+ (ctx.isPrimKey || range.type === 3 ))
2083
2100
  {
2084
2101
  return this._write(trans => {
2085
2102
  const { primaryKey } = ctx.table.core.schema;
@@ -3234,7 +3251,6 @@ function updateTablesAndIndexes(db, oldVersion, trans, idbUpgradeTrans) {
3234
3251
  const queue = [];
3235
3252
  const versions = db._versions;
3236
3253
  let globalSchema = db._dbSchema = buildGlobalSchema(db, db.idbdb, idbUpgradeTrans);
3237
- let anyContentUpgraderHasRun = false;
3238
3254
  const versToRun = versions.filter(v => v._cfg.version >= oldVersion);
3239
3255
  if (versToRun.length === 0) {
3240
3256
  return DexiePromise.resolve();
@@ -3268,7 +3284,6 @@ function updateTablesAndIndexes(db, oldVersion, trans, idbUpgradeTrans) {
3268
3284
  if (contentUpgrade && version._cfg.version > oldVersion) {
3269
3285
  generateMiddlewareStacks(db, idbUpgradeTrans);
3270
3286
  trans._memoizedTables = {};
3271
- anyContentUpgraderHasRun = true;
3272
3287
  let upgradeSchema = shallowClone(newSchema);
3273
3288
  diff.del.forEach(table => {
3274
3289
  upgradeSchema[table] = oldSchema[table];
@@ -3295,10 +3310,8 @@ function updateTablesAndIndexes(db, oldVersion, trans, idbUpgradeTrans) {
3295
3310
  }
3296
3311
  });
3297
3312
  queue.push(idbtrans => {
3298
- if (!anyContentUpgraderHasRun || !hasIEDeleteObjectStoreBug) {
3299
- const newSchema = version._cfg.dbschema;
3300
- deleteRemovedTables(newSchema, idbtrans);
3301
- }
3313
+ const newSchema = version._cfg.dbschema;
3314
+ deleteRemovedTables(newSchema, idbtrans);
3302
3315
  removeTablesApi(db, [db.Transaction.prototype]);
3303
3316
  setApiOnPlace(db, [db.Transaction.prototype], db._storeNames, db._dbSchema);
3304
3317
  trans.schema = db._dbSchema;
@@ -3351,8 +3364,7 @@ function getSchemaDiff(oldSchema, newSchema) {
3351
3364
  };
3352
3365
  if ((
3353
3366
  '' + (oldDef.primKey.keyPath || '')) !== ('' + (newDef.primKey.keyPath || '')) ||
3354
- (oldDef.primKey.auto !== newDef.primKey.auto && !isIEOrEdge))
3355
- {
3367
+ (oldDef.primKey.auto !== newDef.primKey.auto)) {
3356
3368
  change.recreate = true;
3357
3369
  diff.change.push(change);
3358
3370
  }
@@ -4005,7 +4017,7 @@ function enterTransactionScope(db, mode, storeNames, parentTransaction, scopeFun
4005
4017
  catch (ex) {
4006
4018
  if (ex.name === errnames.InvalidState && db.isOpen() && --db._state.PR1398_maxLoop > 0) {
4007
4019
  console.warn('Dexie: Need to reopen db');
4008
- db._close();
4020
+ db.close({ disableAutoOpen: false });
4009
4021
  return db.open().then(() => enterTransactionScope(db, mode, storeNames, null, scopeFunc));
4010
4022
  }
4011
4023
  return rejection(ex);
@@ -5142,7 +5154,6 @@ class Dexie$1 {
5142
5154
  else
5143
5155
  console.warn(`Another connection wants to delete database '${this.name}'. Closing db now to resume the delete request.`);
5144
5156
  this.close({ disableAutoOpen: false });
5145
- this._state.openComplete = false;
5146
5157
  });
5147
5158
  this.on("blocked", ev => {
5148
5159
  if (!ev.newVersion || ev.newVersion < ev.oldVersion)
@@ -5250,32 +5261,39 @@ class Dexie$1 {
5250
5261
  catch (e) { }
5251
5262
  this.idbdb = null;
5252
5263
  }
5253
- state.dbReadyPromise = new DexiePromise(resolve => {
5254
- state.dbReadyResolve = resolve;
5255
- });
5256
- state.openCanceller = new DexiePromise((_, reject) => {
5257
- state.cancelOpen = reject;
5258
- });
5264
+ if (!state.isBeingOpened) {
5265
+ state.dbReadyPromise = new DexiePromise(resolve => {
5266
+ state.dbReadyResolve = resolve;
5267
+ });
5268
+ state.openCanceller = new DexiePromise((_, reject) => {
5269
+ state.cancelOpen = reject;
5270
+ });
5271
+ }
5259
5272
  }
5260
5273
  close({ disableAutoOpen } = { disableAutoOpen: true }) {
5261
- const wasOpen = this.isOpen();
5262
- this._close();
5263
5274
  const state = this._state;
5264
- if (disableAutoOpen)
5265
- this._state.autoOpen = false;
5266
- else if (wasOpen && this._options.autoOpen) {
5267
- this._state.autoOpen = true;
5275
+ if (disableAutoOpen) {
5276
+ if (state.isBeingOpened) {
5277
+ state.cancelOpen(new exceptions.DatabaseClosed());
5278
+ }
5279
+ this._close();
5280
+ state.autoOpen = false;
5281
+ state.dbOpenError = new exceptions.DatabaseClosed();
5282
+ }
5283
+ else {
5284
+ this._close();
5285
+ state.autoOpen = this._options.autoOpen ||
5286
+ state.isBeingOpened;
5287
+ state.openComplete = false;
5288
+ state.dbOpenError = null;
5268
5289
  }
5269
- state.dbOpenError = new exceptions.DatabaseClosed();
5270
- if (state.isBeingOpened)
5271
- state.cancelOpen(state.dbOpenError);
5272
5290
  }
5273
- delete() {
5274
- const hasArguments = arguments.length > 0;
5291
+ delete(closeOptions = { disableAutoOpen: true }) {
5292
+ const hasInvalidArguments = arguments.length > 0 && typeof arguments[0] !== 'object';
5275
5293
  const state = this._state;
5276
5294
  return new DexiePromise((resolve, reject) => {
5277
5295
  const doDelete = () => {
5278
- this.close({ disableAutoOpen: false });
5296
+ this.close(closeOptions);
5279
5297
  var req = this._deps.indexedDB.deleteDatabase(this.name);
5280
5298
  req.onsuccess = wrap(() => {
5281
5299
  _onDatabaseDeleted(this._deps, this.name);
@@ -5284,8 +5302,8 @@ class Dexie$1 {
5284
5302
  req.onerror = eventRejectHandler(reject);
5285
5303
  req.onblocked = this._fireOnBlocked;
5286
5304
  };
5287
- if (hasArguments)
5288
- throw new exceptions.InvalidArgument("Arguments not allowed in db.delete()");
5305
+ if (hasInvalidArguments)
5306
+ throw new exceptions.InvalidArgument("Invalid closeOptions argument to db.delete()");
5289
5307
  if (state.isBeingOpened) {
5290
5308
  state.dbReadyPromise.then(doDelete);
5291
5309
  }
@@ -5620,15 +5638,9 @@ if (typeof dispatchEvent !== 'undefined' && typeof addEventListener !== 'undefin
5620
5638
  globalEvents(DEXIE_STORAGE_MUTATED_EVENT_NAME, updatedParts => {
5621
5639
  if (!propagatingLocally) {
5622
5640
  let event;
5623
- if (isIEOrEdge) {
5624
- event = document.createEvent('CustomEvent');
5625
- event.initCustomEvent(STORAGE_MUTATED_DOM_EVENT_NAME, true, true, updatedParts);
5626
- }
5627
- else {
5628
- event = new CustomEvent(STORAGE_MUTATED_DOM_EVENT_NAME, {
5629
- detail: updatedParts
5630
- });
5631
- }
5641
+ event = new CustomEvent(STORAGE_MUTATED_DOM_EVENT_NAME, {
5642
+ detail: updatedParts
5643
+ });
5632
5644
  propagatingLocally = true;
5633
5645
  dispatchEvent(event);
5634
5646
  propagatingLocally = false;
@@ -5673,23 +5685,31 @@ if (typeof BroadcastChannel !== 'undefined') {
5673
5685
 
5674
5686
  if (typeof addEventListener !== 'undefined') {
5675
5687
  addEventListener('pagehide', (event) => {
5676
- if (event.persisted) {
5688
+ if (!Dexie$1.disableBfCache && event.persisted) {
5689
+ if (debug)
5690
+ console.debug('Dexie: handling persisted pagehide');
5677
5691
  bc?.close();
5678
- }
5679
- for (const db of connections) {
5680
- db.close({ disableAutoOpen: false });
5692
+ for (const db of connections) {
5693
+ db.close({ disableAutoOpen: false });
5694
+ }
5681
5695
  }
5682
5696
  });
5683
5697
  addEventListener('pageshow', (event) => {
5684
- if (event.persisted) {
5698
+ if (!Dexie$1.disableBfCache && event.persisted) {
5699
+ if (debug)
5700
+ console.debug('Dexie: handling persisted pageshow');
5685
5701
  createBC();
5686
5702
  propagateLocally({ all: new RangeSet(-Infinity, [[]]) });
5687
5703
  }
5688
5704
  });
5689
5705
  }
5690
5706
 
5707
+ function replacePrefix(a, b) {
5708
+ return new PropModification({ replacePrefix: [a, b] });
5709
+ }
5710
+
5691
5711
  DexiePromise.rejectionMapper = mapError;
5692
5712
  setDebug(debug);
5693
5713
 
5694
- export { Dexie$1 as Dexie, Entity, RangeSet, cmp, Dexie$1 as default, liveQuery, mergeRanges, rangesOverlap };
5714
+ export { Dexie$1 as Dexie, Entity, PropModSymbol, PropModification, RangeSet, cmp, Dexie$1 as default, liveQuery, mergeRanges, rangesOverlap, replacePrefix };
5695
5715
  //# sourceMappingURL=dexie.mjs.map