ENbext.dev
DocumentationFonctionnalités

Traduction automatique depuis l’anglais. Consulter l’original.

Sur cette page

Capacités

Une capacité est une forme partagée que de nombreux plugins différents peuvent implémenter derrière une seule interface. C'est la chose à laquelle votre code d'application communique ; le plugin correspond à l'implémentation spécifique que vous avez installée. Lorsque vous passez d'un logiciel de messagerie à un autre, le code qui appelle mailer.send(...) ne change pas — seul le plugin derrière la fonctionnalité le fait.

Cette page explique quelles sont les capacités, pourquoi bext les possède, comment elles passent des idées expérimentales aux valeurs par défaut et comment vous en installerez une une fois que l'ensemble de base sera disponible.

Capacité vs plugin#

La distinction est importante, car les mots sont faciles à confondre :

  • Un plugin est une implémentation concrète unique. @bext/mailer-smtp est un plugin. Il sait comment ouvrir une connexion SMTP, s'authentifier et envoyer un message.
  • Une capacité est le trait – la forme – que tout plugin de messagerie doit implémenter. Mailer est une capacité. Il dit "envoyer un message, récupérer un identifiant, voici le type d'erreur".

Une fonctionnalité, de nombreux plugins. Vous choisissez le plugin ; votre code ne voit que la capacité.

text
your code
   |
   v
  Mailer (capability — stable surface)
   |
   +-- @bext/mailer-smtp       (plugin)
   +-- @bext/mailer-ses        (plugin)
   +-- @bext/mailer-resend     (plugin)
   +-- @bext/mailer-postmark   (plugin)

Si une forme mérite d'être transformée en fonctionnalité, il existe déjà deux plugins ou plus qui souhaitent l'implémenter. Une forme avec un seul backend n’est qu’un plugin avec une bonne surface de configuration – pas une fonctionnalité.

Chaque plugin déclare, dans son manifeste, quelles fonctionnalités il fournit et dont il dépend :

toml
# plugin.toml
[manifest]
name = "auth-jwt"
version = "1.0.0"
provides_capabilities = ["auth"]
requires_capabilities = ["session"]

Le registre utilise ces champs pour résoudre le graphique de dépendance lorsque vous installez un plugin, vous ne pouvez donc pas vous retrouver avec un plugin Auth qui n'a pas de backend Session derrière lui.

Pourquoi les capacités existent#

La version courte : , votre code d'application ne devrait pas avoir à se soucier de l'identité de l'expéditeur. Vous écrivez mailer.send(...) et quelqu'un d'autre (l'opérateur, l'équipe opérationnelle, la personne qui exécute l'instance de production) sélectionne le backend dans la configuration. Remplacez SMTP par SES ou SES par Resend, et rien dans votre code ne change. La capacité est le contrat qui sécurise cet échange.

La version plus longue est que bext traite la surface des capacités comme un engagement envers tous ceux qui en dépendent. Une fois qu'une fonctionnalité est stable, les plugins s'appuient sur elle, les configurations la référencent et le registre l'indexe. Remodeler la fonctionnalité plus tard briserait chacun de ces plugins à la fois. La règle est donc la suivante : , une surface à capacité stable est effectivement permanente. Nous préférons ne livrer aucune capacité plutôt qu’une capacité qui doit être repensée six mois plus tard.

C’est également la raison pour laquelle la barre est haute pour ajouter une nouvelle capacité. bext doit voir au moins deux fournisseurs réels, au moins un plugin qui veut dépendre de la capacité, une surface de caractéristiques qui ne divulgue les bizarreries d'aucun fournisseur et une implémentation de référence qui prouve que la forme tient de bout en bout. En cas de doute, cela reste un plugin.

Anti-fragmentation#

L’ajout de capacités est également soumis à des règles anti-fragmentation explicites, car le pire résultat pour un écosystème est de disposer de deux capacités qui font presque la même chose. En pratique, cela signifie :

  • Un nom, une chose. Deux fonctionnalités qui se chevauchent (par exemple, une répartition entre « cache en cours » et « cache distribué ») sont unifiées ou l'une d'entre elles est rejetée.
  • Aucune forme couplée au fournisseur. Si un trait a un champ nommé d'après l'API d'un fournisseur ( postmark_message_id, par exemple), ce n'est pas une forme partagée, c'est une interface privée portant un chapeau. Retour à la planche à dessin.
  • Aucun héritage de capacité. Un plugin qui implémente Auth n'implémente pas automatiquement également Session. Chaque fonctionnalité est autonome et un plugin qui souhaite les deux déclare les deux.

