From f63900e17a4571e3b94c1c2b22778047d7598adf Mon Sep 17 00:00:00 2001 From: pradip mandal Date: Sat, 16 Mar 2024 11:25:55 +0530 Subject: [PATCH 1/2] support to store url in indexDB --- lib/browser/index.js | 24 ++-- lib/browser/urlStorageIndexDB.js | 118 ++++++++++++++++++ ...rlStorage.js => urlStorageLocalStorage.js} | 4 +- 3 files changed, 132 insertions(+), 14 deletions(-) create mode 100644 lib/browser/urlStorageIndexDB.js rename lib/browser/{urlStorage.js => urlStorageLocalStorage.js} (95%) diff --git a/lib/browser/index.js b/lib/browser/index.js index a3908545..051855ed 100644 --- a/lib/browser/index.js +++ b/lib/browser/index.js @@ -1,18 +1,18 @@ -import BaseUpload from '../upload.js' -import NoopUrlStorage from '../noopUrlStorage.js' -import { enableDebugLog } from '../logger.js' import DetailedError from '../error.js' - -import { canStoreURLs, WebStorageUrlStorage } from './urlStorage.js' -import DefaultHttpStack from './httpStack.js' +import { enableDebugLog } from '../logger.js' +import NoopUrlStorage from '../noopUrlStorage.js' +import BaseUpload from '../upload.js' import FileReader from './fileReader.js' import fingerprint from './fileSignature.js' +import DefaultHttpStack from './httpStack.js' +import { canStoreURLsInIndexDB, WebIndexDBStorageUrlStorage } from './urlStorageIndexDB.js' +import { canStoreURLsInLocalStorage, WebLocalStorageUrlStorage } from './urlStorageLocalStorage.js' const defaultOptions = { ...BaseUpload.defaultOptions, httpStack: new DefaultHttpStack(), fileReader: new FileReader(), - urlStorage: canStoreURLs ? new WebStorageUrlStorage() : new NoopUrlStorage(), + urlStorage:canStoreURLsInIndexDB ? new WebIndexDBStorageUrlStorage() : canStoreURLsInLocalStorage ? new WebLocalStorageUrlStorage() : new NoopUrlStorage(), fingerprint, } @@ -35,11 +35,11 @@ const isSupported = typeof Blob.prototype.slice === 'function' export { - Upload, - canStoreURLs, - defaultOptions, - isSupported, - enableDebugLog, + canStoreURLsInLocalStorage, DefaultHttpStack, + defaultOptions, DetailedError, + enableDebugLog, + isSupported, + Upload } diff --git a/lib/browser/urlStorageIndexDB.js b/lib/browser/urlStorageIndexDB.js new file mode 100644 index 00000000..c28cb881 --- /dev/null +++ b/lib/browser/urlStorageIndexDB.js @@ -0,0 +1,118 @@ +const isSupportIndexDB = () => { + return 'indexedDB' in window && !/iPad|iPhone|iPod/.test(navigator.platform); + }; + let hasStorage = false; + try { + hasStorage = isSupportIndexDB(); + } catch (e) { + if (e.code === e.SECURITY_ERR || e.code === e.QUOTA_EXCEEDED_ERR) { + hasStorage = false; + } else { + throw e; + } + } + + export const canStoreURLsInIndexDB = hasStorage; + + export class WebIndexDBStorageUrlStorage { + constructor() { + this.dbName = 'tusUrlStorage'; + this.storeName = 'upload'; + this.dbPromise = this.openDatabase(); + } + + openDatabase() { + return new Promise((resolve, reject) => { + const openRequest = indexedDB.open(this.dbName); + openRequest.onupgradeneeded = function () { + const db = openRequest.result; + if (!db.objectStoreNames.contains(this.storeName)) { + db.createObjectStore(this.storeName, {keyPath: 'urlStorageKey'}); + } + }.bind(this); + openRequest.onsuccess = function () { + resolve(openRequest.result); + }; + openRequest.onerror = reject; + }); + } + + async _getAllUploadWithKeys() { + try { + const db = await this.dbPromise; + const transaction = db.transaction(this.storeName, 'readonly'); + const store = transaction.objectStore(this.storeName); + const request = store.getAll(); + const results = await new Promise((resolve, reject) => { + request.onsuccess = () => resolve(request.result); + request.onerror = reject; + }); + return results.map((result) => ({ + ...result, + urlStorageKey: result.urlStorageKey, + })); + } catch (error) { + console.error('Error getting all uploads with keys:', error); + throw error; + } + } + + async findAllUploads() { + try { + const results = await this._getAllUploadWithKeys(); + return results; + } catch (error) { + console.error('Error finding all uploads:', error); + throw error; + } + } + + async findUploadsByFingerprint(fingerprint) { + try { + const allData = await this._getAllUploadWithKeys(); + const results = allData.find( + (data) => data.urlStorageKey.indexOf(`tus::${fingerprint}::`) === 0 + ); + + return results ? [results] : []; + } catch (error) { + console.error('Error finding uploads by fingerprint:', error); + throw error; + } + } + + async removeUpload(urlStorageKey) { + try { + const db = await this.dbPromise; + const transaction = db.transaction(this.storeName, 'readwrite'); + const store = transaction.objectStore(this.storeName); + const request = store.delete(urlStorageKey); + await new Promise((resolve, reject) => { + request.onsuccess = resolve; + request.onerror = reject; + }); + } catch (error) { + console.error('Error removing upload:', error); + throw error; + } + } + + async addUpload(fingerprint, upload) { + try { + const id = Math.round(Math.random() * 1e12); + const key = `tus::${fingerprint}::${id}`; + const db = await this.dbPromise; + const transaction = db.transaction(this.storeName, 'readwrite'); + const store = transaction.objectStore(this.storeName); + const request = store.put({urlStorageKey: key, ...upload}); + await new Promise((resolve, reject) => { + request.onsuccess = () => resolve(key); + request.onerror = reject; + }); + return key; + } catch (error) { + console.error('Error adding upload:', error); + throw error; + } + } + } diff --git a/lib/browser/urlStorage.js b/lib/browser/urlStorageLocalStorage.js similarity index 95% rename from lib/browser/urlStorage.js rename to lib/browser/urlStorageLocalStorage.js index 3def8a76..e5d37039 100644 --- a/lib/browser/urlStorage.js +++ b/lib/browser/urlStorageLocalStorage.js @@ -22,9 +22,9 @@ try { } } -export const canStoreURLs = hasStorage +export const canStoreURLsInLocalStorage = hasStorage -export class WebStorageUrlStorage { +export class WebLocalStorageUrlStorage { findAllUploads() { const results = this._findEntries('tus::') return Promise.resolve(results) From 0ef565c8b1016cc93eecaadd0f893ce2b0755b06 Mon Sep 17 00:00:00 2001 From: pradip mandal Date: Sat, 16 Mar 2024 11:29:05 +0530 Subject: [PATCH 2/2] export canStoreURLsInIndexDB --- lib/browser/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/browser/index.js b/lib/browser/index.js index 051855ed..2ddf6e63 100644 --- a/lib/browser/index.js +++ b/lib/browser/index.js @@ -35,6 +35,7 @@ const isSupported = typeof Blob.prototype.slice === 'function' export { + canStoreURLsInIndexDB, canStoreURLsInLocalStorage, DefaultHttpStack, defaultOptions,