@flowgram.ai/variable-core 0.1.0-alpha.2 → 0.1.0-alpha.21

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.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
  var __decorateClass = (decorators, target, key, kind) => {
20
30
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
@@ -27,10 +37,11 @@ var __decorateClass = (decorators, target, key, kind) => {
27
37
  var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
28
38
 
29
39
  // src/index.ts
30
- var src_exports = {};
31
- __export(src_exports, {
40
+ var index_exports = {};
41
+ __export(index_exports, {
32
42
  ASTFactory: () => ASTFactory,
33
43
  ASTKind: () => ASTKind,
44
+ ASTMatch: () => ASTMatch,
34
45
  ASTNode: () => ASTNode,
35
46
  ASTNodeFlags: () => ASTNodeFlags,
36
47
  ASTRegisters: () => ASTRegisters,
@@ -39,12 +50,12 @@ __export(src_exports, {
39
50
  BaseType: () => BaseType,
40
51
  BaseVariableField: () => BaseVariableField,
41
52
  BooleanType: () => BooleanType,
53
+ CustomType: () => CustomType,
42
54
  DataNode: () => DataNode,
43
55
  EnumerateExpression: () => EnumerateExpression,
44
- ExpressionList: () => ExpressionList,
45
56
  IntegerType: () => IntegerType,
46
57
  KeyPathExpression: () => KeyPathExpression,
47
- KeyPathExpressionV2: () => KeyPathExpressionV2,
58
+ LegacyKeyPathExpression: () => LegacyKeyPathExpression,
48
59
  ListNode: () => ListNode,
49
60
  MapNode: () => MapNode,
50
61
  MapType: () => MapType,
@@ -62,25 +73,25 @@ __export(src_exports, {
62
73
  VariableEngine: () => VariableEngine,
63
74
  VariableEngineProvider: () => VariableEngineProvider,
64
75
  VariableFieldKeyRenameService: () => VariableFieldKeyRenameService,
65
- VariableTable: () => VariableTable,
76
+ WrapArrayExpression: () => WrapArrayExpression,
66
77
  injectToAST: () => injectToAST,
67
78
  isMatchAST: () => isMatchAST,
68
79
  postConstructAST: () => postConstructAST,
69
80
  useAvailableVariables: () => useAvailableVariables,
70
81
  useCurrentScope: () => useCurrentScope,
71
- useScopeAvailable: () => useScopeAvailable,
72
- useScopeContext: () => useScopeContext
82
+ useOutputVariables: () => useOutputVariables,
83
+ useScopeAvailable: () => useScopeAvailable
73
84
  });
74
- module.exports = __toCommonJS(src_exports);
85
+ module.exports = __toCommonJS(index_exports);
75
86
 
76
87
  // src/variable-container-module.ts
77
- var import_inversify7 = require("inversify");
88
+ var import_inversify8 = require("inversify");
78
89
 
79
90
  // src/variable-engine.ts
80
- var import_rxjs6 = require("rxjs");
81
- var import_inversify5 = require("inversify");
82
- var import_utils10 = require("@flowgram.ai/utils");
83
- var import_utils11 = require("@flowgram.ai/utils");
91
+ var import_rxjs7 = require("rxjs");
92
+ var import_inversify6 = require("inversify");
93
+ var import_utils8 = require("@flowgram.ai/utils");
94
+ var import_utils9 = require("@flowgram.ai/utils");
84
95
 
85
96
  // src/utils/toDisposable.tsx
86
97
  var import_utils = require("@flowgram.ai/utils");
@@ -110,9 +121,170 @@ var createMemo = () => {
110
121
  return memo;
111
122
  };
112
123
 
124
+ // src/scope/variable-table.ts
125
+ var import_rxjs = require("rxjs");
126
+ var import_utils2 = require("@flowgram.ai/utils");
127
+ var VariableTable = class {
128
+ constructor(parentTable) {
129
+ this.parentTable = parentTable;
130
+ this.table = /* @__PURE__ */ new Map();
131
+ this.toDispose = new import_utils2.DisposableCollection();
132
+ /**
133
+ * @deprecated
134
+ */
135
+ this.onDataChangeEmitter = new import_utils2.Emitter();
136
+ this.variables$ = new import_rxjs.Subject();
137
+ /**
138
+ * An observable that listens for value changes on any variable within the table.
139
+ */
140
+ this.anyVariableChange$ = this.variables$.pipe(
141
+ (0, import_rxjs.switchMap)(
142
+ (_variables) => (0, import_rxjs.merge)(
143
+ ..._variables.map(
144
+ (_v) => _v.value$.pipe(
145
+ // Skip the initial value of the BehaviorSubject
146
+ (0, import_rxjs.skip)(1)
147
+ )
148
+ )
149
+ )
150
+ ),
151
+ (0, import_rxjs.share)()
152
+ );
153
+ /**
154
+ * @deprecated Use onListOrAnyVarChange instead.
155
+ */
156
+ this.onDataChange = this.onDataChangeEmitter.event;
157
+ this._version = 0;
158
+ this.toDispose.pushAll([
159
+ this.onDataChangeEmitter,
160
+ // Activate the share() operator
161
+ this.onAnyVariableChange(() => {
162
+ this.bumpVersion();
163
+ })
164
+ ]);
165
+ }
166
+ /**
167
+ * Subscribes to updates on any variable in the list.
168
+ * @param observer A function to be called when any variable's value changes.
169
+ * @returns A disposable object to unsubscribe from the updates.
170
+ */
171
+ onAnyVariableChange(observer) {
172
+ return subsToDisposable(this.anyVariableChange$.subscribe(observer));
173
+ }
174
+ /**
175
+ * Subscribes to changes in the variable list (additions or removals).
176
+ * @param observer A function to be called when the list of variables changes.
177
+ * @returns A disposable object to unsubscribe from the updates.
178
+ */
179
+ onVariableListChange(observer) {
180
+ return subsToDisposable(this.variables$.subscribe(observer));
181
+ }
182
+ /**
183
+ * Subscribes to both variable list changes and updates to any variable in the list.
184
+ * @param observer A function to be called when either the list or a variable in it changes.
185
+ * @returns A disposable collection to unsubscribe from both events.
186
+ */
187
+ onListOrAnyVarChange(observer) {
188
+ const disposables = new import_utils2.DisposableCollection();
189
+ disposables.pushAll([this.onVariableListChange(observer), this.onAnyVariableChange(observer)]);
190
+ return disposables;
191
+ }
192
+ /**
193
+ * Fires change events to notify listeners that the data has been updated.
194
+ */
195
+ fireChange() {
196
+ this.bumpVersion();
197
+ this.onDataChangeEmitter.fire();
198
+ this.variables$.next(this.variables);
199
+ this.parentTable?.fireChange();
200
+ }
201
+ /**
202
+ * The current version of the variable table, incremented on each change.
203
+ */
204
+ get version() {
205
+ return this._version;
206
+ }
207
+ /**
208
+ * Increments the version number, resetting to 0 if it reaches MAX_SAFE_INTEGER.
209
+ */
210
+ bumpVersion() {
211
+ this._version = this._version + 1;
212
+ if (this._version === Number.MAX_SAFE_INTEGER) {
213
+ this._version = 0;
214
+ }
215
+ }
216
+ /**
217
+ * An array of all variables in the table.
218
+ */
219
+ get variables() {
220
+ return Array.from(this.table.values());
221
+ }
222
+ /**
223
+ * An array of all variable keys in the table.
224
+ */
225
+ get variableKeys() {
226
+ return Array.from(this.table.keys());
227
+ }
228
+ /**
229
+ * Retrieves a variable or a nested property field by its key path.
230
+ * @param keyPath An array of keys representing the path to the desired field.
231
+ * @returns The found variable or property field, or undefined if not found.
232
+ */
233
+ getByKeyPath(keyPath) {
234
+ const [variableKey, ...propertyKeys] = keyPath || [];
235
+ if (!variableKey) {
236
+ return;
237
+ }
238
+ const variable = this.getVariableByKey(variableKey);
239
+ return propertyKeys.length ? variable?.getByKeyPath(propertyKeys) : variable;
240
+ }
241
+ /**
242
+ * Retrieves a variable by its key.
243
+ * @param key The key of the variable to retrieve.
244
+ * @returns The variable declaration if found, otherwise undefined.
245
+ */
246
+ getVariableByKey(key) {
247
+ return this.table.get(key);
248
+ }
249
+ /**
250
+ * Adds a variable to the table.
251
+ * If a parent table exists, the variable is also added to the parent.
252
+ * @param variable The variable declaration to add.
253
+ */
254
+ addVariableToTable(variable) {
255
+ this.table.set(variable.key, variable);
256
+ if (this.parentTable) {
257
+ this.parentTable.addVariableToTable(variable);
258
+ }
259
+ }
260
+ /**
261
+ * Removes a variable from the table.
262
+ * If a parent table exists, the variable is also removed from the parent.
263
+ * @param key The key of the variable to remove.
264
+ */
265
+ removeVariableFromTable(key) {
266
+ this.table.delete(key);
267
+ if (this.parentTable) {
268
+ this.parentTable.removeVariableFromTable(key);
269
+ }
270
+ }
271
+ /**
272
+ * Disposes of all resources used by the variable table.
273
+ */
274
+ dispose() {
275
+ this.variableKeys.forEach(
276
+ (_key) => this.parentTable?.removeVariableFromTable(_key)
277
+ );
278
+ this.parentTable?.fireChange();
279
+ this.variables$.complete();
280
+ this.variables$.unsubscribe();
281
+ this.toDispose.dispose();
282
+ }
283
+ };
284
+
113
285
  // src/scope/scope-chain.ts
114
286
  var import_inversify = require("inversify");
115
- var import_utils2 = require("@flowgram.ai/utils");
287
+ var import_utils3 = require("@flowgram.ai/utils");
116
288
 
117
289
  // src/providers.ts
118
290
  var VariableEngineProvider = Symbol("DynamicVariableEngine");
@@ -121,13 +293,13 @@ var ContainerProvider = Symbol("ContainerProvider");
121
293
  // src/scope/scope-chain.ts
122
294
  var ScopeChain = class {
123
295
  constructor() {
124
- this.toDispose = new import_utils2.DisposableCollection();
296
+ this.toDispose = new import_utils3.DisposableCollection();
125
297
  }
126
298
  get variableEngine() {
127
299
  return this.variableEngineProvider();
128
300
  }
129
301
  /**
130
- * 所有作用域依赖关系刷新
302
+ * Refreshes the dependency and coverage relationships for all scopes.
131
303
  */
132
304
  refreshAllChange() {
133
305
  this.variableEngine.getAllScopes().forEach((_scope) => {
@@ -153,7 +325,7 @@ ScopeChain = __decorateClass([
153
325
  ], ScopeChain);
154
326
 
155
327
  // src/scope/scope.ts
156
- var import_utils9 = require("@flowgram.ai/utils");
328
+ var import_utils7 = require("@flowgram.ai/utils");
157
329
 
158
330
  // src/ast/types.ts
159
331
  var ASTKind = /* @__PURE__ */ ((ASTKind2) => {
@@ -166,12 +338,13 @@ var ASTKind = /* @__PURE__ */ ((ASTKind2) => {
166
338
  ASTKind2["Map"] = "Map";
167
339
  ASTKind2["Union"] = "Union";
168
340
  ASTKind2["Any"] = "Any";
341
+ ASTKind2["CustomType"] = "CustomType";
169
342
  ASTKind2["Property"] = "Property";
170
343
  ASTKind2["VariableDeclaration"] = "VariableDeclaration";
171
344
  ASTKind2["VariableDeclarationList"] = "VariableDeclarationList";
172
345
  ASTKind2["KeyPathExpression"] = "KeyPathExpression";
173
346
  ASTKind2["EnumerateExpression"] = "EnumerateExpression";
174
- ASTKind2["ExpressionList"] = "ExpressionList";
347
+ ASTKind2["WrapArrayExpression"] = "WrapArrayExpression";
175
348
  ASTKind2["ListNode"] = "ListNode";
176
349
  ASTKind2["DataNode"] = "DataNode";
177
350
  ASTKind2["MapNode"] = "MapNode";
@@ -179,8 +352,8 @@ var ASTKind = /* @__PURE__ */ ((ASTKind2) => {
179
352
  })(ASTKind || {});
180
353
 
181
354
  // src/ast/ast-registers.ts
182
- var import_lodash3 = require("lodash");
183
- var import_inversify2 = require("inversify");
355
+ var import_lodash_es4 = require("lodash-es");
356
+ var import_inversify3 = require("inversify");
184
357
 
185
358
  // src/ast/utils/inversify.ts
186
359
  var injectToAST = (serviceIdentifier) => function(target, propertyKey) {
@@ -210,6 +383,43 @@ var postConstructAST = () => (target, propertyKey) => {
210
383
  }
211
384
  };
212
385
 
386
+ // src/ast/flags.ts
387
+ var ASTNodeFlags = /* @__PURE__ */ ((ASTNodeFlags2) => {
388
+ ASTNodeFlags2[ASTNodeFlags2["None"] = 0] = "None";
389
+ ASTNodeFlags2[ASTNodeFlags2["VariableField"] = 1] = "VariableField";
390
+ ASTNodeFlags2[ASTNodeFlags2["Expression"] = 4] = "Expression";
391
+ ASTNodeFlags2[ASTNodeFlags2["BasicType"] = 8] = "BasicType";
392
+ ASTNodeFlags2[ASTNodeFlags2["DrilldownType"] = 16] = "DrilldownType";
393
+ ASTNodeFlags2[ASTNodeFlags2["EnumerateType"] = 32] = "EnumerateType";
394
+ ASTNodeFlags2[ASTNodeFlags2["UnionType"] = 64] = "UnionType";
395
+ ASTNodeFlags2[ASTNodeFlags2["VariableType"] = 120] = "VariableType";
396
+ return ASTNodeFlags2;
397
+ })(ASTNodeFlags || {});
398
+
399
+ // src/ast/match.ts
400
+ var ASTMatch;
401
+ ((ASTMatch2) => {
402
+ ASTMatch2.isString = (node) => node?.kind === "String" /* String */;
403
+ ASTMatch2.isNumber = (node) => node?.kind === "Number" /* Number */;
404
+ ASTMatch2.isBoolean = (node) => node?.kind === "Boolean" /* Boolean */;
405
+ ASTMatch2.isInteger = (node) => node?.kind === "Integer" /* Integer */;
406
+ ASTMatch2.isObject = (node) => node?.kind === "Object" /* Object */;
407
+ ASTMatch2.isArray = (node) => node?.kind === "Array" /* Array */;
408
+ ASTMatch2.isMap = (node) => node?.kind === "Map" /* Map */;
409
+ ASTMatch2.isCustomType = (node) => node?.kind === "CustomType" /* CustomType */;
410
+ ASTMatch2.isVariableDeclaration = (node) => node?.kind === "VariableDeclaration" /* VariableDeclaration */;
411
+ ASTMatch2.isProperty = (node) => node?.kind === "Property" /* Property */;
412
+ ASTMatch2.isBaseVariableField = (node) => !!(node?.flags || 0 & 1 /* VariableField */);
413
+ ASTMatch2.isVariableDeclarationList = (node) => node?.kind === "VariableDeclarationList" /* VariableDeclarationList */;
414
+ ASTMatch2.isEnumerateExpression = (node) => node?.kind === "EnumerateExpression" /* EnumerateExpression */;
415
+ ASTMatch2.isWrapArrayExpression = (node) => node?.kind === "WrapArrayExpression" /* WrapArrayExpression */;
416
+ ASTMatch2.isKeyPathExpression = (node) => node?.kind === "KeyPathExpression" /* KeyPathExpression */;
417
+ function is(node, targetType) {
418
+ return node?.kind === targetType?.kind;
419
+ }
420
+ ASTMatch2.is = is;
421
+ })(ASTMatch || (ASTMatch = {}));
422
+
213
423
  // src/ast/utils/helpers.ts
214
424
  function updateChildNodeHelper({
215
425
  getChildNode,
@@ -245,73 +455,64 @@ function getAllChildren(ast) {
245
455
  return [...ast.children, ...ast.children.map((_child) => getAllChildren(_child)).flat()];
246
456
  }
247
457
  function isMatchAST(node, targetType) {
248
- return node?.kind === targetType?.kind;
458
+ return ASTMatch.is(node, targetType);
249
459
  }
250
460
 
251
- // src/ast/flags.ts
252
- var ASTNodeFlags = /* @__PURE__ */ ((ASTNodeFlags2) => {
253
- ASTNodeFlags2[ASTNodeFlags2["None"] = 0] = "None";
254
- ASTNodeFlags2[ASTNodeFlags2["VariableField"] = 1] = "VariableField";
255
- ASTNodeFlags2[ASTNodeFlags2["Expression"] = 4] = "Expression";
256
- ASTNodeFlags2[ASTNodeFlags2["BasicType"] = 8] = "BasicType";
257
- ASTNodeFlags2[ASTNodeFlags2["DrilldownType"] = 16] = "DrilldownType";
258
- ASTNodeFlags2[ASTNodeFlags2["EnumerateType"] = 32] = "EnumerateType";
259
- ASTNodeFlags2[ASTNodeFlags2["UnionType"] = 64] = "UnionType";
260
- ASTNodeFlags2[ASTNodeFlags2["VariableType"] = 120] = "VariableType";
261
- return ASTNodeFlags2;
262
- })(ASTNodeFlags || {});
263
-
264
461
  // src/ast/ast-node.ts
265
- var import_rxjs = require("rxjs");
462
+ var import_rxjs2 = require("rxjs");
266
463
  var import_nanoid = require("nanoid");
464
+ var import_lodash_es = require("lodash-es");
267
465
  var import_fast_equals = require("fast-equals");
268
- var import_utils3 = require("@flowgram.ai/utils");
466
+ var import_utils4 = require("@flowgram.ai/utils");
269
467
  var ASTNode = class _ASTNode {
270
468
  /**
271
- * 构造函数
272
- * @param createParams 创建 ASTNode 的必要参数
273
- * @param injectOptions 依赖注入各种模块
469
+ * Constructor.
470
+ * @param createParams Necessary parameters for creating an ASTNode.
471
+ * @param injectOptions Dependency injection for various modules.
274
472
  */
275
473
  constructor({ key, parent, scope }, opts) {
276
474
  /**
277
- * 节点 Flags,记录一些 Flag 信息
475
+ * Node flags, used to record some flag information.
278
476
  */
279
477
  this.flags = 0 /* None */;
280
478
  /**
281
- * 节点的版本号,每 fireChange 一次 version + 1
479
+ * The version number of the ASTNode, which increments by 1 each time `fireChange` is called.
282
480
  */
283
481
  this._version = 0;
284
482
  /**
285
- * 更新锁
483
+ * Update lock.
484
+ * - When set to `true`, `fireChange` will not trigger any events.
485
+ * - This is useful when multiple updates are needed, and you want to avoid multiple triggers.
286
486
  */
287
487
  this.changeLocked = false;
288
488
  /**
289
- * Batch Update 相关参数
489
+ * Parameters related to batch updates.
290
490
  */
291
491
  this._batch = {
292
492
  batching: false,
293
493
  hasChangesInBatch: false
294
494
  };
295
495
  /**
296
- * AST 节点变化事件,基于 Rxjs 实现
297
- * - 使用了 BehaviorSubject, 在订阅时会自动触发一次事件,事件为当前值
496
+ * AST node change Observable events, implemented based on RxJS.
497
+ * - Emits the current ASTNode value upon subscription.
498
+ * - Emits a new value whenever `fireChange` is called.
298
499
  */
299
- this.value$ = new import_rxjs.BehaviorSubject(this);
500
+ this.value$ = new import_rxjs2.BehaviorSubject(this);
300
501
  /**
301
- * 子节点
502
+ * Child ASTNodes.
302
503
  */
303
504
  this._children = /* @__PURE__ */ new Set();
304
505
  /**
305
- * 删除节点处理事件列表
506
+ * List of disposal handlers for the ASTNode.
306
507
  */
307
- this.toDispose = new import_utils3.DisposableCollection(
308
- import_utils3.Disposable.create(() => {
508
+ this.toDispose = new import_utils4.DisposableCollection(
509
+ import_utils4.Disposable.create(() => {
309
510
  this.parent?.fireChange();
310
511
  this.children.forEach((child) => child.dispose());
311
512
  })
312
513
  );
313
514
  /**
314
- * 销毁时触发的回调
515
+ * Callback triggered upon disposal.
315
516
  */
316
517
  this.onDispose = this.toDispose.onDispose;
317
518
  this.scope = scope;
@@ -319,10 +520,19 @@ var ASTNode = class _ASTNode {
319
520
  this.opts = opts;
320
521
  this.key = key || (0, import_nanoid.nanoid)();
321
522
  this.fromJSON = this.withBatchUpdate(this.fromJSON.bind(this));
322
- this.dispatchGlobalEvent({ type: "NewAST" });
523
+ const rawToJSON = this.toJSON?.bind(this);
524
+ this.toJSON = () => (0, import_lodash_es.omitBy)(
525
+ {
526
+ // always include kind
527
+ kind: this.kind,
528
+ ...rawToJSON?.() || {}
529
+ },
530
+ // remove undefined fields
531
+ import_lodash_es.isNil
532
+ );
323
533
  }
324
534
  /**
325
- * AST 节点的类型
535
+ * The type of the ASTNode.
326
536
  */
327
537
  get kind() {
328
538
  if (!this.constructor.kind) {
@@ -331,24 +541,14 @@ var ASTNode = class _ASTNode {
331
541
  return this.constructor.kind;
332
542
  }
333
543
  /**
334
- * 获取当前节点所有子节点
544
+ * Gets all child ASTNodes of the current ASTNode.
335
545
  */
336
546
  get children() {
337
547
  return Array.from(this._children);
338
548
  }
339
549
  /**
340
- * 转化为 ASTNodeJSON
341
- * @returns
342
- */
343
- toJSON() {
344
- console.warn("[VariableEngine] Please Implement toJSON method for " + this.kind);
345
- return {
346
- kind: this.kind
347
- };
348
- }
349
- /**
350
- * 创建子节点
351
- * @param json 子节点的 AST JSON
550
+ * Creates a child ASTNode.
551
+ * @param json The AST JSON of the child ASTNode.
352
552
  * @returns
353
553
  */
354
554
  createChildNode(json) {
@@ -359,15 +559,15 @@ var ASTNode = class _ASTNode {
359
559
  });
360
560
  this._children.add(child);
361
561
  child.toDispose.push(
362
- import_utils3.Disposable.create(() => {
562
+ import_utils4.Disposable.create(() => {
363
563
  this._children.delete(child);
364
564
  })
365
565
  );
366
566
  return child;
367
567
  }
368
568
  /**
369
- * 更新子节点,快速实现子节点更新消费逻辑
370
- * @param keyInThis 当前对象上的指定 key
569
+ * Updates a child ASTNode, quickly implementing the consumption logic for child ASTNode updates.
570
+ * @param keyInThis The specified key on the current object.
371
571
  */
372
572
  updateChildNodeByKey(keyInThis, nextJSON) {
373
573
  this.withBatchUpdate(updateChildNodeHelper).call(this, {
@@ -378,8 +578,8 @@ var ASTNode = class _ASTNode {
378
578
  });
379
579
  }
380
580
  /**
381
- * 批处理更新,批处理函数内所有的 fireChange 都合并成一个
382
- * @param updater 批处理函数
581
+ * Batch updates the ASTNode, merging all `fireChange` calls within the batch function into one.
582
+ * @param updater The batch function.
383
583
  * @returns
384
584
  */
385
585
  withBatchUpdate(updater) {
@@ -399,7 +599,7 @@ var ASTNode = class _ASTNode {
399
599
  };
400
600
  }
401
601
  /**
402
- * 触发当前节点更新
602
+ * Triggers an update for the current node.
403
603
  */
404
604
  fireChange() {
405
605
  if (this.changeLocked || this.disposed) {
@@ -415,29 +615,31 @@ var ASTNode = class _ASTNode {
415
615
  this.parent?.fireChange();
416
616
  }
417
617
  /**
418
- * 节点的版本值
419
- * - 通过 NodeA === NodeB && versionA === versionB 可以比较两者是否相等
618
+ * The version value of the ASTNode.
619
+ * - You can used to check whether ASTNode are updated.
420
620
  */
421
621
  get version() {
422
622
  return this._version;
423
623
  }
424
624
  /**
425
- * 节点唯一 hash
625
+ * The unique hash value of the ASTNode.
626
+ * - It will update when the ASTNode is updated.
627
+ * - You can used to check two ASTNode are equal.
426
628
  */
427
629
  get hash() {
428
630
  return `${this._version}${this.kind}${this.key}`;
429
631
  }
430
632
  /**
431
- * 监听 AST 节点的变化
432
- * @param observer 监听回调
433
- * @param selector 监听指定数据
633
+ * Listens for changes to the ASTNode.
634
+ * @param observer The listener callback.
635
+ * @param selector Listens for specified data.
434
636
  * @returns
435
637
  */
436
638
  subscribe(observer, { selector, debounceAnimation, triggerOnInit } = {}) {
437
639
  return subsToDisposable(
438
640
  this.value$.pipe(
439
- (0, import_rxjs.map)(() => selector ? selector(this) : this),
440
- (0, import_rxjs.distinctUntilChanged)(
641
+ (0, import_rxjs2.map)(() => selector ? selector(this) : this),
642
+ (0, import_rxjs2.distinctUntilChanged)(
441
643
  (a, b) => (0, import_fast_equals.shallowEqual)(a, b),
442
644
  (value) => {
443
645
  if (value instanceof _ASTNode) {
@@ -446,13 +648,17 @@ var ASTNode = class _ASTNode {
446
648
  return value;
447
649
  }
448
650
  ),
449
- // 默认跳过 BehaviorSubject 第一次触发
450
- triggerOnInit ? (0, import_rxjs.tap)(() => null) : (0, import_rxjs.skip)(1),
451
- // 每个 animationFrame 内所有更新合并成一个
452
- debounceAnimation ? (0, import_rxjs.debounceTime)(0, import_rxjs.animationFrameScheduler) : (0, import_rxjs.tap)(() => null)
651
+ // By default, skip the first trigger of BehaviorSubject.
652
+ triggerOnInit ? (0, import_rxjs2.tap)(() => null) : (0, import_rxjs2.skip)(1),
653
+ // All updates within each animationFrame are merged into one.
654
+ debounceAnimation ? (0, import_rxjs2.debounceTime)(0, import_rxjs2.animationFrameScheduler) : (0, import_rxjs2.tap)(() => null)
453
655
  ).subscribe(observer)
454
656
  );
455
657
  }
658
+ /**
659
+ * Dispatches a global event for the current ASTNode.
660
+ * @param event The global event.
661
+ */
456
662
  dispatchGlobalEvent(event) {
457
663
  this.scope.event.dispatch({
458
664
  ...event,
@@ -460,7 +666,7 @@ var ASTNode = class _ASTNode {
460
666
  });
461
667
  }
462
668
  /**
463
- * 销毁
669
+ * Disposes the ASTNode.
464
670
  */
465
671
  dispose() {
466
672
  if (this.toDispose.disposed) {
@@ -483,8 +689,9 @@ var BaseType = class extends ASTNode {
483
689
  this.flags = 8 /* BasicType */;
484
690
  }
485
691
  /**
486
- * 类型是否一致,节点有额外信息判断,请参考 extraTypeInfoEqual
487
- * @param targetTypeJSON
692
+ * Check if the current type is equal to the target type.
693
+ * @param targetTypeJSONOrKind The type to compare with.
694
+ * @returns `true` if the types are equal, `false` otherwise.
488
695
  */
489
696
  isTypeEqual(targetTypeJSONOrKind) {
490
697
  const targetTypeJSON = parseTypeJsonOrKind(targetTypeJSONOrKind);
@@ -496,17 +703,15 @@ var BaseType = class extends ASTNode {
496
703
  return this.kind === targetTypeJSON?.kind;
497
704
  }
498
705
  /**
499
- * 可下钻类型需实现
500
- * @param keyPath
706
+ * Get a variable field by key path.
707
+ *
708
+ * This method should be implemented by drillable types.
709
+ * @param keyPath The key path to search for.
710
+ * @returns The variable field if found, otherwise `undefined`.
501
711
  */
502
712
  getByKeyPath(keyPath = []) {
503
713
  throw new Error(`Get By Key Path is not implemented for Type: ${this.kind}`);
504
714
  }
505
- toJSON() {
506
- return {
507
- kind: this.kind
508
- };
509
- }
510
715
  };
511
716
 
512
717
  // src/ast/type/array.ts
@@ -515,13 +720,24 @@ var ArrayType = class extends BaseType {
515
720
  super(...arguments);
516
721
  this.flags = 16 /* DrilldownType */ | 32 /* EnumerateType */;
517
722
  }
723
+ /**
724
+ * Deserializes the `ArrayJSON` to the `ArrayType`.
725
+ * @param json The `ArrayJSON` to deserialize.
726
+ */
518
727
  fromJSON({ items }) {
519
728
  this.updateChildNodeByKey("items", parseTypeJsonOrKind(items));
520
729
  }
521
- // items 类型是否可下钻
730
+ /**
731
+ * Whether the items type can be drilled down.
732
+ */
522
733
  get canDrilldownItems() {
523
734
  return !!(this.items?.flags & 16 /* DrilldownType */);
524
735
  }
736
+ /**
737
+ * Get a variable field by key path.
738
+ * @param keyPath The key path to search for.
739
+ * @returns The variable field if found, otherwise `undefined`.
740
+ */
525
741
  getByKeyPath(keyPath) {
526
742
  const [curr, ...rest] = keyPath || [];
527
743
  if (curr === "0" && this.canDrilldownItems) {
@@ -529,19 +745,24 @@ var ArrayType = class extends BaseType {
529
745
  }
530
746
  return void 0;
531
747
  }
748
+ /**
749
+ * Check if the current type is equal to the target type.
750
+ * @param targetTypeJSONOrKind The type to compare with.
751
+ * @returns `true` if the types are equal, `false` otherwise.
752
+ */
532
753
  isTypeEqual(targetTypeJSONOrKind) {
533
754
  const targetTypeJSON = parseTypeJsonOrKind(targetTypeJSONOrKind);
534
755
  const isSuperEqual = super.isTypeEqual(targetTypeJSONOrKind);
535
756
  if (targetTypeJSON?.weak || targetTypeJSON?.kind === "Union" /* Union */) {
536
757
  return isSuperEqual;
537
758
  }
538
- return targetTypeJSON && isSuperEqual && // 弱比较,只需要比较 Kind 即可
759
+ return targetTypeJSON && isSuperEqual && // Weak comparison, only need to compare the Kind.
539
760
  (targetTypeJSON?.weak || this.customStrongEqual(targetTypeJSON));
540
761
  }
541
762
  /**
542
- * Array 强比较
543
- * @param targetTypeJSON
544
- * @returns
763
+ * Array strong comparison.
764
+ * @param targetTypeJSON The type to compare with.
765
+ * @returns `true` if the types are equal, `false` otherwise.
545
766
  */
546
767
  customStrongEqual(targetTypeJSON) {
547
768
  if (!this.items) {
@@ -549,6 +770,10 @@ var ArrayType = class extends BaseType {
549
770
  }
550
771
  return this.items?.isTypeEqual(targetTypeJSON.items);
551
772
  }
773
+ /**
774
+ * Serialize the `ArrayType` to `ArrayJSON`
775
+ * @returns The JSON representation of `ArrayType`.
776
+ */
552
777
  toJSON() {
553
778
  return {
554
779
  kind: "Array" /* Array */,
@@ -564,7 +789,31 @@ var StringType = class extends BaseType {
564
789
  super(...arguments);
565
790
  this.flags = 8 /* BasicType */;
566
791
  }
567
- fromJSON() {
792
+ /**
793
+ * see https://json-schema.org/understanding-json-schema/reference/string#format
794
+ */
795
+ get format() {
796
+ return this._format;
797
+ }
798
+ /**
799
+ * Deserialize the `StringJSON` to the `StringType`.
800
+ *
801
+ * @param json StringJSON representation of the `StringType`.
802
+ */
803
+ fromJSON(json) {
804
+ if (json?.format !== this._format) {
805
+ this._format = json?.format;
806
+ this.fireChange();
807
+ }
808
+ }
809
+ /**
810
+ * Serialize the `StringType` to `StringJSON`.
811
+ * @returns The JSON representation of `StringType`.
812
+ */
813
+ toJSON() {
814
+ return {
815
+ format: this._format
816
+ };
568
817
  }
569
818
  };
570
819
  StringType.kind = "String" /* String */;
@@ -575,61 +824,84 @@ var IntegerType = class extends BaseType {
575
824
  super(...arguments);
576
825
  this.flags = 8 /* BasicType */;
577
826
  }
827
+ /**
828
+ * Deserializes the `IntegerJSON` to the `IntegerType`.
829
+ * @param json The `IntegerJSON` to deserialize.
830
+ */
578
831
  fromJSON() {
579
832
  }
833
+ toJSON() {
834
+ return {};
835
+ }
580
836
  };
581
837
  IntegerType.kind = "Integer" /* Integer */;
582
838
 
583
839
  // src/ast/type/boolean.ts
584
840
  var BooleanType = class extends BaseType {
841
+ /**
842
+ * Deserializes the `BooleanJSON` to the `BooleanType`.
843
+ * @param json The `BooleanJSON` to deserialize.
844
+ */
585
845
  fromJSON() {
586
846
  }
847
+ toJSON() {
848
+ return {};
849
+ }
587
850
  };
588
851
  BooleanType.kind = "Boolean" /* Boolean */;
589
852
 
590
853
  // src/ast/type/number.ts
591
854
  var NumberType = class extends BaseType {
855
+ /**
856
+ * Deserializes the `NumberJSON` to the `NumberType`.
857
+ * @param json The `NumberJSON` to deserialize.
858
+ */
592
859
  fromJSON() {
593
860
  }
861
+ toJSON() {
862
+ return {};
863
+ }
594
864
  };
595
865
  NumberType.kind = "Number" /* Number */;
596
866
 
597
867
  // src/ast/type/map.ts
598
868
  var MapType = class extends BaseType {
869
+ /**
870
+ * Deserializes the `MapJSON` to the `MapType`.
871
+ * @param json The `MapJSON` to deserialize.
872
+ */
599
873
  fromJSON({ keyType = "String" /* String */, valueType }) {
600
874
  this.updateChildNodeByKey("keyType", parseTypeJsonOrKind(keyType));
601
875
  this.updateChildNodeByKey("valueType", parseTypeJsonOrKind(valueType));
602
876
  }
603
- // Value 类型是否可下钻,后续实现
604
- // get canDrilldownValue(): boolean {
605
- // return !!(this.valueType.flags & ASTNodeFlags.DrilldownType);
606
- // }
607
- // getByKeyPath(keyPath: string[]): BaseVariableField | undefined {
608
- // const [curr, ...rest] = keyPath || [];
609
- // if (curr === '*' && this.canDrilldownValue) {
610
- // return this.valueType.getByKeyPath(rest);
611
- // }
612
- // return undefined;
613
- // }
877
+ /**
878
+ * Check if the current type is equal to the target type.
879
+ * @param targetTypeJSONOrKind The type to compare with.
880
+ * @returns `true` if the types are equal, `false` otherwise.
881
+ */
614
882
  isTypeEqual(targetTypeJSONOrKind) {
615
883
  const targetTypeJSON = parseTypeJsonOrKind(targetTypeJSONOrKind);
616
884
  const isSuperEqual = super.isTypeEqual(targetTypeJSONOrKind);
617
885
  if (targetTypeJSON?.weak || targetTypeJSON?.kind === "Union" /* Union */) {
618
886
  return isSuperEqual;
619
887
  }
620
- return targetTypeJSON && isSuperEqual && // 弱比较,只需要比较 Kind 即可
888
+ return targetTypeJSON && isSuperEqual && // Weak comparison, only need to compare the Kind.
621
889
  (targetTypeJSON?.weak || this.customStrongEqual(targetTypeJSON));
622
890
  }
623
891
  /**
624
- * Map 强比较
625
- * @param targetTypeJSON
626
- * @returns
892
+ * Map strong comparison.
893
+ * @param targetTypeJSON The type to compare with.
894
+ * @returns `true` if the types are equal, `false` otherwise.
627
895
  */
628
896
  customStrongEqual(targetTypeJSON) {
629
897
  const { keyType = "String" /* String */, valueType } = targetTypeJSON;
630
898
  const isValueTypeEqual = !valueType && !this.valueType || this.valueType?.isTypeEqual(valueType);
631
899
  return isValueTypeEqual && this.keyType?.isTypeEqual(keyType);
632
900
  }
901
+ /**
902
+ * Serialize the node to a JSON object.
903
+ * @returns The JSON representation of the node.
904
+ */
633
905
  toJSON() {
634
906
  return {
635
907
  kind: "Map" /* Map */,
@@ -638,17 +910,23 @@ var MapType = class extends BaseType {
638
910
  };
639
911
  }
640
912
  };
641
- // public flags: ASTNodeFlags = ASTNodeFlags.DrilldownType | ASTNodeFlags.EnumerateType;
642
913
  MapType.kind = "Map" /* Map */;
643
914
 
644
915
  // src/ast/type/object.ts
645
- var import_lodash = require("lodash");
916
+ var import_lodash_es2 = require("lodash-es");
646
917
  var ObjectType = class extends BaseType {
647
918
  constructor() {
648
919
  super(...arguments);
649
920
  this.flags = 16 /* DrilldownType */;
921
+ /**
922
+ * A map of property keys to `Property` instances.
923
+ */
650
924
  this.propertyTable = /* @__PURE__ */ new Map();
651
925
  }
926
+ /**
927
+ * Deserializes the `ObjectJSON` to the `ObjectType`.
928
+ * @param json The `ObjectJSON` to deserialize.
929
+ */
652
930
  fromJSON({ properties }) {
653
931
  const removedKeys = new Set(this.propertyTable.keys());
654
932
  const prev = [...this.properties || []];
@@ -682,16 +960,19 @@ var ObjectType = class extends BaseType {
682
960
  }
683
961
  });
684
962
  }
963
+ /**
964
+ * Serialize the `ObjectType` to `ObjectJSON`.
965
+ * @returns The JSON representation of `ObjectType`.
966
+ */
685
967
  toJSON() {
686
968
  return {
687
- kind: "Object" /* Object */,
688
969
  properties: this.properties.map((_property) => _property.toJSON())
689
970
  };
690
971
  }
691
972
  /**
692
- * 根据 KeyPath 找到对应的变量
693
- * @param keyPath 变量路径
694
- * @returns
973
+ * Get a variable field by key path.
974
+ * @param keyPath The key path to search for.
975
+ * @returns The variable field if found, otherwise `undefined`.
695
976
  */
696
977
  getByKeyPath(keyPath) {
697
978
  const [curr, ...restKeyPath] = keyPath;
@@ -704,25 +985,30 @@ var ObjectType = class extends BaseType {
704
985
  }
705
986
  return void 0;
706
987
  }
988
+ /**
989
+ * Check if the current type is equal to the target type.
990
+ * @param targetTypeJSONOrKind The type to compare with.
991
+ * @returns `true` if the types are equal, `false` otherwise.
992
+ */
707
993
  isTypeEqual(targetTypeJSONOrKind) {
708
994
  const targetTypeJSON = parseTypeJsonOrKind(targetTypeJSONOrKind);
709
995
  const isSuperEqual = super.isTypeEqual(targetTypeJSONOrKind);
710
996
  if (targetTypeJSON?.weak || targetTypeJSON?.kind === "Union" /* Union */) {
711
997
  return isSuperEqual;
712
998
  }
713
- return targetTypeJSON && isSuperEqual && // 弱比较,只需要比较 Kind 即可
999
+ return targetTypeJSON && isSuperEqual && // Weak comparison, only need to compare the Kind.
714
1000
  (targetTypeJSON?.weak || this.customStrongEqual(targetTypeJSON));
715
1001
  }
716
1002
  /**
717
- * Object 类型强比较
718
- * @param targetTypeJSON
719
- * @returns
1003
+ * Object type strong comparison.
1004
+ * @param targetTypeJSON The type to compare with.
1005
+ * @returns `true` if the types are equal, `false` otherwise.
720
1006
  */
721
1007
  customStrongEqual(targetTypeJSON) {
722
1008
  const targetProperties = targetTypeJSON.properties || [];
723
1009
  const sourcePropertyKeys = Array.from(this.propertyTable.keys());
724
1010
  const targetPropertyKeys = targetProperties.map((_target) => _target.key);
725
- const isKeyStrongEqual = !(0, import_lodash.xor)(sourcePropertyKeys, targetPropertyKeys).length;
1011
+ const isKeyStrongEqual = !(0, import_lodash_es2.xor)(sourcePropertyKeys, targetPropertyKeys).length;
726
1012
  return isKeyStrongEqual && targetProperties.every((targetProperty) => {
727
1013
  const sourceProperty = this.propertyTable.get(targetProperty.key);
728
1014
  return sourceProperty && sourceProperty.key === targetProperty.key && sourceProperty.type?.isTypeEqual(targetProperty?.type);
@@ -731,8 +1017,48 @@ var ObjectType = class extends BaseType {
731
1017
  };
732
1018
  ObjectType.kind = "Object" /* Object */;
733
1019
 
1020
+ // src/ast/type/custom-type.ts
1021
+ var CustomType = class extends BaseType {
1022
+ /**
1023
+ * The name of the custom type.
1024
+ */
1025
+ get typeName() {
1026
+ return this._typeName;
1027
+ }
1028
+ /**
1029
+ * Deserializes the `CustomTypeJSON` to the `CustomType`.
1030
+ * @param json The `CustomTypeJSON` to deserialize.
1031
+ */
1032
+ fromJSON(json) {
1033
+ if (this._typeName !== json.typeName) {
1034
+ this._typeName = json.typeName;
1035
+ this.fireChange();
1036
+ }
1037
+ }
1038
+ /**
1039
+ * Check if the current type is equal to the target type.
1040
+ * @param targetTypeJSONOrKind The type to compare with.
1041
+ * @returns `true` if the types are equal, `false` otherwise.
1042
+ */
1043
+ isTypeEqual(targetTypeJSONOrKind) {
1044
+ const targetTypeJSON = parseTypeJsonOrKind(targetTypeJSONOrKind);
1045
+ if (targetTypeJSON?.kind === "Union" /* Union */) {
1046
+ return (targetTypeJSON?.types || [])?.some(
1047
+ (_subType) => this.isTypeEqual(_subType)
1048
+ );
1049
+ }
1050
+ return targetTypeJSON?.kind === this.kind && targetTypeJSON?.typeName === this.typeName;
1051
+ }
1052
+ toJSON() {
1053
+ return {
1054
+ typeName: this.typeName
1055
+ };
1056
+ }
1057
+ };
1058
+ CustomType.kind = "CustomType" /* CustomType */;
1059
+
734
1060
  // src/ast/expression/base-expression.ts
735
- var import_rxjs2 = require("rxjs");
1061
+ var import_rxjs3 = require("rxjs");
736
1062
  var import_fast_equals2 = require("fast-equals");
737
1063
 
738
1064
  // src/ast/utils/variable-field.ts
@@ -754,25 +1080,24 @@ var BaseExpression = class extends ASTNode {
754
1080
  super(params, opts);
755
1081
  this.flags = 4 /* Expression */;
756
1082
  /**
757
- * 引用变量
1083
+ * The variable fields referenced by the expression.
758
1084
  */
759
1085
  this._refs = [];
760
- this.refreshRefs$ = new import_rxjs2.Subject();
1086
+ this.refreshRefs$ = new import_rxjs3.Subject();
761
1087
  /**
762
- * 监听引用变量变化
763
- * 监听 [a.b.c] -> [a.b]
1088
+ * An observable that emits the referenced variable fields when they change.
764
1089
  */
765
1090
  this.refs$ = this.refreshRefs$.pipe(
766
- (0, import_rxjs2.map)(() => this.getRefFields()),
767
- (0, import_rxjs2.distinctUntilChanged)(import_fast_equals2.shallowEqual),
768
- (0, import_rxjs2.switchMap)(
769
- (refs) => !refs?.length ? (0, import_rxjs2.of)([]) : (0, import_rxjs2.combineLatest)(
1091
+ (0, import_rxjs3.map)(() => this.getRefFields()),
1092
+ (0, import_rxjs3.distinctUntilChanged)(import_fast_equals2.shallowEqual),
1093
+ (0, import_rxjs3.switchMap)(
1094
+ (refs) => !refs?.length ? (0, import_rxjs3.of)([]) : (0, import_rxjs3.combineLatest)(
770
1095
  refs.map(
771
- (ref) => ref ? ref.value$ : (0, import_rxjs2.of)(void 0)
1096
+ (ref) => ref ? ref.value$ : (0, import_rxjs3.of)(void 0)
772
1097
  )
773
1098
  )
774
1099
  ),
775
- (0, import_rxjs2.share)()
1100
+ (0, import_rxjs3.share)()
776
1101
  );
777
1102
  this.toDispose.push(
778
1103
  subsToDisposable(
@@ -784,114 +1109,42 @@ var BaseExpression = class extends ASTNode {
784
1109
  );
785
1110
  }
786
1111
  /**
787
- * 获取全局变量表,方便表达式获取引用变量
1112
+ * Get the global variable table, which is used to access referenced variables.
788
1113
  */
789
1114
  get globalVariableTable() {
790
1115
  return this.scope.variableEngine.globalVariableTable;
791
1116
  }
792
1117
  /**
793
- * 父变量字段,通过由近而远的方式进行排序
1118
+ * Parent variable fields, sorted from closest to farthest.
794
1119
  */
795
1120
  get parentFields() {
796
1121
  return getParentFields(this);
797
1122
  }
1123
+ /**
1124
+ * The variable fields referenced by the expression.
1125
+ */
798
1126
  get refs() {
799
1127
  return this._refs;
800
1128
  }
801
1129
  /**
802
- * 刷新变量引用
1130
+ * Refresh the variable references.
803
1131
  */
804
1132
  refreshRefs() {
805
1133
  this.refreshRefs$.next();
806
1134
  }
807
1135
  };
808
1136
 
809
- // src/ast/expression/expression-list.ts
810
- var ExpressionList = class extends ASTNode {
811
- fromJSON({ expressions }) {
812
- this.expressions = expressions.map((_expression, idx) => {
813
- const prevExpression = this.expressions[idx];
814
- if (prevExpression.kind !== _expression.kind) {
815
- prevExpression.dispose();
816
- this.fireChange();
817
- return this.createChildNode(_expression);
818
- }
819
- prevExpression.fromJSON(_expression);
820
- return prevExpression;
821
- });
822
- }
823
- toJSON() {
824
- return {
825
- kind: "ExpressionList" /* ExpressionList */,
826
- properties: this.expressions.map((_expression) => _expression.toJSON())
827
- };
828
- }
829
- };
830
- ExpressionList.kind = "ExpressionList" /* ExpressionList */;
831
-
832
- // src/ast/expression/keypath-expression.ts
833
- var import_fast_equals3 = require("fast-equals");
834
- var KeyPathExpression = class extends BaseExpression {
835
- constructor(params, opts) {
836
- super(params, opts);
837
- this._keyPath = [];
838
- this.toDispose.pushAll([
839
- // 可以用变量列表变化时候 (有新增或者删除时)
840
- this.scope.available.onVariableListChange(() => {
841
- this.refreshRefs();
842
- }),
843
- // this._keyPath 指向的可引用变量发生变化时,刷新引用数据
844
- this.scope.available.onAnyVariableChange((_v) => {
845
- if (_v.key === this._keyPath[0]) {
846
- this.refreshRefs();
847
- }
848
- })
849
- ]);
850
- }
851
- get keyPath() {
852
- return this._keyPath;
853
- }
854
- getRefFields() {
855
- const ref = this.scope.available.getByKeyPath(this._keyPath);
856
- return ref ? [ref] : [];
857
- }
858
- get returnType() {
859
- const [refNode] = this._refs || [];
860
- if (refNode && refNode.flags & 1 /* VariableField */) {
861
- return refNode.type;
862
- }
863
- return;
864
- }
865
- /**
866
- * 业务重改该方法可快速定制自己的 Path 表达式
867
- * - 只需要将业务的 Path 解析为变量系统的 KeyPath 即可
868
- * @param json 业务定义的 Path 表达式
869
- * @returns
870
- */
871
- parseToKeyPath(json) {
872
- return json.keyPath;
873
- }
874
- fromJSON(json) {
875
- const keyPath = this.parseToKeyPath(json);
876
- if (!(0, import_fast_equals3.shallowEqual)(keyPath, this._keyPath)) {
877
- this._keyPath = keyPath;
878
- this.refreshRefs();
879
- }
880
- }
881
- toJSON() {
882
- return {
883
- kind: "KeyPathExpression" /* KeyPathExpression */,
884
- keyPath: this._keyPath
885
- };
886
- }
887
- };
888
- KeyPathExpression.kind = "KeyPathExpression" /* KeyPathExpression */;
889
-
890
1137
  // src/ast/expression/enumerate-expression.ts
891
1138
  var EnumerateExpression = class extends BaseExpression {
1139
+ /**
1140
+ * The expression to be enumerated.
1141
+ */
892
1142
  get enumerateFor() {
893
1143
  return this._enumerateFor;
894
1144
  }
1145
+ /**
1146
+ * The return type of the expression.
1147
+ */
895
1148
  get returnType() {
896
1149
  const childReturnType = this.enumerateFor?.returnType;
897
1150
  if (childReturnType?.kind === "Array" /* Array */) {
@@ -899,12 +1152,24 @@ var EnumerateExpression = class extends BaseExpression {
899
1152
  }
900
1153
  return void 0;
901
1154
  }
1155
+ /**
1156
+ * Get the variable fields referenced by the expression.
1157
+ * @returns An empty array, as this expression does not reference any variables.
1158
+ */
902
1159
  getRefFields() {
903
1160
  return [];
904
1161
  }
1162
+ /**
1163
+ * Deserializes the `EnumerateExpressionJSON` to the `EnumerateExpression`.
1164
+ * @param json The `EnumerateExpressionJSON` to deserialize.
1165
+ */
905
1166
  fromJSON({ enumerateFor: expression }) {
906
1167
  this.updateChildNodeByKey("_enumerateFor", expression);
907
1168
  }
1169
+ /**
1170
+ * Serialize the `EnumerateExpression` to `EnumerateExpressionJSON`.
1171
+ * @returns The JSON representation of `EnumerateExpression`.
1172
+ */
908
1173
  toJSON() {
909
1174
  return {
910
1175
  kind: "EnumerateExpression" /* EnumerateExpression */,
@@ -914,16 +1179,17 @@ var EnumerateExpression = class extends BaseExpression {
914
1179
  };
915
1180
  EnumerateExpression.kind = "EnumerateExpression" /* EnumerateExpression */;
916
1181
 
917
- // src/ast/expression/keypath-expression-v2.ts
918
- var import_fast_equals4 = require("fast-equals");
1182
+ // src/ast/expression/keypath-expression.ts
1183
+ var import_rxjs4 = require("rxjs");
1184
+ var import_fast_equals3 = require("fast-equals");
919
1185
 
920
1186
  // src/ast/utils/expression.ts
921
- var import_lodash2 = require("lodash");
1187
+ var import_lodash_es3 = require("lodash-es");
922
1188
  function getAllRefs(ast) {
923
1189
  return getAllChildren(ast).filter((_child) => _child.flags & 4 /* Expression */).map((_child) => _child.refs).flat().filter(Boolean);
924
1190
  }
925
1191
  function checkRefCycle(curr, refNodes) {
926
- if ((0, import_lodash2.intersection)(curr.scope.coverScopes, refNodes.map((_ref) => _ref?.scope).filter(Boolean)).length === 0) {
1192
+ if ((0, import_lodash_es3.intersection)(curr.scope.coverScopes, refNodes.map((_ref) => _ref?.scope).filter(Boolean)).length === 0) {
927
1193
  return false;
928
1194
  }
929
1195
  const visited = /* @__PURE__ */ new Set();
@@ -935,39 +1201,48 @@ function checkRefCycle(curr, refNodes) {
935
1201
  queue.push(ref);
936
1202
  }
937
1203
  }
938
- return (0, import_lodash2.intersection)(Array.from(visited), getParentFields(curr)).length > 0;
1204
+ return (0, import_lodash_es3.intersection)(Array.from(visited), getParentFields(curr)).length > 0;
939
1205
  }
940
1206
 
941
- // src/ast/expression/keypath-expression-v2.ts
942
- var KeyPathExpressionV2 = class extends BaseExpression {
1207
+ // src/ast/expression/keypath-expression.ts
1208
+ var KeyPathExpression = class extends BaseExpression {
943
1209
  constructor(params, opts) {
944
1210
  super(params, opts);
945
1211
  this._keyPath = [];
946
1212
  this.toDispose.pushAll([
947
- // 可以用变量列表变化时候 (有新增或者删除时)
1213
+ // Can be used when the variable list changes (when there are additions or deletions).
948
1214
  this.scope.available.onVariableListChange(() => {
949
1215
  this.refreshRefs();
950
1216
  }),
951
- // this._keyPath 指向的可引用变量发生变化时,刷新引用数据
1217
+ // When the referable variable pointed to by this._keyPath changes, refresh the reference data.
952
1218
  this.scope.available.onAnyVariableChange((_v) => {
953
1219
  if (_v.key === this._keyPath[0]) {
954
1220
  this.refreshRefs();
955
1221
  }
956
1222
  }),
957
1223
  subsToDisposable(
958
- this.refs$.subscribe((_type) => {
1224
+ this.refs$.pipe(
1225
+ (0, import_rxjs4.distinctUntilChanged)(
1226
+ (prev, next) => prev === next,
1227
+ (_refs) => _refs?.[0]?.type?.hash
1228
+ )
1229
+ ).subscribe((_type) => {
959
1230
  const [ref] = this._refs;
960
- if (this.prevRefTypeHash !== ref?.type?.hash) {
961
- this.prevRefTypeHash = ref?.type?.hash;
962
- this.updateChildNodeByKey("_returnType", this.getReturnTypeJSONByRef(ref));
963
- }
1231
+ this.updateChildNodeByKey("_returnType", this.getReturnTypeJSONByRef(ref));
964
1232
  })
965
1233
  )
966
1234
  ]);
967
1235
  }
1236
+ /**
1237
+ * The key path of the variable.
1238
+ */
968
1239
  get keyPath() {
969
1240
  return this._keyPath;
970
1241
  }
1242
+ /**
1243
+ * Get the variable fields referenced by the expression.
1244
+ * @returns An array of referenced variable fields.
1245
+ */
971
1246
  getRefFields() {
972
1247
  const ref = this.scope.available.getByKeyPath(this._keyPath);
973
1248
  if (checkRefCycle(this, [ref])) {
@@ -979,39 +1254,189 @@ var KeyPathExpressionV2 = class extends BaseExpression {
979
1254
  }
980
1255
  return ref ? [ref] : [];
981
1256
  }
1257
+ /**
1258
+ * The return type of the expression.
1259
+ */
982
1260
  get returnType() {
983
1261
  return this._returnType;
984
1262
  }
985
1263
  /**
986
- * 业务重改该方法可快速定制自己的 Path 表达式
987
- * - 只需要将业务的 Path 解析为变量系统的 KeyPath 即可
988
- * @param json 业务定义的 Path 表达式
989
- * @returns
1264
+ * Parse the business-defined path expression into a key path.
1265
+ *
1266
+ * Businesses can quickly customize their own path expressions by modifying this method.
1267
+ * @param json The path expression defined by the business.
1268
+ * @returns The key path.
990
1269
  */
991
1270
  parseToKeyPath(json) {
992
1271
  return json.keyPath;
993
1272
  }
1273
+ /**
1274
+ * Deserializes the `KeyPathExpressionJSON` to the `KeyPathExpression`.
1275
+ * @param json The `KeyPathExpressionJSON` to deserialize.
1276
+ */
994
1277
  fromJSON(json) {
995
1278
  const keyPath = this.parseToKeyPath(json);
996
- if (!(0, import_fast_equals4.shallowEqual)(keyPath, this._keyPath)) {
1279
+ if (!(0, import_fast_equals3.shallowEqual)(keyPath, this._keyPath)) {
997
1280
  this._keyPath = keyPath;
1281
+ this._rawPathJson = json;
998
1282
  this.refreshRefs();
999
1283
  }
1000
1284
  }
1285
+ /**
1286
+ * Get the return type JSON by reference.
1287
+ * @param _ref The referenced variable field.
1288
+ * @returns The JSON representation of the return type.
1289
+ */
1001
1290
  getReturnTypeJSONByRef(_ref) {
1002
1291
  return _ref?.type?.toJSON();
1003
1292
  }
1293
+ /**
1294
+ * Serialize the `KeyPathExpression` to `KeyPathExpressionJSON`.
1295
+ * @returns The JSON representation of `KeyPathExpression`.
1296
+ */
1297
+ toJSON() {
1298
+ return this._rawPathJson;
1299
+ }
1300
+ };
1301
+ KeyPathExpression.kind = "KeyPathExpression" /* KeyPathExpression */;
1302
+
1303
+ // src/ast/expression/legacy-keypath-expression.ts
1304
+ var import_fast_equals4 = require("fast-equals");
1305
+ var LegacyKeyPathExpression = class extends BaseExpression {
1306
+ constructor(params, opts) {
1307
+ super(params, opts);
1308
+ this._keyPath = [];
1309
+ this.toDispose.pushAll([
1310
+ // Can be used when the variable list changes (when there are additions or deletions).
1311
+ this.scope.available.onVariableListChange(() => {
1312
+ this.refreshRefs();
1313
+ }),
1314
+ // When the referable variable pointed to by this._keyPath changes, refresh the reference data.
1315
+ this.scope.available.onAnyVariableChange((_v) => {
1316
+ if (_v.key === this._keyPath[0]) {
1317
+ this.refreshRefs();
1318
+ }
1319
+ })
1320
+ ]);
1321
+ }
1322
+ /**
1323
+ * The key path of the variable.
1324
+ */
1325
+ get keyPath() {
1326
+ return this._keyPath;
1327
+ }
1328
+ /**
1329
+ * Get the variable fields referenced by the expression.
1330
+ * @returns An array of referenced variable fields.
1331
+ */
1332
+ getRefFields() {
1333
+ const ref = this.scope.available.getByKeyPath(this._keyPath);
1334
+ return ref ? [ref] : [];
1335
+ }
1336
+ /**
1337
+ * The return type of the expression.
1338
+ */
1339
+ get returnType() {
1340
+ const [refNode] = this._refs || [];
1341
+ if (refNode && refNode.flags & 1 /* VariableField */) {
1342
+ return refNode.type;
1343
+ }
1344
+ return;
1345
+ }
1346
+ /**
1347
+ * Parse the business-defined path expression into a key path.
1348
+ *
1349
+ * Businesses can quickly customize their own path expressions by modifying this method.
1350
+ * @param json The path expression defined by the business.
1351
+ * @returns The key path.
1352
+ */
1353
+ parseToKeyPath(json) {
1354
+ return json.keyPath;
1355
+ }
1356
+ /**
1357
+ * Deserializes the `KeyPathExpressionJSON` to the `KeyPathExpression`.
1358
+ * @param json The `KeyPathExpressionJSON` to deserialize.
1359
+ */
1360
+ fromJSON(json) {
1361
+ const keyPath = this.parseToKeyPath(json);
1362
+ if (!(0, import_fast_equals4.shallowEqual)(keyPath, this._keyPath)) {
1363
+ this._keyPath = keyPath;
1364
+ this._rawPathJson = json;
1365
+ this.refreshRefs();
1366
+ }
1367
+ }
1368
+ /**
1369
+ * Serialize the `KeyPathExpression` to `KeyPathExpressionJSON`.
1370
+ * @returns The JSON representation of `KeyPathExpression`.
1371
+ */
1372
+ toJSON() {
1373
+ return this._rawPathJson;
1374
+ }
1375
+ };
1376
+ LegacyKeyPathExpression.kind = "KeyPathExpression" /* KeyPathExpression */;
1377
+
1378
+ // src/ast/expression/wrap-array-expression.ts
1379
+ var WrapArrayExpression = class extends BaseExpression {
1380
+ /**
1381
+ * The expression to be wrapped.
1382
+ */
1383
+ get wrapFor() {
1384
+ return this._wrapFor;
1385
+ }
1386
+ /**
1387
+ * The return type of the expression.
1388
+ */
1389
+ get returnType() {
1390
+ return this._returnType;
1391
+ }
1392
+ /**
1393
+ * Refresh the return type of the expression.
1394
+ */
1395
+ refreshReturnType() {
1396
+ const childReturnTypeJSON = this.wrapFor?.returnType?.toJSON();
1397
+ this.updateChildNodeByKey("_returnType", {
1398
+ kind: "Array" /* Array */,
1399
+ items: childReturnTypeJSON
1400
+ });
1401
+ }
1402
+ /**
1403
+ * Get the variable fields referenced by the expression.
1404
+ * @returns An empty array, as this expression does not reference any variables.
1405
+ */
1406
+ getRefFields() {
1407
+ return [];
1408
+ }
1409
+ /**
1410
+ * Deserializes the `WrapArrayExpressionJSON` to the `WrapArrayExpression`.
1411
+ * @param json The `WrapArrayExpressionJSON` to deserialize.
1412
+ */
1413
+ fromJSON({ wrapFor: expression }) {
1414
+ this.updateChildNodeByKey("_wrapFor", expression);
1415
+ }
1416
+ /**
1417
+ * Serialize the `WrapArrayExpression` to `WrapArrayExpressionJSON`.
1418
+ * @returns The JSON representation of `WrapArrayExpression`.
1419
+ */
1004
1420
  toJSON() {
1005
1421
  return {
1006
- kind: "KeyPathExpression" /* KeyPathExpression */,
1007
- keyPath: this._keyPath
1422
+ kind: "WrapArrayExpression" /* WrapArrayExpression */,
1423
+ wrapFor: this.wrapFor?.toJSON()
1008
1424
  };
1009
1425
  }
1426
+ init() {
1427
+ this.refreshReturnType = this.refreshReturnType.bind(this);
1428
+ this.toDispose.push(
1429
+ this.subscribe(this.refreshReturnType, {
1430
+ selector: (curr) => curr.wrapFor?.returnType,
1431
+ triggerOnInit: true
1432
+ })
1433
+ );
1434
+ }
1010
1435
  };
1011
- KeyPathExpressionV2.kind = "KeyPathExpression" /* KeyPathExpression */;
1012
-
1013
- // src/ast/declaration/variable-declaration.ts
1014
- var import_utils4 = require("@flowgram.ai/utils");
1436
+ WrapArrayExpression.kind = "WrapArrayExpression" /* WrapArrayExpression */;
1437
+ __decorateClass([
1438
+ postConstructAST()
1439
+ ], WrapArrayExpression.prototype, "init", 1);
1015
1440
 
1016
1441
  // src/ast/declaration/base-variable-field.ts
1017
1442
  var import_fast_equals5 = require("fast-equals");
@@ -1022,35 +1447,73 @@ var BaseVariableField = class extends ASTNode {
1022
1447
  this._meta = {};
1023
1448
  }
1024
1449
  /**
1025
- * 父变量字段,通过由近而远的方式进行排序
1450
+ * Parent variable fields, sorted from closest to farthest
1026
1451
  */
1027
1452
  get parentFields() {
1028
1453
  return getParentFields(this);
1029
1454
  }
1455
+ /**
1456
+ * KeyPath of the variable field, sorted from farthest to closest
1457
+ */
1458
+ get keyPath() {
1459
+ return [...this.parentFields.reverse().map((_field) => _field.key), this.key];
1460
+ }
1461
+ /**
1462
+ * Metadata of the variable field, you cans store information like `title`, `icon`, etc.
1463
+ */
1030
1464
  get meta() {
1031
1465
  return this._meta;
1032
1466
  }
1467
+ /**
1468
+ * Type of the variable field, similar to js code:
1469
+ * `const v: string`
1470
+ */
1033
1471
  get type() {
1034
1472
  return this._initializer?.returnType || this._type;
1035
1473
  }
1474
+ /**
1475
+ * Initializer of the variable field, similar to js code:
1476
+ * `const v = 'hello'`
1477
+ *
1478
+ * with initializer, the type of field will be inferred from the initializer.
1479
+ */
1036
1480
  get initializer() {
1037
1481
  return this._initializer;
1038
1482
  }
1039
1483
  /**
1040
- * 解析 VariableDeclarationJSON 从而生成变量声明节点
1484
+ * The global unique hash of the field, and will be changed when the field is updated.
1485
+ */
1486
+ get hash() {
1487
+ return `[${this._version}]${this.keyPath.join(".")}`;
1488
+ }
1489
+ /**
1490
+ * Deserialize the `BaseVariableFieldJSON` to the `BaseVariableField`.
1491
+ * @param json ASTJSON representation of `BaseVariableField`
1041
1492
  */
1042
1493
  fromJSON({ type, initializer, meta }) {
1043
1494
  this.updateType(type);
1044
1495
  this.updateInitializer(initializer);
1045
1496
  this.updateMeta(meta);
1046
1497
  }
1498
+ /**
1499
+ * Update the type of the variable field
1500
+ * @param type type ASTJSON representation of Type
1501
+ */
1047
1502
  updateType(type) {
1048
1503
  const nextTypeJson = typeof type === "string" ? { kind: type } : type;
1049
1504
  this.updateChildNodeByKey("_type", nextTypeJson);
1050
1505
  }
1506
+ /**
1507
+ * Update the initializer of the variable field
1508
+ * @param nextInitializer initializer ASTJSON representation of Expression
1509
+ */
1051
1510
  updateInitializer(nextInitializer) {
1052
1511
  this.updateChildNodeByKey("_initializer", nextInitializer);
1053
1512
  }
1513
+ /**
1514
+ * Update the meta data of the variable field
1515
+ * @param nextMeta meta data of the variable field
1516
+ */
1054
1517
  updateMeta(nextMeta) {
1055
1518
  if (!(0, import_fast_equals5.shallowEqual)(nextMeta, this._meta)) {
1056
1519
  this._meta = nextMeta;
@@ -1058,7 +1521,8 @@ var BaseVariableField = class extends ASTNode {
1058
1521
  }
1059
1522
  }
1060
1523
  /**
1061
- * 根据 keyPath 去找下钻的变量字段
1524
+ * Get the variable field by keyPath, similar to js code:
1525
+ * `v.a.b`
1062
1526
  * @param keyPath
1063
1527
  * @returns
1064
1528
  */
@@ -1069,7 +1533,7 @@ var BaseVariableField = class extends ASTNode {
1069
1533
  return void 0;
1070
1534
  }
1071
1535
  /**
1072
- * 监听类型变化
1536
+ * Subscribe to type change of the variable field
1073
1537
  * @param observer
1074
1538
  * @returns
1075
1539
  */
@@ -1077,12 +1541,11 @@ var BaseVariableField = class extends ASTNode {
1077
1541
  return this.subscribe(observer, { selector: (curr) => curr.type });
1078
1542
  }
1079
1543
  /**
1080
- * 转换为 JSON
1081
- * @returns
1544
+ * Serialize the variable field to JSON
1545
+ * @returns ASTNodeJSON representation of `BaseVariableField`
1082
1546
  */
1083
1547
  toJSON() {
1084
1548
  return {
1085
- kind: this.kind,
1086
1549
  key: this.key,
1087
1550
  type: this.type?.toJSON(),
1088
1551
  initializer: this.initializer?.toJSON(),
@@ -1096,34 +1559,42 @@ var VariableDeclaration = class extends BaseVariableField {
1096
1559
  constructor(params) {
1097
1560
  super(params);
1098
1561
  this._order = 0;
1099
- this.scope.output.addVariableToTable(this);
1100
- this.toDispose.push(
1101
- import_utils4.Disposable.create(() => {
1102
- this.scope.output.setHasChanges();
1103
- this.scope.output.removeVariableFromTable(this.key);
1104
- })
1105
- );
1106
1562
  }
1563
+ /**
1564
+ * Variable sorting order, which is used to sort variables in `scope.outputs.variables`
1565
+ */
1107
1566
  get order() {
1108
1567
  return this._order;
1109
1568
  }
1110
1569
  /**
1111
- * 解析 VariableDeclarationJSON 从而生成变量声明节点
1570
+ * Deserialize the `VariableDeclarationJSON` to the `VariableDeclaration`.
1112
1571
  */
1113
1572
  fromJSON({ order, ...rest }) {
1114
1573
  this.updateOrder(order);
1115
1574
  super.fromJSON(rest);
1116
1575
  }
1576
+ /**
1577
+ * Update the sorting order of the variable declaration.
1578
+ * @param order Variable sorting order. Default is 0.
1579
+ */
1117
1580
  updateOrder(order = 0) {
1118
1581
  if (order !== this._order) {
1119
1582
  this._order = order;
1120
- this.scope.output.setHasChanges();
1583
+ this.dispatchGlobalEvent({
1584
+ type: "ReSortVariableDeclarations"
1585
+ });
1121
1586
  this.fireChange();
1122
1587
  }
1123
1588
  }
1124
- // 监听类型变化
1125
- onTypeChange(observer) {
1126
- return this.subscribe(observer, { selector: (curr) => curr.type });
1589
+ /**
1590
+ * Serialize the `VariableDeclaration` to `VariableDeclarationJSON`.
1591
+ * @returns The JSON representation of `VariableDeclaration`.
1592
+ */
1593
+ toJSON() {
1594
+ return {
1595
+ ...super.toJSON(),
1596
+ order: this.order
1597
+ };
1127
1598
  }
1128
1599
  };
1129
1600
  VariableDeclaration.kind = "VariableDeclaration" /* VariableDeclaration */;
@@ -1132,8 +1603,18 @@ VariableDeclaration.kind = "VariableDeclaration" /* VariableDeclaration */;
1132
1603
  var VariableDeclarationList = class extends ASTNode {
1133
1604
  constructor() {
1134
1605
  super(...arguments);
1606
+ /**
1607
+ * Map of variable declarations, keyed by variable name.
1608
+ */
1135
1609
  this.declarationTable = /* @__PURE__ */ new Map();
1136
1610
  }
1611
+ /**
1612
+ * Deserialize the `VariableDeclarationListJSON` to the `VariableDeclarationList`.
1613
+ * - VariableDeclarationListChangeAction will be dispatched after deserialization.
1614
+ *
1615
+ * @param declarations Variable declarations.
1616
+ * @param startOrder The starting order number for variables. Default is 0.
1617
+ */
1137
1618
  fromJSON({ declarations, startOrder }) {
1138
1619
  const removedKeys = new Set(this.declarationTable.keys());
1139
1620
  const prev = [...this.declarations || []];
@@ -1173,10 +1654,14 @@ var VariableDeclarationList = class extends ASTNode {
1173
1654
  }
1174
1655
  });
1175
1656
  }
1657
+ /**
1658
+ * Serialize the `VariableDeclarationList` to the `VariableDeclarationListJSON`.
1659
+ * @returns ASTJSON representation of `VariableDeclarationList`
1660
+ */
1176
1661
  toJSON() {
1177
1662
  return {
1178
1663
  kind: "VariableDeclarationList" /* VariableDeclarationList */,
1179
- properties: this.declarations.map((_declaration) => _declaration.toJSON())
1664
+ declarations: this.declarations.map((_declaration) => _declaration.toJSON())
1180
1665
  };
1181
1666
  }
1182
1667
  };
@@ -1190,9 +1675,16 @@ Property.kind = "Property" /* Property */;
1190
1675
  // src/ast/common/data-node.ts
1191
1676
  var import_fast_equals6 = require("fast-equals");
1192
1677
  var DataNode = class extends ASTNode {
1678
+ /**
1679
+ * The data of the node.
1680
+ */
1193
1681
  get data() {
1194
1682
  return this._data;
1195
1683
  }
1684
+ /**
1685
+ * Deserializes the `DataNodeJSON` to the `DataNode`.
1686
+ * @param json The `DataNodeJSON` to deserialize.
1687
+ */
1196
1688
  fromJSON(json) {
1197
1689
  const { kind, ...restData } = json;
1198
1690
  if (!(0, import_fast_equals6.shallowEqual)(restData, this._data)) {
@@ -1200,12 +1692,20 @@ var DataNode = class extends ASTNode {
1200
1692
  this.fireChange();
1201
1693
  }
1202
1694
  }
1695
+ /**
1696
+ * Serialize the `DataNode` to `DataNodeJSON`.
1697
+ * @returns The JSON representation of `DataNode`.
1698
+ */
1203
1699
  toJSON() {
1204
1700
  return {
1205
1701
  kind: "DataNode" /* DataNode */,
1206
1702
  ...this._data
1207
1703
  };
1208
1704
  }
1705
+ /**
1706
+ * Partially update the data of the node.
1707
+ * @param nextData The data to be updated.
1708
+ */
1209
1709
  partialUpdate(nextData) {
1210
1710
  if (!(0, import_fast_equals6.shallowEqual)(nextData, this._data)) {
1211
1711
  this._data = {
@@ -1220,9 +1720,16 @@ DataNode.kind = "DataNode" /* DataNode */;
1220
1720
 
1221
1721
  // src/ast/common/list-node.ts
1222
1722
  var ListNode = class extends ASTNode {
1723
+ /**
1724
+ * The list of nodes.
1725
+ */
1223
1726
  get list() {
1224
1727
  return this._list;
1225
1728
  }
1729
+ /**
1730
+ * Deserializes the `ListNodeJSON` to the `ListNode`.
1731
+ * @param json The `ListNodeJSON` to deserialize.
1732
+ */
1226
1733
  fromJSON({ list }) {
1227
1734
  this._list.slice(list.length).forEach((_item) => {
1228
1735
  _item.dispose();
@@ -1239,6 +1746,10 @@ var ListNode = class extends ASTNode {
1239
1746
  return prevItem;
1240
1747
  });
1241
1748
  }
1749
+ /**
1750
+ * Serialize the `ListNode` to `ListNodeJSON`.
1751
+ * @returns The JSON representation of `ListNode`.
1752
+ */
1242
1753
  toJSON() {
1243
1754
  return {
1244
1755
  kind: "ListNode" /* ListNode */,
@@ -1254,6 +1765,10 @@ var MapNode = class extends ASTNode {
1254
1765
  super(...arguments);
1255
1766
  this.map = /* @__PURE__ */ new Map();
1256
1767
  }
1768
+ /**
1769
+ * Deserializes the `MapNodeJSON` to the `MapNode`.
1770
+ * @param json The `MapNodeJSON` to deserialize.
1771
+ */
1257
1772
  fromJSON({ map: map4 }) {
1258
1773
  const removedKeys = new Set(this.map.keys());
1259
1774
  for (const [key, item] of map4 || []) {
@@ -1264,6 +1779,10 @@ var MapNode = class extends ASTNode {
1264
1779
  this.remove(removeKey);
1265
1780
  }
1266
1781
  }
1782
+ /**
1783
+ * Serialize the `MapNode` to `MapNodeJSON`.
1784
+ * @returns The JSON representation of `MapNode`.
1785
+ */
1267
1786
  toJSON() {
1268
1787
  return {
1269
1788
  kind: "MapNode" /* MapNode */,
@@ -1271,9 +1790,10 @@ var MapNode = class extends ASTNode {
1271
1790
  };
1272
1791
  }
1273
1792
  /**
1274
- * Map 中设置 ASTNode
1275
- * @param key ASTNode 的索引,
1276
- * @param json
1793
+ * Set a node in the map.
1794
+ * @param key The key of the node.
1795
+ * @param nextJSON The JSON representation of the node.
1796
+ * @returns The node instance.
1277
1797
  */
1278
1798
  set(key, nextJSON) {
1279
1799
  return this.withBatchUpdate(updateChildNodeHelper).call(this, {
@@ -1284,8 +1804,8 @@ var MapNode = class extends ASTNode {
1284
1804
  });
1285
1805
  }
1286
1806
  /**
1287
- * 移除指定 ASTNode
1288
- * @param key
1807
+ * Remove a node from the map.
1808
+ * @param key The key of the node.
1289
1809
  */
1290
1810
  remove(key) {
1291
1811
  this.get(key)?.dispose();
@@ -1293,9 +1813,9 @@ var MapNode = class extends ASTNode {
1293
1813
  this.fireChange();
1294
1814
  }
1295
1815
  /**
1296
- * 获取 ASTNode
1297
- * @param key
1298
- * @returns
1816
+ * Get a node from the map.
1817
+ * @param key The key of the node.
1818
+ * @returns The node instance if found, otherwise `undefined`.
1299
1819
  */
1300
1820
  get(key) {
1301
1821
  return this.map.get(key);
@@ -1306,9 +1826,12 @@ MapNode.kind = "MapNode" /* MapNode */;
1306
1826
  // src/ast/ast-registers.ts
1307
1827
  var ASTRegisters = class {
1308
1828
  /**
1309
- * 核心 AST 节点注册
1829
+ * Core AST node registration.
1310
1830
  */
1311
1831
  constructor() {
1832
+ /**
1833
+ * @deprecated Please use `@injectToAst(XXXService) declare xxxService: XXXService` to achieve external dependency injection.
1834
+ */
1312
1835
  this.injectors = /* @__PURE__ */ new Map();
1313
1836
  this.astMap = /* @__PURE__ */ new Map();
1314
1837
  this.registerAST(StringType);
@@ -1318,18 +1841,19 @@ var ASTRegisters = class {
1318
1841
  this.registerAST(ObjectType);
1319
1842
  this.registerAST(ArrayType);
1320
1843
  this.registerAST(MapType);
1844
+ this.registerAST(CustomType);
1321
1845
  this.registerAST(Property);
1322
1846
  this.registerAST(VariableDeclaration);
1323
1847
  this.registerAST(VariableDeclarationList);
1324
1848
  this.registerAST(KeyPathExpression);
1325
1849
  this.registerAST(EnumerateExpression);
1326
- this.registerAST(ExpressionList);
1850
+ this.registerAST(WrapArrayExpression);
1327
1851
  this.registerAST(MapNode);
1328
1852
  this.registerAST(DataNode);
1329
1853
  }
1330
1854
  /**
1331
- * 创建 AST 节点
1332
- * @param param 创建参数
1855
+ * Creates an AST node.
1856
+ * @param param Creation parameters.
1333
1857
  * @returns
1334
1858
  */
1335
1859
  createAST(json, { parent, scope }) {
@@ -1347,8 +1871,9 @@ var ASTRegisters = class {
1347
1871
  injector?.() || {}
1348
1872
  );
1349
1873
  node.changeLocked = true;
1350
- node.fromJSON((0, import_lodash3.omit)(json, ["key", "kind"]));
1874
+ node.fromJSON((0, import_lodash_es4.omit)(json, ["key", "kind"]));
1351
1875
  node.changeLocked = false;
1876
+ node.dispatchGlobalEvent({ type: "NewAST" });
1352
1877
  if (Reflect.hasMetadata(POST_CONSTRUCT_AST_SYMBOL, node)) {
1353
1878
  const postConstructKey = Reflect.getMetadata(POST_CONSTRUCT_AST_SYMBOL, node);
1354
1879
  node[postConstructKey]?.();
@@ -1356,7 +1881,7 @@ var ASTRegisters = class {
1356
1881
  return node;
1357
1882
  }
1358
1883
  /**
1359
- * 根据 AST 节点类型获取节点 Registry
1884
+ * Gets the node Registry by AST node type.
1360
1885
  * @param kind
1361
1886
  * @returns
1362
1887
  */
@@ -1364,9 +1889,8 @@ var ASTRegisters = class {
1364
1889
  return this.astMap.get(kind);
1365
1890
  }
1366
1891
  /**
1367
- * 注册 AST 节点
1892
+ * Registers an AST node.
1368
1893
  * @param ASTNode
1369
- * @param injector
1370
1894
  */
1371
1895
  registerAST(ASTNode2, injector) {
1372
1896
  this.astMap.set(ASTNode2.kind, ASTNode2);
@@ -1376,13 +1900,16 @@ var ASTRegisters = class {
1376
1900
  }
1377
1901
  };
1378
1902
  ASTRegisters = __decorateClass([
1379
- (0, import_inversify2.injectable)()
1903
+ (0, import_inversify3.injectable)()
1380
1904
  ], ASTRegisters);
1381
1905
 
1382
1906
  // src/ast/factory.ts
1383
1907
  var ASTFactory;
1384
1908
  ((ASTFactory2) => {
1385
- ASTFactory2.createString = () => ({ kind: "String" /* String */ });
1909
+ ASTFactory2.createString = (json) => ({
1910
+ kind: "String" /* String */,
1911
+ ...json || {}
1912
+ });
1386
1913
  ASTFactory2.createNumber = () => ({ kind: "Number" /* Number */ });
1387
1914
  ASTFactory2.createBoolean = () => ({ kind: "Boolean" /* Boolean */ });
1388
1915
  ASTFactory2.createInteger = () => ({ kind: "Integer" /* Integer */ });
@@ -1402,6 +1929,10 @@ var ASTFactory;
1402
1929
  kind: "Union" /* Union */,
1403
1930
  ...json
1404
1931
  });
1932
+ ASTFactory2.createCustomType = (json) => ({
1933
+ kind: "CustomType" /* CustomType */,
1934
+ ...json
1935
+ });
1405
1936
  ASTFactory2.createVariableDeclaration = (json) => ({
1406
1937
  kind: "VariableDeclaration" /* VariableDeclaration */,
1407
1938
  ...json
@@ -1422,115 +1953,13 @@ var ASTFactory;
1422
1953
  kind: "KeyPathExpression" /* KeyPathExpression */,
1423
1954
  ...json
1424
1955
  });
1956
+ ASTFactory2.createWrapArrayExpression = (json) => ({
1957
+ kind: "WrapArrayExpression" /* WrapArrayExpression */,
1958
+ ...json
1959
+ });
1960
+ ASTFactory2.create = (targetType, json) => ({ kind: targetType.kind, ...json });
1425
1961
  })(ASTFactory || (ASTFactory = {}));
1426
1962
 
1427
- // src/scope/variable-table.ts
1428
- var import_rxjs3 = require("rxjs");
1429
- var import_utils5 = require("@flowgram.ai/utils");
1430
- var import_utils6 = require("@flowgram.ai/utils");
1431
- var VariableTable = class {
1432
- constructor(parentTable) {
1433
- this.parentTable = parentTable;
1434
- this.table = /* @__PURE__ */ new Map();
1435
- this.onDataChangeEmitter = new import_utils5.Emitter();
1436
- this.variables$ = new import_rxjs3.Subject();
1437
- // 监听变量列表中的单个变量变化
1438
- this.anyVariableChange$ = this.variables$.pipe(
1439
- (0, import_rxjs3.switchMap)(
1440
- (_variables) => (0, import_rxjs3.merge)(
1441
- ..._variables.map(
1442
- (_v) => _v.value$.pipe(
1443
- // 跳过 BehaviorSubject 第一个
1444
- (0, import_rxjs3.skip)(1)
1445
- )
1446
- )
1447
- )
1448
- ),
1449
- (0, import_rxjs3.share)()
1450
- );
1451
- this.onDataChange = this.onDataChangeEmitter.event;
1452
- this._version = 0;
1453
- }
1454
- /**
1455
- * 监听任意变量变化
1456
- * @param observer 监听器,变量变化时会吐出值
1457
- * @returns
1458
- */
1459
- onAnyVariableChange(observer) {
1460
- return subsToDisposable(this.anyVariableChange$.subscribe(observer));
1461
- }
1462
- /**
1463
- * 列表或者任意变量变化
1464
- * @param observer
1465
- */
1466
- onAnyChange(observer) {
1467
- const disposables = new import_utils6.DisposableCollection();
1468
- disposables.pushAll([this.onDataChange(observer), this.onAnyVariableChange(observer)]);
1469
- return disposables;
1470
- }
1471
- fireChange() {
1472
- this._version++;
1473
- this.onDataChangeEmitter.fire();
1474
- this.parentTable?.fireChange();
1475
- }
1476
- get version() {
1477
- return this._version;
1478
- }
1479
- get variables() {
1480
- return Array.from(this.table.values());
1481
- }
1482
- get variableKeys() {
1483
- return Array.from(this.table.keys());
1484
- }
1485
- /**
1486
- * 根据 keyPath 找到对应的变量,或 Property 节点
1487
- * @param keyPath
1488
- * @returns
1489
- */
1490
- getByKeyPath(keyPath) {
1491
- const [variableKey, ...propertyKeys] = keyPath || [];
1492
- if (!variableKey) {
1493
- return;
1494
- }
1495
- const variable = this.getVariableByKey(variableKey);
1496
- return propertyKeys.length ? variable?.getByKeyPath(propertyKeys) : variable;
1497
- }
1498
- /**
1499
- * 根据 key 值找到相应的变量
1500
- * @param key
1501
- * @returns
1502
- */
1503
- getVariableByKey(key) {
1504
- return this.table.get(key);
1505
- }
1506
- /**
1507
- * 往 variableTable 添加输出变量
1508
- * @param variable
1509
- */
1510
- addVariableToTable(variable) {
1511
- this.table.set(variable.key, variable);
1512
- if (this.parentTable) {
1513
- this.parentTable.addVariableToTable(variable);
1514
- }
1515
- this.variables$.next(this.variables);
1516
- }
1517
- /**
1518
- * 从 variableTable 中移除变量
1519
- * @param key
1520
- */
1521
- removeVariableFromTable(key) {
1522
- this.table.delete(key);
1523
- if (this.parentTable) {
1524
- this.parentTable.removeVariableFromTable(key);
1525
- }
1526
- this.variables$.next(this.variables);
1527
- }
1528
- dispose() {
1529
- this.variableKeys.forEach((_key) => this.parentTable?.removeVariableFromTable(_key));
1530
- this.onDataChangeEmitter.dispose();
1531
- }
1532
- };
1533
-
1534
1963
  // src/scope/datas/scope-output-data.ts
1535
1964
  var ScopeOutputData = class {
1536
1965
  constructor(scope) {
@@ -1539,7 +1968,7 @@ var ScopeOutputData = class {
1539
1968
  this._hasChanges = false;
1540
1969
  this.variableTable = new VariableTable(scope.variableEngine.globalVariableTable);
1541
1970
  this.scope.toDispose.pushAll([
1542
- // AST 根节点更新时,检查在这次 AST 变化期间节点是否有变化
1971
+ // When the root AST node is updated, check if there are any changes.
1543
1972
  this.scope.ast.subscribe(() => {
1544
1973
  if (this._hasChanges) {
1545
1974
  this.memo.clear();
@@ -1548,23 +1977,66 @@ var ScopeOutputData = class {
1548
1977
  this._hasChanges = false;
1549
1978
  }
1550
1979
  }),
1980
+ this.scope.event.on("DisposeAST", (_action) => {
1981
+ if (_action.ast?.kind === "VariableDeclaration" /* VariableDeclaration */) {
1982
+ this.removeVariableFromTable(_action.ast.key);
1983
+ }
1984
+ }),
1985
+ this.scope.event.on("NewAST", (_action) => {
1986
+ if (_action.ast?.kind === "VariableDeclaration" /* VariableDeclaration */) {
1987
+ this.addVariableToTable(_action.ast);
1988
+ }
1989
+ }),
1990
+ this.scope.event.on("ReSortVariableDeclarations", () => {
1991
+ this._hasChanges = true;
1992
+ }),
1551
1993
  this.variableTable
1552
1994
  ]);
1553
1995
  }
1996
+ /**
1997
+ * The variable engine instance.
1998
+ */
1554
1999
  get variableEngine() {
1555
2000
  return this.scope.variableEngine;
1556
2001
  }
2002
+ /**
2003
+ * The global variable table from the variable engine.
2004
+ */
1557
2005
  get globalVariableTable() {
1558
2006
  return this.scope.variableEngine.globalVariableTable;
1559
2007
  }
2008
+ /**
2009
+ * The current version of the output data, which increments on each change.
2010
+ */
2011
+ get version() {
2012
+ return this.variableTable.version;
2013
+ }
2014
+ /**
2015
+ * @deprecated use onListOrAnyVarChange instead
2016
+ */
1560
2017
  get onDataChange() {
1561
2018
  return this.variableTable.onDataChange.bind(this.variableTable);
1562
2019
  }
2020
+ /**
2021
+ * An event that fires when the list of output variables changes.
2022
+ */
2023
+ get onVariableListChange() {
2024
+ return this.variableTable.onVariableListChange.bind(this.variableTable);
2025
+ }
2026
+ /**
2027
+ * An event that fires when any output variable's value changes.
2028
+ */
1563
2029
  get onAnyVariableChange() {
1564
2030
  return this.variableTable.onAnyVariableChange.bind(this.variableTable);
1565
2031
  }
1566
2032
  /**
1567
- * 作用域输出变量
2033
+ * An event that fires when the output variable list changes or any variable's value is updated.
2034
+ */
2035
+ get onListOrAnyVarChange() {
2036
+ return this.variableTable.onListOrAnyVarChange.bind(this.variableTable);
2037
+ }
2038
+ /**
2039
+ * The output variable declarations of the scope, sorted by order.
1568
2040
  */
1569
2041
  get variables() {
1570
2042
  return this.memo(
@@ -1573,7 +2045,7 @@ var ScopeOutputData = class {
1573
2045
  );
1574
2046
  }
1575
2047
  /**
1576
- * 输出的变量 keys
2048
+ * The keys of the output variables.
1577
2049
  */
1578
2050
  get variableKeys() {
1579
2051
  return this.memo("variableKeys", () => this.variableTable.variableKeys);
@@ -1585,83 +2057,119 @@ var ScopeOutputData = class {
1585
2057
  this.variableTable.addVariableToTable(variable);
1586
2058
  this._hasChanges = true;
1587
2059
  }
1588
- // 标记为发生了变化,用于变量排序变化的场景
1589
- setHasChanges() {
1590
- this._hasChanges = true;
1591
- }
1592
2060
  removeVariableFromTable(key) {
1593
2061
  this.variableTable.removeVariableFromTable(key);
1594
2062
  this._hasChanges = true;
1595
2063
  }
2064
+ /**
2065
+ * Retrieves a variable declaration by its key.
2066
+ * @param key The key of the variable.
2067
+ * @returns The `VariableDeclaration` or `undefined` if not found.
2068
+ */
1596
2069
  getVariableByKey(key) {
1597
2070
  return this.variableTable.getVariableByKey(key);
1598
2071
  }
1599
- // 通知覆盖作用域更新可用变量
2072
+ /**
2073
+ * Notifies the covering scopes that the available variables have changed.
2074
+ */
1600
2075
  notifyCoversChange() {
1601
2076
  this.scope.coverScopes.forEach((scope) => scope.available.refresh());
1602
2077
  }
1603
2078
  };
1604
2079
 
1605
2080
  // src/scope/datas/scope-available-data.ts
1606
- var import_rxjs4 = require("rxjs");
1607
- var import_lodash4 = require("lodash");
2081
+ var import_rxjs5 = require("rxjs");
2082
+ var import_lodash_es5 = require("lodash-es");
1608
2083
  var import_fast_equals7 = require("fast-equals");
1609
- var import_utils7 = require("@flowgram.ai/utils");
1610
- var import_utils8 = require("@flowgram.ai/utils");
2084
+ var import_utils5 = require("@flowgram.ai/utils");
2085
+ var import_utils6 = require("@flowgram.ai/utils");
1611
2086
  var ScopeAvailableData = class {
1612
2087
  constructor(scope) {
1613
2088
  this.scope = scope;
1614
2089
  this.memo = createMemo();
1615
- this.refresh$ = new import_rxjs4.Subject();
2090
+ this._version = 0;
2091
+ this.refresh$ = new import_rxjs5.Subject();
1616
2092
  this._variables = [];
1617
2093
  /**
1618
- * 监听
2094
+ * An observable that emits when the list of available variables changes.
1619
2095
  */
1620
2096
  this.variables$ = this.refresh$.pipe(
1621
- // 输出变量是否 version 发生变化
1622
- (0, import_rxjs4.map)(() => (0, import_lodash4.flatten)(this.depScopes.map((scope) => scope.output.variables || []))),
1623
- // 变量列表浅比较
1624
- (0, import_rxjs4.distinctUntilChanged)(import_fast_equals7.shallowEqual),
1625
- (0, import_rxjs4.share)()
2097
+ // Map to the flattened list of variables from all dependency scopes.
2098
+ (0, import_rxjs5.map)(() => (0, import_lodash_es5.flatten)(this.depScopes.map((scope) => scope.output.variables || []))),
2099
+ // Use shallow equality to check if the variable list has changed.
2100
+ (0, import_rxjs5.distinctUntilChanged)(import_fast_equals7.shallowEqual),
2101
+ (0, import_rxjs5.share)()
1626
2102
  );
1627
- // 监听变量列表中的单个变量变化
2103
+ /**
2104
+ * An observable that emits when any variable in the available list changes its value.
2105
+ */
1628
2106
  this.anyVariableChange$ = this.variables$.pipe(
1629
- (0, import_rxjs4.switchMap)(
1630
- (_variables) => (0, import_rxjs4.merge)(
2107
+ (0, import_rxjs5.switchMap)(
2108
+ (_variables) => (0, import_rxjs5.merge)(
1631
2109
  ..._variables.map(
1632
2110
  (_v) => _v.value$.pipe(
1633
- // 跳过 BehaviorSubject 第一个
1634
- (0, import_rxjs4.skip)(1)
2111
+ // Skip the initial value of the BehaviorSubject.
2112
+ (0, import_rxjs5.skip)(1)
1635
2113
  )
1636
2114
  )
1637
2115
  )
1638
2116
  ),
1639
- (0, import_rxjs4.share)()
2117
+ (0, import_rxjs5.share)()
1640
2118
  );
1641
- this.onDataChangeEmitter = new import_utils8.Emitter();
1642
2119
  /**
1643
- * 监听变量列表变化 + 任意子变量变化
2120
+ * @deprecated
2121
+ */
2122
+ this.onDataChangeEmitter = new import_utils6.Emitter();
2123
+ this.onListOrAnyVarChangeEmitter = new import_utils6.Emitter();
2124
+ /**
2125
+ * @deprecated use available.onListOrAnyVarChange instead
1644
2126
  */
1645
2127
  this.onDataChange = this.onDataChangeEmitter.event;
2128
+ /**
2129
+ * An event that fires when the variable list changes or any variable's value is updated.
2130
+ */
2131
+ this.onListOrAnyVarChange = this.onListOrAnyVarChangeEmitter.event;
1646
2132
  this.scope.toDispose.pushAll([
1647
2133
  this.onVariableListChange((_variables) => {
1648
2134
  this._variables = _variables;
1649
2135
  this.memo.clear();
1650
2136
  this.onDataChangeEmitter.fire(this._variables);
2137
+ this.bumpVersion();
2138
+ this.onListOrAnyVarChangeEmitter.fire(this._variables);
1651
2139
  }),
1652
2140
  this.onAnyVariableChange(() => {
1653
2141
  this.onDataChangeEmitter.fire(this._variables);
2142
+ this.bumpVersion();
2143
+ this.onListOrAnyVarChangeEmitter.fire(this._variables);
1654
2144
  }),
1655
- import_utils7.Disposable.create(() => {
2145
+ import_utils5.Disposable.create(() => {
1656
2146
  this.refresh$.complete();
1657
2147
  this.refresh$.unsubscribe();
1658
2148
  })
1659
2149
  ]);
1660
2150
  }
2151
+ /**
2152
+ * The global variable table from the variable engine.
2153
+ */
1661
2154
  get globalVariableTable() {
1662
2155
  return this.scope.variableEngine.globalVariableTable;
1663
2156
  }
1664
- // 刷新可访问变量列表
2157
+ /**
2158
+ * The current version of the available data, which increments on each change.
2159
+ */
2160
+ get version() {
2161
+ return this._version;
2162
+ }
2163
+ bumpVersion() {
2164
+ this._version = this._version + 1;
2165
+ if (this._version === Number.MAX_SAFE_INTEGER) {
2166
+ this._version = 0;
2167
+ }
2168
+ }
2169
+ /**
2170
+ * Refreshes the list of available variables.
2171
+ * This should be called when the dependencies of the scope change.
2172
+ */
1665
2173
  refresh() {
1666
2174
  if (this.scope.disposed) {
1667
2175
  return;
@@ -1669,43 +2177,43 @@ var ScopeAvailableData = class {
1669
2177
  this.refresh$.next();
1670
2178
  }
1671
2179
  /**
1672
- * 监听任意变量变化
1673
- * @param observer 监听器,变量变化时会吐出值
1674
- * @returns
2180
+ * Subscribes to changes in any variable's value in the available list.
2181
+ * @param observer A function to be called with the changed variable.
2182
+ * @returns A disposable to unsubscribe from the changes.
1675
2183
  */
1676
2184
  onAnyVariableChange(observer) {
1677
2185
  return subsToDisposable(this.anyVariableChange$.subscribe(observer));
1678
2186
  }
1679
2187
  /**
1680
- * 监听变量列表变化
1681
- * @param observer
1682
- * @returns
2188
+ * Subscribes to changes in the list of available variables.
2189
+ * @param observer A function to be called with the new list of variables.
2190
+ * @returns A disposable to unsubscribe from the changes.
1683
2191
  */
1684
2192
  onVariableListChange(observer) {
1685
2193
  return subsToDisposable(this.variables$.subscribe(observer));
1686
2194
  }
1687
2195
  /**
1688
- * 获取可消费变量
2196
+ * Gets the list of available variables.
1689
2197
  */
1690
2198
  get variables() {
1691
2199
  return this._variables;
1692
2200
  }
1693
2201
  /**
1694
- * 获取可访问的变量 keys
2202
+ * Gets the keys of the available variables.
1695
2203
  */
1696
2204
  get variableKeys() {
1697
2205
  return this.memo("availableKeys", () => this._variables.map((_v) => _v.key));
1698
2206
  }
1699
2207
  /**
1700
- * 返回依赖的作用域
2208
+ * Gets the dependency scopes.
1701
2209
  */
1702
2210
  get depScopes() {
1703
2211
  return this.scope.depScopes;
1704
2212
  }
1705
2213
  /**
1706
- * 通过 keyPath 找到可用变量
1707
- * @param keyPath
1708
- * @returns
2214
+ * Retrieves a variable field by its key path from the available variables.
2215
+ * @param keyPath The key path to the variable field.
2216
+ * @returns The found `BaseVariableField` or `undefined`.
1709
2217
  */
1710
2218
  getByKeyPath(keyPath = []) {
1711
2219
  if (!this.variableKeys.includes(keyPath[0])) {
@@ -1713,32 +2221,78 @@ var ScopeAvailableData = class {
1713
2221
  }
1714
2222
  return this.globalVariableTable.getByKeyPath(keyPath);
1715
2223
  }
2224
+ /**
2225
+ * Tracks changes to a variable field by its key path.
2226
+ * This includes changes to its type, value, or any nested properties.
2227
+ * @param keyPath The key path to the variable field to track.
2228
+ * @param cb The callback to execute when the variable changes.
2229
+ * @param opts Configuration options for the subscription.
2230
+ * @returns A disposable to unsubscribe from the tracking.
2231
+ */
2232
+ trackByKeyPath(keyPath = [], cb, opts) {
2233
+ const { triggerOnInit = true, debounceAnimation, selector } = opts || {};
2234
+ return subsToDisposable(
2235
+ (0, import_rxjs5.merge)(this.anyVariableChange$, this.variables$).pipe(
2236
+ triggerOnInit ? (0, import_rxjs5.startWith)() : (0, import_rxjs5.tap)(() => null),
2237
+ (0, import_rxjs5.map)(() => {
2238
+ const v = this.getByKeyPath(keyPath);
2239
+ return selector ? selector(v) : v;
2240
+ }),
2241
+ (0, import_rxjs5.distinctUntilChanged)(
2242
+ (a, b) => (0, import_fast_equals7.shallowEqual)(a, b),
2243
+ (value) => {
2244
+ if (value instanceof ASTNode) {
2245
+ return value.hash;
2246
+ }
2247
+ return value;
2248
+ }
2249
+ ),
2250
+ // Debounce updates to a single emission per animation frame.
2251
+ debounceAnimation ? (0, import_rxjs5.debounceTime)(0, import_rxjs5.animationFrameScheduler) : (0, import_rxjs5.tap)(() => null)
2252
+ ).subscribe(cb)
2253
+ );
2254
+ }
1716
2255
  };
1717
2256
 
1718
2257
  // src/scope/datas/scope-event-data.ts
1719
- var import_rxjs5 = require("rxjs");
2258
+ var import_rxjs6 = require("rxjs");
1720
2259
  var ScopeEventData = class {
1721
2260
  constructor(scope) {
1722
2261
  this.scope = scope;
1723
- this.event$ = new import_rxjs5.Subject();
2262
+ this.event$ = new import_rxjs6.Subject();
1724
2263
  scope.toDispose.pushAll([
1725
2264
  this.subscribe((_action) => {
1726
2265
  scope.variableEngine.fireGlobalEvent(_action);
1727
2266
  })
1728
2267
  ]);
1729
2268
  }
2269
+ /**
2270
+ * Dispatches a global event.
2271
+ * @param action The event action to dispatch.
2272
+ */
1730
2273
  dispatch(action) {
1731
2274
  if (this.scope.disposed) {
1732
2275
  return;
1733
2276
  }
1734
2277
  this.event$.next(action);
1735
2278
  }
2279
+ /**
2280
+ * Subscribes to all global events.
2281
+ * @param observer The observer function to call with the event action.
2282
+ * @returns A disposable to unsubscribe from the events.
2283
+ */
1736
2284
  subscribe(observer) {
1737
2285
  return subsToDisposable(this.event$.subscribe(observer));
1738
2286
  }
2287
+ /**
2288
+ * Subscribes to a specific type of global event.
2289
+ * @param type The type of the event to subscribe to.
2290
+ * @param observer The observer function to call with the event action.
2291
+ * @returns A disposable to unsubscribe from the event.
2292
+ */
1739
2293
  on(type, observer) {
1740
2294
  return subsToDisposable(
1741
- this.event$.pipe((0, import_rxjs5.filter)((_action) => _action.type === type)).subscribe(observer)
2295
+ this.event$.pipe((0, import_rxjs6.filter)((_action) => _action.type === type)).subscribe(observer)
1742
2296
  );
1743
2297
  }
1744
2298
  };
@@ -1747,10 +2301,10 @@ var ScopeEventData = class {
1747
2301
  var Scope = class {
1748
2302
  constructor(options) {
1749
2303
  /**
1750
- * 数据缓存
2304
+ * A memoization utility for caching computed values.
1751
2305
  */
1752
2306
  this.memo = createMemo();
1753
- this.toDispose = new import_utils9.DisposableCollection();
2307
+ this.toDispose = new import_utils7.DisposableCollection();
1754
2308
  this.onDispose = this.toDispose.onDispose;
1755
2309
  this.id = options.id;
1756
2310
  this.meta = options.meta || {};
@@ -1759,7 +2313,7 @@ var Scope = class {
1759
2313
  this.ast = this.variableEngine.astRegisters.createAST(
1760
2314
  {
1761
2315
  kind: "MapNode" /* MapNode */,
1762
- key: this.id
2316
+ key: String(this.id)
1763
2317
  },
1764
2318
  {
1765
2319
  scope: this
@@ -1768,25 +2322,41 @@ var Scope = class {
1768
2322
  this.output = new ScopeOutputData(this);
1769
2323
  this.available = new ScopeAvailableData(this);
1770
2324
  }
2325
+ /**
2326
+ * Refreshes the covering scopes.
2327
+ */
1771
2328
  refreshCovers() {
1772
2329
  this.memo.clear("covers");
1773
2330
  }
2331
+ /**
2332
+ * Refreshes the dependency scopes and the available variables.
2333
+ */
1774
2334
  refreshDeps() {
1775
2335
  this.memo.clear("deps");
1776
2336
  this.available.refresh();
1777
2337
  }
2338
+ /**
2339
+ * Gets the scopes that this scope depends on.
2340
+ */
1778
2341
  get depScopes() {
1779
2342
  return this.memo(
1780
2343
  "deps",
1781
2344
  () => this.variableEngine.chain.getDeps(this).filter((_scope) => Boolean(_scope) && !_scope?.disposed)
1782
2345
  );
1783
2346
  }
2347
+ /**
2348
+ * Gets the scopes that are covered by this scope.
2349
+ */
1784
2350
  get coverScopes() {
1785
2351
  return this.memo(
1786
2352
  "covers",
1787
2353
  () => this.variableEngine.chain.getCovers(this).filter((_scope) => Boolean(_scope) && !_scope?.disposed)
1788
2354
  );
1789
2355
  }
2356
+ /**
2357
+ * Disposes of the scope and its resources.
2358
+ * This will also trigger updates in dependent and covering scopes.
2359
+ */
1790
2360
  dispose() {
1791
2361
  this.ast.dispose();
1792
2362
  this.toDispose.dispose();
@@ -1796,6 +2366,32 @@ var Scope = class {
1796
2366
  get disposed() {
1797
2367
  return this.toDispose.disposed;
1798
2368
  }
2369
+ setVar(arg1, arg2) {
2370
+ if (typeof arg1 === "string" && arg2 !== void 0) {
2371
+ return this.ast.set(arg1, arg2);
2372
+ }
2373
+ if (typeof arg1 === "object" && arg2 === void 0) {
2374
+ return this.ast.set("outputs", arg1);
2375
+ }
2376
+ throw new Error("Invalid arguments");
2377
+ }
2378
+ /**
2379
+ * Retrieves a variable from the scope by its key.
2380
+ *
2381
+ * @param key The key of the variable to retrieve. Defaults to 'outputs'.
2382
+ * @returns The AST node for the variable, or `undefined` if not found.
2383
+ */
2384
+ getVar(key = "outputs") {
2385
+ return this.ast.get(key);
2386
+ }
2387
+ /**
2388
+ * Clears a variable from the scope by its key.
2389
+ *
2390
+ * @param key The key of the variable to clear. Defaults to 'outputs'.
2391
+ */
2392
+ clearVar(key = "outputs") {
2393
+ return this.ast.remove(key);
2394
+ }
1799
2395
  };
1800
2396
 
1801
2397
  // src/variable-engine.ts
@@ -1803,47 +2399,74 @@ var VariableEngine = class {
1803
2399
  constructor(chain, astRegisters) {
1804
2400
  this.chain = chain;
1805
2401
  this.astRegisters = astRegisters;
1806
- this.toDispose = new import_utils10.DisposableCollection();
2402
+ this.toDispose = new import_utils8.DisposableCollection();
1807
2403
  this.memo = createMemo();
1808
2404
  this.scopeMap = /* @__PURE__ */ new Map();
1809
- this.globalEvent$ = new import_rxjs6.Subject();
1810
- this.onScopeChangeEmitter = new import_utils11.Emitter();
2405
+ /**
2406
+ * A rxjs subject that emits global events occurring within the variable engine.
2407
+ */
2408
+ this.globalEvent$ = new import_rxjs7.Subject();
2409
+ this.onScopeChangeEmitter = new import_utils9.Emitter();
2410
+ /**
2411
+ * A table containing all global variables.
2412
+ */
1811
2413
  this.globalVariableTable = new VariableTable();
2414
+ /**
2415
+ * An event that fires whenever a scope is added, updated, or deleted.
2416
+ */
1812
2417
  this.onScopeChange = this.onScopeChangeEmitter.event;
1813
2418
  this.toDispose.pushAll([
1814
2419
  chain,
1815
- import_utils10.Disposable.create(() => {
2420
+ import_utils8.Disposable.create(() => {
1816
2421
  this.getAllScopes().forEach((scope) => scope.dispose());
1817
2422
  this.globalVariableTable.dispose();
1818
2423
  })
1819
2424
  ]);
1820
2425
  }
2426
+ /**
2427
+ * The Inversify container instance.
2428
+ */
1821
2429
  get container() {
1822
2430
  return this.containerProvider();
1823
2431
  }
1824
2432
  dispose() {
1825
2433
  this.toDispose.dispose();
1826
2434
  }
1827
- // 根据 scopeId 找到作用域
2435
+ /**
2436
+ * Retrieves a scope by its unique identifier.
2437
+ * @param scopeId The ID of the scope to retrieve.
2438
+ * @returns The scope if found, otherwise undefined.
2439
+ */
1828
2440
  getScopeById(scopeId) {
1829
2441
  return this.scopeMap.get(scopeId);
1830
2442
  }
1831
- // 移除作用域
2443
+ /**
2444
+ * Removes a scope by its unique identifier and disposes of it.
2445
+ * @param scopeId The ID of the scope to remove.
2446
+ */
1832
2447
  removeScopeById(scopeId) {
1833
2448
  this.getScopeById(scopeId)?.dispose();
1834
2449
  }
1835
- // 获取 Scope,如果 Scope 存在且类型相同,则会直接使用
1836
- createScope(id, meta) {
2450
+ /**
2451
+ * Creates a new scope or retrieves an existing one if the ID and type match.
2452
+ * @param id The unique identifier for the scope.
2453
+ * @param meta Optional metadata for the scope, defined by the user.
2454
+ * @param options Options for creating the scope.
2455
+ * @param options.ScopeConstructor The constructor to use for creating the scope. Defaults to `Scope`.
2456
+ * @returns The created or existing scope.
2457
+ */
2458
+ createScope(id, meta, options = {}) {
2459
+ const { ScopeConstructor = Scope } = options;
1837
2460
  let scope = this.getScopeById(id);
1838
2461
  if (!scope) {
1839
- scope = new Scope({ variableEngine: this, meta, id });
2462
+ scope = new ScopeConstructor({ variableEngine: this, meta, id });
1840
2463
  this.scopeMap.set(id, scope);
1841
2464
  this.onScopeChangeEmitter.fire({ type: "add", scope });
1842
2465
  scope.toDispose.pushAll([
1843
2466
  scope.ast.subscribe(() => {
1844
2467
  this.onScopeChangeEmitter.fire({ type: "update", scope });
1845
2468
  }),
1846
- // 可用变量发生变化
2469
+ // Fires when available variables change
1847
2470
  scope.available.onDataChange(() => {
1848
2471
  this.onScopeChangeEmitter.fire({ type: "available", scope });
1849
2472
  })
@@ -1855,7 +2478,12 @@ var VariableEngine = class {
1855
2478
  }
1856
2479
  return scope;
1857
2480
  }
1858
- // 获取系统中所有的作用域
2481
+ /**
2482
+ * Retrieves all scopes currently managed by the engine.
2483
+ * @param options Options for retrieving the scopes.
2484
+ * @param options.sort Whether to sort the scopes based on their dependency chain.
2485
+ * @returns An array of all scopes.
2486
+ */
1859
2487
  getAllScopes({
1860
2488
  sort
1861
2489
  } = {}) {
@@ -1868,9 +2496,19 @@ var VariableEngine = class {
1868
2496
  }
1869
2497
  return [...allScopes];
1870
2498
  }
2499
+ /**
2500
+ * Fires a global event to be broadcast to all listeners.
2501
+ * @param event The global event to fire.
2502
+ */
1871
2503
  fireGlobalEvent(event) {
1872
2504
  this.globalEvent$.next(event);
1873
2505
  }
2506
+ /**
2507
+ * Subscribes to a specific type of global event.
2508
+ * @param type The type of the event to listen for.
2509
+ * @param observer A function to be called when the event is observed.
2510
+ * @returns A disposable object to unsubscribe from the event.
2511
+ */
1874
2512
  onGlobalEvent(type, observer) {
1875
2513
  return subsToDisposable(
1876
2514
  this.globalEvent$.subscribe((_action) => {
@@ -1882,30 +2520,45 @@ var VariableEngine = class {
1882
2520
  }
1883
2521
  };
1884
2522
  __decorateClass([
1885
- (0, import_inversify5.inject)(ContainerProvider)
2523
+ (0, import_inversify6.inject)(ContainerProvider)
1886
2524
  ], VariableEngine.prototype, "containerProvider", 2);
1887
2525
  __decorateClass([
1888
- (0, import_inversify5.preDestroy)()
2526
+ (0, import_inversify6.preDestroy)()
1889
2527
  ], VariableEngine.prototype, "dispose", 1);
1890
2528
  VariableEngine = __decorateClass([
1891
- (0, import_inversify5.injectable)(),
1892
- __decorateParam(0, (0, import_inversify5.inject)(ScopeChain)),
1893
- __decorateParam(1, (0, import_inversify5.inject)(ASTRegisters))
2529
+ (0, import_inversify6.injectable)(),
2530
+ __decorateParam(0, (0, import_inversify6.inject)(ScopeChain)),
2531
+ __decorateParam(1, (0, import_inversify6.inject)(ASTRegisters))
1894
2532
  ], VariableEngine);
1895
2533
 
1896
2534
  // src/services/variable-field-key-rename-service.ts
1897
- var import_lodash5 = require("lodash");
1898
- var import_inversify6 = require("inversify");
1899
- var import_utils12 = require("@flowgram.ai/utils");
2535
+ var import_lodash_es6 = require("lodash-es");
2536
+ var import_inversify7 = require("inversify");
2537
+ var import_utils10 = require("@flowgram.ai/utils");
1900
2538
  var VariableFieldKeyRenameService = class {
1901
2539
  constructor() {
1902
- this.toDispose = new import_utils12.DisposableCollection();
1903
- this.renameEmitter = new import_utils12.Emitter();
1904
- // 没有被 rename 的字段通过 disposeInList 透出,让业务区分变量是 rename 删除的,还是真正从列表中删除的
1905
- this.disposeInListEmitter = new import_utils12.Emitter();
2540
+ this.toDispose = new import_utils10.DisposableCollection();
2541
+ this.renameEmitter = new import_utils10.Emitter();
2542
+ /**
2543
+ * Emits events for fields that are disposed of during a list change, but not renamed.
2544
+ * This helps distinguish between a field that was truly removed and one that was renamed.
2545
+ */
2546
+ this.disposeInListEmitter = new import_utils10.Emitter();
2547
+ /**
2548
+ * An event that fires when a variable field key is successfully renamed.
2549
+ */
1906
2550
  this.onRename = this.renameEmitter.event;
2551
+ /**
2552
+ * An event that fires when a field is removed from a list (and not part of a rename).
2553
+ */
1907
2554
  this.onDisposeInList = this.disposeInListEmitter.event;
1908
2555
  }
2556
+ /**
2557
+ * Handles changes in a list of fields to detect rename operations.
2558
+ * @param ast The AST node where the change occurred.
2559
+ * @param prev The list of fields before the change.
2560
+ * @param next The list of fields after the change.
2561
+ */
1909
2562
  handleFieldListChange(ast, prev, next) {
1910
2563
  if (!ast || !prev?.length || !next?.length) {
1911
2564
  this.notifyFieldsDispose(prev, next);
@@ -1936,8 +2589,13 @@ var VariableFieldKeyRenameService = class {
1936
2589
  }
1937
2590
  this.renameEmitter.fire(renameNodeInfo);
1938
2591
  }
2592
+ /**
2593
+ * Notifies listeners about fields that were removed from a list.
2594
+ * @param prev The list of fields before the change.
2595
+ * @param next The list of fields after the change.
2596
+ */
1939
2597
  notifyFieldsDispose(prev, next) {
1940
- const removedFields = (0, import_lodash5.difference)(prev || [], next || []);
2598
+ const removedFields = (0, import_lodash_es6.difference)(prev || [], next || []);
1941
2599
  removedFields.forEach((_field) => this.disposeInListEmitter.fire(_field));
1942
2600
  }
1943
2601
  init() {
@@ -1961,20 +2619,20 @@ var VariableFieldKeyRenameService = class {
1961
2619
  }
1962
2620
  };
1963
2621
  __decorateClass([
1964
- (0, import_inversify6.inject)(VariableEngine)
2622
+ (0, import_inversify7.inject)(VariableEngine)
1965
2623
  ], VariableFieldKeyRenameService.prototype, "variableEngine", 2);
1966
2624
  __decorateClass([
1967
- (0, import_inversify6.postConstruct)()
2625
+ (0, import_inversify7.postConstruct)()
1968
2626
  ], VariableFieldKeyRenameService.prototype, "init", 1);
1969
2627
  __decorateClass([
1970
- (0, import_inversify6.preDestroy)()
2628
+ (0, import_inversify7.preDestroy)()
1971
2629
  ], VariableFieldKeyRenameService.prototype, "dispose", 1);
1972
2630
  VariableFieldKeyRenameService = __decorateClass([
1973
- (0, import_inversify6.injectable)()
2631
+ (0, import_inversify7.injectable)()
1974
2632
  ], VariableFieldKeyRenameService);
1975
2633
 
1976
2634
  // src/variable-container-module.ts
1977
- var VariableContainerModule = new import_inversify7.ContainerModule((bind) => {
2635
+ var VariableContainerModule = new import_inversify8.ContainerModule((bind) => {
1978
2636
  bind(VariableEngine).toSelf().inSingletonScope();
1979
2637
  bind(ASTRegisters).toSelf().inSingletonScope();
1980
2638
  bind(VariableFieldKeyRenameService).toSelf().inSingletonScope();
@@ -1983,28 +2641,48 @@ var VariableContainerModule = new import_inversify7.ContainerModule((bind) => {
1983
2641
  });
1984
2642
 
1985
2643
  // src/react/context.tsx
1986
- var import_react = require("react");
2644
+ var import_react = __toESM(require("react"));
1987
2645
  var ScopeContext = (0, import_react.createContext)(null);
1988
- var ScopeProvider = ScopeContext.Provider;
1989
- var useScopeContext = () => (0, import_react.useContext)(ScopeContext);
1990
- var useCurrentScope = () => (0, import_react.useContext)(ScopeContext)?.scope;
2646
+ var ScopeProvider = (props) => {
2647
+ const { scope, value, children } = props;
2648
+ const scopeToUse = scope || value?.scope;
2649
+ if (!scopeToUse) {
2650
+ throw new Error("[ScopeProvider] scope is required");
2651
+ }
2652
+ return /* @__PURE__ */ import_react.default.createElement(ScopeContext.Provider, { value: { scope: scopeToUse } }, children);
2653
+ };
2654
+ var useCurrentScope = (params) => {
2655
+ const { strict = false } = params || {};
2656
+ const context = (0, import_react.useContext)(ScopeContext);
2657
+ if (!context) {
2658
+ if (strict) {
2659
+ throw new Error("useCurrentScope must be used within a <ScopeProvider scope={scope}>");
2660
+ }
2661
+ console.warn("useCurrentScope should be used within a <ScopeProvider scope={scope}>");
2662
+ }
2663
+ return context?.scope;
2664
+ };
1991
2665
 
1992
- // src/react/hooks/useScopeAvailable.ts
2666
+ // src/react/hooks/use-scope-available.ts
1993
2667
  var import_react2 = require("react");
1994
2668
  var import_core = require("@flowgram.ai/core");
1995
- function useScopeAvailable() {
1996
- const scope = useCurrentScope();
2669
+ function useScopeAvailable(params) {
2670
+ const { autoRefresh = true } = params || {};
2671
+ const scope = useCurrentScope({ strict: true });
1997
2672
  const refresh = (0, import_core.useRefresh)();
1998
2673
  (0, import_react2.useEffect)(() => {
1999
- const disposable = scope.available.onDataChange(() => {
2674
+ if (!autoRefresh) {
2675
+ return () => null;
2676
+ }
2677
+ const disposable = scope.available.onListOrAnyVarChange(() => {
2000
2678
  refresh();
2001
2679
  });
2002
2680
  return () => disposable.dispose();
2003
- }, []);
2681
+ }, [autoRefresh]);
2004
2682
  return scope.available;
2005
2683
  }
2006
2684
 
2007
- // src/react/hooks/useAvailableVariables.ts
2685
+ // src/react/hooks/use-available-variables.ts
2008
2686
  var import_react3 = require("react");
2009
2687
  var import_core2 = require("@flowgram.ai/core");
2010
2688
  function useAvailableVariables() {
@@ -2013,7 +2691,7 @@ function useAvailableVariables() {
2013
2691
  const refresh = (0, import_core2.useRefresh)();
2014
2692
  (0, import_react3.useEffect)(() => {
2015
2693
  if (!scope) {
2016
- const disposable2 = variableEngine.globalVariableTable.onAnyChange(() => {
2694
+ const disposable2 = variableEngine.globalVariableTable.onListOrAnyVarChange(() => {
2017
2695
  refresh();
2018
2696
  });
2019
2697
  return () => disposable2.dispose();
@@ -2025,10 +2703,31 @@ function useAvailableVariables() {
2025
2703
  }, []);
2026
2704
  return scope ? scope.available.variables : variableEngine.globalVariableTable.variables;
2027
2705
  }
2706
+
2707
+ // src/react/hooks/use-output-variables.ts
2708
+ var import_react4 = require("react");
2709
+ var import_core3 = require("@flowgram.ai/core");
2710
+ function useOutputVariables() {
2711
+ const scope = useCurrentScope();
2712
+ const refresh = (0, import_core3.useRefresh)();
2713
+ (0, import_react4.useEffect)(() => {
2714
+ if (!scope) {
2715
+ throw new Error(
2716
+ "[useOutputVariables]: No scope found, useOutputVariables must be used in <ScopeProvider>"
2717
+ );
2718
+ }
2719
+ const disposable = scope.output.onListOrAnyVarChange(() => {
2720
+ refresh();
2721
+ });
2722
+ return () => disposable.dispose();
2723
+ }, []);
2724
+ return scope?.output.variables || [];
2725
+ }
2028
2726
  // Annotate the CommonJS export names for ESM import in node:
2029
2727
  0 && (module.exports = {
2030
2728
  ASTFactory,
2031
2729
  ASTKind,
2730
+ ASTMatch,
2032
2731
  ASTNode,
2033
2732
  ASTNodeFlags,
2034
2733
  ASTRegisters,
@@ -2037,12 +2736,12 @@ function useAvailableVariables() {
2037
2736
  BaseType,
2038
2737
  BaseVariableField,
2039
2738
  BooleanType,
2739
+ CustomType,
2040
2740
  DataNode,
2041
2741
  EnumerateExpression,
2042
- ExpressionList,
2043
2742
  IntegerType,
2044
2743
  KeyPathExpression,
2045
- KeyPathExpressionV2,
2744
+ LegacyKeyPathExpression,
2046
2745
  ListNode,
2047
2746
  MapNode,
2048
2747
  MapType,
@@ -2060,13 +2759,13 @@ function useAvailableVariables() {
2060
2759
  VariableEngine,
2061
2760
  VariableEngineProvider,
2062
2761
  VariableFieldKeyRenameService,
2063
- VariableTable,
2762
+ WrapArrayExpression,
2064
2763
  injectToAST,
2065
2764
  isMatchAST,
2066
2765
  postConstructAST,
2067
2766
  useAvailableVariables,
2068
2767
  useCurrentScope,
2069
- useScopeAvailable,
2070
- useScopeContext
2768
+ useOutputVariables,
2769
+ useScopeAvailable
2071
2770
  });
2072
2771
  //# sourceMappingURL=index.js.map