L’objectif est que chaque capacité mérite son nom parce qu’elle est distincte, utile et stable selon ses propres conditions.

L'échelle de promotion#

Une fonctionnalité n’apparaît pas comme « stable de première partie » dès le premier jour. Il parcourt une échelle et chaque échelon porte un engagement spécifique sur ce que le bext brisera et ne brisera pas.

Étape 1 — Expérimental#

La fonctionnalité existe comme preuve de concept, généralement dans le dépôt personnel de quelqu'un. Le dépôt bext n’en est pas informé. Il se peut qu'un petit groupe d'utilisateurs l'exécute. Il n'y a aucun test de conformité, aucune signature, aucune inscription dans le registre. Tout peut changer sans prévenir.

Étape 2 — Aperçu#

La fonctionnalité est publiée dans le registre sous l'espace de noms @preview/. Vous pouvez l'installer, mais le chemin d'installation vous avertit que vous optez pour le code d'aperçu. Il n'y a aucune garantie de compatibilité ascendante : une fonctionnalité de prévisualisation peut être remodelée dans la prochaine version. L'aperçu est l'endroit où les utilisateurs sérieux échangent la stabilité contre un accès anticipé, et leurs rapports de bogues expliquent comment la forme est renforcée.

Étape 3 — Stable propriétaire#

La fonctionnalité réside sous l’espace de noms @bext/. Sa surface de traits est verrouillée, le harnais de plugins exécute une suite de conformité pour chaque fournisseur, la documentation est disponible sur ce site et la forme est prise en charge indéfiniment. Le supprimer ou le renommer nécessite un successeur nommé et une fenêtre de migration suffisamment longue pour que l'écosystème puisse suivre.

Étape 4 — Par défaut#

La fonctionnalité est installée par défaut sur les nouveaux sites échafaudés par bext new. Il s’agit de l’échelon le plus élevé : cette capacité est si universellement utile que ne pas l’avoir est une surprise. Très peu de capacités atteignent ce niveau.

Engagements de stabilité#

Chaque ligne comporte une fenêtre explicite de stabilité de l'API :

Niveau Stabilité de l'API Fenêtre de compatibilité ascendante
Expérimental Aucun Aucun
Aperçu Version du correctif stable 60 jours
Première partie Version majeure stable 18 mois
Défaut Fermé; la dépréciation nécessite un successeur nommé 24 mois

Les manifestes de plugin déclarent leur propre niveau de stabilité, donc un plugin qui dépend d'une fonctionnalité de prévisualisation hérite des garanties de prévisualisation, et un plugin sur une fonctionnalité propriétaire hérite de la longue fenêtre. Si vous expédiez une production, ciblez la première partie ou la valeur par défaut.

Conseil

Si vous recherchez un plugin qui effectue un travail spécifique (SMTP, sessions Redis, traçage OTLP…), accédez directement aux pages de fonctionnalités individuelles — Authentification, Session, Courrier, Traceur ou Programmé. Cette page est la base conceptuelle sur laquelle ces pages s'appuient.

Les cinq capacités fondamentales#

Cinq capacités constituent la base dont dépendent la plupart des autres. Ils arriveront bientôt sous la forme de la première vague de fonctionnalités stables et propriétaires, chacune avec une véritable surface de traits, deux ou plusieurs plugins de référence et une suite de tests de conformité.

Authentification#

