@flowgram.ai/variable-layout 0.2.16 → 0.2.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,8 +1,13 @@
1
- import { Scope, VariableEngine, ASTNodeJSON, ASTNode, ScopeChain } from '@flowgram.ai/variable-core';
1
+ import { Scope, VariableEngine, ASTNodeJSON, ASTNode, BaseVariableField, ScopeChain } from '@flowgram.ai/variable-core';
2
2
  import { FlowNodeEntity, FlowDocument, FlowVirtualTree } from '@flowgram.ai/document';
3
3
  import { EntityData, EntityManager } from '@flowgram.ai/core';
4
4
  import { interfaces } from 'inversify';
5
5
 
6
+ /**
7
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
8
+ * SPDX-License-Identifier: MIT
9
+ */
10
+
6
11
  declare enum FlowNodeScopeTypeEnum {
7
12
  public = "public",
8
13
  private = "private"
@@ -16,7 +21,13 @@ interface ScopeVirtualNode {
16
21
  flowNodeType: 'virtualNode';
17
22
  }
18
23
  type ScopeChainNode = FlowNodeEntity | ScopeVirtualNode;
19
- type FlowNodeScope = Scope<FlowNodeScopeMeta>;
24
+ interface FlowNodeScope extends Scope<FlowNodeScopeMeta> {
25
+ }
26
+
27
+ /**
28
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
29
+ * SPDX-License-Identifier: MIT
30
+ */
20
31
 
21
32
  interface Options {
22
33
  variableEngine: VariableEngine;
@@ -95,8 +106,25 @@ declare class FlowNodeVariableData extends EntityData {
95
106
  getDefaultData(): {};
96
107
  constructor(entity: FlowNodeEntity, opts: Options);
97
108
  initPrivate(): FlowNodeScope;
109
+ /**
110
+ * Find a variable field by key path in the public scope by scope chain.
111
+ * @param keyPath - The key path of the variable field.
112
+ * @returns The variable field, or undefined if not found.
113
+ */
114
+ getByKeyPath(keyPath: string[]): BaseVariableField | undefined;
115
+ /**
116
+ * Find a variable field by key path in the private scope by scope chain.
117
+ * @param keyPath - The key path of the variable field.
118
+ * @returns The variable field, or undefined if not found.
119
+ */
120
+ getByKeyPathInPrivate(keyPath: string[]): BaseVariableField | undefined;
98
121
  }
99
122
 
123
+ /**
124
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
125
+ * SPDX-License-Identifier: MIT
126
+ */
127
+
100
128
  interface TransformerContext {
101
129
  scope: FlowNodeScope;
102
130
  document: FlowDocument;
@@ -105,13 +133,28 @@ interface TransformerContext {
105
133
  type IScopeTransformer = (scopes: Scope[], ctx: TransformerContext) => Scope[];
106
134
  declare class ScopeChainTransformService {
107
135
  protected configs?: VariableLayoutConfig | undefined;
108
- protected transformDepsFns: IScopeTransformer[];
109
- protected transformCoversFns: IScopeTransformer[];
136
+ protected transformerMap: Map<string, {
137
+ transformDeps: IScopeTransformer;
138
+ transformCovers: IScopeTransformer;
139
+ }>;
110
140
  document: FlowDocument;
111
141
  variableEngine: VariableEngine;
112
142
  constructor(configs?: VariableLayoutConfig | undefined);
113
- registerTransformDeps(transformer: IScopeTransformer): void;
114
- registerTransformCovers(transformer: IScopeTransformer): void;
143
+ /**
144
+ * check if transformer registered
145
+ * @param transformerId used to identify transformer, prevent duplicated
146
+ * @returns
147
+ */
148
+ hasTransformer(transformerId: string): boolean;
149
+ /**
150
+ * register new transform function
151
+ * @param transformerId used to identify transformer, prevent duplicated transformer
152
+ * @param transformer
153
+ */
154
+ registerTransformer(transformerId: string, transformer: {
155
+ transformDeps: IScopeTransformer;
156
+ transformCovers: IScopeTransformer;
157
+ }): void;
115
158
  transformDeps(scopes: Scope[], { scope }: {
116
159
  scope: Scope;
117
160
  }): Scope[];
@@ -120,6 +163,11 @@ declare class ScopeChainTransformService {
120
163
  }): Scope[];
121
164
  }
122
165
 
166
+ /**
167
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
168
+ * SPDX-License-Identifier: MIT
169
+ */
170
+
123
171
  interface VariableLayoutConfig {
124
172
  /**
125
173
  * 节点的子节点输出变量,不能被后续节点所访问,用于固定布局场景
@@ -128,23 +176,27 @@ interface VariableLayoutConfig {
128
176
  */
129
177
  isNodeChildrenPrivate?: (node: ScopeChainNode) => boolean;
130
178
  /**
131
- * 用于自由画布场景,部分场景通过连线或者其他交互形式来表达节点之间的父子关系,需要可配置化
179
+ * 用于固定布局场景时:父子中间存在大量无用节点(如 inlineBlocks 等,需要配置化略过)
180
+ * 用于自由画布场景时:部分场景通过连线或者其他交互形式来表达节点之间的父子关系,需可配置化
132
181
  */
133
- getFreeChildren?: (node: FlowNodeEntity) => FlowNodeEntity[];
134
- getFreeParent?: (node: FlowNodeEntity) => FlowNodeEntity | undefined;
182
+ getNodeChildren?: (node: FlowNodeEntity) => FlowNodeEntity[];
183
+ getNodeParent?: (node: FlowNodeEntity) => FlowNodeEntity | undefined;
135
184
  /**
136
- * @deprecated
137
185
  * 对依赖作用域进行微调
138
186
  */
139
187
  transformDeps?: IScopeTransformer;
140
188
  /**
141
- * @deprecated
142
189
  * 对依赖作用域进行微调
143
190
  */
144
191
  transformCovers?: IScopeTransformer;
145
192
  }
146
193
  declare const VariableLayoutConfig: unique symbol;
147
194
 
195
+ /**
196
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
197
+ * SPDX-License-Identifier: MIT
198
+ */
199
+
148
200
  /**
149
201
  * 自由布局作用域链实现
150
202
  */
@@ -159,11 +211,16 @@ declare class FreeLayoutScopeChain extends ScopeChain {
159
211
  protected getAllOutputLayerNodes(curr: FlowNodeEntity): FlowNodeEntity[];
160
212
  getDeps(scope: FlowNodeScope): FlowNodeScope[];
161
213
  getCovers(scope: FlowNodeScope): FlowNodeScope[];
162
- getChildren(node: FlowNodeEntity): FlowNodeEntity[];
163
- getParent(node: FlowNodeEntity): FlowNodeEntity | undefined;
214
+ getNodeChildren(node: FlowNodeEntity): FlowNodeEntity[];
215
+ getNodeParent(node: FlowNodeEntity): FlowNodeEntity | undefined;
164
216
  sortAll(): Scope[];
165
217
  }
166
218
 
219
+ /**
220
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
221
+ * SPDX-License-Identifier: MIT
222
+ */
223
+
167
224
  /**
168
225
  * 基于 FlowVirtualTree 的 ScopeOrder 实现
169
226
  */
@@ -183,39 +240,18 @@ declare class FixedLayoutScopeChain extends ScopeChain {
183
240
  private getAllSortedChildScope;
184
241
  }
185
242
 
243
+ /**
244
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
245
+ * SPDX-License-Identifier: MIT
246
+ */
247
+
186
248
  declare class GlobalScope extends Scope {
187
249
  static readonly ID: unique symbol;
188
- static is(scope: Scope): scope is GlobalScope;
189
- /**
190
- * Sets a variable in the Global Scope with the given key and JSON value.
191
- *
192
- * @param key - The key under which the variable will be stored.
193
- * @param json - The JSON value to store.
194
- * @returns The updated AST node.
195
- */
196
- setVar(key: string, json: ASTNodeJSON): ASTNode;
197
- /**
198
- * Sets a variable in the Global Scope with the default key 'outputs'.
199
- *
200
- * @param json - The JSON value to store.
201
- * @returns The updated AST node.
202
- */
203
- setVar(json: ASTNodeJSON): ASTNode;
204
- /**
205
- * Retrieves a variable from the Global Scope by key.
206
- *
207
- * @param key - The key of the variable to retrieve. Defaults to 'outputs'.
208
- * @returns The value of the variable, or undefined if not found.
209
- */
210
- getVar(key?: string): ASTNode<any, any> | undefined;
211
- /**
212
- * Clears a variable from the Global Scope by key.
213
- *
214
- * @param key - The key of the variable to clear. Defaults to 'outputs'.
215
- * @returns The updated AST node.
216
- */
217
- clearVar(key?: string): void;
250
+ static is(scope: Scope): boolean;
218
251
  }
219
252
  declare const bindGlobalScope: (bind: interfaces.Bind) => void;
220
253
 
221
- export { FixedLayoutScopeChain, type FlowNodeScope, type FlowNodeScopeMeta, FlowNodeScopeTypeEnum as FlowNodeScopeType, FlowNodeVariableData, FreeLayoutScopeChain, GlobalScope, ScopeChainTransformService, VariableLayoutConfig, bindGlobalScope };
254
+ declare function getNodeScope(node: FlowNodeEntity): FlowNodeScope;
255
+ declare function getNodePrivateScope(node: FlowNodeEntity): FlowNodeScope;
256
+
257
+ export { FixedLayoutScopeChain, type FlowNodeScope, type FlowNodeScopeMeta, FlowNodeScopeTypeEnum as FlowNodeScopeType, FlowNodeVariableData, FreeLayoutScopeChain, GlobalScope, ScopeChainTransformService, VariableLayoutConfig, bindGlobalScope, getNodePrivateScope, getNodeScope };
package/dist/index.js CHANGED
@@ -36,7 +36,9 @@ __export(src_exports, {
36
36
  GlobalScope: () => GlobalScope,
37
37
  ScopeChainTransformService: () => ScopeChainTransformService,
38
38
  VariableLayoutConfig: () => VariableLayoutConfig,
39
- bindGlobalScope: () => bindGlobalScope
39
+ bindGlobalScope: () => bindGlobalScope,
40
+ getNodePrivateScope: () => getNodePrivateScope,
41
+ getNodeScope: () => getNodeScope
40
42
  });
41
43
  module.exports = __toCommonJS(src_exports);
42
44
 
@@ -153,6 +155,22 @@ var FlowNodeVariableData = class extends import_core.EntityData {
153
155
  }
154
156
  return this._private;
155
157
  }
158
+ /**
159
+ * Find a variable field by key path in the public scope by scope chain.
160
+ * @param keyPath - The key path of the variable field.
161
+ * @returns The variable field, or undefined if not found.
162
+ */
163
+ getByKeyPath(keyPath) {
164
+ return this.public.available.getByKeyPath(keyPath);
165
+ }
166
+ /**
167
+ * Find a variable field by key path in the private scope by scope chain.
168
+ * @param keyPath - The key path of the variable field.
169
+ * @returns The variable field, or undefined if not found.
170
+ */
171
+ getByKeyPathInPrivate(keyPath) {
172
+ return this.private?.available.getByKeyPath(keyPath);
173
+ }
156
174
  };
157
175
  FlowNodeVariableData.type = "FlowNodeVariableData";
158
176
 
@@ -171,43 +189,59 @@ var import_inversify = require("inversify");
171
189
  var import_variable_core = require("@flowgram.ai/variable-core");
172
190
  var import_document = require("@flowgram.ai/document");
173
191
  var import_core2 = require("@flowgram.ai/core");
192
+ var passthrough = (scopes, ctx) => scopes;
174
193
  var ScopeChainTransformService = class {
175
194
  constructor(configs) {
176
195
  this.configs = configs;
177
- this.transformDepsFns = [];
178
- this.transformCoversFns = [];
179
- if (this.configs?.transformDeps) {
180
- this.transformDepsFns.push(this.configs.transformDeps);
181
- }
182
- if (this.configs?.transformCovers) {
183
- this.transformCoversFns.push(this.configs.transformCovers);
196
+ this.transformerMap = /* @__PURE__ */ new Map();
197
+ if (this.configs?.transformDeps || this.configs?.transformCovers) {
198
+ this.transformerMap.set("VARIABLE_LAYOUT_CONFIG", {
199
+ transformDeps: this.configs.transformDeps || passthrough,
200
+ transformCovers: this.configs.transformCovers || passthrough
201
+ });
184
202
  }
185
203
  }
186
- registerTransformDeps(transformer) {
187
- this.transformDepsFns.push(transformer);
204
+ /**
205
+ * check if transformer registered
206
+ * @param transformerId used to identify transformer, prevent duplicated
207
+ * @returns
208
+ */
209
+ hasTransformer(transformerId) {
210
+ return this.transformerMap.has(transformerId);
188
211
  }
189
- registerTransformCovers(transformer) {
190
- this.transformCoversFns.push(transformer);
212
+ /**
213
+ * register new transform function
214
+ * @param transformerId used to identify transformer, prevent duplicated transformer
215
+ * @param transformer
216
+ */
217
+ registerTransformer(transformerId, transformer) {
218
+ this.transformerMap.set(transformerId, transformer);
191
219
  }
192
220
  transformDeps(scopes, { scope }) {
193
- return this.transformDepsFns.reduce(
194
- (scopes2, transformer) => transformer(scopes2, {
221
+ return Array.from(this.transformerMap.values()).reduce((scopes2, transformer) => {
222
+ if (!transformer.transformDeps) {
223
+ return scopes2;
224
+ }
225
+ scopes2 = transformer.transformDeps(scopes2, {
195
226
  scope,
196
227
  document: this.document,
197
228
  variableEngine: this.variableEngine
198
- }),
199
- scopes
200
- );
229
+ });
230
+ return scopes2;
231
+ }, scopes);
201
232
  }
202
233
  transformCovers(scopes, { scope }) {
203
- return this.transformCoversFns.reduce(
204
- (scopes2, transformer) => transformer(scopes2, {
234
+ return Array.from(this.transformerMap.values()).reduce((scopes2, transformer) => {
235
+ if (!transformer.transformCovers) {
236
+ return scopes2;
237
+ }
238
+ scopes2 = transformer.transformCovers(scopes2, {
205
239
  scope,
206
240
  document: this.document,
207
241
  variableEngine: this.variableEngine
208
- }),
209
- scopes
210
- );
242
+ });
243
+ return scopes2;
244
+ }, scopes);
211
245
  }
212
246
  };
213
247
  __decorateClass([
@@ -229,33 +263,6 @@ var GlobalScope = class extends import_variable_core2.Scope {
229
263
  static is(scope) {
230
264
  return scope.id === GlobalScope.ID;
231
265
  }
232
- setVar(arg1, arg2) {
233
- if (typeof arg1 === "string" && arg2 !== void 0) {
234
- return this.ast.set(arg1, arg2);
235
- }
236
- if (typeof arg1 === "object" && arg2 === void 0) {
237
- return this.ast.set("outputs", arg1);
238
- }
239
- throw new Error("Invalid arguments");
240
- }
241
- /**
242
- * Retrieves a variable from the Global Scope by key.
243
- *
244
- * @param key - The key of the variable to retrieve. Defaults to 'outputs'.
245
- * @returns The value of the variable, or undefined if not found.
246
- */
247
- getVar(key = "outputs") {
248
- return this.ast.get(key);
249
- }
250
- /**
251
- * Clears a variable from the Global Scope by key.
252
- *
253
- * @param key - The key of the variable to clear. Defaults to 'outputs'.
254
- * @returns The updated AST node.
255
- */
256
- clearVar(key = "outputs") {
257
- return this.ast.remove(key);
258
- }
259
266
  };
260
267
  GlobalScope.ID = Symbol("GlobalScope");
261
268
  GlobalScope = __decorateClass([
@@ -298,16 +305,16 @@ var FreeLayoutScopeChain = class extends import_variable_core3.ScopeChain {
298
305
  }
299
306
  // 获取同一层级所有输入节点
300
307
  getAllInputLayerNodes(curr) {
301
- const currParent = this.getParent(curr);
308
+ const currParent = this.getNodeParent(curr);
302
309
  return (curr.getData(import_free_layout_core.WorkflowNodeLinesData)?.allInputNodes || []).filter(
303
- (_node) => this.getParent(_node) === currParent
310
+ (_node) => this.getNodeParent(_node) === currParent
304
311
  );
305
312
  }
306
313
  // 获取同一层级所有输出节点
307
314
  getAllOutputLayerNodes(curr) {
308
- const currParent = this.getParent(curr);
315
+ const currParent = this.getNodeParent(curr);
309
316
  return (curr.getData(import_free_layout_core.WorkflowNodeLinesData)?.allOutputNodes || []).filter(
310
- (_node) => this.getParent(_node) === currParent
317
+ (_node) => this.getNodeParent(_node) === currParent
311
318
  );
312
319
  }
313
320
  getDeps(scope) {
@@ -326,7 +333,7 @@ var FreeLayoutScopeChain = class extends import_variable_core3.ScopeChain {
326
333
  if (currVarData?.private && scope !== currVarData.private) {
327
334
  deps.push(currVarData.private);
328
335
  }
329
- curr = this.getParent(curr);
336
+ curr = this.getNodeParent(curr);
330
337
  }
331
338
  const globalScope = this.variableEngine.getScopeById(GlobalScope.ID);
332
339
  if (globalScope) {
@@ -337,7 +344,8 @@ var FreeLayoutScopeChain = class extends import_variable_core3.ScopeChain {
337
344
  }
338
345
  getCovers(scope) {
339
346
  if (GlobalScope.is(scope)) {
340
- return this.variableEngine.getAllScopes({ sort: true }).filter((_scope) => !GlobalScope.is(_scope));
347
+ const scopes2 = this.variableEngine.getAllScopes({ sort: true }).filter((_scope) => !GlobalScope.is(_scope));
348
+ return this.transformService.transformCovers(scopes2, { scope });
341
349
  }
342
350
  const { node } = scope.meta || {};
343
351
  if (!node) {
@@ -346,7 +354,7 @@ var FreeLayoutScopeChain = class extends import_variable_core3.ScopeChain {
346
354
  const isPrivate = scope.meta.type === "private" /* private */;
347
355
  const queue = [];
348
356
  if (isPrivate) {
349
- queue.push(...this.getChildren(node));
357
+ queue.push(...this.getNodeChildren(node));
350
358
  } else {
351
359
  queue.push(...this.getAllOutputLayerNodes(node) || []);
352
360
  }
@@ -355,7 +363,7 @@ var FreeLayoutScopeChain = class extends import_variable_core3.ScopeChain {
355
363
  const _node = queue.shift();
356
364
  const variableData = _node.getData(FlowNodeVariableData);
357
365
  scopes.push(...variableData.allScopes);
358
- const children = _node && this.getChildren(_node);
366
+ const children = _node && this.getNodeChildren(_node);
359
367
  if (children?.length) {
360
368
  queue.push(...children);
361
369
  }
@@ -367,9 +375,9 @@ var FreeLayoutScopeChain = class extends import_variable_core3.ScopeChain {
367
375
  const uniqScopes = Array.from(new Set(scopes));
368
376
  return this.transformService.transformCovers(uniqScopes, { scope });
369
377
  }
370
- getChildren(node) {
371
- if (this.configs?.getFreeChildren) {
372
- return this.configs.getFreeChildren?.(node);
378
+ getNodeChildren(node) {
379
+ if (this.configs?.getNodeChildren) {
380
+ return this.configs.getNodeChildren?.(node);
373
381
  }
374
382
  const nodeMeta = node.getNodeMeta();
375
383
  const subCanvas = nodeMeta.subCanvas?.(node);
@@ -382,9 +390,9 @@ var FreeLayoutScopeChain = class extends import_variable_core3.ScopeChain {
382
390
  }
383
391
  return this.tree.getChildren(node);
384
392
  }
385
- getParent(node) {
386
- if (this.configs?.getFreeParent) {
387
- return this.configs.getFreeParent(node);
393
+ getNodeParent(node) {
394
+ if (this.configs?.getNodeParent) {
395
+ return this.configs.getNodeParent(node);
388
396
  }
389
397
  let parent = node.document.originTree.getParent(node);
390
398
  while (parent?.flowNodeType === import_document2.FlowNodeBaseType.GROUP) {
@@ -506,7 +514,8 @@ var FixedLayoutScopeChain = class extends import_variable_core4.ScopeChain {
506
514
  return this.transformService.transformCovers([], { scope });
507
515
  }
508
516
  if (GlobalScope.is(scope)) {
509
- return this.variableEngine.getAllScopes({ sort: true }).filter((_scope) => !GlobalScope.is(_scope));
517
+ const scopes = this.variableEngine.getAllScopes({ sort: true }).filter((_scope) => !GlobalScope.is(_scope));
518
+ return this.transformService.transformCovers(scopes, { scope });
510
519
  }
511
520
  const node = scope.meta.node;
512
521
  if (!node) {
@@ -631,6 +640,14 @@ FixedLayoutScopeChain = __decorateClass([
631
640
  __decorateParam(1, (0, import_inversify4.optional)()),
632
641
  __decorateParam(1, (0, import_inversify4.inject)(VariableLayoutConfig))
633
642
  ], FixedLayoutScopeChain);
643
+
644
+ // src/utils.ts
645
+ function getNodeScope(node) {
646
+ return node.getData(FlowNodeVariableData).public;
647
+ }
648
+ function getNodePrivateScope(node) {
649
+ return node.getData(FlowNodeVariableData).initPrivate();
650
+ }
634
651
  // Annotate the CommonJS export names for ESM import in node:
635
652
  0 && (module.exports = {
636
653
  FixedLayoutScopeChain,
@@ -640,6 +657,8 @@ FixedLayoutScopeChain = __decorateClass([
640
657
  GlobalScope,
641
658
  ScopeChainTransformService,
642
659
  VariableLayoutConfig,
643
- bindGlobalScope
660
+ bindGlobalScope,
661
+ getNodePrivateScope,
662
+ getNodeScope
644
663
  });
645
664
  //# sourceMappingURL=index.js.map