@flowgram.ai/variable-core 0.5.4 → 0.5.6

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/esm/index.js CHANGED
@@ -60,13 +60,15 @@ var VariableTable = class {
60
60
  */
61
61
  this.onDataChangeEmitter = new Emitter();
62
62
  this.variables$ = new Subject();
63
- // 监听变量列表中的单个变量变化
63
+ /**
64
+ * An observable that listens for value changes on any variable within the table.
65
+ */
64
66
  this.anyVariableChange$ = this.variables$.pipe(
65
67
  switchMap(
66
68
  (_variables) => merge(
67
69
  ..._variables.map(
68
70
  (_v) => _v.value$.pipe(
69
- // 跳过 BehaviorSubject 第一个
71
+ // Skip the initial value of the BehaviorSubject
70
72
  skip(1)
71
73
  )
72
74
  )
@@ -75,68 +77,84 @@ var VariableTable = class {
75
77
  share()
76
78
  );
77
79
  /**
78
- * @deprecated use onListOrAnyVarChange instead
80
+ * @deprecated Use onListOrAnyVarChange instead.
79
81
  */
80
82
  this.onDataChange = this.onDataChangeEmitter.event;
81
83
  this._version = 0;
82
84
  this.toDispose.pushAll([
83
85
  this.onDataChangeEmitter,
84
- // active share()
86
+ // Activate the share() operator
85
87
  this.onAnyVariableChange(() => {
86
88
  this.bumpVersion();
87
89
  })
88
90
  ]);
89
91
  }
90
92
  /**
91
- * listen to any variable update in list
92
- * @param observer
93
- * @returns
93
+ * Subscribes to updates on any variable in the list.
94
+ * @param observer A function to be called when any variable's value changes.
95
+ * @returns A disposable object to unsubscribe from the updates.
94
96
  */
95
97
  onAnyVariableChange(observer) {
96
98
  return subsToDisposable(this.anyVariableChange$.subscribe(observer));
97
99
  }
98
100
  /**
99
- * listen to variable list change
100
- * @param observer
101
- * @returns
101
+ * Subscribes to changes in the variable list (additions or removals).
102
+ * @param observer A function to be called when the list of variables changes.
103
+ * @returns A disposable object to unsubscribe from the updates.
102
104
  */
103
105
  onVariableListChange(observer) {
104
106
  return subsToDisposable(this.variables$.subscribe(observer));
105
107
  }
106
108
  /**
107
- * listen to variable list change + any variable update in list
108
- * @param observer
109
+ * Subscribes to both variable list changes and updates to any variable in the list.
110
+ * @param observer A function to be called when either the list or a variable in it changes.
111
+ * @returns A disposable collection to unsubscribe from both events.
109
112
  */
110
113
  onListOrAnyVarChange(observer) {
111
114
  const disposables = new DisposableCollection();
112
115
  disposables.pushAll([this.onVariableListChange(observer), this.onAnyVariableChange(observer)]);
113
116
  return disposables;
114
117
  }
118
+ /**
119
+ * Fires change events to notify listeners that the data has been updated.
120
+ */
115
121
  fireChange() {
116
122
  this.bumpVersion();
117
123
  this.onDataChangeEmitter.fire();
118
124
  this.variables$.next(this.variables);
119
125
  this.parentTable?.fireChange();
120
126
  }
127
+ /**
128
+ * The current version of the variable table, incremented on each change.
129
+ */
121
130
  get version() {
122
131
  return this._version;
123
132
  }
133
+ /**
134
+ * Increments the version number, resetting to 0 if it reaches MAX_SAFE_INTEGER.
135
+ */
124
136
  bumpVersion() {
125
137
  this._version = this._version + 1;
126
138
  if (this._version === Number.MAX_SAFE_INTEGER) {
127
139
  this._version = 0;
128
140
  }
129
141
  }
142
+ /**
143
+ * An array of all variables in the table.
144
+ */
130
145
  get variables() {
131
146
  return Array.from(this.table.values());
132
147
  }
148
+ /**
149
+ * An array of all variable keys in the table.
150
+ */
133
151
  get variableKeys() {
134
152
  return Array.from(this.table.keys());
135
153
  }
136
154
  /**
137
- * 根据 keyPath 找到对应的变量,或 Property 节点
138
- * @param keyPath
139
- * @returns
155
+ * Retrieves a variable or a nested property field by its key path.
156
+ * @param keyPath An array of keys representing the path to the desired field.
157
+ * @returns The found variable or property field, or undefined if not found.
140
158
  */
141
159
  getByKeyPath(keyPath) {
142
160
  const [variableKey, ...propertyKeys] = keyPath || [];
@@ -147,16 +165,17 @@ var VariableTable = class {
147
165
  return propertyKeys.length ? variable?.getByKeyPath(propertyKeys) : variable;
148
166
  }
149
167
  /**
150
- * 根据 key 值找到相应的变量
151
- * @param key
152
- * @returns
168
+ * Retrieves a variable by its key.
169
+ * @param key The key of the variable to retrieve.
170
+ * @returns The variable declaration if found, otherwise undefined.
153
171
  */
154
172
  getVariableByKey(key) {
155
173
  return this.table.get(key);
156
174
  }
157
175
  /**
158
- * variableTable 添加输出变量
159
- * @param variable
176
+ * Adds a variable to the table.
177
+ * If a parent table exists, the variable is also added to the parent.
178
+ * @param variable The variable declaration to add.
160
179
  */
161
180
  addVariableToTable(variable) {
162
181
  this.table.set(variable.key, variable);
@@ -165,8 +184,9 @@ var VariableTable = class {
165
184
  }
166
185
  }
167
186
  /**
168
- * variableTable 中移除变量
169
- * @param key
187
+ * Removes a variable from the table.
188
+ * If a parent table exists, the variable is also removed from the parent.
189
+ * @param key The key of the variable to remove.
170
190
  */
171
191
  removeVariableFromTable(key) {
172
192
  this.table.delete(key);
@@ -174,6 +194,9 @@ var VariableTable = class {
174
194
  this.parentTable.removeVariableFromTable(key);
175
195
  }
176
196
  }
197
+ /**
198
+ * Disposes of all resources used by the variable table.
199
+ */
177
200
  dispose() {
178
201
  this.variableKeys.forEach(
179
202
  (_key) => this.parentTable?.removeVariableFromTable(_key)
@@ -202,7 +225,7 @@ var ScopeChain = class {
202
225
  return this.variableEngineProvider();
203
226
  }
204
227
  /**
205
- * 所有作用域依赖关系刷新
228
+ * Refreshes the dependency and coverage relationships for all scopes.
206
229
  */
207
230
  refreshAllChange() {
208
231
  this.variableEngine.getAllScopes().forEach((_scope) => {
@@ -286,6 +309,19 @@ var postConstructAST = () => (target, propertyKey) => {
286
309
  }
287
310
  };
288
311
 
312
+ // src/ast/flags.ts
313
+ var ASTNodeFlags = /* @__PURE__ */ ((ASTNodeFlags2) => {
314
+ ASTNodeFlags2[ASTNodeFlags2["None"] = 0] = "None";
315
+ ASTNodeFlags2[ASTNodeFlags2["VariableField"] = 1] = "VariableField";
316
+ ASTNodeFlags2[ASTNodeFlags2["Expression"] = 4] = "Expression";
317
+ ASTNodeFlags2[ASTNodeFlags2["BasicType"] = 8] = "BasicType";
318
+ ASTNodeFlags2[ASTNodeFlags2["DrilldownType"] = 16] = "DrilldownType";
319
+ ASTNodeFlags2[ASTNodeFlags2["EnumerateType"] = 32] = "EnumerateType";
320
+ ASTNodeFlags2[ASTNodeFlags2["UnionType"] = 64] = "UnionType";
321
+ ASTNodeFlags2[ASTNodeFlags2["VariableType"] = 120] = "VariableType";
322
+ return ASTNodeFlags2;
323
+ })(ASTNodeFlags || {});
324
+
289
325
  // src/ast/match.ts
290
326
  var ASTMatch;
291
327
  ((ASTMatch2) => {
@@ -299,8 +335,10 @@ var ASTMatch;
299
335
  ASTMatch2.isCustomType = (node) => node?.kind === "CustomType" /* CustomType */;
300
336
  ASTMatch2.isVariableDeclaration = (node) => node?.kind === "VariableDeclaration" /* VariableDeclaration */;
301
337
  ASTMatch2.isProperty = (node) => node?.kind === "Property" /* Property */;
338
+ ASTMatch2.isBaseVariableField = (node) => !!(node?.flags || 0 & 1 /* VariableField */);
302
339
  ASTMatch2.isVariableDeclarationList = (node) => node?.kind === "VariableDeclarationList" /* VariableDeclarationList */;
303
340
  ASTMatch2.isEnumerateExpression = (node) => node?.kind === "EnumerateExpression" /* EnumerateExpression */;
341
+ ASTMatch2.isWrapArrayExpression = (node) => node?.kind === "WrapArrayExpression" /* WrapArrayExpression */;
304
342
  ASTMatch2.isKeyPathExpression = (node) => node?.kind === "KeyPathExpression" /* KeyPathExpression */;
305
343
  function is(node, targetType) {
306
344
  return node?.kind === targetType?.kind;
@@ -346,19 +384,6 @@ function isMatchAST(node, targetType) {
346
384
  return ASTMatch.is(node, targetType);
347
385
  }
348
386
 
349
- // src/ast/flags.ts
350
- var ASTNodeFlags = /* @__PURE__ */ ((ASTNodeFlags2) => {
351
- ASTNodeFlags2[ASTNodeFlags2["None"] = 0] = "None";
352
- ASTNodeFlags2[ASTNodeFlags2["VariableField"] = 1] = "VariableField";
353
- ASTNodeFlags2[ASTNodeFlags2["Expression"] = 4] = "Expression";
354
- ASTNodeFlags2[ASTNodeFlags2["BasicType"] = 8] = "BasicType";
355
- ASTNodeFlags2[ASTNodeFlags2["DrilldownType"] = 16] = "DrilldownType";
356
- ASTNodeFlags2[ASTNodeFlags2["EnumerateType"] = 32] = "EnumerateType";
357
- ASTNodeFlags2[ASTNodeFlags2["UnionType"] = 64] = "UnionType";
358
- ASTNodeFlags2[ASTNodeFlags2["VariableType"] = 120] = "VariableType";
359
- return ASTNodeFlags2;
360
- })(ASTNodeFlags || {});
361
-
362
387
  // src/ast/ast-node.ts
363
388
  import {
364
389
  BehaviorSubject,
@@ -374,41 +399,44 @@ import { shallowEqual } from "fast-equals";
374
399
  import { Disposable as Disposable2, DisposableCollection as DisposableCollection3 } from "@flowgram.ai/utils";
375
400
  var ASTNode = class _ASTNode {
376
401
  /**
377
- * 构造函数
378
- * @param createParams 创建 ASTNode 的必要参数
379
- * @param injectOptions 依赖注入各种模块
402
+ * Constructor.
403
+ * @param createParams Necessary parameters for creating an ASTNode.
404
+ * @param injectOptions Dependency injection for various modules.
380
405
  */
381
406
  constructor({ key, parent, scope }, opts) {
382
407
  /**
383
- * 节点 Flags,记录一些 Flag 信息
408
+ * Node flags, used to record some flag information.
384
409
  */
385
410
  this.flags = 0 /* None */;
386
411
  /**
387
- * 节点的版本号,每 fireChange 一次 version + 1
412
+ * The version number of the ASTNode, which increments by 1 each time `fireChange` is called.
388
413
  */
389
414
  this._version = 0;
390
415
  /**
391
- * 更新锁
416
+ * Update lock.
417
+ * - When set to `true`, `fireChange` will not trigger any events.
418
+ * - This is useful when multiple updates are needed, and you want to avoid multiple triggers.
392
419
  */
393
420
  this.changeLocked = false;
394
421
  /**
395
- * Batch Update 相关参数
422
+ * Parameters related to batch updates.
396
423
  */
397
424
  this._batch = {
398
425
  batching: false,
399
426
  hasChangesInBatch: false
400
427
  };
401
428
  /**
402
- * AST 节点变化事件,基于 Rxjs 实现
403
- * - 使用了 BehaviorSubject, 在订阅时会自动触发一次事件,事件为当前值
429
+ * AST node change Observable events, implemented based on RxJS.
430
+ * - Emits the current ASTNode value upon subscription.
431
+ * - Emits a new value whenever `fireChange` is called.
404
432
  */
405
433
  this.value$ = new BehaviorSubject(this);
406
434
  /**
407
- * 子节点
435
+ * Child ASTNodes.
408
436
  */
409
437
  this._children = /* @__PURE__ */ new Set();
410
438
  /**
411
- * 删除节点处理事件列表
439
+ * List of disposal handlers for the ASTNode.
412
440
  */
413
441
  this.toDispose = new DisposableCollection3(
414
442
  Disposable2.create(() => {
@@ -417,7 +445,7 @@ var ASTNode = class _ASTNode {
417
445
  })
418
446
  );
419
447
  /**
420
- * 销毁时触发的回调
448
+ * Callback triggered upon disposal.
421
449
  */
422
450
  this.onDispose = this.toDispose.onDispose;
423
451
  this.scope = scope;
@@ -427,7 +455,7 @@ var ASTNode = class _ASTNode {
427
455
  this.fromJSON = this.withBatchUpdate(this.fromJSON.bind(this));
428
456
  }
429
457
  /**
430
- * AST 节点的类型
458
+ * The type of the ASTNode.
431
459
  */
432
460
  get kind() {
433
461
  if (!this.constructor.kind) {
@@ -436,13 +464,13 @@ var ASTNode = class _ASTNode {
436
464
  return this.constructor.kind;
437
465
  }
438
466
  /**
439
- * 获取当前节点所有子节点
467
+ * Gets all child ASTNodes of the current ASTNode.
440
468
  */
441
469
  get children() {
442
470
  return Array.from(this._children);
443
471
  }
444
472
  /**
445
- * 转化为 ASTNodeJSON
473
+ * Serializes the current ASTNode to ASTNodeJSON.
446
474
  * @returns
447
475
  */
448
476
  toJSON() {
@@ -452,8 +480,8 @@ var ASTNode = class _ASTNode {
452
480
  };
453
481
  }
454
482
  /**
455
- * 创建子节点
456
- * @param json 子节点的 AST JSON
483
+ * Creates a child ASTNode.
484
+ * @param json The AST JSON of the child ASTNode.
457
485
  * @returns
458
486
  */
459
487
  createChildNode(json) {
@@ -471,8 +499,8 @@ var ASTNode = class _ASTNode {
471
499
  return child;
472
500
  }
473
501
  /**
474
- * 更新子节点,快速实现子节点更新消费逻辑
475
- * @param keyInThis 当前对象上的指定 key
502
+ * Updates a child ASTNode, quickly implementing the consumption logic for child ASTNode updates.
503
+ * @param keyInThis The specified key on the current object.
476
504
  */
477
505
  updateChildNodeByKey(keyInThis, nextJSON) {
478
506
  this.withBatchUpdate(updateChildNodeHelper).call(this, {
@@ -483,8 +511,8 @@ var ASTNode = class _ASTNode {
483
511
  });
484
512
  }
485
513
  /**
486
- * 批处理更新,批处理函数内所有的 fireChange 都合并成一个
487
- * @param updater 批处理函数
514
+ * Batch updates the ASTNode, merging all `fireChange` calls within the batch function into one.
515
+ * @param updater The batch function.
488
516
  * @returns
489
517
  */
490
518
  withBatchUpdate(updater) {
@@ -504,7 +532,7 @@ var ASTNode = class _ASTNode {
504
532
  };
505
533
  }
506
534
  /**
507
- * 触发当前节点更新
535
+ * Triggers an update for the current node.
508
536
  */
509
537
  fireChange() {
510
538
  if (this.changeLocked || this.disposed) {
@@ -520,22 +548,24 @@ var ASTNode = class _ASTNode {
520
548
  this.parent?.fireChange();
521
549
  }
522
550
  /**
523
- * 节点的版本值
524
- * - 通过 NodeA === NodeB && versionA === versionB 可以比较两者是否相等
551
+ * The version value of the ASTNode.
552
+ * - You can used to check whether ASTNode are updated.
525
553
  */
526
554
  get version() {
527
555
  return this._version;
528
556
  }
529
557
  /**
530
- * 节点唯一 hash
558
+ * The unique hash value of the ASTNode.
559
+ * - It will update when the ASTNode is updated.
560
+ * - You can used to check two ASTNode are equal.
531
561
  */
532
562
  get hash() {
533
563
  return `${this._version}${this.kind}${this.key}`;
534
564
  }
535
565
  /**
536
- * 监听 AST 节点的变化
537
- * @param observer 监听回调
538
- * @param selector 监听指定数据
566
+ * Listens for changes to the ASTNode.
567
+ * @param observer The listener callback.
568
+ * @param selector Listens for specified data.
539
569
  * @returns
540
570
  */
541
571
  subscribe(observer, { selector, debounceAnimation, triggerOnInit } = {}) {
@@ -551,13 +581,17 @@ var ASTNode = class _ASTNode {
551
581
  return value;
552
582
  }
553
583
  ),
554
- // 默认跳过 BehaviorSubject 第一次触发
584
+ // By default, skip the first trigger of BehaviorSubject.
555
585
  triggerOnInit ? tap(() => null) : skip2(1),
556
- // 每个 animationFrame 内所有更新合并成一个
586
+ // All updates within each animationFrame are merged into one.
557
587
  debounceAnimation ? debounceTime(0, animationFrameScheduler) : tap(() => null)
558
588
  ).subscribe(observer)
559
589
  );
560
590
  }
591
+ /**
592
+ * Dispatches a global event for the current ASTNode.
593
+ * @param event The global event.
594
+ */
561
595
  dispatchGlobalEvent(event) {
562
596
  this.scope.event.dispatch({
563
597
  ...event,
@@ -565,7 +599,7 @@ var ASTNode = class _ASTNode {
565
599
  });
566
600
  }
567
601
  /**
568
- * 销毁
602
+ * Disposes the ASTNode.
569
603
  */
570
604
  dispose() {
571
605
  if (this.toDispose.disposed) {
@@ -588,8 +622,9 @@ var BaseType = class extends ASTNode {
588
622
  this.flags = 8 /* BasicType */;
589
623
  }
590
624
  /**
591
- * 类型是否一致
592
- * @param targetTypeJSON
625
+ * Check if the current type is equal to the target type.
626
+ * @param targetTypeJSONOrKind The type to compare with.
627
+ * @returns `true` if the types are equal, `false` otherwise.
593
628
  */
594
629
  isTypeEqual(targetTypeJSONOrKind) {
595
630
  const targetTypeJSON = parseTypeJsonOrKind(targetTypeJSONOrKind);
@@ -601,15 +636,18 @@ var BaseType = class extends ASTNode {
601
636
  return this.kind === targetTypeJSON?.kind;
602
637
  }
603
638
  /**
604
- * 可下钻类型需实现
605
- * @param keyPath
639
+ * Get a variable field by key path.
640
+ *
641
+ * This method should be implemented by drillable types.
642
+ * @param keyPath The key path to search for.
643
+ * @returns The variable field if found, otherwise `undefined`.
606
644
  */
607
645
  getByKeyPath(keyPath = []) {
608
646
  throw new Error(`Get By Key Path is not implemented for Type: ${this.kind}`);
609
647
  }
610
648
  /**
611
- * Get AST JSON for current base type
612
- * @returns
649
+ * Serialize the node to a JSON object.
650
+ * @returns The JSON representation of the node.
613
651
  */
614
652
  toJSON() {
615
653
  return {
@@ -624,13 +662,24 @@ var ArrayType = class extends BaseType {
624
662
  super(...arguments);
625
663
  this.flags = 16 /* DrilldownType */ | 32 /* EnumerateType */;
626
664
  }
665
+ /**
666
+ * Deserializes the `ArrayJSON` to the `ArrayType`.
667
+ * @param json The `ArrayJSON` to deserialize.
668
+ */
627
669
  fromJSON({ items }) {
628
670
  this.updateChildNodeByKey("items", parseTypeJsonOrKind(items));
629
671
  }
630
- // items 类型是否可下钻
672
+ /**
673
+ * Whether the items type can be drilled down.
674
+ */
631
675
  get canDrilldownItems() {
632
676
  return !!(this.items?.flags & 16 /* DrilldownType */);
633
677
  }
678
+ /**
679
+ * Get a variable field by key path.
680
+ * @param keyPath The key path to search for.
681
+ * @returns The variable field if found, otherwise `undefined`.
682
+ */
634
683
  getByKeyPath(keyPath) {
635
684
  const [curr, ...rest] = keyPath || [];
636
685
  if (curr === "0" && this.canDrilldownItems) {
@@ -638,19 +687,24 @@ var ArrayType = class extends BaseType {
638
687
  }
639
688
  return void 0;
640
689
  }
690
+ /**
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.
694
+ */
641
695
  isTypeEqual(targetTypeJSONOrKind) {
642
696
  const targetTypeJSON = parseTypeJsonOrKind(targetTypeJSONOrKind);
643
697
  const isSuperEqual = super.isTypeEqual(targetTypeJSONOrKind);
644
698
  if (targetTypeJSON?.weak || targetTypeJSON?.kind === "Union" /* Union */) {
645
699
  return isSuperEqual;
646
700
  }
647
- return targetTypeJSON && isSuperEqual && // 弱比较,只需要比较 Kind 即可
701
+ return targetTypeJSON && isSuperEqual && // Weak comparison, only need to compare the Kind.
648
702
  (targetTypeJSON?.weak || this.customStrongEqual(targetTypeJSON));
649
703
  }
650
704
  /**
651
- * Array 强比较
652
- * @param targetTypeJSON
653
- * @returns
705
+ * Array strong comparison.
706
+ * @param targetTypeJSON The type to compare with.
707
+ * @returns `true` if the types are equal, `false` otherwise.
654
708
  */
655
709
  customStrongEqual(targetTypeJSON) {
656
710
  if (!this.items) {
@@ -658,6 +712,10 @@ var ArrayType = class extends BaseType {
658
712
  }
659
713
  return this.items?.isTypeEqual(targetTypeJSON.items);
660
714
  }
715
+ /**
716
+ * Serialize the `ArrayType` to `ArrayJSON`
717
+ * @returns The JSON representation of `ArrayType`.
718
+ */
661
719
  toJSON() {
662
720
  return {
663
721
  kind: "Array" /* Array */,
@@ -674,11 +732,16 @@ var StringType = class extends BaseType {
674
732
  this.flags = 8 /* BasicType */;
675
733
  }
676
734
  /**
677
- * https://json-schema.org/understanding-json-schema/reference/type#format
735
+ * see https://json-schema.org/understanding-json-schema/reference/string#format
678
736
  */
679
737
  get format() {
680
738
  return this._format;
681
739
  }
740
+ /**
741
+ * Deserialize the `StringJSON` to the `StringType`.
742
+ *
743
+ * @param json StringJSON representation of the `StringType`.
744
+ */
682
745
  fromJSON(json) {
683
746
  if (json?.format !== this._format) {
684
747
  this._format = json?.format;
@@ -694,6 +757,10 @@ var IntegerType = class extends BaseType {
694
757
  super(...arguments);
695
758
  this.flags = 8 /* BasicType */;
696
759
  }
760
+ /**
761
+ * Deserializes the `IntegerJSON` to the `IntegerType`.
762
+ * @param json The `IntegerJSON` to deserialize.
763
+ */
697
764
  fromJSON() {
698
765
  }
699
766
  };
@@ -701,6 +768,10 @@ IntegerType.kind = "Integer" /* Integer */;
701
768
 
702
769
  // src/ast/type/boolean.ts
703
770
  var BooleanType = class extends BaseType {
771
+ /**
772
+ * Deserializes the `BooleanJSON` to the `BooleanType`.
773
+ * @param json The `BooleanJSON` to deserialize.
774
+ */
704
775
  fromJSON() {
705
776
  }
706
777
  };
@@ -708,6 +779,10 @@ BooleanType.kind = "Boolean" /* Boolean */;
708
779
 
709
780
  // src/ast/type/number.ts
710
781
  var NumberType = class extends BaseType {
782
+ /**
783
+ * Deserializes the `NumberJSON` to the `NumberType`.
784
+ * @param json The `NumberJSON` to deserialize.
785
+ */
711
786
  fromJSON() {
712
787
  }
713
788
  };
@@ -715,40 +790,42 @@ NumberType.kind = "Number" /* Number */;
715
790
 
716
791
  // src/ast/type/map.ts
717
792
  var MapType = class extends BaseType {
793
+ /**
794
+ * Deserializes the `MapJSON` to the `MapType`.
795
+ * @param json The `MapJSON` to deserialize.
796
+ */
718
797
  fromJSON({ keyType = "String" /* String */, valueType }) {
719
798
  this.updateChildNodeByKey("keyType", parseTypeJsonOrKind(keyType));
720
799
  this.updateChildNodeByKey("valueType", parseTypeJsonOrKind(valueType));
721
800
  }
722
- // Value 类型是否可下钻,后续实现
723
- // get canDrilldownValue(): boolean {
724
- // return !!(this.valueType.flags & ASTNodeFlags.DrilldownType);
725
- // }
726
- // getByKeyPath(keyPath: string[]): BaseVariableField | undefined {
727
- // const [curr, ...rest] = keyPath || [];
728
- // if (curr === '*' && this.canDrilldownValue) {
729
- // return this.valueType.getByKeyPath(rest);
730
- // }
731
- // return undefined;
732
- // }
801
+ /**
802
+ * Check if the current type is equal to the target type.
803
+ * @param targetTypeJSONOrKind The type to compare with.
804
+ * @returns `true` if the types are equal, `false` otherwise.
805
+ */
733
806
  isTypeEqual(targetTypeJSONOrKind) {
734
807
  const targetTypeJSON = parseTypeJsonOrKind(targetTypeJSONOrKind);
735
808
  const isSuperEqual = super.isTypeEqual(targetTypeJSONOrKind);
736
809
  if (targetTypeJSON?.weak || targetTypeJSON?.kind === "Union" /* Union */) {
737
810
  return isSuperEqual;
738
811
  }
739
- return targetTypeJSON && isSuperEqual && // 弱比较,只需要比较 Kind 即可
812
+ return targetTypeJSON && isSuperEqual && // Weak comparison, only need to compare the Kind.
740
813
  (targetTypeJSON?.weak || this.customStrongEqual(targetTypeJSON));
741
814
  }
742
815
  /**
743
- * Map 强比较
744
- * @param targetTypeJSON
745
- * @returns
816
+ * Map strong comparison.
817
+ * @param targetTypeJSON The type to compare with.
818
+ * @returns `true` if the types are equal, `false` otherwise.
746
819
  */
747
820
  customStrongEqual(targetTypeJSON) {
748
821
  const { keyType = "String" /* String */, valueType } = targetTypeJSON;
749
822
  const isValueTypeEqual = !valueType && !this.valueType || this.valueType?.isTypeEqual(valueType);
750
823
  return isValueTypeEqual && this.keyType?.isTypeEqual(keyType);
751
824
  }
825
+ /**
826
+ * Serialize the node to a JSON object.
827
+ * @returns The JSON representation of the node.
828
+ */
752
829
  toJSON() {
753
830
  return {
754
831
  kind: "Map" /* Map */,
@@ -757,7 +834,6 @@ var MapType = class extends BaseType {
757
834
  };
758
835
  }
759
836
  };
760
- // public flags: ASTNodeFlags = ASTNodeFlags.DrilldownType | ASTNodeFlags.EnumerateType;
761
837
  MapType.kind = "Map" /* Map */;
762
838
 
763
839
  // src/ast/type/object.ts
@@ -766,8 +842,15 @@ var ObjectType = class extends BaseType {
766
842
  constructor() {
767
843
  super(...arguments);
768
844
  this.flags = 16 /* DrilldownType */;
845
+ /**
846
+ * A map of property keys to `Property` instances.
847
+ */
769
848
  this.propertyTable = /* @__PURE__ */ new Map();
770
849
  }
850
+ /**
851
+ * Deserializes the `ObjectJSON` to the `ObjectType`.
852
+ * @param json The `ObjectJSON` to deserialize.
853
+ */
771
854
  fromJSON({ properties }) {
772
855
  const removedKeys = new Set(this.propertyTable.keys());
773
856
  const prev = [...this.properties || []];
@@ -801,6 +884,10 @@ var ObjectType = class extends BaseType {
801
884
  }
802
885
  });
803
886
  }
887
+ /**
888
+ * Serialize the `ObjectType` to `ObjectJSON`.
889
+ * @returns The JSON representation of `ObjectType`.
890
+ */
804
891
  toJSON() {
805
892
  return {
806
893
  kind: "Object" /* Object */,
@@ -808,9 +895,9 @@ var ObjectType = class extends BaseType {
808
895
  };
809
896
  }
810
897
  /**
811
- * 根据 KeyPath 找到对应的变量
812
- * @param keyPath 变量路径
813
- * @returns
898
+ * Get a variable field by key path.
899
+ * @param keyPath The key path to search for.
900
+ * @returns The variable field if found, otherwise `undefined`.
814
901
  */
815
902
  getByKeyPath(keyPath) {
816
903
  const [curr, ...restKeyPath] = keyPath;
@@ -823,19 +910,24 @@ var ObjectType = class extends BaseType {
823
910
  }
824
911
  return void 0;
825
912
  }
913
+ /**
914
+ * Check if the current type is equal to the target type.
915
+ * @param targetTypeJSONOrKind The type to compare with.
916
+ * @returns `true` if the types are equal, `false` otherwise.
917
+ */
826
918
  isTypeEqual(targetTypeJSONOrKind) {
827
919
  const targetTypeJSON = parseTypeJsonOrKind(targetTypeJSONOrKind);
828
920
  const isSuperEqual = super.isTypeEqual(targetTypeJSONOrKind);
829
921
  if (targetTypeJSON?.weak || targetTypeJSON?.kind === "Union" /* Union */) {
830
922
  return isSuperEqual;
831
923
  }
832
- return targetTypeJSON && isSuperEqual && // 弱比较,只需要比较 Kind 即可
924
+ return targetTypeJSON && isSuperEqual && // Weak comparison, only need to compare the Kind.
833
925
  (targetTypeJSON?.weak || this.customStrongEqual(targetTypeJSON));
834
926
  }
835
927
  /**
836
- * Object 类型强比较
837
- * @param targetTypeJSON
838
- * @returns
928
+ * Object type strong comparison.
929
+ * @param targetTypeJSON The type to compare with.
930
+ * @returns `true` if the types are equal, `false` otherwise.
839
931
  */
840
932
  customStrongEqual(targetTypeJSON) {
841
933
  const targetProperties = targetTypeJSON.properties || [];
@@ -852,15 +944,27 @@ ObjectType.kind = "Object" /* Object */;
852
944
 
853
945
  // src/ast/type/custom-type.ts
854
946
  var CustomType = class extends BaseType {
947
+ /**
948
+ * The name of the custom type.
949
+ */
855
950
  get typeName() {
856
951
  return this._typeName;
857
952
  }
953
+ /**
954
+ * Deserializes the `CustomTypeJSON` to the `CustomType`.
955
+ * @param json The `CustomTypeJSON` to deserialize.
956
+ */
858
957
  fromJSON(json) {
859
958
  if (this._typeName !== json.typeName) {
860
959
  this._typeName = json.typeName;
861
960
  this.fireChange();
862
961
  }
863
962
  }
963
+ /**
964
+ * Check if the current type is equal to the target type.
965
+ * @param targetTypeJSONOrKind The type to compare with.
966
+ * @returns `true` if the types are equal, `false` otherwise.
967
+ */
864
968
  isTypeEqual(targetTypeJSONOrKind) {
865
969
  const targetTypeJSON = parseTypeJsonOrKind(targetTypeJSONOrKind);
866
970
  if (targetTypeJSON?.kind === "Union" /* Union */) {
@@ -904,13 +1008,12 @@ var BaseExpression = class extends ASTNode {
904
1008
  super(params, opts);
905
1009
  this.flags = 4 /* Expression */;
906
1010
  /**
907
- * 引用变量
1011
+ * The variable fields referenced by the expression.
908
1012
  */
909
1013
  this._refs = [];
910
1014
  this.refreshRefs$ = new Subject2();
911
1015
  /**
912
- * 监听引用变量变化
913
- * 监听 [a.b.c] -> [a.b]
1016
+ * An observable that emits the referenced variable fields when they change.
914
1017
  */
915
1018
  this.refs$ = this.refreshRefs$.pipe(
916
1019
  map2(() => this.getRefFields()),
@@ -934,91 +1037,42 @@ var BaseExpression = class extends ASTNode {
934
1037
  );
935
1038
  }
936
1039
  /**
937
- * 获取全局变量表,方便表达式获取引用变量
1040
+ * Get the global variable table, which is used to access referenced variables.
938
1041
  */
939
1042
  get globalVariableTable() {
940
1043
  return this.scope.variableEngine.globalVariableTable;
941
1044
  }
942
1045
  /**
943
- * 父变量字段,通过由近而远的方式进行排序
1046
+ * Parent variable fields, sorted from closest to farthest.
944
1047
  */
945
1048
  get parentFields() {
946
1049
  return getParentFields(this);
947
1050
  }
1051
+ /**
1052
+ * The variable fields referenced by the expression.
1053
+ */
948
1054
  get refs() {
949
1055
  return this._refs;
950
1056
  }
951
1057
  /**
952
- * 刷新变量引用
1058
+ * Refresh the variable references.
953
1059
  */
954
1060
  refreshRefs() {
955
1061
  this.refreshRefs$.next();
956
1062
  }
957
1063
  };
958
1064
 
959
- // src/ast/expression/keypath-expression.ts
960
- import { shallowEqual as shallowEqual3 } from "fast-equals";
961
- var KeyPathExpression = class extends BaseExpression {
962
- constructor(params, opts) {
963
- super(params, opts);
964
- this._keyPath = [];
965
- this.toDispose.pushAll([
966
- // 可以用变量列表变化时候 (有新增或者删除时)
967
- this.scope.available.onVariableListChange(() => {
968
- this.refreshRefs();
969
- }),
970
- // this._keyPath 指向的可引用变量发生变化时,刷新引用数据
971
- this.scope.available.onAnyVariableChange((_v) => {
972
- if (_v.key === this._keyPath[0]) {
973
- this.refreshRefs();
974
- }
975
- })
976
- ]);
977
- }
978
- get keyPath() {
979
- return this._keyPath;
980
- }
981
- getRefFields() {
982
- const ref = this.scope.available.getByKeyPath(this._keyPath);
983
- return ref ? [ref] : [];
984
- }
985
- get returnType() {
986
- const [refNode] = this._refs || [];
987
- if (refNode && refNode.flags & 1 /* VariableField */) {
988
- return refNode.type;
989
- }
990
- return;
991
- }
992
- /**
993
- * 业务重改该方法可快速定制自己的 Path 表达式
994
- * - 只需要将业务的 Path 解析为变量系统的 KeyPath 即可
995
- * @param json 业务定义的 Path 表达式
996
- * @returns
997
- */
998
- parseToKeyPath(json) {
999
- return json.keyPath;
1000
- }
1001
- fromJSON(json) {
1002
- const keyPath = this.parseToKeyPath(json);
1003
- if (!shallowEqual3(keyPath, this._keyPath)) {
1004
- this._keyPath = keyPath;
1005
- this.refreshRefs();
1006
- }
1007
- }
1008
- toJSON() {
1009
- return {
1010
- kind: "KeyPathExpression" /* KeyPathExpression */,
1011
- keyPath: this._keyPath
1012
- };
1013
- }
1014
- };
1015
- KeyPathExpression.kind = "KeyPathExpression" /* KeyPathExpression */;
1016
-
1017
1065
  // src/ast/expression/enumerate-expression.ts
1018
1066
  var EnumerateExpression = class extends BaseExpression {
1067
+ /**
1068
+ * The expression to be enumerated.
1069
+ */
1019
1070
  get enumerateFor() {
1020
1071
  return this._enumerateFor;
1021
1072
  }
1073
+ /**
1074
+ * The return type of the expression.
1075
+ */
1022
1076
  get returnType() {
1023
1077
  const childReturnType = this.enumerateFor?.returnType;
1024
1078
  if (childReturnType?.kind === "Array" /* Array */) {
@@ -1026,12 +1080,24 @@ var EnumerateExpression = class extends BaseExpression {
1026
1080
  }
1027
1081
  return void 0;
1028
1082
  }
1083
+ /**
1084
+ * Get the variable fields referenced by the expression.
1085
+ * @returns An empty array, as this expression does not reference any variables.
1086
+ */
1029
1087
  getRefFields() {
1030
1088
  return [];
1031
1089
  }
1090
+ /**
1091
+ * Deserializes the `EnumerateExpressionJSON` to the `EnumerateExpression`.
1092
+ * @param json The `EnumerateExpressionJSON` to deserialize.
1093
+ */
1032
1094
  fromJSON({ enumerateFor: expression }) {
1033
1095
  this.updateChildNodeByKey("_enumerateFor", expression);
1034
1096
  }
1097
+ /**
1098
+ * Serialize the `EnumerateExpression` to `EnumerateExpressionJSON`.
1099
+ * @returns The JSON representation of `EnumerateExpression`.
1100
+ */
1035
1101
  toJSON() {
1036
1102
  return {
1037
1103
  kind: "EnumerateExpression" /* EnumerateExpression */,
@@ -1041,8 +1107,8 @@ var EnumerateExpression = class extends BaseExpression {
1041
1107
  };
1042
1108
  EnumerateExpression.kind = "EnumerateExpression" /* EnumerateExpression */;
1043
1109
 
1044
- // src/ast/expression/keypath-expression-v2.ts
1045
- import { shallowEqual as shallowEqual4 } from "fast-equals";
1110
+ // src/ast/expression/keypath-expression.ts
1111
+ import { shallowEqual as shallowEqual3 } from "fast-equals";
1046
1112
 
1047
1113
  // src/ast/utils/expression.ts
1048
1114
  import { intersection } from "lodash-es";
@@ -1065,17 +1131,17 @@ function checkRefCycle(curr, refNodes) {
1065
1131
  return intersection(Array.from(visited), getParentFields(curr)).length > 0;
1066
1132
  }
1067
1133
 
1068
- // src/ast/expression/keypath-expression-v2.ts
1069
- var KeyPathExpressionV2 = class extends BaseExpression {
1134
+ // src/ast/expression/keypath-expression.ts
1135
+ var KeyPathExpression = class extends BaseExpression {
1070
1136
  constructor(params, opts) {
1071
1137
  super(params, opts);
1072
1138
  this._keyPath = [];
1073
1139
  this.toDispose.pushAll([
1074
- // 可以用变量列表变化时候 (有新增或者删除时)
1140
+ // Can be used when the variable list changes (when there are additions or deletions).
1075
1141
  this.scope.available.onVariableListChange(() => {
1076
1142
  this.refreshRefs();
1077
1143
  }),
1078
- // this._keyPath 指向的可引用变量发生变化时,刷新引用数据
1144
+ // When the referable variable pointed to by this._keyPath changes, refresh the reference data.
1079
1145
  this.scope.available.onAnyVariableChange((_v) => {
1080
1146
  if (_v.key === this._keyPath[0]) {
1081
1147
  this.refreshRefs();
@@ -1092,9 +1158,16 @@ var KeyPathExpressionV2 = class extends BaseExpression {
1092
1158
  )
1093
1159
  ]);
1094
1160
  }
1161
+ /**
1162
+ * The key path of the variable.
1163
+ */
1095
1164
  get keyPath() {
1096
1165
  return this._keyPath;
1097
1166
  }
1167
+ /**
1168
+ * Get the variable fields referenced by the expression.
1169
+ * @returns An array of referenced variable fields.
1170
+ */
1098
1171
  getRefFields() {
1099
1172
  const ref = this.scope.available.getByKeyPath(this._keyPath);
1100
1173
  if (checkRefCycle(this, [ref])) {
@@ -1106,28 +1179,45 @@ var KeyPathExpressionV2 = class extends BaseExpression {
1106
1179
  }
1107
1180
  return ref ? [ref] : [];
1108
1181
  }
1182
+ /**
1183
+ * The return type of the expression.
1184
+ */
1109
1185
  get returnType() {
1110
1186
  return this._returnType;
1111
1187
  }
1112
1188
  /**
1113
- * 业务重改该方法可快速定制自己的 Path 表达式
1114
- * - 只需要将业务的 Path 解析为变量系统的 KeyPath 即可
1115
- * @param json 业务定义的 Path 表达式
1116
- * @returns
1189
+ * Parse the business-defined path expression into a key path.
1190
+ *
1191
+ * Businesses can quickly customize their own path expressions by modifying this method.
1192
+ * @param json The path expression defined by the business.
1193
+ * @returns The key path.
1117
1194
  */
1118
1195
  parseToKeyPath(json) {
1119
1196
  return json.keyPath;
1120
1197
  }
1198
+ /**
1199
+ * Deserializes the `KeyPathExpressionJSON` to the `KeyPathExpression`.
1200
+ * @param json The `KeyPathExpressionJSON` to deserialize.
1201
+ */
1121
1202
  fromJSON(json) {
1122
1203
  const keyPath = this.parseToKeyPath(json);
1123
- if (!shallowEqual4(keyPath, this._keyPath)) {
1204
+ if (!shallowEqual3(keyPath, this._keyPath)) {
1124
1205
  this._keyPath = keyPath;
1125
1206
  this.refreshRefs();
1126
1207
  }
1127
1208
  }
1209
+ /**
1210
+ * Get the return type JSON by reference.
1211
+ * @param _ref The referenced variable field.
1212
+ * @returns The JSON representation of the return type.
1213
+ */
1128
1214
  getReturnTypeJSONByRef(_ref) {
1129
1215
  return _ref?.type?.toJSON();
1130
1216
  }
1217
+ /**
1218
+ * Serialize the `KeyPathExpression` to `KeyPathExpressionJSON`.
1219
+ * @returns The JSON representation of `KeyPathExpression`.
1220
+ */
1131
1221
  toJSON() {
1132
1222
  return {
1133
1223
  kind: "KeyPathExpression" /* KeyPathExpression */,
@@ -1135,16 +1225,102 @@ var KeyPathExpressionV2 = class extends BaseExpression {
1135
1225
  };
1136
1226
  }
1137
1227
  };
1138
- KeyPathExpressionV2.kind = "KeyPathExpression" /* KeyPathExpression */;
1228
+ KeyPathExpression.kind = "KeyPathExpression" /* KeyPathExpression */;
1229
+
1230
+ // src/ast/expression/legacy-keypath-expression.ts
1231
+ import { shallowEqual as shallowEqual4 } from "fast-equals";
1232
+ var LegacyKeyPathExpression = class extends BaseExpression {
1233
+ constructor(params, opts) {
1234
+ super(params, opts);
1235
+ this._keyPath = [];
1236
+ this.toDispose.pushAll([
1237
+ // Can be used when the variable list changes (when there are additions or deletions).
1238
+ this.scope.available.onVariableListChange(() => {
1239
+ this.refreshRefs();
1240
+ }),
1241
+ // When the referable variable pointed to by this._keyPath changes, refresh the reference data.
1242
+ this.scope.available.onAnyVariableChange((_v) => {
1243
+ if (_v.key === this._keyPath[0]) {
1244
+ this.refreshRefs();
1245
+ }
1246
+ })
1247
+ ]);
1248
+ }
1249
+ /**
1250
+ * The key path of the variable.
1251
+ */
1252
+ get keyPath() {
1253
+ return this._keyPath;
1254
+ }
1255
+ /**
1256
+ * Get the variable fields referenced by the expression.
1257
+ * @returns An array of referenced variable fields.
1258
+ */
1259
+ getRefFields() {
1260
+ const ref = this.scope.available.getByKeyPath(this._keyPath);
1261
+ return ref ? [ref] : [];
1262
+ }
1263
+ /**
1264
+ * The return type of the expression.
1265
+ */
1266
+ get returnType() {
1267
+ const [refNode] = this._refs || [];
1268
+ if (refNode && refNode.flags & 1 /* VariableField */) {
1269
+ return refNode.type;
1270
+ }
1271
+ return;
1272
+ }
1273
+ /**
1274
+ * Parse the business-defined path expression into a key path.
1275
+ *
1276
+ * Businesses can quickly customize their own path expressions by modifying this method.
1277
+ * @param json The path expression defined by the business.
1278
+ * @returns The key path.
1279
+ */
1280
+ parseToKeyPath(json) {
1281
+ return json.keyPath;
1282
+ }
1283
+ /**
1284
+ * Deserializes the `KeyPathExpressionJSON` to the `KeyPathExpression`.
1285
+ * @param json The `KeyPathExpressionJSON` to deserialize.
1286
+ */
1287
+ fromJSON(json) {
1288
+ const keyPath = this.parseToKeyPath(json);
1289
+ if (!shallowEqual4(keyPath, this._keyPath)) {
1290
+ this._keyPath = keyPath;
1291
+ this.refreshRefs();
1292
+ }
1293
+ }
1294
+ /**
1295
+ * Serialize the `KeyPathExpression` to `KeyPathExpressionJSON`.
1296
+ * @returns The JSON representation of `KeyPathExpression`.
1297
+ */
1298
+ toJSON() {
1299
+ return {
1300
+ kind: "KeyPathExpression" /* KeyPathExpression */,
1301
+ keyPath: this._keyPath
1302
+ };
1303
+ }
1304
+ };
1305
+ LegacyKeyPathExpression.kind = "KeyPathExpression" /* KeyPathExpression */;
1139
1306
 
1140
1307
  // src/ast/expression/wrap-array-expression.ts
1141
1308
  var WrapArrayExpression = class extends BaseExpression {
1309
+ /**
1310
+ * The expression to be wrapped.
1311
+ */
1142
1312
  get wrapFor() {
1143
1313
  return this._wrapFor;
1144
1314
  }
1315
+ /**
1316
+ * The return type of the expression.
1317
+ */
1145
1318
  get returnType() {
1146
1319
  return this._returnType;
1147
1320
  }
1321
+ /**
1322
+ * Refresh the return type of the expression.
1323
+ */
1148
1324
  refreshReturnType() {
1149
1325
  const childReturnTypeJSON = this.wrapFor?.returnType?.toJSON();
1150
1326
  this.updateChildNodeByKey("_returnType", {
@@ -1152,12 +1328,24 @@ var WrapArrayExpression = class extends BaseExpression {
1152
1328
  items: childReturnTypeJSON
1153
1329
  });
1154
1330
  }
1331
+ /**
1332
+ * Get the variable fields referenced by the expression.
1333
+ * @returns An empty array, as this expression does not reference any variables.
1334
+ */
1155
1335
  getRefFields() {
1156
1336
  return [];
1157
1337
  }
1338
+ /**
1339
+ * Deserializes the `WrapArrayExpressionJSON` to the `WrapArrayExpression`.
1340
+ * @param json The `WrapArrayExpressionJSON` to deserialize.
1341
+ */
1158
1342
  fromJSON({ wrapFor: expression }) {
1159
1343
  this.updateChildNodeByKey("_wrapFor", expression);
1160
1344
  }
1345
+ /**
1346
+ * Serialize the `WrapArrayExpression` to `WrapArrayExpressionJSON`.
1347
+ * @returns The JSON representation of `WrapArrayExpression`.
1348
+ */
1161
1349
  toJSON() {
1162
1350
  return {
1163
1351
  kind: "WrapArrayExpression" /* WrapArrayExpression */,
@@ -1188,41 +1376,73 @@ var BaseVariableField = class extends ASTNode {
1188
1376
  this._meta = {};
1189
1377
  }
1190
1378
  /**
1191
- * 父变量字段,通过由近而远的方式进行排序
1379
+ * Parent variable fields, sorted from closest to farthest
1192
1380
  */
1193
1381
  get parentFields() {
1194
1382
  return getParentFields(this);
1195
1383
  }
1384
+ /**
1385
+ * KeyPath of the variable field, sorted from farthest to closest
1386
+ */
1196
1387
  get keyPath() {
1197
1388
  return [...this.parentFields.reverse().map((_field) => _field.key), this.key];
1198
1389
  }
1390
+ /**
1391
+ * Metadata of the variable field, you cans store information like `title`, `icon`, etc.
1392
+ */
1199
1393
  get meta() {
1200
1394
  return this._meta;
1201
1395
  }
1396
+ /**
1397
+ * Type of the variable field, similar to js code:
1398
+ * `const v: string`
1399
+ */
1202
1400
  get type() {
1203
1401
  return this._initializer?.returnType || this._type;
1204
1402
  }
1403
+ /**
1404
+ * Initializer of the variable field, similar to js code:
1405
+ * `const v = 'hello'`
1406
+ *
1407
+ * with initializer, the type of field will be inferred from the initializer.
1408
+ */
1205
1409
  get initializer() {
1206
1410
  return this._initializer;
1207
1411
  }
1412
+ /**
1413
+ * The global unique hash of the field, and will be changed when the field is updated.
1414
+ */
1208
1415
  get hash() {
1209
1416
  return `[${this._version}]${this.keyPath.join(".")}`;
1210
1417
  }
1211
1418
  /**
1212
- * 解析 VariableDeclarationJSON 从而生成变量声明节点
1419
+ * Deserialize the `BaseVariableFieldJSON` to the `BaseVariableField`.
1420
+ * @param json ASTJSON representation of `BaseVariableField`
1213
1421
  */
1214
1422
  fromJSON({ type, initializer, meta }) {
1215
1423
  this.updateType(type);
1216
1424
  this.updateInitializer(initializer);
1217
1425
  this.updateMeta(meta);
1218
1426
  }
1427
+ /**
1428
+ * Update the type of the variable field
1429
+ * @param type type ASTJSON representation of Type
1430
+ */
1219
1431
  updateType(type) {
1220
1432
  const nextTypeJson = typeof type === "string" ? { kind: type } : type;
1221
1433
  this.updateChildNodeByKey("_type", nextTypeJson);
1222
1434
  }
1435
+ /**
1436
+ * Update the initializer of the variable field
1437
+ * @param nextInitializer initializer ASTJSON representation of Expression
1438
+ */
1223
1439
  updateInitializer(nextInitializer) {
1224
1440
  this.updateChildNodeByKey("_initializer", nextInitializer);
1225
1441
  }
1442
+ /**
1443
+ * Update the meta data of the variable field
1444
+ * @param nextMeta meta data of the variable field
1445
+ */
1226
1446
  updateMeta(nextMeta) {
1227
1447
  if (!shallowEqual5(nextMeta, this._meta)) {
1228
1448
  this._meta = nextMeta;
@@ -1230,7 +1450,8 @@ var BaseVariableField = class extends ASTNode {
1230
1450
  }
1231
1451
  }
1232
1452
  /**
1233
- * 根据 keyPath 去找下钻的变量字段
1453
+ * Get the variable field by keyPath, similar to js code:
1454
+ * `v.a.b`
1234
1455
  * @param keyPath
1235
1456
  * @returns
1236
1457
  */
@@ -1241,7 +1462,7 @@ var BaseVariableField = class extends ASTNode {
1241
1462
  return void 0;
1242
1463
  }
1243
1464
  /**
1244
- * 监听类型变化
1465
+ * Subscribe to type change of the variable field
1245
1466
  * @param observer
1246
1467
  * @returns
1247
1468
  */
@@ -1249,8 +1470,8 @@ var BaseVariableField = class extends ASTNode {
1249
1470
  return this.subscribe(observer, { selector: (curr) => curr.type });
1250
1471
  }
1251
1472
  /**
1252
- * 转换为 JSON
1253
- * @returns
1473
+ * Serialize the variable field to JSON
1474
+ * @returns ASTNodeJSON representation of `BaseVariableField`
1254
1475
  */
1255
1476
  toJSON() {
1256
1477
  return {
@@ -1269,16 +1490,23 @@ var VariableDeclaration = class extends BaseVariableField {
1269
1490
  super(params);
1270
1491
  this._order = 0;
1271
1492
  }
1493
+ /**
1494
+ * Variable sorting order, which is used to sort variables in `scope.outputs.variables`
1495
+ */
1272
1496
  get order() {
1273
1497
  return this._order;
1274
1498
  }
1275
1499
  /**
1276
- * 解析 VariableDeclarationJSON 从而生成变量声明节点
1500
+ * Deserialize the `VariableDeclarationJSON` to the `VariableDeclaration`.
1277
1501
  */
1278
1502
  fromJSON({ order, ...rest }) {
1279
1503
  this.updateOrder(order);
1280
1504
  super.fromJSON(rest);
1281
1505
  }
1506
+ /**
1507
+ * Update the sorting order of the variable declaration.
1508
+ * @param order Variable sorting order. Default is 0.
1509
+ */
1282
1510
  updateOrder(order = 0) {
1283
1511
  if (order !== this._order) {
1284
1512
  this._order = order;
@@ -1288,10 +1516,6 @@ var VariableDeclaration = class extends BaseVariableField {
1288
1516
  this.fireChange();
1289
1517
  }
1290
1518
  }
1291
- // 监听类型变化
1292
- onTypeChange(observer) {
1293
- return this.subscribe(observer, { selector: (curr) => curr.type });
1294
- }
1295
1519
  };
1296
1520
  VariableDeclaration.kind = "VariableDeclaration" /* VariableDeclaration */;
1297
1521
 
@@ -1299,8 +1523,18 @@ VariableDeclaration.kind = "VariableDeclaration" /* VariableDeclaration */;
1299
1523
  var VariableDeclarationList = class extends ASTNode {
1300
1524
  constructor() {
1301
1525
  super(...arguments);
1526
+ /**
1527
+ * Map of variable declarations, keyed by variable name.
1528
+ */
1302
1529
  this.declarationTable = /* @__PURE__ */ new Map();
1303
1530
  }
1531
+ /**
1532
+ * Deserialize the `VariableDeclarationListJSON` to the `VariableDeclarationList`.
1533
+ * - VariableDeclarationListChangeAction will be dispatched after deserialization.
1534
+ *
1535
+ * @param declarations Variable declarations.
1536
+ * @param startOrder The starting order number for variables. Default is 0.
1537
+ */
1304
1538
  fromJSON({ declarations, startOrder }) {
1305
1539
  const removedKeys = new Set(this.declarationTable.keys());
1306
1540
  const prev = [...this.declarations || []];
@@ -1340,10 +1574,14 @@ var VariableDeclarationList = class extends ASTNode {
1340
1574
  }
1341
1575
  });
1342
1576
  }
1577
+ /**
1578
+ * Serialize the `VariableDeclarationList` to the `VariableDeclarationListJSON`.
1579
+ * @returns ASTJSON representation of `VariableDeclarationList`
1580
+ */
1343
1581
  toJSON() {
1344
1582
  return {
1345
1583
  kind: "VariableDeclarationList" /* VariableDeclarationList */,
1346
- properties: this.declarations.map((_declaration) => _declaration.toJSON())
1584
+ declarations: this.declarations.map((_declaration) => _declaration.toJSON())
1347
1585
  };
1348
1586
  }
1349
1587
  };
@@ -1357,9 +1595,16 @@ Property.kind = "Property" /* Property */;
1357
1595
  // src/ast/common/data-node.ts
1358
1596
  import { shallowEqual as shallowEqual6 } from "fast-equals";
1359
1597
  var DataNode = class extends ASTNode {
1598
+ /**
1599
+ * The data of the node.
1600
+ */
1360
1601
  get data() {
1361
1602
  return this._data;
1362
1603
  }
1604
+ /**
1605
+ * Deserializes the `DataNodeJSON` to the `DataNode`.
1606
+ * @param json The `DataNodeJSON` to deserialize.
1607
+ */
1363
1608
  fromJSON(json) {
1364
1609
  const { kind, ...restData } = json;
1365
1610
  if (!shallowEqual6(restData, this._data)) {
@@ -1367,12 +1612,20 @@ var DataNode = class extends ASTNode {
1367
1612
  this.fireChange();
1368
1613
  }
1369
1614
  }
1615
+ /**
1616
+ * Serialize the `DataNode` to `DataNodeJSON`.
1617
+ * @returns The JSON representation of `DataNode`.
1618
+ */
1370
1619
  toJSON() {
1371
1620
  return {
1372
1621
  kind: "DataNode" /* DataNode */,
1373
1622
  ...this._data
1374
1623
  };
1375
1624
  }
1625
+ /**
1626
+ * Partially update the data of the node.
1627
+ * @param nextData The data to be updated.
1628
+ */
1376
1629
  partialUpdate(nextData) {
1377
1630
  if (!shallowEqual6(nextData, this._data)) {
1378
1631
  this._data = {
@@ -1387,9 +1640,16 @@ DataNode.kind = "DataNode" /* DataNode */;
1387
1640
 
1388
1641
  // src/ast/common/list-node.ts
1389
1642
  var ListNode = class extends ASTNode {
1643
+ /**
1644
+ * The list of nodes.
1645
+ */
1390
1646
  get list() {
1391
1647
  return this._list;
1392
1648
  }
1649
+ /**
1650
+ * Deserializes the `ListNodeJSON` to the `ListNode`.
1651
+ * @param json The `ListNodeJSON` to deserialize.
1652
+ */
1393
1653
  fromJSON({ list }) {
1394
1654
  this._list.slice(list.length).forEach((_item) => {
1395
1655
  _item.dispose();
@@ -1406,6 +1666,10 @@ var ListNode = class extends ASTNode {
1406
1666
  return prevItem;
1407
1667
  });
1408
1668
  }
1669
+ /**
1670
+ * Serialize the `ListNode` to `ListNodeJSON`.
1671
+ * @returns The JSON representation of `ListNode`.
1672
+ */
1409
1673
  toJSON() {
1410
1674
  return {
1411
1675
  kind: "ListNode" /* ListNode */,
@@ -1421,6 +1685,10 @@ var MapNode = class extends ASTNode {
1421
1685
  super(...arguments);
1422
1686
  this.map = /* @__PURE__ */ new Map();
1423
1687
  }
1688
+ /**
1689
+ * Deserializes the `MapNodeJSON` to the `MapNode`.
1690
+ * @param json The `MapNodeJSON` to deserialize.
1691
+ */
1424
1692
  fromJSON({ map: map4 }) {
1425
1693
  const removedKeys = new Set(this.map.keys());
1426
1694
  for (const [key, item] of map4 || []) {
@@ -1431,6 +1699,10 @@ var MapNode = class extends ASTNode {
1431
1699
  this.remove(removeKey);
1432
1700
  }
1433
1701
  }
1702
+ /**
1703
+ * Serialize the `MapNode` to `MapNodeJSON`.
1704
+ * @returns The JSON representation of `MapNode`.
1705
+ */
1434
1706
  toJSON() {
1435
1707
  return {
1436
1708
  kind: "MapNode" /* MapNode */,
@@ -1438,9 +1710,10 @@ var MapNode = class extends ASTNode {
1438
1710
  };
1439
1711
  }
1440
1712
  /**
1441
- * Map 中设置 ASTNode
1442
- * @param key ASTNode 的索引,
1443
- * @param json
1713
+ * Set a node in the map.
1714
+ * @param key The key of the node.
1715
+ * @param nextJSON The JSON representation of the node.
1716
+ * @returns The node instance.
1444
1717
  */
1445
1718
  set(key, nextJSON) {
1446
1719
  return this.withBatchUpdate(updateChildNodeHelper).call(this, {
@@ -1451,8 +1724,8 @@ var MapNode = class extends ASTNode {
1451
1724
  });
1452
1725
  }
1453
1726
  /**
1454
- * 移除指定 ASTNode
1455
- * @param key
1727
+ * Remove a node from the map.
1728
+ * @param key The key of the node.
1456
1729
  */
1457
1730
  remove(key) {
1458
1731
  this.get(key)?.dispose();
@@ -1460,9 +1733,9 @@ var MapNode = class extends ASTNode {
1460
1733
  this.fireChange();
1461
1734
  }
1462
1735
  /**
1463
- * 获取 ASTNode
1464
- * @param key
1465
- * @returns
1736
+ * Get a node from the map.
1737
+ * @param key The key of the node.
1738
+ * @returns The node instance if found, otherwise `undefined`.
1466
1739
  */
1467
1740
  get(key) {
1468
1741
  return this.map.get(key);
@@ -1473,7 +1746,7 @@ MapNode.kind = "MapNode" /* MapNode */;
1473
1746
  // src/ast/ast-registers.ts
1474
1747
  var ASTRegisters = class {
1475
1748
  /**
1476
- * 核心 AST 节点注册
1749
+ * Core AST node registration.
1477
1750
  */
1478
1751
  constructor() {
1479
1752
  this.injectors = /* @__PURE__ */ new Map();
@@ -1489,15 +1762,15 @@ var ASTRegisters = class {
1489
1762
  this.registerAST(Property);
1490
1763
  this.registerAST(VariableDeclaration);
1491
1764
  this.registerAST(VariableDeclarationList);
1492
- this.registerAST(KeyPathExpressionV2);
1765
+ this.registerAST(KeyPathExpression);
1493
1766
  this.registerAST(EnumerateExpression);
1494
1767
  this.registerAST(WrapArrayExpression);
1495
1768
  this.registerAST(MapNode);
1496
1769
  this.registerAST(DataNode);
1497
1770
  }
1498
1771
  /**
1499
- * 创建 AST 节点
1500
- * @param param 创建参数
1772
+ * Creates an AST node.
1773
+ * @param param Creation parameters.
1501
1774
  * @returns
1502
1775
  */
1503
1776
  createAST(json, { parent, scope }) {
@@ -1525,7 +1798,7 @@ var ASTRegisters = class {
1525
1798
  return node;
1526
1799
  }
1527
1800
  /**
1528
- * 根据 AST 节点类型获取节点 Registry
1801
+ * Gets the node Registry by AST node type.
1529
1802
  * @param kind
1530
1803
  * @returns
1531
1804
  */
@@ -1533,7 +1806,7 @@ var ASTRegisters = class {
1533
1806
  return this.astMap.get(kind);
1534
1807
  }
1535
1808
  /**
1536
- * 注册 AST 节点
1809
+ * Registers an AST node.
1537
1810
  * @param ASTNode
1538
1811
  * @param injector
1539
1812
  */
@@ -1613,7 +1886,7 @@ var ScopeOutputData = class {
1613
1886
  this._hasChanges = false;
1614
1887
  this.variableTable = new VariableTable(scope.variableEngine.globalVariableTable);
1615
1888
  this.scope.toDispose.pushAll([
1616
- // When root AST node is updated, check if there are any changes during this AST change
1889
+ // When the root AST node is updated, check if there are any changes.
1617
1890
  this.scope.ast.subscribe(() => {
1618
1891
  if (this._hasChanges) {
1619
1892
  this.memo.clear();
@@ -1638,12 +1911,21 @@ var ScopeOutputData = class {
1638
1911
  this.variableTable
1639
1912
  ]);
1640
1913
  }
1914
+ /**
1915
+ * The variable engine instance.
1916
+ */
1641
1917
  get variableEngine() {
1642
1918
  return this.scope.variableEngine;
1643
1919
  }
1920
+ /**
1921
+ * The global variable table from the variable engine.
1922
+ */
1644
1923
  get globalVariableTable() {
1645
1924
  return this.scope.variableEngine.globalVariableTable;
1646
1925
  }
1926
+ /**
1927
+ * The current version of the output data, which increments on each change.
1928
+ */
1647
1929
  get version() {
1648
1930
  return this.variableTable.version;
1649
1931
  }
@@ -1654,25 +1936,25 @@ var ScopeOutputData = class {
1654
1936
  return this.variableTable.onDataChange.bind(this.variableTable);
1655
1937
  }
1656
1938
  /**
1657
- * listen to variable list change
1939
+ * An event that fires when the list of output variables changes.
1658
1940
  */
1659
1941
  get onVariableListChange() {
1660
1942
  return this.variableTable.onVariableListChange.bind(this.variableTable);
1661
1943
  }
1662
1944
  /**
1663
- * listen to any variable update in list
1945
+ * An event that fires when any output variable's value changes.
1664
1946
  */
1665
1947
  get onAnyVariableChange() {
1666
1948
  return this.variableTable.onAnyVariableChange.bind(this.variableTable);
1667
1949
  }
1668
1950
  /**
1669
- * listen to variable list change + any variable update in list
1951
+ * An event that fires when the output variable list changes or any variable's value is updated.
1670
1952
  */
1671
1953
  get onListOrAnyVarChange() {
1672
1954
  return this.variableTable.onListOrAnyVarChange.bind(this.variableTable);
1673
1955
  }
1674
1956
  /**
1675
- * Scope Output Variable Declarations
1957
+ * The output variable declarations of the scope, sorted by order.
1676
1958
  */
1677
1959
  get variables() {
1678
1960
  return this.memo(
@@ -1681,7 +1963,7 @@ var ScopeOutputData = class {
1681
1963
  );
1682
1964
  }
1683
1965
  /**
1684
- * Output Variable Keys
1966
+ * The keys of the output variables.
1685
1967
  */
1686
1968
  get variableKeys() {
1687
1969
  return this.memo("variableKeys", () => this.variableTable.variableKeys);
@@ -1697,11 +1979,16 @@ var ScopeOutputData = class {
1697
1979
  this.variableTable.removeVariableFromTable(key);
1698
1980
  this._hasChanges = true;
1699
1981
  }
1982
+ /**
1983
+ * Retrieves a variable declaration by its key.
1984
+ * @param key The key of the variable.
1985
+ * @returns The `VariableDeclaration` or `undefined` if not found.
1986
+ */
1700
1987
  getVariableByKey(key) {
1701
1988
  return this.variableTable.getVariableByKey(key);
1702
1989
  }
1703
1990
  /**
1704
- *
1991
+ * Notifies the covering scopes that the available variables have changed.
1705
1992
  */
1706
1993
  notifyCoversChange() {
1707
1994
  this.scope.coverScopes.forEach((scope) => scope.available.refresh());
@@ -1734,22 +2021,24 @@ var ScopeAvailableData = class {
1734
2021
  this.refresh$ = new Subject3();
1735
2022
  this._variables = [];
1736
2023
  /**
1737
- * 监听
2024
+ * An observable that emits when the list of available variables changes.
1738
2025
  */
1739
2026
  this.variables$ = this.refresh$.pipe(
1740
- // 输出变量是否 version 发生变化
2027
+ // Map to the flattened list of variables from all dependency scopes.
1741
2028
  map3(() => flatten(this.depScopes.map((scope) => scope.output.variables || []))),
1742
- // 变量列表浅比较
2029
+ // Use shallow equality to check if the variable list has changed.
1743
2030
  distinctUntilChanged3(shallowEqual7),
1744
2031
  share3()
1745
2032
  );
1746
- // 监听变量列表中的单个变量变化
2033
+ /**
2034
+ * An observable that emits when any variable in the available list changes its value.
2035
+ */
1747
2036
  this.anyVariableChange$ = this.variables$.pipe(
1748
2037
  switchMap3(
1749
2038
  (_variables) => merge2(
1750
2039
  ..._variables.map(
1751
2040
  (_v) => _v.value$.pipe(
1752
- // 跳过 BehaviorSubject 第一个
2041
+ // Skip the initial value of the BehaviorSubject.
1753
2042
  skip3(1)
1754
2043
  )
1755
2044
  )
@@ -1767,7 +2056,7 @@ var ScopeAvailableData = class {
1767
2056
  */
1768
2057
  this.onDataChange = this.onDataChangeEmitter.event;
1769
2058
  /**
1770
- * listen to variable list change + any variable drilldown change
2059
+ * An event that fires when the variable list changes or any variable's value is updated.
1771
2060
  */
1772
2061
  this.onListOrAnyVarChange = this.onListOrAnyVarChangeEmitter.event;
1773
2062
  this.scope.toDispose.pushAll([
@@ -1789,9 +2078,15 @@ var ScopeAvailableData = class {
1789
2078
  })
1790
2079
  ]);
1791
2080
  }
2081
+ /**
2082
+ * The global variable table from the variable engine.
2083
+ */
1792
2084
  get globalVariableTable() {
1793
2085
  return this.scope.variableEngine.globalVariableTable;
1794
2086
  }
2087
+ /**
2088
+ * The current version of the available data, which increments on each change.
2089
+ */
1795
2090
  get version() {
1796
2091
  return this._version;
1797
2092
  }
@@ -1801,7 +2096,10 @@ var ScopeAvailableData = class {
1801
2096
  this._version = 0;
1802
2097
  }
1803
2098
  }
1804
- // 刷新可访问变量列表
2099
+ /**
2100
+ * Refreshes the list of available variables.
2101
+ * This should be called when the dependencies of the scope change.
2102
+ */
1805
2103
  refresh() {
1806
2104
  if (this.scope.disposed) {
1807
2105
  return;
@@ -1809,43 +2107,43 @@ var ScopeAvailableData = class {
1809
2107
  this.refresh$.next();
1810
2108
  }
1811
2109
  /**
1812
- * listen to any variable update in list
1813
- * @param observer
1814
- * @returns
2110
+ * Subscribes to changes in any variable's value in the available list.
2111
+ * @param observer A function to be called with the changed variable.
2112
+ * @returns A disposable to unsubscribe from the changes.
1815
2113
  */
1816
2114
  onAnyVariableChange(observer) {
1817
2115
  return subsToDisposable(this.anyVariableChange$.subscribe(observer));
1818
2116
  }
1819
2117
  /**
1820
- * listen to variable list change
1821
- * @param observer
1822
- * @returns
2118
+ * Subscribes to changes in the list of available variables.
2119
+ * @param observer A function to be called with the new list of variables.
2120
+ * @returns A disposable to unsubscribe from the changes.
1823
2121
  */
1824
2122
  onVariableListChange(observer) {
1825
2123
  return subsToDisposable(this.variables$.subscribe(observer));
1826
2124
  }
1827
2125
  /**
1828
- * 获取可消费变量
2126
+ * Gets the list of available variables.
1829
2127
  */
1830
2128
  get variables() {
1831
2129
  return this._variables;
1832
2130
  }
1833
2131
  /**
1834
- * 获取可访问的变量 keys
2132
+ * Gets the keys of the available variables.
1835
2133
  */
1836
2134
  get variableKeys() {
1837
2135
  return this.memo("availableKeys", () => this._variables.map((_v) => _v.key));
1838
2136
  }
1839
2137
  /**
1840
- * 返回依赖的作用域
2138
+ * Gets the dependency scopes.
1841
2139
  */
1842
2140
  get depScopes() {
1843
2141
  return this.scope.depScopes;
1844
2142
  }
1845
2143
  /**
1846
- * 通过 keyPath 找到可用变量
1847
- * @param keyPath
1848
- * @returns
2144
+ * Retrieves a variable field by its key path from the available variables.
2145
+ * @param keyPath The key path to the variable field.
2146
+ * @returns The found `BaseVariableField` or `undefined`.
1849
2147
  */
1850
2148
  getByKeyPath(keyPath = []) {
1851
2149
  if (!this.variableKeys.includes(keyPath[0])) {
@@ -1854,8 +2152,12 @@ var ScopeAvailableData = class {
1854
2152
  return this.globalVariableTable.getByKeyPath(keyPath);
1855
2153
  }
1856
2154
  /**
1857
- * Track Variable Change (Includes type update and children update) By KeyPath
1858
- * @returns
2155
+ * Tracks changes to a variable field by its key path.
2156
+ * This includes changes to its type, value, or any nested properties.
2157
+ * @param keyPath The key path to the variable field to track.
2158
+ * @param cb The callback to execute when the variable changes.
2159
+ * @param opts Configuration options for the subscription.
2160
+ * @returns A disposable to unsubscribe from the tracking.
1859
2161
  */
1860
2162
  trackByKeyPath(keyPath = [], cb, opts) {
1861
2163
  const { triggerOnInit = true, debounceAnimation, selector } = opts || {};
@@ -1875,7 +2177,7 @@ var ScopeAvailableData = class {
1875
2177
  return value;
1876
2178
  }
1877
2179
  ),
1878
- // 每个 animationFrame 内所有更新合并成一个
2180
+ // Debounce updates to a single emission per animation frame.
1879
2181
  debounceAnimation ? debounceTime2(0, animationFrameScheduler2) : tap2(() => null)
1880
2182
  ).subscribe(cb)
1881
2183
  );
@@ -1894,15 +2196,30 @@ var ScopeEventData = class {
1894
2196
  })
1895
2197
  ]);
1896
2198
  }
2199
+ /**
2200
+ * Dispatches a global event.
2201
+ * @param action The event action to dispatch.
2202
+ */
1897
2203
  dispatch(action) {
1898
2204
  if (this.scope.disposed) {
1899
2205
  return;
1900
2206
  }
1901
2207
  this.event$.next(action);
1902
2208
  }
2209
+ /**
2210
+ * Subscribes to all global events.
2211
+ * @param observer The observer function to call with the event action.
2212
+ * @returns A disposable to unsubscribe from the events.
2213
+ */
1903
2214
  subscribe(observer) {
1904
2215
  return subsToDisposable(this.event$.subscribe(observer));
1905
2216
  }
2217
+ /**
2218
+ * Subscribes to a specific type of global event.
2219
+ * @param type The type of the event to subscribe to.
2220
+ * @param observer The observer function to call with the event action.
2221
+ * @returns A disposable to unsubscribe from the event.
2222
+ */
1906
2223
  on(type, observer) {
1907
2224
  return subsToDisposable(
1908
2225
  this.event$.pipe(filter((_action) => _action.type === type)).subscribe(observer)
@@ -1914,7 +2231,7 @@ var ScopeEventData = class {
1914
2231
  var Scope = class {
1915
2232
  constructor(options) {
1916
2233
  /**
1917
- * 数据缓存
2234
+ * A memoization utility for caching computed values.
1918
2235
  */
1919
2236
  this.memo = createMemo();
1920
2237
  this.toDispose = new DisposableCollection4();
@@ -1935,25 +2252,41 @@ var Scope = class {
1935
2252
  this.output = new ScopeOutputData(this);
1936
2253
  this.available = new ScopeAvailableData(this);
1937
2254
  }
2255
+ /**
2256
+ * Refreshes the covering scopes.
2257
+ */
1938
2258
  refreshCovers() {
1939
2259
  this.memo.clear("covers");
1940
2260
  }
2261
+ /**
2262
+ * Refreshes the dependency scopes and the available variables.
2263
+ */
1941
2264
  refreshDeps() {
1942
2265
  this.memo.clear("deps");
1943
2266
  this.available.refresh();
1944
2267
  }
2268
+ /**
2269
+ * Gets the scopes that this scope depends on.
2270
+ */
1945
2271
  get depScopes() {
1946
2272
  return this.memo(
1947
2273
  "deps",
1948
2274
  () => this.variableEngine.chain.getDeps(this).filter((_scope) => Boolean(_scope) && !_scope?.disposed)
1949
2275
  );
1950
2276
  }
2277
+ /**
2278
+ * Gets the scopes that are covered by this scope.
2279
+ */
1951
2280
  get coverScopes() {
1952
2281
  return this.memo(
1953
2282
  "covers",
1954
2283
  () => this.variableEngine.chain.getCovers(this).filter((_scope) => Boolean(_scope) && !_scope?.disposed)
1955
2284
  );
1956
2285
  }
2286
+ /**
2287
+ * Disposes of the scope and its resources.
2288
+ * This will also trigger updates in dependent and covering scopes.
2289
+ */
1957
2290
  dispose() {
1958
2291
  this.ast.dispose();
1959
2292
  this.toDispose.dispose();
@@ -1973,19 +2306,18 @@ var Scope = class {
1973
2306
  throw new Error("Invalid arguments");
1974
2307
  }
1975
2308
  /**
1976
- * Retrieves a variable from the Scope by key.
2309
+ * Retrieves a variable from the scope by its key.
1977
2310
  *
1978
- * @param key - The key of the variable to retrieve. Defaults to 'outputs'.
1979
- * @returns The value of the variable, or undefined if not found.
2311
+ * @param key The key of the variable to retrieve. Defaults to 'outputs'.
2312
+ * @returns The AST node for the variable, or `undefined` if not found.
1980
2313
  */
1981
2314
  getVar(key = "outputs") {
1982
2315
  return this.ast.get(key);
1983
2316
  }
1984
2317
  /**
1985
- * Clears a variable from the Scope by key.
2318
+ * Clears a variable from the scope by its key.
1986
2319
  *
1987
- * @param key - The key of the variable to clear. Defaults to 'outputs'.
1988
- * @returns The updated AST node.
2320
+ * @param key The key of the variable to clear. Defaults to 'outputs'.
1989
2321
  */
1990
2322
  clearVar(key = "outputs") {
1991
2323
  return this.ast.remove(key);
@@ -2000,9 +2332,18 @@ var VariableEngine = class {
2000
2332
  this.toDispose = new DisposableCollection5();
2001
2333
  this.memo = createMemo();
2002
2334
  this.scopeMap = /* @__PURE__ */ new Map();
2335
+ /**
2336
+ * A rxjs subject that emits global events occurring within the variable engine.
2337
+ */
2003
2338
  this.globalEvent$ = new Subject5();
2004
2339
  this.onScopeChangeEmitter = new Emitter3();
2340
+ /**
2341
+ * A table containing all global variables.
2342
+ */
2005
2343
  this.globalVariableTable = new VariableTable();
2344
+ /**
2345
+ * An event that fires whenever a scope is added, updated, or deleted.
2346
+ */
2006
2347
  this.onScopeChange = this.onScopeChangeEmitter.event;
2007
2348
  this.toDispose.pushAll([
2008
2349
  chain,
@@ -2012,26 +2353,37 @@ var VariableEngine = class {
2012
2353
  })
2013
2354
  ]);
2014
2355
  }
2356
+ /**
2357
+ * The Inversify container instance.
2358
+ */
2015
2359
  get container() {
2016
2360
  return this.containerProvider();
2017
2361
  }
2018
2362
  dispose() {
2019
2363
  this.toDispose.dispose();
2020
2364
  }
2021
- // 根据 scopeId 找到作用域
2365
+ /**
2366
+ * Retrieves a scope by its unique identifier.
2367
+ * @param scopeId The ID of the scope to retrieve.
2368
+ * @returns The scope if found, otherwise undefined.
2369
+ */
2022
2370
  getScopeById(scopeId) {
2023
2371
  return this.scopeMap.get(scopeId);
2024
2372
  }
2025
- // 移除作用域
2373
+ /**
2374
+ * Removes a scope by its unique identifier and disposes of it.
2375
+ * @param scopeId The ID of the scope to remove.
2376
+ */
2026
2377
  removeScopeById(scopeId) {
2027
2378
  this.getScopeById(scopeId)?.dispose();
2028
2379
  }
2029
2380
  /**
2030
- * Get Scope, if Scope exists and type is same, will use it directly
2031
- * @param id scope id
2032
- * @param meta scope meta, defined by user
2033
- * @param ScopeConstructor scope constructor, default is Scope. you can extends Scope to create your own scope
2034
- * @returns
2381
+ * Creates a new scope or retrieves an existing one if the ID and type match.
2382
+ * @param id The unique identifier for the scope.
2383
+ * @param meta Optional metadata for the scope, defined by the user.
2384
+ * @param options Options for creating the scope.
2385
+ * @param options.ScopeConstructor The constructor to use for creating the scope. Defaults to `Scope`.
2386
+ * @returns The created or existing scope.
2035
2387
  */
2036
2388
  createScope(id, meta, options = {}) {
2037
2389
  const { ScopeConstructor = Scope } = options;
@@ -2044,7 +2396,7 @@ var VariableEngine = class {
2044
2396
  scope.ast.subscribe(() => {
2045
2397
  this.onScopeChangeEmitter.fire({ type: "update", scope });
2046
2398
  }),
2047
- // 可用变量发生变化
2399
+ // Fires when available variables change
2048
2400
  scope.available.onDataChange(() => {
2049
2401
  this.onScopeChangeEmitter.fire({ type: "available", scope });
2050
2402
  })
@@ -2056,7 +2408,12 @@ var VariableEngine = class {
2056
2408
  }
2057
2409
  return scope;
2058
2410
  }
2059
- // 获取系统中所有的作用域
2411
+ /**
2412
+ * Retrieves all scopes currently managed by the engine.
2413
+ * @param options Options for retrieving the scopes.
2414
+ * @param options.sort Whether to sort the scopes based on their dependency chain.
2415
+ * @returns An array of all scopes.
2416
+ */
2060
2417
  getAllScopes({
2061
2418
  sort
2062
2419
  } = {}) {
@@ -2069,9 +2426,19 @@ var VariableEngine = class {
2069
2426
  }
2070
2427
  return [...allScopes];
2071
2428
  }
2429
+ /**
2430
+ * Fires a global event to be broadcast to all listeners.
2431
+ * @param event The global event to fire.
2432
+ */
2072
2433
  fireGlobalEvent(event) {
2073
2434
  this.globalEvent$.next(event);
2074
2435
  }
2436
+ /**
2437
+ * Subscribes to a specific type of global event.
2438
+ * @param type The type of the event to listen for.
2439
+ * @param observer A function to be called when the event is observed.
2440
+ * @returns A disposable object to unsubscribe from the event.
2441
+ */
2075
2442
  onGlobalEvent(type, observer) {
2076
2443
  return subsToDisposable(
2077
2444
  this.globalEvent$.subscribe((_action) => {
@@ -2102,11 +2469,26 @@ var VariableFieldKeyRenameService = class {
2102
2469
  constructor() {
2103
2470
  this.toDispose = new DisposableCollection6();
2104
2471
  this.renameEmitter = new Emitter4();
2105
- // 没有被 rename 的字段通过 disposeInList 透出,让业务区分变量是 rename 删除的,还是真正从列表中删除的
2472
+ /**
2473
+ * Emits events for fields that are disposed of during a list change, but not renamed.
2474
+ * This helps distinguish between a field that was truly removed and one that was renamed.
2475
+ */
2106
2476
  this.disposeInListEmitter = new Emitter4();
2477
+ /**
2478
+ * An event that fires when a variable field key is successfully renamed.
2479
+ */
2107
2480
  this.onRename = this.renameEmitter.event;
2481
+ /**
2482
+ * An event that fires when a field is removed from a list (and not part of a rename).
2483
+ */
2108
2484
  this.onDisposeInList = this.disposeInListEmitter.event;
2109
2485
  }
2486
+ /**
2487
+ * Handles changes in a list of fields to detect rename operations.
2488
+ * @param ast The AST node where the change occurred.
2489
+ * @param prev The list of fields before the change.
2490
+ * @param next The list of fields after the change.
2491
+ */
2110
2492
  handleFieldListChange(ast, prev, next) {
2111
2493
  if (!ast || !prev?.length || !next?.length) {
2112
2494
  this.notifyFieldsDispose(prev, next);
@@ -2137,6 +2519,11 @@ var VariableFieldKeyRenameService = class {
2137
2519
  }
2138
2520
  this.renameEmitter.fire(renameNodeInfo);
2139
2521
  }
2522
+ /**
2523
+ * Notifies listeners about fields that were removed from a list.
2524
+ * @param prev The list of fields before the change.
2525
+ * @param next The list of fields after the change.
2526
+ */
2140
2527
  notifyFieldsDispose(prev, next) {
2141
2528
  const removedFields = difference(prev || [], next || []);
2142
2529
  removedFields.forEach((_field) => this.disposeInListEmitter.fire(_field));
@@ -2184,28 +2571,48 @@ var VariableContainerModule = new ContainerModule((bind) => {
2184
2571
  });
2185
2572
 
2186
2573
  // src/react/context.tsx
2187
- import { createContext, useContext } from "react";
2574
+ import React, { createContext, useContext } from "react";
2188
2575
  var ScopeContext = createContext(null);
2189
- var ScopeProvider = ScopeContext.Provider;
2190
- var useScopeContext = () => useContext(ScopeContext);
2191
- var useCurrentScope = () => useContext(ScopeContext)?.scope;
2576
+ var ScopeProvider = (props) => {
2577
+ const { scope, value, children } = props;
2578
+ const scopeToUse = scope || value?.scope;
2579
+ if (!scopeToUse) {
2580
+ throw new Error("[ScopeProvider] scope is required");
2581
+ }
2582
+ return /* @__PURE__ */ React.createElement(ScopeContext.Provider, { value: { scope: scopeToUse } }, children);
2583
+ };
2584
+ var useCurrentScope = (params) => {
2585
+ const { strict = false } = params || {};
2586
+ const context = useContext(ScopeContext);
2587
+ if (!context) {
2588
+ if (strict) {
2589
+ throw new Error("useCurrentScope must be used within a <ScopeProvider scope={scope}>");
2590
+ }
2591
+ console.warn("useCurrentScope should be used within a <ScopeProvider scope={scope}>");
2592
+ }
2593
+ return context?.scope;
2594
+ };
2192
2595
 
2193
- // src/react/hooks/useScopeAvailable.ts
2596
+ // src/react/hooks/use-scope-available.ts
2194
2597
  import { useEffect } from "react";
2195
2598
  import { useRefresh } from "@flowgram.ai/core";
2196
- function useScopeAvailable() {
2599
+ function useScopeAvailable(params) {
2600
+ const { autoRefresh = true } = params || {};
2197
2601
  const scope = useCurrentScope();
2198
2602
  const refresh = useRefresh();
2199
2603
  useEffect(() => {
2200
- const disposable = scope.available.onDataChange(() => {
2604
+ if (!autoRefresh) {
2605
+ return () => null;
2606
+ }
2607
+ const disposable = scope.available.onListOrAnyVarChange(() => {
2201
2608
  refresh();
2202
2609
  });
2203
2610
  return () => disposable.dispose();
2204
- }, []);
2611
+ }, [autoRefresh]);
2205
2612
  return scope.available;
2206
2613
  }
2207
2614
 
2208
- // src/react/hooks/useAvailableVariables.ts
2615
+ // src/react/hooks/use-available-variables.ts
2209
2616
  import { useEffect as useEffect2 } from "react";
2210
2617
  import { useRefresh as useRefresh2, useService } from "@flowgram.ai/core";
2211
2618
  function useAvailableVariables() {
@@ -2226,6 +2633,26 @@ function useAvailableVariables() {
2226
2633
  }, []);
2227
2634
  return scope ? scope.available.variables : variableEngine.globalVariableTable.variables;
2228
2635
  }
2636
+
2637
+ // src/react/hooks/use-output-variables.ts
2638
+ import { useEffect as useEffect3 } from "react";
2639
+ import { useRefresh as useRefresh3 } from "@flowgram.ai/core";
2640
+ function useOutputVariables() {
2641
+ const scope = useCurrentScope();
2642
+ const refresh = useRefresh3();
2643
+ useEffect3(() => {
2644
+ if (!scope) {
2645
+ throw new Error(
2646
+ "[useOutputVariables]: No scope found, useOutputVariables must be used in <ScopeProvider>"
2647
+ );
2648
+ }
2649
+ const disposable = scope.output.onListOrAnyVarChange(() => {
2650
+ refresh();
2651
+ });
2652
+ return () => disposable.dispose();
2653
+ }, []);
2654
+ return scope.output.variables;
2655
+ }
2229
2656
  export {
2230
2657
  ASTFactory,
2231
2658
  ASTKind,
@@ -2243,7 +2670,7 @@ export {
2243
2670
  EnumerateExpression,
2244
2671
  IntegerType,
2245
2672
  KeyPathExpression,
2246
- KeyPathExpressionV2,
2673
+ LegacyKeyPathExpression,
2247
2674
  ListNode,
2248
2675
  MapNode,
2249
2676
  MapType,
@@ -2267,7 +2694,7 @@ export {
2267
2694
  postConstructAST,
2268
2695
  useAvailableVariables,
2269
2696
  useCurrentScope,
2270
- useScopeAvailable,
2271
- useScopeContext
2697
+ useOutputVariables,
2698
+ useScopeAvailable
2272
2699
  };
2273
2700
  //# sourceMappingURL=index.js.map