commit 3f2c6a741460e555c5e8faacbad0c22b2d5e4eb7
parent e40233c0378150094e025125960510c24b5bcdef
Author: Florian Dold <dold@taler.net>
Date: Sun, 19 Jul 2026 22:41:28 +0200
idb-bridge: fix multiEntry indexes never matching
getIndexKeys branched on an array keyPath; a multiEntry index has a string
keyPath with an array value, so each element was never indexed separately.
Diffstat:
1 file changed, 33 insertions(+), 7 deletions(-)
diff --git a/packages/idb-bridge/src/util/getIndexKeys.ts b/packages/idb-bridge/src/util/getIndexKeys.ts
@@ -24,16 +24,42 @@ export function getIndexKeys(
keyPath: IDBKeyPath | IDBKeyPath[],
multiEntry: boolean,
): IDBValidKey[] {
- if (multiEntry && Array.isArray(keyPath)) {
- const keys = [];
- for (const subkeyPath of keyPath) {
- const key = extractKey(subkeyPath, value);
+ if (multiEntry && typeof keyPath === "string") {
+ // A multiEntry index has a *string* keyPath whose value is an array, and
+ // indexes each element separately. (A multiEntry index with an array
+ // keyPath is invalid per spec and rejected by createIndex.) Matching on
+ // Array.isArray(keyPath) instead meant this branch never ran for a real
+ // multiEntry index: the array value fell through below and was indexed
+ // as one compound key, so a lookup for a single element matched nothing.
+ const key = extractKey(keyPath, value);
+ if (!Array.isArray(key)) {
+ // Not an array: behaves like an ordinary single-key index.
+ if (key == null) {
+ return [];
+ }
+ try {
+ return [valueToKey(key)];
+ } catch {
+ return [];
+ }
+ }
+ const keys: IDBValidKey[] = [];
+ const seen = new Set<string>();
+ for (const item of key) {
+ let k: IDBValidKey;
try {
- const k = valueToKey(key);
- keys.push(k);
+ k = valueToKey(item);
} catch {
- // Ignore invalid subkeys
+ // Spec: entries that are not valid keys are skipped, not fatal.
+ continue;
+ }
+ // Spec: duplicate entries are recorded once.
+ const dedupeKey = JSON.stringify(k);
+ if (seen.has(dedupeKey)) {
+ continue;
}
+ seen.add(dedupeKey);
+ keys.push(k);
}
return keys;
} else if (typeof keyPath === "string" || Array.isArray(keyPath)) {