indexeddbshim 19.0.4 → 19.0.6
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/coverage-badge.svg +1 -1
- package/badges/tests-badge.svg +1 -1
- package/dist/CFG.d.ts +1 -1
- package/dist/CFG.d.ts.map +1 -1
- package/dist/DOMException.d.ts.map +1 -1
- package/dist/IDBCursor.d.ts.map +1 -1
- package/dist/IDBDatabase.d.ts.map +1 -1
- package/dist/IDBFactory.d.ts +1 -2
- package/dist/IDBFactory.d.ts.map +1 -1
- package/dist/IDBIndex.d.ts +2 -6
- package/dist/IDBIndex.d.ts.map +1 -1
- package/dist/IDBKeyRange.d.ts.map +1 -1
- package/dist/IDBObjectStore.d.ts.map +1 -1
- package/dist/IDBRecord.d.ts.map +1 -1
- package/dist/IDBRequest.d.ts.map +1 -1
- package/dist/IDBTransaction.d.ts.map +1 -1
- package/dist/Key.d.ts.map +1 -1
- package/dist/Sca.d.ts.map +1 -1
- package/dist/indexeddbshim-Key.js +40 -28
- 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 +525 -225
- package/dist/indexeddbshim-UnicodeIdentifiers-node.cjs.map +1 -1
- package/dist/indexeddbshim-UnicodeIdentifiers.js +553 -252
- package/dist/indexeddbshim-UnicodeIdentifiers.js.map +1 -1
- package/dist/indexeddbshim-UnicodeIdentifiers.min.js +3 -3
- package/dist/indexeddbshim-UnicodeIdentifiers.min.js.map +1 -1
- package/dist/indexeddbshim-node.cjs +525 -225
- package/dist/indexeddbshim-node.cjs.map +1 -1
- package/dist/indexeddbshim-noninvasive.js +553 -252
- package/dist/indexeddbshim-noninvasive.js.map +1 -1
- package/dist/indexeddbshim-noninvasive.min.js +3 -3
- package/dist/indexeddbshim-noninvasive.min.js.map +1 -1
- package/dist/indexeddbshim.js +553 -252
- package/dist/indexeddbshim.js.map +1 -1
- package/dist/indexeddbshim.min.js +3 -3
- package/dist/indexeddbshim.min.js.map +1 -1
- package/dist/nodeWebSQL.d.ts.map +1 -1
- package/dist/setGlobalVars.d.ts +1 -1
- package/dist/setGlobalVars.d.ts.map +1 -1
- package/dist/util.d.ts.map +1 -1
- package/package.json +22 -17
- package/src/CFG.js +18 -4
- package/src/DOMException.js +6 -0
- package/src/DOMStringList.js +3 -0
- package/src/IDBCursor.js +36 -3
- package/src/IDBDatabase.js +26 -10
- package/src/IDBFactory.js +105 -5
- package/src/IDBIndex.js +49 -32
- package/src/IDBKeyRange.js +8 -7
- package/src/IDBObjectStore.js +25 -2
- package/src/IDBRecord.js +2 -0
- package/src/IDBRequest.js +7 -4
- package/src/IDBTransaction.js +111 -34
- package/src/Key.js +17 -16
- package/src/Sca.js +9 -4
- package/src/nodeWebSQL.js +1 -0
- package/src/setGlobalVars.js +86 -77
- package/src/util.js +5 -6
package/src/IDBTransaction.js
CHANGED
|
@@ -273,10 +273,12 @@ IDBTransaction.prototype.__callTransFinishedCb = function (err, cb) {
|
|
|
273
273
|
*/
|
|
274
274
|
IDBTransaction.prototype.__executeRequests = function () {
|
|
275
275
|
const me = this;
|
|
276
|
+
/* c8 ignore start -- Dead code: `__executeRequests` has exactly one caller (a single `setTimeout` scheduled once per transaction), so `me.__running` can never already be `true` when this function starts. */
|
|
276
277
|
if (me.__running) {
|
|
277
278
|
if (CFG.DEBUG) { console.log('Looks like the request set is already running', me.mode); }
|
|
278
279
|
return;
|
|
279
280
|
}
|
|
281
|
+
/* c8 ignore stop -- see comment above */
|
|
280
282
|
|
|
281
283
|
// The synchronous script that created this transaction (and
|
|
282
284
|
// synchronously queued whatever requests it wanted to) has now
|
|
@@ -297,6 +299,10 @@ IDBTransaction.prototype.__executeRequests = function () {
|
|
|
297
299
|
let q,
|
|
298
300
|
i = -1;
|
|
299
301
|
|
|
302
|
+
// On a standard driver, `keepAliveAndWait` issues a SQL query, which
|
|
303
|
+
// is a macrotask. Otherwise it issues ten microtasks.
|
|
304
|
+
const keepAliveAttempts = isStandardDriver ? 1 : 10;
|
|
305
|
+
|
|
300
306
|
/**
|
|
301
307
|
* A continuation that must still be able to observe the
|
|
302
308
|
* transaction as safe to extend (e.g., re-checking whether an
|
|
@@ -323,6 +329,7 @@ IDBTransaction.prototype.__executeRequests = function () {
|
|
|
323
329
|
queueMicrotask(cb);
|
|
324
330
|
return;
|
|
325
331
|
}
|
|
332
|
+
/* c8 ignore start -- Browser-only path: in every automated test environment (Node's websql-configurable/better-sqlite3 driver, and the fake/mock drivers modeled after it) `__usesStandardDriver()` is always `false` (they support the 4-arg `nonstandardTransCb` signature), so `isStandardDriver` is never `true` and this branch is never reached. Only a real standard (3-arg) WebSQL driver, as found in an actual browser, would exercise it. */
|
|
326
333
|
try {
|
|
327
334
|
tx.executeSql('SELECT 1', [], function () {
|
|
328
335
|
cb();
|
|
@@ -332,10 +339,11 @@ IDBTransaction.prototype.__executeRequests = function () {
|
|
|
332
339
|
});
|
|
333
340
|
} catch (err) {
|
|
334
341
|
// The driver has already finalized the transaction (or otherwise
|
|
335
|
-
// rejected the call) -- nothing left to hold open
|
|
336
|
-
//
|
|
337
|
-
|
|
342
|
+
// rejected the call) -- nothing left to hold open. We explicitly
|
|
343
|
+
// abort the transaction here.
|
|
344
|
+
me.__abortTransaction(/** @type {Error|DOMException} */ (err));
|
|
338
345
|
}
|
|
346
|
+
/* c8 ignore stop -- see comment above */
|
|
339
347
|
}
|
|
340
348
|
|
|
341
349
|
/**
|
|
@@ -348,19 +356,25 @@ IDBTransaction.prototype.__executeRequests = function () {
|
|
|
348
356
|
* @returns {void}
|
|
349
357
|
*/
|
|
350
358
|
function success (result, req) {
|
|
359
|
+
/* c8 ignore start -- Defensive: only reached if the transaction was independently errored/finished by a concurrent path (e.g. a driver-level failure or explicit `abort()`) racing with this request's own in-flight SQL success callback; not reliably reproducible without directly manipulating the SQL driver's callback timing. */
|
|
351
360
|
if (me.__errored || me.__requestsFinished) {
|
|
352
361
|
// We've already called "onerror", "onabort", or thrown within the transaction, so don't do it again.
|
|
353
362
|
return;
|
|
354
363
|
}
|
|
364
|
+
/* c8 ignore stop -- see comment above */
|
|
355
365
|
if (req) {
|
|
356
366
|
q.req = req; // Need to do this in case of cursors
|
|
357
367
|
}
|
|
358
|
-
|
|
368
|
+
/* c8 ignore start -- Dead code: `launchQueuedOp` only ever passes `success` as a callback in the branch where `q.req` is already truthy, and a falsy `req` param here leaves `q.req` unchanged, so `q.req` can't be falsy at this point. */
|
|
369
|
+
if (!q.req) {
|
|
359
370
|
return;
|
|
360
371
|
}
|
|
372
|
+
/* c8 ignore stop -- see comment above */
|
|
373
|
+
/* c8 ignore start -- Defensive: only reached if the SQL driver invoked this request's success callback more than once for the same queued op; not reliably reproducible without directly manipulating the SQL driver. */
|
|
361
374
|
if (q.req.__done) { // Avoid continuing with aborted requests
|
|
362
375
|
return;
|
|
363
376
|
}
|
|
377
|
+
/* c8 ignore stop -- see comment above */
|
|
364
378
|
q.req.__done = true;
|
|
365
379
|
q.req.__result = result;
|
|
366
380
|
q.req.__error = null;
|
|
@@ -378,6 +392,7 @@ IDBTransaction.prototype.__executeRequests = function () {
|
|
|
378
392
|
// is what actually resets `__handlerActive`, once it's
|
|
379
393
|
// confirmed (across its own bounded microtask wait) that no
|
|
380
394
|
// such continuation queued anything.
|
|
395
|
+
/* c8 ignore start -- Deliberately not tested: throwing from a request's `onsuccess` handler to exercise this branch would surface as an uncaught error through this test suite's `window.onerror` shim, which (per `retention-spec.js`'s `assertLater` comment) can trigger unbounded recursion here; not safe to trigger directly. */
|
|
381
396
|
if (e.__legacyOutputDidListenersThrowError) {
|
|
382
397
|
logError('Error', 'An error occurred in a success handler attached to request chain', e.__legacyOutputDidListenersThrowError); // We do nothing else with this error as per spec
|
|
383
398
|
if (!me.__committed) { // An explicit `commit()` locks in the commit, so errors thrown afterward must not abort it
|
|
@@ -386,6 +401,7 @@ IDBTransaction.prototype.__executeRequests = function () {
|
|
|
386
401
|
return;
|
|
387
402
|
}
|
|
388
403
|
}
|
|
404
|
+
/* c8 ignore stop -- see comment above */
|
|
389
405
|
util.runContinuationSafely(advanceAfterDispatch);
|
|
390
406
|
}
|
|
391
407
|
|
|
@@ -397,14 +413,18 @@ IDBTransaction.prototype.__executeRequests = function () {
|
|
|
397
413
|
* @returns {void}
|
|
398
414
|
*/
|
|
399
415
|
function error (...args /* tx, err */) {
|
|
416
|
+
/* c8 ignore start -- Defensive: only reached if the transaction was independently errored/finished by a concurrent path racing with this request's own in-flight SQL error callback; not reliably reproducible without directly manipulating the SQL driver's callback timing. */
|
|
400
417
|
if (me.__errored || me.__requestsFinished) {
|
|
401
418
|
// We've already called "onerror", "onabort", or thrown within
|
|
402
419
|
// the transaction, so don't do it again.
|
|
403
420
|
return;
|
|
404
421
|
}
|
|
422
|
+
/* c8 ignore stop -- see comment above */
|
|
423
|
+
/* c8 ignore start -- Defensive: only reached if the SQL driver invoked this request's error callback more than once, or after its success callback already ran; not reliably reproducible without directly manipulating the SQL driver. */
|
|
405
424
|
if (q.req && q.req.__done) { // Avoid continuing with aborted requests
|
|
406
425
|
return;
|
|
407
426
|
}
|
|
427
|
+
/* c8 ignore stop -- see comment above */
|
|
408
428
|
const err = /** @type {Error|DOMException} */ (findError(args));
|
|
409
429
|
if (!q.req) {
|
|
410
430
|
me.__abortTransaction(err);
|
|
@@ -428,9 +448,11 @@ IDBTransaction.prototype.__executeRequests = function () {
|
|
|
428
448
|
}
|
|
429
449
|
);
|
|
430
450
|
q.req.addDefaultEventListener('error', function () {
|
|
431
|
-
|
|
451
|
+
/* c8 ignore start -- Defensive: this default listener is skipped entirely by `eventtargeter` whenever the event was `preventDefault()`-ed (the only case in which the shared `q` variable above could have already advanced to a different, non-request queue entry by the time a default listener runs); not reachable via the public API under normal (synchronous) dispatch. */
|
|
452
|
+
if (!q.req) {
|
|
432
453
|
return;
|
|
433
454
|
}
|
|
455
|
+
/* c8 ignore stop -- see comment above */
|
|
434
456
|
me.__abortTransaction(q.req.__error);
|
|
435
457
|
});
|
|
436
458
|
|
|
@@ -440,15 +462,19 @@ IDBTransaction.prototype.__executeRequests = function () {
|
|
|
440
462
|
q.req.dispatchEvent(e);
|
|
441
463
|
// Do not set __active or __handlerActive flags to false yet --
|
|
442
464
|
// see the matching comment in `success`, above.
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
465
|
+
/* c8 ignore start -- Deliberately not tested: throwing from a request's `onerror` handler to exercise this branch would surface as an uncaught error through this test suite's `window.onerror` shim, which (per `retention-spec.js`'s `assertLater` comment) can trigger unbounded recursion here; not safe to trigger directly. */
|
|
466
|
+
if (!e.__legacyOutputDidListenersThrowError) {
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
logError('Error', 'An error occurred in an error handler attached to request chain', e.__legacyOutputDidListenersThrowError); // We do nothing else with this error as per spec
|
|
471
|
+
e.preventDefault(); // Prevent 'error' default as steps indicate we should abort with `AbortError` even without cancellation
|
|
472
|
+
if (me.__committed) { // An explicit `commit()` locks in the commit, so errors thrown afterward must not abort it
|
|
473
|
+
util.runContinuationSafely(advanceAfterDispatch);
|
|
474
|
+
return;
|
|
451
475
|
}
|
|
476
|
+
me.__abortTransaction(createDOMException('AbortError', 'A request was aborted (in user handler after error).'));
|
|
477
|
+
/* c8 ignore stop -- see comment above */
|
|
452
478
|
}
|
|
453
479
|
|
|
454
480
|
/**
|
|
@@ -472,9 +498,11 @@ IDBTransaction.prototype.__executeRequests = function () {
|
|
|
472
498
|
// (not reset here).
|
|
473
499
|
return true;
|
|
474
500
|
}
|
|
501
|
+
/* c8 ignore start -- Defensive: reaching this queue entry via the normal advancement path after it was independently marked `__done` (e.g. by `__abortTransaction`'s own separate, async per-request error dispatch) requires a narrow race between that async cleanup and this synchronous advancement; not reliably reproducible without directly manipulating that timing. */
|
|
475
502
|
if (q.req.__done) { // Avoid continuing with aborted requests
|
|
476
503
|
return false;
|
|
477
504
|
}
|
|
505
|
+
/* c8 ignore stop -- see comment above */
|
|
478
506
|
// We're now handing off to (possibly async) work for
|
|
479
507
|
// this request, so the transaction is no longer active
|
|
480
508
|
// until its own `success`/`error` dispatch (below)
|
|
@@ -497,18 +525,22 @@ IDBTransaction.prototype.__executeRequests = function () {
|
|
|
497
525
|
return;
|
|
498
526
|
}
|
|
499
527
|
q.op(tx, q.args, success, error, executeNextRequest);
|
|
528
|
+
/* c8 ignore start -- Defensive: `q.op` (the SQL driver callback) is expected to report failures via its own `error`/`failure` callback argument rather than throwing synchronously; not reliably reproducible without directly forcing the driver to throw. */
|
|
500
529
|
} catch (e) {
|
|
501
530
|
error(/** @type {Error} */ (e));
|
|
502
531
|
}
|
|
532
|
+
/* c8 ignore stop -- see comment above */
|
|
503
533
|
}
|
|
504
534
|
|
|
505
535
|
/**
|
|
506
536
|
* @returns {void}
|
|
507
537
|
*/
|
|
508
538
|
function runQueuedRequest () {
|
|
539
|
+
/* c8 ignore start -- Defensive: only reached if `prepareNextRequest` returns `false` (see its own ignore comment above for why that's not reliably reproducible). */
|
|
509
540
|
if (!prepareNextRequest()) {
|
|
510
541
|
return;
|
|
511
542
|
}
|
|
543
|
+
/* c8 ignore stop -- see comment above */
|
|
512
544
|
launchQueuedOp();
|
|
513
545
|
}
|
|
514
546
|
|
|
@@ -530,16 +562,20 @@ IDBTransaction.prototype.__executeRequests = function () {
|
|
|
530
562
|
* consumer of that same handler (e.g. one that resolves a
|
|
531
563
|
* promise from within `onsuccess` and only attaches `oncomplete`
|
|
532
564
|
* afterward) ever gets a turn to run, so it can miss `complete`
|
|
533
|
-
*
|
|
534
|
-
*
|
|
535
|
-
*
|
|
565
|
+
* afterward) ever gets a turn to run, so it can miss `complete`
|
|
566
|
+
* entirely. On a non-standard driver, `readonly` requests don't hold
|
|
567
|
+
* a real SQL transaction open, so there's no file-lock/connection
|
|
568
|
+
* collision risk. On a standard driver, the wait now issues real SQL
|
|
569
|
+
* inside the read transaction, so this does carry a slight risk.
|
|
536
570
|
* @param {number} attemptsLeft
|
|
537
571
|
* @returns {void}
|
|
538
572
|
*/
|
|
539
573
|
function checkQueueEntry (attemptsLeft) {
|
|
574
|
+
/* c8 ignore start -- Defensive: only reached if the transaction is independently errored/finished (e.g. an explicit `abort()`) during this function's keep-alive polling wait; not reliably reproducible without a contrived timing race. */
|
|
540
575
|
if (me.__errored || me.__requestsFinished) {
|
|
541
576
|
return;
|
|
542
577
|
}
|
|
578
|
+
/* c8 ignore stop -- see comment above */
|
|
543
579
|
if (i < me.__requests.length) {
|
|
544
580
|
runQueuedRequest();
|
|
545
581
|
return;
|
|
@@ -561,13 +597,15 @@ IDBTransaction.prototype.__executeRequests = function () {
|
|
|
561
597
|
* @returns {void}
|
|
562
598
|
*/
|
|
563
599
|
function executeNextRequest () {
|
|
600
|
+
/* c8 ignore start -- Defensive: only reached if the transaction was independently errored/finished by a concurrent path racing with this continuation; not reliably reproducible without a contrived timing race. */
|
|
564
601
|
if (me.__errored || me.__requestsFinished) {
|
|
565
602
|
// We've already called "onerror", "onabort", or thrown within the transaction, so don't do it again.
|
|
566
603
|
return;
|
|
567
604
|
}
|
|
605
|
+
/* c8 ignore stop -- see comment above */
|
|
568
606
|
i++;
|
|
569
607
|
if (i >= me.__requests.length) {
|
|
570
|
-
checkQueueEntry(
|
|
608
|
+
checkQueueEntry(keepAliveAttempts);
|
|
571
609
|
return;
|
|
572
610
|
}
|
|
573
611
|
runQueuedRequest();
|
|
@@ -599,21 +637,22 @@ IDBTransaction.prototype.__executeRequests = function () {
|
|
|
599
637
|
* @returns {void}
|
|
600
638
|
*/
|
|
601
639
|
function advanceAfterDispatch () {
|
|
640
|
+
/* c8 ignore start -- Defensive: only reached if the transaction was independently errored/finished by a concurrent path racing with this continuation; not reliably reproducible without a contrived timing race. */
|
|
602
641
|
if (me.__errored || me.__requestsFinished) {
|
|
603
642
|
return;
|
|
604
643
|
}
|
|
644
|
+
/* c8 ignore stop -- see comment above */
|
|
605
645
|
i++;
|
|
606
646
|
if (i >= me.__requests.length) {
|
|
607
|
-
checkQueueEntry(
|
|
647
|
+
checkQueueEntry(keepAliveAttempts);
|
|
608
648
|
return;
|
|
609
649
|
}
|
|
610
650
|
keepAliveAndWait(() => {
|
|
611
|
-
if (
|
|
612
|
-
|
|
613
|
-
}
|
|
614
|
-
if (!prepareNextRequest()) {
|
|
651
|
+
/* c8 ignore start -- Defensive: only reached if the transaction was independently errored/finished (or the next request's preparation failed) by a concurrent path racing with this continuation; not reliably reproducible without a contrived timing race. */
|
|
652
|
+
if (me.__errored || me.__requestsFinished || !prepareNextRequest()) {
|
|
615
653
|
return;
|
|
616
654
|
}
|
|
655
|
+
/* c8 ignore stop -- see comment above */
|
|
617
656
|
launchQueuedOp();
|
|
618
657
|
});
|
|
619
658
|
}
|
|
@@ -621,10 +660,12 @@ IDBTransaction.prototype.__executeRequests = function () {
|
|
|
621
660
|
executeNextRequest();
|
|
622
661
|
},
|
|
623
662
|
function webSQLError (webSQLErr) {
|
|
663
|
+
/* c8 ignore start -- Dead code: the underlying websql-configurable driver's `_onTransactionComplete` always passes either `null` or a genuine `Error`/`DOMException` as this callback's argument, never the literal value `true`, under any driver used by the test suite. */
|
|
624
664
|
// @ts-expect-error It's ok
|
|
625
665
|
if (webSQLErr === true) { // Not a genuine SQL error
|
|
626
666
|
return;
|
|
627
667
|
}
|
|
668
|
+
/* c8 ignore stop -- see comment above */
|
|
628
669
|
const err = webSQLErrback(/** @type {Error & {code?: number}} */ (webSQLErr));
|
|
629
670
|
me.__abortTransaction(err);
|
|
630
671
|
},
|
|
@@ -635,19 +676,27 @@ IDBTransaction.prototype.__executeRequests = function () {
|
|
|
635
676
|
if (me.__transFinishedCb !== IDBTransaction.prototype.__transFinishedCb) { // Node
|
|
636
677
|
return;
|
|
637
678
|
}
|
|
679
|
+
/* c8 ignore start -- Defensive: reaching this callback before `requestsFinished` has already set `__transactionEndCallback` (or finished) would require the underlying driver's own "queue empty" signal to race ahead of this codebase's own request-completion tracking; not observed (nor reliably reproducible) in this test suite, where the latter always wins. */
|
|
638
680
|
if (!me.__transactionEndCallback && !me.__requestsFinished) {
|
|
639
681
|
me.__transactionFinished = true;
|
|
640
682
|
return;
|
|
641
683
|
}
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
684
|
+
/* c8 ignore stop -- see comment above */
|
|
685
|
+
/* c8 ignore start -- Dead code in practice: by the time this callback runs, `requestsFinished` has always already set `__transactionEndCallback` (per the guard above), and `__completed`/`__transFinishedCbFired` are always already set true by `requestsFinished`'s own `__callTransFinishedCb` call, so this guard always returns early and the fall-through body below is never reached; not reliably reproducible without a contrived timing race. */
|
|
686
|
+
if (!me.__transactionEndCallback || me.__completed || me.__transFinishedCbFired) {
|
|
687
|
+
return;
|
|
645
688
|
}
|
|
689
|
+
|
|
690
|
+
me.__transFinishedCbFired = true;
|
|
691
|
+
me.__transFinishedCb(me.__errored, me.__transactionEndCallback);
|
|
692
|
+
/* c8 ignore stop -- see comment above */
|
|
646
693
|
},
|
|
647
694
|
function (currentTask, err, done, rollback, commit) {
|
|
695
|
+
/* c8 ignore start -- Defensive: `err` here would mean the underlying WebSQL/SQLite driver reported a genuine unhandled SQL error bubbling out of this transaction's own executed statements -- every `executeSql` error callback in this codebase already handles/reports its own errors (returning `false`), so this is not reliably reproducible without mocking the SQL layer. */
|
|
648
696
|
if (err) {
|
|
649
697
|
return true;
|
|
650
698
|
}
|
|
699
|
+
/* c8 ignore stop -- see comment above */
|
|
651
700
|
// `readonly` transactions never hold a real SQL transaction open
|
|
652
701
|
// (see `WebSQLTransaction`'s constructor skipping `BEGIN;` for
|
|
653
702
|
// them), so there's no commit/rollback round trip to defer --
|
|
@@ -699,6 +748,7 @@ IDBTransaction.prototype.__executeRequests = function () {
|
|
|
699
748
|
*/
|
|
700
749
|
function complete () {
|
|
701
750
|
me.__completed = true;
|
|
751
|
+
/* c8 ignore next -- Debug-only log; no test sets `CFG.DEBUG`. */
|
|
702
752
|
if (CFG.DEBUG) { console.log('Transaction completed'); }
|
|
703
753
|
const evt = createEvent('complete');
|
|
704
754
|
try {
|
|
@@ -706,6 +756,7 @@ IDBTransaction.prototype.__executeRequests = function () {
|
|
|
706
756
|
me.dispatchEvent(evt);
|
|
707
757
|
me.__internal = false;
|
|
708
758
|
me.dispatchEvent(createEvent('__complete'));
|
|
759
|
+
/* c8 ignore start -- Deliberately not tested: throwing from an `oncomplete`/`__complete` handler to exercise this branch would surface as an uncaught error through this test suite's `window.onerror` shim, which (per `retention-spec.js`'s `assertLater` comment) can trigger unbounded recursion here; not safe to trigger directly. */
|
|
709
760
|
} catch (e) {
|
|
710
761
|
me.__internal = false;
|
|
711
762
|
// An error occurred in the "oncomplete" handler.
|
|
@@ -713,6 +764,7 @@ IDBTransaction.prototype.__executeRequests = function () {
|
|
|
713
764
|
// (this may seem odd/bad, but it's how all native IndexedDB implementations work)
|
|
714
765
|
me.__errored = true;
|
|
715
766
|
throw e;
|
|
767
|
+
/* c8 ignore stop -- see comment above */
|
|
716
768
|
} finally {
|
|
717
769
|
activeTransactions.delete(me);
|
|
718
770
|
me.__storeHandles = {};
|
|
@@ -720,10 +772,12 @@ IDBTransaction.prototype.__executeRequests = function () {
|
|
|
720
772
|
}
|
|
721
773
|
}
|
|
722
774
|
if (me.mode === 'readwrite' || me.mode === 'readonly') {
|
|
775
|
+
/* c8 ignore start -- Dead code in practice: `__transactionFinished` is only ever set by the driver-queue-idle-races-ahead scenario described above (also `c8 ignore`d there), which is not observed in this test suite. */
|
|
723
776
|
if (me.__transactionFinished) {
|
|
724
777
|
complete();
|
|
725
778
|
return;
|
|
726
779
|
}
|
|
780
|
+
/* c8 ignore stop -- see comment above */
|
|
727
781
|
me.__transactionEndCallback = complete;
|
|
728
782
|
// The underlying SQL driver's own "queue empty" check
|
|
729
783
|
// (`nonstandardTransCb`, above) typically already ran and
|
|
@@ -760,6 +814,7 @@ IDBTransaction.prototype.__executeRequests = function () {
|
|
|
760
814
|
IDBTransaction.prototype.__createRequest = function (source) {
|
|
761
815
|
const me = this;
|
|
762
816
|
const request = IDBRequest.__createInstance();
|
|
817
|
+
/* c8 ignore next -- Defensive: every call site (via `__addToTransactionQueue` or directly) always passes an explicit `source`, so the `me.db` fallback is not reachable via the public API. */
|
|
763
818
|
request.__source = source !== undefined ? source : me.db;
|
|
764
819
|
request.__transaction = me;
|
|
765
820
|
return request;
|
|
@@ -829,9 +884,11 @@ IDBTransaction.prototype.__pushToQueue = function (request, callback, args) {
|
|
|
829
884
|
* @returns {void}
|
|
830
885
|
*/
|
|
831
886
|
IDBTransaction.prototype.__assertActive = function () {
|
|
887
|
+
/* c8 ignore start -- Defensive: every call site (via `__addToTransactionQueue`/`__addNonRequestToTransactionQueue`) either already performed the static `IDBTransaction.__assertActive(tx)` check synchronously just beforehand, or queues against a transaction just created fresh (necessarily active), so this redundant instance-level check is not reachable via the public API. */
|
|
832
888
|
if (!this.__active || !this.__handlerActive || this.__committed) {
|
|
833
889
|
throw createDOMException('TransactionInactiveError', 'A request was placed against a transaction which is currently not active, or which is finished');
|
|
834
890
|
}
|
|
891
|
+
/* c8 ignore stop -- see comment above */
|
|
835
892
|
};
|
|
836
893
|
|
|
837
894
|
/**
|
|
@@ -845,6 +902,7 @@ IDBTransaction.prototype.__assertWritable = function () {
|
|
|
845
902
|
}
|
|
846
903
|
};
|
|
847
904
|
|
|
905
|
+
/* c8 ignore start -- Dead code: this instance method has no callers anywhere in src/ (confirmed via grep); every real call site uses the static `IDBTransaction.__assertVersionChange(tx)` directly instead. */
|
|
848
906
|
/**
|
|
849
907
|
* @this {IDBTransactionFull}
|
|
850
908
|
* @returns {void}
|
|
@@ -852,6 +910,7 @@ IDBTransaction.prototype.__assertWritable = function () {
|
|
|
852
910
|
IDBTransaction.prototype.__assertVersionChange = function () {
|
|
853
911
|
IDBTransaction.__assertVersionChange(this);
|
|
854
912
|
};
|
|
913
|
+
/* c8 ignore stop -- see comment above */
|
|
855
914
|
|
|
856
915
|
/**
|
|
857
916
|
* Returns the specified object store.
|
|
@@ -872,9 +931,11 @@ IDBTransaction.prototype.objectStore = function (objectStoreName) {
|
|
|
872
931
|
throw createDOMException('NotFoundError', objectStoreName + ' is not participating in this transaction');
|
|
873
932
|
}
|
|
874
933
|
const store = me.db.__objectStores[objectStoreName];
|
|
934
|
+
/* c8 ignore start -- Defensive: `me.__objectStoreNames` (checked just above) and `me.db.__objectStores` are always kept in sync by every code path that adds/renames/removes a store, so a name that passes the participation check above should always also be found here; not reliably reproducible via the public API. */
|
|
875
935
|
if (!store) {
|
|
876
936
|
throw createDOMException('NotFoundError', objectStoreName + ' does not exist in ' + me.db.name);
|
|
877
937
|
}
|
|
938
|
+
/* c8 ignore stop -- see comment above */
|
|
878
939
|
|
|
879
940
|
if (!Object.hasOwn(me.__storeHandles, objectStoreName) ||
|
|
880
941
|
// These latter conditions are to allow store
|
|
@@ -895,10 +956,12 @@ IDBTransaction.prototype.objectStore = function (objectStoreName) {
|
|
|
895
956
|
IDBTransaction.prototype.__abortTransaction = function (err) {
|
|
896
957
|
const me = this;
|
|
897
958
|
logError('Error', 'An error occurred in a transaction', err);
|
|
959
|
+
/* c8 ignore start -- Defensive re-entrancy guard: only reached if `__abortTransaction` is invoked a second time on the same transaction after `__errored` is already `true` (e.g. two independent internal error paths racing); not reliably reproducible without a contrived timing race. */
|
|
898
960
|
if (me.__errored) {
|
|
899
961
|
// We've already called "onerror", "onabort", or thrown, so don't do it again.
|
|
900
962
|
return;
|
|
901
963
|
}
|
|
964
|
+
/* c8 ignore stop -- see comment above */
|
|
902
965
|
me.__errored = true;
|
|
903
966
|
|
|
904
967
|
if (me.mode === 'versionchange') { // Steps for aborting an upgrade transaction
|
|
@@ -936,19 +999,15 @@ IDBTransaction.prototype.__abortTransaction = function (err) {
|
|
|
936
999
|
me.__error = err;
|
|
937
1000
|
}
|
|
938
1001
|
|
|
1002
|
+
/* c8 ignore start -- Defense in depth: `err` is only ever `null` here via `IDBTransaction.prototype.abort`'s own `__abortTransaction(null)` call, which now checks `__requestsFinished` itself first and throws `InvalidStateError` synchronously before ever reaching this point -- so this guard should not see a non-null `err` in practice. */
|
|
939
1003
|
if (me.__requestsFinished && err !== null) {
|
|
940
1004
|
// The transaction has already completed, so we can't call "onerror" or "onabort".
|
|
941
|
-
// So throw the error instead.
|
|
942
|
-
// `IDBTransaction.prototype.abort`'s own `__abortTransaction(null)`
|
|
943
|
-
// call, which now checks `__requestsFinished` itself first and
|
|
944
|
-
// throws `InvalidStateError` synchronously before ever reaching
|
|
945
|
-
// this point -- so this guard is just defense in depth against
|
|
946
|
-
// `err` somehow being `null` some other way, not something this
|
|
947
|
-
// path should see in practice.
|
|
1005
|
+
// So throw the error instead.
|
|
948
1006
|
setTimeout(() => {
|
|
949
1007
|
throw err;
|
|
950
1008
|
}, 0);
|
|
951
1009
|
}
|
|
1010
|
+
/* c8 ignore stop -- see comment above */
|
|
952
1011
|
|
|
953
1012
|
/**
|
|
954
1013
|
* @param {import('websql-configurable/lib/websql/WebSQLTransaction.js').default|null} [tx]
|
|
@@ -957,9 +1016,13 @@ IDBTransaction.prototype.__abortTransaction = function (err) {
|
|
|
957
1016
|
*/
|
|
958
1017
|
function abort (tx, errOrResult) {
|
|
959
1018
|
if (!tx) {
|
|
1019
|
+
/* c8 ignore next -- Debug-only log; only reached via the no-op `abort()` calls below (rare paths), and requires `CFG.DEBUG` to have any effect anyway. */
|
|
960
1020
|
if (CFG.DEBUG) { console.log('Rollback not possible due to missing transaction', me); }
|
|
1021
|
+
/* c8 ignore start -- Defensive: the underlying WebSQL/SQLite driver erroring on the manual `ROLLBACK` executed below (with a result object exposing a numeric `code`) is not reliably reproducible without mocking the SQL layer. */
|
|
961
1022
|
} else if (errOrResult && 'code' in errOrResult && typeof errOrResult.code === 'number') {
|
|
962
1023
|
if (CFG.DEBUG) { console.log('Rollback erred; feature is probably not supported as per WebSQL', me); }
|
|
1024
|
+
/* c8 ignore stop -- see comment above */
|
|
1025
|
+
/* c8 ignore next -- Debug-only log; no test sets `CFG.DEBUG`. */
|
|
963
1026
|
} else if (CFG.DEBUG) { console.log('Rollback succeeded', me); }
|
|
964
1027
|
|
|
965
1028
|
me.dispatchEvent(createEvent('__preabort'));
|
|
@@ -973,9 +1036,11 @@ IDBTransaction.prototype.__abortTransaction = function (err) {
|
|
|
973
1036
|
// behaves first-in-first-out with the same timeout so we could
|
|
974
1037
|
// just use a `forEach`.
|
|
975
1038
|
return promises.then(function () {
|
|
976
|
-
|
|
1039
|
+
/* c8 ignore start -- Dead code: the preceding `.filter()` only keeps entries with a truthy `q.req`, and nothing ever resets `q.req` back to a falsy value afterward, so this invariant can't actually be violated. */
|
|
1040
|
+
if (!q.req) {
|
|
977
1041
|
throw new Error('Missing request');
|
|
978
1042
|
}
|
|
1043
|
+
/* c8 ignore stop -- see comment above */
|
|
979
1044
|
q.req.__done = true;
|
|
980
1045
|
q.req.__result = undefined;
|
|
981
1046
|
q.req.__error = createDOMException('AbortError', 'A request was aborted (an unfinished request).');
|
|
@@ -984,9 +1049,11 @@ IDBTransaction.prototype.__abortTransaction = function (err) {
|
|
|
984
1049
|
/** @type {(resolve: (value?: unknown) => void) => void} */
|
|
985
1050
|
(resolve) => {
|
|
986
1051
|
setTimeout(() => {
|
|
987
|
-
|
|
1052
|
+
/* c8 ignore start -- Dead code: same invariant as above -- `q.req` was already confirmed truthy by the outer `.filter()` and is never reset. */
|
|
1053
|
+
if (!q.req) {
|
|
988
1054
|
throw new Error('Missing request');
|
|
989
1055
|
}
|
|
1056
|
+
/* c8 ignore stop -- see comment above */
|
|
990
1057
|
q.req.dispatchEvent(reqEvt); // No need to catch errors
|
|
991
1058
|
resolve();
|
|
992
1059
|
}, 0);
|
|
@@ -1003,10 +1070,12 @@ IDBTransaction.prototype.__abortTransaction = function (err) {
|
|
|
1003
1070
|
releaseFinishedTransaction(me);
|
|
1004
1071
|
}, 0);
|
|
1005
1072
|
return undefined;
|
|
1073
|
+
/* c8 ignore start -- Diagnostic safety net: nothing in the preceding promise chain normally rejects (the only throws it could catch are the dead invariant-violation checks above), so this handler is not reachable in practice. */
|
|
1006
1074
|
}).catch((err) => {
|
|
1007
1075
|
console.log('Abort error');
|
|
1008
1076
|
throw err;
|
|
1009
1077
|
});
|
|
1078
|
+
/* c8 ignore stop -- see comment above */
|
|
1010
1079
|
}
|
|
1011
1080
|
|
|
1012
1081
|
me.__transFinishedCb(true, function (rollback) {
|
|
@@ -1014,10 +1083,12 @@ IDBTransaction.prototype.__abortTransaction = function (err) {
|
|
|
1014
1083
|
// rollback automatically), but for Node.js, etc., we give chance for
|
|
1015
1084
|
// manual aborts which would otherwise not work.
|
|
1016
1085
|
if (me.mode === 'readwrite') {
|
|
1086
|
+
/* c8 ignore start -- Dead code in practice: `__transactionFinished` is only ever set by the driver-queue-idle-races-ahead scenario described earlier in this file (also `c8 ignore`d there), which is not observed in this test suite. */
|
|
1017
1087
|
if (me.__transactionFinished) {
|
|
1018
1088
|
abort();
|
|
1019
1089
|
return;
|
|
1020
1090
|
}
|
|
1091
|
+
/* c8 ignore stop -- see comment above */
|
|
1021
1092
|
me.__transactionEndCallback = abort;
|
|
1022
1093
|
return;
|
|
1023
1094
|
}
|
|
@@ -1028,11 +1099,13 @@ IDBTransaction.prototype.__abortTransaction = function (err) {
|
|
|
1028
1099
|
abort,
|
|
1029
1100
|
/** @type {import('websql-configurable/lib/websql/WebSQLTransaction.js').SqlErrorCallback} */ (abort)
|
|
1030
1101
|
); // Not working in some circumstances, even in Node
|
|
1102
|
+
/* c8 ignore start -- Defensive: the underlying WebSQL/SQLite driver throwing synchronously on `ROLLBACK` is not reliably reproducible without mocking the SQL layer. */
|
|
1031
1103
|
} catch (err) {
|
|
1032
1104
|
// Browser errs when transaction has ended and since it most likely already erred here,
|
|
1033
1105
|
// we call to abort
|
|
1034
1106
|
abort();
|
|
1035
1107
|
}
|
|
1108
|
+
/* c8 ignore stop -- see comment above */
|
|
1036
1109
|
} else {
|
|
1037
1110
|
abort(null, {code: 0});
|
|
1038
1111
|
}
|
|
@@ -1048,6 +1121,7 @@ IDBTransaction.prototype.abort = function () {
|
|
|
1048
1121
|
if (!(me instanceof IDBTransaction)) {
|
|
1049
1122
|
throw new TypeError('Illegal invocation');
|
|
1050
1123
|
}
|
|
1124
|
+
/* c8 ignore next -- Debug-only log; no test sets `CFG.DEBUG`. */
|
|
1051
1125
|
if (CFG.DEBUG) { console.log('The transaction was aborted', me); }
|
|
1052
1126
|
IDBTransaction.__assertNotFinished(me);
|
|
1053
1127
|
if (me.__committed) {
|
|
@@ -1077,6 +1151,7 @@ IDBTransaction.prototype.commit = function () {
|
|
|
1077
1151
|
if (!me.__active || !me.__handlerActive || me.__committed) {
|
|
1078
1152
|
throw createDOMException('InvalidStateError', 'Failed to execute \'commit\' on \'IDBTransaction\': The transaction is not active.');
|
|
1079
1153
|
}
|
|
1154
|
+
/* c8 ignore next -- Debug-only log; no test sets `CFG.DEBUG`. */
|
|
1080
1155
|
if (CFG.DEBUG) { console.log('The transaction was explicitly committed', me); }
|
|
1081
1156
|
me.__committed = true;
|
|
1082
1157
|
};
|
|
@@ -1118,6 +1193,7 @@ IDBTransaction.__assertNotFinished = function (tx) {
|
|
|
1118
1193
|
};
|
|
1119
1194
|
|
|
1120
1195
|
// object store methods behave differently: see https://github.com/w3c/IndexedDB/issues/192
|
|
1196
|
+
/* c8 ignore start -- Dead code: this function has no callers anywhere in src/ (confirmed via grep); object store methods use `IDBTransaction.__assertActive`/`__assertNotFinished` directly instead. */
|
|
1121
1197
|
/**
|
|
1122
1198
|
*
|
|
1123
1199
|
* @param {IDBTransactionFull} tx
|
|
@@ -1133,6 +1209,7 @@ IDBTransaction.__assertNotFinishedObjectStoreMethod = function (tx) {
|
|
|
1133
1209
|
throw err;
|
|
1134
1210
|
}
|
|
1135
1211
|
};
|
|
1212
|
+
/* c8 ignore stop -- see comment above */
|
|
1136
1213
|
|
|
1137
1214
|
/**
|
|
1138
1215
|
*
|
package/src/Key.js
CHANGED
|
@@ -613,8 +613,14 @@ function convertValueToKeyValueDecoded (input, seen, multiEntry, fullKeys) {
|
|
|
613
613
|
(!fullKeys && keys.every((k) => cmp(
|
|
614
614
|
/** @type {Key} */ (k), /** @type {Key} */ (key.value)
|
|
615
615
|
) !== 0)) ||
|
|
616
|
+
// `keys` holds full `{type, value}` objects here (see
|
|
617
|
+
// `safePush` below), so -- like the sibling branch
|
|
618
|
+
// above -- `cmp` (which expects raw `Value`s, not
|
|
619
|
+
// decoded key objects) must compare their `.value`s,
|
|
620
|
+
// not the wrapper objects themselves.
|
|
616
621
|
(fullKeys && keys.every((k) => cmp(
|
|
617
|
-
/** @type {Key} */ (
|
|
622
|
+
/** @type {Key} */ (/** @type {KeyValueObject} */ (k).value),
|
|
623
|
+
/** @type {Key} */ (key.value)
|
|
618
624
|
) !== 0))
|
|
619
625
|
) {
|
|
620
626
|
safePush(keys, fullKeys ? key : key.value);
|
|
@@ -629,9 +635,7 @@ function convertValueToKeyValueDecoded (input, seen, multiEntry, fullKeys) {
|
|
|
629
635
|
} case 'date': {
|
|
630
636
|
const date = /** @type {Date} */ (input);
|
|
631
637
|
if (!Number.isNaN(date.getTime())) {
|
|
632
|
-
return fullKeys
|
|
633
|
-
? {type, value: date.getTime()}
|
|
634
|
-
: {type, value: new Date(date)};
|
|
638
|
+
return {type, value: fullKeys ? date.getTime() : new Date(date)};
|
|
635
639
|
}
|
|
636
640
|
return {type, invalid: true, message: 'Not a valid date'};
|
|
637
641
|
// Falls through
|
|
@@ -707,10 +711,9 @@ function extractKeyValueDecodedFromValueUsingKeyPath (value, keyPath, multiEntry
|
|
|
707
711
|
if (r.failure) {
|
|
708
712
|
return r;
|
|
709
713
|
}
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
return convertValueToMultiEntryKeyDecoded(r.value, fullKeys);
|
|
714
|
+
return !multiEntry
|
|
715
|
+
? convertValueToKeyValueDecoded(r.value, null, false, fullKeys)
|
|
716
|
+
: convertValueToMultiEntryKeyDecoded(r.value, fullKeys);
|
|
714
717
|
}
|
|
715
718
|
|
|
716
719
|
/**
|
|
@@ -889,10 +892,9 @@ function isKeyInRange (key, range, checkCached) {
|
|
|
889
892
|
function isMultiEntryMatch (encodedEntry, encodedKey) {
|
|
890
893
|
const keyType = encodedCharToKeyType[encodedKey.slice(0, 1)];
|
|
891
894
|
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
return encodedKey === encodedEntry;
|
|
895
|
+
return keyType === 'array'
|
|
896
|
+
? encodedKey.indexOf(encodedEntry) > 1
|
|
897
|
+
: encodedKey === encodedEntry;
|
|
896
898
|
}
|
|
897
899
|
|
|
898
900
|
/**
|
|
@@ -993,10 +995,9 @@ function encode (key, inArray) {
|
|
|
993
995
|
* @returns {undefined|ValueType}
|
|
994
996
|
*/
|
|
995
997
|
function decode (key, inArray) {
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
return types[encodedCharToKeyType[key.slice(0, 1)]].decode(key, inArray);
|
|
998
|
+
return typeof key !== 'string'
|
|
999
|
+
? undefined
|
|
1000
|
+
: types[encodedCharToKeyType[key.slice(0, 1)]].decode(key, inArray);
|
|
1000
1001
|
}
|
|
1001
1002
|
|
|
1002
1003
|
/**
|
package/src/Sca.js
CHANGED
|
@@ -15,14 +15,17 @@ const specSet = structuredCloningForStorage
|
|
|
15
15
|
|
|
16
16
|
const origFileList = specSet && !Array.isArray(specSet) && 'filelist' in specSet
|
|
17
17
|
? specSet.filelist
|
|
18
|
+
/* c8 ignore next -- Defensive fallback if typeson-registry's `filelist` preset entry ever goes missing */
|
|
18
19
|
: undefined;
|
|
19
20
|
|
|
20
21
|
const origTest = origFileList && typeof origFileList === 'object' && 'test' in origFileList && typeof origFileList.test === 'function'
|
|
21
22
|
? origFileList.test
|
|
23
|
+
/* c8 ignore next -- Defensive fallback if typeson-registry's `filelist.test` ever goes missing */
|
|
22
24
|
: undefined;
|
|
23
25
|
|
|
24
26
|
const origRevive = origFileList && typeof origFileList === 'object' && 'revive' in origFileList && typeof origFileList.revive === 'function'
|
|
25
27
|
? origFileList.revive
|
|
28
|
+
/* c8 ignore next -- Defensive fallback if typeson-registry's `filelist.revive` ever goes missing */
|
|
26
29
|
: undefined;
|
|
27
30
|
|
|
28
31
|
const customFileList = origFileList
|
|
@@ -34,10 +37,9 @@ const customFileList = origFileList
|
|
|
34
37
|
* @returns {boolean}
|
|
35
38
|
*/
|
|
36
39
|
test (x, state) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return typeof origTest === 'function' ? origTest(x, state) : false;
|
|
40
|
+
return typeof FileList !== 'undefined'
|
|
41
|
+
? x instanceof FileList
|
|
42
|
+
: ((typeof origTest === 'function') && origTest(x, state));
|
|
41
43
|
},
|
|
42
44
|
/**
|
|
43
45
|
* @param {unknown} x
|
|
@@ -48,13 +50,16 @@ const customFileList = origFileList
|
|
|
48
50
|
if (typeof FileList !== 'undefined') {
|
|
49
51
|
return Reflect.construct(FileList, [x]);
|
|
50
52
|
}
|
|
53
|
+
/* c8 ignore next -- Defensive fallback if typeson-registry's `filelist.revive` ever goes missing */
|
|
51
54
|
return typeof origRevive === 'function' ? origRevive(x, state) : undefined;
|
|
52
55
|
}
|
|
53
56
|
}
|
|
57
|
+
/* c8 ignore next -- Defensive fallback if typeson-registry's `filelist` preset entry ever goes missing */
|
|
54
58
|
: undefined;
|
|
55
59
|
|
|
56
60
|
let typeson = new Typeson().register([
|
|
57
61
|
structuredCloningForStorage,
|
|
62
|
+
/* c8 ignore next -- Defensive fallback if typeson-registry's `filelist` preset entry ever goes missing */
|
|
58
63
|
customFileList ? {filelist: customFileList} : {}
|
|
59
64
|
]);
|
|
60
65
|
|
package/src/nodeWebSQL.js
CHANGED
|
@@ -29,6 +29,7 @@ import CFG from './CFG.js';
|
|
|
29
29
|
* @returns {SQLiteDatabaseInstance}
|
|
30
30
|
*/
|
|
31
31
|
function wrappedSQLiteDatabase (name) {
|
|
32
|
+
// eslint-disable-next-line jsdoc/ts-ban-ts-comment -- TS 6/7
|
|
32
33
|
// @ts-ignore It's ok; needed under some TS versions
|
|
33
34
|
const db = new SQLiteDatabase(name, {});
|
|
34
35
|
if (CFG.sqlBusyTimeout) {
|