🚀 DAY 5 OF LAUNCH WEEK:Introducing Webhook Events for Alert Changes.Learn more
Socket
Book a DemoInstallSign in
Socket

@flowgram.ai/demo-free-layout

Package Overview
Dependencies
Maintainers
3
Versions
93
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@flowgram.ai/demo-free-layout

自由布局最佳实践 demo

latest
npmnpm
Version
1.0.0
Version published
Maintainers
3
Created
Source

FlowGram.AI - Demo Free Layout

Best-practice demo for free layout

Installation

npx @flowgram.ai/create-app@latest free-layout

Project Overview

Core Tech Stack

  • Frontend framework: React 18 + TypeScript
  • Build tool: Rsbuild (a modern build tool based on Rspack)
  • Styling: Less + Styled Components + CSS Variables
  • UI library: Semi Design (@douyinfe/semi-ui)
  • State management: Flowgram’s in-house editor framework
  • Dependency injection: Inversify

Core Dependencies

  • @flowgram.ai/free-layout-editor: Core dependency for the free layout editor
  • @flowgram.ai/free-snap-plugin: Auto-alignment and guide-lines plugin
  • @flowgram.ai/free-lines-plugin: Connection line rendering plugin
  • @flowgram.ai/free-node-panel-plugin: Node add-panel rendering plugin
  • @flowgram.ai/minimap-plugin: Minimap plugin
  • @flowgram.ai/free-container-plugin: Sub-canvas plugin
  • @flowgram.ai/free-group-plugin: Grouping plugin
  • @flowgram.ai/form-materials: Form materials
  • @flowgram.ai/runtime-interface: Runtime interfaces
  • @flowgram.ai/runtime-js: JS runtime module
  • @flowgram.ai/panel-manager-plugin: Sidebar panel management

Code Guide

Directory Structure

src/
├── app.tsx                  # Application entry file
├── editor.tsx               # Main editor component
├── initial-data.ts          # Initial data configuration
├── assets/                  # Static assets
├── components/              # Component library
│   ├── index.ts
│   ├── add-node/            # Add-node component
│   ├── base-node/           # Base node components
│   ├── comment/             # Comment components
│   ├── group/               # Group components
│   ├── line-add-button/     # Connection add button
│   ├── node-menu/           # Node menu
│   ├── node-panel/          # Node add panel
│   ├── selector-box-popover/ # Selection box popover
│   ├── sidebar/             # Sidebar
│   ├── testrun/             # Test-run module
│   │   ├── hooks/           # Test-run hooks
│   │   ├── node-status-bar/ # Node status bar
│   │   ├── testrun-button/  # Test-run button
│   │   ├── testrun-form/    # Test-run form
│   │   ├── testrun-json-input/ # JSON input component
│   │   └── testrun-panel/   # Test-run panel
│   └── tools/               # Utility components
├── context/                 # React Context
│   ├── node-render-context.ts # Current rendering node context
│   ├── sidebar-context        # Sidebar context
├── form-components/         # Form component library
│   ├── form-content/        # Form content
│   ├── form-header/         # Form header
│   ├── form-inputs/         # Form inputs
│   └── form-item/           # Form item
│   └── feedback.tsx         # Validation error rendering
├── hooks/
│   ├── index.ts
│   ├── use-editor-props.tsx # Editor props hook
│   ├── use-is-sidebar.ts    # Sidebar state hook
│   ├── use-node-render-context.ts # Node render context hook
│   └── use-port-click.ts    # Port click hook
├── nodes/                    # Node definitions
│   ├── index.ts
│   ├── constants.ts         # Node constants
│   ├── default-form-meta.ts # Default form metadata
│   ├── block-end/           # Block end node
│   ├── block-start/         # Block start node
│   ├── break/               # Break node
│   ├── code/                # Code node
│   ├── comment/             # Comment node
│   ├── condition/           # Condition node
│   ├── continue/            # Continue node
│   ├── end/                 # End node
│   ├── group/               # Group node
│   ├── http/                # HTTP node
│   ├── llm/                 # LLM node
│   ├── loop/                # Loop node
│   ├── start/               # Start node
│   └── variable/            # Variable node
├── plugins/                 # Plugin system
│   ├── index.ts
│   ├── context-menu-plugin/ # Right-click context menu plugin
│   ├── runtime-plugin/      # Runtime plugin
│   │   ├── client/          # Client
│   │   │   ├── browser-client/ # Browser client
│   │   │   └── server-client/  # Server client
│   │   └── runtime-service/ # Runtime service
│   └── variable-panel-plugin/ # Variable panel plugin
│       └── components/      # Variable panel components
├── services/                 # Service layer
│   ├── index.ts
│   └── custom-service.ts    # Custom service
├── shortcuts/                # Shortcuts system
│   ├── index.ts
│   ├── constants.ts         # Shortcut constants
│   ├── shortcuts.ts         # Shortcut definitions
│   ├── type.ts              # Type definitions
│   ├── collapse/            # Collapse shortcut
│   ├── copy/                # Copy shortcut
│   ├── delete/              # Delete shortcut
│   ├── expand/              # Expand shortcut
│   ├── paste/               # Paste shortcut
│   ├── select-all/          # Select-all shortcut
│   ├── zoom-in/             # Zoom-in shortcut
│   └── zoom-out/            # Zoom-out shortcut
├── styles/                   # Styles
├── typings/                  # Type definitions
│   ├── index.ts
│   ├── json-schema.ts       # JSON Schema types
│   └── node.ts              # Node type definitions
└── utils/                    # Utility functions
    ├── index.ts
    └── on-drag-line-end.ts  # Handle end of drag line

