- Início
- Documentation
- Nativos
- Runtime do Carregador de Addon Nativo
Runtime do Carregador de Addon Nativo
Este documento analisa em profundidade a camada de carregamento/validação de addon em @f5-sales-demo/pi-natives: como native.ts decide qual arquivo .node carregar, quando a extração de payload embutido é executada e como falhas de inicialização são reportadas.
Arquivos de implementação
Seção intitulada “Arquivos de implementação”packages/natives/src/native.tspackages/natives/src/embedded-addon.tspackages/natives/src/bindings.tspackages/natives/package.json
Escopo e responsabilidade
Seção intitulada “Escopo e responsabilidade”As responsabilidades do carregador/runtime são intencionalmente restritas:
- Construir uma lista de candidatos para nomes de arquivos e diretórios do addon com reconhecimento de plataforma/CPU.
- Opcionalmente materializar um addon embutido em um diretório de cache versionado por usuário.
- Tentar candidatos em ordem determinística.
- Rejeitar addons obsoletos ou incompatíveis via
validateNativeantes de expor os bindings.
Fora do escopo aqui: comportamento específico de módulo para grep/text/highlight.
Entradas do runtime e estado derivado
Seção intitulada “Entradas do runtime e estado derivado”Na inicialização do módulo (export const native = loadNative();), native.ts computa o contexto estático:
- Tag de plataforma:
${process.platform}-${process.arch}(por exemplodarwin-arm64). - Versão do pacote: de
packages/natives/package.json(campoversion). - Diretórios principais:
nativeDir:packages/natives/nativelocal ao pacote.execDir: diretório contendoprocess.execPath.versionedDir:<getNativesDir()>/<packageVersion>.- Fallback
userDataDir:- Windows:
%LOCALAPPDATA%/xcsh(ou%USERPROFILE%/AppData/Local/xcsh). - Não-Windows:
~/.local/bin.
- Windows:
- Modo binário compilado (
isCompiledBinary): verdadeiro se qualquer uma das condições for atendida:- Variável de ambiente
PI_COMPILEDestá definida, ou import.meta.urlcontém marcadores embutidos do Bun ($bunfs,~BUN,%7EBUN).
- Variável de ambiente
- Override de variante:
PI_NATIVE_VARIANT(apenasmodern/baseline; valores inválidos são ignorados). - Variante selecionada: override explícito, caso contrário detecção de AVX2 em tempo de execução no x64 (
modernse AVX2, senãobaseline).
Suporte de plataforma e resolução de tag
Seção intitulada “Suporte de plataforma e resolução de tag”SUPPORTED_PLATFORMS é fixado em:
linux-x64linux-arm64darwin-x64darwin-arm64win32-x64
Detalhes de comportamento:
- Plataformas não suportadas não são rejeitadas antecipadamente.
- O carregador ainda tenta todos os candidatos computados primeiro.
- Se nada for carregado, ele lança um erro explícito de plataforma não suportada listando as tags suportadas.
Isso preserva diagnósticos úteis para casos de quase-acerto enquanto ainda falha de forma definitiva para alvos verdadeiramente não suportados.
Seleção de variante (modern / baseline / padrão)
Seção intitulada “Seleção de variante (modern / baseline / padrão)”Comportamento x64
Seção intitulada “Comportamento x64”- Se
PI_NATIVE_VARIANTémodernoubaseline, esse valor prevalece. - Caso contrário, detecta suporte a AVX2:
- Linux: escaneia
/proc/cpuinfoporavx2. - macOS: consulta
sysctl(machdep.cpu.leaf7_features, fallbackmachdep.cpu.features). - Windows: executa PowerShell
[System.Runtime.Intrinsics.X86.Avx2]::IsSupported.
- Linux: escaneia
- Resultado:
- AVX2 disponível ->
modern - AVX2 indisponível/indetectável ->
baseline
- AVX2 disponível ->
Comportamento não-x64
Seção intitulada “Comportamento não-x64”- Nenhuma variante é usada; o carregador permanece com o nome de arquivo padrão (
pi_natives.<platform>-<arch>.node).
Construção do nome de arquivo
Seção intitulada “Construção do nome de arquivo”Dado tag = <platform>-<arch>:
- Não-x64 ou sem variante:
pi_natives.<tag>.node - x64 +
modern: tenta na ordempi_natives.<tag>-modern.nodepi_natives.<tag>-baseline.node(fallback intencional)
- x64 +
baseline: apenaspi_natives.<tag>-baseline.node
O addonLabel usado nas mensagens de erro finais é <tag> ou <tag> (<variant>).
Construção do caminho de candidatos e ordenação de fallback
Seção intitulada “Construção do caminho de candidatos e ordenação de fallback”native.ts constrói pools de candidatos antes de qualquer chamada require(...).
Candidatos de release
Seção intitulada “Candidatos de release”Construídos a partir da lista de nomes de arquivos resolvida por variante e pesquisados nesta ordem:
-
Runtime não compilado:
<nativeDir>/<filename><execDir>/<filename>
-
Runtime compilado (
PI_COMPILEDou marcadores embutidos do Bun):<versionedDir>/<filename><userDataDir>/<filename><nativeDir>/<filename><execDir>/<filename>
dedupedCandidates remove duplicatas preservando a ordem da primeira ocorrência.
Sequência final do runtime
Seção intitulada “Sequência final do runtime”No momento do carregamento:
- Candidato de extração embutida opcional (se produzido) é inserido no início.
- Candidatos deduplicados restantes são tentados em ordem.
- O primeiro candidato que tanto executa
require(...)quanto passa emvalidateNative(...)vence.
Ciclo de vida da extração de addon embutido
Seção intitulada “Ciclo de vida da extração de addon embutido”embedded-addon.ts define uma forma de manifesto gerado:
platformTagversionfiles[]onde cada entrada possuivariant,filename,filePath
O padrão atual no repositório é embeddedAddon: null; artefatos compilados podem substituir isso com metadados reais.
Máquina de estados da extração
Seção intitulada “Máquina de estados da extração”A extração (maybeExtractEmbeddedAddon) executa apenas quando todas as condições são atendidas:
isCompiledBinary === trueembeddedAddon !== nullembeddedAddon.platformTag === platformTagembeddedAddon.version === packageVersion- Um arquivo embutido apropriado para a variante é encontrado
A seleção de arquivo por variante espelha a intenção da variante do runtime:
- Não-x64: preferir
default, depois o primeiro arquivo disponível. - x64 +
modern: preferirmodern, fallback parabaseline. - x64 +
baseline: exigirbaseline.
Comportamento de materialização:
- Garantir que
<versionedDir>existe (mkdirSync(..., { recursive: true })). - Se
<versionedDir>/<selected filename>já existe, reutilizá-lo (sem reescrita). - Caso contrário, ler o
filePathfonte embutido e gravar o arquivo de destino. - Retornar o caminho de destino para a tentativa de carregamento de maior prioridade.
Em caso de falha, a extração não causa crash imediatamente; ela adiciona uma entrada de erro (falha na criação de diretório ou gravação) e o carregador prossegue para a sondagem normal de candidatos.
Ciclo de vida e transições de estado
Seção intitulada “Ciclo de vida e transições de estado”Init -> Compute platform/version/variant/candidate lists -> (Compiled + embedded manifest matches?) yes -> Try extract embedded to versionedDir (record errors, continue) no -> Skip extraction -> For each runtime candidate in order: require(candidate) -> success: validateNative -> pass: return bindings (READY) -> fail: record error, continue -> failure: record error, continue -> none loaded: if unsupported platform tag -> throw Unsupported platform else -> throw Failed to load (full tried-path diagnostics + hints)Verificações de contrato do validateNative
Seção intitulada “Verificações de contrato do validateNative”validateNative(bindings, source) impõe um contrato somente de funções sobre NativeBindings na inicialização.
Mecânica:
- Para cada nome de exportação requerido, verifica
typeof bindings[name] === "function". - Nomes ausentes são agregados.
- Se algum estiver ausente, o carregador lança:
- caminho do addon fonte,
- lista de exportações ausentes,
- dica de comando de rebuild.
Esta é uma porta de compatibilidade rígida contra binários obsoletos, builds parciais e desvio de símbolos/nomes.
Mapeamento da API JS ↔ exportação nativa (porta de validação)
Seção intitulada “Mapeamento da API JS ↔ exportação nativa (porta de validação)”Nome do binding JS verificado em validateNative | Nome esperado da exportação nativa |
|---|---|
grep | grep |
glob | glob |
highlightCode | highlightCode |
executeShell | executeShell |
PtySession | PtySession |
Shell | Shell |
visibleWidth | visibleWidth |
getSystemInfo | getSystemInfo |
getWorkProfile | getWorkProfile |
invalidateFsScanCache | invalidateFsScanCache |
Nota: bindings.ts declara apenas o membro base cancelWork(id); arquivos types.ts dos módulos fazem declaration-merge de símbolos adicionais que validateNative impõe.
Comportamento de falha e diagnósticos
Seção intitulada “Comportamento de falha e diagnósticos”Plataforma não suportada
Seção intitulada “Plataforma não suportada”Se todos os candidatos falharem e platformTag não estiver em SUPPORTED_PLATFORMS, o carregador lança:
Unsupported platform: <tag>- Lista completa de plataformas suportadas
- Orientação explícita para reportar problemas
Sintomas de binário obsoleto / incompatibilidade
Seção intitulada “Sintomas de binário obsoleto / incompatibilidade”Sinal típico de incompatibilidade de binário obsoleto:
Native addon missing exports (<candidate>). Missing: ...
Causas comuns:
- Binário
.nodeantigo de versão/forma de API anterior do pacote. - Artefato de variante incorreto selecionado (para x64).
- Nova exportação Rust não presente no artefato carregado.
Comportamento do carregador:
- Registra falhas de exportações ausentes por candidato.
- Continua sondando os candidatos restantes.
- Se nenhum candidato validar, o erro final inclui cada caminho tentado com cada mensagem de falha.
Falhas de inicialização em binário compilado
Seção intitulada “Falhas de inicialização em binário compilado”No modo compilado, os diagnósticos finais incluem:
- caminhos esperados do cache versionado (
<versionedDir>/<filename>), - remediação para excluir o
<versionedDir>obsoleto e reexecutar, - comandos
curlde download direto de release para cada nome de arquivo esperado.
Falhas de inicialização não compiladas
Seção intitulada “Falhas de inicialização não compiladas”No modo normal de pacote/runtime, os diagnósticos finais incluem:
- dica de reinstalação (
bun install @f5-sales-demo/pi-natives), - comando de rebuild local (
bun --cwd=packages/natives run build), - dica opcional de build de variante x64 (
TARGET_VARIANT=baseline|modern ...).
Comportamento do runtime
Seção intitulada “Comportamento do runtime”- O carregador sempre usa a cadeia de candidatos de release.
- Definir
PI_DEVapenas habilita diagnósticos por candidato no console (Loaded native addon...e erros de carregamento).