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.
Files changed (98) hide show
  1. package/badges/licenses-badge.svg +1 -1
  2. package/dist/CFG.d.ts +80 -0
  3. package/dist/CFG.d.ts.map +1 -0
  4. package/dist/DOMException.d.ts +71 -0
  5. package/dist/DOMException.d.ts.map +1 -0
  6. package/dist/DOMStringList.d.ts +20 -0
  7. package/dist/DOMStringList.d.ts.map +1 -0
  8. package/dist/Event.d.ts +21 -0
  9. package/dist/Event.d.ts.map +1 -0
  10. package/dist/IDBCursor.d.ts +289 -0
  11. package/dist/IDBCursor.d.ts.map +1 -0
  12. package/dist/IDBDatabase.d.ts +144 -0
  13. package/dist/IDBDatabase.d.ts.map +1 -0
  14. package/dist/IDBFactory.d.ts +96 -0
  15. package/dist/IDBFactory.d.ts.map +1 -0
  16. package/dist/IDBIndex.d.ts +243 -0
  17. package/dist/IDBIndex.d.ts.map +1 -0
  18. package/dist/IDBKeyRange.d.ts +79 -0
  19. package/dist/IDBKeyRange.d.ts.map +1 -0
  20. package/dist/IDBObjectStore.d.ts +273 -0
  21. package/dist/IDBObjectStore.d.ts.map +1 -0
  22. package/dist/IDBRequest.d.ts +90 -0
  23. package/dist/IDBRequest.d.ts.map +1 -0
  24. package/dist/IDBTransaction.d.ts +271 -0
  25. package/dist/IDBTransaction.d.ts.map +1 -0
  26. package/dist/IDBVersionChangeEvent.d.ts +23 -0
  27. package/dist/IDBVersionChangeEvent.d.ts.map +1 -0
  28. package/dist/Key.d.ts +214 -0
  29. package/dist/Key.d.ts.map +1 -0
  30. package/dist/Sca.d.ts +31 -0
  31. package/dist/Sca.d.ts.map +1 -0
  32. package/dist/UnicodeIdentifiers.d.ts +3 -0
  33. package/dist/UnicodeIdentifiers.d.ts.map +1 -0
  34. package/dist/browser-UnicodeIdentifiers.d.ts +2 -0
  35. package/dist/browser-UnicodeIdentifiers.d.ts.map +1 -0
  36. package/dist/browser-noninvasive.d.ts +3 -0
  37. package/dist/browser-noninvasive.d.ts.map +1 -0
  38. package/dist/browser.d.ts +2 -0
  39. package/dist/browser.d.ts.map +1 -0
  40. package/dist/cmp.d.ts +9 -0
  41. package/dist/cmp.d.ts.map +1 -0
  42. package/dist/indexeddbshim-Key.js +491 -189
  43. package/dist/indexeddbshim-Key.js.map +1 -1
  44. package/dist/indexeddbshim-Key.min.js +2 -2
  45. package/dist/indexeddbshim-Key.min.js.map +1 -1
  46. package/dist/indexeddbshim-UnicodeIdentifiers-node.cjs +17263 -1396
  47. package/dist/indexeddbshim-UnicodeIdentifiers-node.cjs.map +1 -1
  48. package/dist/indexeddbshim-UnicodeIdentifiers.js +3892 -1271
  49. package/dist/indexeddbshim-UnicodeIdentifiers.js.map +1 -1
  50. package/dist/indexeddbshim-UnicodeIdentifiers.min.js +2 -2
  51. package/dist/indexeddbshim-UnicodeIdentifiers.min.js.map +1 -1
  52. package/dist/indexeddbshim-node.cjs +17259 -1396
  53. package/dist/indexeddbshim-node.cjs.map +1 -1
  54. package/dist/indexeddbshim-noninvasive.js +3887 -1271
  55. package/dist/indexeddbshim-noninvasive.js.map +1 -1
  56. package/dist/indexeddbshim-noninvasive.min.js +2 -2
  57. package/dist/indexeddbshim-noninvasive.min.js.map +1 -1
  58. package/dist/indexeddbshim.js +3887 -1271
  59. package/dist/indexeddbshim.js.map +1 -1
  60. package/dist/indexeddbshim.min.js +2 -2
  61. package/dist/indexeddbshim.min.js.map +1 -1
  62. package/dist/node-UnicodeIdentifiers.d.ts +8 -0
  63. package/dist/node-UnicodeIdentifiers.d.ts.map +1 -0
  64. package/dist/node.d.ts +8 -0
  65. package/dist/node.d.ts.map +1 -0
  66. package/dist/nodeWebSQL.d.ts +3 -0
  67. package/dist/nodeWebSQL.d.ts.map +1 -0
  68. package/dist/setGlobalVars.d.ts +79 -0
  69. package/dist/setGlobalVars.d.ts.map +1 -0
  70. package/dist/unicode-regex.d.ts +3 -0
  71. package/dist/unicode-regex.d.ts.map +1 -0
  72. package/dist/util.d.ts +174 -0
  73. package/dist/util.d.ts.map +1 -0
  74. package/package.json +40 -27
  75. package/src/CFG.js +89 -11
  76. package/src/DOMException.js +116 -29
  77. package/src/DOMStringList.js +92 -2
  78. package/src/Event.js +19 -4
  79. package/src/IDBCursor.js +339 -67
  80. package/src/IDBDatabase.js +87 -10
  81. package/src/IDBFactory.js +319 -56
  82. package/src/IDBIndex.js +385 -96
  83. package/src/IDBKeyRange.js +86 -13
  84. package/src/IDBObjectStore.js +326 -68
  85. package/src/IDBRequest.js +59 -1
  86. package/src/IDBTransaction.js +247 -38
  87. package/src/IDBVersionChangeEvent.js +28 -3
  88. package/src/Key.js +273 -156
  89. package/src/Sca.js +29 -4
  90. package/src/browser-UnicodeIdentifiers.js +5 -1
  91. package/src/cmp.js +5 -5
  92. package/src/node-UnicodeIdentifiers.js +9 -0
  93. package/src/node.js +5 -0
  94. package/src/nodeWebSQL.js +11 -5
  95. package/src/setGlobalVars.js +156 -21
  96. package/src/unicode-regex.js +9 -1
  97. package/src/util.js +228 -40
  98. package/typings/shimIndexedDB.d.ts +9 -0
