promisify DB access
This commit is contained in:
parent
02fd4f1abe
commit
acc4d83b9d
|
@ -1,4 +1,4 @@
|
|||
/* global getDatabase, getStyles, saveStyle */
|
||||
/* global dbExec, getStyles, saveStyle */
|
||||
'use strict';
|
||||
|
||||
// eslint-disable-next-line no-var
|
||||
|
@ -6,7 +6,7 @@ var browserCommands, contextMenus;
|
|||
|
||||
// *************************************************************************
|
||||
// preload the DB and report errors
|
||||
getDatabase(() => {}, (...args) => {
|
||||
dbExec().catch((...args) => {
|
||||
args.forEach(arg => 'message' in arg && console.error(arg.message));
|
||||
});
|
||||
|
||||
|
@ -183,7 +183,7 @@ prefs.subscribe((id, checked) => {
|
|||
// *************************************************************************
|
||||
|
||||
function webNavigationListener(method, {url, tabId, frameId}) {
|
||||
getStyles({matchUrl: url, enabled: true, asHash: true}, styles => {
|
||||
getStyles({matchUrl: url, enabled: true, asHash: true}).then(styles => {
|
||||
if (method && !url.startsWith('chrome:') && tabId >= 0) {
|
||||
chrome.tabs.sendMessage(tabId, {
|
||||
method,
|
||||
|
@ -209,9 +209,9 @@ function updateIcon(tab, styles) {
|
|||
stylesReceived(styles);
|
||||
return;
|
||||
}
|
||||
getTabRealURL(tab).then(url =>
|
||||
getStyles({matchUrl: url, enabled: true, asHash: true},
|
||||
stylesReceived));
|
||||
getTabRealURL(tab)
|
||||
.then(url => getStyles({matchUrl: url, enabled: true, asHash: true}))
|
||||
.then(stylesReceived);
|
||||
|
||||
function stylesReceived(styles) {
|
||||
let numStyles = styles.length;
|
||||
|
@ -255,7 +255,7 @@ function onRuntimeMessage(request, sender, sendResponse) {
|
|||
switch (request.method) {
|
||||
|
||||
case 'getStyles':
|
||||
getStyles(request, sendResponse);
|
||||
getStyles(request).then(sendResponse);
|
||||
return KEEP_CHANNEL_OPEN;
|
||||
|
||||
case 'saveStyle':
|
||||
|
@ -263,9 +263,9 @@ function onRuntimeMessage(request, sender, sendResponse) {
|
|||
return KEEP_CHANNEL_OPEN;
|
||||
|
||||
case 'healthCheck':
|
||||
getDatabase(
|
||||
() => sendResponse(true),
|
||||
() => sendResponse(false));
|
||||
dbExec()
|
||||
.then(() => sendResponse(true))
|
||||
.catch(() => sendResponse(false));
|
||||
return KEEP_CHANNEL_OPEN;
|
||||
|
||||
case 'download':
|
||||
|
|
23
messaging.js
23
messaging.js
|
@ -268,13 +268,13 @@ function sessionStorageHash(name) {
|
|||
}
|
||||
|
||||
|
||||
function onBackgroundReady() {
|
||||
return BG ? Promise.resolve() : new Promise(ping);
|
||||
function onBackgroundReady(...dataPassthru) {
|
||||
return BG ? Promise.resolve(...dataPassthru) : new Promise(ping);
|
||||
function ping(resolve) {
|
||||
chrome.runtime.sendMessage({method: 'healthCheck'}, health => {
|
||||
if (health !== undefined) {
|
||||
BG = chrome.extension.getBackgroundPage();
|
||||
resolve();
|
||||
resolve(...dataPassthru);
|
||||
} else {
|
||||
ping(resolve);
|
||||
}
|
||||
|
@ -285,20 +285,13 @@ function onBackgroundReady() {
|
|||
|
||||
// in case Chrome haven't yet loaded the bg page and displays our page like edit/manage
|
||||
function getStylesSafe(options) {
|
||||
return new Promise(resolve => {
|
||||
if (BG) {
|
||||
BG.getStyles(options, resolve);
|
||||
} else {
|
||||
onBackgroundReady().then(() =>
|
||||
BG.getStyles(options, resolve));
|
||||
}
|
||||
});
|
||||
return onBackgroundReady(options).then(BG.getStyles);
|
||||
}
|
||||
|
||||
|
||||
function saveStyleSafe(style) {
|
||||
return onBackgroundReady()
|
||||
.then(() => BG.saveStyle(BG.deepCopy(style)))
|
||||
return onBackgroundReady(BG.deepCopy(style))
|
||||
.then(BG.saveStyle)
|
||||
.then(savedStyle => {
|
||||
if (style.notify === false) {
|
||||
handleUpdate(savedStyle, style);
|
||||
|
@ -309,8 +302,8 @@ function saveStyleSafe(style) {
|
|||
|
||||
|
||||
function deleteStyleSafe({id, notify = true} = {}) {
|
||||
return onBackgroundReady()
|
||||
.then(() => BG.deleteStyle({id, notify}))
|
||||
return onBackgroundReady({id, notify})
|
||||
.then(BG.deleteStyle)
|
||||
.then(() => {
|
||||
if (!notify) {
|
||||
handleDelete(id);
|
||||
|
|
120
storage.js
120
storage.js
|
@ -43,58 +43,69 @@ var chromeLocal = {
|
|||
};
|
||||
|
||||
|
||||
function getDatabase(ready, error) {
|
||||
const dbOpenRequest = window.indexedDB.open('stylish', 2);
|
||||
dbOpenRequest.onsuccess = event => {
|
||||
ready(event.target.result);
|
||||
};
|
||||
dbOpenRequest.onerror = event => {
|
||||
console.warn(event.target.errorCode);
|
||||
if (error) {
|
||||
error(event);
|
||||
function dbExec(method, data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
Object.assign(indexedDB.open('stylish', 2), {
|
||||
onsuccess(event) {
|
||||
const database = event.target.result;
|
||||
if (!method) {
|
||||
resolve(database);
|
||||
} else {
|
||||
const transaction = database.transaction(['styles'], 'readwrite');
|
||||
const store = transaction.objectStore('styles');
|
||||
Object.assign(store[method](data), {
|
||||
onsuccess: event => resolve(event, store, transaction, database),
|
||||
onerror: reject,
|
||||
});
|
||||
}
|
||||
};
|
||||
dbOpenRequest.onupgradeneeded = event => {
|
||||
},
|
||||
onerror(event) {
|
||||
console.warn(event.target.errorCode);
|
||||
reject(event);
|
||||
},
|
||||
onupgradeneeded(event) {
|
||||
if (event.oldVersion == 0) {
|
||||
event.target.result.createObjectStore('styles', {
|
||||
keyPath: 'id',
|
||||
autoIncrement: true,
|
||||
});
|
||||
}
|
||||
};
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function getStyles(options, callback) {
|
||||
function getStyles(options) {
|
||||
if (cachedStyles.list) {
|
||||
callback(filterStyles(options));
|
||||
return;
|
||||
return Promise.resolve(filterStyles(options));
|
||||
}
|
||||
if (cachedStyles.mutex.inProgress) {
|
||||
cachedStyles.mutex.onDone.push({options, callback});
|
||||
return;
|
||||
return new Promise(resolve => {
|
||||
cachedStyles.mutex.onDone.push({options, resolve});
|
||||
});
|
||||
}
|
||||
cachedStyles.mutex.inProgress = true;
|
||||
|
||||
getDatabase(db => {
|
||||
const tx = db.transaction(['styles'], 'readonly');
|
||||
const os = tx.objectStore('styles');
|
||||
os.getAll().onsuccess = event => {
|
||||
return dbExec('getAll').then(event => {
|
||||
cachedStyles.list = event.target.result || [];
|
||||
cachedStyles.byId.clear();
|
||||
const t0 = performance.now();
|
||||
let hasTimeToCompile = true;
|
||||
for (const style of cachedStyles.list) {
|
||||
cachedStyles.byId.set(style.id, style);
|
||||
compileStyleRegExps({style});
|
||||
if (hasTimeToCompile) {
|
||||
hasTimeToCompile = !compileStyleRegExps({style}) || performance.now() - t0 > 100;
|
||||
}
|
||||
}
|
||||
callback(filterStyles(options));
|
||||
|
||||
cachedStyles.mutex.inProgress = false;
|
||||
for (const {options, callback} of cachedStyles.mutex.onDone) {
|
||||
callback(filterStyles(options));
|
||||
for (const {options, resolve} of cachedStyles.mutex.onDone) {
|
||||
resolve(filterStyles(options));
|
||||
}
|
||||
cachedStyles.mutex.onDone = [];
|
||||
};
|
||||
}, null);
|
||||
return filterStyles(options);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -213,12 +224,7 @@ function filterStylesInternal({
|
|||
|
||||
|
||||
function saveStyle(style) {
|
||||
return new Promise(resolve => {
|
||||
getDatabase(db => {
|
||||
const tx = db.transaction(['styles'], 'readwrite');
|
||||
const os = tx.objectStore('styles');
|
||||
|
||||
const id = style.id == '0' ? 0 : Number(style.id) || null;
|
||||
const id = Number(style.id) >= 0 ? Number(style.id) : null;
|
||||
const reason = style.reason;
|
||||
const notify = style.notify !== false;
|
||||
delete style.method;
|
||||
|
@ -228,32 +234,42 @@ function saveStyle(style) {
|
|||
delete style.name;
|
||||
}
|
||||
let existed, codeIsUpdated;
|
||||
|
||||
if (id !== null) {
|
||||
// Update or create
|
||||
style.id = id;
|
||||
os.get(id).onsuccess = eventGet => {
|
||||
const oldStyle = eventGet.target.result;
|
||||
return dbExec('get', id).then((event, store) => {
|
||||
const oldStyle = event.target.result;
|
||||
existed = Boolean(oldStyle);
|
||||
codeIsUpdated = !existed || style.sections && !styleSectionsEqual(style, oldStyle);
|
||||
write(Object.assign({}, oldStyle, style));
|
||||
};
|
||||
style = Object.assign({}, oldStyle, style);
|
||||
return write(style, store);
|
||||
});
|
||||
} else {
|
||||
// Create
|
||||
delete style.id;
|
||||
write(Object.assign({
|
||||
style = Object.assign({
|
||||
// Set optional things if they're undefined
|
||||
enabled: true,
|
||||
updateUrl: null,
|
||||
md5Url: null,
|
||||
url: null,
|
||||
originalMd5: null,
|
||||
}, style));
|
||||
}, style);
|
||||
return write(style);
|
||||
}
|
||||
|
||||
function write(style) {
|
||||
function write(style, store) {
|
||||
style.sections = normalizeStyleSections(style);
|
||||
os.put(style).onsuccess = event => {
|
||||
if (store) {
|
||||
return new Promise(resolve => {
|
||||
store.put(style).onsuccess = event => resolve(done(event));
|
||||
});
|
||||
} else {
|
||||
return dbExec('put', style).then(done);
|
||||
}
|
||||
}
|
||||
|
||||
function done(event) {
|
||||
style.id = style.id || event.target.result;
|
||||
invalidateCache(existed ? {updated: style} : {added: style});
|
||||
compileStyleRegExps({style});
|
||||
|
@ -268,28 +284,21 @@ function saveStyle(style) {
|
|||
} else if (reason == 'import') {
|
||||
chrome.storage.local.remove(DIGEST_KEY_PREFIX + style.id, ignoreChromeError);
|
||||
}
|
||||
resolve(style);
|
||||
};
|
||||
return style;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function deleteStyle({id, notify = true}) {
|
||||
id = Number(id);
|
||||
chrome.storage.local.remove(DIGEST_KEY_PREFIX + id, ignoreChromeError);
|
||||
return new Promise(resolve =>
|
||||
getDatabase(db => {
|
||||
const tx = db.transaction(['styles'], 'readwrite');
|
||||
const os = tx.objectStore('styles');
|
||||
os.delete(Number(id)).onsuccess = () => {
|
||||
return dbExec('delete', id).then(() => {
|
||||
invalidateCache({deletedId: id});
|
||||
if (notify) {
|
||||
notifyAllTabs({method: 'styleDeleted', id});
|
||||
}
|
||||
resolve(id);
|
||||
};
|
||||
}));
|
||||
return id;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -448,11 +457,12 @@ function compileStyleRegExps({style, compileAll}) {
|
|||
const rx = tryRegExp(anchored);
|
||||
cachedStyles.regexps.set(cacheKey, rx || false);
|
||||
if (!compileAll && performance.now() - t0 > 100) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
13
update.js
13
update.js
|
@ -22,17 +22,14 @@ var updater = {
|
|||
|
||||
checkAllStyles({observer = () => {}, save = true, ignoreDigest} = {}) {
|
||||
updater.resetInterval();
|
||||
return new Promise(resolve => {
|
||||
getStyles({}, styles => {
|
||||
return getStyles({}).then(styles => {
|
||||
styles = styles.filter(style => style.updateUrl);
|
||||
observer(updater.COUNT, styles.length);
|
||||
Promise.all(styles.map(style =>
|
||||
updater.checkStyle({style, observer, save, ignoreDigest})
|
||||
)).then(() => {
|
||||
return Promise.all(
|
||||
styles.map(style =>
|
||||
updater.checkStyle({style, observer, save, ignoreDigest})));
|
||||
}).then(() => {
|
||||
observer(updater.DONE);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user