Skip to content

Instantly share code, notes, and snippets.

@inexorabletash
Last active May 20, 2024 02:54
Show Gist options
  • Save inexorabletash/5462871 to your computer and use it in GitHub Desktop.
Save inexorabletash/5462871 to your computer and use it in GitHub Desktop.
Helper for creating an IDBKeyRange for all keys with a given prefix
// Copyright 2019 Google LLC.
// SPDX-License-Identifier: Apache-2.0
// Basic p(r)olyfill for proposed feature
// This defines no successor of empty arrays, so the range for prefix
// [] or [[],[]] has no upper bound.
// An alternate definition would preclude adding additional nesting,
// so the range for prefix [] would have upper bound [[]] and the
// range for prefix [[], []] would have upper bound [[], [[]]].
IDBKeyRange.forPrefix = function(prefix) {
// Ensure prefix is a valid key itself:
if (indexedDB.cmp(prefix, prefix) !== 0) throw new TypeError();
var MAX_DATE_VALUE = 8640000000000000;
var UPPER_BOUND = {
NUMBER: new Date(-MAX_DATE_VALUE),
DATE: "",
STRING: [],
ARRAY: undefined
};
var upperKey = successor(prefix);
if (upperKey === undefined)
return IDBKeyRange.lowerBound(prefix);
return IDBKeyRange.bound(prefix, upperKey, false, true);
function successor(key) {
if (typeof key === 'number') {
if (key === Infinity)
return UPPER_BOUND.NUMBER;
if (key === -Infinity)
return -Number.MAX_VALUE;
if (key === 0)
return Number.MIN_VALUE;
var epsilon = Math.abs(key);
while (key + epsilon / 2 !== key)
epsilon = epsilon / 2;
return key + epsilon;
}
if (key instanceof Date) {
if (key.valueOf() + 1 > MAX_DATE_VALUE)
return UPPER_BOUND.DATE;
return new Date(key.valueOf() + 1);
}
if (typeof key === 'string') {
var len = key.length;
while (len > 0) {
var head = key.substring(0, len - 1),
tail = key.charCodeAt(len - 1);
if (tail !== 0xFFFF)
return head + String.fromCharCode(tail + 1);
key = head;
--len;
}
return UPPER_BOUND.STRING;
}
if (Array.isArray(key)) {
key = key.slice(); // Operate on a copy.
len = key.length;
while (len > 0) {
tail = successor(key.pop());
if (tail !== undefined) {
key.push(tail);
return key;
}
--len;
}
return UPPER_BOUND.ARRAY;
}
throw new TypeError();
}
};
@jfroelich
Copy link

Should line 62 be var len = key.length ?

@brettz9
Copy link

brettz9 commented Feb 24, 2017

@jfroelich, unlike would be the case for let or const, the presence of an earlier var len in the function ensures the declaration gets effectively hoisted to the top, so line 62 is not a problem. It is generally considered better style though to declare such vars at the top of the function, especially in such cases where it is used out of the defining block like this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment