flowgram.ai/packages/variable-engine/variable-layout/src/services/scope-chain-transform-service.ts
Yiwei Mao 93aa3e77b1
feat(variable): batch outputs (#426)
* feat: get by key path in flow-node-variable-data

* feat: scope chain transform service

* feat: form outputs plugin

* feat: base variable field

* feat: move set var get var to scope

* feat: batch outputs

* feat: form plugin create effect by func

* feat: batch output key configuration

* feat: merge effet api in form plugin

* feat: form plugin

* fix: variable layout test

* feat: simplify defineFormPluginCreator
2025-07-01 03:47:52 +00:00

97 lines
2.7 KiB
TypeScript

import { inject, injectable, optional } from 'inversify';
import { Scope, VariableEngine } from '@flowgram.ai/variable-core';
import { FlowDocument } from '@flowgram.ai/document';
import { lazyInject } from '@flowgram.ai/core';
import { VariableLayoutConfig } from '../variable-layout-config';
import { FlowNodeScope } from '../types';
export interface TransformerContext {
scope: FlowNodeScope;
document: FlowDocument;
variableEngine: VariableEngine;
}
export type IScopeTransformer = (scopes: Scope[], ctx: TransformerContext) => Scope[];
const passthrough: IScopeTransformer = (scopes, ctx) => scopes;
@injectable()
export class ScopeChainTransformService {
protected transformerMap: Map<
string,
{ transformDeps: IScopeTransformer; transformCovers: IScopeTransformer }
> = new Map();
@lazyInject(FlowDocument) document: FlowDocument;
@lazyInject(VariableEngine) variableEngine: VariableEngine;
constructor(
@optional()
@inject(VariableLayoutConfig)
protected configs?: VariableLayoutConfig
) {
if (this.configs?.transformDeps || this.configs?.transformCovers) {
this.transformerMap.set('VARIABLE_LAYOUT_CONFIG', {
transformDeps: this.configs.transformDeps || passthrough,
transformCovers: this.configs.transformCovers || passthrough,
});
}
}
/**
* check if transformer registered
* @param transformerId used to identify transformer, prevent duplicated
* @returns
*/
hasTransformer(transformerId: string) {
return this.transformerMap.has(transformerId);
}
/**
* register new transform function
* @param transformerId used to identify transformer, prevent duplicated transformer
* @param transformer
*/
registerTransformer(
transformerId: string,
transformer: {
transformDeps: IScopeTransformer;
transformCovers: IScopeTransformer;
}
) {
this.transformerMap.set(transformerId, transformer);
}
transformDeps(scopes: Scope[], { scope }: { scope: Scope }): Scope[] {
return Array.from(this.transformerMap.values()).reduce((scopes, transformer) => {
if (!transformer.transformDeps) {
return scopes;
}
scopes = transformer.transformDeps(scopes, {
scope,
document: this.document,
variableEngine: this.variableEngine,
});
return scopes;
}, scopes);
}
transformCovers(scopes: Scope[], { scope }: { scope: Scope }): Scope[] {
return Array.from(this.transformerMap.values()).reduce((scopes, transformer) => {
if (!transformer.transformCovers) {
return scopes;
}
scopes = transformer.transformCovers(scopes, {
scope,
document: this.document,
variableEngine: this.variableEngine,
});
return scopes;
}, scopes);
}
}