- 分阶段加载智能体配置并按需缓存 MCP 工具 - 合并画布状态更新与节点尺寸监听,启用大图可视区域渲染和静态连线 - 隔离 Tinyflow Store 实例并补充数据同步与回归测试
87 lines
2.3 KiB
TypeScript
87 lines
2.3 KiB
TypeScript
import type { TinyflowOptions } from '@tinyflow-ai/ui';
|
|
|
|
type TinyflowDataOption = Exclude<
|
|
TinyflowOptions['data'],
|
|
string | undefined
|
|
>;
|
|
type StructuredCloneFn = <T>(value: T) => T;
|
|
|
|
function createDataSignature(data: unknown) {
|
|
if (data == null || typeof data === 'string') {
|
|
return String(data ?? '');
|
|
}
|
|
try {
|
|
return JSON.stringify(data);
|
|
} catch {
|
|
return '';
|
|
}
|
|
}
|
|
|
|
function safeDeepClone<T>(value: T): T {
|
|
if (value === null || typeof value !== 'object') {
|
|
return value;
|
|
}
|
|
|
|
try {
|
|
const clone = (globalThis as { structuredClone?: StructuredCloneFn })
|
|
.structuredClone;
|
|
if (clone) {
|
|
return clone(value);
|
|
}
|
|
} catch {
|
|
// Fall through to JSON cloning for browsers without native structuredClone.
|
|
}
|
|
|
|
try {
|
|
return JSON.parse(JSON.stringify(value));
|
|
} catch {
|
|
console.warn(
|
|
'Failed to clone object, returning original (may cause issues)',
|
|
value,
|
|
);
|
|
return value;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 维护 Vue 属性数据与 Tinyflow 原生数据之间的同步边界。
|
|
*
|
|
* 原生画布回传的数据会被父组件再次作为属性传入。延迟到属性更新时再比较
|
|
* 两侧签名,可以阻止同一份画布状态被重新深拷贝并整图应用,同时避免在
|
|
* 每一帧提前序列化完整画布。
|
|
*/
|
|
export function createTinyflowDataSync() {
|
|
let lastAppliedDataSignature = '';
|
|
let lastNativeData: TinyflowOptions['data'] | null = null;
|
|
|
|
return {
|
|
cloneExternalDataIfChanged(data: TinyflowOptions['data']) {
|
|
if (data == null || typeof data === 'string') {
|
|
return null;
|
|
}
|
|
const signature = createDataSignature(data);
|
|
if (lastNativeData != null) {
|
|
const nativeSignature = createDataSignature(lastNativeData);
|
|
lastNativeData = null;
|
|
if (signature && signature === nativeSignature) {
|
|
lastAppliedDataSignature = signature;
|
|
return null;
|
|
}
|
|
lastAppliedDataSignature = '';
|
|
}
|
|
if (signature && signature === lastAppliedDataSignature) {
|
|
return null;
|
|
}
|
|
lastAppliedDataSignature = signature;
|
|
return safeDeepClone(data as TinyflowDataOption);
|
|
},
|
|
markNativeData(data: TinyflowOptions['data']) {
|
|
lastNativeData = data;
|
|
},
|
|
reset() {
|
|
lastAppliedDataSignature = '';
|
|
lastNativeData = null;
|
|
},
|
|
};
|
|
}
|