mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-07-02 13:34:53 +02:00
Fix:Include Watcher as lib with no dependencies and fix tiny-readdir bug #610
This commit is contained in:
parent
160dac109d
commit
ec6e70725c
34 changed files with 2187 additions and 281 deletions
104
server/libs/watcher/tiny-readdir.js
Normal file
104
server/libs/watcher/tiny-readdir.js
Normal file
|
@ -0,0 +1,104 @@
|
|||
"use strict";
|
||||
/* IMPORT */
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const promise_concurrency_limiter_1 = require("./promise-concurrency-limiter");
|
||||
/* HELPERS */
|
||||
const limiter = new promise_concurrency_limiter_1.default({ concurrency: 500 });
|
||||
/* TINY READDIR */
|
||||
const readdir = (rootPath, options) => {
|
||||
var _a, _b, _c, _d;
|
||||
const followSymlinks = (_a = options === null || options === void 0 ? void 0 : options.followSymlinks) !== null && _a !== void 0 ? _a : false, maxDepth = (_b = options === null || options === void 0 ? void 0 : options.depth) !== null && _b !== void 0 ? _b : Infinity, isIgnored = (_c = options === null || options === void 0 ? void 0 : options.ignore) !== null && _c !== void 0 ? _c : (() => false), signal = (_d = options === null || options === void 0 ? void 0 : options.signal) !== null && _d !== void 0 ? _d : { aborted: false }, directories = [], files = [], symlinks = [], map = {}, resultEmpty = { directories: [], files: [], symlinks: [], map: {} }, result = { directories, files, symlinks, map };
|
||||
const handleDirectory = (dirmap, subPath, depth) => {
|
||||
dirmap.directories.push(subPath);
|
||||
directories.push(subPath);
|
||||
if (depth >= maxDepth)
|
||||
return;
|
||||
|
||||
// if depth > 1 and the limiter is full, then we cannot queue this function or the current promise will never return
|
||||
if (depth > 1 && limiter.count >= limiter.concurrency) return populateResultFromPath(subPath, depth + 1)
|
||||
|
||||
return limiter.add(() => populateResultFromPath(subPath, depth + 1));
|
||||
};
|
||||
const handleFile = (dirmap, subPath) => {
|
||||
dirmap.files.push(subPath);
|
||||
files.push(subPath);
|
||||
};
|
||||
const handleSymlink = (dirmap, subPath, depth) => {
|
||||
dirmap.symlinks.push(subPath);
|
||||
symlinks.push(subPath);
|
||||
if (!followSymlinks)
|
||||
return;
|
||||
if (depth >= maxDepth)
|
||||
return;
|
||||
return limiter.add(() => populateResultFromSymlink(subPath, depth + 1));
|
||||
};
|
||||
const handleStat = (dirmap, rootPath, stat, depth) => {
|
||||
if (signal.aborted)
|
||||
return;
|
||||
if (isIgnored(rootPath))
|
||||
return;
|
||||
if (stat.isDirectory()) {
|
||||
return handleDirectory(dirmap, rootPath, depth);
|
||||
}
|
||||
else if (stat.isFile()) {
|
||||
return handleFile(dirmap, rootPath);
|
||||
}
|
||||
else if (stat.isSymbolicLink()) {
|
||||
return handleSymlink(dirmap, rootPath, depth);
|
||||
}
|
||||
};
|
||||
const handleDirent = (dirmap, rootPath, dirent, depth) => {
|
||||
if (signal.aborted)
|
||||
return;
|
||||
const subPath = `${rootPath}${path.sep}${dirent.name}`;
|
||||
if (isIgnored(subPath))
|
||||
return;
|
||||
if (dirent.isDirectory()) {
|
||||
return handleDirectory(dirmap, subPath, depth);
|
||||
}
|
||||
else if (dirent.isFile()) {
|
||||
return handleFile(dirmap, subPath);
|
||||
}
|
||||
else if (dirent.isSymbolicLink()) {
|
||||
return handleSymlink(dirmap, subPath, depth);
|
||||
}
|
||||
};
|
||||
const handleDirents = (dirmap, rootPath, dirents, depth) => {
|
||||
return Promise.all(dirents.map((dirent) => {
|
||||
return handleDirent(dirmap, rootPath, dirent, depth);
|
||||
}));
|
||||
};
|
||||
const populateResultFromPath = async (rootPath, depth) => {
|
||||
if (signal.aborted)
|
||||
return;
|
||||
if (depth > maxDepth)
|
||||
return;
|
||||
const dirents = await fs.promises.readdir(rootPath, { withFileTypes: true }).catch(() => []);
|
||||
if (signal.aborted)
|
||||
return;
|
||||
const dirmap = map[rootPath] = { directories: [], files: [], symlinks: [] };
|
||||
if (!dirents.length)
|
||||
return;
|
||||
await handleDirents(dirmap, rootPath, dirents, depth);
|
||||
};
|
||||
const populateResultFromSymlink = async (rootPath, depth) => {
|
||||
try {
|
||||
const realPath = await fs.promises.realpath(rootPath), stat = await fs.promises.stat(realPath), dirmap = map[rootPath] = { directories: [], files: [], symlinks: [] };
|
||||
await handleStat(dirmap, realPath, stat, depth);
|
||||
}
|
||||
catch (_a) { }
|
||||
};
|
||||
const getResult = async (rootPath, depth = 1) => {
|
||||
rootPath = path.normalize(rootPath);
|
||||
await populateResultFromPath(rootPath, depth);
|
||||
if (signal.aborted)
|
||||
return resultEmpty;
|
||||
return result;
|
||||
};
|
||||
return getResult(rootPath);
|
||||
};
|
||||
/* EXPORT */
|
||||
module.exports = readdir;
|
||||
module.exports.default = readdir;
|
||||
Object.defineProperty(module.exports, "__esModule", { value: true });
|
Loading…
Add table
Add a link
Reference in a new issue