@uppy/utils
Advanced tools
Comparing version 5.3.0 to 5.4.0
# @uppy/utils | ||
## 5.4.0 | ||
Released: 2023-06-19 | ||
Included in: Uppy v3.10.0 | ||
- @uppy/companion,@uppy/core,@uppy/dashboard,@uppy/golden-retriever,@uppy/status-bar,@uppy/utils: Migrate all lodash' per-method-packages usage to lodash. (LinusMain / #4274) | ||
- @uppy/aws-s3-multipart,@uppy/aws-s3,@uppy/tus,@uppy/utils,@uppy/xhr-upload: When file is removed (or all are canceled), controller.abort queued requests (Artur Paikin / #4504) | ||
- @uppy/utils: rename `EventTracker` -> `EventManager` (Stephen Wooten / #4481) | ||
## 5.1.3 | ||
@@ -4,0 +13,0 @@ |
@@ -5,3 +5,2 @@ import hasOwnProperty from './hasProperty.js'; | ||
*/ | ||
export const { | ||
@@ -17,5 +16,3 @@ AbortController | ||
} | ||
const err = new DOMException(message, 'AbortError'); | ||
if (options != null && hasOwnProperty(options, 'cause')) { | ||
@@ -29,4 +26,3 @@ Object.defineProperty(err, 'cause', { | ||
} | ||
return err; | ||
}; |
const DATA_URL_PATTERN = /^data:([^/]+\/[^,;]+(?:[^,]*?))(;base64)?,([\s\S]*)$/; | ||
export default function dataURItoBlob(dataURI, opts, toFile) { | ||
var _ref, _opts$mimeType; | ||
// get the base64 data | ||
const dataURIData = DATA_URL_PATTERN.exec(dataURI); // user may provide mime type, if not get it from data URI | ||
const dataURIData = DATA_URL_PATTERN.exec(dataURI); | ||
// user may provide mime type, if not get it from data URI | ||
const mimeType = (_ref = (_opts$mimeType = opts.mimeType) != null ? _opts$mimeType : dataURIData == null ? void 0 : dataURIData[1]) != null ? _ref : 'plain/text'; | ||
let data; | ||
if (dataURIData[2] != null) { | ||
const binary = atob(decodeURIComponent(dataURIData[3])); | ||
const bytes = new Uint8Array(binary.length); | ||
for (let i = 0; i < binary.length; i++) { | ||
bytes[i] = binary.charCodeAt(i); | ||
} | ||
data = [bytes]; | ||
} else { | ||
data = [decodeURIComponent(dataURIData[3])]; | ||
} // Convert to a File? | ||
} | ||
// Convert to a File? | ||
if (toFile) { | ||
@@ -30,3 +27,2 @@ return new File(data, opts.name || '', { | ||
} | ||
return new Blob(data, { | ||
@@ -33,0 +29,0 @@ type: mimeType |
import { createAbortError } from './AbortController.js'; | ||
/** | ||
@@ -9,34 +10,24 @@ * Return a Promise that resolves after `ms` milliseconds. | ||
*/ | ||
export default function delay(ms, opts) { | ||
return new Promise((resolve, reject) => { | ||
var _opts$signal, _opts$signal2; | ||
if (opts != null && (_opts$signal = opts.signal) != null && _opts$signal.aborted) { | ||
return reject(createAbortError()); | ||
} | ||
const timeout = setTimeout(() => { | ||
cleanup(); // eslint-disable-line no-use-before-define | ||
resolve(); | ||
}, ms); | ||
function onabort() { | ||
clearTimeout(timeout); | ||
cleanup(); // eslint-disable-line no-use-before-define | ||
reject(createAbortError()); | ||
} | ||
opts == null ? void 0 : (_opts$signal2 = opts.signal) == null ? void 0 : _opts$signal2.addEventListener('abort', onabort); | ||
function cleanup() { | ||
var _opts$signal3; | ||
opts == null ? void 0 : (_opts$signal3 = opts.signal) == null ? void 0 : _opts$signal3.removeEventListener('abort', onabort); | ||
} | ||
return undefined; | ||
}); | ||
} |
@@ -1,3 +0,2 @@ | ||
import throttle from 'lodash.throttle'; | ||
import throttle from 'lodash/throttle.js'; | ||
function emitSocketProgress(uploader, progressData, file) { | ||
@@ -9,3 +8,2 @@ const { | ||
} = progressData; | ||
if (progress) { | ||
@@ -20,3 +18,2 @@ uploader.uppy.log(`Upload progress: ${progress}`); | ||
} | ||
export default throttle(emitSocketProgress, 300, { | ||
@@ -23,0 +20,0 @@ leading: true, |
import hasProperty from './hasProperty.js'; | ||
class ErrorWithCause extends Error { | ||
@@ -8,6 +7,4 @@ constructor(message, options) { | ||
} | ||
super(message); | ||
this.cause = options.cause; | ||
if (this.cause && hasProperty(this.cause, 'isNetworkError')) { | ||
@@ -17,5 +14,3 @@ this.isNetworkError = this.cause.isNetworkError; | ||
} | ||
} | ||
export default ErrorWithCause; |
import NetworkError from './NetworkError.js'; | ||
/** | ||
* Wrapper around window.fetch that throws a NetworkError when appropriate | ||
*/ | ||
export default function fetchWithNetworkError() { | ||
@@ -7,0 +7,0 @@ return fetch(...arguments).catch(err => { |
export function filterNonFailedFiles(files) { | ||
const hasError = file => 'error' in file && file.error; | ||
return files.filter(file => !hasError(file)); | ||
} // Don't double-emit upload-started for Golden Retriever-restored files that were already started | ||
} | ||
// Don't double-emit upload-started for Golden Retriever-restored files that were already started | ||
export function filterFilesToEmitUploadStarted(files) { | ||
return files.filter(file => !file.progress.uploadStarted || !file.isRestored); | ||
} |
import isDOMElement from './isDOMElement.js'; | ||
/** | ||
@@ -8,3 +9,2 @@ * Find one or more DOM elements. | ||
*/ | ||
export default function findAllDOMElements(element) { | ||
@@ -15,8 +15,6 @@ if (typeof element === 'string') { | ||
} | ||
if (typeof element === 'object' && isDOMElement(element)) { | ||
return [element]; | ||
} | ||
return null; | ||
} |
import isDOMElement from './isDOMElement.js'; | ||
/** | ||
@@ -8,3 +9,2 @@ * Find a DOM element. | ||
*/ | ||
export default function findDOMElement(element, context) { | ||
@@ -14,12 +14,9 @@ if (context === void 0) { | ||
} | ||
if (typeof element === 'string') { | ||
return context.querySelector(element); | ||
} | ||
if (isDOMElement(element)) { | ||
return element; | ||
} | ||
return null; | ||
} |
import getFileType from './getFileType.js'; | ||
function encodeCharacter(character) { | ||
return character.charCodeAt(0).toString(32); | ||
} | ||
function encodeFilename(name) { | ||
@@ -14,2 +12,3 @@ let suffix = ''; | ||
} | ||
/** | ||
@@ -22,46 +21,40 @@ * Takes a file object and turns it into fileID, by converting file.name to lowercase, | ||
*/ | ||
export default function generateFileID(file) { | ||
// It's tempting to do `[items].filter(Boolean).join('-')` here, but that | ||
// is slower! simple string concatenation is fast | ||
let id = 'uppy'; | ||
if (typeof file.name === 'string') { | ||
id += `-${encodeFilename(file.name.toLowerCase())}`; | ||
} | ||
if (file.type !== undefined) { | ||
id += `-${file.type}`; | ||
} | ||
if (file.meta && typeof file.meta.relativePath === 'string') { | ||
id += `-${encodeFilename(file.meta.relativePath.toLowerCase())}`; | ||
} | ||
if (file.data.size !== undefined) { | ||
id += `-${file.data.size}`; | ||
} | ||
if (file.data.lastModified !== undefined) { | ||
id += `-${file.data.lastModified}`; | ||
} | ||
return id; | ||
} | ||
return id; | ||
} // If the provider has a stable, unique ID, then we can use that to identify the file. | ||
// If the provider has a stable, unique ID, then we can use that to identify the file. | ||
// Then we don't have to generate our own ID, and we can add the same file many times if needed (different path) | ||
function hasFileStableId(file) { | ||
if (!file.isRemote || !file.remote) return false; // These are the providers that it seems like have stable IDs for their files. The other's I haven't checked yet. | ||
if (!file.isRemote || !file.remote) return false; | ||
// These are the providers that it seems like have stable IDs for their files. The other's I haven't checked yet. | ||
const stableIdProviders = new Set(['box', 'dropbox', 'drive', 'facebook', 'unsplash']); | ||
return stableIdProviders.has(file.remote.provider); | ||
} | ||
export function getSafeFileId(file) { | ||
if (hasFileStableId(file)) return file.id; | ||
const fileType = getFileType(file); | ||
return generateFileID({ ...file, | ||
return generateFileID({ | ||
...file, | ||
type: fileType | ||
}); | ||
} |
import webkitGetAsEntryApi from './utils/webkitGetAsEntryApi/index.js'; | ||
import fallbackApi from './utils/fallbackApi.js'; | ||
/** | ||
@@ -17,3 +18,2 @@ * Returns a promise that resolves to the array of dropped files (if a folder is | ||
*/ | ||
export default async function getDroppedFiles(dataTransfer, _temp) { | ||
@@ -23,12 +23,10 @@ let { | ||
} = _temp === void 0 ? {} : _temp; | ||
// Get all files from all subdirs. Works (at least) in Chrome, Mozilla, and Safari | ||
try { | ||
const accumulator = []; | ||
for await (const file of webkitGetAsEntryApi(dataTransfer, logDropError)) { | ||
accumulator.push(file); | ||
} | ||
return accumulator; // Otherwise just return all first-order files | ||
return accumulator; | ||
// Otherwise just return all first-order files | ||
} catch { | ||
@@ -35,0 +33,0 @@ return fallbackApi(dataTransfer); |
@@ -1,3 +0,4 @@ | ||
import toArray from '../../toArray.js'; // .files fallback, should be implemented in any browser | ||
import toArray from '../../toArray.js'; | ||
// .files fallback, should be implemented in any browser | ||
export default function fallbackApi(dataTransfer) { | ||
@@ -4,0 +5,0 @@ const files = toArray(dataTransfer.files); |
@@ -14,5 +14,5 @@ /** | ||
directoryReader.readEntries(entries => { | ||
const newEntries = [...oldEntries, ...entries]; // According to the FileSystem API spec, getFilesAndDirectoriesFromDirectory() | ||
const newEntries = [...oldEntries, ...entries]; | ||
// According to the FileSystem API spec, getFilesAndDirectoriesFromDirectory() | ||
// must be called until it calls the onSuccess with an empty array. | ||
if (entries.length) { | ||
@@ -23,7 +23,9 @@ queueMicrotask(() => { | ||
}); | ||
}); // Done iterating this particular directory | ||
}); | ||
// Done iterating this particular directory | ||
} else { | ||
onSuccess(newEntries); | ||
} | ||
}, // Make sure we resolve on error anyway, it's fine if only one directory couldn't be parsed! | ||
}, | ||
// Make sure we resolve on error anyway, it's fine if only one directory couldn't be parsed! | ||
error => { | ||
@@ -30,0 +32,0 @@ logDropError(error); |
import getFilesAndDirectoriesFromDirectory from './getFilesAndDirectoriesFromDirectory.js'; | ||
/** | ||
@@ -6,3 +7,2 @@ * Polyfill for the new (experimental) getAsFileSystemHandle API (using the popular webkitGetAsEntry behind the scenes) | ||
*/ | ||
function getAsFileSystemHandleFromEntry(entry, logDropError) { | ||
@@ -14,7 +14,5 @@ if (entry == null) return entry; | ||
name: entry.name, | ||
getFile() { | ||
return new Promise((resolve, reject) => entry.file(resolve, reject)); | ||
}, | ||
async *values() { | ||
@@ -30,26 +28,29 @@ // If the file is a directory. | ||
} | ||
}; | ||
} | ||
async function* createPromiseToAddFileOrParseDirectory(entry, relativePath, lastResortFile) { | ||
if (lastResortFile === void 0) { | ||
lastResortFile = undefined; | ||
function createPromiseToAddFileOrParseDirectory(entry, relativePath, lastResortFile) { | ||
try { | ||
if (lastResortFile === void 0) { | ||
lastResortFile = undefined; | ||
} | ||
return async function* () { | ||
// For each dropped item, - make sure it's a file/directory, and start deepening in! | ||
if (entry.kind === 'file') { | ||
const file = await entry.getFile(); | ||
if (file != null) { | ||
file.relativePath = relativePath ? `${relativePath}/${entry.name}` : null; | ||
yield file; | ||
} else if (lastResortFile != null) yield lastResortFile; | ||
} else if (entry.kind === 'directory') { | ||
for await (const handle of entry.values()) { | ||
// Recurse on the directory, appending the dir name to the relative path | ||
yield* createPromiseToAddFileOrParseDirectory(handle, `${relativePath}/${entry.name}`); | ||
} | ||
} else if (lastResortFile != null) yield lastResortFile; | ||
}(); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
// For each dropped item, - make sure it's a file/directory, and start deepening in! | ||
if (entry.kind === 'file') { | ||
const file = await entry.getFile(); | ||
if (file != null) { | ||
file.relativePath = relativePath ? `${relativePath}/${entry.name}` : null; | ||
yield file; | ||
} else if (lastResortFile != null) yield lastResortFile; | ||
} else if (entry.kind === 'directory') { | ||
for await (const handle of entry.values()) { | ||
// Recurse on the directory, appending the dir name to the relative path | ||
yield* createPromiseToAddFileOrParseDirectory(handle, `${relativePath}/${entry.name}`); | ||
} | ||
} else if (lastResortFile != null) yield lastResortFile; | ||
} | ||
/** | ||
@@ -62,4 +63,2 @@ * Load all files from data transfer, and recursively read any directories. | ||
*/ | ||
export default async function* getFilesFromDataTransfer(dataTransfer, logDropError) { | ||
@@ -71,14 +70,14 @@ // Retrieving the dropped items must happen synchronously | ||
var _fileSystemHandle; | ||
let fileSystemHandle; | ||
let fileSystemHandle; // TODO enable getAsFileSystemHandle API once we can get it working with subdirectories | ||
// TODO enable getAsFileSystemHandle API once we can get it working with subdirectories | ||
// IMPORTANT: Need to check isSecureContext *before* calling getAsFileSystemHandle | ||
// or else Chrome will crash when running in HTTP: https://github.com/transloadit/uppy/issues/4133 | ||
// if (window.isSecureContext && item.getAsFileSystemHandle != null) entry = await item.getAsFileSystemHandle() | ||
// `webkitGetAsEntry` exists in all popular browsers (including non-WebKit browsers), | ||
// however it may be renamed to getAsEntry() in the future, so you should code defensively, looking for both. | ||
// from https://developer.mozilla.org/en-US/docs/Web/API/DataTransferItem/webkitGetAsEntry | ||
const getAsEntry = () => typeof item.getAsEntry === 'function' ? item.getAsEntry() : item.webkitGetAsEntry(); // eslint-disable-next-line prefer-const | ||
const getAsEntry = () => typeof item.getAsEntry === 'function' ? item.getAsEntry() : item.webkitGetAsEntry(); | ||
// eslint-disable-next-line prefer-const | ||
(_fileSystemHandle = fileSystemHandle) != null ? _fileSystemHandle : fileSystemHandle = getAsFileSystemHandleFromEntry(getAsEntry(), logDropError); | ||
@@ -88,3 +87,2 @@ return { | ||
lastResortFile: item.getAsFile() // can be used as a fallback in case other methods fail | ||
}; | ||
@@ -91,0 +89,0 @@ })); |
@@ -8,4 +8,4 @@ /** | ||
export default function getFileNameAndExtension(fullFileName) { | ||
const lastDot = fullFileName.lastIndexOf('.'); // these count as no extension: "no-dot", "trailing-dot." | ||
const lastDot = fullFileName.lastIndexOf('.'); | ||
// these count as no extension: "no-dot", "trailing-dot." | ||
if (lastDot === -1 || lastDot === fullFileName.length - 1) { | ||
@@ -17,3 +17,2 @@ return { | ||
} | ||
return { | ||
@@ -20,0 +19,0 @@ name: fullFileName.slice(0, lastDot), |
@@ -5,13 +5,10 @@ import getFileNameAndExtension from './getFileNameAndExtension.js'; | ||
var _getFileNameAndExtens; | ||
if (file.type) return file.type; | ||
const fileExtension = file.name ? (_getFileNameAndExtens = getFileNameAndExtension(file.name).extension) == null ? void 0 : _getFileNameAndExtens.toLowerCase() : null; | ||
if (fileExtension && fileExtension in mimeTypes) { | ||
// else, see if we can map extension to a mime type | ||
return mimeTypes[fileExtension]; | ||
} // if all fails, fall back to a generic byte stream type | ||
} | ||
// if all fails, fall back to a generic byte stream type | ||
return 'application/octet-stream'; | ||
} |
@@ -7,5 +7,5 @@ /** | ||
*/ | ||
function getTextDirection(element) { | ||
var _element; | ||
// There is another way to determine text direction using getComputedStyle(), as done here: | ||
@@ -21,6 +21,4 @@ // https://github.com/pencil-js/text-direction/blob/2a235ce95089b3185acec3b51313cbba921b3811/text-direction.js | ||
} | ||
return (_element = element) == null ? void 0 : _element.dir; | ||
} | ||
export default getTextDirection; |
@@ -10,7 +10,6 @@ /** | ||
} | ||
/** | ||
* Returns a timestamp in the format of `hours:minutes:seconds` | ||
*/ | ||
export default function getTimeStamp() { | ||
@@ -17,0 +16,0 @@ const date = new Date(); |
@@ -8,16 +8,12 @@ /** | ||
const div = document.body; | ||
if (!('draggable' in div) || !('ondragstart' in div && 'ondrop' in div)) { | ||
return false; | ||
} | ||
if (!('FormData' in window)) { | ||
return false; | ||
} | ||
if (!('FileReader' in window)) { | ||
return false; | ||
} | ||
return true; | ||
} |
@@ -11,4 +11,3 @@ /** | ||
} | ||
return false; | ||
} |
@@ -5,6 +5,4 @@ function isNetworkError(xhr) { | ||
} | ||
return xhr.readyState !== 0 && xhr.readyState !== 4 || xhr.status === 0; | ||
} | ||
export default isNetworkError; |
export default function isPreviewSupported(fileType) { | ||
if (!fileType) return false; // list of images that browsers can preview | ||
if (!fileType) return false; | ||
// list of images that browsers can preview | ||
return /^[^/]+\/(jpe?g|gif|png|svg|svg\+xml|bmp|webp|avif)$/.test(fileType); | ||
} |
@@ -5,2 +5,3 @@ // ___Why not add the mime-types package? | ||
// https://github.com/jshttp/mime-db/blob/master/db.json | ||
export default { | ||
@@ -7,0 +8,0 @@ md: 'text/markdown', |
@@ -6,3 +6,2 @@ class NetworkError extends Error { | ||
} | ||
super(`This looks like a network error, the endpoint might be blocked by an internet provider or a firewall.`); | ||
@@ -13,5 +12,3 @@ this.cause = error; | ||
} | ||
} | ||
export default NetworkError; |
import secondsToTime from './secondsToTime.js'; | ||
export default function prettyETA(seconds) { | ||
const time = secondsToTime(seconds); // Only display hours and minutes if they are greater than 0 but always | ||
const time = secondsToTime(seconds); | ||
// Only display hours and minutes if they are greater than 0 but always | ||
// display minutes if hours is being displayed | ||
// Display a leading zero if the there is a preceding unit: 1m 05s, but 5s | ||
const hoursStr = time.hours === 0 ? '' : `${time.hours}h`; | ||
@@ -8,0 +9,0 @@ const minutesStr = time.minutes === 0 ? '' : `${time.hours === 0 ? time.minutes : ` ${time.minutes.toString(10).padStart(2, '0')}`}m`; |
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; } | ||
var _aliveTimer = /*#__PURE__*/_classPrivateFieldLooseKey("aliveTimer"); | ||
var _isDone = /*#__PURE__*/_classPrivateFieldLooseKey("isDone"); | ||
var _onTimedOut = /*#__PURE__*/_classPrivateFieldLooseKey("onTimedOut"); | ||
var _timeout = /*#__PURE__*/_classPrivateFieldLooseKey("timeout"); | ||
/** | ||
@@ -42,3 +35,2 @@ * Helper to abort upload requests if there has not been any progress for `timeout` ms. | ||
} | ||
progress() { | ||
@@ -49,3 +41,2 @@ // Some browsers fire another progress event when the upload is | ||
if (_classPrivateFieldLooseBase(this, _isDone)[_isDone]) return; | ||
if (_classPrivateFieldLooseBase(this, _timeout)[_timeout] > 0) { | ||
@@ -56,3 +47,2 @@ clearTimeout(_classPrivateFieldLooseBase(this, _aliveTimer)[_aliveTimer]); | ||
} | ||
done() { | ||
@@ -65,5 +55,3 @@ if (!_classPrivateFieldLooseBase(this, _isDone)[_isDone]) { | ||
} | ||
} | ||
export default ProgressTimeout; |
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; } | ||
function createCancelError(cause) { | ||
@@ -12,49 +9,30 @@ return new Error('Cancelled', { | ||
} | ||
function abortOn(signal) { | ||
if (signal != null) { | ||
var _this$then; | ||
const abortPromise = () => this.abort(signal.reason); | ||
signal.addEventListener('abort', abortPromise, { | ||
once: true | ||
}); | ||
const removeAbortListener = () => { | ||
signal.removeEventListener('abort', abortPromise); | ||
}; | ||
this.then(removeAbortListener, removeAbortListener); | ||
(_this$then = this.then) == null ? void 0 : _this$then.call(this, removeAbortListener, removeAbortListener); | ||
} | ||
return this; | ||
} | ||
var _activeRequests = /*#__PURE__*/_classPrivateFieldLooseKey("activeRequests"); | ||
var _queuedHandlers = /*#__PURE__*/_classPrivateFieldLooseKey("queuedHandlers"); | ||
var _paused = /*#__PURE__*/_classPrivateFieldLooseKey("paused"); | ||
var _pauseTimer = /*#__PURE__*/_classPrivateFieldLooseKey("pauseTimer"); | ||
var _downLimit = /*#__PURE__*/_classPrivateFieldLooseKey("downLimit"); | ||
var _upperLimit = /*#__PURE__*/_classPrivateFieldLooseKey("upperLimit"); | ||
var _rateLimitingTimer = /*#__PURE__*/_classPrivateFieldLooseKey("rateLimitingTimer"); | ||
var _call = /*#__PURE__*/_classPrivateFieldLooseKey("call"); | ||
var _queueNext = /*#__PURE__*/_classPrivateFieldLooseKey("queueNext"); | ||
var _next = /*#__PURE__*/_classPrivateFieldLooseKey("next"); | ||
var _queue = /*#__PURE__*/_classPrivateFieldLooseKey("queue"); | ||
var _dequeue = /*#__PURE__*/_classPrivateFieldLooseKey("dequeue"); | ||
var _resume = /*#__PURE__*/_classPrivateFieldLooseKey("resume"); | ||
var _increaseLimit = /*#__PURE__*/_classPrivateFieldLooseKey("increaseLimit"); | ||
export class RateLimitedQueue { | ||
@@ -116,10 +94,7 @@ constructor(limit) { | ||
} | ||
_classPrivateFieldLooseBase(this, _downLimit)[_downLimit] = this.limit; | ||
this.limit = Math.ceil((_classPrivateFieldLooseBase(this, _upperLimit)[_upperLimit] + _classPrivateFieldLooseBase(this, _downLimit)[_downLimit]) / 2); | ||
for (let i = _classPrivateFieldLooseBase(this, _downLimit)[_downLimit]; i <= this.limit; i++) { | ||
_classPrivateFieldLooseBase(this, _queueNext)[_queueNext](); | ||
} | ||
if (_classPrivateFieldLooseBase(this, _upperLimit)[_upperLimit] - _classPrivateFieldLooseBase(this, _downLimit)[_downLimit] > 3) { | ||
@@ -132,3 +107,2 @@ _classPrivateFieldLooseBase(this, _rateLimitingTimer)[_rateLimitingTimer] = setTimeout(_classPrivateFieldLooseBase(this, _increaseLimit)[_increaseLimit], 2000); | ||
}); | ||
if (typeof limit !== 'number' || limit === 0) { | ||
@@ -140,3 +114,2 @@ this.limit = Infinity; | ||
} | ||
run(fn, queueOptions) { | ||
@@ -146,9 +119,6 @@ if (!_classPrivateFieldLooseBase(this, _paused)[_paused] && _classPrivateFieldLooseBase(this, _activeRequests)[_activeRequests] < this.limit) { | ||
} | ||
return _classPrivateFieldLooseBase(this, _queue)[_queue](fn, queueOptions); | ||
} | ||
wrapPromiseFunction(fn, queueOptions) { | ||
wrapSyncFunction(fn, queueOptions) { | ||
var _this = this; | ||
return function () { | ||
@@ -158,9 +128,26 @@ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { | ||
} | ||
const queuedRequest = _this.run(() => { | ||
fn(...args); | ||
queueMicrotask(() => queuedRequest.done()); | ||
return () => {}; | ||
}, queueOptions); | ||
return { | ||
abortOn, | ||
abort() { | ||
queuedRequest.abort(); | ||
} | ||
}; | ||
}; | ||
} | ||
wrapPromiseFunction(fn, queueOptions) { | ||
var _this2 = this; | ||
return function () { | ||
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { | ||
args[_key2] = arguments[_key2]; | ||
} | ||
let queuedRequest; | ||
const outerPromise = new Promise((resolve, reject) => { | ||
queuedRequest = _this.run(() => { | ||
queuedRequest = _this2.run(() => { | ||
let cancelError; | ||
let innerPromise; | ||
try { | ||
@@ -171,3 +158,2 @@ innerPromise = Promise.resolve(fn(...args)); | ||
} | ||
innerPromise.then(result => { | ||
@@ -193,7 +179,5 @@ if (cancelError) { | ||
}); | ||
outerPromise.abort = cause => { | ||
queuedRequest.abort(cause); | ||
}; | ||
outerPromise.abortOn = abortOn; | ||
@@ -203,7 +187,5 @@ return outerPromise; | ||
} | ||
resume() { | ||
_classPrivateFieldLooseBase(this, _paused)[_paused] = false; | ||
clearTimeout(_classPrivateFieldLooseBase(this, _pauseTimer)[_pauseTimer]); | ||
for (let i = 0; i < this.limit; i++) { | ||
@@ -213,3 +195,2 @@ _classPrivateFieldLooseBase(this, _queueNext)[_queueNext](); | ||
} | ||
/** | ||
@@ -225,6 +206,4 @@ * Freezes the queue for a while or indefinitely. | ||
} | ||
_classPrivateFieldLooseBase(this, _paused)[_paused] = true; | ||
clearTimeout(_classPrivateFieldLooseBase(this, _pauseTimer)[_pauseTimer]); | ||
if (duration != null) { | ||
@@ -234,2 +213,3 @@ _classPrivateFieldLooseBase(this, _pauseTimer)[_pauseTimer] = setTimeout(_classPrivateFieldLooseBase(this, _resume)[_resume], duration); | ||
} | ||
/** | ||
@@ -245,8 +225,5 @@ * Pauses the queue for a duration, and lower the limit of concurrent requests | ||
*/ | ||
rateLimit(duration) { | ||
clearTimeout(_classPrivateFieldLooseBase(this, _rateLimitingTimer)[_rateLimitingTimer]); | ||
this.pause(duration); | ||
if (this.limit > 1 && Number.isFinite(this.limit)) { | ||
@@ -258,9 +235,6 @@ _classPrivateFieldLooseBase(this, _upperLimit)[_upperLimit] = this.limit - 1; | ||
} | ||
get isPaused() { | ||
return _classPrivateFieldLooseBase(this, _paused)[_paused]; | ||
} | ||
} | ||
function _call2(fn) { | ||
@@ -270,3 +244,2 @@ _classPrivateFieldLooseBase(this, _activeRequests)[_activeRequests] += 1; | ||
let cancelActive; | ||
try { | ||
@@ -278,3 +251,2 @@ cancelActive = fn(); | ||
} | ||
return { | ||
@@ -286,3 +258,2 @@ abort: cause => { | ||
cancelActive(cause); | ||
_classPrivateFieldLooseBase(this, _queueNext)[_queueNext](); | ||
@@ -294,3 +265,2 @@ }, | ||
_classPrivateFieldLooseBase(this, _activeRequests)[_activeRequests] -= 1; | ||
_classPrivateFieldLooseBase(this, _queueNext)[_queueNext](); | ||
@@ -300,3 +270,2 @@ } | ||
} | ||
function _queueNext2() { | ||
@@ -308,3 +277,2 @@ // Do it soon but not immediately, this allows clearing out the entire queue synchronously | ||
} | ||
function _next2() { | ||
@@ -314,18 +282,14 @@ if (_classPrivateFieldLooseBase(this, _paused)[_paused] || _classPrivateFieldLooseBase(this, _activeRequests)[_activeRequests] >= this.limit) { | ||
} | ||
if (_classPrivateFieldLooseBase(this, _queuedHandlers)[_queuedHandlers].length === 0) { | ||
return; | ||
} // Dispatch the next request, and update the abort/done handlers | ||
} | ||
// Dispatch the next request, and update the abort/done handlers | ||
// so that cancelling it does the Right Thing (and doesn't just try | ||
// to dequeue an already-running request). | ||
const next = _classPrivateFieldLooseBase(this, _queuedHandlers)[_queuedHandlers].shift(); | ||
const handler = _classPrivateFieldLooseBase(this, _call)[_call](next.fn); | ||
next.abort = handler.abort; | ||
next.done = handler.done; | ||
} | ||
function _queue2(fn, options) { | ||
@@ -335,3 +299,2 @@ if (options === void 0) { | ||
} | ||
const handler = { | ||
@@ -347,7 +310,5 @@ fn, | ||
}; | ||
const index = _classPrivateFieldLooseBase(this, _queuedHandlers)[_queuedHandlers].findIndex(other => { | ||
return handler.priority > other.priority; | ||
}); | ||
if (index === -1) { | ||
@@ -358,9 +319,6 @@ _classPrivateFieldLooseBase(this, _queuedHandlers)[_queuedHandlers].push(handler); | ||
} | ||
return handler; | ||
} | ||
function _dequeue2(handler) { | ||
const index = _classPrivateFieldLooseBase(this, _queuedHandlers)[_queuedHandlers].indexOf(handler); | ||
if (index !== -1) { | ||
@@ -370,3 +328,2 @@ _classPrivateFieldLooseBase(this, _queuedHandlers)[_queuedHandlers].splice(index, 1); | ||
} | ||
export const internalRateLimitedQueue = Symbol('__queue'); |
import getFileNameAndExtension from './getFileNameAndExtension.js'; | ||
export default function remoteFileObjToLocal(file) { | ||
return { ...file, | ||
return { | ||
...file, | ||
type: file.mimeType, | ||
@@ -5,0 +6,0 @@ extension: file.name ? getFileNameAndExtension(file.name).extension : null |
@@ -5,11 +5,8 @@ // TODO remove (no longer in use) | ||
const rejections = []; | ||
function resolved(value) { | ||
resolutions.push(value); | ||
} | ||
function rejected(error) { | ||
rejections.push(error); | ||
} | ||
const wait = Promise.all(promises.map(promise => promise.then(resolved, rejected))); | ||
@@ -16,0 +13,0 @@ return wait.then(() => { |
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; } | ||
import has from './hasProperty.js'; | ||
function insertReplacement(source, rx, replacement) { | ||
@@ -19,9 +15,8 @@ const newParts = []; | ||
} | ||
return rx[Symbol.split](chunk).forEach((raw, i, list) => { | ||
if (raw !== '') { | ||
newParts.push(raw); | ||
} // Interlace with the `replacement` value | ||
} | ||
// Interlace with the `replacement` value | ||
if (i < list.length - 1) { | ||
@@ -34,2 +29,3 @@ newParts.push(replacement); | ||
} | ||
/** | ||
@@ -46,4 +42,2 @@ * Takes a string with placeholder variables like `%{smart_count} file selected` | ||
*/ | ||
function interpolate(phrase, options) { | ||
@@ -54,3 +48,2 @@ const dollarRegex = /\$/g; | ||
if (options == null) return interpolated; | ||
for (const arg of Object.keys(options)) { | ||
@@ -62,16 +55,14 @@ if (arg !== '_') { | ||
let replacement = options[arg]; | ||
if (typeof replacement === 'string') { | ||
replacement = dollarRegex[Symbol.replace](replacement, dollarBillsYall); | ||
} // We create a new `RegExp` each time instead of using a more-efficient | ||
} | ||
// We create a new `RegExp` each time instead of using a more-efficient | ||
// string replace so that the same argument can be replaced multiple times | ||
// in the same phrase. | ||
interpolated = insertReplacement(interpolated, new RegExp(`%\\{${arg}\\}`, 'g'), replacement); | ||
} | ||
} | ||
return interpolated; | ||
} | ||
/** | ||
@@ -88,6 +79,3 @@ * Translates strings with interpolation & pluralization support. | ||
*/ | ||
var _apply = /*#__PURE__*/_classPrivateFieldLooseKey("apply"); | ||
export default class Translator { | ||
@@ -103,3 +91,2 @@ /** | ||
strings: {}, | ||
pluralize(n) { | ||
@@ -109,8 +96,5 @@ if (n === 1) { | ||
} | ||
return 1; | ||
} | ||
}; | ||
if (Array.isArray(locales)) { | ||
@@ -122,3 +106,2 @@ locales.forEach(_classPrivateFieldLooseBase(this, _apply)[_apply], this); | ||
} | ||
/** | ||
@@ -134,2 +117,3 @@ * Public translate method | ||
} | ||
/** | ||
@@ -142,4 +126,2 @@ * Get a translation and return the translated and interpolated parts as an array. | ||
*/ | ||
translateArray(key, options) { | ||
@@ -149,6 +131,4 @@ if (!has(this.locale.strings, key)) { | ||
} | ||
const string = this.locale.strings[key]; | ||
const hasPluralForms = typeof string === 'object'; | ||
if (hasPluralForms) { | ||
@@ -159,11 +139,7 @@ if (options && typeof options.smart_count !== 'undefined') { | ||
} | ||
throw new Error('Attempted to use a string with plural forms, but no value was given for %{smart_count}'); | ||
} | ||
return interpolate(string, options); | ||
} | ||
} | ||
function _apply2(locale) { | ||
@@ -173,6 +149,7 @@ if (!(locale != null && locale.strings)) { | ||
} | ||
const prevLocale = this.locale; | ||
this.locale = { ...prevLocale, | ||
strings: { ...prevLocale.strings, | ||
this.locale = { | ||
...prevLocale, | ||
strings: { | ||
...prevLocale.strings, | ||
...locale.strings | ||
@@ -179,0 +156,0 @@ } |
@@ -12,6 +12,6 @@ /** | ||
// Return the empty string if maxLength is zero | ||
if (maxLength === 0) return ''; // Return original string if it's already shorter than maxLength | ||
if (string.length <= maxLength) return string; // Return truncated substring appended of the ellipsis char if string can't be meaningfully truncated | ||
if (maxLength === 0) return ''; | ||
// Return original string if it's already shorter than maxLength | ||
if (string.length <= maxLength) return string; | ||
// Return truncated substring appended of the ellipsis char if string can't be meaningfully truncated | ||
if (maxLength <= separator.length + 1) return `${string.slice(0, maxLength - 1)}…`; | ||
@@ -18,0 +18,0 @@ const charsToShow = maxLength - separator.length; |
{ | ||
"name": "@uppy/utils", | ||
"description": "Shared utility functions for Uppy Core and plugins maintained by the Uppy team.", | ||
"version": "5.3.0", | ||
"version": "5.4.0", | ||
"license": "MIT", | ||
@@ -23,3 +23,4 @@ "types": "types/index.d.ts", | ||
"./lib/Translator": "./lib/Translator.js", | ||
"./lib/EventTracker": "./lib/EventTracker.js", | ||
"./lib/EventTracker": "./lib/EventManager.js", | ||
"./lib/EventManager": "./lib/EventManager.js", | ||
"./lib/ProgressTimeout": "./lib/ProgressTimeout.js", | ||
@@ -30,2 +31,3 @@ "./lib/RateLimitedQueue": "./lib/RateLimitedQueue.js", | ||
"./lib/dataURItoFile": "./lib/dataURItoFile.js", | ||
"./lib/emaFilter": "./lib/emaFilter.js", | ||
"./lib/emitSocketProgress": "./lib/emitSocketProgress.js", | ||
@@ -70,3 +72,3 @@ "./lib/findAllDOMElements": "./lib/findAllDOMElements.js", | ||
"dependencies": { | ||
"lodash.throttle": "^4.1.1" | ||
"lodash": "^4.17.21" | ||
}, | ||
@@ -73,0 +75,0 @@ "devDependencies": { |
@@ -1,2 +0,2 @@ | ||
import throttle from 'lodash.throttle' | ||
import throttle from 'lodash/throttle.js' | ||
@@ -3,0 +3,0 @@ function emitSocketProgress (uploader, progressData, file) { |
@@ -10,3 +10,3 @@ function createCancelError (cause) { | ||
const removeAbortListener = () => { signal.removeEventListener('abort', abortPromise) } | ||
this.then(removeAbortListener, removeAbortListener) | ||
this.then?.(removeAbortListener, removeAbortListener) | ||
} | ||
@@ -132,2 +132,19 @@ | ||
wrapSyncFunction (fn, queueOptions) { | ||
return (...args) => { | ||
const queuedRequest = this.run(() => { | ||
fn(...args) | ||
queueMicrotask(() => queuedRequest.done()) | ||
return () => {} | ||
}, queueOptions) | ||
return { | ||
abortOn, | ||
abort () { | ||
queuedRequest.abort() | ||
}, | ||
} | ||
} | ||
} | ||
wrapPromiseFunction (fn, queueOptions) { | ||
@@ -134,0 +151,0 @@ return (...args) => { |
@@ -22,4 +22,4 @@ declare module '@uppy/utils/lib/Translator' { | ||
declare module '@uppy/utils/lib/EventTracker' { | ||
namespace EventTracker { | ||
declare module '@uppy/utils/lib/EventManager' { | ||
namespace EventManager { | ||
export type EventHandler = (...args: any[]) => void | ||
@@ -32,6 +32,6 @@ export interface Emitter { | ||
class EventTracker { | ||
constructor (emitter: EventTracker.Emitter) | ||
class EventManager { | ||
constructor (emitter: EventManager.Emitter) | ||
on (event: string, handler: EventTracker.EventHandler): void | ||
on (event: string, handler: EventManager.EventHandler): void | ||
@@ -41,3 +41,3 @@ remove (): void | ||
export default EventTracker | ||
export default EventManager | ||
} | ||
@@ -44,0 +44,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
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
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
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
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
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
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
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
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
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
266272
185
3497
+ Addedlodash@^4.17.21
+ Addedlodash@4.17.21(transitive)
- Removedlodash.throttle@^4.1.1
- Removedlodash.throttle@4.1.1(transitive)