@flowgram.ai/variable-core 0.5.5 → 0.5.7

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;
@@ -45,7 +55,7 @@ __export(index_exports, {
45
55
  EnumerateExpression: () => EnumerateExpression,
46
56
  IntegerType: () => IntegerType,
47
57
  KeyPathExpression: () => KeyPathExpression,
48
- KeyPathExpressionV2: () => KeyPathExpressionV2,
58
+ LegacyKeyPathExpression: () => LegacyKeyPathExpression,
49
59
  ListNode: () => ListNode,
50
60
  MapNode: () => MapNode,
51
61
  MapType: () => MapType,
@@ -69,8 +79,8 @@ __export(index_exports, {
69
79
  postConstructAST: () => postConstructAST,
70
80
  useAvailableVariables: () => useAvailableVariables,
71
81
  useCurrentScope: () => useCurrentScope,
72
- useScopeAvailable: () => useScopeAvailable,
73
- useScopeContext: () => useScopeContext
82
+ useOutputVariables: () => useOutputVariables,
83
+ useScopeAvailable: () => useScopeAvailable
74
84
  });
75
85
  module.exports = __toCommonJS(index_exports);
76
86
 
@@ -124,13 +134,15 @@ var VariableTable = class {
124
134
  */
125
135
  this.onDataChangeEmitter = new import_utils2.Emitter();
126
136
  this.variables$ = new import_rxjs.Subject();
127
- // 监听变量列表中的单个变量变化
137
+ /**
138
+ * An observable that listens for value changes on any variable within the table.
139
+ */
128
140
  this.anyVariableChange$ = this.variables$.pipe(
129
141
  (0, import_rxjs.switchMap)(
130
142
  (_variables) => (0, import_rxjs.merge)(
131
143
  ..._variables.map(
132
144
  (_v) => _v.value$.pipe(
133
- // 跳过 BehaviorSubject 第一个
145
+ // Skip the initial value of the BehaviorSubject
134
146
  (0, import_rxjs.skip)(1)
135
147
  )
136
148
  )
@@ -139,68 +151,84 @@ var VariableTable = class {
139
151
  (0, import_rxjs.share)()
140
152
  );
141
153
  /**
142
- * @deprecated use onListOrAnyVarChange instead
154
+ * @deprecated Use onListOrAnyVarChange instead.
143
155
  */
144
156
  this.onDataChange = this.onDataChangeEmitter.event;
145
157
  this._version = 0;
146
158
  this.toDispose.pushAll([
147
159
  this.onDataChangeEmitter,
148
- // active share()
160
+ // Activate the share() operator
149
161
  this.onAnyVariableChange(() => {
150
162
  this.bumpVersion();
151
163
  })
152
164
  ]);
153
165
  }
154
166
  /**
155
- * listen to any variable update in list
156
- * @param observer
157
- * @returns
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.
158
170
  */
159
171
  onAnyVariableChange(observer) {
160
172
  return subsToDisposable(this.anyVariableChange$.subscribe(observer));
161
173
  }
162
174
  /**
163
- * listen to variable list change
164
- * @param observer
165
- * @returns
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.
166
178
  */
167
179
  onVariableListChange(observer) {
168
180
  return subsToDisposable(this.variables$.subscribe(observer));
169
181
  }
170
182
  /**
171
- * listen to variable list change + any variable update in list
172
- * @param observer
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.
173
186
  */
174
187
  onListOrAnyVarChange(observer) {
175
188
  const disposables = new import_utils2.DisposableCollection();
176
189
  disposables.pushAll([this.onVariableListChange(observer), this.onAnyVariableChange(observer)]);
177
190
  return disposables;
178
191
  }
192
+ /**
193
+ * Fires change events to notify listeners that the data has been updated.
194
+ */
179
195
  fireChange() {
180
196
  this.bumpVersion();
181
197
  this.onDataChangeEmitter.fire();
182
198
  this.variables$.next(this.variables);
183
199
  this.parentTable?.fireChange();
184
200
  }
201
+ /**
202
+ * The current version of the variable table, incremented on each change.
203
+ */
185
204
  get version() {
186
205
  return this._version;
187
206
  }
207
+ /**
208
+ * Increments the version number, resetting to 0 if it reaches MAX_SAFE_INTEGER.
209
+ */
188
210
  bumpVersion() {
189
211
  this._version = this._version + 1;
190
212
  if (this._version === Number.MAX_SAFE_INTEGER) {
191
213
  this._version = 0;
192
214
  }
193
215
  }
216
+ /**
217
+ * An array of all variables in the table.
218
+ */
194
219
  get variables() {
195
220
  return Array.from(this.table.values());
196
221
  }
222
+ /**
223
+ * An array of all variable keys in the table.
224
+ */
197
225
  get variableKeys() {
198
226
  return Array.from(this.table.keys());
199
227
  }
200
228
  /**
201
- * 根据 keyPath 找到对应的变量,或 Property 节点
202
- * @param keyPath
203
- * @returns
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.
204
232
  */
205
233
  getByKeyPath(keyPath) {
206
234
  const [variableKey, ...propertyKeys] = keyPath || [];
@@ -211,16 +239,17 @@ var VariableTable = class {
211
239
  return propertyKeys.length ? variable?.getByKeyPath(propertyKeys) : variable;
212
240
  }
213
241
  /**
214
- * 根据 key 值找到相应的变量
215
- * @param key
216
- * @returns
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.
217
245
  */
218
246
  getVariableByKey(key) {
219
247
  return this.table.get(key);
220
248
  }
221
249
  /**
222
- * variableTable 添加输出变量
223
- * @param variable
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.
224
253
  */
225
254
  addVariableToTable(variable) {
226
255
  this.table.set(variable.key, variable);
@@ -229,8 +258,9 @@ var VariableTable = class {
229
258
  }
230
259
  }
231
260
  /**
232
- * variableTable 中移除变量
233
- * @param key
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.
234
264
  */
235
265
  removeVariableFromTable(key) {
236
266
  this.table.delete(key);
@@ -238,6 +268,9 @@ var VariableTable = class {
238
268
  this.parentTable.removeVariableFromTable(key);
239
269
  }
240
270
  }
271
+ /**
272
+ * Disposes of all resources used by the variable table.
273
+ */
241
274
  dispose() {
242
275
  this.variableKeys.forEach(
243
276
  (_key) => this.parentTable?.removeVariableFromTable(_key)
@@ -266,7 +299,7 @@ var ScopeChain = class {
266
299
  return this.variableEngineProvider();
267
300
  }
268
301
  /**
269
- * 所有作用域依赖关系刷新
302
+ * Refreshes the dependency and coverage relationships for all scopes.
270
303
  */
271
304
  refreshAllChange() {
272
305
  this.variableEngine.getAllScopes().forEach((_scope) => {
@@ -350,6 +383,19 @@ var postConstructAST = () => (target, propertyKey) => {
350
383
  }
351
384
  };
352
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
+
353
399
  // src/ast/match.ts
354
400
  var ASTMatch;
355
401
  ((ASTMatch2) => {
@@ -363,8 +409,10 @@ var ASTMatch;
363
409
  ASTMatch2.isCustomType = (node) => node?.kind === "CustomType" /* CustomType */;
364
410
  ASTMatch2.isVariableDeclaration = (node) => node?.kind === "VariableDeclaration" /* VariableDeclaration */;
365
411
  ASTMatch2.isProperty = (node) => node?.kind === "Property" /* Property */;
412
+ ASTMatch2.isBaseVariableField = (node) => !!(node?.flags || 0 & 1 /* VariableField */);
366
413
  ASTMatch2.isVariableDeclarationList = (node) => node?.kind === "VariableDeclarationList" /* VariableDeclarationList */;
367
414
  ASTMatch2.isEnumerateExpression = (node) => node?.kind === "EnumerateExpression" /* EnumerateExpression */;
415
+ ASTMatch2.isWrapArrayExpression = (node) => node?.kind === "WrapArrayExpression" /* WrapArrayExpression */;
368
416
  ASTMatch2.isKeyPathExpression = (node) => node?.kind === "KeyPathExpression" /* KeyPathExpression */;
369
417
  function is(node, targetType) {
370
418
  return node?.kind === targetType?.kind;
@@ -410,19 +458,6 @@ function isMatchAST(node, targetType) {
410
458
  return ASTMatch.is(node, targetType);
411
459
  }
412
460
 
413
- // src/ast/flags.ts
414
- var ASTNodeFlags = /* @__PURE__ */ ((ASTNodeFlags2) => {
415
- ASTNodeFlags2[ASTNodeFlags2["None"] = 0] = "None";
416
- ASTNodeFlags2[ASTNodeFlags2["VariableField"] = 1] = "VariableField";
417
- ASTNodeFlags2[ASTNodeFlags2["Expression"] = 4] = "Expression";
418
- ASTNodeFlags2[ASTNodeFlags2["BasicType"] = 8] = "BasicType";
419
- ASTNodeFlags2[ASTNodeFlags2["DrilldownType"] = 16] = "DrilldownType";
420
- ASTNodeFlags2[ASTNodeFlags2["EnumerateType"] = 32] = "EnumerateType";
421
- ASTNodeFlags2[ASTNodeFlags2["UnionType"] = 64] = "UnionType";
422
- ASTNodeFlags2[ASTNodeFlags2["VariableType"] = 120] = "VariableType";
423
- return ASTNodeFlags2;
424
- })(ASTNodeFlags || {});
425
-
426
461
  // src/ast/ast-node.ts
427
462
  var import_rxjs2 = require("rxjs");
428
463
  var import_nanoid = require("nanoid");
@@ -430,41 +465,44 @@ var import_fast_equals = require("fast-equals");
430
465
  var import_utils4 = require("@flowgram.ai/utils");
431
466
  var ASTNode = class _ASTNode {
432
467
  /**
433
- * 构造函数
434
- * @param createParams 创建 ASTNode 的必要参数
435
- * @param injectOptions 依赖注入各种模块
468
+ * Constructor.
469
+ * @param createParams Necessary parameters for creating an ASTNode.
470
+ * @param injectOptions Dependency injection for various modules.
436
471
  */
437
472
  constructor({ key, parent, scope }, opts) {
438
473
  /**
439
- * 节点 Flags,记录一些 Flag 信息
474
+ * Node flags, used to record some flag information.
440
475
  */
441
476
  this.flags = 0 /* None */;
442
477
  /**
443
- * 节点的版本号,每 fireChange 一次 version + 1
478
+ * The version number of the ASTNode, which increments by 1 each time `fireChange` is called.
444
479
  */
445
480
  this._version = 0;
446
481
  /**
447
- * 更新锁
482
+ * Update lock.
483
+ * - When set to `true`, `fireChange` will not trigger any events.
484
+ * - This is useful when multiple updates are needed, and you want to avoid multiple triggers.
448
485
  */
449
486
  this.changeLocked = false;
450
487
  /**
451
- * Batch Update 相关参数
488
+ * Parameters related to batch updates.
452
489
  */
453
490
  this._batch = {
454
491
  batching: false,
455
492
  hasChangesInBatch: false
456
493
  };
457
494
  /**
458
- * AST 节点变化事件,基于 Rxjs 实现
459
- * - 使用了 BehaviorSubject, 在订阅时会自动触发一次事件,事件为当前值
495
+ * AST node change Observable events, implemented based on RxJS.
496
+ * - Emits the current ASTNode value upon subscription.
497
+ * - Emits a new value whenever `fireChange` is called.
460
498
  */
461
499
  this.value$ = new import_rxjs2.BehaviorSubject(this);
462
500
  /**
463
- * 子节点
501
+ * Child ASTNodes.
464
502
  */
465
503
  this._children = /* @__PURE__ */ new Set();
466
504
  /**
467
- * 删除节点处理事件列表
505
+ * List of disposal handlers for the ASTNode.
468
506
  */
469
507
  this.toDispose = new import_utils4.DisposableCollection(
470
508
  import_utils4.Disposable.create(() => {
@@ -473,7 +511,7 @@ var ASTNode = class _ASTNode {
473
511
  })
474
512
  );
475
513
  /**
476
- * 销毁时触发的回调
514
+ * Callback triggered upon disposal.
477
515
  */
478
516
  this.onDispose = this.toDispose.onDispose;
479
517
  this.scope = scope;
@@ -483,7 +521,7 @@ var ASTNode = class _ASTNode {
483
521
  this.fromJSON = this.withBatchUpdate(this.fromJSON.bind(this));
484
522
  }
485
523
  /**
486
- * AST 节点的类型
524
+ * The type of the ASTNode.
487
525
  */
488
526
  get kind() {
489
527
  if (!this.constructor.kind) {
@@ -492,13 +530,13 @@ var ASTNode = class _ASTNode {
492
530
  return this.constructor.kind;
493
531
  }
494
532
  /**
495
- * 获取当前节点所有子节点
533
+ * Gets all child ASTNodes of the current ASTNode.
496
534
  */
497
535
  get children() {
498
536
  return Array.from(this._children);
499
537
  }
500
538
  /**
501
- * 转化为 ASTNodeJSON
539
+ * Serializes the current ASTNode to ASTNodeJSON.
502
540
  * @returns
503
541
  */
504
542
  toJSON() {
@@ -508,8 +546,8 @@ var ASTNode = class _ASTNode {
508
546
  };
509
547
  }
510
548
  /**
511
- * 创建子节点
512
- * @param json 子节点的 AST JSON
549
+ * Creates a child ASTNode.
550
+ * @param json The AST JSON of the child ASTNode.
513
551
  * @returns
514
552
  */
515
553
  createChildNode(json) {
@@ -527,8 +565,8 @@ var ASTNode = class _ASTNode {
527
565
  return child;
528
566
  }
529
567
  /**
530
- * 更新子节点,快速实现子节点更新消费逻辑
531
- * @param keyInThis 当前对象上的指定 key
568
+ * Updates a child ASTNode, quickly implementing the consumption logic for child ASTNode updates.
569
+ * @param keyInThis The specified key on the current object.
532
570
  */
533
571
  updateChildNodeByKey(keyInThis, nextJSON) {
534
572
  this.withBatchUpdate(updateChildNodeHelper).call(this, {
@@ -539,8 +577,8 @@ var ASTNode = class _ASTNode {
539
577
  });
540
578
  }
541
579
  /**
542
- * 批处理更新,批处理函数内所有的 fireChange 都合并成一个
543
- * @param updater 批处理函数
580
+ * Batch updates the ASTNode, merging all `fireChange` calls within the batch function into one.
581
+ * @param updater The batch function.
544
582
  * @returns
545
583
  */
546
584
  withBatchUpdate(updater) {
@@ -560,7 +598,7 @@ var ASTNode = class _ASTNode {
560
598
  };
561
599
  }
562
600
  /**
563
- * 触发当前节点更新
601
+ * Triggers an update for the current node.
564
602
  */
565
603
  fireChange() {
566
604
  if (this.changeLocked || this.disposed) {
@@ -576,22 +614,24 @@ var ASTNode = class _ASTNode {
576
614
  this.parent?.fireChange();
577
615
  }
578
616
  /**
579
- * 节点的版本值
580
- * - 通过 NodeA === NodeB && versionA === versionB 可以比较两者是否相等
617
+ * The version value of the ASTNode.
618
+ * - You can used to check whether ASTNode are updated.
581
619
  */
582
620
  get version() {
583
621
  return this._version;
584
622
  }
585
623
  /**
586
- * 节点唯一 hash
624
+ * The unique hash value of the ASTNode.
625
+ * - It will update when the ASTNode is updated.
626
+ * - You can used to check two ASTNode are equal.
587
627
  */
588
628
  get hash() {
589
629
  return `${this._version}${this.kind}${this.key}`;
590
630
  }
591
631
  /**
592
- * 监听 AST 节点的变化
593
- * @param observer 监听回调
594
- * @param selector 监听指定数据
632
+ * Listens for changes to the ASTNode.
633
+ * @param observer The listener callback.
634
+ * @param selector Listens for specified data.
595
635
  * @returns
596
636
  */
597
637
  subscribe(observer, { selector, debounceAnimation, triggerOnInit } = {}) {
@@ -607,13 +647,17 @@ var ASTNode = class _ASTNode {
607
647
  return value;
608
648
  }
609
649
  ),
610
- // 默认跳过 BehaviorSubject 第一次触发
650
+ // By default, skip the first trigger of BehaviorSubject.
611
651
  triggerOnInit ? (0, import_rxjs2.tap)(() => null) : (0, import_rxjs2.skip)(1),
612
- // 每个 animationFrame 内所有更新合并成一个
652
+ // All updates within each animationFrame are merged into one.
613
653
  debounceAnimation ? (0, import_rxjs2.debounceTime)(0, import_rxjs2.animationFrameScheduler) : (0, import_rxjs2.tap)(() => null)
614
654
  ).subscribe(observer)
615
655
  );
616
656
  }
657
+ /**
658
+ * Dispatches a global event for the current ASTNode.
659
+ * @param event The global event.
660
+ */
617
661
  dispatchGlobalEvent(event) {
618
662
  this.scope.event.dispatch({
619
663
  ...event,
@@ -621,7 +665,7 @@ var ASTNode = class _ASTNode {
621
665
  });
622
666
  }
623
667
  /**
624
- * 销毁
668
+ * Disposes the ASTNode.
625
669
  */
626
670
  dispose() {
627
671
  if (this.toDispose.disposed) {
@@ -644,8 +688,9 @@ var BaseType = class extends ASTNode {
644
688
  this.flags = 8 /* BasicType */;
645
689
  }
646
690
  /**
647
- * 类型是否一致
648
- * @param targetTypeJSON
691
+ * Check if the current type is equal to the target type.
692
+ * @param targetTypeJSONOrKind The type to compare with.
693
+ * @returns `true` if the types are equal, `false` otherwise.
649
694
  */
650
695
  isTypeEqual(targetTypeJSONOrKind) {
651
696
  const targetTypeJSON = parseTypeJsonOrKind(targetTypeJSONOrKind);
@@ -657,15 +702,18 @@ var BaseType = class extends ASTNode {
657
702
  return this.kind === targetTypeJSON?.kind;
658
703
  }
659
704
  /**
660
- * 可下钻类型需实现
661
- * @param keyPath
705
+ * Get a variable field by key path.
706
+ *
707
+ * This method should be implemented by drillable types.
708
+ * @param keyPath The key path to search for.
709
+ * @returns The variable field if found, otherwise `undefined`.
662
710
  */
663
711
  getByKeyPath(keyPath = []) {
664
712
  throw new Error(`Get By Key Path is not implemented for Type: ${this.kind}`);
665
713
  }
666
714
  /**
667
- * Get AST JSON for current base type
668
- * @returns
715
+ * Serialize the node to a JSON object.
716
+ * @returns The JSON representation of the node.
669
717
  */
670
718
  toJSON() {
671
719
  return {
@@ -680,13 +728,24 @@ var ArrayType = class extends BaseType {
680
728
  super(...arguments);
681
729
  this.flags = 16 /* DrilldownType */ | 32 /* EnumerateType */;
682
730
  }
731
+ /**
732
+ * Deserializes the `ArrayJSON` to the `ArrayType`.
733
+ * @param json The `ArrayJSON` to deserialize.
734
+ */
683
735
  fromJSON({ items }) {
684
736
  this.updateChildNodeByKey("items", parseTypeJsonOrKind(items));
685
737
  }
686
- // items 类型是否可下钻
738
+ /**
739
+ * Whether the items type can be drilled down.
740
+ */
687
741
  get canDrilldownItems() {
688
742
  return !!(this.items?.flags & 16 /* DrilldownType */);
689
743
  }
744
+ /**
745
+ * Get a variable field by key path.
746
+ * @param keyPath The key path to search for.
747
+ * @returns The variable field if found, otherwise `undefined`.
748
+ */
690
749
  getByKeyPath(keyPath) {
691
750
  const [curr, ...rest] = keyPath || [];
692
751
  if (curr === "0" && this.canDrilldownItems) {
@@ -694,19 +753,24 @@ var ArrayType = class extends BaseType {
694
753
  }
695
754
  return void 0;
696
755
  }
756
+ /**
757
+ * Check if the current type is equal to the target type.
758
+ * @param targetTypeJSONOrKind The type to compare with.
759
+ * @returns `true` if the types are equal, `false` otherwise.
760
+ */
697
761
  isTypeEqual(targetTypeJSONOrKind) {
698
762
  const targetTypeJSON = parseTypeJsonOrKind(targetTypeJSONOrKind);
699
763
  const isSuperEqual = super.isTypeEqual(targetTypeJSONOrKind);
700
764
  if (targetTypeJSON?.weak || targetTypeJSON?.kind === "Union" /* Union */) {
701
765
  return isSuperEqual;
702
766
  }
703
- return targetTypeJSON && isSuperEqual && // 弱比较,只需要比较 Kind 即可
767
+ return targetTypeJSON && isSuperEqual && // Weak comparison, only need to compare the Kind.
704
768
  (targetTypeJSON?.weak || this.customStrongEqual(targetTypeJSON));
705
769
  }
706
770
  /**
707
- * Array 强比较
708
- * @param targetTypeJSON
709
- * @returns
771
+ * Array strong comparison.
772
+ * @param targetTypeJSON The type to compare with.
773
+ * @returns `true` if the types are equal, `false` otherwise.
710
774
  */
711
775
  customStrongEqual(targetTypeJSON) {
712
776
  if (!this.items) {
@@ -714,6 +778,10 @@ var ArrayType = class extends BaseType {
714
778
  }
715
779
  return this.items?.isTypeEqual(targetTypeJSON.items);
716
780
  }
781
+ /**
782
+ * Serialize the `ArrayType` to `ArrayJSON`
783
+ * @returns The JSON representation of `ArrayType`.
784
+ */
717
785
  toJSON() {
718
786
  return {
719
787
  kind: "Array" /* Array */,
@@ -730,11 +798,16 @@ var StringType = class extends BaseType {
730
798
  this.flags = 8 /* BasicType */;
731
799
  }
732
800
  /**
733
- * https://json-schema.org/understanding-json-schema/reference/type#format
801
+ * see https://json-schema.org/understanding-json-schema/reference/string#format
734
802
  */
735
803
  get format() {
736
804
  return this._format;
737
805
  }
806
+ /**
807
+ * Deserialize the `StringJSON` to the `StringType`.
808
+ *
809
+ * @param json StringJSON representation of the `StringType`.
810
+ */
738
811
  fromJSON(json) {
739
812
  if (json?.format !== this._format) {
740
813
  this._format = json?.format;
@@ -750,6 +823,10 @@ var IntegerType = class extends BaseType {
750
823
  super(...arguments);
751
824
  this.flags = 8 /* BasicType */;
752
825
  }
826
+ /**
827
+ * Deserializes the `IntegerJSON` to the `IntegerType`.
828
+ * @param json The `IntegerJSON` to deserialize.
829
+ */
753
830
  fromJSON() {
754
831
  }
755
832
  };
@@ -757,6 +834,10 @@ IntegerType.kind = "Integer" /* Integer */;
757
834
 
758
835
  // src/ast/type/boolean.ts
759
836
  var BooleanType = class extends BaseType {
837
+ /**
838
+ * Deserializes the `BooleanJSON` to the `BooleanType`.
839
+ * @param json The `BooleanJSON` to deserialize.
840
+ */
760
841
  fromJSON() {
761
842
  }
762
843
  };
@@ -764,6 +845,10 @@ BooleanType.kind = "Boolean" /* Boolean */;
764
845
 
765
846
  // src/ast/type/number.ts
766
847
  var NumberType = class extends BaseType {
848
+ /**
849
+ * Deserializes the `NumberJSON` to the `NumberType`.
850
+ * @param json The `NumberJSON` to deserialize.
851
+ */
767
852
  fromJSON() {
768
853
  }
769
854
  };
@@ -771,40 +856,42 @@ NumberType.kind = "Number" /* Number */;
771
856
 
772
857
  // src/ast/type/map.ts
773
858
  var MapType = class extends BaseType {
859
+ /**
860
+ * Deserializes the `MapJSON` to the `MapType`.
861
+ * @param json The `MapJSON` to deserialize.
862
+ */
774
863
  fromJSON({ keyType = "String" /* String */, valueType }) {
775
864
  this.updateChildNodeByKey("keyType", parseTypeJsonOrKind(keyType));
776
865
  this.updateChildNodeByKey("valueType", parseTypeJsonOrKind(valueType));
777
866
  }
778
- // Value 类型是否可下钻,后续实现
779
- // get canDrilldownValue(): boolean {
780
- // return !!(this.valueType.flags & ASTNodeFlags.DrilldownType);
781
- // }
782
- // getByKeyPath(keyPath: string[]): BaseVariableField | undefined {
783
- // const [curr, ...rest] = keyPath || [];
784
- // if (curr === '*' && this.canDrilldownValue) {
785
- // return this.valueType.getByKeyPath(rest);
786
- // }
787
- // return undefined;
788
- // }
867
+ /**
868
+ * Check if the current type is equal to the target type.
869
+ * @param targetTypeJSONOrKind The type to compare with.
870
+ * @returns `true` if the types are equal, `false` otherwise.
871
+ */
789
872
  isTypeEqual(targetTypeJSONOrKind) {
790
873
  const targetTypeJSON = parseTypeJsonOrKind(targetTypeJSONOrKind);
791
874
  const isSuperEqual = super.isTypeEqual(targetTypeJSONOrKind);
792
875
  if (targetTypeJSON?.weak || targetTypeJSON?.kind === "Union" /* Union */) {
793
876
  return isSuperEqual;
794
877
  }
795
- return targetTypeJSON && isSuperEqual && // 弱比较,只需要比较 Kind 即可
878
+ return targetTypeJSON && isSuperEqual && // Weak comparison, only need to compare the Kind.
796
879
  (targetTypeJSON?.weak || this.customStrongEqual(targetTypeJSON));
797
880
  }
798
881
  /**
799
- * Map 强比较
800
- * @param targetTypeJSON
801
- * @returns
882
+ * Map strong comparison.
883
+ * @param targetTypeJSON The type to compare with.
884
+ * @returns `true` if the types are equal, `false` otherwise.
802
885
  */
803
886
  customStrongEqual(targetTypeJSON) {
804
887
  const { keyType = "String" /* String */, valueType } = targetTypeJSON;
805
888
  const isValueTypeEqual = !valueType && !this.valueType || this.valueType?.isTypeEqual(valueType);
806
889
  return isValueTypeEqual && this.keyType?.isTypeEqual(keyType);
807
890
  }
891
+ /**
892
+ * Serialize the node to a JSON object.
893
+ * @returns The JSON representation of the node.
894
+ */
808
895
  toJSON() {
809
896
  return {
810
897
  kind: "Map" /* Map */,
@@ -813,7 +900,6 @@ var MapType = class extends BaseType {
813
900
  };
814
901
  }
815
902
  };
816
- // public flags: ASTNodeFlags = ASTNodeFlags.DrilldownType | ASTNodeFlags.EnumerateType;
817
903
  MapType.kind = "Map" /* Map */;
818
904
 
819
905
  // src/ast/type/object.ts
@@ -822,8 +908,15 @@ var ObjectType = class extends BaseType {
822
908
  constructor() {
823
909
  super(...arguments);
824
910
  this.flags = 16 /* DrilldownType */;
911
+ /**
912
+ * A map of property keys to `Property` instances.
913
+ */
825
914
  this.propertyTable = /* @__PURE__ */ new Map();
826
915
  }
916
+ /**
917
+ * Deserializes the `ObjectJSON` to the `ObjectType`.
918
+ * @param json The `ObjectJSON` to deserialize.
919
+ */
827
920
  fromJSON({ properties }) {
828
921
  const removedKeys = new Set(this.propertyTable.keys());
829
922
  const prev = [...this.properties || []];
@@ -857,6 +950,10 @@ var ObjectType = class extends BaseType {
857
950
  }
858
951
  });
859
952
  }
953
+ /**
954
+ * Serialize the `ObjectType` to `ObjectJSON`.
955
+ * @returns The JSON representation of `ObjectType`.
956
+ */
860
957
  toJSON() {
861
958
  return {
862
959
  kind: "Object" /* Object */,
@@ -864,9 +961,9 @@ var ObjectType = class extends BaseType {
864
961
  };
865
962
  }
866
963
  /**
867
- * 根据 KeyPath 找到对应的变量
868
- * @param keyPath 变量路径
869
- * @returns
964
+ * Get a variable field by key path.
965
+ * @param keyPath The key path to search for.
966
+ * @returns The variable field if found, otherwise `undefined`.
870
967
  */
871
968
  getByKeyPath(keyPath) {
872
969
  const [curr, ...restKeyPath] = keyPath;
@@ -879,19 +976,24 @@ var ObjectType = class extends BaseType {
879
976
  }
880
977
  return void 0;
881
978
  }
979
+ /**
980
+ * Check if the current type is equal to the target type.
981
+ * @param targetTypeJSONOrKind The type to compare with.
982
+ * @returns `true` if the types are equal, `false` otherwise.
983
+ */
882
984
  isTypeEqual(targetTypeJSONOrKind) {
883
985
  const targetTypeJSON = parseTypeJsonOrKind(targetTypeJSONOrKind);
884
986
  const isSuperEqual = super.isTypeEqual(targetTypeJSONOrKind);
885
987
  if (targetTypeJSON?.weak || targetTypeJSON?.kind === "Union" /* Union */) {
886
988
  return isSuperEqual;
887
989
  }
888
- return targetTypeJSON && isSuperEqual && // 弱比较,只需要比较 Kind 即可
990
+ return targetTypeJSON && isSuperEqual && // Weak comparison, only need to compare the Kind.
889
991
  (targetTypeJSON?.weak || this.customStrongEqual(targetTypeJSON));
890
992
  }
891
993
  /**
892
- * Object 类型强比较
893
- * @param targetTypeJSON
894
- * @returns
994
+ * Object type strong comparison.
995
+ * @param targetTypeJSON The type to compare with.
996
+ * @returns `true` if the types are equal, `false` otherwise.
895
997
  */
896
998
  customStrongEqual(targetTypeJSON) {
897
999
  const targetProperties = targetTypeJSON.properties || [];
@@ -908,15 +1010,27 @@ ObjectType.kind = "Object" /* Object */;
908
1010
 
909
1011
  // src/ast/type/custom-type.ts
910
1012
  var CustomType = class extends BaseType {
1013
+ /**
1014
+ * The name of the custom type.
1015
+ */
911
1016
  get typeName() {
912
1017
  return this._typeName;
913
1018
  }
1019
+ /**
1020
+ * Deserializes the `CustomTypeJSON` to the `CustomType`.
1021
+ * @param json The `CustomTypeJSON` to deserialize.
1022
+ */
914
1023
  fromJSON(json) {
915
1024
  if (this._typeName !== json.typeName) {
916
1025
  this._typeName = json.typeName;
917
1026
  this.fireChange();
918
1027
  }
919
1028
  }
1029
+ /**
1030
+ * Check if the current type is equal to the target type.
1031
+ * @param targetTypeJSONOrKind The type to compare with.
1032
+ * @returns `true` if the types are equal, `false` otherwise.
1033
+ */
920
1034
  isTypeEqual(targetTypeJSONOrKind) {
921
1035
  const targetTypeJSON = parseTypeJsonOrKind(targetTypeJSONOrKind);
922
1036
  if (targetTypeJSON?.kind === "Union" /* Union */) {
@@ -952,13 +1066,12 @@ var BaseExpression = class extends ASTNode {
952
1066
  super(params, opts);
953
1067
  this.flags = 4 /* Expression */;
954
1068
  /**
955
- * 引用变量
1069
+ * The variable fields referenced by the expression.
956
1070
  */
957
1071
  this._refs = [];
958
1072
  this.refreshRefs$ = new import_rxjs3.Subject();
959
1073
  /**
960
- * 监听引用变量变化
961
- * 监听 [a.b.c] -> [a.b]
1074
+ * An observable that emits the referenced variable fields when they change.
962
1075
  */
963
1076
  this.refs$ = this.refreshRefs$.pipe(
964
1077
  (0, import_rxjs3.map)(() => this.getRefFields()),
@@ -982,91 +1095,42 @@ var BaseExpression = class extends ASTNode {
982
1095
  );
983
1096
  }
984
1097
  /**
985
- * 获取全局变量表,方便表达式获取引用变量
1098
+ * Get the global variable table, which is used to access referenced variables.
986
1099
  */
987
1100
  get globalVariableTable() {
988
1101
  return this.scope.variableEngine.globalVariableTable;
989
1102
  }
990
1103
  /**
991
- * 父变量字段,通过由近而远的方式进行排序
1104
+ * Parent variable fields, sorted from closest to farthest.
992
1105
  */
993
1106
  get parentFields() {
994
1107
  return getParentFields(this);
995
1108
  }
1109
+ /**
1110
+ * The variable fields referenced by the expression.
1111
+ */
996
1112
  get refs() {
997
1113
  return this._refs;
998
1114
  }
999
1115
  /**
1000
- * 刷新变量引用
1116
+ * Refresh the variable references.
1001
1117
  */
1002
1118
  refreshRefs() {
1003
1119
  this.refreshRefs$.next();
1004
1120
  }
1005
1121
  };
1006
1122
 
1007
- // src/ast/expression/keypath-expression.ts
1008
- var import_fast_equals3 = require("fast-equals");
1009
- var KeyPathExpression = class extends BaseExpression {
1010
- constructor(params, opts) {
1011
- super(params, opts);
1012
- this._keyPath = [];
1013
- this.toDispose.pushAll([
1014
- // 可以用变量列表变化时候 (有新增或者删除时)
1015
- this.scope.available.onVariableListChange(() => {
1016
- this.refreshRefs();
1017
- }),
1018
- // this._keyPath 指向的可引用变量发生变化时,刷新引用数据
1019
- this.scope.available.onAnyVariableChange((_v) => {
1020
- if (_v.key === this._keyPath[0]) {
1021
- this.refreshRefs();
1022
- }
1023
- })
1024
- ]);
1025
- }
1026
- get keyPath() {
1027
- return this._keyPath;
1028
- }
1029
- getRefFields() {
1030
- const ref = this.scope.available.getByKeyPath(this._keyPath);
1031
- return ref ? [ref] : [];
1032
- }
1033
- get returnType() {
1034
- const [refNode] = this._refs || [];
1035
- if (refNode && refNode.flags & 1 /* VariableField */) {
1036
- return refNode.type;
1037
- }
1038
- return;
1039
- }
1040
- /**
1041
- * 业务重改该方法可快速定制自己的 Path 表达式
1042
- * - 只需要将业务的 Path 解析为变量系统的 KeyPath 即可
1043
- * @param json 业务定义的 Path 表达式
1044
- * @returns
1045
- */
1046
- parseToKeyPath(json) {
1047
- return json.keyPath;
1048
- }
1049
- fromJSON(json) {
1050
- const keyPath = this.parseToKeyPath(json);
1051
- if (!(0, import_fast_equals3.shallowEqual)(keyPath, this._keyPath)) {
1052
- this._keyPath = keyPath;
1053
- this.refreshRefs();
1054
- }
1055
- }
1056
- toJSON() {
1057
- return {
1058
- kind: "KeyPathExpression" /* KeyPathExpression */,
1059
- keyPath: this._keyPath
1060
- };
1061
- }
1062
- };
1063
- KeyPathExpression.kind = "KeyPathExpression" /* KeyPathExpression */;
1064
-
1065
1123
  // src/ast/expression/enumerate-expression.ts
1066
1124
  var EnumerateExpression = class extends BaseExpression {
1125
+ /**
1126
+ * The expression to be enumerated.
1127
+ */
1067
1128
  get enumerateFor() {
1068
1129
  return this._enumerateFor;
1069
1130
  }
1131
+ /**
1132
+ * The return type of the expression.
1133
+ */
1070
1134
  get returnType() {
1071
1135
  const childReturnType = this.enumerateFor?.returnType;
1072
1136
  if (childReturnType?.kind === "Array" /* Array */) {
@@ -1074,12 +1138,24 @@ var EnumerateExpression = class extends BaseExpression {
1074
1138
  }
1075
1139
  return void 0;
1076
1140
  }
1141
+ /**
1142
+ * Get the variable fields referenced by the expression.
1143
+ * @returns An empty array, as this expression does not reference any variables.
1144
+ */
1077
1145
  getRefFields() {
1078
1146
  return [];
1079
1147
  }
1148
+ /**
1149
+ * Deserializes the `EnumerateExpressionJSON` to the `EnumerateExpression`.
1150
+ * @param json The `EnumerateExpressionJSON` to deserialize.
1151
+ */
1080
1152
  fromJSON({ enumerateFor: expression }) {
1081
1153
  this.updateChildNodeByKey("_enumerateFor", expression);
1082
1154
  }
1155
+ /**
1156
+ * Serialize the `EnumerateExpression` to `EnumerateExpressionJSON`.
1157
+ * @returns The JSON representation of `EnumerateExpression`.
1158
+ */
1083
1159
  toJSON() {
1084
1160
  return {
1085
1161
  kind: "EnumerateExpression" /* EnumerateExpression */,
@@ -1089,8 +1165,8 @@ var EnumerateExpression = class extends BaseExpression {
1089
1165
  };
1090
1166
  EnumerateExpression.kind = "EnumerateExpression" /* EnumerateExpression */;
1091
1167
 
1092
- // src/ast/expression/keypath-expression-v2.ts
1093
- var import_fast_equals4 = require("fast-equals");
1168
+ // src/ast/expression/keypath-expression.ts
1169
+ var import_fast_equals3 = require("fast-equals");
1094
1170
 
1095
1171
  // src/ast/utils/expression.ts
1096
1172
  var import_lodash_es2 = require("lodash-es");
@@ -1113,17 +1189,17 @@ function checkRefCycle(curr, refNodes) {
1113
1189
  return (0, import_lodash_es2.intersection)(Array.from(visited), getParentFields(curr)).length > 0;
1114
1190
  }
1115
1191
 
1116
- // src/ast/expression/keypath-expression-v2.ts
1117
- var KeyPathExpressionV2 = class extends BaseExpression {
1192
+ // src/ast/expression/keypath-expression.ts
1193
+ var KeyPathExpression = class extends BaseExpression {
1118
1194
  constructor(params, opts) {
1119
1195
  super(params, opts);
1120
1196
  this._keyPath = [];
1121
1197
  this.toDispose.pushAll([
1122
- // 可以用变量列表变化时候 (有新增或者删除时)
1198
+ // Can be used when the variable list changes (when there are additions or deletions).
1123
1199
  this.scope.available.onVariableListChange(() => {
1124
1200
  this.refreshRefs();
1125
1201
  }),
1126
- // this._keyPath 指向的可引用变量发生变化时,刷新引用数据
1202
+ // When the referable variable pointed to by this._keyPath changes, refresh the reference data.
1127
1203
  this.scope.available.onAnyVariableChange((_v) => {
1128
1204
  if (_v.key === this._keyPath[0]) {
1129
1205
  this.refreshRefs();
@@ -1140,9 +1216,16 @@ var KeyPathExpressionV2 = class extends BaseExpression {
1140
1216
  )
1141
1217
  ]);
1142
1218
  }
1219
+ /**
1220
+ * The key path of the variable.
1221
+ */
1143
1222
  get keyPath() {
1144
1223
  return this._keyPath;
1145
1224
  }
1225
+ /**
1226
+ * Get the variable fields referenced by the expression.
1227
+ * @returns An array of referenced variable fields.
1228
+ */
1146
1229
  getRefFields() {
1147
1230
  const ref = this.scope.available.getByKeyPath(this._keyPath);
1148
1231
  if (checkRefCycle(this, [ref])) {
@@ -1154,28 +1237,122 @@ var KeyPathExpressionV2 = class extends BaseExpression {
1154
1237
  }
1155
1238
  return ref ? [ref] : [];
1156
1239
  }
1240
+ /**
1241
+ * The return type of the expression.
1242
+ */
1157
1243
  get returnType() {
1158
1244
  return this._returnType;
1159
1245
  }
1160
1246
  /**
1161
- * 业务重改该方法可快速定制自己的 Path 表达式
1162
- * - 只需要将业务的 Path 解析为变量系统的 KeyPath 即可
1163
- * @param json 业务定义的 Path 表达式
1164
- * @returns
1247
+ * Parse the business-defined path expression into a key path.
1248
+ *
1249
+ * Businesses can quickly customize their own path expressions by modifying this method.
1250
+ * @param json The path expression defined by the business.
1251
+ * @returns The key path.
1165
1252
  */
1166
1253
  parseToKeyPath(json) {
1167
1254
  return json.keyPath;
1168
1255
  }
1256
+ /**
1257
+ * Deserializes the `KeyPathExpressionJSON` to the `KeyPathExpression`.
1258
+ * @param json The `KeyPathExpressionJSON` to deserialize.
1259
+ */
1169
1260
  fromJSON(json) {
1170
1261
  const keyPath = this.parseToKeyPath(json);
1171
- if (!(0, import_fast_equals4.shallowEqual)(keyPath, this._keyPath)) {
1262
+ if (!(0, import_fast_equals3.shallowEqual)(keyPath, this._keyPath)) {
1172
1263
  this._keyPath = keyPath;
1173
1264
  this.refreshRefs();
1174
1265
  }
1175
1266
  }
1267
+ /**
1268
+ * Get the return type JSON by reference.
1269
+ * @param _ref The referenced variable field.
1270
+ * @returns The JSON representation of the return type.
1271
+ */
1176
1272
  getReturnTypeJSONByRef(_ref) {
1177
1273
  return _ref?.type?.toJSON();
1178
1274
  }
1275
+ /**
1276
+ * Serialize the `KeyPathExpression` to `KeyPathExpressionJSON`.
1277
+ * @returns The JSON representation of `KeyPathExpression`.
1278
+ */
1279
+ toJSON() {
1280
+ return {
1281
+ kind: "KeyPathExpression" /* KeyPathExpression */,
1282
+ keyPath: this._keyPath
1283
+ };
1284
+ }
1285
+ };
1286
+ KeyPathExpression.kind = "KeyPathExpression" /* KeyPathExpression */;
1287
+
1288
+ // src/ast/expression/legacy-keypath-expression.ts
1289
+ var import_fast_equals4 = require("fast-equals");
1290
+ var LegacyKeyPathExpression = class extends BaseExpression {
1291
+ constructor(params, opts) {
1292
+ super(params, opts);
1293
+ this._keyPath = [];
1294
+ this.toDispose.pushAll([
1295
+ // Can be used when the variable list changes (when there are additions or deletions).
1296
+ this.scope.available.onVariableListChange(() => {
1297
+ this.refreshRefs();
1298
+ }),
1299
+ // When the referable variable pointed to by this._keyPath changes, refresh the reference data.
1300
+ this.scope.available.onAnyVariableChange((_v) => {
1301
+ if (_v.key === this._keyPath[0]) {
1302
+ this.refreshRefs();
1303
+ }
1304
+ })
1305
+ ]);
1306
+ }
1307
+ /**
1308
+ * The key path of the variable.
1309
+ */
1310
+ get keyPath() {
1311
+ return this._keyPath;
1312
+ }
1313
+ /**
1314
+ * Get the variable fields referenced by the expression.
1315
+ * @returns An array of referenced variable fields.
1316
+ */
1317
+ getRefFields() {
1318
+ const ref = this.scope.available.getByKeyPath(this._keyPath);
1319
+ return ref ? [ref] : [];
1320
+ }
1321
+ /**
1322
+ * The return type of the expression.
1323
+ */
1324
+ get returnType() {
1325
+ const [refNode] = this._refs || [];
1326
+ if (refNode && refNode.flags & 1 /* VariableField */) {
1327
+ return refNode.type;
1328
+ }
1329
+ return;
1330
+ }
1331
+ /**
1332
+ * Parse the business-defined path expression into a key path.
1333
+ *
1334
+ * Businesses can quickly customize their own path expressions by modifying this method.
1335
+ * @param json The path expression defined by the business.
1336
+ * @returns The key path.
1337
+ */
1338
+ parseToKeyPath(json) {
1339
+ return json.keyPath;
1340
+ }
1341
+ /**
1342
+ * Deserializes the `KeyPathExpressionJSON` to the `KeyPathExpression`.
1343
+ * @param json The `KeyPathExpressionJSON` to deserialize.
1344
+ */
1345
+ fromJSON(json) {
1346
+ const keyPath = this.parseToKeyPath(json);
1347
+ if (!(0, import_fast_equals4.shallowEqual)(keyPath, this._keyPath)) {
1348
+ this._keyPath = keyPath;
1349
+ this.refreshRefs();
1350
+ }
1351
+ }
1352
+ /**
1353
+ * Serialize the `KeyPathExpression` to `KeyPathExpressionJSON`.
1354
+ * @returns The JSON representation of `KeyPathExpression`.
1355
+ */
1179
1356
  toJSON() {
1180
1357
  return {
1181
1358
  kind: "KeyPathExpression" /* KeyPathExpression */,
@@ -1183,16 +1360,25 @@ var KeyPathExpressionV2 = class extends BaseExpression {
1183
1360
  };
1184
1361
  }
1185
1362
  };
1186
- KeyPathExpressionV2.kind = "KeyPathExpression" /* KeyPathExpression */;
1363
+ LegacyKeyPathExpression.kind = "KeyPathExpression" /* KeyPathExpression */;
1187
1364
 
1188
1365
  // src/ast/expression/wrap-array-expression.ts
1189
1366
  var WrapArrayExpression = class extends BaseExpression {
1367
+ /**
1368
+ * The expression to be wrapped.
1369
+ */
1190
1370
  get wrapFor() {
1191
1371
  return this._wrapFor;
1192
1372
  }
1373
+ /**
1374
+ * The return type of the expression.
1375
+ */
1193
1376
  get returnType() {
1194
1377
  return this._returnType;
1195
1378
  }
1379
+ /**
1380
+ * Refresh the return type of the expression.
1381
+ */
1196
1382
  refreshReturnType() {
1197
1383
  const childReturnTypeJSON = this.wrapFor?.returnType?.toJSON();
1198
1384
  this.updateChildNodeByKey("_returnType", {
@@ -1200,12 +1386,24 @@ var WrapArrayExpression = class extends BaseExpression {
1200
1386
  items: childReturnTypeJSON
1201
1387
  });
1202
1388
  }
1389
+ /**
1390
+ * Get the variable fields referenced by the expression.
1391
+ * @returns An empty array, as this expression does not reference any variables.
1392
+ */
1203
1393
  getRefFields() {
1204
1394
  return [];
1205
1395
  }
1396
+ /**
1397
+ * Deserializes the `WrapArrayExpressionJSON` to the `WrapArrayExpression`.
1398
+ * @param json The `WrapArrayExpressionJSON` to deserialize.
1399
+ */
1206
1400
  fromJSON({ wrapFor: expression }) {
1207
1401
  this.updateChildNodeByKey("_wrapFor", expression);
1208
1402
  }
1403
+ /**
1404
+ * Serialize the `WrapArrayExpression` to `WrapArrayExpressionJSON`.
1405
+ * @returns The JSON representation of `WrapArrayExpression`.
1406
+ */
1209
1407
  toJSON() {
1210
1408
  return {
1211
1409
  kind: "WrapArrayExpression" /* WrapArrayExpression */,
@@ -1236,41 +1434,73 @@ var BaseVariableField = class extends ASTNode {
1236
1434
  this._meta = {};
1237
1435
  }
1238
1436
  /**
1239
- * 父变量字段,通过由近而远的方式进行排序
1437
+ * Parent variable fields, sorted from closest to farthest
1240
1438
  */
1241
1439
  get parentFields() {
1242
1440
  return getParentFields(this);
1243
1441
  }
1442
+ /**
1443
+ * KeyPath of the variable field, sorted from farthest to closest
1444
+ */
1244
1445
  get keyPath() {
1245
1446
  return [...this.parentFields.reverse().map((_field) => _field.key), this.key];
1246
1447
  }
1448
+ /**
1449
+ * Metadata of the variable field, you cans store information like `title`, `icon`, etc.
1450
+ */
1247
1451
  get meta() {
1248
1452
  return this._meta;
1249
1453
  }
1454
+ /**
1455
+ * Type of the variable field, similar to js code:
1456
+ * `const v: string`
1457
+ */
1250
1458
  get type() {
1251
1459
  return this._initializer?.returnType || this._type;
1252
1460
  }
1461
+ /**
1462
+ * Initializer of the variable field, similar to js code:
1463
+ * `const v = 'hello'`
1464
+ *
1465
+ * with initializer, the type of field will be inferred from the initializer.
1466
+ */
1253
1467
  get initializer() {
1254
1468
  return this._initializer;
1255
1469
  }
1470
+ /**
1471
+ * The global unique hash of the field, and will be changed when the field is updated.
1472
+ */
1256
1473
  get hash() {
1257
1474
  return `[${this._version}]${this.keyPath.join(".")}`;
1258
1475
  }
1259
1476
  /**
1260
- * 解析 VariableDeclarationJSON 从而生成变量声明节点
1477
+ * Deserialize the `BaseVariableFieldJSON` to the `BaseVariableField`.
1478
+ * @param json ASTJSON representation of `BaseVariableField`
1261
1479
  */
1262
1480
  fromJSON({ type, initializer, meta }) {
1263
1481
  this.updateType(type);
1264
1482
  this.updateInitializer(initializer);
1265
1483
  this.updateMeta(meta);
1266
1484
  }
1485
+ /**
1486
+ * Update the type of the variable field
1487
+ * @param type type ASTJSON representation of Type
1488
+ */
1267
1489
  updateType(type) {
1268
1490
  const nextTypeJson = typeof type === "string" ? { kind: type } : type;
1269
1491
  this.updateChildNodeByKey("_type", nextTypeJson);
1270
1492
  }
1493
+ /**
1494
+ * Update the initializer of the variable field
1495
+ * @param nextInitializer initializer ASTJSON representation of Expression
1496
+ */
1271
1497
  updateInitializer(nextInitializer) {
1272
1498
  this.updateChildNodeByKey("_initializer", nextInitializer);
1273
1499
  }
1500
+ /**
1501
+ * Update the meta data of the variable field
1502
+ * @param nextMeta meta data of the variable field
1503
+ */
1274
1504
  updateMeta(nextMeta) {
1275
1505
  if (!(0, import_fast_equals5.shallowEqual)(nextMeta, this._meta)) {
1276
1506
  this._meta = nextMeta;
@@ -1278,7 +1508,8 @@ var BaseVariableField = class extends ASTNode {
1278
1508
  }
1279
1509
  }
1280
1510
  /**
1281
- * 根据 keyPath 去找下钻的变量字段
1511
+ * Get the variable field by keyPath, similar to js code:
1512
+ * `v.a.b`
1282
1513
  * @param keyPath
1283
1514
  * @returns
1284
1515
  */
@@ -1289,7 +1520,7 @@ var BaseVariableField = class extends ASTNode {
1289
1520
  return void 0;
1290
1521
  }
1291
1522
  /**
1292
- * 监听类型变化
1523
+ * Subscribe to type change of the variable field
1293
1524
  * @param observer
1294
1525
  * @returns
1295
1526
  */
@@ -1297,8 +1528,8 @@ var BaseVariableField = class extends ASTNode {
1297
1528
  return this.subscribe(observer, { selector: (curr) => curr.type });
1298
1529
  }
1299
1530
  /**
1300
- * 转换为 JSON
1301
- * @returns
1531
+ * Serialize the variable field to JSON
1532
+ * @returns ASTNodeJSON representation of `BaseVariableField`
1302
1533
  */
1303
1534
  toJSON() {
1304
1535
  return {
@@ -1317,16 +1548,23 @@ var VariableDeclaration = class extends BaseVariableField {
1317
1548
  super(params);
1318
1549
  this._order = 0;
1319
1550
  }
1551
+ /**
1552
+ * Variable sorting order, which is used to sort variables in `scope.outputs.variables`
1553
+ */
1320
1554
  get order() {
1321
1555
  return this._order;
1322
1556
  }
1323
1557
  /**
1324
- * 解析 VariableDeclarationJSON 从而生成变量声明节点
1558
+ * Deserialize the `VariableDeclarationJSON` to the `VariableDeclaration`.
1325
1559
  */
1326
1560
  fromJSON({ order, ...rest }) {
1327
1561
  this.updateOrder(order);
1328
1562
  super.fromJSON(rest);
1329
1563
  }
1564
+ /**
1565
+ * Update the sorting order of the variable declaration.
1566
+ * @param order Variable sorting order. Default is 0.
1567
+ */
1330
1568
  updateOrder(order = 0) {
1331
1569
  if (order !== this._order) {
1332
1570
  this._order = order;
@@ -1336,10 +1574,6 @@ var VariableDeclaration = class extends BaseVariableField {
1336
1574
  this.fireChange();
1337
1575
  }
1338
1576
  }
1339
- // 监听类型变化
1340
- onTypeChange(observer) {
1341
- return this.subscribe(observer, { selector: (curr) => curr.type });
1342
- }
1343
1577
  };
1344
1578
  VariableDeclaration.kind = "VariableDeclaration" /* VariableDeclaration */;
1345
1579
 
@@ -1347,8 +1581,18 @@ VariableDeclaration.kind = "VariableDeclaration" /* VariableDeclaration */;
1347
1581
  var VariableDeclarationList = class extends ASTNode {
1348
1582
  constructor() {
1349
1583
  super(...arguments);
1584
+ /**
1585
+ * Map of variable declarations, keyed by variable name.
1586
+ */
1350
1587
  this.declarationTable = /* @__PURE__ */ new Map();
1351
1588
  }
1589
+ /**
1590
+ * Deserialize the `VariableDeclarationListJSON` to the `VariableDeclarationList`.
1591
+ * - VariableDeclarationListChangeAction will be dispatched after deserialization.
1592
+ *
1593
+ * @param declarations Variable declarations.
1594
+ * @param startOrder The starting order number for variables. Default is 0.
1595
+ */
1352
1596
  fromJSON({ declarations, startOrder }) {
1353
1597
  const removedKeys = new Set(this.declarationTable.keys());
1354
1598
  const prev = [...this.declarations || []];
@@ -1388,10 +1632,14 @@ var VariableDeclarationList = class extends ASTNode {
1388
1632
  }
1389
1633
  });
1390
1634
  }
1635
+ /**
1636
+ * Serialize the `VariableDeclarationList` to the `VariableDeclarationListJSON`.
1637
+ * @returns ASTJSON representation of `VariableDeclarationList`
1638
+ */
1391
1639
  toJSON() {
1392
1640
  return {
1393
1641
  kind: "VariableDeclarationList" /* VariableDeclarationList */,
1394
- properties: this.declarations.map((_declaration) => _declaration.toJSON())
1642
+ declarations: this.declarations.map((_declaration) => _declaration.toJSON())
1395
1643
  };
1396
1644
  }
1397
1645
  };
@@ -1405,9 +1653,16 @@ Property.kind = "Property" /* Property */;
1405
1653
  // src/ast/common/data-node.ts
1406
1654
  var import_fast_equals6 = require("fast-equals");
1407
1655
  var DataNode = class extends ASTNode {
1656
+ /**
1657
+ * The data of the node.
1658
+ */
1408
1659
  get data() {
1409
1660
  return this._data;
1410
1661
  }
1662
+ /**
1663
+ * Deserializes the `DataNodeJSON` to the `DataNode`.
1664
+ * @param json The `DataNodeJSON` to deserialize.
1665
+ */
1411
1666
  fromJSON(json) {
1412
1667
  const { kind, ...restData } = json;
1413
1668
  if (!(0, import_fast_equals6.shallowEqual)(restData, this._data)) {
@@ -1415,12 +1670,20 @@ var DataNode = class extends ASTNode {
1415
1670
  this.fireChange();
1416
1671
  }
1417
1672
  }
1673
+ /**
1674
+ * Serialize the `DataNode` to `DataNodeJSON`.
1675
+ * @returns The JSON representation of `DataNode`.
1676
+ */
1418
1677
  toJSON() {
1419
1678
  return {
1420
1679
  kind: "DataNode" /* DataNode */,
1421
1680
  ...this._data
1422
1681
  };
1423
1682
  }
1683
+ /**
1684
+ * Partially update the data of the node.
1685
+ * @param nextData The data to be updated.
1686
+ */
1424
1687
  partialUpdate(nextData) {
1425
1688
  if (!(0, import_fast_equals6.shallowEqual)(nextData, this._data)) {
1426
1689
  this._data = {
@@ -1435,9 +1698,16 @@ DataNode.kind = "DataNode" /* DataNode */;
1435
1698
 
1436
1699
  // src/ast/common/list-node.ts
1437
1700
  var ListNode = class extends ASTNode {
1701
+ /**
1702
+ * The list of nodes.
1703
+ */
1438
1704
  get list() {
1439
1705
  return this._list;
1440
1706
  }
1707
+ /**
1708
+ * Deserializes the `ListNodeJSON` to the `ListNode`.
1709
+ * @param json The `ListNodeJSON` to deserialize.
1710
+ */
1441
1711
  fromJSON({ list }) {
1442
1712
  this._list.slice(list.length).forEach((_item) => {
1443
1713
  _item.dispose();
@@ -1454,6 +1724,10 @@ var ListNode = class extends ASTNode {
1454
1724
  return prevItem;
1455
1725
  });
1456
1726
  }
1727
+ /**
1728
+ * Serialize the `ListNode` to `ListNodeJSON`.
1729
+ * @returns The JSON representation of `ListNode`.
1730
+ */
1457
1731
  toJSON() {
1458
1732
  return {
1459
1733
  kind: "ListNode" /* ListNode */,
@@ -1469,6 +1743,10 @@ var MapNode = class extends ASTNode {
1469
1743
  super(...arguments);
1470
1744
  this.map = /* @__PURE__ */ new Map();
1471
1745
  }
1746
+ /**
1747
+ * Deserializes the `MapNodeJSON` to the `MapNode`.
1748
+ * @param json The `MapNodeJSON` to deserialize.
1749
+ */
1472
1750
  fromJSON({ map: map4 }) {
1473
1751
  const removedKeys = new Set(this.map.keys());
1474
1752
  for (const [key, item] of map4 || []) {
@@ -1479,6 +1757,10 @@ var MapNode = class extends ASTNode {
1479
1757
  this.remove(removeKey);
1480
1758
  }
1481
1759
  }
1760
+ /**
1761
+ * Serialize the `MapNode` to `MapNodeJSON`.
1762
+ * @returns The JSON representation of `MapNode`.
1763
+ */
1482
1764
  toJSON() {
1483
1765
  return {
1484
1766
  kind: "MapNode" /* MapNode */,
@@ -1486,9 +1768,10 @@ var MapNode = class extends ASTNode {
1486
1768
  };
1487
1769
  }
1488
1770
  /**
1489
- * Map 中设置 ASTNode
1490
- * @param key ASTNode 的索引,
1491
- * @param json
1771
+ * Set a node in the map.
1772
+ * @param key The key of the node.
1773
+ * @param nextJSON The JSON representation of the node.
1774
+ * @returns The node instance.
1492
1775
  */
1493
1776
  set(key, nextJSON) {
1494
1777
  return this.withBatchUpdate(updateChildNodeHelper).call(this, {
@@ -1499,8 +1782,8 @@ var MapNode = class extends ASTNode {
1499
1782
  });
1500
1783
  }
1501
1784
  /**
1502
- * 移除指定 ASTNode
1503
- * @param key
1785
+ * Remove a node from the map.
1786
+ * @param key The key of the node.
1504
1787
  */
1505
1788
  remove(key) {
1506
1789
  this.get(key)?.dispose();
@@ -1508,9 +1791,9 @@ var MapNode = class extends ASTNode {
1508
1791
  this.fireChange();
1509
1792
  }
1510
1793
  /**
1511
- * 获取 ASTNode
1512
- * @param key
1513
- * @returns
1794
+ * Get a node from the map.
1795
+ * @param key The key of the node.
1796
+ * @returns The node instance if found, otherwise `undefined`.
1514
1797
  */
1515
1798
  get(key) {
1516
1799
  return this.map.get(key);
@@ -1521,7 +1804,7 @@ MapNode.kind = "MapNode" /* MapNode */;
1521
1804
  // src/ast/ast-registers.ts
1522
1805
  var ASTRegisters = class {
1523
1806
  /**
1524
- * 核心 AST 节点注册
1807
+ * Core AST node registration.
1525
1808
  */
1526
1809
  constructor() {
1527
1810
  this.injectors = /* @__PURE__ */ new Map();
@@ -1537,15 +1820,15 @@ var ASTRegisters = class {
1537
1820
  this.registerAST(Property);
1538
1821
  this.registerAST(VariableDeclaration);
1539
1822
  this.registerAST(VariableDeclarationList);
1540
- this.registerAST(KeyPathExpressionV2);
1823
+ this.registerAST(KeyPathExpression);
1541
1824
  this.registerAST(EnumerateExpression);
1542
1825
  this.registerAST(WrapArrayExpression);
1543
1826
  this.registerAST(MapNode);
1544
1827
  this.registerAST(DataNode);
1545
1828
  }
1546
1829
  /**
1547
- * 创建 AST 节点
1548
- * @param param 创建参数
1830
+ * Creates an AST node.
1831
+ * @param param Creation parameters.
1549
1832
  * @returns
1550
1833
  */
1551
1834
  createAST(json, { parent, scope }) {
@@ -1573,7 +1856,7 @@ var ASTRegisters = class {
1573
1856
  return node;
1574
1857
  }
1575
1858
  /**
1576
- * 根据 AST 节点类型获取节点 Registry
1859
+ * Gets the node Registry by AST node type.
1577
1860
  * @param kind
1578
1861
  * @returns
1579
1862
  */
@@ -1581,7 +1864,7 @@ var ASTRegisters = class {
1581
1864
  return this.astMap.get(kind);
1582
1865
  }
1583
1866
  /**
1584
- * 注册 AST 节点
1867
+ * Registers an AST node.
1585
1868
  * @param ASTNode
1586
1869
  * @param injector
1587
1870
  */
@@ -1661,7 +1944,7 @@ var ScopeOutputData = class {
1661
1944
  this._hasChanges = false;
1662
1945
  this.variableTable = new VariableTable(scope.variableEngine.globalVariableTable);
1663
1946
  this.scope.toDispose.pushAll([
1664
- // When root AST node is updated, check if there are any changes during this AST change
1947
+ // When the root AST node is updated, check if there are any changes.
1665
1948
  this.scope.ast.subscribe(() => {
1666
1949
  if (this._hasChanges) {
1667
1950
  this.memo.clear();
@@ -1686,12 +1969,21 @@ var ScopeOutputData = class {
1686
1969
  this.variableTable
1687
1970
  ]);
1688
1971
  }
1972
+ /**
1973
+ * The variable engine instance.
1974
+ */
1689
1975
  get variableEngine() {
1690
1976
  return this.scope.variableEngine;
1691
1977
  }
1978
+ /**
1979
+ * The global variable table from the variable engine.
1980
+ */
1692
1981
  get globalVariableTable() {
1693
1982
  return this.scope.variableEngine.globalVariableTable;
1694
1983
  }
1984
+ /**
1985
+ * The current version of the output data, which increments on each change.
1986
+ */
1695
1987
  get version() {
1696
1988
  return this.variableTable.version;
1697
1989
  }
@@ -1702,25 +1994,25 @@ var ScopeOutputData = class {
1702
1994
  return this.variableTable.onDataChange.bind(this.variableTable);
1703
1995
  }
1704
1996
  /**
1705
- * listen to variable list change
1997
+ * An event that fires when the list of output variables changes.
1706
1998
  */
1707
1999
  get onVariableListChange() {
1708
2000
  return this.variableTable.onVariableListChange.bind(this.variableTable);
1709
2001
  }
1710
2002
  /**
1711
- * listen to any variable update in list
2003
+ * An event that fires when any output variable's value changes.
1712
2004
  */
1713
2005
  get onAnyVariableChange() {
1714
2006
  return this.variableTable.onAnyVariableChange.bind(this.variableTable);
1715
2007
  }
1716
2008
  /**
1717
- * listen to variable list change + any variable update in list
2009
+ * An event that fires when the output variable list changes or any variable's value is updated.
1718
2010
  */
1719
2011
  get onListOrAnyVarChange() {
1720
2012
  return this.variableTable.onListOrAnyVarChange.bind(this.variableTable);
1721
2013
  }
1722
2014
  /**
1723
- * Scope Output Variable Declarations
2015
+ * The output variable declarations of the scope, sorted by order.
1724
2016
  */
1725
2017
  get variables() {
1726
2018
  return this.memo(
@@ -1729,7 +2021,7 @@ var ScopeOutputData = class {
1729
2021
  );
1730
2022
  }
1731
2023
  /**
1732
- * Output Variable Keys
2024
+ * The keys of the output variables.
1733
2025
  */
1734
2026
  get variableKeys() {
1735
2027
  return this.memo("variableKeys", () => this.variableTable.variableKeys);
@@ -1745,11 +2037,16 @@ var ScopeOutputData = class {
1745
2037
  this.variableTable.removeVariableFromTable(key);
1746
2038
  this._hasChanges = true;
1747
2039
  }
2040
+ /**
2041
+ * Retrieves a variable declaration by its key.
2042
+ * @param key The key of the variable.
2043
+ * @returns The `VariableDeclaration` or `undefined` if not found.
2044
+ */
1748
2045
  getVariableByKey(key) {
1749
2046
  return this.variableTable.getVariableByKey(key);
1750
2047
  }
1751
2048
  /**
1752
- *
2049
+ * Notifies the covering scopes that the available variables have changed.
1753
2050
  */
1754
2051
  notifyCoversChange() {
1755
2052
  this.scope.coverScopes.forEach((scope) => scope.available.refresh());
@@ -1770,22 +2067,24 @@ var ScopeAvailableData = class {
1770
2067
  this.refresh$ = new import_rxjs4.Subject();
1771
2068
  this._variables = [];
1772
2069
  /**
1773
- * 监听
2070
+ * An observable that emits when the list of available variables changes.
1774
2071
  */
1775
2072
  this.variables$ = this.refresh$.pipe(
1776
- // 输出变量是否 version 发生变化
2073
+ // Map to the flattened list of variables from all dependency scopes.
1777
2074
  (0, import_rxjs4.map)(() => (0, import_lodash_es4.flatten)(this.depScopes.map((scope) => scope.output.variables || []))),
1778
- // 变量列表浅比较
2075
+ // Use shallow equality to check if the variable list has changed.
1779
2076
  (0, import_rxjs4.distinctUntilChanged)(import_fast_equals7.shallowEqual),
1780
2077
  (0, import_rxjs4.share)()
1781
2078
  );
1782
- // 监听变量列表中的单个变量变化
2079
+ /**
2080
+ * An observable that emits when any variable in the available list changes its value.
2081
+ */
1783
2082
  this.anyVariableChange$ = this.variables$.pipe(
1784
2083
  (0, import_rxjs4.switchMap)(
1785
2084
  (_variables) => (0, import_rxjs4.merge)(
1786
2085
  ..._variables.map(
1787
2086
  (_v) => _v.value$.pipe(
1788
- // 跳过 BehaviorSubject 第一个
2087
+ // Skip the initial value of the BehaviorSubject.
1789
2088
  (0, import_rxjs4.skip)(1)
1790
2089
  )
1791
2090
  )
@@ -1803,7 +2102,7 @@ var ScopeAvailableData = class {
1803
2102
  */
1804
2103
  this.onDataChange = this.onDataChangeEmitter.event;
1805
2104
  /**
1806
- * listen to variable list change + any variable drilldown change
2105
+ * An event that fires when the variable list changes or any variable's value is updated.
1807
2106
  */
1808
2107
  this.onListOrAnyVarChange = this.onListOrAnyVarChangeEmitter.event;
1809
2108
  this.scope.toDispose.pushAll([
@@ -1825,9 +2124,15 @@ var ScopeAvailableData = class {
1825
2124
  })
1826
2125
  ]);
1827
2126
  }
2127
+ /**
2128
+ * The global variable table from the variable engine.
2129
+ */
1828
2130
  get globalVariableTable() {
1829
2131
  return this.scope.variableEngine.globalVariableTable;
1830
2132
  }
2133
+ /**
2134
+ * The current version of the available data, which increments on each change.
2135
+ */
1831
2136
  get version() {
1832
2137
  return this._version;
1833
2138
  }
@@ -1837,7 +2142,10 @@ var ScopeAvailableData = class {
1837
2142
  this._version = 0;
1838
2143
  }
1839
2144
  }
1840
- // 刷新可访问变量列表
2145
+ /**
2146
+ * Refreshes the list of available variables.
2147
+ * This should be called when the dependencies of the scope change.
2148
+ */
1841
2149
  refresh() {
1842
2150
  if (this.scope.disposed) {
1843
2151
  return;
@@ -1845,43 +2153,43 @@ var ScopeAvailableData = class {
1845
2153
  this.refresh$.next();
1846
2154
  }
1847
2155
  /**
1848
- * listen to any variable update in list
1849
- * @param observer
1850
- * @returns
2156
+ * Subscribes to changes in any variable's value in the available list.
2157
+ * @param observer A function to be called with the changed variable.
2158
+ * @returns A disposable to unsubscribe from the changes.
1851
2159
  */
1852
2160
  onAnyVariableChange(observer) {
1853
2161
  return subsToDisposable(this.anyVariableChange$.subscribe(observer));
1854
2162
  }
1855
2163
  /**
1856
- * listen to variable list change
1857
- * @param observer
1858
- * @returns
2164
+ * Subscribes to changes in the list of available variables.
2165
+ * @param observer A function to be called with the new list of variables.
2166
+ * @returns A disposable to unsubscribe from the changes.
1859
2167
  */
1860
2168
  onVariableListChange(observer) {
1861
2169
  return subsToDisposable(this.variables$.subscribe(observer));
1862
2170
  }
1863
2171
  /**
1864
- * 获取可消费变量
2172
+ * Gets the list of available variables.
1865
2173
  */
1866
2174
  get variables() {
1867
2175
  return this._variables;
1868
2176
  }
1869
2177
  /**
1870
- * 获取可访问的变量 keys
2178
+ * Gets the keys of the available variables.
1871
2179
  */
1872
2180
  get variableKeys() {
1873
2181
  return this.memo("availableKeys", () => this._variables.map((_v) => _v.key));
1874
2182
  }
1875
2183
  /**
1876
- * 返回依赖的作用域
2184
+ * Gets the dependency scopes.
1877
2185
  */
1878
2186
  get depScopes() {
1879
2187
  return this.scope.depScopes;
1880
2188
  }
1881
2189
  /**
1882
- * 通过 keyPath 找到可用变量
1883
- * @param keyPath
1884
- * @returns
2190
+ * Retrieves a variable field by its key path from the available variables.
2191
+ * @param keyPath The key path to the variable field.
2192
+ * @returns The found `BaseVariableField` or `undefined`.
1885
2193
  */
1886
2194
  getByKeyPath(keyPath = []) {
1887
2195
  if (!this.variableKeys.includes(keyPath[0])) {
@@ -1890,8 +2198,12 @@ var ScopeAvailableData = class {
1890
2198
  return this.globalVariableTable.getByKeyPath(keyPath);
1891
2199
  }
1892
2200
  /**
1893
- * Track Variable Change (Includes type update and children update) By KeyPath
1894
- * @returns
2201
+ * Tracks changes to a variable field by its key path.
2202
+ * This includes changes to its type, value, or any nested properties.
2203
+ * @param keyPath The key path to the variable field to track.
2204
+ * @param cb The callback to execute when the variable changes.
2205
+ * @param opts Configuration options for the subscription.
2206
+ * @returns A disposable to unsubscribe from the tracking.
1895
2207
  */
1896
2208
  trackByKeyPath(keyPath = [], cb, opts) {
1897
2209
  const { triggerOnInit = true, debounceAnimation, selector } = opts || {};
@@ -1911,7 +2223,7 @@ var ScopeAvailableData = class {
1911
2223
  return value;
1912
2224
  }
1913
2225
  ),
1914
- // 每个 animationFrame 内所有更新合并成一个
2226
+ // Debounce updates to a single emission per animation frame.
1915
2227
  debounceAnimation ? (0, import_rxjs4.debounceTime)(0, import_rxjs4.animationFrameScheduler) : (0, import_rxjs4.tap)(() => null)
1916
2228
  ).subscribe(cb)
1917
2229
  );
@@ -1930,15 +2242,30 @@ var ScopeEventData = class {
1930
2242
  })
1931
2243
  ]);
1932
2244
  }
2245
+ /**
2246
+ * Dispatches a global event.
2247
+ * @param action The event action to dispatch.
2248
+ */
1933
2249
  dispatch(action) {
1934
2250
  if (this.scope.disposed) {
1935
2251
  return;
1936
2252
  }
1937
2253
  this.event$.next(action);
1938
2254
  }
2255
+ /**
2256
+ * Subscribes to all global events.
2257
+ * @param observer The observer function to call with the event action.
2258
+ * @returns A disposable to unsubscribe from the events.
2259
+ */
1939
2260
  subscribe(observer) {
1940
2261
  return subsToDisposable(this.event$.subscribe(observer));
1941
2262
  }
2263
+ /**
2264
+ * Subscribes to a specific type of global event.
2265
+ * @param type The type of the event to subscribe to.
2266
+ * @param observer The observer function to call with the event action.
2267
+ * @returns A disposable to unsubscribe from the event.
2268
+ */
1942
2269
  on(type, observer) {
1943
2270
  return subsToDisposable(
1944
2271
  this.event$.pipe((0, import_rxjs5.filter)((_action) => _action.type === type)).subscribe(observer)
@@ -1950,7 +2277,7 @@ var ScopeEventData = class {
1950
2277
  var Scope = class {
1951
2278
  constructor(options) {
1952
2279
  /**
1953
- * 数据缓存
2280
+ * A memoization utility for caching computed values.
1954
2281
  */
1955
2282
  this.memo = createMemo();
1956
2283
  this.toDispose = new import_utils7.DisposableCollection();
@@ -1971,25 +2298,41 @@ var Scope = class {
1971
2298
  this.output = new ScopeOutputData(this);
1972
2299
  this.available = new ScopeAvailableData(this);
1973
2300
  }
2301
+ /**
2302
+ * Refreshes the covering scopes.
2303
+ */
1974
2304
  refreshCovers() {
1975
2305
  this.memo.clear("covers");
1976
2306
  }
2307
+ /**
2308
+ * Refreshes the dependency scopes and the available variables.
2309
+ */
1977
2310
  refreshDeps() {
1978
2311
  this.memo.clear("deps");
1979
2312
  this.available.refresh();
1980
2313
  }
2314
+ /**
2315
+ * Gets the scopes that this scope depends on.
2316
+ */
1981
2317
  get depScopes() {
1982
2318
  return this.memo(
1983
2319
  "deps",
1984
2320
  () => this.variableEngine.chain.getDeps(this).filter((_scope) => Boolean(_scope) && !_scope?.disposed)
1985
2321
  );
1986
2322
  }
2323
+ /**
2324
+ * Gets the scopes that are covered by this scope.
2325
+ */
1987
2326
  get coverScopes() {
1988
2327
  return this.memo(
1989
2328
  "covers",
1990
2329
  () => this.variableEngine.chain.getCovers(this).filter((_scope) => Boolean(_scope) && !_scope?.disposed)
1991
2330
  );
1992
2331
  }
2332
+ /**
2333
+ * Disposes of the scope and its resources.
2334
+ * This will also trigger updates in dependent and covering scopes.
2335
+ */
1993
2336
  dispose() {
1994
2337
  this.ast.dispose();
1995
2338
  this.toDispose.dispose();
@@ -2009,19 +2352,18 @@ var Scope = class {
2009
2352
  throw new Error("Invalid arguments");
2010
2353
  }
2011
2354
  /**
2012
- * Retrieves a variable from the Scope by key.
2355
+ * Retrieves a variable from the scope by its key.
2013
2356
  *
2014
- * @param key - The key of the variable to retrieve. Defaults to 'outputs'.
2015
- * @returns The value of the variable, or undefined if not found.
2357
+ * @param key The key of the variable to retrieve. Defaults to 'outputs'.
2358
+ * @returns The AST node for the variable, or `undefined` if not found.
2016
2359
  */
2017
2360
  getVar(key = "outputs") {
2018
2361
  return this.ast.get(key);
2019
2362
  }
2020
2363
  /**
2021
- * Clears a variable from the Scope by key.
2364
+ * Clears a variable from the scope by its key.
2022
2365
  *
2023
- * @param key - The key of the variable to clear. Defaults to 'outputs'.
2024
- * @returns The updated AST node.
2366
+ * @param key The key of the variable to clear. Defaults to 'outputs'.
2025
2367
  */
2026
2368
  clearVar(key = "outputs") {
2027
2369
  return this.ast.remove(key);
@@ -2036,9 +2378,18 @@ var VariableEngine = class {
2036
2378
  this.toDispose = new import_utils8.DisposableCollection();
2037
2379
  this.memo = createMemo();
2038
2380
  this.scopeMap = /* @__PURE__ */ new Map();
2381
+ /**
2382
+ * A rxjs subject that emits global events occurring within the variable engine.
2383
+ */
2039
2384
  this.globalEvent$ = new import_rxjs6.Subject();
2040
2385
  this.onScopeChangeEmitter = new import_utils9.Emitter();
2386
+ /**
2387
+ * A table containing all global variables.
2388
+ */
2041
2389
  this.globalVariableTable = new VariableTable();
2390
+ /**
2391
+ * An event that fires whenever a scope is added, updated, or deleted.
2392
+ */
2042
2393
  this.onScopeChange = this.onScopeChangeEmitter.event;
2043
2394
  this.toDispose.pushAll([
2044
2395
  chain,
@@ -2048,26 +2399,37 @@ var VariableEngine = class {
2048
2399
  })
2049
2400
  ]);
2050
2401
  }
2402
+ /**
2403
+ * The Inversify container instance.
2404
+ */
2051
2405
  get container() {
2052
2406
  return this.containerProvider();
2053
2407
  }
2054
2408
  dispose() {
2055
2409
  this.toDispose.dispose();
2056
2410
  }
2057
- // 根据 scopeId 找到作用域
2411
+ /**
2412
+ * Retrieves a scope by its unique identifier.
2413
+ * @param scopeId The ID of the scope to retrieve.
2414
+ * @returns The scope if found, otherwise undefined.
2415
+ */
2058
2416
  getScopeById(scopeId) {
2059
2417
  return this.scopeMap.get(scopeId);
2060
2418
  }
2061
- // 移除作用域
2419
+ /**
2420
+ * Removes a scope by its unique identifier and disposes of it.
2421
+ * @param scopeId The ID of the scope to remove.
2422
+ */
2062
2423
  removeScopeById(scopeId) {
2063
2424
  this.getScopeById(scopeId)?.dispose();
2064
2425
  }
2065
2426
  /**
2066
- * Get Scope, if Scope exists and type is same, will use it directly
2067
- * @param id scope id
2068
- * @param meta scope meta, defined by user
2069
- * @param ScopeConstructor scope constructor, default is Scope. you can extends Scope to create your own scope
2070
- * @returns
2427
+ * Creates a new scope or retrieves an existing one if the ID and type match.
2428
+ * @param id The unique identifier for the scope.
2429
+ * @param meta Optional metadata for the scope, defined by the user.
2430
+ * @param options Options for creating the scope.
2431
+ * @param options.ScopeConstructor The constructor to use for creating the scope. Defaults to `Scope`.
2432
+ * @returns The created or existing scope.
2071
2433
  */
2072
2434
  createScope(id, meta, options = {}) {
2073
2435
  const { ScopeConstructor = Scope } = options;
@@ -2080,7 +2442,7 @@ var VariableEngine = class {
2080
2442
  scope.ast.subscribe(() => {
2081
2443
  this.onScopeChangeEmitter.fire({ type: "update", scope });
2082
2444
  }),
2083
- // 可用变量发生变化
2445
+ // Fires when available variables change
2084
2446
  scope.available.onDataChange(() => {
2085
2447
  this.onScopeChangeEmitter.fire({ type: "available", scope });
2086
2448
  })
@@ -2092,7 +2454,12 @@ var VariableEngine = class {
2092
2454
  }
2093
2455
  return scope;
2094
2456
  }
2095
- // 获取系统中所有的作用域
2457
+ /**
2458
+ * Retrieves all scopes currently managed by the engine.
2459
+ * @param options Options for retrieving the scopes.
2460
+ * @param options.sort Whether to sort the scopes based on their dependency chain.
2461
+ * @returns An array of all scopes.
2462
+ */
2096
2463
  getAllScopes({
2097
2464
  sort
2098
2465
  } = {}) {
@@ -2105,9 +2472,19 @@ var VariableEngine = class {
2105
2472
  }
2106
2473
  return [...allScopes];
2107
2474
  }
2475
+ /**
2476
+ * Fires a global event to be broadcast to all listeners.
2477
+ * @param event The global event to fire.
2478
+ */
2108
2479
  fireGlobalEvent(event) {
2109
2480
  this.globalEvent$.next(event);
2110
2481
  }
2482
+ /**
2483
+ * Subscribes to a specific type of global event.
2484
+ * @param type The type of the event to listen for.
2485
+ * @param observer A function to be called when the event is observed.
2486
+ * @returns A disposable object to unsubscribe from the event.
2487
+ */
2111
2488
  onGlobalEvent(type, observer) {
2112
2489
  return subsToDisposable(
2113
2490
  this.globalEvent$.subscribe((_action) => {
@@ -2138,11 +2515,26 @@ var VariableFieldKeyRenameService = class {
2138
2515
  constructor() {
2139
2516
  this.toDispose = new import_utils10.DisposableCollection();
2140
2517
  this.renameEmitter = new import_utils10.Emitter();
2141
- // 没有被 rename 的字段通过 disposeInList 透出,让业务区分变量是 rename 删除的,还是真正从列表中删除的
2518
+ /**
2519
+ * Emits events for fields that are disposed of during a list change, but not renamed.
2520
+ * This helps distinguish between a field that was truly removed and one that was renamed.
2521
+ */
2142
2522
  this.disposeInListEmitter = new import_utils10.Emitter();
2523
+ /**
2524
+ * An event that fires when a variable field key is successfully renamed.
2525
+ */
2143
2526
  this.onRename = this.renameEmitter.event;
2527
+ /**
2528
+ * An event that fires when a field is removed from a list (and not part of a rename).
2529
+ */
2144
2530
  this.onDisposeInList = this.disposeInListEmitter.event;
2145
2531
  }
2532
+ /**
2533
+ * Handles changes in a list of fields to detect rename operations.
2534
+ * @param ast The AST node where the change occurred.
2535
+ * @param prev The list of fields before the change.
2536
+ * @param next The list of fields after the change.
2537
+ */
2146
2538
  handleFieldListChange(ast, prev, next) {
2147
2539
  if (!ast || !prev?.length || !next?.length) {
2148
2540
  this.notifyFieldsDispose(prev, next);
@@ -2173,6 +2565,11 @@ var VariableFieldKeyRenameService = class {
2173
2565
  }
2174
2566
  this.renameEmitter.fire(renameNodeInfo);
2175
2567
  }
2568
+ /**
2569
+ * Notifies listeners about fields that were removed from a list.
2570
+ * @param prev The list of fields before the change.
2571
+ * @param next The list of fields after the change.
2572
+ */
2176
2573
  notifyFieldsDispose(prev, next) {
2177
2574
  const removedFields = (0, import_lodash_es5.difference)(prev || [], next || []);
2178
2575
  removedFields.forEach((_field) => this.disposeInListEmitter.fire(_field));
@@ -2220,28 +2617,48 @@ var VariableContainerModule = new import_inversify8.ContainerModule((bind) => {
2220
2617
  });
2221
2618
 
2222
2619
  // src/react/context.tsx
2223
- var import_react = require("react");
2620
+ var import_react = __toESM(require("react"));
2224
2621
  var ScopeContext = (0, import_react.createContext)(null);
2225
- var ScopeProvider = ScopeContext.Provider;
2226
- var useScopeContext = () => (0, import_react.useContext)(ScopeContext);
2227
- var useCurrentScope = () => (0, import_react.useContext)(ScopeContext)?.scope;
2622
+ var ScopeProvider = (props) => {
2623
+ const { scope, value, children } = props;
2624
+ const scopeToUse = scope || value?.scope;
2625
+ if (!scopeToUse) {
2626
+ throw new Error("[ScopeProvider] scope is required");
2627
+ }
2628
+ return /* @__PURE__ */ import_react.default.createElement(ScopeContext.Provider, { value: { scope: scopeToUse } }, children);
2629
+ };
2630
+ var useCurrentScope = (params) => {
2631
+ const { strict = false } = params || {};
2632
+ const context = (0, import_react.useContext)(ScopeContext);
2633
+ if (!context) {
2634
+ if (strict) {
2635
+ throw new Error("useCurrentScope must be used within a <ScopeProvider scope={scope}>");
2636
+ }
2637
+ console.warn("useCurrentScope should be used within a <ScopeProvider scope={scope}>");
2638
+ }
2639
+ return context?.scope;
2640
+ };
2228
2641
 
2229
- // src/react/hooks/useScopeAvailable.ts
2642
+ // src/react/hooks/use-scope-available.ts
2230
2643
  var import_react2 = require("react");
2231
2644
  var import_core = require("@flowgram.ai/core");
2232
- function useScopeAvailable() {
2233
- const scope = useCurrentScope();
2645
+ function useScopeAvailable(params) {
2646
+ const { autoRefresh = true } = params || {};
2647
+ const scope = useCurrentScope({ strict: true });
2234
2648
  const refresh = (0, import_core.useRefresh)();
2235
2649
  (0, import_react2.useEffect)(() => {
2236
- const disposable = scope.available.onDataChange(() => {
2650
+ if (!autoRefresh) {
2651
+ return () => null;
2652
+ }
2653
+ const disposable = scope.available.onListOrAnyVarChange(() => {
2237
2654
  refresh();
2238
2655
  });
2239
2656
  return () => disposable.dispose();
2240
- }, []);
2657
+ }, [autoRefresh]);
2241
2658
  return scope.available;
2242
2659
  }
2243
2660
 
2244
- // src/react/hooks/useAvailableVariables.ts
2661
+ // src/react/hooks/use-available-variables.ts
2245
2662
  var import_react3 = require("react");
2246
2663
  var import_core2 = require("@flowgram.ai/core");
2247
2664
  function useAvailableVariables() {
@@ -2262,6 +2679,26 @@ function useAvailableVariables() {
2262
2679
  }, []);
2263
2680
  return scope ? scope.available.variables : variableEngine.globalVariableTable.variables;
2264
2681
  }
2682
+
2683
+ // src/react/hooks/use-output-variables.ts
2684
+ var import_react4 = require("react");
2685
+ var import_core3 = require("@flowgram.ai/core");
2686
+ function useOutputVariables() {
2687
+ const scope = useCurrentScope();
2688
+ const refresh = (0, import_core3.useRefresh)();
2689
+ (0, import_react4.useEffect)(() => {
2690
+ if (!scope) {
2691
+ throw new Error(
2692
+ "[useOutputVariables]: No scope found, useOutputVariables must be used in <ScopeProvider>"
2693
+ );
2694
+ }
2695
+ const disposable = scope.output.onListOrAnyVarChange(() => {
2696
+ refresh();
2697
+ });
2698
+ return () => disposable.dispose();
2699
+ }, []);
2700
+ return scope?.output.variables || [];
2701
+ }
2265
2702
  // Annotate the CommonJS export names for ESM import in node:
2266
2703
  0 && (module.exports = {
2267
2704
  ASTFactory,
@@ -2280,7 +2717,7 @@ function useAvailableVariables() {
2280
2717
  EnumerateExpression,
2281
2718
  IntegerType,
2282
2719
  KeyPathExpression,
2283
- KeyPathExpressionV2,
2720
+ LegacyKeyPathExpression,
2284
2721
  ListNode,
2285
2722
  MapNode,
2286
2723
  MapType,
@@ -2304,7 +2741,7 @@ function useAvailableVariables() {
2304
2741
  postConstructAST,
2305
2742
  useAvailableVariables,
2306
2743
  useCurrentScope,
2307
- useScopeAvailable,
2308
- useScopeContext
2744
+ useOutputVariables,
2745
+ useScopeAvailable
2309
2746
  });
2310
2747
  //# sourceMappingURL=index.js.map