package/src/IDBIndex.js CHANGED
@@ -1,4 +1,4 @@
1
- import SyncPromise from 'sync-promise';
1
+ import SyncPromise from 'sync-promise-expanded';
2
2
  import {createDOMException} from './DOMException.js';
3
3
  import {IDBCursor, IDBCursorWithValue} from './IDBCursor.js';
4
4
  import * as util from './util.js';
@@ -11,22 +11,70 @@ import IDBObjectStore from './IDBObjectStore.js';
11
11
 
12
12
  const readonlyProperties = ['objectStore', 'keyPath', 'multiEntry', 'unique'];
13
13
 
14
- /* eslint-disable jsdoc/check-param-names */
14
+ /**
15
+ * @typedef {number} Integer
16
+ */
17
+
18
+ /**
19
+ * @typedef {{
20
+ * columnName: string,
21
+ * keyPath: import('./Key.js').KeyPath,
22
+ * optionalParams: {
23
+ * unique: boolean,
24
+ * multiEntry: boolean
25
+ * }
26
+ * deleted?: boolean,
27
+ * __deleted?: boolean,
28
+ * cursors?: import('./IDBCursor.js').IDBCursorWithValueFull[],
29
+ * }} IDBIndexProperties
30
+ */
31
+
15
32
  /**
16
33
  * IDB Index.
17
34
  * @see http://www.w3.org/TR/IndexedDB/#idl-def-IDBIndex
18
- * @param {IDBObjectStore} store
19
- * @param {IDBIndexProperties} indexProperties
20
35
  * @class
21
36
  */
22
37
  function IDBIndex () {
23
- /* eslint-enable jsdoc/check-param-names */
24
38
  throw new TypeError('Illegal constructor');
25
39
  }
26
40
  const IDBIndexAlias = IDBIndex;