Key Directory Functions

1. /components - Component Library

  • base-node: Base rendering components for all nodes
  • testrun: Complete test-run module, including status bar, form, and panel
  • sidebar: Sidebar components providing tools and property panels
  • node-panel: Node add panel with drag-to-add capability

2. /nodes - Node System

Each node type has its own directory, including:

  • Node registration (index.ts)
  • Form metadata (form-meta.ts)
  • Node-specific components and logic

3. /plugins - Plugin System

  • runtime-plugin: Supports both browser and server modes
  • context-menu-plugin: Right-click context menu
  • variable-panel-plugin: Variable management panel

4. /shortcuts - Shortcuts System

Complete keyboard shortcut support, including:

  • Basic actions: copy, paste, delete, select-all
  • View actions: zoom-in, zoom-out, collapse, expand
  • Each shortcut has its own implementation module

Application Architecture

Core Design Patterns

1. Plugin Architecture

Highly modular plugin system; each feature is an independent plugin:

plugins: () => [
  createFreeLinesPlugin({ renderInsideLine: LineAddButton }),
  createMinimapPlugin({ /* config */ }),
  createFreeSnapPlugin({ /* alignment config */ }),
  createFreeNodePanelPlugin({ renderer: NodePanel }),
  createContainerNodePlugin({}),
  createFreeGroupPlugin({ groupNodeRender: GroupNodeRender }),
  createContextMenuPlugin({}),
  createRuntimePlugin({ mode: 'browser' }),
  createVariablePanelPlugin({})
]

2. Node Registry Pattern

Manage different workflow node types via a registry:

export const nodeRegistries: FlowNodeRegistry[] = [
  ConditionNodeRegistry,    // Condition node
  StartNodeRegistry,        // Start node
  EndNodeRegistry,          // End node
  LLMNodeRegistry,          // LLM node
  LoopNodeRegistry,         // Loop node
  CommentNodeRegistry,      // Comment node
  HTTPNodeRegistry,         // HTTP node
  CodeNodeRegistry,         // Code node
  // ... more node types
];

3. Dependency Injection

Use Inversify for service DI:

onBind: ({ bind }) => {
  bind(CustomService).toSelf().inSingletonScope();
}

Core Features

1. Editor Configuration System

useEditorProps is the configuration center of the editor:

export function useEditorProps(
  initialData: FlowDocumentJSON,
  nodeRegistries: FlowNodeRegistry[]
): FreeLayoutProps {
  return useMemo<FreeLayoutProps>(() => ({
    background: true,                    // Background grid
    readonly: false,                     // Readonly mode
    initialData,                         // Initial data
    nodeRegistries,                      // Node registries

    // Core feature configs
    playground: { preventGlobalGesture: true /* Prevent Mac browser swipe gestures */ },
    nodeEngine: { enable: true },
    variableEngine: { enable: true },
    history: { enable: true, enableChangeNode: true },

    // Business rules
    canAddLine: (ctx, fromPort, toPort) => { /* Connection rules */ },
    canDeleteLine: (ctx, line) => { /* Line deletion rules */ },
    canDeleteNode: (ctx, node) => { /* Node deletion rules */ },
    canDropToNode: (ctx, params) => { /* Drag-and-drop rules */ },

    // Plugins
    plugins: () => [/* Plugin list */],

    // Events
    onContentChange: debounce((ctx, event) => { /* Auto save */ }, 1000),
    onInit: (ctx) => { /* Initialization */ },
    onAllLayersRendered: (ctx) => { /* After render */ }
  }), []);
}

