diff --git a/apps/create-app/src/index.ts b/apps/create-app/src/index.ts
index d890d754..0c0235b3 100644
--- a/apps/create-app/src/index.ts
+++ b/apps/create-app/src/index.ts
@@ -41,7 +41,8 @@ program
{ name: 'Free Layout Demo', value: 'demo-free-layout' },
{ name: 'Fixed Layout Demo Simple', value: 'demo-fixed-layout-simple' },
{ name: 'Free Layout Demo Simple', value: 'demo-free-layout-simple' },
- { name: 'Free Layout Nextjs Demo', value: 'demo-nextjs' }
+ { name: 'Free Layout Nextjs Demo', value: 'demo-nextjs' },
+ { name: 'Free Layout Vite Demo Simple', value: 'demo-vite' }
],
},
]);
diff --git a/apps/demo-fixed-layout/src/nodes/condition/index.ts b/apps/demo-fixed-layout/src/nodes/condition/index.ts
index f0b0a619..f260b6b0 100644
--- a/apps/demo-fixed-layout/src/nodes/condition/index.ts
+++ b/apps/demo-fixed-layout/src/nodes/condition/index.ts
@@ -43,6 +43,7 @@ export const ConditionNodeRegistry: FlowNodeRegistry = {
},
},
},
+ blocks: [],
},
{
id: nanoid(5),
diff --git a/apps/demo-vite/.eslintrc.js b/apps/demo-vite/.eslintrc.js
new file mode 100644
index 00000000..eb44479a
--- /dev/null
+++ b/apps/demo-vite/.eslintrc.js
@@ -0,0 +1,16 @@
+const { defineConfig } = require('@flowgram.ai/eslint-config');
+
+module.exports = defineConfig({
+ preset: 'web',
+ packageRoot: __dirname,
+ rules: {
+ 'no-console': 'off',
+ 'react/prop-types': 'off',
+ 'react/no-deprecated': 'off',
+ },
+ settings: {
+ react: {
+ version: 'detect', // 自动检测 React 版本
+ },
+ },
+});
diff --git a/apps/demo-vite/index.html b/apps/demo-vite/index.html
new file mode 100644
index 00000000..698444fb
--- /dev/null
+++ b/apps/demo-vite/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Flow FreeLayoutEditor Demo
+
+
+
+
+
+
diff --git a/apps/demo-vite/package.json b/apps/demo-vite/package.json
new file mode 100644
index 00000000..bead384f
--- /dev/null
+++ b/apps/demo-vite/package.json
@@ -0,0 +1,55 @@
+{
+ "name": "@flowgram.ai/demo-vite",
+ "version": "0.1.0",
+ "description": "",
+ "keywords": [],
+ "license": "MIT",
+ "main": "./src/index.tsx",
+ "files": [
+ "src/",
+ ".eslintrc.js",
+ ".gitignore",
+ "index.html",
+ "package.json",
+ "vite.config.js",
+ "tsconfig.json"
+ ],
+ "scripts": {
+ "dev": "vite",
+ "start": "vite",
+ "build": "exit 0",
+ "clean": "rimraf dist",
+ "build:production": "vite build",
+ "lint": "eslint ./src --cache",
+ "lint:fix": "eslint ./src --fix",
+ "test": "exit",
+ "test:cov": "exit",
+ "watch": "exit 0",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "@flowgram.ai/free-layout-editor": "workspace:*",
+ "@flowgram.ai/free-snap-plugin": "workspace:*",
+ "@flowgram.ai/minimap-plugin": "workspace:*",
+ "react": "^18",
+ "react-dom": "^18"
+ },
+ "devDependencies": {
+ "@flowgram.ai/ts-config": "workspace:*",
+ "@flowgram.ai/eslint-config": "workspace:*",
+ "@vitejs/plugin-react": "^4.4.1",
+ "@types/lodash-es": "^4.17.12",
+ "@types/node": "^18",
+ "@types/react": "^18",
+ "@types/react-dom": "^18",
+ "eslint": "^8.54.0",
+ "cross-env": "~7.0.3",
+ "globals": "^15.11.0",
+ "less": "^4.1.2",
+ "vite": "^6.3.5"
+ },
+ "publishConfig": {
+ "access": "public",
+ "registry": "https://registry.npmjs.org/"
+ }
+}
diff --git a/apps/demo-vite/src/app.tsx b/apps/demo-vite/src/app.tsx
new file mode 100644
index 00000000..150c56b5
--- /dev/null
+++ b/apps/demo-vite/src/app.tsx
@@ -0,0 +1,7 @@
+import { createRoot } from 'react-dom/client';
+
+import { Editor } from './editor';
+
+const app = createRoot(document.getElementById('root')!);
+
+app.render();
diff --git a/apps/demo-vite/src/components/minimap.tsx b/apps/demo-vite/src/components/minimap.tsx
new file mode 100644
index 00000000..518eacfa
--- /dev/null
+++ b/apps/demo-vite/src/components/minimap.tsx
@@ -0,0 +1,35 @@
+import { FlowMinimapService, MinimapRender } from '@flowgram.ai/minimap-plugin';
+import { useService } from '@flowgram.ai/free-layout-editor';
+
+export const Minimap = () => {
+ const minimapService = useService(FlowMinimapService);
+ return (
+
+
+
+ );
+};
diff --git a/apps/demo-vite/src/components/node-add-panel.tsx b/apps/demo-vite/src/components/node-add-panel.tsx
new file mode 100644
index 00000000..ba7ede20
--- /dev/null
+++ b/apps/demo-vite/src/components/node-add-panel.tsx
@@ -0,0 +1,30 @@
+import React from 'react';
+
+import { WorkflowDragService, useService } from '@flowgram.ai/free-layout-editor';
+
+const cardkeys = ['Node1', 'Node2'];
+
+export const NodeAddPanel: React.FC = (props) => {
+ const startDragSerivce = useService(WorkflowDragService);
+
+ return (
+
+ {cardkeys.map((nodeType) => (
+
+ startDragSerivce.startDragCard(nodeType, e, {
+ data: {
+ title: `New ${nodeType}`,
+ content: 'xxxx',
+ },
+ })
+ }
+ >
+ {nodeType}
+
+ ))}
+
+ );
+};
diff --git a/apps/demo-vite/src/components/tools.tsx b/apps/demo-vite/src/components/tools.tsx
new file mode 100644
index 00000000..6f38bac3
--- /dev/null
+++ b/apps/demo-vite/src/components/tools.tsx
@@ -0,0 +1,36 @@
+import { useEffect, useState } from 'react';
+
+import { usePlaygroundTools, useClientContext } from '@flowgram.ai/free-layout-editor';
+
+export function Tools() {
+ const { history } = useClientContext();
+ const tools = usePlaygroundTools();
+ const [canUndo, setCanUndo] = useState(false);
+ const [canRedo, setCanRedo] = useState(false);
+
+ useEffect(() => {
+ const disposable = history.undoRedoService.onChange(() => {
+ setCanUndo(history.canUndo());
+ setCanRedo(history.canRedo());
+ });
+ return () => disposable.dispose();
+ }, [history]);
+
+ return (
+
+
+
+
+
+
+
+ {Math.floor(tools.zoom * 100)}%
+
+ );
+}
diff --git a/apps/demo-vite/src/editor.tsx b/apps/demo-vite/src/editor.tsx
new file mode 100644
index 00000000..267f7012
--- /dev/null
+++ b/apps/demo-vite/src/editor.tsx
@@ -0,0 +1,24 @@
+import { EditorRenderer, FreeLayoutEditorProvider } from '@flowgram.ai/free-layout-editor';
+
+import { useEditorProps } from './hooks/use-editor-props';
+import { Tools } from './components/tools';
+import { NodeAddPanel } from './components/node-add-panel';
+import { Minimap } from './components/minimap';
+import '@flowgram.ai/free-layout-editor/index.css';
+import './index.css';
+
+export const Editor = () => {
+ const editorProps = useEditorProps();
+ return (
+
+
+
+ );
+};
diff --git a/apps/demo-vite/src/hooks/use-editor-props.tsx b/apps/demo-vite/src/hooks/use-editor-props.tsx
new file mode 100644
index 00000000..84163317
--- /dev/null
+++ b/apps/demo-vite/src/hooks/use-editor-props.tsx
@@ -0,0 +1,155 @@
+import { useMemo } from 'react';
+
+import { createMinimapPlugin } from '@flowgram.ai/minimap-plugin';
+import { createFreeSnapPlugin } from '@flowgram.ai/free-snap-plugin';
+import {
+ FreeLayoutProps,
+ WorkflowNodeProps,
+ WorkflowNodeRenderer,
+ Field,
+ useNodeRender,
+} from '@flowgram.ai/free-layout-editor';
+
+import { nodeRegistries } from '../node-registries';
+import { initialData } from '../initial-data';
+
+export const useEditorProps = () =>
+ useMemo(
+ () => ({
+ /**
+ * Whether to enable the background
+ */
+ background: true,
+ /**
+ * Whether it is read-only or not, the node cannot be dragged in read-only mode
+ */
+ readonly: false,
+ /**
+ * Initial data
+ * 初始化数据
+ */
+ initialData,
+ /**
+ * Node registries
+ * 节点注册
+ */
+ nodeRegistries,
+ /**
+ * Get the default node registry, which will be merged with the 'nodeRegistries'
+ * 提供默认的节点注册,这个会和 nodeRegistries 做合并
+ */
+ getNodeDefaultRegistry(type) {
+ return {
+ type,
+ meta: {
+ defaultExpanded: true,
+ },
+ formMeta: {
+ /**
+ * Render form
+ */
+ render: () => (
+ <>
+ name="title">
+ {({ field }) => {field.value}
}
+
+
+ name="content">
+
+
+
+ >
+ ),
+ },
+ };
+ },
+ materials: {
+ /**
+ * Render Node
+ */
+ renderDefaultNode: (props: WorkflowNodeProps) => {
+ const { form } = useNodeRender();
+ return (
+
+ {form?.render()}
+
+ );
+ },
+ },
+ /**
+ * Content change
+ */
+ onContentChange(ctx, event) {
+ // console.log('Auto Save: ', event, ctx.document.toJSON());
+ },
+ // /**
+ // * Node engine enable, you can configure formMeta in the FlowNodeRegistry
+ // */
+ nodeEngine: {
+ enable: true,
+ },
+ /**
+ * Redo/Undo enable
+ */
+ history: {
+ enable: true,
+ enableChangeNode: true, // Listen Node engine data change
+ },
+ /**
+ * Playground init
+ */
+ onInit: (ctx) => {},
+ /**
+ * Playground render
+ */
+ onAllLayersRendered(ctx) {
+ // Fitview
+ ctx.document.fitView(false);
+ },
+ /**
+ * Playground dispose
+ */
+ onDispose() {
+ console.log('---- Playground Dispose ----');
+ },
+ plugins: () => [
+ /**
+ * Minimap plugin
+ * 缩略图插件
+ */
+ createMinimapPlugin({
+ disableLayer: true,
+ canvasStyle: {
+ canvasWidth: 182,
+ canvasHeight: 102,
+ canvasPadding: 50,
+ canvasBackground: 'rgba(245, 245, 245, 1)',
+ canvasBorderRadius: 10,
+ viewportBackground: 'rgba(235, 235, 235, 1)',
+ viewportBorderRadius: 4,
+ viewportBorderColor: 'rgba(201, 201, 201, 1)',
+ viewportBorderWidth: 1,
+ viewportBorderDashLength: 2,
+ nodeColor: 'rgba(255, 255, 255, 1)',
+ nodeBorderRadius: 2,
+ nodeBorderWidth: 0.145,
+ nodeBorderColor: 'rgba(6, 7, 9, 0.10)',
+ overlayColor: 'rgba(255, 255, 255, 0)',
+ },
+ inactiveDebounceTime: 1,
+ }),
+ /**
+ * Snap plugin
+ * 自动对齐及辅助线插件
+ */
+ createFreeSnapPlugin({
+ edgeColor: '#00B2B2',
+ alignColor: '#00B2B2',
+ edgeLineWidth: 1,
+ alignLineWidth: 1,
+ alignCrossWidth: 8,
+ }),
+ ],
+ }),
+ []
+ );
diff --git a/apps/demo-vite/src/index.css b/apps/demo-vite/src/index.css
new file mode 100644
index 00000000..c76cebfb
--- /dev/null
+++ b/apps/demo-vite/src/index.css
@@ -0,0 +1,107 @@
+.demo-free-node {
+ display: flex;
+ min-width: 300px;
+ min-height: 100px;
+ flex-direction: column;
+ align-items: flex-start;
+ box-sizing: border-box;
+ border-radius: 8px;
+ border: 1px solid var(--light-usage-border-color-border, rgba(28, 31, 35, 0.08));
+ background: #fff;
+ box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.1);
+}
+
+.demo-free-node-title {
+ background-color: #93bfe2;
+ width: 100%;
+ border-radius: 8px 8px 0 0;
+ padding: 4px 12px;
+}
+.demo-free-node-content {
+ padding: 4px 12px;
+ flex-grow: 1;
+ width: 100%;
+}
+.demo-free-node::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: -1;
+ background-color: white;
+ border-radius: 7px;
+}
+
+.demo-free-node:hover:before {
+ -webkit-filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.3)) drop-shadow(0 4px 14px rgba(0, 0, 0, 0.1));
+ filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.3)) drop-shadow(0 4px 14px rgba(0, 0, 0, 0.1));
+}
+
+.demo-free-node.activated:before,
+.demo-free-node.selected:before {
+ outline: 2px solid var(--light-usage-primary-color-primary, #4d53e8);
+ -webkit-filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.3)) drop-shadow(0 4px 14px rgba(0, 0, 0, 0.1));
+ filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.3)) drop-shadow(0 4px 14px rgba(0, 0, 0, 0.1));
+}
+
+.demo-free-sidebar {
+ height: 100%;
+ overflow-y: auto;
+ padding: 12px 16px 0;
+ box-sizing: border-box;
+ background: #f7f7fa;
+ border-right: 1px solid rgba(29, 28, 35, 0.08);
+}
+
+.demo-free-right-top-panel {
+ position: fixed;
+ right: 10px;
+ top: 70px;
+ width: 300px;
+ z-index: 999;
+}
+
+.demo-free-card {
+ width: 140px;
+ height: 60px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 20px;
+ background: #fff;
+ border-radius: 8px;
+ box-shadow: 0 6px 8px 0 rgba(28, 31, 35, 0.03);
+ cursor: -webkit-grab;
+ cursor: grab;
+ line-height: 16px;
+ margin-bottom: 12px;
+ overflow: hidden;
+ padding: 16px;
+ position: relative;
+ color: black;
+}
+
+.demo-free-layout {
+ display: flex;
+ flex-direction: row;
+ flex-grow: 1;
+}
+
+.demo-free-editor {
+ flex-grow: 1;
+ position: relative;
+ height: 100%;
+}
+
+.demo-free-container {
+ position: absolute;
+ left: 0;
+ top: 0;
+ display: flex;
+ width: 100%;
+ height: 100%;
+ flex-direction: column;
+}
+
diff --git a/apps/demo-vite/src/index.tsx b/apps/demo-vite/src/index.tsx
new file mode 100644
index 00000000..c38080e9
--- /dev/null
+++ b/apps/demo-vite/src/index.tsx
@@ -0,0 +1 @@
+export { Editor as DemoFreeLayout } from './editor';
diff --git a/apps/demo-vite/src/initial-data.ts b/apps/demo-vite/src/initial-data.ts
new file mode 100644
index 00000000..e23756e0
--- /dev/null
+++ b/apps/demo-vite/src/initial-data.ts
@@ -0,0 +1,49 @@
+import { WorkflowJSON } from '@flowgram.ai/free-layout-editor';
+
+export const initialData: WorkflowJSON = {
+ nodes: [
+ {
+ id: 'start_0',
+ type: 'start',
+ meta: {
+ position: { x: 0, y: 0 },
+ },
+ data: {
+ title: 'Start',
+ content: 'Start content',
+ },
+ },
+ {
+ id: 'node_0',
+ type: 'custom',
+ meta: {
+ position: { x: 400, y: 0 },
+ },
+ data: {
+ title: 'Custom',
+ content: 'Custom node content',
+ },
+ },
+ {
+ id: 'end_0',
+ type: 'end',
+ meta: {
+ position: { x: 800, y: 0 },
+ },
+ data: {
+ title: 'End',
+ content: 'End content',
+ },
+ },
+ ],
+ edges: [
+ {
+ sourceNodeID: 'start_0',
+ targetNodeID: 'node_0',
+ },
+ {
+ sourceNodeID: 'node_0',
+ targetNodeID: 'end_0',
+ },
+ ],
+};
diff --git a/apps/demo-vite/src/node-registries.ts b/apps/demo-vite/src/node-registries.ts
new file mode 100644
index 00000000..703a1f60
--- /dev/null
+++ b/apps/demo-vite/src/node-registries.ts
@@ -0,0 +1,30 @@
+import { WorkflowNodeRegistry } from '@flowgram.ai/free-layout-editor';
+
+/**
+ * You can customize your own node registry
+ * 你可以自定义节点的注册器
+ */
+export const nodeRegistries: WorkflowNodeRegistry[] = [
+ {
+ type: 'start',
+ meta: {
+ isStart: true, // Mark as start
+ deleteDisable: true, // The start node cannot be deleted
+ copyDisable: true, // The start node cannot be copied
+ defaultPorts: [{ type: 'output' }], // Used to define the input and output ports, the start node only has the output port
+ },
+ },
+ {
+ type: 'end',
+ meta: {
+ deleteDisable: true,
+ copyDisable: true,
+ defaultPorts: [{ type: 'input' }],
+ },
+ },
+ {
+ type: 'custom',
+ meta: {},
+ defaultPorts: [{ type: 'output' }, { type: 'input' }], // A normal node has two ports
+ },
+];
diff --git a/apps/demo-vite/tsconfig.json b/apps/demo-vite/tsconfig.json
new file mode 100644
index 00000000..171a60f5
--- /dev/null
+++ b/apps/demo-vite/tsconfig.json
@@ -0,0 +1,23 @@
+{
+ "extends": "@flowgram.ai/ts-config/tsconfig.flow.path.json",
+ "compilerOptions": {
+ "rootDir": "./src",
+ "outDir": "./dist",
+ "experimentalDecorators": true,
+ "target": "es2020",
+ "module": "esnext",
+ "strictPropertyInitialization": false,
+ "strict": true,
+ "esModuleInterop": true,
+ "moduleResolution": "node",
+ "skipLibCheck": true,
+ "noUnusedLocals": true,
+ "noImplicitAny": true,
+ "allowJs": true,
+ "resolveJsonModule": true,
+ "types": ["node"],
+ "jsx": "react-jsx",
+ "lib": ["es6", "dom", "es2020", "es2019.Array"]
+ },
+ "include": ["./src"],
+}
diff --git a/apps/demo-vite/vite.config.js b/apps/demo-vite/vite.config.js
new file mode 100644
index 00000000..4a5def4c
--- /dev/null
+++ b/apps/demo-vite/vite.config.js
@@ -0,0 +1,7 @@
+import { defineConfig } from 'vite';
+import react from '@vitejs/plugin-react';
+
+// https://vite.dev/config/
+export default defineConfig({
+ plugins: [react()],
+});
diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml
index ec9341ba..7341fb5e 100644
--- a/common/config/rush/pnpm-lock.yaml
+++ b/common/config/rush/pnpm-lock.yaml
@@ -532,6 +532,61 @@ importers:
specifier: ^8.54.0
version: 8.57.1
+ ../../apps/demo-vite:
+ dependencies:
+ '@flowgram.ai/free-layout-editor':
+ specifier: workspace:*
+ version: link:../../packages/client/free-layout-editor
+ '@flowgram.ai/free-snap-plugin':
+ specifier: workspace:*
+ version: link:../../packages/plugins/free-snap-plugin
+ '@flowgram.ai/minimap-plugin':
+ specifier: workspace:*
+ version: link:../../packages/plugins/minimap-plugin
+ react:
+ specifier: ^18
+ version: 18.3.1
+ react-dom:
+ specifier: ^18
+ version: 18.3.1(react@18.3.1)
+ devDependencies:
+ '@flowgram.ai/eslint-config':
+ specifier: workspace:*
+ version: link:../../config/eslint-config
+ '@flowgram.ai/ts-config':
+ specifier: workspace:*
+ version: link:../../config/ts-config
+ '@types/lodash-es':
+ specifier: ^4.17.12
+ version: 4.17.12
+ '@types/node':
+ specifier: ^18
+ version: 18.19.68
+ '@types/react':
+ specifier: ^18
+ version: 18.3.16
+ '@types/react-dom':
+ specifier: ^18
+ version: 18.3.5(@types/react@18.3.16)
+ '@vitejs/plugin-react':
+ specifier: ^4.4.1
+ version: 4.4.1(vite@6.3.5)
+ cross-env:
+ specifier: ~7.0.3
+ version: 7.0.3
+ eslint:
+ specifier: ^8.54.0
+ version: 8.57.1
+ globals:
+ specifier: ^15.11.0
+ version: 15.13.0
+ less:
+ specifier: ^4.1.2
+ version: 4.3.0
+ vite:
+ specifier: ^6.3.5
+ version: 6.3.5(@types/node@18.19.68)(less@4.3.0)
+
../../apps/docs:
dependencies:
'@codesandbox/sandpack-react':
@@ -3979,6 +4034,11 @@ packages:
resolution: {integrity: sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==}
engines: {node: '>=6.9.0'}
+ /@babel/helper-plugin-utils@7.27.1:
+ resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==}
+ engines: {node: '>=6.9.0'}
+ dev: true
+
/@babel/helper-remap-async-to-generator@7.25.9(@babel/core@7.26.0):
resolution: {integrity: sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==}
engines: {node: '>=6.9.0'}
@@ -4755,6 +4815,26 @@ packages:
- supports-color
dev: false
+ /@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.26.10):
+ resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.26.10
+ '@babel/helper-plugin-utils': 7.27.1
+ dev: true
+
+ /@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.26.10):
+ resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.26.10
+ '@babel/helper-plugin-utils': 7.27.1
+ dev: true
+
/@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.0):
resolution: {integrity: sha512-s5XwpQYCqGerXl+Pu6VDL3x0j2d82eiV77UJ8a2mDHAW7j9SWRqQ2y1fNo1Z74CdcYipl5Z41zvjj4Nfzq36rw==}
engines: {node: '>=6.9.0'}
@@ -6718,6 +6798,14 @@ packages:
dev: true
optional: true
+ /@rollup/rollup-android-arm-eabi@4.40.2:
+ resolution: {integrity: sha512-JkdNEq+DFxZfUwxvB58tHMHBHVgX23ew41g1OQinthJ+ryhdRk67O31S7sYw8u2lTjHUPFxwar07BBt1KHp/hg==}
+ cpu: [arm]
+ os: [android]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@rollup/rollup-android-arm64@4.28.1:
resolution: {integrity: sha512-EbkK285O+1YMrg57xVA+Dp0tDBRB93/BZKph9XhMjezf6F4TpYjaUSuPt5J0fZXlSag0LmZAsTmdGGqPp4pQFA==}
cpu: [arm64]
@@ -6726,6 +6814,14 @@ packages:
dev: true
optional: true
+ /@rollup/rollup-android-arm64@4.40.2:
+ resolution: {integrity: sha512-13unNoZ8NzUmnndhPTkWPWbX3vtHodYmy+I9kuLxN+F+l+x3LdVF7UCu8TWVMt1POHLh6oDHhnOA04n8oJZhBw==}
+ cpu: [arm64]
+ os: [android]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@rollup/rollup-darwin-arm64@4.28.1:
resolution: {integrity: sha512-prduvrMKU6NzMq6nxzQw445zXgaDBbMQvmKSJaxpaZ5R1QDM8w+eGxo6Y/jhT/cLoCvnZI42oEqf9KQNYz1fqQ==}
cpu: [arm64]
@@ -6734,6 +6830,14 @@ packages:
dev: true
optional: true
+ /@rollup/rollup-darwin-arm64@4.40.2:
+ resolution: {integrity: sha512-Gzf1Hn2Aoe8VZzevHostPX23U7N5+4D36WJNHK88NZHCJr7aVMG4fadqkIf72eqVPGjGc0HJHNuUaUcxiR+N/w==}
+ cpu: [arm64]
+ os: [darwin]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@rollup/rollup-darwin-x64@4.28.1:
resolution: {integrity: sha512-WsvbOunsUk0wccO/TV4o7IKgloJ942hVFK1CLatwv6TJspcCZb9umQkPdvB7FihmdxgaKR5JyxDjWpCOp4uZlQ==}
cpu: [x64]
@@ -6742,6 +6846,14 @@ packages:
dev: true
optional: true
+ /@rollup/rollup-darwin-x64@4.40.2:
+ resolution: {integrity: sha512-47N4hxa01a4x6XnJoskMKTS8XZ0CZMd8YTbINbi+w03A2w4j1RTlnGHOz/P0+Bg1LaVL6ufZyNprSg+fW5nYQQ==}
+ cpu: [x64]
+ os: [darwin]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@rollup/rollup-freebsd-arm64@4.28.1:
resolution: {integrity: sha512-HTDPdY1caUcU4qK23FeeGxCdJF64cKkqajU0iBnTVxS8F7H/7BewvYoG+va1KPSL63kQ1PGNyiwKOfReavzvNA==}
cpu: [arm64]
@@ -6750,6 +6862,14 @@ packages:
dev: true
optional: true
+ /@rollup/rollup-freebsd-arm64@4.40.2:
+ resolution: {integrity: sha512-8t6aL4MD+rXSHHZUR1z19+9OFJ2rl1wGKvckN47XFRVO+QL/dUSpKA2SLRo4vMg7ELA8pzGpC+W9OEd1Z/ZqoQ==}
+ cpu: [arm64]
+ os: [freebsd]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@rollup/rollup-freebsd-x64@4.28.1:
resolution: {integrity: sha512-m/uYasxkUevcFTeRSM9TeLyPe2QDuqtjkeoTpP9SW0XxUWfcYrGDMkO/m2tTw+4NMAF9P2fU3Mw4ahNvo7QmsQ==}
cpu: [x64]
@@ -6758,6 +6878,14 @@ packages:
dev: true
optional: true
+ /@rollup/rollup-freebsd-x64@4.40.2:
+ resolution: {integrity: sha512-C+AyHBzfpsOEYRFjztcYUFsH4S7UsE9cDtHCtma5BK8+ydOZYgMmWg1d/4KBytQspJCld8ZIujFMAdKG1xyr4Q==}
+ cpu: [x64]
+ os: [freebsd]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@rollup/rollup-linux-arm-gnueabihf@4.28.1:
resolution: {integrity: sha512-QAg11ZIt6mcmzpNE6JZBpKfJaKkqTm1A9+y9O+frdZJEuhQxiugM05gnCWiANHj4RmbgeVJpTdmKRmH/a+0QbA==}
cpu: [arm]
@@ -6767,6 +6895,14 @@ packages:
dev: true
optional: true
+ /@rollup/rollup-linux-arm-gnueabihf@4.40.2:
+ resolution: {integrity: sha512-de6TFZYIvJwRNjmW3+gaXiZ2DaWL5D5yGmSYzkdzjBDS3W+B9JQ48oZEsmMvemqjtAFzE16DIBLqd6IQQRuG9Q==}
+ cpu: [arm]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@rollup/rollup-linux-arm-musleabihf@4.28.1:
resolution: {integrity: sha512-dRP9PEBfolq1dmMcFqbEPSd9VlRuVWEGSmbxVEfiq2cs2jlZAl0YNxFzAQS2OrQmsLBLAATDMb3Z6MFv5vOcXg==}
cpu: [arm]
@@ -6776,6 +6912,14 @@ packages:
dev: true
optional: true
+ /@rollup/rollup-linux-arm-musleabihf@4.40.2:
+ resolution: {integrity: sha512-urjaEZubdIkacKc930hUDOfQPysezKla/O9qV+O89enqsqUmQm8Xj8O/vh0gHg4LYfv7Y7UsE3QjzLQzDYN1qg==}
+ cpu: [arm]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@rollup/rollup-linux-arm64-gnu@4.28.1:
resolution: {integrity: sha512-uGr8khxO+CKT4XU8ZUH1TTEUtlktK6Kgtv0+6bIFSeiSlnGJHG1tSFSjm41uQ9sAO/5ULx9mWOz70jYLyv1QkA==}
cpu: [arm64]
@@ -6785,6 +6929,14 @@ packages:
dev: true
optional: true
+ /@rollup/rollup-linux-arm64-gnu@4.40.2:
+ resolution: {integrity: sha512-KlE8IC0HFOC33taNt1zR8qNlBYHj31qGT1UqWqtvR/+NuCVhfufAq9fxO8BMFC22Wu0rxOwGVWxtCMvZVLmhQg==}
+ cpu: [arm64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@rollup/rollup-linux-arm64-musl@4.28.1:
resolution: {integrity: sha512-QF54q8MYGAqMLrX2t7tNpi01nvq5RI59UBNx+3+37zoKX5KViPo/gk2QLhsuqok05sSCRluj0D00LzCwBikb0A==}
cpu: [arm64]
@@ -6794,6 +6946,14 @@ packages:
dev: true
optional: true
+ /@rollup/rollup-linux-arm64-musl@4.40.2:
+ resolution: {integrity: sha512-j8CgxvfM0kbnhu4XgjnCWJQyyBOeBI1Zq91Z850aUddUmPeQvuAy6OiMdPS46gNFgy8gN1xkYyLgwLYZG3rBOg==}
+ cpu: [arm64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@rollup/rollup-linux-loongarch64-gnu@4.28.1:
resolution: {integrity: sha512-vPul4uodvWvLhRco2w0GcyZcdyBfpfDRgNKU+p35AWEbJ/HPs1tOUrkSueVbBS0RQHAf/A+nNtDpvw95PeVKOA==}
cpu: [loong64]
@@ -6803,6 +6963,14 @@ packages:
dev: true
optional: true
+ /@rollup/rollup-linux-loongarch64-gnu@4.40.2:
+ resolution: {integrity: sha512-Ybc/1qUampKuRF4tQXc7G7QY9YRyeVSykfK36Y5Qc5dmrIxwFhrOzqaVTNoZygqZ1ZieSWTibfFhQ5qK8jpWxw==}
+ cpu: [loong64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@rollup/rollup-linux-powerpc64le-gnu@4.28.1:
resolution: {integrity: sha512-pTnTdBuC2+pt1Rmm2SV7JWRqzhYpEILML4PKODqLz+C7Ou2apEV52h19CR7es+u04KlqplggmN9sqZlekg3R1A==}
cpu: [ppc64]
@@ -6812,6 +6980,14 @@ packages:
dev: true
optional: true
+ /@rollup/rollup-linux-powerpc64le-gnu@4.40.2:
+ resolution: {integrity: sha512-3FCIrnrt03CCsZqSYAOW/k9n625pjpuMzVfeI+ZBUSDT3MVIFDSPfSUgIl9FqUftxcUXInvFah79hE1c9abD+Q==}
+ cpu: [ppc64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@rollup/rollup-linux-riscv64-gnu@4.28.1:
resolution: {integrity: sha512-vWXy1Nfg7TPBSuAncfInmAI/WZDd5vOklyLJDdIRKABcZWojNDY0NJwruY2AcnCLnRJKSaBgf/GiJfauu8cQZA==}
cpu: [riscv64]
@@ -6821,6 +6997,22 @@ packages:
dev: true
optional: true
+ /@rollup/rollup-linux-riscv64-gnu@4.40.2:
+ resolution: {integrity: sha512-QNU7BFHEvHMp2ESSY3SozIkBPaPBDTsfVNGx3Xhv+TdvWXFGOSH2NJvhD1zKAT6AyuuErJgbdvaJhYVhVqrWTg==}
+ cpu: [riscv64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@rollup/rollup-linux-riscv64-musl@4.40.2:
+ resolution: {integrity: sha512-5W6vNYkhgfh7URiXTO1E9a0cy4fSgfE4+Hl5agb/U1sa0kjOLMLC1wObxwKxecE17j0URxuTrYZZME4/VH57Hg==}
+ cpu: [riscv64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@rollup/rollup-linux-s390x-gnu@4.28.1:
resolution: {integrity: sha512-/yqC2Y53oZjb0yz8PVuGOQQNOTwxcizudunl/tFs1aLvObTclTwZ0JhXF2XcPT/zuaymemCDSuuUPXJJyqeDOg==}
cpu: [s390x]
@@ -6830,6 +7022,14 @@ packages:
dev: true
optional: true
+ /@rollup/rollup-linux-s390x-gnu@4.40.2:
+ resolution: {integrity: sha512-B7LKIz+0+p348JoAL4X/YxGx9zOx3sR+o6Hj15Y3aaApNfAshK8+mWZEf759DXfRLeL2vg5LYJBB7DdcleYCoQ==}
+ cpu: [s390x]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@rollup/rollup-linux-x64-gnu@4.28.1:
resolution: {integrity: sha512-fzgeABz7rrAlKYB0y2kSEiURrI0691CSL0+KXwKwhxvj92VULEDQLpBYLHpF49MSiPG4sq5CK3qHMnb9tlCjBw==}
cpu: [x64]
@@ -6839,6 +7039,14 @@ packages:
dev: true
optional: true
+ /@rollup/rollup-linux-x64-gnu@4.40.2:
+ resolution: {integrity: sha512-lG7Xa+BmBNwpjmVUbmyKxdQJ3Q6whHjMjzQplOs5Z+Gj7mxPtWakGHqzMqNER68G67kmCX9qX57aRsW5V0VOng==}
+ cpu: [x64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@rollup/rollup-linux-x64-musl@4.28.1:
resolution: {integrity: sha512-xQTDVzSGiMlSshpJCtudbWyRfLaNiVPXt1WgdWTwWz9n0U12cI2ZVtWe/Jgwyv/6wjL7b66uu61Vg0POWVfz4g==}
cpu: [x64]
@@ -6848,6 +7056,14 @@ packages:
dev: true
optional: true
+ /@rollup/rollup-linux-x64-musl@4.40.2:
+ resolution: {integrity: sha512-tD46wKHd+KJvsmije4bUskNuvWKFcTOIM9tZ/RrmIvcXnbi0YK/cKS9FzFtAm7Oxi2EhV5N2OpfFB348vSQRXA==}
+ cpu: [x64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@rollup/rollup-win32-arm64-msvc@4.28.1:
resolution: {integrity: sha512-wSXmDRVupJstFP7elGMgv+2HqXelQhuNf+IS4V+nUpNVi/GUiBgDmfwD0UGN3pcAnWsgKG3I52wMOBnk1VHr/A==}
cpu: [arm64]
@@ -6856,6 +7072,14 @@ packages:
dev: true
optional: true
+ /@rollup/rollup-win32-arm64-msvc@4.40.2:
+ resolution: {integrity: sha512-Bjv/HG8RRWLNkXwQQemdsWw4Mg+IJ29LK+bJPW2SCzPKOUaMmPEppQlu/Fqk1d7+DX3V7JbFdbkh/NMmurT6Pg==}
+ cpu: [arm64]
+ os: [win32]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@rollup/rollup-win32-ia32-msvc@4.28.1:
resolution: {integrity: sha512-ZkyTJ/9vkgrE/Rk9vhMXhf8l9D+eAhbAVbsGsXKy2ohmJaWg0LPQLnIxRdRp/bKyr8tXuPlXhIoGlEB5XpJnGA==}
cpu: [ia32]
@@ -6864,6 +7088,14 @@ packages:
dev: true
optional: true
+ /@rollup/rollup-win32-ia32-msvc@4.40.2:
+ resolution: {integrity: sha512-dt1llVSGEsGKvzeIO76HToiYPNPYPkmjhMHhP00T9S4rDern8P2ZWvWAQUEJ+R1UdMWJ/42i/QqJ2WV765GZcA==}
+ cpu: [ia32]
+ os: [win32]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@rollup/rollup-win32-x64-msvc@4.28.1:
resolution: {integrity: sha512-ZvK2jBafvttJjoIdKm/Q/Bh7IJ1Ose9IBOwpOXcOvW3ikGTQGmKDgxTC6oCAzW6PynbkKP8+um1du81XJHZ0JA==}
cpu: [x64]
@@ -6872,6 +7104,14 @@ packages:
dev: true
optional: true
+ /@rollup/rollup-win32-x64-msvc@4.40.2:
+ resolution: {integrity: sha512-bwspbWB04XJpeElvsp+DCylKfF4trJDa2Y9Go8O6A7YLX2LIKGcNK/CYImJN6ZP4DcuOHB4Utl3iCbnR62DudA==}
+ cpu: [x64]
+ os: [win32]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@rsbuild/core@1.1.13:
resolution: {integrity: sha512-XBL2hrin8731W6iTGGL+x3cv07n4vm2D7u6XHRwtQkRfySzAqGx7ThlQLdNX/dJwfsoQrYQuWl/qzaljjXtGtg==}
engines: {node: '>=16.7.0'}
@@ -7744,6 +7984,35 @@ packages:
resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==}
dev: true
+ /@types/babel__core@7.20.5:
+ resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
+ dependencies:
+ '@babel/parser': 7.27.0
+ '@babel/types': 7.27.0
+ '@types/babel__generator': 7.27.0
+ '@types/babel__template': 7.4.4
+ '@types/babel__traverse': 7.20.7
+ dev: true
+
+ /@types/babel__generator@7.27.0:
+ resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==}
+ dependencies:
+ '@babel/types': 7.27.0
+ dev: true
+
+ /@types/babel__template@7.4.4:
+ resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==}
+ dependencies:
+ '@babel/parser': 7.27.0
+ '@babel/types': 7.27.0
+ dev: true
+
+ /@types/babel__traverse@7.20.7:
+ resolution: {integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==}
+ dependencies:
+ '@babel/types': 7.27.0
+ dev: true
+
/@types/bezier-js@4.1.3:
resolution: {integrity: sha512-FNVVCu5mx/rJCWBxLTcL7oOajmGtWtBTDjq6DSUWUI12GeePivrZZXz+UgE0D6VYsLEjvExRO03z4hVtu3pTEQ==}
dev: true
@@ -8367,6 +8636,22 @@ packages:
/@ungap/structured-clone@1.2.1:
resolution: {integrity: sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==}
+ /@vitejs/plugin-react@4.4.1(vite@6.3.5):
+ resolution: {integrity: sha512-IpEm5ZmeXAP/osiBXVVP5KjFMzbWOonMs0NaQQl+xYnUAcq4oHUBsF2+p4MgKWG4YMmFYJU8A6sxRPuowllm6w==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ peerDependencies:
+ vite: ^4.2.0 || ^5.0.0 || ^6.0.0
+ dependencies:
+ '@babel/core': 7.26.10
+ '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.26.10)
+ '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.26.10)
+ '@types/babel__core': 7.20.5
+ react-refresh: 0.17.0
+ vite: 6.3.5(@types/node@18.19.68)(less@4.3.0)
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
/@vitest/coverage-v8@0.32.4(vitest@0.34.6):
resolution: {integrity: sha512-itiCYY3TmWEK+5wnFBoNr0ZA+adACp7Op1r2TeX5dPOgU2See7+Gx2NlK2lVMHVxfPsu5z9jszKa3i//eR+hqg==}
peerDependencies:
@@ -10702,6 +10987,17 @@ packages:
dependencies:
picomatch: 4.0.2
+ /fdir@6.4.4(picomatch@4.0.2):
+ resolution: {integrity: sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==}
+ peerDependencies:
+ picomatch: ^3 || ^4
+ peerDependenciesMeta:
+ picomatch:
+ optional: true
+ dependencies:
+ picomatch: 4.0.2
+ dev: true
+
/fetch-blob@3.2.0:
resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
engines: {node: ^12.20 || >= 14.13}
@@ -12062,6 +12358,24 @@ packages:
source-map: 0.6.1
dev: true
+ /less@4.3.0:
+ resolution: {integrity: sha512-X9RyH9fvemArzfdP8Pi3irr7lor2Ok4rOttDXBhlwDg+wKQsXOXgHWduAJE1EsF7JJx0w0bcO6BC6tCKKYnXKA==}
+ engines: {node: '>=14'}
+ hasBin: true
+ dependencies:
+ copy-anything: 2.0.6
+ parse-node-version: 1.0.1
+ tslib: 2.8.1
+ optionalDependencies:
+ errno: 0.1.8
+ graceful-fs: 4.2.11
+ image-size: 0.5.5
+ make-dir: 2.1.0
+ mime: 1.6.0
+ needle: 3.3.1
+ source-map: 0.6.1
+ dev: true
+
/levn@0.4.1:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'}
@@ -13973,6 +14287,15 @@ packages:
picocolors: 1.1.1
source-map-js: 1.2.1
+ /postcss@8.5.3:
+ resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==}
+ engines: {node: ^10 || ^12 || >=14}
+ dependencies:
+ nanoid: 3.3.8
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+ dev: true
+
/prelude-ls@1.2.1:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'}
@@ -14199,6 +14522,11 @@ packages:
resolution: {integrity: sha512-FPvF2XxTSikpJxcr+bHut2H4gJ17+18Uy20D5/F+SKzFap62R3cM5wH6b8WN3LyGSYeQilLEcJcR1fjBSI2S1A==}
engines: {node: '>=0.10.0'}
+ /react-refresh@0.17.0:
+ resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
/react-resizable@3.0.5(react-dom@18.3.1)(react@18.3.1):
resolution: {integrity: sha512-vKpeHhI5OZvYn82kXOs1bC8aOXktGU5AmKAgaZS4F5JPburCtbmDPqE7Pzp+1kN4+Wb81LlF33VpGwWwtXem+w==}
peerDependencies:
@@ -14660,6 +14988,36 @@ packages:
fsevents: 2.3.3
dev: true
+ /rollup@4.40.2:
+ resolution: {integrity: sha512-tfUOg6DTP4rhQ3VjOO6B4wyrJnGOX85requAXvqYTHsOgb2TFJdZ3aWpT8W2kPoypSGP7dZUyzxJ9ee4buM5Fg==}
+ engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+ hasBin: true
+ dependencies:
+ '@types/estree': 1.0.7
+ optionalDependencies:
+ '@rollup/rollup-android-arm-eabi': 4.40.2
+ '@rollup/rollup-android-arm64': 4.40.2
+ '@rollup/rollup-darwin-arm64': 4.40.2
+ '@rollup/rollup-darwin-x64': 4.40.2
+ '@rollup/rollup-freebsd-arm64': 4.40.2
+ '@rollup/rollup-freebsd-x64': 4.40.2
+ '@rollup/rollup-linux-arm-gnueabihf': 4.40.2
+ '@rollup/rollup-linux-arm-musleabihf': 4.40.2
+ '@rollup/rollup-linux-arm64-gnu': 4.40.2
+ '@rollup/rollup-linux-arm64-musl': 4.40.2
+ '@rollup/rollup-linux-loongarch64-gnu': 4.40.2
+ '@rollup/rollup-linux-powerpc64le-gnu': 4.40.2
+ '@rollup/rollup-linux-riscv64-gnu': 4.40.2
+ '@rollup/rollup-linux-riscv64-musl': 4.40.2
+ '@rollup/rollup-linux-s390x-gnu': 4.40.2
+ '@rollup/rollup-linux-x64-gnu': 4.40.2
+ '@rollup/rollup-linux-x64-musl': 4.40.2
+ '@rollup/rollup-win32-arm64-msvc': 4.40.2
+ '@rollup/rollup-win32-ia32-msvc': 4.40.2
+ '@rollup/rollup-win32-x64-msvc': 4.40.2
+ fsevents: 2.3.3
+ dev: true
+
/rrweb-cssom@0.6.0:
resolution: {integrity: sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==}
dev: true
@@ -15651,6 +16009,14 @@ packages:
fdir: 6.4.2(picomatch@4.0.2)
picomatch: 4.0.2
+ /tinyglobby@0.2.13:
+ resolution: {integrity: sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==}
+ engines: {node: '>=12.0.0'}
+ dependencies:
+ fdir: 6.4.4(picomatch@4.0.2)
+ picomatch: 4.0.2
+ dev: true
+
/tinypool@0.7.0:
resolution: {integrity: sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==}
engines: {node: '>=14.0.0'}
@@ -16279,6 +16645,58 @@ packages:
fsevents: 2.3.3
dev: true
+ /vite@6.3.5(@types/node@18.19.68)(less@4.3.0):
+ resolution: {integrity: sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==}
+ engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
+ jiti: '>=1.21.0'
+ less: '*'
+ lightningcss: ^1.21.0
+ sass: '*'
+ sass-embedded: '*'
+ stylus: '*'
+ sugarss: '*'
+ terser: ^5.16.0
+ tsx: ^4.8.1
+ yaml: ^2.4.2
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ jiti:
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+ tsx:
+ optional: true
+ yaml:
+ optional: true
+ dependencies:
+ '@types/node': 18.19.68
+ esbuild: 0.25.4
+ fdir: 6.4.4(picomatch@4.0.2)
+ less: 4.3.0
+ picomatch: 4.0.2
+ postcss: 8.5.3
+ rollup: 4.40.2
+ tinyglobby: 0.2.13
+ optionalDependencies:
+ fsevents: 2.3.3
+ dev: true
+
/vitest@0.34.6(jsdom@22.1.0):
resolution: {integrity: sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==}
engines: {node: '>=v14.18.0'}
diff --git a/packages/canvas-engine/document/src/flow-document.ts b/packages/canvas-engine/document/src/flow-document.ts
index 35a2c43f..807376a2 100644
--- a/packages/canvas-engine/document/src/flow-document.ts
+++ b/packages/canvas-engine/document/src/flow-document.ts
@@ -79,6 +79,8 @@ export class FlowDocument implements Disposable {
readonly onLayoutChange = this.onLayoutChangeEmitter.event;
+ private _disposed = false;
+
root: FlowNodeEntity;
/**
@@ -98,6 +100,13 @@ export class FlowDocument implements Disposable {
*/
renderTree: FlowRenderTree;
+ /**
+ *
+ */
+ get disposed(): boolean {
+ return this._disposed;
+ }
+
@postConstruct()
init(): void {
if (!this.options) this.options = FlowDocumentOptionsDefault;
@@ -126,6 +135,7 @@ export class FlowDocument implements Disposable {
* @param fireRender 是否要触发渲染,默认 true
*/
fromJSON(json: FlowDocumentJSON | any, fireRender = true): void {
+ if (this._disposed) return;
// 清空 tree 数据 重新计算
this.originTree.clear();
this.renderTree.clear();
@@ -665,6 +675,7 @@ export class FlowDocument implements Disposable {
}
dispose() {
+ if (this._disposed) return;
this.registers.clear();
this.nodeRegistryCache.clear();
this.originTree.dispose();
@@ -673,5 +684,6 @@ export class FlowDocument implements Disposable {
this.onNodeCreateEmitter.dispose();
this.onNodeDisposeEmitter.dispose();
this.onLayoutChangeEmitter.dispose();
+ this._disposed = true;
}
}
diff --git a/packages/canvas-engine/free-layout-core/src/workflow-document.ts b/packages/canvas-engine/free-layout-core/src/workflow-document.ts
index 2d6376a1..5286d65a 100644
--- a/packages/canvas-engine/free-layout-core/src/workflow-document.ts
+++ b/packages/canvas-engine/free-layout-core/src/workflow-document.ts
@@ -55,8 +55,6 @@ export class WorkflowDocument extends FlowDocument {
readonly onReload = this._onReloadEmitter.event;
- private disposed = false;
-
/**
* 数据加载完成
*/
@@ -102,6 +100,7 @@ export class WorkflowDocument extends FlowDocument {
}
async load(): Promise {
+ if (this.disposed) return;
this._loading = true;
await super.load();
this._loading = false;
@@ -109,6 +108,7 @@ export class WorkflowDocument extends FlowDocument {
}
async reload(json: WorkflowJSON, delayTime = 0): Promise {
+ if (this.disposed) return;
this._loading = true;
this.clear();
this.fromJSON(json);
@@ -123,6 +123,7 @@ export class WorkflowDocument extends FlowDocument {
* @param json
*/
fromJSON(json: Partial, fireRender = true): void {
+ if (this.disposed) return;
const workflowJSON: WorkflowJSON = {
nodes: json.nodes ?? [],
edges: json.edges ?? [],
@@ -563,11 +564,7 @@ export class WorkflowDocument extends FlowDocument {
}
dispose() {
- if (this.disposed) {
- return;
- }
super.dispose();
- this.disposed = true;
this._onReloadEmitter.dispose();
}
diff --git a/rush.json b/rush.json
index d69ec530..1d096573 100644
--- a/rush.json
+++ b/rush.json
@@ -771,6 +771,12 @@
"projectFolder": "apps/demo-react-16",
"versionPolicyName": "appPolicy",
"tags": ["level-1", "team-flow", "demo"]
+ },
+ {
+ "packageName": "@flowgram.ai/demo-vite",
+ "projectFolder": "apps/demo-vite",
+ "versionPolicyName": "appPolicy",
+ "tags": ["level-1", "team-flow", "demo"]
}
]
}