Ce guide décrit @newvexa/flowora@0.1.0-beta.2, reçue et vérifiée pour l’intégration locale du site. La version publique npm sous MIT reste 0.1.0-beta.1 : @next fournit cette beta.1, pas les nouveaux panneaux ni updateConnection() et les noms de liens présentés ici. Consultez le statut et l’installation de la candidate avant de réutiliser l’exemple.
Créer un lien avec les quatre sélecteurs
Dans le vrai composant Angular, ouvrez Gérer les liens depuis le rail d’outils de l’éditeur ou le menu contextuel du canvas. Le panneau présente le formulaire Ajouter un lien, puis la liste Liens existants. Vous pouvez aussi relier les ports sur le canvas ; le formulaire permet de choisir explicitement chaque extrémité.
- Dans Nœud source, choisissez une étape possédant une sortie.
- Dans Port de sortie, choisissez l’un de ses ports
outputs. Le libellé indique le type et l’identifiant du port. - Dans Nœud cible, choisissez une étape possédant une entrée.
- Dans Port d’entrée, choisissez l’un de ses ports
inputs. - Renseignez éventuellement Nom du lien (facultatif), puis cliquez sur Ajouter le lien.
Changer de nœud réinitialise le choix du port vers son premier port disponible : vérifiez les quatre sélecteurs avant l’ajout. Les groupes n’offrent pas de ports. Le store reste l’autorité pour les extrémités, les types, les cardinalités, les doublons et la politique de cycles. Un port occupé n’est pas libéré automatiquement : un formulaire invalide ne remplace ni ne supprime un lien existant, et n’enregistre pas de création partielle.
La création et son nom initial forment une seule action annulable. Le lien ajouté est sélectionné. Pour les règles de types, multiple et allowCycles, reprenez le contrat des ports et des connexions ; nommer un lien ne change aucune de ces règles.
Sélectionner, renommer et supprimer le bon lien
Dans Liens existants, chaque ligne indique le nom ou son libellé de remplacement, ses extrémités et les identifiants des ports. Cliquez sur le lien pour le sélectionner, ou sur son bouton Propriétés pour ouvrir directement Propriétés de la sélection. Le clic sur le trait du canvas reste disponible ; sa zone interactive est plus large que le trait visible.
Dans Lien sélectionné, le champ Nom du lien se trouve dans la section Identité. Modifiez-le, puis validez le changement en quittant le champ : la commande de renommage est déclenchée sur change, pas à chaque caractère. Effacez le contenu pour retrouver le libellé source → cible.
Pour retirer uniquement ce lien, utilisez Supprimer le lien dans ses propriétés, ou Supprimer sur sa ligne dans le gestionnaire. Ces commandes ciblent la connexion affichée, sans supprimer ses nœuds. Les champs de texte conservent la saisie et ne doivent pas déclencher les raccourcis de suppression du canvas.
Les commandes Annuler / Rétablir restaurent création, renommage et suppression, avec les noms. Sélectionner un lien n’ajoute pas d’entrée d’historique. Un nom n’est jamais un identifiant : le renommage conserve l’ID, le nœud source, le nœud cible et leurs ports.
Un nom facultatif, en texte brut
EditorConnection.name est une chaîne facultative limitée à 256 unités de code UTF-16, soit la longueur JavaScript string.length, pas un nombre de glyphes visibles ni d’octets UTF-8. Certains caractères, notamment des emoji, occupent deux unités. La validation portable conserve le texte exact, y compris les espaces, l’Unicode et les chaînes ressemblant à du HTML. Le renderer l’affiche comme du texte : jamais comme du HTML ou un script.
| Patch ou valeur | Résultat dans la candidate beta.2 |
|---|---|
{ name: 'Chemin principal' } | Renomme le lien existant ; seule la propriété name est acceptée. |
{ name: '' } | Efface le nom visible. La chaîne vide reste une valeur valide ; les commandes de gestion affichent un libellé dérivé des extrémités. |
{} ou un nom déjà identique | Aucun changement de snapshot ni d’historique : c’est un no-op. |
{ name: undefined }, type incorrect, propriété inconnue ou nom trop long | Refus atomique : le lien, le snapshot et l’historique ne sont pas modifiés par ce patch invalide. |
L’absence de name dans un document ancien est valide ; elle n’est pas équivalente à une propriété explicitement présente à undefined dans un patch. Pour effacer le nom par API, utilisez editor.updateConnection(connectionId, { name: '' }), pas undefined.
API portable : signatures réellement livrées
Les commandes viennent de la racine @newvexa/flowora, sans Angular, Rete, Workify ou backend. Les signatures ci-dessous sont celles des déclarations de la candidate locale, pas une API supplémentaire déjà disponible dans le registry beta.1.
| Commande | Contrat |
|---|---|
connect(source: Endpoint, target: Endpoint): string | Crée le lien et retourne son ID. Chaque Endpoint contient nodeId et portId ; il n’y a pas de troisième argument pour le nom. |
updateConnection(id: string, patch: ConnectionPatch): void | Applique un patch de nom validé. ConnectionPatch est Partial<Pick<EditorConnection, "name">>. |
getConnection(id: string): EditorConnection | undefined | Lit le lien sans le muter. |
removeConnection(id: string): void | Supprime la connexion ciblée. |
undo(): void / redo(): void | Parcourt l’historique des commandes acceptées. |
Ce programme complet reprend l’exemple portable fourni sous MIT avec la candidate. Il crée deux nœuds fictifs, vérifie leurs ports, regroupe création et nom initial dans une transaction, puis renomme, exporte, réimporte et supprime le lien avant de restaurer cette suppression. Les snippets sont du texte à compiler dans votre application, jamais des expressions exécutées par ces pages Astro.
import { Editor, createDemoDocument, type ConnectionPatch } from '@newvexa/flowora';
const editor = new Editor(createDemoDocument());
const sourceId = editor.addFromCatalog('start', { x: 0, y: 500 });
const targetId = editor.addFromCatalog('response', { x: 320, y: 500 });
const source = editor.getNode(sourceId);
const target = editor.getNode(targetId);
if (!source?.outputs[0] || !target?.inputs[0]) throw new Error('Ports manquants');
editor.beginTransaction();
let connectionId: string;
try {
connectionId = editor.connect(
{ nodeId: sourceId, portId: source.outputs[0].id },
{ nodeId: targetId, portId: target.inputs[0].id },
);
const patch: ConnectionPatch = { name: 'Chemin principal' };
editor.updateConnection(connectionId, patch);
editor.endTransaction();
} catch (error) {
editor.cancelTransaction();
throw error;
}
editor.updateConnection(connectionId, { name: 'Message de départ' });
const json = editor.toJSON();
editor.loadJSON(json);
editor.removeConnection(connectionId);
editor.undo(); // restaure le lien avec son nom
editor.dispose(); beginTransaction(), endTransaction() et cancelTransaction() regroupent l’historique et permettent d’annuler l’ensemble en cas d’erreur. Ne modifiez pas directement un snapshot. Dans un écran, gardez une instance stable par document et assurez sa libération avec dispose() lorsque son propriétaire est détruit, y compris sur vos chemins d’erreur.
documentChange : une garantie ciblée sur le formulaire
Pour le formulaire Ajouter un lien, la sortie Angular documentChange transmet une seule fois le document final après succès, avec le nom initial. Elle ne transmet pas le lien temporaire si cette action est annulée. Cette garantie concerne ce formulaire du renderer.
Les snapshots et les abonnements directs du store restent live pendant la transaction, comme pour les déplacements : Editor.subscribe() et Editor.onEvent() peuvent observer les étapes internes, notamment entre connect() et updateConnection(). Une transaction regroupe l’historique ; elle ne masque pas universellement les notifications. Si votre persistance observe directement le store, définissez sa propre politique de sauvegarde plutôt que de supposer le contrat du formulaire Angular.
JSON et historique : schemaVersion reste à 1
Le document conserve schemaVersion: 1. La candidate beta.2 accepte les anciens documents sans name sur leurs connexions, sans inventer ce champ. Les noms existants sont conservés par export/import JSON, remplacement du document, duplication des nœuds concernés et historique. Les limites du graphe et la borne globale de 32 MiB UTF-8 pour le JSON restent applicables.
La beta.1 publique valide strictement les propriétés des connexions et refuse un document contenant name, même si schemaVersion vaut toujours 1 ou si le nom est vide. Un document nommé nécessite la candidate locale beta.2 ou une version ultérieure qui conserve cette prise en charge. Effacer le nom avec name: '' n’est donc pas une conversion vers beta.1.
Identifiez explicitement la version de votre hôte avant une ouverture ou un partage. Pour l’import atomique, l’export et les contraintes de stockage local, consultez JSON & données locales. Le nom sert à l’édition : il ne crée ni routage métier, ni exécution de workflow.
Visibilité SVG : préserver la couche de connexions
Les liens sont dessinés derrière les cartes, dans les coordonnées du document. Dans beta.1, une petite boîte SVG débordante pouvait être réduite à zéro par un reset svg { max-width: 100% } appliqué sur son parent de coordonnées : des paths valides existaient alors sans trait visible. La candidate beta.2 utilise désormais un SVG dimensionné au viewport, avec position et dimensions explicites, un viewBox correspondant aux coordonnées du document et un overflow limité à cette vue. Elle protège cette couche avec max-width: none et max-height: none. Côté hôte, réservez les resets responsive aux médias concernés, pas aux couches de dessin de l’éditeur.
La présence d’un path, d’un attribut d ou un hit-test isolé ne prouve pas la visibilité. Contrôlez dans votre application les dimensions, les styles, le rendu à plusieurs zooms et les commandes sur le vrai composant Angular compilé en AOT avec linker. Ce guide n’annonce pas de nouvelle campagne navigateur et ne remplace pas cette validation. Le correctif ne réalise aucun appel HTTP métier et n’installe aucun backend.