2. Node Type System

The app supports multiple workflow node types:

export enum WorkflowNodeType {
  Start = 'start',           // Start node
  End = 'end',               // End node
  LLM = 'llm',               // Large language model node
  HTTP = 'http',             // HTTP request node
  Code = 'code',             // Code execution node
  Variable = 'variable',     // Variable node
  Condition = 'condition',   // Conditional node
  Loop = 'loop',             // Loop node
  BlockStart = 'block-start', // Sub-canvas start node
  BlockEnd = 'block-end',    // Sub-canvas end node
  Comment = 'comment',       // Comment node
  Continue = 'continue',     // Continue node
  Break = 'break',           // Break node
}

Each node follows a unified registration pattern:

export const StartNodeRegistry: FlowNodeRegistry = {
  type: WorkflowNodeType.Start,
  meta: {
    isStart: true,
    deleteDisable: true,        // Not deletable
    copyDisable: true,          // Not copyable
    nodePanelVisible: false,    // Hidden in node panel
    defaultPorts: [{ type: 'output' }],
    size: { width: 360, height: 211 }
  },
  info: {
    icon: iconStart,
    description: 'The starting node of the workflow, used to set up information needed to launch the workflow.'
  },
  formMeta,                     // Form configuration
  canAdd() { return false; }    // Disallow multiple start nodes
};

3. Plugin Architecture

App features are modularized via the plugin system:

Core Plugin List

  • FreeLinesPlugin - Connection rendering and interaction
  • MinimapPlugin - Minimap navigation
  • FreeSnapPlugin - Auto-alignment and guide-lines
  • FreeNodePanelPlugin - Node add panel
  • ContainerNodePlugin - Container nodes (e.g., loop nodes)
  • FreeGroupPlugin - Node grouping
  • ContextMenuPlugin - Right-click context menu
  • RuntimePlugin - Workflow runtime
  • VariablePanelPlugin - Variable management panel

4. Runtime System

Two run modes are supported:

createRuntimePlugin({
  mode: 'browser',              // Browser mode
  // mode: 'server',            // Server mode
  // serverConfig: {
  //   domain: 'localhost',
  //   port: 4000,
  //   protocol: 'http',
  // },
})

Design Philosophy and Advantages

1. Highly Modular

  • Plugin architecture: Each feature is an independent plugin, easy to extend and maintain
  • Node registry system: Add new node types without changing core code
  • Componentized UI: Highly reusable components with clear responsibilities

2. Type Safety

  • Full TypeScript support: End-to-end type safety from configuration to runtime
  • JSON Schema integration: Node data validated by schemas
  • Strongly typed plugin interfaces: Clear type constraints for plugin development

3. User Experience

  • Real-time preview: Run and debug workflows live
  • Rich interactions: Dragging, zooming, snapping, shortcuts for a complete editing experience
  • Visual feedback: Minimap, status indicators, line animations

4. Extensibility

  • Open plugin system: Third parties can easily develop custom plugins
  • Flexible node system: Custom node types and form configurations supported
  • Multiple runtimes: Both browser and server modes

5. Performance

  • On-demand loading: Components and plugins support lazy loading
  • Debounce: Performance optimizations for high-frequency operations like auto-save

Technical Highlights

1. In-house Editor Framework

Based on @flowgram.ai/free-layout-editor, providing:

  • Free-layout canvas system
  • Full undo/redo functionality
  • Lifecycle management for nodes and connections
  • Variable engine and expression system

2. Advanced Build Configuration

Using Rsbuild as the build tool:

export default defineConfig({
  plugins: [pluginReact(), pluginLess()],
  source: {
    entry: { index: './src/app.tsx' },
    decorators: { version: 'legacy' }  // Enable decorators
  },
  tools: {
    rspack: {
      ignoreWarnings: [/Critical dependency/]  // Ignore specific warnings
    }
  }
});

3. Internationalization

Built-in multilingual support:

i18n: {
  locale: navigator.language,
  languages: {
    'zh-CN': {
      'Never Remind': '不再提示',
      'Hold {{key}} to drag node out': '按住 {{key}} 可以将节点拖出',
    },
    'en-US': {},
  }
}

FAQs

Package last updated on 28 Oct 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts