Le registre de contributions
Un registre par type, derrière une inscription unique : K.contribute(type, entree). Le type n'est pas fermé, un point de contribution nouveau se déclare sans toucher au noyau. Toute inscription rend un jeton de libération, agrégé par source, ce qui permet de décharger un plugin sans que le noyau connaisse la nature de ses contributions.
Types en usage
| Type | API de haut niveau | Surfaces qui la lisent |
|---|---|---|
| command | K.commands.register(spec) | Palette, menus, raccourcis, panneau Actions, scripts |
| panel | K.shell.registerPanel(spec) | Docks, menu Affichage, sélecteur de panneaux |
| setting | K.settings.declare(spec) | Préférences |
| widget | K.dashboard.registerWidget(spec) | Tableau de bord |
| editor | K.editors.register(spec) | Onglets de la zone centrale |
Les tâches et les connecteurs ne passent pas par contribute : le moteur de workflows tient sa propre table (K.workflows.declarerTache), et le registre de connecteurs la sienne. Tous deux rendent malgré tout un jeton de libération, et émettent un évènement à chaque mutation.
Enveloppe d'une contribution
| Champ | Description |
|---|---|
| id | Requis. Une inscription sans identifiant lève. |
| source | core par défaut. Sinon l'identifiant du plugin, ou user. |
| title | Objet {fr, en}, ou une clé de translations.js si la source est le cœur. |
| declarative | Drapeau. Contribution issue d'un manifeste, donc connue avant toute exécution. |
Règle de remplacement
Une source peut remplacer sa propre contribution. Le cas visé n'est pas un doublon : un plugin déclare une commande dans son manifeste, puis, une fois activé, enregistre son implémentation réelle sous le même identifiant.
Une source ne peut jamais écraser celle d'une autre. Le noyau écrit un avertissement en console et rend un jeton inerte. Cette règle empêche un plugin de reprendre à son compte la navigation du noyau en déclarant core.go.dashboard.
Déclaratif contre impératif
Le drapeau declarative distingue ce qui vient d'un manifeste, donc connu avant toute exécution, de ce qui vient de code déjà actif. Une commande déclarative n'a pas de handler : elle apparait dans la palette, et son invocation déclenche le réveil de sa source.
Si l'activation aboutit sans installer de handler, le dispatch échoue explicitement : Commande sans gestionnaire après activation.
Jetons et libération
Chaque jeton est ajouté à un agrégat par source. La libération se fait en ordre inverse d'inscription : une contribution tardive peut dépendre d'une contribution antérieure, jamais l'inverse. releaseSource() remplace le démontage manuel, qui devait énumérer chaque puits et risquait d'en oublier un.
Évènements
| Évènement | Charge utile | Émis par |
|---|---|---|
| registry.changed | {type, id, added} | Noyau, à chaque mutation. |
| command.before | {id, args} | Noyau, après les gardes, avant le handler. |
| command.after | {id, args, result} | Noyau, après succès. |
| command.error | {id, args, error} | Noyau, sur refus ou échec. |
| setting.changed | {id, value, layer} | Réglages. |
| workflow.tasks.changed | {id} | Moteur de workflows. |
| dashboard.changed | Aucune | Registre de widgets. |
Hooks annulables
K.events.emitBlocking(nom, charge) attend ses abonnés et renvoie false si l'un d'eux a annulé. C'est le point d'injection propre pour les scripts de surcharge, qui peuvent ainsi refuser une sauvegarde ou un lancement de moteur sans toucher au cœur. Les abonnés peuvent être asynchrones.
Réglages en couches
Quatre couches, de la moins prioritaire à la plus prioritaire : default, edition, user, project. La valeur effective est calculée à la lecture, jamais figée à l'écriture : sans cela, une surcharge posée tardivement n'aurait aucun effet sur ce qui a déjà lu.
Le menu natif ne suit pas le registre
La barre de menus est native, construite en Rust au démarrage, et ne se reconstruit pas. Le menu Affichage liste les panneaux du noyau, connus à la compilation, puis une entrée Tous les panneaux... qui lit le registre au moment de l'ouverture. C'est le seul endroit où apparaissent les panneaux de plugins.
Le pont Rust vers JS passe par window.IsoFindPanelMenu.activer(rang), qui exécute la commande <id>.toggle correspondante. Les coches sont resynchronisées sur registry.changed et command.after.