indexeddbshim 12.0.0 → 13.0.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 +1 -1
- package/badges/licenses-badge-dev.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 +288 -0
- package/dist/IDBCursor.d.ts.map +1 -0
- package/dist/IDBDatabase.d.ts +143 -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 +88 -0
- package/dist/IDBRequest.d.ts.map +1 -0
- package/dist/IDBTransaction.d.ts +270 -0
- package/dist/IDBTransaction.d.ts.map +1 -0
- package/dist/IDBVersionChangeEvent.d.ts +22 -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 +553 -252
- 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 +17560 -1302
- package/dist/indexeddbshim-UnicodeIdentifiers-node.cjs.map +1 -1
- package/dist/indexeddbshim-UnicodeIdentifiers.js +4367 -1604
- 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 +17556 -1302
- package/dist/indexeddbshim-node.cjs.map +1 -1
- package/dist/indexeddbshim-noninvasive.js +4362 -1604
- 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 +4362 -1604
- 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/index.html +1 -1
- package/package.json +51 -37
- package/src/CFG.js +89 -11
- package/src/DOMException.js +117 -31
- package/src/DOMStringList.js +93 -3
- package/src/Event.js +19 -4
- package/src/IDBCursor.js +350 -76
- package/src/IDBDatabase.js +88 -10
- package/src/IDBFactory.js +331 -61
- package/src/IDBIndex.js +393 -110
- package/src/IDBKeyRange.js +90 -17
- package/src/IDBObjectStore.js +347 -86
- package/src/IDBRequest.js +59 -1
- package/src/IDBTransaction.js +254 -46
- package/src/IDBVersionChangeEvent.js +28 -3
- package/src/Key.d.ts +1 -0
- package/src/Key.js +272 -162
- 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 +159 -22
- package/src/unicode-regex.js +2 -0
- package/src/util.js +229 -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,50 +235,66 @@ 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
|
|
240
|
+
const sqlStr = sql.join(' ');
|
|
241
|
+
if (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) {
|
|
149
247
|
me.__prefetchedIndex = 0;
|
|
150
248
|
me.__prefetchedData = data.rows;
|
|
151
|
-
CFG.DEBUG
|
|
249
|
+
if (CFG.DEBUG) { console.log('Preloaded ' + me.__prefetchedData.length + ' records for cursor'); }
|
|
152
250
|
me.__decode(data.rows.item(0), success);
|
|
153
251
|
} else if (data.rows.length === 1) {
|
|
154
252
|
me.__decode(data.rows.item(0), success);
|
|
155
253
|
} else {
|
|
156
|
-
CFG.DEBUG
|
|
254
|
+
if (CFG.DEBUG) { console.log('Reached end of cursors'); }
|
|
157
255
|
success(undefined, undefined, undefined);
|
|
158
256
|
}
|
|
159
257
|
}, function (tx, err) {
|
|
160
|
-
CFG.DEBUG
|
|
258
|
+
if (CFG.DEBUG) { console.log('Could not execute Cursor.continue', sqlStr, sqlValues); }
|
|
161
259
|
error(err);
|
|
260
|
+
return false;
|
|
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
|
|
|
170
279
|
if (me.__prefetchedData && me.__prefetchedData.length === me.__prefetchedIndex) {
|
|
171
|
-
CFG.DEBUG
|
|
280
|
+
if (CFG.DEBUG) { console.log('Reached end of multiEntry cursor'); }
|
|
172
281
|
success(undefined, undefined, undefined);
|
|
173
282
|
return;
|
|
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
|
|
337
|
+
const sqlStr = sql.join(' ');
|
|
338
|
+
if (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,49 +393,62 @@ 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
|
}
|
|
280
403
|
};
|
|
281
|
-
CFG.DEBUG
|
|
404
|
+
if (CFG.DEBUG) { console.log('Preloaded ' + me.__prefetchedData.length + ' records for multiEntry cursor'); }
|
|
282
405
|
me.__decode(rows[0], success);
|
|
283
406
|
} else if (rows.length === 1) {
|
|
284
|
-
CFG.DEBUG
|
|
407
|
+
if (CFG.DEBUG) { console.log('Reached end of multiEntry cursor'); }
|
|
285
408
|
me.__decode(rows[0], success);
|
|
286
409
|
} else {
|
|
287
|
-
CFG.DEBUG
|
|
410
|
+
if (CFG.DEBUG) { console.log('Reached end of multiEntry cursor'); }
|
|
288
411
|
success(undefined, undefined, undefined);
|
|
289
412
|
}
|
|
290
413
|
} else {
|
|
291
|
-
CFG.DEBUG
|
|
414
|
+
if (CFG.DEBUG) { console.log('Reached end of multiEntry cursor'); }
|
|
292
415
|
success(undefined, undefined, undefined);
|
|
293
416
|
}
|
|
294
417
|
}, function (tx, err) {
|
|
295
|
-
CFG.DEBUG
|
|
418
|
+
if (CFG.DEBUG) { console.log('Could not execute Cursor.continue', sqlStr, sqlValues); }
|
|
296
419
|
error(err);
|
|
420
|
+
return false;
|
|
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) {
|
|
@@ -362,18 +514,39 @@ IDBCursor.prototype.__decode = function (rowItem, callback) {
|
|
|
362
514
|
);
|
|
363
515
|
const val = me.__valueDecoder.decode(encVal);
|
|
364
516
|
const primaryKey = Key.decode(encPrimaryKey);
|
|
365
|
-
callback(key, val, primaryKey, encKey
|
|
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,25 @@ 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
|
-
if (!arguments.length)
|
|
746
|
+
if (!arguments.length) {
|
|
747
|
+
throw new TypeError('A value must be passed to update()');
|
|
748
|
+
}
|
|
517
749
|
IDBTransaction.__assertActive(me.__store.transaction);
|
|
518
|
-
|
|
750
|
+
/** @type {import('./IDBTransaction.js').IDBTransactionFull} */ (
|
|
751
|
+
me.__store.transaction
|
|
752
|
+
).__assertWritable();
|
|
519
753
|
me.__sourceOrEffectiveObjStoreDeleted();
|
|
520
754
|
if (!me.__gotValue) {
|
|
521
755
|
throw createDOMException('InvalidStateError', 'The cursor is being iterated or has iterated past its end.');
|
|
@@ -523,8 +757,15 @@ IDBCursor.prototype.update = function (valueToUpdate) {
|
|
|
523
757
|
if (me.__keyOnly) {
|
|
524
758
|
throw createDOMException('InvalidStateError', 'This cursor method cannot be called when the key only flag has been set.');
|
|
525
759
|
}
|
|
526
|
-
const request =
|
|
760
|
+
const request = /** @type {import('./IDBTransaction.js').IDBTransactionFull} */ (
|
|
761
|
+
me.__store.transaction
|
|
762
|
+
).__createRequest(me);
|
|
527
763
|
const key = me.primaryKey;
|
|
764
|
+
|
|
765
|
+
/**
|
|
766
|
+
* @param {import('./Key.js').Value} clonedValue
|
|
767
|
+
* @returns {void}
|
|
768
|
+
*/
|
|
528
769
|
function addToQueue (clonedValue) {
|
|
529
770
|
// We set the `invalidateCache` argument to `false` since the old value shouldn't be accessed
|
|
530
771
|
IDBObjectStore.__storingRecordObjectStore(request, me.__store, false, clonedValue, false, key);
|
|
@@ -542,10 +783,16 @@ IDBCursor.prototype.update = function (valueToUpdate) {
|
|
|
542
783
|
return request;
|
|
543
784
|
};
|
|
544
785
|
|
|
786
|
+
/**
|
|
787
|
+
* @this {IDBCursorFull}
|
|
788
|
+
* @returns {IDBRequest}
|
|
789
|
+
*/
|
|
545
790
|
IDBCursor.prototype.delete = function () {
|
|
546
791
|
const me = this;
|
|
547
792
|
IDBTransaction.__assertActive(me.__store.transaction);
|
|
548
|
-
|
|
793
|
+
/** @type {import('./IDBTransaction.js').IDBTransactionFull} */ (
|
|
794
|
+
me.__store.transaction
|
|
795
|
+
).__assertWritable();
|
|
549
796
|
me.__sourceOrEffectiveObjStoreDeleted();
|
|
550
797
|
if (!me.__gotValue) {
|
|
551
798
|
throw createDOMException('InvalidStateError', 'The cursor is being iterated or has iterated past its end.');
|
|
@@ -553,23 +800,33 @@ IDBCursor.prototype.delete = function () {
|
|
|
553
800
|
if (me.__keyOnly) {
|
|
554
801
|
throw createDOMException('InvalidStateError', 'This cursor method cannot be called when the key only flag has been set.');
|
|
555
802
|
}
|
|
556
|
-
return
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
803
|
+
return /** @type {import('./IDBTransaction.js').IDBTransactionFull} */ (
|
|
804
|
+
this.__store.transaction
|
|
805
|
+
).__addToTransactionQueue(function cursorDelete (tx, args, success, error) {
|
|
806
|
+
me.__find(
|
|
807
|
+
undefined, undefined, tx,
|
|
808
|
+
/** @type {KeySuccess} */
|
|
809
|
+
function (key, value, primaryKey) {
|
|
810
|
+
const sql = 'DELETE FROM ' + util.escapeStoreNameForSQL(me.__store.__currentName) + ' WHERE "key" = ?';
|
|
811
|
+
if (CFG.DEBUG) { console.log(sql, key, primaryKey); }
|
|
812
|
+
// Key.convertValueToKey(primaryKey); // Already checked when entered
|
|
813
|
+
tx.executeSql(sql, [util.escapeSQLiteStatement(
|
|
814
|
+
/** @type {string} */ (Key.encode(primaryKey))
|
|
815
|
+
)], function (tx, data) {
|
|
816
|
+
if (data.rowsAffected === 1) {
|
|
817
|
+
// We don't invalidate the cache (as we don't access it anymore
|
|
818
|
+
// and it will set the index off)
|
|
819
|
+
success(undefined);
|
|
820
|
+
} else {
|
|
821
|
+
// @ts-expect-error Apparently ok
|
|
822
|
+
error('No rows with key found' + key);
|
|
823
|
+
}
|
|
824
|
+
}, function (tx, data) {
|
|
825
|
+
error(data);
|
|
826
|
+
return false;
|
|
827
|
+
});
|
|
828
|
+
}, error
|
|
829
|
+
);
|
|
573
830
|
}, undefined, me);
|
|
574
831
|
};
|
|
575
832
|
|
|
@@ -583,10 +840,14 @@ Object.defineProperty(IDBCursor, 'prototype', {
|
|
|
583
840
|
writable: false
|
|
584
841
|
});
|
|
585
842
|
|
|
843
|
+
/**
|
|
844
|
+
* @class
|
|
845
|
+
*/
|
|
586
846
|
function IDBCursorWithValue () {
|
|
587
847
|
throw new TypeError('Illegal constructor');
|
|
588
848
|
}
|
|
589
849
|
|
|
850
|
+
// @ts-expect-error It's ok
|
|
590
851
|
IDBCursorWithValue.prototype = Object.create(IDBCursor.prototype);
|
|
591
852
|
Object.defineProperty(IDBCursorWithValue.prototype, 'constructor', {
|
|
592
853
|
enumerable: false,
|
|
@@ -596,13 +857,26 @@ Object.defineProperty(IDBCursorWithValue.prototype, 'constructor', {
|
|
|
596
857
|
});
|
|
597
858
|
|
|
598
859
|
const IDBCursorWithValueAlias = IDBCursorWithValue;
|
|
860
|
+
/**
|
|
861
|
+
*
|
|
862
|
+
* @param {...any} args
|
|
863
|
+
* @returns {IDBCursorWithValueFull}
|
|
864
|
+
*/
|
|
599
865
|
IDBCursorWithValue.__createInstance = function (...args) {
|
|
866
|
+
/**
|
|
867
|
+
* @class
|
|
868
|
+
* @this {IDBCursorWithValueFull}
|
|
869
|
+
*/
|
|
600
870
|
function IDBCursorWithValue () {
|
|
601
|
-
|
|
871
|
+
const [query, direction, store, source, keyColumnName, valueColumnName, count] = args;
|
|
872
|
+
IDBCursor.__super.call(this, query, direction, store, source, keyColumnName, valueColumnName, count);
|
|
873
|
+
// @ts-expect-error It's ok
|
|
602
874
|
this[Symbol.toStringTag] = 'IDBCursorWithValue';
|
|
603
875
|
util.defineReadonlyProperties(this, 'value');
|
|
604
876
|
}
|
|
605
877
|
IDBCursorWithValue.prototype = IDBCursorWithValueAlias.prototype;
|
|
878
|
+
|
|
879
|
+
// @ts-expect-error It's ok
|
|
606
880
|
return new IDBCursorWithValue();
|
|
607
881
|
};
|
|
608
882
|
|