inbasic / turbo-download-manager-v2

a multi-thread download manager with a built-in audio, video and image grabber
http://www.add0n.com/turbo-download-manager-v2.html
Mozilla Public License 2.0
135 stars 45 forks source link

Restore doesn't work; store meta info in idb #24

Open saizai opened 3 years ago

saizai commented 3 years ago

If downloads.cache isn't populated (e.g. the extension crashed & was reloaded), then this will fail. https://github.com/inbasic/turbo-download-manager-v2/blob/6b565b09dc8934547939c6b7ea7fddae1ffcdfd6/v3/downloads/manager.js#L457-L482

This could be fixed by adding this to manager.js:

manager.updateDb = (obj) => {
  if (manager.db) {
    const transaction = manager.db.transaction('downloads', 'readwrite');
//    transaction.oncomplete = resolve;
    transaction.onerror = e => reject(Error('Manager.updateDb, ' + e.target.error));
    transaction.objectStore('downloads').put(JSON.parse(JSON.stringify(downloads.cache[obj.id])));
    transaction.commit();
  };
};

{
  request = indexedDB.open('downloads', 1);
  request.onupgradeneeded = () => {
    // TODO - Remove this line when Firefox supports indexedDB.databases()
    if (('databases' in indexedDB) === false) {
      localStorage.setItem('downloads', true);
    }
    request.result.createObjectStore('downloads', {
      keyPath: 'id'
    });
  };
  request.onerror = e => reject(Error('File.open, ' + e.target.error));
  request.onsuccess = () => {
    manager.db = request.result;
    manager.opened = true;
  };
}

downloads.onChanged.addListener(manager.updateDb);

Then one could do something like this at that restore:

req = manager.db.transaction('downloads','readonly').objectStore('downloads').getAll()
req.onSuccess = () => { 
 ...
}

However, the IDB storage necessarily removes functions, callbacks, etc. So downloads.download would need to be refactored to accept this.

inbasic commented 3 years ago

I am not sure how to replicate this. As far as I see, the function does not rely on the existing entries of downloads.cache after a restart. The downloads.download({}, id => {..}) is supposed to prepare a new download entry so the cache must be available.