(root: string)
| 2521 | } |
| 2522 | |
| 2523 | export async function listNotes(root: string): Promise<NoteMeta[]> { |
| 2524 | const startedAt = performance.now() |
| 2525 | await hydratePersistedNoteMetaCache(root) |
| 2526 | const noteFiles: Array<{ |
| 2527 | full: string |
| 2528 | folder: NoteFolder |
| 2529 | siblingOrder: number |
| 2530 | isSymlink: boolean |
| 2531 | }> = [] |
| 2532 | const walkFolder = async ( |
| 2533 | folder: NoteFolder, |
| 2534 | dirAbs: string, |
| 2535 | dirReal: string, |
| 2536 | topAbs: string, |
| 2537 | isPrimaryRoot: boolean, |
| 2538 | ancestors: Set<string> |
| 2539 | ): Promise<void> => { |
| 2540 | let entries: Dirent[] |
| 2541 | try { |
| 2542 | entries = await fs.readdir(dirAbs, { withFileTypes: true }) |
| 2543 | } catch { |
| 2544 | return |
| 2545 | } |
| 2546 | for (const [index, entry] of entries.entries()) { |
| 2547 | const full = path.join(dirAbs, entry.name) |
| 2548 | const childReal = await resolveDirDescent(full, entry, dirReal, ancestors) |
| 2549 | if (childReal !== null) { |
| 2550 | if (entry.name.startsWith('.')) continue |
| 2551 | if (isPrimaryRoot && dirAbs === topAbs && shouldHidePrimaryRootEntry(entry.name)) continue |
| 2552 | ancestors.add(childReal) |
| 2553 | await walkFolder(folder, full, childReal, topAbs, isPrimaryRoot, ancestors) |
| 2554 | ancestors.delete(childReal) |
| 2555 | continue |
| 2556 | } |
| 2557 | if ( |
| 2558 | (await isMarkdownNoteEntry(full, entry)) || |
| 2559 | (await isExcalidrawFileEntry(full, entry)) |
| 2560 | ) { |
| 2561 | noteFiles.push({ full, folder, siblingOrder: index, isSymlink: entry.isSymbolicLink() }) |
| 2562 | } |
| 2563 | } |
| 2564 | } |
| 2565 | |
| 2566 | for (const folder of FOLDERS) { |
| 2567 | const topAbs = await folderRoot(root, folder) |
| 2568 | const isPrimaryRoot = folder === 'inbox' && path.resolve(topAbs) === path.resolve(root) |
| 2569 | const topReal = await realpathOrResolve(topAbs) |
| 2570 | await walkFolder(folder, topAbs, topReal, topAbs, isPrimaryRoot, new Set([topReal])) |
| 2571 | } |
| 2572 | |
| 2573 | const metas = ( |
| 2574 | await mapLimit(noteFiles, NOTE_META_READ_CONCURRENCY, async (file) => { |
| 2575 | try { |
| 2576 | return await readMeta(root, file.full, file.folder, file.siblingOrder, file.isSymlink) |
| 2577 | } catch { |
| 2578 | return null |
| 2579 | } |
| 2580 | }) |
no test coverage detected