UNPKG

uppy

Version:

Almost as cute as a Puppy :dog:

206 lines (166 loc) 7.92 kB
'use strict'; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var Plugin = require('../Plugin'); var ServiceWorkerStore = require('./ServiceWorkerStore'); var IndexedDBStore = require('./IndexedDBStore' /** * Restore Files plugin — restores selected files and resumes uploads * after a closed tab or a browser crash! * * Uses localStorage, IndexedDB and ServiceWorker to do its magic, read more: * https://uppy.io/blog/2017/07/golden-retriever/ */ );module.exports = function (_Plugin) { _inherits(RestoreFiles, _Plugin); function RestoreFiles(core, opts) { _classCallCheck(this, RestoreFiles); var _this = _possibleConstructorReturn(this, _Plugin.call(this, core, opts)); _this.type = 'debugger'; _this.id = 'RestoreFiles'; _this.title = 'Restore Files'; var defaultOptions = { serviceWorker: false }; _this.opts = _extends({}, defaultOptions, opts); _this.ServiceWorkerStore = null; if (_this.opts.serviceWorker) { _this.ServiceWorkerStore = new ServiceWorkerStore(core, { storeName: core.getID() }); } _this.IndexedDBStore = new IndexedDBStore(core, _extends({}, opts.indexedDB || {}, { storeName: core.getID() })); _this.saveFilesStateToLocalStorage = _this.saveFilesStateToLocalStorage.bind(_this); _this.loadFilesStateFromLocalStorage = _this.loadFilesStateFromLocalStorage.bind(_this); _this.loadFileBlobsFromServiceWorker = _this.loadFileBlobsFromServiceWorker.bind(_this); _this.loadFileBlobsFromIndexedDB = _this.loadFileBlobsFromIndexedDB.bind(_this); _this.onBlobsLoaded = _this.onBlobsLoaded.bind(_this); return _this; } RestoreFiles.prototype.loadFilesStateFromLocalStorage = function loadFilesStateFromLocalStorage() { var savedState = localStorage.getItem('uppyState:' + this.core.opts.id); if (savedState) { this.core.log('Recovered some state from Local Storage'); this.core.setState(JSON.parse(savedState)); } }; RestoreFiles.prototype.saveFilesStateToLocalStorage = function saveFilesStateToLocalStorage() { var files = JSON.stringify({ currentUploads: this.core.state.currentUploads, files: this.core.state.files }); localStorage.setItem('uppyState:' + this.core.opts.id, files); }; RestoreFiles.prototype.loadFileBlobsFromServiceWorker = function loadFileBlobsFromServiceWorker() { var _this2 = this; this.ServiceWorkerStore.list().then(function (blobs) { var numberOfFilesRecovered = Object.keys(blobs).length; var numberOfFilesTryingToRecover = Object.keys(_this2.core.state.files).length; if (numberOfFilesRecovered === numberOfFilesTryingToRecover) { _this2.core.log('Successfully recovered ' + numberOfFilesRecovered + ' blobs from Service Worker!'); _this2.core.info('Successfully recovered ' + numberOfFilesRecovered + ' files', 'success', 3000); _this2.onBlobsLoaded(blobs); } else { _this2.core.log('Failed to recover blobs from Service Worker, trying IndexedDB now...'); _this2.loadFileBlobsFromIndexedDB(); } }); }; RestoreFiles.prototype.loadFileBlobsFromIndexedDB = function loadFileBlobsFromIndexedDB() { var _this3 = this; this.IndexedDBStore.list().then(function (blobs) { var numberOfFilesRecovered = Object.keys(blobs).length; if (numberOfFilesRecovered > 0) { _this3.core.log('Successfully recovered ' + numberOfFilesRecovered + ' blobs from Indexed DB!'); _this3.core.info('Successfully recovered ' + numberOfFilesRecovered + ' files', 'success', 3000); return _this3.onBlobsLoaded(blobs); } _this3.core.log('Couldn’t recover anything from IndexedDB :('); }); }; RestoreFiles.prototype.onBlobsLoaded = function onBlobsLoaded(blobs) { var _this4 = this; var obsoleteBlobs = []; var updatedFiles = _extends({}, this.core.state.files); Object.keys(blobs).forEach(function (fileID) { var originalFile = _this4.core.getFile(fileID); if (!originalFile) { obsoleteBlobs.push(fileID); return; } var cachedData = blobs[fileID]; var updatedFileData = { data: cachedData, isRestored: true }; var updatedFile = _extends({}, originalFile, updatedFileData); updatedFiles[fileID] = updatedFile; _this4.core.generatePreview(updatedFile); }); this.core.setState({ files: updatedFiles }); this.core.emit('core:restored'); if (obsoleteBlobs.length) { this.deleteBlobs(obsoleteBlobs).then(function () { _this4.core.log('RestoreFiles: cleaned up ' + obsoleteBlobs.length + ' old files'); }); } }; RestoreFiles.prototype.deleteBlobs = function deleteBlobs(fileIDs) { var _this5 = this; var promises = []; fileIDs.forEach(function (id) { if (_this5.ServiceWorkerStore) { promises.push(_this5.ServiceWorkerStore.delete(id)); } if (_this5.IndexedDBStore) { promises.push(_this5.IndexedDBStore.delete(id)); } }); return Promise.all(promises); }; RestoreFiles.prototype.install = function install() { var _this6 = this; this.loadFilesStateFromLocalStorage(); if (Object.keys(this.core.state.files).length > 0) { if (this.ServiceWorkerStore) { this.core.log('Attempting to load files from Service Worker...'); this.loadFileBlobsFromServiceWorker(); } else { this.core.log('Attempting to load files from Indexed DB...'); this.loadFileBlobsFromIndexedDB(); } } this.core.on('core:file-added', function (file) { if (file.isRemote) return; if (_this6.ServiceWorkerStore) { _this6.ServiceWorkerStore.put(file).catch(function (err) { _this6.core.log('Could not store file', 'error'); _this6.core.log(err); }); } _this6.IndexedDBStore.put(file).catch(function (err) { _this6.core.log('Could not store file', 'error'); _this6.core.log(err); }); }); this.core.on('core:file-removed', function (fileID) { if (_this6.ServiceWorkerStore) _this6.ServiceWorkerStore.delete(fileID); _this6.IndexedDBStore.delete(fileID); }); this.core.on('core:state-update', this.saveFilesStateToLocalStorage); this.core.on('core:restored', function () { // start all uploads again when file blobs are restored var _core$getState = _this6.core.getState(), currentUploads = _core$getState.currentUploads; if (currentUploads) { Object.keys(currentUploads).forEach(function (uploadId) { _this6.core.restore(uploadId, currentUploads[uploadId]); }); } }); }; return RestoreFiles; }(Plugin); //# sourceMappingURL=index.js.map