dexie 4.0.1-alpha.15 → 4.0.1-alpha.17

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.d.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * By David Fahlander, david.fahlander@gmail.com
6
6
  *
7
- * Version 4.0.1-alpha.15, Thu Jun 01 2023
7
+ * Version 4.0.1-alpha.17, Thu Jun 01 2023
8
8
  *
9
9
  * https://dexie.org
10
10
  *
@@ -656,6 +656,8 @@ export interface DBCoreIndex {
656
656
  readonly multiEntry?: boolean;
657
657
  /** Extract (using keyPath) a key from given value (object). Null for outbound primary keys */
658
658
  readonly extractKey: ((value: any) => any) | null;
659
+ /** If this index is a virtual index, lowLevelIndex represents the actual IndexedDB index behind it */
660
+ readonly lowLevelIndex?: DBCoreIndex;
659
661
  }
660
662
  export interface DBCore {
661
663
  stack: "dbcore";
package/dist/dexie.js CHANGED
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * By David Fahlander, david.fahlander@gmail.com
6
6
  *
7
- * Version 4.0.1-alpha.15, Thu Jun 01 2023
7
+ * Version 4.0.1-alpha.17, Thu Jun 01 2023
8
8
  *
9
9
  * https://dexie.org
10
10
  *
@@ -232,10 +232,24 @@
232
232
  function flatten(a) {
233
233
  return concat.apply([], a);
234
234
  }
235
- var intrinsicTypeNames = "Boolean,String,Date,RegExp,Blob,File,FileList,FileSystemFileHandle,FileSystemDirectoryHandle,ArrayBuffer,DataView,Uint8ClampedArray,ImageBitmap,ImageData,Map,Set,CryptoKey"
235
+ var intrinsicTypeNames = "Array,Boolean,String,Date,RegExp,Blob,File,FileList,FileSystemFileHandle,FileSystemDirectoryHandle,ArrayBuffer,DataView,Uint8ClampedArray,ImageBitmap,ImageData,Map,Set,CryptoKey"
236
236
  .split(',').concat(flatten([8, 16, 32, 64].map(function (num) { return ["Int", "Uint", "Float"].map(function (t) { return t + num + "Array"; }); }))).filter(function (t) { return _global[t]; });
237
- var intrinsicTypes = intrinsicTypeNames.map(function (t) { return _global[t]; });
238
- arrayToObject(intrinsicTypeNames, function (x) { return [x, true]; });
237
+ var intrinsicTypes = new Set(intrinsicTypeNames.map(function (t) { return _global[t]; }));
238
+ function cloneSimpleObjectTree(o) {
239
+ var rv = {};
240
+ for (var k in o)
241
+ if (hasOwn(o, k)) {
242
+ var v = o[k];
243
+ rv[k] = !v || typeof v !== 'object' || intrinsicTypes.has(v.constructor) ? v : cloneSimpleObjectTree(v);
244
+ }
245
+ return rv;
246
+ }
247
+ function objectIsEmpty(o) {
248
+ for (var k in o)
249
+ if (hasOwn(o, k))
250
+ return false;
251
+ return true;
252
+ }
239
253
  var circularRefs = null;
240
254
  function deepClone(any) {
241
255
  circularRefs = new WeakMap();
@@ -256,7 +270,7 @@
256
270
  rv.push(innerDeepClone(x[i]));
257
271
  }
258
272
  }
259
- else if (intrinsicTypes.indexOf(x.constructor) >= 0) {
273
+ else if (intrinsicTypes.has(x.constructor)) {
260
274
  rv = x;
261
275
  }
262
276
  else {
@@ -1270,7 +1284,7 @@
1270
1284
  }
1271
1285
  }
1272
1286
 
1273
- var DEXIE_VERSION = '4.0.1-alpha.15';
1287
+ var DEXIE_VERSION = '4.0.1-alpha.17';
1274
1288
  var maxString = String.fromCharCode(65535);
1275
1289
  var minKey = -Infinity;
1276
1290
  var INVALID_KEY_ARGUMENT = "Invalid key provided. Keys must be of type string, number, Date or Array<string | number | Date>.";
