matrix-react-sdk
Version:
SDK for matrix.org using React
129 lines (122 loc) • 14.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getIDBFactory = getIDBFactory;
exports.idbDelete = idbDelete;
exports.idbLoad = idbLoad;
exports.idbSave = idbSave;
/*
Copyright 2024 New Vector Ltd.
Copyright 2019-2021 , 2024 The Matrix.org Foundation C.I.C.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/
/**
* Retrieves the IndexedDB factory object.
*
* @returns {IDBFactory | undefined} The IndexedDB factory object if available, or undefined if it is not supported.
*/
function getIDBFactory() {
// IndexedDB loading is lazy for easier testing.
// just *accessing* _indexedDB throws an exception in firefox with
// indexeddb disabled.
try {
// `self` is preferred for service workers, which access this file's functions.
// We check `self` first because `window` returns something which doesn't work for service workers.
// Note: `self?.indexedDB ?? window.indexedDB` breaks in service workers for unknown reasons.
return self?.indexedDB ? self.indexedDB : window.indexedDB;
} catch (e) {}
}
let idb = null;
async function idbInit() {
if (!getIDBFactory()) {
throw new Error("IndexedDB not available");
}
idb = await new Promise((resolve, reject) => {
const request = getIDBFactory().open("matrix-react-sdk", 1);
request.onerror = reject;
request.onsuccess = () => {
resolve(request.result);
};
request.onupgradeneeded = () => {
const db = request.result;
db.createObjectStore("pickleKey");
db.createObjectStore("account");
};
});
}
/**
* Loads an item from an IndexedDB table within the underlying `matrix-react-sdk` database.
*
* If IndexedDB access is not supported in the environment, an error is thrown.
*
* @param {string} table The name of the object store in IndexedDB.
* @param {string | string[]} key The key where the data is stored.
* @returns {Promise<any>} A promise that resolves with the retrieved item from the table.
*/
async function idbLoad(table, key) {
if (!idb) {
await idbInit();
}
return new Promise((resolve, reject) => {
const txn = idb.transaction([table], "readonly");
txn.onerror = reject;
const objectStore = txn.objectStore(table);
const request = objectStore.get(key);
request.onerror = reject;
request.onsuccess = event => {
resolve(request.result);
};
});
}
/**
* Saves data to an IndexedDB table within the underlying `matrix-react-sdk` database.
*
* If IndexedDB access is not supported in the environment, an error is thrown.
*
* @param {string} table The name of the object store in the IndexedDB.
* @param {string|string[]} key The key to use for storing the data.
* @param {*} data The data to be saved.
* @returns {Promise<void>} A promise that resolves when the data is saved successfully.
*/
async function idbSave(table, key, data) {
if (!idb) {
await idbInit();
}
return new Promise((resolve, reject) => {
const txn = idb.transaction([table], "readwrite");
txn.onerror = reject;
const objectStore = txn.objectStore(table);
const request = objectStore.put(data, key);
request.onerror = reject;
request.onsuccess = event => {
resolve();
};
});
}
/**
* Deletes a record from an IndexedDB table within the underlying `matrix-react-sdk` database.
*
* If IndexedDB access is not supported in the environment, an error is thrown.
*
* @param {string} table The name of the object store where the record is stored.
* @param {string|string[]} key The key of the record to be deleted.
* @returns {Promise<void>} A Promise that resolves when the record(s) have been successfully deleted.
*/
async function idbDelete(table, key) {
if (!idb) {
await idbInit();
}
return new Promise((resolve, reject) => {
const txn = idb.transaction([table], "readwrite");
txn.onerror = reject;
const objectStore = txn.objectStore(table);
const request = objectStore.delete(key);
request.onerror = reject;
request.onsuccess = () => {
resolve();
};
});
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJnZXRJREJGYWN0b3J5Iiwic2VsZiIsImluZGV4ZWREQiIsIndpbmRvdyIsImUiLCJpZGIiLCJpZGJJbml0IiwiRXJyb3IiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsInJlcXVlc3QiLCJvcGVuIiwib25lcnJvciIsIm9uc3VjY2VzcyIsInJlc3VsdCIsIm9udXBncmFkZW5lZWRlZCIsImRiIiwiY3JlYXRlT2JqZWN0U3RvcmUiLCJpZGJMb2FkIiwidGFibGUiLCJrZXkiLCJ0eG4iLCJ0cmFuc2FjdGlvbiIsIm9iamVjdFN0b3JlIiwiZ2V0IiwiZXZlbnQiLCJpZGJTYXZlIiwiZGF0YSIsInB1dCIsImlkYkRlbGV0ZSIsImRlbGV0ZSJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9TdG9yYWdlQWNjZXNzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAyNCBOZXcgVmVjdG9yIEx0ZC5cbkNvcHlyaWdodCAyMDE5LTIwMjEgLCAyMDI0IFRoZSBNYXRyaXgub3JnIEZvdW5kYXRpb24gQy5JLkMuXG5cblNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vbmx5IE9SIEdQTC0zLjAtb25seVxuUGxlYXNlIHNlZSBMSUNFTlNFIGZpbGVzIGluIHRoZSByZXBvc2l0b3J5IHJvb3QgZm9yIGZ1bGwgZGV0YWlscy5cbiovXG5cbi8qKlxuICogUmV0cmlldmVzIHRoZSBJbmRleGVkREIgZmFjdG9yeSBvYmplY3QuXG4gKlxuICogQHJldHVybnMge0lEQkZhY3RvcnkgfCB1bmRlZmluZWR9IFRoZSBJbmRleGVkREIgZmFjdG9yeSBvYmplY3QgaWYgYXZhaWxhYmxlLCBvciB1bmRlZmluZWQgaWYgaXQgaXMgbm90IHN1cHBvcnRlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldElEQkZhY3RvcnkoKTogSURCRmFjdG9yeSB8IHVuZGVmaW5lZCB7XG4gICAgLy8gSW5kZXhlZERCIGxvYWRpbmcgaXMgbGF6eSBmb3IgZWFzaWVyIHRlc3RpbmcuXG5cbiAgICAvLyBqdXN0ICphY2Nlc3NpbmcqIF9pbmRleGVkREIgdGhyb3dzIGFuIGV4Y2VwdGlvbiBpbiBmaXJlZm94IHdpdGhcbiAgICAvLyBpbmRleGVkZGIgZGlzYWJsZWQuXG4gICAgdHJ5IHtcbiAgICAgICAgLy8gYHNlbGZgIGlzIHByZWZlcnJlZCBmb3Igc2VydmljZSB3b3JrZXJzLCB3aGljaCBhY2Nlc3MgdGhpcyBmaWxlJ3MgZnVuY3Rpb25zLlxuICAgICAgICAvLyBXZSBjaGVjayBgc2VsZmAgZmlyc3QgYmVjYXVzZSBgd2luZG93YCByZXR1cm5zIHNvbWV0aGluZyB3aGljaCBkb2Vzbid0IHdvcmsgZm9yIHNlcnZpY2Ugd29ya2Vycy5cbiAgICAgICAgLy8gTm90ZTogYHNlbGY/LmluZGV4ZWREQiA/PyB3aW5kb3cuaW5kZXhlZERCYCBicmVha3MgaW4gc2VydmljZSB3b3JrZXJzIGZvciB1bmtub3duIHJlYXNvbnMuXG4gICAgICAgIHJldHVybiBzZWxmPy5pbmRleGVkREIgPyBzZWxmLmluZGV4ZWREQiA6IHdpbmRvdy5pbmRleGVkREI7XG4gICAgfSBjYXRjaCAoZSkge31cbn1cblxubGV0IGlkYjogSURCRGF0YWJhc2UgfCBudWxsID0gbnVsbDtcblxuYXN5bmMgZnVuY3Rpb24gaWRiSW5pdCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIWdldElEQkZhY3RvcnkoKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbmRleGVkREIgbm90IGF2YWlsYWJsZVwiKTtcbiAgICB9XG4gICAgaWRiID0gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0gZ2V0SURCRmFjdG9yeSgpIS5vcGVuKFwibWF0cml4LXJlYWN0LXNka1wiLCAxKTtcbiAgICAgICAgcmVxdWVzdC5vbmVycm9yID0gcmVqZWN0O1xuICAgICAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgICAgIHJlc29sdmUocmVxdWVzdC5yZXN1bHQpO1xuICAgICAgICB9O1xuICAgICAgICByZXF1ZXN0Lm9udXBncmFkZW5lZWRlZCA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGRiID0gcmVxdWVzdC5yZXN1bHQ7XG4gICAgICAgICAgICBkYi5jcmVhdGVPYmplY3RTdG9yZShcInBpY2tsZUtleVwiKTtcbiAgICAgICAgICAgIGRiLmNyZWF0ZU9iamVjdFN0b3JlKFwiYWNjb3VudFwiKTtcbiAgICAgICAgfTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBMb2FkcyBhbiBpdGVtIGZyb20gYW4gSW5kZXhlZERCIHRhYmxlIHdpdGhpbiB0aGUgdW5kZXJseWluZyBgbWF0cml4LXJlYWN0LXNka2AgZGF0YWJhc2UuXG4gKlxuICogSWYgSW5kZXhlZERCIGFjY2VzcyBpcyBub3Qgc3VwcG9ydGVkIGluIHRoZSBlbnZpcm9ubWVudCwgYW4gZXJyb3IgaXMgdGhyb3duLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWJsZSBUaGUgbmFtZSBvZiB0aGUgb2JqZWN0IHN0b3JlIGluIEluZGV4ZWREQi5cbiAqIEBwYXJhbSB7c3RyaW5nIHwgc3RyaW5nW119IGtleSBUaGUga2V5IHdoZXJlIHRoZSBkYXRhIGlzIHN0b3JlZC5cbiAqIEByZXR1cm5zIHtQcm9taXNlPGFueT59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIHJldHJpZXZlZCBpdGVtIGZyb20gdGhlIHRhYmxlLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaWRiTG9hZCh0YWJsZTogc3RyaW5nLCBrZXk6IHN0cmluZyB8IHN0cmluZ1tdKTogUHJvbWlzZTxhbnk+IHtcbiAgICBpZiAoIWlkYikge1xuICAgICAgICBhd2FpdCBpZGJJbml0KCk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHR4biA9IGlkYiEudHJhbnNhY3Rpb24oW3RhYmxlXSwgXCJyZWFkb25seVwiKTtcbiAgICAgICAgdHhuLm9uZXJyb3IgPSByZWplY3Q7XG5cbiAgICAgICAgY29uc3Qgb2JqZWN0U3RvcmUgPSB0eG4ub2JqZWN0U3RvcmUodGFibGUpO1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0gb2JqZWN0U3RvcmUuZ2V0KGtleSk7XG4gICAgICAgIHJlcXVlc3Qub25lcnJvciA9IHJlamVjdDtcbiAgICAgICAgcmVxdWVzdC5vbnN1Y2Nlc3MgPSAoZXZlbnQpOiB2b2lkID0+IHtcbiAgICAgICAgICAgIHJlc29sdmUocmVxdWVzdC5yZXN1bHQpO1xuICAgICAgICB9O1xuICAgIH0pO1xufVxuXG4vKipcbiAqIFNhdmVzIGRhdGEgdG8gYW4gSW5kZXhlZERCIHRhYmxlIHdpdGhpbiB0aGUgdW5kZXJseWluZyBgbWF0cml4LXJlYWN0LXNka2AgZGF0YWJhc2UuXG4gKlxuICogSWYgSW5kZXhlZERCIGFjY2VzcyBpcyBub3Qgc3VwcG9ydGVkIGluIHRoZSBlbnZpcm9ubWVudCwgYW4gZXJyb3IgaXMgdGhyb3duLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWJsZSBUaGUgbmFtZSBvZiB0aGUgb2JqZWN0IHN0b3JlIGluIHRoZSBJbmRleGVkREIuXG4gKiBAcGFyYW0ge3N0cmluZ3xzdHJpbmdbXX0ga2V5IFRoZSBrZXkgdG8gdXNlIGZvciBzdG9yaW5nIHRoZSBkYXRhLlxuICogQHBhcmFtIHsqfSBkYXRhIFRoZSBkYXRhIHRvIGJlIHNhdmVkLlxuICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIGRhdGEgaXMgc2F2ZWQgc3VjY2Vzc2Z1bGx5LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaWRiU2F2ZSh0YWJsZTogc3RyaW5nLCBrZXk6IHN0cmluZyB8IHN0cmluZ1tdLCBkYXRhOiBhbnkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIWlkYikge1xuICAgICAgICBhd2FpdCBpZGJJbml0KCk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHR4biA9IGlkYiEudHJhbnNhY3Rpb24oW3RhYmxlXSwgXCJyZWFkd3JpdGVcIik7XG4gICAgICAgIHR4bi5vbmVycm9yID0gcmVqZWN0O1xuXG4gICAgICAgIGNvbnN0IG9iamVjdFN0b3JlID0gdHhuLm9iamVjdFN0b3JlKHRhYmxlKTtcbiAgICAgICAgY29uc3QgcmVxdWVzdCA9IG9iamVjdFN0b3JlLnB1dChkYXRhLCBrZXkpO1xuICAgICAgICByZXF1ZXN0Lm9uZXJyb3IgPSByZWplY3Q7XG4gICAgICAgIHJlcXVlc3Qub25zdWNjZXNzID0gKGV2ZW50KTogdm9pZCA9PiB7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgIH07XG4gICAgfSk7XG59XG5cbi8qKlxuICogRGVsZXRlcyBhIHJlY29yZCBmcm9tIGFuIEluZGV4ZWREQiB0YWJsZSB3aXRoaW4gdGhlIHVuZGVybHlpbmcgYG1hdHJpeC1yZWFjdC1zZGtgIGRhdGFiYXNlLlxuICpcbiAqIElmIEluZGV4ZWREQiBhY2Nlc3MgaXMgbm90IHN1cHBvcnRlZCBpbiB0aGUgZW52aXJvbm1lbnQsIGFuIGVycm9yIGlzIHRocm93bi5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGFibGUgVGhlIG5hbWUgb2YgdGhlIG9iamVjdCBzdG9yZSB3aGVyZSB0aGUgcmVjb3JkIGlzIHN0b3JlZC5cbiAqIEBwYXJhbSB7c3RyaW5nfHN0cmluZ1tdfSBrZXkgVGhlIGtleSBvZiB0aGUgcmVjb3JkIHRvIGJlIGRlbGV0ZWQuXG4gKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gQSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgcmVjb3JkKHMpIGhhdmUgYmVlbiBzdWNjZXNzZnVsbHkgZGVsZXRlZC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGlkYkRlbGV0ZSh0YWJsZTogc3RyaW5nLCBrZXk6IHN0cmluZyB8IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCFpZGIpIHtcbiAgICAgICAgYXdhaXQgaWRiSW5pdCgpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBjb25zdCB0eG4gPSBpZGIhLnRyYW5zYWN0aW9uKFt0YWJsZV0sIFwicmVhZHdyaXRlXCIpO1xuICAgICAgICB0eG4ub25lcnJvciA9IHJlamVjdDtcblxuICAgICAgICBjb25zdCBvYmplY3RTdG9yZSA9IHR4bi5vYmplY3RTdG9yZSh0YWJsZSk7XG4gICAgICAgIGNvbnN0IHJlcXVlc3QgPSBvYmplY3RTdG9yZS5kZWxldGUoa2V5KTtcbiAgICAgICAgcmVxdWVzdC5vbmVycm9yID0gcmVqZWN0O1xuICAgICAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgfTtcbiAgICB9KTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNBLGFBQWFBLENBQUEsRUFBMkI7RUFDcEQ7O0VBRUE7RUFDQTtFQUNBLElBQUk7SUFDQTtJQUNBO0lBQ0E7SUFDQSxPQUFPQyxJQUFJLEVBQUVDLFNBQVMsR0FBR0QsSUFBSSxDQUFDQyxTQUFTLEdBQUdDLE1BQU0sQ0FBQ0QsU0FBUztFQUM5RCxDQUFDLENBQUMsT0FBT0UsQ0FBQyxFQUFFLENBQUM7QUFDakI7QUFFQSxJQUFJQyxHQUF1QixHQUFHLElBQUk7QUFFbEMsZUFBZUMsT0FBT0EsQ0FBQSxFQUFrQjtFQUNwQyxJQUFJLENBQUNOLGFBQWEsQ0FBQyxDQUFDLEVBQUU7SUFDbEIsTUFBTSxJQUFJTyxLQUFLLENBQUMseUJBQXlCLENBQUM7RUFDOUM7RUFDQUYsR0FBRyxHQUFHLE1BQU0sSUFBSUcsT0FB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