Просмотр исходного кода

feat(editor): node.scope (#851)

* feat(editor): node.scope

* fix: variable engine
Yiwei Mao 3 месяцев назад
Родитель
Сommit
fcbf83eda4

+ 5 - 6
apps/docs/src/en/guide/advanced/variable/variable-output.mdx

@@ -12,7 +12,7 @@ We mainly divide variables into two categories:
 Outputting a node variable means that this variable is bound to the life cycle of the current node. When the node is created, the variable is born; when the node is deleted, the variable also disappears. We usually have two ways to output node variables:
 Outputting a node variable means that this variable is bound to the life cycle of the current node. When the node is created, the variable is born; when the node is deleted, the variable also disappears. We usually have two ways to output node variables:
 
 
 1.  **Through form configuration**: In the node's setting panel (Form), declare output variables through some preset configurations or custom logic. This method is very intuitive, what you see is what you get.
 1.  **Through form configuration**: In the node's setting panel (Form), declare output variables through some preset configurations or custom logic. This method is very intuitive, what you see is what you get.
-2.  **Through API calls**: In the plugin (Plugin), dynamically add, modify or delete variables for the node by calling the `getNodeScope` API. This method is more flexible and suitable for handling complex and dynamic business scenarios.
+2.  **Through API calls**: In the plugin (Plugin), dynamically add, modify or delete variables for the node by calling the `node.scope` API. This method is more flexible and suitable for handling complex and dynamic business scenarios.
 
 
 Next, we will explore the specific usage of these two methods in depth.
 Next, we will explore the specific usage of these two methods in depth.
 
 
@@ -117,13 +117,13 @@ export const nodeRegistries: FlowNodeRegistry[] = [
 
 
 ```
 ```
 
 
-### Method 2: Use the `getNodeScope` API
+### Method 2: Use the `node.scope` API
 
 
-In addition to static configuration in the form, we can also get the scope in the plugin (Plugin) through the `getNodeScope` API to dynamically operate the variables of the node.
+In addition to static configuration in the form, we can also get the scope in the plugin (Plugin) through the `node.scope` API to dynamically operate the variables of the node.
 
 
 This method gives you a high degree of freedom. You can add, delete, modify, and query the variables of the node at any time and any place.
 This method gives you a high degree of freedom. You can add, delete, modify, and query the variables of the node at any time and any place.
 
 
-`getNodeScope` will return a node's variable scope (Scope) object, which has several core methods:
+`node.scope` will return a node's variable scope (Scope) object, which has several core methods:
 
 
 - `setVar(variable)`: Set a variable.
 - `setVar(variable)`: Set a variable.
 - `setVar(namespace, variable)`: Set a variable under the specified namespace.
 - `setVar(namespace, variable)`: Set a variable under the specified namespace.
@@ -139,7 +139,6 @@ import {
   FlowDocument,
   FlowDocument,
   definePluginCreator,
   definePluginCreator,
   PluginCreator,
   PluginCreator,
-  getNodeScope,
 } from '@flowgram.ai/fixed-layout-editor';
 } from '@flowgram.ai/fixed-layout-editor';
 
 
 
 
@@ -147,7 +146,7 @@ export const createSyncVariablePlugin: PluginCreator<SyncVariablePluginOptions>
   definePluginCreator<SyncVariablePluginOptions, FixedLayoutPluginContext>({
   definePluginCreator<SyncVariablePluginOptions, FixedLayoutPluginContext>({
     onInit(ctx, options) {
     onInit(ctx, options) {
       const startNode = ctx.get(FlowDocument).getNode('start_0');
       const startNode = ctx.get(FlowDocument).getNode('start_0');
-      const startScope =  getNodeScope(startNode)
+      const startScope =  startNode.scope!
 
 
       // 1. Set Variable For Start Scope
       // 1. Set Variable For Start Scope
       startScope.setVar(
       startScope.setVar(

+ 5 - 6
apps/docs/src/zh/guide/advanced/variable/variable-output.mdx

@@ -12,7 +12,7 @@
 输出节点变量,意味着这个变量和当前节点的生命周期是绑定的。当节点被创建时,变量就诞生了;当节点被删除时,变量也随之消逝。我们通常有两种方式来输出节点变量:
 输出节点变量,意味着这个变量和当前节点的生命周期是绑定的。当节点被创建时,变量就诞生了;当节点被删除时,变量也随之消逝。我们通常有两种方式来输出节点变量:
 
 
 1.  **通过表单配置**:在节点的设置面板(Form)中,通过一些预设的配置或自定义的逻辑来声明输出变量。这种方式非常直观,所见即所得。
 1.  **通过表单配置**:在节点的设置面板(Form)中,通过一些预设的配置或自定义的逻辑来声明输出变量。这种方式非常直观,所见即所得。
-2.  **通过 API 调用**:在插件(Plugin)中,通过调用 `getNodeScope` API 来动态地为节点添加、修改或删除变量。这种方式更加灵活,适合处理复杂的、动态的业务场景。
+2.  **通过 API 调用**:在插件(Plugin)中,通过调用 `node.scope` API 来动态地为节点添加、修改或删除变量。这种方式更加灵活,适合处理复杂的、动态的业务场景。
 
 
 接下来,我们将深入探讨这两种方式的具体用法。
 接下来,我们将深入探讨这两种方式的具体用法。
 
 
@@ -117,13 +117,13 @@ export const nodeRegistries: FlowNodeRegistry[] = [
 
 
 ```
 ```
 
 
-### 方式二:使用 `getNodeScope` API
+### 方式二:使用 `node.scope` API
 
 
-除了在表单中静态配置,我们还可以在插件(Plugin)中,通过 `getNodeScope` API 来获取作用域,从而动态地操作节点的变量。
+除了在表单中静态配置,我们还可以在插件(Plugin)中,通过 `node.scope` API 来获取作用域,从而动态地操作节点的变量。
 
 
 这种方式赋予了你极高的自由度,你可以在任何时机、任何地点,对节点的变量进行增、删、改、查。
 这种方式赋予了你极高的自由度,你可以在任何时机、任何地点,对节点的变量进行增、删、改、查。
 
 
-`getNodeScope` 会返回一个节点的变量作用域(Scope)对象,这个对象上挂载了几个核心方法:
+`node.scope` 会返回一个节点的变量作用域(Scope)对象,这个对象上挂载了几个核心方法:
 
 
 - `setVar(variable)`: 设置一个变量。
 - `setVar(variable)`: 设置一个变量。
 - `setVar(namespace, variable)`: 在指定的命名空间下设置一个变量。
 - `setVar(namespace, variable)`: 在指定的命名空间下设置一个变量。
@@ -139,7 +139,6 @@ import {
   FlowDocument,
   FlowDocument,
   definePluginCreator,
   definePluginCreator,
   PluginCreator,
   PluginCreator,
-  getNodeScope,
 } from '@flowgram.ai/fixed-layout-editor';
 } from '@flowgram.ai/fixed-layout-editor';
 
 
 
 
@@ -147,7 +146,7 @@ export const createSyncVariablePlugin: PluginCreator<SyncVariablePluginOptions>
   definePluginCreator<SyncVariablePluginOptions, FixedLayoutPluginContext>({
   definePluginCreator<SyncVariablePluginOptions, FixedLayoutPluginContext>({
     onInit(ctx, options) {
     onInit(ctx, options) {
       const startNode = ctx.get(FlowDocument).getNode('start_0');
       const startNode = ctx.get(FlowDocument).getNode('start_0');
-      const startScope =  getNodeScope(startNode)
+      const startScope =  startNode.scope!
 
 
       // 1. Set Variable For Start Scope
       // 1. Set Variable For Start Scope
       startScope.setVar(
       startScope.setVar(

+ 28 - 3
packages/client/editor/src/preset/editor-default-preset.ts

@@ -4,6 +4,7 @@
  */
  */
 
 
 import { interfaces } from 'inversify';
 import { interfaces } from 'inversify';
+import { FlowNodeScope, getNodePrivateScope, getNodeScope } from '@flowgram.ai/variable-plugin';
 import { FlowRendererContainerModule, FlowRendererRegistry } from '@flowgram.ai/renderer';
 import { FlowRendererContainerModule, FlowRendererRegistry } from '@flowgram.ai/renderer';
 import { createReduxDevToolPlugin } from '@flowgram.ai/redux-devtool-plugin';
 import { createReduxDevToolPlugin } from '@flowgram.ai/redux-devtool-plugin';
 import { createNodeVariablePlugin } from '@flowgram.ai/node-variable-plugin';
 import { createNodeVariablePlugin } from '@flowgram.ai/node-variable-plugin';
@@ -90,10 +91,11 @@ export function createDefaultPreset<CTX extends EditorPluginContext = EditorPlug
           // }
           // }
           // TODO 这个会触发组件注册,后续要废弃这个,通过 materials 插件来做
           // TODO 这个会触发组件注册,后续要废弃这个,通过 materials 插件来做
           ctx.get<FlowRendererRegistry>(FlowRendererRegistry).init();
           ctx.get<FlowRendererRegistry>(FlowRendererRegistry).init();
-          /**
-           * Define node.form
-           */
+
           ctx.document.onNodeCreate(({ node }) => {
           ctx.document.onNodeCreate(({ node }) => {
+            /**
+             * Define node.form
+             */
             if (opts.nodeEngine && opts.nodeEngine.enable !== false) {
             if (opts.nodeEngine && opts.nodeEngine.enable !== false) {
               let cache: NodeFormProps<any> | undefined;
               let cache: NodeFormProps<any> | undefined;
               Object.defineProperty(node, 'form', {
               Object.defineProperty(node, 'form', {
@@ -104,6 +106,29 @@ export function createDefaultPreset<CTX extends EditorPluginContext = EditorPlug
                 },
                 },
               });
               });
             }
             }
+
+            /**
+             * Define node.scope & node.privateScope
+             */
+            if (opts.variableEngine && opts.variableEngine.enable !== false) {
+              let cache: FlowNodeScope | undefined;
+              let privateCache: FlowNodeScope | undefined;
+
+              Object.defineProperty(node, 'scope', {
+                get: () => {
+                  if (cache) return cache;
+                  cache = getNodeScope(node);
+                  return cache;
+                },
+              });
+              Object.defineProperty(node, 'privateScope', {
+                get: () => {
+                  if (privateCache) return privateCache;
+                  privateCache = getNodePrivateScope(node);
+                  return privateCache;
+                },
+              });
+            }
           });
           });
         },
         },
         onReady(ctx) {
         onReady(ctx) {

+ 3 - 1
packages/client/editor/src/preset/editor-props.ts

@@ -3,7 +3,7 @@
  * SPDX-License-Identifier: MIT
  * SPDX-License-Identifier: MIT
  */
  */
 
 
-import { VariablePluginOptions } from '@flowgram.ai/variable-plugin';
+import { FlowNodeScope, VariablePluginOptions } from '@flowgram.ai/variable-plugin';
 import { ReduxDevToolPluginOptions } from '@flowgram.ai/redux-devtool-plugin';
 import { ReduxDevToolPluginOptions } from '@flowgram.ai/redux-devtool-plugin';
 import { PlaygroundReactProps, SelectionService } from '@flowgram.ai/playground-react';
 import { PlaygroundReactProps, SelectionService } from '@flowgram.ai/playground-react';
 import { NodeCorePluginOptions } from '@flowgram.ai/node-core-plugin';
 import { NodeCorePluginOptions } from '@flowgram.ai/node-core-plugin';
@@ -25,6 +25,8 @@ import { PluginContext } from '@flowgram.ai/core';
 declare module '@flowgram.ai/document' {
 declare module '@flowgram.ai/document' {
   interface FlowNodeEntity {
   interface FlowNodeEntity {
     form: NodeFormProps<any> | undefined;
     form: NodeFormProps<any> | undefined;
+    scope: FlowNodeScope | undefined;
+    privateScope: FlowNodeScope | undefined;
   }
   }
 }
 }
 
 

+ 10 - 0
packages/variable-engine/variable-layout/src/utils.ts

@@ -7,10 +7,20 @@ import { FlowNodeEntity } from '@flowgram.ai/document';
 
 
 import { FlowNodeVariableData } from './flow-node-variable-data';
 import { FlowNodeVariableData } from './flow-node-variable-data';
 
 
+/**
+ * Use `node.scope` instead
+ * @deprecated
+ * @param node
+ */
 export function getNodeScope(node: FlowNodeEntity) {
 export function getNodeScope(node: FlowNodeEntity) {
   return node.getData(FlowNodeVariableData).public;
   return node.getData(FlowNodeVariableData).public;
 }
 }
 
 
+/**
+ * Use `node.privateScope` instead
+ * @deprecated
+ * @param node
+ */
 export function getNodePrivateScope(node: FlowNodeEntity) {
 export function getNodePrivateScope(node: FlowNodeEntity) {
   return node.getData(FlowNodeVariableData).initPrivate();
   return node.getData(FlowNodeVariableData).initPrivate();
 }
 }