Add: improve import performance (#547)
* Add: implement db putMany * Fix: putMany returns a list of ids
This commit is contained in:
parent
8291da0bb5
commit
5646b8a0d9
|
@ -17,6 +17,7 @@ window.API_METHODS = Object.assign(window.API_METHODS || {}, {
|
||||||
getStyle: styleManager.get,
|
getStyle: styleManager.get,
|
||||||
getStylesByUrl: styleManager.getStylesByUrl,
|
getStylesByUrl: styleManager.getStylesByUrl,
|
||||||
importStyle: styleManager.importStyle,
|
importStyle: styleManager.importStyle,
|
||||||
|
importManyStyles: styleManager.importMany,
|
||||||
installStyle: styleManager.installStyle,
|
installStyle: styleManager.installStyle,
|
||||||
styleExists: styleManager.styleExists,
|
styleExists: styleManager.styleExists,
|
||||||
toggleStyle: styleManager.toggleStyle,
|
toggleStyle: styleManager.toggleStyle,
|
||||||
|
|
|
@ -74,39 +74,48 @@ const db = (() => {
|
||||||
}
|
}
|
||||||
|
|
||||||
function dbExecIndexedDB(method, ...args) {
|
function dbExecIndexedDB(method, ...args) {
|
||||||
return new Promise((resolve, reject) => {
|
return open().then(database => {
|
||||||
Object.assign(indexedDB.open('stylish', 2), {
|
if (!method) {
|
||||||
onsuccess(event) {
|
return database;
|
||||||
const database = event.target.result;
|
}
|
||||||
if (!method) {
|
if (method === 'putMany') {
|
||||||
resolve(database);
|
return putMany(database, ...args);
|
||||||
} else {
|
}
|
||||||
const transaction = database.transaction(['styles'], 'readwrite');
|
const mode = method.startsWith('get') ? 'readonly' : 'readwrite';
|
||||||
const store = transaction.objectStore('styles');
|
const transaction = database.transaction(['styles'], mode);
|
||||||
try {
|
const store = transaction.objectStore('styles');
|
||||||
Object.assign(store[method](...args), {
|
return storeRequest(store, method, ...args);
|
||||||
onsuccess: event => resolve(event, store, transaction, database),
|
});
|
||||||
onerror: reject,
|
|
||||||
});
|
function storeRequest(store, method, ...args) {
|
||||||
} catch (err) {
|
return new Promise((resolve, reject) => {
|
||||||
reject(err);
|
const request = store[method](...args);
|
||||||
}
|
request.onsuccess = resolve;
|
||||||
}
|
request.onerror = reject;
|
||||||
},
|
});
|
||||||
onerror(event) {
|
}
|
||||||
console.warn(event.target.error || event.target.errorCode);
|
|
||||||
reject(event);
|
function open() {
|
||||||
},
|
return new Promise((resolve, reject) => {
|
||||||
onupgradeneeded(event) {
|
const request = indexedDB.open('stylish', 2);
|
||||||
|
request.onsuccess = () => resolve(request.result);
|
||||||
|
request.onerror = reject;
|
||||||
|
request.onupgradeneeded = event => {
|
||||||
if (event.oldVersion === 0) {
|
if (event.oldVersion === 0) {
|
||||||
event.target.result.createObjectStore('styles', {
|
event.target.result.createObjectStore('styles', {
|
||||||
keyPath: 'id',
|
keyPath: 'id',
|
||||||
autoIncrement: true,
|
autoIncrement: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
function putMany(database, items) {
|
||||||
|
const transaction = database.transaction(['styles'], 'readwrite');
|
||||||
|
const store = transaction.objectStore('styles');
|
||||||
|
return Promise.all(items.map(item => storeRequest(store, 'put', item)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function dbExecChromeStorage(method, data) {
|
function dbExecChromeStorage(method, data) {
|
||||||
|
@ -118,17 +127,33 @@ const db = (() => {
|
||||||
|
|
||||||
case 'put':
|
case 'put':
|
||||||
if (!data.id) {
|
if (!data.id) {
|
||||||
return getAllStyles().then(styles => {
|
return getMaxId().then(id => {
|
||||||
data.id = 1;
|
data.id = id + 1;
|
||||||
for (const style of styles) {
|
|
||||||
data.id = Math.max(data.id, style.id + 1);
|
|
||||||
}
|
|
||||||
return dbExecChromeStorage('put', data);
|
return dbExecChromeStorage('put', data);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return chromeLocal.setValue(STYLE_KEY_PREFIX + data.id, data)
|
return chromeLocal.setValue(STYLE_KEY_PREFIX + data.id, data)
|
||||||
.then(() => (chrome.runtime.lastError ? Promise.reject() : data.id));
|
.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':
|
case 'delete':
|
||||||
return chromeLocal.remove(STYLE_KEY_PREFIX + data);
|
return chromeLocal.remove(STYLE_KEY_PREFIX + data);
|
||||||
|
|
||||||
|
@ -150,5 +175,17 @@ const db = (() => {
|
||||||
return styles;
|
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;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -55,6 +55,7 @@ const styleManager = (() => {
|
||||||
editSave,
|
editSave,
|
||||||
findStyle,
|
findStyle,
|
||||||
importStyle,
|
importStyle,
|
||||||
|
importMany,
|
||||||
toggleStyle,
|
toggleStyle,
|
||||||
setStyleExclusions,
|
setStyleExclusions,
|
||||||
getAllStyles, // used by import-export
|
getAllStyles, // used by import-export
|
||||||
|
@ -138,6 +139,18 @@ const styleManager = (() => {
|
||||||
.then(newData => handleSave(newData, 'import'));
|
.then(newData => handleSave(newData, 'import'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function importMany(items) {
|
||||||
|
return db.exec('putMany', items)
|
||||||
|
.then(events => {
|
||||||
|
for (let i = 0; i < items.length; i++) {
|
||||||
|
if (!items[i].id) {
|
||||||
|
items[i].id = events[i].target.result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Promise.all(items.map(i => handleSave(i, 'import')));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function installStyle(data, reason = null) {
|
function installStyle(data, reason = null) {
|
||||||
const style = styles.get(data.id);
|
const style = styles.get(data.id);
|
||||||
if (!style) {
|
if (!style) {
|
||||||
|
|
|
@ -126,13 +126,20 @@ function importFromString(jsonString) {
|
||||||
oldStyles.map(style => [style.id, style]));
|
oldStyles.map(style => [style.id, style]));
|
||||||
oldStylesByName = json.length && new Map(
|
oldStylesByName = json.length && new Map(
|
||||||
oldStyles.map(style => [style.name.trim(), style]));
|
oldStyles.map(style => [style.name.trim(), style]));
|
||||||
return Promise.all(json.map((item, i) => {
|
|
||||||
|
const items = [];
|
||||||
|
json.forEach((item, i) => {
|
||||||
const info = analyze(item, i);
|
const info = analyze(item, i);
|
||||||
if (info) {
|
if (info) {
|
||||||
return API.importStyle(item)
|
items.push({info, item});
|
||||||
.then(style => updateStats(style, info));
|
|
||||||
}
|
}
|
||||||
}));
|
});
|
||||||
|
return API.importManyStyles(items.map(i => i.item))
|
||||||
|
.then(styles => {
|
||||||
|
for (let i = 0; i < styles.length; i++) {
|
||||||
|
updateStats(styles[i], items[i].info);
|
||||||
|
}
|
||||||
|
});
|
||||||
})
|
})
|
||||||
.then(done);
|
.then(done);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user