indexeddbshim 17.0.0 → 17.2.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 +62 -0
- package/badges/licenses-badge-dev.svg +1 -1
- package/badges/licenses-badge.svg +1 -1
- package/dist/CFG.d.ts +1 -0
- package/dist/CFG.d.ts.map +1 -1
- package/dist/DOMException.d.ts.map +1 -1
- package/dist/IDBCursor.d.ts +25 -18
- package/dist/IDBCursor.d.ts.map +1 -1
- package/dist/IDBFactory.d.ts +19 -19
- package/dist/IDBFactory.d.ts.map +1 -1
- package/dist/IDBIndex.d.ts.map +1 -1
- package/dist/IDBKeyRange.d.ts +5 -5
- package/dist/IDBKeyRange.d.ts.map +1 -1
- package/dist/IDBTransaction.d.ts +24 -3
- package/dist/IDBTransaction.d.ts.map +1 -1
- package/dist/Key.d.ts +41 -41
- package/dist/Key.d.ts.map +1 -1
- package/dist/indexeddbshim-Key.js +88 -69
- 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 +1682 -1056
- package/dist/indexeddbshim-UnicodeIdentifiers-node.cjs.map +1 -1
- package/dist/indexeddbshim-UnicodeIdentifiers.js +886 -663
- package/dist/indexeddbshim-UnicodeIdentifiers.js.map +1 -1
- package/dist/indexeddbshim-UnicodeIdentifiers.min.js +4 -4
- package/dist/indexeddbshim-UnicodeIdentifiers.min.js.map +1 -1
- package/dist/indexeddbshim-node.cjs +1682 -1056
- package/dist/indexeddbshim-node.cjs.map +1 -1
- package/dist/indexeddbshim-noninvasive.js +886 -663
- package/dist/indexeddbshim-noninvasive.js.map +1 -1
- package/dist/indexeddbshim-noninvasive.min.js +4 -4
- package/dist/indexeddbshim-noninvasive.min.js.map +1 -1
- package/dist/indexeddbshim.js +890 -660
- package/dist/indexeddbshim.js.map +1 -1
- package/dist/indexeddbshim.min.js +4 -4
- package/dist/indexeddbshim.min.js.map +1 -1
- package/dist/node-UnicodeIdentifiers.d.ts.map +1 -1
- package/dist/node.d.ts.map +1 -1
- package/dist/nodeSQLiteDatabase.d.ts +65 -0
- package/dist/nodeSQLiteDatabase.d.ts.map +1 -0
- package/dist/nodeWebSQL.d.ts.map +1 -1
- package/dist/util.d.ts +5 -0
- package/dist/util.d.ts.map +1 -1
- package/package.json +22 -18
- package/src/CFG.js +3 -0
- package/src/DOMException.js +10 -10
- package/src/IDBCursor.js +152 -102
- package/src/IDBFactory.js +30 -26
- package/src/IDBIndex.js +1 -2
- package/src/IDBKeyRange.js +5 -5
- package/src/IDBTransaction.js +35 -5
- package/src/Key.js +63 -55
- package/src/node-UnicodeIdentifiers.js +5 -1
- package/src/node.js +5 -1
- package/src/nodeSQLiteDatabase.js +174 -0
- package/src/nodeWebSQL.js +1 -3
- package/src/util.js +62 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-UnicodeIdentifiers.d.ts","sourceRoot":"","sources":["../src/node-UnicodeIdentifiers.js"],"names":[],"mappings":";AASA;;;;GAIG;AACH,sCAJW,OAAO,oBAAoB,EAAE,aAAa,wBAExC,OAAO,oBAAoB,EAAE,aAAa,GAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"node-UnicodeIdentifiers.d.ts","sourceRoot":"","sources":["../src/node-UnicodeIdentifiers.js"],"names":[],"mappings":";AASA;;;;GAIG;AACH,sCAJW,OAAO,oBAAoB,EAAE,aAAa,wBAExC,OAAO,oBAAoB,EAAE,aAAa,GAAC,MAAM,CAe7D"}
|
package/dist/node.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.js"],"names":[],"mappings":";AAQA;;;;GAIG;AACH,sCAJW,OAAO,oBAAoB,EAAE,aAAa,wBAExC,OAAO,oBAAoB,EAAE,aAAa,GAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.js"],"names":[],"mappings":";AAQA;;;;GAIG;AACH,sCAJW,OAAO,oBAAoB,EAAE,aAAa,wBAExC,OAAO,oBAAoB,EAAE,aAAa,GAAC,MAAM,CAQ7D"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export default SQLiteDatabase;
|
|
2
|
+
export type SQLProfileCallback = (sql: string, duration: number) => void;
|
|
3
|
+
export type SQLTraceCallback = ((sql: string) => void) | undefined;
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {(sql: string, duration: number) => void} SQLProfileCallback
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {((sql: string) => void)|undefined} SQLTraceCallback
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* @param {string} name
|
|
12
|
+
* @param {{busyTimeout?: number, trace?: (sql: string) => void, profile?: SQLProfileCallback}} [opts]
|
|
13
|
+
* @returns {void}
|
|
14
|
+
*/
|
|
15
|
+
declare function SQLiteDatabase(name: string, opts?: {
|
|
16
|
+
busyTimeout?: number;
|
|
17
|
+
trace?: (sql: string) => void;
|
|
18
|
+
profile?: SQLProfileCallback;
|
|
19
|
+
}): void;
|
|
20
|
+
declare class SQLiteDatabase {
|
|
21
|
+
/**
|
|
22
|
+
* @typedef {(sql: string, duration: number) => void} SQLProfileCallback
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* @typedef {((sql: string) => void)|undefined} SQLTraceCallback
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* @param {string} name
|
|
29
|
+
* @param {{busyTimeout?: number, trace?: (sql: string) => void, profile?: SQLProfileCallback}} [opts]
|
|
30
|
+
* @returns {void}
|
|
31
|
+
*/
|
|
32
|
+
constructor(name: string, opts?: {
|
|
33
|
+
busyTimeout?: number;
|
|
34
|
+
trace?: (sql: string) => void;
|
|
35
|
+
profile?: SQLProfileCallback;
|
|
36
|
+
});
|
|
37
|
+
_db: any;
|
|
38
|
+
/**
|
|
39
|
+
* @param {{sql: string, args: unknown[]}[]} queries
|
|
40
|
+
* @param {boolean} readOnly
|
|
41
|
+
* @param {(err: Error|null, results?: SQLiteResult[]) => void} callback
|
|
42
|
+
* @returns {void}
|
|
43
|
+
*/
|
|
44
|
+
exec(queries: {
|
|
45
|
+
sql: string;
|
|
46
|
+
args: unknown[];
|
|
47
|
+
}[], readOnly: boolean, callback: (err: Error | null, results?: SQLiteResult[]) => void): void;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
*
|
|
51
|
+
*/
|
|
52
|
+
declare class SQLiteResult {
|
|
53
|
+
/**
|
|
54
|
+
* @param {Error|null|undefined} error
|
|
55
|
+
* @param {number|undefined} [insertId]
|
|
56
|
+
* @param {number} [rowsAffected]
|
|
57
|
+
* @param {object[]} [rows]
|
|
58
|
+
*/
|
|
59
|
+
constructor(error: Error | null | undefined, insertId?: number | undefined, rowsAffected?: number, rows?: object[]);
|
|
60
|
+
error: Error | null | undefined;
|
|
61
|
+
insertId: number | undefined;
|
|
62
|
+
rowsAffected: number | undefined;
|
|
63
|
+
rows: object[] | undefined;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=nodeSQLiteDatabase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nodeSQLiteDatabase.d.ts","sourceRoot":"","sources":["../src/nodeSQLiteDatabase.js"],"names":[],"mappings":";iCAyBa,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI;+BAIvC,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC,GAAC,SAAS;AAL9C;;GAEG;AAEH;;GAEG;AAEH;;;;GAIG;AACH,sCAJW,MAAM,SACN;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,kBAAkB,CAAA;CAAC,GACjF,IAAI,CAkEhB;;IA7ED;;OAEG;IAEH;;OAEG;IAEH;;;;OAIG;IACH,kBAJW,MAAM,SACN;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAAC,OAAO,CAAC,EAAE,kBAAkB,CAAA;KAAC,EAmE7F;IA9CG,SA6CE;IAyBN;;;;;OAKG;IACH,cALW;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,EAAE,CAAA;KAAC,EAAE,YAChC,OAAO,YACP,CAAC,GAAG,EAAE,KAAK,GAAC,IAAI,EAAE,OAAO,CAAC,EAAE,YAAY,EAAE,KAAK,IAAI,GACjD,IAAI,CA0ChB;;AAzKD;;GAEG;AACH;IACI;;;;;OAKG;IACH,mBALW,KAAK,GAAC,IAAI,GAAC,SAAS,aACpB,MAAM,GAAC,SAAS,iBAChB,MAAM,SACN,MAAM,EAAE,EAOlB;IAJG,gCAAkB;IAClB,6BAAwB;IACxB,iCAAgC;IAChC,2BAAgB;CAEvB"}
|
package/dist/nodeWebSQL.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nodeWebSQL.d.ts","sourceRoot":"","sources":["../src/nodeWebSQL.js"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"nodeWebSQL.d.ts","sourceRoot":"","sources":["../src/nodeWebSQL.js"],"names":[],"mappings":";AAsBA,iHAAiE"}
|
package/dist/util.d.ts
CHANGED
|
@@ -172,4 +172,9 @@ export function convertToSequenceDOMString(val: AnyValue): string | string[];
|
|
|
172
172
|
* @returns {v is null|undefined}
|
|
173
173
|
*/
|
|
174
174
|
export function isNullish(v: AnyValue): v is null | undefined;
|
|
175
|
+
/**
|
|
176
|
+
* @param {() => void} fn
|
|
177
|
+
* @returns {void}
|
|
178
|
+
*/
|
|
179
|
+
export function runContinuationSafely(fn: () => void): void;
|
|
175
180
|
//# sourceMappingURL=util.d.ts.map
|
package/dist/util.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.js"],"names":[],"mappings":"sBAKa,MAAM;;
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.js"],"names":[],"mappings":"sBAKa,MAAM;;uBA6fN,GAAG;AAndhB;;;;GAIG;AACH,2CAHW,MAAM,GACJ,MAAM,CASlB;AAED;;;GAGG;AACH,4CAHW,MAAM,GACJ,MAAM,CAclB;AAuBD;;;;GAIG;AACH,qDAJW,MAAM,GAEJ,MAAM,CAoClB;AAmBD;;;;GAIG;AACH,uDAHW,MAAM,GACJ,MAAM,CAkClB;AAED;;;GAGG;AACH,6CAHW,MAAM,GACJ,MAAM,CAIlB;AAED;;;GAGG;AACH,6CAHW,MAAM,GACJ,MAAM,CAIlB;AAED;;;GAGG;AACH,sDAHW,MAAM,GACJ,MAAM,CAIlB;AAED;;;;GAIG;AACH,mCAHW,MAAM,GACJ,MAAM,CAKlB;AAzID;;;GAGG;AACH,8BAHW,MAAM,GACJ,MAAM,CAIlB;AAqID;;GAEG;AAGH;;;;;GAKG;AACH,gCAJW,QAAQ,QACR,QAAQ,GACN,OAAO,CAInB;AAED;;;;GAIG;AACH,2BAHW,QAAQ,GACN,GAAG,IAAI,MAAM,CAIzB;AAED;;;;GAIG;AACH,4BAHW,MAAM,GACJ,OAAO,CAInB;AAED;;;;GAIG;AACH,4BAHW,MAAM,GACJ,OAAO,CAKnB;AAED;;;;GAIG;AACH,8BAHW,MAAM,GACJ,OAAO,CAKnB;AAED;;;;GAIG;AACH,4BAHW,MAAM,GACJ,OAAO,CAKnB;AAED;;;;GAIG;AACH,8BAHW,QAAQ,GACN,OAAO,CAOnB;AAED;;;;GAIG;AACH,gCAHW,QAAQ,GACN,OAAO,CAOnB;AAED;;;;;GAKG;AACH,0CAJW,MAAM,SACN,MAAM,EAAE,GACN,IAAI,CAkBhB;AAED;;;;;GAKG;AACH,kDAJW,MAAM,SACN,MAAM,EAAE,GACN,IAAI,CAchB;AAED;;;;;;;GAOG;AACH,8CANW,MAAM,GAAG;IACnB,CAAK,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CACnB,aACO,MAAM,EAAE,GACN,IAAI,CA2BhB;AAED;;;;;;;;GAQG;AACH,8CAPW,MAAM,SACN,MAAM,GAAC,MAAM,EAAE,WACf,IAAI,GAAC;IACf,CAAK,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CACnB,GACS,IAAI,CA8BhB;AAgCD;;;;GAIG;AACH,wCAHW,MAAM,GAAC,MAAM,EAAE,GACb,OAAO,CAWnB;AAED;;;;;GAKG;AACH,qCALW,MAAM,QACN,oBAAoB,GAAC,eAAe,GAElC,MAAM,CAyBlB;AAED;;GAEG;AAEH;;;;GAIG;AACH,sCAJW,QAAQ,gBACR,OAAO,GACL,MAAM,CAIlB;AAWD;;;;GAIG;AACH,gDAHW,QAAQ,GACN,MAAM,GAAC,MAAM,EAAE,CAW3B;AAED;;;GAGG;AACH,6BAHW,QAAQ,GACN,CAAC,IAAI,IAAI,GAAC,SAAS,CAI/B;AA6BD;;;GAGG;AACH,0CAHW,MAAM,IAAI,GACR,IAAI,CAmBhB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "indexeddbshim",
|
|
3
|
-
"version": "17.
|
|
3
|
+
"version": "17.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"author": "Parashuram <code@nparashuram.com>",
|
|
6
6
|
"contributors": [
|
|
@@ -156,17 +156,18 @@
|
|
|
156
156
|
"node": "^22.18.0 || >= 24.11.0"
|
|
157
157
|
},
|
|
158
158
|
"dependencies": {
|
|
159
|
+
"@node-static/node-static": "^0.9.0",
|
|
160
|
+
"better-sqlite3": "^13.0.3",
|
|
159
161
|
"canvas": "^3.2.3",
|
|
160
162
|
"eventtargeter": "0.9.0",
|
|
161
|
-
"sync-promise-expanded": "^
|
|
162
|
-
"typeson": "10.
|
|
163
|
-
"typeson-registry": "13.
|
|
163
|
+
"sync-promise-expanded": "^2.0.0",
|
|
164
|
+
"typeson": "10.2.0",
|
|
165
|
+
"typeson-registry": "13.1.0",
|
|
164
166
|
"websql-configurable": "^3.0.3"
|
|
165
167
|
},
|
|
166
168
|
"devDependencies": {
|
|
167
169
|
"@babel/core": "^8.0.1",
|
|
168
170
|
"@babel/preset-env": "^8.0.2",
|
|
169
|
-
"@brettz9/node-static": "^0.1.1",
|
|
170
171
|
"@es-joy/json-file-reporter": "^1.5.0",
|
|
171
172
|
"@rollup/plugin-babel": "^7.1.0",
|
|
172
173
|
"@rollup/plugin-commonjs": "^29.0.3",
|
|
@@ -174,36 +175,37 @@
|
|
|
174
175
|
"@rollup/plugin-json": "^6.1.0",
|
|
175
176
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
176
177
|
"@rollup/plugin-terser": "^1.0.0",
|
|
177
|
-
"@types/
|
|
178
|
+
"@types/better-sqlite3": "^9.6.0",
|
|
179
|
+
"@types/node": "^26.2.0",
|
|
178
180
|
"@types/websql": "^0.0.30",
|
|
179
181
|
"@unicode/unicode-17.0.0": "^1.6.17",
|
|
180
182
|
"babel-plugin-add-module-exports": "1.0.4",
|
|
181
|
-
"bson": "^7.3.
|
|
183
|
+
"bson": "^7.3.2",
|
|
182
184
|
"builtin-modules": "^5.3.0",
|
|
183
185
|
"c8": "^12.0.0",
|
|
184
186
|
"chai": "6.2.2",
|
|
185
187
|
"chokidar-cli": "^3.0.0",
|
|
186
188
|
"colors": "1.4.0",
|
|
187
189
|
"copyfiles": "^2.4.1",
|
|
188
|
-
"core-js-bundle": "^3.
|
|
190
|
+
"core-js-bundle": "^3.50.0",
|
|
189
191
|
"coveradge": "^0.8.2",
|
|
190
192
|
"cyclonejs": "1.1.4",
|
|
191
193
|
"delay-cli": "^3.0.0",
|
|
192
|
-
"eslint": "^10.8.
|
|
193
|
-
"eslint-config-ash-nazg": "^
|
|
194
|
-
"globals": "^17.
|
|
194
|
+
"eslint": "^10.8.1",
|
|
195
|
+
"eslint-config-ash-nazg": "^42.5.0",
|
|
196
|
+
"globals": "^17.11.0",
|
|
195
197
|
"is-date-object": "1.1.0",
|
|
196
198
|
"isomorphic-fetch": "^3.0.0",
|
|
197
|
-
"jsdom": "^30.0.
|
|
198
|
-
"license-badger": "^0.
|
|
199
|
+
"jsdom": "^30.0.1",
|
|
200
|
+
"license-badger": "^0.23.0",
|
|
199
201
|
"local-xmlhttprequest": "2.0.0",
|
|
200
|
-
"mocha": "^11.
|
|
202
|
+
"mocha": "^11.8.0",
|
|
201
203
|
"mocha-badge-generator": "^0.11.0",
|
|
202
204
|
"mocha-multi-reporters": "^1.5.1",
|
|
203
205
|
"npm-run-all": "^4.1.5",
|
|
204
206
|
"open-cli": "^9.0.0",
|
|
205
207
|
"rimraf": "^6.1.3",
|
|
206
|
-
"rollup": "^4.62.
|
|
208
|
+
"rollup": "^4.62.4",
|
|
207
209
|
"rollup-plugin-filesize": "^10.0.0",
|
|
208
210
|
"rollup-plugin-node-polyfills": "^0.2.1",
|
|
209
211
|
"sinon": "^22.1.0",
|
|
@@ -211,14 +213,16 @@
|
|
|
211
213
|
"sourcemap-transformer": "git+https://github.com/brettz9/sourcemap-transformer.git",
|
|
212
214
|
"typescript": "^6.0.3",
|
|
213
215
|
"w3c-blob": "0.0.1",
|
|
214
|
-
"ws": "^8.21.
|
|
216
|
+
"ws": "^8.21.3"
|
|
215
217
|
},
|
|
216
218
|
"allowScripts": {
|
|
217
219
|
"es5-ext@0.10.64": true,
|
|
218
220
|
"fsevents@2.3.3": true,
|
|
219
221
|
"sqlite3@5.1.7": true,
|
|
220
222
|
"canvas@3.2.3": true,
|
|
221
|
-
"
|
|
222
|
-
"
|
|
223
|
+
"unrs-resolver@1.12.2": true,
|
|
224
|
+
"better-sqlite3@13.0.3": true,
|
|
225
|
+
"core-js-bundle@3.50.0": true,
|
|
226
|
+
"is-hidden-file@1.1.2": true
|
|
223
227
|
}
|
|
224
228
|
}
|
package/src/CFG.js
CHANGED
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
* sqlBusyTimeout: number,
|
|
43
43
|
* sqlTrace: () => void,
|
|
44
44
|
* sqlProfile: () => void,
|
|
45
|
+
* escapeNULForSQLiteStatements: boolean,
|
|
45
46
|
* createIndexes: boolean
|
|
46
47
|
* }} ConfigValues
|
|
47
48
|
*/
|
|
@@ -215,6 +216,8 @@ const CFG = /** @type {ConfigValues} */ ({});
|
|
|
215
216
|
'sqlBusyTimeout', // Defaults to 1000
|
|
216
217
|
'sqlTrace', // Callback not used by default
|
|
217
218
|
'sqlProfile', // Callback not used by default
|
|
219
|
+
// Defaults to true except in Node builds where we can preserve literal NUL with better-sqlite3
|
|
220
|
+
'escapeNULForSQLiteStatements',
|
|
218
221
|
|
|
219
222
|
'createIndexes'
|
|
220
223
|
]).forEach((prop) => {
|
package/src/DOMException.js
CHANGED
|
@@ -368,22 +368,22 @@ try {
|
|
|
368
368
|
const createDOMException = useNativeDOMException
|
|
369
369
|
// eslint-disable-next-line @stylistic/operator-linebreak -- Need JSDoc
|
|
370
370
|
? /**
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
371
|
+
* @param {string} name
|
|
372
|
+
* @param {string} message
|
|
373
|
+
* @param {ErrorLike} [error]
|
|
374
|
+
* @returns {DOMException}
|
|
375
|
+
*/
|
|
376
376
|
function (name, message, error) {
|
|
377
377
|
logError(name, message, error);
|
|
378
378
|
return createNativeDOMException(name, message);
|
|
379
379
|
}
|
|
380
380
|
// eslint-disable-next-line @stylistic/operator-linebreak -- Need JSDoc
|
|
381
381
|
: /**
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
382
|
+
* @param {string} name
|
|
383
|
+
* @param {string} message
|
|
384
|
+
* @param {ErrorLike} [error]
|
|
385
|
+
* @returns {Error}
|
|
386
|
+
*/
|
|
387
387
|
function (name, message, error) {
|
|
388
388
|
logError(name, message, error);
|
|
389
389
|
return createNonNativeDOMException(name, message);
|
package/src/IDBCursor.js
CHANGED
|
@@ -46,6 +46,9 @@ import CFG from './CFG.js';
|
|
|
46
46
|
* __unique: boolean,
|
|
47
47
|
* __sqlDirection: "DESC"|"ASC",
|
|
48
48
|
* __matchedKeys: {[key: string]: true},
|
|
49
|
+
* __continuationKey: import('./Key.js').Key|undefined,
|
|
50
|
+
* __continuationPrimaryKey: import('./Key.js').Key|undefined,
|
|
51
|
+
* __multiEntryExhausted: boolean,
|
|
49
52
|
* __invalidateCache: () => void
|
|
50
53
|
* }} IDBCursorFull
|
|
51
54
|
*/
|
|
@@ -117,6 +120,9 @@ IDBCursor.__super = function IDBCursor (query, direction, store, source, keyColu
|
|
|
117
120
|
this.__valueDecoder = this.__keyOnly ? Key : Sca;
|
|
118
121
|
this.__count = count;
|
|
119
122
|
this.__prefetchedIndex = -1;
|
|
123
|
+
this.__continuationKey = undefined;
|
|
124
|
+
this.__continuationPrimaryKey = undefined;
|
|
125
|
+
this.__multiEntryExhausted = false;
|
|
120
126
|
this.__multiEntryIndex = this.__indexSource
|
|
121
127
|
? 'multiEntry' in source && source.multiEntry
|
|
122
128
|
: false;
|
|
@@ -270,77 +276,107 @@ const leftBracketRegex = /\[/gu;
|
|
|
270
276
|
* @param {SQLTransaction} tx
|
|
271
277
|
* @param {KeySuccess} success
|
|
272
278
|
* @param {FindError} error
|
|
273
|
-
* @param {Integer
|
|
279
|
+
* @param {Integer} [recordsToLoad]
|
|
274
280
|
* @this {IDBCursorFull}
|
|
275
281
|
* @returns {void}
|
|
276
282
|
*/
|
|
277
|
-
IDBCursor.prototype.__findMultiEntry = function (key, primaryKey, tx, success, error, recordsToLoad) {
|
|
283
|
+
IDBCursor.prototype.__findMultiEntry = function (key, primaryKey, tx, success, error, recordsToLoad = 1) {
|
|
278
284
|
const me = this;
|
|
279
285
|
|
|
280
|
-
if (me.
|
|
281
|
-
if (CFG.DEBUG) { console.log('Reached end of multiEntry cursor'); }
|
|
286
|
+
if (me.__multiEntryExhausted) {
|
|
287
|
+
if (CFG.DEBUG) { console.log('[multiEntry] Reached end of multiEntry cursor (already exhausted)'); }
|
|
282
288
|
success(undefined, undefined, undefined);
|
|
283
289
|
return;
|
|
284
290
|
}
|
|
285
291
|
|
|
286
292
|
const quotedKeyColumnName = util.sqlQuote(me.__keyColumnName);
|
|
287
|
-
const
|
|
288
|
-
/** @type {string[]} */
|
|
289
|
-
const sqlValues = [];
|
|
290
|
-
sql.push('WHERE', quotedKeyColumnName, 'NOT NULL');
|
|
291
|
-
if (me.__range && (me.__range.lower !== undefined && Array.isArray(me.__range.upper))) {
|
|
292
|
-
if (me.__range.upper.indexOf(me.__range.lower) === 0) {
|
|
293
|
-
sql.push('AND', quotedKeyColumnName, "LIKE ? ESCAPE '^'");
|
|
294
|
-
sqlValues.push(
|
|
295
|
-
'%' + util.sqlLIKEEscape(
|
|
296
|
-
/** @type {string} */ (me.__range.__lowerCached).slice(0, -1)
|
|
297
|
-
) + '%'
|
|
298
|
-
);
|
|
299
|
-
}
|
|
300
|
-
}
|
|
293
|
+
const quotedKey = util.sqlQuote('key');
|
|
301
294
|
|
|
302
295
|
// Determine the ORDER BY direction based on the cursor.
|
|
303
296
|
const direction = me.__sqlDirection;
|
|
304
297
|
const op = direction === 'ASC' ? '>' : '<';
|
|
305
|
-
const quotedKey = util.sqlQuote('key');
|
|
306
298
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
sql
|
|
318
|
-
|
|
319
|
-
sqlValues
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
299
|
+
/**
|
|
300
|
+
* Runs (and, if a batch of underlying rows produces no matching
|
|
301
|
+
* multi-entry values, repeatedly re-runs) the query for the next batch
|
|
302
|
+
* of underlying rows, advancing `me.__continuationKey`/
|
|
303
|
+
* `me.__continuationPrimaryKey` (tracking the last *physical* row
|
|
304
|
+
* scanned) each time, until either some matches are found or the
|
|
305
|
+
* underlying table is exhausted.
|
|
306
|
+
* @returns {void}
|
|
307
|
+
*/
|
|
308
|
+
function runQuery () {
|
|
309
|
+
const sql = ['SELECT * FROM', util.escapeStoreNameForSQL(me.__store.__currentName)];
|
|
310
|
+
/** @type {string[]} */
|
|
311
|
+
const sqlValues = [];
|
|
312
|
+
sql.push('WHERE', quotedKeyColumnName, 'NOT NULL');
|
|
313
|
+
if (me.__range && (me.__range.lower !== undefined && Array.isArray(me.__range.upper))) {
|
|
314
|
+
if (me.__range.upper.indexOf(me.__range.lower) === 0) {
|
|
315
|
+
sql.push('AND', quotedKeyColumnName, "LIKE ? ESCAPE '^'");
|
|
316
|
+
sqlValues.push(
|
|
317
|
+
'%' + util.sqlLIKEEscape(
|
|
318
|
+
/** @type {string} */ (me.__range.__lowerCached).slice(0, -1)
|
|
319
|
+
) + '%'
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
325
323
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
324
|
+
if (primaryKey !== undefined) {
|
|
325
|
+
sql.push('AND', quotedKey, op + '= ?');
|
|
326
|
+
// Key.convertValueToKey(primaryKey); // Already checked by `continuePrimaryKey`
|
|
327
|
+
sqlValues.push(/** @type {string} */ (Key.encode(primaryKey)));
|
|
328
|
+
}
|
|
329
|
+
if (key !== undefined) {
|
|
330
|
+
sql.push('AND', quotedKeyColumnName, op + '= ?');
|
|
331
|
+
// Key.convertValueToKey(key); // Already checked by `continue` or `continuePrimaryKey`
|
|
332
|
+
sqlValues.push(/** @type {string} */ (Key.encode(key)));
|
|
333
|
+
} else if (me.__continuationKey !== undefined) {
|
|
334
|
+
// Resume from the last underlying (physical) row we scanned, not
|
|
335
|
+
// from the last *matching* multi-entry value (which lives in a
|
|
336
|
+
// different key-space than the raw index column and cannot be
|
|
337
|
+
// reliably compared against it, e.g. for array index keys).
|
|
338
|
+
sql.push(
|
|
339
|
+
'AND (', quotedKeyColumnName, op, '?',
|
|
340
|
+
'OR (', quotedKeyColumnName, '= ?', 'AND', quotedKey, op, '?))'
|
|
341
|
+
);
|
|
342
|
+
const encodedContinuationKey = /** @type {string} */ (
|
|
343
|
+
Key.encode(me.__continuationKey, true)
|
|
344
|
+
);
|
|
345
|
+
sqlValues.push(
|
|
346
|
+
encodedContinuationKey,
|
|
347
|
+
encodedContinuationKey,
|
|
348
|
+
/** @type {string} */ (Key.encode(me.__continuationPrimaryKey))
|
|
349
|
+
);
|
|
329
350
|
}
|
|
330
351
|
|
|
331
|
-
|
|
352
|
+
if (!me.__count) {
|
|
353
|
+
// 1. Sort by key
|
|
354
|
+
sql.push('ORDER BY', quotedKeyColumnName, direction);
|
|
332
355
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
356
|
+
// 2. Sort by primaryKey (if defined and not unique)
|
|
357
|
+
if (!me.__unique && me.__keyColumnName !== 'key') { // Avoid adding 'key' twice
|
|
358
|
+
sql.push(',', util.sqlQuote('key'), direction);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// 3. Sort by position (if defined)
|
|
362
|
+
|
|
363
|
+
if (!me.__unique && me.__indexSource) {
|
|
364
|
+
// 4. Sort by object store position (if defined and not unique)
|
|
365
|
+
sql.push(',', util.sqlQuote(me.__valueColumnName), direction);
|
|
366
|
+
}
|
|
367
|
+
sql.push('LIMIT', String(recordsToLoad));
|
|
336
368
|
}
|
|
337
|
-
sql.
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
369
|
+
const sqlStr = sql.join(' ');
|
|
370
|
+
if (CFG.DEBUG) { console.log('[multiEntry] query', sqlStr, sqlValues); }
|
|
371
|
+
|
|
372
|
+
tx.executeSql(sqlStr, sqlValues, function (tx, data) {
|
|
373
|
+
if (data.rows.length === 0) {
|
|
374
|
+
me.__multiEntryExhausted = true;
|
|
375
|
+
if (CFG.DEBUG) { console.log('[multiEntry] Reached end of multiEntry cursor (no more rows)'); }
|
|
376
|
+
success(undefined, undefined, undefined);
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
341
379
|
|
|
342
|
-
tx.executeSql(sqlStr, sqlValues, function (tx, data) {
|
|
343
|
-
if (data.rows.length > 0) {
|
|
344
380
|
if (me.__count) { // Avoid caching and other processing below
|
|
345
381
|
let ct = 0;
|
|
346
382
|
for (let i = 0; i < data.rows.length; i++) {
|
|
@@ -352,6 +388,17 @@ IDBCursor.prototype.__findMultiEntry = function (key, primaryKey, tx, success, e
|
|
|
352
388
|
success(undefined, ct, undefined);
|
|
353
389
|
return;
|
|
354
390
|
}
|
|
391
|
+
|
|
392
|
+
// Track how far we've physically scanned, regardless of whether
|
|
393
|
+
// this batch produced any matches, so the next batch (if any)
|
|
394
|
+
// resumes after this one instead of re-scanning or stopping early.
|
|
395
|
+
const lastRawRow = data.rows.item(data.rows.length - 1);
|
|
396
|
+
me.__continuationKey = Key.decode(lastRawRow[me.__keyColumnName], true);
|
|
397
|
+
me.__continuationPrimaryKey = Key.decode(lastRawRow.key);
|
|
398
|
+
if (data.rows.length < recordsToLoad) {
|
|
399
|
+
me.__multiEntryExhausted = true;
|
|
400
|
+
}
|
|
401
|
+
|
|
355
402
|
const rows = [];
|
|
356
403
|
for (let i = 0; i < data.rows.length; i++) {
|
|
357
404
|
const rowItem = data.rows.item(i);
|
|
@@ -373,6 +420,18 @@ IDBCursor.prototype.__findMultiEntry = function (key, primaryKey, tx, success, e
|
|
|
373
420
|
rows.push(clone);
|
|
374
421
|
}
|
|
375
422
|
}
|
|
423
|
+
|
|
424
|
+
if (rows.length === 0) {
|
|
425
|
+
if (me.__multiEntryExhausted) {
|
|
426
|
+
if (CFG.DEBUG) { console.log('[multiEntry] Reached end of multiEntry cursor (last batch had no matches)'); }
|
|
427
|
+
success(undefined, undefined, undefined);
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
if (CFG.DEBUG) { console.log('[multiEntry] batch had no matches; fetching next batch'); }
|
|
431
|
+
runQuery();
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
|
|
376
435
|
const reverse = me.direction.indexOf('prev') === 0;
|
|
377
436
|
rows.sort(function (a, b) {
|
|
378
437
|
if (a.matchingKey.replaceAll(leftBracketRegex, 'z') < b.matchingKey.replaceAll(leftBracketRegex, 'z')) {
|
|
@@ -390,37 +449,28 @@ IDBCursor.prototype.__findMultiEntry = function (key, primaryKey, tx, success, e
|
|
|
390
449
|
return 0;
|
|
391
450
|
});
|
|
392
451
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
} else {
|
|
416
|
-
if (CFG.DEBUG) { console.log('Reached end of multiEntry cursor'); }
|
|
417
|
-
success(undefined, undefined, undefined);
|
|
418
|
-
}
|
|
419
|
-
}, function (tx, err) {
|
|
420
|
-
if (CFG.DEBUG) { console.log('Could not execute Cursor.continue', sqlStr, sqlValues); }
|
|
421
|
-
error(err);
|
|
422
|
-
return false;
|
|
423
|
-
});
|
|
452
|
+
me.__prefetchedIndex = 0;
|
|
453
|
+
me.__prefetchedData = {
|
|
454
|
+
data: rows,
|
|
455
|
+
length: rows.length,
|
|
456
|
+
/**
|
|
457
|
+
* @param {Integer} index
|
|
458
|
+
* @returns {RowItemNonNull}
|
|
459
|
+
*/
|
|
460
|
+
item (index) {
|
|
461
|
+
return this.data[index];
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
if (CFG.DEBUG) { console.log('[multiEntry] Preloaded ' + me.__prefetchedData.length + ' records for multiEntry cursor'); }
|
|
465
|
+
me.__decode(rows[0], success);
|
|
466
|
+
}, function (tx, err) {
|
|
467
|
+
if (CFG.DEBUG) { console.log('[multiEntry] Could not execute Cursor.continue', sqlStr, sqlValues); }
|
|
468
|
+
error(err);
|
|
469
|
+
return false;
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
runQuery();
|
|
424
474
|
};
|
|
425
475
|
|
|
426
476
|
/**
|
|
@@ -432,19 +482,19 @@ IDBCursor.prototype.__findMultiEntry = function (key, primaryKey, tx, success, e
|
|
|
432
482
|
*/
|
|
433
483
|
|
|
434
484
|
/**
|
|
435
|
-
* @callback SuccessArg
|
|
436
|
-
* @param {StructuredCloneValue} value
|
|
437
|
-
* @param {import('./IDBRequest.js').IDBRequestFull} req
|
|
438
|
-
* @returns {void}
|
|
439
|
-
*/
|
|
485
|
+
* @callback SuccessArg
|
|
486
|
+
* @param {StructuredCloneValue} value
|
|
487
|
+
* @param {import('./IDBRequest.js').IDBRequestFull} req
|
|
488
|
+
* @returns {void}
|
|
489
|
+
*/
|
|
440
490
|
|
|
441
491
|
/**
|
|
442
|
-
* @callback SuccessCallback
|
|
443
|
-
* @param {IndexedDBKey} key
|
|
444
|
-
* @param {StructuredCloneValue} value
|
|
445
|
-
* @param {IndexedDBKey} primaryKey
|
|
446
|
-
* @returns {void}
|
|
447
|
-
*/
|
|
492
|
+
* @callback SuccessCallback
|
|
493
|
+
* @param {IndexedDBKey} key
|
|
494
|
+
* @param {StructuredCloneValue} value
|
|
495
|
+
* @param {IndexedDBKey} primaryKey
|
|
496
|
+
* @returns {void}
|
|
497
|
+
*/
|
|
448
498
|
|
|
449
499
|
/**
|
|
450
500
|
* Creates an "onsuccess" callback.
|
|
@@ -472,11 +522,11 @@ IDBCursor.prototype.__onsuccess = function (success) {
|
|
|
472
522
|
|
|
473
523
|
/**
|
|
474
524
|
* @typedef {{
|
|
475
|
-
* matchingKey: string,
|
|
476
|
-
* key: string,
|
|
477
|
-
* [k: string]: string
|
|
478
|
-
* }} RowItemNonNull
|
|
479
|
-
*/
|
|
525
|
+
* matchingKey: string,
|
|
526
|
+
* key: string,
|
|
527
|
+
* [k: string]: string
|
|
528
|
+
* }} RowItemNonNull
|
|
529
|
+
*/
|
|
480
530
|
|
|
481
531
|
/**
|
|
482
532
|
*
|
|
@@ -540,6 +590,7 @@ IDBCursor.prototype.__sourceOrEffectiveObjStoreDeleted = function () {
|
|
|
540
590
|
IDBCursor.prototype.__invalidateCache = function () {
|
|
541
591
|
// @ts-expect-error Why is this not being found?
|
|
542
592
|
this.__prefetchedData = null;
|
|
593
|
+
this.__multiEntryExhausted = false;
|
|
543
594
|
};
|
|
544
595
|
|
|
545
596
|
/**
|
|
@@ -599,9 +650,8 @@ IDBCursor.prototype.__continueFinish = function (key, primaryKey, advanceState)
|
|
|
599
650
|
me.__advanceCount--;
|
|
600
651
|
me.__key = k;
|
|
601
652
|
me.__continue(undefined, true);
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
)(); // We don't call success yet but do need to advance the transaction queue
|
|
653
|
+
// We don't call success yet but do need to advance the transaction queue
|
|
654
|
+
util.runContinuationSafely(/** @type {() => void} */ (executeNextRequest));
|
|
605
655
|
return;
|
|
606
656
|
}
|
|
607
657
|
me.__advanceCount = undefined;
|
|
@@ -627,12 +677,12 @@ IDBCursor.prototype.__continueFinish = function (key, primaryKey, advanceState)
|
|
|
627
677
|
return;
|
|
628
678
|
}
|
|
629
679
|
// @ts-expect-error Todo: Our bug to fix
|
|
630
|
-
cursorContinue(tx, args, success, error);
|
|
680
|
+
util.runContinuationSafely(() => cursorContinue(tx, args, success, error));
|
|
631
681
|
}
|
|
632
682
|
if (me.__unique && !me.__multiEntryIndex &&
|
|
633
683
|
encKey === Key.encode(me.key, me.__multiEntryIndex)) {
|
|
634
684
|
// @ts-expect-error Todo: Our bug to fix
|
|
635
|
-
cursorContinue(tx, args, success, error);
|
|
685
|
+
util.runContinuationSafely(() => cursorContinue(tx, args, success, error));
|
|
636
686
|
return;
|
|
637
687
|
}
|
|
638
688
|
checkKey();
|