Refactor chromeStorageDB (#840)
* Fix: the return type of dbExecChromeStorage('put') is wrong * Refactor: pull out db-chrome-storage * Fix: the signature of putMany is different
This commit is contained in:
parent
f32b6b6989
commit
0a79bde610
84
background/db-chrome-storage.js
Normal file
84
background/db-chrome-storage.js
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
/* global promisify */
|
||||||
|
/* exported createChromeStorageDB */
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
function createChromeStorageDB() {
|
||||||
|
const get = promisify(chrome.storage.local.get.bind(chrome.storage.local));
|
||||||
|
const set = promisify(chrome.storage.local.set.bind(chrome.storage.local));
|
||||||
|
const remove = promisify(chrome.storage.local.remove.bind(chrome.storage.local));
|
||||||
|
|
||||||
|
let INC;
|
||||||
|
|
||||||
|
const PREFIX = 'style-';
|
||||||
|
const METHODS = {
|
||||||
|
// FIXME: we don't use this method at all. Should we remove this?
|
||||||
|
get: id => get(PREFIX + id)
|
||||||
|
.then(result => result[PREFIX + id]),
|
||||||
|
put: obj => Promise.resolve()
|
||||||
|
.then(() => {
|
||||||
|
if (!obj.id) {
|
||||||
|
return prepareInc()
|
||||||
|
.then(() => {
|
||||||
|
// FIXME: should we clone the object?
|
||||||
|
obj.id = INC++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(() => set({[PREFIX + obj.id]: obj}))
|
||||||
|
.then(() => obj.id),
|
||||||
|
putMany: items => prepareInc()
|
||||||
|
.then(() => {
|
||||||
|
for (const item of items) {
|
||||||
|
if (!item.id) {
|
||||||
|
item.id = INC++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return set(items.reduce((obj, curr) => {
|
||||||
|
obj[PREFIX + curr.id] = curr;
|
||||||
|
return obj;
|
||||||
|
}, {}));
|
||||||
|
})
|
||||||
|
.then(() => items.map(i => i.id)),
|
||||||
|
delete: id => remove(PREFIX + id),
|
||||||
|
getAll: () => get(null)
|
||||||
|
.then(result => {
|
||||||
|
const output = [];
|
||||||
|
for (const key in result) {
|
||||||
|
if (key.startsWith(PREFIX) && Number(key.slice(PREFIX.length))) {
|
||||||
|
output.push(result[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
return {exec};
|
||||||
|
|
||||||
|
function exec(method, ...args) {
|
||||||
|
if (METHODS[method]) {
|
||||||
|
return METHODS[method](...args)
|
||||||
|
.then(result => {
|
||||||
|
if (method === 'putMany' && result.map) {
|
||||||
|
return result.map(r => ({target: {result: r}}));
|
||||||
|
}
|
||||||
|
return {target: {result}};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(`unknown DB method ${method}`));
|
||||||
|
}
|
||||||
|
|
||||||
|
function prepareInc() {
|
||||||
|
if (INC) return Promise.resolve();
|
||||||
|
return get(null).then(result => {
|
||||||
|
INC = 1;
|
||||||
|
for (const key in result) {
|
||||||
|
if (key.startsWith(PREFIX)) {
|
||||||
|
const id = Number(key.slice(PREFIX.length));
|
||||||
|
if (id >= INC) {
|
||||||
|
INC = id + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
/* global chromeLocal ignoreChromeError workerUtil */
|
/* global chromeLocal ignoreChromeError workerUtil createChromeStorageDB */
|
||||||
/* exported db */
|
/* exported db */
|
||||||
/*
|
/*
|
||||||
Initialize a database. There are some problems using IndexedDB in Firefox:
|
Initialize a database. There are some problems using IndexedDB in Firefox:
|
||||||
|
@ -94,7 +94,7 @@ const db = (() => {
|
||||||
}
|
}
|
||||||
|
|
||||||
function useChromeStorage(err) {
|
function useChromeStorage(err) {
|
||||||
exec = dbExecChromeStorage;
|
exec = createChromeStorageDB().exec;
|
||||||
chromeLocal.set({dbInChromeStorage: true}, ignoreChromeError);
|
chromeLocal.set({dbInChromeStorage: true}, ignoreChromeError);
|
||||||
if (err) {
|
if (err) {
|
||||||
chromeLocal.setValue('dbInChromeStorageReason', workerUtil.cloneError(err));
|
chromeLocal.setValue('dbInChromeStorageReason', workerUtil.cloneError(err));
|
||||||
|
@ -153,75 +153,4 @@ const db = (() => {
|
||||||
return Promise.all(items.map(item => storeRequest(store, 'put', item)));
|
return Promise.all(items.map(item => storeRequest(store, 'put', item)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function dbExecChromeStorage(method, data) {
|
|
||||||
const STYLE_KEY_PREFIX = 'style-';
|
|
||||||
switch (method) {
|
|
||||||
case 'get':
|
|
||||||
return chromeLocal.getValue(STYLE_KEY_PREFIX + data)
|
|
||||||
.then(result => ({target: {result}}));
|
|
||||||
|
|
||||||
case 'put':
|
|
||||||
if (!data.id) {
|
|
||||||
return getMaxId().then(id => {
|
|
||||||
data.id = id + 1;
|
|
||||||
return dbExecChromeStorage('put', data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return chromeLocal.setValue(STYLE_KEY_PREFIX + data.id, data)
|
|
||||||
.then(() => (chrome.runtime.lastError ? Promise.reject() : data.id));
|
|
||||||
|
|
||||||
case 'putMany': {
|
|
||||||
const newItems = data.filter(i => !i.id);
|
|
||||||
const doPut = () =>
|
|
||||||
chromeLocal.set(data.reduce((o, item) => {
|
|
||||||
o[STYLE_KEY_PREFIX + item.id] = item;
|
|
||||||
return o;
|
|
||||||
}, {}))
|
|
||||||
.then(() => data.map(d => ({target: {result: d.id}})));
|
|
||||||
if (newItems.length) {
|
|
||||||
return getMaxId().then(id => {
|
|
||||||
for (const item of newItems) {
|
|
||||||
item.id = ++id;
|
|
||||||
}
|
|
||||||
return doPut();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return doPut();
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'delete':
|
|
||||||
return chromeLocal.remove(STYLE_KEY_PREFIX + data);
|
|
||||||
|
|
||||||
case 'getAll':
|
|
||||||
return getAllStyles()
|
|
||||||
.then(styles => ({target: {result: styles}}));
|
|
||||||
}
|
|
||||||
return Promise.reject();
|
|
||||||
|
|
||||||
function getAllStyles() {
|
|
||||||
return chromeLocal.get(null).then(storage => {
|
|
||||||
const styles = [];
|
|
||||||
for (const key in storage) {
|
|
||||||
if (key.startsWith(STYLE_KEY_PREFIX) &&
|
|
||||||
Number(key.substr(STYLE_KEY_PREFIX.length))) {
|
|
||||||
styles.push(storage[key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return styles;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getMaxId() {
|
|
||||||
return getAllStyles().then(styles => {
|
|
||||||
let result = 0;
|
|
||||||
for (const style of styles) {
|
|
||||||
if (style.id > result) {
|
|
||||||
result = style.id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
"background/token-manager.js",
|
"background/token-manager.js",
|
||||||
"background/sync.js",
|
"background/sync.js",
|
||||||
"background/content-scripts.js",
|
"background/content-scripts.js",
|
||||||
|
"background/db-chrome-storage.js",
|
||||||
"background/db.js",
|
"background/db.js",
|
||||||
"background/style-manager.js",
|
"background/style-manager.js",
|
||||||
"background/navigator-util.js",
|
"background/navigator-util.js",
|
||||||
|
|
Loading…
Reference in New Issue
Block a user