- Startseite
- Documentation
- Nativ
- Natives Text/Such-Pipeline
Natives Text/Such-Pipeline
Dieses Dokument bildet die Text/Such-Oberfläche (grep, glob, text, highlight) von @f5-sales-demo/pi-natives ab — von TypeScript-Wrappern zu Rust N-API-Exporten und zurück zu JS-Ergebnisobjekten.
Die Terminologie folgt docs/natives-architecture.md:
- Wrapper: TS-API in
packages/natives/src/* - Rust-Modulschicht: N-API-Exporte in
crates/pi-natives/src/* - Geteilter Scan-Cache:
fs_cache-gestützter Verzeichniseintrags-Cache, der von Discovery/Such-Abläufen verwendet wird
Implementierungsdateien
Abschnitt betitelt „Implementierungsdateien“packages/natives/src/grep/index.tspackages/natives/src/grep/types.tspackages/natives/src/glob/index.tspackages/natives/src/glob/types.tspackages/natives/src/text/index.tspackages/natives/src/text/types.tspackages/natives/src/highlight/index.tspackages/natives/src/highlight/types.tscrates/pi-natives/src/grep.rscrates/pi-natives/src/glob.rscrates/pi-natives/src/glob_util.rscrates/pi-natives/src/fs_cache.rscrates/pi-natives/src/text.rscrates/pi-natives/src/highlight.rscrates/pi-natives/src/fd.rs
JS-API ↔ Rust-Export-Zuordnung
Abschnitt betitelt „JS-API ↔ Rust-Export-Zuordnung“| JS-Wrapper-API | Rust-Export (#[napi], snake_case -> camelCase) | Rust-Modul |
|---|---|---|
grep(options, onMatch?) | grep | grep.rs |
searchContent(content, options) | search | grep.rs |
hasMatch(content, pattern, options?) | hasMatch | grep.rs |
fuzzyFind(options) | fuzzyFind | fd.rs |
glob(options, onMatch?) | glob | glob.rs |
invalidateFsScanCache(path?) | invalidateFsScanCache | fs_cache.rs |
wrapTextWithAnsi(text, width) | wrapTextWithAnsi | text.rs |
truncateToWidth(text, maxWidth, ellipsis, pad) | truncateToWidth | text.rs |
sliceWithWidth(line, startCol, length, strict?) | sliceWithWidth | text.rs |
extractSegments(line, beforeEnd, afterStart, afterLen, strictAfter) | extractSegments | text.rs |
sanitizeText(text) | sanitizeText | text.rs |
visibleWidth(text) | visibleWidth | text.rs |
highlightCode(code, lang, colors) | highlightCode | highlight.rs |
supportsLanguage(lang) | supportsLanguage | highlight.rs |
getSupportedLanguages() | getSupportedLanguages | highlight.rs |
Pipeline-Übersicht nach Subsystem
Abschnitt betitelt „Pipeline-Übersicht nach Subsystem“1) Regex-Suche (grep, searchContent, hasMatch)
Abschnitt betitelt „1) Regex-Suche (grep, searchContent, hasMatch)“Eingabe-/Options-Ablauf
Abschnitt betitelt „Eingabe-/Options-Ablauf“- Der TS-Wrapper leitet Optionen an die native Schicht weiter:
grep/index.tsübergibtoptionsweitgehend unverändert und wandelt den Callback von(match) => voidin die napi-threadsafe-Callback-Form(err, match)um.searchContentundhasMatchübergeben String/Uint8Arraydirekt.
- Rust-Option-Structs in
grep.rsdeserialisieren camelCase-Felder (ignoreCase,maxCount,contextBefore,contextAfter,maxColumns,timeoutMs). greperstellt einCancelTokenaustimeoutMs+AbortSignalund läuft innerhalb vontask::blocking("grep", ...).
Ausführungszweige
Abschnitt betitelt „Ausführungszweige“- In-Memory-Zweig (reines Hilfsmittel)
search→search_sync→run_searchauf den bereitgestellten Inhaltsbytes.- Kein Dateisystem-Scan, kein
fs_cache.
- Einzeldatei-Zweig (dateisystemabhängig)
grep_synclöst den Pfad auf, prüft ob Metadaten eine Datei sind, streamt bis zuMAX_FILE_BYTESpro Datei (4 MiB) durch den Ripgrep-Matcher.
- Verzeichnis-Zweig (dateisystemabhängig)
- Optionaler Cache-Lookup über
fs_cache::get_or_scanbeicache: true. - Frischer Scan über
fs_cache::force_rescanbeicache: false. - Optionale Leer-Ergebnis-Neuprüfung wenn das Cache-Alter
empty_recheck_ms()überschreitet. - Eintragsfilterung: nur Dateien + optionaler Glob-Filter (
glob_util) + optionales Typ-Filter-Mapping (js,ts,rust, etc.).
- Optionaler Cache-Lookup über
Such-/Sammlungssemantik
Abschnitt betitelt „Such-/Sammlungssemantik“- Regex-Engine:
grep_regex::RegexMatcherBuildermitignoreCaseundmultiline. - Kontext-Auflösung:
contextBefore/contextAfterüberschreiben das Legacy-context.- Nicht-Inhaltsmodi setzen die Kontextsammlung auf null.
- Ausgabemodi:
content=> einGrepMatchpro Treffer.countundfilesWithMatcheswerden beide auf Zählstil-Einträge abgebildet (lineNumber=0,line="",matchCountgesetzt).
- Limits:
- Globaler
offsetundmaxCountwerden dateienübergreifend angewendet. - Der parallele Pfad wird nur verwendet wenn
maxCountnicht gesetzt ist undoffset == 0; andernfalls bewahrt der sequentielle Pfad deterministische globale Offset/Limit-Semantik.
- Globaler
Ergebnisformung zurück zu JS
Abschnitt betitelt „Ergebnisformung zurück zu JS“- Rust-
SearchResult/GrepResult-Felder werden über N-API-Objektfeldkonvertierung auf TS-Typen abgebildet. - Zähler werden auf
u32begrenzt bevor sie die N-API-Grenze überschreiten. - Optionale Booleans werden ausgelassen, es sei denn sie sind in einigen Pfaden wahr (
limitReached). - Der Streaming-Callback empfängt jeden geformten
GrepMatch(Inhalts- oder Zähleintrag).
Fehlerverhalten
Abschnitt betitelt „Fehlerverhalten“searchContentgibtSearchResult.errorfür Regex-/Suchfehler zurück anstatt zu werfen.greplehnt bei schweren Fehlern ab (ungültiger Pfad, ungültiges Glob/Regex, Abbruch-Timeout/Abort).hasMatchgibtResult<bool>zurück und wirft bei ungültigem Muster/UTF-8-Dekodierungsfehlern.- Datei-Öffnungs-/Suchfehler bei Multi-Datei-Scans werden pro Datei übersprungen; der Scan wird fortgesetzt.
Behandlung fehlerhafter Regex
Abschnitt betitelt „Behandlung fehlerhafter Regex“grep.rs bereinigt geschweifte Klammern vor der Regex-Kompilierung:
- Ungültige wiederholungsähnliche geschweifte Klammern werden escaped (
{/}->\{/\}), wenn sie nicht{N},{N,},{N,M}bilden können. - Dies verhindert, dass häufige Literal-Template-Fragmente (zum Beispiel
${platform}) als fehlerhafte Wiederholungen fehlschlagen. - Verbleibende ungültige Regex-Syntax gibt weiterhin einen Regex-Fehler zurück.
2) Datei-Discovery (glob) und Fuzzy-Pfadsuche (fuzzyFind)
Abschnitt betitelt „2) Datei-Discovery (glob) und Fuzzy-Pfadsuche (fuzzyFind)“glob und fuzzyFind teilen sich fs_cache-Scans; die Matching-Logik unterscheidet sich.
glob-Ablauf
Abschnitt betitelt „glob-Ablauf“- TS-Wrapper (
glob/index.ts):path.resolve(options.path).- Standardwerte:
pattern="*",hidden=false,gitignore=true,recursive=true.
- Rust
globerstelltGlobConfigund kompiliert das Muster überglob_util::compile_glob. - Eintragsquelle:
cache=true=>get_or_scan+ optionaler veralteter-Leer-force_rescan.cache=false=>force_rescan(..., store=false)(nur frisch).
- Filterung:
.gitwird immer übersprungen.node_moduleswird übersprungen, es sei denn angefordert (includeNodeModulesoder Muster erwähnt node_modules).- Glob-Match anwenden.
- Dateityp-Filter anwenden; Symlink-
file/dir-Filter lösen Ziel-Metadaten auf.
- Optionale Sortierung nach mtime absteigend (
sortByMtime) vor dem Abschneiden aufmaxResults.
fuzzyFind-Ablauf (implementiert in fd.rs)
Abschnitt betitelt „fuzzyFind-Ablauf (implementiert in fd.rs)“- Der TS-Wrapper wird aus dem
grep-Modul exportiert, aber die Rust-Implementierung befindet sich infd.rs. - Gemeinsame Scan-Quelle aus
fs_cachemit derselben Cache/Kein-Cache-Aufteilung und Richtlinie zur Neuprüfung veralteter Leer-Ergebnisse. - Bewertung:
- Exakt / beginnt-mit / enthält / Subsequenz-basierter Fuzzy-Score
- Separator/Interpunktions-normalisierter Bewertungspfad
- Verzeichnis-Bonus und deterministischer Gleichstandsbruch (
score absteigend, dannpath aufsteigend)
- Symlink-Einträge werden von Fuzzy-Ergebnissen ausgeschlossen.
Fehlerverhalten
Abschnitt betitelt „Fehlerverhalten“- Ungültiges Glob-Muster => Fehler von
glob_util::compile_glob. - Der Suchwurzel muss ein existierendes Verzeichnis sein (
resolve_search_path), andernfalls Fehler. - Abbrüche/Timeouts werden als Abort-Fehler über
CancelToken::heartbeat()-Prüfungen in Schleifen weitergegeben.
Behandlung fehlerhafter Globs
Abschnitt betitelt „Behandlung fehlerhafter Globs“glob_util::build_glob_pattern ist tolerant:
- Normalisiert
\zu/. - Fügt einfachen rekursiven Mustern automatisch
**/voran wennrecursive=true. - Schließt automatisch unbalancierte
{...-Alternationsgruppen vor der Kompilierung.
3) Geteilter Scan-/Cache-Lebenszyklus (fs_cache)
Abschnitt betitelt „3) Geteilter Scan-/Cache-Lebenszyklus (fs_cache)“fs_cache speichert Scan-Ergebnisse als normalisierte relative Einträge (path, fileType, optionale mtime), indiziert durch:
- Kanonischen Suchwurzel
include_hiddenuse_gitignore
Cache-Zustandsübergänge
Abschnitt betitelt „Cache-Zustandsübergänge“- Miss / deaktiviert
- TTL ist
0oder Schlüssel fehlt/abgelaufen -> frischescollect_entries.
- TTL ist
- Hit
- Eintragsalter
< cache_ttl_ms()-> gecachte Einträge +cache_age_mszurückgeben.
- Eintragsalter
- Neuprüfung veralteter Leer-Ergebnisse (Aufrufer-Richtlinie in
glob/grep/fd)- Wenn eine Abfrage null Treffer liefert und
cache_age_ms >= empty_recheck_ms(), einen Rescan erzwingen.
- Wenn eine Abfrage null Treffer liefert und
- Invalidierung
invalidateFsScanCache(path?):- Kein Argument: alle Schlüssel löschen
- Pfad-Argument: Schlüssel entfernen, deren Wurzel den Zielpfad als Präfix hat
Kompromiss bei veralteten Ergebnissen
Abschnitt betitelt „Kompromiss bei veralteten Ergebnissen“- Der Cache bevorzugt niedrige Latenz bei wiederholten Scans gegenüber sofortiger Konsistenz.
- Das TTL-Fenster kann veraltete positive/negative Ergebnisse zurückgeben.
- Die Neuprüfung leerer Ergebnisse reduziert veraltete Negative für ältere gecachte Scans auf Kosten eines zusätzlichen Scans.
- Explizite Invalidierung ist der vorgesehene Korrektheitsmechanismus nach Dateimutationen.
4) ANSI-Text-Hilfsfunktionen (text)
Abschnitt betitelt „4) ANSI-Text-Hilfsfunktionen (text)“Dies sind reine In-Memory-Hilfsfunktionen (kein Dateisystem-Scanning).
Grenzen und Verantwortlichkeiten
Abschnitt betitelt „Grenzen und Verantwortlichkeiten“text.rsbesitzt Terminal-Zell-Semantik:- ANSI-Sequenz-Parsing
- Graphem-bewusste Breite und Slicing
- Wrap/Truncate/Sanitize-Verhalten
grep.rs-Zeilenkürzung (maxColumns) ist separat:- Einfache Zeichengrenzen-Kürzung von Trefferzeilen mit
... - Nicht ANSI-Zustand-erhaltend und nicht Terminal-Zellbreiten-bewusst
- Einfache Zeichengrenzen-Kürzung von Trefferzeilen mit
Schlüsselverhalten
Abschnitt betitelt „Schlüsselverhalten“wrapTextWithAnsi: Umbricht nach sichtbarer Breite, überträgt aktive SGR-Codes über umbrochene Zeilen.truncateToWidth: Sichtbare-Zellen-Kürzung mit Ellipsis-Richtlinie (Unicode,Ascii,Omit), optionalem rechten Padding und Fast-Path, der den originalen JS-String zurückgibt wenn unverändert.sliceWithWidth: Spalten-Slicing mit optionaler strikter Breitendurchsetzung.extractSegments: Extrahiert Vorher/Nachher-Segmente um ein Overlay, wobei der ANSI-Zustand für dasafter-Segment wiederhergestellt wird.sanitizeText: Entfernt ANSI-Escapes + Steuerzeichen, verwirft einzelne Surrogate, normalisiert CR/LF durch Entfernung von\r.visibleWidth: Zählt sichtbare Terminal-Zellen (Tabs verwenden festeTAB_WIDTHaus der Rust-Implementierung).
Fehlerverhalten
Abschnitt betitelt „Fehlerverhalten“Textfunktionen geben generell deterministisch transformierte Ausgaben zurück; Fehler beschränken sich auf JS-String-Konvertierungsgrenzen (N-API-Argumentkonvertierungsfehler).
5) Syntax-Highlighting (highlight)
Abschnitt betitelt „5) Syntax-Highlighting (highlight)“highlight.rs ist reine Transformation (kein FS, kein Cache).
- Der Wrapper leitet
code, optionaleslangund eine ANSI-Farbpalette weiter. - Rust löst die Syntax auf durch:
- Token/Name-Lookup
- Erweiterungs-Lookup
- Alias-Tabellen-Fallback (
ts/tsx/js -> JavaScript, etc.) - Fallback auf Klartext-Syntax wenn nicht aufgelöst
- Jede Zeile wird mit syntect
ParseStateund Scope-Stack geparst. - Scopes werden auf 11 semantische Farbkategorien abgebildet und ANSI-Farbcodes eingefügt/zurückgesetzt.
Fehlerverhalten
Abschnitt betitelt „Fehlerverhalten“- Ein Parse-Fehler pro Zeile lässt den Aufruf nicht fehlschlagen: diese Zeile wird ohne Highlighting angehängt und die Verarbeitung wird fortgesetzt.
- Unbekannte/nicht unterstützte Sprache fällt auf Klartext-Syntax zurück.
Reine Hilfsfunktionen vs. dateisystemabhängige Abläufe
Abschnitt betitelt „Reine Hilfsfunktionen vs. dateisystemabhängige Abläufe“| Ablauf | Dateisystemzugriff | Geteilter Cache | Anmerkungen |
|---|---|---|---|
searchContent / hasMatch | Nein | Nein | Regex nur auf bereitgestellten Bytes/String |
text-Modulfunktionen | Nein | Nein | Nur ANSI/Breite/Bereinigung |
highlight-Modulfunktionen | Nein | Nein | Nur Syntax + ANSI-Färbung |
glob | Ja | Optional | Verzeichnis-Scans + Glob-Filterung |
fuzzyFind | Ja | Optional | Verzeichnis-Scans + Fuzzy-Bewertung |
grep (Datei-/Verzeichnispfad) | Ja | Optional (Verzeichnismodus) | Ripgrep über Dateien, optionale Filter/Callback |
End-to-End-Lebenszyklus-Zusammenfassung
Abschnitt betitelt „End-to-End-Lebenszyklus-Zusammenfassung“- Der Aufrufer ruft den TS-Wrapper mit typisierten Optionen auf.
- Der Wrapper normalisiert Standardwerte (insbesondere
glob) und leitet an dennative.*-Export weiter. - Rust validiert/normalisiert Optionen und erstellt Matcher/Such-Konfiguration.
- Für Dateisystem-Abläufe werden Einträge gescannt (Cache-Hit/Miss/Rescan) und dann gefiltert/bewertet.
- Worker-Schleifen rufen periodisch den Cancel-Heartbeat auf; Timeout/Abort kann die Ausführung beenden.
- Rust formt Ausgaben in N-API-Objekte (
lineNumber,matchCount,limitReached, etc.). - Der TS-Wrapper gibt typisierte JS-Objekte zurück (und optionale Pro-Match-Callbacks für
grep/glob).