Signal-Desktop/js/storage.js

132 lines
2.8 KiB
JavaScript

// Copyright 2014-2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
/* global _ */
/* eslint-disable more/no-then */
// eslint-disable-next-line func-names
(function () {
window.Whisper = window.Whisper || {};
let ready = false;
let items;
let callbacks = [];
reset();
async function put(key, value) {
if (value === undefined) {
window.log.warn(`storage/put: undefined provided for key ${key}`);
}
if (!ready) {
window.log.warn('Called storage.put before storage is ready. key:', key);
}
const data = { id: key, value };
items[key] = data;
await window.Signal.Data.createOrUpdateItem(data);
if (_.has(window, ['reduxActions', 'items', 'putItemExternal'])) {
window.reduxActions.items.putItemExternal(key, value);
}
}
function get(key, defaultValue) {
if (!ready) {
window.log.warn('Called storage.get before storage is ready. key:', key);
}
const item = items[key];
if (!item) {
return defaultValue;
}
return item.value;
}
async function remove(key) {
if (!ready) {
window.log.warn(
'Called storage.remove before storage is ready. key:',
key
);
}
delete items[key];
await window.Signal.Data.removeItemById(key);
if (_.has(window, ['reduxActions', 'items', 'removeItemExternal'])) {
window.reduxActions.items.removeItemExternal(key);
}
}
function onready(callback) {
if (ready) {
callback();
} else {
callbacks.push(callback);
}
}
function callListeners() {
if (ready) {
callbacks.forEach(callback => callback());
callbacks = [];
}
}
async function fetch() {
this.reset();
const array = await window.Signal.Data.getAllItems();
for (let i = 0, max = array.length; i < max; i += 1) {
const item = array[i];
const { id } = item;
items[id] = item;
}
ready = true;
callListeners();
}
function getItemsState() {
const data = _.clone(items);
const ids = Object.keys(data);
ids.forEach(id => {
data[id] = data[id].value;
});
return data;
}
function reset() {
ready = false;
items = Object.create(null);
}
const storage = {
fetch,
put,
get,
getItemsState,
remove,
onready,
reset,
};
// Keep a reference to this storage system, since there are scenarios where
// we need to replace it with the legacy storage system for a while.
window.newStorage = storage;
window.textsecure = window.textsecure || {};
window.textsecure.storage = window.textsecure.storage || {};
window.installStorage = newStorage => {
window.storage = newStorage;
window.textsecure.storage.impl = newStorage;
};
window.installStorage(storage);
})();