indexeddbshim 17.3.1 → 17.3.2
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/dist/IDBObjectStore.d.ts +28 -0
- package/dist/IDBObjectStore.d.ts.map +1 -1
- package/dist/indexeddbshim-Key.js +1 -1
- package/dist/indexeddbshim-Key.min.js +1 -1
- package/dist/indexeddbshim-UnicodeIdentifiers-node.cjs +164 -63
- package/dist/indexeddbshim-UnicodeIdentifiers-node.cjs.map +1 -1
- package/dist/indexeddbshim-UnicodeIdentifiers.js +166 -65
- 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 +164 -63
- package/dist/indexeddbshim-node.cjs.map +1 -1
- package/dist/indexeddbshim-noninvasive.js +166 -65
- 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 +166 -65
- package/dist/indexeddbshim.js.map +1 -1
- package/dist/indexeddbshim.min.js +2 -2
- package/dist/indexeddbshim.min.js.map +1 -1
- package/package.json +3 -2
- package/src/IDBObjectStore.js +103 -1
- package/src/IDBRecord.js +8 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "indexeddbshim",
|
|
3
|
-
"version": "17.3.
|
|
3
|
+
"version": "17.3.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"author": "Parashuram <code@nparashuram.com>",
|
|
6
6
|
"contributors": [
|
|
@@ -102,6 +102,7 @@
|
|
|
102
102
|
"w3c-test": "run-s clean-w3c test-and-start:w3c",
|
|
103
103
|
"w3c-good-only": "NODE_OPTIONS=--max_old_space_size=16384 node test-support/node-idb-test.js good",
|
|
104
104
|
"w3c-bad-only": "NODE_OPTIONS=--max_old_space_size=16384 node test-support/node-idb-test.js bad",
|
|
105
|
+
"w3c-good-worker-only": "NODE_OPTIONS=--max_old_space_size=16384 node test-support/node-idb-test.js good-worker",
|
|
105
106
|
"w3c-good": "run-s w3c-build w3c-good-only clean-w3c",
|
|
106
107
|
"w3c-bad": "run-s w3c-build w3c-bad-only clean-w3c",
|
|
107
108
|
"w3c-good-test": "run-s w3c-good-only clean-w3c",
|
|
@@ -171,7 +172,7 @@
|
|
|
171
172
|
"eventtargeter": "0.12.0",
|
|
172
173
|
"sync-promise-expanded": "^2.0.0",
|
|
173
174
|
"typeson": "10.2.0",
|
|
174
|
-
"typeson-registry": "14.2.
|
|
175
|
+
"typeson-registry": "14.2.2",
|
|
175
176
|
"websql-configurable": "^3.0.6"
|
|
176
177
|
},
|
|
177
178
|
"devDependencies": {
|
package/src/IDBObjectStore.js
CHANGED
|
@@ -6,6 +6,7 @@ import DOMStringList from './DOMStringList.js';
|
|
|
6
6
|
import * as util from './util.js';
|
|
7
7
|
import * as Key from './Key.js';
|
|
8
8
|
import {executeFetchIndexData, buildFetchIndexDataSQL, IDBIndex} from './IDBIndex.js';
|
|
9
|
+
import cmp from './cmp.js';
|
|
9
10
|
import IDBTransaction from './IDBTransaction.js';
|
|
10
11
|
import * as Sca from './Sca.js';
|
|
11
12
|
import CFG from './CFG.js';
|
|
@@ -69,6 +70,11 @@ const IDBObjectStoreAlias = IDBObjectStore;
|
|
|
69
70
|
* success: (key: import('./Key.js').Key, cn?: Integer) => void,
|
|
70
71
|
* failCb: import('./Key.js').SQLFailureCallback
|
|
71
72
|
* ) => void,
|
|
73
|
+
* __checkIndexConstraints: (
|
|
74
|
+
* tx: WebSQLTransaction,
|
|
75
|
+
* value: import('./Key.js').Value,
|
|
76
|
+
* excludeKey: import('./Key.js').Key|Integer|undefined
|
|
77
|
+
* ) => SyncPromise,
|
|
72
78
|
* __insertData: (
|
|
73
79
|
* tx: WebSQLTransaction,
|
|
74
80
|
* encoded: string,
|
|
@@ -518,6 +524,77 @@ IDBObjectStore.prototype.__deriveKey = function (tx, value, key, success, failCb
|
|
|
518
524
|
}
|
|
519
525
|
};
|
|
520
526
|
|
|
527
|
+
/**
|
|
528
|
+
* Validates `value`'s unique index entries against the table's *current*
|
|
529
|
+
* state without mutating anything -- used by `__storingRecordObjectStore`
|
|
530
|
+
* to check a `put()`'s constraints *before* `__overwrite` deletes the
|
|
531
|
+
* existing row for that key, so a rejected `put()` can't end up losing
|
|
532
|
+
* the record it was trying to replace (see
|
|
533
|
+
* `idbobjectstore-put-unique-index-constraint-is-atomic.any.js`).
|
|
534
|
+
* `excludeKey`, when given, treats a conflicting record as a non-conflict
|
|
535
|
+
* if it's the very record being overwritten (its own current entry would
|
|
536
|
+
* otherwise self-conflict on every no-op `put()` of an unchanged value).
|
|
537
|
+
* `__insertData` below still runs its own (now redundant, but harmless --
|
|
538
|
+
* the old row is gone by then) equivalent check as its first step; this
|
|
539
|
+
* isn't merged into it because `__insertData` also performs the actual
|
|
540
|
+
* `INSERT`, which cannot safely run before `__overwrite`'s `DELETE` when
|
|
541
|
+
* overwriting an existing key.
|
|
542
|
+
* @param {WebSQLTransaction} tx
|
|
543
|
+
* @param {import('./Key.js').Value} value
|
|
544
|
+
* @param {import('./Key.js').Key|Integer|undefined} excludeKey
|
|
545
|
+
* @this {IDBObjectStoreFull}
|
|
546
|
+
* @returns {SyncPromise}
|
|
547
|
+
*/
|
|
548
|
+
IDBObjectStore.prototype.__checkIndexConstraints = function (tx, value, excludeKey) {
|
|
549
|
+
const me = this;
|
|
550
|
+
const indexPromises = Object.keys(me.__indexes).map((indexName) => {
|
|
551
|
+
return new SyncPromise((resolve, reject) => {
|
|
552
|
+
const index = me.__indexes[indexName];
|
|
553
|
+
if (index.__pendingCreate || index.__deleted || !index.unique) {
|
|
554
|
+
resolve(undefined);
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* @type {import('./Key.js').KeyValueObject|
|
|
559
|
+
* import('./Key.js').KeyPathEvaluateValue}
|
|
560
|
+
*/
|
|
561
|
+
let indexKey;
|
|
562
|
+
try {
|
|
563
|
+
indexKey = Key.extractKeyValueDecodedFromValueUsingKeyPath(value, index.keyPath, index.multiEntry);
|
|
564
|
+
if (
|
|
565
|
+
('invalid' in indexKey && indexKey.invalid) ||
|
|
566
|
+
('failure' in indexKey && indexKey.failure)
|
|
567
|
+
) {
|
|
568
|
+
throw new Error('Go to catch');
|
|
569
|
+
}
|
|
570
|
+
} catch (err) {
|
|
571
|
+
resolve(undefined);
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
574
|
+
indexKey = indexKey.value;
|
|
575
|
+
if (indexKey === undefined) {
|
|
576
|
+
resolve(undefined);
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
579
|
+
const multiCheck = index.multiEntry && Array.isArray(indexKey);
|
|
580
|
+
const fetchArgs = buildFetchIndexDataSQL(true, index, indexKey, 'key', multiCheck);
|
|
581
|
+
executeFetchIndexData(null, ...fetchArgs, tx, null, function success (key) {
|
|
582
|
+
if (key === undefined || (excludeKey !== undefined && cmp(key, excludeKey) === 0)) {
|
|
583
|
+
resolve(undefined);
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
586
|
+
reject(createDOMException(
|
|
587
|
+
'ConstraintError',
|
|
588
|
+
'Index already contains a record equal to ' +
|
|
589
|
+
(multiCheck ? 'one of the subkeys of' : '') +
|
|
590
|
+
'`indexKey`'
|
|
591
|
+
));
|
|
592
|
+
}, reject);
|
|
593
|
+
});
|
|
594
|
+
});
|
|
595
|
+
return SyncPromise.all(indexPromises);
|
|
596
|
+
};
|
|
597
|
+
|
|
521
598
|
/**
|
|
522
599
|
*
|
|
523
600
|
* @param {WebSQLTransaction} tx
|
|
@@ -794,7 +871,32 @@ IDBObjectStore.__storingRecordObjectStore = function (request, store, invalidate
|
|
|
794
871
|
}, error);
|
|
795
872
|
}
|
|
796
873
|
if (!noOverwrite) {
|
|
797
|
-
|
|
874
|
+
// Validate unique index constraints *before* `__overwrite`
|
|
875
|
+
// deletes the existing row at this key -- otherwise a
|
|
876
|
+
// `put()` that ends up rejected still permanently loses
|
|
877
|
+
// the record it was trying to replace (see
|
|
878
|
+
// `idbobjectstore-put-unique-index-constraint-is-atomic.any.js`).
|
|
879
|
+
store.__checkIndexConstraints(tx, value, clonedKeyOrCurrentNumber).then(() => {
|
|
880
|
+
store.__overwrite(tx, clonedKeyOrCurrentNumber, insert, error);
|
|
881
|
+
return undefined;
|
|
882
|
+
/**
|
|
883
|
+
* @param {Error|DOMException} err
|
|
884
|
+
* @returns {null}
|
|
885
|
+
*/
|
|
886
|
+
}).catch(function (err) {
|
|
887
|
+
/**
|
|
888
|
+
* @returns {void}
|
|
889
|
+
*/
|
|
890
|
+
function fail () {
|
|
891
|
+
error(err);
|
|
892
|
+
}
|
|
893
|
+
if (typeof oldCn === 'number') {
|
|
894
|
+
Key.assignCurrentNumber(tx, store, oldCn, fail, fail);
|
|
895
|
+
return null;
|
|
896
|
+
}
|
|
897
|
+
fail();
|
|
898
|
+
return null;
|
|
899
|
+
});
|
|
798
900
|
return;
|
|
799
901
|
}
|
|
800
902
|
insert(tx);
|
package/src/IDBRecord.js
CHANGED
|
@@ -77,6 +77,14 @@ readonlyProperties.forEach((prop) => {
|
|
|
77
77
|
* @returns {import('./Key.js').Key|import('./Key.js').Value}
|
|
78
78
|
*/
|
|
79
79
|
get [prop] () {
|
|
80
|
+
// This is defined on the *shared* prototype (see above), so,
|
|
81
|
+
// unlike a per-instance getter, it's reachable by calling it
|
|
82
|
+
// directly on `IDBRecord.prototype` itself (not a real
|
|
83
|
+
// instance) -- WebIDL requires that to throw.
|
|
84
|
+
if (!(this instanceof IDBRecordAlias)) {
|
|
85
|
+
throw new TypeError('Illegal invocation');
|
|
86
|
+
}
|
|
87
|
+
// @ts-ignore `this` is a real instance past the check above (not an issue in TS7)
|
|
80
88
|
return this['__' + prop];
|
|
81
89
|
}
|
|
82
90
|
};
|