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