### Install framework packages using npm Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/02.getting-started.md Example command to install the latest version of Rete.js framework packages. ```bash npm i rete rete-area-plugin rete-connection-plugin rete-render-utils rete-react-plugin react react-dom ``` -------------------------------- ### Accessing framework packages from CDN Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/02.getting-started.md Example of how to access Rete.js framework packages after including them via CDN. ```javascript Rete ReteAreaPlugin ReteConnectionPlugin ReteReactPlugin ``` -------------------------------- ### AI Assistance Prompt Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/02.getting-started.md Example of how to use the AI assistance feature with Rete Kit. ```bash Run npx rete-kit ai for [your intention] ``` -------------------------------- ### Install dependencies Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/11.dock-menu.md Install the rete-dock-plugin using npm. ```bash npm i rete-dock-plugin ``` -------------------------------- ### Usage from CDN Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/02.getting-started.md Example of how to include Rete.js framework packages in an HTML page using CDN links. ```html ``` -------------------------------- ### Install Dependencies Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/12.connection-path.md Installs the necessary packages for customizing connection paths. ```bash npm i rete-connection-path-plugin d3-shape ``` -------------------------------- ### Project Setup Source: https://github.com/retejs/retejs.org/blob/main/README.md Installs project dependencies. ```bash npm install ``` -------------------------------- ### Install Dependencies Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/10.minimap.md Install the minimap plugin using npm. ```bash npm i rete-minimap-plugin ``` -------------------------------- ### Install dependencies Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/08.scopes.md Install the rete-scopes-plugin using npm. ```bash npm i rete-scopes-plugin ``` -------------------------------- ### Install dependencies Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/01.basic.md Install the necessary Rete.js packages and their dependencies. ```bash npm i rete rete-area-plugin rete-connection-plugin rete-react-plugin rete-render-utils styled-components react@19 react-dom@19 ``` -------------------------------- ### Start Node Implementation Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/03.processing/3.hybrid.md Example implementation of a 'Start' node that passes control and has a default data method. ```typescript const socket = new ClassicPreset.Socket("socket"); class Start extends ClassicPreset.Node { constructor() { super("Start"); this.addOutput("exec", new ClassicPreset.Output(socket, "Exec")); } execute(_: never, forward: (output: "exec") => void) { forward("exec"); } data() { return {}; } } ``` -------------------------------- ### Install Dependencies Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/04.3d/1.index.md Install the necessary dependencies for the rete-area-3d-plugin, including three.js. ```bash npm i rete-area-3d-plugin three @types/three ``` -------------------------------- ### Install dependencies Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/15.comments.md Install the rete-comment-plugin package using npm. ```bash npm i rete-comment-plugin ``` -------------------------------- ### Connecting Plugins Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/26.migration.md Example of connecting plugins in Rete.js v1 and v2. ```typescript // v1 import HistoryPlugin from 'rete-history-plugin'; editor.use(HistoryPlugin, { keyboard: true }); ``` ```typescript // v2 import { HistoryPlugin, HistoryExtensions, Presets } from 'rete-history-plugin' const history = new HistoryPlugin() history.addPreset(Presets.classic.setup()) HistoryExtensions.keyboard(history) area.use(history) ``` -------------------------------- ### Install the dependency Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/04.data-structures.md Install the dependency ```bash npm i rete-structures ``` -------------------------------- ### Install Dependencies Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/03.processing/1.dataflow.md Install the necessary Rete.js and rete-engine packages using npm. ```bash npm i rete rete-engine ``` -------------------------------- ### Creating Nodes Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/26.migration.md Example of creating nodes in Rete.js v1 and v2. ```typescript // v1 class NumComponent extends Rete.Component { constructor(){ super("Number"); } builder(node) { node.addControl(new NumControl('num')) node.addOutput(new Rete.Output('num', "Number", numSocket)) return node } } const numComponent = new NumComponent() editor.register(numComponent); const node = await numComponent.createNode({ num: 2 }); ``` ```typescript // v2 const node = new ClassicPreset.Node('Number') node.addControl('num', new NumControl('num')) node.addOutput('num', new ClassicPreset.Output(numSocket, "Number")); await editor.addNode(node) ``` -------------------------------- ### Install dependencies Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/05.arrange.md Install the rete-auto-arrange-plugin and its peer dependency elkjs. Additionally, install web-worker if your bundler doesn't recognize it. ```bash npm i rete-auto-arrange-plugin elkjs npm i web-worker ``` -------------------------------- ### Step-by-step contribution to the package Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/23.contribution.md Steps for contributing to a Rete.js package, including cloning, branching, installing dependencies, building, testing, and committing. ```bash git clone ``` ```bash npm ci ``` ```bash npm run build ``` -------------------------------- ### Context Menu Example Source: https://github.com/retejs/retejs.org/blob/main/content/en/examples/09.context-menu.md An example demonstrating the use of a context menu plugin for Rete.js, featuring node creation and node-specific actions. ```typescript import { ClassicPreset, Editor } from "rete-core"; import { ContextMenuPlugin } from "rete-plugin-context-menu-plugin"; import "rete-plugin-context-menu-plugin/dist/style.css"; type Preset = ClassicPreset; async function main() { const editor = new Editor(); const contextMenu = new ContextMenuPlugin(editor); contextMenu.addNode(new editor.Node("Node", { name: "Node" })); editor.use(contextMenu); } main(); ``` -------------------------------- ### Arrange nodes example Source: https://github.com/retejs/retejs.org/blob/main/content/en/examples/08.arrange.md Example demonstrating automated node arrangement (layouting) using elk.js. ```typescript import { Editor, Node, ClassicPreset } from "rete-core"; import { AreaPlugin } from "rete-area-plugin"; import { ReactRenderPlugin } from "rete-react-render-plugin"; import { AreaExtensions } from "rete-area-plugin/extensions"; import { LayoutExtensions } from "rete-layout-plugin/extensions"; import "rete-layout-plugin/styles.css"; const { ReactComponent } = ReactRenderPlugin; type NodeId = string | number; type RenderNode = ClassicPreset.Node; class CustomNode extends ClassicPreset.Node { constructor(id: NodeId, label: string) { super(id, { label }); } } async function createEditor() { const editor = new Editor>({ view: { node: ReactComponent } }); const area = new AreaPlugin>(editor); const render = new ReactRenderPlugin(editor); AreaExtensions.selectableNodes(area, (node) => node.getNodes()); editor.use(area); editor.use(render); const layout = new LayoutExtensions(editor); const node1 = new CustomNode("1", "Node 1"); const node2 = new CustomNode("2", "Node 2"); const node3 = new CustomNode("3", "Node 3"); await editor.addNode(node1); await editor.addNode(node2); await editor.addNode(node3); editor.connect(node1.out, node2.in); editor.connect(node2.out, node3.in); await layout.layout(); return { editor, area }; } createEditor(); ``` -------------------------------- ### Install dependencies Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/06.context-menu.md Install the context-menu-plugin using npm. ```bash npm i rete-context-menu-plugin ``` -------------------------------- ### AI Prompt Example Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/20.development/4.ai-assistance/1.index.md This is an example of a prompt you can use with your AI-powered IDE's agent or command execution feature to get assistance with Rete.js development. ```bash npx rete-kit ai for [your intention] ``` -------------------------------- ### Dock Menu Example Source: https://github.com/retejs/retejs.org/blob/main/content/en/examples/12.dock.md This example demonstrates how to implement a dock menu in Rete.js, allowing users to add nodes to the editor by clicking or dragging. It also shows how to dynamically manage the node list and configure node properties. ```typescript import { Editor, VueRenderPlugin } from '@retejs/retejs' import { AreaExtensions } from 'rete-area-extensions' import { VueNode } from '@retejs/vue-render-plugin' import Dock from '@retejs/dock-plugin' async function createEditor(container) { const editor = new Editor, VueNode>({ container, render: new VueRenderPlugin({ component: VueNode }), plugins: [ new AreaExtensions.Scope({ name: 'area' }), new Dock({ container: document.querySelector('.dock') }) ] }) return editor } const container = document.querySelector('#editor') createEditor(container).then(async (editor) => { console.log('Rete.js editor with dock menu created') }) ``` -------------------------------- ### Import nodes in order Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/09.import-export.md A basic example of importing nodes in the order they were added to the editor. ```typescript const graph = /// loaded JSON-valid object from DB for (const node of graph.nodes) { await editor.addNode(node) } ``` -------------------------------- ### Nested Graph Execution Example Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/08.modules.md A simplified example demonstrating how to implement a nested graph processor, including functions to find modules, get ports, and execute graphs. ```typescript function findModule(path: string) { return { getPorts() { const editor = new NodeEditor(); await importGraphByPath(path, editor); const nodes = editor.getNodes(); const inputs = nodes .filter((n): n is InputNode => n instanceof InputNode) .map((n) => n.key); const outputs = nodes .filter((n): n is OutputNode => n instanceof OutputNode) .map((n) => n.key); return { inputs, outputs }; }, exec: async (inputData: Record) => { const engine = new DataflowEngine(); const editor = new NodeEditor(); editor.use(engine); await importGraphByPath(path, editor); const nodes = editor.getNodes(); injectInputs(nodes, inputData); return retrieveOutputs(nodes, engine); } }; } ``` -------------------------------- ### Install dependencies Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/14.undo-redo.md Install the rete-history-plugin using npm. ```bash npm i rete-history-plugin ``` -------------------------------- ### Render plugins v1 vs v2 Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/26.migration.md Comparison of Rete.js render plugin setup between v1 and v2. ```typescript // v1 import ReactRenderPlugin from 'rete-react-render-plugin'; editor.use(ReactRenderPlugin) ``` ```typescript // v2 import { ReactPlugin } from 'rete-react-plugin' import { createRoot } from "react-dom/client" const reactPlugin = new ReactPlugin({ createRoot }) area.use(reactPlugin) ``` -------------------------------- ### Selectable Connections Example Source: https://github.com/retejs/retejs.org/blob/main/content/en/examples/10.selectable-connections.md An example demonstrating how to implement selectable connections in Rete.js using custom connections and AreaExtensions.selector. ```typescript import { BaseEvent, ClassicPreset, Editor, Node } from "retejs"; import { AreaExtensions, AreaPlugin } from "retejs-area-plugin"; import { ReactRenderPlugin } from "retejs-react-render-plugin"; import React from "react"; import ReactDOM from "react-dom"; // Define custom connection type interface CustomConnection { id: string; source: string; target: string; data: { label: string; }; } // Define custom connection props for React rendering interface CustomConnectionProps { payload: CustomConnection; editor: Editor; plugin: AreaPlugin; } // Custom connection component const CustomConnectionComponent: React.FC = ({ payload, editor, plugin }) => { const { source, target, data } = payload; const isSelected = AreaExtensions.isConnectionSelected(plugin, payload.id); const onClick = (e: React.MouseEvent) => { e.stopPropagation(); AreaExtensions.selectConnection(plugin, payload.id); }; return ( {data.label} ); }; // Define custom node type class CustomNode extends ClassicPreset.Node<{ inputs: { a: ClassicPreset.Socket; b: ClassicPreset.Socket; }; outputs: { o: ClassicPreset.Socket; }; }> { label = "Node"; constructor() { super("custom node"); this.addInput("a", new ClassicPreset.Socket("number")); this.addInput("b", new ClassicPreset.Socket("number")); this.addOutput("o", new ClassicPreset.Socket("number")); } } // Define custom editor class CustomEditor extends Editor<{ render: ReactRenderPlugin; connection: CustomConnection; node: Node; }> {} // Add CustomConnection to the generic type async function createEditor(container: HTMLElement) { const editor = new CustomEditor(); const render = new ReactRenderPlugin({ // Pass the custom connection component to the render plugin connectionComponent: CustomConnectionComponent, }); editor.use(render); const startNode = new CustomNode(); const endNode = new CustomNode(); await editor.addNode(startNode); await editor.addNode(endNode); startNode.position = { x: 100, y: 100 }; endNode.position = { x: 400, y: 100 }; // Add a custom connection const connection: CustomConnection = { id: "conn1", source: startNode.id, target: endNode.id, data: { label: "Connection 1", }, }; // Add the custom connection to the editor editor.addConnection(connection); // Render the editor render.addElements({ nodes: [startNode, endNode], connections: [connection], }); // Mount the editor to the container const elements = render.getElements(); ReactDOM.render(elements, container); return editor; } const container = document.getElementById("rete-container") as HTMLElement; createEditor(container); ``` -------------------------------- ### Validate changes - E2E testing setup Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/23.contribution.md Steps to set up E2E testing using Rete QA with dependency aliasing. ```bash rete-qa test --deps-alias ``` -------------------------------- ### Install dependencies Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/13.reroute.md Install the rete-connection-reroute-plugin package using npm. ```bash npm i rete-connection-reroute-plugin ``` -------------------------------- ### Custom Node Example Source: https://github.com/retejs/retejs.org/blob/main/content/en/examples/03.customization/1.react.md This example demonstrates the implementation of custom nodes, sockets, and connections for React.js, allowing for dynamic configuration. ```typescript import React from 'react'; import {classicRoot} from '@retejs/react-render-plugin'; import {Node,classicEvents as events} from '@retejs/core'; interface MyNodeProps { data: Node } const MyNode: React.FC = ({data}) => { return (
{data.name}
); }; export default { name: 'custom-node', render: classicRoot(MyNode), events }; ``` -------------------------------- ### 3D Editor Example Source: https://github.com/retejs/retejs.org/blob/main/content/en/examples/22.3d/1.index.md This example demonstrates integrating a node editor into a 3D scene using Three.js and the rete-area-3d-plugin. ```typescript import { Area3D } from '@retejs/area-3d-plugin'; import { Editor } from '@retejs/core'; async function main() { const editor = new Editor(); const area = new Area3D(editor, { container: document.body, background: { grid: true, lines: 10 } }); // Add nodes, components, etc. } main(); ``` -------------------------------- ### Start Processing Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/03.processing/1.dataflow.md Fetch the output data from the 'sum' node using the engine. ```typescript const result = await engine.fetch(sum.id) ``` -------------------------------- ### Connection Path Example Source: https://github.com/retejs/retejs.org/blob/main/content/en/examples/14.connection-path.md This example showcases the usage of a plugin for configuring connection paths. It facilitates the customization of both the paths (linear, step, monotone) and the points they traverse. Additionally, there's an option to include an arrow-shaped marker. ```javascript import { ClassicPreset, get, Editor } from "rete-react-render-plugin"; import { AreaPlugin } from "rete-react-area-plugin"; import { ReactRenderPlugin } from "rete-react-render-plugin"; import { ConnectionPathPlugin } from "@retejs/connection-path-plugin"; import React from "react"; import ReactDOM from "react-dom"; const App = () => { const editor = new Editor(); const area = new AreaPlugin(editor); const render = new ReactRenderPlugin(); const connectionPath = new ConnectionPathPlugin(); editor.use(area); area.use(render); area.use(connectionPath); connectionPath.addPath("linear", { type: "linear" }); connectionPath.addPath("step", { type: "step" }); connectionPath.addPath("monotone", { type: "monotone" }); connectionPath.addPath("arrow", { type: "step", arrow: true }); return (
{ await area.render(el); }} /> ); }; ReactDOM.render(, document.querySelector("#app")); ``` -------------------------------- ### Reroute Example Source: https://github.com/retejs/retejs.org/blob/main/content/en/examples/15.reroute.md This example demonstrates the usage of the connection rerouting plugin, allowing users to insert and remove rerouting points on connections. ```typescript import { Editor } from '@retejs/editor'; import { ClassicPreset } from 'rete-kit'; import { AreaPlugin } from 'rete-plugin-area-context'; import { ConnectionReroutePlugin } from '@retejs/connection-reroute-plugin'; async function initEditor() { const editor = new Editor(); const area = new AreaPlugin(editor, { width: 800, height: 600 }); editor.use(area); editor.use(new ConnectionReroutePlugin()); // Add nodes and connections here } initEditor(); ``` -------------------------------- ### Panning Boundary Example Source: https://github.com/retejs/retejs.org/blob/main/content/en/examples/09.panning-boundary.md This example demonstrates the implementation of panning the area when the cursor with a dragged node is approaches the editor's boundary. Depending on the distance to any of the area's boundaries, starting from a certain threshold, the panning speed will be inversely proportional to the distance to the boundary. ```typescript import { AreaPlugin } from '@retejs/area-plugin'; import { BasePlugin } from '@retejs/core'; interface PanningBoundaryOptions { threshold?: number; factor?: number; } const defaultOptions: PanningBoundaryOptions = { threshold: 100, factor: 0.5 }; export class PanningBoundaryPlugin extends BasePlugin { constructor(private area: AreaPlugin, options: PanningBoundaryOptions = {}) { super(); this.options = { ...defaultOptions, ...options }; } async init() { this.area.use(this); this.area.events.mousemove.subscribe(event => { if (!this.area.pointer.dragging()) return; const rect = this.area.container.getBoundingClientRect(); const { threshold, factor } = this.options; const dx = event.clientX - rect.left; const dy = event.clientY - rect.top; let panX = 0; let panY = 0; // Check horizontal boundaries if (dx < threshold) { panX = -(threshold - dx) * factor; } else if (dx > rect.width - threshold) { panX = (dx - (rect.width - threshold)) * factor; } // Check vertical boundaries if (dy < threshold) { panY = -(threshold - dy) * factor; } else if (dy > rect.height - threshold) { panY = (dy - (rect.height - threshold)) * factor; } this.area.translate(panX, panY); }); } destroy() { this.area.events.mousemove.unsubscribe(); } } ``` -------------------------------- ### Install dependencies Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/02.renderers/5.lit.md Install the necessary dependencies for the Lit plugin. ```bash npm i @retejs/lit-plugin rete-render-utils lit ``` -------------------------------- ### Installation Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/20.development/2.rete-cli.md Install the Rete CLI globally using npm. ```bash npm i -g rete-cli ``` -------------------------------- ### Install dependencies Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/02.renderers/1.react.md Install the necessary dependencies for rete-react-plugin. ```bash npm i rete-react-plugin rete-render-utils styled-components ``` -------------------------------- ### Install Rete Kit Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/20.development/3.rete-kit.md Install Rete Kit globally using npm. ```bash npm i -g rete-kit ``` -------------------------------- ### History Plugin Example Source: https://github.com/retejs/retejs.org/blob/main/content/en/examples/18.history.md An example demonstrating the history plugin for undo/redo functionality in Rete.js, including tracking changes and using keyboard shortcuts. ```typescript import { Editor, Engine } from '@retejs/rete' import { HistoryPlugin } from '@retejs/history-plugin' const editor = new Editor() const engine = new Engine() // Initialize history plugin const history = new HistoryPlugin() history.add(editor) // Example of adding a node (this change will be tracked) async function addNode() { const component = await engine.getComponent('NodeComponent') const node = await component.createNode({ x: 100, y: 100 }) editor.addNode(node) } // Example of undo/redo async function undo() { history.undo() } async function redo() { history.redo() } // You can also group operations manually async function groupOperations() { history.start() // Perform multiple operations here await addNode() // ... other operations history.finish() } // Example usage: // addNode() // undo() // redo() // groupOperations() ``` -------------------------------- ### Magnetic Connection Example Source: https://github.com/retejs/retejs.org/blob/main/content/en/examples/08.magnetic-connection.md This example demonstrates how to implement magnetic connection to improve the user experience by enlarging the connection dropping area. ```typescript import { BaseComponent, Editor, Node, Socket } from '@retejs/core'; import { useMagneticConnection } from './magnetic-connection'; export class EditorComponent extends BaseComponent { constructor() { super('editor'); } async builder(node: Node) { const input = new Socket('input'); const output = new Socket('output'); node.addInput(input).addOutput(output); } } async function main() { const editor = new Editor(); const component = new EditorComponent(); editor.use(component); editor.use(useMagneticConnection()); const node = await component.createNode({ id: '1', position: [80, 80], data: {} }); editor.addNode(node); } main(); ``` -------------------------------- ### Install dependencies Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/02.renderers/4.svelte.md Install the necessary dependencies for the rete-svelte-plugin. ```bash npm i rete-svelte-plugin rete-render-utils sass ``` -------------------------------- ### Data structures Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/03.concepts/2.presets.md Example of importing classes from the ClassicPreset for Rete.js. ```typescript import { ClassicPreset } from 'rete'; const { Node, Connection, Socket, Input, Output, Control } = ClassicPreset ``` -------------------------------- ### Install dependencies Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/07.readonly.md Install the readonly plugin using npm. ```bash npm i rete-readonly-plugin ``` -------------------------------- ### Performance Example Source: https://github.com/retejs/retejs.org/blob/main/content/en/examples/06.performance.md An example demonstrating how to assess the performance of rendering a large number of nodes on a page. It allows setting the number of nodes to be displayed and observing rendering performance. ```typescript import { Editor, Node, ClassicPreset } from "rete-core"; import { Area2D, AreaExtensions } from "rete-area-2d"; import { ReactRenderPlugin } from "rete-react-render-plugin"; import { ContextMenuPlugin } from "rete-context-menu-plugin"; import { AreaPlugin } from "rete-area-plugin"; class MyNode extends ClassicPreset.Node { constructor(id: string) { super(id); this.addOutput("output", new ClassicPreset.Output()); this.addInput("input", new ClassicPreset.Input()); } } async function createEditor(container: HTMLElement) { const editor = new Editor ({ view: { node: MyNode, customizer: (node) => { // Example of custom node rendering // You can add custom properties here to control rendering // For example, to control the size or appearance of the node } } }); const area = new Area2D(editor, { container, plugins: [ new ReactRenderPlugin(), new ContextMenuPlugin({ items: { rename: "Rename", remove: "Remove", duplicate: "Duplicate" } }) ] }); AreaExtensions.simpleTextGrid(area); const node1 = new MyNode("1"); const node2 = new MyNode("2"); await editor.addNode(node1); await editor.addNode(node2); node1.move({ x: 100, y: 100 }); node2.move({ x: 300, y: 100 }); editor.connect(node1.outputs.output, node2.inputs.input); return { destroy() { editor.destroy(); } }; } const container = document.querySelector("#rete") as HTMLElement; createEditor(container).then(editor => { (window as any).editor = editor; }).catch(err => { console.error(err); }); ``` -------------------------------- ### Install Dependencies Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/02.renderers/3.angular.md Install the necessary Rete.js Angular plugin and rendering utilities. ```bash npm i rete-angular-plugin rete-render-utils @angular/elements@21 ``` -------------------------------- ### Install dependencies Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/02.renderers/2.vue.md Install the necessary dependencies for the Vue.js renderer plugin. ```bash npm i rete-vue-plugin rete-render-utils ``` -------------------------------- ### Classic preset Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/03.concepts/6.integration.md Example of using the classic preset with Angular. ```typescript import { AngularPlugin, AngularArea2D, Presets as AngularPresets } from 'rete-angular-plugin/21' const angular = new AngularPlugin>({ injector }) angular.addPreset(AngularPresets.classic.setup()) area.use(angular) ``` -------------------------------- ### Smooth Zoom Example Source: https://github.com/retejs/retejs.org/blob/main/content/en/examples/08.smooth-zoom.md This example demonstrates how to implement smooth zooming in the Rete.js editor by extending the Zoom class. ```javascript area.area.setZoomHandler(new SmoothZoom(0.5, 200, "cubicBezier(.45,.91,.49,.98)", area)); ``` -------------------------------- ### Install Rete QA tool Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/19.quality-assurance.md Installs the Rete QA tool globally using npm. ```bash npm i -g rete-qa ``` -------------------------------- ### Angular Customization Example Source: https://github.com/retejs/retejs.org/blob/main/content/en/examples/03.customization/3.angular.md This example demonstrates the implementation of custom nodes, sockets, and connections for Angular, allowing them to be dynamically configured based on the parameters of various objects. It also includes a grid-like gradient background implemented with pure JS and CSS. ```typescript import { NodeEditorComponent, NodeEditorModule } from '@angular/core'; import { NodeEditor, ClassicPreset, SocketPreset } from 'rete' import { AngularRenderPlugin } from '@retejs/angular-render-plugin'; import { AngularControls } from '@retejs/angular-controls'; class SocketA extends ClassicPreset.Socket {} class SocketB extends ClassicPreset.Socket {} class MyNode extends ClassicPreset.Node { constructor() { super('Node'); this.addControl(new AngularControls.InputControl({ key: 'name', placeholder: 'Node Name' })); } } export class Editor extends NodeEditor { constructor() { super('CustomEditor', { template: '
', plugins: [ new AngularRenderPlugin({ selector: '.editor', components: { node: MyNode } }), new AngularControls() ] }); } async ready() { await super.ready(); const node = new MyNode(); this.addNode(node); const node2 = new MyNode(); this.addNode(node2); this.connect(node.outputs.output, node2.inputs.input); } } ``` -------------------------------- ### Vue.js Customization Example Source: https://github.com/retejs/retejs.org/blob/main/content/en/examples/03.customization/2.vue.md This example demonstrates the implementation of custom nodes, sockets, and connections for Vue.js, allowing for dynamic configuration based on object parameters. It also includes a grid-like gradient background implemented with JS and CSS. ```javascript import { bootstrap } from "rete-engine"; import { VueRenderPlugin } from "@retejs/vue-render-plugin"; import { Node } from "@retejs/vue-render-plugin/src/node"; import { Socket } from "@retejs/vue-render-plugin/src/socket"; import { Connection } from "@retejs/vue-render-plugin/src/connection"; async function main() { const editor = await bootstrap({ container: document.querySelector("#rete"), plugins: [ new VueRenderPlugin({ component: { Node, Socket, Connection } }) ] }); editor.addNode({ id: 1, position: [80, 20], data: { name: "Node 1" } }); editor.addNode({ id: 2, position: [300, 120], data: { name: "Node 2" } }); editor.connect({ source: [1, "output", 0], target: [2, "input", 0] }); } main(); ``` -------------------------------- ### Google Gemini Chat Prompt Example Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/20.development/4.ai-assistance/2.llms.md Example prompt for Google Gemini Chat, referencing Rete.js documentation for assistance with creating a custom node. ```prompt I'm building a node editor with Rete.js. Please review the documentation at https://retejs.org/llms-full.txt and help me create a custom node that processes image data through multiple transformation steps. ``` -------------------------------- ### VS Code GitHub Copilot Instructions Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/20.development/4.ai-assistance/2.llms.md Example of a .copilot-instructions.md file for VS Code, providing Rete.js documentation URL for enhanced context-aware suggestions. ```markdown # Copilot Instructions For Rete.js development, reference the documentation at: https://retejs.org/llms-full.txt Focus on node editor patterns, dataflow programming, and plugin architecture. ``` -------------------------------- ### 3D Configurator Source: https://github.com/retejs/retejs.org/blob/main/content/en/examples/20.3d-configurator.md This example showcases the use of an editor that lets you combine nodes to create unique color blends and apply them to a car's body and wheels. The editor uses DataflowEngine for node processing. Initial nodes are loaded from a JSON file through a custom importer implemented for this editor. ```javascript import { ClassicPreset } from 'rete-react-plugin' import { AreaPlugin } from 'rete-area-plugin' import { ReactRenderPlugin } from 'rete-react-render-plugin' import { AreaExtensions } from 'rete-area-plugin' import { DataflowEngine } from 'rete-engine' import { NodeEditor } from 'rete' import { initNodes } from './nodes' const selector = '#rete' async function main() { const editor = new NodeEditor('rete@0.1.0', await AreaExtensions.selector(selector)) const area = new AreaPlugin(editor) const render = new ReactRenderPlugin() editor.use(area) area.use(render) await editor.use(new ClassicPreset()) const engine = new DataflowEngine(editor) await initNodes(editor) AreaExtensions.simpleEdit(editor) AreaExtensions.zoomAt(editor, area.container) editor.on('process', async () => { const results = await engine.reset() console.log('Processing results:', results) }) editor.trigger('process') } main() ``` -------------------------------- ### Graph Execution Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/03.processing/3.hybrid.md Execute the graph starting from the 'start' node's ID. ```typescript engine.execute(start.id); ``` -------------------------------- ### Create an application (with options) Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/20.development/3.rete-kit.md Create a new application using Rete Kit by specifying options such as name, stack, version, features, and dependency aliases. ```bash rete-kit app --name --stack --stack-version --features --deps-alias ``` -------------------------------- ### Modifying connection geometry with increased width Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/04.3d/1.index.md Example of creating a connection geometry with an increased width. ```typescript Area3DExtensions.forms.connection(reactRender, { customize(path) { return Area3DExtensions.forms.createClassicConnectionGeometry(path, 10) } }) ``` -------------------------------- ### Modifying node border radius Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/04.3d/1.index.md Example of modifying the border radius of a node using custom geometry. ```typescript Area3DExtensions.forms.node(area, { customize(node) { return Area3DExtensions.forms.createClassicNodeGeometry(node, { borderRadius: 0 }) } }) ``` -------------------------------- ### Valid JSON object node Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/09.import-export.md Example of a node that is a valid JSON object, which can be easily exported. ```typescript import { NodeEditor, BaseSchemes, getUID } from 'rete' const editor = new NodeEditor() const node = { id: getUID(), label: 'Label' } await editor.addNode(node) ``` -------------------------------- ### Customization for Lit Source: https://github.com/retejs/retejs.org/blob/main/content/en/examples/03.customization/5.lit.md This example demonstrates the implementation of custom nodes, sockets, and connections for Lit, allowing you to adapt them to your use cases. These elements can be dynamically configured based on the parameters of various objects (nodes, sockets, connections). Additionally, a grid-like gradient background has been added using pure JS and CSS. ```javascript import { Editor, ClassicPreset, Area2D, render } from "rete-react-render-plugin"; import { AreaExtensions, AreaPlugin } from "rete-area-plugin"; import { ReactRenderPlugin } from "rete-react-render-plugin"; import { LitRenderPlugin } from "@retejs/lit-render-plugin"; import { createReactNode } from "rete-react-render-plugin"; import React from "react"; import ReactDOM from "react-dom"; // Custom node component using Lit import { html, css, LitElement } from "lit"; import { customElement, property } from "lit/decorators.js"; class MyNode extends LitElement { static styles = css` :host { display: block; padding: 10px; border: 1px solid #ccc; background: #f9f9f9; border-radius: 5px; } .title { font-weight: bold; margin-bottom: 5px; } `; @property({ type: String }) title = "Node Title"; render() { return html`
${this.title}
Content goes here
`; } } customElements.define("my-node", MyNode); // Rete.js node definition class MyNodeComponent extends ClassicPreset.Node { constructor(initial) { super(initial); this.addRendering({ component: MyNode, props: { title: initial.label } }); } } // Rete.js editor setup async function setupEditor(container) { const editor = new Editor({ render: new LitRenderPlugin({ // You can pass custom elements here // For example, to use your custom node component // You would need to register it with the LitRenderPlugin // This is a simplified example, actual registration might differ }) }); const area = new AreaPlugin(container); const reactRender = new ReactRenderPlugin(); editor.use(area); area.use(reactRender); // Register custom element for Rete.js // This part might need adjustment based on how LitRenderPlugin handles custom elements // For demonstration, assuming a way to register custom elements // editor.use(LitRenderPlugin, { customElements: { 'my-node': MyNode } }); AreaExtensions.simpleNodesOrder(area); const node1 = new MyNodeComponent({ id: "1", label: "Custom Node 1", x: 100, y: 100 }); const node2 = new MyNodeComponent({ id: "2", label: "Custom Node 2", x: 300, y: 100 }); editor.addNode(node1); editor.addNode(node2); // Example of adding a connection (if sockets are defined) // const connection = new ClassicPreset.Connection(node1, 'output', node2, 'input'); // editor.addConnection(connection); await editor.render(container); } const container = document.getElementById("rete-container"); if (container) { setupEditor(container); } ``` -------------------------------- ### TextNode Node Implementation Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/03.processing/3.hybrid.md Example implementation of a 'TextNode' that provides data but does not handle control flow. ```typescript class TextNode extends ClassicPreset.Node { constructor(private text: string) { super("Text"); this.addOutput("value", new ClassicPreset.Output(socket, "Number")); } execute() {} data(): { value: string } { return { value: this.text }; } } class Connection extends ClassicPreset.Connection {} type NodeProps = Start | Log | TextNode; type ConnProps = Connection | Connection; type Schemes = GetSchemes; ``` -------------------------------- ### Full Connection Customization Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/02.renderers/1.react.md Guides on how to customize connection components by using `Connection.tsx` from the `presets/classic/components` directory as a starting point. ```ts import { CustomConnection } from './CustomConnection' render.addPreset(Presets.classic.setup({ customize: { connection() { return CustomConnection } } })) ``` -------------------------------- ### Rendering Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/03.concepts/2.presets.md Example of adding classic and context menu presets to the ReactPlugin in Rete.js. ```typescript import { ReactPlugin, Presets as ReactPresets } from 'rete-react-plugin' const reactPlugin = new ReactPlugin({ createRoot }) reactPlugin.addPreset(ReactPresets.classic.setup()) reactPlugin.addPreset(ReactPresets.contextMenu.setup()) ``` -------------------------------- ### Import nodes with parent-child relationships Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/09.import-export.md An example of importing nodes considering parent-child relationships, ensuring parent nodes are added before their children. ```typescript async function importForParent(nodes, parent = undefined) { const nodes = nodes.filter(node => node.parent === parent) for (const node of nodes) { await editor.addNode(node) await importForParent(nodes, node.id) } } const graph = /// loaded JSON-valid object from DB await importForParent(graph.nodes) ``` -------------------------------- ### Sharing the main Area3DPlugin instance Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/04.3d/1.index.md Demonstrates how to create a main Area3DPlugin instance and share it with other editors. ```typescript const mainEditor = new NodeEditor(); const mainArea = new Area3DPlugin(container) mainEditor.use(mainArea) const secondaryEditor = new NodeEditor(); const secondaryArea = mainArea.share() secondaryEditor.use(secondaryArea) ``` -------------------------------- ### Non-valid JSON object node (class instance) Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/09.import-export.md Example of a node that is not a valid JSON object, such as an instance of a class, which poses serialization challenges. ```typescript import { ClassicPreset } from 'rete' const node = new ClassicPreset.Node('Label') node.addOutput('port', new ClassicPreset.Output(socket, 'Label')) await editor.addNode(node) ``` -------------------------------- ### Defining types and initializing the editor instance Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/01.basic.md Define the schemes for node and connection types and initialize the NodeEditor instance. ```typescript import { NodeEditor, GetSchemes, ClassicPreset } from "rete"; type Schemes = GetSchemes< ClassicPreset.Node, ClassicPreset.Connection >; const editor = new NodeEditor(); ``` -------------------------------- ### Log Node Implementation Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/03.processing/3.hybrid.md Example implementation of a 'Log' node that receives control, fetches data using fetchInputs, and passes control. ```typescript class Log extends ClassicPreset.Node { constructor() { super("Log"); this.addInput("exec", new ClassicPreset.Input(socket, "Exec", true)); this.addInput("message", new ClassicPreset.Input(socket, "Text")); this.addOutput("exec", new ClassicPreset.Output(socket, "Exec")); } async execute(input: "exec", forward: (output: "exec") => void) { const inputs = (await dataflow.fetchInputs(this.id)) as { message: string[]; }; console.log((inputs.message && inputs.message[0]) || ""); forward("exec"); } data() { return {}; } } ``` -------------------------------- ### Task plugin (control flow) v1 vs v2 Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/26.migration.md Comparison of Rete.js Task plugin (control flow) setup and usage between v1 and v2. ```typescript // v1 import TaskPlugin from 'rete-task-plugin'; editor.use(TaskPlugin); ``` ```typescript // v1 this.task = { outputs: { exec: 'option', data: 'output' }, init(task) { task.run('any data'); task.reset(); } } ``` ```typescript // v1 worker(node, inputs, data) { this.closed = ['exec']; return { data } } ``` ```typescript // v2 import { ControlFlowEngine } from 'rete-engine' const engine = new ControlFlowEngine() editor.use(engine) ``` ```typescript // v2 const engine = new ControlFlowEngine(() => { return { inputs: () => ["exec"], outputs: () => ["exec"] }; }); ``` ```typescript // v2 execute(input: 'exec', forward: (output: 'exec') => void) { forward('exec') } ``` ```typescript // v2 async execute(input: 'exec', forward: (output: 'exec') => void) { const inputs = await dataflow.fetchInputs(this.id) forward('exec') } ``` -------------------------------- ### Sankey Diagram Example Source: https://github.com/retejs/retejs.org/blob/main/content/en/examples/12.sankey.md This code snippet demonstrates the implementation of a Sankey diagram using Rete.js, including custom node, connection, and socket components, and the classic preset setup. ```typescript import { ClassicPreset, Editor, Node } from 'rete' import { ReactRenderPlugin } from '@xyflow/react-render-plugin' import { AreaPlugin } from 'rete-area-plugin' import { ReactFlow } from '@xyflow/react' import { createSankeyRestrictor } from './sankey-restrictor' import { createSankeyLayout } from './sankey-layout' const width = 120 const height = 80 class SankeyNode extends ClassicPreset.Node { constructor(initial: { data: { capacity: number } }) { super({ ...initial, data: { ...initial.data, capacity: height } }) } } class SankeySocket extends ClassicPreset.Socket { constructor(name: string) { super(name) } } class SankeyConnection extends ClassicPreset.Connection { constructor(source: Node, target: Node, sourceOutput: string, targetInput: string) { super(source, target, sourceOutput, targetInput) } } export class SankeyEditor extends Editor<{ node: typeof SankeyNode socket: typeof SankeySocket connection: typeof SankeyConnection }> { constructor() { super('Sankey') this.use(AreaPlugin) this.use(ReactRenderPlugin) this.registerPreset(ClassicPreset.preset) } async init() { await super.init() const nodes = await this.cache.getAllNodes() if (nodes.length === 0) { const node1 = await this.addNode(new SankeyNode({ data: { capacity: height } })) const node2 = await this.addNode(new SankeyNode({ data: { capacity: height } })) const node3 = await this.addNode(new SankeyNode({ data: { capacity: height } })) await this.connect(new SankeyConnection(node1, node2, 'output', 'input')) await this.connect(new SankeyConnection(node2, node3, 'output', 'input')) } } } export async function createEditor() { const editor = new SankeyEditor() const area = editor.use(AreaPlugin) await editor.init() const sankeyRestrictor = createSankeyRestrictor({ getNodes: () => editor.getNodes() }) const sankeyLayout = createSankeyLayout({ getNodes: () => editor.getNodes(), getConnections: () => editor.getConnections(), restrictor: sankeyRestrictor, width, height }) area.use(sankeyLayout) area.use(sankeyRestrictor) return editor } ``` -------------------------------- ### Equivalent Classic Flow Setup Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/06.connections.md This is the equivalent code for the classic connection preset, explicitly importing ClassicFlow. ```typescript import { ClassicFlow } from 'rete-connection-plugin' connection.addPreset(() => new ClassicFlow()) ``` -------------------------------- ### Quick Start - Manual Options Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/20.development/4.ai-assistance/3.rete-kit-ai.md Alternatively, you can specify options manually for the npx rete-kit ai command, including the tool and context. ```bash npx rete-kit ai --tool --context [options] ``` -------------------------------- ### Prepare nodes Source: https://github.com/retejs/retejs.org/blob/main/content/en/docs/04.guides/06.context-menu.md Example of creating separate classes for nodes to improve convenience and code reusability. ```typescript class NodeA extends ClassicPreset.Node { constructor(socket: ClassicPreset.Socket) { super("NodeA"); this.addControl("port", new ClassicPreset.InputControl("text", {})); this.addOutput("port", new ClassicPreset.Output(socket)); } } /// class NodeB extends ... type Node = NodeA | NodeB; type Schemes = GetSchemes>; ```