mirror of
https://gitee.com/ByteDance/flowgram.ai.git
synced 2025-07-07 17:43:29 +08:00
fix: FlowNodeRegistry.extendChildRegistries extend nested, add document.isExtend (#269)
This commit is contained in:
parent
bac29feb3a
commit
755aaf2223
@ -0,0 +1,116 @@
|
||||
import { beforeEach, describe, expect, it } from 'vitest';
|
||||
|
||||
import { createDocumentContainer } from './flow-document-container.mock';
|
||||
import { FlowDocument, FlowNodeRegistry } from '../src';
|
||||
|
||||
function registerNode(doc: FlowDocument, newRegistry: FlowNodeRegistry): FlowNodeRegistry {
|
||||
doc.registerFlowNodes(newRegistry);
|
||||
return doc.getNodeRegistry(newRegistry.type);
|
||||
}
|
||||
const mockRegistries: FlowNodeRegistry[] = [
|
||||
{
|
||||
type: 'dynamicSplit',
|
||||
meta: {},
|
||||
onCreate(node, json) {
|
||||
return node.document.addInlineBlocks(node, json.blocks || []);
|
||||
},
|
||||
extendChildRegistries: [
|
||||
{
|
||||
type: 'blockIcon',
|
||||
customKey: 'blockIcon_base',
|
||||
},
|
||||
{
|
||||
type: 'inlineBlocks',
|
||||
customKey: 'inlineBlocks_base',
|
||||
},
|
||||
],
|
||||
onAdd: () => {},
|
||||
},
|
||||
{
|
||||
type: 'a',
|
||||
extend: 'dynamicSplit',
|
||||
},
|
||||
{
|
||||
type: 'b',
|
||||
extend: 'a',
|
||||
extendChildRegistries: [
|
||||
{
|
||||
type: 'blockIcon',
|
||||
customKey: 'blockIcon_from_b',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'c',
|
||||
extend: 'b',
|
||||
extendChildRegistries: [
|
||||
{
|
||||
type: 'blockIcon',
|
||||
customKey: 'blockIcon_from_c',
|
||||
},
|
||||
{
|
||||
type: 'inlineBlocks',
|
||||
customKey: 'inlineBlocks_from_c',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
describe('flow-node-registry', () => {
|
||||
let doc: FlowDocument;
|
||||
beforeEach(() => {
|
||||
const container = createDocumentContainer();
|
||||
doc = container.get<FlowDocument>(FlowDocument);
|
||||
doc.registerFlowNodes(...mockRegistries);
|
||||
});
|
||||
it('extend check', () => {
|
||||
expect(doc.getNodeRegistry('dynamicSplit').__extends__).toEqual(undefined);
|
||||
expect(doc.getNodeRegistry('a').__extends__).toEqual(['dynamicSplit']);
|
||||
expect(doc.getNodeRegistry('b').__extends__).toEqual(['a', 'dynamicSplit']);
|
||||
expect(doc.getNodeRegistry('c').__extends__).toEqual(['b', 'a', 'dynamicSplit']);
|
||||
expect(doc.isExtend('dynamicSplit', 'dynamicSplit')).toBeFalsy();
|
||||
expect(doc.isExtend('a', 'b')).toBeFalsy();
|
||||
expect(doc.isExtend('a', 'dynamicSplit')).toBeTruthy();
|
||||
expect(doc.isExtend('b', 'dynamicSplit')).toBeTruthy();
|
||||
expect(doc.isExtend('b', 'a')).toBeTruthy();
|
||||
expect(doc.isExtend('c', 'dynamicSplit')).toBeTruthy();
|
||||
expect(doc.isExtend('c', 'b')).toBeTruthy();
|
||||
expect(doc.isExtend('c', 'a')).toBeTruthy();
|
||||
});
|
||||
it('base extend', () => {
|
||||
expect(doc.getNodeRegistry('a').onAdd).toBeTypeOf('function');
|
||||
doc.addNode({
|
||||
id: 'a',
|
||||
type: 'a',
|
||||
parent: doc.root,
|
||||
});
|
||||
expect(doc.toString()).toEqual(`root
|
||||
|-- a
|
||||
|---- $blockIcon$a
|
||||
|---- $inlineBlocks$a`);
|
||||
expect(doc.getNode('$blockIcon$a').getNodeRegistry().customKey).toBe('blockIcon_base');
|
||||
});
|
||||
it('extend nested', () => {
|
||||
expect(doc.getNodeRegistry('b').onAdd).toBeTypeOf('function');
|
||||
doc.addNode({
|
||||
id: 'b',
|
||||
type: 'b',
|
||||
parent: doc.root,
|
||||
});
|
||||
doc.addNode({
|
||||
id: 'c',
|
||||
type: 'c',
|
||||
parent: doc.root,
|
||||
});
|
||||
expect(doc.toString()).toEqual(`root
|
||||
|-- b
|
||||
|---- $blockIcon$b
|
||||
|---- $inlineBlocks$b
|
||||
|-- c
|
||||
|---- $blockIcon$c
|
||||
|---- $inlineBlocks$c`);
|
||||
expect(doc.getNode('$blockIcon$b').getNodeRegistry().customKey).toBe('blockIcon_from_b');
|
||||
expect(doc.getNode('$inlineBlocks$b').getNodeRegistry().customKey).toBe('inlineBlocks_base');
|
||||
expect(doc.getNode('$blockIcon$c').getNodeRegistry().customKey).toBe('blockIcon_from_c');
|
||||
expect(doc.getNode('$inlineBlocks$c').getNodeRegistry().customKey).toBe('inlineBlocks_from_c');
|
||||
});
|
||||
});
|
||||
@ -433,10 +433,23 @@ export class FlowDocument<T = FlowDocumentJSON> implements Disposable {
|
||||
...preRegistry?.meta,
|
||||
...newRegistry?.meta,
|
||||
},
|
||||
extendChildRegistries: FlowNodeRegistry.mergeChildRegistries(
|
||||
preRegistry?.extendChildRegistries,
|
||||
newRegistry?.extendChildRegistries
|
||||
),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check node extend
|
||||
* @param currentType
|
||||
* @param parentType
|
||||
*/
|
||||
isExtend(currentType: FlowNodeType, parentType: FlowNodeType): boolean {
|
||||
return (this.getNodeRegistry(currentType).__extends__ || []).includes(parentType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出数据,可以重载
|
||||
*/
|
||||
|
||||
@ -276,6 +276,10 @@ export interface FlowNodeRegistry<M extends FlowNodeMeta = FlowNodeMeta> {
|
||||
}
|
||||
) => FlowNodeEntity;
|
||||
|
||||
/**
|
||||
* 内部用于继承逻辑判断,不要使用
|
||||
*/
|
||||
__extends__?: FlowNodeType[];
|
||||
/**
|
||||
* 扩展注册器
|
||||
*/
|
||||
@ -283,17 +287,43 @@ export interface FlowNodeRegistry<M extends FlowNodeMeta = FlowNodeMeta> {
|
||||
}
|
||||
|
||||
export namespace FlowNodeRegistry {
|
||||
export function mergeChildRegistries(
|
||||
r1: FlowNodeRegistry[] = [],
|
||||
r2: FlowNodeRegistry[] = []
|
||||
): FlowNodeRegistry[] {
|
||||
if (r1.length === 0 || r2.length === 0) {
|
||||
return [...r1, ...r2];
|
||||
}
|
||||
const r1Filter = r1.map((r1Current) => {
|
||||
const r2Current = r2.find((n) => n.type === r1Current.type);
|
||||
if (r2Current) {
|
||||
return merge(r1Current, r2Current, r1Current.type);
|
||||
}
|
||||
return r1Current;
|
||||
});
|
||||
const r2Filter = r2.filter((n) => !r1.some((r) => r.type === n.type));
|
||||
return [...r1Filter, ...r2Filter];
|
||||
}
|
||||
export function merge(
|
||||
registry1: FlowNodeRegistry,
|
||||
registry2: FlowNodeRegistry,
|
||||
finalType: FlowNodeType
|
||||
): FlowNodeRegistry {
|
||||
const extendKeys = registry1.__extends__ ? registry1.__extends__.slice() : [];
|
||||
if (registry1.type !== registry2.type) {
|
||||
extendKeys.unshift(registry1.type);
|
||||
}
|
||||
return {
|
||||
...registry1,
|
||||
...registry2,
|
||||
extendChildRegistries: mergeChildRegistries(
|
||||
registry1.extendChildRegistries,
|
||||
registry2.extendChildRegistries
|
||||
),
|
||||
meta: { ...registry1.meta, ...registry2.meta },
|
||||
extend: undefined,
|
||||
type: finalType,
|
||||
__extends__: extendKeys,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user