- Accueil
- Documentation
- Natifs
- Runtime du chargeur d'addon natif
Runtime du chargeur d'addon natif
Ce document examine en profondeur la couche de chargement/validation des addons dans @f5-sales-demo/pi-natives : comment native.ts décide quel fichier .node charger, quand l’extraction de la charge utile embarquée s’exécute, et comment les échecs au démarrage sont signalés.
Fichiers d’implémentation
Section intitulée « Fichiers d’implémentation »packages/natives/src/native.tspackages/natives/src/embedded-addon.tspackages/natives/src/bindings.tspackages/natives/package.json
Périmètre et responsabilité
Section intitulée « Périmètre et responsabilité »Les responsabilités du chargeur/runtime sont intentionnellement restreintes :
- Construire une liste de candidats tenant compte de la plateforme et du CPU pour les noms de fichiers et répertoires des addons.
- Optionnellement matérialiser un addon embarqué dans un répertoire de cache versionné par utilisateur.
- Essayer les candidats dans un ordre déterministe.
- Rejeter les addons obsolètes ou incompatibles via
validateNativeavant d’exposer les bindings.
Hors périmètre ici : le comportement spécifique aux modules grep/text/highlight.
Entrées du runtime et état dérivé
Section intitulée « Entrées du runtime et état dérivé »À l’initialisation du module (export const native = loadNative();), native.ts calcule le contexte statique :
- Tag de plateforme :
${process.platform}-${process.arch}(par exempledarwin-arm64). - Version du package : depuis
packages/natives/package.json(champversion). - Répertoires principaux :
nativeDir: local au packagepackages/natives/native.execDir: répertoire contenantprocess.execPath.versionedDir:<getNativesDir()>/<packageVersion>.- Repli
userDataDir:- Windows :
%LOCALAPPDATA%/xcsh(ou%USERPROFILE%/AppData/Local/xcsh). - Non-Windows :
~/.local/bin.
- Windows :
- Mode binaire compilé (
isCompiledBinary) : vrai si l’une des conditions suivantes est remplie :- La variable d’environnement
PI_COMPILEDest définie, ou import.meta.urlcontient des marqueurs embarqués Bun ($bunfs,~BUN,%7EBUN).
- La variable d’environnement
- Surcharge de variante :
PI_NATIVE_VARIANT(modern/baselineuniquement ; les valeurs invalides sont ignorées). - Variante sélectionnée : surcharge explicite, sinon détection AVX2 au runtime sur x64 (
modernsi AVX2, sinonbaseline).
Support des plateformes et résolution des tags
Section intitulée « Support des plateformes et résolution des tags »SUPPORTED_PLATFORMS est fixé à :
linux-x64linux-arm64darwin-x64darwin-arm64win32-x64
Détail du comportement :
- Les plateformes non supportées ne sont pas rejetées immédiatement.
- Le chargeur essaie d’abord tous les candidats calculés.
- Si rien ne se charge, il lève une erreur explicite de plateforme non supportée listant les tags supportés.
Cela préserve des diagnostics utiles pour les cas presque compatibles tout en échouant de manière ferme pour les cibles véritablement non supportées.
Sélection de variante (modern / baseline / défaut)
Section intitulée « Sélection de variante (modern / baseline / défaut) »Comportement x64
Section intitulée « Comportement x64 »- Si
PI_NATIVE_VARIANTestmodernoubaseline, cette valeur prévaut. - Sinon, détecter le support AVX2 :
- Linux : scanner
/proc/cpuinfopouravx2. - macOS : interroger
sysctl(machdep.cpu.leaf7_features, repli surmachdep.cpu.features). - Windows : exécuter PowerShell
[System.Runtime.Intrinsics.X86.Avx2]::IsSupported.
- Linux : scanner
- Résultat :
- AVX2 disponible ->
modern - AVX2 indisponible/indétectable ->
baseline
- AVX2 disponible ->
Comportement non-x64
Section intitulée « Comportement non-x64 »- Aucune variante n’est utilisée ; le chargeur reste sur le nom de fichier par défaut (
pi_natives.<platform>-<arch>.node).
Construction du nom de fichier
Section intitulée « Construction du nom de fichier »Étant donné tag = <platform>-<arch> :
- Non-x64 ou pas de variante :
pi_natives.<tag>.node - x64 +
modern: essayer dans l’ordrepi_natives.<tag>-modern.nodepi_natives.<tag>-baseline.node(repli intentionnel)
- x64 +
baseline: uniquementpi_natives.<tag>-baseline.node
Le addonLabel utilisé dans les messages d’erreur finaux est soit <tag> soit <tag> (<variant>).
Construction des chemins candidats et ordre de repli
Section intitulée « Construction des chemins candidats et ordre de repli »native.ts construit des pools de candidats avant tout appel require(...).
Candidats de release
Section intitulée « Candidats de release »Construits à partir de la liste de noms de fichiers résolus par variante et recherchés dans cet ordre :
-
Runtime non compilé :
<nativeDir>/<filename><execDir>/<filename>
-
Runtime compilé (
PI_COMPILEDou marqueurs embarqués Bun) :<versionedDir>/<filename><userDataDir>/<filename><nativeDir>/<filename><execDir>/<filename>
dedupedCandidates supprime les doublons tout en préservant l’ordre de première occurrence.
Séquence finale au runtime
Section intitulée « Séquence finale au runtime »Au moment du chargement :
- Le candidat optionnel d’extraction embarquée (s’il a été produit) est inséré en tête.
- Les candidats dédupliqués restants sont essayés dans l’ordre.
- Le premier candidat qui réussit à la fois le
require(...)et passevalidateNative(...)est retenu.
Cycle de vie de l’extraction de l’addon embarqué
Section intitulée « Cycle de vie de l’extraction de l’addon embarqué »embedded-addon.ts définit une structure de manifeste généré :
platformTagversionfiles[]où chaque entrée possèdevariant,filename,filePath
La valeur par défaut actuellement committée est embeddedAddon: null ; les artefacts compilés peuvent remplacer ceci par de véritables métadonnées.
Machine à états de l’extraction
Section intitulée « Machine à états de l’extraction »L’extraction (maybeExtractEmbeddedAddon) s’exécute uniquement lorsque toutes les conditions sont remplies :
isCompiledBinary === trueembeddedAddon !== nullembeddedAddon.platformTag === platformTagembeddedAddon.version === packageVersion- Un fichier embarqué approprié à la variante est trouvé
La sélection du fichier de variante reflète l’intention de variante au runtime :
- Non-x64 : préférer
default, puis le premier fichier disponible. - x64 +
modern: préférermodern, repli surbaseline. - x64 +
baseline: exigerbaseline.
Comportement de matérialisation :
- S’assurer que
<versionedDir>existe (mkdirSync(..., { recursive: true })). - Si
<versionedDir>/<selected filename>existe déjà, le réutiliser (pas de réécriture). - Sinon, lire le
filePathsource embarqué et écrire le fichier cible. - Retourner le chemin cible pour la tentative de chargement de plus haute priorité.
En cas d’échec, l’extraction ne plante pas immédiatement ; elle ajoute une entrée d’erreur (échec de création de répertoire ou d’écriture) et le chargeur passe au sondage normal des candidats.
Cycle de vie et transitions d’état
Section intitulée « Cycle de vie et transitions d’état »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)Vérifications contractuelles de validateNative
Section intitulée « Vérifications contractuelles de validateNative »validateNative(bindings, source) applique un contrat exclusivement basé sur les fonctions sur NativeBindings au démarrage.
Mécanisme :
- Pour chaque nom d’export requis, il vérifie
typeof bindings[name] === "function". - Les noms manquants sont agrégés.
- Si certains sont manquants, le chargeur lève une erreur contenant :
- le chemin de l’addon source,
- la liste des exports manquants,
- une indication de commande de reconstruction.
Il s’agit d’une barrière de compatibilité stricte contre les binaires obsolètes, les builds partiels et la dérive de symboles/noms.
Correspondance API JS ↔ exports natifs (barrière de validation)
Section intitulée « Correspondance API JS ↔ exports natifs (barrière de validation) »Nom du binding JS vérifié dans validateNative | Nom d’export natif attendu |
|---|---|
grep | grep |
glob | glob |
highlightCode | highlightCode |
executeShell | executeShell |
PtySession | PtySession |
Shell | Shell |
visibleWidth | visibleWidth |
getSystemInfo | getSystemInfo |
getWorkProfile | getWorkProfile |
invalidateFsScanCache | invalidateFsScanCache |
Note : bindings.ts déclare uniquement le membre de base cancelWork(id) ; les fichiers types.ts des modules effectuent une fusion de déclarations pour les symboles supplémentaires que validateNative impose.
Comportement en cas d’échec et diagnostics
Section intitulée « Comportement en cas d’échec et diagnostics »Plateforme non supportée
Section intitulée « Plateforme non supportée »Si tous les candidats échouent et que platformTag n’est pas dans SUPPORTED_PLATFORMS, le chargeur lève :
Unsupported platform: <tag>- La liste complète des plateformes supportées
- Des indications explicites pour signaler un problème
Symptômes de binaire obsolète / incompatible
Section intitulée « Symptômes de binaire obsolète / incompatible »Signal typique d’incompatibilité obsolète :
Native addon missing exports (<candidate>). Missing: ...
Causes courantes :
- Ancien binaire
.nodeprovenant d’une version précédente du package/de la forme de l’API. - Mauvais artefact de variante sélectionné (pour x64).
- Nouvel export Rust absent de l’artefact chargé.
Comportement du chargeur :
- Enregistre les échecs d’exports manquants par candidat.
- Continue le sondage des candidats restants.
- Si aucun candidat n’est validé, l’erreur finale inclut chaque chemin tenté avec chaque message d’échec.
Échecs de démarrage en mode binaire compilé
Section intitulée « Échecs de démarrage en mode binaire compilé »En mode compilé, les diagnostics finaux incluent :
- les chemins cibles attendus du cache versionné (
<versionedDir>/<filename>), - une remédiation consistant à supprimer le
<versionedDir>obsolète et relancer, - des commandes
curlde téléchargement direct de la release pour chaque nom de fichier attendu.
Échecs de démarrage en mode non compilé
Section intitulée « Échecs de démarrage en mode non compilé »En mode package/runtime normal, les diagnostics finaux incluent :
- une indication de réinstallation (
bun install @f5-sales-demo/pi-natives), - une commande de reconstruction locale (
bun --cwd=packages/natives run build), - une indication optionnelle de build de variante x64 (
TARGET_VARIANT=baseline|modern ...).
Comportement au runtime
Section intitulée « Comportement au runtime »- Le chargeur utilise toujours la chaîne de candidats de release.
- Définir
PI_DEVactive uniquement les diagnostics par candidat dans la console (Loaded native addon...et les erreurs de chargement).