41
+
42
+ /**
43
+ * @typedef {IDBIndex & {
44
+ * name: string,
45
+ * keyPath: import('./Key.js').KeyPath,
46
+ * multiEntry: boolean,
47
+ * unique: boolean,
48
+ * objectStore: import('./IDBObjectStore.js').IDBObjectStoreFull,
49
+ * __pendingCreate?: boolean,
50
+ * __deleted?: boolean,
51
+ * __originalName: string,
52
+ * __currentName: string,
53
+ * __pendingName?: string,
54
+ * __pendingDelete?: boolean,
55
+ * __name: string,
56
+ * __multiEntry: boolean,
57
+ * __unique: boolean,
58
+ * __objectStore: import('./IDBObjectStore.js').IDBObjectStoreFull,
59
+ * __keyPath: import('./Key.js').KeyPath,
60
+ * __recreated?: boolean
61
+ * }} IDBIndexFull
62
+ */
63
+
64
+ /**
65
+ *
66
+ * @param {import('./IDBObjectStore.js').IDBObjectStoreFull} store
67
+ * @param {IDBIndexProperties} indexProperties
68
+ * @returns {IDBIndexFull}
69
+ */
27
70
  IDBIndex.__createInstance = function (store, indexProperties) {
71
+ /**
72
+ * @class
73
+ * @this {IDBIndexFull}
74
+ */
28
75
  function IDBIndex () {
29
76
  const me = this;
77
+ // @ts-expect-error It's ok
30
78
  me[Symbol.toStringTag] = 'IDBIndex';
31
79
  util.defineReadonlyProperties(me, readonlyProperties);
32
80
  me.__objectStore = store;
@@ -38,16 +86,31 @@ IDBIndex.__createInstance = function (store, indexProperties) {
38
86
  me.__deleted = Boolean(indexProperties.__deleted);
39
87
  me.__objectStore.__cursors = indexProperties.cursors || [];
40
88
  Object.defineProperty(me, '__currentName', {
89
+ /**
90
+ * @this {IDBIndexFull}
91
+ * @returns {string}
92
+ */
41
93
  get () {
42
- return '__pendingName' in me ? me.__pendingName : me.name;
94
+ return '__pendingName' in me
95
+ ? /** @type {string} */ (me.__pendingName)
96
+ : me.name;
43
97
  }
44
98
  });
45
99
  Object.defineProperty(me, 'name', {
46
100
  enumerable: false,
47
101
  configurable: false,
102
+ /**
103
+ * @this {IDBIndexFull}
104
+ * @returns {string}
105
+ */
48
106
  get () {
49
107
  return this.__name;
50
108
  },
109
+ /**
110
+ * @param {string} newName
111
+ * @this {IDBIndexFull}
112
+ * @returns {void}
113
+ */
51
114
  set (newName) {
52
115
  const me = this;
53
116
  newName = util.convertToDOMString(newName);
@@ -72,7 +135,9 @@ IDBIndex.__createInstance = function (store, indexProperties) {
72
135
  objectStore.__indexes[newName] = me;
73
136
  objectStore.indexNames.splice(objectStore.indexNames.indexOf(oldName), 1, newName);
74
137
 
75
- const storeHandle = objectStore.transaction.__storeHandles[objectStore.name];
138
+ const storeHandle = /** @type {import('./IDBTransaction.js').IDBTransactionFull} */ (
139
+ objectStore.transaction
140
+ ).__storeHandles[objectStore.name];
76
141
  const oldIndexHandle = storeHandle.__indexHandles[oldName];
77
142
  oldIndexHandle.__name = newName; // Fix old references
78
143
  storeHandle.__indexHandles[newName] = oldIndexHandle; // Ensure new reference accessible
@@ -82,24 +147,37 @@ IDBIndex.__createInstance = function (store, indexProperties) {
82
147
  ['key', 'BLOB ' + (objectStore.autoIncrement ? 'UNIQUE, inc INTEGER PRIMARY KEY AUTOINCREMENT' : 'PRIMARY KEY')],
83
148
  ['value', 'BLOB']
84
149
  ].concat(
150
+ // @ts-expect-error Has numeric indexes instead of iterator
85
151
  [...objectStore.indexNames]
86
152
  .filter((indexName) => indexName !== newName)
87
153
  .map((indexName) => [util.escapeIndexNameForSQL(indexName), 'BLOB'])
88
154
  );
89
155
 
90
- me.__renameIndex(objectStore, oldName, newName, colInfoToPreserveArr, function (tx, success) {
91
- IDBIndexAlias.__updateIndexList(store, tx, function (store) {
92
- delete storeHandle.__pendingName;
93
- success(store);
94
- });
95
- });
156
+ me.__renameIndex(
157
+ objectStore, oldName, newName, colInfoToPreserveArr,
158
+ function (tx, success) {
159
+ IDBIndexAlias.__updateIndexList(store, tx, function (store) {
160
+ delete storeHandle.__pendingName;
161
+ success(store);
162
+ });
163
+ }
164
+ );
96
165
  }
97
166
  });
98
167
  }
99
168
  IDBIndex.prototype = IDBIndexAlias.prototype;
169
+
170
+ // @ts-expect-error It's ok
100
171
  return new IDBIndex();
101
172
  };
102
173
 
174
+ /**
175
+ *
176
+ * @param {IDBIndexFull} index
177
+ * @param {string} [msg]
178
+ * @throws {DOMException}
179
+ * @returns {void}
180
+ */
103
181
  IDBIndex.__invalidStateIfDeleted = function (index, msg) {
104
182
  if (index.__deleted || index.__pendingDelete || (
105
183
  index.__pendingCreate && index.objectStore.transaction && index.objectStore.transaction.__errored
@@ -110,10 +188,9 @@ IDBIndex.__invalidStateIfDeleted = function (index, msg) {
110
188
 
111
189
  /**
112
190
  * Clones an IDBIndex instance for a different IDBObjectStore instance.
113
- * @param {IDBIndex} index
114
- * @param {IDBObjectStore} store
115
- * @protected
116
- * @returns {IDBIndex}
191
+ * @param {IDBIndexFull} index
192
+ * @param {import('./IDBObjectStore.js').IDBObjectStoreFull} store
193
+ * @returns {IDBIndexFull}
117
194
  */
118
195
  IDBIndex.__clone = function (index, store) {
119
196
  const idx = IDBIndex.__createInstance(store, {
@@ -124,7 +201,11 @@ IDBIndex.__clone = function (index, store) {
124
201
  unique: index.unique
125
202
  }
126
203
  });
127
- ['__pendingCreate', '__pendingDelete', '__deleted', '__originalName', '__recreated'].forEach((p) => {
204
+ /** @type {const} */ ([
205
+ '__pendingCreate', '__pendingDelete', '__deleted',
206
+ '__originalName', '__recreated'
207
+ ]).forEach((p) => {
208
+ // @ts-expect-error Why is this type "never"?
128
209
  idx[p] = index[p];
129
210
  });
130
211
  return idx;
@@ -132,10 +213,9 @@ IDBIndex.__clone = function (index, store) {
132
213
 
133
214
  /**
134
215
  * Creates a new index on an object store.
135
- * @param {IDBObjectStore} store
136
- * @param {IDBIndex} index
216
+ * @param {import('./IDBObjectStore.js').IDBObjectStoreFull} store
217
+ * @param {IDBIndexFull} index
137
218
  * @returns {void}
138
- * @protected
139
219
  */
140
220
  IDBIndex.__createIndex = function (store, index) {
141
221
  const indexName = index.name;
@@ -160,14 +240,27 @@ IDBIndex.__createIndex = function (store, index) {
160
240
 
161
241
  // Create the index in WebSQL
162
242
  const {transaction} = store;
163
- transaction.__addNonRequestToTransactionQueue(function createIndex (tx, args, success, failure) {
243
+ /** @type {import('./IDBTransaction.js').IDBTransactionFull} */ (
244
+ transaction
245
+ ).__addNonRequestToTransactionQueue(function createIndex (tx, args, success, failure) {
164
246
  const columnExists = idx && (idx.__deleted || idx.__recreated); // This check must occur here rather than earlier as properties may not have been set yet otherwise
247
+
248
+ /** @type {{[key: string]: boolean}} */
165
249
  let indexValues = {};
166
250
 
251
+ /**
252
+ * @param {SQLTransaction} tx
253
+ * @param {SQLError} err
254
+ * @returns {void}
255
+ */
167
256
  function error (tx, err) {
168
257
  failure(createDOMException('UnknownError', 'Could not create index "' + indexName + '"' + err.code + '::' + err.message, err));
169
258
  }
170
259
 
260
+ /**
261
+ * @param {SQLTransaction} tx
262
+ * @returns {void}
263
+ */
171
264
  function applyIndex (tx) {
172
265
  // Update the object store's index list
173
266
  IDBIndex.__updateIndexList(store, tx, function () {
@@ -176,17 +269,26 @@ IDBIndex.__createIndex = function (store, index) {
176
269
  CFG.DEBUG && console.log('Adding existing ' + storeName + ' records to the ' + indexName + ' index');
177
270
  addIndexEntry(0);
178
271
 
272
+ /**
273
+ * @param {Integer} i
274
+ * @returns {void}
275
+ */
179
276
  function addIndexEntry (i) {
180
277
  if (i < data.rows.length) {
181
278
  try {
182
279
  const value = Sca.decode(util.unescapeSQLiteResponse(data.rows.item(i).value));
183
- let indexKey = Key.extractKeyValueDecodedFromValueUsingKeyPath(value, index.keyPath, index.multiEntry); // Todo: Do we need this stricter error checking?
184
- if (indexKey.invalid || indexKey.failure) { // Todo: Do we need invalid checks and should we instead treat these as being duplicates?
280
+ const indexKey = Key.extractKeyValueDecodedFromValueUsingKeyPath(value, index.keyPath, index.multiEntry); // Todo: Do we need this stricter error checking?
281
+ if (
282
+ ('invalid' in indexKey && indexKey.invalid) ||
283
+ ('failure' in indexKey && indexKey.failure)
284
+ ) { // Todo: Do we need invalid checks and should we instead treat these as being duplicates?
185
285
  throw new Error('Go to catch; ignore bad indexKey');
186
286
  }
187
- indexKey = Key.encode(indexKey.value, index.multiEntry);
287
+ const indexKeyStr = /** @type {string} */ (
288
+ Key.encode(indexKey.value, index.multiEntry)
289
+ );
188
290
  if (index.unique) {
189
- if (indexValues[indexKey]) {
291
+ if (indexValues[indexKeyStr]) {
190
292
  indexValues = {};
191
293
  failure(createDOMException(
192
294
  'ConstraintError',
@@ -194,16 +296,17 @@ IDBIndex.__createIndex = function (store, index) {
194
296
  ));
195
297
  return;
196
298
  }
197
- indexValues[indexKey] = true;
299
+ indexValues[indexKeyStr] = true;
198
300
  }
199
301
 
200
302
  tx.executeSql(
201
303
  'UPDATE ' + util.escapeStoreNameForSQL(storeName) + ' SET ' +
202
304
  util.escapeIndexNameForSQL(indexName) + ' = ? WHERE "key" = ?',
203
- [util.escapeSQLiteStatement(indexKey), data.rows.item(i).key],
305
+ [util.escapeSQLiteStatement(indexKeyStr), data.rows.item(i).key],
204
306
  function (tx, data) {
205
307
  addIndexEntry(i + 1);
206
- }, error
308
+ },
309
+ /** @type {SQLStatementErrorCallback} */ (error)
207
310
  );
208
311
  } catch (e) {
209
312
  // Not a valid value to insert into index, so just continue
@@ -222,13 +325,17 @@ IDBIndex.__createIndex = function (store, index) {
222
325
  success(store);
223
326
  }
224
327
  }
225
- }, error);
226
- }, error);
328
+ }, /** @type {SQLStatementErrorCallback} */ (error));
329
+ }, /** @type {SQLStatementErrorCallback} */ (error));
227
330
  }
228
331
 
229
332
  const escapedStoreNameSQL = util.escapeStoreNameForSQL(storeName);
230
333
  const escapedIndexNameSQL = util.escapeIndexNameForSQL(index.name);
231
334
 
335
+ /**
336
+ * @param {SQLTransaction} tx
337
+ * @returns {void}
338
+ */
232
339
  function addIndexSQL (tx) {
233
340
  if (!CFG.useSQLiteIndexes) {
234
341
  applyIndex(tx);
@@ -244,7 +351,7 @@ IDBIndex.__createIndex = function (store, index) {
244
351
  '" ON ' + escapedStoreNameSQL + '(' + escapedIndexNameSQL + ')',
245
352
  [],
246
353
  applyIndex,
247
- error
354
+ /** @type {SQLStatementErrorCallback} */ (error)
248
355
  );
249
356
  }
250
357
 
@@ -256,16 +363,17 @@ IDBIndex.__createIndex = function (store, index) {
256
363
  // For a new index, add a new column to the object store, then apply the index
257
364
  const sql = ['ALTER TABLE', escapedStoreNameSQL, 'ADD', escapedIndexNameSQL, 'BLOB'].join(' ');
258
365
  CFG.DEBUG && console.log(sql);
259
- tx.executeSql(sql, [], addIndexSQL, error);
366
+ tx.executeSql(
367
+ sql, [], addIndexSQL, /** @type {SQLStatementErrorCallback} */ (error)
368
+ );
260
369
  }
261
- }, undefined, store);
370
+ });
262
371
  };
263
372
 
264
373
  /**
265
374
  * Deletes an index from an object store.
266
- * @param {IDBObjectStore} store
267
- * @param {IDBIndex} index
268
- * @protected
375
+ * @param {import('./IDBObjectStore.js').IDBObjectStoreFull} store
376
+ * @param {IDBIndexFull} index
269
377
  * @returns {void}
270
378
  */
271
379
  IDBIndex.__deleteIndex = function (store, index) {
@@ -280,11 +388,21 @@ IDBIndex.__deleteIndex = function (store, index) {
280
388
 
281
389
  // Remove the index in WebSQL
282
390
  const {transaction} = store;
283
- transaction.__addNonRequestToTransactionQueue(function deleteIndex (tx, args, success, failure) {
391
+ /** @type {import('./IDBTransaction.js').IDBTransactionFull} */ (
392
+ transaction
393
+ ).__addNonRequestToTransactionQueue(function deleteIndex (tx, args, success, failure) {
394
+ /**
395
+ * @param {SQLTransaction} tx
396
+ * @param {SQLError} err
397
+ * @returns {void}
398
+ */
284
399
  function error (tx, err) {
285
400
  failure(createDOMException('UnknownError', 'Could not delete index "' + index.name + '"', err));
286
401
  }
287
402
 
403
+ /**
404
+ * @returns {void}
405
+ */
288
406
  function finishDeleteIndex () {
289
407
  // Update the object store's index list
290
408
  IDBIndex.__updateIndexList(store, tx, function (store) {
@@ -296,7 +414,7 @@ IDBIndex.__deleteIndex = function (store, index) {
296
414
  delete indexHandle.__pendingDelete;
297
415
  }
298
416
  success(store);
299
- }, error);
417
+ }, /** @type {SQLStatementErrorCallback} */ (error));
300
418
  }
301
419
 
302
420
  if (!CFG.useSQLiteIndexes) {
@@ -311,24 +429,31 @@ IDBIndex.__deleteIndex = function (store, index) {
311
429
  ),
312
430
  [],
313
431
  finishDeleteIndex,
314
- error
432
+ /** @type {SQLStatementErrorCallback} */ (error)
315
433
  );
316
- }, undefined, store);
434
+ });
317
435
  };
318
436
 
437
+ /**
438
+ * @typedef {{[key: string]: IDBIndexProperties}} IndexList
439
+ */
440
+
319
441
  /**
320
442
  * Updates index list for the given object store.
321
- * @param {IDBObjectStore} store
322
- * @param {object} tx
323
- * @param {function} success
324
- * @param {function} failure
443
+ * @param {import('./IDBObjectStore.js').IDBObjectStoreFull} store
444
+ * @param {SQLTransaction} tx
445
+ * @param {(store: IDBObjectStore) => void} success
446
+ * @param {(
447
+ * tx: SQLTransaction,
448
+ * err: SQLError
449
+ * ) => boolean} [failure]
325
450
  * @returns {void}
326
451
  */
327
452
  IDBIndex.__updateIndexList = function (store, tx, success, failure) {
453
+ /** @type {IndexList} **/
328
454
  const indexList = {};
329
455
  for (let i = 0; i < store.indexNames.length; i++) {
330
456
  const idx = store.__indexes[store.indexNames[i]];
331
- /** @type {IDBIndexProperties} **/
332
457
  indexList[idx.name] = {
333
458
  columnName: idx.name,
334
459
  keyPath: idx.keyPath,
@@ -336,24 +461,28 @@ IDBIndex.__updateIndexList = function (store, tx, success, failure) {
336
461
  unique: idx.unique,
337
462
  multiEntry: idx.multiEntry
338
463
  },
339
- deleted: Boolean(idx.deleted)
464
+ deleted: Boolean(idx.__deleted)
340
465
  };
341
466
  }
342
467
 
343
468
  CFG.DEBUG && console.log('Updating the index list for ' + store.__currentName, indexList);
344
469
  tx.executeSql('UPDATE __sys__ SET "indexList" = ? WHERE "name" = ?', [JSON.stringify(indexList), util.escapeSQLiteStatement(store.__currentName)], function () {
345
470
  success(store);
346
- }, failure);
471
+ }, /** @type {SQLStatementErrorCallback} */ (failure));
347
472
  };
348
473
 
474
+ /**
475
+ * @typedef {any|IDBKeyRange} Query
476
+ */
477
+
349
478
  /**
350
479
  * Retrieves index data for the given key.
351
- * @param {*|IDBKeyRange} range
352
- * @param {string} opType
480
+ * @param {Query} range
481
+ * @param {"value"|"key"|"count"} opType
353
482
  * @param {boolean} nullDisallowed
354
- * @param {number} count
355
- * @returns {IDBRequest}
356
- * @private
483
+ * @param {number} [count]
484
+ * @this {IDBIndexFull}
485
+ * @returns {import('./IDBRequest.js').IDBRequestFull}
357
486
  */
358
487
  IDBIndex.prototype.__fetchIndexData = function (range, opType, nullDisallowed, count) {
359
488
  const me = this;
@@ -373,20 +502,24 @@ IDBIndex.prototype.__fetchIndexData = function (range, opType, nullDisallowed, c
373
502
  }
374
503
 
375
504
  const fetchArgs = buildFetchIndexDataSQL(nullDisallowed, me, range, opType, false);
376
- return me.objectStore.transaction.__addToTransactionQueue(function (...args) {
377
- executeFetchIndexData(count, ...fetchArgs, ...args);
505
+ return /** @type {import('./IDBTransaction.js').IDBTransactionFull} */ (
506
+ me.objectStore.transaction
507
+ ).__addToTransactionQueue(function (...args) {
508
+ executeFetchIndexData(
509
+ count,
510
+ ...fetchArgs,
511
+ // @ts-expect-error It's ok
512
+ ...args
513
+ );
378
514
  }, undefined, me);
379
515
  };
380
516
 
381
- /* eslint-disable jsdoc/check-param-names */
382
517
  /**
383
518
  * Opens a cursor over the given key range.
384
- * @param {*|IDBKeyRange} query
385
- * @param {string} direction
386
- * @returns {IDBRequest}
519
+ * @this {IDBIndexFull}
520
+ * @returns {import('./IDBRequest.js').IDBRequestFull}
387
521
  */
388
522
  IDBIndex.prototype.openCursor = function (/* query, direction */) {
389
- /* eslint-enable jsdoc/check-param-names */
390
523
  const me = this;
391
524
  // eslint-disable-next-line prefer-rest-params
392
525
  const [query, direction] = arguments;
@@ -395,15 +528,12 @@ IDBIndex.prototype.openCursor = function (/* query, direction */) {
395
528
  return cursor.__request;
396
529
  };
397
530
 
398
- /* eslint-disable jsdoc/check-param-names */
399
531
  /**
400
532
  * Opens a cursor over the given key range. The cursor only includes key values, not data.
401
- * @param {*|IDBKeyRange} query
402
- * @param {string} direction
403
- * @returns {IDBRequest}
533
+ * @this {IDBIndexFull}
534
+ * @returns {import('./IDBRequest.js').IDBRequestFull}
404
535
  */
405
536
  IDBIndex.prototype.openKeyCursor = function (/* query, direction */) {
406
- /* eslint-enable jsdoc/check-param-names */
407
537
  const me = this;
408
538
  // eslint-disable-next-line prefer-rest-params
409
539
  const [query, direction] = arguments;
@@ -412,6 +542,13 @@ IDBIndex.prototype.openKeyCursor = function (/* query, direction */) {
412
542
  return cursor.__request;
413
543
  };
414
544
 
545
+ /**
546
+ *
547
+ * @param {Query} query
548
+ * @throws {TypeError}
549
+ * @this {IDBIndexFull}
550
+ * @returns {import('./IDBRequest.js').IDBRequestFull}
551
+ */
415
552
  IDBIndex.prototype.get = function (query) {
416
553
  if (!arguments.length) { // Per https://heycam.github.io/webidl/
417
554
  throw new TypeError('A parameter was missing for `IDBIndex.get`.');
@@ -419,6 +556,13 @@ IDBIndex.prototype.get = function (query) {
419
556
  return this.__fetchIndexData(query, 'value', true);
420
557
  };
421
558
 
559
+ /**
560
+ *
561
+ * @param {Query} query
562
+ * @throws {TypeError}
563
+ * @this {IDBIndexFull}
564
+ * @returns {import('./IDBRequest.js').IDBRequestFull}
565
+ */
422
566
  IDBIndex.prototype.getKey = function (query) {
423
567
  if (!arguments.length) { // Per https://heycam.github.io/webidl/
424
568
  throw new TypeError('A parameter was missing for `IDBIndex.getKey`.');
@@ -426,18 +570,30 @@ IDBIndex.prototype.getKey = function (query) {
426
570
  return this.__fetchIndexData(query, 'key', true);
427
571
  };
428
572
 
573
+ /**
574
+ * @this {IDBIndexFull}
575
+ * @returns {import('./IDBRequest.js').IDBRequestFull}
576
+ */
429
577
  IDBIndex.prototype.getAll = function (/* query, count */) {
430
578
  // eslint-disable-next-line prefer-rest-params
431
579
  const [query, count] = arguments;
432
580
  return this.__fetchIndexData(query, 'value', false, count);
433
581
  };
434
582
 
583
+ /**
584
+ * @this {IDBIndexFull}
585
+ * @returns {import('./IDBRequest.js').IDBRequestFull}
586
+ */
435
587
  IDBIndex.prototype.getAllKeys = function (/* query, count */) {
436
588
  // eslint-disable-next-line prefer-rest-params
437
589
  const [query, count] = arguments;
438
590
  return this.__fetchIndexData(query, 'key', false, count);
439
591
  };
440
592
 
593
+ /**
594
+ * @this {IDBIndexFull}
595
+ * @returns {import('./IDBRequest.js').IDBRequestFull}
596
+ */
441
597
  IDBIndex.prototype.count = function (/* query */) {
442
598
  const me = this;
443
599
  // eslint-disable-next-line prefer-rest-params
@@ -454,6 +610,19 @@ IDBIndex.prototype.count = function (/* query */) {
454
610
  return me.__fetchIndexData(query, 'count', false);
455
611
  };
456
612
 
613
+ /**
614
+ *
615
+ * @param {import('./IDBObjectStore.js').IDBObjectStoreFull} store
616
+ * @param {string} oldName
617
+ * @param {string} newName
618
+ * @param {string[][]} colInfoToPreserveArr
619
+ * @param {null|((
620
+ * tx: SQLTransaction,
621
+ * success: ((store: IDBObjectStore) => void)
622
+ * ) => void)} cb
623
+ * @this {IDBIndexFull}
624
+ * @returns {void}
625
+ */
457
626
  IDBIndex.prototype.__renameIndex = function (store, oldName, newName, colInfoToPreserveArr = [], cb = null) {
458
627
  const newNameType = 'BLOB';
459
628
  const storeName = store.__currentName;
@@ -467,10 +636,20 @@ IDBIndex.prototype.__renameIndex = function (store, oldName, newName, colInfoToP
467
636
 
468
637
  // We could adapt the approach at http://stackoverflow.com/a/8430746/271577
469
638
  // to make the approach reusable without passing column names, but it is a bit fragile
470
- store.transaction.__addNonRequestToTransactionQueue(function renameIndex (tx, args, success, error) {
639
+ /** @type {import('./IDBTransaction.js').IDBTransactionFull} */ (
640
+ store.transaction
641
+ ).__addNonRequestToTransactionQueue(function renameIndex (tx, args, success, error) {
642
+ /**
643
+ * @param {SQLTransaction} tx
644
+ * @param {SQLError} err
645
+ * @returns {void}
646
+ */
471
647
  function sqlError (tx, err) {
472
648
  error(err);
473
649
  }
650
+ /**
651
+ * @returns {void}
652
+ */
474
653
  function finish () {
475
654
  if (cb) {
476
655
  cb(tx, success);
@@ -512,9 +691,17 @@ IDBIndex.prototype.__renameIndex = function (store, oldName, newName, colInfoToP
512
691
  const sql = 'CREATE INDEX ' +
513
692
  escapedIndexToRecreate + ' ON ' + escapedStoreNameSQL + '(' + escapedIndexNameSQL + ')';
514
693
  CFG.DEBUG && console.log(sql);
515
- tx.executeSql(sql, [], resolve, function (tx, err) {
516
- reject(err);
517
- });
694
+ tx.executeSql(
695
+ sql,
696
+ [],
697
+ resolve,
698
+ /* eslint-disable no-extra-parens -- TS */
699
+ /** @type {SQLStatementErrorCallback} */
700
+ (function (tx, err) {
701
+ reject(err);
702
+ })
703
+ /* eslint-enable no-extra-parens -- TS */
704
+ );
518
705
  // }, function (tx, err) {
519
706
  // reject(err);
520
707
  // });
@@ -525,31 +712,59 @@ IDBIndex.prototype.__renameIndex = function (store, oldName, newName, colInfoToP
525
712
  // Chrome erring here if not dropped first; Node does not
526
713
  const sql = 'DROP INDEX IF EXISTS ' + escapedIndexToRecreate;
527
714
  CFG.DEBUG && console.log(sql);
528
- tx.executeSql(sql, [], function () {
529
- const sql = 'CREATE INDEX ' + escapedIndexToRecreate +
530
- ' ON ' + escapedStoreNameSQL + '("key")';
531
- CFG.DEBUG && console.log(sql);
532
- tx.executeSql(sql, [], resolve, function (tx, err) {
715
+ tx.executeSql(
716
+ sql, [], function () {
717
+ const sql = 'CREATE INDEX ' + escapedIndexToRecreate +
718
+ ' ON ' + escapedStoreNameSQL + '("key")';
719
+ CFG.DEBUG && console.log(sql);
720
+ tx.executeSql(
721
+ sql, [], resolve,
722
+ /* eslint-disable no-extra-parens -- TS */
723
+ /** @type {SQLStatementErrorCallback} */
724
+ (function (tx, err) {
725
+ /* eslint-enable no-extra-parens -- TS */
726
+ reject(err);
727
+ })
728
+ );
729
+ },
730
+ /* eslint-disable no-extra-parens -- TS */
731
+ /** @type {SQLStatementErrorCallback} */
732
+ (function (tx, err) {
733
+ /* eslint-enable no-extra-parens -- TS */
533
734
  reject(err);
534
- });
535
- }, function (tx, err) {
536
- reject(err);
537
- });
735
+ })
736
+ );
538
737
  })
539
738
  );
540
- SyncPromise.all(indexCreations).then(finish, error).catch((err) => {
739
+ SyncPromise.all(indexCreations).then(
740
+ finish,
741
+ /** @type {(reason: any) => PromiseLike<never>} */
742
+ (error)
743
+ ).catch((err) => {
541
744
  console.log('Index rename error');
542
745
  throw err;
543
746
  });
544
- }, sqlError);
545
- }, sqlError);
546
- }, sqlError);
547
- }, sqlError);
747
+ }, /** @type {SQLStatementErrorCallback} */ (sqlError));
748
+ }, /** @type {SQLStatementErrorCallback} */ (sqlError));
749
+ }, /** @type {SQLStatementErrorCallback} */ (sqlError));
750
+ }, /** @type {SQLStatementErrorCallback} */ (sqlError));
548
751
  });
549
752
  };
550
753
 
754
+ /**
755
+ * @typedef {any} AnyValue
756
+ */
757
+
551
758
  Object.defineProperty(IDBIndex, Symbol.hasInstance, {
552
- value: (obj) => util.isObj(obj) && typeof obj.openCursor === 'function' && typeof obj.multiEntry === 'boolean'
759
+ /**
760
+ * @param {AnyValue} obj
761
+ * @returns {boolean}
762
+ */
763
+ value: (obj) => util.isObj(obj) &&
764
+ 'openCursor' in obj &&
765
+ typeof obj.openCursor === 'function' &&
766
+ 'multiEntry' in obj &&
767
+ typeof obj.multiEntry === 'boolean'
553
768
  });
554
769
 
555
770
  util.defineReadonlyOuterInterface(IDBIndex.prototype, readonlyProperties);
@@ -561,12 +776,31 @@ Object.defineProperty(IDBIndex, 'prototype', {
561
776
  writable: false
562
777
  });
563
778
 
564
- function executeFetchIndexData (count, unboundedDisallowed, index, hasKey, range, opType, multiChecks, sql, sqlValues, tx, args, success, error) {
779
+ /**
780
+ * @param {number|null} count
781
+ * @param {boolean} unboundedDisallowed
782
+ * @param {IDBIndexFull} index
783
+ * @param {boolean} hasKey
784
+ * @param {import('./Key.js').Value|import('./Key.js').Key} range
785
+ * @param {"value"|"key"|"count"} opType
786
+ * @param {boolean} multiChecks
787
+ * @param {string[]} sql
788
+ * @param {string[]} sqlValues
789
+ * @param {SQLTransaction} tx
790
+ * @param {null|undefined} args
791
+ * @param {(result: number|undefined|[]|AnyValue|AnyValue[]) => void} success
792
+ * @param {(tx: SQLTransaction, err: SQLError) => void} error
793
+ * @returns {void}
794
+ */
795
+ function executeFetchIndexData (
796
+ count, unboundedDisallowed, index, hasKey, range, opType,
797
+ multiChecks, sql, sqlValues, tx, args, success, error
798
+ ) {
565
799
  if (unboundedDisallowed) {
566
800
  count = 1;
567
801
  }
568
802
  if (count) {
569
- sql.push('LIMIT', count);
803
+ sql.push('LIMIT', String(count));
570
804
  }
571
805
  const isCount = opType === 'count';
572
806
  CFG.DEBUG && console.log('Trying to fetch data for Index', sql.join(' '), sqlValues);
@@ -576,11 +810,27 @@ function executeFetchIndexData (count, unboundedDisallowed, index, hasKey, range
576
810
  const decode = isCount
577
811
  ? () => { /* */ }
578
812
  : (opType === 'key'
579
- ? (record) => {
813
+ // eslint-disable-next-line operator-linebreak -- JSDoc
814
+ ?
815
+ /**
816
+ * @param {{
817
+ * key: string
818
+ * }} record
819
+ * @returns {import('./Key.js').ValueType|undefined}
820
+ */
821
+ (record) => {
580
822
  // Key.convertValueToKey(record.key); // Already validated before storage
581
823
  return Key.decode(util.unescapeSQLiteResponse(record.key));
582
824
  }
583
- : (record) => { // when opType is value
825
+ // eslint-disable-next-line operator-linebreak -- JSDoc
826
+ :
827
+ /**
828
+ * @param {{
829
+ * value: string
830
+ * }} record
831
+ * @returns {AnyValue}
832
+ */
833
+ (record) => { // when opType is value
584
834
  return Sca.decode(util.unescapeSQLiteResponse(record.value));
585
835
  });
586
836
  if (index.multiEntry) {
@@ -588,11 +838,23 @@ function executeFetchIndexData (count, unboundedDisallowed, index, hasKey, range
588
838
  const encodedKey = Key.encode(range, index.multiEntry);
589
839
  for (let i = 0; i < data.rows.length; i++) {
590
840
  const row = data.rows.item(i);
591
- const rowKey = Key.decode(row[escapedIndexNameForKeyCol]);
841
+ const rowKey = /** @type {import('./Key.js').ValueTypeArray} */ (
842
+ Key.decode(row[escapedIndexNameForKeyCol])
843
+ );
592
844
  let record;
593
845
  if (hasKey && (
594
- (multiChecks && range.some((check) => rowKey.includes(check))) || // More precise than our SQL
595
- Key.isMultiEntryMatch(encodedKey, row[escapedIndexNameForKeyCol])
846
+ (multiChecks && range.some(
847
+ /**
848
+ * @param {string} check
849
+ * @returns {boolean}
850
+ */
851
+ (check) => rowKey.includes(check)
852
+ )) || // More precise than our SQL
853
+ Key.isMultiEntryMatch(
854
+ /** @type {string} */
855
+ (encodedKey),
856
+ row[escapedIndexNameForKeyCol]
857
+ )
596
858
  )) {
597
859
  recordCount++;
598
860
  record = row;
@@ -625,10 +887,29 @@ function executeFetchIndexData (count, unboundedDisallowed, index, hasKey, range
625
887
  } else {
626
888
  success(unboundedDisallowed ? records[0] : records);
627
889
  }
628
- }, error);
890
+ }, /** @type {SQLStatementErrorCallback} */ (error));
629
891
  }
630
892
 
631
- function buildFetchIndexDataSQL (nullDisallowed, index, range, opType, multiChecks) {
893
+ /**
894
+ * @param {boolean} nullDisallowed
895
+ * @param {IDBIndexFull} index
896
+ * @param {import('./Key.js').Value|import('./Key.js').Key} range
897
+ * @param {"value"|"key"|"count"} opType
898
+ * @param {boolean} multiChecks
899
+ * @returns {[
900
+ * nullDisallowed: boolean,
901
+ * index: IDBIndexFull,
902
+ * hasRange: boolean,
903
+ * range: import('./Key.js').Value|import('./Key.js').Key,
904
+ * opType: "value"|"key"|"count",
905
+ * multiChecks: boolean,
906
+ * sql: string[],
907
+ * sqlValues: string[]
908
+ * ]}
909
+ */
910
+ function buildFetchIndexDataSQL (
911
+ nullDisallowed, index, range, opType, multiChecks
912
+ ) {
632
913
  const hasRange = nullDisallowed || !util.isNullish(range);
633
914
  const col = opType === 'count' ? 'key' : opType; // It doesn't matter which column we use for 'count' as long as it is valid
634
915
  const sql = [
@@ -638,19 +919,27 @@ function buildFetchIndexDataSQL (nullDisallowed, index, range, opType, multiChec
638
919
  'FROM', util.escapeStoreNameForSQL(index.objectStore.__currentName),
639
920
  'WHERE', util.escapeIndexNameForSQL(index.name), 'NOT NULL'
640
921
  ];
922
+
923
+ /** @type {string[]} */
641
924
  const sqlValues = [];
642
925
  if (hasRange) {
643
926
  if (multiChecks) {
644
927
  sql.push('AND (');
645
- range.forEach((innerKey, i) => {
928
+ /** @type {import('./Key.js').KeyPathArray} */ (
929
+ range
930
+ ).forEach((innerKey, i) => {
646
931
  if (i > 0) sql.push('OR');
647
932
  sql.push(util.escapeIndexNameForSQL(index.name), "LIKE ? ESCAPE '^' ");
648
- sqlValues.push('%' + util.sqlLIKEEscape(Key.encode(innerKey, index.multiEntry)) + '%');
933
+ sqlValues.push('%' + util.sqlLIKEEscape(
934
+ /** @type {string} */ (Key.encode(innerKey, index.multiEntry))
935
+ ) + '%');
649
936
  });
650
937
  sql.push(')');
651
938
  } else if (index.multiEntry) {
652
939
  sql.push('AND', util.escapeIndexNameForSQL(index.name), "LIKE ? ESCAPE '^'");
653
- sqlValues.push('%' + util.sqlLIKEEscape(Key.encode(range, index.multiEntry)) + '%');
940
+ sqlValues.push('%' + util.sqlLIKEEscape(
941
+ /** @type {string} */ (Key.encode(range, index.multiEntry))
942
+ ) + '%');
654
943
  } else {
655
944
  const convertedRange = convertValueToKeyRange(range, nullDisallowed);
656
945
  setSQLForKeyRange(convertedRange, util.escapeIndexNameForSQL(index.name), sql, sqlValues, true, false);