indexeddbshim 16.1.0 → 17.1.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/README.md +65 -3
- package/badges/licenses-badge-dev.svg +1 -1
- package/badges/licenses-badge.svg +1 -1
- package/dist/CFG.d.ts +1 -0
- package/dist/CFG.d.ts.map +1 -1
- package/dist/DOMException.d.ts.map +1 -1
- package/dist/DOMStringList.d.ts.map +1 -1
- package/dist/IDBCursor.d.ts +12 -3
- package/dist/IDBCursor.d.ts.map +1 -1
- package/dist/IDBDatabase.d.ts +2 -1
- package/dist/IDBDatabase.d.ts.map +1 -1
- package/dist/IDBFactory.d.ts +2 -1
- package/dist/IDBFactory.d.ts.map +1 -1
- package/dist/IDBIndex.d.ts +2 -1
- package/dist/IDBIndex.d.ts.map +1 -1
- package/dist/IDBKeyRange.d.ts +1 -1
- package/dist/IDBKeyRange.d.ts.map +1 -1
- package/dist/IDBObjectStore.d.ts +2 -1
- package/dist/IDBObjectStore.d.ts.map +1 -1
- package/dist/IDBRequest.d.ts +5 -3
- package/dist/IDBRequest.d.ts.map +1 -1
- package/dist/IDBTransaction.d.ts +23 -1
- package/dist/IDBTransaction.d.ts.map +1 -1
- package/dist/Key.d.ts.map +1 -1
- package/dist/Sca.d.ts.map +1 -1
- package/dist/UnicodeIdentifiers.d.ts.map +1 -1
- package/dist/browser-noninvasive.d.ts.map +1 -1
- package/dist/indexeddbshim-Key.js +1863 -1669
- package/dist/indexeddbshim-Key.js.map +1 -1
- package/dist/indexeddbshim-Key.min.js +2 -2
- package/dist/indexeddbshim-Key.min.js.map +1 -1
- package/dist/indexeddbshim-UnicodeIdentifiers-node.cjs +2373 -1893
- package/dist/indexeddbshim-UnicodeIdentifiers-node.cjs.map +1 -1
- package/dist/indexeddbshim-UnicodeIdentifiers.js +3124 -2285
- package/dist/indexeddbshim-UnicodeIdentifiers.js.map +1 -1
- package/dist/indexeddbshim-UnicodeIdentifiers.min.js +9 -2
- package/dist/indexeddbshim-UnicodeIdentifiers.min.js.map +1 -1
- package/dist/indexeddbshim-node.cjs +2373 -1893
- package/dist/indexeddbshim-node.cjs.map +1 -1
- package/dist/indexeddbshim-noninvasive.js +3123 -2284
- package/dist/indexeddbshim-noninvasive.js.map +1 -1
- package/dist/indexeddbshim-noninvasive.min.js +9 -2
- package/dist/indexeddbshim-noninvasive.min.js.map +1 -1
- package/dist/indexeddbshim.js +3120 -2282
- package/dist/indexeddbshim.js.map +1 -1
- package/dist/indexeddbshim.min.js +9 -2
- package/dist/indexeddbshim.min.js.map +1 -1
- package/dist/node-UnicodeIdentifiers.d.ts +2 -2
- package/dist/node-UnicodeIdentifiers.d.ts.map +1 -1
- package/dist/node.d.ts +2 -2
- package/dist/node.d.ts.map +1 -1
- package/dist/nodeSQLiteDatabase.d.ts +65 -0
- package/dist/nodeSQLiteDatabase.d.ts.map +1 -0
- package/dist/nodeWebSQL.d.ts.map +1 -1
- package/dist/util.d.ts +5 -0
- package/dist/util.d.ts.map +1 -1
- package/package.json +118 -106
- package/src/CFG.js +5 -3
- package/src/DOMException.js +11 -9
- package/src/DOMStringList.js +8 -3
- package/src/Event.js +2 -0
- package/src/IDBCursor.js +152 -95
- package/src/IDBDatabase.js +9 -6
- package/src/IDBFactory.js +31 -20
- package/src/IDBIndex.js +83 -79
- package/src/IDBKeyRange.js +42 -35
- package/src/IDBObjectStore.js +83 -77
- package/src/IDBRequest.js +28 -15
- package/src/IDBTransaction.js +40 -6
- package/src/IDBVersionChangeEvent.js +2 -0
- package/src/Key.js +28 -14
- package/src/Sca.js +2 -1
- package/src/UnicodeIdentifiers.js +2 -2
- package/src/browser-UnicodeIdentifiers.js +0 -1
- package/src/browser-noninvasive.js +0 -1
- package/src/browser.js +0 -1
- package/src/node-UnicodeIdentifiers.js +6 -2
- package/src/node.js +6 -2
- package/src/nodeSQLiteDatabase.js +174 -0
- package/src/nodeWebSQL.js +1 -3
- package/src/setGlobalVars.js +13 -13
- package/src/util.js +75 -15
package/src/IDBCursor.js
CHANGED
|
@@ -46,6 +46,9 @@ import CFG from './CFG.js';
|
|
|
46
46
|
* __unique: boolean,
|
|
47
47
|
* __sqlDirection: "DESC"|"ASC",
|
|
48
48
|
* __matchedKeys: {[key: string]: true},
|
|
49
|
+
* __continuationKey: import('./Key.js').Key|undefined,
|
|
50
|
+
* __continuationPrimaryKey: import('./Key.js').Key|undefined,
|
|
51
|
+
* __multiEntryExhausted: boolean,
|
|
49
52
|
* __invalidateCache: () => void
|
|
50
53
|
* }} IDBCursorFull
|
|
51
54
|
*/
|
|
@@ -58,6 +61,7 @@ import CFG from './CFG.js';
|
|
|
58
61
|
|
|
59
62
|
/**
|
|
60
63
|
* @class
|
|
64
|
+
* @throws {TypeError}
|
|
61
65
|
*/
|
|
62
66
|
function IDBCursor () {
|
|
63
67
|
throw new TypeError('Illegal constructor');
|
|
@@ -67,7 +71,7 @@ const IDBCursorAlias = IDBCursor;
|
|
|
67
71
|
/* eslint-disable func-name-matching -- API */
|
|
68
72
|
/**
|
|
69
73
|
* The IndexedDB Cursor Object.
|
|
70
|
-
* @see
|
|
74
|
+
* @see https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBCursor
|
|
71
75
|
* @param {IDBKeyRange} query
|
|
72
76
|
* @param {string} direction
|
|
73
77
|
* @param {import('./IDBObjectStore.js').IDBObjectStoreFull} store
|
|
@@ -116,6 +120,9 @@ IDBCursor.__super = function IDBCursor (query, direction, store, source, keyColu
|
|
|
116
120
|
this.__valueDecoder = this.__keyOnly ? Key : Sca;
|
|
117
121
|
this.__count = count;
|
|
118
122
|
this.__prefetchedIndex = -1;
|
|
123
|
+
this.__continuationKey = undefined;
|
|
124
|
+
this.__continuationPrimaryKey = undefined;
|
|
125
|
+
this.__multiEntryExhausted = false;
|
|
119
126
|
this.__multiEntryIndex = this.__indexSource
|
|
120
127
|
? 'multiEntry' in source && source.multiEntry
|
|
121
128
|
: false;
|
|
@@ -151,11 +158,10 @@ IDBCursor.__createInstance = function (...args) {
|
|
|
151
158
|
* @returns {void}
|
|
152
159
|
*/
|
|
153
160
|
IDBCursor.prototype.__find = function (...args /* key, tx, success, error, recordsToLoad */) {
|
|
161
|
+
const [key, primaryKey, tx, success, error, recordsToLoad] = args;
|
|
154
162
|
if (this.__multiEntryIndex) {
|
|
155
|
-
const [key, primaryKey, tx, success, error, recordsToLoad] = args;
|
|
156
163
|
this.__findMultiEntry(key, primaryKey, tx, success, error, recordsToLoad);
|
|
157
164
|
} else {
|
|
158
|
-
const [key, primaryKey, tx, success, error, recordsToLoad] = args;
|
|
159
165
|
this.__findBasic(key, primaryKey, tx, success, error, recordsToLoad);
|
|
160
166
|
}
|
|
161
167
|
};
|
|
@@ -185,7 +191,7 @@ IDBCursor.prototype.__find = function (...args /* key, tx, success, error, recor
|
|
|
185
191
|
*/
|
|
186
192
|
IDBCursor.prototype.__findBasic = function (key, primaryKey, tx, success, error, recordsToLoad) {
|
|
187
193
|
const continueCall = recordsToLoad !== undefined;
|
|
188
|
-
recordsToLoad
|
|
194
|
+
recordsToLoad ||= 1;
|
|
189
195
|
|
|
190
196
|
const me = this;
|
|
191
197
|
const quotedKeyColumnName = util.sqlQuote(me.__keyColumnName);
|
|
@@ -270,77 +276,107 @@ const leftBracketRegex = /\[/gu;
|
|
|
270
276
|
* @param {SQLTransaction} tx
|
|
271
277
|
* @param {KeySuccess} success
|
|
272
278
|
* @param {FindError} error
|
|
273
|
-
* @param {Integer
|
|
279
|
+
* @param {Integer} [recordsToLoad]
|
|
274
280
|
* @this {IDBCursorFull}
|
|
275
281
|
* @returns {void}
|
|
276
282
|
*/
|
|
277
|
-
IDBCursor.prototype.__findMultiEntry = function (key, primaryKey, tx, success, error, recordsToLoad) {
|
|
283
|
+
IDBCursor.prototype.__findMultiEntry = function (key, primaryKey, tx, success, error, recordsToLoad = 1) {
|
|
278
284
|
const me = this;
|
|
279
285
|
|
|
280
|
-
if (me.
|
|
281
|
-
if (CFG.DEBUG) { console.log('Reached end of multiEntry cursor'); }
|
|
286
|
+
if (me.__multiEntryExhausted) {
|
|
287
|
+
if (CFG.DEBUG) { console.log('[multiEntry] Reached end of multiEntry cursor (already exhausted)'); }
|
|
282
288
|
success(undefined, undefined, undefined);
|
|
283
289
|
return;
|
|
284
290
|
}
|
|
285
291
|
|
|
286
292
|
const quotedKeyColumnName = util.sqlQuote(me.__keyColumnName);
|
|
287
|
-
const
|
|
288
|
-
/** @type {string[]} */
|
|
289
|
-
const sqlValues = [];
|
|
290
|
-
sql.push('WHERE', quotedKeyColumnName, 'NOT NULL');
|
|
291
|
-
if (me.__range && (me.__range.lower !== undefined && Array.isArray(me.__range.upper))) {
|
|
292
|
-
if (me.__range.upper.indexOf(me.__range.lower) === 0) {
|
|
293
|
-
sql.push('AND', quotedKeyColumnName, "LIKE ? ESCAPE '^'");
|
|
294
|
-
sqlValues.push(
|
|
295
|
-
'%' + util.sqlLIKEEscape(
|
|
296
|
-
/** @type {string} */ (me.__range.__lowerCached).slice(0, -1)
|
|
297
|
-
) + '%'
|
|
298
|
-
);
|
|
299
|
-
}
|
|
300
|
-
}
|
|
293
|
+
const quotedKey = util.sqlQuote('key');
|
|
301
294
|
|
|
302
295
|
// Determine the ORDER BY direction based on the cursor.
|
|
303
296
|
const direction = me.__sqlDirection;
|
|
304
297
|
const op = direction === 'ASC' ? '>' : '<';
|
|
305
|
-
const quotedKey = util.sqlQuote('key');
|
|
306
298
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
sql
|
|
318
|
-
|
|
319
|
-
sqlValues
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
299
|
+
/**
|
|
300
|
+
* Runs (and, if a batch of underlying rows produces no matching
|
|
301
|
+
* multi-entry values, repeatedly re-runs) the query for the next batch
|
|
302
|
+
* of underlying rows, advancing `me.__continuationKey`/
|
|
303
|
+
* `me.__continuationPrimaryKey` (tracking the last *physical* row
|
|
304
|
+
* scanned) each time, until either some matches are found or the
|
|
305
|
+
* underlying table is exhausted.
|
|
306
|
+
* @returns {void}
|
|
307
|
+
*/
|
|
308
|
+
function runQuery () {
|
|
309
|
+
const sql = ['SELECT * FROM', util.escapeStoreNameForSQL(me.__store.__currentName)];
|
|
310
|
+
/** @type {string[]} */
|
|
311
|
+
const sqlValues = [];
|
|
312
|
+
sql.push('WHERE', quotedKeyColumnName, 'NOT NULL');
|
|
313
|
+
if (me.__range && (me.__range.lower !== undefined && Array.isArray(me.__range.upper))) {
|
|
314
|
+
if (me.__range.upper.indexOf(me.__range.lower) === 0) {
|
|
315
|
+
sql.push('AND', quotedKeyColumnName, "LIKE ? ESCAPE '^'");
|
|
316
|
+
sqlValues.push(
|
|
317
|
+
'%' + util.sqlLIKEEscape(
|
|
318
|
+
/** @type {string} */ (me.__range.__lowerCached).slice(0, -1)
|
|
319
|
+
) + '%'
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
325
323
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
324
|
+
if (primaryKey !== undefined) {
|
|
325
|
+
sql.push('AND', quotedKey, op + '= ?');
|
|
326
|
+
// Key.convertValueToKey(primaryKey); // Already checked by `continuePrimaryKey`
|
|
327
|
+
sqlValues.push(/** @type {string} */ (Key.encode(primaryKey)));
|
|
328
|
+
}
|
|
329
|
+
if (key !== undefined) {
|
|
330
|
+
sql.push('AND', quotedKeyColumnName, op + '= ?');
|
|
331
|
+
// Key.convertValueToKey(key); // Already checked by `continue` or `continuePrimaryKey`
|
|
332
|
+
sqlValues.push(/** @type {string} */ (Key.encode(key)));
|
|
333
|
+
} else if (me.__continuationKey !== undefined) {
|
|
334
|
+
// Resume from the last underlying (physical) row we scanned, not
|
|
335
|
+
// from the last *matching* multi-entry value (which lives in a
|
|
336
|
+
// different key-space than the raw index column and cannot be
|
|
337
|
+
// reliably compared against it, e.g. for array index keys).
|
|
338
|
+
sql.push(
|
|
339
|
+
'AND (', quotedKeyColumnName, op, '?',
|
|
340
|
+
'OR (', quotedKeyColumnName, '= ?', 'AND', quotedKey, op, '?))'
|
|
341
|
+
);
|
|
342
|
+
const encodedContinuationKey = /** @type {string} */ (
|
|
343
|
+
Key.encode(me.__continuationKey, true)
|
|
344
|
+
);
|
|
345
|
+
sqlValues.push(
|
|
346
|
+
encodedContinuationKey,
|
|
347
|
+
encodedContinuationKey,
|
|
348
|
+
/** @type {string} */ (Key.encode(me.__continuationPrimaryKey))
|
|
349
|
+
);
|
|
329
350
|
}
|
|
330
351
|
|
|
331
|
-
|
|
352
|
+
if (!me.__count) {
|
|
353
|
+
// 1. Sort by key
|
|
354
|
+
sql.push('ORDER BY', quotedKeyColumnName, direction);
|
|
332
355
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
356
|
+
// 2. Sort by primaryKey (if defined and not unique)
|
|
357
|
+
if (!me.__unique && me.__keyColumnName !== 'key') { // Avoid adding 'key' twice
|
|
358
|
+
sql.push(',', util.sqlQuote('key'), direction);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// 3. Sort by position (if defined)
|
|
362
|
+
|
|
363
|
+
if (!me.__unique && me.__indexSource) {
|
|
364
|
+
// 4. Sort by object store position (if defined and not unique)
|
|
365
|
+
sql.push(',', util.sqlQuote(me.__valueColumnName), direction);
|
|
366
|
+
}
|
|
367
|
+
sql.push('LIMIT', String(recordsToLoad));
|
|
336
368
|
}
|
|
337
|
-
sql.
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
369
|
+
const sqlStr = sql.join(' ');
|
|
370
|
+
if (CFG.DEBUG) { console.log('[multiEntry] query', sqlStr, sqlValues); }
|
|
371
|
+
|
|
372
|
+
tx.executeSql(sqlStr, sqlValues, function (tx, data) {
|
|
373
|
+
if (data.rows.length === 0) {
|
|
374
|
+
me.__multiEntryExhausted = true;
|
|
375
|
+
if (CFG.DEBUG) { console.log('[multiEntry] Reached end of multiEntry cursor (no more rows)'); }
|
|
376
|
+
success(undefined, undefined, undefined);
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
341
379
|
|
|
342
|
-
tx.executeSql(sqlStr, sqlValues, function (tx, data) {
|
|
343
|
-
if (data.rows.length > 0) {
|
|
344
380
|
if (me.__count) { // Avoid caching and other processing below
|
|
345
381
|
let ct = 0;
|
|
346
382
|
for (let i = 0; i < data.rows.length; i++) {
|
|
@@ -352,6 +388,17 @@ IDBCursor.prototype.__findMultiEntry = function (key, primaryKey, tx, success, e
|
|
|
352
388
|
success(undefined, ct, undefined);
|
|
353
389
|
return;
|
|
354
390
|
}
|
|
391
|
+
|
|
392
|
+
// Track how far we've physically scanned, regardless of whether
|
|
393
|
+
// this batch produced any matches, so the next batch (if any)
|
|
394
|
+
// resumes after this one instead of re-scanning or stopping early.
|
|
395
|
+
const lastRawRow = data.rows.item(data.rows.length - 1);
|
|
396
|
+
me.__continuationKey = Key.decode(lastRawRow[me.__keyColumnName], true);
|
|
397
|
+
me.__continuationPrimaryKey = Key.decode(lastRawRow.key);
|
|
398
|
+
if (data.rows.length < recordsToLoad) {
|
|
399
|
+
me.__multiEntryExhausted = true;
|
|
400
|
+
}
|
|
401
|
+
|
|
355
402
|
const rows = [];
|
|
356
403
|
for (let i = 0; i < data.rows.length; i++) {
|
|
357
404
|
const rowItem = data.rows.item(i);
|
|
@@ -366,13 +413,25 @@ IDBCursor.prototype.__findMultiEntry = function (key, primaryKey, tx, success, e
|
|
|
366
413
|
matchingKey: /** @type {string} */ (
|
|
367
414
|
Key.encode(matchingKey, true)
|
|
368
415
|
),
|
|
369
|
-
key: rowItem.key
|
|
416
|
+
key: rowItem.key,
|
|
417
|
+
[me.__keyColumnName]: rowItem[me.__keyColumnName],
|
|
418
|
+
[me.__valueColumnName]: rowItem[me.__valueColumnName]
|
|
370
419
|
};
|
|
371
|
-
clone[me.__keyColumnName] = rowItem[me.__keyColumnName];
|
|
372
|
-
clone[me.__valueColumnName] = rowItem[me.__valueColumnName];
|
|
373
420
|
rows.push(clone);
|
|
374
421
|
}
|
|
375
422
|
}
|
|
423
|
+
|
|
424
|
+
if (rows.length === 0) {
|
|
425
|
+
if (me.__multiEntryExhausted) {
|
|
426
|
+
if (CFG.DEBUG) { console.log('[multiEntry] Reached end of multiEntry cursor (last batch had no matches)'); }
|
|
427
|
+
success(undefined, undefined, undefined);
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
if (CFG.DEBUG) { console.log('[multiEntry] batch had no matches; fetching next batch'); }
|
|
431
|
+
runQuery();
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
|
|
376
435
|
const reverse = me.direction.indexOf('prev') === 0;
|
|
377
436
|
rows.sort(function (a, b) {
|
|
378
437
|
if (a.matchingKey.replaceAll(leftBracketRegex, 'z') < b.matchingKey.replaceAll(leftBracketRegex, 'z')) {
|
|
@@ -390,37 +449,28 @@ IDBCursor.prototype.__findMultiEntry = function (key, primaryKey, tx, success, e
|
|
|
390
449
|
return 0;
|
|
391
450
|
});
|
|
392
451
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
} else {
|
|
416
|
-
if (CFG.DEBUG) { console.log('Reached end of multiEntry cursor'); }
|
|
417
|
-
success(undefined, undefined, undefined);
|
|
418
|
-
}
|
|
419
|
-
}, function (tx, err) {
|
|
420
|
-
if (CFG.DEBUG) { console.log('Could not execute Cursor.continue', sqlStr, sqlValues); }
|
|
421
|
-
error(err);
|
|
422
|
-
return false;
|
|
423
|
-
});
|
|
452
|
+
me.__prefetchedIndex = 0;
|
|
453
|
+
me.__prefetchedData = {
|
|
454
|
+
data: rows,
|
|
455
|
+
length: rows.length,
|
|
456
|
+
/**
|
|
457
|
+
* @param {Integer} index
|
|
458
|
+
* @returns {RowItemNonNull}
|
|
459
|
+
*/
|
|
460
|
+
item (index) {
|
|
461
|
+
return this.data[index];
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
if (CFG.DEBUG) { console.log('[multiEntry] Preloaded ' + me.__prefetchedData.length + ' records for multiEntry cursor'); }
|
|
465
|
+
me.__decode(rows[0], success);
|
|
466
|
+
}, function (tx, err) {
|
|
467
|
+
if (CFG.DEBUG) { console.log('[multiEntry] Could not execute Cursor.continue', sqlStr, sqlValues); }
|
|
468
|
+
error(err);
|
|
469
|
+
return false;
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
runQuery();
|
|
424
474
|
};
|
|
425
475
|
|
|
426
476
|
/**
|
|
@@ -496,7 +546,7 @@ IDBCursor.prototype.__decode = function (rowItem, callback) {
|
|
|
496
546
|
if (!me.__matchedKeys) {
|
|
497
547
|
me.__matchedKeys = {};
|
|
498
548
|
}
|
|
499
|
-
if (me.__matchedKeys[rowItem.matchingKey]) {
|
|
549
|
+
if (me.__matchedKeys[rowItem.matchingKey] === true) {
|
|
500
550
|
callback(undefined, undefined, undefined);
|
|
501
551
|
return;
|
|
502
552
|
}
|
|
@@ -540,6 +590,7 @@ IDBCursor.prototype.__sourceOrEffectiveObjStoreDeleted = function () {
|
|
|
540
590
|
IDBCursor.prototype.__invalidateCache = function () {
|
|
541
591
|
// @ts-expect-error Why is this not being found?
|
|
542
592
|
this.__prefetchedData = null;
|
|
593
|
+
this.__multiEntryExhausted = false;
|
|
543
594
|
};
|
|
544
595
|
|
|
545
596
|
/**
|
|
@@ -599,9 +650,8 @@ IDBCursor.prototype.__continueFinish = function (key, primaryKey, advanceState)
|
|
|
599
650
|
me.__advanceCount--;
|
|
600
651
|
me.__key = k;
|
|
601
652
|
me.__continue(undefined, true);
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
)(); // We don't call success yet but do need to advance the transaction queue
|
|
653
|
+
// We don't call success yet but do need to advance the transaction queue
|
|
654
|
+
util.runContinuationSafely(/** @type {() => void} */ (executeNextRequest));
|
|
605
655
|
return;
|
|
606
656
|
}
|
|
607
657
|
me.__advanceCount = undefined;
|
|
@@ -627,12 +677,12 @@ IDBCursor.prototype.__continueFinish = function (key, primaryKey, advanceState)
|
|
|
627
677
|
return;
|
|
628
678
|
}
|
|
629
679
|
// @ts-expect-error Todo: Our bug to fix
|
|
630
|
-
cursorContinue(tx, args, success, error);
|
|
680
|
+
util.runContinuationSafely(() => cursorContinue(tx, args, success, error));
|
|
631
681
|
}
|
|
632
682
|
if (me.__unique && !me.__multiEntryIndex &&
|
|
633
683
|
encKey === Key.encode(me.key, me.__multiEntryIndex)) {
|
|
634
684
|
// @ts-expect-error Todo: Our bug to fix
|
|
635
|
-
cursorContinue(tx, args, success, error);
|
|
685
|
+
util.runContinuationSafely(() => cursorContinue(tx, args, success, error));
|
|
636
686
|
return;
|
|
637
687
|
}
|
|
638
688
|
checkKey();
|
|
@@ -779,6 +829,7 @@ IDBCursor.prototype.update = function (valueToUpdate) {
|
|
|
779
829
|
if (cmp(me.primaryKey, evaluatedKey) !== 0) {
|
|
780
830
|
throw createDOMException('DataError', 'The key of the supplied value to `update` is not equal to the cursor\'s effective key');
|
|
781
831
|
}
|
|
832
|
+
// eslint-disable-next-line unicorn/prefer-hoisting-branch-code -- Different
|
|
782
833
|
addToQueue(clonedValue);
|
|
783
834
|
} else {
|
|
784
835
|
const clonedValue = Sca.clone(valueToUpdate);
|
|
@@ -836,6 +887,7 @@ IDBCursor.prototype.delete = function () {
|
|
|
836
887
|
|
|
837
888
|
IDBCursor.prototype[Symbol.toStringTag] = 'IDBCursorPrototype';
|
|
838
889
|
|
|
890
|
+
/* eslint-disable unicorn/no-top-level-side-effects -- Would be good */
|
|
839
891
|
util.defineReadonlyOuterInterface(
|
|
840
892
|
IDBCursor.prototype,
|
|
841
893
|
['source', 'direction', 'key', 'primaryKey', 'request']
|
|
@@ -843,14 +895,17 @@ util.defineReadonlyOuterInterface(
|
|
|
843
895
|
Object.defineProperty(IDBCursor, 'prototype', {
|
|
844
896
|
writable: false
|
|
845
897
|
});
|
|
898
|
+
/* eslint-enable unicorn/no-top-level-side-effects -- Would be good */
|
|
846
899
|
|
|
847
900
|
/**
|
|
848
901
|
* @class
|
|
902
|
+
* @throws {TypeError}
|
|
849
903
|
*/
|
|
850
904
|
function IDBCursorWithValue () {
|
|
851
905
|
throw new TypeError('Illegal constructor');
|
|
852
906
|
}
|
|
853
907
|
|
|
908
|
+
/* eslint-disable unicorn/no-top-level-side-effects -- Would be good */
|
|
854
909
|
// @ts-expect-error It's ok
|
|
855
910
|
IDBCursorWithValue.prototype = Object.create(IDBCursor.prototype);
|
|
856
911
|
Object.defineProperty(IDBCursorWithValue.prototype, 'constructor', {
|
|
@@ -859,6 +914,7 @@ Object.defineProperty(IDBCursorWithValue.prototype, 'constructor', {
|
|
|
859
914
|
configurable: true,
|
|
860
915
|
value: IDBCursorWithValue
|
|
861
916
|
});
|
|
917
|
+
/* eslint-enable unicorn/no-top-level-side-effects -- Would be good */
|
|
862
918
|
|
|
863
919
|
const IDBCursorWithValueAlias = IDBCursorWithValue;
|
|
864
920
|
/**
|
|
@@ -884,12 +940,13 @@ IDBCursorWithValue.__createInstance = function (...args) {
|
|
|
884
940
|
return new IDBCursorWithValue();
|
|
885
941
|
};
|
|
886
942
|
|
|
943
|
+
/* eslint-disable unicorn/no-top-level-side-effects -- Would be good */
|
|
887
944
|
util.defineReadonlyOuterInterface(IDBCursorWithValue.prototype, ['value']);
|
|
888
|
-
|
|
889
945
|
IDBCursorWithValue.prototype[Symbol.toStringTag] = 'IDBCursorWithValuePrototype';
|
|
890
946
|
|
|
891
947
|
Object.defineProperty(IDBCursorWithValue, 'prototype', {
|
|
892
948
|
writable: false
|
|
893
949
|
});
|
|
950
|
+
/* eslint-enable unicorn/no-top-level-side-effects -- Would be good */
|
|
894
951
|
|
|
895
952
|
export {IDBCursor, IDBCursorWithValue};
|
package/src/IDBDatabase.js
CHANGED
|
@@ -23,8 +23,9 @@ const readonlyProperties = ['name', 'version', 'objectStoreNames'];
|
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* IDB Database Object.
|
|
26
|
-
* @see
|
|
26
|
+
* @see https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#database-interface
|
|
27
27
|
* @class
|
|
28
|
+
* @throws {TypeError}
|
|
28
29
|
*/
|
|
29
30
|
function IDBDatabase () {
|
|
30
31
|
this.__versionTransaction = null;
|
|
@@ -165,7 +166,7 @@ IDBDatabase.prototype.createObjectStore = function (storeName /* , createOptions
|
|
|
165
166
|
throw createDOMException('SyntaxError', 'The keyPath argument contains an invalid key path.');
|
|
166
167
|
}
|
|
167
168
|
|
|
168
|
-
if (this.__objectStores
|
|
169
|
+
if (Object.hasOwn(this.__objectStores, storeName) && !this.__objectStores[storeName].__pendingDelete) {
|
|
169
170
|
throw createDOMException('ConstraintError', 'Object store "' + storeName + '" already exists in ' + this.name);
|
|
170
171
|
}
|
|
171
172
|
|
|
@@ -244,7 +245,8 @@ IDBDatabase.prototype.transaction = function (storeNames /* , mode */) {
|
|
|
244
245
|
// Creating new array also ensures sequence is passed by value: https://heycam.github.io/webidl/#idl-sequence
|
|
245
246
|
? [...new Set( // to be unique
|
|
246
247
|
util.convertToSequenceDOMString(storeNames) // iterables have `ToString` applied (and we convert to array for convenience)
|
|
247
|
-
|
|
248
|
+
// eslint-disable-next-line unicorn/require-array-sort-compare -- IndexedDB requires code unit comparison (default behavior)
|
|
249
|
+
)].toSorted() // must be sorted
|
|
248
250
|
: [util.convertToDOMString(storeNames)];
|
|
249
251
|
|
|
250
252
|
/* (function () {
|
|
@@ -258,7 +260,7 @@ IDBDatabase.prototype.transaction = function (storeNames /* , mode */) {
|
|
|
258
260
|
// prioritizing readonly but not starving readwrite).
|
|
259
261
|
// Even for readonly transactions, due to [issue 17](https://github.com/nolanlawson/node-websql/issues/17),
|
|
260
262
|
// we're not currently actually running the SQL requests in parallel.
|
|
261
|
-
mode
|
|
263
|
+
mode ||= 'readonly';
|
|
262
264
|
|
|
263
265
|
IDBTransaction.__assertNotVersionChange(this.__versionTransaction);
|
|
264
266
|
if (this.__closePending) {
|
|
@@ -321,7 +323,7 @@ IDBDatabase.prototype.__forceClose = function (msg) {
|
|
|
321
323
|
const evt = createEvent('close');
|
|
322
324
|
setTimeout(() => {
|
|
323
325
|
me.dispatchEvent(evt);
|
|
324
|
-
});
|
|
326
|
+
}, 0);
|
|
325
327
|
}
|
|
326
328
|
};
|
|
327
329
|
trans.__abortTransaction(createDOMException(
|
|
@@ -331,7 +333,7 @@ IDBDatabase.prototype.__forceClose = function (msg) {
|
|
|
331
333
|
});
|
|
332
334
|
me.__transactions = [];
|
|
333
335
|
};
|
|
334
|
-
|
|
336
|
+
/* eslint-disable unicorn/no-top-level-side-effects -- Would be good */
|
|
335
337
|
util.defineOuterInterface(IDBDatabase.prototype, listeners);
|
|
336
338
|
util.defineReadonlyOuterInterface(IDBDatabase.prototype, readonlyProperties);
|
|
337
339
|
|
|
@@ -345,5 +347,6 @@ Object.defineProperty(IDBDatabase.prototype, 'constructor', {
|
|
|
345
347
|
Object.defineProperty(IDBDatabase, 'prototype', {
|
|
346
348
|
writable: false
|
|
347
349
|
});
|
|
350
|
+
/* eslint-enable unicorn/no-top-level-side-effects -- Would be good */
|
|
348
351
|
|
|
349
352
|
export default IDBDatabase;
|