@neodx/vfs
Version:
Simple virtual file system - working dir context, lazy changes, different modes, integrations and moreover
86 lines (82 loc) • 2.17 kB
JavaScript
;
var std = require('@neodx/std');
var pathe = require('pathe');
var createVfsPlugin = require('../_internal/create-vfs-plugin-1jK9qNm1.cjs');
function scan() {
return createVfsPlugin.createVfsPlugin('scan', vfs => {
async function scanImpl(pathOrParams, params) {
return await scanVfs(
vfs,
std.isTypeOfString(pathOrParams)
? {
...params,
path: pathOrParams
}
: pathOrParams
);
}
vfs.scan = scanImpl;
return vfs;
});
}
async function scanVfs(
vfs,
{
path = '.',
cache = createScanVfsCache(),
filter = std.True,
signal: manualSignal,
barrier: manualBarrier = std.False,
timeout,
maxDepth,
withFileTypes
} = {}
) {
const signal = std.combineAbortSignals([manualSignal, std.tryCreateTimeoutSignal(timeout)]);
const barrier = std.some(
...std.compact([manualBarrier, std.isDefined(maxDepth) && (({ depth }) => depth >= maxDepth)])
);
const result = [];
async function iterate(params) {
signal.throwIfAborted();
Object.freeze(params);
const resolved = vfs.resolve(path, params.relativePath);
const children = await (cache.visited[resolved] ??= vfs.readDir(resolved, {
withFileTypes: true
}));
await std.concurrently(
children,
async dirent => {
signal.throwIfAborted();
const scanned = {
relativePath: pathe.join(params.relativePath, dirent.name),
dirent,
depth: params.depth + 1
};
if (filter(scanned)) result.push(scanned);
if (dirent.isDirectory() && !barrier(scanned)) await iterate(scanned);
},
10
);
}
await iterate({
relativePath: '.',
depth: 0
});
return withFileTypes ? result : result.map(item => item.relativePath);
}
const createScanVfsCache = () => {
const visited = {};
return {
visited,
clear() {
for (const key of Object.keys(visited)) {
delete visited[key];
}
}
};
};
exports.createScanVfsCache = createScanVfsCache;
exports.scan = scan;
exports.scanVfs = scanVfs;
//# sourceMappingURL=scan.cjs.map