Aucun remplacement automatique d’imports.

Flowora est indépendant de Rete et de Workify. Ses types, commandes, hooks, templates et options ne sont pas compatibles par renommage avec les plugins ou presets Rete. Ce guide décrit un travail applicatif, pas un patch universel de migration.

Extraire d’abord des données neutres

Sortez les informations métier des instances ClassicPreset : identifiants, types, noms, propriétés JSON, ports, positions, dimensions, liens et groupements. Aucun objet Rete, composant Angular ou handler d’exécution ne doit entrer dans EditorDocument. Préservez les identifiants utilisés par vos propriétés et votre backend ; sinon, établissez et conservez une table de conversion explicite.

Le viewport du renderer existant doit être converti en x, y et zoom Flowora. Les coordonnées des enfants sont absolues : si votre plugin de groupes les stocke relativement à un parent, composez ces coordonnées avant la conversion. Ne supposez pas qu’une position de DOM est une position du graphe.

Un adaptateur typé, après extraction par votre application

L’exemple ci-dessous accepte un DTO normalisé que votre application produit depuis sa version réelle de Rete et ses plugins. Il préfixe les identifiants de ports par direction et valide le résultat. Il ne prétend pas connaître l’API d’export de votre projet. Les identifiants, clés de sockets et types doivent respecter les règles Flowora ; adaptez leur table de correspondance si nécessaire.

TypeScript · conversion DTO vers EditorDocument
import { validateDocument } from '@newvexa/flowora';
import type { EditorDocument, JsonObject, Port, Viewport } from '@newvexa/flowora';

// DTO applicatif que VOUS extrayez depuis votre éditeur Rete.
// Ce n'est pas une API Rete, ni un format universel de plugin.
interface LegacySocketDTO {
  readonly key: string;
  readonly label: string;
  readonly type: string;
  readonly multiple: boolean;
}
interface LegacyNodeDTO {
  readonly id: string;
  readonly type: string;
  readonly name: string;
  readonly x: number;
  readonly y: number;
  readonly width: number;
  readonly height: number;
  readonly data: JsonObject;
  readonly inputs: readonly LegacySocketDTO[];
  readonly outputs: readonly LegacySocketDTO[];
  readonly parentId?: string;
}
interface LegacyLinkDTO {
  readonly id: string;
  readonly source: string;
  readonly outputKey: string;
  readonly target: string;
  readonly inputKey: string;
}
export interface LegacyDocumentDTO {
  readonly id: string;
  readonly name: string;
  readonly nodes: readonly LegacyNodeDTO[];
  readonly links: readonly LegacyLinkDTO[];
  readonly viewport: Viewport;
}

function port(socket: LegacySocketDTO, direction: 'input' | 'output'): Port {
  return {
    // Préfixes pour éviter une collision entre entrée et sortie du même nœud.
    id: direction + '-' + socket.key,
    label: socket.label,
    type: socket.type,
    multiple: socket.multiple,
  };
}

export function migrateReteDTO(source: LegacyDocumentDTO): EditorDocument {
  return validateDocument({
    schemaVersion: 1,
    id: source.id,
    name: source.name,
    nodes: source.nodes.map((node) => ({
      id: node.id,
      type: node.type,
      name: node.name,
      position: { x: node.x, y: node.y },
      width: node.width,
      height: node.height,
      inputs: node.inputs.map((socket) => port(socket, 'input')),
      outputs: node.outputs.map((socket) => port(socket, 'output')),
      config: node.data,
      ...(node.parentId === undefined ? {} : { parentId: node.parentId }),
    })),
    connections: source.links.map((link) => ({
      id: link.id,
      source: { nodeId: link.source, portId: 'output-' + link.outputKey },
      target: { nodeId: link.target, portId: 'input-' + link.inputKey },
    })),
    viewport: source.viewport,
  });
}

Cette conversion conserve les cardinalités du DTO et utilise le rejet des cycles par défaut. Si l’ancien graphe contient des cycles que votre édition doit accepter, décidez explicitement d’une politique et alignez validateDocument, le constructeur d’Editor et les imports avec allowCycles: true. Cela ne rend pas une boucle exécutable. La hiérarchie de groupes reste sans cycles et un parent doit référencer un nœud de type group sans ports.

Adapter les sockets et les presets

Une connexion relie une sortie à une entrée par nodeId et portId. Le type de socket métier doit devenir un type de port explicite ; seuls les types identiques ou le type de port any sont compatibles. La règle multiple vaut pour les deux directions. Ne l’activez pas partout pour masquer les erreurs d’un ancien export.

Définissez vos NodePreset dans le catalogue de l’instance pour retrouver les types métier dans la palette. Le guide catalogue et ports donne un preset complet. Un nœud importé peut garder ses dimensions ; un ajout depuis le catalogue utilise par défaut 220 × 112. Le thème et les courbes ne définissent pas la validité d’une connexion.

Réutiliser l’affichage, pas les instances de modèle

Le renderer FloworaEditorComponent accepte nodeTemplate et inspectorTemplate. Adaptez les entrées de vos composants métier vers EditorNode ou un view-model de l’hôte, puis utilisez-les dans ces templates. Les formulaires passent par editor.updateNode() ou le callback update(patch), et non par la mutation d’une instance Rete. Consultez l’exemple Angular DI et templates.

Les équivalences ont des frontières

Le store couvre modèle, sélection, déplacement, duplication, suppression, groupes et historique transactionnel. Le renderer couvre canvas, pan/zoom, ports, chemins SVG, palette et inspector ; ELK est facultatif. Ces capacités ne garantissent pas la reprise de chaque hook, plugin, raccourci, preset ou politique de validation de votre ancien éditeur.

parentId représente un groupe visuel, pas une portée de variables ou un sous-workflow. L’attente utilisateur reste une configuration : votre backend conserve les sessions et conversations. Email, RAG, conditions et scripts restent des données, sans méthode execute(). Conservez l’exécuteur actuel ou compilez le document vers un modèle d’exécution séparé ; ne déduisez pas un runtime du renderer.

Une migration réversible, document par document

Versionnez la conversion et gardez les anciens exports. Montez un écran Flowora alternatif avec un export fictif ou anonymisé ; vérifiez identifiants, positions, dimensions, propriétés, types de ports, liens et parents. Commencez par un graphe simple, puis ajoutez branches, cardinalités et groupes. Comparez les documents, pas uniquement une capture visuelle.

Ajoutez, modifiez, annulez, sauvegardez, exportez et rechargez avant de remplacer les écritures de l’ancien éditeur. Gardez stable le contrat du backend pendant le pilote. Ne lancez jamais un email, un script ou une autre action réelle en double pour comparer deux interfaces. Des tests d’édition n’attestent ni l’exécution métier, ni une compatibilité Angular de production, ni une migration complète.

Une intégration indépendante.

Vous pouvez conserver votre moteur ou connecter Workify dans une étape séparée. Flowora ne dépend pas de Workify et n’en modifie ni les packages, ni les services, ni la licence.