@flowgram.ai/document 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/typings/flow.ts","../../src/typings/flow-layout.ts","../../src/typings/flow-transition.ts","../../src/typings/flow-node-register.ts","../../src/typings/flow-operation.ts","../../src/entities/flow-node-entity.ts","../../src/datas/flow-node-transform-data.ts","../../src/datas/flow-node-render-data.ts","../../src/datas/flow-node-transition-data.ts","../../src/entities/flow-document-transformer-entity.ts","../../src/entities/flow-renderer-state-entity.ts","../../src/flow-document.ts","../../src/flow-virtual-tree.ts","../../src/flow-render-tree.ts","../../src/flow-document-options.ts","../../src/flow-document-contribution.ts","../../src/flow-document-config.ts","../../src/flow-document-container-module.ts","../../src/services/flow-drag-service.ts","../../src/services/flow-group-service/flow-group-controller.ts","../../src/services/flow-group-service/flow-group-utils.ts","../../src/services/flow-operation-base-service.ts","../../src/services/flow-group-service/flow-group-service.ts","../../src/layout/vertical-fixed-layout.ts","../../src/layout/horizontal-fixed-layout.ts","../../src/utils/get-default-spacing.ts"],"sourcesContent":["/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { FlowNodeEntity } from '../entities';\nimport { type FlowNodeMeta } from './flow-node-register';\n\nexport type FlowNodeType = string | number;\n\n/**\n * Flow node json data\n */\nexport interface FlowNodeJSON {\n id: string;\n type?: FlowNodeBaseType | FlowNodeSplitType | FlowNodeType; // 如果缺省 则 为 block\n data?: Record<string, any>; // 节点额外扩展的内容\n meta?: FlowNodeMeta;\n blocks?: FlowNodeJSON[]; // 子节点\n}\n\nexport type FlowDocumentJSON = {\n nodes: FlowNodeJSON[];\n};\n\nexport enum FlowNodeBaseType {\n START = 'start', // 开始节点\n DEFAULT = 'default', // 默认节点类型\n ROOT = 'root', // 根节点\n EMPTY = 'empty', // 空节点,宽和高为 0\n INLINE_BLOCKS = 'inlineBlocks', // 所有块合并为 InlineBlocks\n BLOCK_ICON = 'blockIcon', // 图标节点,如条件分支的头部的 菱形图标\n BLOCK = 'block', // 块节点\n BLOCK_ORDER_ICON = 'blockOrderIcon', // 带顺序的图标节点,一般为 block 第一个分支节点\n GROUP = 'group', // 分组节点\n END = 'end', // 结束节点\n BREAK = 'break', // 分支结束\n CONDITION = 'condition', // 可以连接多条线的条件判断节点,目前只支持横向布局\n SUB_CANVAS = 'subCanvas', // 自由布局子画布\n MULTI_INPUTS = 'multiInputs', // 多输入\n MULTI_OUTPUTS = 'multiOutputs', // 多输出\n INPUT = 'input', // 输入节点\n OUTPUT = 'output', // 输出节点\n SLOT = 'slot', // 插槽节点\n SLOT_BLOCK = 'slotBlock', // 插槽子节点\n}\n\nexport enum FlowNodeSplitType {\n SIMPLE_SPLIT = 'simpleSplit', // 无 BlockOrderIcon\n DYNAMIC_SPLIT = 'dynamicSplit', // 动态分支\n STATIC_SPLIT = 'staticSplit', // 静态分支\n}\n\nexport enum FlowDocumentConfigEnum {\n // 结束节点拖拽分支逻辑\n END_NODES_REFINE_BRANCH = 'END_NODES_REFINE_BRANCH',\n}\n\nexport const FLOW_DEFAULT_HIDDEN_TYPES: FlowNodeType[] = [\n FlowNodeBaseType.ROOT,\n FlowNodeBaseType.INLINE_BLOCKS,\n FlowNodeBaseType.BLOCK,\n];\n\nexport type AddNodeData = FlowNodeJSON & {\n originParent?: FlowNodeEntity;\n parent?: FlowNodeEntity;\n hidden?: boolean;\n index?: number;\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { IPoint, PaddingSchema, ScrollSchema, SizeSchema } from '@flowgram.ai/utils';\n\nimport { type FlowNodeEntity } from '../entities';\nimport { type FlowNodeTransformData } from '../datas';\n\nexport const FlowLayout = Symbol('FlowLayout');\nexport const FlowLayoutContribution = Symbol('FlowLayoutContribution');\n\nexport enum FlowLayoutDefault {\n VERTICAL_FIXED_LAYOUT = 'vertical-fixed-layout', // 垂直固定布局\n HORIZONTAL_FIXED_LAYOUT = 'horizontal-fixed-layout', // 水平固定布局\n}\n\nexport namespace FlowLayoutDefault {\n export function isVertical(layout: FlowLayout): boolean {\n return layout.name === FlowLayoutDefault.VERTICAL_FIXED_LAYOUT;\n }\n}\n\nexport interface FlowLayoutContribution {\n onAfterUpdateLocalTransform?: (transform: FlowNodeTransformData, layout: FlowLayout) => void;\n}\n\n/**\n * 流程布局算法\n */\nexport interface FlowLayout {\n /**\n * 布局名字\n */\n name: string;\n /**\n * 布局切换时候触发\n */\n reload?(): void;\n /**\n * 更新布局\n */\n update(): void;\n\n /**\n * 获取节点的 padding 数据\n * @param node\n */\n getPadding(node: FlowNodeEntity): PaddingSchema;\n\n /**\n * 获取默认滚动 目前用在 scroll-limit-layer\n * @param contentSize\n */\n getInitScroll(contentSize: SizeSchema): ScrollSchema;\n\n /**\n * 获取默认输入点\n */\n getDefaultInputPoint(node: FlowNodeEntity): IPoint;\n\n /**\n * 获取默认输出点\n */\n getDefaultOutputPoint(node: FlowNodeEntity): IPoint;\n\n /**\n * 获取默认远点\n */\n getDefaultNodeOrigin(): IPoint;\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { type IPoint } from '@flowgram.ai/utils';\n\nimport { type FlowNodeEntity } from '../entities';\nimport { type LABEL_SIDE_TYPE } from './flow-node-register';\n\n// 内置几种线条\nexport enum FlowTransitionLineEnum {\n STRAIGHT_LINE, // 直线\n DIVERGE_LINE, // 分支线 (一种 ROUNDED_LINE)\n MERGE_LINE, // 汇聚线 (一种 ROUNDED_LINE)\n ROUNDED_LINE, // 自定义圆角转弯线\n CUSTOM_LINE, // 自定义,用于处理循环节点等自定义线条\n DRAGGING_LINE, // 分支拖拽场景渲染的线条\n}\n\nexport interface Vertex extends IPoint {\n radiusX?: number;\n radiusY?: number;\n // 圆弧出入点位置移动\n moveX?: number;\n moveY?: number;\n /**\n * Strategy for handling arc curvature when space is insufficient, defaults to compress\n */\n radiusOverflow?: 'compress' | 'truncate';\n}\n\nexport interface FlowTransitionLine {\n type: FlowTransitionLineEnum;\n from: IPoint;\n to: IPoint;\n vertices?: Vertex[]; // 自定义圆角转弯线需要转弯的拐点\n arrow?: boolean; // 是否有箭头\n renderKey?: string; // 只有自定义线条需要\n isHorizontal?: boolean; // 是否为水平布局\n isDraggingLine?: boolean; // 是否是拖拽线条\n activated?: boolean; // 是否激活态\n side?: LABEL_SIDE_TYPE; // 区分是否分支前缀线条\n style?: React.CSSProperties;\n lineId?: string;\n}\n\n// 内置几种标签\nexport enum FlowTransitionLabelEnum {\n ADDER_LABEL, // 添加按钮\n TEXT_LABEL, // 文本标签\n COLLAPSE_LABEL, // 复合节点收起的展开标签\n COLLAPSE_ADDER_LABEL, // 复合节点收起 + 加号复合标签\n CUSTOM_LABEL, // 自定义,用于处理循环节点等自定义标签\n BRANCH_DRAGGING_LABEL, // 分支拖拽场景下的 label\n}\n\nexport interface FlowTransitionLabel {\n type: FlowTransitionLabelEnum;\n // type === 'CUSTOM_LABEL'需要配置的数据\n renderKey?: string;\n offset: IPoint; // 位置\n width?: number; // 宽度\n rotate?: string; // 循环, 如 '60deg'\n /**\n * Anchor point for positioning, relative to the label's bounding box\n * 重心偏移量,相对于标签边界框\n *\n * Format: [x, y] / 格式:[x, y]\n * Default Value: [0.5, 0.5] indicates center / 默认值:[0.5, 0.5] 表示居中\n */\n origin?: [number, number];\n props?: Record<string, any>;\n labelId?: string;\n}\n\nexport interface AdderProps {\n node: FlowNodeEntity; // 实际挂载 label 的节点\n from: FlowNodeEntity; // 边起始点在哪个节点\n to: FlowNodeEntity; // 边终点在哪个节点\n renderTo: FlowNodeEntity; // 实际渲染(renderTree)边终点在哪个节点\n [key: string]: any;\n}\n\nexport interface CollapseProps {\n node: FlowNodeEntity; // 实际挂载 label 的节点\n collapseNode: FlowNodeEntity; // 要展开收起的节点,默认为 node\n activateNode?: FlowNodeEntity; // 设置获取 label 激活状态的节点\n forceVisible?: boolean; // 是否强制显示\n [key: string]: any;\n}\n\nexport interface CustomLabelProps {\n node: FlowNodeEntity; // 实际挂载 label 的节点\n [key: string]: any;\n}\n\nexport interface CollapseAdderProps extends AdderProps, CollapseProps {\n [key: string]: any;\n}\n\nexport interface DragNodeProps {\n node: FlowNodeEntity; // 实际挂载 label 的节点\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { type IPoint } from '@flowgram.ai/utils';\nimport { PaddingSchema } from '@flowgram.ai/utils';\nimport { PositionSchema } from '@flowgram.ai/utils';\nimport { type EntityDataRegistry, type OriginSchema, type SizeSchema } from '@flowgram.ai/core';\n\nimport { FlowDocument } from '../flow-document';\nimport { type FlowNodeEntity } from '../entities';\nimport { type FlowNodeTransformData, type FlowNodeTransitionData } from '../datas';\nimport { type FlowTransitionLabel, type FlowTransitionLine } from './flow-transition';\nimport { FlowLayout, FlowLayoutDefault } from './flow-layout';\nimport {\n FLOW_DEFAULT_HIDDEN_TYPES,\n FlowNodeBaseType,\n type FlowNodeJSON,\n FlowNodeType,\n} from './flow';\n\n/**\n * 节点渲染相关配置信息,可扩展\n */\nexport interface FlowNodeMeta {\n isStart?: boolean; // 是否为开始节点\n addable?: boolean; // 是否可添加节点\n expandable?: boolean; // 是否可展开\n draggable?: boolean | ((node: FlowNodeEntity) => boolean); // 是否可拖拽\n selectable?: boolean | ((node: FlowNodeEntity, mousePos?: PositionSchema) => boolean); // 是否可被框选\n deleteDisable?: boolean; // 是否禁用删除\n copyDisable?: boolean; // 禁用复制\n addDisable?: boolean; // 禁止添加\n hidden?: boolean; // 是否隐藏\n // maxSize?: SizeSchema // 默认展开后的大小\n size?: SizeSchema; // 默认大小\n autoResizeDisable?: boolean; // 禁用监听节点变化自动调整大小\n /**\n * @deprecated 使用 NodeRegister.getOrigin 代替\n */\n origin?: OriginSchema; // 原点配置,默认 垂直 { x: 0.5, y: 0 } 水平 { x: 0, y: 0.5 }\n defaultExpanded?: boolean; // 默认是否展开\n defaultCollapsed?: boolean; // 复合节点默认是否收起\n spacing?: number | ((transform: FlowNodeTransformData) => number); // 兄弟节点间,等价于 marginBottom\n padding?: PaddingSchema | ((transform: FlowNodeTransformData) => PaddingSchema); // 节点设置了 padding,则不需要 inlineSpacingPre 和 inlineSpacingAfter\n inlineSpacingPre?: number | ((transform: FlowNodeTransformData) => number); // 父子节点间,等价于 paddingTop 或者 paddingLeft\n inlineSpacingAfter?: number | ((transform: FlowNodeTransformData) => number); // 父子节点间,等价于 paddingBottom 或者 paddingRight\n renderKey?: string; // 节点的渲染组件,可以绑定 react 组件\n isInlineBlocks?: boolean | ((node: FlowNodeEntity) => boolean); // 采用水平布局\n minInlineBlockSpacing?: number | ((node: FlowNodeTransformData) => number); // 最小的 inlineBlock 的间距\n isNodeEnd?: boolean; // 是否标识节点结束\n [key: string]: any;\n}\n\n/**\n * spacing default key 值\n */\nexport const DefaultSpacingKey = {\n /**\n * 普通节点间距。垂直 / 水平\n */\n NODE_SPACING: 'SPACING',\n /**\n * 分支节点间距\n */\n BRANCH_SPACING: 'BRANCH_SPACING',\n /**\n * 圆弧线条 x radius\n */\n ROUNDED_LINE_X_RADIUS: 'ROUNDED_LINE_X_RADIUS',\n /**\n * 圆弧线条 y radius\n */\n ROUNDED_LINE_Y_RADIUS: 'ROUNDED_LINE_Y_RADIUS',\n /**\n * dynamicSplit block list 下部留白间距,因为有两个拐弯,所以翻一倍\n */\n INLINE_BLOCKS_PADDING_BOTTOM: 'INLINE_BLOCKS_PADDING_BOTTOM',\n /**\n * 复合节点距离上个节点的距离\n * 条件分支菱形下边和分支的距离\n */\n COLLAPSED_SPACING: 'COLLAPSED_SPACING',\n /**\n * width of hover area\n */\n HOVER_AREA_WIDTH: 'HOVER_AREA_WIDTH',\n};\n\n/**\n * 默认一些间隔参数\n */\nexport const DEFAULT_SPACING = {\n NULL: 0,\n [DefaultSpacingKey.NODE_SPACING]: 32, // 普通节点间距。垂直 / 水平\n [DefaultSpacingKey.BRANCH_SPACING]: 20, // 分支节点间距\n /**\n * @deprecated use 'BRANCH_SPACING' instead\n */\n MARGIN_RIGHT: 20, // 分支节点右边间距\n INLINE_BLOCK_PADDING_BOTTOM: 16, // block 底部留白\n INLINE_BLOCKS_PADDING_TOP: 30, // block list 上部留白间距\n // JS 浮点数有误差,1046.6 -1006.6 = 39.9999999,会导致 间距/20 < 2 导致布局计算问题,因此需要额外增加 0.1 像素\n [DefaultSpacingKey.INLINE_BLOCKS_PADDING_BOTTOM]: 40.1, // block lit 下部留白间距,因为有两个拐弯,所以翻一倍\n MIN_INLINE_BLOCK_SPACING: 200, // 分支间最小边距 (垂直布局)\n MIN_INLINE_BLOCK_SPACING_HORIZONTAL: 80, // 分支间最小边距 (水平布局)\n [DefaultSpacingKey.COLLAPSED_SPACING]: 12, // 复合节点距离上个节点的距离\n [DefaultSpacingKey.ROUNDED_LINE_X_RADIUS]: 16, // 圆弧线条 x radius\n [DefaultSpacingKey.ROUNDED_LINE_Y_RADIUS]: 20, // 圆弧线条 y radius\n [DefaultSpacingKey.HOVER_AREA_WIDTH]: 20, // width of hover area\n};\n\n/**\n * 拖拽种类枚举\n * 1. 节点拖拽\n * 2. 分支拖拽\n */\nexport enum DRAGGING_TYPE {\n NODE = 'node',\n BRANCH = 'branch',\n}\n\n/**\n * 拖拽分支 Adder、Line 类型\n */\nexport enum LABEL_SIDE_TYPE {\n // 前缀分支\n PRE_BRANCH = 'pre_branch',\n NORMAL_BRANCH = 'normal_branch',\n}\n\n/**\n * 默认节点大小\n */\nexport const DEFAULT_SIZE = {\n width: 280,\n height: 60,\n};\n\n/**\n * 默认 meta 配置\n */\nexport const DEFAULT_FLOW_NODE_META: (\n nodeType: FlowNodeType,\n document: FlowDocument\n) => FlowNodeMeta = (nodeType: FlowNodeType, document: FlowDocument) => {\n const hidden = FLOW_DEFAULT_HIDDEN_TYPES.includes(nodeType);\n return {\n isStart: nodeType === 'start',\n hidden,\n defaultExpanded: document.options.allNodesDefaultExpanded,\n size: DEFAULT_SIZE,\n origin: document.layout.getDefaultNodeOrigin(),\n isInlineBlocks: nodeType === FlowNodeBaseType.INLINE_BLOCKS,\n // miniSize: { width: 200, height: 40 },\n spacing: DEFAULT_SPACING.SPACING,\n inlineSpacingPre: 0,\n inlineSpacingAfter: 0,\n expandable: true,\n draggable: true,\n selectable: true,\n renderKey: '',\n minInlineBlockSpacing: () => {\n const isVertical = FlowLayoutDefault.isVertical(document.layout);\n return isVertical\n ? DEFAULT_SPACING.MIN_INLINE_BLOCK_SPACING\n : DEFAULT_SPACING.MIN_INLINE_BLOCK_SPACING_HORIZONTAL;\n },\n } as FlowNodeMeta;\n};\n\n/**\n * 节点注册\n */\nexport interface FlowNodeRegistry<M extends FlowNodeMeta = FlowNodeMeta> {\n /**\n * 从另外一个注册扩展\n */\n extend?: string;\n /**\n * 节点类型\n */\n type: FlowNodeType;\n /**\n * 节点注册的数据,可以理解为 ECS 里的 Component, 这里可以配置自定义数据\n */\n dataRegistries?: EntityDataRegistry[];\n /**\n * 节点画布相关初始化配置信息,会覆盖 DEFAULT_FLOW_NODE_META\n */\n meta?: Partial<M>;\n /**\n * 自定义创建节点,可以自定义节点的树形结构\n * 返回新加入的节点,这样才能统计缓存\n *\n * @action 使用该方法,在创建时候将会忽略 json blocks 数据,而是交给适用节点自己处理 json 逻辑\n */\n onCreate?: (node: FlowNodeEntity, json: FlowNodeJSON) => FlowNodeEntity[] | void;\n /**\n * 添加子 block,一般用于分支的动态添加\n */\n onBlockChildCreate?: (\n node: FlowNodeEntity,\n json: FlowNodeJSON,\n addedNodes?: FlowNodeEntity[] // 新创建的节点都要存在这里\n ) => FlowNodeEntity;\n /**\n * 创建线条\n */\n getLines?: (transition: FlowNodeTransitionData, layout: FlowLayout) => FlowTransitionLine[];\n /**\n * 创建 label\n */\n getLabels?: (transition: FlowNodeTransitionData, layout: FlowLayout) => FlowTransitionLabel[];\n\n /**\n * 调整子节点的线条,优先级高于子节点本身的 getLines\n */\n getChildLines?: (transition: FlowNodeTransitionData, layout: FlowLayout) => FlowTransitionLine[];\n\n /**\n * 调整子节点的 Labels,优先级高于子节点本身的 getLabels\n */\n getChildLabels?: (\n transition: FlowNodeTransitionData,\n layout: FlowLayout\n ) => FlowTransitionLabel[];\n\n /**\n * 自定义输入节点\n */\n getInputPoint?: (transform: FlowNodeTransformData, layout: FlowLayout) => IPoint;\n /**\n * 自定义输出节点\n */\n getOutputPoint?: (transform: FlowNodeTransformData, layoutKey: FlowLayout) => IPoint;\n /**\n * 获取当前节点 Position 偏移量,偏移量计算只能使用已经计算完的数据,如上一个节点或者子节点,不然会造成 o(n^2) 复杂度\n *\n * 1. 切记不要用当前节点的 localBounds(相对位置 bbox),因为 delta 计算发生在 localBounds 计算之前\n * 2. 切记不要用 bounds(绝对位置 bbox, 会触发所有父节点绝对位置计算), bounds 只能在最终 render 时候使用\n * 3. 可以用 pre 节点 和 子节点的 localBounds 或者 size 数据,因为子节点是先算的\n * 4. 可以用当前节点的 size (所有子节点的最大 bbox), 这是已经确定下来的\n */\n getDelta?: (transform: FlowNodeTransformData, layout: FlowLayout) => IPoint | undefined;\n\n /**\n * 动态获取原点,会覆盖 meta.origin\n */\n getOrigin?(transform: FlowNodeTransformData, layout: FlowLayout): IPoint;\n /**\n * 原点 X 偏移\n * @param transform\n */\n getOriginDeltaX?: (transform: FlowNodeTransformData, layout: FlowLayout) => number;\n /**\n * 原点 Y 偏移\n * @param transform\n */\n getOriginDeltaY?: (transform: FlowNodeTransformData, layout: FlowLayout) => number;\n /**\n * 通过 parent 计算当前节点的偏移,规则同 getDelta\n */\n getChildDelta?: (childBlock: FlowNodeTransformData, layout: FlowLayout) => IPoint | undefined;\n /**\n * 在当前节点布局完成后调用,可以对布局做更精细的调整\n */\n onAfterUpdateLocalTransform?: (transform: FlowNodeTransformData, layout: FlowLayout) => void;\n\n /**\n * 子节点的 registry 覆盖,这里通过 originParent 来查找\n */\n extendChildRegistries?: FlowNodeRegistry[];\n\n /**\n * @deprecated\n * 自定义子节点添加逻辑\n * @param node 节点\n * @param json 添加的节点 JSON\n * @param options 其它配置\n * @returns\n */\n addChild?: (\n node: FlowNodeEntity,\n json: FlowNodeJSON,\n options?: {\n hidden?: boolean;\n index?: number;\n }\n ) => FlowNodeEntity;\n\n /**\n * 内部用于继承逻辑判断,不要使用\n */\n __extends__?: FlowNodeType[];\n /**\n * 扩展注册器\n */\n [key: string]: any;\n}\n\nexport namespace FlowNodeRegistry {\n export function mergeChildRegistries(\n r1: FlowNodeRegistry[] = [],\n r2: FlowNodeRegistry[] = []\n ): FlowNodeRegistry[] {\n if (r1.length === 0 || r2.length === 0) {\n return [...r1, ...r2];\n }\n const r1Filter = r1.map((r1Current) => {\n const r2Current = r2.find((n) => n.type === r1Current.type);\n if (r2Current) {\n return merge(r1Current, r2Current, r1Current.type);\n }\n return r1Current;\n });\n const r2Filter = r2.filter((n) => !r1.some((r) => r.type === n.type));\n return [...r1Filter, ...r2Filter];\n }\n export function merge(\n registry1: FlowNodeRegistry,\n registry2: FlowNodeRegistry,\n finalType: FlowNodeType\n ): FlowNodeRegistry {\n const extendKeys = registry1.__extends__ ? registry1.__extends__.slice() : [];\n if (registry1.type !== registry2.type) {\n extendKeys.unshift(registry1.type);\n }\n return {\n ...registry1,\n ...registry2,\n extendChildRegistries: mergeChildRegistries(\n registry1.extendChildRegistries,\n registry2.extendChildRegistries\n ),\n meta: { ...registry1.meta, ...registry2.meta },\n extend: undefined,\n type: finalType,\n __extends__: extendKeys,\n };\n }\n\n export function extend(\n registry: FlowNodeRegistry,\n extendRegistries: FlowNodeRegistry[]\n ): FlowNodeRegistry {\n if (!extendRegistries.length) return registry;\n return extendRegistries.reduce((res, ext) => merge(res, ext, registry.type), registry);\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Event } from '@flowgram.ai/utils';\nimport { Disposable } from '@flowgram.ai/utils';\n\nimport { type FlowNodeEntity } from '../entities/flow-node-entity';\nimport { AddNodeData, FlowNodeJSON } from './flow';\n\nexport enum OperationType {\n addFromNode = 'addFromNode',\n deleteFromNode = 'deleteFromNode',\n addBlock = 'addBlock',\n deleteBlock = 'deleteBlock',\n createGroup = 'createGroup',\n ungroup = 'ungroup',\n moveNodes = 'moveNodes',\n moveBlock = 'moveBlock',\n moveChildNodes = 'moveChildNodes',\n addNodes = 'addNodes',\n deleteNodes = 'deleteNodes',\n addChildNode = 'addChildNode',\n deleteChildNode = 'deleteChildNode',\n addNode = 'addNode',\n deleteNode = 'deleteNode',\n}\n\nexport interface AddOrDeleteFromNodeOperationValue {\n fromId: string;\n data: FlowNodeJSON;\n}\n\nexport interface AddOrDeleteNodeOperationValue {\n fromId: string;\n data: FlowNodeJSON;\n}\n\nexport interface AddFromNodeOperation {\n type: OperationType.addFromNode;\n value: AddOrDeleteFromNodeOperationValue;\n}\n\nexport interface DeleteFromNodeOperation {\n type: OperationType.deleteFromNode;\n value: AddOrDeleteFromNodeOperationValue;\n}\n\nexport interface AddOrDeleteBlockValue {\n targetId: string;\n index?: number;\n blockData: FlowNodeJSON;\n parentId?: string;\n}\n\nexport interface createOrUngroupValue {\n targetId: string;\n groupId: string;\n nodeIds: string[];\n}\n\nexport interface AddBlockOperation {\n type: OperationType.addBlock;\n value: AddOrDeleteBlockValue;\n}\n\nexport interface DeleteBlockOperation {\n type: OperationType.deleteBlock;\n value: AddOrDeleteBlockValue;\n}\n\nexport interface CreateGroupOperation {\n type: OperationType.createGroup;\n value: createOrUngroupValue;\n}\n\nexport interface UngroupOperation {\n type: OperationType.ungroup;\n value: createOrUngroupValue;\n}\n\nexport interface MoveNodesOperationValue {\n fromId: string;\n toId: string;\n nodeIds: string[];\n}\n\nexport interface MoveNodesOperation {\n type: OperationType.moveNodes;\n value: MoveNodesOperationValue;\n}\n\nexport interface AddOrDeleteNodesOperationValue {\n fromId: string;\n nodes: FlowNodeJSON[];\n}\n\nexport interface AddNodesOperation {\n type: OperationType.addNodes;\n value: AddOrDeleteNodesOperationValue;\n}\n\nexport interface DeleteNodesOperation {\n type: OperationType.deleteNodes;\n value: AddOrDeleteNodesOperationValue;\n}\n\nexport interface MoveChildNodesOperationValue {\n nodeIds: string[];\n fromParentId: string;\n fromIndex: number;\n toParentId: string;\n toIndex: number;\n}\n\nexport type MoveBlockOperationValue = {\n nodeId: string;\n fromParentId: string;\n fromIndex: number;\n toParentId: string;\n toIndex: number;\n};\n\nexport interface MoveBlockOperation {\n type: OperationType.moveBlock;\n value: MoveBlockOperationValue;\n}\n\nexport interface MoveChildNodesOperation {\n type: OperationType.moveChildNodes;\n value: MoveChildNodesOperationValue;\n}\n\nexport interface AddChildNodeOperation {\n type: OperationType.addChildNode;\n value: AddOrDeleteChildNodeValue;\n}\n\nexport interface DeleteChildNodeOperation {\n type: OperationType.deleteChildNode;\n value: AddOrDeleteChildNodeValue;\n}\n\nexport interface AddOrDeleteChildNodeValue {\n data: FlowNodeJSON;\n parentId?: string;\n index?: number;\n originParentId?: string;\n hidden?: boolean;\n}\n\nexport interface AddNodeOperation {\n type: OperationType.addNode;\n value: AddOrDeleteNodeValue;\n}\n\nexport interface DeleteNodeOperation {\n type: OperationType.deleteNode;\n value: AddOrDeleteNodeValue;\n}\n\nexport interface AddOrDeleteNodeValue {\n data: FlowNodeJSON;\n parentId?: string;\n index?: number;\n hidden?: boolean;\n}\n\nexport type FlowOperation =\n | AddFromNodeOperation\n | DeleteFromNodeOperation\n | AddBlockOperation\n | DeleteBlockOperation\n | CreateGroupOperation\n | UngroupOperation\n | MoveNodesOperation\n | AddNodesOperation\n | DeleteNodesOperation\n | MoveBlockOperation\n | AddChildNodeOperation\n | DeleteChildNodeOperation\n | MoveChildNodesOperation\n | AddNodeOperation\n | DeleteNodeOperation;\n\nexport type FlowNodeEntityOrId = string | FlowNodeEntity;\n\n// 添加节点时的配置\nexport type AddNodeConfig = {\n // 父节点\n parent?: FlowNodeEntityOrId;\n // 是否隐藏\n hidden?: boolean;\n // 插入位置\n index?: number;\n};\n\n/**\n * 添加block时的配置\n */\nexport interface AddBlockConfig {\n // 父节点,默认去找 $inlineBlocks$\n parent?: FlowNodeEntity;\n // 插入位置,默认最后\n index?: number;\n}\n\n/**\n * 移动节点时的配置\n */\nexport interface MoveNodeConfig {\n // 目标父节点,如果不传,默认使用移动节点的父节点\n parent?: FlowNodeEntityOrId;\n // 目标位置, 默认移动到最后\n index?: number;\n}\n\n/**\n * 节点添加事件\n */\nexport interface OnNodeAddEvent {\n node: FlowNodeEntity;\n data: AddNodeData;\n}\n\n/**\n * 节点移动事件\n */\nexport interface OnNodeMoveEvent {\n node: FlowNodeEntity;\n fromParent: FlowNodeEntity;\n fromIndex: number;\n toParent: FlowNodeEntity;\n toIndex: number;\n}\n\nexport interface FlowOperationBaseService extends Disposable {\n /**\n * 执行操作\n * @param operation 可序列化的操作\n * @returns 操作返回\n */\n apply(operation: FlowOperation): any;\n\n /**\n * 添加节点,如果节点已经存在则不会重复创建\n * @param nodeJSON 节点数据\n * @param config 配置\n * @returns 成功添加的节点\n */\n addNode(nodeJSON: FlowNodeJSON, config?: AddNodeConfig): FlowNodeEntity;\n\n /**\n * 基于某一个起始节点往后面添加\n * @param fromNode 起始节点\n * @param nodeJSON 添加的节点JSON\n */\n addFromNode(fromNode: FlowNodeEntityOrId, nodeJSON: FlowNodeJSON): FlowNodeEntity;\n\n /**\n * 删除节点\n * @param node 节点\n * @returns\n */\n deleteNode(node: FlowNodeEntityOrId): void;\n\n /**\n * 批量删除节点\n * @param nodes\n */\n deleteNodes(nodes: FlowNodeEntityOrId[]): void;\n\n /**\n * 添加块(分支)\n * @param target 目标\n * @param blockJSON 块数据\n * @param config 配置\n * @returns\n */\n addBlock(\n target: FlowNodeEntityOrId,\n blockJSON: FlowNodeJSON,\n config?: AddBlockConfig\n ): FlowNodeEntity;\n\n /**\n * 移动节点\n * @param node 被移动的节点\n * @param config 移动节点配置\n */\n moveNode(node: FlowNodeEntityOrId, config?: MoveNodeConfig): void;\n\n /**\n * 拖拽节点\n * @param param0\n * @returns\n */\n dragNodes({ dropNode, nodes }: { dropNode: FlowNodeEntity; nodes: FlowNodeEntity[] }): void;\n\n /**\n * 添加节点的回调\n */\n onNodeAdd: Event<OnNodeAddEvent>;\n\n /**\n * 节点移动的回调\n */\n onNodeMove: Event<OnNodeMoveEvent>;\n}\n\nexport const FlowOperationBaseService = Symbol('FlowOperationBaseService');\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Event, type Rectangle } from '@flowgram.ai/utils';\nimport { Entity, type EntityOpts } from '@flowgram.ai/core';\n\nimport {\n FlowLayoutDefault,\n FlowNodeJSON,\n FlowNodeMeta,\n FlowNodeRegistry,\n FlowNodeType,\n} from '../typings';\nimport type { FlowDocument } from '../flow-document';\nimport { FlowNodeRenderData, FlowNodeTransformData } from '../datas';\n\nexport interface FlowNodeEntityConfig extends EntityOpts {\n document: FlowDocument;\n flowNodeType: FlowNodeType;\n originParent?: FlowNodeEntity;\n meta?: FlowNodeMeta;\n}\n\nexport interface FlowNodeInitData {\n originParent?: FlowNodeEntity;\n parent?: FlowNodeEntity;\n hidden?: boolean;\n meta?: FlowNodeMeta;\n index?: number;\n}\n\nexport class FlowNodeEntity extends Entity<FlowNodeEntityConfig> {\n private _memoLocalCache = new Map<string, any>();\n\n private _memoGlobalCache = new Map<string, any>();\n\n static type = 'FlowNodeEntity';\n\n private _registerCache?: FlowNodeRegistry;\n\n private _metaCache?: Required<FlowNodeMeta>;\n\n metaFromJSON?: FlowNodeMeta;\n\n /**\n * 真实的父节点,条件块在内部会创建一些空的块节点,这些块需要关联它真实的父亲节点\n */\n originParent?: FlowNodeEntity;\n\n flowNodeType: FlowNodeType = 'unknown'; // 流程类型\n\n /**\n * 是否隐藏\n */\n private _hidden = false;\n\n index = -1;\n\n /**\n * 文档引用\n */\n document: FlowDocument;\n\n constructor(conf: FlowNodeEntityConfig) {\n super(conf);\n this.document = conf.document;\n this.flowNodeType = conf.flowNodeType;\n this.originParent = conf.originParent;\n this.metaFromJSON = conf.meta;\n this.onDispose(() => {\n this.document.originTree\n .getChildren(this)\n .slice()\n .forEach((child) => {\n child.dispose();\n });\n this.document.originTree.remove(this, false);\n this.originParent = undefined;\n });\n }\n\n initData(initConf: FlowNodeInitData): void {\n if (initConf.originParent !== this.originParent) {\n this.originParent = initConf.originParent;\n this._registerCache = undefined;\n }\n if (initConf.parent) {\n initConf.parent.addChild(this, initConf.index);\n }\n // TODO 这个 meta 不会触发 data 数据更新\n if (initConf.meta !== this.metaFromJSON) {\n this._metaCache = undefined;\n this.metaFromJSON = initConf.meta;\n }\n this._hidden = !!(this.getNodeMeta().hidden || initConf.hidden);\n }\n\n get isStart(): boolean {\n return this.getNodeMeta().isStart;\n }\n\n get isFirst(): boolean {\n return !this.pre;\n }\n\n get isLast(): boolean {\n return !this.next;\n }\n\n /**\n * 子节点采用水平布局\n */\n get isInlineBlocks(): boolean {\n const originIsInlineBlocks = this.getNodeMeta().isInlineBlocks;\n return typeof originIsInlineBlocks === 'function'\n ? originIsInlineBlocks(this)\n : originIsInlineBlocks;\n }\n\n /**\n * 水平节点\n */\n get isInlineBlock(): boolean {\n const parent = this.document.renderTree.getParent(this);\n return !!(parent && parent.isInlineBlocks);\n }\n\n /**\n * 节点结束标记\n * - 当前节点是结束节点\n * - 当前节点最后一个节点包含结束标记\n * - 当前节点为 inlineBlock,每一个 block 包含结束标记\n *\n * 由子元素确定,因此使用 memoLocal\n */\n get isNodeEnd(): boolean {\n return this.memoLocal<boolean>('isNodeEnd', () => {\n if (this.getNodeMeta().isNodeEnd) {\n return true;\n }\n\n if (this.isInlineBlocks && this.collapsedChildren.length) {\n return this.collapsedChildren.every((child) => child.isNodeEnd);\n }\n\n if (this.lastCollapsedChild) {\n return this.lastCollapsedChild.isNodeEnd;\n }\n\n return false;\n });\n }\n\n /**\n * 添加 子节点\n *\n * @param child 插入节点\n */\n addChild(child: FlowNodeEntity, index?: number) {\n if (child.parent === this) return;\n this.document.originTree.addChild(this, child, index);\n }\n\n get hasChild(): boolean {\n return this.children.length > 0;\n }\n\n get pre(): FlowNodeEntity | undefined {\n return this.document.renderTree.getPre(this);\n }\n\n get next(): FlowNodeEntity | undefined {\n return this.document.renderTree.getNext(this);\n }\n\n get parent(): FlowNodeEntity | undefined {\n return this.document.renderTree.getParent(this);\n }\n\n getNodeRegistry<M extends FlowNodeRegistry = FlowNodeRegistry & { meta: FlowNodeMeta }>(): M {\n if (this._registerCache) return this._registerCache as M;\n this._registerCache = this.document.getNodeRegistry(this.flowNodeType, this.originParent);\n return this._registerCache as M;\n }\n\n /**\n * @deprecated\n * use getNodeRegistry instead\n */\n getNodeRegister<M extends FlowNodeRegistry = FlowNodeRegistry>(): M {\n return this.getNodeRegistry<M>();\n }\n\n getNodeMeta<M extends FlowNodeMeta = FlowNodeMeta>(): M & Required<FlowNodeMeta> {\n if (this._metaCache) return this._metaCache as M & Required<FlowNodeMeta>;\n if (this.metaFromJSON) {\n this._metaCache = {\n ...this.getNodeRegistry().meta,\n ...this.metaFromJSON,\n } as M & Required<FlowNodeMeta>;\n } else {\n this._metaCache = this.getNodeRegistry().meta as M & Required<FlowNodeMeta>;\n }\n return this._metaCache as M & Required<FlowNodeMeta>;\n }\n\n /**\n * 获取所有子节点,包含 child 及其所有兄弟节点\n */\n get allChildren(): FlowNodeEntity[] {\n const children: FlowNodeEntity[] = [];\n for (const child of this.children) {\n children.push(child);\n children.push(...child.allChildren);\n }\n return children;\n }\n\n /**\n * 获取所有收起的子节点,包含 child 及其所有兄弟节点\n */\n get allCollapsedChildren(): FlowNodeEntity[] {\n const children: FlowNodeEntity[] = [];\n for (const child of this.collapsedChildren) {\n children.push(child);\n children.push(...child.allCollapsedChildren);\n }\n return children;\n }\n\n /**\n *\n * Get child blocks\n *\n * use `blocks` instead\n * @deprecated\n */\n\n get collapsedChildren(): FlowNodeEntity[] {\n return this.document.renderTree.getCollapsedChildren(this);\n }\n\n /**\n * Get child blocks\n */\n get blocks(): FlowNodeEntity[] {\n return this.collapsedChildren;\n }\n\n /**\n * Get last block\n */\n get lastBlock(): FlowNodeEntity | undefined {\n return this.lastCollapsedChild;\n }\n\n /**\n * use `lastBlock` instead\n */\n get lastCollapsedChild(): FlowNodeEntity | undefined {\n const { collapsedChildren } = this;\n return collapsedChildren[collapsedChildren.length - 1];\n }\n\n /**\n * 获取子节点,如果子节点收起来,则会返回 空数组\n */\n get children(): FlowNodeEntity[] {\n return this.document.renderTree.getChildren(this);\n }\n\n get lastChild(): FlowNodeEntity | undefined {\n const { children } = this;\n return children[children.length - 1];\n }\n\n get firstChild(): FlowNodeEntity | undefined {\n return this.children[0];\n }\n\n memoLocal<T>(key: string, fn: () => T): T {\n if (this._memoLocalCache.has(key)) {\n return this._memoLocalCache.get(key) as T;\n }\n const data = fn();\n this._memoLocalCache.set(key, data);\n return data as T;\n }\n\n memoGlobal<T>(key: string, fn: () => T): T {\n if (this._memoGlobalCache.has(key)) {\n return this._memoGlobalCache.get(key) as T;\n }\n const data = fn();\n this._memoGlobalCache.set(key, data);\n return data as T;\n }\n\n clearMemoGlobal() {\n this._memoGlobalCache.clear();\n }\n\n clearMemoLocal() {\n this._memoLocalCache.clear();\n }\n\n get childrenLength() {\n return this.children.length;\n }\n\n get collapsed(): boolean {\n if (this.document.renderTree.isCollapsed(this)) return true;\n return !!this.parent?.collapsed;\n }\n\n set collapsed(collapsed) {\n this.document.renderTree.setCollapsed(this, collapsed);\n this.clearMemoGlobal();\n this.clearMemoLocal();\n }\n\n get hidden(): boolean {\n return this._hidden;\n }\n\n // 展开该节点\n openInsideCollapsed() {\n this.document.renderTree.openNodeInsideCollapsed(this);\n }\n\n /**\n * 可以重载\n */\n getJSONData(): any {\n return this.getExtInfo();\n }\n\n /**\n * 生成 JSON\n * @param newId\n */\n toJSON(): FlowNodeJSON {\n return this.document.toNodeJSON(this);\n }\n\n get isVertical(): boolean {\n return this.document.layout.name === FlowLayoutDefault.VERTICAL_FIXED_LAYOUT;\n }\n\n /**\n * 修改节点扩展信息\n * @param info\n */\n updateExtInfo<T extends Record<string, any> = Record<string, any>>(\n extInfo: T,\n fullUpdate?: boolean\n ): void {\n this.getData(FlowNodeRenderData).updateExtInfo(extInfo, fullUpdate);\n }\n\n /**\n * 获取节点扩展信息\n */\n getExtInfo<T extends Record<string, any> = Record<string, any>>(): T {\n return this.getData<FlowNodeRenderData>(FlowNodeRenderData).getExtInfo() as T;\n }\n\n get onExtInfoChange(): Event<{ newInfo: any; oldInfo: any }> {\n return this.renderData.onExtInfoChange;\n }\n\n /**\n * 获取渲染数据\n */\n get renderData(): FlowNodeRenderData {\n return this.getData(FlowNodeRenderData);\n }\n\n /**\n * 获取位置大小数据\n */\n get transform(): FlowNodeTransformData {\n return this.getData(FlowNodeTransformData);\n }\n\n /**\n * 获取节点的位置及大小矩形\n */\n get bounds(): Rectangle {\n return this.transform.bounds;\n }\n\n /**\n * Check node extend type\n */\n isExtend(parentType: FlowNodeType): boolean {\n return this.document.isExtend(this.flowNodeType, parentType);\n }\n\n /**\n * Check node type\n * @param parentType\n */\n isTypeOrExtendType(parentType: FlowNodeType): boolean {\n return this.document.isTypeOrExtendType(this.flowNodeType, parentType);\n }\n}\n\nexport namespace FlowNodeEntity {\n export function is(obj: Entity): obj is FlowNodeEntity {\n return obj instanceof FlowNodeEntity;\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Disposable, type IPoint, Rectangle } from '@flowgram.ai/utils';\nimport {\n Bounds,\n EntityData,\n PositionSchema,\n type SizeSchema,\n TransformData,\n} from '@flowgram.ai/core';\n\nimport type { FlowNodeEntity } from '../entities';\nimport { FlowNodeRenderData } from './flow-node-render-data';\n\nexport interface FlowNodeTransformSchema {\n size: SizeSchema; // 当前节点大小\n}\n\nexport class FlowNodeTransformData extends EntityData<FlowNodeTransformSchema> {\n static type = 'FlowNodeTransformData';\n\n // 这里加 declare 原因:覆盖了 EntityData 默认的 EntityType,如果不声明会报 TS2612 错误\n declare entity: FlowNodeEntity;\n\n transform: TransformData;\n\n renderState: FlowNodeRenderData;\n\n localDirty = true;\n\n get origin() {\n return this.transform.origin;\n }\n\n get key(): string {\n return this.entity.id;\n }\n\n getDefaultData(): FlowNodeTransformSchema {\n const { size, hidden } = this.entity.getNodeMeta();\n // 更新默认 size 大小\n return {\n size: !hidden ? { ...size } : { width: 0, height: 0 },\n };\n }\n\n constructor(entity: FlowNodeEntity) {\n super(entity);\n const { origin } = this.entity.getNodeMeta();\n this.transform = this.entity.addData<TransformData>(TransformData);\n this.transform.changeLocked = true;\n this.transform.update({ origin: { ...origin } });\n this.transform.changeLocked = false;\n this.renderState = this.entity.addData<FlowNodeRenderData>(FlowNodeRenderData);\n this.bindChange(this.transform);\n // 删除节点要让下一个节点或者父节点变成 dirty\n this.toDispose.push(\n Disposable.create(() => {\n const { next, parent } = this;\n if (next) next.localDirty = true;\n if (parent) parent.localDirty = true;\n })\n );\n // this.bindChange(this.renderState)\n }\n\n /**\n * 获取节点是否展开\n */\n get collapsed(): boolean {\n return this.entity.collapsed;\n }\n\n set collapsed(collapsed: boolean) {\n this.entity.collapsed = collapsed;\n this.localDirty = true;\n\n // 第一个子节点也设置为 dirty\n if (this.firstChild) this.firstChild.localDirty = true;\n\n this.fireChange();\n }\n\n /**\n * 获取节点的大小\n */\n get size(): SizeSchema {\n return this.entity.memoGlobal<SizeSchema>('size', () => {\n if (this.isContainer) return this.transform.localSize;\n return this.data.size;\n });\n }\n\n get position(): PositionSchema {\n const { position } = this.transform;\n return {\n x: position.x,\n y: position.y,\n };\n }\n\n set position(position: PositionSchema) {\n this.transform.update({\n position,\n });\n }\n\n set size(size: SizeSchema) {\n const { width, height } = this.data.size;\n // Container size 由子节点决定\n if (this.isContainer) return;\n if (size.width !== width || size.height !== height) {\n this._data.size = { ...size };\n this.localDirty = true;\n this.fireChange();\n }\n }\n\n get inputPoint() {\n return this.entity.memoGlobal<IPoint>('inputPoint', () => {\n const { getInputPoint } = this.entity.getNodeRegistry();\n return getInputPoint\n ? getInputPoint(this, this.entity.document.layout)\n : this.defaultInputPoint;\n });\n }\n\n get defaultInputPoint() {\n return this.entity.memoGlobal<IPoint>('defaultInputPoint', () =>\n this.entity.document.layout.getDefaultInputPoint(this.entity)\n );\n }\n\n get defaultOutputPoint() {\n return this.entity.memoGlobal<IPoint>('defaultOutputPoint', () =>\n this.entity.document.layout.getDefaultOutputPoint(this.entity)\n );\n }\n\n get outputPoint() {\n return this.entity.memoGlobal<IPoint>('outputPoint', () => {\n const { getOutputPoint } = this.entity.getNodeRegistry();\n return getOutputPoint\n ? getOutputPoint(this, this.entity.document.layout)\n : this.defaultOutputPoint;\n });\n }\n\n /**\n * 原点的最左偏移\n */\n get originDeltaX(): number {\n return this.entity.memoLocal<number>('originDeltaX', () => {\n const { children } = this;\n const { getOriginDeltaX } = this.entity.getNodeRegistry();\n if (getOriginDeltaX) return getOriginDeltaX(this, this.entity.document.layout);\n // 没有子节点,则采用自身的原点偏移\n if (children.length === 0) {\n return -this.size.width * this.origin.x;\n }\n // 采用子节点的最左偏移量来计算\n if (children.length === 1) return children[0].originDeltaX;\n // 这里代表水平偏移,则采用第一个节点加上自身偏移\n if (this.entity.isInlineBlocks && children.length > 1) {\n return children[0].originDeltaX + this.transform.position.x;\n }\n return children.reduce((res: undefined | number, child) => {\n const deltaX = child.originDeltaX;\n return res === undefined || deltaX < res ? deltaX : (res as number);\n }, undefined) as number;\n });\n }\n\n /**\n * 原点 y 轴偏移\n */\n get originDeltaY(): number {\n return this.entity.memoLocal<number>('originDeltaY', () => {\n const { children } = this;\n const { getOriginDeltaY } = this.entity.getNodeRegistry();\n if (getOriginDeltaY) return getOriginDeltaY(this, this.entity.document.layout);\n // 没有子节点,则采用自身的原点偏移\n if (children.length === 0) {\n return -this.size.height * this.origin.y;\n }\n // 采用子节点的最上偏移量来计算\n if (children.length === 1) return children[0].originDeltaY;\n // 这里代表水平偏移,则采用第一个节点加上自身偏移\n if (this.entity.isInlineBlocks && children.length > 1) {\n return children[0].originDeltaY + this.transform.position.y;\n }\n return children.reduce((res: undefined | number, child) => {\n const deltaY = child.originDeltaY;\n return res === undefined || deltaY < res ? deltaY : (res as number);\n }, undefined) as number;\n });\n }\n\n /**\n * 绝对坐标 bbox, 不包含自身的 spacing(marginBottom), 但是包含 inlineSpacing 和 子节点的 spacing\n */\n get bounds(): Rectangle {\n return this.entity.memoGlobal<Rectangle>('bounds', () => {\n const { transform } = this;\n\n if (this.isContainer) {\n const childrenRects = transform.children.map(\n (c) => c.entity.getData<FlowNodeTransformData>(FlowNodeTransformData)!.boundsWithPadding\n );\n // Container 要加上 inlineSpacing\n return Rectangle.enlarge(childrenRects).withPadding(this.padding);\n }\n return transform.bounds; // 单个节点取默认的 bounds\n });\n }\n\n get boundsWithPadding(): Rectangle {\n return this.entity.memoGlobal<Rectangle>('boundsWithPadding', () => {\n const { transform } = this;\n\n if (this.isContainer) {\n const childrenRects = transform.children.map(\n (c) => c.entity.getData<FlowNodeTransformData>(FlowNodeTransformData)!.boundsWithPadding\n );\n return Rectangle.enlarge(childrenRects).withPadding(this.padding);\n }\n return transform.bounds.clone().withPadding(this.padding);\n });\n }\n\n get isContainer(): boolean {\n return this.transform.isContainer;\n }\n\n /**\n * 相对坐标 bbox, 这里的 localBounds 会加入 padding 一起算\n */\n get localBounds(): Rectangle {\n return this.entity.memoLocal<Rectangle>('localBounds', () => {\n const { transform } = this;\n\n if (this.isContainer) {\n const childrenRects = transform.children.map(\n (c) => c.entity.getData<FlowNodeTransformData>(FlowNodeTransformData)!.localBounds\n );\n const childrenBounds = Rectangle.enlarge(childrenRects).withPadding(this.padding);\n return Bounds.applyMatrix(childrenBounds, transform.localTransform);\n }\n\n return transform.localBounds.clone().withPadding(this.padding);\n });\n }\n\n get padding() {\n return this.entity.document.layout.getPadding(this.entity);\n }\n\n setParentTransform(transform?: FlowNodeTransformData): void {\n // 拖拽父元素变化需要重新布局\n if (this.transform.parent !== transform?.transform) {\n this.localDirty = true;\n }\n this.transform.setParent(transform?.transform);\n }\n\n get spacing(): number {\n const { spacing } = this.entity.getNodeMeta();\n return typeof spacing === 'function' ? spacing(this) : spacing;\n }\n\n get inlineSpacingPre(): number {\n const { inlineSpacingPre } = this.entity.getNodeMeta();\n return typeof inlineSpacingPre === 'function' ? inlineSpacingPre(this) : inlineSpacingPre;\n }\n\n get inlineSpacingAfter(): number {\n const { inlineSpacingAfter } = this.entity.getNodeMeta();\n return typeof inlineSpacingAfter === 'function' ? inlineSpacingAfter(this) : inlineSpacingAfter;\n }\n\n get minInlineBlockSpacing(): number {\n const { minInlineBlockSpacing } = this.entity.getNodeMeta();\n return typeof minInlineBlockSpacing === 'function'\n ? minInlineBlockSpacing(this)\n : minInlineBlockSpacing;\n }\n\n get children(): FlowNodeTransformData[] {\n return this.entity.children.map(\n (child) => child.getData<FlowNodeTransformData>(FlowNodeTransformData)!\n );\n }\n\n /**\n * 上一个节点的 transform 数据\n */\n get pre(): FlowNodeTransformData | undefined {\n return this.entity.pre?.getData<FlowNodeTransformData>(FlowNodeTransformData);\n }\n\n get originParent(): FlowNodeTransformData | undefined {\n return this.entity.originParent?.getData<FlowNodeTransformData>(FlowNodeTransformData);\n }\n\n get isFirst(): boolean {\n return this.entity.isFirst;\n }\n\n get isLast(): boolean {\n return this.entity.isLast;\n }\n\n get lastChild(): FlowNodeTransformData | undefined {\n return this.entity.lastChild?.getData<FlowNodeTransformData>(FlowNodeTransformData);\n }\n\n get firstChild(): FlowNodeTransformData | undefined {\n return this.entity.firstChild?.getData<FlowNodeTransformData>(FlowNodeTransformData);\n }\n\n /**\n * 下一个节点的 transform 数据\n */\n get next(): FlowNodeTransformData | undefined {\n return this.entity.next?.getData<FlowNodeTransformData>(FlowNodeTransformData);\n }\n\n /**\n * parent 节点的 transform 数据\n */\n get parent(): FlowNodeTransformData | undefined {\n return this.entity.parent?.getData<FlowNodeTransformData>(FlowNodeTransformData);\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Compare, Disposable, domUtils, Emitter } from '@flowgram.ai/utils';\nimport { EntityData } from '@flowgram.ai/core';\n\nimport { FlowNodeBaseType } from '../typings';\nimport type { FlowNodeEntity } from '../entities';\nimport { FlowNodeTransformData } from './index';\n\nexport interface FlowNodeRenderSchema {\n addable: boolean; // 是否可添加节点\n expandable: boolean; // 是否可展开\n collapsed?: boolean; // 复合节点是否收起\n expanded: boolean;\n activated: boolean; // 是否高亮节点\n hovered: boolean; // 是否悬浮在节点上\n dragging: boolean; // 是否正在拖拽\n stackIndex: number; // 渲染层级\n extInfo?: Record<string, any>; // 扩展渲染状态字段\n}\n\n/**\n * 节点渲染状态相关数据\n */\nexport class FlowNodeRenderData extends EntityData<FlowNodeRenderSchema> {\n static type = 'FlowNodeRenderData';\n\n declare entity: FlowNodeEntity;\n\n private _node?: HTMLDivElement;\n\n protected onExtInfoChangeEmitter = new Emitter<{ newInfo: any; oldInfo: any }>();\n\n readonly onExtInfoChange = this.onExtInfoChangeEmitter.event;\n\n get key(): string {\n return this.entity.id;\n }\n\n getDefaultData(): FlowNodeRenderSchema {\n const { addable, expandable, defaultExpanded } = this.entity.getNodeMeta();\n return {\n addable,\n expandable,\n expanded: defaultExpanded || false,\n activated: false,\n hovered: false,\n dragging: false,\n stackIndex: 0,\n };\n }\n\n updateExtInfo(info: Record<string, any>, fullUpdate?: boolean) {\n const oldInfo = this.data.extInfo;\n const newInfo = fullUpdate ? info : { ...oldInfo, ...info };\n if (Compare.isChanged(oldInfo, newInfo)) {\n this.update({\n extInfo: newInfo,\n });\n this.onExtInfoChangeEmitter.fire({ oldInfo, newInfo });\n }\n }\n\n getExtInfo(): Record<string, any> | undefined {\n return this.data.extInfo;\n }\n\n constructor(entity: FlowNodeEntity) {\n super(entity);\n this.toDispose.push(\n Disposable.create(() => {\n if (this._node) this._node.remove();\n })\n );\n }\n\n get addable(): boolean {\n return this.data.addable;\n }\n\n get expandable(): boolean {\n return this.data.expandable;\n }\n\n get draggable(): boolean {\n const { draggable } = this.entity.getNodeMeta();\n\n if (typeof draggable === 'function') {\n return draggable(this.entity);\n }\n\n return draggable;\n }\n\n get expanded(): boolean {\n return this.data.expanded;\n }\n\n set expanded(expanded: boolean) {\n if (this.expandable && this.data.expanded !== expanded) {\n this.data.expanded = expanded;\n this.fireChange();\n }\n }\n\n toggleExpand() {\n this.expanded = !this.expanded;\n }\n\n mouseLeaveTimeout?: ReturnType<typeof setTimeout>;\n\n toggleMouseEnter(silent = false) {\n this.entity.document.renderState.setNodeHovered(this.entity);\n if (silent) return;\n const transform = this.entity.getData(FlowNodeTransformData)!;\n if (transform.renderState.hidden) {\n return;\n }\n if (this.mouseLeaveTimeout) {\n clearTimeout(this.mouseLeaveTimeout);\n this.mouseLeaveTimeout = undefined;\n }\n\n transform.renderState.hovered = true;\n\n if (this.entity.isFirst && this.entity.parent?.id !== 'root') {\n // 分支中第一个节点 hover,parent activated 设置为 true\n transform.parent!.renderState.activated = true;\n } else {\n transform.renderState.activated = true;\n }\n }\n\n toggleMouseLeave(silent = false) {\n this.entity.document.renderState.setNodeHovered(undefined);\n if (silent) return;\n const transform = this.entity.getData(FlowNodeTransformData)!;\n this.mouseLeaveTimeout = setTimeout(() => {\n transform.renderState.hovered = false;\n\n if (this.entity.isFirst && this.entity.parent?.id !== 'root') {\n transform.parent!.renderState.activated = false;\n }\n transform.renderState.activated = false;\n }, 200);\n }\n\n get hidden(): boolean {\n return this.entity.hidden;\n }\n\n set hovered(hovered: boolean) {\n this.data.hovered = hovered;\n this.fireChange();\n }\n\n get hovered() {\n return this.data.hovered;\n }\n\n get dragging(): boolean {\n return this.data.dragging;\n }\n\n set dragging(dragging: boolean) {\n if (this.data.dragging !== dragging) {\n this.data.dragging = dragging;\n this.fireChange();\n }\n }\n\n set activated(activated: boolean) {\n if (this.entity.flowNodeType === FlowNodeBaseType.BLOCK_ICON && this.entity.parent) {\n this.entity.parent.getData<FlowNodeRenderData>(FlowNodeRenderData)!.activated = activated;\n return;\n }\n if (this.data.activated !== activated) {\n this.data.activated = activated;\n this.fireChange();\n }\n }\n\n get activated() {\n const { entity } = this;\n if (entity.parent && entity.parent.getData<FlowNodeRenderData>(FlowNodeRenderData)!.activated) {\n return true;\n }\n return this.data.activated;\n }\n\n get stackIndex(): number {\n return this.data.stackIndex;\n }\n\n set stackIndex(index: number) {\n this.data.stackIndex = index;\n }\n\n get lineActivated() {\n const { activated } = this;\n if (!activated) return false;\n // 只有 parent 高亮的情况才高亮下面的线条,否则只高亮 node\n // inlineBlock 仅看自身\n // 圈选情况下个节点被高量,则也跟着高量\n return Boolean(\n this.entity.parent?.getData(FlowNodeRenderData)?.activated ||\n this.entity.isInlineBlock ||\n this.entity.next?.getData(FlowNodeRenderData)!.activated\n );\n }\n\n get node(): HTMLDivElement {\n if (this._node) return this._node;\n this._node = domUtils.createDivWithClass('gedit-flow-activity-node');\n this._node.dataset.testid = 'sdk.workflow.canvas.node';\n this._node.dataset.nodeId = this.entity.id;\n return this._node;\n }\n\n dispose() {\n super.dispose();\n this.onExtInfoChangeEmitter.dispose();\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Point } from '@flowgram.ai/utils';\nimport { EntityData } from '@flowgram.ai/core';\n\nimport {\n type FlowTransitionLabel,\n FlowTransitionLabelEnum,\n type FlowTransitionLine,\n FlowTransitionLineEnum,\n} from '../typings';\nimport { type FlowNodeEntity } from '../entities';\nimport { FlowNodeTransformData } from './flow-node-transform-data';\nimport { FlowNodeRenderData } from './flow-node-render-data';\n\nexport interface FlowNodeTransitionSchema {}\n\n// 画线到下一个节点\nexport const drawLineToNext = (transition: FlowNodeTransitionData) => {\n const { transform } = transition;\n\n // 默认绘制一根连接到下一个节点的线条\n const currentOutput = transform.outputPoint;\n if (transform.next) {\n return [\n {\n type: FlowTransitionLineEnum.STRAIGHT_LINE,\n from: currentOutput,\n to: transform.next.inputPoint,\n },\n ];\n }\n\n return [];\n};\n\n// 画线到父节点的结尾\nexport const drawLineToBottom = (transition: FlowNodeTransitionData) => {\n const { transform } = transition;\n\n const currentOutput = transform.outputPoint;\n const parentOutput = transform.parent?.outputPoint;\n if (\n !transform.next &&\n parentOutput &&\n !new Point().copyFrom(currentOutput).equals(parentOutput) &&\n !transition.isNodeEnd\n ) {\n return [\n {\n type: FlowTransitionLineEnum.STRAIGHT_LINE,\n from: currentOutput,\n to: parentOutput,\n },\n ];\n }\n\n return [];\n};\n\nexport class FlowNodeTransitionData extends EntityData<FlowNodeTransitionSchema> {\n static type = 'FlowNodeTransitionData';\n\n declare entity: FlowNodeEntity;\n\n // 当前节点的 transform\n declare transform: FlowNodeTransformData;\n\n declare renderData: FlowNodeRenderData;\n\n getDefaultData(): FlowNodeTransitionSchema {\n return {};\n }\n\n formatLines(lines: FlowTransitionLine[]) {\n if (this.entity.document.options?.formatNodeLines) {\n return this.entity.document.options?.formatNodeLines?.(this.entity, lines);\n }\n return lines;\n }\n\n formatLabels(labels: FlowTransitionLabel[]) {\n if (this.entity.document.options.formatNodeLabels) {\n return this.entity.document.options?.formatNodeLabels?.(this.entity, labels);\n }\n return labels;\n }\n\n get lines(): FlowTransitionLine[] {\n return this.entity.memoGlobal<FlowTransitionLine[]>('lines', () => {\n const { getChildLines } = this.entity.parent?.getNodeRegistry() || {};\n\n if (getChildLines) {\n return this.formatLines(getChildLines(this, this.entity.document.layout));\n }\n\n const { getLines } = this.entity.getNodeRegistry();\n\n if (getLines) {\n return this.formatLines(getLines(this, this.entity.document.layout));\n }\n\n // 横向布局不画线\n if (this.transform.entity.isInlineBlock) {\n return [];\n }\n\n return this.formatLines([...drawLineToNext(this), ...drawLineToBottom(this)]);\n });\n }\n\n get labels() {\n return this.entity.memoGlobal<FlowTransitionLabel[]>('labels', () => {\n const { getChildLabels } = this.entity.parent?.getNodeRegistry() || {};\n\n if (getChildLabels) {\n return this.formatLabels(getChildLabels(this, this.entity.document.layout));\n }\n\n const { getLabels } = this.entity.getNodeRegistry();\n\n if (getLabels) {\n return this.formatLabels(getLabels(this, this.entity.document.layout));\n }\n\n // 横向布局不画加号\n if (this.transform.entity.isInlineBlock) {\n return [];\n }\n\n // 默认在中间点添加一个加号\n const currentOutput = this.transform.outputPoint;\n if (this.transform.next) {\n return this.formatLabels([\n {\n offset: Point.getMiddlePoint(currentOutput, this.transform.next.inputPoint),\n type: FlowTransitionLabelEnum.ADDER_LABEL,\n },\n ]);\n }\n\n const parentOutput = this.transform.parent?.outputPoint;\n if (\n parentOutput &&\n !new Point().copyFrom(currentOutput).equals(parentOutput) &&\n !this.isNodeEnd\n ) {\n return this.formatLabels([\n {\n offset: parentOutput,\n type: FlowTransitionLabelEnum.ADDER_LABEL,\n },\n ]);\n }\n\n return [];\n });\n }\n\n constructor(entity: FlowNodeEntity) {\n super(entity);\n this.transform = this.entity.addData<FlowNodeTransformData>(FlowNodeTransformData);\n this.renderData = this.entity.addData<FlowNodeRenderData>(FlowNodeRenderData);\n\n this.bindChange(this.transform);\n this.bindChange(this.renderData);\n }\n\n get collapsed() {\n return this.entity.collapsed;\n }\n\n get isNodeEnd(): boolean {\n return this.entity.isNodeEnd;\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Emitter } from '@flowgram.ai/utils';\nimport { ConfigEntity, type EntityOpts } from '@flowgram.ai/core';\n\nimport type { FlowDocument } from '../flow-document';\nimport { FlowNodeTransformData } from '../datas';\n\ninterface FlowDocumentTransformerEntityConfig extends EntityOpts {\n document: FlowDocument;\n}\n\n/**\n * 用于通知所有 layer 更新\n */\nexport class FlowDocumentTransformerEntity extends ConfigEntity<\n {\n loading: boolean;\n treeVersion: number;\n },\n FlowDocumentTransformerEntityConfig\n> {\n static type = 'FlowDocumentTransformerEntity';\n\n protected onRefreshEmitter = new Emitter<void>();\n\n protected lastTransformVersion = -1;\n\n protected lastTreeVersion = -1;\n\n document: FlowDocument;\n\n readonly onRefresh = this.onRefreshEmitter.event;\n\n constructor(conf: FlowDocumentTransformerEntityConfig) {\n super(conf);\n this.document = conf.document;\n this.toDispose.push(\n this.document.originTree.onTreeChange(() => {\n this.config.treeVersion += 1;\n this.fireChange();\n })\n );\n this.toDispose.push(this.onRefreshEmitter);\n }\n\n getDefaultConfig(): { loading: boolean; treeVersion: number } {\n return {\n loading: true,\n treeVersion: 0,\n };\n }\n\n get loading(): boolean {\n return this.config.loading;\n }\n\n set loading(loading) {\n if (this.config.loading !== loading) {\n this.config.loading = loading;\n this.fireChange();\n }\n }\n\n /**\n * 更新矩阵结构 (这个只有在树结构变化时候才会触发,如:添加节点、删除节点、改变位置节点)\n */\n updateTransformsTree(): void {\n // 更新 node 结构树\n this.document.renderTree.traverse((node, depth, index) => {\n const transform = node.getData<FlowNodeTransformData>(FlowNodeTransformData)!;\n // 收起时清空子节点\n if (transform.collapsed) {\n transform.transform.clearChildren();\n }\n if (node.parent) {\n transform.setParentTransform(node.parent!.getData(FlowNodeTransformData));\n }\n // 更新 index\n node.index = index;\n });\n }\n\n clear(): void {\n this.lastTreeVersion = -1;\n this.lastTransformVersion = -1;\n }\n\n isTreeDirty(): boolean {\n const transformVersion = this.entityManager.getEntityDataVersion(FlowNodeTransformData);\n const isTreeVersionChanged = this.lastTreeVersion !== this.config.treeVersion;\n const isTransformVersionChanged = this.lastTransformVersion !== transformVersion;\n return isTreeVersionChanged || isTransformVersionChanged;\n }\n\n /**\n * 刷新节点的相对偏移\n */\n refresh(): void {\n const transformVersion = this.entityManager.getEntityDataVersion(FlowNodeTransformData);\n\n const isTreeVersionChanged = this.lastTreeVersion !== this.config.treeVersion;\n const isTransformVersionChanged = this.lastTransformVersion !== transformVersion;\n\n this.entityManager.changeEntityLocked = true;\n if (isTreeVersionChanged) {\n this.document.renderTree.updateRenderStruct(); // 重新调整 renderTree 结构\n this.updateTransformsTree(); // 更新树结构\n this.lastTreeVersion = this.config.treeVersion;\n }\n\n if (isTreeVersionChanged || isTransformVersionChanged) {\n // 位置计算不需要重新触发 Layer 刷新\n this.document.layout.update(); // 更新布局\n this.lastTransformVersion = this.entityManager.getEntityDataVersion(FlowNodeTransformData);\n this.lastTreeVersion = this.config.treeVersion;\n this.onRefreshEmitter.fire();\n }\n\n this.entityManager.changeEntityLocked = false;\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { debounce } from 'lodash-es';\nimport { type Disposable } from '@flowgram.ai/utils';\nimport { ConfigEntity, type EntityOpts } from '@flowgram.ai/core';\n\nimport { LABEL_SIDE_TYPE } from '../typings';\nimport { type FlowNodeEntity } from './flow-node-entity';\n\ninterface FlowRendererStateEntityConfig extends EntityOpts {}\n\ninterface FlowRendererState {\n nodeHoveredId?: string;\n nodeDroppingId?: string;\n nodeDragStartId?: string;\n nodeDragIds?: string[]; // 框选批量拖拽\n nodeDragIdsWithChildren?: string[]; // 批量拖拽(含子节点)\n dragLabelSide?: LABEL_SIDE_TYPE;\n dragging?: boolean;\n isBranch?: boolean;\n}\n/**\n * 渲染相关的全局状态管理\n */\nexport class FlowRendererStateEntity extends ConfigEntity<\n FlowRendererState,\n FlowRendererStateEntityConfig\n> {\n static type = 'FlowRendererStateEntity';\n\n getDefaultConfig() {\n return {};\n }\n\n constructor(conf: FlowRendererStateEntityConfig) {\n super(conf);\n }\n\n getNodeHovered(): FlowNodeEntity | undefined {\n return this.config.nodeHoveredId\n ? this.entityManager.getEntityById(this.config.nodeHoveredId)\n : undefined;\n }\n\n setNodeHovered(node: FlowNodeEntity | undefined): void {\n this.updateConfig({\n nodeHoveredId: node?.id,\n });\n }\n\n get dragging() {\n return this.config.dragging;\n }\n\n setDragging(dragging: boolean) {\n this.updateConfig({\n dragging,\n });\n }\n\n get isBranch() {\n return this.config.isBranch;\n }\n\n setIsBranch(isBranch: boolean) {\n this.updateConfig({\n isBranch,\n });\n }\n\n getDragLabelSide(): LABEL_SIDE_TYPE | undefined {\n return this.config.dragLabelSide;\n }\n\n setDragLabelSide(dragLabelSide?: LABEL_SIDE_TYPE): void {\n this.updateConfig({\n dragLabelSide,\n });\n }\n\n getNodeDroppingId(): string | undefined {\n return this.config.nodeDroppingId;\n }\n\n setNodeDroppingId(nodeDroppingId?: string): void {\n this.updateConfig({\n nodeDroppingId,\n });\n }\n\n getDragStartEntity(): FlowNodeEntity | undefined {\n const { nodeDragStartId } = this.config;\n return this.entityManager.getEntityById(nodeDragStartId!);\n }\n\n setDragStartEntity(node?: FlowNodeEntity): void {\n this.updateConfig({\n nodeDragStartId: node?.id,\n });\n }\n\n // 拖拽多个节点时\n getDragEntities(): FlowNodeEntity[] {\n const { nodeDragIds } = this.config;\n return (nodeDragIds || []).map((_id) => this.entityManager.getEntityById(_id)!);\n }\n\n // 设置拖拽的节点\n setDragEntities(nodes: FlowNodeEntity[]): void {\n this.updateConfig({\n nodeDragIds: nodes.map((_node) => _node.id),\n nodeDragIdsWithChildren: nodes\n .map((_node) => [_node.id, ..._node.allCollapsedChildren.map((_n) => _n.id)])\n .flat(),\n });\n }\n\n onNodeHoveredChange(\n fn: (hoveredNode: FlowNodeEntity | undefined) => void,\n debounceTime = 100 // 延迟执行避免频繁 hover\n ): Disposable {\n return this.onConfigChanged(debounce(() => fn(this.getNodeHovered()), debounceTime));\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { omit } from 'lodash-es';\nimport { inject, injectable, multiInject, optional, postConstruct } from 'inversify';\nimport { type Disposable, Emitter } from '@flowgram.ai/utils';\nimport { type EntityData, type EntityDataRegistry, EntityManager } from '@flowgram.ai/core';\n\nimport {\n AddNodeData,\n DEFAULT_FLOW_NODE_META,\n type FlowDocumentJSON,\n FlowLayout,\n FlowLayoutDefault,\n FlowNodeBaseType,\n type FlowNodeJSON,\n FlowNodeRegistry,\n FlowNodeType,\n} from './typings';\nimport { FlowVirtualTree } from './flow-virtual-tree';\nimport { FlowRenderTree } from './flow-render-tree';\nimport {\n ConstantKeys,\n FlowDocumentOptions,\n FlowDocumentOptionsDefault,\n} from './flow-document-options';\nimport { FlowDocumentContribution } from './flow-document-contribution';\nimport { FlowDocumentConfig } from './flow-document-config';\nimport { FlowDocumentTransformerEntity, FlowNodeEntity, FlowRendererStateEntity } from './entities';\n\nexport type FlowDocumentProvider = () => FlowDocument;\nexport const FlowDocumentProvider = Symbol('FlowDocumentProvider');\n/**\n * 流程整个文档数据\n */\n@injectable()\nexport class FlowDocument<T = FlowDocumentJSON> implements Disposable {\n @inject(EntityManager) protected entityManager: EntityManager;\n\n @inject(FlowDocumentConfig) readonly config: FlowDocumentConfig;\n\n /**\n * 流程画布配置项\n */\n @inject(FlowDocumentOptions) @optional() public options: FlowDocumentOptions;\n\n @multiInject(FlowDocumentContribution)\n @optional()\n protected contributions: FlowDocumentContribution[] = [];\n\n protected registers = new Map<FlowNodeType, FlowNodeRegistry>();\n\n private nodeRegistryCache = new Map<string, any>();\n\n protected nodeDataRegistries: EntityDataRegistry[] = [];\n\n protected layouts: FlowLayout[] = [];\n\n protected currentLayoutKey: string = '';\n\n protected onNodeUpdateEmitter = new Emitter<{\n node: FlowNodeEntity;\n /**\n * use 'json' instead\n * @deprecated\n */\n data: FlowNodeJSON;\n json: FlowNodeJSON;\n }>();\n\n protected onNodeCreateEmitter = new Emitter<{\n node: FlowNodeEntity;\n /**\n * use 'json' instead\n * @deprecated\n */\n data: FlowNodeJSON;\n json: FlowNodeJSON;\n }>();\n\n protected onNodeDisposeEmitter = new Emitter<{\n node: FlowNodeEntity;\n }>();\n\n protected onLayoutChangeEmitter = new Emitter<FlowLayout>();\n\n readonly onNodeUpdate = this.onNodeUpdateEmitter.event;\n\n readonly onNodeCreate = this.onNodeCreateEmitter.event;\n\n readonly onNodeDispose = this.onNodeDisposeEmitter.event;\n\n readonly onLayoutChange = this.onLayoutChangeEmitter.event;\n\n private _disposed = false;\n\n root: FlowNodeEntity;\n\n /**\n * 原始的 tree 结构\n */\n originTree: FlowVirtualTree<FlowNodeEntity>;\n\n transformer: FlowDocumentTransformerEntity;\n\n /**\n * 渲染相关的全局轧辊台\n */\n renderState: FlowRendererStateEntity;\n\n /**\n * 渲染后的 tree 结构\n */\n renderTree: FlowRenderTree<FlowNodeEntity>;\n\n /**\n *\n */\n get disposed(): boolean {\n return this._disposed;\n }\n\n @postConstruct()\n init(): void {\n if (!this.options) this.options = FlowDocumentOptionsDefault;\n this.currentLayoutKey = this.options.defaultLayout || FlowLayoutDefault.VERTICAL_FIXED_LAYOUT;\n this.contributions.forEach((contrib) => contrib.registerDocument?.(this));\n this.root = this.addNode({ id: 'root', type: FlowNodeBaseType.ROOT });\n this.originTree = new FlowVirtualTree<FlowNodeEntity>(this.root);\n this.transformer = this.entityManager.createEntity<FlowDocumentTransformerEntity>(\n FlowDocumentTransformerEntity,\n { document: this }\n );\n this.renderState =\n this.entityManager.createEntity<FlowRendererStateEntity>(FlowRendererStateEntity);\n this.renderTree = new FlowRenderTree<FlowNodeEntity>(this.root, this.originTree, this);\n // 布局第一次加载时候触发一次\n this.layout.reload?.();\n }\n\n /**\n * 从数据初始化 O(n)\n * @param json\n */\n /**\n * 加载数据,可以被重载\n * @param json 文档数据更新\n * @param fireRender 是否要触发渲染,默认 true\n */\n fromJSON(json: FlowDocumentJSON | any, fireRender = true): void {\n if (this._disposed) return;\n // 清空 tree 数据 重新计算\n this.originTree.clear();\n this.renderTree.clear();\n // 暂停触发画布更新\n this.entityManager.changeEntityLocked = true;\n // 添加前的节点\n const oldNodes = this.entityManager.getEntities<FlowNodeEntity>(FlowNodeEntity);\n // 添加后的节点\n const newNodes: FlowNodeEntity[] = [this.root];\n this.addBlocksAsChildren(this.root, json.nodes || [], newNodes);\n // 删除无效的节点\n oldNodes.forEach((node) => {\n if (!newNodes.includes(node)) {\n node.dispose();\n }\n });\n this.entityManager.changeEntityLocked = false;\n this.transformer.loading = false;\n if (fireRender) this.fireRender();\n }\n\n get layout(): FlowLayout {\n const layout = this.layouts.find((layout) => layout.name == this.currentLayoutKey);\n if (!layout) {\n throw new Error(`Unknown flow layout: ${this.currentLayoutKey}`);\n }\n return layout;\n }\n\n async load(): Promise<void> {\n await Promise.all(this.contributions.map((c) => c.loadDocument?.(this)));\n }\n\n get loading(): boolean {\n return this.transformer.loading;\n }\n\n /**\n * 触发 render\n */\n fireRender(): void {\n if (this.transformer.isTreeDirty()) {\n this.entityManager.fireEntityChanged(FlowNodeEntity.type);\n this.entityManager.fireEntityChanged(FlowDocumentTransformerEntity.type);\n }\n }\n\n /**\n * 从指定节点的下一个节点新增\n * @param fromNode\n * @param json\n */\n addFromNode(fromNode: FlowNodeEntity | string, json: FlowNodeJSON): FlowNodeEntity {\n const node = typeof fromNode === 'string' ? this.getNode(fromNode)! : fromNode;\n this.entityManager.changeEntityLocked = true;\n const { parent } = node;\n const result = this.addNode({\n ...json,\n parent,\n // originParent,\n });\n this.originTree.insertAfter(node, result);\n this.entityManager.changeEntityLocked = false;\n this.entityManager.fireEntityChanged(FlowNodeEntity.type);\n return result;\n }\n\n removeNode(node: FlowNodeEntity | string) {\n if (typeof node === 'string') {\n this.getNode(node)?.dispose();\n } else {\n node.dispose();\n }\n }\n\n /**\n * 添加节点,如果节点已经存在则不会重复创建\n * @param data\n * @param addedNodes\n */\n addNode(data: AddNodeData, addedNodes?: FlowNodeEntity[]): FlowNodeEntity {\n const { id, type = 'block', originParent, parent, meta, hidden, index } = data;\n let node = this.getNode(id);\n let isNew = false;\n const register = this.getNodeRegistry(type, data.originParent);\n // node 类型变化则全部删除重新来\n if (node && node.flowNodeType !== data.type) {\n node.dispose();\n node = undefined;\n }\n if (!node) {\n const { dataRegistries } = register;\n node = this.entityManager.createEntity<FlowNodeEntity>(FlowNodeEntity, {\n id,\n document: this,\n flowNodeType: type,\n originParent,\n meta,\n });\n this.options.preNodeCreate?.(node);\n const datas = dataRegistries\n ? this.nodeDataRegistries.concat(...dataRegistries)\n : this.nodeDataRegistries;\n node.addInitializeData(datas);\n node.onDispose(() => this.onNodeDisposeEmitter.fire({ node: node! }));\n this.options.fromNodeJSON?.(node, data, true);\n isNew = true;\n } else {\n this.options.fromNodeJSON?.(node, data, false);\n }\n // 初始化数据重制\n node.initData({\n originParent,\n parent,\n meta,\n hidden,\n index,\n });\n // 开始节点加到 root 里边\n if (node.isStart) {\n this.root.addChild(node);\n }\n addedNodes?.push(node);\n // 自定义创建逻辑\n if (register.onCreate) {\n const extendNodes = register.onCreate(node, data);\n if (extendNodes && addedNodes) {\n addedNodes.push(...extendNodes);\n }\n } else if (data.blocks && data.blocks.length > 0) {\n // 兼容老的写法\n if (!data.blocks[0].type) {\n this.addInlineBlocks(node, data.blocks, addedNodes);\n } else {\n this.addBlocksAsChildren(node, data.blocks as FlowNodeJSON[], addedNodes);\n }\n }\n\n if (isNew) {\n this.onNodeCreateEmitter.fire({\n node,\n data,\n json: data,\n });\n } else {\n this.onNodeUpdateEmitter.fire({ node, data, json: data });\n }\n\n return node;\n }\n\n addBlocksAsChildren(\n parent: FlowNodeEntity,\n blocks: FlowNodeJSON[],\n addedNodes?: FlowNodeEntity[]\n ): void {\n for (const block of blocks) {\n this.addNode(\n {\n ...block,\n parent,\n },\n addedNodes\n );\n }\n }\n\n /**\n * block 格式:\n * node: (最原始的 id)\n * blockIcon\n * inlineBlocks\n * block\n * blockOrderIcon\n * block\n * blockOrderIcon\n * @param node\n * @param blocks\n * @param addedNodes\n */\n addInlineBlocks(\n node: FlowNodeEntity,\n blocks: FlowNodeJSON[],\n addedNodes: FlowNodeEntity[] = []\n ): FlowNodeEntity[] {\n // 块列表开始节点,用来展示块的按钮\n const blockIconNode = this.addNode({\n id: `$blockIcon$${node.id}`,\n type: FlowNodeBaseType.BLOCK_ICON,\n originParent: node,\n parent: node,\n });\n addedNodes.push(blockIconNode);\n // 水平布局\n const inlineBlocksNode = this.addNode({\n id: `$inlineBlocks$${node.id}`,\n type: FlowNodeBaseType.INLINE_BLOCKS,\n originParent: node,\n parent: node,\n });\n addedNodes.push(inlineBlocksNode);\n blocks.forEach((blockData) => {\n this.addBlock(node, blockData, addedNodes);\n });\n return addedNodes;\n }\n\n /**\n * 添加单个 block\n * @param target\n * @param blockData\n * @param addedNodes\n * @param parent 默认去找 $inlineBlocks$\n */\n addBlock(\n target: FlowNodeEntity | string,\n blockData: FlowNodeJSON,\n addedNodes?: FlowNodeEntity[],\n parent?: FlowNodeEntity,\n index?: number\n ): FlowNodeEntity {\n const node: FlowNodeEntity = typeof target === 'string' ? this.getNode(target)! : target;\n const { onBlockChildCreate } = node.getNodeRegistry();\n if (onBlockChildCreate) {\n return onBlockChildCreate(node, blockData, addedNodes);\n }\n parent = parent || this.getNode(`$inlineBlocks$${node.id}`);\n // 块节点会生成一个空的 Block 节点用来切割 Block\n const block = this.addNode({\n ...omit(blockData, 'blocks'),\n type: blockData.type || FlowNodeBaseType.BLOCK,\n originParent: node,\n parent,\n index,\n });\n\n if (blockData.meta?.defaultCollapsed) {\n block.collapsed = true;\n }\n\n // 块开始节点\n const blockOrderIcon = this.addNode({\n id: `$blockOrderIcon$${blockData.id}`,\n type: FlowNodeBaseType.BLOCK_ORDER_ICON,\n originParent: node,\n meta: blockData.meta,\n data: blockData.data,\n parent: block,\n });\n addedNodes?.push(block, blockOrderIcon);\n if (blockData.blocks) {\n this.addBlocksAsChildren(block, blockData.blocks as FlowNodeJSON[], addedNodes);\n }\n return block;\n }\n\n /**\n * 根据 id 获取节点\n * @param id\n */\n getNode(id: string): FlowNodeEntity | undefined {\n if (!id) return undefined;\n return this.entityManager.getEntityById<FlowNodeEntity>(id);\n }\n\n /**\n * 注册节点\n * @param registries\n */\n registerFlowNodes<T extends FlowNodeRegistry<any>>(...registries: T[]): void {\n registries.forEach((newRegistry) => {\n if (!newRegistry) {\n throw new Error('[FlowDocument] registerFlowNodes parameters get undefined registry.');\n }\n const preRegistry = this.registers.get(newRegistry.type);\n this.registers.set(newRegistry.type, {\n ...preRegistry,\n ...newRegistry,\n meta: {\n ...preRegistry?.meta,\n ...newRegistry?.meta,\n },\n extendChildRegistries: FlowNodeRegistry.mergeChildRegistries(\n preRegistry?.extendChildRegistries,\n newRegistry?.extendChildRegistries\n ),\n });\n });\n }\n\n /**\n * Check node extend\n * @param currentType\n * @param extendType\n */\n isExtend(currentType: FlowNodeType, extendType: FlowNodeType): boolean {\n return (this.getNodeRegistry(currentType).__extends__ || []).includes(extendType);\n }\n\n /**\n * Check node type\n * @param currentType\n * @param extendType\n */\n isTypeOrExtendType(currentType: FlowNodeType, extendType: FlowNodeType): boolean {\n return currentType === extendType || this.isExtend(currentType, extendType);\n }\n\n /**\n * 导出数据,可以重载\n */\n toJSON(): T | any {\n if (this.disposed) {\n throw new Error(\n 'The FlowDocument has been disposed and it is no longer possible to call toJSON.'\n );\n }\n return {\n nodes: this.root.toJSON().blocks,\n };\n }\n\n /**\n * @deprecated\n * use `getNodeRegistry` instead\n */\n getNodeRegister<T extends FlowNodeRegistry = FlowNodeRegistry>(\n type: FlowNodeType,\n originParent?: FlowNodeEntity\n ): T {\n return this.getNodeRegistry<T>(type, originParent);\n }\n\n getNodeRegistry<T extends FlowNodeRegistry = FlowNodeRegistry>(\n type: FlowNodeType,\n originParent?: FlowNodeEntity\n ): T {\n const typeKey = `${type}_${originParent?.flowNodeType || ''}`;\n if (this.nodeRegistryCache.has(typeKey)) {\n return this.nodeRegistryCache.get(typeKey) as T;\n }\n const customDefaultRegistry = this.options.getNodeDefaultRegistry?.(type);\n let register = this.registers.get(type) || { type };\n const extendRegisters: FlowNodeRegistry[] = [];\n const extendKey = register.extend;\n // 继承重载\n if (register.extend && this.registers.has(register.extend)) {\n register = FlowNodeRegistry.merge(\n this.getNodeRegistry(register.extend),\n register,\n register.type\n );\n }\n // 父节点覆盖\n if (originParent) {\n const extendRegister = this.getNodeRegistry(\n originParent.flowNodeType\n ).extendChildRegistries?.find((r) => r.type === type);\n if (extendRegister) {\n if (extendRegister.extend && this.registers.has(extendRegister.extend)) {\n extendRegisters.push(this.registers.get(extendRegister.extend)!);\n }\n extendRegisters.push(extendRegister);\n }\n }\n register = FlowNodeRegistry.extend(register, extendRegisters);\n const defaultNodeMeta = DEFAULT_FLOW_NODE_META(type, this);\n defaultNodeMeta.spacing =\n this.options?.constants?.[ConstantKeys.NODE_SPACING] || defaultNodeMeta.spacing;\n\n const res = {\n ...customDefaultRegistry,\n ...register,\n meta: {\n ...defaultNodeMeta,\n ...customDefaultRegistry?.meta,\n ...register.meta,\n },\n } as T;\n // Save the \"extend\" attribute\n if (extendKey) {\n res.extend = extendKey;\n }\n this.nodeRegistryCache.set(typeKey, res);\n return res;\n }\n\n /**\n * 节点注入数据\n * @param nodeDatas\n */\n registerNodeDatas(...nodeDatas: EntityDataRegistry[]): void {\n this.nodeDataRegistries.push(...nodeDatas);\n }\n\n /**\n * traverse all nodes, O(n)\n * R\n * |\n * +---1\n * | |\n * | +---1.1\n * | |\n * | +---1.2\n * | |\n * | +---1.3\n * | | |\n * | | +---1.3.1\n * | | |\n * | | +---1.3.2\n * | |\n * | +---1.4\n * |\n * +---2\n * |\n * +---2.1\n *\n * sort: [1, 1.1, 1.2, 1.3, 1.3.1, 1.3.2, 1.4, 2, 2.1]\n * @param fn\n * @param node\n * @param depth\n * @return isBreak\n */\n traverse(\n fn: (node: FlowNodeEntity, depth: number, index: number) => boolean | void,\n node = this.root,\n depth = 0\n ): boolean | void {\n return this.originTree.traverse(fn, node, depth);\n }\n\n get size(): number {\n return this.getAllNodes().length;\n }\n\n hasNode(nodeId: string): boolean {\n return !!this.entityManager.getEntityById(nodeId);\n }\n\n getAllNodes(): FlowNodeEntity[] {\n return this.entityManager.getEntities(FlowNodeEntity);\n }\n\n toString(showType?: boolean): string {\n return this.originTree.toString(showType);\n }\n\n /**\n * 返回需要渲染的数据\n */\n getRenderDatas<T extends EntityData>(\n dataRegistry: EntityDataRegistry<T>,\n containHiddenNodes = true\n ): T[] {\n const result: T[] = [];\n this.renderTree.traverse((node) => {\n if (!containHiddenNodes && node.hidden) return;\n result.push(node.getData<T>(dataRegistry)!);\n });\n return result;\n }\n\n toNodeJSON(node: FlowNodeEntity): FlowNodeJSON {\n if (this.options.toNodeJSON) {\n return this.options.toNodeJSON(node);\n }\n const nodesMap: Record<string, FlowNodeJSON> = {};\n let startNodeJSON: FlowNodeJSON;\n this.traverse((node) => {\n const isSystemNode = node.id.startsWith('$');\n if (isSystemNode) return;\n const nodeJSONData = node.getJSONData();\n const nodeJSON: FlowNodeJSON = {\n id: node.id,\n type: node.flowNodeType,\n };\n if (nodeJSONData !== undefined) {\n nodeJSON.data = nodeJSONData;\n }\n if (!startNodeJSON) startNodeJSON = nodeJSON;\n let { parent } = node;\n if (parent && parent.id.startsWith('$')) {\n parent = parent.originParent;\n }\n const parentJSON = parent ? nodesMap[parent.id] : undefined;\n if (parentJSON) {\n if (!parentJSON.blocks) {\n parentJSON.blocks = [];\n }\n parentJSON.blocks.push(nodeJSON);\n }\n nodesMap[node.id] = nodeJSON;\n }, node);\n return startNodeJSON!;\n }\n\n /**\n * 移动节点\n * @param param0\n * @returns\n */\n moveNodes({\n dropNodeId,\n sortNodeIds,\n inside = false,\n }: {\n dropNodeId: string;\n sortNodeIds: string[];\n inside?: boolean;\n }) {\n const dropEntity = this.getNode(dropNodeId);\n if (!dropEntity) {\n return;\n }\n\n const sortNodes = sortNodeIds.map((id) => this.getNode(id)!);\n\n // 按照顺序一个个移动到目标节点下\n this.entityManager.changeEntityLocked = true;\n for (const node of sortNodes.reverse()) {\n if (inside) {\n this.originTree.addChild(dropEntity, node, 0);\n } else {\n this.originTree.insertAfter(dropEntity, node);\n }\n }\n\n this.entityManager.changeEntityLocked = false;\n this.fireRender();\n }\n\n /**\n * 移动子节点\n * @param param0\n * @returns\n */\n moveChildNodes({\n toParentId,\n toIndex,\n nodeIds,\n }: {\n toParentId: string;\n nodeIds: string[];\n toIndex: number;\n }) {\n if (nodeIds.length === 0) {\n return;\n }\n\n const toParent = this.getNode(toParentId);\n if (!toParent) {\n return;\n }\n\n this.entityManager.changeEntityLocked = true;\n\n this.originTree.moveChilds(\n toParent,\n nodeIds.map((nodeId) => this.getNode(nodeId) as FlowNodeEntity),\n toIndex\n );\n\n this.entityManager.changeEntityLocked = false;\n this.fireRender();\n }\n\n /**\n * 注册布局\n * @param layout\n */\n registerLayout(layout: FlowLayout) {\n this.layouts.push(layout);\n }\n\n /**\n * 更新布局\n * @param layoutKey\n */\n setLayout(layoutKey: string) {\n if (this.currentLayoutKey === layoutKey) return;\n const layout = this.layouts.find((layout) => layout.name === layoutKey);\n if (!layout) return;\n this.currentLayoutKey = layoutKey;\n this.transformer.clear();\n layout.reload?.();\n this.fireRender();\n this.onLayoutChangeEmitter.fire(this.layout);\n }\n\n /**\n * 切换垂直或水平布局\n */\n toggleFixedLayout() {\n this.setLayout(\n this.layout.name === FlowLayoutDefault.HORIZONTAL_FIXED_LAYOUT\n ? FlowLayoutDefault.VERTICAL_FIXED_LAYOUT\n : FlowLayoutDefault.HORIZONTAL_FIXED_LAYOUT\n );\n }\n\n dispose() {\n if (this._disposed) return;\n this.registers.clear();\n this.nodeRegistryCache.clear();\n this.originTree.dispose();\n this.renderTree.dispose();\n this.onNodeUpdateEmitter.dispose();\n this.onNodeCreateEmitter.dispose();\n this.onNodeDisposeEmitter.dispose();\n this.onLayoutChangeEmitter.dispose();\n this._disposed = true;\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { type Disposable, Emitter } from '@flowgram.ai/utils';\n\nimport { type FlowNodeType } from './typings';\n\n/**\n * 存储节点的 tree 结构信息\n * 策略是 \"重修改轻查询\",即修改时候做的事情更多,查询都通过指针来操作\n */\nexport class FlowVirtualTree<T extends { id: string; flowNodeType?: FlowNodeType }>\n implements Disposable\n{\n protected onTreeChangeEmitter = new Emitter<void>();\n\n /**\n * tree 结构变化时候触发\n */\n onTreeChange = this.onTreeChangeEmitter.event;\n\n protected map: Map<T, FlowVirtualTree.NodeInfo<T>> = new Map();\n\n constructor(readonly root: T) {}\n\n dispose() {\n this.map.clear();\n this.onTreeChangeEmitter.dispose();\n }\n\n getInfo(node: T): FlowVirtualTree.NodeInfo<T> {\n let res: FlowVirtualTree.NodeInfo<T> | undefined = this.map.get(node);\n if (!res) {\n res = { children: [] };\n this.map.set(node, res);\n }\n return res;\n }\n\n clear(): void {\n this.map.clear();\n }\n\n cloneMap(): Map<T, FlowVirtualTree.NodeInfo<T>> {\n const newMap: Map<T, FlowVirtualTree.NodeInfo<T>> = new Map();\n for (const [key, value] of this.map) {\n newMap.set(key, {\n ...value,\n children: value.children.slice(),\n });\n }\n\n return newMap;\n }\n\n clone(): FlowVirtualTree<T> {\n const newTree = new FlowVirtualTree<T>(this.root);\n newTree.map = this.cloneMap();\n return newTree;\n }\n\n remove(node: T, withChildren = true): void {\n this.removeParent(node);\n if (withChildren) {\n this._removeChildren(node);\n }\n this.map.delete(node);\n this.fireTreeChange();\n }\n\n addChild(parent: T, child: T, index?: number): T {\n const parentInfo = this.getInfo(parent);\n const childInfo = this.getInfo(child);\n if (childInfo.parent) {\n if (childInfo.parent === parent) return child;\n if (childInfo.parent !== parent) {\n this.removeParent(child);\n }\n }\n\n const len = parentInfo.children.length;\n const idx = typeof index === 'undefined' ? len - 1 : index - 1;\n const lastChild = parentInfo.children[idx];\n const nextChild = parentInfo.children[idx + 1];\n if (lastChild) this.getInfo(lastChild).next = child;\n if (nextChild) this.getInfo(nextChild).pre = child;\n childInfo.pre = lastChild;\n childInfo.next = nextChild;\n parentInfo.children.splice(idx + 1, 0, child);\n childInfo.parent = parent;\n this.fireTreeChange();\n return child;\n }\n\n moveChilds(parent: T, childs: T[], index?: number): T[] {\n const parentInfo = this.getInfo(parent);\n const len = parentInfo.children.length;\n let childIndex: number = index ?? len;\n\n childs.forEach((child) => {\n const childInfo = this.getInfo(child);\n if (childInfo.parent) {\n this.removeParent(child);\n }\n });\n\n childs.forEach((child) => {\n const childInfo = this.getInfo(child);\n let lastChild: T | undefined = parentInfo.children[childIndex - 1];\n let nextChild: T | undefined = parentInfo.children[childIndex];\n\n if (lastChild) this.getInfo(lastChild).next = child;\n if (nextChild) this.getInfo(nextChild).pre = child;\n childInfo.pre = lastChild;\n childInfo.next = nextChild;\n parentInfo.children.splice(childIndex, 0, child);\n childInfo.parent = parent;\n childIndex++;\n });\n\n this.fireTreeChange();\n return childs;\n }\n\n getById(id: string): T | undefined {\n for (const node of this.map.keys()) {\n if (node.id === id) return node;\n }\n }\n\n /**\n * 插入节点到后边\n * @param before\n * @param after\n */\n insertAfter(before: T, after: T) {\n const beforeInfo = this.getInfo(before);\n const afterInfo = this.getInfo(after);\n this.removeParent(after);\n if (beforeInfo.parent) {\n const parentInfo = this.getInfo(beforeInfo.parent);\n parentInfo.children.splice(parentInfo.children.indexOf(before) + 1, 0, after);\n const { next } = beforeInfo;\n if (next) {\n this.getInfo(next).pre = after;\n }\n afterInfo.next = next;\n beforeInfo.next = after;\n afterInfo.pre = before;\n afterInfo.parent = beforeInfo.parent;\n }\n this.fireTreeChange();\n }\n\n removeParent(node: T): void {\n const info = this.getInfo(node);\n if (!info.parent) return;\n const parentInfo = this.getInfo(info.parent);\n const index = parentInfo.children.indexOf(node);\n parentInfo.children.splice(index, 1);\n const { pre, next } = info;\n if (pre) this.getInfo(pre).next = next;\n if (next) this.getInfo(next).pre = pre;\n this.fireTreeChange();\n }\n\n private _removeChildren(node: T): void {\n // 删除子节点\n const children = this.getChildren(node);\n if (children.length > 0) {\n children.forEach((child) => {\n this._removeChildren(child);\n this.map.delete(child);\n });\n }\n }\n\n getParent(node: T): T | undefined {\n return this.getInfo(node).parent;\n }\n\n getPre(node: T): T | undefined {\n return this.getInfo(node).pre;\n }\n\n getNext(node: T): T | undefined {\n return this.getInfo(node).next;\n }\n\n getChildren(node: T): T[] {\n return this.getInfo(node).children;\n }\n\n traverse(\n fn: (node: T, depth: number, index: number) => boolean | void,\n node = this.root,\n depth = 0,\n index = 0\n ): boolean | void {\n const breaked = fn(node, depth, index);\n if (breaked) return true;\n const info = this.getInfo(node);\n const shouldBreak = info.children.find((child, i) => this.traverse(fn, child, depth + 1, i));\n if (shouldBreak) return true;\n }\n\n /**\n * 通知文档树结构更新\n */\n fireTreeChange(): void {\n this.onTreeChangeEmitter.fire();\n }\n\n get size(): number {\n return this.map.size;\n }\n\n toString(showType?: boolean): string {\n const ret: string[] = [];\n this.traverse((node, depth) => {\n if (depth === 0) {\n ret.push(node.id);\n } else {\n ret.push(\n `|${new Array(depth).fill('--').join('')} ${\n showType ? `${node.flowNodeType}(${node.id})` : node.id\n }`\n );\n }\n });\n return `${ret.join('\\n')}`;\n }\n}\n\nexport namespace FlowVirtualTree {\n export interface NodeInfo<T> {\n parent?: T;\n next?: T;\n pre?: T;\n children: T[];\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { FlowDocumentConfigEnum, FlowNodeBaseType, FlowNodeSplitType } from './typings';\nimport { FlowVirtualTree } from './flow-virtual-tree';\nimport type { FlowDocument } from './flow-document';\nimport type { FlowNodeEntity } from './entities';\n\n/**\n * Render Tree 会只读模式,不具备操作 tree 结构元素\n */\nexport class FlowRenderTree<T extends FlowNodeEntity> extends FlowVirtualTree<T> {\n protected originTree: FlowVirtualTree<T>;\n\n protected document: FlowDocument;\n\n /**\n * 折叠的节点\n * @protected\n */\n protected nodesCollapsed = new Set<T>();\n\n constructor(readonly root: T, originTree: FlowVirtualTree<T>, document: FlowDocument) {\n super(root);\n this.originTree = originTree;\n this.onTreeChange = this.originTree.onTreeChange;\n this.document = document;\n }\n\n isCollapsed(node: T): boolean {\n return this.nodesCollapsed.has(node);\n }\n\n get collapsedNodeList(): T[] {\n return Array.from(this.nodesCollapsed);\n }\n\n /**\n * 折叠元素\n * @param node\n * @param collapsed\n */\n setCollapsed(node: T, collapsed: boolean): void {\n if (collapsed) {\n this.nodesCollapsed.add(node);\n } else {\n this.nodesCollapsed.delete(node);\n }\n this.originTree.fireTreeChange();\n }\n\n /**\n *\n */\n openNodeInsideCollapsed(node: T) {\n // 找到所有的originTree上的parent\n let curr: T | undefined = this.originTree.getInfo(node)?.parent;\n\n while (curr) {\n if (this.nodesCollapsed.has(curr)) {\n this.nodesCollapsed.delete(curr);\n }\n const { parent } = this.originTree.getInfo(curr) || {};\n curr = parent;\n }\n this.originTree.fireTreeChange();\n }\n\n /**\n * 更新结束节点等位置信息,分支里如果全是结束节点则要做相应的偏移\n */\n updateRenderStruct(): void {\n this.map = this.originTree.cloneMap();\n\n // 结束节点位置更新逻辑开关\n if (this.document.config.get(FlowDocumentConfigEnum.END_NODES_REFINE_BRANCH)) {\n this.refineBranch(this.root);\n }\n\n // 节点展开收起\n this.hideCollapsed();\n }\n\n /**\n * 隐藏收起节点\n */\n protected hideCollapsed() {\n this.nodesCollapsed.forEach(collapsedNode => {\n const collapsedNodeInfo = this.getInfo(collapsedNode);\n if (!collapsedNodeInfo) {\n // 自动回收节点数据\n this.nodesCollapsed.delete(collapsedNode);\n return;\n }\n\n const iconChild = collapsedNodeInfo.children.find(\n _child =>\n _child.flowNodeType === FlowNodeBaseType.BLOCK_ICON ||\n _child.flowNodeType === FlowNodeBaseType.BLOCK_ORDER_ICON,\n );\n\n // ⚠️注意:BLOCK_ICON 和 BLOCK_ORDER_ICON 作为一个 block 的标识节点,收起时需要保留\n if (iconChild) {\n const iconInfo = this.getInfo(iconChild);\n iconInfo.next = undefined;\n iconInfo.pre = undefined;\n collapsedNodeInfo.children = [iconChild];\n\n return;\n }\n\n // 收起节点children置为空\n collapsedNodeInfo.children = [];\n });\n }\n\n // 节点是否为结束节点\n isNodeEnd(node: T): boolean {\n if (node.getNodeMeta().isNodeEnd) {\n return true;\n }\n const { children } = this.getInfo(node);\n\n if (children.length > 0 && node.isInlineBlocks) {\n return children.every(child => this.isNodeEnd(child));\n }\n\n if (node.isInlineBlock) {\n return this.isNodeEnd(children[children.length - 1]);\n }\n\n return false;\n }\n\n /**\n * 优化精简分支线\n * - 结束节点拉直分支线\n */\n protected refineBranch(block: T) {\n let curr: T | undefined = this.getInfo(block).children[0];\n\n while (curr) {\n if (\n curr.flowNodeType === FlowNodeSplitType.DYNAMIC_SPLIT ||\n curr.flowNodeType === FlowNodeSplitType.STATIC_SPLIT\n ) {\n const { next, children: branchChildren } = this.getInfo(curr);\n const { children } = this.getInfo(branchChildren[1]);\n\n const passBlocks = (children || []).filter(child => !this.isNodeEnd(child));\n\n const shouldDragAllNextNodes = passBlocks.length === 1;\n if (shouldDragAllNextNodes && next) {\n this.dragNextNodesToBlock(passBlocks[0], next);\n }\n\n // 对每一个分支再进行refineBranch\n children?.forEach(child => {\n this.refineBranch(child);\n });\n\n if (shouldDragAllNextNodes) {\n break;\n }\n }\n\n curr = curr.next as T;\n }\n }\n\n // 结束节点拽分支,将后续节点拽到对应分支内\n protected dragNextNodesToBlock(toBlock: T, next: T) {\n const toBlockInfo = this.getInfo(toBlock);\n const nextInfo = this.getInfo(next);\n const toBlockLastChild = toBlockInfo.children[toBlock.children.length - 1];\n\n if (nextInfo.parent) {\n const nextParentInfo = this.getInfo(nextInfo.parent);\n\n // 1. next的节点和之前的节点断连\n if (nextInfo.pre) {\n this.getInfo(nextInfo.pre).next = undefined;\n }\n\n // 2. next连接到before上\n if (toBlockLastChild) {\n const lastChildInfo = this.getInfo(toBlockLastChild);\n lastChildInfo.next = next;\n nextInfo.pre = toBlockLastChild;\n }\n\n // 3. 获取所有后续节点, 将所有后续节点重新设置parent\n const nextNodeIndex = nextParentInfo.children.indexOf(next);\n const allNextNodes = nextParentInfo.children.slice(nextNodeIndex);\n nextParentInfo.children = nextParentInfo.children.slice(0, nextNodeIndex);\n for (const node of allNextNodes) {\n const nodeInfo = this.getInfo(node);\n toBlockInfo.children.push(node);\n nodeInfo.parent = toBlock;\n }\n }\n }\n\n getInfo(node: T): FlowVirtualTree.NodeInfo<T> {\n const info = this.map.get(node) || this.originTree.getInfo(node);\n return info;\n }\n\n // 或者originTree节点的信息\n getOriginInfo(node: T): FlowVirtualTree.NodeInfo<T> {\n return this.originTree.getInfo(node);\n }\n\n // 获取收起的隐藏节点\n getCollapsedChildren(node: T): T[] {\n return this.getOriginInfo(node).children || [];\n }\n\n remove(): void {\n throw new Error('Render Tree cannot use remove node');\n }\n\n addChild(): T {\n throw new Error('Render tree cannot use add child');\n }\n\n insertAfter(): void {\n throw new Error('Render tree cannot use insert after');\n }\n\n removeParent(): void {\n throw new Error('Render tree cannot use remove parent');\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport {\n type FlowNodeJSON,\n DefaultSpacingKey,\n FlowTransitionLine,\n FlowTransitionLabel,\n FlowNodeRegistry,\n FlowNodeType,\n} from './typings';\nimport { FlowNodeEntity } from './entities';\n\nexport const FlowDocumentOptions = Symbol('FlowDocumentOptions');\n\n/**\n * 流程画布配置\n */\nexport interface FlowDocumentOptions {\n /**\n * 布局,默认 垂直布局\n */\n defaultLayout?: string;\n /**\n * 所有节点的默认展开状态\n */\n allNodesDefaultExpanded?: boolean;\n toNodeJSON?(node: FlowNodeEntity): FlowNodeJSON;\n fromNodeJSON?(node: FlowNodeEntity, json: FlowNodeJSON, isFirstCreate: boolean): void;\n constants?: Record<string, any>;\n formatNodeLines?: (node: FlowNodeEntity, lines: FlowTransitionLine[]) => FlowTransitionLine[];\n formatNodeLabels?: (node: FlowNodeEntity, lines: FlowTransitionLabel[]) => FlowTransitionLabel[];\n preNodeCreate?: (node: FlowNodeEntity) => void;\n /**\n * 获取默认的节点配置\n */\n getNodeDefaultRegistry?: (type: FlowNodeType) => FlowNodeRegistry;\n}\n\nexport const FlowDocumentOptionsDefault: FlowDocumentOptions = {\n allNodesDefaultExpanded: false,\n};\n\n/**\n * 支持外部 constants 自定义的 key 枚举\n */\nexport const ConstantKeys = {\n ...DefaultSpacingKey,\n /**\n * loop 底部留白\n */\n INLINE_SPACING_BOTTOM: 'INLINE_SPACING_BOTTOM',\n /**\n * inlineBlocks 的 inlineTop\n * loop 循环线条上边距\n */\n INLINE_BLOCKS_INLINE_SPACING_TOP: 'INLINE_BLOCKS_INLINE_SPACING_TOP',\n /**\n * inlineBlocks 的 inlineBottom\n * loop 循环线条的下边距\n *\n */\n INLINE_BLOCKS_INLINE_SPACING_BOTTOM: 'INLINE_BLOCKS_INLINE_SPACING_BOTTOM',\n /***\n * 线条、label 默认颜色\n */\n BASE_COLOR: 'BASE_COLOR',\n /***\n * 线条、label 激活后的颜色\n */\n BASE_ACTIVATED_COLOR: 'BASE_ACTIVATED_COLOR',\n /**\n * Branch bottom margin\n * 分支下边距\n */\n INLINE_BLOCKS_PADDING_TOP: 'INLINE_BLOCKS_PADDING_TOP',\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { type FlowDocument } from './flow-document';\n\nexport const FlowDocumentContribution = Symbol('FlowDocumentContribution');\n\nexport interface FlowDocumentContribution<T extends FlowDocument = FlowDocument> {\n /**\n * 注册\n * @param document\n */\n registerDocument?(document: T): void;\n\n /**\n * 加载数据\n * @param document\n */\n loadDocument?(document: T): Promise<void>;\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { inject, injectable, optional } from 'inversify';\nimport { Emitter } from '@flowgram.ai/utils';\n\nexport const FlowDocumentConfigDefaultData = Symbol('FlowDocumentConfigDefaultData');\n\n/**\n * 用于文档扩展配置\n */\n@injectable()\nexport class FlowDocumentConfig {\n private onDataChangeEmitter = new Emitter<string>();\n\n readonly onChange = this.onDataChangeEmitter.event;\n\n constructor(\n @inject(FlowDocumentConfigDefaultData)\n @optional()\n private _data: Record<string, any> = {},\n ) {}\n\n get(key: string): any {\n return this._data[key];\n }\n\n set(key: string, value: any): void {\n if (this.get(key) !== value) {\n this._data[key] = value;\n this.onDataChangeEmitter.fire(key);\n }\n }\n\n registerConfigs(config: Record<string, any>) {\n Object.keys(config).forEach(key => {\n this.set(key, config[key]);\n });\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { ContainerModule } from 'inversify';\n\nimport { FlowOperationBaseService } from './typings/flow-operation';\nimport { FlowDragService } from './services/flow-drag-service';\nimport { FlowGroupService, FlowOperationBaseServiceImpl } from './services';\nimport { HorizontalFixedLayout, VerticalFixedLayout } from './layout';\nimport { FlowDocumentContribution } from './flow-document-contribution';\nimport { FlowDocumentConfig } from './flow-document-config';\nimport { FlowDocument, FlowDocumentProvider } from './flow-document';\n\nexport const FlowDocumentContainerModule = new ContainerModule((bind) => {\n bind(FlowDocument).toSelf().inSingletonScope();\n bind(FlowDocumentProvider)\n .toDynamicValue((ctx) => () => ctx.container.get(FlowDocument))\n .inSingletonScope();\n bind(FlowDocumentConfig).toSelf().inSingletonScope();\n bind(VerticalFixedLayout).toSelf().inSingletonScope();\n bind(HorizontalFixedLayout).toSelf().inSingletonScope();\n bind(FlowDragService).toSelf().inSingletonScope();\n bind(FlowOperationBaseService).to(FlowOperationBaseServiceImpl).inSingletonScope();\n bind(FlowGroupService).toSelf().inSingletonScope();\n bind(FlowDocumentContribution).toDynamicValue((ctx) => ({\n registerDocument: (document: FlowDocument) => {\n document.registerLayout(ctx.container.get(VerticalFixedLayout));\n document.registerLayout(ctx.container.get(HorizontalFixedLayout));\n },\n }));\n});\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { inject, injectable } from 'inversify';\nimport { Emitter } from '@flowgram.ai/utils';\nimport { EntityManager } from '@flowgram.ai/core';\n\nimport { FlowGroupUtils } from './flow-group-service/flow-group-utils';\nimport {\n FlowNodeBaseType,\n FlowNodeJSON,\n FlowOperationBaseService,\n LABEL_SIDE_TYPE,\n} from '../typings';\nimport { FlowDocument } from '../flow-document';\nimport { FlowNodeEntity, FlowRendererStateEntity } from '../entities';\n\n/**\n * 拖拽相关操作\n * 外部实现抽象类\n */\n@injectable()\nexport class FlowDragService {\n @inject(FlowDocument)\n protected document: FlowDocument;\n\n @inject(FlowOperationBaseService)\n protected operationService: FlowOperationBaseService;\n\n @inject(EntityManager)\n protected entityManager: EntityManager;\n\n protected onDropEmitter = new Emitter<{\n dropNode: FlowNodeEntity;\n dragNodes: FlowNodeEntity[];\n dragJSON?: FlowNodeJSON;\n }>();\n\n readonly onDrop = this.onDropEmitter.event;\n\n get renderState(): FlowRendererStateEntity {\n return this.document.renderState;\n }\n\n // 拖拽所有节点中的首个节点\n get dragStartNode(): FlowNodeEntity {\n return this.renderState.getDragStartEntity()!;\n }\n\n // 拖拽的所有节点\n get dragNodes(): FlowNodeEntity[] {\n return this.renderState.getDragEntities();\n }\n\n // 放置的区域\n get dropNodeId(): string | undefined {\n return this.renderState.getNodeDroppingId();\n }\n\n // 是否在拖拽分支\n get isDragBranch(): boolean {\n return this.renderState.isBranch || this.dragStartNode?.isInlineBlock;\n }\n\n // 拖拽的所有节点及其自节点\n get nodeDragIdsWithChildren(): string[] {\n return this.renderState.config.nodeDragIdsWithChildren || [];\n }\n\n get dragging(): boolean {\n return !!this.renderState.dragging;\n }\n\n get labelSide(): LABEL_SIDE_TYPE | undefined {\n return this.renderState.config.dragLabelSide;\n }\n\n /**\n * 放置到目标分支\n */\n dropBranch(): void {\n this.dropNode();\n }\n\n /**\n * 移动并且创建节点\n * Move and create node\n */\n async dropCreateNode(\n json: FlowNodeJSON,\n onCreateNode?: (json: FlowNodeJSON, dropEntity: FlowNodeEntity) => Promise<FlowNodeEntity>\n ) {\n const dropEntity = this.document.getNode(this.dropNodeId!);\n\n if (!dropEntity) {\n return;\n }\n\n if (json) {\n const dragNodes = await onCreateNode?.(json, dropEntity);\n this.onDropEmitter.fire({\n dropNode: dropEntity,\n dragNodes: dragNodes ? [dragNodes] : [],\n dragJSON: json,\n });\n }\n }\n\n /**\n * 移动到目标节点\n */\n dropNode(): void {\n const dropEntity = this.document.getNode(this.dropNodeId!);\n if (!dropEntity) {\n return;\n }\n\n const sortNodes: FlowNodeEntity[] = [];\n let curr: FlowNodeEntity | undefined = this.dragStartNode;\n while (curr && this.dragNodes.includes(curr)) {\n sortNodes.push(curr);\n curr = curr.next;\n }\n\n this.operationService.dragNodes({\n dropNode: dropEntity,\n nodes: sortNodes,\n });\n\n if (sortNodes.length > 0) {\n this.onDropEmitter.fire({\n dropNode: dropEntity,\n dragNodes: sortNodes,\n });\n }\n }\n\n /**\n * 拖拽是否可以释放在该节点后面\n */\n isDroppableNode(node: FlowNodeEntity) {\n // 没有拖拽节点时,所有节点都不可 drop\n if (!this.dragging || this.isDragBranch) {\n return false;\n }\n\n // 当前节点 & 下一个节点是否在拖拽区域\n if (\n this.nodeDragIdsWithChildren.includes(node.id) ||\n (node.next && this.nodeDragIdsWithChildren.includes(node.next.id))\n ) {\n return false;\n }\n\n if (node.isInlineBlocks || node.isInlineBlock) {\n return false;\n }\n\n // 分组节点不能嵌套\n const hasGroupNode = this.dragNodes.some(\n (node) => node.flowNodeType === FlowNodeBaseType.GROUP\n );\n if (hasGroupNode) {\n const group = FlowGroupUtils.getNodeRecursionGroupController(node);\n if (group) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * 拖拽分支是否可以释放在该分支\n * @param node 拖拽的分支节点\n * @param side 分支的前面还是后面\n */\n isDroppableBranch(node: FlowNodeEntity, side: LABEL_SIDE_TYPE = LABEL_SIDE_TYPE.NORMAL_BRANCH) {\n // 外部添加拖拽标识,默认所有分支均可添加\n if (this.renderState.isBranch) {\n return true;\n }\n // 拖拽的是分支\n if (this.isDragBranch) {\n if (\n // 拖拽到分支\n !node.isInlineBlock ||\n // 只能在同一分支条件下\n node.parent !== this.dragStartNode.parent ||\n // 自己不能拖拽给自己\n node === this.dragStartNode\n ) {\n return false;\n }\n\n // 分支的下一个节点不是当前要拖拽的节点\n if (side === LABEL_SIDE_TYPE.NORMAL_BRANCH && node.next !== this.dragStartNode) {\n return true;\n }\n\n // 分支的前一个节点不是当前要拖拽的节点\n if (side === LABEL_SIDE_TYPE.PRE_BRANCH && node.pre !== this.dragStartNode) {\n return true;\n }\n }\n\n return false;\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Rectangle } from '@flowgram.ai/utils';\n\nimport { FlowNodeEntity } from '../../entities';\nimport { FlowNodeRenderData, FlowNodeTransformData } from '../../datas';\nimport { FlowGroupUtils } from './flow-group-utils';\n\n/** 分组控制器 */\nexport class FlowGroupController {\n private constructor(public readonly groupNode: FlowNodeEntity) {}\n\n public get nodes(): FlowNodeEntity[] {\n return this.groupNode.collapsedChildren || [];\n }\n\n public get collapsed(): boolean {\n const groupTransformData = this.groupNode.getData<FlowNodeTransformData>(FlowNodeTransformData);\n return groupTransformData.collapsed;\n }\n\n public collapse(): void {\n this.collapsed = true;\n }\n\n public expand(): void {\n this.collapsed = false;\n }\n\n /** 获取分组外围的最大边框 */\n public get bounds(): Rectangle {\n const groupNodeBounds =\n this.groupNode.getData<FlowNodeTransformData>(FlowNodeTransformData).bounds;\n return groupNodeBounds;\n }\n\n /** 是否是开始节点 */\n public isStartNode(node?: FlowNodeEntity): boolean {\n if (!node) {\n return false;\n }\n const nodes = this.nodes;\n if (!nodes[0]) {\n return false;\n }\n return node.id === nodes[0].id;\n }\n\n /** 是否是结束节点 */\n public isEndNode(node?: FlowNodeEntity): boolean {\n if (!node) {\n return false;\n }\n const nodes = this.nodes;\n if (!nodes[nodes.length - 1]) {\n return false;\n }\n return node.id === nodes[nodes.length - 1].id;\n }\n\n public set note(note: string) {\n this.groupNode.getNodeMeta().note = note;\n }\n\n public get note(): string {\n return this.groupNode.getNodeMeta().note || '';\n }\n\n public set noteHeight(height: number) {\n this.groupNode.getNodeMeta().noteHeight = height;\n }\n\n public get noteHeight(): number {\n return this.groupNode.getNodeMeta().noteHeight || 0;\n }\n\n public get positionConfig(): Record<string, number> {\n return this.groupNode.getNodeMeta().positionConfig;\n }\n\n private set collapsed(collapsed: boolean) {\n const groupTransformData = this.groupNode.getData<FlowNodeTransformData>(FlowNodeTransformData);\n groupTransformData.collapsed = collapsed;\n groupTransformData.localDirty = true;\n if (groupTransformData.parent) groupTransformData.parent.localDirty = true;\n if (groupTransformData.parent?.firstChild)\n groupTransformData.parent.firstChild.localDirty = true;\n }\n\n public set hovered(hovered: boolean) {\n const groupRenderData = this.groupNode.getData<FlowNodeRenderData>(FlowNodeRenderData);\n if (hovered) {\n groupRenderData.toggleMouseEnter();\n } else {\n groupRenderData.toggleMouseLeave();\n }\n if (groupRenderData.hovered === hovered) {\n return;\n }\n groupRenderData.hovered = hovered;\n }\n\n public get hovered(): boolean {\n const groupRenderData = this.groupNode.getData<FlowNodeRenderData>(FlowNodeRenderData);\n return groupRenderData.hovered;\n }\n\n public static create(groupNode?: FlowNodeEntity): FlowGroupController | undefined {\n if (!groupNode) {\n return;\n }\n if (!FlowGroupUtils.isGroupNode(groupNode)) {\n return;\n }\n return new FlowGroupController(groupNode);\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { FlowNodeBaseType } from '../../typings';\nimport { FlowNodeEntity } from '../../entities';\nimport { FlowGroupController } from './flow-group-controller';\n\nexport namespace FlowGroupUtils {\n /** 找到节点所有上级 */\n const findNodeParents = (node: FlowNodeEntity): FlowNodeEntity[] => {\n const parents = [];\n let parent = node.parent;\n while (parent) {\n parents.push(parent);\n parent = parent.parent;\n }\n return parents;\n };\n\n /** 节点是否处于分组中 */\n const isNodeInGroup = (node: FlowNodeEntity): boolean => {\n // 处于分组中\n if (node?.parent?.flowNodeType === FlowNodeBaseType.GROUP) {\n return true;\n }\n return false;\n };\n\n /** 判断节点能否组成分组 */\n export const validate = (nodes: FlowNodeEntity[]): boolean => {\n if (!nodes || !Array.isArray(nodes) || nodes.length === 0) {\n // 参数不合法\n return false;\n }\n\n // 判断是否有分组节点\n const isGroupRelatedNode = nodes.some((node) => isGroupNode(node));\n if (isGroupRelatedNode) return false;\n\n // 判断是否有节点已经处于分组中\n const hasGroup = nodes.some((node) => node && isNodeInGroup(node));\n if (hasGroup) return false;\n\n // 判断是否来自同一个父亲\n const parent = nodes[0].parent;\n const isSameParent = nodes.every((node) => node.parent === parent);\n if (!isSameParent) return false;\n\n // 判断节点索引是否连续\n const indexes = nodes.map((node) => node.index).sort((a, b) => a - b);\n const isIndexContinuous = indexes.every((index, i, arr) => {\n if (i === 0) {\n return true;\n }\n return index === arr[i - 1] + 1;\n });\n if (!isIndexContinuous) return false;\n\n // 判断节点父亲是否已经在分组中\n const parents = findNodeParents(nodes[0]);\n const parentsInGroup = parents.some((parent) => isNodeInGroup(parent));\n if (parentsInGroup) return false;\n\n // 参数正确\n return true;\n };\n\n /** 获取节点分组控制 */\n export const getNodeGroupController = (\n node?: FlowNodeEntity\n ): FlowGroupController | undefined => {\n if (!node) {\n return;\n }\n if (!isNodeInGroup(node)) {\n return;\n }\n const groupNode = node?.parent;\n return FlowGroupController.create(groupNode);\n };\n\n /** 向上递归查找分组递归控制 */\n export const getNodeRecursionGroupController = (\n node?: FlowNodeEntity\n ): FlowGroupController | undefined => {\n if (!node) {\n return;\n }\n const group = getNodeGroupController(node);\n if (group) {\n return group;\n }\n if (node.parent) {\n return getNodeRecursionGroupController(node.parent);\n }\n return;\n };\n\n /** 是否分组节点 */\n export const isGroupNode = (group: FlowNodeEntity): boolean =>\n group.flowNodeType === FlowNodeBaseType.GROUP;\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { inject, injectable, postConstruct } from 'inversify';\nimport { DisposableCollection, Emitter } from '@flowgram.ai/utils';\nimport { EntityManager } from '@flowgram.ai/core';\n\nimport {\n FlowOperation,\n FlowOperationBaseService,\n MoveChildNodesOperationValue,\n OperationType,\n} from '../typings/flow-operation';\nimport {\n AddBlockConfig,\n AddNodeConfig,\n AddNodeData,\n FlowNodeBaseType,\n FlowNodeEntityOrId,\n FlowNodeJSON,\n MoveNodeConfig,\n OnNodeAddEvent,\n OnNodeMoveEvent,\n} from '../typings';\nimport { FlowDocument } from '../flow-document';\nimport { FlowNodeEntity } from '../entities';\n\n/**\n * 操作服务\n */\n@injectable()\nexport class FlowOperationBaseServiceImpl implements FlowOperationBaseService {\n @inject(EntityManager)\n protected entityManager: EntityManager;\n\n @inject(FlowDocument)\n protected document: FlowDocument;\n\n protected onNodeAddEmitter = new Emitter<OnNodeAddEvent>();\n\n readonly onNodeAdd = this.onNodeAddEmitter.event;\n\n protected toDispose = new DisposableCollection();\n\n private onNodeMoveEmitter = new Emitter<OnNodeMoveEvent>();\n\n readonly onNodeMove = this.onNodeMoveEmitter.event;\n\n @postConstruct()\n protected init() {\n this.toDispose.pushAll([this.onNodeAddEmitter, this.onNodeMoveEmitter]);\n }\n\n addNode(nodeJSON: FlowNodeJSON, config: AddNodeConfig = {}): FlowNodeEntity {\n const { parent, index, hidden } = config;\n let parentEntity;\n\n if (parent) {\n parentEntity = this.toNodeEntity(parent);\n }\n\n let register;\n if (parentEntity) {\n register = parentEntity.getNodeRegistry();\n }\n\n const addJSON = {\n ...nodeJSON,\n type: nodeJSON.type || FlowNodeBaseType.BLOCK,\n };\n\n const addNodeData: AddNodeData = {\n ...addJSON,\n parent: parentEntity,\n index,\n hidden,\n };\n\n let added;\n if (parentEntity && register?.addChild) {\n added = register.addChild(parentEntity, addJSON, {\n index,\n hidden,\n });\n } else {\n added = this.document.addNode(addNodeData);\n }\n\n this.onNodeAddEmitter.fire({\n node: added,\n data: addNodeData,\n });\n\n return added;\n }\n\n addFromNode(fromNode: FlowNodeEntityOrId, nodeJSON: FlowNodeJSON): FlowNodeEntity {\n return this.document.addFromNode(fromNode, nodeJSON);\n }\n\n deleteNode(node: FlowNodeEntityOrId): void {\n this.document.removeNode(node);\n }\n\n deleteNodes(nodes: FlowNodeEntityOrId[]): void {\n (nodes || []).forEach((node) => {\n this.deleteNode(node);\n });\n }\n\n addBlock(\n target: FlowNodeEntityOrId,\n blockJSON: FlowNodeJSON,\n config: AddBlockConfig = {}\n ): FlowNodeEntity {\n const { parent, index } = config;\n return this.document.addBlock(target, blockJSON, undefined, parent, index);\n }\n\n moveNode(node: FlowNodeEntityOrId, config: MoveNodeConfig = {}) {\n const { parent: newParent, index } = config;\n const entity = this.toNodeEntity(node);\n const parent = entity?.parent;\n\n if (!parent) {\n return;\n }\n\n const newParentEntity: FlowNodeEntity | undefined = newParent\n ? this.toNodeEntity(newParent)\n : parent;\n\n if (!newParentEntity) {\n console.warn('no new parent found', newParent);\n return;\n }\n\n let toIndex = typeof index === 'undefined' ? newParentEntity.collapsedChildren.length : index;\n\n return this.doMoveNode(entity, newParentEntity, toIndex);\n }\n\n /**\n * 拖拽节点\n * @param param0\n * @returns\n */\n dragNodes({ dropNode, nodes }: { dropNode: FlowNodeEntity; nodes: FlowNodeEntity[] }) {\n if (nodes.length === 0) {\n return;\n }\n\n const startNode = nodes[0];\n const fromParent = startNode.parent;\n const toParent = dropNode.parent;\n\n if (!fromParent || !toParent) {\n return;\n }\n\n const fromIndex = fromParent.children.findIndex((child) => child === startNode);\n const dropIndex = toParent.children.findIndex((child) => child === dropNode);\n\n let toIndex = dropIndex + 1;\n // 同父级节点移动,处理脏路径\n if (fromParent === toParent && fromIndex < dropIndex) {\n toIndex = toIndex - nodes.length;\n }\n\n const value: MoveChildNodesOperationValue = {\n nodeIds: nodes.map((node) => node.id),\n fromParentId: fromParent.id,\n toParentId: toParent.id,\n fromIndex,\n toIndex,\n };\n\n return this.apply({\n type: OperationType.moveChildNodes,\n value,\n });\n }\n\n /**\n * 执行操作\n * @param operation 可序列化的操作\n * @returns 操作返回\n */\n apply(operation: FlowOperation): any {\n const document = this.document;\n switch (operation.type) {\n case OperationType.addFromNode:\n return document.addFromNode(operation.value.fromId, operation.value.data);\n case OperationType.deleteFromNode:\n return document.getNode(operation.value?.data?.id)?.dispose();\n case OperationType.addBlock: {\n let parent;\n\n if (operation.value.parentId) {\n parent = document.getNode(operation.value.parentId);\n }\n return document.addBlock(\n operation.value.targetId,\n operation.value.blockData,\n undefined,\n parent,\n operation.value.index\n );\n }\n case OperationType.deleteBlock: {\n const entity = document.getNode(operation.value?.blockData.id);\n return entity?.dispose();\n }\n case OperationType.createGroup: {\n const groupNode = document.addFromNode(operation.value.targetId, {\n id: operation.value.groupId,\n type: FlowNodeBaseType.GROUP,\n });\n document.moveNodes({\n dropNodeId: operation.value.groupId,\n sortNodeIds: operation.value.nodeIds,\n inside: true,\n });\n return groupNode;\n }\n case OperationType.ungroup: {\n document.moveNodes({\n dropNodeId: operation.value.groupId,\n sortNodeIds: operation.value.nodeIds,\n });\n return document.getNode(operation.value.groupId)?.dispose();\n }\n case OperationType.moveNodes: {\n return document.moveNodes({\n dropNodeId: operation.value.toId,\n sortNodeIds: operation.value.nodeIds,\n });\n }\n case OperationType.moveBlock: {\n return document.moveChildNodes({\n ...operation.value,\n nodeIds: [operation.value.nodeId],\n });\n }\n case OperationType.addNodes: {\n let fromId = operation.value.fromId;\n (operation.value.nodes || []).forEach((node) => {\n const added = document.addFromNode(fromId, node);\n fromId = added.id;\n });\n break;\n }\n case OperationType.deleteNodes: {\n (operation.value.nodes || []).forEach((node) => {\n const entity = document.getNode(node.id);\n entity?.dispose();\n });\n break;\n }\n case OperationType.addChildNode: {\n return document.addNode({\n ...operation.value.data,\n parent: operation.value.parentId ? document.getNode(operation.value.parentId) : undefined,\n originParent: operation.value.originParentId\n ? document.getNode(operation.value.originParentId)\n : undefined,\n index: operation.value.index,\n hidden: operation.value.hidden,\n });\n }\n case OperationType.deleteChildNode:\n return document.getNode(operation.value.data.id)?.dispose();\n case OperationType.moveChildNodes:\n return document.moveChildNodes(operation.value);\n default:\n throw new Error(`unknown operation type`);\n }\n }\n\n /**\n * 事务执行\n * @param transaction\n */\n transact(transaction: () => void) {\n transaction();\n }\n\n dispose() {\n this.toDispose.dispose();\n }\n\n protected toId(node: FlowNodeEntityOrId): string {\n return typeof node === 'string' ? node : node.id;\n }\n\n protected toNodeEntity(node: FlowNodeEntityOrId): FlowNodeEntity | undefined {\n return typeof node === 'string' ? this.document.getNode(node) : node;\n }\n\n protected getNodeIndex(node: FlowNodeEntityOrId): number {\n const entity = this.toNodeEntity(node);\n const parent = entity?.parent;\n\n if (!parent) {\n return -1;\n }\n\n return parent.children.findIndex((child) => child === entity);\n }\n\n protected doMoveNode(node: FlowNodeEntity, newParent: FlowNodeEntity, index: number) {\n if (!node.parent) {\n throw new Error('root node cannot move');\n }\n\n const event: OnNodeMoveEvent = {\n node,\n fromParent: node.parent,\n toParent: newParent,\n fromIndex: this.getNodeIndex(node),\n toIndex: index,\n };\n\n this.document.moveChildNodes({\n nodeIds: [this.toId(node)],\n toParentId: this.toId(newParent),\n toIndex: index,\n });\n this.onNodeMoveEmitter.fire(event);\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { nanoid } from 'nanoid';\nimport { inject, injectable } from 'inversify';\nimport { EntityManager } from '@flowgram.ai/core';\n\nimport { FlowNodeBaseType, FlowOperationBaseService, OperationType } from '../../typings';\nimport { FlowNodeEntity } from '../../entities';\nimport { FlowGroupUtils } from './flow-group-utils';\nimport { FlowGroupController } from './flow-group-controller';\n\n@injectable()\n/** 分组服务 */\nexport class FlowGroupService {\n @inject(EntityManager) public readonly entityManager: EntityManager;\n\n @inject(FlowOperationBaseService)\n public readonly operationService: FlowOperationBaseService;\n\n /** 创建分组节点 */\n public createGroup(nodes: FlowNodeEntity[]): FlowNodeEntity | undefined {\n if (!nodes || !Array.isArray(nodes) || nodes.length === 0) {\n return;\n }\n if (!FlowGroupUtils.validate(nodes)) {\n return;\n }\n const sortedNodes: FlowNodeEntity[] = nodes.sort((a, b) => a.index - b.index);\n const fromNode = sortedNodes[0];\n const groupId = `group_${nanoid(5)}`;\n this.operationService.apply({\n type: OperationType.createGroup,\n value: {\n targetId: fromNode.id,\n groupId,\n nodeIds: nodes.map((node) => node.id),\n },\n });\n const groupNode = this.entityManager.getEntityById<FlowNodeEntity>(groupId);\n if (!groupNode) {\n return;\n }\n const group = this.groupController(groupNode);\n if (!group) {\n return;\n }\n group.expand();\n return groupNode;\n }\n\n /** 删除分组 */\n public deleteGroup(groupNode: FlowNodeEntity): void {\n const json = groupNode.toJSON();\n if (!groupNode.pre || !json) {\n return;\n }\n this.operationService.apply({\n type: OperationType.deleteNodes,\n value: {\n fromId: groupNode.pre.id,\n nodes: [json],\n },\n });\n }\n\n /** 取消分组 */\n public ungroup(groupNode: FlowNodeEntity): void {\n const group = this.groupController(groupNode);\n if (!group) {\n return;\n }\n const nodes = group.nodes;\n if (!groupNode.pre) {\n return;\n }\n group.collapse();\n this.operationService.apply({\n type: OperationType.ungroup,\n value: {\n groupId: groupNode.id,\n targetId: groupNode.pre.id,\n nodeIds: nodes.map((node) => node.id),\n },\n });\n }\n\n /** 返回所有分组节点 */\n public getAllGroups(): FlowGroupController[] {\n const allNodes = this.entityManager.getEntities<FlowNodeEntity>(FlowNodeEntity);\n const groupNodes = allNodes.filter((node) => node.flowNodeType === FlowNodeBaseType.GROUP);\n return groupNodes\n .map((node) => this.groupController(node))\n .filter(Boolean) as FlowGroupController[];\n }\n\n /** 获取分组控制器*/\n public groupController(group: FlowNodeEntity): FlowGroupController | undefined {\n return FlowGroupController.create(group);\n }\n\n public static validate(nodes: FlowNodeEntity[]): boolean {\n return FlowGroupUtils.validate(nodes);\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { injectable, inject, multiInject, optional } from 'inversify';\nimport { IPoint, OriginSchema, PaddingSchema, ScrollSchema, SizeSchema } from '@flowgram.ai/utils';\n\nimport { type FlowLayout, FlowLayoutDefault, FlowLayoutContribution } from '../typings';\nimport { type FlowDocument, FlowDocumentProvider } from '../flow-document';\nimport { FlowNodeEntity } from '../entities';\nimport { FlowNodeTransformData } from '../datas';\n\n// 开始节点距离上边 36 像素\nconst DEFAULT_SCROLL = -36;\n\n/**\n * 用于描述节点的结构特征\n */\ninterface FlowNodeTransformStructData {\n childrenLength: number;\n index: number;\n}\n/**\n * 用于描述节点的结构特征\n */\ninterface FlowNodeTransformStructData {\n childrenLength: number;\n index: number;\n}\n\nfunction isStructDataEqual(\n struct1: FlowNodeTransformStructData,\n struct2: FlowNodeTransformStructData\n): boolean {\n return struct1.childrenLength === struct2.childrenLength && struct1.index === struct2.index;\n}\n\n@injectable()\nexport class VerticalFixedLayout implements FlowLayout {\n name = FlowLayoutDefault.VERTICAL_FIXED_LAYOUT;\n\n protected structDataMap = new WeakMap<FlowNodeEntity, FlowNodeTransformStructData>();\n\n @inject(FlowDocumentProvider) protected documentProvider: FlowDocumentProvider;\n\n @multiInject(FlowLayoutContribution)\n @optional()\n contribs?: FlowLayoutContribution[];\n\n get document(): FlowDocument {\n return this.documentProvider();\n }\n\n reload() {\n this.structDataMap = new WeakMap();\n }\n\n /**\n * 更新布局\n */\n update(): void {\n this.updateLocalTransform(this.document.root);\n }\n\n /**\n * 更新节点的偏移\n * @param node\n * @param forceChange\n */\n updateLocalTransform(node: FlowNodeEntity, forceChange = false): boolean {\n const { children, parent, isInlineBlock } = node;\n\n const transform = node.getData<FlowNodeTransformData>(FlowNodeTransformData);\n const { getDelta, getOrigin } = node.getNodeRegistry();\n const lastStructData = this.structDataMap.get(node) || {\n childrenLength: 0,\n index: -1,\n };\n // 重新计算都要清空 bounds 缓存,因为 bounds 依赖所有\n node.clearMemoGlobal();\n let localDirty = transform.localDirty || forceChange;\n const newStructData: FlowNodeTransformStructData = {\n index: node.index,\n childrenLength: node.children.length,\n };\n // index 变化也要重新计算\n if (!isStructDataEqual(lastStructData, newStructData)) {\n localDirty = true;\n this.structDataMap.set(node, newStructData);\n }\n // Step1: 计算子节点\n let siblingDirty = false;\n if (children.length > 0) {\n for (const child of children) {\n const childDirty = this.updateLocalTransform(child, siblingDirty);\n // 子节点变更则父节点跟着变更\n if (childDirty) {\n siblingDirty = true;\n localDirty = true;\n }\n }\n }\n // 如果没有变更则不执行\n if (!localDirty) return false;\n // Step2: 计算节点的 position 偏移量\n node.clearMemoLocal();\n transform.transform.update({\n origin: getOrigin ? getOrigin(transform, this) : this.getDefaultNodeOrigin(),\n });\n const preTransform = transform.pre;\n const delta = getDelta?.(transform, this) || { x: 0, y: 0 };\n const inlineSpacingPre =\n isInlineBlock && transform.parent?.inlineSpacingPre ? transform.parent?.inlineSpacingPre : 0;\n const fromParentDelta = parent?.getNodeRegistry().getChildDelta?.(transform, this) || {\n x: 0,\n y: 0,\n };\n delta.x += fromParentDelta.x;\n delta.y += fromParentDelta.y;\n\n // Step3:根据上一个节点的相对偏移算当前偏移\n const position = { x: delta.x, y: delta.y };\n // 垂直布局\n if (isInlineBlock) {\n position.y += inlineSpacingPre;\n } else {\n position.y += preTransform?.localBounds.bottom || 0;\n position.y += preTransform?.spacing || 0;\n }\n\n transform.transform.update({\n size: transform.data.size,\n position,\n });\n\n // 布局结束后可执行额外逻辑\n this.onAfterUpdateLocalTransform(transform);\n\n transform.localDirty = false;\n\n return true;\n }\n\n onAfterUpdateLocalTransform(transform: FlowNodeTransformData) {\n // 执行 register 上的 onAfterUpdateLocalTransform\n const { onAfterUpdateLocalTransform } = transform.entity.getNodeRegistry();\n onAfterUpdateLocalTransform?.(transform, this);\n\n // 执行 contribution 上的 onAfterUpdateLocalTransform\n this.contribs?.forEach((_contrib) => {\n _contrib?.onAfterUpdateLocalTransform?.(transform, this);\n });\n }\n\n getNodeTransform(node: FlowNodeEntity): FlowNodeTransformData {\n return node.getData(FlowNodeTransformData)!;\n }\n\n getPadding(node: FlowNodeEntity): PaddingSchema {\n const { inlineSpacingPre, inlineSpacingAfter, padding } = node.getNodeMeta();\n const transform = this.getNodeTransform(node);\n if (padding) {\n return typeof padding === 'function' ? padding(transform) : padding;\n }\n\n const paddingPre =\n typeof inlineSpacingPre === 'function' ? inlineSpacingPre(transform) : inlineSpacingPre;\n const paddingAfter =\n typeof inlineSpacingAfter === 'function' ? inlineSpacingAfter(transform) : inlineSpacingAfter;\n\n return {\n left: 0,\n top: paddingPre,\n right: 0,\n bottom: paddingAfter,\n };\n }\n\n getInitScroll(contentSize: SizeSchema): ScrollSchema {\n return {\n scrollX: -contentSize.width / 2,\n scrollY: DEFAULT_SCROLL,\n };\n }\n\n getDefaultInputPoint(node: FlowNodeEntity): IPoint {\n return this.getNodeTransform(node).bounds.topCenter;\n }\n\n getDefaultOutputPoint(node: FlowNodeEntity): IPoint {\n return this.getNodeTransform(node).bounds.bottomCenter;\n }\n\n getDefaultNodeOrigin(): OriginSchema {\n return { x: 0.5, y: 0 };\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { injectable, inject, multiInject, optional } from 'inversify';\nimport { IPoint, OriginSchema, PaddingSchema, ScrollSchema, SizeSchema } from '@flowgram.ai/utils';\n\nimport { type FlowLayout, FlowLayoutDefault, FlowLayoutContribution } from '../typings';\nimport { type FlowDocument, FlowDocumentProvider } from '../flow-document';\nimport { FlowNodeEntity } from '../entities';\nimport { FlowNodeTransformData } from '../datas';\n\n// 开始节点距离上边 36 像素\nconst DEFAULT_SCROLL = -36;\n\n/**\n * 用于描述节点的结构特征\n */\ninterface FlowNodeTransformStructData {\n childrenLength: number;\n index: number;\n}\n/**\n * 用于描述节点的结构特征\n */\ninterface FlowNodeTransformStructData {\n childrenLength: number;\n index: number;\n}\n\nfunction isStructDataEqual(\n struct1: FlowNodeTransformStructData,\n struct2: FlowNodeTransformStructData\n): boolean {\n return struct1.childrenLength === struct2.childrenLength && struct1.index === struct2.index;\n}\n\n@injectable()\nexport class HorizontalFixedLayout implements FlowLayout {\n name = FlowLayoutDefault.HORIZONTAL_FIXED_LAYOUT;\n\n protected structDataMap = new WeakMap<FlowNodeEntity, FlowNodeTransformStructData>();\n\n @inject(FlowDocumentProvider) protected documentProvider: FlowDocumentProvider;\n\n @multiInject(FlowLayoutContribution)\n @optional()\n contribs?: FlowLayoutContribution[];\n\n get document(): FlowDocument {\n return this.documentProvider();\n }\n\n reload() {\n this.structDataMap = new WeakMap();\n }\n\n /**\n * 更新布局\n */\n update(): void {\n this.updateLocalTransform(this.document.root);\n }\n\n /**\n * 更新节点的偏移\n * @param node\n * @param forceChange\n */\n updateLocalTransform(node: FlowNodeEntity, forceChange = false): boolean {\n const { children, parent, isInlineBlock } = node;\n\n const transform = node.getData<FlowNodeTransformData>(FlowNodeTransformData);\n const { getDelta, getOrigin } = node.getNodeRegistry();\n const lastStructData = this.structDataMap.get(node) || {\n childrenLength: 0,\n index: -1,\n };\n // 重新计算都要清空 bounds 缓存,因为 bounds 依赖所有\n node.clearMemoGlobal();\n let localDirty = transform.localDirty || forceChange;\n const newStructData: FlowNodeTransformStructData = {\n index: node.index,\n childrenLength: node.children.length,\n };\n // index 变化也要重新计算\n if (!isStructDataEqual(lastStructData, newStructData)) {\n localDirty = true;\n this.structDataMap.set(node, newStructData);\n }\n // Step1: 计算子节点\n let siblingDirty = false;\n if (children.length > 0) {\n for (const child of children) {\n const childDirty = this.updateLocalTransform(child, siblingDirty);\n // 子节点变更则父节点跟着变更\n if (childDirty) {\n siblingDirty = true;\n localDirty = true;\n }\n }\n }\n // 如果没有变更则不执行\n if (!localDirty) return false;\n // Step2: 计算节点的 position 偏移量\n node.clearMemoLocal();\n transform.transform.update({\n origin: getOrigin ? getOrigin(transform, this) : this.getDefaultNodeOrigin(),\n });\n const preTransform = transform.pre;\n const delta = getDelta?.(transform, this) || { x: 0, y: 0 };\n const inlineSpacingPre =\n isInlineBlock && transform.parent?.inlineSpacingPre ? transform.parent?.inlineSpacingPre : 0;\n const fromParentDelta = parent?.getNodeRegistry().getChildDelta?.(transform, this) || {\n x: 0,\n y: 0,\n };\n delta.x += fromParentDelta.x;\n delta.y += fromParentDelta.y;\n\n // Step3:根据上一个节点的相对偏移算当前偏移\n const position = { x: delta.x, y: delta.y };\n // 水平布局\n if (isInlineBlock) {\n position.x += inlineSpacingPre;\n } else {\n position.x += preTransform?.localBounds.right || 0;\n position.x += preTransform?.spacing || 0;\n }\n\n transform.transform.update({\n size: transform.data.size,\n position,\n });\n\n // 布局结束后可执行额外逻辑\n this.onAfterUpdateLocalTransform(transform);\n\n transform.localDirty = false;\n\n return true;\n }\n\n onAfterUpdateLocalTransform(transform: FlowNodeTransformData) {\n // 执行 register 上的 onAfterUpdateLocalTransform\n const { onAfterUpdateLocalTransform } = transform.entity.getNodeRegistry();\n onAfterUpdateLocalTransform?.(transform, this);\n\n // 执行 contribution 上的 onAfterUpdateLocalTransform\n this.contribs?.forEach((_contrib) => {\n _contrib?.onAfterUpdateLocalTransform?.(transform, this);\n });\n }\n\n getNodeTransform(node: FlowNodeEntity): FlowNodeTransformData {\n return node.getData(FlowNodeTransformData)!;\n }\n\n getPadding(node: FlowNodeEntity): PaddingSchema {\n const { inlineSpacingPre, inlineSpacingAfter, padding } = node.getNodeMeta();\n const transform = this.getNodeTransform(node);\n if (padding) {\n return typeof padding === 'function' ? padding(transform) : padding;\n }\n\n const paddingPre =\n typeof inlineSpacingPre === 'function' ? inlineSpacingPre(transform) : inlineSpacingPre;\n const paddingAfter =\n typeof inlineSpacingAfter === 'function' ? inlineSpacingAfter(transform) : inlineSpacingAfter;\n\n return {\n left: paddingPre,\n top: 0,\n right: paddingAfter,\n bottom: 0,\n };\n }\n\n getInitScroll(contentSize: SizeSchema): ScrollSchema {\n return {\n scrollX: DEFAULT_SCROLL,\n scrollY: -contentSize.height / 2,\n };\n }\n\n getDefaultInputPoint(node: FlowNodeEntity): IPoint {\n return this.getNodeTransform(node).bounds.leftCenter;\n }\n\n getDefaultOutputPoint(node: FlowNodeEntity): IPoint {\n return this.getNodeTransform(node).bounds.rightCenter;\n }\n\n getDefaultNodeOrigin(): OriginSchema {\n return { x: 0, y: 0.5 };\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { DEFAULT_SPACING } from '../typings';\nimport { FlowDocumentOptions } from '../flow-document-options';\nimport { FlowNodeEntity } from '../entities/flow-node-entity';\n\n/**\n *\n * @param node 节点 entity\n * @param key 从 DocumentOptions 里获取 constants 的 key\n * @param defaultSpacing 默认从 DEFAULT_SPACING 获取 spacing,也可以外部传入默认值\n * @returns\n */\nexport const getDefaultSpacing = (node: FlowNodeEntity, key: string, defaultSpacing?: number) => {\n const flowDocumentOptions = node.getService<FlowDocumentOptions>(FlowDocumentOptions);\n const spacing = flowDocumentOptions?.constants?.[key] || defaultSpacing || DEFAULT_SPACING[key];\n return spacing;\n};\n"],"mappings":"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","names":["FlowNodeBaseType","FlowNodeSplitType","FlowDocumentConfigEnum","FlowLayoutDefault","FlowTransitionLineEnum","FlowTransitionLabelEnum","DRAGGING_TYPE","LABEL_SIDE_TYPE","FlowNodeRegistry","OperationType","Disposable","EntityData","EntityData","Disposable","EntityData","EntityData","FlowNodeEntity","Emitter","Emitter","ConfigEntity","inject","injectable","optional","Emitter","Emitter","Emitter","Emitter","Emitter","layout","node","inject","optional","injectable","inject","injectable","Emitter","EntityManager","FlowGroupUtils","parent","Emitter","node","inject","EntityManager","injectable","inject","injectable","postConstruct","Emitter","EntityManager","Emitter","inject","EntityManager","postConstruct","injectable","inject","injectable","EntityManager","inject","EntityManager","injectable","injectable","inject","multiInject","optional","inject","multiInject","optional","injectable","injectable","inject","multiInject","optional","DEFAULT_SCROLL","isStructDataEqual","inject","multiInject","optional","injectable"]}
1
+ {"version":3,"sources":["../../src/typings/flow.ts","../../src/typings/flow-layout.ts","../../src/typings/flow-transition.ts","../../src/typings/flow-node-register.ts","../../src/typings/flow-operation.ts","../../src/entities/flow-node-entity.ts","../../src/datas/flow-node-transform-data.ts","../../src/datas/flow-node-render-data.ts","../../src/datas/flow-node-transition-data.ts","../../src/entities/flow-document-transformer-entity.ts","../../src/entities/flow-renderer-state-entity.ts","../../src/flow-document.ts","../../src/flow-virtual-tree.ts","../../src/flow-render-tree.ts","../../src/flow-document-options.ts","../../src/flow-document-contribution.ts","../../src/flow-document-config.ts","../../src/flow-document-container-module.ts","../../src/services/flow-drag-service.ts","../../src/services/flow-group-service/flow-group-controller.ts","../../src/services/flow-group-service/flow-group-utils.ts","../../src/services/flow-operation-base-service.ts","../../src/services/flow-group-service/flow-group-service.ts","../../src/layout/vertical-fixed-layout.ts","../../src/layout/horizontal-fixed-layout.ts","../../src/utils/get-default-spacing.ts"],"sourcesContent":["/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { FlowNodeEntity } from '../entities';\nimport { type FlowNodeMeta } from './flow-node-register';\n\nexport type FlowNodeType = string | number;\n\n/**\n * Flow node json data\n */\nexport interface FlowNodeJSON {\n id: string;\n type?: FlowNodeBaseType | FlowNodeSplitType | FlowNodeType; // 如果缺省 则 为 block\n data?: Record<string, any>; // 节点额外扩展的内容\n meta?: FlowNodeMeta;\n blocks?: FlowNodeJSON[]; // 子节点\n}\n\nexport type FlowDocumentJSON = {\n nodes: FlowNodeJSON[];\n};\n\nexport enum FlowNodeBaseType {\n START = 'start', // 开始节点\n DEFAULT = 'default', // 默认节点类型\n ROOT = 'root', // 根节点\n EMPTY = 'empty', // 空节点,宽和高为 0\n INLINE_BLOCKS = 'inlineBlocks', // 所有块合并为 InlineBlocks\n BLOCK_ICON = 'blockIcon', // 图标节点,如条件分支的头部的 菱形图标\n BLOCK = 'block', // 块节点\n BLOCK_ORDER_ICON = 'blockOrderIcon', // 带顺序的图标节点,一般为 block 第一个分支节点\n GROUP = 'group', // 分组节点\n END = 'end', // 结束节点\n BREAK = 'break', // 分支结束\n CONDITION = 'condition', // 可以连接多条线的条件判断节点,目前只支持横向布局\n SUB_CANVAS = 'subCanvas', // 自由布局子画布\n MULTI_INPUTS = 'multiInputs', // 多输入\n MULTI_OUTPUTS = 'multiOutputs', // 多输出\n INPUT = 'input', // 输入节点\n OUTPUT = 'output', // 输出节点\n SLOT = 'slot', // 插槽节点\n SLOT_BLOCK = 'slotBlock', // 插槽子节点\n}\n\nexport enum FlowNodeSplitType {\n SIMPLE_SPLIT = 'simpleSplit', // 无 BlockOrderIcon\n DYNAMIC_SPLIT = 'dynamicSplit', // 动态分支\n STATIC_SPLIT = 'staticSplit', // 静态分支\n}\n\nexport enum FlowDocumentConfigEnum {\n // 结束节点拖拽分支逻辑\n END_NODES_REFINE_BRANCH = 'END_NODES_REFINE_BRANCH',\n}\n\nexport const FLOW_DEFAULT_HIDDEN_TYPES: FlowNodeType[] = [\n FlowNodeBaseType.ROOT,\n FlowNodeBaseType.INLINE_BLOCKS,\n FlowNodeBaseType.BLOCK,\n];\n\nexport type AddNodeData = FlowNodeJSON & {\n originParent?: FlowNodeEntity;\n parent?: FlowNodeEntity;\n hidden?: boolean;\n index?: number;\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { IPoint, PaddingSchema, ScrollSchema, SizeSchema } from '@flowgram.ai/utils';\n\nimport { type FlowNodeEntity } from '../entities';\nimport { type FlowNodeTransformData } from '../datas';\n\nexport const FlowLayout = Symbol('FlowLayout');\nexport const FlowLayoutContribution = Symbol('FlowLayoutContribution');\n\nexport enum FlowLayoutDefault {\n VERTICAL_FIXED_LAYOUT = 'vertical-fixed-layout', // 垂直固定布局\n HORIZONTAL_FIXED_LAYOUT = 'horizontal-fixed-layout', // 水平固定布局\n}\n\nexport namespace FlowLayoutDefault {\n export function isVertical(layout: FlowLayout): boolean {\n return layout.name === FlowLayoutDefault.VERTICAL_FIXED_LAYOUT;\n }\n}\n\nexport interface FlowLayoutContribution {\n onAfterUpdateLocalTransform?: (transform: FlowNodeTransformData, layout: FlowLayout) => void;\n}\n\n/**\n * 流程布局算法\n */\nexport interface FlowLayout {\n /**\n * 布局名字\n */\n name: string;\n /**\n * 布局切换时候触发\n */\n reload?(): void;\n /**\n * 更新布局\n */\n update(): void;\n\n /**\n * 获取节点的 padding 数据\n * @param node\n */\n getPadding(node: FlowNodeEntity): PaddingSchema;\n\n /**\n * 获取默认滚动 目前用在 scroll-limit-layer\n * @param contentSize\n */\n getInitScroll(contentSize: SizeSchema): ScrollSchema;\n\n /**\n * 获取默认输入点\n */\n getDefaultInputPoint(node: FlowNodeEntity): IPoint;\n\n /**\n * 获取默认输出点\n */\n getDefaultOutputPoint(node: FlowNodeEntity): IPoint;\n\n /**\n * 获取默认远点\n */\n getDefaultNodeOrigin(): IPoint;\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { type IPoint } from '@flowgram.ai/utils';\n\nimport { type FlowNodeEntity } from '../entities';\nimport { type LABEL_SIDE_TYPE } from './flow-node-register';\n\n// 内置几种线条\nexport enum FlowTransitionLineEnum {\n STRAIGHT_LINE, // 直线\n DIVERGE_LINE, // 分支线 (一种 ROUNDED_LINE)\n MERGE_LINE, // 汇聚线 (一种 ROUNDED_LINE)\n ROUNDED_LINE, // 自定义圆角转弯线\n CUSTOM_LINE, // 自定义,用于处理循环节点等自定义线条\n DRAGGING_LINE, // 分支拖拽场景渲染的线条\n}\n\nexport interface Vertex extends IPoint {\n radiusX?: number;\n radiusY?: number;\n // 圆弧出入点位置移动\n moveX?: number;\n moveY?: number;\n /**\n * Strategy for handling arc curvature when space is insufficient, defaults to compress\n */\n radiusOverflow?: 'compress' | 'truncate';\n}\n\nexport interface FlowTransitionLine {\n type: FlowTransitionLineEnum;\n from: IPoint;\n to: IPoint;\n vertices?: Vertex[]; // 自定义圆角转弯线需要转弯的拐点\n arrow?: boolean; // 是否有箭头\n renderKey?: string; // 只有自定义线条需要\n isHorizontal?: boolean; // 是否为水平布局\n isDraggingLine?: boolean; // 是否是拖拽线条\n activated?: boolean; // 是否激活态\n side?: LABEL_SIDE_TYPE; // 区分是否分支前缀线条\n style?: React.CSSProperties;\n lineId?: string;\n}\n\n// 内置几种标签\nexport enum FlowTransitionLabelEnum {\n ADDER_LABEL, // 添加按钮\n TEXT_LABEL, // 文本标签\n COLLAPSE_LABEL, // 复合节点收起的展开标签\n COLLAPSE_ADDER_LABEL, // 复合节点收起 + 加号复合标签\n CUSTOM_LABEL, // 自定义,用于处理循环节点等自定义标签\n BRANCH_DRAGGING_LABEL, // 分支拖拽场景下的 label\n}\n\nexport interface FlowTransitionLabel {\n type: FlowTransitionLabelEnum;\n // type === 'CUSTOM_LABEL'需要配置的数据\n renderKey?: string;\n offset: IPoint; // 位置\n width?: number; // 宽度\n rotate?: string; // 循环, 如 '60deg'\n /**\n * Anchor point for positioning, relative to the label's bounding box\n * 重心偏移量,相对于标签边界框\n *\n * Format: [x, y] / 格式:[x, y]\n * Default Value: [0.5, 0.5] indicates center / 默认值:[0.5, 0.5] 表示居中\n */\n origin?: [number, number];\n props?: Record<string, any>;\n labelId?: string;\n}\n\nexport interface AdderProps {\n node: FlowNodeEntity; // 实际挂载 label 的节点\n from: FlowNodeEntity; // 边起始点在哪个节点\n to: FlowNodeEntity; // 边终点在哪个节点\n renderTo: FlowNodeEntity; // 实际渲染(renderTree)边终点在哪个节点\n [key: string]: any;\n}\n\nexport interface CollapseProps {\n node: FlowNodeEntity; // 实际挂载 label 的节点\n collapseNode: FlowNodeEntity; // 要展开收起的节点,默认为 node\n activateNode?: FlowNodeEntity; // 设置获取 label 激活状态的节点\n forceVisible?: boolean; // 是否强制显示\n [key: string]: any;\n}\n\nexport interface CustomLabelProps {\n node: FlowNodeEntity; // 实际挂载 label 的节点\n [key: string]: any;\n}\n\nexport interface CollapseAdderProps extends AdderProps, CollapseProps {\n [key: string]: any;\n}\n\nexport interface DragNodeProps {\n node: FlowNodeEntity; // 实际挂载 label 的节点\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { type IPoint } from '@flowgram.ai/utils';\nimport { PaddingSchema } from '@flowgram.ai/utils';\nimport { PositionSchema } from '@flowgram.ai/utils';\nimport { type EntityDataRegistry, type OriginSchema, type SizeSchema } from '@flowgram.ai/core';\n\nimport { FlowDocument } from '../flow-document';\nimport { type FlowNodeEntity } from '../entities';\nimport { type FlowNodeTransformData, type FlowNodeTransitionData } from '../datas';\nimport { type FlowTransitionLabel, type FlowTransitionLine } from './flow-transition';\nimport { FlowLayout, FlowLayoutDefault } from './flow-layout';\nimport {\n FLOW_DEFAULT_HIDDEN_TYPES,\n FlowNodeBaseType,\n type FlowNodeJSON,\n FlowNodeType,\n} from './flow';\n\n/**\n * 节点渲染相关配置信息,可扩展\n */\nexport interface FlowNodeMeta {\n isStart?: boolean; // 是否为开始节点\n addable?: boolean; // 是否可添加节点\n expandable?: boolean; // 是否可展开\n draggable?: boolean | ((node: FlowNodeEntity) => boolean); // 是否可拖拽\n selectable?: boolean | ((node: FlowNodeEntity, mousePos?: PositionSchema) => boolean); // 是否可被框选\n deleteDisable?: boolean; // 是否禁用删除\n copyDisable?: boolean; // 禁用复制\n addDisable?: boolean; // 禁止添加\n hidden?: boolean; // 是否隐藏\n // maxSize?: SizeSchema // 默认展开后的大小\n size?: SizeSchema; // 默认大小\n autoResizeDisable?: boolean; // 禁用监听节点变化自动调整大小\n /**\n * @deprecated 使用 NodeRegister.getOrigin 代替\n */\n origin?: OriginSchema; // 原点配置,默认 垂直 { x: 0.5, y: 0 } 水平 { x: 0, y: 0.5 }\n defaultExpanded?: boolean; // 默认是否展开\n defaultCollapsed?: boolean; // 复合节点默认是否收起\n spacing?: number | ((transform: FlowNodeTransformData) => number); // 兄弟节点间,等价于 marginBottom\n padding?: PaddingSchema | ((transform: FlowNodeTransformData) => PaddingSchema); // 节点设置了 padding,则不需要 inlineSpacingPre 和 inlineSpacingAfter\n inlineSpacingPre?: number | ((transform: FlowNodeTransformData) => number); // 父子节点间,等价于 paddingTop 或者 paddingLeft\n inlineSpacingAfter?: number | ((transform: FlowNodeTransformData) => number); // 父子节点间,等价于 paddingBottom 或者 paddingRight\n renderKey?: string; // 节点的渲染组件,可以绑定 react 组件\n isInlineBlocks?: boolean | ((node: FlowNodeEntity) => boolean); // 采用水平布局\n minInlineBlockSpacing?: number | ((node: FlowNodeTransformData) => number); // 最小的 inlineBlock 的间距\n isNodeEnd?: boolean; // 是否标识节点结束\n [key: string]: any;\n}\n\n/**\n * spacing default key 值\n */\nexport const DefaultSpacingKey = {\n /**\n * 普通节点间距。垂直 / 水平\n */\n NODE_SPACING: 'SPACING',\n /**\n * 分支节点间距\n */\n BRANCH_SPACING: 'BRANCH_SPACING',\n /**\n * 圆弧线条拐角 radius\n */\n ROUNDED_LINE_RADIUS: 'ROUNDED_LINE_RADIUS',\n /**\n * 圆弧线条 x radius\n */\n ROUNDED_LINE_X_RADIUS: 'ROUNDED_LINE_X_RADIUS',\n /**\n * 圆弧线条 y radius\n */\n ROUNDED_LINE_Y_RADIUS: 'ROUNDED_LINE_Y_RADIUS',\n /**\n * dynamicSplit block list 下部留白间距,因为有两个拐弯,所以翻一倍\n */\n INLINE_BLOCKS_PADDING_BOTTOM: 'INLINE_BLOCKS_PADDING_BOTTOM',\n /**\n * 复合节点距离上个节点的距离\n * 条件分支菱形下边和分支的距离\n */\n COLLAPSED_SPACING: 'COLLAPSED_SPACING',\n /**\n * width of hover area\n */\n HOVER_AREA_WIDTH: 'HOVER_AREA_WIDTH',\n};\n\n/**\n * 默认一些间隔参数\n */\nexport const DEFAULT_SPACING = {\n NULL: 0,\n [DefaultSpacingKey.NODE_SPACING]: 32, // 普通节点间距。垂直 / 水平\n [DefaultSpacingKey.BRANCH_SPACING]: 20, // 分支节点间距\n /**\n * @deprecated use 'BRANCH_SPACING' instead\n */\n MARGIN_RIGHT: 20, // 分支节点右边间距\n INLINE_BLOCK_PADDING_BOTTOM: 16, // block 底部留白\n INLINE_BLOCKS_PADDING_TOP: 30, // block list 上部留白间距\n // JS 浮点数有误差,1046.6 -1006.6 = 39.9999999,会导致 间距/20 < 2 导致布局计算问题,因此需要额外增加 0.1 像素\n [DefaultSpacingKey.INLINE_BLOCKS_PADDING_BOTTOM]: 40.1, // block lit 下部留白间距,因为有两个拐弯,所以翻一倍\n MIN_INLINE_BLOCK_SPACING: 200, // 分支间最小边距 (垂直布局)\n MIN_INLINE_BLOCK_SPACING_HORIZONTAL: 80, // 分支间最小边距 (水平布局)\n [DefaultSpacingKey.COLLAPSED_SPACING]: 12, // 复合节点距离上个节点的距离\n [DefaultSpacingKey.ROUNDED_LINE_RADIUS]: 16, // 圆弧线条拐角 radius\n [DefaultSpacingKey.ROUNDED_LINE_X_RADIUS]: 16, // 圆弧线条 x radius\n [DefaultSpacingKey.ROUNDED_LINE_Y_RADIUS]: 20, // 圆弧线条 y radius\n [DefaultSpacingKey.HOVER_AREA_WIDTH]: 20, // width of hover area\n};\n\n/**\n * 拖拽种类枚举\n * 1. 节点拖拽\n * 2. 分支拖拽\n */\nexport enum DRAGGING_TYPE {\n NODE = 'node',\n BRANCH = 'branch',\n}\n\n/**\n * 拖拽分支 Adder、Line 类型\n */\nexport enum LABEL_SIDE_TYPE {\n // 前缀分支\n PRE_BRANCH = 'pre_branch',\n NORMAL_BRANCH = 'normal_branch',\n}\n\n/**\n * 默认节点大小\n */\nexport const DEFAULT_SIZE = {\n width: 280,\n height: 60,\n};\n\n/**\n * 默认 meta 配置\n */\nexport const DEFAULT_FLOW_NODE_META: (\n nodeType: FlowNodeType,\n document: FlowDocument\n) => FlowNodeMeta = (nodeType: FlowNodeType, document: FlowDocument) => {\n const hidden = FLOW_DEFAULT_HIDDEN_TYPES.includes(nodeType);\n return {\n isStart: nodeType === 'start',\n hidden,\n defaultExpanded: document.options.allNodesDefaultExpanded,\n size: DEFAULT_SIZE,\n origin: document.layout.getDefaultNodeOrigin(),\n isInlineBlocks: nodeType === FlowNodeBaseType.INLINE_BLOCKS,\n // miniSize: { width: 200, height: 40 },\n spacing: DEFAULT_SPACING.SPACING,\n inlineSpacingPre: 0,\n inlineSpacingAfter: 0,\n expandable: true,\n draggable: true,\n selectable: true,\n renderKey: '',\n minInlineBlockSpacing: () => {\n const isVertical = FlowLayoutDefault.isVertical(document.layout);\n return isVertical\n ? DEFAULT_SPACING.MIN_INLINE_BLOCK_SPACING\n : DEFAULT_SPACING.MIN_INLINE_BLOCK_SPACING_HORIZONTAL;\n },\n } as FlowNodeMeta;\n};\n\n/**\n * 节点注册\n */\nexport interface FlowNodeRegistry<M extends FlowNodeMeta = FlowNodeMeta> {\n /**\n * 从另外一个注册扩展\n */\n extend?: string;\n /**\n * 节点类型\n */\n type: FlowNodeType;\n /**\n * 节点注册的数据,可以理解为 ECS 里的 Component, 这里可以配置自定义数据\n */\n dataRegistries?: EntityDataRegistry[];\n /**\n * 节点画布相关初始化配置信息,会覆盖 DEFAULT_FLOW_NODE_META\n */\n meta?: Partial<M>;\n /**\n * 自定义创建节点,可以自定义节点的树形结构\n * 返回新加入的节点,这样才能统计缓存\n *\n * @action 使用该方法,在创建时候将会忽略 json blocks 数据,而是交给适用节点自己处理 json 逻辑\n */\n onCreate?: (node: FlowNodeEntity, json: FlowNodeJSON) => FlowNodeEntity[] | void;\n /**\n * 添加子 block,一般用于分支的动态添加\n */\n onBlockChildCreate?: (\n node: FlowNodeEntity,\n json: FlowNodeJSON,\n addedNodes?: FlowNodeEntity[] // 新创建的节点都要存在这里\n ) => FlowNodeEntity;\n /**\n * 创建线条\n */\n getLines?: (transition: FlowNodeTransitionData, layout: FlowLayout) => FlowTransitionLine[];\n /**\n * 创建 label\n */\n getLabels?: (transition: FlowNodeTransitionData, layout: FlowLayout) => FlowTransitionLabel[];\n\n /**\n * 调整子节点的线条,优先级高于子节点本身的 getLines\n */\n getChildLines?: (transition: FlowNodeTransitionData, layout: FlowLayout) => FlowTransitionLine[];\n\n /**\n * 调整子节点的 Labels,优先级高于子节点本身的 getLabels\n */\n getChildLabels?: (\n transition: FlowNodeTransitionData,\n layout: FlowLayout\n ) => FlowTransitionLabel[];\n\n /**\n * 自定义输入节点\n */\n getInputPoint?: (transform: FlowNodeTransformData, layout: FlowLayout) => IPoint;\n /**\n * 自定义输出节点\n */\n getOutputPoint?: (transform: FlowNodeTransformData, layoutKey: FlowLayout) => IPoint;\n /**\n * 获取当前节点 Position 偏移量,偏移量计算只能使用已经计算完的数据,如上一个节点或者子节点,不然会造成 o(n^2) 复杂度\n *\n * 1. 切记不要用当前节点的 localBounds(相对位置 bbox),因为 delta 计算发生在 localBounds 计算之前\n * 2. 切记不要用 bounds(绝对位置 bbox, 会触发所有父节点绝对位置计算), bounds 只能在最终 render 时候使用\n * 3. 可以用 pre 节点 和 子节点的 localBounds 或者 size 数据,因为子节点是先算的\n * 4. 可以用当前节点的 size (所有子节点的最大 bbox), 这是已经确定下来的\n */\n getDelta?: (transform: FlowNodeTransformData, layout: FlowLayout) => IPoint | undefined;\n\n /**\n * 动态获取原点,会覆盖 meta.origin\n */\n getOrigin?(transform: FlowNodeTransformData, layout: FlowLayout): IPoint;\n /**\n * 原点 X 偏移\n * @param transform\n */\n getOriginDeltaX?: (transform: FlowNodeTransformData, layout: FlowLayout) => number;\n /**\n * 原点 Y 偏移\n * @param transform\n */\n getOriginDeltaY?: (transform: FlowNodeTransformData, layout: FlowLayout) => number;\n /**\n * 通过 parent 计算当前节点的偏移,规则同 getDelta\n */\n getChildDelta?: (childBlock: FlowNodeTransformData, layout: FlowLayout) => IPoint | undefined;\n /**\n * 在当前节点布局完成后调用,可以对布局做更精细的调整\n */\n onAfterUpdateLocalTransform?: (transform: FlowNodeTransformData, layout: FlowLayout) => void;\n\n /**\n * 子节点的 registry 覆盖,这里通过 originParent 来查找\n */\n extendChildRegistries?: FlowNodeRegistry[];\n\n /**\n * @deprecated\n * 自定义子节点添加逻辑\n * @param node 节点\n * @param json 添加的节点 JSON\n * @param options 其它配置\n * @returns\n */\n addChild?: (\n node: FlowNodeEntity,\n json: FlowNodeJSON,\n options?: {\n hidden?: boolean;\n index?: number;\n }\n ) => FlowNodeEntity;\n\n /**\n * 内部用于继承逻辑判断,不要使用\n */\n __extends__?: FlowNodeType[];\n /**\n * 扩展注册器\n */\n [key: string]: any;\n}\n\nexport namespace FlowNodeRegistry {\n export function mergeChildRegistries(\n r1: FlowNodeRegistry[] = [],\n r2: FlowNodeRegistry[] = []\n ): FlowNodeRegistry[] {\n if (r1.length === 0 || r2.length === 0) {\n return [...r1, ...r2];\n }\n const r1Filter = r1.map((r1Current) => {\n const r2Current = r2.find((n) => n.type === r1Current.type);\n if (r2Current) {\n return merge(r1Current, r2Current, r1Current.type);\n }\n return r1Current;\n });\n const r2Filter = r2.filter((n) => !r1.some((r) => r.type === n.type));\n return [...r1Filter, ...r2Filter];\n }\n export function merge(\n registry1: FlowNodeRegistry,\n registry2: FlowNodeRegistry,\n finalType: FlowNodeType\n ): FlowNodeRegistry {\n const extendKeys = registry1.__extends__ ? registry1.__extends__.slice() : [];\n if (registry1.type !== registry2.type) {\n extendKeys.unshift(registry1.type);\n }\n return {\n ...registry1,\n ...registry2,\n extendChildRegistries: mergeChildRegistries(\n registry1.extendChildRegistries,\n registry2.extendChildRegistries\n ),\n meta: { ...registry1.meta, ...registry2.meta },\n extend: undefined,\n type: finalType,\n __extends__: extendKeys,\n };\n }\n\n export function extend(\n registry: FlowNodeRegistry,\n extendRegistries: FlowNodeRegistry[]\n ): FlowNodeRegistry {\n if (!extendRegistries.length) return registry;\n return extendRegistries.reduce((res, ext) => merge(res, ext, registry.type), registry);\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Event } from '@flowgram.ai/utils';\nimport { Disposable } from '@flowgram.ai/utils';\n\nimport { type FlowNodeEntity } from '../entities/flow-node-entity';\nimport { AddNodeData, FlowNodeJSON } from './flow';\n\nexport enum OperationType {\n addFromNode = 'addFromNode',\n deleteFromNode = 'deleteFromNode',\n addBlock = 'addBlock',\n deleteBlock = 'deleteBlock',\n createGroup = 'createGroup',\n ungroup = 'ungroup',\n moveNodes = 'moveNodes',\n moveBlock = 'moveBlock',\n moveChildNodes = 'moveChildNodes',\n addNodes = 'addNodes',\n deleteNodes = 'deleteNodes',\n addChildNode = 'addChildNode',\n deleteChildNode = 'deleteChildNode',\n addNode = 'addNode',\n deleteNode = 'deleteNode',\n}\n\nexport interface AddOrDeleteFromNodeOperationValue {\n fromId: string;\n data: FlowNodeJSON;\n}\n\nexport interface AddOrDeleteNodeOperationValue {\n fromId: string;\n data: FlowNodeJSON;\n}\n\nexport interface AddFromNodeOperation {\n type: OperationType.addFromNode;\n value: AddOrDeleteFromNodeOperationValue;\n}\n\nexport interface DeleteFromNodeOperation {\n type: OperationType.deleteFromNode;\n value: AddOrDeleteFromNodeOperationValue;\n}\n\nexport interface AddOrDeleteBlockValue {\n targetId: string;\n index?: number;\n blockData: FlowNodeJSON;\n parentId?: string;\n}\n\nexport interface createOrUngroupValue {\n targetId: string;\n groupId: string;\n nodeIds: string[];\n}\n\nexport interface AddBlockOperation {\n type: OperationType.addBlock;\n value: AddOrDeleteBlockValue;\n}\n\nexport interface DeleteBlockOperation {\n type: OperationType.deleteBlock;\n value: AddOrDeleteBlockValue;\n}\n\nexport interface CreateGroupOperation {\n type: OperationType.createGroup;\n value: createOrUngroupValue;\n}\n\nexport interface UngroupOperation {\n type: OperationType.ungroup;\n value: createOrUngroupValue;\n}\n\nexport interface MoveNodesOperationValue {\n fromId: string;\n toId: string;\n nodeIds: string[];\n}\n\nexport interface MoveNodesOperation {\n type: OperationType.moveNodes;\n value: MoveNodesOperationValue;\n}\n\nexport interface AddOrDeleteNodesOperationValue {\n fromId: string;\n nodes: FlowNodeJSON[];\n}\n\nexport interface AddNodesOperation {\n type: OperationType.addNodes;\n value: AddOrDeleteNodesOperationValue;\n}\n\nexport interface DeleteNodesOperation {\n type: OperationType.deleteNodes;\n value: AddOrDeleteNodesOperationValue;\n}\n\nexport interface MoveChildNodesOperationValue {\n nodeIds: string[];\n fromParentId: string;\n fromIndex: number;\n toParentId: string;\n toIndex: number;\n}\n\nexport type MoveBlockOperationValue = {\n nodeId: string;\n fromParentId: string;\n fromIndex: number;\n toParentId: string;\n toIndex: number;\n};\n\nexport interface MoveBlockOperation {\n type: OperationType.moveBlock;\n value: MoveBlockOperationValue;\n}\n\nexport interface MoveChildNodesOperation {\n type: OperationType.moveChildNodes;\n value: MoveChildNodesOperationValue;\n}\n\nexport interface AddChildNodeOperation {\n type: OperationType.addChildNode;\n value: AddOrDeleteChildNodeValue;\n}\n\nexport interface DeleteChildNodeOperation {\n type: OperationType.deleteChildNode;\n value: AddOrDeleteChildNodeValue;\n}\n\nexport interface AddOrDeleteChildNodeValue {\n data: FlowNodeJSON;\n parentId?: string;\n index?: number;\n originParentId?: string;\n hidden?: boolean;\n}\n\nexport interface AddNodeOperation {\n type: OperationType.addNode;\n value: AddOrDeleteNodeValue;\n}\n\nexport interface DeleteNodeOperation {\n type: OperationType.deleteNode;\n value: AddOrDeleteNodeValue;\n}\n\nexport interface AddOrDeleteNodeValue {\n data: FlowNodeJSON;\n parentId?: string;\n index?: number;\n hidden?: boolean;\n}\n\nexport type FlowOperation =\n | AddFromNodeOperation\n | DeleteFromNodeOperation\n | AddBlockOperation\n | DeleteBlockOperation\n | CreateGroupOperation\n | UngroupOperation\n | MoveNodesOperation\n | AddNodesOperation\n | DeleteNodesOperation\n | MoveBlockOperation\n | AddChildNodeOperation\n | DeleteChildNodeOperation\n | MoveChildNodesOperation\n | AddNodeOperation\n | DeleteNodeOperation;\n\nexport type FlowNodeEntityOrId = string | FlowNodeEntity;\n\n// 添加节点时的配置\nexport type AddNodeConfig = {\n // 父节点\n parent?: FlowNodeEntityOrId;\n // 是否隐藏\n hidden?: boolean;\n // 插入位置\n index?: number;\n};\n\n/**\n * 添加block时的配置\n */\nexport interface AddBlockConfig {\n // 父节点,默认去找 $inlineBlocks$\n parent?: FlowNodeEntity;\n // 插入位置,默认最后\n index?: number;\n}\n\n/**\n * 移动节点时的配置\n */\nexport interface MoveNodeConfig {\n // 目标父节点,如果不传,默认使用移动节点的父节点\n parent?: FlowNodeEntityOrId;\n // 目标位置, 默认移动到最后\n index?: number;\n}\n\n/**\n * 节点添加事件\n */\nexport interface OnNodeAddEvent {\n node: FlowNodeEntity;\n data: AddNodeData;\n}\n\n/**\n * 节点移动事件\n */\nexport interface OnNodeMoveEvent {\n node: FlowNodeEntity;\n fromParent: FlowNodeEntity;\n fromIndex: number;\n toParent: FlowNodeEntity;\n toIndex: number;\n}\n\nexport interface FlowOperationBaseService extends Disposable {\n /**\n * 执行操作\n * @param operation 可序列化的操作\n * @returns 操作返回\n */\n apply(operation: FlowOperation): any;\n\n /**\n * 添加节点,如果节点已经存在则不会重复创建\n * @param nodeJSON 节点数据\n * @param config 配置\n * @returns 成功添加的节点\n */\n addNode(nodeJSON: FlowNodeJSON, config?: AddNodeConfig): FlowNodeEntity;\n\n /**\n * 基于某一个起始节点往后面添加\n * @param fromNode 起始节点\n * @param nodeJSON 添加的节点JSON\n */\n addFromNode(fromNode: FlowNodeEntityOrId, nodeJSON: FlowNodeJSON): FlowNodeEntity;\n\n /**\n * 删除节点\n * @param node 节点\n * @returns\n */\n deleteNode(node: FlowNodeEntityOrId): void;\n\n /**\n * 批量删除节点\n * @param nodes\n */\n deleteNodes(nodes: FlowNodeEntityOrId[]): void;\n\n /**\n * 添加块(分支)\n * @param target 目标\n * @param blockJSON 块数据\n * @param config 配置\n * @returns\n */\n addBlock(\n target: FlowNodeEntityOrId,\n blockJSON: FlowNodeJSON,\n config?: AddBlockConfig\n ): FlowNodeEntity;\n\n /**\n * 移动节点\n * @param node 被移动的节点\n * @param config 移动节点配置\n */\n moveNode(node: FlowNodeEntityOrId, config?: MoveNodeConfig): void;\n\n /**\n * 拖拽节点\n * @param param0\n * @returns\n */\n dragNodes({ dropNode, nodes }: { dropNode: FlowNodeEntity; nodes: FlowNodeEntity[] }): void;\n\n /**\n * 添加节点的回调\n */\n onNodeAdd: Event<OnNodeAddEvent>;\n\n /**\n * 节点移动的回调\n */\n onNodeMove: Event<OnNodeMoveEvent>;\n}\n\nexport const FlowOperationBaseService = Symbol('FlowOperationBaseService');\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Event, type Rectangle } from '@flowgram.ai/utils';\nimport { Entity, type EntityOpts } from '@flowgram.ai/core';\n\nimport {\n FlowLayoutDefault,\n FlowNodeJSON,\n FlowNodeMeta,\n FlowNodeRegistry,\n FlowNodeType,\n} from '../typings';\nimport type { FlowDocument } from '../flow-document';\nimport { FlowNodeRenderData, FlowNodeTransformData } from '../datas';\n\nexport interface FlowNodeEntityConfig extends EntityOpts {\n document: FlowDocument;\n flowNodeType: FlowNodeType;\n originParent?: FlowNodeEntity;\n meta?: FlowNodeMeta;\n}\n\nexport interface FlowNodeInitData {\n originParent?: FlowNodeEntity;\n parent?: FlowNodeEntity;\n hidden?: boolean;\n meta?: FlowNodeMeta;\n index?: number;\n}\n\nexport class FlowNodeEntity extends Entity<FlowNodeEntityConfig> {\n private _memoLocalCache = new Map<string, any>();\n\n private _memoGlobalCache = new Map<string, any>();\n\n static type = 'FlowNodeEntity';\n\n private _registerCache?: FlowNodeRegistry;\n\n private _metaCache?: Required<FlowNodeMeta>;\n\n metaFromJSON?: FlowNodeMeta;\n\n /**\n * 真实的父节点,条件块在内部会创建一些空的块节点,这些块需要关联它真实的父亲节点\n */\n originParent?: FlowNodeEntity;\n\n flowNodeType: FlowNodeType = 'unknown'; // 流程类型\n\n /**\n * 是否隐藏\n */\n private _hidden = false;\n\n index = -1;\n\n /**\n * 文档引用\n */\n document: FlowDocument;\n\n constructor(conf: FlowNodeEntityConfig) {\n super(conf);\n this.document = conf.document;\n this.flowNodeType = conf.flowNodeType;\n this.originParent = conf.originParent;\n this.metaFromJSON = conf.meta;\n this.onDispose(() => {\n this.document.originTree\n .getChildren(this)\n .slice()\n .forEach((child) => {\n child.dispose();\n });\n this.document.originTree.remove(this, false);\n this.originParent = undefined;\n });\n }\n\n initData(initConf: FlowNodeInitData): void {\n if (initConf.originParent !== this.originParent) {\n this.originParent = initConf.originParent;\n this._registerCache = undefined;\n }\n if (initConf.parent) {\n initConf.parent.addChild(this, initConf.index);\n }\n // TODO 这个 meta 不会触发 data 数据更新\n if (initConf.meta !== this.metaFromJSON) {\n this._metaCache = undefined;\n this.metaFromJSON = initConf.meta;\n }\n this._hidden = !!(this.getNodeMeta().hidden || initConf.hidden);\n }\n\n get isStart(): boolean {\n return this.getNodeMeta().isStart;\n }\n\n get isFirst(): boolean {\n return !this.pre;\n }\n\n get isLast(): boolean {\n return !this.next;\n }\n\n /**\n * 子节点采用水平布局\n */\n get isInlineBlocks(): boolean {\n const originIsInlineBlocks = this.getNodeMeta().isInlineBlocks;\n return typeof originIsInlineBlocks === 'function'\n ? originIsInlineBlocks(this)\n : originIsInlineBlocks;\n }\n\n /**\n * 水平节点\n */\n get isInlineBlock(): boolean {\n const parent = this.document.renderTree.getParent(this);\n return !!(parent && parent.isInlineBlocks);\n }\n\n /**\n * 节点结束标记\n * - 当前节点是结束节点\n * - 当前节点最后一个节点包含结束标记\n * - 当前节点为 inlineBlock,每一个 block 包含结束标记\n *\n * 由子元素确定,因此使用 memoLocal\n */\n get isNodeEnd(): boolean {\n return this.memoLocal<boolean>('isNodeEnd', () => {\n if (this.getNodeMeta().isNodeEnd) {\n return true;\n }\n\n if (this.isInlineBlocks && this.collapsedChildren.length) {\n return this.collapsedChildren.every((child) => child.isNodeEnd);\n }\n\n if (this.lastCollapsedChild) {\n return this.lastCollapsedChild.isNodeEnd;\n }\n\n return false;\n });\n }\n\n /**\n * 添加 子节点\n *\n * @param child 插入节点\n */\n addChild(child: FlowNodeEntity, index?: number) {\n if (child.parent === this) return;\n this.document.originTree.addChild(this, child, index);\n }\n\n get hasChild(): boolean {\n return this.children.length > 0;\n }\n\n get pre(): FlowNodeEntity | undefined {\n return this.document.renderTree.getPre(this);\n }\n\n get next(): FlowNodeEntity | undefined {\n return this.document.renderTree.getNext(this);\n }\n\n get parent(): FlowNodeEntity | undefined {\n return this.document.renderTree.getParent(this);\n }\n\n getNodeRegistry<M extends FlowNodeRegistry = FlowNodeRegistry & { meta: FlowNodeMeta }>(): M {\n if (this._registerCache) return this._registerCache as M;\n this._registerCache = this.document.getNodeRegistry(this.flowNodeType, this.originParent);\n return this._registerCache as M;\n }\n\n /**\n * @deprecated\n * use getNodeRegistry instead\n */\n getNodeRegister<M extends FlowNodeRegistry = FlowNodeRegistry>(): M {\n return this.getNodeRegistry<M>();\n }\n\n getNodeMeta<M extends FlowNodeMeta = FlowNodeMeta>(): M & Required<FlowNodeMeta> {\n if (this._metaCache) return this._metaCache as M & Required<FlowNodeMeta>;\n if (this.metaFromJSON) {\n this._metaCache = {\n ...this.getNodeRegistry().meta,\n ...this.metaFromJSON,\n } as M & Required<FlowNodeMeta>;\n } else {\n this._metaCache = this.getNodeRegistry().meta as M & Required<FlowNodeMeta>;\n }\n return this._metaCache as M & Required<FlowNodeMeta>;\n }\n\n /**\n * 获取所有子节点,包含 child 及其所有兄弟节点\n */\n get allChildren(): FlowNodeEntity[] {\n const children: FlowNodeEntity[] = [];\n for (const child of this.children) {\n children.push(child);\n children.push(...child.allChildren);\n }\n return children;\n }\n\n /**\n * 获取所有收起的子节点,包含 child 及其所有兄弟节点\n */\n get allCollapsedChildren(): FlowNodeEntity[] {\n const children: FlowNodeEntity[] = [];\n for (const child of this.collapsedChildren) {\n children.push(child);\n children.push(...child.allCollapsedChildren);\n }\n return children;\n }\n\n /**\n *\n * Get child blocks\n *\n * use `blocks` instead\n * @deprecated\n */\n\n get collapsedChildren(): FlowNodeEntity[] {\n return this.document.renderTree.getCollapsedChildren(this);\n }\n\n /**\n * Get child blocks\n */\n get blocks(): FlowNodeEntity[] {\n return this.collapsedChildren;\n }\n\n /**\n * Get last block\n */\n get lastBlock(): FlowNodeEntity | undefined {\n return this.lastCollapsedChild;\n }\n\n /**\n * use `lastBlock` instead\n */\n get lastCollapsedChild(): FlowNodeEntity | undefined {\n const { collapsedChildren } = this;\n return collapsedChildren[collapsedChildren.length - 1];\n }\n\n /**\n * 获取子节点,如果子节点收起来,则会返回 空数组\n */\n get children(): FlowNodeEntity[] {\n return this.document.renderTree.getChildren(this);\n }\n\n get lastChild(): FlowNodeEntity | undefined {\n const { children } = this;\n return children[children.length - 1];\n }\n\n get firstChild(): FlowNodeEntity | undefined {\n return this.children[0];\n }\n\n memoLocal<T>(key: string, fn: () => T): T {\n if (this._memoLocalCache.has(key)) {\n return this._memoLocalCache.get(key) as T;\n }\n const data = fn();\n this._memoLocalCache.set(key, data);\n return data as T;\n }\n\n memoGlobal<T>(key: string, fn: () => T): T {\n if (this._memoGlobalCache.has(key)) {\n return this._memoGlobalCache.get(key) as T;\n }\n const data = fn();\n this._memoGlobalCache.set(key, data);\n return data as T;\n }\n\n clearMemoGlobal() {\n this._memoGlobalCache.clear();\n }\n\n clearMemoLocal() {\n this._memoLocalCache.clear();\n }\n\n get childrenLength() {\n return this.children.length;\n }\n\n get collapsed(): boolean {\n if (this.document.renderTree.isCollapsed(this)) return true;\n return !!this.parent?.collapsed;\n }\n\n set collapsed(collapsed) {\n this.document.renderTree.setCollapsed(this, collapsed);\n this.clearMemoGlobal();\n this.clearMemoLocal();\n }\n\n get hidden(): boolean {\n return this._hidden;\n }\n\n // 展开该节点\n openInsideCollapsed() {\n this.document.renderTree.openNodeInsideCollapsed(this);\n }\n\n /**\n * 可以重载\n */\n getJSONData(): any {\n return this.getExtInfo();\n }\n\n /**\n * 生成 JSON\n * @param newId\n */\n toJSON(): FlowNodeJSON {\n return this.document.toNodeJSON(this);\n }\n\n get isVertical(): boolean {\n return this.document.layout.name === FlowLayoutDefault.VERTICAL_FIXED_LAYOUT;\n }\n\n /**\n * 修改节点扩展信息\n * @param info\n */\n updateExtInfo<T extends Record<string, any> = Record<string, any>>(\n extInfo: T,\n fullUpdate?: boolean\n ): void {\n this.getData(FlowNodeRenderData).updateExtInfo(extInfo, fullUpdate);\n }\n\n /**\n * 获取节点扩展信息\n */\n getExtInfo<T extends Record<string, any> = Record<string, any>>(): T {\n return this.getData<FlowNodeRenderData>(FlowNodeRenderData).getExtInfo() as T;\n }\n\n get onExtInfoChange(): Event<{ newInfo: any; oldInfo: any }> {\n return this.renderData.onExtInfoChange;\n }\n\n /**\n * 获取渲染数据\n */\n get renderData(): FlowNodeRenderData {\n return this.getData(FlowNodeRenderData);\n }\n\n /**\n * 获取位置大小数据\n */\n get transform(): FlowNodeTransformData {\n return this.getData(FlowNodeTransformData);\n }\n\n /**\n * 获取节点的位置及大小矩形\n */\n get bounds(): Rectangle {\n return this.transform.bounds;\n }\n\n /**\n * Check node extend type\n */\n isExtend(parentType: FlowNodeType): boolean {\n return this.document.isExtend(this.flowNodeType, parentType);\n }\n\n /**\n * Check node type\n * @param parentType\n */\n isTypeOrExtendType(parentType: FlowNodeType): boolean {\n return this.document.isTypeOrExtendType(this.flowNodeType, parentType);\n }\n}\n\nexport namespace FlowNodeEntity {\n export function is(obj: Entity): obj is FlowNodeEntity {\n return obj instanceof FlowNodeEntity;\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Disposable, type IPoint, Rectangle } from '@flowgram.ai/utils';\nimport {\n Bounds,\n EntityData,\n PositionSchema,\n type SizeSchema,\n TransformData,\n} from '@flowgram.ai/core';\n\nimport type { FlowNodeEntity } from '../entities';\nimport { FlowNodeRenderData } from './flow-node-render-data';\n\nexport interface FlowNodeTransformSchema {\n size: SizeSchema; // 当前节点大小\n}\n\nexport class FlowNodeTransformData extends EntityData<FlowNodeTransformSchema> {\n static type = 'FlowNodeTransformData';\n\n // 这里加 declare 原因:覆盖了 EntityData 默认的 EntityType,如果不声明会报 TS2612 错误\n declare entity: FlowNodeEntity;\n\n transform: TransformData;\n\n renderState: FlowNodeRenderData;\n\n localDirty = true;\n\n get origin() {\n return this.transform.origin;\n }\n\n get key(): string {\n return this.entity.id;\n }\n\n getDefaultData(): FlowNodeTransformSchema {\n const { size, hidden } = this.entity.getNodeMeta();\n // 更新默认 size 大小\n return {\n size: !hidden ? { ...size } : { width: 0, height: 0 },\n };\n }\n\n constructor(entity: FlowNodeEntity) {\n super(entity);\n const { origin } = this.entity.getNodeMeta();\n this.transform = this.entity.addData<TransformData>(TransformData);\n this.transform.changeLocked = true;\n this.transform.update({ origin: { ...origin } });\n this.transform.changeLocked = false;\n this.renderState = this.entity.addData<FlowNodeRenderData>(FlowNodeRenderData);\n this.bindChange(this.transform);\n // 删除节点要让下一个节点或者父节点变成 dirty\n this.toDispose.push(\n Disposable.create(() => {\n const { next, parent } = this;\n if (next) next.localDirty = true;\n if (parent) parent.localDirty = true;\n })\n );\n // this.bindChange(this.renderState)\n }\n\n /**\n * 获取节点是否展开\n */\n get collapsed(): boolean {\n return this.entity.collapsed;\n }\n\n set collapsed(collapsed: boolean) {\n this.entity.collapsed = collapsed;\n this.localDirty = true;\n\n // 第一个子节点也设置为 dirty\n if (this.firstChild) this.firstChild.localDirty = true;\n\n this.fireChange();\n }\n\n /**\n * 获取节点的大小\n */\n get size(): SizeSchema {\n return this.entity.memoGlobal<SizeSchema>('size', () => {\n if (this.isContainer) return this.transform.localSize;\n return this.data.size;\n });\n }\n\n get position(): PositionSchema {\n const { position } = this.transform;\n return {\n x: position.x,\n y: position.y,\n };\n }\n\n set position(position: PositionSchema) {\n this.transform.update({\n position,\n });\n }\n\n set size(size: SizeSchema) {\n const { width, height } = this.data.size;\n // Container size 由子节点决定\n if (this.isContainer) return;\n if (size.width !== width || size.height !== height) {\n this._data.size = { ...size };\n this.localDirty = true;\n this.fireChange();\n }\n }\n\n get inputPoint() {\n return this.entity.memoGlobal<IPoint>('inputPoint', () => {\n const { getInputPoint } = this.entity.getNodeRegistry();\n return getInputPoint\n ? getInputPoint(this, this.entity.document.layout)\n : this.defaultInputPoint;\n });\n }\n\n get defaultInputPoint() {\n return this.entity.memoGlobal<IPoint>('defaultInputPoint', () =>\n this.entity.document.layout.getDefaultInputPoint(this.entity)\n );\n }\n\n get defaultOutputPoint() {\n return this.entity.memoGlobal<IPoint>('defaultOutputPoint', () =>\n this.entity.document.layout.getDefaultOutputPoint(this.entity)\n );\n }\n\n get outputPoint() {\n return this.entity.memoGlobal<IPoint>('outputPoint', () => {\n const { getOutputPoint } = this.entity.getNodeRegistry();\n return getOutputPoint\n ? getOutputPoint(this, this.entity.document.layout)\n : this.defaultOutputPoint;\n });\n }\n\n /**\n * 原点的最左偏移\n */\n get originDeltaX(): number {\n return this.entity.memoLocal<number>('originDeltaX', () => {\n const { children } = this;\n const { getOriginDeltaX } = this.entity.getNodeRegistry();\n if (getOriginDeltaX) return getOriginDeltaX(this, this.entity.document.layout);\n // 没有子节点,则采用自身的原点偏移\n if (children.length === 0) {\n return -this.size.width * this.origin.x;\n }\n // 采用子节点的最左偏移量来计算\n if (children.length === 1) return children[0].originDeltaX;\n // 这里代表水平偏移,则采用第一个节点加上自身偏移\n if (this.entity.isInlineBlocks && children.length > 1) {\n return children[0].originDeltaX + this.transform.position.x;\n }\n return children.reduce((res: undefined | number, child) => {\n const deltaX = child.originDeltaX;\n return res === undefined || deltaX < res ? deltaX : (res as number);\n }, undefined) as number;\n });\n }\n\n /**\n * 原点 y 轴偏移\n */\n get originDeltaY(): number {\n return this.entity.memoLocal<number>('originDeltaY', () => {\n const { children } = this;\n const { getOriginDeltaY } = this.entity.getNodeRegistry();\n if (getOriginDeltaY) return getOriginDeltaY(this, this.entity.document.layout);\n // 没有子节点,则采用自身的原点偏移\n if (children.length === 0) {\n return -this.size.height * this.origin.y;\n }\n // 采用子节点的最上偏移量来计算\n if (children.length === 1) return children[0].originDeltaY;\n // 这里代表水平偏移,则采用第一个节点加上自身偏移\n if (this.entity.isInlineBlocks && children.length > 1) {\n return children[0].originDeltaY + this.transform.position.y;\n }\n return children.reduce((res: undefined | number, child) => {\n const deltaY = child.originDeltaY;\n return res === undefined || deltaY < res ? deltaY : (res as number);\n }, undefined) as number;\n });\n }\n\n /**\n * 绝对坐标 bbox, 不包含自身的 spacing(marginBottom), 但是包含 inlineSpacing 和 子节点的 spacing\n */\n get bounds(): Rectangle {\n return this.entity.memoGlobal<Rectangle>('bounds', () => {\n const { transform } = this;\n\n if (this.isContainer) {\n const childrenRects = transform.children.map(\n (c) => c.entity.getData<FlowNodeTransformData>(FlowNodeTransformData)!.boundsWithPadding\n );\n // Container 要加上 inlineSpacing\n return Rectangle.enlarge(childrenRects).withPadding(this.padding);\n }\n return transform.bounds; // 单个节点取默认的 bounds\n });\n }\n\n get boundsWithPadding(): Rectangle {\n return this.entity.memoGlobal<Rectangle>('boundsWithPadding', () => {\n const { transform } = this;\n\n if (this.isContainer) {\n const childrenRects = transform.children.map(\n (c) => c.entity.getData<FlowNodeTransformData>(FlowNodeTransformData)!.boundsWithPadding\n );\n return Rectangle.enlarge(childrenRects).withPadding(this.padding);\n }\n return transform.bounds.clone().withPadding(this.padding);\n });\n }\n\n get isContainer(): boolean {\n return this.transform.isContainer;\n }\n\n /**\n * 相对坐标 bbox, 这里的 localBounds 会加入 padding 一起算\n */\n get localBounds(): Rectangle {\n return this.entity.memoLocal<Rectangle>('localBounds', () => {\n const { transform } = this;\n\n if (this.isContainer) {\n const childrenRects = transform.children.map(\n (c) => c.entity.getData<FlowNodeTransformData>(FlowNodeTransformData)!.localBounds\n );\n const childrenBounds = Rectangle.enlarge(childrenRects).withPadding(this.padding);\n return Bounds.applyMatrix(childrenBounds, transform.localTransform);\n }\n\n return transform.localBounds.clone().withPadding(this.padding);\n });\n }\n\n get padding() {\n return this.entity.document.layout.getPadding(this.entity);\n }\n\n setParentTransform(transform?: FlowNodeTransformData): void {\n // 拖拽父元素变化需要重新布局\n if (this.transform.parent !== transform?.transform) {\n this.localDirty = true;\n }\n this.transform.setParent(transform?.transform);\n }\n\n get spacing(): number {\n const { spacing } = this.entity.getNodeMeta();\n return typeof spacing === 'function' ? spacing(this) : spacing;\n }\n\n get inlineSpacingPre(): number {\n const { inlineSpacingPre } = this.entity.getNodeMeta();\n return typeof inlineSpacingPre === 'function' ? inlineSpacingPre(this) : inlineSpacingPre;\n }\n\n get inlineSpacingAfter(): number {\n const { inlineSpacingAfter } = this.entity.getNodeMeta();\n return typeof inlineSpacingAfter === 'function' ? inlineSpacingAfter(this) : inlineSpacingAfter;\n }\n\n get minInlineBlockSpacing(): number {\n const { minInlineBlockSpacing } = this.entity.getNodeMeta();\n return typeof minInlineBlockSpacing === 'function'\n ? minInlineBlockSpacing(this)\n : minInlineBlockSpacing;\n }\n\n get children(): FlowNodeTransformData[] {\n return this.entity.children.map(\n (child) => child.getData<FlowNodeTransformData>(FlowNodeTransformData)!\n );\n }\n\n /**\n * 上一个节点的 transform 数据\n */\n get pre(): FlowNodeTransformData | undefined {\n return this.entity.pre?.getData<FlowNodeTransformData>(FlowNodeTransformData);\n }\n\n get originParent(): FlowNodeTransformData | undefined {\n return this.entity.originParent?.getData<FlowNodeTransformData>(FlowNodeTransformData);\n }\n\n get isFirst(): boolean {\n return this.entity.isFirst;\n }\n\n get isLast(): boolean {\n return this.entity.isLast;\n }\n\n get lastChild(): FlowNodeTransformData | undefined {\n return this.entity.lastChild?.getData<FlowNodeTransformData>(FlowNodeTransformData);\n }\n\n get firstChild(): FlowNodeTransformData | undefined {\n return this.entity.firstChild?.getData<FlowNodeTransformData>(FlowNodeTransformData);\n }\n\n /**\n * 下一个节点的 transform 数据\n */\n get next(): FlowNodeTransformData | undefined {\n return this.entity.next?.getData<FlowNodeTransformData>(FlowNodeTransformData);\n }\n\n /**\n * parent 节点的 transform 数据\n */\n get parent(): FlowNodeTransformData | undefined {\n return this.entity.parent?.getData<FlowNodeTransformData>(FlowNodeTransformData);\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Compare, Disposable, domUtils, Emitter } from '@flowgram.ai/utils';\nimport { EntityData } from '@flowgram.ai/core';\n\nimport { FlowNodeBaseType } from '../typings';\nimport type { FlowNodeEntity } from '../entities';\nimport { FlowNodeTransformData } from './index';\n\nexport interface FlowNodeRenderSchema {\n addable: boolean; // 是否可添加节点\n expandable: boolean; // 是否可展开\n collapsed?: boolean; // 复合节点是否收起\n expanded: boolean;\n activated: boolean; // 是否高亮节点\n hovered: boolean; // 是否悬浮在节点上\n dragging: boolean; // 是否正在拖拽\n stackIndex: number; // 渲染层级\n extInfo?: Record<string, any>; // 扩展渲染状态字段\n}\n\n/**\n * 节点渲染状态相关数据\n */\nexport class FlowNodeRenderData extends EntityData<FlowNodeRenderSchema> {\n static type = 'FlowNodeRenderData';\n\n declare entity: FlowNodeEntity;\n\n private _node?: HTMLDivElement;\n\n protected onExtInfoChangeEmitter = new Emitter<{ newInfo: any; oldInfo: any }>();\n\n readonly onExtInfoChange = this.onExtInfoChangeEmitter.event;\n\n get key(): string {\n return this.entity.id;\n }\n\n getDefaultData(): FlowNodeRenderSchema {\n const { addable, expandable, defaultExpanded } = this.entity.getNodeMeta();\n return {\n addable,\n expandable,\n expanded: defaultExpanded || false,\n activated: false,\n hovered: false,\n dragging: false,\n stackIndex: 0,\n };\n }\n\n updateExtInfo(info: Record<string, any>, fullUpdate?: boolean) {\n const oldInfo = this.data.extInfo;\n const newInfo = fullUpdate ? info : { ...oldInfo, ...info };\n if (Compare.isChanged(oldInfo, newInfo)) {\n this.update({\n extInfo: newInfo,\n });\n this.onExtInfoChangeEmitter.fire({ oldInfo, newInfo });\n }\n }\n\n getExtInfo(): Record<string, any> | undefined {\n return this.data.extInfo;\n }\n\n constructor(entity: FlowNodeEntity) {\n super(entity);\n this.toDispose.push(\n Disposable.create(() => {\n if (this._node) this._node.remove();\n })\n );\n }\n\n get addable(): boolean {\n return this.data.addable;\n }\n\n get expandable(): boolean {\n return this.data.expandable;\n }\n\n get draggable(): boolean {\n const { draggable } = this.entity.getNodeMeta();\n\n if (typeof draggable === 'function') {\n return draggable(this.entity);\n }\n\n return draggable;\n }\n\n get expanded(): boolean {\n return this.data.expanded;\n }\n\n set expanded(expanded: boolean) {\n if (this.expandable && this.data.expanded !== expanded) {\n this.data.expanded = expanded;\n this.fireChange();\n }\n }\n\n toggleExpand() {\n this.expanded = !this.expanded;\n }\n\n mouseLeaveTimeout?: ReturnType<typeof setTimeout>;\n\n toggleMouseEnter(silent = false) {\n this.entity.document.renderState.setNodeHovered(this.entity);\n if (silent) return;\n const transform = this.entity.getData(FlowNodeTransformData)!;\n if (transform.renderState.hidden) {\n return;\n }\n if (this.mouseLeaveTimeout) {\n clearTimeout(this.mouseLeaveTimeout);\n this.mouseLeaveTimeout = undefined;\n }\n\n transform.renderState.hovered = true;\n\n if (this.entity.isFirst && this.entity.parent?.id !== 'root') {\n // 分支中第一个节点 hover,parent activated 设置为 true\n transform.parent!.renderState.activated = true;\n } else {\n transform.renderState.activated = true;\n }\n }\n\n toggleMouseLeave(silent = false) {\n this.entity.document.renderState.setNodeHovered(undefined);\n if (silent) return;\n const transform = this.entity.getData(FlowNodeTransformData)!;\n this.mouseLeaveTimeout = setTimeout(() => {\n transform.renderState.hovered = false;\n\n if (this.entity.isFirst && this.entity.parent?.id !== 'root') {\n transform.parent!.renderState.activated = false;\n }\n transform.renderState.activated = false;\n }, 200);\n }\n\n get hidden(): boolean {\n return this.entity.hidden;\n }\n\n set hovered(hovered: boolean) {\n this.data.hovered = hovered;\n this.fireChange();\n }\n\n get hovered() {\n return this.data.hovered;\n }\n\n get dragging(): boolean {\n return this.data.dragging;\n }\n\n set dragging(dragging: boolean) {\n if (this.data.dragging !== dragging) {\n this.data.dragging = dragging;\n this.fireChange();\n }\n }\n\n set activated(activated: boolean) {\n if (this.entity.flowNodeType === FlowNodeBaseType.BLOCK_ICON && this.entity.parent) {\n this.entity.parent.getData<FlowNodeRenderData>(FlowNodeRenderData)!.activated = activated;\n return;\n }\n if (this.data.activated !== activated) {\n this.data.activated = activated;\n this.fireChange();\n }\n }\n\n get activated() {\n const { entity } = this;\n if (entity.parent && entity.parent.getData<FlowNodeRenderData>(FlowNodeRenderData)!.activated) {\n return true;\n }\n return this.data.activated;\n }\n\n get stackIndex(): number {\n return this.data.stackIndex;\n }\n\n set stackIndex(index: number) {\n this.data.stackIndex = index;\n }\n\n get lineActivated() {\n const { activated } = this;\n if (!activated) return false;\n // 只有 parent 高亮的情况才高亮下面的线条,否则只高亮 node\n // inlineBlock 仅看自身\n // 圈选情况下个节点被高量,则也跟着高量\n return Boolean(\n this.entity.parent?.getData(FlowNodeRenderData)?.activated ||\n this.entity.isInlineBlock ||\n this.entity.next?.getData(FlowNodeRenderData)!.activated\n );\n }\n\n get node(): HTMLDivElement {\n if (this._node) return this._node;\n this._node = domUtils.createDivWithClass('gedit-flow-activity-node');\n this._node.dataset.testid = 'sdk.workflow.canvas.node';\n this._node.dataset.nodeId = this.entity.id;\n return this._node;\n }\n\n dispose() {\n super.dispose();\n this.onExtInfoChangeEmitter.dispose();\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Point } from '@flowgram.ai/utils';\nimport { EntityData } from '@flowgram.ai/core';\n\nimport {\n FlowNodeBaseType,\n type FlowTransitionLabel,\n FlowTransitionLabelEnum,\n type FlowTransitionLine,\n FlowTransitionLineEnum,\n} from '../typings';\nimport { type FlowNodeEntity } from '../entities';\nimport { FlowNodeTransformData } from './flow-node-transform-data';\nimport { FlowNodeRenderData } from './flow-node-render-data';\n\nexport interface FlowNodeTransitionSchema {}\n\n// 画线到下一个节点\nexport const drawLineToNext = (transition: FlowNodeTransitionData) => {\n const { transform } = transition;\n\n // 默认绘制一根连接到下一个节点的线条\n const currentOutput = transform.outputPoint;\n if (transform.next) {\n return [\n {\n type: FlowTransitionLineEnum.STRAIGHT_LINE,\n from: currentOutput,\n to: transform.next.inputPoint,\n },\n ];\n }\n\n return [];\n};\n\n// 画线到父节点的结尾\nexport const drawLineToBottom = (transition: FlowNodeTransitionData) => {\n const { transform } = transition;\n\n const currentOutput = transform.outputPoint;\n const isParentRoot = transform.parent?.entity.flowNodeType === FlowNodeBaseType.ROOT;\n const parentOutput = transform.parent?.outputPoint;\n if (\n !isParentRoot &&\n !transform.next &&\n parentOutput &&\n !new Point().copyFrom(currentOutput).equals(parentOutput) &&\n !transition.isNodeEnd\n ) {\n return [\n {\n type: FlowTransitionLineEnum.STRAIGHT_LINE,\n from: currentOutput,\n to: parentOutput,\n },\n ];\n }\n\n return [];\n};\n\nexport class FlowNodeTransitionData extends EntityData<FlowNodeTransitionSchema> {\n static type = 'FlowNodeTransitionData';\n\n declare entity: FlowNodeEntity;\n\n // 当前节点的 transform\n declare transform: FlowNodeTransformData;\n\n declare renderData: FlowNodeRenderData;\n\n getDefaultData(): FlowNodeTransitionSchema {\n return {};\n }\n\n formatLines(lines: FlowTransitionLine[]) {\n if (this.entity.document.options?.formatNodeLines) {\n return this.entity.document.options?.formatNodeLines?.(this.entity, lines);\n }\n return lines;\n }\n\n formatLabels(labels: FlowTransitionLabel[]) {\n if (this.entity.document.options.formatNodeLabels) {\n return this.entity.document.options?.formatNodeLabels?.(this.entity, labels);\n }\n return labels;\n }\n\n get lines(): FlowTransitionLine[] {\n return this.entity.memoGlobal<FlowTransitionLine[]>('lines', () => {\n const { getChildLines } = this.entity.parent?.getNodeRegistry() || {};\n\n if (getChildLines) {\n return this.formatLines(getChildLines(this, this.entity.document.layout));\n }\n\n const { getLines } = this.entity.getNodeRegistry();\n\n if (getLines) {\n return this.formatLines(getLines(this, this.entity.document.layout));\n }\n\n // 横向布局不画线\n if (this.transform.entity.isInlineBlock) {\n return [];\n }\n\n return this.formatLines([...drawLineToNext(this), ...drawLineToBottom(this)]);\n });\n }\n\n get labels() {\n return this.entity.memoGlobal<FlowTransitionLabel[]>('labels', () => {\n const { getChildLabels } = this.entity.parent?.getNodeRegistry() || {};\n\n if (getChildLabels) {\n return this.formatLabels(getChildLabels(this, this.entity.document.layout));\n }\n\n const { getLabels } = this.entity.getNodeRegistry();\n\n if (getLabels) {\n return this.formatLabels(getLabels(this, this.entity.document.layout));\n }\n\n // 横向布局不画加号\n if (this.transform.entity.isInlineBlock) {\n return [];\n }\n\n // 默认在中间点添加一个加号\n const currentOutput = this.transform.outputPoint;\n if (this.transform.next) {\n return this.formatLabels([\n {\n offset: Point.getMiddlePoint(currentOutput, this.transform.next.inputPoint),\n type: FlowTransitionLabelEnum.ADDER_LABEL,\n },\n ]);\n }\n\n const parentOutput = this.transform.parent?.outputPoint;\n if (\n parentOutput &&\n !new Point().copyFrom(currentOutput).equals(parentOutput) &&\n !this.isNodeEnd\n ) {\n return this.formatLabels([\n {\n offset: parentOutput,\n type: FlowTransitionLabelEnum.ADDER_LABEL,\n },\n ]);\n }\n\n return [];\n });\n }\n\n constructor(entity: FlowNodeEntity) {\n super(entity);\n this.transform = this.entity.addData<FlowNodeTransformData>(FlowNodeTransformData);\n this.renderData = this.entity.addData<FlowNodeRenderData>(FlowNodeRenderData);\n\n this.bindChange(this.transform);\n this.bindChange(this.renderData);\n }\n\n get collapsed() {\n return this.entity.collapsed;\n }\n\n get isNodeEnd(): boolean {\n return this.entity.isNodeEnd;\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Emitter } from '@flowgram.ai/utils';\nimport { ConfigEntity, type EntityOpts } from '@flowgram.ai/core';\n\nimport type { FlowDocument } from '../flow-document';\nimport { FlowNodeTransformData } from '../datas';\n\ninterface FlowDocumentTransformerEntityConfig extends EntityOpts {\n document: FlowDocument;\n}\n\n/**\n * 用于通知所有 layer 更新\n */\nexport class FlowDocumentTransformerEntity extends ConfigEntity<\n {\n loading: boolean;\n treeVersion: number;\n },\n FlowDocumentTransformerEntityConfig\n> {\n static type = 'FlowDocumentTransformerEntity';\n\n protected onRefreshEmitter = new Emitter<void>();\n\n protected lastTransformVersion = -1;\n\n protected lastTreeVersion = -1;\n\n document: FlowDocument;\n\n readonly onRefresh = this.onRefreshEmitter.event;\n\n constructor(conf: FlowDocumentTransformerEntityConfig) {\n super(conf);\n this.document = conf.document;\n this.toDispose.push(\n this.document.originTree.onTreeChange(() => {\n this.config.treeVersion += 1;\n this.fireChange();\n })\n );\n this.toDispose.push(this.onRefreshEmitter);\n }\n\n getDefaultConfig(): { loading: boolean; treeVersion: number } {\n return {\n loading: true,\n treeVersion: 0,\n };\n }\n\n get loading(): boolean {\n return this.config.loading;\n }\n\n set loading(loading) {\n if (this.config.loading !== loading) {\n this.config.loading = loading;\n this.fireChange();\n }\n }\n\n /**\n * 更新矩阵结构 (这个只有在树结构变化时候才会触发,如:添加节点、删除节点、改变位置节点)\n */\n updateTransformsTree(): void {\n // 更新 node 结构树\n this.document.renderTree.traverse((node, depth, index) => {\n const transform = node.getData<FlowNodeTransformData>(FlowNodeTransformData)!;\n // 收起时清空子节点\n if (transform.collapsed) {\n transform.transform.clearChildren();\n }\n if (node.parent) {\n transform.setParentTransform(node.parent!.getData(FlowNodeTransformData));\n }\n // 更新 index\n node.index = index;\n });\n }\n\n clear(): void {\n this.lastTreeVersion = -1;\n this.lastTransformVersion = -1;\n }\n\n isTreeDirty(): boolean {\n const transformVersion = this.entityManager.getEntityDataVersion(FlowNodeTransformData);\n const isTreeVersionChanged = this.lastTreeVersion !== this.config.treeVersion;\n const isTransformVersionChanged = this.lastTransformVersion !== transformVersion;\n return isTreeVersionChanged || isTransformVersionChanged;\n }\n\n /**\n * 刷新节点的相对偏移\n */\n refresh(): void {\n const transformVersion = this.entityManager.getEntityDataVersion(FlowNodeTransformData);\n\n const isTreeVersionChanged = this.lastTreeVersion !== this.config.treeVersion;\n const isTransformVersionChanged = this.lastTransformVersion !== transformVersion;\n\n this.entityManager.changeEntityLocked = true;\n if (isTreeVersionChanged) {\n this.document.renderTree.updateRenderStruct(); // 重新调整 renderTree 结构\n this.updateTransformsTree(); // 更新树结构\n this.lastTreeVersion = this.config.treeVersion;\n }\n\n if (isTreeVersionChanged || isTransformVersionChanged) {\n // 位置计算不需要重新触发 Layer 刷新\n this.document.layout.update(); // 更新布局\n this.lastTransformVersion = this.entityManager.getEntityDataVersion(FlowNodeTransformData);\n this.lastTreeVersion = this.config.treeVersion;\n this.onRefreshEmitter.fire();\n }\n\n this.entityManager.changeEntityLocked = false;\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { debounce } from 'lodash-es';\nimport { type Disposable } from '@flowgram.ai/utils';\nimport { ConfigEntity, type EntityOpts } from '@flowgram.ai/core';\n\nimport { LABEL_SIDE_TYPE } from '../typings';\nimport { type FlowNodeEntity } from './flow-node-entity';\n\ninterface FlowRendererStateEntityConfig extends EntityOpts {}\n\ninterface FlowRendererState {\n nodeHoveredId?: string;\n nodeDroppingId?: string;\n nodeDragStartId?: string;\n nodeDragIds?: string[]; // 框选批量拖拽\n nodeDragIdsWithChildren?: string[]; // 批量拖拽(含子节点)\n dragLabelSide?: LABEL_SIDE_TYPE;\n dragging?: boolean;\n isBranch?: boolean;\n}\n/**\n * 渲染相关的全局状态管理\n */\nexport class FlowRendererStateEntity extends ConfigEntity<\n FlowRendererState,\n FlowRendererStateEntityConfig\n> {\n static type = 'FlowRendererStateEntity';\n\n getDefaultConfig() {\n return {};\n }\n\n constructor(conf: FlowRendererStateEntityConfig) {\n super(conf);\n }\n\n getNodeHovered(): FlowNodeEntity | undefined {\n return this.config.nodeHoveredId\n ? this.entityManager.getEntityById(this.config.nodeHoveredId)\n : undefined;\n }\n\n setNodeHovered(node: FlowNodeEntity | undefined): void {\n this.updateConfig({\n nodeHoveredId: node?.id,\n });\n }\n\n get dragging() {\n return this.config.dragging;\n }\n\n setDragging(dragging: boolean) {\n this.updateConfig({\n dragging,\n });\n }\n\n get isBranch() {\n return this.config.isBranch;\n }\n\n setIsBranch(isBranch: boolean) {\n this.updateConfig({\n isBranch,\n });\n }\n\n getDragLabelSide(): LABEL_SIDE_TYPE | undefined {\n return this.config.dragLabelSide;\n }\n\n setDragLabelSide(dragLabelSide?: LABEL_SIDE_TYPE): void {\n this.updateConfig({\n dragLabelSide,\n });\n }\n\n getNodeDroppingId(): string | undefined {\n return this.config.nodeDroppingId;\n }\n\n setNodeDroppingId(nodeDroppingId?: string): void {\n this.updateConfig({\n nodeDroppingId,\n });\n }\n\n getDragStartEntity(): FlowNodeEntity | undefined {\n const { nodeDragStartId } = this.config;\n return this.entityManager.getEntityById(nodeDragStartId!);\n }\n\n setDragStartEntity(node?: FlowNodeEntity): void {\n this.updateConfig({\n nodeDragStartId: node?.id,\n });\n }\n\n // 拖拽多个节点时\n getDragEntities(): FlowNodeEntity[] {\n const { nodeDragIds } = this.config;\n return (nodeDragIds || []).map((_id) => this.entityManager.getEntityById(_id)!);\n }\n\n // 设置拖拽的节点\n setDragEntities(nodes: FlowNodeEntity[]): void {\n this.updateConfig({\n nodeDragIds: nodes.map((_node) => _node.id),\n nodeDragIdsWithChildren: nodes\n .map((_node) => [_node.id, ..._node.allCollapsedChildren.map((_n) => _n.id)])\n .flat(),\n });\n }\n\n onNodeHoveredChange(\n fn: (hoveredNode: FlowNodeEntity | undefined) => void,\n debounceTime = 100 // 延迟执行避免频繁 hover\n ): Disposable {\n return this.onConfigChanged(debounce(() => fn(this.getNodeHovered()), debounceTime));\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { omit } from 'lodash-es';\nimport { inject, injectable, multiInject, optional, postConstruct } from 'inversify';\nimport { type Disposable, Emitter } from '@flowgram.ai/utils';\nimport { type EntityData, type EntityDataRegistry, EntityManager } from '@flowgram.ai/core';\n\nimport {\n AddNodeData,\n DEFAULT_FLOW_NODE_META,\n type FlowDocumentJSON,\n FlowLayout,\n FlowLayoutDefault,\n FlowNodeBaseType,\n type FlowNodeJSON,\n FlowNodeRegistry,\n FlowNodeType,\n} from './typings';\nimport { FlowVirtualTree } from './flow-virtual-tree';\nimport { FlowRenderTree } from './flow-render-tree';\nimport {\n ConstantKeys,\n FlowDocumentOptions,\n FlowDocumentOptionsDefault,\n} from './flow-document-options';\nimport { FlowDocumentContribution } from './flow-document-contribution';\nimport { FlowDocumentConfig } from './flow-document-config';\nimport { FlowDocumentTransformerEntity, FlowNodeEntity, FlowRendererStateEntity } from './entities';\n\nexport type FlowDocumentProvider = () => FlowDocument;\nexport const FlowDocumentProvider = Symbol('FlowDocumentProvider');\n/**\n * 流程整个文档数据\n */\n@injectable()\nexport class FlowDocument<T = FlowDocumentJSON> implements Disposable {\n @inject(EntityManager) protected entityManager: EntityManager;\n\n @inject(FlowDocumentConfig) readonly config: FlowDocumentConfig;\n\n /**\n * 流程画布配置项\n */\n @inject(FlowDocumentOptions) @optional() public options: FlowDocumentOptions;\n\n @multiInject(FlowDocumentContribution)\n @optional()\n protected contributions: FlowDocumentContribution[] = [];\n\n protected registers = new Map<FlowNodeType, FlowNodeRegistry>();\n\n private nodeRegistryCache = new Map<string, any>();\n\n protected nodeDataRegistries: EntityDataRegistry[] = [];\n\n protected layouts: FlowLayout[] = [];\n\n protected currentLayoutKey: string = '';\n\n protected onNodeUpdateEmitter = new Emitter<{\n node: FlowNodeEntity;\n /**\n * use 'json' instead\n * @deprecated\n */\n data: FlowNodeJSON;\n json: FlowNodeJSON;\n }>();\n\n protected onNodeCreateEmitter = new Emitter<{\n node: FlowNodeEntity;\n /**\n * use 'json' instead\n * @deprecated\n */\n data: FlowNodeJSON;\n json: FlowNodeJSON;\n }>();\n\n protected onNodeDisposeEmitter = new Emitter<{\n node: FlowNodeEntity;\n }>();\n\n protected onLayoutChangeEmitter = new Emitter<FlowLayout>();\n\n readonly onNodeUpdate = this.onNodeUpdateEmitter.event;\n\n readonly onNodeCreate = this.onNodeCreateEmitter.event;\n\n readonly onNodeDispose = this.onNodeDisposeEmitter.event;\n\n readonly onLayoutChange = this.onLayoutChangeEmitter.event;\n\n private _disposed = false;\n\n root: FlowNodeEntity;\n\n /**\n * 原始的 tree 结构\n */\n originTree: FlowVirtualTree<FlowNodeEntity>;\n\n transformer: FlowDocumentTransformerEntity;\n\n /**\n * 渲染相关的全局轧辊台\n */\n renderState: FlowRendererStateEntity;\n\n /**\n * 渲染后的 tree 结构\n */\n renderTree: FlowRenderTree<FlowNodeEntity>;\n\n /**\n *\n */\n get disposed(): boolean {\n return this._disposed;\n }\n\n @postConstruct()\n init(): void {\n if (!this.options) this.options = FlowDocumentOptionsDefault;\n this.currentLayoutKey = this.options.defaultLayout || FlowLayoutDefault.VERTICAL_FIXED_LAYOUT;\n this.contributions.forEach((contrib) => contrib.registerDocument?.(this));\n this.root = this.addNode({ id: 'root', type: FlowNodeBaseType.ROOT });\n this.originTree = new FlowVirtualTree<FlowNodeEntity>(this.root);\n this.transformer = this.entityManager.createEntity<FlowDocumentTransformerEntity>(\n FlowDocumentTransformerEntity,\n { document: this }\n );\n this.renderState =\n this.entityManager.createEntity<FlowRendererStateEntity>(FlowRendererStateEntity);\n this.renderTree = new FlowRenderTree<FlowNodeEntity>(this.root, this.originTree, this);\n // 布局第一次加载时候触发一次\n this.layout.reload?.();\n }\n\n /**\n * 从数据初始化 O(n)\n * @param json\n */\n /**\n * 加载数据,可以被重载\n * @param json 文档数据更新\n * @param fireRender 是否要触发渲染,默认 true\n */\n fromJSON(json: FlowDocumentJSON | any, fireRender = true): void {\n if (this._disposed) return;\n // 清空 tree 数据 重新计算\n this.originTree.clear();\n this.renderTree.clear();\n // 暂停触发画布更新\n this.entityManager.changeEntityLocked = true;\n // 添加前的节点\n const oldNodes = this.entityManager.getEntities<FlowNodeEntity>(FlowNodeEntity);\n // 添加后的节点\n const newNodes: FlowNodeEntity[] = [this.root];\n this.addBlocksAsChildren(this.root, json.nodes || [], newNodes);\n // 删除无效的节点\n oldNodes.forEach((node) => {\n if (!newNodes.includes(node)) {\n node.dispose();\n }\n });\n this.entityManager.changeEntityLocked = false;\n this.transformer.loading = false;\n if (fireRender) this.fireRender();\n }\n\n get layout(): FlowLayout {\n const layout = this.layouts.find((layout) => layout.name == this.currentLayoutKey);\n if (!layout) {\n throw new Error(`Unknown flow layout: ${this.currentLayoutKey}`);\n }\n return layout;\n }\n\n async load(): Promise<void> {\n await Promise.all(this.contributions.map((c) => c.loadDocument?.(this)));\n }\n\n get loading(): boolean {\n return this.transformer.loading;\n }\n\n /**\n * 触发 render\n */\n fireRender(): void {\n if (this.transformer.isTreeDirty()) {\n this.entityManager.fireEntityChanged(FlowNodeEntity.type);\n this.entityManager.fireEntityChanged(FlowDocumentTransformerEntity.type);\n }\n }\n\n /**\n * 从指定节点的下一个节点新增\n * @param fromNode\n * @param json\n */\n addFromNode(fromNode: FlowNodeEntity | string, json: FlowNodeJSON): FlowNodeEntity {\n const node = typeof fromNode === 'string' ? this.getNode(fromNode)! : fromNode;\n this.entityManager.changeEntityLocked = true;\n const { parent } = node;\n const result = this.addNode({\n ...json,\n parent,\n // originParent,\n });\n this.originTree.insertAfter(node, result);\n this.entityManager.changeEntityLocked = false;\n this.entityManager.fireEntityChanged(FlowNodeEntity.type);\n return result;\n }\n\n removeNode(node: FlowNodeEntity | string) {\n if (typeof node === 'string') {\n this.getNode(node)?.dispose();\n } else {\n node.dispose();\n }\n }\n\n /**\n * 添加节点,如果节点已经存在则不会重复创建\n * @param data\n * @param addedNodes\n */\n addNode(data: AddNodeData, addedNodes?: FlowNodeEntity[]): FlowNodeEntity {\n const { id, type = 'block', originParent, parent, meta, hidden, index } = data;\n let node = this.getNode(id);\n let isNew = false;\n const register = this.getNodeRegistry(type, data.originParent);\n // node 类型变化则全部删除重新来\n if (node && node.flowNodeType !== data.type) {\n node.dispose();\n node = undefined;\n }\n if (!node) {\n const { dataRegistries } = register;\n node = this.entityManager.createEntity<FlowNodeEntity>(FlowNodeEntity, {\n id,\n document: this,\n flowNodeType: type,\n originParent,\n meta,\n });\n this.options.preNodeCreate?.(node);\n const datas = dataRegistries\n ? this.nodeDataRegistries.concat(...dataRegistries)\n : this.nodeDataRegistries;\n node.addInitializeData(datas);\n node.onDispose(() => this.onNodeDisposeEmitter.fire({ node: node! }));\n this.options.fromNodeJSON?.(node, data, true);\n isNew = true;\n } else {\n this.options.fromNodeJSON?.(node, data, false);\n }\n // 初始化数据重制\n node.initData({\n originParent,\n parent,\n meta,\n hidden,\n index,\n });\n // 开始节点加到 root 里边\n if (node.isStart) {\n this.root.addChild(node);\n }\n addedNodes?.push(node);\n // 自定义创建逻辑\n if (register.onCreate) {\n const extendNodes = register.onCreate(node, data);\n if (extendNodes && addedNodes) {\n addedNodes.push(...extendNodes);\n }\n } else if (data.blocks && data.blocks.length > 0) {\n // 兼容老的写法\n if (!data.blocks[0].type) {\n this.addInlineBlocks(node, data.blocks, addedNodes);\n } else {\n this.addBlocksAsChildren(node, data.blocks as FlowNodeJSON[], addedNodes);\n }\n }\n\n if (isNew) {\n this.onNodeCreateEmitter.fire({\n node,\n data,\n json: data,\n });\n } else {\n this.onNodeUpdateEmitter.fire({ node, data, json: data });\n }\n\n return node;\n }\n\n addBlocksAsChildren(\n parent: FlowNodeEntity,\n blocks: FlowNodeJSON[],\n addedNodes?: FlowNodeEntity[]\n ): void {\n for (const block of blocks) {\n this.addNode(\n {\n ...block,\n parent,\n },\n addedNodes\n );\n }\n }\n\n /**\n * block 格式:\n * node: (最原始的 id)\n * blockIcon\n * inlineBlocks\n * block\n * blockOrderIcon\n * block\n * blockOrderIcon\n * @param node\n * @param blocks\n * @param addedNodes\n */\n addInlineBlocks(\n node: FlowNodeEntity,\n blocks: FlowNodeJSON[],\n addedNodes: FlowNodeEntity[] = []\n ): FlowNodeEntity[] {\n // 块列表开始节点,用来展示块的按钮\n const blockIconNode = this.addNode({\n id: `$blockIcon$${node.id}`,\n type: FlowNodeBaseType.BLOCK_ICON,\n originParent: node,\n parent: node,\n });\n addedNodes.push(blockIconNode);\n // 水平布局\n const inlineBlocksNode = this.addNode({\n id: `$inlineBlocks$${node.id}`,\n type: FlowNodeBaseType.INLINE_BLOCKS,\n originParent: node,\n parent: node,\n });\n addedNodes.push(inlineBlocksNode);\n blocks.forEach((blockData) => {\n this.addBlock(node, blockData, addedNodes);\n });\n return addedNodes;\n }\n\n /**\n * 添加单个 block\n * @param target\n * @param blockData\n * @param addedNodes\n * @param parent 默认去找 $inlineBlocks$\n */\n addBlock(\n target: FlowNodeEntity | string,\n blockData: FlowNodeJSON,\n addedNodes?: FlowNodeEntity[],\n parent?: FlowNodeEntity,\n index?: number\n ): FlowNodeEntity {\n const node: FlowNodeEntity = typeof target === 'string' ? this.getNode(target)! : target;\n const { onBlockChildCreate } = node.getNodeRegistry();\n if (onBlockChildCreate) {\n return onBlockChildCreate(node, blockData, addedNodes);\n }\n parent = parent || this.getNode(`$inlineBlocks$${node.id}`);\n // 块节点会生成一个空的 Block 节点用来切割 Block\n const block = this.addNode({\n ...omit(blockData, 'blocks'),\n type: blockData.type || FlowNodeBaseType.BLOCK,\n originParent: node,\n parent,\n index,\n });\n\n if (blockData.meta?.defaultCollapsed) {\n block.collapsed = true;\n }\n\n // 块开始节点\n const blockOrderIcon = this.addNode({\n id: `$blockOrderIcon$${blockData.id}`,\n type: FlowNodeBaseType.BLOCK_ORDER_ICON,\n originParent: node,\n meta: blockData.meta,\n data: blockData.data,\n parent: block,\n });\n addedNodes?.push(block, blockOrderIcon);\n if (blockData.blocks) {\n this.addBlocksAsChildren(block, blockData.blocks as FlowNodeJSON[], addedNodes);\n }\n return block;\n }\n\n /**\n * 根据 id 获取节点\n * @param id\n */\n getNode(id: string): FlowNodeEntity | undefined {\n if (!id) return undefined;\n return this.entityManager.getEntityById<FlowNodeEntity>(id);\n }\n\n /**\n * 注册节点\n * @param registries\n */\n registerFlowNodes<T extends FlowNodeRegistry<any>>(...registries: T[]): void {\n registries.forEach((newRegistry) => {\n if (!newRegistry) {\n throw new Error('[FlowDocument] registerFlowNodes parameters get undefined registry.');\n }\n const preRegistry = this.registers.get(newRegistry.type);\n this.registers.set(newRegistry.type, {\n ...preRegistry,\n ...newRegistry,\n meta: {\n ...preRegistry?.meta,\n ...newRegistry?.meta,\n },\n extendChildRegistries: FlowNodeRegistry.mergeChildRegistries(\n preRegistry?.extendChildRegistries,\n newRegistry?.extendChildRegistries\n ),\n });\n });\n }\n\n /**\n * Check node extend\n * @param currentType\n * @param extendType\n */\n isExtend(currentType: FlowNodeType, extendType: FlowNodeType): boolean {\n return (this.getNodeRegistry(currentType).__extends__ || []).includes(extendType);\n }\n\n /**\n * Check node type\n * @param currentType\n * @param extendType\n */\n isTypeOrExtendType(currentType: FlowNodeType, extendType: FlowNodeType): boolean {\n return currentType === extendType || this.isExtend(currentType, extendType);\n }\n\n /**\n * 导出数据,可以重载\n */\n toJSON(): T | any {\n if (this.disposed) {\n throw new Error(\n 'The FlowDocument has been disposed and it is no longer possible to call toJSON.'\n );\n }\n return {\n nodes: this.root.toJSON().blocks,\n };\n }\n\n /**\n * @deprecated\n * use `getNodeRegistry` instead\n */\n getNodeRegister<T extends FlowNodeRegistry = FlowNodeRegistry>(\n type: FlowNodeType,\n originParent?: FlowNodeEntity\n ): T {\n return this.getNodeRegistry<T>(type, originParent);\n }\n\n getNodeRegistry<T extends FlowNodeRegistry = FlowNodeRegistry>(\n type: FlowNodeType,\n originParent?: FlowNodeEntity\n ): T {\n const typeKey = `${type}_${originParent?.flowNodeType || ''}`;\n if (this.nodeRegistryCache.has(typeKey)) {\n return this.nodeRegistryCache.get(typeKey) as T;\n }\n const customDefaultRegistry = this.options.getNodeDefaultRegistry?.(type);\n let register = this.registers.get(type) || { type };\n const extendRegisters: FlowNodeRegistry[] = [];\n const extendKey = register.extend;\n // 继承重载\n if (register.extend && this.registers.has(register.extend)) {\n register = FlowNodeRegistry.merge(\n this.getNodeRegistry(register.extend),\n register,\n register.type\n );\n }\n // 父节点覆盖\n if (originParent) {\n const extendRegister = this.getNodeRegistry(\n originParent.flowNodeType\n ).extendChildRegistries?.find((r) => r.type === type);\n if (extendRegister) {\n if (extendRegister.extend && this.registers.has(extendRegister.extend)) {\n extendRegisters.push(this.registers.get(extendRegister.extend)!);\n }\n extendRegisters.push(extendRegister);\n }\n }\n register = FlowNodeRegistry.extend(register, extendRegisters);\n const defaultNodeMeta = DEFAULT_FLOW_NODE_META(type, this);\n defaultNodeMeta.spacing =\n this.options?.constants?.[ConstantKeys.NODE_SPACING] || defaultNodeMeta.spacing;\n\n const res = {\n ...customDefaultRegistry,\n ...register,\n meta: {\n ...defaultNodeMeta,\n ...customDefaultRegistry?.meta,\n ...register.meta,\n },\n } as T;\n // Save the \"extend\" attribute\n if (extendKey) {\n res.extend = extendKey;\n }\n this.nodeRegistryCache.set(typeKey, res);\n return res;\n }\n\n /**\n * 节点注入数据\n * @param nodeDatas\n */\n registerNodeDatas(...nodeDatas: EntityDataRegistry[]): void {\n this.nodeDataRegistries.push(...nodeDatas);\n }\n\n /**\n * traverse all nodes, O(n)\n * R\n * |\n * +---1\n * | |\n * | +---1.1\n * | |\n * | +---1.2\n * | |\n * | +---1.3\n * | | |\n * | | +---1.3.1\n * | | |\n * | | +---1.3.2\n * | |\n * | +---1.4\n * |\n * +---2\n * |\n * +---2.1\n *\n * sort: [1, 1.1, 1.2, 1.3, 1.3.1, 1.3.2, 1.4, 2, 2.1]\n * @param fn\n * @param node\n * @param depth\n * @return isBreak\n */\n traverse(\n fn: (node: FlowNodeEntity, depth: number, index: number) => boolean | void,\n node = this.root,\n depth = 0\n ): boolean | void {\n return this.originTree.traverse(fn, node, depth);\n }\n\n get size(): number {\n return this.getAllNodes().length;\n }\n\n hasNode(nodeId: string): boolean {\n return !!this.entityManager.getEntityById(nodeId);\n }\n\n getAllNodes(): FlowNodeEntity[] {\n return this.entityManager.getEntities(FlowNodeEntity);\n }\n\n toString(showType?: boolean): string {\n return this.originTree.toString(showType);\n }\n\n /**\n * 返回需要渲染的数据\n */\n getRenderDatas<T extends EntityData>(\n dataRegistry: EntityDataRegistry<T>,\n containHiddenNodes = true\n ): T[] {\n const result: T[] = [];\n this.renderTree.traverse((node) => {\n if (!containHiddenNodes && node.hidden) return;\n result.push(node.getData<T>(dataRegistry)!);\n });\n return result;\n }\n\n toNodeJSON(node: FlowNodeEntity): FlowNodeJSON {\n if (this.options.toNodeJSON) {\n return this.options.toNodeJSON(node);\n }\n const nodesMap: Record<string, FlowNodeJSON> = {};\n let startNodeJSON: FlowNodeJSON;\n this.traverse((node) => {\n const isSystemNode = node.id.startsWith('$');\n if (isSystemNode) return;\n const nodeJSONData = node.getJSONData();\n const nodeJSON: FlowNodeJSON = {\n id: node.id,\n type: node.flowNodeType,\n };\n if (nodeJSONData !== undefined) {\n nodeJSON.data = nodeJSONData;\n }\n if (!startNodeJSON) startNodeJSON = nodeJSON;\n let { parent } = node;\n if (parent && parent.id.startsWith('$')) {\n parent = parent.originParent;\n }\n const parentJSON = parent ? nodesMap[parent.id] : undefined;\n if (parentJSON) {\n if (!parentJSON.blocks) {\n parentJSON.blocks = [];\n }\n parentJSON.blocks.push(nodeJSON);\n }\n nodesMap[node.id] = nodeJSON;\n }, node);\n return startNodeJSON!;\n }\n\n /**\n * 移动节点\n * @param param0\n * @returns\n */\n moveNodes({\n dropNodeId,\n sortNodeIds,\n inside = false,\n }: {\n dropNodeId: string;\n sortNodeIds: string[];\n inside?: boolean;\n }) {\n const dropEntity = this.getNode(dropNodeId);\n if (!dropEntity) {\n return;\n }\n\n const sortNodes = sortNodeIds.map((id) => this.getNode(id)!);\n\n // 按照顺序一个个移动到目标节点下\n this.entityManager.changeEntityLocked = true;\n for (const node of sortNodes.reverse()) {\n if (inside) {\n this.originTree.addChild(dropEntity, node, 0);\n } else {\n this.originTree.insertAfter(dropEntity, node);\n }\n }\n\n this.entityManager.changeEntityLocked = false;\n this.fireRender();\n }\n\n /**\n * 移动子节点\n * @param param0\n * @returns\n */\n moveChildNodes({\n toParentId,\n toIndex,\n nodeIds,\n }: {\n toParentId: string;\n nodeIds: string[];\n toIndex: number;\n }) {\n if (nodeIds.length === 0) {\n return;\n }\n\n const toParent = this.getNode(toParentId);\n if (!toParent) {\n return;\n }\n\n this.entityManager.changeEntityLocked = true;\n\n this.originTree.moveChilds(\n toParent,\n nodeIds.map((nodeId) => this.getNode(nodeId) as FlowNodeEntity),\n toIndex\n );\n\n this.entityManager.changeEntityLocked = false;\n this.fireRender();\n }\n\n /**\n * 注册布局\n * @param layout\n */\n registerLayout(layout: FlowLayout) {\n this.layouts.push(layout);\n }\n\n /**\n * 更新布局\n * @param layoutKey\n */\n setLayout(layoutKey: string) {\n if (this.currentLayoutKey === layoutKey) return;\n const layout = this.layouts.find((layout) => layout.name === layoutKey);\n if (!layout) return;\n this.currentLayoutKey = layoutKey;\n this.transformer.clear();\n layout.reload?.();\n this.fireRender();\n this.onLayoutChangeEmitter.fire(this.layout);\n }\n\n /**\n * 切换垂直或水平布局\n */\n toggleFixedLayout() {\n this.setLayout(\n this.layout.name === FlowLayoutDefault.HORIZONTAL_FIXED_LAYOUT\n ? FlowLayoutDefault.VERTICAL_FIXED_LAYOUT\n : FlowLayoutDefault.HORIZONTAL_FIXED_LAYOUT\n );\n }\n\n dispose() {\n if (this._disposed) return;\n this.registers.clear();\n this.nodeRegistryCache.clear();\n this.originTree.dispose();\n this.renderTree.dispose();\n this.onNodeUpdateEmitter.dispose();\n this.onNodeCreateEmitter.dispose();\n this.onNodeDisposeEmitter.dispose();\n this.onLayoutChangeEmitter.dispose();\n this._disposed = true;\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { type Disposable, Emitter } from '@flowgram.ai/utils';\n\nimport { type FlowNodeType } from './typings';\n\n/**\n * 存储节点的 tree 结构信息\n * 策略是 \"重修改轻查询\",即修改时候做的事情更多,查询都通过指针来操作\n */\nexport class FlowVirtualTree<T extends { id: string; flowNodeType?: FlowNodeType }>\n implements Disposable\n{\n protected onTreeChangeEmitter = new Emitter<void>();\n\n /**\n * tree 结构变化时候触发\n */\n onTreeChange = this.onTreeChangeEmitter.event;\n\n protected map: Map<T, FlowVirtualTree.NodeInfo<T>> = new Map();\n\n constructor(readonly root: T) {}\n\n dispose() {\n this.map.clear();\n this.onTreeChangeEmitter.dispose();\n }\n\n getInfo(node: T): FlowVirtualTree.NodeInfo<T> {\n let res: FlowVirtualTree.NodeInfo<T> | undefined = this.map.get(node);\n if (!res) {\n res = { children: [] };\n this.map.set(node, res);\n }\n return res;\n }\n\n clear(): void {\n this.map.clear();\n }\n\n cloneMap(): Map<T, FlowVirtualTree.NodeInfo<T>> {\n const newMap: Map<T, FlowVirtualTree.NodeInfo<T>> = new Map();\n for (const [key, value] of this.map) {\n newMap.set(key, {\n ...value,\n children: value.children.slice(),\n });\n }\n\n return newMap;\n }\n\n clone(): FlowVirtualTree<T> {\n const newTree = new FlowVirtualTree<T>(this.root);\n newTree.map = this.cloneMap();\n return newTree;\n }\n\n remove(node: T, withChildren = true): void {\n this.removeParent(node);\n if (withChildren) {\n this._removeChildren(node);\n }\n this.map.delete(node);\n this.fireTreeChange();\n }\n\n addChild(parent: T, child: T, index?: number): T {\n const parentInfo = this.getInfo(parent);\n const childInfo = this.getInfo(child);\n if (childInfo.parent) {\n if (childInfo.parent === parent) return child;\n if (childInfo.parent !== parent) {\n this.removeParent(child);\n }\n }\n\n const len = parentInfo.children.length;\n const idx = typeof index === 'undefined' ? len - 1 : index - 1;\n const lastChild = parentInfo.children[idx];\n const nextChild = parentInfo.children[idx + 1];\n if (lastChild) this.getInfo(lastChild).next = child;\n if (nextChild) this.getInfo(nextChild).pre = child;\n childInfo.pre = lastChild;\n childInfo.next = nextChild;\n parentInfo.children.splice(idx + 1, 0, child);\n childInfo.parent = parent;\n this.fireTreeChange();\n return child;\n }\n\n moveChilds(parent: T, childs: T[], index?: number): T[] {\n const parentInfo = this.getInfo(parent);\n const len = parentInfo.children.length;\n let childIndex: number = index ?? len;\n\n childs.forEach((child) => {\n const childInfo = this.getInfo(child);\n if (childInfo.parent) {\n this.removeParent(child);\n }\n });\n\n childs.forEach((child) => {\n const childInfo = this.getInfo(child);\n let lastChild: T | undefined = parentInfo.children[childIndex - 1];\n let nextChild: T | undefined = parentInfo.children[childIndex];\n\n if (lastChild) this.getInfo(lastChild).next = child;\n if (nextChild) this.getInfo(nextChild).pre = child;\n childInfo.pre = lastChild;\n childInfo.next = nextChild;\n parentInfo.children.splice(childIndex, 0, child);\n childInfo.parent = parent;\n childIndex++;\n });\n\n this.fireTreeChange();\n return childs;\n }\n\n getById(id: string): T | undefined {\n for (const node of this.map.keys()) {\n if (node.id === id) return node;\n }\n }\n\n /**\n * 插入节点到后边\n * @param before\n * @param after\n */\n insertAfter(before: T, after: T) {\n const beforeInfo = this.getInfo(before);\n const afterInfo = this.getInfo(after);\n this.removeParent(after);\n if (beforeInfo.parent) {\n const parentInfo = this.getInfo(beforeInfo.parent);\n parentInfo.children.splice(parentInfo.children.indexOf(before) + 1, 0, after);\n const { next } = beforeInfo;\n if (next) {\n this.getInfo(next).pre = after;\n }\n afterInfo.next = next;\n beforeInfo.next = after;\n afterInfo.pre = before;\n afterInfo.parent = beforeInfo.parent;\n }\n this.fireTreeChange();\n }\n\n removeParent(node: T): void {\n const info = this.getInfo(node);\n if (!info.parent) return;\n const parentInfo = this.getInfo(info.parent);\n const index = parentInfo.children.indexOf(node);\n parentInfo.children.splice(index, 1);\n const { pre, next } = info;\n if (pre) this.getInfo(pre).next = next;\n if (next) this.getInfo(next).pre = pre;\n this.fireTreeChange();\n }\n\n private _removeChildren(node: T): void {\n // 删除子节点\n const children = this.getChildren(node);\n if (children.length > 0) {\n children.forEach((child) => {\n this._removeChildren(child);\n this.map.delete(child);\n });\n }\n }\n\n getParent(node: T): T | undefined {\n return this.getInfo(node).parent;\n }\n\n getPre(node: T): T | undefined {\n return this.getInfo(node).pre;\n }\n\n getNext(node: T): T | undefined {\n return this.getInfo(node).next;\n }\n\n getChildren(node: T): T[] {\n return this.getInfo(node).children;\n }\n\n traverse(\n fn: (node: T, depth: number, index: number) => boolean | void,\n node = this.root,\n depth = 0,\n index = 0\n ): boolean | void {\n const breaked = fn(node, depth, index);\n if (breaked) return true;\n const info = this.getInfo(node);\n const shouldBreak = info.children.find((child, i) => this.traverse(fn, child, depth + 1, i));\n if (shouldBreak) return true;\n }\n\n /**\n * 通知文档树结构更新\n */\n fireTreeChange(): void {\n this.onTreeChangeEmitter.fire();\n }\n\n get size(): number {\n return this.map.size;\n }\n\n toString(showType?: boolean): string {\n const ret: string[] = [];\n this.traverse((node, depth) => {\n if (depth === 0) {\n ret.push(node.id);\n } else {\n ret.push(\n `|${new Array(depth).fill('--').join('')} ${\n showType ? `${node.flowNodeType}(${node.id})` : node.id\n }`\n );\n }\n });\n return `${ret.join('\\n')}`;\n }\n}\n\nexport namespace FlowVirtualTree {\n export interface NodeInfo<T> {\n parent?: T;\n next?: T;\n pre?: T;\n children: T[];\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { FlowDocumentConfigEnum, FlowNodeBaseType, FlowNodeSplitType } from './typings';\nimport { FlowVirtualTree } from './flow-virtual-tree';\nimport type { FlowDocument } from './flow-document';\nimport type { FlowNodeEntity } from './entities';\n\n/**\n * Render Tree 会只读模式,不具备操作 tree 结构元素\n */\nexport class FlowRenderTree<T extends FlowNodeEntity> extends FlowVirtualTree<T> {\n protected originTree: FlowVirtualTree<T>;\n\n protected document: FlowDocument;\n\n /**\n * 折叠的节点\n * @protected\n */\n protected nodesCollapsed = new Set<T>();\n\n constructor(readonly root: T, originTree: FlowVirtualTree<T>, document: FlowDocument) {\n super(root);\n this.originTree = originTree;\n this.onTreeChange = this.originTree.onTreeChange;\n this.document = document;\n }\n\n isCollapsed(node: T): boolean {\n return this.nodesCollapsed.has(node);\n }\n\n get collapsedNodeList(): T[] {\n return Array.from(this.nodesCollapsed);\n }\n\n /**\n * 折叠元素\n * @param node\n * @param collapsed\n */\n setCollapsed(node: T, collapsed: boolean): void {\n if (collapsed) {\n this.nodesCollapsed.add(node);\n } else {\n this.nodesCollapsed.delete(node);\n }\n this.originTree.fireTreeChange();\n }\n\n /**\n *\n */\n openNodeInsideCollapsed(node: T) {\n // 找到所有的originTree上的parent\n let curr: T | undefined = this.originTree.getInfo(node)?.parent;\n\n while (curr) {\n if (this.nodesCollapsed.has(curr)) {\n this.nodesCollapsed.delete(curr);\n }\n const { parent } = this.originTree.getInfo(curr) || {};\n curr = parent;\n }\n this.originTree.fireTreeChange();\n }\n\n /**\n * 更新结束节点等位置信息,分支里如果全是结束节点则要做相应的偏移\n */\n updateRenderStruct(): void {\n this.map = this.originTree.cloneMap();\n\n // 结束节点位置更新逻辑开关\n if (this.document.config.get(FlowDocumentConfigEnum.END_NODES_REFINE_BRANCH)) {\n this.refineBranch(this.root);\n }\n\n // 节点展开收起\n this.hideCollapsed();\n }\n\n /**\n * 隐藏收起节点\n */\n protected hideCollapsed() {\n this.nodesCollapsed.forEach(collapsedNode => {\n const collapsedNodeInfo = this.getInfo(collapsedNode);\n if (!collapsedNodeInfo) {\n // 自动回收节点数据\n this.nodesCollapsed.delete(collapsedNode);\n return;\n }\n\n const iconChild = collapsedNodeInfo.children.find(\n _child =>\n _child.flowNodeType === FlowNodeBaseType.BLOCK_ICON ||\n _child.flowNodeType === FlowNodeBaseType.BLOCK_ORDER_ICON,\n );\n\n // ⚠️注意:BLOCK_ICON 和 BLOCK_ORDER_ICON 作为一个 block 的标识节点,收起时需要保留\n if (iconChild) {\n const iconInfo = this.getInfo(iconChild);\n iconInfo.next = undefined;\n iconInfo.pre = undefined;\n collapsedNodeInfo.children = [iconChild];\n\n return;\n }\n\n // 收起节点children置为空\n collapsedNodeInfo.children = [];\n });\n }\n\n // 节点是否为结束节点\n isNodeEnd(node: T): boolean {\n if (node.getNodeMeta().isNodeEnd) {\n return true;\n }\n const { children } = this.getInfo(node);\n\n if (children.length > 0 && node.isInlineBlocks) {\n return children.every(child => this.isNodeEnd(child));\n }\n\n if (node.isInlineBlock) {\n return this.isNodeEnd(children[children.length - 1]);\n }\n\n return false;\n }\n\n /**\n * 优化精简分支线\n * - 结束节点拉直分支线\n */\n protected refineBranch(block: T) {\n let curr: T | undefined = this.getInfo(block).children[0];\n\n while (curr) {\n if (\n curr.flowNodeType === FlowNodeSplitType.DYNAMIC_SPLIT ||\n curr.flowNodeType === FlowNodeSplitType.STATIC_SPLIT\n ) {\n const { next, children: branchChildren } = this.getInfo(curr);\n const { children } = this.getInfo(branchChildren[1]);\n\n const passBlocks = (children || []).filter(child => !this.isNodeEnd(child));\n\n const shouldDragAllNextNodes = passBlocks.length === 1;\n if (shouldDragAllNextNodes && next) {\n this.dragNextNodesToBlock(passBlocks[0], next);\n }\n\n // 对每一个分支再进行refineBranch\n children?.forEach(child => {\n this.refineBranch(child);\n });\n\n if (shouldDragAllNextNodes) {\n break;\n }\n }\n\n curr = curr.next as T;\n }\n }\n\n // 结束节点拽分支,将后续节点拽到对应分支内\n protected dragNextNodesToBlock(toBlock: T, next: T) {\n const toBlockInfo = this.getInfo(toBlock);\n const nextInfo = this.getInfo(next);\n const toBlockLastChild = toBlockInfo.children[toBlock.children.length - 1];\n\n if (nextInfo.parent) {\n const nextParentInfo = this.getInfo(nextInfo.parent);\n\n // 1. next的节点和之前的节点断连\n if (nextInfo.pre) {\n this.getInfo(nextInfo.pre).next = undefined;\n }\n\n // 2. next连接到before上\n if (toBlockLastChild) {\n const lastChildInfo = this.getInfo(toBlockLastChild);\n lastChildInfo.next = next;\n nextInfo.pre = toBlockLastChild;\n }\n\n // 3. 获取所有后续节点, 将所有后续节点重新设置parent\n const nextNodeIndex = nextParentInfo.children.indexOf(next);\n const allNextNodes = nextParentInfo.children.slice(nextNodeIndex);\n nextParentInfo.children = nextParentInfo.children.slice(0, nextNodeIndex);\n for (const node of allNextNodes) {\n const nodeInfo = this.getInfo(node);\n toBlockInfo.children.push(node);\n nodeInfo.parent = toBlock;\n }\n }\n }\n\n getInfo(node: T): FlowVirtualTree.NodeInfo<T> {\n const info = this.map.get(node) || this.originTree.getInfo(node);\n return info;\n }\n\n // 或者originTree节点的信息\n getOriginInfo(node: T): FlowVirtualTree.NodeInfo<T> {\n return this.originTree.getInfo(node);\n }\n\n // 获取收起的隐藏节点\n getCollapsedChildren(node: T): T[] {\n return this.getOriginInfo(node).children || [];\n }\n\n remove(): void {\n throw new Error('Render Tree cannot use remove node');\n }\n\n addChild(): T {\n throw new Error('Render tree cannot use add child');\n }\n\n insertAfter(): void {\n throw new Error('Render tree cannot use insert after');\n }\n\n removeParent(): void {\n throw new Error('Render tree cannot use remove parent');\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport {\n type FlowNodeJSON,\n DefaultSpacingKey,\n FlowTransitionLine,\n FlowTransitionLabel,\n FlowNodeRegistry,\n FlowNodeType,\n} from './typings';\nimport { FlowNodeEntity } from './entities';\n\nexport const FlowDocumentOptions = Symbol('FlowDocumentOptions');\n\n/**\n * 流程画布配置\n */\nexport interface FlowDocumentOptions {\n /**\n * 布局,默认 垂直布局\n */\n defaultLayout?: string;\n /**\n * 所有节点的默认展开状态\n */\n allNodesDefaultExpanded?: boolean;\n toNodeJSON?(node: FlowNodeEntity): FlowNodeJSON;\n fromNodeJSON?(node: FlowNodeEntity, json: FlowNodeJSON, isFirstCreate: boolean): void;\n constants?: Record<string, any>;\n formatNodeLines?: (node: FlowNodeEntity, lines: FlowTransitionLine[]) => FlowTransitionLine[];\n formatNodeLabels?: (node: FlowNodeEntity, lines: FlowTransitionLabel[]) => FlowTransitionLabel[];\n preNodeCreate?: (node: FlowNodeEntity) => void;\n /**\n * 获取默认的节点配置\n */\n getNodeDefaultRegistry?: (type: FlowNodeType) => FlowNodeRegistry;\n}\n\nexport const FlowDocumentOptionsDefault: FlowDocumentOptions = {\n allNodesDefaultExpanded: false,\n};\n\n/**\n * 支持外部 constants 自定义的 key 枚举\n */\nexport const ConstantKeys = {\n ...DefaultSpacingKey,\n /**\n * loop 底部留白\n */\n INLINE_SPACING_BOTTOM: 'INLINE_SPACING_BOTTOM',\n /**\n * inlineBlocks 的 inlineTop\n * loop 循环线条上边距\n */\n INLINE_BLOCKS_INLINE_SPACING_TOP: 'INLINE_BLOCKS_INLINE_SPACING_TOP',\n /**\n * inlineBlocks 的 inlineBottom\n * loop 循环线条的下边距\n *\n */\n INLINE_BLOCKS_INLINE_SPACING_BOTTOM: 'INLINE_BLOCKS_INLINE_SPACING_BOTTOM',\n /***\n * 线条、label 默认颜色\n */\n BASE_COLOR: 'BASE_COLOR',\n /***\n * 线条、label 激活后的颜色\n */\n BASE_ACTIVATED_COLOR: 'BASE_ACTIVATED_COLOR',\n /**\n * Branch bottom margin\n * 分支下边距\n */\n INLINE_BLOCKS_PADDING_TOP: 'INLINE_BLOCKS_PADDING_TOP',\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { type FlowDocument } from './flow-document';\n\nexport const FlowDocumentContribution = Symbol('FlowDocumentContribution');\n\nexport interface FlowDocumentContribution<T extends FlowDocument = FlowDocument> {\n /**\n * 注册\n * @param document\n */\n registerDocument?(document: T): void;\n\n /**\n * 加载数据\n * @param document\n */\n loadDocument?(document: T): Promise<void>;\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { inject, injectable, optional } from 'inversify';\nimport { Emitter } from '@flowgram.ai/utils';\n\nexport const FlowDocumentConfigDefaultData = Symbol('FlowDocumentConfigDefaultData');\n\n/**\n * 用于文档扩展配置\n */\n@injectable()\nexport class FlowDocumentConfig {\n private onDataChangeEmitter = new Emitter<string>();\n\n readonly onChange = this.onDataChangeEmitter.event;\n\n constructor(\n @inject(FlowDocumentConfigDefaultData)\n @optional()\n private _data: Record<string, any> = {},\n ) {}\n\n get(key: string): any {\n return this._data[key];\n }\n\n set(key: string, value: any): void {\n if (this.get(key) !== value) {\n this._data[key] = value;\n this.onDataChangeEmitter.fire(key);\n }\n }\n\n registerConfigs(config: Record<string, any>) {\n Object.keys(config).forEach(key => {\n this.set(key, config[key]);\n });\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { ContainerModule } from 'inversify';\n\nimport { FlowOperationBaseService } from './typings/flow-operation';\nimport { FlowDragService } from './services/flow-drag-service';\nimport { FlowGroupService, FlowOperationBaseServiceImpl } from './services';\nimport { HorizontalFixedLayout, VerticalFixedLayout } from './layout';\nimport { FlowDocumentContribution } from './flow-document-contribution';\nimport { FlowDocumentConfig } from './flow-document-config';\nimport { FlowDocument, FlowDocumentProvider } from './flow-document';\n\nexport const FlowDocumentContainerModule = new ContainerModule((bind) => {\n bind(FlowDocument).toSelf().inSingletonScope();\n bind(FlowDocumentProvider)\n .toDynamicValue((ctx) => () => ctx.container.get(FlowDocument))\n .inSingletonScope();\n bind(FlowDocumentConfig).toSelf().inSingletonScope();\n bind(VerticalFixedLayout).toSelf().inSingletonScope();\n bind(HorizontalFixedLayout).toSelf().inSingletonScope();\n bind(FlowDragService).toSelf().inSingletonScope();\n bind(FlowOperationBaseService).to(FlowOperationBaseServiceImpl).inSingletonScope();\n bind(FlowGroupService).toSelf().inSingletonScope();\n bind(FlowDocumentContribution).toDynamicValue((ctx) => ({\n registerDocument: (document: FlowDocument) => {\n document.registerLayout(ctx.container.get(VerticalFixedLayout));\n document.registerLayout(ctx.container.get(HorizontalFixedLayout));\n },\n }));\n});\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { inject, injectable } from 'inversify';\nimport { Emitter } from '@flowgram.ai/utils';\nimport { EntityManager } from '@flowgram.ai/core';\n\nimport { FlowGroupUtils } from './flow-group-service/flow-group-utils';\nimport {\n FlowNodeBaseType,\n FlowNodeJSON,\n FlowOperationBaseService,\n LABEL_SIDE_TYPE,\n} from '../typings';\nimport { FlowDocument } from '../flow-document';\nimport { FlowNodeEntity, FlowRendererStateEntity } from '../entities';\n\n/**\n * 拖拽相关操作\n * 外部实现抽象类\n */\n@injectable()\nexport class FlowDragService {\n @inject(FlowDocument)\n protected document: FlowDocument;\n\n @inject(FlowOperationBaseService)\n protected operationService: FlowOperationBaseService;\n\n @inject(EntityManager)\n protected entityManager: EntityManager;\n\n protected onDropEmitter = new Emitter<{\n dropNode: FlowNodeEntity;\n dragNodes: FlowNodeEntity[];\n dragJSON?: FlowNodeJSON;\n }>();\n\n readonly onDrop = this.onDropEmitter.event;\n\n get renderState(): FlowRendererStateEntity {\n return this.document.renderState;\n }\n\n // 拖拽所有节点中的首个节点\n get dragStartNode(): FlowNodeEntity {\n return this.renderState.getDragStartEntity()!;\n }\n\n // 拖拽的所有节点\n get dragNodes(): FlowNodeEntity[] {\n return this.renderState.getDragEntities();\n }\n\n // 放置的区域\n get dropNodeId(): string | undefined {\n return this.renderState.getNodeDroppingId();\n }\n\n // 是否在拖拽分支\n get isDragBranch(): boolean {\n return this.renderState.isBranch || this.dragStartNode?.isInlineBlock;\n }\n\n // 拖拽的所有节点及其自节点\n get nodeDragIdsWithChildren(): string[] {\n return this.renderState.config.nodeDragIdsWithChildren || [];\n }\n\n get dragging(): boolean {\n return !!this.renderState.dragging;\n }\n\n get labelSide(): LABEL_SIDE_TYPE | undefined {\n return this.renderState.config.dragLabelSide;\n }\n\n /**\n * 放置到目标分支\n */\n dropBranch(): void {\n this.dropNode();\n }\n\n /**\n * 移动并且创建节点\n * Move and create node\n */\n async dropCreateNode(\n json: FlowNodeJSON,\n onCreateNode?: (json: FlowNodeJSON, dropEntity: FlowNodeEntity) => Promise<FlowNodeEntity>\n ) {\n const dropEntity = this.document.getNode(this.dropNodeId!);\n\n if (!dropEntity) {\n return;\n }\n\n if (json) {\n const dragNodes = await onCreateNode?.(json, dropEntity);\n this.onDropEmitter.fire({\n dropNode: dropEntity,\n dragNodes: dragNodes ? [dragNodes] : [],\n dragJSON: json,\n });\n }\n }\n\n /**\n * 移动到目标节点\n */\n dropNode(): void {\n const dropEntity = this.document.getNode(this.dropNodeId!);\n if (!dropEntity) {\n return;\n }\n\n const sortNodes: FlowNodeEntity[] = [];\n let curr: FlowNodeEntity | undefined = this.dragStartNode;\n while (curr && this.dragNodes.includes(curr)) {\n sortNodes.push(curr);\n curr = curr.next;\n }\n\n this.operationService.dragNodes({\n dropNode: dropEntity,\n nodes: sortNodes,\n });\n\n if (sortNodes.length > 0) {\n this.onDropEmitter.fire({\n dropNode: dropEntity,\n dragNodes: sortNodes,\n });\n }\n }\n\n /**\n * 拖拽是否可以释放在该节点后面\n */\n isDroppableNode(node: FlowNodeEntity) {\n // 没有拖拽节点时,所有节点都不可 drop\n if (!this.dragging || this.isDragBranch) {\n return false;\n }\n\n // 当前节点 & 下一个节点是否在拖拽区域\n if (\n this.nodeDragIdsWithChildren.includes(node.id) ||\n (node.next && this.nodeDragIdsWithChildren.includes(node.next.id))\n ) {\n return false;\n }\n\n if (node.isInlineBlocks || node.isInlineBlock) {\n return false;\n }\n\n // 分组节点不能嵌套\n const hasGroupNode = this.dragNodes.some(\n (node) => node.flowNodeType === FlowNodeBaseType.GROUP\n );\n if (hasGroupNode) {\n const group = FlowGroupUtils.getNodeRecursionGroupController(node);\n if (group) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * 拖拽分支是否可以释放在该分支\n * @param node 拖拽的分支节点\n * @param side 分支的前面还是后面\n */\n isDroppableBranch(node: FlowNodeEntity, side: LABEL_SIDE_TYPE = LABEL_SIDE_TYPE.NORMAL_BRANCH) {\n // 外部添加拖拽标识,默认所有分支均可添加\n if (this.renderState.isBranch) {\n return true;\n }\n // 拖拽的是分支\n if (this.isDragBranch) {\n if (\n // 拖拽到分支\n !node.isInlineBlock ||\n // 只能在同一分支条件下\n node.parent !== this.dragStartNode.parent ||\n // 自己不能拖拽给自己\n node === this.dragStartNode\n ) {\n return false;\n }\n\n // 分支的下一个节点不是当前要拖拽的节点\n if (side === LABEL_SIDE_TYPE.NORMAL_BRANCH && node.next !== this.dragStartNode) {\n return true;\n }\n\n // 分支的前一个节点不是当前要拖拽的节点\n if (side === LABEL_SIDE_TYPE.PRE_BRANCH && node.pre !== this.dragStartNode) {\n return true;\n }\n }\n\n return false;\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Rectangle } from '@flowgram.ai/utils';\n\nimport { FlowNodeEntity } from '../../entities';\nimport { FlowNodeRenderData, FlowNodeTransformData } from '../../datas';\nimport { FlowGroupUtils } from './flow-group-utils';\n\n/** 分组控制器 */\nexport class FlowGroupController {\n private constructor(public readonly groupNode: FlowNodeEntity) {}\n\n public get nodes(): FlowNodeEntity[] {\n return this.groupNode.collapsedChildren || [];\n }\n\n public get collapsed(): boolean {\n const groupTransformData = this.groupNode.getData<FlowNodeTransformData>(FlowNodeTransformData);\n return groupTransformData.collapsed;\n }\n\n public collapse(): void {\n this.collapsed = true;\n }\n\n public expand(): void {\n this.collapsed = false;\n }\n\n /** 获取分组外围的最大边框 */\n public get bounds(): Rectangle {\n const groupNodeBounds =\n this.groupNode.getData<FlowNodeTransformData>(FlowNodeTransformData).bounds;\n return groupNodeBounds;\n }\n\n /** 是否是开始节点 */\n public isStartNode(node?: FlowNodeEntity): boolean {\n if (!node) {\n return false;\n }\n const nodes = this.nodes;\n if (!nodes[0]) {\n return false;\n }\n return node.id === nodes[0].id;\n }\n\n /** 是否是结束节点 */\n public isEndNode(node?: FlowNodeEntity): boolean {\n if (!node) {\n return false;\n }\n const nodes = this.nodes;\n if (!nodes[nodes.length - 1]) {\n return false;\n }\n return node.id === nodes[nodes.length - 1].id;\n }\n\n public set note(note: string) {\n this.groupNode.getNodeMeta().note = note;\n }\n\n public get note(): string {\n return this.groupNode.getNodeMeta().note || '';\n }\n\n public set noteHeight(height: number) {\n this.groupNode.getNodeMeta().noteHeight = height;\n }\n\n public get noteHeight(): number {\n return this.groupNode.getNodeMeta().noteHeight || 0;\n }\n\n public get positionConfig(): Record<string, number> {\n return this.groupNode.getNodeMeta().positionConfig;\n }\n\n private set collapsed(collapsed: boolean) {\n const groupTransformData = this.groupNode.getData<FlowNodeTransformData>(FlowNodeTransformData);\n groupTransformData.collapsed = collapsed;\n groupTransformData.localDirty = true;\n if (groupTransformData.parent) groupTransformData.parent.localDirty = true;\n if (groupTransformData.parent?.firstChild)\n groupTransformData.parent.firstChild.localDirty = true;\n }\n\n public set hovered(hovered: boolean) {\n const groupRenderData = this.groupNode.getData<FlowNodeRenderData>(FlowNodeRenderData);\n if (hovered) {\n groupRenderData.toggleMouseEnter();\n } else {\n groupRenderData.toggleMouseLeave();\n }\n if (groupRenderData.hovered === hovered) {\n return;\n }\n groupRenderData.hovered = hovered;\n }\n\n public get hovered(): boolean {\n const groupRenderData = this.groupNode.getData<FlowNodeRenderData>(FlowNodeRenderData);\n return groupRenderData.hovered;\n }\n\n public static create(groupNode?: FlowNodeEntity): FlowGroupController | undefined {\n if (!groupNode) {\n return;\n }\n if (!FlowGroupUtils.isGroupNode(groupNode)) {\n return;\n }\n return new FlowGroupController(groupNode);\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { FlowNodeBaseType } from '../../typings';\nimport { FlowNodeEntity } from '../../entities';\nimport { FlowGroupController } from './flow-group-controller';\n\nexport namespace FlowGroupUtils {\n /** 找到节点所有上级 */\n const findNodeParents = (node: FlowNodeEntity): FlowNodeEntity[] => {\n const parents = [];\n let parent = node.parent;\n while (parent) {\n parents.push(parent);\n parent = parent.parent;\n }\n return parents;\n };\n\n /** 节点是否处于分组中 */\n const isNodeInGroup = (node: FlowNodeEntity): boolean => {\n // 处于分组中\n if (node?.parent?.flowNodeType === FlowNodeBaseType.GROUP) {\n return true;\n }\n return false;\n };\n\n /** 判断节点能否组成分组 */\n export const validate = (nodes: FlowNodeEntity[]): boolean => {\n if (!nodes || !Array.isArray(nodes) || nodes.length === 0) {\n // 参数不合法\n return false;\n }\n\n // 判断是否有分组节点\n const isGroupRelatedNode = nodes.some((node) => isGroupNode(node));\n if (isGroupRelatedNode) return false;\n\n // 判断是否有节点已经处于分组中\n const hasGroup = nodes.some((node) => node && isNodeInGroup(node));\n if (hasGroup) return false;\n\n // 判断是否来自同一个父亲\n const parent = nodes[0].parent;\n const isSameParent = nodes.every((node) => node.parent === parent);\n if (!isSameParent) return false;\n\n // 判断节点索引是否连续\n const indexes = nodes.map((node) => node.index).sort((a, b) => a - b);\n const isIndexContinuous = indexes.every((index, i, arr) => {\n if (i === 0) {\n return true;\n }\n return index === arr[i - 1] + 1;\n });\n if (!isIndexContinuous) return false;\n\n // 判断节点父亲是否已经在分组中\n const parents = findNodeParents(nodes[0]);\n const parentsInGroup = parents.some((parent) => isNodeInGroup(parent));\n if (parentsInGroup) return false;\n\n // 参数正确\n return true;\n };\n\n /** 获取节点分组控制 */\n export const getNodeGroupController = (\n node?: FlowNodeEntity\n ): FlowGroupController | undefined => {\n if (!node) {\n return;\n }\n if (!isNodeInGroup(node)) {\n return;\n }\n const groupNode = node?.parent;\n return FlowGroupController.create(groupNode);\n };\n\n /** 向上递归查找分组递归控制 */\n export const getNodeRecursionGroupController = (\n node?: FlowNodeEntity\n ): FlowGroupController | undefined => {\n if (!node) {\n return;\n }\n const group = getNodeGroupController(node);\n if (group) {\n return group;\n }\n if (node.parent) {\n return getNodeRecursionGroupController(node.parent);\n }\n return;\n };\n\n /** 是否分组节点 */\n export const isGroupNode = (group: FlowNodeEntity): boolean =>\n group.flowNodeType === FlowNodeBaseType.GROUP;\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { inject, injectable, postConstruct } from 'inversify';\nimport { DisposableCollection, Emitter } from '@flowgram.ai/utils';\nimport { EntityManager } from '@flowgram.ai/core';\n\nimport {\n FlowOperation,\n FlowOperationBaseService,\n MoveChildNodesOperationValue,\n OperationType,\n} from '../typings/flow-operation';\nimport {\n AddBlockConfig,\n AddNodeConfig,\n AddNodeData,\n FlowNodeBaseType,\n FlowNodeEntityOrId,\n FlowNodeJSON,\n MoveNodeConfig,\n OnNodeAddEvent,\n OnNodeMoveEvent,\n} from '../typings';\nimport { FlowDocument } from '../flow-document';\nimport { FlowNodeEntity } from '../entities';\n\n/**\n * 操作服务\n */\n@injectable()\nexport class FlowOperationBaseServiceImpl implements FlowOperationBaseService {\n @inject(EntityManager)\n protected entityManager: EntityManager;\n\n @inject(FlowDocument)\n protected document: FlowDocument;\n\n protected onNodeAddEmitter = new Emitter<OnNodeAddEvent>();\n\n readonly onNodeAdd = this.onNodeAddEmitter.event;\n\n protected toDispose = new DisposableCollection();\n\n private onNodeMoveEmitter = new Emitter<OnNodeMoveEvent>();\n\n readonly onNodeMove = this.onNodeMoveEmitter.event;\n\n @postConstruct()\n protected init() {\n this.toDispose.pushAll([this.onNodeAddEmitter, this.onNodeMoveEmitter]);\n }\n\n addNode(nodeJSON: FlowNodeJSON, config: AddNodeConfig = {}): FlowNodeEntity {\n const { parent, index, hidden } = config;\n let parentEntity;\n\n if (parent) {\n parentEntity = this.toNodeEntity(parent);\n }\n\n let register;\n if (parentEntity) {\n register = parentEntity.getNodeRegistry();\n }\n\n const addJSON = {\n ...nodeJSON,\n type: nodeJSON.type || FlowNodeBaseType.BLOCK,\n };\n\n const addNodeData: AddNodeData = {\n ...addJSON,\n parent: parentEntity,\n index,\n hidden,\n };\n\n let added;\n if (parentEntity && register?.addChild) {\n added = register.addChild(parentEntity, addJSON, {\n index,\n hidden,\n });\n } else {\n added = this.document.addNode(addNodeData);\n }\n\n this.onNodeAddEmitter.fire({\n node: added,\n data: addNodeData,\n });\n\n return added;\n }\n\n addFromNode(fromNode: FlowNodeEntityOrId, nodeJSON: FlowNodeJSON): FlowNodeEntity {\n return this.document.addFromNode(fromNode, nodeJSON);\n }\n\n deleteNode(node: FlowNodeEntityOrId): void {\n this.document.removeNode(node);\n }\n\n deleteNodes(nodes: FlowNodeEntityOrId[]): void {\n (nodes || []).forEach((node) => {\n this.deleteNode(node);\n });\n }\n\n addBlock(\n target: FlowNodeEntityOrId,\n blockJSON: FlowNodeJSON,\n config: AddBlockConfig = {}\n ): FlowNodeEntity {\n const { parent, index } = config;\n return this.document.addBlock(target, blockJSON, undefined, parent, index);\n }\n\n moveNode(node: FlowNodeEntityOrId, config: MoveNodeConfig = {}) {\n const { parent: newParent, index } = config;\n const entity = this.toNodeEntity(node);\n const parent = entity?.parent;\n\n if (!parent) {\n return;\n }\n\n const newParentEntity: FlowNodeEntity | undefined = newParent\n ? this.toNodeEntity(newParent)\n : parent;\n\n if (!newParentEntity) {\n console.warn('no new parent found', newParent);\n return;\n }\n\n let toIndex = typeof index === 'undefined' ? newParentEntity.collapsedChildren.length : index;\n\n return this.doMoveNode(entity, newParentEntity, toIndex);\n }\n\n /**\n * 拖拽节点\n * @param param0\n * @returns\n */\n dragNodes({ dropNode, nodes }: { dropNode: FlowNodeEntity; nodes: FlowNodeEntity[] }) {\n if (nodes.length === 0) {\n return;\n }\n\n const startNode = nodes[0];\n const fromParent = startNode.parent;\n const toParent = dropNode.parent;\n\n if (!fromParent || !toParent) {\n return;\n }\n\n const fromIndex = fromParent.children.findIndex((child) => child === startNode);\n const dropIndex = toParent.children.findIndex((child) => child === dropNode);\n\n let toIndex = dropIndex + 1;\n // 同父级节点移动,处理脏路径\n if (fromParent === toParent && fromIndex < dropIndex) {\n toIndex = toIndex - nodes.length;\n }\n\n const value: MoveChildNodesOperationValue = {\n nodeIds: nodes.map((node) => node.id),\n fromParentId: fromParent.id,\n toParentId: toParent.id,\n fromIndex,\n toIndex,\n };\n\n return this.apply({\n type: OperationType.moveChildNodes,\n value,\n });\n }\n\n /**\n * 执行操作\n * @param operation 可序列化的操作\n * @returns 操作返回\n */\n apply(operation: FlowOperation): any {\n const document = this.document;\n switch (operation.type) {\n case OperationType.addFromNode:\n return document.addFromNode(operation.value.fromId, operation.value.data);\n case OperationType.deleteFromNode:\n return document.getNode(operation.value?.data?.id)?.dispose();\n case OperationType.addBlock: {\n let parent;\n\n if (operation.value.parentId) {\n parent = document.getNode(operation.value.parentId);\n }\n return document.addBlock(\n operation.value.targetId,\n operation.value.blockData,\n undefined,\n parent,\n operation.value.index\n );\n }\n case OperationType.deleteBlock: {\n const entity = document.getNode(operation.value?.blockData.id);\n return entity?.dispose();\n }\n case OperationType.createGroup: {\n const groupNode = document.addFromNode(operation.value.targetId, {\n id: operation.value.groupId,\n type: FlowNodeBaseType.GROUP,\n });\n document.moveNodes({\n dropNodeId: operation.value.groupId,\n sortNodeIds: operation.value.nodeIds,\n inside: true,\n });\n return groupNode;\n }\n case OperationType.ungroup: {\n document.moveNodes({\n dropNodeId: operation.value.groupId,\n sortNodeIds: operation.value.nodeIds,\n });\n return document.getNode(operation.value.groupId)?.dispose();\n }\n case OperationType.moveNodes: {\n return document.moveNodes({\n dropNodeId: operation.value.toId,\n sortNodeIds: operation.value.nodeIds,\n });\n }\n case OperationType.moveBlock: {\n return document.moveChildNodes({\n ...operation.value,\n nodeIds: [operation.value.nodeId],\n });\n }\n case OperationType.addNodes: {\n let fromId = operation.value.fromId;\n (operation.value.nodes || []).forEach((node) => {\n const added = document.addFromNode(fromId, node);\n fromId = added.id;\n });\n break;\n }\n case OperationType.deleteNodes: {\n (operation.value.nodes || []).forEach((node) => {\n const entity = document.getNode(node.id);\n entity?.dispose();\n });\n break;\n }\n case OperationType.addChildNode: {\n return document.addNode({\n ...operation.value.data,\n parent: operation.value.parentId ? document.getNode(operation.value.parentId) : undefined,\n originParent: operation.value.originParentId\n ? document.getNode(operation.value.originParentId)\n : undefined,\n index: operation.value.index,\n hidden: operation.value.hidden,\n });\n }\n case OperationType.deleteChildNode:\n return document.getNode(operation.value.data.id)?.dispose();\n case OperationType.moveChildNodes:\n return document.moveChildNodes(operation.value);\n default:\n throw new Error(`unknown operation type`);\n }\n }\n\n /**\n * 事务执行\n * @param transaction\n */\n transact(transaction: () => void) {\n transaction();\n }\n\n dispose() {\n this.toDispose.dispose();\n }\n\n protected toId(node: FlowNodeEntityOrId): string {\n return typeof node === 'string' ? node : node.id;\n }\n\n protected toNodeEntity(node: FlowNodeEntityOrId): FlowNodeEntity | undefined {\n return typeof node === 'string' ? this.document.getNode(node) : node;\n }\n\n protected getNodeIndex(node: FlowNodeEntityOrId): number {\n const entity = this.toNodeEntity(node);\n const parent = entity?.parent;\n\n if (!parent) {\n return -1;\n }\n\n return parent.children.findIndex((child) => child === entity);\n }\n\n protected doMoveNode(node: FlowNodeEntity, newParent: FlowNodeEntity, index: number) {\n if (!node.parent) {\n throw new Error('root node cannot move');\n }\n\n const event: OnNodeMoveEvent = {\n node,\n fromParent: node.parent,\n toParent: newParent,\n fromIndex: this.getNodeIndex(node),\n toIndex: index,\n };\n\n this.document.moveChildNodes({\n nodeIds: [this.toId(node)],\n toParentId: this.toId(newParent),\n toIndex: index,\n });\n this.onNodeMoveEmitter.fire(event);\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { nanoid } from 'nanoid';\nimport { inject, injectable } from 'inversify';\nimport { EntityManager } from '@flowgram.ai/core';\n\nimport { FlowNodeBaseType, FlowOperationBaseService, OperationType } from '../../typings';\nimport { FlowNodeEntity } from '../../entities';\nimport { FlowGroupUtils } from './flow-group-utils';\nimport { FlowGroupController } from './flow-group-controller';\n\n@injectable()\n/** 分组服务 */\nexport class FlowGroupService {\n @inject(EntityManager) public readonly entityManager: EntityManager;\n\n @inject(FlowOperationBaseService)\n public readonly operationService: FlowOperationBaseService;\n\n /** 创建分组节点 */\n public createGroup(nodes: FlowNodeEntity[]): FlowNodeEntity | undefined {\n if (!nodes || !Array.isArray(nodes) || nodes.length === 0) {\n return;\n }\n if (!FlowGroupUtils.validate(nodes)) {\n return;\n }\n const sortedNodes: FlowNodeEntity[] = nodes.sort((a, b) => a.index - b.index);\n const fromNode = sortedNodes[0];\n const groupId = `group_${nanoid(5)}`;\n this.operationService.apply({\n type: OperationType.createGroup,\n value: {\n targetId: fromNode.id,\n groupId,\n nodeIds: nodes.map((node) => node.id),\n },\n });\n const groupNode = this.entityManager.getEntityById<FlowNodeEntity>(groupId);\n if (!groupNode) {\n return;\n }\n const group = this.groupController(groupNode);\n if (!group) {\n return;\n }\n group.expand();\n return groupNode;\n }\n\n /** 删除分组 */\n public deleteGroup(groupNode: FlowNodeEntity): void {\n const json = groupNode.toJSON();\n if (!groupNode.pre || !json) {\n return;\n }\n this.operationService.apply({\n type: OperationType.deleteNodes,\n value: {\n fromId: groupNode.pre.id,\n nodes: [json],\n },\n });\n }\n\n /** 取消分组 */\n public ungroup(groupNode: FlowNodeEntity): void {\n const group = this.groupController(groupNode);\n if (!group) {\n return;\n }\n const nodes = group.nodes;\n if (!groupNode.pre) {\n return;\n }\n group.collapse();\n this.operationService.apply({\n type: OperationType.ungroup,\n value: {\n groupId: groupNode.id,\n targetId: groupNode.pre.id,\n nodeIds: nodes.map((node) => node.id),\n },\n });\n }\n\n /** 返回所有分组节点 */\n public getAllGroups(): FlowGroupController[] {\n const allNodes = this.entityManager.getEntities<FlowNodeEntity>(FlowNodeEntity);\n const groupNodes = allNodes.filter((node) => node.flowNodeType === FlowNodeBaseType.GROUP);\n return groupNodes\n .map((node) => this.groupController(node))\n .filter(Boolean) as FlowGroupController[];\n }\n\n /** 获取分组控制器*/\n public groupController(group: FlowNodeEntity): FlowGroupController | undefined {\n return FlowGroupController.create(group);\n }\n\n public static validate(nodes: FlowNodeEntity[]): boolean {\n return FlowGroupUtils.validate(nodes);\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { injectable, inject, multiInject, optional } from 'inversify';\nimport { IPoint, OriginSchema, PaddingSchema, ScrollSchema, SizeSchema } from '@flowgram.ai/utils';\n\nimport { type FlowLayout, FlowLayoutDefault, FlowLayoutContribution } from '../typings';\nimport { type FlowDocument, FlowDocumentProvider } from '../flow-document';\nimport { FlowNodeEntity } from '../entities';\nimport { FlowNodeTransformData } from '../datas';\n\n// 开始节点距离上边 36 像素\nconst DEFAULT_SCROLL = -36;\n\n/**\n * 用于描述节点的结构特征\n */\ninterface FlowNodeTransformStructData {\n childrenLength: number;\n index: number;\n}\n/**\n * 用于描述节点的结构特征\n */\ninterface FlowNodeTransformStructData {\n childrenLength: number;\n index: number;\n}\n\nfunction isStructDataEqual(\n struct1: FlowNodeTransformStructData,\n struct2: FlowNodeTransformStructData\n): boolean {\n return struct1.childrenLength === struct2.childrenLength && struct1.index === struct2.index;\n}\n\n@injectable()\nexport class VerticalFixedLayout implements FlowLayout {\n name = FlowLayoutDefault.VERTICAL_FIXED_LAYOUT;\n\n protected structDataMap = new WeakMap<FlowNodeEntity, FlowNodeTransformStructData>();\n\n @inject(FlowDocumentProvider) protected documentProvider: FlowDocumentProvider;\n\n @multiInject(FlowLayoutContribution)\n @optional()\n contribs?: FlowLayoutContribution[];\n\n get document(): FlowDocument {\n return this.documentProvider();\n }\n\n reload() {\n this.structDataMap = new WeakMap();\n }\n\n /**\n * 更新布局\n */\n update(): void {\n this.updateLocalTransform(this.document.root);\n }\n\n /**\n * 更新节点的偏移\n * @param node\n * @param forceChange\n */\n updateLocalTransform(node: FlowNodeEntity, forceChange = false): boolean {\n const { children, parent, isInlineBlock } = node;\n\n const transform = node.getData<FlowNodeTransformData>(FlowNodeTransformData);\n const { getDelta, getOrigin } = node.getNodeRegistry();\n const lastStructData = this.structDataMap.get(node) || {\n childrenLength: 0,\n index: -1,\n };\n // 重新计算都要清空 bounds 缓存,因为 bounds 依赖所有\n node.clearMemoGlobal();\n let localDirty = transform.localDirty || forceChange;\n const newStructData: FlowNodeTransformStructData = {\n index: node.index,\n childrenLength: node.children.length,\n };\n // index 变化也要重新计算\n if (!isStructDataEqual(lastStructData, newStructData)) {\n localDirty = true;\n this.structDataMap.set(node, newStructData);\n }\n // Step1: 计算子节点\n let siblingDirty = false;\n if (children.length > 0) {\n for (const child of children) {\n const childDirty = this.updateLocalTransform(child, siblingDirty);\n // 子节点变更则父节点跟着变更\n if (childDirty) {\n siblingDirty = true;\n localDirty = true;\n }\n }\n }\n // 如果没有变更则不执行\n if (!localDirty) return false;\n // Step2: 计算节点的 position 偏移量\n node.clearMemoLocal();\n transform.transform.update({\n origin: getOrigin ? getOrigin(transform, this) : this.getDefaultNodeOrigin(),\n });\n const preTransform = transform.pre;\n const delta = getDelta?.(transform, this) || { x: 0, y: 0 };\n const inlineSpacingPre =\n isInlineBlock && transform.parent?.inlineSpacingPre ? transform.parent?.inlineSpacingPre : 0;\n const fromParentDelta = parent?.getNodeRegistry().getChildDelta?.(transform, this) || {\n x: 0,\n y: 0,\n };\n delta.x += fromParentDelta.x;\n delta.y += fromParentDelta.y;\n\n // Step3:根据上一个节点的相对偏移算当前偏移\n const position = { x: delta.x, y: delta.y };\n // 垂直布局\n if (isInlineBlock) {\n position.y += inlineSpacingPre;\n } else {\n position.y += preTransform?.localBounds.bottom || 0;\n position.y += preTransform?.spacing || 0;\n }\n\n transform.transform.update({\n size: transform.data.size,\n position,\n });\n\n // 布局结束后可执行额外逻辑\n this.onAfterUpdateLocalTransform(transform);\n\n transform.localDirty = false;\n\n return true;\n }\n\n onAfterUpdateLocalTransform(transform: FlowNodeTransformData) {\n // 执行 register 上的 onAfterUpdateLocalTransform\n const { onAfterUpdateLocalTransform } = transform.entity.getNodeRegistry();\n onAfterUpdateLocalTransform?.(transform, this);\n\n // 执行 contribution 上的 onAfterUpdateLocalTransform\n this.contribs?.forEach((_contrib) => {\n _contrib?.onAfterUpdateLocalTransform?.(transform, this);\n });\n }\n\n getNodeTransform(node: FlowNodeEntity): FlowNodeTransformData {\n return node.getData(FlowNodeTransformData)!;\n }\n\n getPadding(node: FlowNodeEntity): PaddingSchema {\n const { inlineSpacingPre, inlineSpacingAfter, padding } = node.getNodeMeta();\n const transform = this.getNodeTransform(node);\n if (padding) {\n return typeof padding === 'function' ? padding(transform) : padding;\n }\n\n const paddingPre =\n typeof inlineSpacingPre === 'function' ? inlineSpacingPre(transform) : inlineSpacingPre;\n const paddingAfter =\n typeof inlineSpacingAfter === 'function' ? inlineSpacingAfter(transform) : inlineSpacingAfter;\n\n return {\n left: 0,\n top: paddingPre,\n right: 0,\n bottom: paddingAfter,\n };\n }\n\n getInitScroll(contentSize: SizeSchema): ScrollSchema {\n return {\n scrollX: -contentSize.width / 2,\n scrollY: DEFAULT_SCROLL,\n };\n }\n\n getDefaultInputPoint(node: FlowNodeEntity): IPoint {\n return this.getNodeTransform(node).bounds.topCenter;\n }\n\n getDefaultOutputPoint(node: FlowNodeEntity): IPoint {\n return this.getNodeTransform(node).bounds.bottomCenter;\n }\n\n getDefaultNodeOrigin(): OriginSchema {\n return { x: 0.5, y: 0 };\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { injectable, inject, multiInject, optional } from 'inversify';\nimport { IPoint, OriginSchema, PaddingSchema, ScrollSchema, SizeSchema } from '@flowgram.ai/utils';\n\nimport { type FlowLayout, FlowLayoutDefault, FlowLayoutContribution } from '../typings';\nimport { type FlowDocument, FlowDocumentProvider } from '../flow-document';\nimport { FlowNodeEntity } from '../entities';\nimport { FlowNodeTransformData } from '../datas';\n\n// 开始节点距离上边 36 像素\nconst DEFAULT_SCROLL = -36;\n\n/**\n * 用于描述节点的结构特征\n */\ninterface FlowNodeTransformStructData {\n childrenLength: number;\n index: number;\n}\n/**\n * 用于描述节点的结构特征\n */\ninterface FlowNodeTransformStructData {\n childrenLength: number;\n index: number;\n}\n\nfunction isStructDataEqual(\n struct1: FlowNodeTransformStructData,\n struct2: FlowNodeTransformStructData\n): boolean {\n return struct1.childrenLength === struct2.childrenLength && struct1.index === struct2.index;\n}\n\n@injectable()\nexport class HorizontalFixedLayout implements FlowLayout {\n name = FlowLayoutDefault.HORIZONTAL_FIXED_LAYOUT;\n\n protected structDataMap = new WeakMap<FlowNodeEntity, FlowNodeTransformStructData>();\n\n @inject(FlowDocumentProvider) protected documentProvider: FlowDocumentProvider;\n\n @multiInject(FlowLayoutContribution)\n @optional()\n contribs?: FlowLayoutContribution[];\n\n get document(): FlowDocument {\n return this.documentProvider();\n }\n\n reload() {\n this.structDataMap = new WeakMap();\n }\n\n /**\n * 更新布局\n */\n update(): void {\n this.updateLocalTransform(this.document.root);\n }\n\n /**\n * 更新节点的偏移\n * @param node\n * @param forceChange\n */\n updateLocalTransform(node: FlowNodeEntity, forceChange = false): boolean {\n const { children, parent, isInlineBlock } = node;\n\n const transform = node.getData<FlowNodeTransformData>(FlowNodeTransformData);\n const { getDelta, getOrigin } = node.getNodeRegistry();\n const lastStructData = this.structDataMap.get(node) || {\n childrenLength: 0,\n index: -1,\n };\n // 重新计算都要清空 bounds 缓存,因为 bounds 依赖所有\n node.clearMemoGlobal();\n let localDirty = transform.localDirty || forceChange;\n const newStructData: FlowNodeTransformStructData = {\n index: node.index,\n childrenLength: node.children.length,\n };\n // index 变化也要重新计算\n if (!isStructDataEqual(lastStructData, newStructData)) {\n localDirty = true;\n this.structDataMap.set(node, newStructData);\n }\n // Step1: 计算子节点\n let siblingDirty = false;\n if (children.length > 0) {\n for (const child of children) {\n const childDirty = this.updateLocalTransform(child, siblingDirty);\n // 子节点变更则父节点跟着变更\n if (childDirty) {\n siblingDirty = true;\n localDirty = true;\n }\n }\n }\n // 如果没有变更则不执行\n if (!localDirty) return false;\n // Step2: 计算节点的 position 偏移量\n node.clearMemoLocal();\n transform.transform.update({\n origin: getOrigin ? getOrigin(transform, this) : this.getDefaultNodeOrigin(),\n });\n const preTransform = transform.pre;\n const delta = getDelta?.(transform, this) || { x: 0, y: 0 };\n const inlineSpacingPre =\n isInlineBlock && transform.parent?.inlineSpacingPre ? transform.parent?.inlineSpacingPre : 0;\n const fromParentDelta = parent?.getNodeRegistry().getChildDelta?.(transform, this) || {\n x: 0,\n y: 0,\n };\n delta.x += fromParentDelta.x;\n delta.y += fromParentDelta.y;\n\n // Step3:根据上一个节点的相对偏移算当前偏移\n const position = { x: delta.x, y: delta.y };\n // 水平布局\n if (isInlineBlock) {\n position.x += inlineSpacingPre;\n } else {\n position.x += preTransform?.localBounds.right || 0;\n position.x += preTransform?.spacing || 0;\n }\n\n transform.transform.update({\n size: transform.data.size,\n position,\n });\n\n // 布局结束后可执行额外逻辑\n this.onAfterUpdateLocalTransform(transform);\n\n transform.localDirty = false;\n\n return true;\n }\n\n onAfterUpdateLocalTransform(transform: FlowNodeTransformData) {\n // 执行 register 上的 onAfterUpdateLocalTransform\n const { onAfterUpdateLocalTransform } = transform.entity.getNodeRegistry();\n onAfterUpdateLocalTransform?.(transform, this);\n\n // 执行 contribution 上的 onAfterUpdateLocalTransform\n this.contribs?.forEach((_contrib) => {\n _contrib?.onAfterUpdateLocalTransform?.(transform, this);\n });\n }\n\n getNodeTransform(node: FlowNodeEntity): FlowNodeTransformData {\n return node.getData(FlowNodeTransformData)!;\n }\n\n getPadding(node: FlowNodeEntity): PaddingSchema {\n const { inlineSpacingPre, inlineSpacingAfter, padding } = node.getNodeMeta();\n const transform = this.getNodeTransform(node);\n if (padding) {\n return typeof padding === 'function' ? padding(transform) : padding;\n }\n\n const paddingPre =\n typeof inlineSpacingPre === 'function' ? inlineSpacingPre(transform) : inlineSpacingPre;\n const paddingAfter =\n typeof inlineSpacingAfter === 'function' ? inlineSpacingAfter(transform) : inlineSpacingAfter;\n\n return {\n left: paddingPre,\n top: 0,\n right: paddingAfter,\n bottom: 0,\n };\n }\n\n getInitScroll(contentSize: SizeSchema): ScrollSchema {\n return {\n scrollX: DEFAULT_SCROLL,\n scrollY: -contentSize.height / 2,\n };\n }\n\n getDefaultInputPoint(node: FlowNodeEntity): IPoint {\n return this.getNodeTransform(node).bounds.leftCenter;\n }\n\n getDefaultOutputPoint(node: FlowNodeEntity): IPoint {\n return this.getNodeTransform(node).bounds.rightCenter;\n }\n\n getDefaultNodeOrigin(): OriginSchema {\n return { x: 0, y: 0.5 };\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { DEFAULT_SPACING } from '../typings';\nimport { FlowDocumentOptions } from '../flow-document-options';\nimport { FlowNodeEntity } from '../entities/flow-node-entity';\n\n/**\n *\n * @param node 节点 entity\n * @param key 从 DocumentOptions 里获取 constants 的 key\n * @param defaultSpacing 默认从 DEFAULT_SPACING 获取 spacing,也可以外部传入默认值\n * @returns\n */\nexport const getDefaultSpacing = (node: FlowNodeEntity, key: string, defaultSpacing?: number) => {\n const flowDocumentOptions = node.getService<FlowDocumentOptions>(FlowDocumentOptions);\n const spacing = flowDocumentOptions?.constants?.[key] || defaultSpacing || DEFAULT_SPACING[key];\n return spacing;\n};\n"],"mappings":"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","names":["FlowNodeBaseType","FlowNodeSplitType","FlowDocumentConfigEnum","FlowLayoutDefault","FlowTransitionLineEnum","FlowTransitionLabelEnum","DRAGGING_TYPE","LABEL_SIDE_TYPE","FlowNodeRegistry","OperationType","Disposable","EntityData","EntityData","Disposable","EntityData","EntityData","FlowNodeEntity","Emitter","Emitter","ConfigEntity","inject","injectable","optional","Emitter","Emitter","Emitter","Emitter","Emitter","layout","node","inject","optional","injectable","inject","injectable","Emitter","EntityManager","FlowGroupUtils","parent","Emitter","node","inject","EntityManager","injectable","inject","injectable","postConstruct","Emitter","EntityManager","Emitter","inject","EntityManager","postConstruct","injectable","inject","injectable","EntityManager","inject","EntityManager","injectable","injectable","inject","multiInject","optional","inject","multiInject","optional","injectable","injectable","inject","multiInject","optional","DEFAULT_SCROLL","isStructDataEqual","inject","multiInject","optional","injectable"]}