indexeddbshim 17.3.3 → 17.4.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 +3 -146
- package/dist/CFG.d.ts +1 -0
- package/dist/CFG.d.ts.map +1 -1
- package/dist/DOMException.d.ts +4 -4
- package/dist/DOMException.d.ts.map +1 -1
- package/dist/IDBFactory.d.ts.map +1 -1
- package/dist/IDBTransaction.d.ts +8 -6
- 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/indexeddbshim-Key.js +54 -14
- 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 +212 -80
- package/dist/indexeddbshim-UnicodeIdentifiers-node.cjs.map +1 -1
- package/dist/indexeddbshim-UnicodeIdentifiers.js +201 -79
- package/dist/indexeddbshim-UnicodeIdentifiers.js.map +1 -1
- package/dist/indexeddbshim-UnicodeIdentifiers.min.js +3 -3
- package/dist/indexeddbshim-UnicodeIdentifiers.min.js.map +1 -1
- package/dist/indexeddbshim-node.cjs +212 -80
- package/dist/indexeddbshim-node.cjs.map +1 -1
- package/dist/indexeddbshim-noninvasive.js +201 -79
- package/dist/indexeddbshim-noninvasive.js.map +1 -1
- package/dist/indexeddbshim-noninvasive.min.js +3 -3
- package/dist/indexeddbshim-noninvasive.min.js.map +1 -1
- package/dist/indexeddbshim.js +201 -79
- package/dist/indexeddbshim.js.map +1 -1
- package/dist/indexeddbshim.min.js +3 -3
- package/dist/indexeddbshim.min.js.map +1 -1
- package/dist/nodeSQLiteDatabase.d.ts.map +1 -1
- package/dist/nodeWebSQL.d.ts.map +1 -1
- package/package.json +8 -9
- package/src/CFG.js +2 -0
- package/src/DOMException.js +21 -21
- package/src/IDBFactory.js +88 -39
- package/src/IDBObjectStore.js +1 -1
- package/src/IDBTransaction.js +7 -1
- package/src/Key.js +34 -12
- package/src/Sca.js +53 -3
- package/src/nodeSQLiteDatabase.js +10 -1
- package/src/nodeWebSQL.js +3 -0
- package/src/setGlobalVars.js +3 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! indexeddbshim - v17.
|
|
1
|
+
/*! indexeddbshim - v17.4.0 - 8/27/2026 */
|
|
2
2
|
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
@@ -1389,6 +1389,7 @@ EventTarget.EventTargetFactory = EventTargetFactory;
|
|
|
1389
1389
|
* sqlBusyTimeout: number,
|
|
1390
1390
|
* sqlTrace: () => void,
|
|
1391
1391
|
* sqlProfile: () => void,
|
|
1392
|
+
* sqlMemoryQuota: number,
|
|
1392
1393
|
* escapeNULForSQLiteStatements: boolean,
|
|
1393
1394
|
* createIndexes: boolean
|
|
1394
1395
|
* }} ConfigValues
|
|
@@ -1545,7 +1546,7 @@ val => {
|
|
|
1545
1546
|
'sqlProfile',
|
|
1546
1547
|
// Callback not used by default
|
|
1547
1548
|
// Defaults to true except in Node builds where we can preserve literal NUL with better-sqlite3
|
|
1548
|
-
'escapeNULForSQLiteStatements', 'createIndexes'].forEach(prop => {
|
|
1549
|
+
'escapeNULForSQLiteStatements', 'sqlMemoryQuota', 'createIndexes'].forEach(prop => {
|
|
1549
1550
|
/** @type {(val: any) => void} */
|
|
1550
1551
|
let validator;
|
|
1551
1552
|
if (Array.isArray(prop)) {
|
|
@@ -2564,41 +2565,40 @@ function findError(args) {
|
|
|
2564
2565
|
* optional here and, in practice, always `undefined` today (the `case 4`/
|
|
2565
2566
|
* `case 7` branches below are effectively unreachable pending upstream
|
|
2566
2567
|
* support for surfacing a real error code).
|
|
2567
|
-
* @param {Error & {code?: number}} webSQLErr
|
|
2568
|
+
* @param {Error & {code?: number|string}} webSQLErr
|
|
2568
2569
|
* @returns {(DOMException|Error) & {
|
|
2569
|
-
* sqlError: Error & {code?: number}
|
|
2570
|
+
* sqlError: Error & {code?: number|string}
|
|
2570
2571
|
* }|QuotaExceededError}
|
|
2571
2572
|
*/
|
|
2572
2573
|
function webSQLErrback(webSQLErr) {
|
|
2573
2574
|
let name,
|
|
2574
2575
|
message,
|
|
2575
2576
|
useQuotaExceededError = false;
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
if (typeof QuotaExceededError !== 'undefined') {
|
|
2583
|
-
useQuotaExceededError = true;
|
|
2584
|
-
}
|
|
2585
|
-
break;
|
|
2586
|
-
}
|
|
2587
|
-
/*
|
|
2588
|
-
// Should a WebSQL timeout treat as IndexedDB `TransactionInactiveError` or `UnknownError`?
|
|
2589
|
-
case 7: { // SQLError.TIMEOUT_ERR
|
|
2590
|
-
// All transaction errors abort later, so no need to mark inactive
|
|
2591
|
-
name = 'TransactionInactiveError';
|
|
2592
|
-
message = 'A request was placed against a transaction which is currently not active, or which is finished (Internal SQL Timeout).';
|
|
2593
|
-
break;
|
|
2577
|
+
if (webSQLErr.code === 4 || webSQLErr.code === 'SQLITE_FULL') {
|
|
2578
|
+
// SQLError.QUOTA_ERR or better-sqlite3 SQLITE_FULL
|
|
2579
|
+
name = 'QuotaExceededError';
|
|
2580
|
+
message = 'The operation failed because there was not enough ' + 'remaining storage space, or the storage quota was reached ' + 'and the user declined to give more space to the database.';
|
|
2581
|
+
if (typeof QuotaExceededError !== 'undefined') {
|
|
2582
|
+
useQuotaExceededError = true;
|
|
2594
2583
|
}
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2584
|
+
} else {
|
|
2585
|
+
switch (webSQLErr.code) {
|
|
2586
|
+
/*
|
|
2587
|
+
// Should a WebSQL timeout treat as IndexedDB `TransactionInactiveError` or `UnknownError`?
|
|
2588
|
+
case 7: { // SQLError.TIMEOUT_ERR
|
|
2589
|
+
// All transaction errors abort later, so no need to mark inactive
|
|
2590
|
+
name = 'TransactionInactiveError';
|
|
2591
|
+
message = 'A request was placed against a transaction which is currently not active, or which is finished (Internal SQL Timeout).';
|
|
2592
|
+
break;
|
|
2601
2593
|
}
|
|
2594
|
+
*/
|
|
2595
|
+
default:
|
|
2596
|
+
{
|
|
2597
|
+
name = 'UnknownError';
|
|
2598
|
+
message = 'The operation failed for reasons unrelated to the database itself and not covered by any other errors.';
|
|
2599
|
+
break;
|
|
2600
|
+
}
|
|
2601
|
+
}
|
|
2602
2602
|
}
|
|
2603
2603
|
message += ' (' + webSQLErr.message + ')--(' + webSQLErr.code + ')';
|
|
2604
2604
|
if (useQuotaExceededError) {
|
|
@@ -2607,7 +2607,7 @@ function webSQLErrback(webSQLErr) {
|
|
|
2607
2607
|
const err =
|
|
2608
2608
|
/**
|
|
2609
2609
|
* @type {(Error | DOMException) & {
|
|
2610
|
-
* sqlError: Error & {code?: number}
|
|
2610
|
+
* sqlError: Error & {code?: number|string}
|
|
2611
2611
|
* }}
|
|
2612
2612
|
*/
|
|
2613
2613
|
createDOMException(name, message);
|
|
@@ -3159,6 +3159,31 @@ function cmp(first, second) {
|
|
|
3159
3159
|
return result;
|
|
3160
3160
|
}
|
|
3161
3161
|
|
|
3162
|
+
/**
|
|
3163
|
+
* @param {unknown[]} arr
|
|
3164
|
+
* @param {number} index
|
|
3165
|
+
* @param {unknown} val
|
|
3166
|
+
* @returns {void}
|
|
3167
|
+
*/
|
|
3168
|
+
const setArrayValue = (arr, index, val) => {
|
|
3169
|
+
if (Reflect.has(Array.prototype, index)) {
|
|
3170
|
+
Object.defineProperty(arr, index, {
|
|
3171
|
+
value: val,
|
|
3172
|
+
enumerable: true,
|
|
3173
|
+
writable: true,
|
|
3174
|
+
configurable: true
|
|
3175
|
+
});
|
|
3176
|
+
} else {
|
|
3177
|
+
arr[index] = val;
|
|
3178
|
+
}
|
|
3179
|
+
};
|
|
3180
|
+
/**
|
|
3181
|
+
* @param {unknown[]} arr
|
|
3182
|
+
* @param {unknown} val
|
|
3183
|
+
* @returns {void}
|
|
3184
|
+
*/
|
|
3185
|
+
const safePush = (arr, val) => setArrayValue(arr, arr.length, val);
|
|
3186
|
+
|
|
3162
3187
|
/**
|
|
3163
3188
|
* @typedef {NodeJS.TypedArray|DataView} ArrayBufferView
|
|
3164
3189
|
*/
|
|
@@ -3421,12 +3446,13 @@ const types = {
|
|
|
3421
3446
|
* @returns {string}
|
|
3422
3447
|
*/
|
|
3423
3448
|
encode(key) {
|
|
3449
|
+
/** @type {(string|null)[]} */
|
|
3424
3450
|
const encoded = [];
|
|
3425
3451
|
for (const [i, item] of key.entries()) {
|
|
3426
3452
|
const encodedItem = encode$1(item, true); // encode the array item
|
|
3427
|
-
encoded
|
|
3453
|
+
setArrayValue(encoded, i, encodedItem);
|
|
3428
3454
|
}
|
|
3429
|
-
encoded
|
|
3455
|
+
safePush(encoded, keyTypeToEncodedChar.invalid + '-'); // append an extra item, so empty arrays sort correctly
|
|
3430
3456
|
let encodedKey = JSON.stringify(encoded);
|
|
3431
3457
|
if (CFG.escapeNULForSQLiteStatements === false) {
|
|
3432
3458
|
encodedKey = encodedKey.replaceAll(String.raw`\u0000`, '\0');
|
|
@@ -3447,7 +3473,7 @@ const types = {
|
|
|
3447
3473
|
for (let i = 0; i < decoded.length; i++) {
|
|
3448
3474
|
const item = decoded[i];
|
|
3449
3475
|
const decodedItem = decode$1(item, true); // decode the item
|
|
3450
|
-
decoded
|
|
3476
|
+
setArrayValue(decoded, i, decodedItem);
|
|
3451
3477
|
}
|
|
3452
3478
|
return decoded;
|
|
3453
3479
|
}
|
|
@@ -3733,7 +3759,7 @@ function convertValueToKeyValueDecoded(input, seen, multiEntry, fullKeys) {
|
|
|
3733
3759
|
// May throw (from binary)
|
|
3734
3760
|
const arr = /** @type {Array<any>} */input;
|
|
3735
3761
|
const len = arr.length;
|
|
3736
|
-
seen
|
|
3762
|
+
safePush(seen, input);
|
|
3737
3763
|
|
|
3738
3764
|
/** @type {(KeyValueObject|Value)[]} */
|
|
3739
3765
|
const keys = [];
|
|
@@ -3760,7 +3786,7 @@ function convertValueToKeyValueDecoded(input, seen, multiEntry, fullKeys) {
|
|
|
3760
3786
|
};
|
|
3761
3787
|
}
|
|
3762
3788
|
if (!multiEntry || !fullKeys && keys.every(k => cmp(k, key.value) !== 0) || fullKeys && keys.every(k => cmp(k, key) !== 0)) {
|
|
3763
|
-
keys
|
|
3789
|
+
safePush(keys, fullKeys ? key : key.value);
|
|
3764
3790
|
}
|
|
3765
3791
|
} catch (err) {
|
|
3766
3792
|
if (!multiEntry) {
|
|
@@ -3914,7 +3940,7 @@ function evaluateKeyPathOnValueToDecodedValue(value, keyPath, multiEntry, fullKe
|
|
|
3914
3940
|
if (key.failure) {
|
|
3915
3941
|
return true;
|
|
3916
3942
|
}
|
|
3917
|
-
result
|
|
3943
|
+
safePush(result, key.value);
|
|
3918
3944
|
return false;
|
|
3919
3945
|
}) ? {
|
|
3920
3946
|
failure: true
|
|
@@ -3975,11 +4001,21 @@ function injectKeyIntoValueUsingKeyPath(value, key, keyPath) {
|
|
|
3975
4001
|
identifiers.forEach(identifier => {
|
|
3976
4002
|
const hop = Object.hasOwn(value, identifier);
|
|
3977
4003
|
if (!hop) {
|
|
3978
|
-
value
|
|
4004
|
+
Object.defineProperty(value, identifier, {
|
|
4005
|
+
value: {},
|
|
4006
|
+
enumerable: true,
|
|
4007
|
+
writable: true,
|
|
4008
|
+
configurable: true
|
|
4009
|
+
});
|
|
3979
4010
|
}
|
|
3980
4011
|
value = value[identifier];
|
|
3981
4012
|
});
|
|
3982
|
-
value
|
|
4013
|
+
Object.defineProperty(value, /** @type {string} */last, {
|
|
4014
|
+
value: key,
|
|
4015
|
+
enumerable: true,
|
|
4016
|
+
writable: true,
|
|
4017
|
+
configurable: true
|
|
4018
|
+
}); // key is already a `keyValue` in our processing so no need to convert
|
|
3983
4019
|
}
|
|
3984
4020
|
|
|
3985
4021
|
/**
|
|
@@ -4048,6 +4084,7 @@ function isMultiEntryMatch(encodedEntry, encodedKey) {
|
|
|
4048
4084
|
* @returns {Key[]}
|
|
4049
4085
|
*/
|
|
4050
4086
|
function findMultiEntryMatches(keyEntry, range) {
|
|
4087
|
+
/** @type {unknown[]} */
|
|
4051
4088
|
const matches = [];
|
|
4052
4089
|
if (Array.isArray(keyEntry)) {
|
|
4053
4090
|
for (let key of keyEntry) {
|
|
@@ -4060,17 +4097,17 @@ function findMultiEntryMatches(keyEntry, range) {
|
|
|
4060
4097
|
} else {
|
|
4061
4098
|
const nested = findMultiEntryMatches(key, range);
|
|
4062
4099
|
if (nested.length > 0) {
|
|
4063
|
-
matches
|
|
4100
|
+
safePush(matches, key);
|
|
4064
4101
|
}
|
|
4065
4102
|
continue;
|
|
4066
4103
|
}
|
|
4067
4104
|
}
|
|
4068
4105
|
if (isNullish(range) || isKeyInRange(key, range, true)) {
|
|
4069
|
-
matches
|
|
4106
|
+
safePush(matches, key);
|
|
4070
4107
|
}
|
|
4071
4108
|
}
|
|
4072
4109
|
} else if (isNullish(range) || isKeyInRange(keyEntry, range, true)) {
|
|
4073
|
-
matches
|
|
4110
|
+
safePush(matches, keyEntry);
|
|
4074
4111
|
}
|
|
4075
4112
|
return matches;
|
|
4076
4113
|
}
|
|
@@ -4094,12 +4131,13 @@ function convertKeyToValue(key) {
|
|
|
4094
4131
|
}
|
|
4095
4132
|
case 'array':
|
|
4096
4133
|
{
|
|
4134
|
+
/** @type {ValueType[]} */
|
|
4097
4135
|
const array = [];
|
|
4098
4136
|
const len = value.length;
|
|
4099
4137
|
let index = 0;
|
|
4100
4138
|
while (index < len) {
|
|
4101
4139
|
const entry = convertKeyToValue(value[index]);
|
|
4102
|
-
array
|
|
4140
|
+
setArrayValue(array, index, entry);
|
|
4103
4141
|
index++;
|
|
4104
4142
|
}
|
|
4105
4143
|
return array;
|
|
@@ -4862,6 +4900,7 @@ if (cleanInterface) {
|
|
|
4862
4900
|
}
|
|
4863
4901
|
|
|
4864
4902
|
let uniqueID = 0;
|
|
4903
|
+
const activeTransactions = new Set();
|
|
4865
4904
|
const listeners$1 = ['onabort', 'oncomplete', 'onerror'];
|
|
4866
4905
|
const readonlyProperties$4 = ['objectStoreNames', 'mode', 'durability', 'db', 'error'];
|
|
4867
4906
|
|
|
@@ -4991,6 +5030,7 @@ IDBTransaction.__createInstance = function (db, storeNames, mode, durability = '
|
|
|
4991
5030
|
me.__mode = mode;
|
|
4992
5031
|
me.__durability = durability;
|
|
4993
5032
|
me.__db = db;
|
|
5033
|
+
activeTransactions.add(me);
|
|
4994
5034
|
me.__error = null;
|
|
4995
5035
|
// @ts-expect-error Part of `ShimEventTarget`
|
|
4996
5036
|
me.__setOptions({
|
|
@@ -5498,6 +5538,7 @@ IDBTransaction.prototype.__executeRequests = function () {
|
|
|
5498
5538
|
me.__errored = true;
|
|
5499
5539
|
throw e;
|
|
5500
5540
|
} finally {
|
|
5541
|
+
activeTransactions.delete(me);
|
|
5501
5542
|
me.__storeHandles = {};
|
|
5502
5543
|
}
|
|
5503
5544
|
}
|
|
@@ -5704,7 +5745,7 @@ IDBTransaction.prototype.__abortTransaction = function (err) {
|
|
|
5704
5745
|
});
|
|
5705
5746
|
}
|
|
5706
5747
|
me.__active = false; // Setting here and in requestsFinished for https://github.com/w3c/IndexedDB/issues/87
|
|
5707
|
-
|
|
5748
|
+
activeTransactions.delete(me);
|
|
5708
5749
|
if (err !== null) {
|
|
5709
5750
|
me.__error = err;
|
|
5710
5751
|
}
|
|
@@ -5923,7 +5964,7 @@ IDBTransaction.__assertNotFinishedObjectStoreMethod = function (tx) {
|
|
|
5923
5964
|
* @returns {void}
|
|
5924
5965
|
*/
|
|
5925
5966
|
IDBTransaction.__assertActive = function (tx) {
|
|
5926
|
-
if (!tx || !tx.__active || tx.__committed) {
|
|
5967
|
+
if (!tx || !tx.__active || !tx.__handlerActive || tx.__committed) {
|
|
5927
5968
|
throw createDOMException('TransactionInactiveError', 'A request was placed against a transaction which is currently not active, or which is finished');
|
|
5928
5969
|
}
|
|
5929
5970
|
};
|
|
@@ -5950,6 +5991,9 @@ Object.defineProperty(IDBTransaction.prototype, 'constructor', {
|
|
|
5950
5991
|
Object.defineProperty(IDBTransaction, 'prototype', {
|
|
5951
5992
|
writable: false
|
|
5952
5993
|
});
|
|
5994
|
+
/* eslint-enable unicorn/no-top-level-side-effects -- Would be good */
|
|
5995
|
+
|
|
5996
|
+
IDBTransaction.activeTransactions = activeTransactions;
|
|
5953
5997
|
|
|
5954
5998
|
class TypesonPromise {
|
|
5955
5999
|
constructor(e) {
|
|
@@ -7095,14 +7139,14 @@ const B = {
|
|
|
7095
7139
|
revive: () => 1 / 0
|
|
7096
7140
|
}
|
|
7097
7141
|
},
|
|
7098
|
-
|
|
7142
|
+
D = {
|
|
7099
7143
|
map: {
|
|
7100
7144
|
test: e => "Map" === toStringTag(e),
|
|
7101
7145
|
replace: e => e.entries().toArray(),
|
|
7102
7146
|
revive: e => new Map(e)
|
|
7103
7147
|
}
|
|
7104
7148
|
},
|
|
7105
|
-
|
|
7149
|
+
R = {
|
|
7106
7150
|
nan: {
|
|
7107
7151
|
test: e => Number.isNaN(e),
|
|
7108
7152
|
replace: () => "NaN",
|
|
@@ -7357,8 +7401,8 @@ const Y = {
|
|
|
7357
7401
|
revive() {}
|
|
7358
7402
|
}
|
|
7359
7403
|
}],
|
|
7360
|
-
ne = [
|
|
7361
|
-
ce = [Z, Y, re, K, ne, O, z, U, _, B, I, h, N, C].concat("function" == typeof Map ?
|
|
7404
|
+
ne = [R, M, L, F],
|
|
7405
|
+
ce = [Z, Y, re, K, ne, O, z, U, _, B, I, h, N, C].concat("function" == typeof Map ? D : [], "function" == typeof Set ? H : [], "function" == typeof ArrayBuffer ? p : [], "function" == typeof Uint8Array ? X : [], "function" == typeof DataView ? w : [], "undefined" != typeof crypto ? v : [], "undefined" != typeof BigInt ? [m, d] : [], "undefined" != typeof DOMException ? A : [], "undefined" != typeof QuotaExceededError ? W : [], "undefined" != typeof WebTransportError ? te : [], "undefined" != typeof DOMRect ? x : [], "undefined" != typeof DOMPoint ? S : [], "undefined" != typeof DOMQuad ? P : [], "undefined" != typeof DOMMatrix ? T : [], "undefined" != typeof AudioData ? f : [], "undefined" != typeof EncodedAudioChunk ? E : [], "undefined" != typeof EncodedVideoChunk ? j : [], "undefined" != typeof VideoFrame ? ee : []);
|
|
7362
7406
|
const ue = ce.concat({
|
|
7363
7407
|
checkDataCloneException: {
|
|
7364
7408
|
test(e) {
|
|
@@ -7375,11 +7419,53 @@ const ue = ce.concat({
|
|
|
7375
7419
|
return false;
|
|
7376
7420
|
}
|
|
7377
7421
|
}
|
|
7422
|
+
}),
|
|
7423
|
+
ye = ue.concat({
|
|
7424
|
+
checkSharedArrayBufferException: {
|
|
7425
|
+
test(e) {
|
|
7426
|
+
if ("SharedArrayBuffer" === {}.toString.call(e).slice(8, -1)) throw new DOMException("The object cannot be cloned.", "DataCloneError");
|
|
7427
|
+
return false;
|
|
7428
|
+
}
|
|
7429
|
+
}
|
|
7378
7430
|
});
|
|
7379
7431
|
|
|
7380
7432
|
// See: https://stackoverflow.com/questions/42170826/categories-for-rejection-by-the-structured-cloning-algorithm
|
|
7381
7433
|
|
|
7382
|
-
|
|
7434
|
+
// Although typeson-registry already has a FileList type in its structured cloning presets,
|
|
7435
|
+
// we need to override it so it works with our tests
|
|
7436
|
+
|
|
7437
|
+
const specSet = ye.flatMap(preset => Array.isArray(preset) ? preset : [preset]).find(preset => preset && !Array.isArray(preset) && 'filelist' in preset);
|
|
7438
|
+
const origFileList = specSet && !Array.isArray(specSet) && 'filelist' in specSet ? specSet.filelist : undefined;
|
|
7439
|
+
const origTest = origFileList && typeof origFileList === 'object' && 'test' in origFileList && typeof origFileList.test === 'function' ? origFileList.test : undefined;
|
|
7440
|
+
const origRevive = origFileList && typeof origFileList === 'object' && 'revive' in origFileList && typeof origFileList.revive === 'function' ? origFileList.revive : undefined;
|
|
7441
|
+
const customFileList = origFileList ? {
|
|
7442
|
+
...origFileList,
|
|
7443
|
+
/**
|
|
7444
|
+
* @param {unknown} x
|
|
7445
|
+
* @param {import('typeson').StateObject} state
|
|
7446
|
+
* @returns {boolean}
|
|
7447
|
+
*/
|
|
7448
|
+
test(x, state) {
|
|
7449
|
+
if (typeof FileList !== 'undefined') {
|
|
7450
|
+
return x instanceof FileList;
|
|
7451
|
+
}
|
|
7452
|
+
return typeof origTest === 'function' ? origTest(x, state) : false;
|
|
7453
|
+
},
|
|
7454
|
+
/**
|
|
7455
|
+
* @param {unknown} x
|
|
7456
|
+
* @param {import('typeson').StateObject} state
|
|
7457
|
+
* @returns {unknown}
|
|
7458
|
+
*/
|
|
7459
|
+
revive(x, state) {
|
|
7460
|
+
if (typeof FileList !== 'undefined') {
|
|
7461
|
+
return Reflect.construct(FileList, [x]);
|
|
7462
|
+
}
|
|
7463
|
+
return typeof origRevive === 'function' ? origRevive(x, state) : undefined;
|
|
7464
|
+
}
|
|
7465
|
+
} : undefined;
|
|
7466
|
+
let typeson = new Typeson().register([ye, customFileList ? {
|
|
7467
|
+
filelist: customFileList
|
|
7468
|
+
} : {}]);
|
|
7383
7469
|
|
|
7384
7470
|
/**
|
|
7385
7471
|
* @param {(preset: import('typeson-registry').Preset) =>
|
|
@@ -7388,7 +7474,7 @@ let typeson = new Typeson().register(ue);
|
|
|
7388
7474
|
*/
|
|
7389
7475
|
function register(func) {
|
|
7390
7476
|
// eslint-disable-next-line unicorn/no-top-level-assignment-in-function -- Should be one-time cache
|
|
7391
|
-
typeson = new Typeson().register(func(
|
|
7477
|
+
typeson = new Typeson().register(func(ye));
|
|
7392
7478
|
}
|
|
7393
7479
|
|
|
7394
7480
|
/**
|
|
@@ -8676,7 +8762,7 @@ IDBObjectStore.__createObjectStore = function (db, store) {
|
|
|
8676
8762
|
tx.executeSql('INSERT INTO __sys__ VALUES (?,?,?,?,?)', [escapeSQLiteStatement(storeName), encodedKeyPath,
|
|
8677
8763
|
// For why converting here, see comment and following
|
|
8678
8764
|
// discussion at:
|
|
8679
|
-
// https://github.com/
|
|
8765
|
+
// https://github.com/indexeddbshim/IndexedDBShim/issues/313#issuecomment-590086778
|
|
8680
8766
|
Number(store.autoIncrement), '{}', 1], function () {
|
|
8681
8767
|
delete store.__pendingCreate;
|
|
8682
8768
|
delete store.__deleted;
|
|
@@ -10449,6 +10535,7 @@ IDBFactory.prototype.open = function (name /* , version */) {
|
|
|
10449
10535
|
}
|
|
10450
10536
|
const req = IDBOpenDBRequest.__createInstance();
|
|
10451
10537
|
let calledDbCreateError = false;
|
|
10538
|
+
let isRevertingSysdb = false;
|
|
10452
10539
|
if (CFG.autoName && name === '') {
|
|
10453
10540
|
// eslint-disable-next-line unicorn/no-top-level-assignment-in-function -- Necessary?
|
|
10454
10541
|
name = 'autoNamedDatabase_' + nameCounter++;
|
|
@@ -10475,7 +10562,7 @@ IDBFactory.prototype.open = function (name /* , version */) {
|
|
|
10475
10562
|
* @returns {boolean}
|
|
10476
10563
|
*/
|
|
10477
10564
|
function dbCreateError(tx, err) {
|
|
10478
|
-
if (calledDbCreateError) {
|
|
10565
|
+
if (calledDbCreateError || isRevertingSysdb) {
|
|
10479
10566
|
return false;
|
|
10480
10567
|
}
|
|
10481
10568
|
// Defensive cleanup: `pendingVersionChanges.set(name, ...)` (see
|
|
@@ -10539,36 +10626,46 @@ IDBFactory.prototype.open = function (name /* , version */) {
|
|
|
10539
10626
|
*/
|
|
10540
10627
|
let sysdbFinishedCb = function (systx, err, cb) {
|
|
10541
10628
|
if (err) {
|
|
10542
|
-
|
|
10543
|
-
|
|
10544
|
-
|
|
10545
|
-
|
|
10546
|
-
|
|
10629
|
+
/**
|
|
10630
|
+
* @param {any} [errorToShow]
|
|
10631
|
+
* @returns {void}
|
|
10632
|
+
*/
|
|
10633
|
+
const manualRevert = function (errorToShow) {
|
|
10634
|
+
/**
|
|
10635
|
+
* @param {string} [msg]
|
|
10636
|
+
* @throws {Error}
|
|
10637
|
+
* @returns {never}
|
|
10638
|
+
*/
|
|
10639
|
+
function reportError(msg) {
|
|
10640
|
+
throw new Error('Unable to roll back upgrade transaction!' + (msg || ''));
|
|
10641
|
+
}
|
|
10547
10642
|
sysdb.transaction(function (systx) {
|
|
10548
|
-
/**
|
|
10549
|
-
*
|
|
10550
|
-
* @param {string} msg
|
|
10551
|
-
* @throws {Error}
|
|
10552
|
-
* @returns {never}
|
|
10553
|
-
*/
|
|
10554
|
-
function reportError(msg) {
|
|
10555
|
-
throw new Error('Unable to roll back upgrade transaction!' + (msg || ''));
|
|
10556
|
-
}
|
|
10557
|
-
|
|
10558
10643
|
// Attempt to revert
|
|
10559
10644
|
if (oldVersion === 0) {
|
|
10560
|
-
systx.executeSql('DELETE FROM dbVersions WHERE "name" = ?', [sqlSafeName]
|
|
10561
|
-
// @ts-expect-error Force to work
|
|
10562
|
-
cb(reportError); // eslint-disable-line promise/no-callback-in-promise -- Convenient
|
|
10563
|
-
},
|
|
10564
|
-
// @ts-expect-error Force to work
|
|
10565
|
-
reportError);
|
|
10645
|
+
systx.executeSql('DELETE FROM dbVersions WHERE "name" = ?', [sqlSafeName]);
|
|
10566
10646
|
} else {
|
|
10567
|
-
systx.executeSql('UPDATE dbVersions SET "version" = ? WHERE "name" = ?', [oldVersion, sqlSafeName]
|
|
10568
|
-
// @ts-expect-error Force to work
|
|
10569
|
-
reportError);
|
|
10647
|
+
systx.executeSql('UPDATE dbVersions SET "version" = ? WHERE "name" = ?', [oldVersion, sqlSafeName]);
|
|
10570
10648
|
}
|
|
10649
|
+
}, function (sqlErr) {
|
|
10650
|
+
isRevertingSysdb = false;
|
|
10651
|
+
cb(sqlErr); // eslint-disable-line promise/no-callback-in-promise -- Convenient
|
|
10652
|
+
}, function () {
|
|
10653
|
+
isRevertingSysdb = false;
|
|
10654
|
+
cb(errorToShow || reportError); // eslint-disable-line promise/no-callback-in-promise -- Convenient
|
|
10571
10655
|
});
|
|
10656
|
+
};
|
|
10657
|
+
try {
|
|
10658
|
+
systx.executeSql('ROLLBACK', [], function () {
|
|
10659
|
+
cb(); // eslint-disable-line promise/no-callback-in-promise -- Convenient
|
|
10660
|
+
}, function (tx, sqlErr) {
|
|
10661
|
+
// Browser/Node may fail with expired transaction, so manually revert
|
|
10662
|
+
manualRevert(sqlErr);
|
|
10663
|
+
return false;
|
|
10664
|
+
});
|
|
10665
|
+
} catch (e) {
|
|
10666
|
+
// Browser may fail with expired transaction above so
|
|
10667
|
+
// no choice but to manually revert
|
|
10668
|
+
manualRevert(e);
|
|
10572
10669
|
}
|
|
10573
10670
|
return;
|
|
10574
10671
|
}
|
|
@@ -10669,6 +10766,7 @@ IDBFactory.prototype.open = function (name /* , version */) {
|
|
|
10669
10766
|
|
|
10670
10767
|
// eslint-disable-next-line camelcase -- Clear API
|
|
10671
10768
|
req.transaction.on__preabort = function () {
|
|
10769
|
+
isRevertingSysdb = true;
|
|
10672
10770
|
pendingVersionChanges.delete(name);
|
|
10673
10771
|
connection.__upgradeTransaction = null;
|
|
10674
10772
|
// We ensure any cache is deleted before any request error events fire and try to reopen
|
|
@@ -10686,6 +10784,7 @@ IDBFactory.prototype.open = function (name /* , version */) {
|
|
|
10686
10784
|
req.__result = undefined;
|
|
10687
10785
|
req.__done = false;
|
|
10688
10786
|
connection.close();
|
|
10787
|
+
isRevertingSysdb = true;
|
|
10689
10788
|
setTimeout(() => {
|
|
10690
10789
|
const err = createDOMException('AbortError', 'The upgrade transaction was aborted.');
|
|
10691
10790
|
sysdbFinishedCb(systx, err, function (reportError) {
|
|
@@ -10747,7 +10846,26 @@ IDBFactory.prototype.open = function (name /* , version */) {
|
|
|
10747
10846
|
}
|
|
10748
10847
|
sysdbFinishedCb = function (systx, err, cb) {
|
|
10749
10848
|
if (err) {
|
|
10750
|
-
rollback(err,
|
|
10849
|
+
rollback(err,
|
|
10850
|
+
/**
|
|
10851
|
+
* @param {Error} [reportError]
|
|
10852
|
+
* @returns {void}
|
|
10853
|
+
*/
|
|
10854
|
+
function (reportError) {
|
|
10855
|
+
sysdb.transaction(function (systx) {
|
|
10856
|
+
if (oldVersion === 0) {
|
|
10857
|
+
systx.executeSql('DELETE FROM dbVersions WHERE "name" = ?', [sqlSafeName]);
|
|
10858
|
+
} else {
|
|
10859
|
+
systx.executeSql('UPDATE dbVersions SET "version" = ? WHERE "name" = ?', [oldVersion, sqlSafeName]);
|
|
10860
|
+
}
|
|
10861
|
+
}, function (sqlErr) {
|
|
10862
|
+
isRevertingSysdb = false;
|
|
10863
|
+
cb(sqlErr); // eslint-disable-line promise/no-callback-in-promise -- Convenient
|
|
10864
|
+
}, function () {
|
|
10865
|
+
isRevertingSysdb = false;
|
|
10866
|
+
cb(reportError); // eslint-disable-line promise/no-callback-in-promise -- Convenient
|
|
10867
|
+
});
|
|
10868
|
+
});
|
|
10751
10869
|
} else {
|
|
10752
10870
|
commit(cb);
|
|
10753
10871
|
}
|
|
@@ -12827,7 +12945,7 @@ function setGlobalVars(idb, initialConfig) {
|
|
|
12827
12945
|
// Ignore Node or other environments
|
|
12828
12946
|
// Bad non-Chrome Android support
|
|
12829
12947
|
/Android (?:2|3|4\.[0-3])/u.test(navigator.userAgent) && !navigator.userAgent.includes('Chrome') ||
|
|
12830
|
-
// Bad non-Safari iOS9 support (see <https://github.com/
|
|
12948
|
+
// Bad non-Safari iOS9 support (see <https://github.com/indexeddbshim/IndexedDBShim/issues/252>)
|
|
12831
12949
|
(!navigator.userAgent.includes('Safari') || navigator.userAgent.includes('Chrome')) &&
|
|
12832
12950
|
// Exclude genuine Safari: https://stackoverflow.com/a/7768006/271577
|
|
12833
12951
|
// Detect iOS: https://stackoverflow.com/questions/9038625/detect-if-device-is-ios/9039885#9039885
|
|
@@ -12837,8 +12955,8 @@ function setGlobalVars(idb, initialConfig) {
|
|
|
12837
12955
|
if (!CFG.DEFAULT_DB_SIZE) {
|
|
12838
12956
|
CFG.DEFAULT_DB_SIZE = (
|
|
12839
12957
|
// Safari currently requires larger size: (We don't need a larger size for Node as node-websql doesn't use this info)
|
|
12840
|
-
// https://github.com/
|
|
12841
|
-
// https://github.com/
|
|
12958
|
+
// https://github.com/indexeddbshim/IndexedDBShim/issues/41
|
|
12959
|
+
// https://github.com/indexeddbshim/IndexedDBShim/issues/115
|
|
12842
12960
|
typeof navigator !== 'undefined' &&
|
|
12843
12961
|
// React Native
|
|
12844
12962
|
navigator.userAgent && navigator.userAgent.includes('Safari') && !navigator.userAgent.includes('Chrome') ? 25 : 4) * 1024 * 1024;
|
|
@@ -14624,7 +14742,7 @@ function SQLiteDatabase(name, opts = {}) {
|
|
|
14624
14742
|
_db: db,
|
|
14625
14743
|
/**
|
|
14626
14744
|
* Compatibility with node-sqlite3's configure API.
|
|
14627
|
-
* @param {'busyTimeout'|'trace'|'profile'} option
|
|
14745
|
+
* @param {'busyTimeout'|'trace'|'profile'|'memoryQuota'} option
|
|
14628
14746
|
* @param {number|((sql: string, duration?: number) => void)} value
|
|
14629
14747
|
* @returns {void}
|
|
14630
14748
|
*/
|
|
@@ -14639,6 +14757,17 @@ function SQLiteDatabase(name, opts = {}) {
|
|
|
14639
14757
|
}
|
|
14640
14758
|
if (option === 'profile') {
|
|
14641
14759
|
profile = /** @type {SQLProfileCallback} */value;
|
|
14760
|
+
return;
|
|
14761
|
+
}
|
|
14762
|
+
if (option === 'memoryQuota') {
|
|
14763
|
+
const bytes = Number(value);
|
|
14764
|
+
// `better-sqlite3` doesn't have a direct `sqlite3_quota_set` binding,
|
|
14765
|
+
// but we can limit the max pages:
|
|
14766
|
+
const pageSizeObj = db.pragma('page_size', {
|
|
14767
|
+
simple: true
|
|
14768
|
+
});
|
|
14769
|
+
const pageSize = Number(pageSizeObj);
|
|
14770
|
+
db.pragma('max_page_count = ' + Math.ceil(bytes / pageSize));
|
|
14642
14771
|
}
|
|
14643
14772
|
},
|
|
14644
14773
|
/**
|
|
@@ -14873,6 +15002,9 @@ function wrappedSQLiteDatabase(name) {
|
|
|
14873
15002
|
if (CFG.sqlProfile) {
|
|
14874
15003
|
db._db.configure('profile', CFG.sqlProfile);
|
|
14875
15004
|
}
|
|
15005
|
+
if (CFG.sqlMemoryQuota) {
|
|
15006
|
+
db._db.configure('memoryQuota', /** @type {number} */CFG.sqlMemoryQuota);
|
|
15007
|
+
}
|
|
14876
15008
|
return db;
|
|
14877
15009
|
}
|
|
14878
15010
|
|