From 202c06040e72f7acc58c972b55794adec498a7d6 Mon Sep 17 00:00:00 2001 From: Yiwei Mao Date: Mon, 28 Apr 2025 10:55:24 +0800 Subject: [PATCH] feat(variable): global variable scope (#182) --- .../src/create-variable-plugin.ts | 5 +- packages/plugins/variable-plugin/src/index.ts | 2 +- .../variable-core/src/scope/scope.ts | 8 + .../variable-core/src/variable-engine.ts | 21 +- .../variable-layout/__mocks__/container.ts | 21 +- .../__mocks__/run-fixed-layout-test.ts | 9 +- .../__mocks__/run-free-layout-test.ts | 9 +- ...iable-fix-enable-global-scope.test.ts.snap | 781 ++++++++++++++++++ ...e-fix-layout-filter-start-end.test.ts.snap | 2 +- .../variable-fix-layout-group.test.ts.snap | 2 +- ...variable-fix-layout-no-config.test.ts.snap | 2 +- .../variable-fix-layout.test.ts.snap | 2 +- ...able-free-enable-global-scope.test.ts.snap | 343 ++++++++ ...e-free-layout-transform-empty.test.ts.snap | 2 +- .../variable-free-layout.test.ts.snap | 2 +- .../variable-fix-enable-global-scope.test.ts | 6 + .../variable-free-enable-global-scope.test.ts | 6 + .../{ => chains}/fixed-layout-scope-chain.ts | 20 +- .../{ => chains}/free-layout-scope-chain.ts | 38 +- .../variable-layout/src/index.ts | 5 +- .../src/scopes/global-scope.ts | 78 ++ 21 files changed, 1325 insertions(+), 39 deletions(-) create mode 100644 packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-fix-enable-global-scope.test.ts.snap create mode 100644 packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-free-enable-global-scope.test.ts.snap create mode 100644 packages/variable-engine/variable-layout/__tests__/variable-fix-enable-global-scope.test.ts create mode 100644 packages/variable-engine/variable-layout/__tests__/variable-free-enable-global-scope.test.ts rename packages/variable-engine/variable-layout/src/{ => chains}/fixed-layout-scope-chain.ts (93%) rename packages/variable-engine/variable-layout/src/{ => chains}/free-layout-scope-chain.ts (84%) create mode 100644 packages/variable-engine/variable-layout/src/scopes/global-scope.ts diff --git a/packages/plugins/variable-plugin/src/create-variable-plugin.ts b/packages/plugins/variable-plugin/src/create-variable-plugin.ts index aad1ef7e..8f088665 100644 --- a/packages/plugins/variable-plugin/src/create-variable-plugin.ts +++ b/packages/plugins/variable-plugin/src/create-variable-plugin.ts @@ -3,6 +3,7 @@ import { FreeLayoutScopeChain, FixedLayoutScopeChain, VariableLayoutConfig, + bindGlobalScope, } from '@flowgram.ai/variable-layout'; import { VariableContainerModule, @@ -43,6 +44,8 @@ export const createVariablePlugin = definePluginCreator({ if (layoutConfig) { bind(VariableLayoutConfig).toConstantValue(layoutConfig || {}); } + + bindGlobalScope(bind); }, onInit(ctx, opts) { const { extendASTNodes } = opts || {}; @@ -55,7 +58,7 @@ export const createVariablePlugin = definePluginCreator({ /** * 注册扩展 AST 节点 */ - (extendASTNodes || []).forEach(info => { + (extendASTNodes || []).forEach((info) => { if (Array.isArray(info)) { const [extendASTNode, injector] = info; diff --git a/packages/plugins/variable-plugin/src/index.ts b/packages/plugins/variable-plugin/src/index.ts index c0786804..04d39d92 100644 --- a/packages/plugins/variable-plugin/src/index.ts +++ b/packages/plugins/variable-plugin/src/index.ts @@ -1,3 +1,3 @@ export * from './create-variable-plugin'; export * from '@flowgram.ai/variable-core'; -export { FlowNodeVariableData } from '@flowgram.ai/variable-layout'; +export { FlowNodeVariableData, GlobalScope } from '@flowgram.ai/variable-layout'; diff --git a/packages/variable-engine/variable-core/src/scope/scope.ts b/packages/variable-engine/variable-core/src/scope/scope.ts index cfa02e3c..d1432823 100644 --- a/packages/variable-engine/variable-core/src/scope/scope.ts +++ b/packages/variable-engine/variable-core/src/scope/scope.ts @@ -5,6 +5,14 @@ import { createMemo } from '../utils/memo'; import { ASTKind, MapNode } from '../ast'; import { ScopeAvailableData, ScopeEventData, ScopeOutputData } from './datas'; +export interface IScopeConstructor { + new (options: { + id: string | symbol; + variableEngine: VariableEngine; + meta?: Record; + }): Scope; +} + export class Scope = Record> { /** * Scope 唯一索引 diff --git a/packages/variable-engine/variable-core/src/variable-engine.ts b/packages/variable-engine/variable-core/src/variable-engine.ts index cfbbe76c..904df65a 100644 --- a/packages/variable-engine/variable-core/src/variable-engine.ts +++ b/packages/variable-engine/variable-core/src/variable-engine.ts @@ -7,6 +7,7 @@ import { subsToDisposable } from './utils/toDisposable'; import { createMemo } from './utils/memo'; import { VariableTable } from './scope/variable-table'; import { ScopeChangeAction } from './scope/types'; +import { IScopeConstructor } from './scope/scope'; import { Scope, ScopeChain, type IVariableTable } from './scope'; import { ContainerProvider } from './providers'; import { ASTRegisters, type GlobalEventActionType } from './ast'; @@ -63,12 +64,26 @@ export class VariableEngine implements Disposable { this.getScopeById(scopeId)?.dispose(); } - // 获取 Scope,如果 Scope 存在且类型相同,则会直接使用 - createScope(id: string | symbol, meta?: Record): Scope { + /** + * Get Scope, if Scope exists and type is same, will use it directly + * @param id scope id + * @param meta scope meta, defined by user + * @param ScopeConstructor scope constructor, default is Scope. you can extends Scope to create your own scope + * @returns + */ + createScope( + id: string | symbol, + meta?: Record, + options: { + ScopeConstructor?: IScopeConstructor; + } = {} + ): Scope { + const { ScopeConstructor = Scope } = options; + let scope = this.getScopeById(id); if (!scope) { - scope = new Scope({ variableEngine: this, meta, id }); + scope = new ScopeConstructor({ variableEngine: this, meta, id }); this.scopeMap.set(id, scope); this.onScopeChangeEmitter.fire({ type: 'add', scope: scope! }); diff --git a/packages/variable-engine/variable-layout/__mocks__/container.ts b/packages/variable-engine/variable-layout/__mocks__/container.ts index e3bcd4ff..cdbf90b6 100644 --- a/packages/variable-engine/variable-layout/__mocks__/container.ts +++ b/packages/variable-engine/variable-layout/__mocks__/container.ts @@ -1,5 +1,6 @@ import { Container } from 'inversify'; import { + ASTFactory, ScopeChain, VariableContainerModule, } from '@flowgram.ai/variable-core'; @@ -9,6 +10,8 @@ import { FixedLayoutScopeChain, FlowNodeVariableData, VariableLayoutConfig, + GlobalScope, + bindGlobalScope, } from '../src'; import { EntityManager } from '@flowgram.ai/core'; import { VariableEngine } from '@flowgram.ai/variable-core'; @@ -18,7 +21,13 @@ import { } from '@flowgram.ai/document'; import { WorkflowDocumentContainerModule, WorkflowLinesManager, WorkflowSimpleLineContribution } from '@flowgram.ai/free-layout-core'; -export function getContainer(layout: 'free' | 'fixed', layoutConfig?: VariableLayoutConfig): Container { +export interface TestConfig extends VariableLayoutConfig { + enableGlobalScope?: boolean; +} + +export function getContainer(layout: 'free' | 'fixed', config?: TestConfig): Container { + const { enableGlobalScope, ...layoutConfig } = config || {}; + const container = createPlaygroundContainer() as Container; container.load(VariableContainerModule); container.load(FlowDocumentContainerModule); @@ -39,10 +48,20 @@ export function getContainer(layout: 'free' | 'fixed', layoutConfig?: VariableLa container.bind(ScopeChain).to(FixedLayoutScopeChain).inSingletonScope(); } + bindGlobalScope(container.bind.bind(container)) + const entityManager = container.get(EntityManager); const variableEngine = container.get(VariableEngine); const document = container.get(FlowDocument); + if (enableGlobalScope) { + // when get global scope, it will auto create it if not exists + container.get(GlobalScope).setVar(ASTFactory.createVariableDeclaration({ + key: 'GlobalScope', + type: ASTFactory.createString(), + })); + } + /** * 扩展 FlowNodeVariableData */ diff --git a/packages/variable-engine/variable-layout/__mocks__/run-fixed-layout-test.ts b/packages/variable-engine/variable-layout/__mocks__/run-fixed-layout-test.ts index 1f29a4e5..0a4bee85 100644 --- a/packages/variable-engine/variable-layout/__mocks__/run-fixed-layout-test.ts +++ b/packages/variable-engine/variable-layout/__mocks__/run-fixed-layout-test.ts @@ -4,11 +4,10 @@ import { ASTKind } from '@flowgram.ai/variable-core'; import { FlowDocument, FlowDocumentJSON } from '@flowgram.ai/document'; import { FlowNodeVariableData, - VariableLayoutConfig, } from '../src'; -import { getContainer } from './container' +import { TestConfig, getContainer } from './container' -export const runFixedLayoutTest = (testName:string, spec: FlowDocumentJSON, config?: VariableLayoutConfig) => { +export const runFixedLayoutTest = (testName:string, spec: FlowDocumentJSON, config?: TestConfig) => { describe(testName, () => { const container = getContainer('fixed', config); const flowDocument = container.get(FlowDocument); @@ -27,8 +26,8 @@ export const runFixedLayoutTest = (testName:string, spec: FlowDocumentJSON, conf } }); - // 创建一个全局作用域 - variableEngine.createScope('globalScope'); + // 创建一个测试作用域 + variableEngine.createScope('testScope'); const traverseVariableDatas = () => flowDocument diff --git a/packages/variable-engine/variable-layout/__mocks__/run-free-layout-test.ts b/packages/variable-engine/variable-layout/__mocks__/run-free-layout-test.ts index 9a528cb3..b1bb6ee9 100644 --- a/packages/variable-engine/variable-layout/__mocks__/run-free-layout-test.ts +++ b/packages/variable-engine/variable-layout/__mocks__/run-free-layout-test.ts @@ -2,13 +2,12 @@ import { describe, expect, test } from 'vitest'; import { VariableEngine } from '@flowgram.ai/variable-core'; import { ASTKind } from '@flowgram.ai/variable-core'; import { - FlowNodeVariableData, - VariableLayoutConfig, + FlowNodeVariableData } from '../src'; -import { getContainer } from './container'; +import { TestConfig, getContainer } from './container'; import { WorkflowDocument, WorkflowJSON } from '@flowgram.ai/free-layout-core'; -export const runFreeLayoutTest = (testName: string, spec: WorkflowJSON, config?: VariableLayoutConfig) => { +export const runFreeLayoutTest = (testName: string, spec: WorkflowJSON, config?: TestConfig) => { describe(testName, async () => { const container = getContainer('free', config); const flowDocument = container.get(WorkflowDocument); @@ -28,7 +27,7 @@ export const runFreeLayoutTest = (testName: string, spec: WorkflowJSON, config?: }); // 创建一个全局作用域 - variableEngine.createScope('globalScope'); + variableEngine.createScope('testScope'); const traverseVariableDatas = () => flowDocument diff --git a/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-fix-enable-global-scope.test.ts.snap b/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-fix-enable-global-scope.test.ts.snap new file mode 100644 index 00000000..5d78bf3c --- /dev/null +++ b/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-fix-enable-global-scope.test.ts.snap @@ -0,0 +1,781 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Variable Fix Layout Enable Global Scope > test get Covers 1`] = ` +Map { + "start" => [ + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "createRecord_8f85ff2c11d", + "exclusiveSplit_ff2c11d0fb4", + "branch_f2c11d0fb42", + "branch_2c11d0fb42c", + "exclusiveSplit_88dbf2c60ae", + "branch_8dbf2c60aee", + "exclusiveSplit_a59afaadc9a", + "branch_59afaadc9ac", + "branch_9afaadc9acd", + "deleteRecords_c32807e97c5", + "branch_dbf2c60aee4", + "updateRecords_7ed2a172c32", + "end", + ], + "getRecords_07e97c55832" => [ + "forEach_260a8f85ff2", + "createRecord_8f85ff2c11d", + "exclusiveSplit_ff2c11d0fb4", + "branch_f2c11d0fb42", + "branch_2c11d0fb42c", + "exclusiveSplit_88dbf2c60ae", + "branch_8dbf2c60aee", + "exclusiveSplit_a59afaadc9a", + "branch_59afaadc9ac", + "branch_9afaadc9acd", + "deleteRecords_c32807e97c5", + "branch_dbf2c60aee4", + "updateRecords_7ed2a172c32", + "end", + ], + "forEach_260a8f85ff2" => [ + "exclusiveSplit_88dbf2c60ae", + "branch_8dbf2c60aee", + "exclusiveSplit_a59afaadc9a", + "branch_59afaadc9ac", + "branch_9afaadc9acd", + "deleteRecords_c32807e97c5", + "branch_dbf2c60aee4", + "updateRecords_7ed2a172c32", + "end", + ], + "createRecord_8f85ff2c11d" => [ + "exclusiveSplit_ff2c11d0fb4", + "branch_f2c11d0fb42", + "branch_2c11d0fb42c", + ], + "exclusiveSplit_ff2c11d0fb4" => [], + "branch_f2c11d0fb42" => [ + "branch_2c11d0fb42c", + ], + "branch_2c11d0fb42c" => [], + "exclusiveSplit_88dbf2c60ae" => [ + "end", + ], + "branch_8dbf2c60aee" => [ + "branch_dbf2c60aee4", + "updateRecords_7ed2a172c32", + ], + "exclusiveSplit_a59afaadc9a" => [], + "branch_59afaadc9ac" => [ + "branch_9afaadc9acd", + "deleteRecords_c32807e97c5", + ], + "branch_9afaadc9acd" => [], + "deleteRecords_c32807e97c5" => [], + "branch_dbf2c60aee4" => [], + "updateRecords_7ed2a172c32" => [], + "end" => [], +} +`; + +exports[`Variable Fix Layout Enable Global Scope > test get Covers After Init Private 1`] = ` +Map { + "start" => [ + "getRecords_07e97c55832", + "getRecords_07e97c55832_private", + "forEach_260a8f85ff2", + "forEach_260a8f85ff2_private", + "createRecord_8f85ff2c11d", + "createRecord_8f85ff2c11d_private", + "exclusiveSplit_ff2c11d0fb4", + "exclusiveSplit_ff2c11d0fb4_private", + "branch_f2c11d0fb42", + "branch_f2c11d0fb42_private", + "branch_2c11d0fb42c", + "branch_2c11d0fb42c_private", + "exclusiveSplit_88dbf2c60ae", + "exclusiveSplit_88dbf2c60ae_private", + "branch_8dbf2c60aee", + "branch_8dbf2c60aee_private", + "exclusiveSplit_a59afaadc9a", + "exclusiveSplit_a59afaadc9a_private", + "branch_59afaadc9ac", + "branch_59afaadc9ac_private", + "branch_9afaadc9acd", + "branch_9afaadc9acd_private", + "deleteRecords_c32807e97c5", + "deleteRecords_c32807e97c5_private", + "branch_dbf2c60aee4", + "branch_dbf2c60aee4_private", + "updateRecords_7ed2a172c32", + "updateRecords_7ed2a172c32_private", + "end", + "end_private", + ], + "getRecords_07e97c55832" => [ + "forEach_260a8f85ff2", + "forEach_260a8f85ff2_private", + "createRecord_8f85ff2c11d", + "createRecord_8f85ff2c11d_private", + "exclusiveSplit_ff2c11d0fb4", + "exclusiveSplit_ff2c11d0fb4_private", + "branch_f2c11d0fb42", + "branch_f2c11d0fb42_private", + "branch_2c11d0fb42c", + "branch_2c11d0fb42c_private", + "exclusiveSplit_88dbf2c60ae", + "exclusiveSplit_88dbf2c60ae_private", + "branch_8dbf2c60aee", + "branch_8dbf2c60aee_private", + "exclusiveSplit_a59afaadc9a", + "exclusiveSplit_a59afaadc9a_private", + "branch_59afaadc9ac", + "branch_59afaadc9ac_private", + "branch_9afaadc9acd", + "branch_9afaadc9acd_private", + "deleteRecords_c32807e97c5", + "deleteRecords_c32807e97c5_private", + "branch_dbf2c60aee4", + "branch_dbf2c60aee4_private", + "updateRecords_7ed2a172c32", + "updateRecords_7ed2a172c32_private", + "end", + "end_private", + ], + "forEach_260a8f85ff2" => [ + "exclusiveSplit_88dbf2c60ae", + "exclusiveSplit_88dbf2c60ae_private", + "branch_8dbf2c60aee", + "branch_8dbf2c60aee_private", + "exclusiveSplit_a59afaadc9a", + "exclusiveSplit_a59afaadc9a_private", + "branch_59afaadc9ac", + "branch_59afaadc9ac_private", + "branch_9afaadc9acd", + "branch_9afaadc9acd_private", + "deleteRecords_c32807e97c5", + "deleteRecords_c32807e97c5_private", + "branch_dbf2c60aee4", + "branch_dbf2c60aee4_private", + "updateRecords_7ed2a172c32", + "updateRecords_7ed2a172c32_private", + "end", + "end_private", + ], + "createRecord_8f85ff2c11d" => [ + "exclusiveSplit_ff2c11d0fb4", + "exclusiveSplit_ff2c11d0fb4_private", + "branch_f2c11d0fb42", + "branch_f2c11d0fb42_private", + "branch_2c11d0fb42c", + "branch_2c11d0fb42c_private", + ], + "exclusiveSplit_ff2c11d0fb4" => [], + "branch_f2c11d0fb42" => [ + "branch_2c11d0fb42c", + "branch_2c11d0fb42c_private", + ], + "branch_2c11d0fb42c" => [], + "exclusiveSplit_88dbf2c60ae" => [ + "end", + "end_private", + ], + "branch_8dbf2c60aee" => [ + "branch_dbf2c60aee4", + "branch_dbf2c60aee4_private", + "updateRecords_7ed2a172c32", + "updateRecords_7ed2a172c32_private", + ], + "exclusiveSplit_a59afaadc9a" => [], + "branch_59afaadc9ac" => [ + "branch_9afaadc9acd", + "branch_9afaadc9acd_private", + "deleteRecords_c32807e97c5", + "deleteRecords_c32807e97c5_private", + ], + "branch_9afaadc9acd" => [], + "deleteRecords_c32807e97c5" => [], + "branch_dbf2c60aee4" => [], + "updateRecords_7ed2a172c32" => [], + "end" => [], +} +`; + +exports[`Variable Fix Layout Enable Global Scope > test get Deps 1`] = ` +Map { + "start" => [ + "GlobalScope", + ], + "getRecords_07e97c55832" => [ + "GlobalScope", + "start", + ], + "forEach_260a8f85ff2" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + ], + "createRecord_8f85ff2c11d" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + ], + "exclusiveSplit_ff2c11d0fb4" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "createRecord_8f85ff2c11d", + ], + "branch_f2c11d0fb42" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "createRecord_8f85ff2c11d", + "exclusiveSplit_ff2c11d0fb4", + ], + "branch_2c11d0fb42c" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "createRecord_8f85ff2c11d", + "exclusiveSplit_ff2c11d0fb4", + "branch_f2c11d0fb42", + ], + "exclusiveSplit_88dbf2c60ae" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + ], + "branch_8dbf2c60aee" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "exclusiveSplit_88dbf2c60ae", + ], + "exclusiveSplit_a59afaadc9a" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "exclusiveSplit_88dbf2c60ae", + "branch_8dbf2c60aee", + ], + "branch_59afaadc9ac" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "exclusiveSplit_88dbf2c60ae", + "branch_8dbf2c60aee", + "exclusiveSplit_a59afaadc9a", + ], + "branch_9afaadc9acd" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "exclusiveSplit_88dbf2c60ae", + "branch_8dbf2c60aee", + "exclusiveSplit_a59afaadc9a", + "branch_59afaadc9ac", + ], + "deleteRecords_c32807e97c5" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "exclusiveSplit_88dbf2c60ae", + "branch_8dbf2c60aee", + "exclusiveSplit_a59afaadc9a", + "branch_59afaadc9ac", + "branch_9afaadc9acd", + ], + "branch_dbf2c60aee4" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "exclusiveSplit_88dbf2c60ae", + "branch_8dbf2c60aee", + ], + "updateRecords_7ed2a172c32" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "exclusiveSplit_88dbf2c60ae", + "branch_8dbf2c60aee", + "branch_dbf2c60aee4", + ], + "end" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "exclusiveSplit_88dbf2c60ae", + ], +} +`; + +exports[`Variable Fix Layout Enable Global Scope > test get Deps After Init Private 1`] = ` +Map { + "start" => [ + "GlobalScope", + "start_private", + ], + "getRecords_07e97c55832" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832_private", + ], + "forEach_260a8f85ff2" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2_private", + ], + "createRecord_8f85ff2c11d" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "forEach_260a8f85ff2_private", + "createRecord_8f85ff2c11d_private", + ], + "exclusiveSplit_ff2c11d0fb4" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "forEach_260a8f85ff2_private", + "createRecord_8f85ff2c11d", + "exclusiveSplit_ff2c11d0fb4_private", + ], + "branch_f2c11d0fb42" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "forEach_260a8f85ff2_private", + "createRecord_8f85ff2c11d", + "exclusiveSplit_ff2c11d0fb4", + "exclusiveSplit_ff2c11d0fb4_private", + "branch_f2c11d0fb42_private", + ], + "branch_2c11d0fb42c" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "forEach_260a8f85ff2_private", + "createRecord_8f85ff2c11d", + "exclusiveSplit_ff2c11d0fb4", + "exclusiveSplit_ff2c11d0fb4_private", + "branch_f2c11d0fb42", + "branch_2c11d0fb42c_private", + ], + "exclusiveSplit_88dbf2c60ae" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "exclusiveSplit_88dbf2c60ae_private", + ], + "branch_8dbf2c60aee" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "exclusiveSplit_88dbf2c60ae", + "exclusiveSplit_88dbf2c60ae_private", + "branch_8dbf2c60aee_private", + ], + "exclusiveSplit_a59afaadc9a" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "exclusiveSplit_88dbf2c60ae", + "exclusiveSplit_88dbf2c60ae_private", + "branch_8dbf2c60aee", + "branch_8dbf2c60aee_private", + "exclusiveSplit_a59afaadc9a_private", + ], + "branch_59afaadc9ac" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "exclusiveSplit_88dbf2c60ae", + "exclusiveSplit_88dbf2c60ae_private", + "branch_8dbf2c60aee", + "branch_8dbf2c60aee_private", + "exclusiveSplit_a59afaadc9a", + "exclusiveSplit_a59afaadc9a_private", + "branch_59afaadc9ac_private", + ], + "branch_9afaadc9acd" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "exclusiveSplit_88dbf2c60ae", + "exclusiveSplit_88dbf2c60ae_private", + "branch_8dbf2c60aee", + "branch_8dbf2c60aee_private", + "exclusiveSplit_a59afaadc9a", + "exclusiveSplit_a59afaadc9a_private", + "branch_59afaadc9ac", + "branch_9afaadc9acd_private", + ], + "deleteRecords_c32807e97c5" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "exclusiveSplit_88dbf2c60ae", + "exclusiveSplit_88dbf2c60ae_private", + "branch_8dbf2c60aee", + "branch_8dbf2c60aee_private", + "exclusiveSplit_a59afaadc9a", + "exclusiveSplit_a59afaadc9a_private", + "branch_59afaadc9ac", + "branch_9afaadc9acd", + "branch_9afaadc9acd_private", + "deleteRecords_c32807e97c5_private", + ], + "branch_dbf2c60aee4" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "exclusiveSplit_88dbf2c60ae", + "exclusiveSplit_88dbf2c60ae_private", + "branch_8dbf2c60aee", + "branch_dbf2c60aee4_private", + ], + "updateRecords_7ed2a172c32" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "exclusiveSplit_88dbf2c60ae", + "exclusiveSplit_88dbf2c60ae_private", + "branch_8dbf2c60aee", + "branch_dbf2c60aee4", + "branch_dbf2c60aee4_private", + "updateRecords_7ed2a172c32_private", + ], + "end" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "exclusiveSplit_88dbf2c60ae", + "end_private", + ], +} +`; + +exports[`Variable Fix Layout Enable Global Scope > test get private scope Covers 1`] = ` +Map { + "start_private" => [ + "start", + ], + "getRecords_07e97c55832_private" => [ + "getRecords_07e97c55832", + ], + "forEach_260a8f85ff2_private" => [ + "forEach_260a8f85ff2", + "forEach_260a8f85ff2_private", + "createRecord_8f85ff2c11d", + "createRecord_8f85ff2c11d_private", + "exclusiveSplit_ff2c11d0fb4", + "exclusiveSplit_ff2c11d0fb4_private", + "branch_f2c11d0fb42", + "branch_f2c11d0fb42_private", + "branch_2c11d0fb42c", + "branch_2c11d0fb42c_private", + ], + "createRecord_8f85ff2c11d_private" => [ + "createRecord_8f85ff2c11d", + ], + "exclusiveSplit_ff2c11d0fb4_private" => [ + "exclusiveSplit_ff2c11d0fb4", + "exclusiveSplit_ff2c11d0fb4_private", + "branch_f2c11d0fb42", + "branch_f2c11d0fb42_private", + "branch_2c11d0fb42c", + "branch_2c11d0fb42c_private", + ], + "branch_f2c11d0fb42_private" => [ + "branch_f2c11d0fb42", + ], + "branch_2c11d0fb42c_private" => [ + "branch_2c11d0fb42c", + ], + "exclusiveSplit_88dbf2c60ae_private" => [ + "exclusiveSplit_88dbf2c60ae", + "exclusiveSplit_88dbf2c60ae_private", + "branch_8dbf2c60aee", + "branch_8dbf2c60aee_private", + "exclusiveSplit_a59afaadc9a", + "exclusiveSplit_a59afaadc9a_private", + "branch_59afaadc9ac", + "branch_59afaadc9ac_private", + "branch_9afaadc9acd", + "branch_9afaadc9acd_private", + "deleteRecords_c32807e97c5", + "deleteRecords_c32807e97c5_private", + "branch_dbf2c60aee4", + "branch_dbf2c60aee4_private", + "updateRecords_7ed2a172c32", + "updateRecords_7ed2a172c32_private", + ], + "branch_8dbf2c60aee_private" => [ + "branch_8dbf2c60aee", + "branch_8dbf2c60aee_private", + "exclusiveSplit_a59afaadc9a", + "exclusiveSplit_a59afaadc9a_private", + "branch_59afaadc9ac", + "branch_59afaadc9ac_private", + "branch_9afaadc9acd", + "branch_9afaadc9acd_private", + "deleteRecords_c32807e97c5", + "deleteRecords_c32807e97c5_private", + ], + "exclusiveSplit_a59afaadc9a_private" => [ + "exclusiveSplit_a59afaadc9a", + "exclusiveSplit_a59afaadc9a_private", + "branch_59afaadc9ac", + "branch_59afaadc9ac_private", + "branch_9afaadc9acd", + "branch_9afaadc9acd_private", + "deleteRecords_c32807e97c5", + "deleteRecords_c32807e97c5_private", + ], + "branch_59afaadc9ac_private" => [ + "branch_59afaadc9ac", + ], + "branch_9afaadc9acd_private" => [ + "branch_9afaadc9acd", + "branch_9afaadc9acd_private", + "deleteRecords_c32807e97c5", + "deleteRecords_c32807e97c5_private", + ], + "deleteRecords_c32807e97c5_private" => [ + "deleteRecords_c32807e97c5", + ], + "branch_dbf2c60aee4_private" => [ + "branch_dbf2c60aee4", + "branch_dbf2c60aee4_private", + "updateRecords_7ed2a172c32", + "updateRecords_7ed2a172c32_private", + ], + "updateRecords_7ed2a172c32_private" => [ + "updateRecords_7ed2a172c32", + ], + "end_private" => [ + "end", + ], +} +`; + +exports[`Variable Fix Layout Enable Global Scope > test get private scope Deps 1`] = ` +Map { + "start_private" => [ + "GlobalScope", + ], + "getRecords_07e97c55832_private" => [ + "GlobalScope", + "start", + ], + "forEach_260a8f85ff2_private" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + ], + "createRecord_8f85ff2c11d_private" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "forEach_260a8f85ff2_private", + ], + "exclusiveSplit_ff2c11d0fb4_private" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "forEach_260a8f85ff2_private", + "createRecord_8f85ff2c11d", + ], + "branch_f2c11d0fb42_private" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "forEach_260a8f85ff2_private", + "createRecord_8f85ff2c11d", + "exclusiveSplit_ff2c11d0fb4", + "exclusiveSplit_ff2c11d0fb4_private", + ], + "branch_2c11d0fb42c_private" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "forEach_260a8f85ff2_private", + "createRecord_8f85ff2c11d", + "exclusiveSplit_ff2c11d0fb4", + "exclusiveSplit_ff2c11d0fb4_private", + "branch_f2c11d0fb42", + ], + "exclusiveSplit_88dbf2c60ae_private" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + ], + "branch_8dbf2c60aee_private" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "exclusiveSplit_88dbf2c60ae", + "exclusiveSplit_88dbf2c60ae_private", + ], + "exclusiveSplit_a59afaadc9a_private" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "exclusiveSplit_88dbf2c60ae", + "exclusiveSplit_88dbf2c60ae_private", + "branch_8dbf2c60aee", + "branch_8dbf2c60aee_private", + ], + "branch_59afaadc9ac_private" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "exclusiveSplit_88dbf2c60ae", + "exclusiveSplit_88dbf2c60ae_private", + "branch_8dbf2c60aee", + "branch_8dbf2c60aee_private", + "exclusiveSplit_a59afaadc9a", + "exclusiveSplit_a59afaadc9a_private", + ], + "branch_9afaadc9acd_private" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "exclusiveSplit_88dbf2c60ae", + "exclusiveSplit_88dbf2c60ae_private", + "branch_8dbf2c60aee", + "branch_8dbf2c60aee_private", + "exclusiveSplit_a59afaadc9a", + "exclusiveSplit_a59afaadc9a_private", + "branch_59afaadc9ac", + ], + "deleteRecords_c32807e97c5_private" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "exclusiveSplit_88dbf2c60ae", + "exclusiveSplit_88dbf2c60ae_private", + "branch_8dbf2c60aee", + "branch_8dbf2c60aee_private", + "exclusiveSplit_a59afaadc9a", + "exclusiveSplit_a59afaadc9a_private", + "branch_59afaadc9ac", + "branch_9afaadc9acd", + "branch_9afaadc9acd_private", + ], + "branch_dbf2c60aee4_private" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "exclusiveSplit_88dbf2c60ae", + "exclusiveSplit_88dbf2c60ae_private", + "branch_8dbf2c60aee", + ], + "updateRecords_7ed2a172c32_private" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "exclusiveSplit_88dbf2c60ae", + "exclusiveSplit_88dbf2c60ae_private", + "branch_8dbf2c60aee", + "branch_dbf2c60aee4", + "branch_dbf2c60aee4_private", + ], + "end_private" => [ + "GlobalScope", + "start", + "getRecords_07e97c55832", + "forEach_260a8f85ff2", + "exclusiveSplit_88dbf2c60ae", + ], +} +`; + +exports[`Variable Fix Layout Enable Global Scope > test sort 1`] = ` +[ + Symbol(GlobalScope), + "start_private", + "start", + "getRecords_07e97c55832", + "getRecords_07e97c55832_private", + "forEach_260a8f85ff2", + "forEach_260a8f85ff2_private", + "createRecord_8f85ff2c11d", + "createRecord_8f85ff2c11d_private", + "exclusiveSplit_ff2c11d0fb4", + "exclusiveSplit_ff2c11d0fb4_private", + "branch_f2c11d0fb42", + "branch_f2c11d0fb42_private", + "branch_2c11d0fb42c", + "branch_2c11d0fb42c_private", + "exclusiveSplit_88dbf2c60ae", + "exclusiveSplit_88dbf2c60ae_private", + "branch_8dbf2c60aee", + "branch_8dbf2c60aee_private", + "exclusiveSplit_a59afaadc9a", + "exclusiveSplit_a59afaadc9a_private", + "branch_59afaadc9ac", + "branch_59afaadc9ac_private", + "branch_9afaadc9acd", + "branch_9afaadc9acd_private", + "deleteRecords_c32807e97c5", + "deleteRecords_c32807e97c5_private", + "branch_dbf2c60aee4", + "branch_dbf2c60aee4_private", + "updateRecords_7ed2a172c32", + "updateRecords_7ed2a172c32_private", + "end", + "end_private", + "testScope", + "$blockIcon$exclusiveSplit_ff2c11d0fb4", + "$inlineBlocks$exclusiveSplit_ff2c11d0fb4", + "$blockOrderIcon$branch_f2c11d0fb42", + "$blockOrderIcon$branch_2c11d0fb42c", + "$blockIcon$exclusiveSplit_88dbf2c60ae", + "$inlineBlocks$exclusiveSplit_88dbf2c60ae", + "$blockOrderIcon$branch_8dbf2c60aee", + "$blockIcon$exclusiveSplit_a59afaadc9a", + "$inlineBlocks$exclusiveSplit_a59afaadc9a", + "$blockOrderIcon$branch_59afaadc9ac", + "$blockOrderIcon$branch_9afaadc9acd", + "$blockOrderIcon$branch_dbf2c60aee4", +] +`; diff --git a/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-fix-layout-filter-start-end.test.ts.snap b/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-fix-layout-filter-start-end.test.ts.snap index d2793593..f63ce1a5 100644 --- a/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-fix-layout-filter-start-end.test.ts.snap +++ b/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-fix-layout-filter-start-end.test.ts.snap @@ -630,7 +630,7 @@ exports[`Variable Fix Layout Filter Start End > test sort 1`] = ` "branch_dbf2c60aee4_private", "updateRecords_7ed2a172c32", "updateRecords_7ed2a172c32_private", - "globalScope", + "testScope", "$blockIcon$exclusiveSplit_ff2c11d0fb4", "$inlineBlocks$exclusiveSplit_ff2c11d0fb4", "$blockOrderIcon$branch_f2c11d0fb42", diff --git a/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-fix-layout-group.test.ts.snap b/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-fix-layout-group.test.ts.snap index 0497bc0c..7e8fdc85 100644 --- a/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-fix-layout-group.test.ts.snap +++ b/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-fix-layout-group.test.ts.snap @@ -128,7 +128,7 @@ exports[`Variable Fix Layout Group > test sort 1`] = ` "node_1_private", "end_0", "end_0_private", - "globalScope", + "testScope", "$group_test$", ] `; diff --git a/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-fix-layout-no-config.test.ts.snap b/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-fix-layout-no-config.test.ts.snap index c2292be6..6482f5c0 100644 --- a/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-fix-layout-no-config.test.ts.snap +++ b/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-fix-layout-no-config.test.ts.snap @@ -713,7 +713,7 @@ exports[`Variable Fix Layout Without Config > test sort 1`] = ` "updateRecords_7ed2a172c32_private", "end", "end_private", - "globalScope", + "testScope", "$blockIcon$exclusiveSplit_ff2c11d0fb4", "$inlineBlocks$exclusiveSplit_ff2c11d0fb4", "$blockOrderIcon$branch_f2c11d0fb42", diff --git a/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-fix-layout.test.ts.snap b/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-fix-layout.test.ts.snap index 0fd048fb..49e821b2 100644 --- a/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-fix-layout.test.ts.snap +++ b/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-fix-layout.test.ts.snap @@ -831,7 +831,7 @@ exports[`Variable Fix Layout > test sort 1`] = ` "updateRecords_7ed2a172c32_private", "end", "end_private", - "globalScope", + "testScope", "$blockIcon$exclusiveSplit_ff2c11d0fb4", "$inlineBlocks$exclusiveSplit_ff2c11d0fb4", "$blockOrderIcon$branch_f2c11d0fb42", diff --git a/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-free-enable-global-scope.test.ts.snap b/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-free-enable-global-scope.test.ts.snap new file mode 100644 index 00000000..7702873d --- /dev/null +++ b/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-free-enable-global-scope.test.ts.snap @@ -0,0 +1,343 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Variable Free Layout Enable Global Scope > test get Covers 1`] = ` +Map { + "start_0" => [ + "base_1", + "base_2", + "end_0", + "loop_1", + "base_3", + "base_in_loop_1", + "base_in_loop_2", + "base_in_loop_3", + ], + "end_0" => [], + "base_1" => [ + "base_2", + "end_0", + "loop_1", + "base_3", + "base_in_loop_1", + "base_in_loop_2", + "base_in_loop_3", + ], + "base_2" => [ + "end_0", + ], + "loop_1" => [ + "base_3", + "end_0", + ], + "base_in_loop_1" => [ + "base_in_loop_3", + ], + "base_in_loop_2" => [ + "base_in_loop_3", + ], + "base_in_loop_3" => [], + "base_3" => [ + "end_0", + ], +} +`; + +exports[`Variable Free Layout Enable Global Scope > test get Covers After Init Private 1`] = ` +Map { + "start_0" => [ + "base_1", + "base_1_private", + "base_2", + "base_2_private", + "end_0", + "end_0_private", + "loop_1", + "loop_1_private", + "base_3", + "base_3_private", + "base_in_loop_1", + "base_in_loop_1_private", + "base_in_loop_2", + "base_in_loop_2_private", + "base_in_loop_3", + "base_in_loop_3_private", + ], + "end_0" => [], + "base_1" => [ + "base_2", + "base_2_private", + "end_0", + "end_0_private", + "loop_1", + "loop_1_private", + "base_3", + "base_3_private", + "base_in_loop_1", + "base_in_loop_1_private", + "base_in_loop_2", + "base_in_loop_2_private", + "base_in_loop_3", + "base_in_loop_3_private", + ], + "base_2" => [ + "end_0", + "end_0_private", + ], + "loop_1" => [ + "base_3", + "base_3_private", + "end_0", + "end_0_private", + ], + "base_in_loop_1" => [ + "base_in_loop_3", + "base_in_loop_3_private", + ], + "base_in_loop_2" => [ + "base_in_loop_3", + "base_in_loop_3_private", + ], + "base_in_loop_3" => [], + "base_3" => [ + "end_0", + "end_0_private", + ], +} +`; + +exports[`Variable Free Layout Enable Global Scope > test get Deps 1`] = ` +Map { + "start_0" => [ + "GlobalScope", + ], + "end_0" => [ + "GlobalScope", + "base_2", + "base_1", + "start_0", + "base_3", + "loop_1", + ], + "base_1" => [ + "GlobalScope", + "start_0", + ], + "base_2" => [ + "GlobalScope", + "base_1", + "start_0", + ], + "loop_1" => [ + "GlobalScope", + "base_1", + "start_0", + ], + "base_in_loop_1" => [ + "GlobalScope", + "base_1", + "start_0", + ], + "base_in_loop_2" => [ + "GlobalScope", + "base_1", + "start_0", + ], + "base_in_loop_3" => [ + "GlobalScope", + "base_in_loop_1", + "base_in_loop_2", + "base_1", + "start_0", + ], + "base_3" => [ + "GlobalScope", + "loop_1", + "base_1", + "start_0", + ], +} +`; + +exports[`Variable Free Layout Enable Global Scope > test get Deps After Init Private 1`] = ` +Map { + "start_0" => [ + "GlobalScope", + "start_0_private", + ], + "end_0" => [ + "GlobalScope", + "base_2", + "base_1", + "start_0", + "base_3", + "loop_1", + "end_0_private", + ], + "base_1" => [ + "GlobalScope", + "start_0", + "base_1_private", + ], + "base_2" => [ + "GlobalScope", + "base_1", + "start_0", + "base_2_private", + ], + "loop_1" => [ + "GlobalScope", + "base_1", + "start_0", + "loop_1_private", + ], + "base_in_loop_1" => [ + "GlobalScope", + "base_in_loop_1_private", + "base_1", + "start_0", + "loop_1_private", + ], + "base_in_loop_2" => [ + "GlobalScope", + "base_in_loop_2_private", + "base_1", + "start_0", + "loop_1_private", + ], + "base_in_loop_3" => [ + "GlobalScope", + "base_in_loop_1", + "base_in_loop_2", + "base_in_loop_3_private", + "base_1", + "start_0", + "loop_1_private", + ], + "base_3" => [ + "GlobalScope", + "loop_1", + "base_1", + "start_0", + "base_3_private", + ], +} +`; + +exports[`Variable Free Layout Enable Global Scope > test get private scope Covers 1`] = ` +Map { + "start_0_private" => [ + "start_0", + ], + "end_0_private" => [ + "end_0", + ], + "base_1_private" => [ + "base_1", + ], + "base_2_private" => [ + "base_2", + ], + "loop_1_private" => [ + "base_in_loop_1", + "base_in_loop_1_private", + "base_in_loop_2", + "base_in_loop_2_private", + "base_in_loop_3", + "base_in_loop_3_private", + "loop_1", + ], + "base_in_loop_1_private" => [ + "base_in_loop_1", + ], + "base_in_loop_2_private" => [ + "base_in_loop_2", + ], + "base_in_loop_3_private" => [ + "base_in_loop_3", + ], + "base_3_private" => [ + "base_3", + ], +} +`; + +exports[`Variable Free Layout Enable Global Scope > test get private scope Deps 1`] = ` +Map { + "start_0_private" => [ + "GlobalScope", + ], + "end_0_private" => [ + "GlobalScope", + "base_2", + "base_1", + "start_0", + "base_3", + "loop_1", + ], + "base_1_private" => [ + "GlobalScope", + "start_0", + ], + "base_2_private" => [ + "GlobalScope", + "base_1", + "start_0", + ], + "loop_1_private" => [ + "GlobalScope", + "base_1", + "start_0", + ], + "base_in_loop_1_private" => [ + "GlobalScope", + "base_1", + "start_0", + "loop_1_private", + ], + "base_in_loop_2_private" => [ + "GlobalScope", + "base_1", + "start_0", + "loop_1_private", + ], + "base_in_loop_3_private" => [ + "GlobalScope", + "base_in_loop_1", + "base_in_loop_2", + "base_1", + "start_0", + "loop_1_private", + ], + "base_3_private" => [ + "GlobalScope", + "loop_1", + "base_1", + "start_0", + ], +} +`; + +exports[`Variable Free Layout Enable Global Scope > test sort 1`] = ` +[ + Symbol(GlobalScope), + "testScope", + "start_0", + "end_0", + "base_1", + "base_2", + "loop_1", + "base_in_loop_1", + "base_in_loop_2", + "base_in_loop_3", + "base_3", + "start_0_private", + "end_0_private", + "base_1_private", + "base_2_private", + "loop_1_private", + "base_in_loop_1_private", + "base_in_loop_2_private", + "base_in_loop_3_private", + "base_3_private", +] +`; diff --git a/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-free-layout-transform-empty.test.ts.snap b/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-free-layout-transform-empty.test.ts.snap index 96efb2e7..591d1479 100644 --- a/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-free-layout-transform-empty.test.ts.snap +++ b/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-free-layout-transform-empty.test.ts.snap @@ -86,7 +86,7 @@ Map { exports[`Variable Free Layout > test sort 1`] = ` [ - "globalScope", + "testScope", "start_0", "end_0", "base_1", diff --git a/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-free-layout.test.ts.snap b/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-free-layout.test.ts.snap index a93c75f0..5b8a722c 100644 --- a/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-free-layout.test.ts.snap +++ b/packages/variable-engine/variable-layout/__tests__/__snapshots__/variable-free-layout.test.ts.snap @@ -290,7 +290,7 @@ Map { exports[`Variable Free Layout > test sort 1`] = ` [ - "globalScope", + "testScope", "start_0", "end_0", "base_1", diff --git a/packages/variable-engine/variable-layout/__tests__/variable-fix-enable-global-scope.test.ts b/packages/variable-engine/variable-layout/__tests__/variable-fix-enable-global-scope.test.ts new file mode 100644 index 00000000..5210e527 --- /dev/null +++ b/packages/variable-engine/variable-layout/__tests__/variable-fix-enable-global-scope.test.ts @@ -0,0 +1,6 @@ +import { runFixedLayoutTest } from '../__mocks__/run-fixed-layout-test'; +import { fixLayout1 } from '../__mocks__/fixed-layout-specs'; + +runFixedLayoutTest('Variable Fix Layout Enable Global Scope', fixLayout1, { + enableGlobalScope: true, +}); diff --git a/packages/variable-engine/variable-layout/__tests__/variable-free-enable-global-scope.test.ts b/packages/variable-engine/variable-layout/__tests__/variable-free-enable-global-scope.test.ts new file mode 100644 index 00000000..8c65973e --- /dev/null +++ b/packages/variable-engine/variable-layout/__tests__/variable-free-enable-global-scope.test.ts @@ -0,0 +1,6 @@ +import { runFreeLayoutTest } from '../__mocks__/run-free-layout-test'; +import { freeLayout1 } from '../__mocks__/free-layout-specs'; + +runFreeLayoutTest('Variable Free Layout Enable Global Scope', freeLayout1, { + enableGlobalScope: true, +}); diff --git a/packages/variable-engine/variable-layout/src/fixed-layout-scope-chain.ts b/packages/variable-engine/variable-layout/src/chains/fixed-layout-scope-chain.ts similarity index 93% rename from packages/variable-engine/variable-layout/src/fixed-layout-scope-chain.ts rename to packages/variable-engine/variable-layout/src/chains/fixed-layout-scope-chain.ts index c3b40abd..5e85a0f9 100644 --- a/packages/variable-engine/variable-layout/src/fixed-layout-scope-chain.ts +++ b/packages/variable-engine/variable-layout/src/chains/fixed-layout-scope-chain.ts @@ -3,9 +3,10 @@ import { Scope, ScopeChain } from '@flowgram.ai/variable-core'; import { FlowDocument, type FlowVirtualTree } from '@flowgram.ai/document'; import { FlowNodeEntity } from '@flowgram.ai/document'; -import { VariableLayoutConfig } from './variable-layout-config'; -import { FlowNodeScope, FlowNodeScopeTypeEnum, ScopeChainNode } from './types'; -import { FlowNodeVariableData } from './flow-node-variable-data'; +import { VariableLayoutConfig } from '../variable-layout-config'; +import { FlowNodeScope, FlowNodeScopeTypeEnum, ScopeChainNode } from '../types'; +import { GlobalScope } from '../scopes/global-scope'; +import { FlowNodeVariableData } from '../flow-node-variable-data'; /** * 基于 FlowVirtualTree 的 ScopeOrder 实现 @@ -114,6 +115,12 @@ export class FixedLayoutScopeChain extends ScopeChain { curr = undefined; } + // If scope is GlobalScope, add globalScope to deps + const globalScope = this.variableEngine.getScopeById(GlobalScope.ID); + if (globalScope) { + deps.unshift(globalScope); + } + return this.transformDeps(deps, { scope }); } @@ -123,6 +130,13 @@ export class FixedLayoutScopeChain extends ScopeChain { return this.transformCovers([], { scope }); } + // If scope is GlobalScope, return all scopes except GlobalScope + if (GlobalScope.is(scope)) { + return this.variableEngine + .getAllScopes({ sort: true }) + .filter((_scope) => !GlobalScope.is(_scope)); + } + const node = scope.meta.node; if (!node) { return this.transformCovers([], { scope }); diff --git a/packages/variable-engine/variable-layout/src/free-layout-scope-chain.ts b/packages/variable-engine/variable-layout/src/chains/free-layout-scope-chain.ts similarity index 84% rename from packages/variable-engine/variable-layout/src/free-layout-scope-chain.ts rename to packages/variable-engine/variable-layout/src/chains/free-layout-scope-chain.ts index 0dabe989..622c616d 100644 --- a/packages/variable-engine/variable-layout/src/free-layout-scope-chain.ts +++ b/packages/variable-engine/variable-layout/src/chains/free-layout-scope-chain.ts @@ -1,12 +1,13 @@ import { inject, optional, postConstruct } from 'inversify'; import { Scope, ScopeChain } from '@flowgram.ai/variable-core'; +import { WorkflowNodeLinesData, WorkflowNodeMeta } from '@flowgram.ai/free-layout-core'; import { FlowNodeEntity, FlowDocument, FlowVirtualTree } from '@flowgram.ai/document'; import { EntityManager } from '@flowgram.ai/core'; -import { WorkflowNodeLinesData, WorkflowNodeMeta } from '@flowgram.ai/free-layout-core'; -import { VariableLayoutConfig } from './variable-layout-config'; -import { FlowNodeScope, FlowNodeScopeTypeEnum } from './types'; -import { FlowNodeVariableData } from './flow-node-variable-data'; +import { VariableLayoutConfig } from '../variable-layout-config'; +import { FlowNodeScope, FlowNodeScopeTypeEnum } from '../types'; +import { GlobalScope } from '../scopes/global-scope'; +import { FlowNodeVariableData } from '../flow-node-variable-data'; /** * 自由布局作用域链实现 @@ -44,14 +45,14 @@ export class FreeLayoutScopeChain extends ScopeChain { // 获取同一层级所有输入节点 protected getAllInputLayerNodes(curr: FlowNodeEntity): FlowNodeEntity[] { return (curr.getData(WorkflowNodeLinesData)?.allInputNodes || []).filter( - _node => _node.parent === curr.parent, + (_node) => _node.parent === curr.parent ); } // 获取同一层级所有输出节点 protected getAllOutputLayerNodes(curr: FlowNodeEntity): FlowNodeEntity[] { return (curr.getData(WorkflowNodeLinesData)?.allOutputNodes || []).filter( - _node => _node.parent === curr.parent, + (_node) => _node.parent === curr.parent ); } @@ -61,7 +62,7 @@ export class FreeLayoutScopeChain extends ScopeChain { return this.transformDeps([], { scope }); } - const scopes: FlowNodeScope[] = []; + const deps: FlowNodeScope[] = []; // 1. 找到依赖的节点 let curr: FlowNodeEntity | undefined = node; @@ -70,24 +71,37 @@ export class FreeLayoutScopeChain extends ScopeChain { const allInputNodes: FlowNodeEntity[] = this.getAllInputLayerNodes(curr); // 2. 获取所有依赖节点的 public 作用域 - scopes.push( - ...allInputNodes.map(_node => _node.getData(FlowNodeVariableData).public).filter(Boolean), + deps.push( + ...allInputNodes.map((_node) => _node.getData(FlowNodeVariableData).public).filter(Boolean) ); // 父节点的 private 也可以访问 const currVarData: FlowNodeVariableData = curr.getData(FlowNodeVariableData); if (currVarData?.private && scope !== currVarData.private) { - scopes.push(currVarData.private); + deps.push(currVarData.private); } curr = this.getParent(curr); } - const uniqScopes = Array.from(new Set(scopes)); - return this.transformDeps(uniqScopes, { scope }); + // If scope is GlobalScope, add globalScope to deps + const globalScope = this.variableEngine.getScopeById(GlobalScope.ID); + if (globalScope) { + deps.unshift(globalScope); + } + + const uniqDeps = Array.from(new Set(deps)); + return this.transformDeps(uniqDeps, { scope }); } getCovers(scope: FlowNodeScope): FlowNodeScope[] { + // If scope is GlobalScope, return all scopes except GlobalScope + if (GlobalScope.is(scope)) { + return this.variableEngine + .getAllScopes({ sort: true }) + .filter((_scope) => !GlobalScope.is(_scope)); + } + const { node } = scope.meta || {}; if (!node) { return this.transformCovers([], { scope }); diff --git a/packages/variable-engine/variable-layout/src/index.ts b/packages/variable-engine/variable-layout/src/index.ts index f7320bb1..daa0aaa8 100644 --- a/packages/variable-engine/variable-layout/src/index.ts +++ b/packages/variable-engine/variable-layout/src/index.ts @@ -1,9 +1,10 @@ export { FlowNodeVariableData } from './flow-node-variable-data'; -export { FreeLayoutScopeChain } from './free-layout-scope-chain'; +export { FreeLayoutScopeChain } from './chains/free-layout-scope-chain'; export { VariableLayoutConfig } from './variable-layout-config'; -export { FixedLayoutScopeChain } from './fixed-layout-scope-chain'; +export { FixedLayoutScopeChain } from './chains/fixed-layout-scope-chain'; export { type FlowNodeScopeMeta, type FlowNodeScope, FlowNodeScopeTypeEnum as FlowNodeScopeType, } from './types'; +export { GlobalScope, bindGlobalScope } from './scopes/global-scope'; diff --git a/packages/variable-engine/variable-layout/src/scopes/global-scope.ts b/packages/variable-engine/variable-layout/src/scopes/global-scope.ts new file mode 100644 index 00000000..8c2dce74 --- /dev/null +++ b/packages/variable-engine/variable-layout/src/scopes/global-scope.ts @@ -0,0 +1,78 @@ +import { injectable, interfaces } from 'inversify'; +import { ASTNode, ASTNodeJSON, Scope, VariableEngine } from '@flowgram.ai/variable-core'; + +@injectable() +export class GlobalScope extends Scope { + static readonly ID = Symbol('GlobalScope'); + + static is(scope: Scope): scope is GlobalScope { + return scope.id === GlobalScope.ID; + } + + /** + * Sets a variable in the Global Scope with the given key and JSON value. + * + * @param key - The key under which the variable will be stored. + * @param json - The JSON value to store. + * @returns The updated AST node. + */ + public setVar(key: string, json: ASTNodeJSON): ASTNode; + + /** + * Sets a variable in the Global Scope with the default key 'outputs'. + * + * @param json - The JSON value to store. + * @returns The updated AST node. + */ + public setVar(json: ASTNodeJSON): ASTNode; + + public setVar(arg1: string | ASTNodeJSON, arg2?: ASTNodeJSON): ASTNode { + if (typeof arg1 === 'string' && arg2 !== undefined) { + return this.ast.set(arg1, arg2); + } + + if (typeof arg1 === 'object' && arg2 === undefined) { + return this.ast.set('outputs', arg1); + } + + throw new Error('Invalid arguments'); + } + + /** + * Retrieves a variable from the Global Scope by key. + * + * @param key - The key of the variable to retrieve. Defaults to 'outputs'. + * @returns The value of the variable, or undefined if not found. + */ + public getVar(key: string = 'outputs') { + return this.ast.get(key); + } + + /** + * Clears a variable from the Global Scope by key. + * + * @param key - The key of the variable to clear. Defaults to 'outputs'. + * @returns The updated AST node. + */ + public clearVar(key: string = 'outputs') { + return this.ast.remove(key); + } +} + +export const bindGlobalScope = (bind: interfaces.Bind) => { + bind(GlobalScope).toDynamicValue((ctx) => { + const variableEngine = ctx.container.get(VariableEngine); + let scope = variableEngine.getScopeById(GlobalScope.ID) as GlobalScope; + + if (!scope) { + scope = variableEngine.createScope( + GlobalScope.ID, + {}, + { ScopeConstructor: GlobalScope } + ) as GlobalScope; + variableEngine.chain.refreshAllChange(); + } + + return scope; + }); +};