Qui est l’appelant. Un plug-in Auth résout une demande adressée à un utilisateur authentifié, exécute les flux de connexion et de rappel, et émet ou actualise une session. Il ne stocke pas la session elle-même (c'est le travail de la fonctionnalité Session), ce qui signifie que vous pouvez mélanger une stratégie d'authentification JWT avec un magasin de session Redis, ou une authentification par lien magique avec des sessions uniquement par cookies.

Session#

Là où réside la preuve d’identité. Un plugin Session est un magasin : créez une session, lisez-la par identifiant, mettez-la à jour, supprimez-la, touchez-la pour la maintenir en vie. Les backends vont des cookies cryptés apatrides à Redis et Postgres. Les plugins d'authentification dépendent de Session, c'est pourquoi les deux sont livrés ensemble.

Courrier#

Envoyez un e-mail transactionnel. Un plugin Mailer prend un message et renvoie un identifiant de message. SMTP, SES, Resend, Postmark — chaque projet réel en choisit un, et la fonctionnalité lui permet de choisir dans la configuration. Votre code appelle mailer.send(...) et ne pense plus jamais au backend.

Traceur#

Émet un span. Un plugin Tracer est un exportateur de traçage : démarrer un span, terminer un span, attacher des attributs, vider le backend. OTLP, Datadog, Honeycomb et stdout (pour les développeurs) sont tous des cibles valides. Les crochets d'observabilité internes du bext produisent des travées ; le Tracer actif décide où ils vont.

Programmé#

Exécuter une tâche selon une planification. Un plugin Scheduled déclare une ou plusieurs planifications (expression cron, gigue, politique d'exécution manquée) et le runtime de bext les appelle au bon moment. Sur les déploiements multi-instances, le planificateur utilise la fonctionnalité Locking pour garantir qu'une exécution donnée se déclenche une fois dans la flotte, et non une fois par instance.

Comment installer une fonctionnalité#

Les fonctionnalités apparaissent dans votre projet via la CLI. L'installation d'un plugin qui fournit ou nécessite une fonctionnalité se fait en une seule commande :

bash
bext plugins install @bext/auth-jwt

La CLI lit le manifeste du plugin, voit qu'il nécessite la fonctionnalité Session et vous guide dans la sélection d'un backend de session si aucun n'est encore configuré. Il en va de même pour toute dépendance de capacité : la CLI fait apparaître ce qui est nécessaire et vous invite à le résoudre, afin que vous ne vous retrouviez jamais avec un graphique de dépendance brisé au moment de l'exécution.

Installations non interactives#

Remarque

Une fonctionnalité de prévisualisation peut être remodelée sur n'importe quelle version ; sa fenêtre de compatibilité ascendante de 60 jours s'applique par correctif et non par mineur. Si vous expédiez en production, ciblez uniquement les fonctionnalités propriétaires (espace de noms @bext/) ou par défaut.

Si stdin n'est pas un TTY, ou si vous transmettez --yes / -y, ou si vous exportez BEXT_NONINTERACTIVE=1, l'installation s'exécute sans invite et sélectionne automatiquement le premier candidat pour chaque fonctionnalité non satisfaite. Cela vous permet d'installer des scripts dans CI ou Dockerfiles :

bash
BEXT_NONINTERACTIVE=1 bext plugins install ./auth-jwt.wasm
# or
bext plugins install ./auth-jwt.wasm --yes

Les valeurs par défaut sont intentionnelles : @bext/session-cookie pour session, @bext/auth-jwt pour auth, @bext/mailer-smtp pour mailer, @bext/tracer-otlp pour tracer et @bext/cron pour scheduled. Si vous avez besoin d'un backend différent, installez-le d'abord, puis installez le plugin dépendant — la CLI verra la fonctionnalité déjà satisfaite et ne vous le demandera pas.

Une fois installée, la fonctionnalité est automatiquement connectée. Votre code l'utilise via l'API de fonction hôte exposée aux plugins ( auth.user(), mailer.send(...), trace.span(...) ) ou via la configuration dans bext.config.toml :

toml
[auth]
provider = "jwt"

[session]
backend = "cookie"

[mailer]
backend = "ses"

[tracer]
exporter = "otlp"

L'échange du backend est un changement de configuration. Le code qui appelle la fonctionnalité reste exactement le même.

Où aller ensuite#

  • Le aperçu du système de plugins couvre les niveaux sandbox (QuickJS, WASM, nsjail) dans lesquels les fonctionnalités s'exécutent.
  • Construire un plugin montre comment créer un plugin ; l'implémentation d'une fonctionnalité est le même flux et la déclaration de provides_capabilities dans le manifeste.
  • Édition explique comment obtenir un plugin dans l'espace de noms du registre @preview/, qui est le premier véritable échelon de l'échelle de promotion.
Modifier cette page ↗Besoin d’aide ? ↗
Rechercher dans la documentation

Saisissez un sujet, une commande ou une question.