indexeddbshim 11.0.0 → 12.0.0-pre.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/badges/licenses-badge.svg +1 -1
- package/dist/CFG.d.ts +80 -0
- package/dist/CFG.d.ts.map +1 -0
- package/dist/DOMException.d.ts +71 -0
- package/dist/DOMException.d.ts.map +1 -0
- package/dist/DOMStringList.d.ts +20 -0
- package/dist/DOMStringList.d.ts.map +1 -0
- package/dist/Event.d.ts +21 -0
- package/dist/Event.d.ts.map +1 -0
- package/dist/IDBCursor.d.ts +289 -0
- package/dist/IDBCursor.d.ts.map +1 -0
- package/dist/IDBDatabase.d.ts +144 -0
- package/dist/IDBDatabase.d.ts.map +1 -0
- package/dist/IDBFactory.d.ts +96 -0
- package/dist/IDBFactory.d.ts.map +1 -0
- package/dist/IDBIndex.d.ts +243 -0
- package/dist/IDBIndex.d.ts.map +1 -0
- package/dist/IDBKeyRange.d.ts +79 -0
- package/dist/IDBKeyRange.d.ts.map +1 -0
- package/dist/IDBObjectStore.d.ts +273 -0
- package/dist/IDBObjectStore.d.ts.map +1 -0
- package/dist/IDBRequest.d.ts +90 -0
- package/dist/IDBRequest.d.ts.map +1 -0
- package/dist/IDBTransaction.d.ts +271 -0
- package/dist/IDBTransaction.d.ts.map +1 -0
- package/dist/IDBVersionChangeEvent.d.ts +23 -0
- package/dist/IDBVersionChangeEvent.d.ts.map +1 -0
- package/dist/Key.d.ts +214 -0
- package/dist/Key.d.ts.map +1 -0
- package/dist/Sca.d.ts +31 -0
- package/dist/Sca.d.ts.map +1 -0
- package/dist/UnicodeIdentifiers.d.ts +3 -0
- package/dist/UnicodeIdentifiers.d.ts.map +1 -0
- package/dist/browser-UnicodeIdentifiers.d.ts +2 -0
- package/dist/browser-UnicodeIdentifiers.d.ts.map +1 -0
- package/dist/browser-noninvasive.d.ts +3 -0
- package/dist/browser-noninvasive.d.ts.map +1 -0
- package/dist/browser.d.ts +2 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/cmp.d.ts +9 -0
- package/dist/cmp.d.ts.map +1 -0
- package/dist/indexeddbshim-Key.js +491 -189
- package/dist/indexeddbshim-Key.js.map +1 -1
- package/dist/indexeddbshim-Key.min.js +2 -2
- package/dist/indexeddbshim-Key.min.js.map +1 -1
- package/dist/indexeddbshim-UnicodeIdentifiers-node.cjs +17263 -1396
- package/dist/indexeddbshim-UnicodeIdentifiers-node.cjs.map +1 -1
- package/dist/indexeddbshim-UnicodeIdentifiers.js +3892 -1271
- package/dist/indexeddbshim-UnicodeIdentifiers.js.map +1 -1
- package/dist/indexeddbshim-UnicodeIdentifiers.min.js +2 -2
- package/dist/indexeddbshim-UnicodeIdentifiers.min.js.map +1 -1
- package/dist/indexeddbshim-node.cjs +17259 -1396
- package/dist/indexeddbshim-node.cjs.map +1 -1
- package/dist/indexeddbshim-noninvasive.js +3887 -1271
- package/dist/indexeddbshim-noninvasive.js.map +1 -1
- package/dist/indexeddbshim-noninvasive.min.js +2 -2
- package/dist/indexeddbshim-noninvasive.min.js.map +1 -1
- package/dist/indexeddbshim.js +3887 -1271
- package/dist/indexeddbshim.js.map +1 -1
- package/dist/indexeddbshim.min.js +2 -2
- package/dist/indexeddbshim.min.js.map +1 -1
- package/dist/node-UnicodeIdentifiers.d.ts +8 -0
- package/dist/node-UnicodeIdentifiers.d.ts.map +1 -0
- package/dist/node.d.ts +8 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/nodeWebSQL.d.ts +3 -0
- package/dist/nodeWebSQL.d.ts.map +1 -0
- package/dist/setGlobalVars.d.ts +79 -0
- package/dist/setGlobalVars.d.ts.map +1 -0
- package/dist/unicode-regex.d.ts +3 -0
- package/dist/unicode-regex.d.ts.map +1 -0
- package/dist/util.d.ts +174 -0
- package/dist/util.d.ts.map +1 -0
- package/package.json +40 -27
- package/src/CFG.js +89 -11
- package/src/DOMException.js +116 -29
- package/src/DOMStringList.js +92 -2
- package/src/Event.js +19 -4
- package/src/IDBCursor.js +339 -67
- package/src/IDBDatabase.js +87 -10
- package/src/IDBFactory.js +319 -56
- package/src/IDBIndex.js +385 -96
- package/src/IDBKeyRange.js +86 -13
- package/src/IDBObjectStore.js +326 -68
- package/src/IDBRequest.js +59 -1
- package/src/IDBTransaction.js +247 -38
- package/src/IDBVersionChangeEvent.js +28 -3
- package/src/Key.js +273 -156
- package/src/Sca.js +29 -4
- package/src/browser-UnicodeIdentifiers.js +5 -1
- package/src/cmp.js +5 -5
- package/src/node-UnicodeIdentifiers.js +9 -0
- package/src/node.js +5 -0
- package/src/nodeWebSQL.js +11 -5
- package/src/setGlobalVars.js +156 -21
- package/src/unicode-regex.js +9 -1
- package/src/util.js +228 -40
- package/typings/shimIndexedDB.d.ts +9 -0
package/src/IDBFactory.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* globals location */
|
|
2
2
|
import path from 'path';
|
|
3
|
-
import SyncPromise from 'sync-promise';
|
|
3
|
+
import SyncPromise from 'sync-promise-expanded';
|
|
4
4
|
|
|
5
5
|
import {createEvent} from './Event.js';
|
|
6
6
|
import IDBVersionChangeEvent from './IDBVersionChangeEvent.js';
|
|
@@ -13,11 +13,29 @@ import IDBTransaction from './IDBTransaction.js';
|
|
|
13
13
|
import IDBDatabase from './IDBDatabase.js';
|
|
14
14
|
import CFG from './CFG.js';
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* @typedef {number} Integer
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @callback DatabaseDeleted
|
|
22
|
+
* @returns {void}
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/** @type {import('./CFG.js').FSApi} */
|
|
16
26
|
let fs;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @param {import('./CFG.js').FSApi} _fs
|
|
30
|
+
* @returns {void}
|
|
31
|
+
*/
|
|
17
32
|
const setFS = (_fs) => {
|
|
18
33
|
fs = _fs;
|
|
19
34
|
};
|
|
20
35
|
|
|
36
|
+
/**
|
|
37
|
+
* @returns {string}
|
|
38
|
+
*/
|
|
21
39
|
const getOrigin = () => {
|
|
22
40
|
return (typeof location !== 'object' || !location) ? 'null' : location.origin;
|
|
23
41
|
};
|
|
@@ -26,14 +44,34 @@ const hasNullOrigin = () => CFG.checkOrigin !== false && (getOrigin() === 'null'
|
|
|
26
44
|
// Todo: This really should be process and tab-independent so the
|
|
27
45
|
// origin could vary; in the browser, this might be through a
|
|
28
46
|
// `SharedWorker`
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @type {{
|
|
50
|
+
* [key: string]: {
|
|
51
|
+
* [key: string]: {
|
|
52
|
+
* req: import('./IDBRequest.js').IDBOpenDBRequestFull,
|
|
53
|
+
* cb: (req: import('./IDBRequest.js').IDBRequestFull) => void,
|
|
54
|
+
* }[]
|
|
55
|
+
* }
|
|
56
|
+
* }}
|
|
57
|
+
*/
|
|
29
58
|
const connectionQueue = {};
|
|
30
59
|
|
|
60
|
+
/**
|
|
61
|
+
* @param {string} name
|
|
62
|
+
* @param {string} origin
|
|
63
|
+
* @returns {void}
|
|
64
|
+
*/
|
|
31
65
|
function processNextInConnectionQueue (name, origin = getOrigin()) {
|
|
32
66
|
const queueItems = connectionQueue[origin][name];
|
|
33
67
|
if (!queueItems[0]) { // Nothing left to process
|
|
34
68
|
return;
|
|
35
69
|
}
|
|
36
70
|
const {req, cb} = queueItems[0]; // Keep in queue to prevent continuation
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @returns {void}
|
|
74
|
+
*/
|
|
37
75
|
function removeFromQueue () {
|
|
38
76
|
queueItems.shift();
|
|
39
77
|
processNextInConnectionQueue(name, origin);
|
|
@@ -43,8 +81,16 @@ function processNextInConnectionQueue (name, origin = getOrigin()) {
|
|
|
43
81
|
cb(req);
|
|
44
82
|
}
|
|
45
83
|
|
|
46
|
-
|
|
84
|
+
/* eslint-disable default-param-last */
|
|
85
|
+
/**
|
|
86
|
+
* @param {import('./IDBRequest.js').IDBOpenDBRequestFull} req
|
|
87
|
+
* @param {string} name
|
|
88
|
+
* @param {string} origin
|
|
89
|
+
* @param {(req: import('./IDBRequest.js').IDBOpenDBRequestFull) => void} cb
|
|
90
|
+
* @returns {void}
|
|
91
|
+
*/
|
|
47
92
|
function addRequestToConnectionQueue (req, name, origin = getOrigin(), cb) {
|
|
93
|
+
/* eslint-enable default-param-last */
|
|
48
94
|
if (!connectionQueue[origin][name]) {
|
|
49
95
|
connectionQueue[origin][name] = [];
|
|
50
96
|
}
|
|
@@ -55,10 +101,22 @@ function addRequestToConnectionQueue (req, name, origin = getOrigin(), cb) {
|
|
|
55
101
|
}
|
|
56
102
|
}
|
|
57
103
|
|
|
104
|
+
/**
|
|
105
|
+
* @param {import('./IDBDatabase.js').IDBDatabaseFull[]} openConnections
|
|
106
|
+
* @param {import('./IDBRequest.js').IDBRequestFull} req
|
|
107
|
+
* @param {Integer} oldVersion
|
|
108
|
+
* @param {Integer|null} newVersion
|
|
109
|
+
* @returns {SyncPromise}
|
|
110
|
+
*/
|
|
58
111
|
function triggerAnyVersionChangeAndBlockedEvents (openConnections, req, oldVersion, newVersion) {
|
|
59
112
|
// Todo: For Node (and in browser using service workers if available?) the
|
|
60
113
|
// connections ought to involve those in any process; should also
|
|
61
114
|
// auto-close if unloading
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* @param {IDBDatabase} connection
|
|
118
|
+
* @returns {boolean|undefined}
|
|
119
|
+
*/
|
|
62
120
|
const connectionIsClosed = (connection) => connection.__closePending;
|
|
63
121
|
const connectionsClosed = () => openConnections.every((conn) => {
|
|
64
122
|
return connectionIsClosed(conn);
|
|
@@ -72,15 +130,17 @@ function triggerAnyVersionChangeAndBlockedEvents (openConnections, req, oldVersi
|
|
|
72
130
|
// Prior onversionchange must have caused this connection to be closed
|
|
73
131
|
return undefined;
|
|
74
132
|
}
|
|
75
|
-
const e =
|
|
133
|
+
const e = /** @type {Event & IDBVersionChangeEvent} */ (
|
|
134
|
+
new IDBVersionChangeEvent('versionchange', {oldVersion, newVersion})
|
|
135
|
+
);
|
|
76
136
|
return new SyncPromise(function (resolve) {
|
|
77
137
|
setTimeout(() => {
|
|
78
138
|
entry.dispatchEvent(e); // No need to catch errors
|
|
79
|
-
resolve();
|
|
139
|
+
resolve(undefined);
|
|
80
140
|
});
|
|
81
141
|
});
|
|
82
142
|
});
|
|
83
|
-
}, SyncPromise.resolve()).then(function () {
|
|
143
|
+
}, SyncPromise.resolve(undefined)).then(function () {
|
|
84
144
|
if (connectionsClosed()) {
|
|
85
145
|
return undefined;
|
|
86
146
|
}
|
|
@@ -88,11 +148,13 @@ function triggerAnyVersionChangeAndBlockedEvents (openConnections, req, oldVersi
|
|
|
88
148
|
const unblocking = {
|
|
89
149
|
check () {
|
|
90
150
|
if (connectionsClosed()) {
|
|
91
|
-
resolve();
|
|
151
|
+
resolve(undefined);
|
|
92
152
|
}
|
|
93
153
|
}
|
|
94
154
|
};
|
|
95
|
-
const e =
|
|
155
|
+
const e = /** @type {Event & IDBVersionChangeEvent} */ (
|
|
156
|
+
new IDBVersionChangeEvent('blocked', {oldVersion, newVersion})
|
|
157
|
+
);
|
|
96
158
|
setTimeout(() => {
|
|
97
159
|
req.dispatchEvent(e); // No need to catch errors
|
|
98
160
|
if (!connectionsClosed()) {
|
|
@@ -102,17 +164,40 @@ function triggerAnyVersionChangeAndBlockedEvents (openConnections, req, oldVersi
|
|
|
102
164
|
}
|
|
103
165
|
});
|
|
104
166
|
} else {
|
|
105
|
-
resolve();
|
|
167
|
+
resolve(undefined);
|
|
106
168
|
}
|
|
107
169
|
});
|
|
108
170
|
});
|
|
109
171
|
});
|
|
110
172
|
}
|
|
111
173
|
|
|
174
|
+
/**
|
|
175
|
+
* @typedef {import('websql-configurable/lib/websql/WebSQLDatabase.js').default & {
|
|
176
|
+
* _db: {
|
|
177
|
+
* _db: {
|
|
178
|
+
* close: (errBack: (err: Error) => void) => void
|
|
179
|
+
* }
|
|
180
|
+
* }
|
|
181
|
+
* }} DatabaseFull
|
|
182
|
+
*/
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* @type {{
|
|
186
|
+
* [key: string]: {
|
|
187
|
+
* [key: string]: DatabaseFull
|
|
188
|
+
* }
|
|
189
|
+
* }}
|
|
190
|
+
*/
|
|
112
191
|
const websqlDBCache = {};
|
|
192
|
+
|
|
193
|
+
/** @type {import('websql-configurable/lib/websql/WebSQLDatabase.js').default} */
|
|
113
194
|
let sysdb;
|
|
114
195
|
let nameCounter = 0;
|
|
115
196
|
|
|
197
|
+
/**
|
|
198
|
+
* @param {string} name
|
|
199
|
+
* @returns {Integer}
|
|
200
|
+
*/
|
|
116
201
|
function getLatestCachedWebSQLVersion (name) {
|
|
117
202
|
return Object.keys(websqlDBCache[name]).map(Number).reduce(
|
|
118
203
|
(prev, curr) => {
|
|
@@ -121,12 +206,24 @@ function getLatestCachedWebSQLVersion (name) {
|
|
|
121
206
|
);
|
|
122
207
|
}
|
|
123
208
|
|
|
209
|
+
/**
|
|
210
|
+
* @param {string} name
|
|
211
|
+
* @returns {DatabaseFull}
|
|
212
|
+
*/
|
|
124
213
|
function getLatestCachedWebSQLDB (name) {
|
|
125
214
|
return websqlDBCache[name] && websqlDBCache[name][
|
|
126
215
|
getLatestCachedWebSQLVersion(name)
|
|
127
216
|
];
|
|
128
217
|
}
|
|
129
218
|
|
|
219
|
+
/**
|
|
220
|
+
* @param {OpenDatabase} __openDatabase
|
|
221
|
+
* @param {string} name
|
|
222
|
+
* @param {string} escapedDatabaseName
|
|
223
|
+
* @param {DatabaseDeleted} databaseDeleted
|
|
224
|
+
* @param {(tx: SQLTransaction|Error|SQLError, err?: SQLError) => boolean} dbError
|
|
225
|
+
* @returns {void}
|
|
226
|
+
*/
|
|
130
227
|
function cleanupDatabaseResources (__openDatabase, name, escapedDatabaseName, databaseDeleted, dbError) {
|
|
131
228
|
const useMemoryDatabase = typeof CFG.memoryDatabase === 'string';
|
|
132
229
|
if (useMemoryDatabase) {
|
|
@@ -141,13 +238,19 @@ function cleanupDatabaseResources (__openDatabase, name, escapedDatabaseName, da
|
|
|
141
238
|
console.error('The `openDatabase` implementation does not have the expected `._db._db.close` method for closing the database');
|
|
142
239
|
return;
|
|
143
240
|
}
|
|
144
|
-
sqliteDB.close(
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
241
|
+
sqliteDB.close(
|
|
242
|
+
/**
|
|
243
|
+
* @param {Error} err
|
|
244
|
+
* @returns {void}
|
|
245
|
+
*/
|
|
246
|
+
(err) => {
|
|
247
|
+
if (err) {
|
|
248
|
+
console.warn('Error closing (destroying) memory database');
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
databaseDeleted();
|
|
148
252
|
}
|
|
149
|
-
|
|
150
|
-
});
|
|
253
|
+
);
|
|
151
254
|
return;
|
|
152
255
|
}
|
|
153
256
|
if (fs && CFG.deleteDatabaseFiles !== false) {
|
|
@@ -166,7 +269,7 @@ function cleanupDatabaseResources (__openDatabase, name, escapedDatabaseName, da
|
|
|
166
269
|
|
|
167
270
|
const sqliteDB = __openDatabase(
|
|
168
271
|
path.join(CFG.databaseBasePath || '', escapedDatabaseName),
|
|
169
|
-
1,
|
|
272
|
+
'1',
|
|
170
273
|
name,
|
|
171
274
|
CFG.DEFAULT_DB_SIZE
|
|
172
275
|
);
|
|
@@ -189,33 +292,41 @@ function cleanupDatabaseResources (__openDatabase, name, escapedDatabaseName, da
|
|
|
189
292
|
deleteTables(i + 1);
|
|
190
293
|
}, function () {
|
|
191
294
|
deleteTables(i + 1);
|
|
295
|
+
return true;
|
|
192
296
|
});
|
|
193
297
|
}
|
|
194
298
|
}(0));
|
|
195
299
|
}, function (e) {
|
|
196
300
|
// __sys__ table does not exist, but that does not mean delete did not happen
|
|
197
301
|
databaseDeleted();
|
|
302
|
+
return true;
|
|
198
303
|
});
|
|
199
304
|
});
|
|
200
305
|
}
|
|
201
306
|
|
|
202
307
|
/**
|
|
203
|
-
* @callback CreateSysDBSuccessCallback
|
|
204
|
-
* @returns {void}
|
|
205
|
-
*/
|
|
308
|
+
* @callback CreateSysDBSuccessCallback
|
|
309
|
+
* @returns {void}
|
|
310
|
+
*/
|
|
206
311
|
|
|
207
312
|
/**
|
|
208
313
|
* Creates the sysDB to keep track of version numbers for databases.
|
|
209
|
-
* @param {
|
|
314
|
+
* @param {OpenDatabase} __openDatabase
|
|
210
315
|
* @param {CreateSysDBSuccessCallback} success
|
|
211
|
-
* @param {
|
|
316
|
+
* @param {(tx: SQLTransaction|SQLError|Error, err?: SQLError) => void} failure
|
|
212
317
|
* @returns {void}
|
|
213
318
|
*/
|
|
214
319
|
function createSysDB (__openDatabase, success, failure) {
|
|
320
|
+
/**
|
|
321
|
+
*
|
|
322
|
+
* @param {boolean|SQLTransaction|SQLError} tx
|
|
323
|
+
* @param {SQLError} [err]
|
|
324
|
+
* @returns {void}
|
|
325
|
+
*/
|
|
215
326
|
function sysDbCreateError (tx, err) {
|
|
216
|
-
|
|
327
|
+
const er = webSQLErrback(/** @type {SQLError} */ (err) || tx);
|
|
217
328
|
CFG.DEBUG && console.log('Error in sysdb transaction - when creating dbVersions', err);
|
|
218
|
-
failure(
|
|
329
|
+
failure(er);
|
|
219
330
|
}
|
|
220
331
|
|
|
221
332
|
if (sysdb) {
|
|
@@ -230,7 +341,7 @@ function createSysDB (__openDatabase, success, failure) {
|
|
|
230
341
|
: (CFG.databaseBasePath || '')),
|
|
231
342
|
'__sysdb__' + (CFG.addSQLiteExtension !== false ? '.sqlite' : '')
|
|
232
343
|
),
|
|
233
|
-
1,
|
|
344
|
+
'1',
|
|
234
345
|
'System Database',
|
|
235
346
|
CFG.DEFAULT_DB_SIZE
|
|
236
347
|
);
|
|
@@ -240,8 +351,13 @@ function createSysDB (__openDatabase, success, failure) {
|
|
|
240
351
|
success();
|
|
241
352
|
return;
|
|
242
353
|
}
|
|
243
|
-
systx.executeSql(
|
|
244
|
-
|
|
354
|
+
systx.executeSql(
|
|
355
|
+
'CREATE INDEX IF NOT EXISTS dbvname ON dbVersions(name)',
|
|
356
|
+
[],
|
|
357
|
+
success,
|
|
358
|
+
/** @type {SQLStatementErrorCallback} */ (sysDbCreateError)
|
|
359
|
+
);
|
|
360
|
+
}, /** @type {SQLStatementErrorCallback} */ (sysDbCreateError));
|
|
245
361
|
}, sysDbCreateError);
|
|
246
362
|
}
|
|
247
363
|
}
|
|
@@ -254,26 +370,48 @@ function createSysDB (__openDatabase, success, failure) {
|
|
|
254
370
|
function IDBFactory () {
|
|
255
371
|
throw new TypeError('Illegal constructor');
|
|
256
372
|
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* @typedef {(
|
|
376
|
+
* name: string, version: string, displayName: string, estimatedSize: number
|
|
377
|
+
* ) => import('websql-configurable/lib/websql/WebSQLDatabase.js').default} OpenDatabase
|
|
378
|
+
*/
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* @typedef {globalThis.IDBFactory & {
|
|
382
|
+
* __openDatabase: OpenDatabase,
|
|
383
|
+
* __connections: {
|
|
384
|
+
* [key: string]: import('./IDBDatabase.js').IDBDatabaseFull[]
|
|
385
|
+
* }
|
|
386
|
+
* }} IDBFactoryFull
|
|
387
|
+
*/
|
|
388
|
+
|
|
257
389
|
const IDBFactoryAlias = IDBFactory;
|
|
390
|
+
/**
|
|
391
|
+
* @returns {IDBFactoryFull}
|
|
392
|
+
*/
|
|
258
393
|
IDBFactory.__createInstance = function () {
|
|
394
|
+
/**
|
|
395
|
+
* @class
|
|
396
|
+
*/
|
|
259
397
|
function IDBFactory () {
|
|
260
398
|
this[Symbol.toStringTag] = 'IDBFactory';
|
|
261
399
|
this.__connections = {};
|
|
262
400
|
}
|
|
263
401
|
IDBFactory.prototype = IDBFactoryAlias.prototype;
|
|
402
|
+
|
|
403
|
+
// @ts-expect-error It's ok
|
|
264
404
|
return new IDBFactory();
|
|
265
405
|
};
|
|
266
406
|
|
|
267
|
-
/* eslint-disable jsdoc/check-param-names */
|
|
268
407
|
/**
|
|
269
408
|
* The IndexedDB Method to create a new database and return the DB.
|
|
270
409
|
* @param {string} name
|
|
271
|
-
* @
|
|
410
|
+
* @this {IDBFactoryFull}
|
|
272
411
|
* @throws {TypeError} Illegal invocation or no arguments (for database name)
|
|
273
412
|
* @returns {IDBOpenDBRequest}
|
|
274
413
|
*/
|
|
275
414
|
IDBFactory.prototype.open = function (name /* , version */) {
|
|
276
|
-
/* eslint-enable jsdoc/check-param-names */
|
|
277
415
|
const me = this;
|
|
278
416
|
if (!(me instanceof IDBFactory)) {
|
|
279
417
|
throw new TypeError('Illegal invocation');
|
|
@@ -306,6 +444,7 @@ IDBFactory.prototype.open = function (name /* , version */) {
|
|
|
306
444
|
const useMemoryDatabase = typeof CFG.memoryDatabase === 'string';
|
|
307
445
|
const useDatabaseCache = CFG.cacheDatabaseInstances !== false || useMemoryDatabase;
|
|
308
446
|
|
|
447
|
+
/** @type {string} */
|
|
309
448
|
let escapedDatabaseName;
|
|
310
449
|
// eslint-disable-next-line no-useless-catch
|
|
311
450
|
try {
|
|
@@ -315,22 +454,39 @@ IDBFactory.prototype.open = function (name /* , version */) {
|
|
|
315
454
|
throw err; // new TypeError('You have supplied a database name which does not match the currently supported configuration, possibly due to a length limit enforced for Node compatibility.');
|
|
316
455
|
}
|
|
317
456
|
|
|
457
|
+
/**
|
|
458
|
+
*
|
|
459
|
+
* @param {SQLTransaction|Error|SQLError} tx
|
|
460
|
+
* @param {SQLError} [err]
|
|
461
|
+
* @returns {boolean}
|
|
462
|
+
*/
|
|
318
463
|
function dbCreateError (tx, err) {
|
|
319
464
|
if (calledDbCreateError) {
|
|
320
|
-
return;
|
|
465
|
+
return true;
|
|
321
466
|
}
|
|
322
|
-
|
|
467
|
+
const er = err ? webSQLErrback(err) : /** @type {Error} */ (tx);
|
|
323
468
|
calledDbCreateError = true;
|
|
324
469
|
// Re: why bubbling here (and how cancelable is only really relevant for `window.onerror`) see: https://github.com/w3c/IndexedDB/issues/86
|
|
325
|
-
const evt = createEvent('error',
|
|
470
|
+
const evt = createEvent('error', er, {bubbles: true, cancelable: true});
|
|
326
471
|
req.__done = true;
|
|
327
|
-
req.__error =
|
|
472
|
+
req.__error = er;
|
|
328
473
|
req.__result = undefined; // Must be undefined if an error per `result` getter
|
|
329
474
|
req.dispatchEvent(evt);
|
|
475
|
+
return true;
|
|
330
476
|
}
|
|
331
477
|
|
|
478
|
+
/**
|
|
479
|
+
*
|
|
480
|
+
* @param {SQLTransaction} tx
|
|
481
|
+
* @param {DatabaseFull} db
|
|
482
|
+
* @param {Integer} oldVersion
|
|
483
|
+
* @returns {void}
|
|
484
|
+
*/
|
|
332
485
|
function setupDatabase (tx, db, oldVersion) {
|
|
333
486
|
tx.executeSql('SELECT "name", "keyPath", "autoInc", "indexList" FROM __sys__', [], function (tx, data) {
|
|
487
|
+
/**
|
|
488
|
+
* @returns {void}
|
|
489
|
+
*/
|
|
334
490
|
function finishRequest () {
|
|
335
491
|
req.__result = connection;
|
|
336
492
|
req.__done = true;
|
|
@@ -345,6 +501,13 @@ IDBFactory.prototype.open = function (name /* , version */) {
|
|
|
345
501
|
const openConnections = me.__connections[name].slice(0, -1);
|
|
346
502
|
triggerAnyVersionChangeAndBlockedEvents(openConnections, req, oldVersion, version).then(function () {
|
|
347
503
|
// DB Upgrade in progress
|
|
504
|
+
/**
|
|
505
|
+
*
|
|
506
|
+
* @param {SQLTransaction} systx
|
|
507
|
+
* @param {boolean|SQLError|DOMException|Error} err
|
|
508
|
+
* @param {(tx?: SQLTransaction|SQLError, err?: SQLError|SQLResultSet) => boolean} cb
|
|
509
|
+
* @returns {void}
|
|
510
|
+
*/
|
|
348
511
|
let sysdbFinishedCb = function (systx, err, cb) {
|
|
349
512
|
if (err) {
|
|
350
513
|
try {
|
|
@@ -353,17 +516,38 @@ IDBFactory.prototype.open = function (name /* , version */) {
|
|
|
353
516
|
// Browser may fail with expired transaction above so
|
|
354
517
|
// no choice but to manually revert
|
|
355
518
|
sysdb.transaction(function (systx) {
|
|
519
|
+
/**
|
|
520
|
+
*
|
|
521
|
+
* @param {string} msg
|
|
522
|
+
* @throws {Error}
|
|
523
|
+
* @returns {never}
|
|
524
|
+
*/
|
|
356
525
|
function reportError (msg) {
|
|
357
526
|
throw new Error('Unable to roll back upgrade transaction!' + (msg || ''));
|
|
358
527
|
}
|
|
359
528
|
|
|
360
529
|
// Attempt to revert
|
|
361
530
|
if (oldVersion === 0) {
|
|
362
|
-
systx.executeSql(
|
|
363
|
-
|
|
364
|
-
|
|
531
|
+
systx.executeSql(
|
|
532
|
+
'DELETE FROM dbVersions WHERE "name" = ?',
|
|
533
|
+
[sqlSafeName],
|
|
534
|
+
function () {
|
|
535
|
+
// @ts-expect-error Force to work
|
|
536
|
+
cb(reportError); // eslint-disable-line promise/no-callback-in-promise
|
|
537
|
+
},
|
|
538
|
+
// @ts-expect-error Force to work
|
|
539
|
+
reportError
|
|
540
|
+
);
|
|
365
541
|
} else {
|
|
366
|
-
systx.executeSql(
|
|
542
|
+
systx.executeSql(
|
|
543
|
+
'UPDATE dbVersions SET "version" = ? WHERE "name" = ?',
|
|
544
|
+
[
|
|
545
|
+
oldVersion, sqlSafeName
|
|
546
|
+
],
|
|
547
|
+
cb,
|
|
548
|
+
// @ts-expect-error Force to work
|
|
549
|
+
reportError
|
|
550
|
+
);
|
|
367
551
|
}
|
|
368
552
|
});
|
|
369
553
|
}
|
|
@@ -374,8 +558,13 @@ IDBFactory.prototype.open = function (name /* , version */) {
|
|
|
374
558
|
};
|
|
375
559
|
|
|
376
560
|
sysdb.transaction(function (systx) {
|
|
561
|
+
/**
|
|
562
|
+
* @returns {void}
|
|
563
|
+
*/
|
|
377
564
|
function versionSet () {
|
|
378
|
-
const e =
|
|
565
|
+
const e = /** @type {import('eventtargeter').EventWithProps & Event & IDBVersionChangeEvent} */ (
|
|
566
|
+
new IDBVersionChangeEvent('upgradeneeded', {oldVersion, newVersion: version})
|
|
567
|
+
);
|
|
379
568
|
req.__result = connection;
|
|
380
569
|
connection.__upgradeTransaction = req.__transaction = req.__result.__versionTransaction = IDBTransaction.__createInstance(req.__result, req.__result.objectStoreNames, 'versionchange');
|
|
381
570
|
req.__done = true;
|
|
@@ -384,7 +573,7 @@ IDBFactory.prototype.open = function (name /* , version */) {
|
|
|
384
573
|
req.dispatchEvent(e);
|
|
385
574
|
|
|
386
575
|
if (e.__legacyOutputDidListenersThrowError) {
|
|
387
|
-
logError('Error', 'An error occurred in an upgradeneeded handler attached to request chain', e.__legacyOutputDidListenersThrowError); // We do nothing else with this error as per spec
|
|
576
|
+
logError('Error', 'An error occurred in an upgradeneeded handler attached to request chain', /** @type {Error} */ (e.__legacyOutputDidListenersThrowError)); // We do nothing else with this error as per spec
|
|
388
577
|
req.transaction.__abortTransaction(createDOMException('AbortError', 'A request was aborted.'));
|
|
389
578
|
return;
|
|
390
579
|
}
|
|
@@ -392,12 +581,15 @@ IDBFactory.prototype.open = function (name /* , version */) {
|
|
|
392
581
|
});
|
|
393
582
|
req.transaction.on__beforecomplete = function (ev) {
|
|
394
583
|
connection.__upgradeTransaction = null;
|
|
395
|
-
|
|
584
|
+
/** @type {import('./IDBDatabase.js').IDBDatabaseFull} */ (
|
|
585
|
+
req.__result
|
|
586
|
+
).__versionTransaction = null;
|
|
396
587
|
sysdbFinishedCb(systx, false, function () {
|
|
397
588
|
req.transaction.__transFinishedCb(false, function () {
|
|
398
589
|
ev.complete();
|
|
399
590
|
req.__transaction = null;
|
|
400
591
|
});
|
|
592
|
+
return true;
|
|
401
593
|
});
|
|
402
594
|
};
|
|
403
595
|
req.transaction.on__preabort = function () {
|
|
@@ -420,15 +612,25 @@ IDBFactory.prototype.open = function (name /* , version */) {
|
|
|
420
612
|
const err = createDOMException('AbortError', 'The upgrade transaction was aborted.');
|
|
421
613
|
sysdbFinishedCb(systx, err, function (reportError) {
|
|
422
614
|
if (oldVersion === 0) {
|
|
423
|
-
cleanupDatabaseResources(
|
|
424
|
-
|
|
615
|
+
cleanupDatabaseResources(
|
|
616
|
+
me.__openDatabase,
|
|
617
|
+
name,
|
|
618
|
+
escapedDatabaseName,
|
|
619
|
+
dbCreateError.bind(null, err),
|
|
620
|
+
// @ts-expect-error It's ok
|
|
621
|
+
reportError || dbCreateError
|
|
622
|
+
);
|
|
623
|
+
return true;
|
|
425
624
|
}
|
|
426
625
|
dbCreateError(err);
|
|
626
|
+
return true;
|
|
427
627
|
});
|
|
428
628
|
});
|
|
429
629
|
};
|
|
430
630
|
req.transaction.on__complete = function () {
|
|
431
|
-
if (
|
|
631
|
+
if (/** @type {import('./IDBDatabase.js').IDBDatabaseFull} */ (
|
|
632
|
+
req.__result
|
|
633
|
+
).__closePending) {
|
|
432
634
|
req.__transaction = null;
|
|
433
635
|
const err = createDOMException('AbortError', 'The connection has been closed.');
|
|
434
636
|
dbCreateError(err);
|
|
@@ -460,7 +662,7 @@ IDBFactory.prototype.open = function (name /* , version */) {
|
|
|
460
662
|
} else {
|
|
461
663
|
systx.executeSql('UPDATE dbVersions SET "version" = ? WHERE "name" = ?', [version, sqlSafeName], versionSet, dbCreateError);
|
|
462
664
|
}
|
|
463
|
-
}, dbCreateError,
|
|
665
|
+
}, dbCreateError, undefined, function (currentTask, err, done, rollback, commit) {
|
|
464
666
|
if (currentTask.readOnly || err) {
|
|
465
667
|
return true;
|
|
466
668
|
}
|
|
@@ -487,14 +689,20 @@ IDBFactory.prototype.open = function (name /* , version */) {
|
|
|
487
689
|
}, dbCreateError);
|
|
488
690
|
}
|
|
489
691
|
|
|
692
|
+
/**
|
|
693
|
+
*
|
|
694
|
+
* @param {Integer} oldVersion
|
|
695
|
+
* @returns {void}
|
|
696
|
+
*/
|
|
490
697
|
function openDB (oldVersion) {
|
|
698
|
+
/** @type {DatabaseFull} */
|
|
491
699
|
let db;
|
|
492
700
|
if ((useMemoryDatabase || useDatabaseCache) && name in websqlDBCache && websqlDBCache[name][version]) {
|
|
493
701
|
db = websqlDBCache[name][version];
|
|
494
702
|
} else {
|
|
495
703
|
db = me.__openDatabase(
|
|
496
704
|
useMemoryDatabase ? CFG.memoryDatabase : path.join(CFG.databaseBasePath || '', escapedDatabaseName),
|
|
497
|
-
1,
|
|
705
|
+
'1',
|
|
498
706
|
name,
|
|
499
707
|
CFG.DEFAULT_DB_SIZE
|
|
500
708
|
);
|
|
@@ -523,6 +731,9 @@ IDBFactory.prototype.open = function (name /* , version */) {
|
|
|
523
731
|
|
|
524
732
|
db.transaction(function (tx) {
|
|
525
733
|
tx.executeSql('CREATE TABLE IF NOT EXISTS __sys__ (name BLOB, keyPath BLOB, autoInc BOOLEAN, indexList BLOB, currNum INTEGER)', [], function () {
|
|
734
|
+
/**
|
|
735
|
+
* @returns {void}
|
|
736
|
+
*/
|
|
526
737
|
function setup () {
|
|
527
738
|
setupDatabase(tx, db, oldVersion);
|
|
528
739
|
}
|
|
@@ -531,7 +742,7 @@ IDBFactory.prototype.open = function (name /* , version */) {
|
|
|
531
742
|
return;
|
|
532
743
|
}
|
|
533
744
|
tx.executeSql('CREATE INDEX IF NOT EXISTS sysname ON __sys__(name)', [], setup, dbCreateError);
|
|
534
|
-
}, dbCreateError);
|
|
745
|
+
}, /** @type {SQLStatementErrorCallback} */ (dbCreateError));
|
|
535
746
|
}, dbCreateError);
|
|
536
747
|
}
|
|
537
748
|
|
|
@@ -567,6 +778,7 @@ IDBFactory.prototype.open = function (name /* , version */) {
|
|
|
567
778
|
/**
|
|
568
779
|
* Deletes a database.
|
|
569
780
|
* @param {string} name
|
|
781
|
+
* @this {IDBFactoryFull}
|
|
570
782
|
* @returns {IDBOpenDBRequest}
|
|
571
783
|
*/
|
|
572
784
|
IDBFactory.prototype.deleteDatabase = function (name) {
|
|
@@ -584,6 +796,7 @@ IDBFactory.prototype.deleteDatabase = function (name) {
|
|
|
584
796
|
name = String(name); // cast to a string
|
|
585
797
|
const sqlSafeName = util.escapeSQLiteStatement(name);
|
|
586
798
|
|
|
799
|
+
/** @type {string} */
|
|
587
800
|
let escapedDatabaseName;
|
|
588
801
|
// eslint-disable-next-line no-useless-catch
|
|
589
802
|
try {
|
|
@@ -600,6 +813,12 @@ IDBFactory.prototype.deleteDatabase = function (name) {
|
|
|
600
813
|
let calledDBError = false;
|
|
601
814
|
let version = 0;
|
|
602
815
|
|
|
816
|
+
/**
|
|
817
|
+
*
|
|
818
|
+
* @param {boolean} err
|
|
819
|
+
* @param {(erred?: boolean) => void} cb
|
|
820
|
+
* @returns {void}
|
|
821
|
+
*/
|
|
603
822
|
let sysdbFinishedCbDelete = function (err, cb) {
|
|
604
823
|
cb(err);
|
|
605
824
|
};
|
|
@@ -607,20 +826,27 @@ IDBFactory.prototype.deleteDatabase = function (name) {
|
|
|
607
826
|
// Although the spec has no specific conditions where an error
|
|
608
827
|
// may occur in `deleteDatabase`, it does provide for
|
|
609
828
|
// `UnknownError` as we may require upon a SQL deletion error
|
|
829
|
+
/**
|
|
830
|
+
*
|
|
831
|
+
* @param {SQLTransaction|SQLError|Error} tx
|
|
832
|
+
* @param {SQLError|boolean} [err]
|
|
833
|
+
* @returns {boolean}
|
|
834
|
+
*/
|
|
610
835
|
function dbError (tx, err) {
|
|
611
836
|
if (calledDBError || err === true) {
|
|
612
|
-
return;
|
|
837
|
+
return true;
|
|
613
838
|
}
|
|
614
|
-
|
|
839
|
+
const er = webSQLErrback(/** @type {SQLError} */ (err || tx));
|
|
615
840
|
sysdbFinishedCbDelete(true, function () {
|
|
616
841
|
req.__done = true;
|
|
617
|
-
req.__error =
|
|
842
|
+
req.__error = er;
|
|
618
843
|
req.__result = undefined; // Must be undefined if an error per `result` getter
|
|
619
844
|
// Re: why bubbling here (and how cancelable is only really relevant for `window.onerror`) see: https://github.com/w3c/IndexedDB/issues/86
|
|
620
|
-
const e = createEvent('error',
|
|
845
|
+
const e = createEvent('error', er, {bubbles: true, cancelable: true});
|
|
621
846
|
req.dispatchEvent(e);
|
|
622
847
|
calledDBError = true;
|
|
623
848
|
});
|
|
849
|
+
return true;
|
|
624
850
|
}
|
|
625
851
|
|
|
626
852
|
addRequestToConnectionQueue(req, name, /* origin */ undefined, function (req) {
|
|
@@ -628,13 +854,19 @@ IDBFactory.prototype.deleteDatabase = function (name) {
|
|
|
628
854
|
// function callback (cb) { cb(); }
|
|
629
855
|
// callback(function () {
|
|
630
856
|
|
|
857
|
+
/**
|
|
858
|
+
* @returns {void}
|
|
859
|
+
*/
|
|
631
860
|
function completeDatabaseDelete () {
|
|
632
861
|
req.__result = undefined;
|
|
633
862
|
req.__done = true;
|
|
634
|
-
const e =
|
|
863
|
+
const e = /** @type {Event & IDBVersionChangeEvent} */ (
|
|
864
|
+
new IDBVersionChangeEvent('success', {oldVersion: version, newVersion: null})
|
|
865
|
+
);
|
|
635
866
|
req.dispatchEvent(e);
|
|
636
867
|
}
|
|
637
868
|
|
|
869
|
+
/** @type {DatabaseDeleted} */
|
|
638
870
|
function databaseDeleted () {
|
|
639
871
|
sysdbFinishedCbDelete(false, function () {
|
|
640
872
|
if (useDatabaseCache && name in websqlDBCache) {
|
|
@@ -668,7 +900,7 @@ IDBFactory.prototype.deleteDatabase = function (name) {
|
|
|
668
900
|
// above code with `DELETE FROM dbVersions`)
|
|
669
901
|
cleanupDatabaseResources(me.__openDatabase, name, escapedDatabaseName, databaseDeleted, dbError);
|
|
670
902
|
}, dbError);
|
|
671
|
-
}, dbError,
|
|
903
|
+
}, dbError, undefined, function (currentTask, err, done, rollback, commit) {
|
|
672
904
|
if (currentTask.readOnly || err) {
|
|
673
905
|
return true;
|
|
674
906
|
}
|
|
@@ -682,6 +914,7 @@ IDBFactory.prototype.deleteDatabase = function (name) {
|
|
|
682
914
|
return false;
|
|
683
915
|
});
|
|
684
916
|
return undefined;
|
|
917
|
+
// @ts-expect-error It's ok
|
|
685
918
|
}, dbError);
|
|
686
919
|
return undefined;
|
|
687
920
|
}, dbError);
|
|
@@ -692,6 +925,13 @@ IDBFactory.prototype.deleteDatabase = function (name) {
|
|
|
692
925
|
return req;
|
|
693
926
|
};
|
|
694
927
|
|
|
928
|
+
/**
|
|
929
|
+
*
|
|
930
|
+
* @param {import('./Key.js').Key} key1
|
|
931
|
+
* @param {import('./Key.js').Key} key2
|
|
932
|
+
* @throws {TypeError}
|
|
933
|
+
* @returns {0|1|-1}
|
|
934
|
+
*/
|
|
695
935
|
IDBFactory.prototype.cmp = function (key1, key2) {
|
|
696
936
|
if (!(this instanceof IDBFactory)) {
|
|
697
937
|
throw new TypeError('Illegal invocation');
|
|
@@ -709,7 +949,11 @@ IDBFactory.prototype.cmp = function (key1, key2) {
|
|
|
709
949
|
/**
|
|
710
950
|
* May return outdated information if a database has since been deleted.
|
|
711
951
|
* @see https://github.com/w3c/IndexedDB/pull/240/files
|
|
712
|
-
* @
|
|
952
|
+
* @this {IDBFactoryFull}
|
|
953
|
+
* @returns {Promise<{
|
|
954
|
+
* name: string,
|
|
955
|
+
* version: Integer
|
|
956
|
+
* }[]>}
|
|
713
957
|
*/
|
|
714
958
|
IDBFactory.prototype.databases = function () {
|
|
715
959
|
const me = this;
|
|
@@ -721,13 +965,20 @@ IDBFactory.prototype.databases = function () {
|
|
|
721
965
|
if (hasNullOrigin()) {
|
|
722
966
|
throw createDOMException('SecurityError', 'Cannot get IndexedDB database names from an opaque origin.');
|
|
723
967
|
}
|
|
968
|
+
/**
|
|
969
|
+
*
|
|
970
|
+
* @param {true|SQLTransaction|SQLError|DOMException|Error} tx
|
|
971
|
+
* @param {SQLError|DOMException|Error} [err]
|
|
972
|
+
* @returns {boolean}
|
|
973
|
+
*/
|
|
724
974
|
function dbGetDatabaseNamesError (tx, err) {
|
|
725
975
|
if (calledDbCreateError) {
|
|
726
|
-
return;
|
|
976
|
+
return true;
|
|
727
977
|
}
|
|
728
|
-
|
|
978
|
+
const er = err ? webSQLErrback(/** @type {SQLError} */ (err)) : tx;
|
|
729
979
|
calledDbCreateError = true;
|
|
730
|
-
reject(
|
|
980
|
+
reject(er);
|
|
981
|
+
return true;
|
|
731
982
|
}
|
|
732
983
|
createSysDB(me.__openDatabase, function () {
|
|
733
984
|
sysdb.readTransaction(function (sysReadTx) {
|
|
@@ -756,15 +1007,22 @@ IDBFactory.prototype.databases = function () {
|
|
|
756
1007
|
* @param {Integer} connIdx
|
|
757
1008
|
* @param {string} msg
|
|
758
1009
|
* @throws {TypeError}
|
|
1010
|
+
* @this {IDBFactoryFull}
|
|
759
1011
|
* @returns {void}
|
|
760
1012
|
*/
|
|
761
1013
|
IDBFactory.prototype.__forceClose = function (dbName, connIdx, msg) {
|
|
762
1014
|
const me = this;
|
|
1015
|
+
/**
|
|
1016
|
+
*
|
|
1017
|
+
* @param {import('./IDBDatabase.js').IDBDatabaseFull} conn
|
|
1018
|
+
* @returns {void}
|
|
1019
|
+
*/
|
|
763
1020
|
function forceClose (conn) {
|
|
764
1021
|
conn.__forceClose(msg);
|
|
765
1022
|
}
|
|
766
1023
|
if (util.isNullish(dbName)) {
|
|
767
|
-
Object.values(me.__connections).forEach((conn) => {
|
|
1024
|
+
(Object.values(me.__connections)).forEach((conn) => {
|
|
1025
|
+
// @ts-expect-error It's ok
|
|
768
1026
|
forceClose(conn);
|
|
769
1027
|
});
|
|
770
1028
|
} else if (!me.__connections[dbName]) {
|
|
@@ -783,6 +1041,11 @@ IDBFactory.prototype.__forceClose = function (dbName, connIdx, msg) {
|
|
|
783
1041
|
}
|
|
784
1042
|
};
|
|
785
1043
|
|
|
1044
|
+
/**
|
|
1045
|
+
*
|
|
1046
|
+
* @param {string} [origin]
|
|
1047
|
+
* @returns {void}
|
|
1048
|
+
*/
|
|
786
1049
|
IDBFactory.prototype.__setConnectionQueueOrigin = function (origin = getOrigin()) {
|
|
787
1050
|
connectionQueue[origin] = {};
|
|
788
1051
|
};
|