UNPKG

igir

Version:

🕹 A zero-setup ROM collection manager that sorts, filters, extracts or archives, patches, and reports on collections of any size on any OS.

374 lines (373 loc) • 12.8 kB
const RETRY_TIMEOUT_MS = 6e4; const RETRY_BACKOFF_MULTIPLIER = 1.2; const RETRY_MIN_BACKOFF_MS = 10; const RETRY_MAX_BACKOFF_MS = 100; const TRANSIENT_ERRNO_CODES = /* @__PURE__ */ new Set([ ...process.platform === "win32" ? ["EACCES", "EPERM"] : [], "EBUSY", "EAGAIN", "EMFILE", "ENFILE", // Everything below this did not exist in `graceful-fs` v4.2.11! "EWOULDBLOCK", "ETXTBSY" ]); class RetryQueue { entries = []; timer; /** * Adds a new entry to the queue and schedules processing if not already scheduled. */ enqueue(entry) { this.entries.push(entry); this.scheduleProcess(); } scheduleProcess() { if (this.timer !== void 0) return; const maxRetries = this.entries.reduce((max, e) => Math.max(max, e.retryCount), 0); const delay = Math.min( Math.max(maxRetries * RETRY_BACKOFF_MULTIPLIER, RETRY_MIN_BACKOFF_MS), RETRY_MAX_BACKOFF_MS ); this.timer = setTimeout(() => { this.timer = void 0; this.process(); }, delay); this.timer.unref(); } process() { const entry = this.entries.shift(); if (entry === void 0) return; entry.retryCount++; if (Date.now() - entry.startTime >= RETRY_TIMEOUT_MS) { entry.timeout(); } else { entry.retry(); } if (this.entries.length > 0) { this.scheduleProcess(); } } } const retryQueue = new RetryQueue(); function wrapCallbackMethod(originalFn, options) { return function(...methodArgs) { let attempts = 0; let backoff = 0; const startTime = Date.now(); const userCallback = methodArgs.pop(); const attempt = () => { Reflect.apply(originalFn, this, [ ...methodArgs, (err, ...resultData) => { attempts++; if (!err) { userCallback(err, ...resultData); return; } const didExceedMaxAttempts = Date.now() - startTime >= RETRY_TIMEOUT_MS || options?.maxAttempts !== void 0 && attempts >= options.maxAttempts; if (didExceedMaxAttempts || !TRANSIENT_ERRNO_CODES.has(err.code ?? "")) { userCallback(err, ...resultData); return; } if (options?.useQueue) { retryQueue.enqueue({ retry: attempt, timeout: () => { userCallback(err); }, startTime, retryCount: attempts }); } else if (options?.backoff) { backoff = Math.min( Math.max(backoff * RETRY_BACKOFF_MULTIPLIER, RETRY_MIN_BACKOFF_MS), RETRY_MAX_BACKOFF_MS ); setTimeout(attempt, backoff); } else { attempt(); } } ]); }; attempt(); }; } function wrapSyncMethod(originalFn, options) { return function(...args) { let attempts = 0; const startTime = Date.now(); for (; ; ) { try { return Reflect.apply(originalFn, this, args); } catch (error) { attempts++; const didExceedMaxAttempts = Date.now() - startTime >= RETRY_TIMEOUT_MS || options?.maxAttempts !== void 0 && attempts >= options.maxAttempts; if (didExceedMaxAttempts || !TRANSIENT_ERRNO_CODES.has(error.code ?? "")) { throw error; } } } }; } function wrapPromiseMethod(originalFn, options) { return async function(...args) { const startTime = Date.now(); return await new Promise((resolve, reject) => { let attempts = 0; let backoff = 0; const attempt = () => { let innerPromise; try { innerPromise = originalFn.apply(this, args); } catch (error) { reject(error instanceof Error ? error : new Error(String(error))); return; } innerPromise.then(resolve).catch((error) => { attempts++; const didExceedMaxAttempts = Date.now() - startTime >= RETRY_TIMEOUT_MS || options?.maxAttempts !== void 0 && attempts >= options.maxAttempts; if (didExceedMaxAttempts || !TRANSIENT_ERRNO_CODES.has(error.code ?? "")) { reject(error instanceof Error ? error : new Error(String(error))); return; } if (options?.useQueue) { retryQueue.enqueue({ retry: attempt, timeout: () => { reject(error instanceof Error ? error : new Error(String(error))); }, startTime, retryCount: attempts }); } else if (options?.backoff) { backoff = Math.min( Math.max(backoff * RETRY_BACKOFF_MULTIPLIER, RETRY_MIN_BACKOFF_MS), RETRY_MAX_BACKOFF_MS ); setTimeout(attempt, backoff); } else { attempt(); } }); }; attempt(); }); }; } var gracefulFs_default = { gracefulify: (fsToPatch) => { fsToPatch.readFile = wrapCallbackMethod(fsToPatch.readFile, { useQueue: true }); fsToPatch.readFileSync = wrapSyncMethod( fsToPatch.readFileSync ); fsToPatch.promises.readFile = wrapPromiseMethod(fsToPatch.promises.readFile, { useQueue: true }); fsToPatch.writeFile = wrapCallbackMethod(fsToPatch.writeFile, { useQueue: true }); fsToPatch.writeFileSync = wrapSyncMethod(fsToPatch.writeFileSync); fsToPatch.promises.writeFile = wrapPromiseMethod( fsToPatch.promises.writeFile, { useQueue: true } ); fsToPatch.appendFile = wrapCallbackMethod(fsToPatch.appendFile, { useQueue: true }); fsToPatch.appendFileSync = wrapSyncMethod(fsToPatch.appendFileSync); fsToPatch.promises.appendFile = wrapPromiseMethod( fsToPatch.promises.appendFile, { useQueue: true } ); fsToPatch.copyFile = wrapCallbackMethod(fsToPatch.copyFile, { useQueue: true }); fsToPatch.copyFileSync = wrapSyncMethod(fsToPatch.copyFileSync); fsToPatch.promises.copyFile = wrapPromiseMethod(fsToPatch.promises.copyFile, { useQueue: true }); fsToPatch.readdir = wrapCallbackMethod(fsToPatch.readdir, { useQueue: true }); fsToPatch.readdirSync = wrapSyncMethod( fsToPatch.readdirSync ); fsToPatch.promises.readdir = wrapPromiseMethod(fsToPatch.promises.readdir, { useQueue: true }); fsToPatch.open = wrapCallbackMethod(fsToPatch.open, { useQueue: true }); fsToPatch.openSync = wrapSyncMethod(fsToPatch.openSync); fsToPatch.promises.open = wrapPromiseMethod(fsToPatch.promises.open, { useQueue: true }); fsToPatch.chown = wrapCallbackMethod(fsToPatch.chown); fsToPatch.chownSync = wrapSyncMethod(fsToPatch.chownSync); fsToPatch.promises.chown = wrapPromiseMethod( fsToPatch.promises.chown ); fsToPatch.fchown = wrapCallbackMethod(fsToPatch.fchown); fsToPatch.fchownSync = wrapSyncMethod(fsToPatch.fchownSync); fsToPatch.lchown = wrapCallbackMethod(fsToPatch.lchown); fsToPatch.lchownSync = wrapSyncMethod(fsToPatch.lchownSync); fsToPatch.promises.lchown = wrapPromiseMethod( fsToPatch.promises.lchown ); fsToPatch.chmod = wrapCallbackMethod(fsToPatch.chmod); fsToPatch.chmodSync = wrapSyncMethod(fsToPatch.chmodSync); fsToPatch.promises.chmod = wrapPromiseMethod( fsToPatch.promises.chmod ); fsToPatch.fchmod = wrapCallbackMethod(fsToPatch.fchmod); fsToPatch.fchmodSync = wrapSyncMethod(fsToPatch.fchmodSync); fsToPatch.lchmod = wrapCallbackMethod(fsToPatch.lchmod); fsToPatch.lchmodSync = wrapSyncMethod(fsToPatch.lchmodSync); fsToPatch.promises.lchmod = wrapPromiseMethod( fsToPatch.promises.lchmod ); fsToPatch.stat = wrapCallbackMethod(fsToPatch.stat); fsToPatch.statSync = wrapSyncMethod(fsToPatch.statSync); fsToPatch.promises.stat = wrapPromiseMethod( fsToPatch.promises.stat ); fsToPatch.fstat = wrapCallbackMethod(fsToPatch.fstat); fsToPatch.fstatSync = wrapSyncMethod(fsToPatch.fstatSync); fsToPatch.lstat = wrapCallbackMethod(fsToPatch.lstat); fsToPatch.lstatSync = wrapSyncMethod(fsToPatch.lstatSync); fsToPatch.promises.lstat = wrapPromiseMethod( fsToPatch.promises.lstat ); fsToPatch.rename = wrapCallbackMethod(fsToPatch.rename, { backoff: true }); fsToPatch.promises.rename = wrapPromiseMethod(fsToPatch.promises.rename, { backoff: true }); fsToPatch.read = wrapCallbackMethod(fsToPatch.read, { maxAttempts: 10 }); fsToPatch.readSync = wrapSyncMethod(fsToPatch.readSync, { maxAttempts: 10 }); fsToPatch.write = wrapCallbackMethod(fsToPatch.write, { maxAttempts: 10 }); fsToPatch.writeSync = wrapSyncMethod(fsToPatch.writeSync, { maxAttempts: 10 }); fsToPatch.access = wrapCallbackMethod(fsToPatch.access); fsToPatch.accessSync = wrapSyncMethod(fsToPatch.accessSync); fsToPatch.promises.access = wrapPromiseMethod( fsToPatch.promises.access ); fsToPatch.fdatasync = wrapCallbackMethod(fsToPatch.fdatasync, { maxAttempts: 10 }); fsToPatch.fdatasyncSync = wrapSyncMethod(fsToPatch.fdatasyncSync, { maxAttempts: 10 }); fsToPatch.fsync = wrapCallbackMethod(fsToPatch.fsync, { maxAttempts: 10 }); fsToPatch.fsyncSync = wrapSyncMethod(fsToPatch.fsyncSync, { maxAttempts: 10 }); fsToPatch.ftruncate = wrapCallbackMethod(fsToPatch.ftruncate, { maxAttempts: 10 }); fsToPatch.ftruncateSync = wrapSyncMethod(fsToPatch.ftruncateSync, { maxAttempts: 10 }); fsToPatch.futimes = wrapCallbackMethod(fsToPatch.futimes, { maxAttempts: 10 }); fsToPatch.futimesSync = wrapSyncMethod(fsToPatch.futimesSync, { maxAttempts: 10 }); fsToPatch.link = wrapCallbackMethod(fsToPatch.link); fsToPatch.linkSync = wrapSyncMethod(fsToPatch.linkSync); fsToPatch.promises.link = wrapPromiseMethod( fsToPatch.promises.link ); fsToPatch.lutimes = wrapCallbackMethod(fsToPatch.lutimes); fsToPatch.lutimesSync = wrapSyncMethod(fsToPatch.lutimesSync); fsToPatch.promises.lutimes = wrapPromiseMethod( fsToPatch.promises.lutimes ); fsToPatch.mkdir = wrapCallbackMethod(fsToPatch.mkdir); fsToPatch.mkdirSync = wrapSyncMethod(fsToPatch.mkdirSync); fsToPatch.promises.mkdir = wrapPromiseMethod( fsToPatch.promises.mkdir ); fsToPatch.mkdtemp = wrapCallbackMethod(fsToPatch.mkdtemp); fsToPatch.mkdtempSync = wrapSyncMethod( fsToPatch.mkdtempSync ); fsToPatch.promises.mkdtemp = wrapPromiseMethod( fsToPatch.promises.mkdtemp ); fsToPatch.opendir = wrapCallbackMethod(fsToPatch.opendir, { useQueue: true }); fsToPatch.opendirSync = wrapSyncMethod( fsToPatch.opendirSync ); fsToPatch.promises.opendir = wrapPromiseMethod(fsToPatch.promises.opendir, { useQueue: true }); fsToPatch.readlink = wrapCallbackMethod(fsToPatch.readlink); fsToPatch.readlinkSync = wrapSyncMethod( fsToPatch.readlinkSync ); fsToPatch.promises.readlink = wrapPromiseMethod( fsToPatch.promises.readlink ); fsToPatch.realpath = wrapCallbackMethod(fsToPatch.realpath); fsToPatch.realpathSync = wrapSyncMethod( fsToPatch.realpathSync ); fsToPatch.promises.realpath = wrapPromiseMethod( fsToPatch.promises.realpath ); fsToPatch.rm = wrapCallbackMethod(fsToPatch.rm); fsToPatch.rmSync = wrapSyncMethod(fsToPatch.rmSync); fsToPatch.promises.rm = wrapPromiseMethod( fsToPatch.promises.rm ); fsToPatch.rmdir = wrapCallbackMethod(fsToPatch.rmdir); fsToPatch.rmdirSync = wrapSyncMethod(fsToPatch.rmdirSync); fsToPatch.promises.rmdir = wrapPromiseMethod( fsToPatch.promises.rmdir ); fsToPatch.symlink = wrapCallbackMethod(fsToPatch.symlink); fsToPatch.symlinkSync = wrapSyncMethod(fsToPatch.symlinkSync); fsToPatch.promises.symlink = wrapPromiseMethod( fsToPatch.promises.symlink ); fsToPatch.truncate = wrapCallbackMethod(fsToPatch.truncate); fsToPatch.truncateSync = wrapSyncMethod(fsToPatch.truncateSync); fsToPatch.promises.truncate = wrapPromiseMethod( fsToPatch.promises.truncate ); fsToPatch.unlink = wrapCallbackMethod(fsToPatch.unlink); fsToPatch.unlinkSync = wrapSyncMethod(fsToPatch.unlinkSync); fsToPatch.promises.unlink = wrapPromiseMethod( fsToPatch.promises.unlink ); fsToPatch.utimes = wrapCallbackMethod(fsToPatch.utimes); fsToPatch.utimesSync = wrapSyncMethod(fsToPatch.utimesSync); fsToPatch.promises.utimes = wrapPromiseMethod( fsToPatch.promises.utimes ); return fsToPatch; } }; export { gracefulFs_default as default }; //# sourceMappingURL=gracefulFs.js.map