- Inicio
- Documentation
- Nativos
- Canalización de texto/búsqueda nativa
Canalización de texto/búsqueda nativa
Este documento mapea la superficie de texto/búsqueda (grep, glob, text, highlight) de @f5-sales-demo/pi-natives desde los envoltorios de TypeScript hasta las exportaciones N-API de Rust y de vuelta a los objetos de resultado de JS.
La terminología sigue docs/natives-architecture.md:
- Wrapper: API de TS en
packages/natives/src/* - Capa de módulo Rust: exportaciones N-API en
crates/pi-natives/src/* - Caché de escaneo compartido: caché de entradas de directorio respaldada por
fs_cacheutilizada por los flujos de descubrimiento/búsqueda
Archivos de implementación
Sección titulada «Archivos de implementación»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
Mapeo de API JS ↔ exportación Rust
Sección titulada «Mapeo de API JS ↔ exportación Rust»| API del wrapper JS | Exportación Rust (#[napi], snake_case -> camelCase) | Módulo Rust |
|---|---|---|
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 |
Descripción general de la canalización por subsistema
Sección titulada «Descripción general de la canalización por subsistema»1) Búsqueda por expresión regular (grep, searchContent, hasMatch)
Sección titulada «1) Búsqueda por expresión regular (grep, searchContent, hasMatch)»Flujo de entrada/opciones
Sección titulada «Flujo de entrada/opciones»- El wrapper de TS reenvía las opciones al módulo nativo:
grep/index.tspasa lasoptionscasi sin cambios y envuelve el callback de(match) => voida la forma de callback thread-safe de napi(err, match).searchContentyhasMatchpasan directamente una cadena de texto oUint8Array.
- Las estructuras de opciones de Rust en
grep.rsdeserializan campos en camelCase (ignoreCase,maxCount,contextBefore,contextAfter,maxColumns,timeoutMs). grepcrea unCancelTokena partir detimeoutMs+AbortSignaly se ejecuta dentro detask::blocking("grep", ...).
Ramas de ejecución
Sección titulada «Ramas de ejecución»- Rama en memoria (utilidad pura)
search→search_sync→run_searchsobre los bytes de contenido proporcionados.- Sin escaneo del sistema de archivos, sin
fs_cache.
- Rama de archivo único (dependiente del sistema de archivos)
grep_syncresuelve la ruta, verifica que los metadatos correspondan a un archivo y transmite hastaMAX_FILE_BYTESpor archivo (4 MiB) a través del comparador de ripgrep.
- Rama de directorio (dependiente del sistema de archivos)
- Búsqueda opcional en caché mediante
fs_cache::get_or_scancuandocache: true. - Escaneo nuevo mediante
fs_cache::force_rescancuandocache: false. - Reverificación opcional de resultados vacíos cuando la antigüedad de la caché supera
empty_recheck_ms(). - Filtrado de entradas: solo archivos + filtro glob opcional (
glob_util) + mapeo de filtro de tipo opcional (js,ts,rust, etc.).
- Búsqueda opcional en caché mediante
Semántica de búsqueda/recolección
Sección titulada «Semántica de búsqueda/recolección»- Motor de expresiones regulares:
grep_regex::RegexMatcherBuilderconignoreCaseymultiline. - Resolución de contexto:
contextBefore/contextAfteranulan elcontextheredado.- Los modos que no son de contenido anulan la recolección de contexto.
- Modos de salida:
content=> unGrepMatchpor coincidencia.countyfilesWithMatchesse mapean a entradas de estilo contador (lineNumber=0,line="",matchCountestablecido).
- Límites:
offsetglobal ymaxCountaplicados entre archivos.- La ruta paralela se usa solo cuando
maxCountno está definido yoffset == 0; de lo contrario, la ruta secuencial preserva la semántica determinista de offset/límite global.
Conformación del resultado de vuelta a JS
Sección titulada «Conformación del resultado de vuelta a JS»- Los campos de
SearchResult/GrepResultde Rust se mapean a tipos de TS mediante la conversión de campos de objetos N-API. - Los contadores se limitan a
u32antes de cruzar N-API. - Los booleanos opcionales se omiten a menos que sean verdaderos en algunas rutas (
limitReached). - El callback de transmisión recibe cada
GrepMatchconformado (entrada de contenido o de contador).
Comportamiento ante fallos
Sección titulada «Comportamiento ante fallos»searchContentdevuelveSearchResult.erroren caso de fallos de expresión regular/búsqueda en lugar de lanzar una excepción.greprechaza ante errores graves (ruta inválida, glob/expresión regular inválida, tiempo de espera de cancelación/cancelación).hasMatchdevuelveResult<bool>y lanza una excepción ante errores de patrón inválido/decodificación UTF-8.- Los errores de apertura/búsqueda de archivos en escaneos de múltiples archivos se omiten por archivo; el escaneo continúa.
Manejo de expresiones regulares malformadas
Sección titulada «Manejo de expresiones regulares malformadas»grep.rs sanea las llaves antes de compilar la expresión regular:
- Las llaves con apariencia de repetición inválida se escapan (
{/}->\{/\}) cuando no pueden formar{N},{N,},{N,M}. - Esto evita que fragmentos literales de plantillas comunes (por ejemplo,
${platform}) fallen como repeticiones malformadas. - La sintaxis de expresión regular inválida restante aún devuelve un error de expresión regular.
2) Descubrimiento de archivos (glob) y búsqueda difusa de rutas (fuzzyFind)
Sección titulada «2) Descubrimiento de archivos (glob) y búsqueda difusa de rutas (fuzzyFind)»glob y fuzzyFind comparten los escaneos de fs_cache; la lógica de coincidencia difiere.
Flujo de glob
Sección titulada «Flujo de glob»- Wrapper de TS (
glob/index.ts):path.resolve(options.path).- Valores predeterminados:
pattern="*",hidden=false,gitignore=true,recursive=true.
- Rust
globconstruyeGlobConfigy compila el patrón medianteglob_util::compile_glob. - Fuente de entradas:
cache=true=>get_or_scan+force_rescanopcional para caché vacía expirada.cache=false=>force_rescan(..., store=false)(solo nuevo).
- Filtrado:
- Omitir
.gitsiempre. - Omitir
node_modulesa menos que se solicite (includeNodeModuleso patrón que mencione node_modules). - Aplicar coincidencia glob.
- Aplicar filtro de tipo de archivo; los filtros de
file/dirde enlaces simbólicos resuelven los metadatos del destino.
- Omitir
- Ordenamiento opcional por mtime descendente (
sortByMtime) antes de truncar amaxResults.
Flujo de fuzzyFind (implementado en fd.rs)
Sección titulada «Flujo de fuzzyFind (implementado en fd.rs)»- El wrapper de TS se exporta desde el módulo
grep, pero la implementación de Rust reside enfd.rs. - Fuente de escaneo compartida desde
fs_cachecon la misma división de caché/sin caché y política de reverificación de vacío expirado. - Puntuación:
- puntuación difusa basada en exacta / comienza con / contiene / subsecuencia
- ruta de puntuación normalizada por separadores/puntuación
- bonificación por directorio y desempate determinista (
score desc, luegopath asc)
- Las entradas de enlaces simbólicos se excluyen de los resultados difusos.
Comportamiento ante fallos
Sección titulada «Comportamiento ante fallos»- Patrón glob inválido => error de
glob_util::compile_glob. - La raíz de búsqueda debe ser un directorio existente (
resolve_search_path), de lo contrario error. - La cancelación/los tiempos de espera se propagan como errores de cancelación mediante verificaciones de
CancelToken::heartbeat()en los bucles.
Manejo de globs malformados
Sección titulada «Manejo de globs malformados»glob_util::build_glob_pattern es tolerante:
- Normaliza
\a/. - Agrega automáticamente el prefijo
**/a patrones recursivos simples cuandorecursive=true. - Cierra automáticamente grupos de alternancia
{...no balanceados antes de compilar.
3) Ciclo de vida del escaneo/caché compartido (fs_cache)
Sección titulada «3) Ciclo de vida del escaneo/caché compartido (fs_cache)»fs_cache almacena los resultados del escaneo como entradas relativas normalizadas (path, fileType, mtime opcional) indexadas por:
- raíz de búsqueda canónica
include_hiddenuse_gitignore
Transiciones de estado de la caché
Sección titulada «Transiciones de estado de la caché»- Fallo / deshabilitada
- TTL es
0o clave ausente/expirada -> nuevocollect_entries.
- TTL es
- Acierto
- Antigüedad de entrada
< cache_ttl_ms()-> devolver entradas en caché +cache_age_ms.
- Antigüedad de entrada
- Reverificación de vacío expirado (política del llamador en
glob/grep/fd)- Si la consulta produce cero coincidencias y
cache_age_ms >= empty_recheck_ms(), forzar un nuevo escaneo.
- Si la consulta produce cero coincidencias y
- Invalidación
invalidateFsScanCache(path?):- sin argumento: borrar todas las claves
- argumento de ruta: eliminar claves cuya raíz tiene como prefijo esa ruta destino
Compensación de resultados expirados
Sección titulada «Compensación de resultados expirados»- La caché favorece los escaneos repetidos de baja latencia sobre la consistencia inmediata.
- La ventana de TTL puede devolver positivos/negativos expirados.
- La reverificación de resultados vacíos reduce los negativos expirados en escaneos en caché más antiguos a costa de un escaneo adicional.
- La invalidación explícita es el mecanismo de corrección previsto tras mutaciones de archivos.
4) Utilidades de texto ANSI (text)
Sección titulada «4) Utilidades de texto ANSI (text)»Estas son utilidades puramente en memoria (sin escaneo del sistema de archivos).
Límites y responsabilidades
Sección titulada «Límites y responsabilidades»text.rsgestiona la semántica de celdas de terminal:- análisis de secuencias ANSI
- ancho y segmentación con reconocimiento de grafemas
- comportamiento de ajuste/truncado/saneamiento
- El truncado de líneas en
grep.rs(maxColumns) es independiente:- truncado simple por límite de caracteres de líneas coincidentes con
... - no preserva el estado ANSI y no tiene reconocimiento del ancho de celda de terminal
- truncado simple por límite de caracteres de líneas coincidentes con
Comportamientos clave
Sección titulada «Comportamientos clave»wrapTextWithAnsi: ajusta por ancho visible, transporta los códigos SGR activos a través de las líneas ajustadas.truncateToWidth: truncado de celdas visibles con política de puntos suspensivos (Unicode,Ascii,Omit), relleno derecho opcional y ruta rápida que devuelve la cadena JS original cuando no cambia.sliceWithWidth: segmentación de columnas con aplicación de ancho estricto opcional.extractSegments: extrae segmentos antes/después alrededor de una superposición mientras restaura el estado ANSI para el segmentoafter.sanitizeText: elimina secuencias ANSI + caracteres de control, descarta sustitutos sueltos, normaliza CR/LF eliminando\r.visibleWidth: cuenta las celdas de terminal visibles (las tabulaciones usanTAB_WIDTHfijo de la implementación de Rust).
Comportamiento ante fallos
Sección titulada «Comportamiento ante fallos»Las funciones de texto generalmente devuelven una salida transformada determinista; los errores se limitan a los límites de conversión de cadenas JS (fallos de conversión de argumentos N-API).
5) Resaltado de sintaxis (highlight)
Sección titulada «5) Resaltado de sintaxis (highlight)»highlight.rs es transformación pura (sin FS, sin caché).
- El wrapper reenvía
code,langopcional y la paleta de colores ANSI. - Rust resuelve la sintaxis mediante:
- búsqueda por token/nombre
- búsqueda por extensión
- tabla de alias de respaldo (
ts/tsx/js -> JavaScript, etc.) - recurso de sintaxis de texto sin formato cuando no se resuelve
- Analiza cada línea con
ParseStatede syntect y la pila de alcances. - Mapea los alcances a 11 categorías de color semánticas e inyecta/restablece los códigos de color ANSI.
Comportamiento ante fallos
Sección titulada «Comportamiento ante fallos»- El fallo al analizar una línea no falla la llamada: esa línea se agrega sin resaltar y el procesamiento continúa.
- El lenguaje desconocido/no compatible recurre a la sintaxis de texto sin formato.
Utilidades puras vs. flujos dependientes del sistema de archivos
Sección titulada «Utilidades puras vs. flujos dependientes del sistema de archivos»| Flujo | Acceso al sistema de archivos | Caché compartida | Notas |
|---|---|---|---|
searchContent / hasMatch | No | No | expresión regular solo sobre bytes/cadena proporcionados |
Funciones del módulo text | No | No | solo ANSI/ancho/saneamiento |
Funciones del módulo highlight | No | No | solo sintaxis + coloreado ANSI |
glob | Sí | Opcional | escaneos de directorio + filtrado glob |
fuzzyFind | Sí | Opcional | escaneos de directorio + puntuación difusa |
grep (ruta de archivo/directorio) | Sí | Opcional (modo directorio) | ripgrep sobre archivos, filtros/callback opcionales |
Resumen del ciclo de vida de extremo a extremo
Sección titulada «Resumen del ciclo de vida de extremo a extremo»- El llamador invoca el wrapper de TS con opciones tipadas.
- El wrapper normaliza los valores predeterminados (especialmente
glob) y los reenvía a la exportaciónnative.*. - Rust valida/normaliza las opciones y construye la configuración del comparador/búsqueda.
- Para los flujos del sistema de archivos, las entradas se escanean (acierto/fallo/reescaneo de caché) y luego se filtran/puntúan.
- Los bucles de trabajo llaman periódicamente al heartbeat de cancelación; el tiempo de espera/cancelación puede terminar la ejecución.
- Rust conforma las salidas en objetos N-API (
lineNumber,matchCount,limitReached, etc.). - El wrapper de TS devuelve objetos JS tipados (y callbacks opcionales por coincidencia para
grep/glob).