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/README.md +32 -4
- package/dist/dexie.d.ts +4 -2
- package/dist/dexie.js +129 -38
- package/dist/dexie.js.map +1 -1
- package/dist/dexie.min.js +1 -1
- package/dist/dexie.min.js.map +1 -1
- package/dist/dexie.mjs +129 -39
- package/dist/dexie.mjs.map +1 -1
- package/dist/modern/dexie.min.mjs +1 -1
- package/dist/modern/dexie.min.mjs.map +1 -1
- package/dist/modern/dexie.mjs +125 -38
- package/dist/modern/dexie.mjs.map +1 -1
- package/package.json +1 -1
package/dist/modern/dexie.mjs
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* By David Fahlander, david.fahlander@gmail.com
|
|
6
6
|
*
|
|
7
|
-
* Version 4.
|
|
7
|
+
* Version 4.4.1, Wed Mar 25 2026
|
|
8
8
|
*
|
|
9
9
|
* https://dexie.org
|
|
10
10
|
*
|
|
@@ -185,12 +185,6 @@ function cloneSimpleObjectTree(o) {
|
|
|
185
185
|
}
|
|
186
186
|
return rv;
|
|
187
187
|
}
|
|
188
|
-
function objectIsEmpty(o) {
|
|
189
|
-
for (const k in o)
|
|
190
|
-
if (hasOwn(o, k))
|
|
191
|
-
return false;
|
|
192
|
-
return true;
|
|
193
|
-
}
|
|
194
188
|
let circularRefs = null;
|
|
195
189
|
function deepClone(any) {
|
|
196
190
|
circularRefs = new WeakMap();
|
|
@@ -1096,12 +1090,12 @@ function tempTransaction(db, mode, storeNames, fn) {
|
|
|
1096
1090
|
}
|
|
1097
1091
|
}
|
|
1098
1092
|
|
|
1099
|
-
const DEXIE_VERSION = '4.
|
|
1093
|
+
const DEXIE_VERSION = '4.4.1';
|
|
1100
1094
|
const maxString = String.fromCharCode(65535);
|
|
1101
1095
|
const minKey = -Infinity;
|
|
1102
1096
|
const INVALID_KEY_ARGUMENT = "Invalid key provided. Keys must be of type string, number, Date or Array<string | number | Date>.";
|
|
1103
1097
|
const STRING_EXPECTED = "String expected.";
|
|
1104
|
-
const
|
|
1098
|
+
const DEFAULT_MAX_CONNECTIONS = 1000;
|
|
1105
1099
|
const DBNAMES_DB = '__dbnames';
|
|
1106
1100
|
const READONLY = 'readonly';
|
|
1107
1101
|
const READWRITE = 'readwrite';
|
|
@@ -1893,13 +1887,14 @@ class Collection {
|
|
|
1893
1887
|
toArray(cb) {
|
|
1894
1888
|
return this._read(trans => {
|
|
1895
1889
|
var ctx = this._ctx;
|
|
1896
|
-
if (
|
|
1890
|
+
if (isPlainKeyRange(ctx, true) && ctx.limit > 0) {
|
|
1897
1891
|
const { valueMapper } = ctx;
|
|
1898
1892
|
const index = getIndexOrStore(ctx, ctx.table.core.schema);
|
|
1899
1893
|
return ctx.table.core.query({
|
|
1900
1894
|
trans,
|
|
1901
1895
|
limit: ctx.limit,
|
|
1902
1896
|
values: true,
|
|
1897
|
+
direction: ctx.dir === 'prev' ? 'prev' : undefined,
|
|
1903
1898
|
query: {
|
|
1904
1899
|
index,
|
|
1905
1900
|
range: ctx.range
|
|
@@ -2021,13 +2016,14 @@ class Collection {
|
|
|
2021
2016
|
}
|
|
2022
2017
|
primaryKeys(cb) {
|
|
2023
2018
|
var ctx = this._ctx;
|
|
2024
|
-
if (
|
|
2019
|
+
if (isPlainKeyRange(ctx, true) && ctx.limit > 0) {
|
|
2025
2020
|
return this._read(trans => {
|
|
2026
2021
|
var index = getIndexOrStore(ctx, ctx.table.core.schema);
|
|
2027
2022
|
return ctx.table.core.query({
|
|
2028
2023
|
trans,
|
|
2029
2024
|
values: false,
|
|
2030
2025
|
limit: ctx.limit,
|
|
2026
|
+
direction: ctx.dir === 'prev' ? 'prev' : undefined,
|
|
2031
2027
|
query: {
|
|
2032
2028
|
index,
|
|
2033
2029
|
range: ctx.range
|
|
@@ -2892,6 +2888,9 @@ function getKeyPathAlias(keyPath) {
|
|
|
2892
2888
|
function createDBCore(db, IdbKeyRange, tmpTrans) {
|
|
2893
2889
|
function extractSchema(db, trans) {
|
|
2894
2890
|
const tables = arrayify(db.objectStoreNames);
|
|
2891
|
+
const tempStore = tables.length > 0
|
|
2892
|
+
? trans.objectStore(tables[0])
|
|
2893
|
+
: {};
|
|
2895
2894
|
return {
|
|
2896
2895
|
schema: {
|
|
2897
2896
|
name: db.name,
|
|
@@ -2936,10 +2935,11 @@ function createDBCore(db, IdbKeyRange, tmpTrans) {
|
|
|
2936
2935
|
return result;
|
|
2937
2936
|
})
|
|
2938
2937
|
},
|
|
2939
|
-
hasGetAll: tables.length > 0 && ('getAll' in
|
|
2938
|
+
hasGetAll: tables.length > 0 && ('getAll' in tempStore) &&
|
|
2940
2939
|
!(typeof navigator !== 'undefined' && /Safari/.test(navigator.userAgent) &&
|
|
2941
2940
|
!/(Chrome\/|Edge\/)/.test(navigator.userAgent) &&
|
|
2942
|
-
[].concat(navigator.userAgent.match(/Safari\/(\d*)/))[1] < 604)
|
|
2941
|
+
[].concat(navigator.userAgent.match(/Safari\/(\d*)/))[1] < 604),
|
|
2942
|
+
hasIdb3Features: 'getAllRecords' in tempStore
|
|
2943
2943
|
};
|
|
2944
2944
|
}
|
|
2945
2945
|
function makeIDBKeyRange(range) {
|
|
@@ -3107,11 +3107,12 @@ function createDBCore(db, IdbKeyRange, tmpTrans) {
|
|
|
3107
3107
|
}, reject);
|
|
3108
3108
|
});
|
|
3109
3109
|
}
|
|
3110
|
-
function query(hasGetAll) {
|
|
3110
|
+
function query(hasGetAll, hasIdb3Features) {
|
|
3111
3111
|
return (request) => {
|
|
3112
3112
|
return new Promise((resolve, reject) => {
|
|
3113
3113
|
resolve = wrap(resolve);
|
|
3114
3114
|
const { trans, values, limit, query } = request;
|
|
3115
|
+
const direction = request.direction ?? 'next';
|
|
3115
3116
|
const nonInfinitLimit = limit === Infinity ? undefined : limit;
|
|
3116
3117
|
const { index, range } = query;
|
|
3117
3118
|
const store = trans.objectStore(tableName);
|
|
@@ -3119,20 +3120,32 @@ function createDBCore(db, IdbKeyRange, tmpTrans) {
|
|
|
3119
3120
|
const idbKeyRange = makeIDBKeyRange(range);
|
|
3120
3121
|
if (limit === 0)
|
|
3121
3122
|
return resolve({ result: [] });
|
|
3122
|
-
if (
|
|
3123
|
+
if (hasIdb3Features) {
|
|
3124
|
+
const options = {
|
|
3125
|
+
query: idbKeyRange,
|
|
3126
|
+
count: nonInfinitLimit,
|
|
3127
|
+
direction
|
|
3128
|
+
};
|
|
3129
|
+
const req = values ?
|
|
3130
|
+
source.getAll(options) :
|
|
3131
|
+
source.getAllKeys(options);
|
|
3132
|
+
req.onsuccess = event => resolve({ result: event.target.result });
|
|
3133
|
+
req.onerror = eventRejectHandler(reject);
|
|
3134
|
+
}
|
|
3135
|
+
else if (hasGetAll && direction === 'next') {
|
|
3123
3136
|
const req = values ?
|
|
3124
3137
|
source.getAll(idbKeyRange, nonInfinitLimit) :
|
|
3125
3138
|
source.getAllKeys(idbKeyRange, nonInfinitLimit);
|
|
3126
|
-
req.onsuccess = event => resolve({ result: event.target.result });
|
|
3139
|
+
req.onsuccess = (event) => resolve({ result: event.target.result });
|
|
3127
3140
|
req.onerror = eventRejectHandler(reject);
|
|
3128
3141
|
}
|
|
3129
3142
|
else {
|
|
3130
3143
|
let count = 0;
|
|
3131
3144
|
const req = values || !('openKeyCursor' in source) ?
|
|
3132
|
-
source.openCursor(idbKeyRange) :
|
|
3133
|
-
source.openKeyCursor(idbKeyRange);
|
|
3145
|
+
source.openCursor(idbKeyRange, direction) :
|
|
3146
|
+
source.openKeyCursor(idbKeyRange, direction);
|
|
3134
3147
|
const result = [];
|
|
3135
|
-
req.onsuccess =
|
|
3148
|
+
req.onsuccess = () => {
|
|
3136
3149
|
const cursor = req.result;
|
|
3137
3150
|
if (!cursor)
|
|
3138
3151
|
return resolve({ result });
|
|
@@ -3190,7 +3203,7 @@ function createDBCore(db, IdbKeyRange, tmpTrans) {
|
|
|
3190
3203
|
req.onerror = eventRejectHandler(reject);
|
|
3191
3204
|
});
|
|
3192
3205
|
},
|
|
3193
|
-
query: query(hasGetAll),
|
|
3206
|
+
query: query(hasGetAll, hasIdb3Features),
|
|
3194
3207
|
openCursor,
|
|
3195
3208
|
count({ query, trans }) {
|
|
3196
3209
|
const { index, range } = query;
|
|
@@ -3205,7 +3218,7 @@ function createDBCore(db, IdbKeyRange, tmpTrans) {
|
|
|
3205
3218
|
}
|
|
3206
3219
|
};
|
|
3207
3220
|
}
|
|
3208
|
-
const { schema, hasGetAll } = extractSchema(db, tmpTrans);
|
|
3221
|
+
const { schema, hasGetAll, hasIdb3Features } = extractSchema(db, tmpTrans);
|
|
3209
3222
|
const tables = schema.tables.map(tableSchema => createDbCoreTable(tableSchema));
|
|
3210
3223
|
const tableMap = {};
|
|
3211
3224
|
tables.forEach(table => tableMap[table.name] = table);
|
|
@@ -3640,6 +3653,63 @@ function createVersionConstructor(db) {
|
|
|
3640
3653
|
});
|
|
3641
3654
|
}
|
|
3642
3655
|
|
|
3656
|
+
const connections = createConnectionsManager();
|
|
3657
|
+
function createConnectionsManager() {
|
|
3658
|
+
if (typeof FinalizationRegistry !== 'undefined' && typeof WeakRef !== 'undefined') {
|
|
3659
|
+
const _refs = new Set();
|
|
3660
|
+
const _registry = new FinalizationRegistry((ref) => {
|
|
3661
|
+
_refs.delete(ref);
|
|
3662
|
+
});
|
|
3663
|
+
const toArray = () => {
|
|
3664
|
+
return Array.from(_refs)
|
|
3665
|
+
.map(ref => ref.deref())
|
|
3666
|
+
.filter((db) => db !== undefined);
|
|
3667
|
+
};
|
|
3668
|
+
const add = (db) => {
|
|
3669
|
+
const ref = new WeakRef(db._novip);
|
|
3670
|
+
_refs.add(ref);
|
|
3671
|
+
_registry.register(db._novip, ref, ref);
|
|
3672
|
+
if (_refs.size > db._options.maxConnections) {
|
|
3673
|
+
const oldestRef = _refs.values().next().value;
|
|
3674
|
+
_refs.delete(oldestRef);
|
|
3675
|
+
_registry.unregister(oldestRef);
|
|
3676
|
+
}
|
|
3677
|
+
};
|
|
3678
|
+
const remove = (db) => {
|
|
3679
|
+
if (!db)
|
|
3680
|
+
return;
|
|
3681
|
+
const iterator = _refs.values();
|
|
3682
|
+
let result = iterator.next();
|
|
3683
|
+
while (!result.done) {
|
|
3684
|
+
const ref = result.value;
|
|
3685
|
+
if (ref.deref() === db._novip) {
|
|
3686
|
+
_refs.delete(ref);
|
|
3687
|
+
_registry.unregister(ref);
|
|
3688
|
+
return;
|
|
3689
|
+
}
|
|
3690
|
+
result = iterator.next();
|
|
3691
|
+
}
|
|
3692
|
+
};
|
|
3693
|
+
return { toArray, add, remove };
|
|
3694
|
+
}
|
|
3695
|
+
else {
|
|
3696
|
+
const connections = [];
|
|
3697
|
+
const toArray = () => connections;
|
|
3698
|
+
const add = (db) => {
|
|
3699
|
+
connections.push(db._novip);
|
|
3700
|
+
};
|
|
3701
|
+
const remove = (db) => {
|
|
3702
|
+
if (!db)
|
|
3703
|
+
return;
|
|
3704
|
+
const index = connections.indexOf(db._novip);
|
|
3705
|
+
if (index !== -1) {
|
|
3706
|
+
connections.splice(index, 1);
|
|
3707
|
+
}
|
|
3708
|
+
};
|
|
3709
|
+
return { toArray, add, remove };
|
|
3710
|
+
}
|
|
3711
|
+
}
|
|
3712
|
+
|
|
3643
3713
|
function getDbNamesTable(indexedDB, IDBKeyRange) {
|
|
3644
3714
|
let dbNamesDB = indexedDB["_dbNamesDB"];
|
|
3645
3715
|
if (!dbNamesDB) {
|
|
@@ -4002,7 +4072,7 @@ function dexieOpen(db) {
|
|
|
4002
4072
|
}
|
|
4003
4073
|
catch (e) {
|
|
4004
4074
|
}
|
|
4005
|
-
connections.
|
|
4075
|
+
connections.add(db);
|
|
4006
4076
|
idbdb.onversionchange = wrap(ev => {
|
|
4007
4077
|
state.vcFired = true;
|
|
4008
4078
|
db.on("versionchange").fire(ev);
|
|
@@ -4884,8 +4954,11 @@ function applyOptimisticOps(result, req, ops, table, cacheEntry, immutable) {
|
|
|
4884
4954
|
}, result);
|
|
4885
4955
|
if (finalResult === result)
|
|
4886
4956
|
return result;
|
|
4887
|
-
|
|
4888
|
-
cmp(extractPrimKey(a), extractPrimKey(b))
|
|
4957
|
+
const sorter = (a, b) => cmp(extractLowLevelIndex(a), extractLowLevelIndex(b)) ||
|
|
4958
|
+
cmp(extractPrimKey(a), extractPrimKey(b));
|
|
4959
|
+
finalResult.sort(req.direction === 'prev' || req.direction === 'prevunique'
|
|
4960
|
+
? (a, b) => sorter(b, a)
|
|
4961
|
+
: sorter);
|
|
4889
4962
|
if (req.limit && req.limit < Infinity) {
|
|
4890
4963
|
if (finalResult.length > req.limit) {
|
|
4891
4964
|
finalResult.length = req.limit;
|
|
@@ -4954,8 +5027,10 @@ function findCompatibleQuery(dbName, tableName, type, req) {
|
|
|
4954
5027
|
return [null, false, tblCache, null];
|
|
4955
5028
|
switch (type) {
|
|
4956
5029
|
case 'query':
|
|
5030
|
+
const reqDirection = req.direction ?? 'next';
|
|
4957
5031
|
const equalEntry = entries.find((entry) => entry.req.limit === req.limit &&
|
|
4958
5032
|
entry.req.values === req.values &&
|
|
5033
|
+
(entry.req.direction ?? 'next') === reqDirection &&
|
|
4959
5034
|
areRangesEqual(entry.req.query.range, req.query.range));
|
|
4960
5035
|
if (equalEntry)
|
|
4961
5036
|
return [
|
|
@@ -4967,6 +5042,7 @@ function findCompatibleQuery(dbName, tableName, type, req) {
|
|
|
4967
5042
|
const superEntry = entries.find((entry) => {
|
|
4968
5043
|
const limit = 'limit' in entry.req ? entry.req.limit : Infinity;
|
|
4969
5044
|
return (limit >= req.limit &&
|
|
5045
|
+
(entry.req.direction ?? 'next') === reqDirection &&
|
|
4970
5046
|
(req.values ? entry.req.values : true) &&
|
|
4971
5047
|
isSuperRange(entry.req.query.range, req.query.range));
|
|
4972
5048
|
});
|
|
@@ -5223,6 +5299,7 @@ let Dexie$1 = class Dexie {
|
|
|
5223
5299
|
indexedDB: deps.indexedDB,
|
|
5224
5300
|
IDBKeyRange: deps.IDBKeyRange,
|
|
5225
5301
|
cache: 'cloned',
|
|
5302
|
+
maxConnections: DEFAULT_MAX_CONNECTIONS,
|
|
5226
5303
|
...options
|
|
5227
5304
|
};
|
|
5228
5305
|
this._deps = {
|
|
@@ -5314,7 +5391,7 @@ let Dexie$1 = class Dexie {
|
|
|
5314
5391
|
this._createTransaction = (mode, storeNames, dbschema, parentTransaction) => new this.Transaction(mode, storeNames, dbschema, this._options.chromeTransactionDurability, parentTransaction);
|
|
5315
5392
|
this._fireOnBlocked = ev => {
|
|
5316
5393
|
this.on("blocked").fire(ev);
|
|
5317
|
-
connections
|
|
5394
|
+
connections.toArray()
|
|
5318
5395
|
.filter(c => c.name === this.name && c !== this && !c._state.vcFired)
|
|
5319
5396
|
.map(c => c.on("versionchange").fire(ev));
|
|
5320
5397
|
};
|
|
@@ -5401,9 +5478,7 @@ let Dexie$1 = class Dexie {
|
|
|
5401
5478
|
_close() {
|
|
5402
5479
|
this.on.close.fire(new CustomEvent('close'));
|
|
5403
5480
|
const state = this._state;
|
|
5404
|
-
|
|
5405
|
-
if (idx >= 0)
|
|
5406
|
-
connections.splice(idx, 1);
|
|
5481
|
+
connections.remove(this);
|
|
5407
5482
|
if (this.idbdb) {
|
|
5408
5483
|
try {
|
|
5409
5484
|
this.idbdb.close();
|
|
@@ -5643,22 +5718,32 @@ function liveQuery(querier) {
|
|
|
5643
5718
|
signal: abortController.signal,
|
|
5644
5719
|
requery: doQuery,
|
|
5645
5720
|
querier,
|
|
5646
|
-
trans: null
|
|
5721
|
+
trans: null,
|
|
5647
5722
|
};
|
|
5648
5723
|
const ret = execute(ctx);
|
|
5724
|
+
if (!startedListening) {
|
|
5725
|
+
globalEvents(DEXIE_STORAGE_MUTATED_EVENT_NAME, mutationListener);
|
|
5726
|
+
startedListening = true;
|
|
5727
|
+
}
|
|
5649
5728
|
Promise.resolve(ret).then((result) => {
|
|
5650
5729
|
hasValue = true;
|
|
5651
5730
|
currentValue = result;
|
|
5652
5731
|
if (closed || ctx.signal.aborted) {
|
|
5653
5732
|
return;
|
|
5654
5733
|
}
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
|
|
5734
|
+
if (shouldNotify()) {
|
|
5735
|
+
doQuery();
|
|
5736
|
+
}
|
|
5737
|
+
else {
|
|
5738
|
+
currentObs = subscr;
|
|
5739
|
+
if (shouldNotify()) {
|
|
5740
|
+
doQuery();
|
|
5741
|
+
}
|
|
5742
|
+
else {
|
|
5743
|
+
accumMuts = {};
|
|
5744
|
+
execInGlobalContext(() => !closed && observer.next && observer.next(result));
|
|
5745
|
+
}
|
|
5660
5746
|
}
|
|
5661
|
-
execInGlobalContext(() => !closed && observer.next && observer.next(result));
|
|
5662
5747
|
}, (err) => {
|
|
5663
5748
|
hasValue = false;
|
|
5664
5749
|
if (!['DatabaseClosedError', 'AbortError'].includes(err?.name)) {
|
|
@@ -5773,7 +5858,9 @@ props(Dexie, {
|
|
|
5773
5858
|
asap: asap$1,
|
|
5774
5859
|
minKey: minKey,
|
|
5775
5860
|
addons: [],
|
|
5776
|
-
connections:
|
|
5861
|
+
connections: {
|
|
5862
|
+
get: connections.toArray
|
|
5863
|
+
},
|
|
5777
5864
|
errnames: errnames,
|
|
5778
5865
|
dependencies: domDeps,
|
|
5779
5866
|
cache,
|
|
@@ -5839,7 +5926,7 @@ if (typeof addEventListener !== 'undefined') {
|
|
|
5839
5926
|
if (debug)
|
|
5840
5927
|
console.debug('Dexie: handling persisted pagehide');
|
|
5841
5928
|
bc?.close();
|
|
5842
|
-
for (const db of connections) {
|
|
5929
|
+
for (const db of connections.toArray()) {
|
|
5843
5930
|
db.close({ disableAutoOpen: false });
|
|
5844
5931
|
}
|
|
5845
5932
|
}
|
|
@@ -5869,5 +5956,5 @@ function replacePrefix(a, b) {
|
|
|
5869
5956
|
DexiePromise.rejectionMapper = mapError;
|
|
5870
5957
|
setDebug(debug);
|
|
5871
5958
|
|
|
5872
|
-
export { Dexie$1 as Dexie, Entity, PropModification, RangeSet, add, cmp, Dexie$1 as default, liveQuery, mergeRanges, rangesOverlap, remove, replacePrefix };
|
|
5959
|
+
export { DEFAULT_MAX_CONNECTIONS, Dexie$1 as Dexie, Entity, PropModification, RangeSet, add, cmp, Dexie$1 as default, liveQuery, mergeRanges, rangesOverlap, remove, replacePrefix };
|
|
5873
5960
|
//# sourceMappingURL=dexie.mjs.map
|