UNPKG

@neodx/vfs

Version:

Simple virtual file system - working dir context, lazy changes, different modes, integrations and moreover

92 lines (89 loc) 2.18 kB
import { combineAbortSignals, tryCreateTimeoutSignal, some, compact, isDefined, True, False, concurrently, isTypeOfString } from '@neodx/std'; import { join } from 'pathe'; import { c as createVfsPlugin } from '../_internal/create-vfs-plugin-BzqnUd8c.mjs'; function scan() { return createVfsPlugin('scan', vfs => { async function scanImpl(pathOrParams, params) { return await scanVfs( vfs, isTypeOfString(pathOrParams) ? { ...params, path: pathOrParams } : pathOrParams ); } vfs.scan = scanImpl; return vfs; }); } async function scanVfs( vfs, { path = '.', cache = createScanVfsCache(), filter = True, signal: manualSignal, barrier: manualBarrier = False, timeout, maxDepth, withFileTypes } = {} ) { const signal = combineAbortSignals([manualSignal, tryCreateTimeoutSignal(timeout)]); const barrier = some( ...compact([manualBarrier, 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 concurrently( children, async dirent => { signal.throwIfAborted(); const scanned = { relativePath: 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]; } } }; }; export { createScanVfsCache, scan, scanVfs }; //# sourceMappingURL=scan.mjs.map