indexeddbshim 11.0.0 → 12.0.0-pre.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/badges/licenses-badge.svg +1 -1
- package/dist/CFG.d.ts +80 -0
- package/dist/CFG.d.ts.map +1 -0
- package/dist/DOMException.d.ts +71 -0
- package/dist/DOMException.d.ts.map +1 -0
- package/dist/DOMStringList.d.ts +20 -0
- package/dist/DOMStringList.d.ts.map +1 -0
- package/dist/Event.d.ts +21 -0
- package/dist/Event.d.ts.map +1 -0
- package/dist/IDBCursor.d.ts +289 -0
- package/dist/IDBCursor.d.ts.map +1 -0
- package/dist/IDBDatabase.d.ts +144 -0
- package/dist/IDBDatabase.d.ts.map +1 -0
- package/dist/IDBFactory.d.ts +96 -0
- package/dist/IDBFactory.d.ts.map +1 -0
- package/dist/IDBIndex.d.ts +243 -0
- package/dist/IDBIndex.d.ts.map +1 -0
- package/dist/IDBKeyRange.d.ts +79 -0
- package/dist/IDBKeyRange.d.ts.map +1 -0
- package/dist/IDBObjectStore.d.ts +273 -0
- package/dist/IDBObjectStore.d.ts.map +1 -0
- package/dist/IDBRequest.d.ts +90 -0
- package/dist/IDBRequest.d.ts.map +1 -0
- package/dist/IDBTransaction.d.ts +271 -0
- package/dist/IDBTransaction.d.ts.map +1 -0
- package/dist/IDBVersionChangeEvent.d.ts +23 -0
- package/dist/IDBVersionChangeEvent.d.ts.map +1 -0
- package/dist/Key.d.ts +214 -0
- package/dist/Key.d.ts.map +1 -0
- package/dist/Sca.d.ts +31 -0
- package/dist/Sca.d.ts.map +1 -0
- package/dist/UnicodeIdentifiers.d.ts +3 -0
- package/dist/UnicodeIdentifiers.d.ts.map +1 -0
- package/dist/browser-UnicodeIdentifiers.d.ts +2 -0
- package/dist/browser-UnicodeIdentifiers.d.ts.map +1 -0
- package/dist/browser-noninvasive.d.ts +3 -0
- package/dist/browser-noninvasive.d.ts.map +1 -0
- package/dist/browser.d.ts +2 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/cmp.d.ts +9 -0
- package/dist/cmp.d.ts.map +1 -0
- package/dist/indexeddbshim-Key.js +491 -189
- 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 +17263 -1396
- package/dist/indexeddbshim-UnicodeIdentifiers-node.cjs.map +1 -1
- package/dist/indexeddbshim-UnicodeIdentifiers.js +3892 -1271
- package/dist/indexeddbshim-UnicodeIdentifiers.js.map +1 -1
- package/dist/indexeddbshim-UnicodeIdentifiers.min.js +2 -2
- package/dist/indexeddbshim-UnicodeIdentifiers.min.js.map +1 -1
- package/dist/indexeddbshim-node.cjs +17259 -1396
- package/dist/indexeddbshim-node.cjs.map +1 -1
- package/dist/indexeddbshim-noninvasive.js +3887 -1271
- package/dist/indexeddbshim-noninvasive.js.map +1 -1
- package/dist/indexeddbshim-noninvasive.min.js +2 -2
- package/dist/indexeddbshim-noninvasive.min.js.map +1 -1
- package/dist/indexeddbshim.js +3887 -1271
- package/dist/indexeddbshim.js.map +1 -1
- package/dist/indexeddbshim.min.js +2 -2
- package/dist/indexeddbshim.min.js.map +1 -1
- package/dist/node-UnicodeIdentifiers.d.ts +8 -0
- package/dist/node-UnicodeIdentifiers.d.ts.map +1 -0
- package/dist/node.d.ts +8 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/nodeWebSQL.d.ts +3 -0
- package/dist/nodeWebSQL.d.ts.map +1 -0
- package/dist/setGlobalVars.d.ts +79 -0
- package/dist/setGlobalVars.d.ts.map +1 -0
- package/dist/unicode-regex.d.ts +3 -0
- package/dist/unicode-regex.d.ts.map +1 -0
- package/dist/util.d.ts +174 -0
- package/dist/util.d.ts.map +1 -0
- package/package.json +40 -27
- package/src/CFG.js +89 -11
- package/src/DOMException.js +116 -29
- package/src/DOMStringList.js +92 -2
- package/src/Event.js +19 -4
- package/src/IDBCursor.js +339 -67
- package/src/IDBDatabase.js +87 -10
- package/src/IDBFactory.js +319 -56
- package/src/IDBIndex.js +385 -96
- package/src/IDBKeyRange.js +86 -13
- package/src/IDBObjectStore.js +326 -68
- package/src/IDBRequest.js +59 -1
- package/src/IDBTransaction.js +247 -38
- package/src/IDBVersionChangeEvent.js +28 -3
- package/src/Key.js +273 -156
- package/src/Sca.js +29 -4
- package/src/browser-UnicodeIdentifiers.js +5 -1
- package/src/cmp.js +5 -5
- package/src/node-UnicodeIdentifiers.js +9 -0
- package/src/node.js +5 -0
- package/src/nodeWebSQL.js +11 -5
- package/src/setGlobalVars.js +156 -21
- package/src/unicode-regex.js +9 -1
- package/src/util.js +228 -40
- package/typings/shimIndexedDB.d.ts +9 -0
package/src/IDBCursor.js
CHANGED
|
@@ -10,6 +10,55 @@ import * as Sca from './Sca.js';
|
|
|
10
10
|
import IDBIndex from './IDBIndex.js'; // eslint-disable-line import/no-named-as-default
|
|
11
11
|
import CFG from './CFG.js';
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {number} Integer
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @typedef {IDBCursor & {
|
|
19
|
+
* primaryKey: import('./Key.js').Key,
|
|
20
|
+
* key: import('./Key.js').Key,
|
|
21
|
+
* direction: string,
|
|
22
|
+
* source: import('./IDBObjectStore.js').IDBObjectStoreFull|
|
|
23
|
+
* import('./IDBIndex.js').IDBIndexFull,
|
|
24
|
+
* __request: import('./IDBRequest.js').IDBRequestFull,
|
|
25
|
+
* __advanceCount: Integer|undefined,
|
|
26
|
+
* __indexSource: boolean,
|
|
27
|
+
* __key: import('./Key.js').Key,
|
|
28
|
+
* __primaryKey: import('./Key.js').Key,
|
|
29
|
+
* __value: import('./Key.js').Value,
|
|
30
|
+
* __store: import('./IDBObjectStore.js').IDBObjectStoreFull,
|
|
31
|
+
* __range: import('./IDBKeyRange.js').IDBKeyRangeFull|undefined,
|
|
32
|
+
* __keyColumnName: string,
|
|
33
|
+
* __valueColumnName: string,
|
|
34
|
+
* __keyOnly: boolean,
|
|
35
|
+
* __valueDecoder: {
|
|
36
|
+
* decode: (str: string) => any,
|
|
37
|
+
* },
|
|
38
|
+
* __count: boolean,
|
|
39
|
+
* __prefetchedIndex: Integer,
|
|
40
|
+
* __prefetchedData: null|SQLResultSetRowList|{
|
|
41
|
+
* data: RowItemNonNull[],
|
|
42
|
+
* length: Integer,
|
|
43
|
+
* item: (index: Integer) => RowItemNonNull
|
|
44
|
+
* },
|
|
45
|
+
* __multiEntryIndex: boolean,
|
|
46
|
+
* __unique: boolean,
|
|
47
|
+
* __sqlDirection: "DESC"|"ASC",
|
|
48
|
+
* __matchedKeys: {[key: string]: true},
|
|
49
|
+
* __invalidateCache: () => void
|
|
50
|
+
* }} IDBCursorFull
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @typedef {IDBCursorFull & {
|
|
55
|
+
* __request: import('./IDBRequest.js').IDBRequestFull,
|
|
56
|
+
* }} IDBCursorWithValueFull
|
|
57
|
+
*/
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @class
|
|
61
|
+
*/
|
|
13
62
|
function IDBCursor () {
|
|
14
63
|
throw new TypeError('Illegal constructor');
|
|
15
64
|
}
|
|
@@ -21,20 +70,27 @@ const IDBCursorAlias = IDBCursor;
|
|
|
21
70
|
* @see http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBCursor
|
|
22
71
|
* @param {IDBKeyRange} query
|
|
23
72
|
* @param {string} direction
|
|
24
|
-
* @param {IDBObjectStore} store
|
|
25
|
-
* @param {IDBObjectStore|
|
|
73
|
+
* @param {import('./IDBObjectStore.js').IDBObjectStoreFull} store
|
|
74
|
+
* @param {import('./IDBObjectStore.js').IDBObjectStoreFull|
|
|
75
|
+
* import('./IDBIndex.js').IDBIndexFull} source
|
|
26
76
|
* @param {string} keyColumnName
|
|
27
77
|
* @param {string} valueColumnName
|
|
28
78
|
* @param {boolean} count
|
|
79
|
+
* @this {IDBCursorFull}
|
|
29
80
|
* @returns {void}
|
|
30
81
|
*/
|
|
31
82
|
IDBCursor.__super = function IDBCursor (query, direction, store, source, keyColumnName, valueColumnName, count) {
|
|
32
83
|
/* eslint-enable func-name-matching */
|
|
84
|
+
// @ts-expect-error Should be ok
|
|
33
85
|
this[Symbol.toStringTag] = 'IDBCursor';
|
|
34
86
|
util.defineReadonlyProperties(this, ['key', 'primaryKey', 'request']);
|
|
35
87
|
IDBObjectStore.__invalidStateIfDeleted(store);
|
|
36
88
|
this.__indexSource = util.instanceOf(source, IDBIndex);
|
|
37
|
-
if (this.__indexSource)
|
|
89
|
+
if (this.__indexSource) {
|
|
90
|
+
IDBIndex.__invalidStateIfDeleted(
|
|
91
|
+
/** @type {import('./IDBIndex.js').IDBIndexFull} */ (source)
|
|
92
|
+
);
|
|
93
|
+
}
|
|
38
94
|
IDBTransaction.__assertActive(store.transaction);
|
|
39
95
|
const range = convertValueToKeyRange(query);
|
|
40
96
|
if (direction !== undefined && !(['next', 'prev', 'nextunique', 'prevunique'].includes(direction))) {
|
|
@@ -60,7 +116,9 @@ IDBCursor.__super = function IDBCursor (query, direction, store, source, keyColu
|
|
|
60
116
|
this.__valueDecoder = this.__keyOnly ? Key : Sca;
|
|
61
117
|
this.__count = count;
|
|
62
118
|
this.__prefetchedIndex = -1;
|
|
63
|
-
this.__multiEntryIndex = this.__indexSource
|
|
119
|
+
this.__multiEntryIndex = this.__indexSource
|
|
120
|
+
? 'multiEntry' in source && source.multiEntry
|
|
121
|
+
: false;
|
|
64
122
|
this.__unique = this.direction.includes('unique');
|
|
65
123
|
this.__sqlDirection = ['prev', 'prevunique'].includes(this.direction) ? 'DESC' : 'ASC';
|
|
66
124
|
|
|
@@ -73,20 +131,58 @@ IDBCursor.__super = function IDBCursor (query, direction, store, source, keyColu
|
|
|
73
131
|
this.continue();
|
|
74
132
|
};
|
|
75
133
|
|
|
134
|
+
/**
|
|
135
|
+
*
|
|
136
|
+
* @param {...any} args
|
|
137
|
+
* @returns {IDBCursorFull}
|
|
138
|
+
*/
|
|
76
139
|
IDBCursor.__createInstance = function (...args) {
|
|
77
140
|
const IDBCursor = IDBCursorAlias.__super;
|
|
78
141
|
IDBCursor.prototype = IDBCursorAlias.prototype;
|
|
142
|
+
|
|
143
|
+
// @ts-expect-error It's ok
|
|
79
144
|
return new IDBCursor(...args);
|
|
80
145
|
};
|
|
81
146
|
|
|
147
|
+
/**
|
|
148
|
+
*
|
|
149
|
+
* @param {...any} args
|
|
150
|
+
* @this {IDBCursorFull}
|
|
151
|
+
* @returns {void}
|
|
152
|
+
*/
|
|
82
153
|
IDBCursor.prototype.__find = function (...args /* key, tx, success, error, recordsToLoad */) {
|
|
83
154
|
if (this.__multiEntryIndex) {
|
|
84
|
-
|
|
155
|
+
const [key, primaryKey, tx, success, error] = args;
|
|
156
|
+
this.__findMultiEntry(key, primaryKey, tx, success, error);
|
|
85
157
|
} else {
|
|
86
|
-
|
|
158
|
+
const [key, primaryKey, tx, success, error, recordsToLoad] = args;
|
|
159
|
+
this.__findBasic(key, primaryKey, tx, success, error, recordsToLoad);
|
|
87
160
|
}
|
|
88
161
|
};
|
|
89
162
|
|
|
163
|
+
/**
|
|
164
|
+
* @typedef {(
|
|
165
|
+
* k: import('./Key.js').Key,
|
|
166
|
+
* val: import('./Key.js').Value,
|
|
167
|
+
* primKey: import('./Key.js').Key
|
|
168
|
+
* ) => void} KeySuccess
|
|
169
|
+
*/
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* @typedef {(tx: SQLTransaction|Error|DOMException|SQLError, err?: SQLError) => void} FindError
|
|
173
|
+
*/
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
*
|
|
177
|
+
* @param {undefined|import('./Key.js').Key} key
|
|
178
|
+
* @param {undefined|import('./Key.js').Key} primaryKey
|
|
179
|
+
* @param {SQLTransaction} tx
|
|
180
|
+
* @param {KeySuccess} success
|
|
181
|
+
* @param {FindError} error
|
|
182
|
+
* @param {Integer|undefined} recordsToLoad
|
|
183
|
+
* @this {IDBCursorFull}
|
|
184
|
+
* @returns {void}
|
|
185
|
+
*/
|
|
90
186
|
IDBCursor.prototype.__findBasic = function (key, primaryKey, tx, success, error, recordsToLoad) {
|
|
91
187
|
const continueCall = recordsToLoad !== undefined;
|
|
92
188
|
recordsToLoad = recordsToLoad || 1;
|
|
@@ -94,7 +190,9 @@ IDBCursor.prototype.__findBasic = function (key, primaryKey, tx, success, error,
|
|
|
94
190
|
const me = this;
|
|
95
191
|
const quotedKeyColumnName = util.sqlQuote(me.__keyColumnName);
|
|
96
192
|
const quotedKey = util.sqlQuote('key');
|
|
97
|
-
|
|
193
|
+
const sql = ['SELECT * FROM', util.escapeStoreNameForSQL(me.__store.__currentName)];
|
|
194
|
+
|
|
195
|
+
/** @type {string[]} */
|
|
98
196
|
const sqlValues = [];
|
|
99
197
|
sql.push('WHERE', quotedKeyColumnName, 'NOT NULL');
|
|
100
198
|
setSQLForKeyRange(me.__range, quotedKeyColumnName, sql, sqlValues, true, true);
|
|
@@ -106,16 +204,16 @@ IDBCursor.prototype.__findBasic = function (key, primaryKey, tx, success, error,
|
|
|
106
204
|
if (primaryKey !== undefined) {
|
|
107
205
|
sql.push('AND', quotedKey, op + '= ?');
|
|
108
206
|
// Key.convertValueToKey(primaryKey); // Already checked by `continuePrimaryKey`
|
|
109
|
-
sqlValues.push(Key.encode(primaryKey));
|
|
207
|
+
sqlValues.push(/** @type {string} */ (Key.encode(primaryKey)));
|
|
110
208
|
}
|
|
111
209
|
if (key !== undefined) {
|
|
112
210
|
sql.push('AND', quotedKeyColumnName, op + '= ?');
|
|
113
211
|
// Key.convertValueToKey(key); // Already checked by `continue` or `continuePrimaryKey`
|
|
114
|
-
sqlValues.push(Key.encode(key));
|
|
212
|
+
sqlValues.push(/** @type {string} */ (Key.encode(key)));
|
|
115
213
|
} else if (continueCall && me.__key !== undefined) {
|
|
116
214
|
sql.push('AND', quotedKeyColumnName, op + ' ?');
|
|
117
215
|
// Key.convertValueToKey(me.__key); // Already checked when stored
|
|
118
|
-
sqlValues.push(Key.encode(me.__key));
|
|
216
|
+
sqlValues.push(/** @type {string} */ (Key.encode(me.__key)));
|
|
119
217
|
}
|
|
120
218
|
|
|
121
219
|
if (!me.__count) {
|
|
@@ -137,12 +235,12 @@ IDBCursor.prototype.__findBasic = function (key, primaryKey, tx, success, error,
|
|
|
137
235
|
// 4. Sort by object store position (if defined and not unique)
|
|
138
236
|
sql.push(',', util.sqlQuote(me.__valueColumnName), direction);
|
|
139
237
|
}
|
|
140
|
-
sql.push('LIMIT', recordsToLoad);
|
|
238
|
+
sql.push('LIMIT', String(recordsToLoad));
|
|
141
239
|
}
|
|
142
|
-
|
|
143
|
-
CFG.DEBUG && console.log(
|
|
240
|
+
const sqlStr = sql.join(' ');
|
|
241
|
+
CFG.DEBUG && console.log(sqlStr, sqlValues);
|
|
144
242
|
|
|
145
|
-
tx.executeSql(
|
|
243
|
+
tx.executeSql(sqlStr, sqlValues, function (tx, data) {
|
|
146
244
|
if (me.__count) {
|
|
147
245
|
success(undefined, data.rows.length, undefined);
|
|
148
246
|
} else if (data.rows.length > 1) {
|
|
@@ -157,13 +255,24 @@ IDBCursor.prototype.__findBasic = function (key, primaryKey, tx, success, error,
|
|
|
157
255
|
success(undefined, undefined, undefined);
|
|
158
256
|
}
|
|
159
257
|
}, function (tx, err) {
|
|
160
|
-
CFG.DEBUG && console.log('Could not execute Cursor.continue',
|
|
258
|
+
CFG.DEBUG && console.log('Could not execute Cursor.continue', sqlStr, sqlValues);
|
|
161
259
|
error(err);
|
|
260
|
+
return true;
|
|
162
261
|
});
|
|
163
262
|
};
|
|
164
263
|
|
|
165
264
|
const leftBracketRegex = /\[/gu;
|
|
166
265
|
|
|
266
|
+
/**
|
|
267
|
+
*
|
|
268
|
+
* @param {undefined|import('./Key.js').Key} key
|
|
269
|
+
* @param {undefined|import('./Key.js').Key} primaryKey
|
|
270
|
+
* @param {SQLTransaction} tx
|
|
271
|
+
* @param {KeySuccess} success
|
|
272
|
+
* @param {FindError} error
|
|
273
|
+
* @this {IDBCursorFull}
|
|
274
|
+
* @returns {void}
|
|
275
|
+
*/
|
|
167
276
|
IDBCursor.prototype.__findMultiEntry = function (key, primaryKey, tx, success, error) {
|
|
168
277
|
const me = this;
|
|
169
278
|
|
|
@@ -174,13 +283,18 @@ IDBCursor.prototype.__findMultiEntry = function (key, primaryKey, tx, success, e
|
|
|
174
283
|
}
|
|
175
284
|
|
|
176
285
|
const quotedKeyColumnName = util.sqlQuote(me.__keyColumnName);
|
|
177
|
-
|
|
286
|
+
const sql = ['SELECT * FROM', util.escapeStoreNameForSQL(me.__store.__currentName)];
|
|
287
|
+
/** @type {string[]} */
|
|
178
288
|
const sqlValues = [];
|
|
179
289
|
sql.push('WHERE', quotedKeyColumnName, 'NOT NULL');
|
|
180
290
|
if (me.__range && (me.__range.lower !== undefined && Array.isArray(me.__range.upper))) {
|
|
181
291
|
if (me.__range.upper.indexOf(me.__range.lower) === 0) {
|
|
182
292
|
sql.push('AND', quotedKeyColumnName, "LIKE ? ESCAPE '^'");
|
|
183
|
-
sqlValues.push(
|
|
293
|
+
sqlValues.push(
|
|
294
|
+
'%' + util.sqlLIKEEscape(
|
|
295
|
+
/** @type {string} */ (me.__range.__lowerCached).slice(0, -1)
|
|
296
|
+
) + '%'
|
|
297
|
+
);
|
|
184
298
|
}
|
|
185
299
|
}
|
|
186
300
|
|
|
@@ -192,16 +306,16 @@ IDBCursor.prototype.__findMultiEntry = function (key, primaryKey, tx, success, e
|
|
|
192
306
|
if (primaryKey !== undefined) {
|
|
193
307
|
sql.push('AND', quotedKey, op + '= ?');
|
|
194
308
|
// Key.convertValueToKey(primaryKey); // Already checked by `continuePrimaryKey`
|
|
195
|
-
sqlValues.push(Key.encode(primaryKey));
|
|
309
|
+
sqlValues.push(/** @type {string} */ (Key.encode(primaryKey)));
|
|
196
310
|
}
|
|
197
311
|
if (key !== undefined) {
|
|
198
312
|
sql.push('AND', quotedKeyColumnName, op + '= ?');
|
|
199
313
|
// Key.convertValueToKey(key); // Already checked by `continue` or `continuePrimaryKey`
|
|
200
|
-
sqlValues.push(Key.encode(key));
|
|
314
|
+
sqlValues.push(/** @type {string} */ (Key.encode(key)));
|
|
201
315
|
} else if (me.__key !== undefined) {
|
|
202
316
|
sql.push('AND', quotedKeyColumnName, op + ' ?');
|
|
203
317
|
// Key.convertValueToKey(me.__key); // Already checked when entered
|
|
204
|
-
sqlValues.push(Key.encode(me.__key));
|
|
318
|
+
sqlValues.push(/** @type {string} */ (Key.encode(me.__key)));
|
|
205
319
|
}
|
|
206
320
|
|
|
207
321
|
if (!me.__count) {
|
|
@@ -220,10 +334,10 @@ IDBCursor.prototype.__findMultiEntry = function (key, primaryKey, tx, success, e
|
|
|
220
334
|
sql.push(',', util.sqlQuote(me.__valueColumnName), direction);
|
|
221
335
|
}
|
|
222
336
|
}
|
|
223
|
-
|
|
224
|
-
CFG.DEBUG && console.log(
|
|
337
|
+
const sqlStr = sql.join(' ');
|
|
338
|
+
CFG.DEBUG && console.log(sqlStr, sqlValues);
|
|
225
339
|
|
|
226
|
-
tx.executeSql(
|
|
340
|
+
tx.executeSql(sqlStr, sqlValues, function (tx, data) {
|
|
227
341
|
if (data.rows.length > 0) {
|
|
228
342
|
if (me.__count) { // Avoid caching and other processing below
|
|
229
343
|
let ct = 0;
|
|
@@ -243,8 +357,13 @@ IDBCursor.prototype.__findMultiEntry = function (key, primaryKey, tx, success, e
|
|
|
243
357
|
const matches = Key.findMultiEntryMatches(rowKey, me.__range);
|
|
244
358
|
|
|
245
359
|
for (const matchingKey of matches) {
|
|
360
|
+
/**
|
|
361
|
+
* @type {RowItemNonNull}
|
|
362
|
+
*/
|
|
246
363
|
const clone = {
|
|
247
|
-
matchingKey:
|
|
364
|
+
matchingKey: /** @type {string} */ (
|
|
365
|
+
Key.encode(matchingKey, true)
|
|
366
|
+
),
|
|
248
367
|
key: rowItem.key
|
|
249
368
|
};
|
|
250
369
|
clone[me.__keyColumnName] = rowItem[me.__keyColumnName];
|
|
@@ -254,10 +373,10 @@ IDBCursor.prototype.__findMultiEntry = function (key, primaryKey, tx, success, e
|
|
|
254
373
|
}
|
|
255
374
|
const reverse = me.direction.indexOf('prev') === 0;
|
|
256
375
|
rows.sort(function (a, b) {
|
|
257
|
-
if (a.matchingKey.
|
|
376
|
+
if (a.matchingKey.replaceAll(leftBracketRegex, 'z') < b.matchingKey.replaceAll(leftBracketRegex, 'z')) {
|
|
258
377
|
return reverse ? 1 : -1;
|
|
259
378
|
}
|
|
260
|
-
if (a.matchingKey.
|
|
379
|
+
if (a.matchingKey.replaceAll(leftBracketRegex, 'z') > b.matchingKey.replaceAll(leftBracketRegex, 'z')) {
|
|
261
380
|
return reverse ? -1 : 1;
|
|
262
381
|
}
|
|
263
382
|
if (a.key < b.key) {
|
|
@@ -274,6 +393,10 @@ IDBCursor.prototype.__findMultiEntry = function (key, primaryKey, tx, success, e
|
|
|
274
393
|
me.__prefetchedData = {
|
|
275
394
|
data: rows,
|
|
276
395
|
length: rows.length,
|
|
396
|
+
/**
|
|
397
|
+
* @param {Integer} index
|
|
398
|
+
* @returns {RowItemNonNull}
|
|
399
|
+
*/
|
|
277
400
|
item (index) {
|
|
278
401
|
return this.data[index];
|
|
279
402
|
}
|
|
@@ -292,31 +415,40 @@ IDBCursor.prototype.__findMultiEntry = function (key, primaryKey, tx, success, e
|
|
|
292
415
|
success(undefined, undefined, undefined);
|
|
293
416
|
}
|
|
294
417
|
}, function (tx, err) {
|
|
295
|
-
CFG.DEBUG && console.log('Could not execute Cursor.continue',
|
|
418
|
+
CFG.DEBUG && console.log('Could not execute Cursor.continue', sqlStr, sqlValues);
|
|
296
419
|
error(err);
|
|
420
|
+
return true;
|
|
297
421
|
});
|
|
298
422
|
};
|
|
299
423
|
|
|
300
424
|
/**
|
|
301
|
-
* @
|
|
302
|
-
|
|
303
|
-
|
|
425
|
+
* @typedef {any} StructuredCloneValue
|
|
426
|
+
*/
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* @typedef {any} IndexedDBKey
|
|
430
|
+
*/
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* @callback SuccessArg
|
|
434
|
+
* @param {StructuredCloneValue} value
|
|
435
|
+
* @param {import('./IDBRequest.js').IDBRequestFull} req
|
|
304
436
|
* @returns {void}
|
|
305
437
|
*/
|
|
306
438
|
|
|
307
439
|
/**
|
|
308
|
-
* @callback
|
|
309
|
-
* @param key
|
|
310
|
-
* @param value
|
|
311
|
-
* @param primaryKey
|
|
440
|
+
* @callback SuccessCallback
|
|
441
|
+
* @param {IndexedDBKey} key
|
|
442
|
+
* @param {StructuredCloneValue} value
|
|
443
|
+
* @param {IndexedDBKey} primaryKey
|
|
312
444
|
* @returns {void}
|
|
313
445
|
*/
|
|
314
446
|
|
|
315
447
|
/**
|
|
316
448
|
* Creates an "onsuccess" callback.
|
|
317
|
-
* @
|
|
318
|
-
* @
|
|
319
|
-
* @returns {
|
|
449
|
+
* @param {SuccessArg} success
|
|
450
|
+
* @this {IDBCursorFull}
|
|
451
|
+
* @returns {SuccessCallback}
|
|
320
452
|
*/
|
|
321
453
|
IDBCursor.prototype.__onsuccess = function (success) {
|
|
322
454
|
const me = this;
|
|
@@ -336,6 +468,26 @@ IDBCursor.prototype.__onsuccess = function (success) {
|
|
|
336
468
|
};
|
|
337
469
|
};
|
|
338
470
|
|
|
471
|
+
/**
|
|
472
|
+
* @typedef {{
|
|
473
|
+
* matchingKey: string,
|
|
474
|
+
* key: string,
|
|
475
|
+
* [k: string]: string
|
|
476
|
+
* }} RowItemNonNull
|
|
477
|
+
*/
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
*
|
|
481
|
+
* @param {RowItemNonNull} rowItem
|
|
482
|
+
* @param {(
|
|
483
|
+
* key: import('./Key.js').Key,
|
|
484
|
+
* val: import('./Key.js').Value,
|
|
485
|
+
* primaryKey: import('./Key.js').Key,
|
|
486
|
+
* encKey?: string
|
|
487
|
+
* ) => void} callback
|
|
488
|
+
* @this {IDBCursorFull}
|
|
489
|
+
* @returns {void}
|
|
490
|
+
*/
|
|
339
491
|
IDBCursor.prototype.__decode = function (rowItem, callback) {
|
|
340
492
|
const me = this;
|
|
341
493
|
if (me.__multiEntryIndex && me.__unique) {
|
|
@@ -365,15 +517,36 @@ IDBCursor.prototype.__decode = function (rowItem, callback) {
|
|
|
365
517
|
callback(key, val, primaryKey, encKey /*, encVal, encPrimaryKey */);
|
|
366
518
|
};
|
|
367
519
|
|
|
520
|
+
/**
|
|
521
|
+
* @this {IDBCursorFull}
|
|
522
|
+
* @returns {void}
|
|
523
|
+
*/
|
|
368
524
|
IDBCursor.prototype.__sourceOrEffectiveObjStoreDeleted = function () {
|
|
369
525
|
IDBObjectStore.__invalidStateIfDeleted(this.__store, "The cursor's effective object store has been deleted");
|
|
370
|
-
if (this.__indexSource)
|
|
526
|
+
if (this.__indexSource) {
|
|
527
|
+
IDBIndex.__invalidStateIfDeleted(
|
|
528
|
+
/** @type {import('./IDBIndex.js').IDBIndexFull} */ (this.source),
|
|
529
|
+
"The cursor's index source has been deleted"
|
|
530
|
+
);
|
|
531
|
+
}
|
|
371
532
|
};
|
|
372
533
|
|
|
534
|
+
/**
|
|
535
|
+
* @this {IDBCursorFull}
|
|
536
|
+
* @returns {void}
|
|
537
|
+
*/
|
|
373
538
|
IDBCursor.prototype.__invalidateCache = function () {
|
|
539
|
+
// @ts-expect-error Why is this not being found?
|
|
374
540
|
this.__prefetchedData = null;
|
|
375
541
|
};
|
|
376
542
|
|
|
543
|
+
/**
|
|
544
|
+
*
|
|
545
|
+
* @param {import('./Key.js').Key} [key]
|
|
546
|
+
* @param {boolean} [advanceContinue]
|
|
547
|
+
* @this {IDBCursorFull}
|
|
548
|
+
* @returns {void}
|
|
549
|
+
*/
|
|
377
550
|
IDBCursor.prototype.__continue = function (key, advanceContinue) {
|
|
378
551
|
const me = this;
|
|
379
552
|
const advanceState = me.__advanceCount !== undefined;
|
|
@@ -395,20 +568,38 @@ IDBCursor.prototype.__continue = function (key, advanceContinue) {
|
|
|
395
568
|
this.__continueFinish(key, undefined, advanceState);
|
|
396
569
|
};
|
|
397
570
|
|
|
571
|
+
/**
|
|
572
|
+
*
|
|
573
|
+
* @param {import('./Key.js').Key} key
|
|
574
|
+
* @param {import('./Key.js').Key} primaryKey
|
|
575
|
+
* @param {boolean} advanceState
|
|
576
|
+
* @this {IDBCursorFull}
|
|
577
|
+
* @returns {void}
|
|
578
|
+
*/
|
|
398
579
|
IDBCursor.prototype.__continueFinish = function (key, primaryKey, advanceState) {
|
|
399
580
|
const me = this;
|
|
400
581
|
const recordsToPreloadOnContinue = me.__advanceCount || CFG.cursorPreloadPackSize || 100;
|
|
401
582
|
me.__gotValue = false;
|
|
402
583
|
me.__request.__done = false;
|
|
403
584
|
|
|
404
|
-
|
|
585
|
+
/** @type {import('./IDBTransaction.js').IDBTransactionFull} */ (
|
|
586
|
+
me.__store.transaction
|
|
587
|
+
).__pushToQueue(me.__request, function cursorContinue (tx, args, success, error, executeNextRequest) {
|
|
588
|
+
/**
|
|
589
|
+
* @param {import('./Key.js').Key} k
|
|
590
|
+
* @param {import('./Key.js').Value} val
|
|
591
|
+
* @param {import('./Key.js').Key} primKey
|
|
592
|
+
* @returns {void}
|
|
593
|
+
*/
|
|
405
594
|
function triggerSuccess (k, val, primKey) {
|
|
406
595
|
if (advanceState) {
|
|
407
|
-
if (me.__advanceCount >= 2 && k !== undefined) {
|
|
596
|
+
if (me.__advanceCount && me.__advanceCount >= 2 && k !== undefined) {
|
|
408
597
|
me.__advanceCount--;
|
|
409
598
|
me.__key = k;
|
|
410
599
|
me.__continue(undefined, true);
|
|
411
|
-
|
|
600
|
+
/** @type {() => void} */ (
|
|
601
|
+
executeNextRequest
|
|
602
|
+
)(); // We don't call success yet but do need to advance the transaction queue
|
|
412
603
|
return;
|
|
413
604
|
}
|
|
414
605
|
me.__advanceCount = undefined;
|
|
@@ -420,8 +611,11 @@ IDBCursor.prototype.__continueFinish = function (key, primaryKey, advanceState)
|
|
|
420
611
|
me.__prefetchedIndex++;
|
|
421
612
|
if (me.__prefetchedIndex < me.__prefetchedData.length) {
|
|
422
613
|
me.__decode(me.__prefetchedData.item(me.__prefetchedIndex), function (k, val, primKey, encKey) {
|
|
614
|
+
/**
|
|
615
|
+
* @returns {void}
|
|
616
|
+
*/
|
|
423
617
|
function checkKey () {
|
|
424
|
-
const cmpResult = key === undefined || cmp(k, key);
|
|
618
|
+
const cmpResult = Number(key === undefined) || cmp(k, key);
|
|
425
619
|
if (cmpResult > 0 || (
|
|
426
620
|
cmpResult === 0 && (
|
|
427
621
|
me.__unique || primaryKey === undefined || cmp(primKey, primaryKey) >= 0
|
|
@@ -444,18 +638,34 @@ IDBCursor.prototype.__continueFinish = function (key, primaryKey, advanceState)
|
|
|
444
638
|
}
|
|
445
639
|
|
|
446
640
|
// No (or not enough) pre-fetched data, do query
|
|
447
|
-
me.__find(
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
641
|
+
me.__find(
|
|
642
|
+
key, primaryKey, tx, triggerSuccess,
|
|
643
|
+
/** @type {FindError} */
|
|
644
|
+
function (...args) {
|
|
645
|
+
me.__advanceCount = undefined;
|
|
646
|
+
const [t, err] = args;
|
|
647
|
+
error(t, err);
|
|
648
|
+
}, recordsToPreloadOnContinue
|
|
649
|
+
);
|
|
451
650
|
});
|
|
452
651
|
};
|
|
453
652
|
|
|
653
|
+
/**
|
|
654
|
+
* @this {IDBCursorFull}
|
|
655
|
+
* @returns {void}
|
|
656
|
+
*/
|
|
454
657
|
IDBCursor.prototype.continue = function (/* key */) {
|
|
455
658
|
// eslint-disable-next-line prefer-rest-params
|
|
456
659
|
this.__continue(arguments[0]);
|
|
457
660
|
};
|
|
458
661
|
|
|
662
|
+
/**
|
|
663
|
+
*
|
|
664
|
+
* @param {import('./Key.js').Key} key
|
|
665
|
+
* @param {import('./Key.js').Key} primaryKey
|
|
666
|
+
* @this {IDBCursorFull}
|
|
667
|
+
* @returns {void}
|
|
668
|
+
*/
|
|
459
669
|
IDBCursor.prototype.continuePrimaryKey = function (key, primaryKey) {
|
|
460
670
|
const me = this;
|
|
461
671
|
IDBTransaction.__assertActive(me.__store.transaction);
|
|
@@ -479,6 +689,10 @@ IDBCursor.prototype.continuePrimaryKey = function (key, primaryKey) {
|
|
|
479
689
|
) {
|
|
480
690
|
throw createDOMException('DataError', 'Cannot continue the cursor in an unexpected direction');
|
|
481
691
|
}
|
|
692
|
+
|
|
693
|
+
/**
|
|
694
|
+
* @returns {void}
|
|
695
|
+
*/
|
|
482
696
|
function noErrors () {
|
|
483
697
|
me.__continueFinish(key, primaryKey, false);
|
|
484
698
|
}
|
|
@@ -499,6 +713,12 @@ IDBCursor.prototype.continuePrimaryKey = function (key, primaryKey) {
|
|
|
499
713
|
}
|
|
500
714
|
};
|
|
501
715
|
|
|
716
|
+
/**
|
|
717
|
+
*
|
|
718
|
+
* @param {Integer} count
|
|
719
|
+
* @this {IDBCursorFull}
|
|
720
|
+
* @returns {void}
|
|
721
|
+
*/
|
|
502
722
|
IDBCursor.prototype.advance = function (count) {
|
|
503
723
|
const me = this;
|
|
504
724
|
count = util.enforceRange(count, 'unsigned long');
|
|
@@ -511,11 +731,23 @@ IDBCursor.prototype.advance = function (count) {
|
|
|
511
731
|
me.__continue();
|
|
512
732
|
};
|
|
513
733
|
|
|
734
|
+
/**
|
|
735
|
+
* @typedef {any} AnyValue
|
|
736
|
+
*/
|
|
737
|
+
|
|
738
|
+
/**
|
|
739
|
+
*
|
|
740
|
+
* @param {AnyValue} valueToUpdate
|
|
741
|
+
* @this {IDBCursorFull}
|
|
742
|
+
* @returns {IDBRequest}
|
|
743
|
+
*/
|
|
514
744
|
IDBCursor.prototype.update = function (valueToUpdate) {
|
|
515
745
|
const me = this;
|
|
516
746
|
if (!arguments.length) throw new TypeError('A value must be passed to update()');
|
|
517
747
|
IDBTransaction.__assertActive(me.__store.transaction);
|
|
518
|
-
|
|
748
|
+
/** @type {import('./IDBTransaction.js').IDBTransactionFull} */ (
|
|
749
|
+
me.__store.transaction
|
|
750
|
+
).__assertWritable();
|
|
519
751
|
me.__sourceOrEffectiveObjStoreDeleted();
|
|
520
752
|
if (!me.__gotValue) {
|
|
521
753
|
throw createDOMException('InvalidStateError', 'The cursor is being iterated or has iterated past its end.');
|
|
@@ -523,8 +755,15 @@ IDBCursor.prototype.update = function (valueToUpdate) {
|
|
|
523
755
|
if (me.__keyOnly) {
|
|
524
756
|
throw createDOMException('InvalidStateError', 'This cursor method cannot be called when the key only flag has been set.');
|
|
525
757
|
}
|
|
526
|
-
const request =
|
|
758
|
+
const request = /** @type {import('./IDBTransaction.js').IDBTransactionFull} */ (
|
|
759
|
+
me.__store.transaction
|
|
760
|
+
).__createRequest(me);
|
|
527
761
|
const key = me.primaryKey;
|
|
762
|
+
|
|
763
|
+
/**
|
|
764
|
+
* @param {import('./Key.js').Value} clonedValue
|
|
765
|
+
* @returns {void}
|
|
766
|
+
*/
|
|
528
767
|
function addToQueue (clonedValue) {
|
|
529
768
|
// We set the `invalidateCache` argument to `false` since the old value shouldn't be accessed
|
|
530
769
|
IDBObjectStore.__storingRecordObjectStore(request, me.__store, false, clonedValue, false, key);
|
|
@@ -542,10 +781,16 @@ IDBCursor.prototype.update = function (valueToUpdate) {
|
|
|
542
781
|
return request;
|
|
543
782
|
};
|
|
544
783
|
|
|
784
|
+
/**
|
|
785
|
+
* @this {IDBCursorFull}
|
|
786
|
+
* @returns {IDBRequest}
|
|
787
|
+
*/
|
|
545
788
|
IDBCursor.prototype.delete = function () {
|
|
546
789
|
const me = this;
|
|
547
790
|
IDBTransaction.__assertActive(me.__store.transaction);
|
|
548
|
-
|
|
791
|
+
/** @type {import('./IDBTransaction.js').IDBTransactionFull} */ (
|
|
792
|
+
me.__store.transaction
|
|
793
|
+
).__assertWritable();
|
|
549
794
|
me.__sourceOrEffectiveObjStoreDeleted();
|
|
550
795
|
if (!me.__gotValue) {
|
|
551
796
|
throw createDOMException('InvalidStateError', 'The cursor is being iterated or has iterated past its end.');
|
|
@@ -553,23 +798,33 @@ IDBCursor.prototype.delete = function () {
|
|
|
553
798
|
if (me.__keyOnly) {
|
|
554
799
|
throw createDOMException('InvalidStateError', 'This cursor method cannot be called when the key only flag has been set.');
|
|
555
800
|
}
|
|
556
|
-
return
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
801
|
+
return /** @type {import('./IDBTransaction.js').IDBTransactionFull} */ (
|
|
802
|
+
this.__store.transaction
|
|
803
|
+
).__addToTransactionQueue(function cursorDelete (tx, args, success, error) {
|
|
804
|
+
me.__find(
|
|
805
|
+
undefined, undefined, tx,
|
|
806
|
+
/** @type {KeySuccess} */
|
|
807
|
+
function (key, value, primaryKey) {
|
|
808
|
+
const sql = 'DELETE FROM ' + util.escapeStoreNameForSQL(me.__store.__currentName) + ' WHERE "key" = ?';
|
|
809
|
+
CFG.DEBUG && console.log(sql, key, primaryKey);
|
|
810
|
+
// Key.convertValueToKey(primaryKey); // Already checked when entered
|
|
811
|
+
tx.executeSql(sql, [util.escapeSQLiteStatement(
|
|
812
|
+
/** @type {string} */ (Key.encode(primaryKey))
|
|
813
|
+
)], function (tx, data) {
|
|
814
|
+
if (data.rowsAffected === 1) {
|
|
815
|
+
// We don't invalidate the cache (as we don't access it anymore
|
|
816
|
+
// and it will set the index off)
|
|
817
|
+
success(undefined);
|
|
818
|
+
} else {
|
|
819
|
+
// @ts-expect-error Apparently ok
|
|
820
|
+
error('No rows with key found' + key);
|
|
821
|
+
}
|
|
822
|
+
}, function (tx, data) {
|
|
823
|
+
error(data);
|
|
824
|
+
return true;
|
|
825
|
+
});
|
|
826
|
+
}, error
|
|
827
|
+
);
|
|
573
828
|
}, undefined, me);
|
|
574
829
|
};
|
|
575
830
|
|
|
@@ -583,10 +838,14 @@ Object.defineProperty(IDBCursor, 'prototype', {
|
|
|
583
838
|
writable: false
|
|
584
839
|
});
|
|
585
840
|
|
|
841
|
+
/**
|
|
842
|
+
* @class
|
|
843
|
+
*/
|
|
586
844
|
function IDBCursorWithValue () {
|
|
587
845
|
throw new TypeError('Illegal constructor');
|
|
588
846
|
}
|
|
589
847
|
|
|
848
|
+
// @ts-expect-error It's ok
|
|
590
849
|
IDBCursorWithValue.prototype = Object.create(IDBCursor.prototype);
|
|
591
850
|
Object.defineProperty(IDBCursorWithValue.prototype, 'constructor', {
|
|
592
851
|
enumerable: false,
|
|
@@ -596,13 +855,26 @@ Object.defineProperty(IDBCursorWithValue.prototype, 'constructor', {
|
|
|
596
855
|
});
|
|
597
856
|
|
|
598
857
|
const IDBCursorWithValueAlias = IDBCursorWithValue;
|
|
858
|
+
/**
|
|
859
|
+
*
|
|
860
|
+
* @param {...any} args
|
|
861
|
+
* @returns {IDBCursorWithValueFull}
|
|
862
|
+
*/
|
|
599
863
|
IDBCursorWithValue.__createInstance = function (...args) {
|
|
864
|
+
/**
|
|
865
|
+
* @class
|
|
866
|
+
* @this {IDBCursorWithValueFull}
|
|
867
|
+
*/
|
|
600
868
|
function IDBCursorWithValue () {
|
|
601
|
-
|
|
869
|
+
const [query, direction, store, source, keyColumnName, valueColumnName, count] = args;
|
|
870
|
+
IDBCursor.__super.call(this, query, direction, store, source, keyColumnName, valueColumnName, count);
|
|
871
|
+
// @ts-expect-error It's ok
|
|
602
872
|
this[Symbol.toStringTag] = 'IDBCursorWithValue';
|
|
603
873
|
util.defineReadonlyProperties(this, 'value');
|
|
604
874
|
}
|
|
605
875
|
IDBCursorWithValue.prototype = IDBCursorWithValueAlias.prototype;
|
|
876
|
+
|
|
877
|
+
// @ts-expect-error It's ok
|
|
606
878
|
return new IDBCursorWithValue();
|
|
607
879
|
};
|
|
608
880
|
|