@@ -3976,7 +3990,9 @@
3976
3990
  var indexList = (indexLookup[keyPathAlias] = indexLookup[keyPathAlias] || []);
3977
3991
  var keyLength = keyPath == null ? 0 : typeof keyPath === 'string' ? 1 : keyPath.length;
3978
3992
  var isVirtual = keyTail > 0;
3979
- var virtualIndex = __assign(__assign({}, lowLevelIndex), { isVirtual: isVirtual, keyTail: keyTail, keyLength: keyLength, extractKey: getKeyExtractor(keyPath), unique: !isVirtual && lowLevelIndex.unique });
3993
+ var virtualIndex = __assign(__assign({}, lowLevelIndex), { name: isVirtual
3994
+ ? "".concat(keyPathAlias, "(virtual-from:").concat(lowLevelIndex.name, ")")
3995
+ : lowLevelIndex.name, lowLevelIndex: lowLevelIndex, isVirtual: isVirtual, keyTail: keyTail, keyLength: keyLength, extractKey: getKeyExtractor(keyPath), unique: !isVirtual && lowLevelIndex.unique });
3980
3996
  indexList.push(virtualIndex);
3981
3997
  if (!virtualIndex.isPrimaryKey) {
3982
3998
  allVirtualIndexes.push(virtualIndex);
@@ -4014,7 +4030,7 @@
4014
4030
  function translateRequest(req) {
4015
4031
  var index = req.query.index;
4016
4032
  return index.isVirtual ? __assign(__assign({}, req), { query: {
4017
- index: index,
4033
+ index: index.lowLevelIndex,
4018
4034
  range: translateRange(req.query.range, index.keyTail)
4019
4035
  } }) : req;
4020
4036
  }
@@ -4480,15 +4496,17 @@
4480
4496
 
4481
4497
  function extendObservabilitySet(target, newSet) {
4482
4498
  keys(newSet).forEach(function (part) {
4483
- var rangeSet = target[part] || (target[part] = new RangeSet());
4484
- mergeRanges(rangeSet, newSet[part]);
4499
+ if (target[part])
4500
+ mergeRanges(target[part], newSet[part]);
4501
+ else
4502
+ target[part] = cloneSimpleObjectTree(newSet[part]);
4485
4503
  });
4486
4504
  return target;
4487
4505
  }
4488
4506
 
4489
4507
  var observabilityMiddleware = {
4490
4508
  stack: "dbcore",
4491
- level: 0,
4509
+ level: 10,
4492
4510
  name: "Observability",
4493
4511
  create: function (core) {
4494
4512
  var dbName = core.schema.name;
@@ -4697,10 +4715,11 @@
4697
4715
  function applyOptimisticOps(result, req, ops, table, cacheEntry, immutable) {
4698
4716
  if (!ops || ops.length === 0)
4699
4717
  return result;
4700
- var sortIndex = req.query.index;
4718
+ var index = req.query.index;
4701
4719
  var primaryKey = table.schema.primaryKey;
4702
4720
  var extractPrimKey = primaryKey.extractKey;
4703
- var extractIndex = sortIndex.extractKey;
4721
+ var extractIndex = index.extractKey;
4722
+ var extractLowLevelIndex = (index.lowLevelIndex || index).extractKey;
4704
4723
  var finalResult = ops.reduce(function (result, op) {
4705
4724
  var modifedResult = result;
4706
4725
  var includedValues = op.type === 'add' || op.type === 'put'
@@ -4739,13 +4758,7 @@
4739
4758
  break;
4740
4759
  case 'deleteRange':
4741
4760
  var range_1 = op.range;
4742
- var rangeSet_1 = new RangeSet(range_1.lower, range_1.upper);
4743
- modifedResult = result.filter(function (item) {
4744
- var key = primaryKey.extractKey(item);
4745
- return !((rangesOverlap(new RangeSet(key), rangeSet_1) &&
4746
- isWithinRange(key, range_1))
4747
- );
4748
- });
4761
+ modifedResult = result.filter(function (item) { return !isWithinRange(extractPrimKey(item), range_1); });
4749
4762
  break;
4750
4763
  }
4751
4764
  return modifedResult;
@@ -4753,10 +4766,10 @@
4753
4766
  if (finalResult === result)
4754
4767
  return result;
4755
4768
  finalResult.sort(function (a, b) {
4756
- return cmp(extractIndex(a), extractIndex(b)) ||
4769
+ return cmp(extractLowLevelIndex(a), extractLowLevelIndex(b)) ||
4757
4770
  cmp(extractPrimKey(a), extractPrimKey(b));
4758
4771
  });
4759
- if (req.limit) {
4772
+ if (req.limit && req.limit < Infinity) {
4760
4773
  if (finalResult.length > req.limit) {
4761
4774
  finalResult.length = req.limit;
4762
4775
  }
@@ -4767,45 +4780,7 @@
4767
4780
  return immutable ? Object.freeze(finalResult) : finalResult;
4768
4781
  }
4769
4782
 
4770
- function obsSetsOverlap(os1, os2) {
4771
- return Object.keys(os1).some(function (key) { return os2[key] && rangesOverlap(os2[key], os1[key]); });
4772
- }
4773
-
4774
4783
  var cache = {};
4775
- function invalidateCachedQueries(updateParts) {
4776
- var queriesToSignal = new Set();
4777
- for (var key in updateParts) {
4778
- var parts = /^idb\:\/\/(.*)\/(.*)\//.exec(key);
4779
- if (parts) {
4780
- var dbName = parts[1], tableName = parts[2];
4781
- var tblCache = cache["idb://".concat(dbName, "/").concat(tableName)];
4782
- if (tblCache)
4783
- invalidateTableQueries(tblCache, updateParts, queriesToSignal);
4784
- }
4785
- }
4786
- queriesToSignal.forEach(function (requery) { return requery(); });
4787
- }
4788
- function invalidateTableQueries(tblCache, mutatedParts, queriesToSignal) {
4789
- var updatedEntryLists = [];
4790
- for (var _i = 0, _a = Object.entries(tblCache.queries.query); _i < _a.length; _i++) {
4791
- var _b = _a[_i], indexName = _b[0], entries = _b[1];
4792
- var filteredEntries = [];
4793
- for (var _c = 0, entries_1 = entries; _c < entries_1.length; _c++) {
4794
- var entry = entries_1[_c];
4795
- if (entry.obsSet && obsSetsOverlap(mutatedParts, entry.obsSet)) {
4796
- entry.subscribers.forEach(function (requery) { return queriesToSignal.add(requery); });
4797
- }
4798
- else {
4799
- filteredEntries.push(entry);
4800
- }
4801
- }
4802
- updatedEntryLists.push([indexName, filteredEntries]);
4803
- }
4804
- for (var _d = 0, updatedEntryLists_1 = updatedEntryLists; _d < updatedEntryLists_1.length; _d++) {
4805
- var _e = updatedEntryLists_1[_d], indexName = _e[0], newEntries = _e[1];
4806
- tblCache.queries.query[indexName] = newEntries;
4807
- }
4808
- }
4809
4784
 
4810
4785
  function areRangesEqual(r1, r2) {
4811
4786
  return (cmp(r1.lower, r2.lower) === 0 &&
@@ -4891,28 +4866,61 @@
4891
4866
  }
4892
4867
  }
4893
4868
 
4894
- function signalSubscribers(tblCache, mutatedParts) {
4895
- extendObservabilitySet(tblCache.unsignaledParts, mutatedParts);
4896
- if (!tblCache.signalTimer) {
4897
- tblCache.signalTimer = setTimeout(function () {
4898
- tblCache.signalTimer = null;
4899
- signalSubscribersNow(tblCache);
4900
- }, 0);
4869
+ function obsSetsOverlap(os1, os2) {
4870
+ return Object.keys(os1).some(function (key) { return os2[key] && rangesOverlap(os2[key], os1[key]); });
4871
+ }
4872
+
4873
+ var unsignaledParts = {};
4874
+ var isTaskEnqueued = false;
4875
+ function signalSubscribersLazily(part) {
4876
+ extendObservabilitySet(unsignaledParts, part);
4877
+ if (!isTaskEnqueued) {
4878
+ isTaskEnqueued = true;
4879
+ queueMicrotask(function () {
4880
+ isTaskEnqueued = false;
4881
+ var parts = unsignaledParts;
4882
+ unsignaledParts = {};
4883
+ signalSubscribersNow(parts);
4884
+ });
4901
4885
  }
4902
4886
  }
4903
- function signalSubscribersNow(tblCache) {
4904
- var collectedSubscribers = new Set();
4905
- for (var _i = 0, _a = Object.values(tblCache.queries.query); _i < _a.length; _i++) {
4906
- var entries = _a[_i];
4907
- for (var _b = 0, entries_1 = entries; _b < entries_1.length; _b++) {
4908
- var entry = entries_1[_b];
4909
- if (entry.obsSet && obsSetsOverlap(entry.obsSet, tblCache.unsignaledParts)) {
4910
- entry.subscribers.forEach(function (requery) { return collectedSubscribers.add(requery); });
4887
+ function signalSubscribersNow(updatedParts, deleteAffectedCacheEntries) {
4888
+ if (deleteAffectedCacheEntries === void 0) { deleteAffectedCacheEntries = false; }
4889
+ var queriesToSignal = new Set();
4890
+ for (var key in updatedParts) {
4891
+ var parts = /^idb\:\/\/(.*)\/(.*)\//.exec(key);
4892
+ if (parts) {
4893
+ var dbName = parts[1], tableName = parts[2];
4894
+ var tblCache = cache["idb://".concat(dbName, "/").concat(tableName)];
4895
+ if (tblCache)
4896
+ signalTableSubscribersNow(tblCache, updatedParts, queriesToSignal, deleteAffectedCacheEntries);
4897
+ }
4898
+ }
4899
+ queriesToSignal.forEach(function (requery) { return requery(); });
4900
+ }
4901
+ function signalTableSubscribersNow(tblCache, updatedParts, outQueriesToSignal, deleteAffectedCacheEntries) {
4902
+ var updatedEntryLists = deleteAffectedCacheEntries && [];
4903
+ for (var _i = 0, _a = Object.entries(tblCache.queries.query); _i < _a.length; _i++) {
4904
+ var _b = _a[_i], indexName = _b[0], entries = _b[1];
4905
+ var filteredEntries = deleteAffectedCacheEntries && [];
4906
+ for (var _c = 0, entries_1 = entries; _c < entries_1.length; _c++) {
4907
+ var entry = entries_1[_c];
4908
+ if (entry.obsSet && obsSetsOverlap(updatedParts, entry.obsSet)) {
4909
+ entry.subscribers.forEach(function (requery) { return outQueriesToSignal.add(requery); });
4910
+ }
4911
+ else if (deleteAffectedCacheEntries) {
4912
+ filteredEntries.push(entry);
4911
4913
  }
4912
4914
  }
4915
+ if (deleteAffectedCacheEntries)
4916
+ updatedEntryLists.push([indexName, filteredEntries]);
4917
+ }
4918
+ if (deleteAffectedCacheEntries) {
4919
+ for (var _d = 0, updatedEntryLists_1 = updatedEntryLists; _d < updatedEntryLists_1.length; _d++) {
4920
+ var _e = updatedEntryLists_1[_d], indexName = _e[0], filteredEntries = _e[1];
4921
+ tblCache.queries.query[indexName] = filteredEntries;
4922
+ }
4913
4923
  }
4914
- tblCache.unsignaledParts = {};
4915
- collectedSubscribers.forEach(function (requery) { return requery(); });
4916
4924
  }
4917
4925
 
4918
4926
  function subscribeToCacheEntry(cacheEntry, container, requery, signal) {
@@ -4934,7 +4942,7 @@
4934
4942
 
4935
4943
  var cacheMiddleware = {
4936
4944
  stack: 'dbcore',
4937
- level: 0,
4945
+ level: 10,
4938
4946
  name: 'Cache',
4939
4947
  create: function (core) {
4940
4948
  var dbName = core.schema.name;
@@ -5018,7 +5026,7 @@
5018
5026
  if (!tblCache)
5019
5027
  return downTable.mutate(req);
5020
5028
  var promise = downTable.mutate(req);
5021
- if (primKey.autoIncrement && (req.type === 'add' || req.type === 'put') && (req.values.length < 50 || getEffectiveKeys(primKey, req).some(function (key) { return key == null; }))) {
5029
+ if (primKey.autoIncrement && (req.type === 'add' || req.type === 'put') && (req.values.length >= 50 || getEffectiveKeys(primKey, req).some(function (key) { return key == null; }))) {
5022
5030
  promise.then(function (res) {
5023
5031
  var reqWithResolvedKeys = __assign(__assign({}, req), { values: req.values.map(function (value, i) {
5024
5032
  var valueWithKey = primKey.keyPath.includes('.')
@@ -5028,15 +5036,15 @@
5028
5036
  return valueWithKey;
5029
5037
  }) });
5030
5038
  tblCache.optimisticOps.push(reqWithResolvedKeys);
5031
- queueMicrotask(function () { return signalSubscribers(tblCache, req.mutatedParts); });
5039
+ queueMicrotask(function () { return signalSubscribersLazily(req.mutatedParts); });
5032
5040
  });
5033
5041
  }
5034
5042
  else {
5035
5043
  tblCache.optimisticOps.push(req);
5036
- signalSubscribers(tblCache, req.mutatedParts);
5044
+ signalSubscribersLazily(req.mutatedParts);
5037
5045
  promise.catch(function () {
5038
5046
  delArrayItem(tblCache.optimisticOps, req);
5039
- signalSubscribers(tblCache, req.mutatedParts);
5047
+ signalSubscribersLazily(req.mutatedParts);
5040
5048
  });
5041
5049
  }
5042
5050
  return promise;
@@ -5208,11 +5216,11 @@
5208
5216
  .filter(function (c) { return c.name === _this.name && c !== _this && !c._state.vcFired; })
5209
5217
  .map(function (c) { return c.on("versionchange").fire(ev); });
5210
5218
  };
5219
+ this.use(cacheExistingValuesMiddleware);
5211
5220
  this.use(virtualIndexMiddleware);
5212
5221
  this.use(hooksMiddleware);
5213
5222
  this.use(cacheMiddleware);
5214
5223
  this.use(observabilityMiddleware);
5215
- this.use(cacheExistingValuesMiddleware);
5216
5224
  this.vip = Object.create(this, { _vip: { value: true } });
5217
5225
  addons.forEach(function (addon) { return addon(_this); });
5218
5226
  }
@@ -5451,7 +5459,7 @@
5451
5459
 
5452
5460
  function liveQuery(querier) {
5453
5461
  var hasValue = false;
5454
- var currentValue = undefined;
5462
+ var currentValue;
5455
5463
  var observable = new Observable(function (observer) {
5456
5464
  var scopeFuncIsAsync = isAsyncFunction(querier);
5457
5465
  function execute(ctx) {
@@ -5460,7 +5468,7 @@
5460
5468
  }
5461
5469
  var rv = newScope(querier, ctx);
5462
5470
  if (scopeFuncIsAsync) {
5463
- rv.then(decrementExpectedAwaits, decrementExpectedAwaits);
5471
+ rv.finally(decrementExpectedAwaits);
5464
5472
  }
5465
5473
  return rv;
5466
5474
  }
@@ -5538,7 +5546,7 @@
5538
5546
  }
5539
5547
  accumMuts = {};
5540
5548
  currentObs = subscr;
5541
- if (keys(currentObs).length > 0 && !startedListening) {
5549
+ if (!objectIsEmpty(currentObs) && !startedListening) {
5542
5550
  globalEvents(DEXIE_STORAGE_MUTATED_EVENT_NAME, mutationListener);
5543
5551
  startedListening = true;
5544
5552
  }
@@ -5673,7 +5681,7 @@
5673
5681
  try {
5674
5682
  propagatingLocally = true;
5675
5683
  globalEvents.storagemutated.fire(updateParts);
5676
- invalidateCachedQueries(updateParts);
5684
+ signalSubscribersNow(updateParts, true);
5677
5685
  }
5678
5686
  finally {
5679
5687
  propagatingLocally = wasMe;