schedule-grid-js/external/idb-keyval/index.js

185 lines
6.3 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

function promisifyRequest(request) {
return new Promise((resolve, reject) => {
// @ts-ignore - file size hacks
request.oncomplete = request.onsuccess = () => resolve(request.result);
// @ts-ignore - file size hacks
request.onabort = request.onerror = () => reject(request.error);
});
}
function createStore(dbName, storeName) {
const request = indexedDB.open(dbName);
request.onupgradeneeded = () => request.result.createObjectStore(storeName);
const dbp = promisifyRequest(request);
return (txMode, callback) => dbp.then((db) => callback(db.transaction(storeName, txMode).objectStore(storeName)));
}
let defaultGetStoreFunc;
function defaultGetStore() {
if (!defaultGetStoreFunc) {
defaultGetStoreFunc = createStore('keyval-store', 'keyval');
}
return defaultGetStoreFunc;
}
/**
* Get a value by its key.
*
* @param key
* @param customStore Method to get a custom store. Use with caution (see the docs).
*/
function get(key, customStore = defaultGetStore()) {
return customStore('readonly', (store) => promisifyRequest(store.get(key)));
}
/**
* Set a value with a key.
*
* @param key
* @param value
* @param customStore Method to get a custom store. Use with caution (see the docs).
*/
function set(key, value, customStore = defaultGetStore()) {
return customStore('readwrite', (store) => {
store.put(value, key);
return promisifyRequest(store.transaction);
});
}
/**
* Set multiple values at once. This is faster than calling set() multiple times.
* It's also atomic if one of the pairs can't be added, none will be added.
*
* @param entries Array of entries, where each entry is an array of `[key, value]`.
* @param customStore Method to get a custom store. Use with caution (see the docs).
*/
function setMany(entries, customStore = defaultGetStore()) {
return customStore('readwrite', (store) => {
entries.forEach((entry) => store.put(entry[1], entry[0]));
return promisifyRequest(store.transaction);
});
}
/**
* Get multiple values by their keys
*
* @param keys
* @param customStore Method to get a custom store. Use with caution (see the docs).
*/
function getMany(keys, customStore = defaultGetStore()) {
return customStore('readonly', (store) => Promise.all(keys.map((key) => promisifyRequest(store.get(key)))));
}
/**
* Update a value. This lets you see the old value and update it as an atomic operation.
*
* @param key
* @param updater A callback that takes the old value and returns a new value.
* @param customStore Method to get a custom store. Use with caution (see the docs).
*/
function update(key, updater, customStore = defaultGetStore()) {
return customStore('readwrite', (store) =>
// Need to create the promise manually.
// If I try to chain promises, the transaction closes in browsers
// that use a promise polyfill (IE10/11).
new Promise((resolve, reject) => {
store.get(key).onsuccess = function () {
try {
store.put(updater(this.result), key);
resolve(promisifyRequest(store.transaction));
}
catch (err) {
reject(err);
}
};
}));
}
/**
* Delete a particular key from the store.
*
* @param key
* @param customStore Method to get a custom store. Use with caution (see the docs).
*/
function del(key, customStore = defaultGetStore()) {
return customStore('readwrite', (store) => {
store.delete(key);
return promisifyRequest(store.transaction);
});
}
/**
* Delete multiple keys at once.
*
* @param keys List of keys to delete.
* @param customStore Method to get a custom store. Use with caution (see the docs).
*/
function delMany(keys, customStore = defaultGetStore()) {
return customStore('readwrite', (store) => {
keys.forEach((key) => store.delete(key));
return promisifyRequest(store.transaction);
});
}
/**
* Clear all values in the store.
*
* @param customStore Method to get a custom store. Use with caution (see the docs).
*/
function clear(customStore = defaultGetStore()) {
return customStore('readwrite', (store) => {
store.clear();
return promisifyRequest(store.transaction);
});
}
function eachCursor(store, callback) {
store.openCursor().onsuccess = function () {
if (!this.result)
return;
callback(this.result);
this.result.continue();
};
return promisifyRequest(store.transaction);
}
/**
* Get all keys in the store.
*
* @param customStore Method to get a custom store. Use with caution (see the docs).
*/
function keys(customStore = defaultGetStore()) {
return customStore('readonly', (store) => {
// Fast path for modern browsers
if (store.getAllKeys) {
return promisifyRequest(store.getAllKeys());
}
const items = [];
return eachCursor(store, (cursor) => items.push(cursor.key)).then(() => items);
});
}
/**
* Get all values in the store.
*
* @param customStore Method to get a custom store. Use with caution (see the docs).
*/
function values(customStore = defaultGetStore()) {
return customStore('readonly', (store) => {
// Fast path for modern browsers
if (store.getAll) {
return promisifyRequest(store.getAll());
}
const items = [];
return eachCursor(store, (cursor) => items.push(cursor.value)).then(() => items);
});
}
/**
* Get all entries in the store. Each entry is an array of `[key, value]`.
*
* @param customStore Method to get a custom store. Use with caution (see the docs).
*/
function entries(customStore = defaultGetStore()) {
return customStore('readonly', (store) => {
// Fast path for modern browsers
// (although, hopefully we'll get a simpler path some day)
if (store.getAll && store.getAllKeys) {
return Promise.all([
promisifyRequest(store.getAllKeys()),
promisifyRequest(store.getAll()),
]).then(([keys, values]) => keys.map((key, i) => [key, values[i]]));
}
const items = [];
return customStore('readonly', (store) => eachCursor(store, (cursor) => items.push([cursor.key, cursor.value])).then(() => items));
});
}
export { clear, createStore, del, delMany, entries, get, getMany, keys, promisifyRequest, set, setMany, update, values };