Socket
Socket
Sign inDemoInstall

@uppy/golden-retriever

Package Overview
Dependencies
10
Maintainers
6
Versions
80
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 3.0.4 to 3.1.0

7

CHANGELOG.md
# @uppy/golden-retriever
## 3.1.0
Released: 2023-07-06
Included in: Uppy v3.11.0
- @uppy/golden-retriever: refactor to modernize the codebase (Antoine du Hamel / #4520)
## 3.0.4

@@ -4,0 +11,0 @@

47

lib/index.js

@@ -7,3 +7,3 @@ import throttle from 'lodash/throttle.js';

const packageJson = {
"version": "3.0.4"
"version": "3.1.0"
};

@@ -198,5 +198,6 @@ /**

};
const fileToSaveEntries = Object.entries(filesToSave);
// If all files have been removed by the user, clear recovery state
if (Object.keys(filesToSave).length === 0) {
if (fileToSaveEntries.length === 0) {
if (this.uppy.getState().recoveredState !== null) {

@@ -214,18 +215,14 @@ this.uppy.setState({

// Also adding file.isRestored to all files, since they will be restored from local storage
const filesToSaveWithoutData = {};
Object.keys(filesToSave).forEach(file => {
if (filesToSave[file].isRemote) {
filesToSaveWithoutData[file] = {
...filesToSave[file],
isRestored: true
};
} else {
filesToSaveWithoutData[file] = {
...filesToSave[file],
isRestored: true,
data: null,
preview: null
};
}
});
const filesToSaveWithoutData = Object.fromEntries(fileToSaveEntries.map(_ref2 => {
let [id, fileInfo] = _ref2;
return [id, fileInfo.isRemote ? {
...fileInfo,
isRestored: true
} : {
...fileInfo,
isRestored: true,
data: null,
preview: null
}];
}));
const pluginData = {};

@@ -329,12 +326,6 @@ // TODO Find a better way to do this?

deleteBlobs(fileIDs) {
const promises = [];
fileIDs.forEach(id => {
if (this.ServiceWorkerStore) {
promises.push(this.ServiceWorkerStore.delete(id));
}
if (this.IndexedDBStore) {
promises.push(this.IndexedDBStore.delete(id));
}
});
return Promise.all(promises);
return Promise.all(fileIDs.map(id => {
var _this$ServiceWorkerSt, _this$ServiceWorkerSt2, _this$IndexedDBStore;
return (_this$ServiceWorkerSt = (_this$ServiceWorkerSt2 = this.ServiceWorkerStore) == null ? void 0 : _this$ServiceWorkerSt2.delete(id)) != null ? _this$ServiceWorkerSt : (_this$IndexedDBStore = this.IndexedDBStore) == null ? void 0 : _this$IndexedDBStore.delete(id);
}));
}

@@ -341,0 +332,0 @@ install() {

@@ -0,1 +1,7 @@

function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; }
var id = 0;
function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; }
/**
* @type {typeof window.indexedDB}
*/
const indexedDB = typeof window !== 'undefined' && (window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.OIndexedDB || window.msIndexedDB);

@@ -7,4 +13,9 @@ const isSupported = !!indexedDB;

const DB_VERSION = 3;
const MiB = 0x100000;
// Set default `expires` dates on existing stored blobs.
/**
* Set default `expires` dates on existing stored blobs.
*
* @param {IDBObjectStore} store
*/
function migrateExpiration(store) {

@@ -22,2 +33,7 @@ const request = store.openCursor();

}
/**
* @param {string} dbName
* @returns {Promise<IDBDatabase>}
*/
function connect(dbName) {

@@ -27,3 +43,9 @@ const request = indexedDB.open(dbName, DB_VERSION);

request.onupgradeneeded = event => {
/**
* @type {IDBDatabase}
*/
const db = event.target.result;
/**
* @type {IDBTransaction}
*/
const {

@@ -59,2 +81,8 @@ transaction

}
/**
* @template T
* @param {IDBRequest<T>} request
* @returns {Promise<T>}
*/
function waitForRequest(request) {

@@ -69,4 +97,12 @@ return new Promise((resolve, reject) => {

let cleanedUp = false;
var _ready = /*#__PURE__*/_classPrivateFieldLooseKey("ready");
class IndexedDBStore {
constructor(opts) {
/**
* @type {Promise<IDBDatabase> | IDBDatabase}
*/
Object.defineProperty(this, _ready, {
writable: true,
value: void 0
});
this.opts = {

@@ -77,19 +113,27 @@ dbName: DB_NAME,

// 24 hours
maxFileSize: 10 * 1024 * 1024,
// 10 MB
maxTotalSize: 300 * 1024 * 1024,
// 300 MB
maxFileSize: 10 * MiB,
maxTotalSize: 300 * MiB,
...opts
};
this.name = this.opts.storeName;
const createConnection = () => {
return connect(this.opts.dbName);
const createConnection = async () => {
const db = await connect(this.opts.dbName);
_classPrivateFieldLooseBase(this, _ready)[_ready] = db;
return db;
};
if (!cleanedUp) {
cleanedUp = true;
this.ready = IndexedDBStore.cleanup().then(createConnection, createConnection);
_classPrivateFieldLooseBase(this, _ready)[_ready] = IndexedDBStore.cleanup().then(createConnection, createConnection);
} else {
this.ready = createConnection();
_classPrivateFieldLooseBase(this, _ready)[_ready] = createConnection();
}
}
get ready() {
return Promise.resolve(_classPrivateFieldLooseBase(this, _ready)[_ready]);
}
// TODO: remove this setter in the next major
set ready(val) {
_classPrivateFieldLooseBase(this, _ready)[_ready] = val;
}
key(fileID) {

@@ -102,15 +146,9 @@ return `${this.name}!${fileID}`;

*/
list() {
return this.ready.then(db => {
const transaction = db.transaction([STORE_NAME], 'readonly');
const store = transaction.objectStore(STORE_NAME);
const request = store.index('store').getAll(IDBKeyRange.only(this.name));
return waitForRequest(request);
}).then(files => {
const result = {};
files.forEach(file => {
result[file.fileID] = file.data;
});
return result;
});
async list() {
const db = await _classPrivateFieldLooseBase(this, _ready)[_ready];
const transaction = db.transaction([STORE_NAME], 'readonly');
const store = transaction.objectStore(STORE_NAME);
const request = store.index('store').getAll(IDBKeyRange.only(this.name));
const files = await waitForRequest(request);
return Object.fromEntries(files.map(file => [file.fileID, file.data]));
}

@@ -121,11 +159,13 @@

*/
get(fileID) {
return this.ready.then(db => {
const transaction = db.transaction([STORE_NAME], 'readonly');
const request = transaction.objectStore(STORE_NAME).get(this.key(fileID));
return waitForRequest(request);
}).then(result => ({
id: result.data.fileID,
data: result.data.data
}));
async get(fileID) {
const db = await _classPrivateFieldLooseBase(this, _ready)[_ready];
const transaction = db.transaction([STORE_NAME], 'readonly');
const request = transaction.objectStore(STORE_NAME).get(this.key(fileID));
const {
data
} = await waitForRequest(request);
return {
id: data.fileID,
data: data.data
};
}

@@ -137,23 +177,23 @@

* @private
* @returns {Promise<number>}
*/
getSize() {
return this.ready.then(db => {
const transaction = db.transaction([STORE_NAME], 'readonly');
const store = transaction.objectStore(STORE_NAME);
const request = store.index('store').openCursor(IDBKeyRange.only(this.name));
return new Promise((resolve, reject) => {
let size = 0;
request.onsuccess = event => {
const cursor = event.target.result;
if (cursor) {
size += cursor.value.data.size;
cursor.continue();
} else {
resolve(size);
}
};
request.onerror = () => {
reject(new Error('Could not retrieve stored blobs size'));
};
});
async getSize() {
const db = await _classPrivateFieldLooseBase(this, _ready)[_ready];
const transaction = db.transaction([STORE_NAME], 'readonly');
const store = transaction.objectStore(STORE_NAME);
const request = store.index('store').openCursor(IDBKeyRange.only(this.name));
return new Promise((resolve, reject) => {
let size = 0;
request.onsuccess = event => {
const cursor = event.target.result;
if (cursor) {
size += cursor.value.data.size;
cursor.continue();
} else {
resolve(size);
}
};
request.onerror = () => {
reject(new Error('Could not retrieve stored blobs size'));
};
});

@@ -165,22 +205,20 @@ }

*/
put(file) {
async put(file) {
if (file.data.size > this.opts.maxFileSize) {
return Promise.reject(new Error('File is too big to store.'));
throw new Error('File is too big to store.');
}
return this.getSize().then(size => {
if (size > this.opts.maxTotalSize) {
return Promise.reject(new Error('No space left'));
}
return this.ready;
}).then(db => {
const transaction = db.transaction([STORE_NAME], 'readwrite');
const request = transaction.objectStore(STORE_NAME).add({
id: this.key(file.id),
fileID: file.id,
store: this.name,
expires: Date.now() + this.opts.expires,
data: file.data
});
return waitForRequest(request);
const size = await this.getSize();
if (size > this.opts.maxTotalSize) {
throw new Error('No space left');
}
const db = _classPrivateFieldLooseBase(this, _ready)[_ready];
const transaction = db.transaction([STORE_NAME], 'readwrite');
const request = transaction.objectStore(STORE_NAME).add({
id: this.key(file.id),
fileID: file.id,
store: this.name,
expires: Date.now() + this.opts.expires,
data: file.data
});
return waitForRequest(request);
}

@@ -191,8 +229,7 @@

*/
delete(fileID) {
return this.ready.then(db => {
const transaction = db.transaction([STORE_NAME], 'readwrite');
const request = transaction.objectStore(STORE_NAME).delete(this.key(fileID));
return waitForRequest(request);
});
async delete(fileID) {
const db = await _classPrivateFieldLooseBase(this, _ready)[_ready];
const transaction = db.transaction([STORE_NAME], 'readwrite');
const request = transaction.objectStore(STORE_NAME).delete(this.key(fileID));
return waitForRequest(request);
}

@@ -204,22 +241,20 @@

*/
static cleanup() {
return connect(DB_NAME).then(db => {
const transaction = db.transaction([STORE_NAME], 'readwrite');
const store = transaction.objectStore(STORE_NAME);
const request = store.index('expires').openCursor(IDBKeyRange.upperBound(Date.now()));
return new Promise((resolve, reject) => {
request.onsuccess = event => {
const cursor = event.target.result;
if (cursor) {
cursor.delete(); // Ignoring return value … it's not terrible if this goes wrong.
cursor.continue();
} else {
resolve(db);
}
};
request.onerror = reject;
});
}).then(db => {
db.close();
static async cleanup() {
const db = await connect(DB_NAME);
const transaction = db.transaction([STORE_NAME], 'readwrite');
const store = transaction.objectStore(STORE_NAME);
const request = store.index('expires').openCursor(IDBKeyRange.upperBound(Date.now()));
await new Promise((resolve, reject) => {
request.onsuccess = event => {
const cursor = event.target.result;
if (cursor) {
cursor.delete(); // Ignoring return value … it's not terrible if this goes wrong.
cursor.continue();
} else {
resolve();
}
};
request.onerror = reject;
});
db.close();
}

@@ -226,0 +261,0 @@ }

@@ -8,3 +8,3 @@ /**

const key = localStorage.key(i);
if (/^uppyState:/.test(key)) {
if (key.startsWith('uppyState:')) {
instances.push(key.slice('uppyState:'.length));

@@ -22,3 +22,3 @@ }

return JSON.parse(str);
} catch (err) {
} catch {
return null;

@@ -25,0 +25,0 @@ }

@@ -5,5 +5,4 @@ /* globals clients */

function getCache(name) {
if (!fileCache[name]) {
fileCache[name] = Object.create(null);
}
var _fileCache$name;
(_fileCache$name = fileCache[name]) != null ? _fileCache$name : fileCache[name] = Object.create(null);
return fileCache[name];

@@ -10,0 +9,0 @@ }

@@ -0,1 +1,4 @@

function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; }
var id = 0;
function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; }
const isSupported = typeof navigator !== 'undefined' && 'serviceWorker' in navigator;

@@ -16,27 +19,38 @@ function waitForServiceWorker() {

}
var _ready = /*#__PURE__*/_classPrivateFieldLooseKey("ready");
class ServiceWorkerStore {
constructor(opts) {
this.ready = waitForServiceWorker();
Object.defineProperty(this, _ready, {
writable: true,
value: void 0
});
_classPrivateFieldLooseBase(this, _ready)[_ready] = waitForServiceWorker().then(val => {
_classPrivateFieldLooseBase(this, _ready)[_ready] = val;
});
this.name = opts.storeName;
}
list() {
const defer = {};
const promise = new Promise((resolve, reject) => {
defer.resolve = resolve;
defer.reject = reject;
});
const onMessage = event => {
if (event.data.store !== this.name) {
return;
}
switch (event.data.type) {
case 'uppy/ALL_FILES':
defer.resolve(event.data.files);
navigator.serviceWorker.removeEventListener('message', onMessage);
break;
default:
defer.reject();
}
};
this.ready.then(() => {
get ready() {
return Promise.resolve(_classPrivateFieldLooseBase(this, _ready)[_ready]);
}
// TODO: remove this setter in the next major
set ready(val) {
_classPrivateFieldLooseBase(this, _ready)[_ready] = val;
}
async list() {
await _classPrivateFieldLooseBase(this, _ready)[_ready];
return new Promise((resolve, reject) => {
const onMessage = event => {
if (event.data.store !== this.name) {
return;
}
switch (event.data.type) {
case 'uppy/ALL_FILES':
resolve(event.data.files);
navigator.serviceWorker.removeEventListener('message', onMessage);
break;
default:
reject();
}
};
navigator.serviceWorker.addEventListener('message', onMessage);

@@ -48,20 +62,17 @@ navigator.serviceWorker.controller.postMessage({

});
return promise;
}
put(file) {
return this.ready.then(() => {
navigator.serviceWorker.controller.postMessage({
type: 'uppy/ADD_FILE',
store: this.name,
file
});
async put(file) {
await _classPrivateFieldLooseBase(this, _ready)[_ready];
navigator.serviceWorker.controller.postMessage({
type: 'uppy/ADD_FILE',
store: this.name,
file
});
}
delete(fileID) {
return this.ready.then(() => {
navigator.serviceWorker.controller.postMessage({
type: 'uppy/REMOVE_FILE',
store: this.name,
fileID
});
async delete(fileID) {
await _classPrivateFieldLooseBase(this, _ready)[_ready];
navigator.serviceWorker.controller.postMessage({
type: 'uppy/REMOVE_FILE',
store: this.name,
fileID
});

@@ -68,0 +79,0 @@ }

{
"name": "@uppy/golden-retriever",
"description": "The GoldenRetriever Uppy plugin saves selected files in browser cache to seamlessly resume uploding after browser crash or accidentally closed tab",
"version": "3.0.4",
"version": "3.1.0",
"license": "MIT",

@@ -32,4 +32,4 @@ "main": "lib/index.js",

"peerDependencies": {
"@uppy/core": "^3.2.1"
"@uppy/core": "^3.3.0"
}
}

@@ -113,5 +113,6 @@ import throttle from 'lodash/throttle.js'

}
const fileToSaveEntries = Object.entries(filesToSave)
// If all files have been removed by the user, clear recovery state
if (Object.keys(filesToSave).length === 0) {
if (fileToSaveEntries.length === 0) {
if (this.uppy.getState().recoveredState !== null) {

@@ -127,18 +128,14 @@ this.uppy.setState({ recoveredState: null })

// Also adding file.isRestored to all files, since they will be restored from local storage
const filesToSaveWithoutData = {}
Object.keys(filesToSave).forEach((file) => {
if (filesToSave[file].isRemote) {
filesToSaveWithoutData[file] = {
...filesToSave[file],
isRestored: true,
}
} else {
filesToSaveWithoutData[file] = {
...filesToSave[file],
isRestored: true,
data: null,
preview: null,
}
const filesToSaveWithoutData = Object.fromEntries(fileToSaveEntries.map(([id, fileInfo]) => [id, fileInfo.isRemote
? {
...fileInfo,
isRestored: true,
}
})
: {
...fileInfo,
isRestored: true,
data: null,
preview: null,
},
]))

@@ -250,12 +247,3 @@ const pluginData = {}

deleteBlobs (fileIDs) {
const promises = []
fileIDs.forEach((id) => {
if (this.ServiceWorkerStore) {
promises.push(this.ServiceWorkerStore.delete(id))
}
if (this.IndexedDBStore) {
promises.push(this.IndexedDBStore.delete(id))
}
})
return Promise.all(promises)
return Promise.all(fileIDs.map(id => this.ServiceWorkerStore?.delete(id) ?? this.IndexedDBStore?.delete(id)))
}

@@ -262,0 +250,0 @@

@@ -0,1 +1,4 @@

/**
* @type {typeof window.indexedDB}
*/
const indexedDB = typeof window !== 'undefined'

@@ -10,4 +13,9 @@ && (window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.OIndexedDB || window.msIndexedDB)

const DB_VERSION = 3
const MiB = 0x10_00_00
// Set default `expires` dates on existing stored blobs.
/**
* Set default `expires` dates on existing stored blobs.
*
* @param {IDBObjectStore} store
*/
function migrateExpiration (store) {

@@ -26,2 +34,6 @@ const request = store.openCursor()

/**
* @param {string} dbName
* @returns {Promise<IDBDatabase>}
*/
function connect (dbName) {

@@ -31,3 +43,9 @@ const request = indexedDB.open(dbName, DB_VERSION)

request.onupgradeneeded = (event) => {
/**
* @type {IDBDatabase}
*/
const db = event.target.result
/**
* @type {IDBTransaction}
*/
const { transaction } = event.currentTarget

@@ -60,2 +78,7 @@

/**
* @template T
* @param {IDBRequest<T>} request
* @returns {Promise<T>}
*/
function waitForRequest (request) {

@@ -72,2 +95,7 @@ return new Promise((resolve, reject) => {

class IndexedDBStore {
/**
* @type {Promise<IDBDatabase> | IDBDatabase}
*/
#ready
constructor (opts) {

@@ -78,4 +106,4 @@ this.opts = {

expires: DEFAULT_EXPIRY, // 24 hours
maxFileSize: 10 * 1024 * 1024, // 10 MB
maxTotalSize: 300 * 1024 * 1024, // 300 MB
maxFileSize: 10 * MiB,
maxTotalSize: 300 * MiB,
...opts,

@@ -86,4 +114,6 @@ }

const createConnection = () => {
return connect(this.opts.dbName)
const createConnection = async () => {
const db = await connect(this.opts.dbName)
this.#ready = db
return db
}

@@ -93,9 +123,18 @@

cleanedUp = true
this.ready = IndexedDBStore.cleanup()
this.#ready = IndexedDBStore.cleanup()
.then(createConnection, createConnection)
} else {
this.ready = createConnection()
this.#ready = createConnection()
}
}
get ready () {
return Promise.resolve(this.#ready)
}
// TODO: remove this setter in the next major
set ready (val) {
this.#ready = val
}
key (fileID) {

@@ -108,16 +147,10 @@ return `${this.name}!${fileID}`

*/
list () {
return this.ready.then((db) => {
const transaction = db.transaction([STORE_NAME], 'readonly')
const store = transaction.objectStore(STORE_NAME)
const request = store.index('store')
.getAll(IDBKeyRange.only(this.name))
return waitForRequest(request)
}).then((files) => {
const result = {}
files.forEach((file) => {
result[file.fileID] = file.data
})
return result
})
async list () {
const db = await this.#ready
const transaction = db.transaction([STORE_NAME], 'readonly')
const store = transaction.objectStore(STORE_NAME)
const request = store.index('store')
.getAll(IDBKeyRange.only(this.name))
const files = await waitForRequest(request)
return Object.fromEntries(files.map(file => [file.fileID, file.data]))
}

@@ -128,12 +161,12 @@

*/
get (fileID) {
return this.ready.then((db) => {
const transaction = db.transaction([STORE_NAME], 'readonly')
const request = transaction.objectStore(STORE_NAME)
.get(this.key(fileID))
return waitForRequest(request)
}).then((result) => ({
id: result.data.fileID,
data: result.data.data,
}))
async get (fileID) {
const db = await this.#ready
const transaction = db.transaction([STORE_NAME], 'readonly')
const request = transaction.objectStore(STORE_NAME)
.get(this.key(fileID))
const { data } = await waitForRequest(request)
return {
id: data.fileID,
data: data.data,
}
}

@@ -145,24 +178,24 @@

* @private
* @returns {Promise<number>}
*/
getSize () {
return this.ready.then((db) => {
const transaction = db.transaction([STORE_NAME], 'readonly')
const store = transaction.objectStore(STORE_NAME)
const request = store.index('store')
.openCursor(IDBKeyRange.only(this.name))
return new Promise((resolve, reject) => {
let size = 0
request.onsuccess = (event) => {
const cursor = event.target.result
if (cursor) {
size += cursor.value.data.size
cursor.continue()
} else {
resolve(size)
}
async getSize () {
const db = await this.#ready
const transaction = db.transaction([STORE_NAME], 'readonly')
const store = transaction.objectStore(STORE_NAME)
const request = store.index('store')
.openCursor(IDBKeyRange.only(this.name))
return new Promise((resolve, reject) => {
let size = 0
request.onsuccess = (event) => {
const cursor = event.target.result
if (cursor) {
size += cursor.value.data.size
cursor.continue()
} else {
resolve(size)
}
request.onerror = () => {
reject(new Error('Could not retrieve stored blobs size'))
}
})
}
request.onerror = () => {
reject(new Error('Could not retrieve stored blobs size'))
}
})

@@ -174,22 +207,20 @@ }

*/
put (file) {
async put (file) {
if (file.data.size > this.opts.maxFileSize) {
return Promise.reject(new Error('File is too big to store.'))
throw new Error('File is too big to store.')
}
return this.getSize().then((size) => {
if (size > this.opts.maxTotalSize) {
return Promise.reject(new Error('No space left'))
}
return this.ready
}).then((db) => {
const transaction = db.transaction([STORE_NAME], 'readwrite')
const request = transaction.objectStore(STORE_NAME).add({
id: this.key(file.id),
fileID: file.id,
store: this.name,
expires: Date.now() + this.opts.expires,
data: file.data,
})
return waitForRequest(request)
const size = await this.getSize()
if (size > this.opts.maxTotalSize) {
throw new Error('No space left')
}
const db = this.#ready
const transaction = db.transaction([STORE_NAME], 'readwrite')
const request = transaction.objectStore(STORE_NAME).add({
id: this.key(file.id),
fileID: file.id,
store: this.name,
expires: Date.now() + this.opts.expires,
data: file.data,
})
return waitForRequest(request)
}

@@ -200,9 +231,8 @@

*/
delete (fileID) {
return this.ready.then((db) => {
const transaction = db.transaction([STORE_NAME], 'readwrite')
const request = transaction.objectStore(STORE_NAME)
.delete(this.key(fileID))
return waitForRequest(request)
})
async delete (fileID) {
const db = await this.#ready
const transaction = db.transaction([STORE_NAME], 'readwrite')
const request = transaction.objectStore(STORE_NAME)
.delete(this.key(fileID))
return waitForRequest(request)
}

@@ -214,23 +244,21 @@

*/
static cleanup () {
return connect(DB_NAME).then((db) => {
const transaction = db.transaction([STORE_NAME], 'readwrite')
const store = transaction.objectStore(STORE_NAME)
const request = store.index('expires')
.openCursor(IDBKeyRange.upperBound(Date.now()))
return new Promise((resolve, reject) => {
request.onsuccess = (event) => {
const cursor = event.target.result
if (cursor) {
cursor.delete() // Ignoring return value … it's not terrible if this goes wrong.
cursor.continue()
} else {
resolve(db)
}
static async cleanup () {
const db = await connect(DB_NAME)
const transaction = db.transaction([STORE_NAME], 'readwrite')
const store = transaction.objectStore(STORE_NAME)
const request = store.index('expires')
.openCursor(IDBKeyRange.upperBound(Date.now()))
await new Promise((resolve, reject) => {
request.onsuccess = (event) => {
const cursor = event.target.result
if (cursor) {
cursor.delete() // Ignoring return value … it's not terrible if this goes wrong.
cursor.continue()
} else {
resolve()
}
request.onerror = reject
})
}).then((db) => {
db.close()
}
request.onerror = reject
})
db.close()
}

@@ -237,0 +265,0 @@ }

@@ -8,3 +8,3 @@ /**

const key = localStorage.key(i)
if (/^uppyState:/.test(key)) {
if (key.startsWith('uppyState:')) {
instances.push(key.slice('uppyState:'.length))

@@ -22,3 +22,3 @@ }

return JSON.parse(str)
} catch (err) {
} catch {
return null

@@ -25,0 +25,0 @@ }

@@ -6,5 +6,3 @@ /* globals clients */

function getCache (name) {
if (!fileCache[name]) {
fileCache[name] = Object.create(null)
}
fileCache[name] ??= Object.create(null)
return fileCache[name]

@@ -11,0 +9,0 @@ }

@@ -19,29 +19,36 @@ const isSupported = typeof navigator !== 'undefined' && 'serviceWorker' in navigator

class ServiceWorkerStore {
#ready
constructor (opts) {
this.ready = waitForServiceWorker()
this.#ready = waitForServiceWorker().then((val) => { this.#ready = val })
this.name = opts.storeName
}
list () {
const defer = {}
const promise = new Promise((resolve, reject) => {
defer.resolve = resolve
defer.reject = reject
})
get ready () {
return Promise.resolve(this.#ready)
}
const onMessage = (event) => {
if (event.data.store !== this.name) {
return
// TODO: remove this setter in the next major
set ready (val) {
this.#ready = val
}
async list () {
await this.#ready
return new Promise((resolve, reject) => {
const onMessage = (event) => {
if (event.data.store !== this.name) {
return
}
switch (event.data.type) {
case 'uppy/ALL_FILES':
resolve(event.data.files)
navigator.serviceWorker.removeEventListener('message', onMessage)
break
default:
reject()
}
}
switch (event.data.type) {
case 'uppy/ALL_FILES':
defer.resolve(event.data.files)
navigator.serviceWorker.removeEventListener('message', onMessage)
break
default:
defer.reject()
}
}
this.ready.then(() => {
navigator.serviceWorker.addEventListener('message', onMessage)

@@ -54,23 +61,19 @@

})
return promise
}
put (file) {
return this.ready.then(() => {
navigator.serviceWorker.controller.postMessage({
type: 'uppy/ADD_FILE',
store: this.name,
file,
})
async put (file) {
await this.#ready
navigator.serviceWorker.controller.postMessage({
type: 'uppy/ADD_FILE',
store: this.name,
file,
})
}
delete (fileID) {
return this.ready.then(() => {
navigator.serviceWorker.controller.postMessage({
type: 'uppy/REMOVE_FILE',
store: this.name,
fileID,
})
async delete (fileID) {
await this.#ready
navigator.serviceWorker.controller.postMessage({
type: 'uppy/REMOVE_FILE',
store: this.name,
fileID,
})

@@ -77,0 +80,0 @@ }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc