use Proxy for db
This commit is contained in:
parent
c95f74e089
commit
155de766e9
|
@ -38,11 +38,7 @@ addAPI(/** @namespace API */ {
|
|||
},
|
||||
}))(),
|
||||
|
||||
/** @type IDBObjectStore */
|
||||
drafts: new Proxy({}, {
|
||||
get: (_, cmd) => (...args) => db.exec.call('drafts', cmd, ...args),
|
||||
}),
|
||||
|
||||
drafts: db.open('drafts'),
|
||||
styles: styleMan,
|
||||
sync: syncMan,
|
||||
updater: updateMan,
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
/* exported createChromeStorageDB */
|
||||
function createChromeStorageDB(PREFIX) {
|
||||
let INC;
|
||||
const isMain = !PREFIX;
|
||||
if (!PREFIX) PREFIX = 'style-';
|
||||
|
||||
return {
|
||||
|
||||
|
@ -19,7 +21,9 @@ function createChromeStorageDB(PREFIX) {
|
|||
const all = await chromeLocal.get();
|
||||
if (!INC) prepareInc(all);
|
||||
return Object.entries(all)
|
||||
.map(([key, val]) => key.startsWith(PREFIX) && Number(key.slice(PREFIX.length)) && val)
|
||||
.map(([key, val]) => key.startsWith(PREFIX) &&
|
||||
(!isMain || Number(key.slice(PREFIX.length))) &&
|
||||
val)
|
||||
.filter(Boolean);
|
||||
},
|
||||
|
||||
|
|
|
@ -11,16 +11,28 @@
|
|||
|
||||
/* exported db */
|
||||
const db = (() => {
|
||||
const DATABASE = 'stylish';
|
||||
const STORE = 'styles';
|
||||
let exec = async (...args) => (
|
||||
exec = await tryUsingIndexedDB().catch(useChromeStorage)
|
||||
)(...args);
|
||||
const DB = 'stylish';
|
||||
const FALLBACK = 'dbInChromeStorage';
|
||||
const dbApi = {
|
||||
async exec(...args) {
|
||||
dbApi.exec = await tryUsingIndexedDB().catch(useChromeStorage);
|
||||
return dbApi.exec(...args);
|
||||
},
|
||||
const proxies = {};
|
||||
const proxyHandler = {
|
||||
get: ({dbName}, cmd) => (...args) => exec(dbName, cmd, ...args),
|
||||
};
|
||||
const getProxy = (dbName = DB) =>
|
||||
/** @type {IDBObjectStore | {putMany: function(items:?[]):Promise<?[]>}} */
|
||||
proxies[dbName] || (
|
||||
proxies[dbName] = new Proxy({dbName}, proxyHandler)
|
||||
);
|
||||
const getStoreName = dbName =>
|
||||
dbName === DB
|
||||
? 'styles'
|
||||
: 'data';
|
||||
return {
|
||||
styles: getProxy(),
|
||||
open: getProxy,
|
||||
};
|
||||
return dbApi;
|
||||
|
||||
async function tryUsingIndexedDB() {
|
||||
// we use chrome.storage.local fallback if IndexedDB doesn't save data,
|
||||
|
@ -40,9 +52,9 @@ const db = (() => {
|
|||
|
||||
async function testDB() {
|
||||
const id = `${performance.now()}.${Math.random()}.${Date.now()}`;
|
||||
await dbExecIndexedDB('put', {id});
|
||||
const e = await dbExecIndexedDB('get', id);
|
||||
await dbExecIndexedDB('delete', e.id); // throws if `e` or id is null
|
||||
await dbExecIndexedDB(DB, 'put', {id});
|
||||
const e = await dbExecIndexedDB(DB, 'get', id);
|
||||
await dbExecIndexedDB(DB, 'delete', e.id); // throws if `e` or id is null
|
||||
}
|
||||
|
||||
async function useChromeStorage(err) {
|
||||
|
@ -53,17 +65,17 @@ const db = (() => {
|
|||
}
|
||||
await require(['/background/db-chrome-storage']); /* global createChromeStorageDB */
|
||||
const BASES = {};
|
||||
return function dbExecChromeStorage(method, ...args) {
|
||||
const prefix = Object(this) instanceof String ? `${this}-` : 'style-';
|
||||
const baseApi = BASES[prefix] || (BASES[prefix] = createChromeStorageDB(prefix));
|
||||
return baseApi[method](...args);
|
||||
};
|
||||
return (dbName, method, ...args) => (
|
||||
BASES[dbName] || (
|
||||
BASES[dbName] = createChromeStorageDB(dbName !== DB && `${dbName}-`)
|
||||
)
|
||||
)[method](...args);
|
||||
}
|
||||
|
||||
async function dbExecIndexedDB(method, ...args) {
|
||||
async function dbExecIndexedDB(dbName, method, ...args) {
|
||||
const mode = method.startsWith('get') ? 'readonly' : 'readwrite';
|
||||
const dbName = Object(this) instanceof String ? `${this}` : DATABASE;
|
||||
const store = (await open(dbName)).transaction([STORE], mode).objectStore(STORE);
|
||||
const storeName = getStoreName(dbName);
|
||||
const store = (await open(dbName)).transaction([storeName], mode).objectStore(storeName);
|
||||
const fn = method === 'putMany' ? putMany : storeRequest;
|
||||
return fn(store, method, ...args);
|
||||
}
|
||||
|
@ -92,7 +104,8 @@ const db = (() => {
|
|||
|
||||
function create(event) {
|
||||
if (event.oldVersion === 0) {
|
||||
event.target.result.createObjectStore(STORE, {
|
||||
const idb = event.target.result;
|
||||
idb.createObjectStore(getStoreName(idb.name), {
|
||||
keyPath: 'id',
|
||||
autoIncrement: true,
|
||||
});
|
||||
|
|
|
@ -105,7 +105,7 @@ const styleMan = (() => {
|
|||
if (ready.then) await ready;
|
||||
const data = id2data(id);
|
||||
const {style, appliesTo} = data;
|
||||
await db.exec('delete', id);
|
||||
db.styles.delete(id);
|
||||
if (reason !== 'sync') {
|
||||
API.sync.delete(style._id, Date.now());
|
||||
}
|
||||
|
@ -251,7 +251,7 @@ const styleMan = (() => {
|
|||
await usercssMan.buildCode(style);
|
||||
}
|
||||
}
|
||||
const events = await db.exec('putMany', items);
|
||||
const events = await db.styles.putMany(items);
|
||||
return Promise.all(items.map((item, i) =>
|
||||
handleSave(item, {reason: 'import'}, events[i])
|
||||
));
|
||||
|
@ -437,7 +437,7 @@ const styleMan = (() => {
|
|||
|
||||
async function saveStyle(style, handlingOptions) {
|
||||
beforeSave(style);
|
||||
const newId = await db.exec('put', style);
|
||||
const newId = await db.styles.put(style);
|
||||
return handleSave(style, handlingOptions, newId);
|
||||
}
|
||||
|
||||
|
@ -477,10 +477,10 @@ const styleMan = (() => {
|
|||
}
|
||||
|
||||
async function init() {
|
||||
const styles = await db.exec('getAll') || [];
|
||||
const styles = await db.styles.getAll() || [];
|
||||
const updated = await Promise.all(styles.map(fixKnownProblems).filter(Boolean));
|
||||
if (updated.length) {
|
||||
await db.exec('putMany', updated);
|
||||
await db.styles.putMany(updated);
|
||||
}
|
||||
styles.forEach(storeInMap);
|
||||
ready = true;
|
||||
|
|
|
@ -209,7 +209,7 @@ const syncMan = (() => {
|
|||
}
|
||||
}
|
||||
if (diff < 0) {
|
||||
doc.id = await db.exec('put', doc);
|
||||
doc.id = await db.styles.put(doc);
|
||||
uuidIndex.set(doc._id, doc.id);
|
||||
return styleUtil.handleSave(doc, {reason: 'sync'});
|
||||
}
|
||||
|
|
|
@ -234,7 +234,7 @@ const updateMan = (() => {
|
|||
if (err && etag && !style.etag) {
|
||||
// first check of ETAG, gonna write it directly to DB as it's too trivial to sync or announce
|
||||
style.etag = etag;
|
||||
await db.exec('put', style);
|
||||
await db.styles.put(style);
|
||||
}
|
||||
return err
|
||||
? Promise.reject(err)
|
||||
|
|
Loading…
Reference in New Issue
Block a user