feat: 增加工作流合法性校验功能

This commit is contained in:
2026-03-04 19:56:42 +08:00
parent a79718b03b
commit ae9bb2c53f
12 changed files with 1755 additions and 38 deletions

View File

@@ -35,6 +35,31 @@ export class Tinyflow {
throw new Error('element must be a string or Element');
}
this.tinyflowEl = this._createTinyflowElement();
this.rootEl.appendChild(this.tinyflowEl);
}
private _setOptions(options: TinyflowOptions) {
this.options = {
theme: options.theme || 'light',
...options
};
}
private _getFlowInstance() {
if (!this.svelteFlowInstance) {
console.warn('Tinyflow instance is not initialized');
return null;
}
return this.svelteFlowInstance;
}
private _applyThemeClass(targetEl: Element, theme?: TinyflowTheme) {
targetEl.classList.remove('tf-theme-light', 'tf-theme-dark');
targetEl.classList.add(theme === 'dark' ? 'tf-theme-dark' : 'tf-theme-light');
}
private _createTinyflowElement() {
const tinyflowEl = document.createElement(componentName) as HTMLElement & {
options: TinyflowOptions;
onInit: (svelteFlowInstance: FlowInstance) => void;
@@ -56,7 +81,56 @@ export class Tinyflow {
}
getData() {
return this.svelteFlowInstance.toObject();
const flow = this._getFlowInstance();
if (!flow) {
return null;
}
return flow.toObject();
}
async focusNode(nodeId: string, options?: { duration?: number; zoom?: number }) {
const flow = this._getFlowInstance();
if (!flow) {
return false;
}
const targetNode = flow.getNode(nodeId);
if (!targetNode) {
return false;
}
// Keep only the target node selected so the canvas has a clear visual focus.
flow.getNodes().forEach((node) => {
flow.updateNode(node.id, { selected: node.id === nodeId });
});
const internalNode = flow.getInternalNode(nodeId) as any;
const absolutePosition =
internalNode?.internals?.positionAbsolute ||
(targetNode as any)?.positionAbsolute ||
targetNode.position ||
{ x: 0, y: 0 };
const width =
internalNode?.measured?.width ||
(targetNode as any)?.measured?.width ||
(targetNode as any)?.width ||
260;
const height =
internalNode?.measured?.height ||
(targetNode as any)?.measured?.height ||
(targetNode as any)?.height ||
120;
const centerX = absolutePosition.x + width / 2;
const centerY = absolutePosition.y + height / 2;
const nextZoom = options?.zoom ?? Math.max(flow.getZoom(), 1);
await flow.setCenter(centerX, centerY, {
zoom: nextZoom,
duration: options?.duration ?? 280
});
return true;
}
setTheme(theme: TinyflowTheme) {