-
-
Save paralin/9b53846efa6e8c807134cddfb956bdfb to your computer and use it in GitHub Desktop.
Helper for creating an IDBKeyRange for all keys with a given prefix
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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(); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment