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,41 +74,50 @@ 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), {
 | 
					 | 
				
			||||||
        onsuccess(event) {
 | 
					 | 
				
			||||||
          const database = event.target.result;
 | 
					 | 
				
			||||||
      if (!method) {
 | 
					      if (!method) {
 | 
				
			||||||
            resolve(database);
 | 
					        return database;
 | 
				
			||||||
          } else {
 | 
					      }
 | 
				
			||||||
            const transaction = database.transaction(['styles'], 'readwrite');
 | 
					      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');
 | 
					      const store = transaction.objectStore('styles');
 | 
				
			||||||
            try {
 | 
					      return storeRequest(store, method, ...args);
 | 
				
			||||||
              Object.assign(store[method](...args), {
 | 
					    });
 | 
				
			||||||
                onsuccess: event => resolve(event, store, transaction, database),
 | 
					
 | 
				
			||||||
                onerror: reject,
 | 
					    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);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
          }
 | 
					
 | 
				
			||||||
        },
 | 
					    function open() {
 | 
				
			||||||
        onerror(event) {
 | 
					      return new Promise((resolve, reject) => {
 | 
				
			||||||
          console.warn(event.target.error || event.target.errorCode);
 | 
					        const request = indexedDB.open('stylish', 2);
 | 
				
			||||||
          reject(event);
 | 
					        request.onsuccess = () => resolve(request.result);
 | 
				
			||||||
        },
 | 
					        request.onerror = reject;
 | 
				
			||||||
        onupgradeneeded(event) {
 | 
					        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) {
 | 
				
			||||||
    const STYLE_KEY_PREFIX = 'style-';
 | 
					    const STYLE_KEY_PREFIX = 'style-';
 | 
				
			||||||
    switch (method) {
 | 
					    switch (method) {
 | 
				
			||||||
| 
						 | 
					@ -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