@neodx/vfs
Version:
Simple virtual file system - working dir context, lazy changes, different modes, integrations and moreover
1 lines • 7.05 kB
Source Map (JSON)
{"version":3,"file":"scan.cjs","sources":["../../../src/plugins/scan.ts"],"sourcesContent":["import {\n combineAbortSignals,\n compact,\n concurrently,\n False,\n isDefined,\n isTypeOfString,\n some,\n True,\n tryCreateTimeoutSignal\n} from '@neodx/std';\nimport { join } from 'pathe';\nimport type { VfsDirent } from '../backend/shared.ts';\nimport type { BaseVfs } from '../core/types.ts';\nimport { createVfsPlugin } from '../create-vfs-plugin.ts';\n\nexport interface ScanPluginApi {\n scan(path?: string, params?: ScanVfsParams): Promise<string[]>;\n scan(params?: ScanVfsParams): Promise<string[]>;\n scan(path: string, params: ScanVfsParams & { withFileTypes: true }): Promise<ScannedItem[]>;\n scan(params: ScanVfsParams & { withFileTypes: true }): Promise<ScannedItem[]>;\n}\n\nexport interface ScanVfsParams {\n /** Path to scan. */\n path?: string;\n /**\n * Should return false if the scanning for the current directory should be stopped.\n * @default False\n */\n barrier?: ScanVfsDirentChecker;\n /**\n * Should return true if the item should be included in the result.\n * @default True\n */\n filter?: ScanVfsDirentChecker;\n /** Custom abort signal. */\n signal?: AbortSignal;\n /** Timeout in milliseconds. */\n timeout?: number;\n /** Maximum depth to scan. */\n maxDepth?: number;\n\n /** If true, the result will contain information about the path, depth, relativePath and dirent. */\n withFileTypes?: boolean;\n /** Optional cache for optimizing multiple scans under relatively static conditions. */\n cache?: ScanVfsCache;\n}\n\nexport interface ScannedItem {\n /** Current scanning depth. */\n depth: number;\n /** Relative path to file or directory */\n relativePath: string;\n dirent: VfsDirent;\n}\n\nexport type ScanVfsDirentChecker = (item: ScannedItem) => boolean;\nexport type ScanVfsCache = ReturnType<typeof createScanVfsCache>;\n\nexport function scan() {\n return createVfsPlugin<ScanPluginApi>('scan', vfs => {\n async function scanImpl(pathOrParams?: string | ScanVfsParams, params?: ScanVfsParams) {\n return await scanVfs(\n vfs,\n isTypeOfString(pathOrParams) ? { ...params, path: pathOrParams } : pathOrParams\n );\n }\n\n vfs.scan = scanImpl as ScanPluginApi['scan'];\n return vfs;\n });\n}\n\nexport async function scanVfs(\n vfs: BaseVfs,\n params: ScanVfsParams & { withFileTypes: true }\n): Promise<ScannedItem[]>;\nexport async function scanVfs(vfs: BaseVfs, params?: ScanVfsParams): Promise<string[]>;\nexport async function scanVfs(\n vfs: BaseVfs,\n {\n path = '.',\n cache = createScanVfsCache(),\n filter = True,\n signal: manualSignal,\n barrier: manualBarrier = False,\n timeout,\n maxDepth,\n withFileTypes\n }: ScanVfsParams = {}\n) {\n const signal = combineAbortSignals([manualSignal, tryCreateTimeoutSignal(timeout)]);\n const barrier = some(\n ...compact([\n manualBarrier,\n isDefined(maxDepth) && (({ depth }: ScannedItem) => depth >= maxDepth)\n ])\n );\n const result: ScannedItem[] = [];\n\n async function iterate(params: Pick<ScannedItem, 'relativePath' | 'depth'>) {\n signal.throwIfAborted();\n Object.freeze(params);\n const resolved = vfs.resolve(path, params.relativePath);\n const children = await (cache.visited[resolved] ??= vfs.readDir(resolved, {\n withFileTypes: true\n }));\n\n await concurrently(\n children,\n async dirent => {\n signal.throwIfAborted();\n const scanned = {\n relativePath: join(params.relativePath, dirent.name),\n dirent,\n depth: params.depth + 1\n };\n\n if (filter(scanned)) result.push(scanned);\n if (dirent.isDirectory() && !barrier(scanned)) await iterate(scanned);\n },\n 10\n );\n }\n\n await iterate({ relativePath: '.', depth: 0 });\n return withFileTypes ? result : result.map(item => item.relativePath);\n}\n\nexport const createScanVfsCache = () => {\n const visited = {} as Record<string, Promise<VfsDirent[]>>;\n\n return {\n visited,\n clear() {\n for (const key of Object.keys(visited)) {\n delete visited[key];\n }\n }\n };\n};\n"],"names":["scan","createVfsPlugin","vfs","scanImpl","pathOrParams","params","scanVfs","isTypeOfString","path","cache","createScanVfsCache","filter","True","signal","manualSignal","barrier","manualBarrier","False","timeout","maxDepth","withFileTypes","combineAbortSignals","tryCreateTimeoutSignal","some","compact","isDefined","depth","result","iterate","throwIfAborted","Object","freeze","resolved","resolve","relativePath","children","visited","readDir","concurrently","dirent","scanned","join","name","push","isDirectory","map","item","clear","key","keys"],"mappings":"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"}