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,
|
||||
getStylesByUrl: styleManager.getStylesByUrl,
|
||||
importStyle: styleManager.importStyle,
|
||||
importManyStyles: styleManager.importMany,
|
||||
installStyle: styleManager.installStyle,
|
||||
styleExists: styleManager.styleExists,
|
||||
toggleStyle: styleManager.toggleStyle,
|
||||
|
|
|
@ -74,41 +74,50 @@ const db = (() => {
|
|||
}
|
||||
|
||||
function dbExecIndexedDB(method, ...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
Object.assign(indexedDB.open('stylish', 2), {
|
||||
onsuccess(event) {
|
||||
const database = event.target.result;
|
||||
return open().then(database => {
|
||||
if (!method) {
|
||||
resolve(database);
|
||||
} else {
|
||||
const transaction = database.transaction(['styles'], 'readwrite');
|
||||
return database;
|
||||
}
|
||||
if (method === 'putMany') {
|
||||
return putMany(database, ...args);
|
||||
}
|
||||
const mode = method.startsWith('get') ? 'readonly' : 'readwrite';
|
||||
const transaction = database.transaction(['styles'], mode);
|
||||
const store = transaction.objectStore('styles');
|
||||
try {
|
||||
Object.assign(store[method](...args), {
|
||||
onsuccess: event => resolve(event, store, transaction, database),
|
||||
onerror: reject,
|
||||
return storeRequest(store, method, ...args);
|
||||
});
|
||||
|
||||
function storeRequest(store, method, ...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = store[method](...args);
|
||||
request.onsuccess = resolve;
|
||||
request.onerror = reject;
|
||||
});
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
}
|
||||
},
|
||||
onerror(event) {
|
||||
console.warn(event.target.error || event.target.errorCode);
|
||||
reject(event);
|
||||
},
|
||||
onupgradeneeded(event) {
|
||||
|
||||
function open() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = indexedDB.open('stylish', 2);
|
||||
request.onsuccess = () => resolve(request.result);
|
||||
request.onerror = reject;
|
||||
request.onupgradeneeded = event => {
|
||||
if (event.oldVersion === 0) {
|
||||
event.target.result.createObjectStore('styles', {
|
||||
keyPath: 'id',
|
||||
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) {
|
||||
const STYLE_KEY_PREFIX = 'style-';
|
||||
switch (method) {
|
||||
|
@ -118,17 +127,33 @@ const db = (() => {
|
|||
|
||||
case 'put':
|
||||
if (!data.id) {
|
||||
return getAllStyles().then(styles => {
|
||||
data.id = 1;
|
||||
for (const style of styles) {
|
||||
data.id = Math.max(data.id, style.id + 1);
|
||||
}
|
||||
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);
|
||||
|
||||
|
@ -150,5 +175,17 @@ const db = (() => {
|
|||
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,
|
||||
findStyle,
|
||||
importStyle,
|
||||
importMany,
|
||||
toggleStyle,
|
||||
setStyleExclusions,
|
||||
getAllStyles, // used by import-export
|
||||
|
@ -138,6 +139,18 @@ const styleManager = (() => {
|
|||
.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) {
|
||||
const style = styles.get(data.id);
|
||||
if (!style) {
|
||||
|
|
|
@ -126,13 +126,20 @@ function importFromString(jsonString) {
|
|||
oldStyles.map(style => [style.id, style]));
|
||||
oldStylesByName = json.length && new Map(
|
||||
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);
|
||||
if (info) {
|
||||
return API.importStyle(item)
|
||||
.then(style => updateStats(style, info));
|
||||
items.push({info, item});
|
||||
}
|
||||
}));
|
||||
});
|
||||
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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user