@flowgram.ai/variable-core 0.1.0-alpha.10

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 ADDED
@@ -0,0 +1,2256 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var __decorateClass = (decorators, target, key, kind) => {
20
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
21
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
22
+ if (decorator = decorators[i])
23
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
24
+ if (kind && result) __defProp(target, key, result);
25
+ return result;
26
+ };
27
+ var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
28
+
29
+ // src/index.ts
30
+ var src_exports = {};
31
+ __export(src_exports, {
32
+ ASTFactory: () => ASTFactory,
33
+ ASTKind: () => ASTKind,
34
+ ASTMatch: () => ASTMatch,
35
+ ASTNode: () => ASTNode,
36
+ ASTNodeFlags: () => ASTNodeFlags,
37
+ ASTRegisters: () => ASTRegisters,
38
+ ArrayType: () => ArrayType,
39
+ BaseExpression: () => BaseExpression,
40
+ BaseType: () => BaseType,
41
+ BaseVariableField: () => BaseVariableField,
42
+ BooleanType: () => BooleanType,
43
+ CustomType: () => CustomType,
44
+ DataNode: () => DataNode,
45
+ EnumerateExpression: () => EnumerateExpression,
46
+ IntegerType: () => IntegerType,
47
+ KeyPathExpression: () => KeyPathExpression,
48
+ KeyPathExpressionV2: () => KeyPathExpressionV2,
49
+ ListNode: () => ListNode,
50
+ MapNode: () => MapNode,
51
+ MapType: () => MapType,
52
+ NumberType: () => NumberType,
53
+ ObjectType: () => ObjectType,
54
+ Property: () => Property,
55
+ Scope: () => Scope,
56
+ ScopeChain: () => ScopeChain,
57
+ ScopeOutputData: () => ScopeOutputData,
58
+ ScopeProvider: () => ScopeProvider,
59
+ StringType: () => StringType,
60
+ VariableContainerModule: () => VariableContainerModule,
61
+ VariableDeclaration: () => VariableDeclaration,
62
+ VariableDeclarationList: () => VariableDeclarationList,
63
+ VariableEngine: () => VariableEngine,
64
+ VariableEngineProvider: () => VariableEngineProvider,
65
+ VariableFieldKeyRenameService: () => VariableFieldKeyRenameService,
66
+ WrapArrayExpression: () => WrapArrayExpression,
67
+ injectToAST: () => injectToAST,
68
+ isMatchAST: () => isMatchAST,
69
+ postConstructAST: () => postConstructAST,
70
+ useAvailableVariables: () => useAvailableVariables,
71
+ useCurrentScope: () => useCurrentScope,
72
+ useScopeAvailable: () => useScopeAvailable,
73
+ useScopeContext: () => useScopeContext
74
+ });
75
+ module.exports = __toCommonJS(src_exports);
76
+
77
+ // src/variable-container-module.ts
78
+ var import_inversify8 = require("inversify");
79
+
80
+ // src/variable-engine.ts
81
+ var import_rxjs6 = require("rxjs");
82
+ var import_inversify6 = require("inversify");
83
+ var import_utils8 = require("@flowgram.ai/utils");
84
+ var import_utils9 = require("@flowgram.ai/utils");
85
+
86
+ // src/utils/toDisposable.tsx
87
+ var import_utils = require("@flowgram.ai/utils");
88
+ function subsToDisposable(subscription) {
89
+ return import_utils.Disposable.create(() => subscription.unsubscribe());
90
+ }
91
+
92
+ // src/utils/memo.ts
93
+ var createMemo = () => {
94
+ const _memoCache = /* @__PURE__ */ new Map();
95
+ const memo = (key, fn) => {
96
+ if (_memoCache.has(key)) {
97
+ return _memoCache.get(key);
98
+ }
99
+ const data = fn();
100
+ _memoCache.set(key, data);
101
+ return data;
102
+ };
103
+ const clear = (key) => {
104
+ if (key) {
105
+ _memoCache.delete(key);
106
+ } else {
107
+ _memoCache.clear();
108
+ }
109
+ };
110
+ memo.clear = clear;
111
+ return memo;
112
+ };
113
+
114
+ // src/scope/variable-table.ts
115
+ var import_rxjs = require("rxjs");
116
+ var import_utils2 = require("@flowgram.ai/utils");
117
+ var VariableTable = class {
118
+ constructor(parentTable) {
119
+ this.parentTable = parentTable;
120
+ this.table = /* @__PURE__ */ new Map();
121
+ this.onDataChangeEmitter = new import_utils2.Emitter();
122
+ this.variables$ = new import_rxjs.Subject();
123
+ // 监听变量列表中的单个变量变化
124
+ this.anyVariableChange$ = this.variables$.pipe(
125
+ (0, import_rxjs.switchMap)(
126
+ (_variables) => (0, import_rxjs.merge)(
127
+ ..._variables.map(
128
+ (_v) => _v.value$.pipe(
129
+ // 跳过 BehaviorSubject 第一个
130
+ (0, import_rxjs.skip)(1)
131
+ )
132
+ )
133
+ )
134
+ ),
135
+ (0, import_rxjs.share)()
136
+ );
137
+ /**
138
+ * @deprecated use onListOrAnyVarChange instead
139
+ */
140
+ this.onDataChange = this.onDataChangeEmitter.event;
141
+ this._version = 0;
142
+ }
143
+ /**
144
+ * listen to any variable update in list
145
+ * @param observer
146
+ * @returns
147
+ */
148
+ onAnyVariableChange(observer) {
149
+ return subsToDisposable(this.anyVariableChange$.subscribe(observer));
150
+ }
151
+ /**
152
+ * listen to variable list change
153
+ * @param observer
154
+ * @returns
155
+ */
156
+ onVariableListChange(observer) {
157
+ return subsToDisposable(this.variables$.subscribe(observer));
158
+ }
159
+ /**
160
+ * listen to variable list change + any variable update in list
161
+ * @param observer
162
+ */
163
+ onListOrAnyVarChange(observer) {
164
+ const disposables = new import_utils2.DisposableCollection();
165
+ disposables.pushAll([this.onVariableListChange(observer), this.onAnyVariableChange(observer)]);
166
+ return disposables;
167
+ }
168
+ fireChange() {
169
+ this._version++;
170
+ this.onDataChangeEmitter.fire();
171
+ this.variables$.next(this.variables);
172
+ this.parentTable?.fireChange();
173
+ }
174
+ get version() {
175
+ return this._version;
176
+ }
177
+ get variables() {
178
+ return Array.from(this.table.values());
179
+ }
180
+ get variableKeys() {
181
+ return Array.from(this.table.keys());
182
+ }
183
+ /**
184
+ * 根据 keyPath 找到对应的变量,或 Property 节点
185
+ * @param keyPath
186
+ * @returns
187
+ */
188
+ getByKeyPath(keyPath) {
189
+ const [variableKey, ...propertyKeys] = keyPath || [];
190
+ if (!variableKey) {
191
+ return;
192
+ }
193
+ const variable = this.getVariableByKey(variableKey);
194
+ return propertyKeys.length ? variable?.getByKeyPath(propertyKeys) : variable;
195
+ }
196
+ /**
197
+ * 根据 key 值找到相应的变量
198
+ * @param key
199
+ * @returns
200
+ */
201
+ getVariableByKey(key) {
202
+ return this.table.get(key);
203
+ }
204
+ /**
205
+ * 往 variableTable 添加输出变量
206
+ * @param variable
207
+ */
208
+ addVariableToTable(variable) {
209
+ this.table.set(variable.key, variable);
210
+ if (this.parentTable) {
211
+ this.parentTable.addVariableToTable(variable);
212
+ }
213
+ }
214
+ /**
215
+ * 从 variableTable 中移除变量
216
+ * @param key
217
+ */
218
+ removeVariableFromTable(key) {
219
+ this.table.delete(key);
220
+ if (this.parentTable) {
221
+ this.parentTable.removeVariableFromTable(key);
222
+ }
223
+ }
224
+ dispose() {
225
+ this.variableKeys.forEach(
226
+ (_key) => this.parentTable?.removeVariableFromTable(_key)
227
+ );
228
+ this.parentTable?.fireChange();
229
+ this.variables$.complete();
230
+ this.variables$.unsubscribe();
231
+ this.onDataChangeEmitter.dispose();
232
+ }
233
+ };
234
+
235
+ // src/scope/scope-chain.ts
236
+ var import_inversify = require("inversify");
237
+ var import_utils3 = require("@flowgram.ai/utils");
238
+
239
+ // src/providers.ts
240
+ var VariableEngineProvider = Symbol("DynamicVariableEngine");
241
+ var ContainerProvider = Symbol("ContainerProvider");
242
+
243
+ // src/scope/scope-chain.ts
244
+ var ScopeChain = class {
245
+ constructor() {
246
+ this.toDispose = new import_utils3.DisposableCollection();
247
+ }
248
+ get variableEngine() {
249
+ return this.variableEngineProvider();
250
+ }
251
+ /**
252
+ * 所有作用域依赖关系刷新
253
+ */
254
+ refreshAllChange() {
255
+ this.variableEngine.getAllScopes().forEach((_scope) => {
256
+ _scope.refreshCovers();
257
+ _scope.refreshDeps();
258
+ });
259
+ }
260
+ dispose() {
261
+ this.toDispose.dispose();
262
+ }
263
+ get disposed() {
264
+ return this.toDispose.disposed;
265
+ }
266
+ get onDispose() {
267
+ return this.toDispose.onDispose;
268
+ }
269
+ };
270
+ __decorateClass([
271
+ (0, import_inversify.inject)(VariableEngineProvider)
272
+ ], ScopeChain.prototype, "variableEngineProvider", 2);
273
+ ScopeChain = __decorateClass([
274
+ (0, import_inversify.injectable)()
275
+ ], ScopeChain);
276
+
277
+ // src/scope/scope.ts
278
+ var import_utils7 = require("@flowgram.ai/utils");
279
+
280
+ // src/ast/types.ts
281
+ var ASTKind = /* @__PURE__ */ ((ASTKind2) => {
282
+ ASTKind2["String"] = "String";
283
+ ASTKind2["Number"] = "Number";
284
+ ASTKind2["Integer"] = "Integer";
285
+ ASTKind2["Boolean"] = "Boolean";
286
+ ASTKind2["Object"] = "Object";
287
+ ASTKind2["Array"] = "Array";
288
+ ASTKind2["Map"] = "Map";
289
+ ASTKind2["Union"] = "Union";
290
+ ASTKind2["Any"] = "Any";
291
+ ASTKind2["CustomType"] = "CustomType";
292
+ ASTKind2["Property"] = "Property";
293
+ ASTKind2["VariableDeclaration"] = "VariableDeclaration";
294
+ ASTKind2["VariableDeclarationList"] = "VariableDeclarationList";
295
+ ASTKind2["KeyPathExpression"] = "KeyPathExpression";
296
+ ASTKind2["EnumerateExpression"] = "EnumerateExpression";
297
+ ASTKind2["WrapArrayExpression"] = "WrapArrayExpression";
298
+ ASTKind2["ListNode"] = "ListNode";
299
+ ASTKind2["DataNode"] = "DataNode";
300
+ ASTKind2["MapNode"] = "MapNode";
301
+ return ASTKind2;
302
+ })(ASTKind || {});
303
+
304
+ // src/ast/ast-registers.ts
305
+ var import_lodash3 = require("lodash");
306
+ var import_inversify3 = require("inversify");
307
+
308
+ // src/ast/utils/inversify.ts
309
+ var injectToAST = (serviceIdentifier) => function(target, propertyKey) {
310
+ if (!serviceIdentifier) {
311
+ throw new Error(
312
+ `ServiceIdentifier ${serviceIdentifier} in @lazyInject is Empty, it might be caused by file circular dependency, please check it.`
313
+ );
314
+ }
315
+ const descriptor = {
316
+ get() {
317
+ const container = this.scope.variableEngine.container;
318
+ return container.get(serviceIdentifier);
319
+ },
320
+ set() {
321
+ },
322
+ configurable: true,
323
+ enumerable: true
324
+ };
325
+ return descriptor;
326
+ };
327
+ var POST_CONSTRUCT_AST_SYMBOL = Symbol("post_construct_ast");
328
+ var postConstructAST = () => (target, propertyKey) => {
329
+ if (!Reflect.hasMetadata(POST_CONSTRUCT_AST_SYMBOL, target)) {
330
+ Reflect.defineMetadata(POST_CONSTRUCT_AST_SYMBOL, propertyKey, target);
331
+ } else {
332
+ throw Error("Duplication Post Construct AST");
333
+ }
334
+ };
335
+
336
+ // src/ast/match.ts
337
+ var ASTMatch;
338
+ ((ASTMatch2) => {
339
+ ASTMatch2.isString = (node) => node?.kind === "String" /* String */;
340
+ ASTMatch2.isNumber = (node) => node?.kind === "Number" /* Number */;
341
+ ASTMatch2.isBoolean = (node) => node?.kind === "Boolean" /* Boolean */;
342
+ ASTMatch2.isInteger = (node) => node?.kind === "Integer" /* Integer */;
343
+ ASTMatch2.isObject = (node) => node?.kind === "Object" /* Object */;
344
+ ASTMatch2.isArray = (node) => node?.kind === "Array" /* Array */;
345
+ ASTMatch2.isMap = (node) => node?.kind === "Map" /* Map */;
346
+ ASTMatch2.isCustomType = (node) => node?.kind === "CustomType" /* CustomType */;
347
+ ASTMatch2.isVariableDeclaration = (node) => node?.kind === "VariableDeclaration" /* VariableDeclaration */;
348
+ ASTMatch2.isProperty = (node) => node?.kind === "Property" /* Property */;
349
+ ASTMatch2.isVariableDeclarationList = (node) => node?.kind === "VariableDeclarationList" /* VariableDeclarationList */;
350
+ ASTMatch2.isEnumerateExpression = (node) => node?.kind === "EnumerateExpression" /* EnumerateExpression */;
351
+ ASTMatch2.isKeyPathExpression = (node) => node?.kind === "KeyPathExpression" /* KeyPathExpression */;
352
+ function is(node, targetType) {
353
+ return node?.kind === targetType?.kind;
354
+ }
355
+ ASTMatch2.is = is;
356
+ })(ASTMatch || (ASTMatch = {}));
357
+
358
+ // src/ast/utils/helpers.ts
359
+ function updateChildNodeHelper({
360
+ getChildNode,
361
+ updateChildNode,
362
+ removeChildNode,
363
+ nextJSON
364
+ }) {
365
+ const currNode = getChildNode();
366
+ const isNewKind = currNode?.kind !== nextJSON?.kind;
367
+ const isNewKey = nextJSON?.key && nextJSON?.key !== currNode?.key;
368
+ if (isNewKind || isNewKey) {
369
+ if (currNode) {
370
+ currNode.dispose();
371
+ removeChildNode();
372
+ }
373
+ if (nextJSON) {
374
+ const newNode = this.createChildNode(nextJSON);
375
+ updateChildNode(newNode);
376
+ this.fireChange();
377
+ return newNode;
378
+ } else {
379
+ this.fireChange();
380
+ }
381
+ } else if (nextJSON) {
382
+ currNode?.fromJSON(nextJSON);
383
+ }
384
+ return currNode;
385
+ }
386
+ function parseTypeJsonOrKind(typeJSONOrKind) {
387
+ return typeof typeJSONOrKind === "string" ? { kind: typeJSONOrKind } : typeJSONOrKind;
388
+ }
389
+ function getAllChildren(ast) {
390
+ return [...ast.children, ...ast.children.map((_child) => getAllChildren(_child)).flat()];
391
+ }
392
+ function isMatchAST(node, targetType) {
393
+ return ASTMatch.is(node, targetType);
394
+ }
395
+
396
+ // src/ast/flags.ts
397
+ var ASTNodeFlags = /* @__PURE__ */ ((ASTNodeFlags2) => {
398
+ ASTNodeFlags2[ASTNodeFlags2["None"] = 0] = "None";
399
+ ASTNodeFlags2[ASTNodeFlags2["VariableField"] = 1] = "VariableField";
400
+ ASTNodeFlags2[ASTNodeFlags2["Expression"] = 4] = "Expression";
401
+ ASTNodeFlags2[ASTNodeFlags2["BasicType"] = 8] = "BasicType";
402
+ ASTNodeFlags2[ASTNodeFlags2["DrilldownType"] = 16] = "DrilldownType";
403
+ ASTNodeFlags2[ASTNodeFlags2["EnumerateType"] = 32] = "EnumerateType";
404
+ ASTNodeFlags2[ASTNodeFlags2["UnionType"] = 64] = "UnionType";
405
+ ASTNodeFlags2[ASTNodeFlags2["VariableType"] = 120] = "VariableType";
406
+ return ASTNodeFlags2;
407
+ })(ASTNodeFlags || {});
408
+
409
+ // src/ast/ast-node.ts
410
+ var import_rxjs2 = require("rxjs");
411
+ var import_nanoid = require("nanoid");
412
+ var import_fast_equals = require("fast-equals");
413
+ var import_utils4 = require("@flowgram.ai/utils");
414
+ var ASTNode = class _ASTNode {
415
+ /**
416
+ * 构造函数
417
+ * @param createParams 创建 ASTNode 的必要参数
418
+ * @param injectOptions 依赖注入各种模块
419
+ */
420
+ constructor({ key, parent, scope }, opts) {
421
+ /**
422
+ * 节点 Flags,记录一些 Flag 信息
423
+ */
424
+ this.flags = 0 /* None */;
425
+ /**
426
+ * 节点的版本号,每 fireChange 一次 version + 1
427
+ */
428
+ this._version = 0;
429
+ /**
430
+ * 更新锁
431
+ */
432
+ this.changeLocked = false;
433
+ /**
434
+ * Batch Update 相关参数
435
+ */
436
+ this._batch = {
437
+ batching: false,
438
+ hasChangesInBatch: false
439
+ };
440
+ /**
441
+ * AST 节点变化事件,基于 Rxjs 实现
442
+ * - 使用了 BehaviorSubject, 在订阅时会自动触发一次事件,事件为当前值
443
+ */
444
+ this.value$ = new import_rxjs2.BehaviorSubject(this);
445
+ /**
446
+ * 子节点
447
+ */
448
+ this._children = /* @__PURE__ */ new Set();
449
+ /**
450
+ * 删除节点处理事件列表
451
+ */
452
+ this.toDispose = new import_utils4.DisposableCollection(
453
+ import_utils4.Disposable.create(() => {
454
+ this.parent?.fireChange();
455
+ this.children.forEach((child) => child.dispose());
456
+ })
457
+ );
458
+ /**
459
+ * 销毁时触发的回调
460
+ */
461
+ this.onDispose = this.toDispose.onDispose;
462
+ this.scope = scope;
463
+ this.parent = parent;
464
+ this.opts = opts;
465
+ this.key = key || (0, import_nanoid.nanoid)();
466
+ this.fromJSON = this.withBatchUpdate(this.fromJSON.bind(this));
467
+ this.dispatchGlobalEvent({ type: "NewAST" });
468
+ }
469
+ /**
470
+ * AST 节点的类型
471
+ */
472
+ get kind() {
473
+ if (!this.constructor.kind) {
474
+ throw new Error(`ASTNode Registry need a kind: ${this.constructor.name}`);
475
+ }
476
+ return this.constructor.kind;
477
+ }
478
+ /**
479
+ * 获取当前节点所有子节点
480
+ */
481
+ get children() {
482
+ return Array.from(this._children);
483
+ }
484
+ /**
485
+ * 转化为 ASTNodeJSON
486
+ * @returns
487
+ */
488
+ toJSON() {
489
+ console.warn("[VariableEngine] Please Implement toJSON method for " + this.kind);
490
+ return {
491
+ kind: this.kind
492
+ };
493
+ }
494
+ /**
495
+ * 创建子节点
496
+ * @param json 子节点的 AST JSON
497
+ * @returns
498
+ */
499
+ createChildNode(json) {
500
+ const astRegisters = this.scope.variableEngine.astRegisters;
501
+ const child = astRegisters.createAST(json, {
502
+ parent: this,
503
+ scope: this.scope
504
+ });
505
+ this._children.add(child);
506
+ child.toDispose.push(
507
+ import_utils4.Disposable.create(() => {
508
+ this._children.delete(child);
509
+ })
510
+ );
511
+ return child;
512
+ }
513
+ /**
514
+ * 更新子节点,快速实现子节点更新消费逻辑
515
+ * @param keyInThis 当前对象上的指定 key
516
+ */
517
+ updateChildNodeByKey(keyInThis, nextJSON) {
518
+ this.withBatchUpdate(updateChildNodeHelper).call(this, {
519
+ getChildNode: () => this[keyInThis],
520
+ updateChildNode: (_node) => this[keyInThis] = _node,
521
+ removeChildNode: () => this[keyInThis] = void 0,
522
+ nextJSON
523
+ });
524
+ }
525
+ /**
526
+ * 批处理更新,批处理函数内所有的 fireChange 都合并成一个
527
+ * @param updater 批处理函数
528
+ * @returns
529
+ */
530
+ withBatchUpdate(updater) {
531
+ return (...args) => {
532
+ if (this._batch.batching) {
533
+ return updater.call(this, ...args);
534
+ }
535
+ this._batch.hasChangesInBatch = false;
536
+ this._batch.batching = true;
537
+ const res = updater.call(this, ...args);
538
+ this._batch.batching = false;
539
+ if (this._batch.hasChangesInBatch) {
540
+ this.fireChange();
541
+ }
542
+ this._batch.hasChangesInBatch = false;
543
+ return res;
544
+ };
545
+ }
546
+ /**
547
+ * 触发当前节点更新
548
+ */
549
+ fireChange() {
550
+ if (this.changeLocked || this.disposed) {
551
+ return;
552
+ }
553
+ if (this._batch.batching) {
554
+ this._batch.hasChangesInBatch = true;
555
+ return;
556
+ }
557
+ this._version++;
558
+ this.value$.next(this);
559
+ this.dispatchGlobalEvent({ type: "UpdateAST" });
560
+ this.parent?.fireChange();
561
+ }
562
+ /**
563
+ * 节点的版本值
564
+ * - 通过 NodeA === NodeB && versionA === versionB 可以比较两者是否相等
565
+ */
566
+ get version() {
567
+ return this._version;
568
+ }
569
+ /**
570
+ * 节点唯一 hash 值
571
+ */
572
+ get hash() {
573
+ return `${this._version}${this.kind}${this.key}`;
574
+ }
575
+ /**
576
+ * 监听 AST 节点的变化
577
+ * @param observer 监听回调
578
+ * @param selector 监听指定数据
579
+ * @returns
580
+ */
581
+ subscribe(observer, { selector, debounceAnimation, triggerOnInit } = {}) {
582
+ return subsToDisposable(
583
+ this.value$.pipe(
584
+ (0, import_rxjs2.map)(() => selector ? selector(this) : this),
585
+ (0, import_rxjs2.distinctUntilChanged)(
586
+ (a, b) => (0, import_fast_equals.shallowEqual)(a, b),
587
+ (value) => {
588
+ if (value instanceof _ASTNode) {
589
+ return value.hash;
590
+ }
591
+ return value;
592
+ }
593
+ ),
594
+ // 默认跳过 BehaviorSubject 第一次触发
595
+ triggerOnInit ? (0, import_rxjs2.tap)(() => null) : (0, import_rxjs2.skip)(1),
596
+ // 每个 animationFrame 内所有更新合并成一个
597
+ debounceAnimation ? (0, import_rxjs2.debounceTime)(0, import_rxjs2.animationFrameScheduler) : (0, import_rxjs2.tap)(() => null)
598
+ ).subscribe(observer)
599
+ );
600
+ }
601
+ dispatchGlobalEvent(event) {
602
+ this.scope.event.dispatch({
603
+ ...event,
604
+ ast: this
605
+ });
606
+ }
607
+ /**
608
+ * 销毁
609
+ */
610
+ dispose() {
611
+ if (this.toDispose.disposed) {
612
+ return;
613
+ }
614
+ this.toDispose.dispose();
615
+ this.dispatchGlobalEvent({ type: "DisposeAST" });
616
+ this.value$.complete();
617
+ this.value$.unsubscribe();
618
+ }
619
+ get disposed() {
620
+ return this.toDispose.disposed;
621
+ }
622
+ };
623
+
624
+ // src/ast/type/base-type.ts
625
+ var BaseType = class extends ASTNode {
626
+ constructor() {
627
+ super(...arguments);
628
+ this.flags = 8 /* BasicType */;
629
+ }
630
+ /**
631
+ * 类型是否一致
632
+ * @param targetTypeJSON
633
+ */
634
+ isTypeEqual(targetTypeJSONOrKind) {
635
+ const targetTypeJSON = parseTypeJsonOrKind(targetTypeJSONOrKind);
636
+ if (targetTypeJSON?.kind === "Union" /* Union */) {
637
+ return (targetTypeJSON?.types || [])?.some(
638
+ (_subType) => this.isTypeEqual(_subType)
639
+ );
640
+ }
641
+ return this.kind === targetTypeJSON?.kind;
642
+ }
643
+ /**
644
+ * 可下钻类型需实现
645
+ * @param keyPath
646
+ */
647
+ getByKeyPath(keyPath = []) {
648
+ throw new Error(`Get By Key Path is not implemented for Type: ${this.kind}`);
649
+ }
650
+ /**
651
+ * Get AST JSON for current base type
652
+ * @returns
653
+ */
654
+ toJSON() {
655
+ return {
656
+ kind: this.kind
657
+ };
658
+ }
659
+ };
660
+
661
+ // src/ast/type/array.ts
662
+ var ArrayType = class extends BaseType {
663
+ constructor() {
664
+ super(...arguments);
665
+ this.flags = 16 /* DrilldownType */ | 32 /* EnumerateType */;
666
+ }
667
+ fromJSON({ items }) {
668
+ this.updateChildNodeByKey("items", parseTypeJsonOrKind(items));
669
+ }
670
+ // items 类型是否可下钻
671
+ get canDrilldownItems() {
672
+ return !!(this.items?.flags & 16 /* DrilldownType */);
673
+ }
674
+ getByKeyPath(keyPath) {
675
+ const [curr, ...rest] = keyPath || [];
676
+ if (curr === "0" && this.canDrilldownItems) {
677
+ return this.items.getByKeyPath(rest);
678
+ }
679
+ return void 0;
680
+ }
681
+ isTypeEqual(targetTypeJSONOrKind) {
682
+ const targetTypeJSON = parseTypeJsonOrKind(targetTypeJSONOrKind);
683
+ const isSuperEqual = super.isTypeEqual(targetTypeJSONOrKind);
684
+ if (targetTypeJSON?.weak || targetTypeJSON?.kind === "Union" /* Union */) {
685
+ return isSuperEqual;
686
+ }
687
+ return targetTypeJSON && isSuperEqual && // 弱比较,只需要比较 Kind 即可
688
+ (targetTypeJSON?.weak || this.customStrongEqual(targetTypeJSON));
689
+ }
690
+ /**
691
+ * Array 强比较
692
+ * @param targetTypeJSON
693
+ * @returns
694
+ */
695
+ customStrongEqual(targetTypeJSON) {
696
+ if (!this.items) {
697
+ return !targetTypeJSON?.items;
698
+ }
699
+ return this.items?.isTypeEqual(targetTypeJSON.items);
700
+ }
701
+ toJSON() {
702
+ return {
703
+ kind: "Array" /* Array */,
704
+ items: this.items?.toJSON()
705
+ };
706
+ }
707
+ };
708
+ ArrayType.kind = "Array" /* Array */;
709
+
710
+ // src/ast/type/string.ts
711
+ var StringType = class extends BaseType {
712
+ constructor() {
713
+ super(...arguments);
714
+ this.flags = 8 /* BasicType */;
715
+ }
716
+ fromJSON() {
717
+ }
718
+ };
719
+ StringType.kind = "String" /* String */;
720
+
721
+ // src/ast/type/integer.ts
722
+ var IntegerType = class extends BaseType {
723
+ constructor() {
724
+ super(...arguments);
725
+ this.flags = 8 /* BasicType */;
726
+ }
727
+ fromJSON() {
728
+ }
729
+ };
730
+ IntegerType.kind = "Integer" /* Integer */;
731
+
732
+ // src/ast/type/boolean.ts
733
+ var BooleanType = class extends BaseType {
734
+ fromJSON() {
735
+ }
736
+ };
737
+ BooleanType.kind = "Boolean" /* Boolean */;
738
+
739
+ // src/ast/type/number.ts
740
+ var NumberType = class extends BaseType {
741
+ fromJSON() {
742
+ }
743
+ };
744
+ NumberType.kind = "Number" /* Number */;
745
+
746
+ // src/ast/type/map.ts
747
+ var MapType = class extends BaseType {
748
+ fromJSON({ keyType = "String" /* String */, valueType }) {
749
+ this.updateChildNodeByKey("keyType", parseTypeJsonOrKind(keyType));
750
+ this.updateChildNodeByKey("valueType", parseTypeJsonOrKind(valueType));
751
+ }
752
+ // Value 类型是否可下钻,后续实现
753
+ // get canDrilldownValue(): boolean {
754
+ // return !!(this.valueType.flags & ASTNodeFlags.DrilldownType);
755
+ // }
756
+ // getByKeyPath(keyPath: string[]): BaseVariableField | undefined {
757
+ // const [curr, ...rest] = keyPath || [];
758
+ // if (curr === '*' && this.canDrilldownValue) {
759
+ // return this.valueType.getByKeyPath(rest);
760
+ // }
761
+ // return undefined;
762
+ // }
763
+ isTypeEqual(targetTypeJSONOrKind) {
764
+ const targetTypeJSON = parseTypeJsonOrKind(targetTypeJSONOrKind);
765
+ const isSuperEqual = super.isTypeEqual(targetTypeJSONOrKind);
766
+ if (targetTypeJSON?.weak || targetTypeJSON?.kind === "Union" /* Union */) {
767
+ return isSuperEqual;
768
+ }
769
+ return targetTypeJSON && isSuperEqual && // 弱比较,只需要比较 Kind 即可
770
+ (targetTypeJSON?.weak || this.customStrongEqual(targetTypeJSON));
771
+ }
772
+ /**
773
+ * Map 强比较
774
+ * @param targetTypeJSON
775
+ * @returns
776
+ */
777
+ customStrongEqual(targetTypeJSON) {
778
+ const { keyType = "String" /* String */, valueType } = targetTypeJSON;
779
+ const isValueTypeEqual = !valueType && !this.valueType || this.valueType?.isTypeEqual(valueType);
780
+ return isValueTypeEqual && this.keyType?.isTypeEqual(keyType);
781
+ }
782
+ toJSON() {
783
+ return {
784
+ kind: "Map" /* Map */,
785
+ keyType: this.keyType?.toJSON(),
786
+ valueType: this.valueType?.toJSON()
787
+ };
788
+ }
789
+ };
790
+ // public flags: ASTNodeFlags = ASTNodeFlags.DrilldownType | ASTNodeFlags.EnumerateType;
791
+ MapType.kind = "Map" /* Map */;
792
+
793
+ // src/ast/type/object.ts
794
+ var import_lodash = require("lodash");
795
+ var ObjectType = class extends BaseType {
796
+ constructor() {
797
+ super(...arguments);
798
+ this.flags = 16 /* DrilldownType */;
799
+ this.propertyTable = /* @__PURE__ */ new Map();
800
+ }
801
+ fromJSON({ properties }) {
802
+ const removedKeys = new Set(this.propertyTable.keys());
803
+ const prev = [...this.properties || []];
804
+ this.properties = (properties || []).map((property) => {
805
+ const existProperty = this.propertyTable.get(property.key);
806
+ removedKeys.delete(property.key);
807
+ if (existProperty) {
808
+ existProperty.fromJSON(property);
809
+ return existProperty;
810
+ } else {
811
+ const newProperty = this.createChildNode({
812
+ ...property,
813
+ kind: "Property" /* Property */
814
+ });
815
+ this.fireChange();
816
+ this.propertyTable.set(property.key, newProperty);
817
+ return newProperty;
818
+ }
819
+ });
820
+ removedKeys.forEach((key) => {
821
+ const property = this.propertyTable.get(key);
822
+ property?.dispose();
823
+ this.propertyTable.delete(key);
824
+ this.fireChange();
825
+ });
826
+ this.dispatchGlobalEvent({
827
+ type: "ObjectPropertiesChange",
828
+ payload: {
829
+ prev,
830
+ next: [...this.properties]
831
+ }
832
+ });
833
+ }
834
+ toJSON() {
835
+ return {
836
+ kind: "Object" /* Object */,
837
+ properties: this.properties.map((_property) => _property.toJSON())
838
+ };
839
+ }
840
+ /**
841
+ * 根据 KeyPath 找到对应的变量
842
+ * @param keyPath 变量路径
843
+ * @returns
844
+ */
845
+ getByKeyPath(keyPath) {
846
+ const [curr, ...restKeyPath] = keyPath;
847
+ const property = this.propertyTable.get(curr);
848
+ if (!restKeyPath.length) {
849
+ return property;
850
+ }
851
+ if (property?.type && property?.type?.flags & 16 /* DrilldownType */) {
852
+ return property.type.getByKeyPath(restKeyPath);
853
+ }
854
+ return void 0;
855
+ }
856
+ isTypeEqual(targetTypeJSONOrKind) {
857
+ const targetTypeJSON = parseTypeJsonOrKind(targetTypeJSONOrKind);
858
+ const isSuperEqual = super.isTypeEqual(targetTypeJSONOrKind);
859
+ if (targetTypeJSON?.weak || targetTypeJSON?.kind === "Union" /* Union */) {
860
+ return isSuperEqual;
861
+ }
862
+ return targetTypeJSON && isSuperEqual && // 弱比较,只需要比较 Kind 即可
863
+ (targetTypeJSON?.weak || this.customStrongEqual(targetTypeJSON));
864
+ }
865
+ /**
866
+ * Object 类型强比较
867
+ * @param targetTypeJSON
868
+ * @returns
869
+ */
870
+ customStrongEqual(targetTypeJSON) {
871
+ const targetProperties = targetTypeJSON.properties || [];
872
+ const sourcePropertyKeys = Array.from(this.propertyTable.keys());
873
+ const targetPropertyKeys = targetProperties.map((_target) => _target.key);
874
+ const isKeyStrongEqual = !(0, import_lodash.xor)(sourcePropertyKeys, targetPropertyKeys).length;
875
+ return isKeyStrongEqual && targetProperties.every((targetProperty) => {
876
+ const sourceProperty = this.propertyTable.get(targetProperty.key);
877
+ return sourceProperty && sourceProperty.key === targetProperty.key && sourceProperty.type?.isTypeEqual(targetProperty?.type);
878
+ });
879
+ }
880
+ };
881
+ ObjectType.kind = "Object" /* Object */;
882
+
883
+ // src/ast/type/custom-type.ts
884
+ var CustomType = class extends BaseType {
885
+ get typeName() {
886
+ return this._typeName;
887
+ }
888
+ fromJSON(json) {
889
+ if (this._typeName !== json.typeName) {
890
+ this._typeName = json.typeName;
891
+ this.fireChange();
892
+ }
893
+ }
894
+ isTypeEqual(targetTypeJSONOrKind) {
895
+ const targetTypeJSON = parseTypeJsonOrKind(targetTypeJSONOrKind);
896
+ if (targetTypeJSON?.kind === "Union" /* Union */) {
897
+ return (targetTypeJSON?.types || [])?.some(
898
+ (_subType) => this.isTypeEqual(_subType)
899
+ );
900
+ }
901
+ return targetTypeJSON?.kind === this.kind && targetTypeJSON?.typeName === this.typeName;
902
+ }
903
+ };
904
+ CustomType.kind = "CustomType" /* CustomType */;
905
+
906
+ // src/ast/expression/base-expression.ts
907
+ var import_rxjs3 = require("rxjs");
908
+ var import_fast_equals2 = require("fast-equals");
909
+
910
+ // src/ast/utils/variable-field.ts
911
+ function getParentFields(ast) {
912
+ let curr = ast.parent;
913
+ const res = [];
914
+ while (curr) {
915
+ if (curr.flags & 1 /* VariableField */) {
916
+ res.push(curr);
917
+ }
918
+ curr = curr.parent;
919
+ }
920
+ return res;
921
+ }
922
+
923
+ // src/ast/expression/base-expression.ts
924
+ var BaseExpression = class extends ASTNode {
925
+ constructor(params, opts) {
926
+ super(params, opts);
927
+ this.flags = 4 /* Expression */;
928
+ /**
929
+ * 引用变量
930
+ */
931
+ this._refs = [];
932
+ this.refreshRefs$ = new import_rxjs3.Subject();
933
+ /**
934
+ * 监听引用变量变化
935
+ * 监听 [a.b.c] -> [a.b]
936
+ */
937
+ this.refs$ = this.refreshRefs$.pipe(
938
+ (0, import_rxjs3.map)(() => this.getRefFields()),
939
+ (0, import_rxjs3.distinctUntilChanged)(import_fast_equals2.shallowEqual),
940
+ (0, import_rxjs3.switchMap)(
941
+ (refs) => !refs?.length ? (0, import_rxjs3.of)([]) : (0, import_rxjs3.combineLatest)(
942
+ refs.map(
943
+ (ref) => ref ? ref.value$ : (0, import_rxjs3.of)(void 0)
944
+ )
945
+ )
946
+ ),
947
+ (0, import_rxjs3.share)()
948
+ );
949
+ this.toDispose.push(
950
+ subsToDisposable(
951
+ this.refs$.subscribe((_refs) => {
952
+ this._refs = _refs;
953
+ this.fireChange();
954
+ })
955
+ )
956
+ );
957
+ }
958
+ /**
959
+ * 获取全局变量表,方便表达式获取引用变量
960
+ */
961
+ get globalVariableTable() {
962
+ return this.scope.variableEngine.globalVariableTable;
963
+ }
964
+ /**
965
+ * 父变量字段,通过由近而远的方式进行排序
966
+ */
967
+ get parentFields() {
968
+ return getParentFields(this);
969
+ }
970
+ get refs() {
971
+ return this._refs;
972
+ }
973
+ /**
974
+ * 刷新变量引用
975
+ */
976
+ refreshRefs() {
977
+ this.refreshRefs$.next();
978
+ }
979
+ };
980
+
981
+ // src/ast/expression/keypath-expression.ts
982
+ var import_fast_equals3 = require("fast-equals");
983
+ var KeyPathExpression = class extends BaseExpression {
984
+ constructor(params, opts) {
985
+ super(params, opts);
986
+ this._keyPath = [];
987
+ this.toDispose.pushAll([
988
+ // 可以用变量列表变化时候 (有新增或者删除时)
989
+ this.scope.available.onVariableListChange(() => {
990
+ this.refreshRefs();
991
+ }),
992
+ // this._keyPath 指向的可引用变量发生变化时,刷新引用数据
993
+ this.scope.available.onAnyVariableChange((_v) => {
994
+ if (_v.key === this._keyPath[0]) {
995
+ this.refreshRefs();
996
+ }
997
+ })
998
+ ]);
999
+ }
1000
+ get keyPath() {
1001
+ return this._keyPath;
1002
+ }
1003
+ getRefFields() {
1004
+ const ref = this.scope.available.getByKeyPath(this._keyPath);
1005
+ return ref ? [ref] : [];
1006
+ }
1007
+ get returnType() {
1008
+ const [refNode] = this._refs || [];
1009
+ if (refNode && refNode.flags & 1 /* VariableField */) {
1010
+ return refNode.type;
1011
+ }
1012
+ return;
1013
+ }
1014
+ /**
1015
+ * 业务重改该方法可快速定制自己的 Path 表达式
1016
+ * - 只需要将业务的 Path 解析为变量系统的 KeyPath 即可
1017
+ * @param json 业务定义的 Path 表达式
1018
+ * @returns
1019
+ */
1020
+ parseToKeyPath(json) {
1021
+ return json.keyPath;
1022
+ }
1023
+ fromJSON(json) {
1024
+ const keyPath = this.parseToKeyPath(json);
1025
+ if (!(0, import_fast_equals3.shallowEqual)(keyPath, this._keyPath)) {
1026
+ this._keyPath = keyPath;
1027
+ this.refreshRefs();
1028
+ }
1029
+ }
1030
+ toJSON() {
1031
+ return {
1032
+ kind: "KeyPathExpression" /* KeyPathExpression */,
1033
+ keyPath: this._keyPath
1034
+ };
1035
+ }
1036
+ };
1037
+ KeyPathExpression.kind = "KeyPathExpression" /* KeyPathExpression */;
1038
+
1039
+ // src/ast/expression/enumerate-expression.ts
1040
+ var EnumerateExpression = class extends BaseExpression {
1041
+ get enumerateFor() {
1042
+ return this._enumerateFor;
1043
+ }
1044
+ get returnType() {
1045
+ const childReturnType = this.enumerateFor?.returnType;
1046
+ if (childReturnType?.kind === "Array" /* Array */) {
1047
+ return childReturnType.items;
1048
+ }
1049
+ return void 0;
1050
+ }
1051
+ getRefFields() {
1052
+ return [];
1053
+ }
1054
+ fromJSON({ enumerateFor: expression }) {
1055
+ this.updateChildNodeByKey("_enumerateFor", expression);
1056
+ }
1057
+ toJSON() {
1058
+ return {
1059
+ kind: "EnumerateExpression" /* EnumerateExpression */,
1060
+ enumerateFor: this.enumerateFor?.toJSON()
1061
+ };
1062
+ }
1063
+ };
1064
+ EnumerateExpression.kind = "EnumerateExpression" /* EnumerateExpression */;
1065
+
1066
+ // src/ast/expression/keypath-expression-v2.ts
1067
+ var import_fast_equals4 = require("fast-equals");
1068
+
1069
+ // src/ast/utils/expression.ts
1070
+ var import_lodash2 = require("lodash");
1071
+ function getAllRefs(ast) {
1072
+ return getAllChildren(ast).filter((_child) => _child.flags & 4 /* Expression */).map((_child) => _child.refs).flat().filter(Boolean);
1073
+ }
1074
+ function checkRefCycle(curr, refNodes) {
1075
+ if ((0, import_lodash2.intersection)(curr.scope.coverScopes, refNodes.map((_ref) => _ref?.scope).filter(Boolean)).length === 0) {
1076
+ return false;
1077
+ }
1078
+ const visited = /* @__PURE__ */ new Set();
1079
+ const queue = [...refNodes];
1080
+ while (queue.length) {
1081
+ const currNode = queue.shift();
1082
+ visited.add(currNode);
1083
+ for (const ref of getAllRefs(currNode).filter((_ref) => !visited.has(_ref))) {
1084
+ queue.push(ref);
1085
+ }
1086
+ }
1087
+ return (0, import_lodash2.intersection)(Array.from(visited), getParentFields(curr)).length > 0;
1088
+ }
1089
+
1090
+ // src/ast/expression/keypath-expression-v2.ts
1091
+ var KeyPathExpressionV2 = class extends BaseExpression {
1092
+ constructor(params, opts) {
1093
+ super(params, opts);
1094
+ this._keyPath = [];
1095
+ this.toDispose.pushAll([
1096
+ // 可以用变量列表变化时候 (有新增或者删除时)
1097
+ this.scope.available.onVariableListChange(() => {
1098
+ this.refreshRefs();
1099
+ }),
1100
+ // this._keyPath 指向的可引用变量发生变化时,刷新引用数据
1101
+ this.scope.available.onAnyVariableChange((_v) => {
1102
+ if (_v.key === this._keyPath[0]) {
1103
+ this.refreshRefs();
1104
+ }
1105
+ }),
1106
+ subsToDisposable(
1107
+ this.refs$.subscribe((_type) => {
1108
+ const [ref] = this._refs;
1109
+ if (this.prevRefTypeHash !== ref?.type?.hash) {
1110
+ this.prevRefTypeHash = ref?.type?.hash;
1111
+ this.updateChildNodeByKey("_returnType", this.getReturnTypeJSONByRef(ref));
1112
+ }
1113
+ })
1114
+ )
1115
+ ]);
1116
+ }
1117
+ get keyPath() {
1118
+ return this._keyPath;
1119
+ }
1120
+ getRefFields() {
1121
+ const ref = this.scope.available.getByKeyPath(this._keyPath);
1122
+ if (checkRefCycle(this, [ref])) {
1123
+ console.warn(
1124
+ "[CustomKeyPathExpression] checkRefCycle: Reference Cycle Existed",
1125
+ this.parentFields.map((_field) => _field.key).reverse()
1126
+ );
1127
+ return [];
1128
+ }
1129
+ return ref ? [ref] : [];
1130
+ }
1131
+ get returnType() {
1132
+ return this._returnType;
1133
+ }
1134
+ /**
1135
+ * 业务重改该方法可快速定制自己的 Path 表达式
1136
+ * - 只需要将业务的 Path 解析为变量系统的 KeyPath 即可
1137
+ * @param json 业务定义的 Path 表达式
1138
+ * @returns
1139
+ */
1140
+ parseToKeyPath(json) {
1141
+ return json.keyPath;
1142
+ }
1143
+ fromJSON(json) {
1144
+ const keyPath = this.parseToKeyPath(json);
1145
+ if (!(0, import_fast_equals4.shallowEqual)(keyPath, this._keyPath)) {
1146
+ this._keyPath = keyPath;
1147
+ this.refreshRefs();
1148
+ }
1149
+ }
1150
+ getReturnTypeJSONByRef(_ref) {
1151
+ return _ref?.type?.toJSON();
1152
+ }
1153
+ toJSON() {
1154
+ return {
1155
+ kind: "KeyPathExpression" /* KeyPathExpression */,
1156
+ keyPath: this._keyPath
1157
+ };
1158
+ }
1159
+ };
1160
+ KeyPathExpressionV2.kind = "KeyPathExpression" /* KeyPathExpression */;
1161
+
1162
+ // src/ast/expression/wrap-array-expression.ts
1163
+ var WrapArrayExpression = class extends BaseExpression {
1164
+ get wrapFor() {
1165
+ return this._wrapFor;
1166
+ }
1167
+ get returnType() {
1168
+ return this._returnType;
1169
+ }
1170
+ refreshReturnType() {
1171
+ const childReturnTypeJSON = this.wrapFor?.returnType?.toJSON();
1172
+ this.updateChildNodeByKey("_returnType", {
1173
+ kind: "Array" /* Array */,
1174
+ items: childReturnTypeJSON
1175
+ });
1176
+ }
1177
+ getRefFields() {
1178
+ return [];
1179
+ }
1180
+ fromJSON({ wrapFor: expression }) {
1181
+ this.updateChildNodeByKey("_wrapFor", expression);
1182
+ }
1183
+ toJSON() {
1184
+ return {
1185
+ kind: "WrapArrayExpression" /* WrapArrayExpression */,
1186
+ wrapFor: this.wrapFor?.toJSON()
1187
+ };
1188
+ }
1189
+ init() {
1190
+ this.refreshReturnType = this.refreshReturnType.bind(this);
1191
+ this.toDispose.push(
1192
+ this.subscribe(this.refreshReturnType, {
1193
+ selector: (curr) => curr.wrapFor?.returnType,
1194
+ triggerOnInit: true
1195
+ })
1196
+ );
1197
+ }
1198
+ };
1199
+ WrapArrayExpression.kind = "WrapArrayExpression" /* WrapArrayExpression */;
1200
+ __decorateClass([
1201
+ postConstructAST()
1202
+ ], WrapArrayExpression.prototype, "init", 1);
1203
+
1204
+ // src/ast/declaration/base-variable-field.ts
1205
+ var import_fast_equals5 = require("fast-equals");
1206
+ var BaseVariableField = class extends ASTNode {
1207
+ constructor() {
1208
+ super(...arguments);
1209
+ this.flags = 1 /* VariableField */;
1210
+ this._meta = {};
1211
+ }
1212
+ /**
1213
+ * 父变量字段,通过由近而远的方式进行排序
1214
+ */
1215
+ get parentFields() {
1216
+ return getParentFields(this);
1217
+ }
1218
+ get keyPath() {
1219
+ return [...this.parentFields.reverse().map((_field) => _field.key), this.key];
1220
+ }
1221
+ get meta() {
1222
+ return this._meta;
1223
+ }
1224
+ get type() {
1225
+ return this._initializer?.returnType || this._type;
1226
+ }
1227
+ get initializer() {
1228
+ return this._initializer;
1229
+ }
1230
+ get hash() {
1231
+ return `[${this._version}]${this.keyPath.join(".")}`;
1232
+ }
1233
+ /**
1234
+ * 解析 VariableDeclarationJSON 从而生成变量声明节点
1235
+ */
1236
+ fromJSON({ type, initializer, meta }) {
1237
+ this.updateType(type);
1238
+ this.updateInitializer(initializer);
1239
+ this.updateMeta(meta);
1240
+ }
1241
+ updateType(type) {
1242
+ const nextTypeJson = typeof type === "string" ? { kind: type } : type;
1243
+ this.updateChildNodeByKey("_type", nextTypeJson);
1244
+ }
1245
+ updateInitializer(nextInitializer) {
1246
+ this.updateChildNodeByKey("_initializer", nextInitializer);
1247
+ }
1248
+ updateMeta(nextMeta) {
1249
+ if (!(0, import_fast_equals5.shallowEqual)(nextMeta, this._meta)) {
1250
+ this._meta = nextMeta;
1251
+ this.fireChange();
1252
+ }
1253
+ }
1254
+ /**
1255
+ * 根据 keyPath 去找下钻的变量字段
1256
+ * @param keyPath
1257
+ * @returns
1258
+ */
1259
+ getByKeyPath(keyPath) {
1260
+ if (this.type?.flags & 16 /* DrilldownType */) {
1261
+ return this.type.getByKeyPath(keyPath);
1262
+ }
1263
+ return void 0;
1264
+ }
1265
+ /**
1266
+ * 监听类型变化
1267
+ * @param observer
1268
+ * @returns
1269
+ */
1270
+ onTypeChange(observer) {
1271
+ return this.subscribe(observer, { selector: (curr) => curr.type });
1272
+ }
1273
+ /**
1274
+ * 转换为 JSON
1275
+ * @returns
1276
+ */
1277
+ toJSON() {
1278
+ return {
1279
+ kind: this.kind,
1280
+ key: this.key,
1281
+ type: this.type?.toJSON(),
1282
+ initializer: this.initializer?.toJSON(),
1283
+ meta: this._meta
1284
+ };
1285
+ }
1286
+ };
1287
+
1288
+ // src/ast/declaration/variable-declaration.ts
1289
+ var VariableDeclaration = class extends BaseVariableField {
1290
+ constructor(params) {
1291
+ super(params);
1292
+ this._order = 0;
1293
+ }
1294
+ get order() {
1295
+ return this._order;
1296
+ }
1297
+ /**
1298
+ * 解析 VariableDeclarationJSON 从而生成变量声明节点
1299
+ */
1300
+ fromJSON({ order, ...rest }) {
1301
+ this.updateOrder(order);
1302
+ super.fromJSON(rest);
1303
+ }
1304
+ updateOrder(order = 0) {
1305
+ if (order !== this._order) {
1306
+ this._order = order;
1307
+ this.dispatchGlobalEvent({
1308
+ type: "ReSortVariableDeclarations"
1309
+ });
1310
+ this.fireChange();
1311
+ }
1312
+ }
1313
+ // 监听类型变化
1314
+ onTypeChange(observer) {
1315
+ return this.subscribe(observer, { selector: (curr) => curr.type });
1316
+ }
1317
+ };
1318
+ VariableDeclaration.kind = "VariableDeclaration" /* VariableDeclaration */;
1319
+
1320
+ // src/ast/declaration/variable-declaration-list.ts
1321
+ var VariableDeclarationList = class extends ASTNode {
1322
+ constructor() {
1323
+ super(...arguments);
1324
+ this.declarationTable = /* @__PURE__ */ new Map();
1325
+ }
1326
+ fromJSON({ declarations, startOrder }) {
1327
+ const removedKeys = new Set(this.declarationTable.keys());
1328
+ const prev = [...this.declarations || []];
1329
+ this.declarations = (declarations || []).map(
1330
+ (declaration, idx) => {
1331
+ const order = (startOrder || 0) + idx;
1332
+ const declarationKey = declaration.key || this.declarations?.[idx]?.key;
1333
+ const existDeclaration = this.declarationTable.get(declarationKey);
1334
+ if (declarationKey) {
1335
+ removedKeys.delete(declarationKey);
1336
+ }
1337
+ if (existDeclaration) {
1338
+ existDeclaration.fromJSON({ order, ...declaration });
1339
+ return existDeclaration;
1340
+ } else {
1341
+ const newDeclaration = this.createChildNode({
1342
+ order,
1343
+ ...declaration,
1344
+ kind: "VariableDeclaration" /* VariableDeclaration */
1345
+ });
1346
+ this.fireChange();
1347
+ this.declarationTable.set(newDeclaration.key, newDeclaration);
1348
+ return newDeclaration;
1349
+ }
1350
+ }
1351
+ );
1352
+ removedKeys.forEach((key) => {
1353
+ const declaration = this.declarationTable.get(key);
1354
+ declaration?.dispose();
1355
+ this.declarationTable.delete(key);
1356
+ });
1357
+ this.dispatchGlobalEvent({
1358
+ type: "VariableListChange",
1359
+ payload: {
1360
+ prev,
1361
+ next: [...this.declarations]
1362
+ }
1363
+ });
1364
+ }
1365
+ toJSON() {
1366
+ return {
1367
+ kind: "VariableDeclarationList" /* VariableDeclarationList */,
1368
+ properties: this.declarations.map((_declaration) => _declaration.toJSON())
1369
+ };
1370
+ }
1371
+ };
1372
+ VariableDeclarationList.kind = "VariableDeclarationList" /* VariableDeclarationList */;
1373
+
1374
+ // src/ast/declaration/property.ts
1375
+ var Property = class extends BaseVariableField {
1376
+ };
1377
+ Property.kind = "Property" /* Property */;
1378
+
1379
+ // src/ast/common/data-node.ts
1380
+ var import_fast_equals6 = require("fast-equals");
1381
+ var DataNode = class extends ASTNode {
1382
+ get data() {
1383
+ return this._data;
1384
+ }
1385
+ fromJSON(json) {
1386
+ const { kind, ...restData } = json;
1387
+ if (!(0, import_fast_equals6.shallowEqual)(restData, this._data)) {
1388
+ this._data = restData;
1389
+ this.fireChange();
1390
+ }
1391
+ }
1392
+ toJSON() {
1393
+ return {
1394
+ kind: "DataNode" /* DataNode */,
1395
+ ...this._data
1396
+ };
1397
+ }
1398
+ partialUpdate(nextData) {
1399
+ if (!(0, import_fast_equals6.shallowEqual)(nextData, this._data)) {
1400
+ this._data = {
1401
+ ...this._data,
1402
+ ...nextData
1403
+ };
1404
+ this.fireChange();
1405
+ }
1406
+ }
1407
+ };
1408
+ DataNode.kind = "DataNode" /* DataNode */;
1409
+
1410
+ // src/ast/common/list-node.ts
1411
+ var ListNode = class extends ASTNode {
1412
+ get list() {
1413
+ return this._list;
1414
+ }
1415
+ fromJSON({ list }) {
1416
+ this._list.slice(list.length).forEach((_item) => {
1417
+ _item.dispose();
1418
+ this.fireChange();
1419
+ });
1420
+ this._list = list.map((_item, idx) => {
1421
+ const prevItem = this._list[idx];
1422
+ if (prevItem.kind !== _item.kind) {
1423
+ prevItem.dispose();
1424
+ this.fireChange();
1425
+ return this.createChildNode(_item);
1426
+ }
1427
+ prevItem.fromJSON(_item);
1428
+ return prevItem;
1429
+ });
1430
+ }
1431
+ toJSON() {
1432
+ return {
1433
+ kind: "ListNode" /* ListNode */,
1434
+ list: this._list.map((item) => item.toJSON())
1435
+ };
1436
+ }
1437
+ };
1438
+ ListNode.kind = "ListNode" /* ListNode */;
1439
+
1440
+ // src/ast/common/map-node.ts
1441
+ var MapNode = class extends ASTNode {
1442
+ constructor() {
1443
+ super(...arguments);
1444
+ this.map = /* @__PURE__ */ new Map();
1445
+ }
1446
+ fromJSON({ map: map4 }) {
1447
+ const removedKeys = new Set(this.map.keys());
1448
+ for (const [key, item] of map4 || []) {
1449
+ removedKeys.delete(key);
1450
+ this.set(key, item);
1451
+ }
1452
+ for (const removeKey of Array.from(removedKeys)) {
1453
+ this.remove(removeKey);
1454
+ }
1455
+ }
1456
+ toJSON() {
1457
+ return {
1458
+ kind: "MapNode" /* MapNode */,
1459
+ map: Array.from(this.map.entries())
1460
+ };
1461
+ }
1462
+ /**
1463
+ * 往 Map 中设置 ASTNode
1464
+ * @param key ASTNode 的索引,
1465
+ * @param json
1466
+ */
1467
+ set(key, nextJSON) {
1468
+ return this.withBatchUpdate(updateChildNodeHelper).call(this, {
1469
+ getChildNode: () => this.get(key),
1470
+ removeChildNode: () => this.map.delete(key),
1471
+ updateChildNode: (nextNode) => this.map.set(key, nextNode),
1472
+ nextJSON
1473
+ });
1474
+ }
1475
+ /**
1476
+ * 移除指定 ASTNode
1477
+ * @param key
1478
+ */
1479
+ remove(key) {
1480
+ this.get(key)?.dispose();
1481
+ this.map.delete(key);
1482
+ this.fireChange();
1483
+ }
1484
+ /**
1485
+ * 获取 ASTNode
1486
+ * @param key
1487
+ * @returns
1488
+ */
1489
+ get(key) {
1490
+ return this.map.get(key);
1491
+ }
1492
+ };
1493
+ MapNode.kind = "MapNode" /* MapNode */;
1494
+
1495
+ // src/ast/ast-registers.ts
1496
+ var ASTRegisters = class {
1497
+ /**
1498
+ * 核心 AST 节点注册
1499
+ */
1500
+ constructor() {
1501
+ this.injectors = /* @__PURE__ */ new Map();
1502
+ this.astMap = /* @__PURE__ */ new Map();
1503
+ this.registerAST(StringType);
1504
+ this.registerAST(NumberType);
1505
+ this.registerAST(BooleanType);
1506
+ this.registerAST(IntegerType);
1507
+ this.registerAST(ObjectType);
1508
+ this.registerAST(ArrayType);
1509
+ this.registerAST(MapType);
1510
+ this.registerAST(CustomType);
1511
+ this.registerAST(Property);
1512
+ this.registerAST(VariableDeclaration);
1513
+ this.registerAST(VariableDeclarationList);
1514
+ this.registerAST(KeyPathExpressionV2);
1515
+ this.registerAST(EnumerateExpression);
1516
+ this.registerAST(WrapArrayExpression);
1517
+ this.registerAST(MapNode);
1518
+ this.registerAST(DataNode);
1519
+ }
1520
+ /**
1521
+ * 创建 AST 节点
1522
+ * @param param 创建参数
1523
+ * @returns
1524
+ */
1525
+ createAST(json, { parent, scope }) {
1526
+ const Registry = this.astMap.get(json.kind);
1527
+ if (!Registry) {
1528
+ throw Error(`ASTKind: ${String(json.kind)} can not find its ASTNode Registry`);
1529
+ }
1530
+ const injector = this.injectors.get(json.kind);
1531
+ const node = new Registry(
1532
+ {
1533
+ key: json.key,
1534
+ scope,
1535
+ parent
1536
+ },
1537
+ injector?.() || {}
1538
+ );
1539
+ node.changeLocked = true;
1540
+ node.fromJSON((0, import_lodash3.omit)(json, ["key", "kind"]));
1541
+ node.changeLocked = false;
1542
+ if (Reflect.hasMetadata(POST_CONSTRUCT_AST_SYMBOL, node)) {
1543
+ const postConstructKey = Reflect.getMetadata(POST_CONSTRUCT_AST_SYMBOL, node);
1544
+ node[postConstructKey]?.();
1545
+ }
1546
+ return node;
1547
+ }
1548
+ /**
1549
+ * 根据 AST 节点类型获取节点 Registry
1550
+ * @param kind
1551
+ * @returns
1552
+ */
1553
+ getASTRegistryByKind(kind) {
1554
+ return this.astMap.get(kind);
1555
+ }
1556
+ /**
1557
+ * 注册 AST 节点
1558
+ * @param ASTNode
1559
+ * @param injector
1560
+ */
1561
+ registerAST(ASTNode2, injector) {
1562
+ this.astMap.set(ASTNode2.kind, ASTNode2);
1563
+ if (injector) {
1564
+ this.injectors.set(ASTNode2.kind, injector);
1565
+ }
1566
+ }
1567
+ };
1568
+ ASTRegisters = __decorateClass([
1569
+ (0, import_inversify3.injectable)()
1570
+ ], ASTRegisters);
1571
+
1572
+ // src/ast/factory.ts
1573
+ var ASTFactory;
1574
+ ((ASTFactory2) => {
1575
+ ASTFactory2.createString = () => ({ kind: "String" /* String */ });
1576
+ ASTFactory2.createNumber = () => ({ kind: "Number" /* Number */ });
1577
+ ASTFactory2.createBoolean = () => ({ kind: "Boolean" /* Boolean */ });
1578
+ ASTFactory2.createInteger = () => ({ kind: "Integer" /* Integer */ });
1579
+ ASTFactory2.createObject = (json) => ({
1580
+ kind: "Object" /* Object */,
1581
+ ...json
1582
+ });
1583
+ ASTFactory2.createArray = (json) => ({
1584
+ kind: "Array" /* Array */,
1585
+ ...json
1586
+ });
1587
+ ASTFactory2.createMap = (json) => ({
1588
+ kind: "Map" /* Map */,
1589
+ ...json
1590
+ });
1591
+ ASTFactory2.createUnion = (json) => ({
1592
+ kind: "Union" /* Union */,
1593
+ ...json
1594
+ });
1595
+ ASTFactory2.createCustomType = (json) => ({
1596
+ kind: "CustomType" /* CustomType */,
1597
+ ...json
1598
+ });
1599
+ ASTFactory2.createVariableDeclaration = (json) => ({
1600
+ kind: "VariableDeclaration" /* VariableDeclaration */,
1601
+ ...json
1602
+ });
1603
+ ASTFactory2.createProperty = (json) => ({
1604
+ kind: "Property" /* Property */,
1605
+ ...json
1606
+ });
1607
+ ASTFactory2.createVariableDeclarationList = (json) => ({
1608
+ kind: "VariableDeclarationList" /* VariableDeclarationList */,
1609
+ ...json
1610
+ });
1611
+ ASTFactory2.createEnumerateExpression = (json) => ({
1612
+ kind: "EnumerateExpression" /* EnumerateExpression */,
1613
+ ...json
1614
+ });
1615
+ ASTFactory2.createKeyPathExpression = (json) => ({
1616
+ kind: "KeyPathExpression" /* KeyPathExpression */,
1617
+ ...json
1618
+ });
1619
+ ASTFactory2.createWrapArrayExpression = (json) => ({
1620
+ kind: "WrapArrayExpression" /* WrapArrayExpression */,
1621
+ ...json
1622
+ });
1623
+ ASTFactory2.create = (targetType, json) => ({ kind: targetType.kind, ...json });
1624
+ })(ASTFactory || (ASTFactory = {}));
1625
+
1626
+ // src/scope/datas/scope-output-data.ts
1627
+ var ScopeOutputData = class {
1628
+ constructor(scope) {
1629
+ this.scope = scope;
1630
+ this.memo = createMemo();
1631
+ this._hasChanges = false;
1632
+ this.variableTable = new VariableTable(scope.variableEngine.globalVariableTable);
1633
+ this.scope.toDispose.pushAll([
1634
+ // When root AST node is updated, check if there are any changes during this AST change
1635
+ this.scope.ast.subscribe(() => {
1636
+ if (this._hasChanges) {
1637
+ this.memo.clear();
1638
+ this.notifyCoversChange();
1639
+ this.variableTable.fireChange();
1640
+ this._hasChanges = false;
1641
+ }
1642
+ }),
1643
+ this.scope.event.on("DisposeAST", (_action) => {
1644
+ if (_action.ast?.kind === "VariableDeclaration" /* VariableDeclaration */) {
1645
+ this.removeVariableFromTable(_action.ast.key);
1646
+ }
1647
+ }),
1648
+ this.scope.event.on("NewAST", (_action) => {
1649
+ if (_action.ast?.kind === "VariableDeclaration" /* VariableDeclaration */) {
1650
+ this.addVariableToTable(_action.ast);
1651
+ }
1652
+ }),
1653
+ this.scope.event.on("ReSortVariableDeclarations", () => {
1654
+ this._hasChanges = true;
1655
+ }),
1656
+ this.variableTable
1657
+ ]);
1658
+ }
1659
+ get variableEngine() {
1660
+ return this.scope.variableEngine;
1661
+ }
1662
+ get globalVariableTable() {
1663
+ return this.scope.variableEngine.globalVariableTable;
1664
+ }
1665
+ /**
1666
+ * @deprecated use onListOrAnyVarChange instead
1667
+ */
1668
+ get onDataChange() {
1669
+ return this.variableTable.onDataChange.bind(this.variableTable);
1670
+ }
1671
+ /**
1672
+ * listen to variable list change
1673
+ */
1674
+ get onVariableListChange() {
1675
+ return this.variableTable.onVariableListChange.bind(this.variableTable);
1676
+ }
1677
+ /**
1678
+ * listen to any variable update in list
1679
+ */
1680
+ get onAnyVariableChange() {
1681
+ return this.variableTable.onAnyVariableChange.bind(this.variableTable);
1682
+ }
1683
+ /**
1684
+ * listen to variable list change + any variable update in list
1685
+ */
1686
+ get onListOrAnyVarChange() {
1687
+ return this.variableTable.onListOrAnyVarChange.bind(this.variableTable);
1688
+ }
1689
+ /**
1690
+ * Scope Output Variable Declarations
1691
+ */
1692
+ get variables() {
1693
+ return this.memo(
1694
+ "variables",
1695
+ () => this.variableTable.variables.sort((a, b) => a.order - b.order)
1696
+ );
1697
+ }
1698
+ /**
1699
+ * Output Variable Keys
1700
+ */
1701
+ get variableKeys() {
1702
+ return this.memo("variableKeys", () => this.variableTable.variableKeys);
1703
+ }
1704
+ addVariableToTable(variable) {
1705
+ if (variable.scope !== this.scope) {
1706
+ throw Error("VariableDeclaration must be a ast node in scope");
1707
+ }
1708
+ this.variableTable.addVariableToTable(variable);
1709
+ this._hasChanges = true;
1710
+ }
1711
+ removeVariableFromTable(key) {
1712
+ this.variableTable.removeVariableFromTable(key);
1713
+ this._hasChanges = true;
1714
+ }
1715
+ getVariableByKey(key) {
1716
+ return this.variableTable.getVariableByKey(key);
1717
+ }
1718
+ /**
1719
+ *
1720
+ */
1721
+ notifyCoversChange() {
1722
+ this.scope.coverScopes.forEach((scope) => scope.available.refresh());
1723
+ }
1724
+ };
1725
+
1726
+ // src/scope/datas/scope-available-data.ts
1727
+ var import_rxjs4 = require("rxjs");
1728
+ var import_lodash4 = require("lodash");
1729
+ var import_fast_equals7 = require("fast-equals");
1730
+ var import_utils5 = require("@flowgram.ai/utils");
1731
+ var import_utils6 = require("@flowgram.ai/utils");
1732
+ var ScopeAvailableData = class {
1733
+ constructor(scope) {
1734
+ this.scope = scope;
1735
+ this.memo = createMemo();
1736
+ this.refresh$ = new import_rxjs4.Subject();
1737
+ this._variables = [];
1738
+ /**
1739
+ * 监听
1740
+ */
1741
+ this.variables$ = this.refresh$.pipe(
1742
+ // 输出变量是否 version 发生变化
1743
+ (0, import_rxjs4.map)(() => (0, import_lodash4.flatten)(this.depScopes.map((scope) => scope.output.variables || []))),
1744
+ // 变量列表浅比较
1745
+ (0, import_rxjs4.distinctUntilChanged)(import_fast_equals7.shallowEqual),
1746
+ (0, import_rxjs4.share)()
1747
+ );
1748
+ // 监听变量列表中的单个变量变化
1749
+ this.anyVariableChange$ = this.variables$.pipe(
1750
+ (0, import_rxjs4.switchMap)(
1751
+ (_variables) => (0, import_rxjs4.merge)(
1752
+ ..._variables.map(
1753
+ (_v) => _v.value$.pipe(
1754
+ // 跳过 BehaviorSubject 第一个
1755
+ (0, import_rxjs4.skip)(1)
1756
+ )
1757
+ )
1758
+ )
1759
+ ),
1760
+ (0, import_rxjs4.share)()
1761
+ );
1762
+ /**
1763
+ * @deprecated
1764
+ */
1765
+ this.onDataChangeEmitter = new import_utils6.Emitter();
1766
+ this.onListOrAnyVarChangeEmitter = new import_utils6.Emitter();
1767
+ /**
1768
+ * @deprecated use available.onListOrAnyVarChange instead
1769
+ */
1770
+ this.onDataChange = this.onDataChangeEmitter.event;
1771
+ /**
1772
+ * listen to variable list change + any variable drilldown change
1773
+ */
1774
+ this.onListOrAnyVarChange = this.onListOrAnyVarChangeEmitter.event;
1775
+ this.scope.toDispose.pushAll([
1776
+ this.onVariableListChange((_variables) => {
1777
+ this._variables = _variables;
1778
+ this.memo.clear();
1779
+ this.onDataChangeEmitter.fire(this._variables);
1780
+ this.onListOrAnyVarChangeEmitter.fire(this._variables);
1781
+ }),
1782
+ this.onAnyVariableChange(() => {
1783
+ this.onDataChangeEmitter.fire(this._variables);
1784
+ this.onListOrAnyVarChangeEmitter.fire(this._variables);
1785
+ }),
1786
+ import_utils5.Disposable.create(() => {
1787
+ this.refresh$.complete();
1788
+ this.refresh$.unsubscribe();
1789
+ })
1790
+ ]);
1791
+ }
1792
+ get globalVariableTable() {
1793
+ return this.scope.variableEngine.globalVariableTable;
1794
+ }
1795
+ // 刷新可访问变量列表
1796
+ refresh() {
1797
+ if (this.scope.disposed) {
1798
+ return;
1799
+ }
1800
+ this.refresh$.next();
1801
+ }
1802
+ /**
1803
+ * listen to any variable update in list
1804
+ * @param observer
1805
+ * @returns
1806
+ */
1807
+ onAnyVariableChange(observer) {
1808
+ return subsToDisposable(this.anyVariableChange$.subscribe(observer));
1809
+ }
1810
+ /**
1811
+ * listen to variable list change
1812
+ * @param observer
1813
+ * @returns
1814
+ */
1815
+ onVariableListChange(observer) {
1816
+ return subsToDisposable(this.variables$.subscribe(observer));
1817
+ }
1818
+ /**
1819
+ * 获取可消费变量
1820
+ */
1821
+ get variables() {
1822
+ return this._variables;
1823
+ }
1824
+ /**
1825
+ * 获取可访问的变量 keys
1826
+ */
1827
+ get variableKeys() {
1828
+ return this.memo("availableKeys", () => this._variables.map((_v) => _v.key));
1829
+ }
1830
+ /**
1831
+ * 返回依赖的作用域
1832
+ */
1833
+ get depScopes() {
1834
+ return this.scope.depScopes;
1835
+ }
1836
+ /**
1837
+ * 通过 keyPath 找到可用变量
1838
+ * @param keyPath
1839
+ * @returns
1840
+ */
1841
+ getByKeyPath(keyPath = []) {
1842
+ if (!this.variableKeys.includes(keyPath[0])) {
1843
+ return;
1844
+ }
1845
+ return this.globalVariableTable.getByKeyPath(keyPath);
1846
+ }
1847
+ /**
1848
+ * Track Variable Change (Includes type update and children update) By KeyPath
1849
+ * @returns
1850
+ */
1851
+ trackByKeyPath(keyPath = [], cb, opts) {
1852
+ const { triggerOnInit = true } = opts || {};
1853
+ return subsToDisposable(
1854
+ (0, import_rxjs4.merge)(this.anyVariableChange$, this.variables$).pipe(
1855
+ triggerOnInit ? (0, import_rxjs4.startWith)() : (0, import_rxjs4.tap)(() => null),
1856
+ (0, import_rxjs4.map)(() => {
1857
+ const v = this.getByKeyPath(keyPath);
1858
+ return { v, hash: v?.hash };
1859
+ }),
1860
+ (0, import_rxjs4.distinctUntilKeyChanged)("hash"),
1861
+ (0, import_rxjs4.map)(({ v }) => v)
1862
+ ).subscribe(cb)
1863
+ );
1864
+ }
1865
+ };
1866
+
1867
+ // src/scope/datas/scope-event-data.ts
1868
+ var import_rxjs5 = require("rxjs");
1869
+ var ScopeEventData = class {
1870
+ constructor(scope) {
1871
+ this.scope = scope;
1872
+ this.event$ = new import_rxjs5.Subject();
1873
+ scope.toDispose.pushAll([
1874
+ this.subscribe((_action) => {
1875
+ scope.variableEngine.fireGlobalEvent(_action);
1876
+ })
1877
+ ]);
1878
+ }
1879
+ dispatch(action) {
1880
+ if (this.scope.disposed) {
1881
+ return;
1882
+ }
1883
+ this.event$.next(action);
1884
+ }
1885
+ subscribe(observer) {
1886
+ return subsToDisposable(this.event$.subscribe(observer));
1887
+ }
1888
+ on(type, observer) {
1889
+ return subsToDisposable(
1890
+ this.event$.pipe((0, import_rxjs5.filter)((_action) => _action.type === type)).subscribe(observer)
1891
+ );
1892
+ }
1893
+ };
1894
+
1895
+ // src/scope/scope.ts
1896
+ var Scope = class {
1897
+ constructor(options) {
1898
+ /**
1899
+ * 数据缓存
1900
+ */
1901
+ this.memo = createMemo();
1902
+ this.toDispose = new import_utils7.DisposableCollection();
1903
+ this.onDispose = this.toDispose.onDispose;
1904
+ this.id = options.id;
1905
+ this.meta = options.meta || {};
1906
+ this.variableEngine = options.variableEngine;
1907
+ this.event = new ScopeEventData(this);
1908
+ this.ast = this.variableEngine.astRegisters.createAST(
1909
+ {
1910
+ kind: "MapNode" /* MapNode */,
1911
+ key: String(this.id)
1912
+ },
1913
+ {
1914
+ scope: this
1915
+ }
1916
+ );
1917
+ this.output = new ScopeOutputData(this);
1918
+ this.available = new ScopeAvailableData(this);
1919
+ }
1920
+ refreshCovers() {
1921
+ this.memo.clear("covers");
1922
+ }
1923
+ refreshDeps() {
1924
+ this.memo.clear("deps");
1925
+ this.available.refresh();
1926
+ }
1927
+ get depScopes() {
1928
+ return this.memo(
1929
+ "deps",
1930
+ () => this.variableEngine.chain.getDeps(this).filter((_scope) => Boolean(_scope) && !_scope?.disposed)
1931
+ );
1932
+ }
1933
+ get coverScopes() {
1934
+ return this.memo(
1935
+ "covers",
1936
+ () => this.variableEngine.chain.getCovers(this).filter((_scope) => Boolean(_scope) && !_scope?.disposed)
1937
+ );
1938
+ }
1939
+ dispose() {
1940
+ this.ast.dispose();
1941
+ this.toDispose.dispose();
1942
+ this.coverScopes.forEach((_scope) => _scope.refreshDeps());
1943
+ this.depScopes.forEach((_scope) => _scope.refreshCovers());
1944
+ }
1945
+ get disposed() {
1946
+ return this.toDispose.disposed;
1947
+ }
1948
+ setVar(arg1, arg2) {
1949
+ if (typeof arg1 === "string" && arg2 !== void 0) {
1950
+ return this.ast.set(arg1, arg2);
1951
+ }
1952
+ if (typeof arg1 === "object" && arg2 === void 0) {
1953
+ return this.ast.set("outputs", arg1);
1954
+ }
1955
+ throw new Error("Invalid arguments");
1956
+ }
1957
+ /**
1958
+ * Retrieves a variable from the Scope by key.
1959
+ *
1960
+ * @param key - The key of the variable to retrieve. Defaults to 'outputs'.
1961
+ * @returns The value of the variable, or undefined if not found.
1962
+ */
1963
+ getVar(key = "outputs") {
1964
+ return this.ast.get(key);
1965
+ }
1966
+ /**
1967
+ * Clears a variable from the Scope by key.
1968
+ *
1969
+ * @param key - The key of the variable to clear. Defaults to 'outputs'.
1970
+ * @returns The updated AST node.
1971
+ */
1972
+ clearVar(key = "outputs") {
1973
+ return this.ast.remove(key);
1974
+ }
1975
+ };
1976
+
1977
+ // src/variable-engine.ts
1978
+ var VariableEngine = class {
1979
+ constructor(chain, astRegisters) {
1980
+ this.chain = chain;
1981
+ this.astRegisters = astRegisters;
1982
+ this.toDispose = new import_utils8.DisposableCollection();
1983
+ this.memo = createMemo();
1984
+ this.scopeMap = /* @__PURE__ */ new Map();
1985
+ this.globalEvent$ = new import_rxjs6.Subject();
1986
+ this.onScopeChangeEmitter = new import_utils9.Emitter();
1987
+ this.globalVariableTable = new VariableTable();
1988
+ this.onScopeChange = this.onScopeChangeEmitter.event;
1989
+ this.toDispose.pushAll([
1990
+ chain,
1991
+ import_utils8.Disposable.create(() => {
1992
+ this.getAllScopes().forEach((scope) => scope.dispose());
1993
+ this.globalVariableTable.dispose();
1994
+ })
1995
+ ]);
1996
+ }
1997
+ get container() {
1998
+ return this.containerProvider();
1999
+ }
2000
+ dispose() {
2001
+ this.toDispose.dispose();
2002
+ }
2003
+ // 根据 scopeId 找到作用域
2004
+ getScopeById(scopeId) {
2005
+ return this.scopeMap.get(scopeId);
2006
+ }
2007
+ // 移除作用域
2008
+ removeScopeById(scopeId) {
2009
+ this.getScopeById(scopeId)?.dispose();
2010
+ }
2011
+ /**
2012
+ * Get Scope, if Scope exists and type is same, will use it directly
2013
+ * @param id scope id
2014
+ * @param meta scope meta, defined by user
2015
+ * @param ScopeConstructor scope constructor, default is Scope. you can extends Scope to create your own scope
2016
+ * @returns
2017
+ */
2018
+ createScope(id, meta, options = {}) {
2019
+ const { ScopeConstructor = Scope } = options;
2020
+ let scope = this.getScopeById(id);
2021
+ if (!scope) {
2022
+ scope = new ScopeConstructor({ variableEngine: this, meta, id });
2023
+ this.scopeMap.set(id, scope);
2024
+ this.onScopeChangeEmitter.fire({ type: "add", scope });
2025
+ scope.toDispose.pushAll([
2026
+ scope.ast.subscribe(() => {
2027
+ this.onScopeChangeEmitter.fire({ type: "update", scope });
2028
+ }),
2029
+ // 可用变量发生变化
2030
+ scope.available.onDataChange(() => {
2031
+ this.onScopeChangeEmitter.fire({ type: "available", scope });
2032
+ })
2033
+ ]);
2034
+ scope.onDispose(() => {
2035
+ this.scopeMap.delete(id);
2036
+ this.onScopeChangeEmitter.fire({ type: "delete", scope });
2037
+ });
2038
+ }
2039
+ return scope;
2040
+ }
2041
+ // 获取系统中所有的作用域
2042
+ getAllScopes({
2043
+ sort
2044
+ } = {}) {
2045
+ const allScopes = Array.from(this.scopeMap.values());
2046
+ if (sort) {
2047
+ const sortScopes = this.chain.sortAll();
2048
+ const remainScopes = new Set(allScopes);
2049
+ sortScopes.forEach((_scope) => remainScopes.delete(_scope));
2050
+ return [...sortScopes, ...Array.from(remainScopes)];
2051
+ }
2052
+ return [...allScopes];
2053
+ }
2054
+ fireGlobalEvent(event) {
2055
+ this.globalEvent$.next(event);
2056
+ }
2057
+ onGlobalEvent(type, observer) {
2058
+ return subsToDisposable(
2059
+ this.globalEvent$.subscribe((_action) => {
2060
+ if (_action.type === type) {
2061
+ observer(_action);
2062
+ }
2063
+ })
2064
+ );
2065
+ }
2066
+ };
2067
+ __decorateClass([
2068
+ (0, import_inversify6.inject)(ContainerProvider)
2069
+ ], VariableEngine.prototype, "containerProvider", 2);
2070
+ __decorateClass([
2071
+ (0, import_inversify6.preDestroy)()
2072
+ ], VariableEngine.prototype, "dispose", 1);
2073
+ VariableEngine = __decorateClass([
2074
+ (0, import_inversify6.injectable)(),
2075
+ __decorateParam(0, (0, import_inversify6.inject)(ScopeChain)),
2076
+ __decorateParam(1, (0, import_inversify6.inject)(ASTRegisters))
2077
+ ], VariableEngine);
2078
+
2079
+ // src/services/variable-field-key-rename-service.ts
2080
+ var import_lodash5 = require("lodash");
2081
+ var import_inversify7 = require("inversify");
2082
+ var import_utils10 = require("@flowgram.ai/utils");
2083
+ var VariableFieldKeyRenameService = class {
2084
+ constructor() {
2085
+ this.toDispose = new import_utils10.DisposableCollection();
2086
+ this.renameEmitter = new import_utils10.Emitter();
2087
+ // 没有被 rename 的字段通过 disposeInList 透出,让业务区分变量是 rename 删除的,还是真正从列表中删除的
2088
+ this.disposeInListEmitter = new import_utils10.Emitter();
2089
+ this.onRename = this.renameEmitter.event;
2090
+ this.onDisposeInList = this.disposeInListEmitter.event;
2091
+ }
2092
+ handleFieldListChange(ast, prev, next) {
2093
+ if (!ast || !prev?.length || !next?.length) {
2094
+ this.notifyFieldsDispose(prev, next);
2095
+ return;
2096
+ }
2097
+ if (prev.length !== next.length) {
2098
+ this.notifyFieldsDispose(prev, next);
2099
+ return;
2100
+ }
2101
+ let renameNodeInfo = null;
2102
+ let existFieldChanged = false;
2103
+ for (const [index, prevField] of prev.entries()) {
2104
+ const nextField = next[index];
2105
+ if (prevField.key !== nextField.key) {
2106
+ if (existFieldChanged) {
2107
+ this.notifyFieldsDispose(prev, next);
2108
+ return;
2109
+ }
2110
+ existFieldChanged = true;
2111
+ if (prevField.type?.kind === nextField.type?.kind) {
2112
+ renameNodeInfo = { before: prevField, after: nextField };
2113
+ }
2114
+ }
2115
+ }
2116
+ if (!renameNodeInfo) {
2117
+ this.notifyFieldsDispose(prev, next);
2118
+ return;
2119
+ }
2120
+ this.renameEmitter.fire(renameNodeInfo);
2121
+ }
2122
+ notifyFieldsDispose(prev, next) {
2123
+ const removedFields = (0, import_lodash5.difference)(prev || [], next || []);
2124
+ removedFields.forEach((_field) => this.disposeInListEmitter.fire(_field));
2125
+ }
2126
+ init() {
2127
+ this.toDispose.pushAll([
2128
+ this.variableEngine.onGlobalEvent(
2129
+ "VariableListChange",
2130
+ (_action) => {
2131
+ this.handleFieldListChange(_action.ast, _action.payload?.prev, _action.payload?.next);
2132
+ }
2133
+ ),
2134
+ this.variableEngine.onGlobalEvent(
2135
+ "ObjectPropertiesChange",
2136
+ (_action) => {
2137
+ this.handleFieldListChange(_action.ast, _action.payload?.prev, _action.payload?.next);
2138
+ }
2139
+ )
2140
+ ]);
2141
+ }
2142
+ dispose() {
2143
+ this.toDispose.dispose();
2144
+ }
2145
+ };
2146
+ __decorateClass([
2147
+ (0, import_inversify7.inject)(VariableEngine)
2148
+ ], VariableFieldKeyRenameService.prototype, "variableEngine", 2);
2149
+ __decorateClass([
2150
+ (0, import_inversify7.postConstruct)()
2151
+ ], VariableFieldKeyRenameService.prototype, "init", 1);
2152
+ __decorateClass([
2153
+ (0, import_inversify7.preDestroy)()
2154
+ ], VariableFieldKeyRenameService.prototype, "dispose", 1);
2155
+ VariableFieldKeyRenameService = __decorateClass([
2156
+ (0, import_inversify7.injectable)()
2157
+ ], VariableFieldKeyRenameService);
2158
+
2159
+ // src/variable-container-module.ts
2160
+ var VariableContainerModule = new import_inversify8.ContainerModule((bind) => {
2161
+ bind(VariableEngine).toSelf().inSingletonScope();
2162
+ bind(ASTRegisters).toSelf().inSingletonScope();
2163
+ bind(VariableFieldKeyRenameService).toSelf().inSingletonScope();
2164
+ bind(VariableEngineProvider).toDynamicValue((ctx) => () => ctx.container.get(VariableEngine));
2165
+ bind(ContainerProvider).toDynamicValue((ctx) => () => ctx.container);
2166
+ });
2167
+
2168
+ // src/react/context.tsx
2169
+ var import_react = require("react");
2170
+ var ScopeContext = (0, import_react.createContext)(null);
2171
+ var ScopeProvider = ScopeContext.Provider;
2172
+ var useScopeContext = () => (0, import_react.useContext)(ScopeContext);
2173
+ var useCurrentScope = () => (0, import_react.useContext)(ScopeContext)?.scope;
2174
+
2175
+ // src/react/hooks/useScopeAvailable.ts
2176
+ var import_react2 = require("react");
2177
+ var import_core = require("@flowgram.ai/core");
2178
+ function useScopeAvailable() {
2179
+ const scope = useCurrentScope();
2180
+ const refresh = (0, import_core.useRefresh)();
2181
+ (0, import_react2.useEffect)(() => {
2182
+ const disposable = scope.available.onDataChange(() => {
2183
+ refresh();
2184
+ });
2185
+ return () => disposable.dispose();
2186
+ }, []);
2187
+ return scope.available;
2188
+ }
2189
+
2190
+ // src/react/hooks/useAvailableVariables.ts
2191
+ var import_react3 = require("react");
2192
+ var import_core2 = require("@flowgram.ai/core");
2193
+ function useAvailableVariables() {
2194
+ const scope = useCurrentScope();
2195
+ const variableEngine = (0, import_core2.useService)(VariableEngine);
2196
+ const refresh = (0, import_core2.useRefresh)();
2197
+ (0, import_react3.useEffect)(() => {
2198
+ if (!scope) {
2199
+ const disposable2 = variableEngine.globalVariableTable.onListOrAnyVarChange(() => {
2200
+ refresh();
2201
+ });
2202
+ return () => disposable2.dispose();
2203
+ }
2204
+ const disposable = scope.available.onDataChange(() => {
2205
+ refresh();
2206
+ });
2207
+ return () => disposable.dispose();
2208
+ }, []);
2209
+ return scope ? scope.available.variables : variableEngine.globalVariableTable.variables;
2210
+ }
2211
+ // Annotate the CommonJS export names for ESM import in node:
2212
+ 0 && (module.exports = {
2213
+ ASTFactory,
2214
+ ASTKind,
2215
+ ASTMatch,
2216
+ ASTNode,
2217
+ ASTNodeFlags,
2218
+ ASTRegisters,
2219
+ ArrayType,
2220
+ BaseExpression,
2221
+ BaseType,
2222
+ BaseVariableField,
2223
+ BooleanType,
2224
+ CustomType,
2225
+ DataNode,
2226
+ EnumerateExpression,
2227
+ IntegerType,
2228
+ KeyPathExpression,
2229
+ KeyPathExpressionV2,
2230
+ ListNode,
2231
+ MapNode,
2232
+ MapType,
2233
+ NumberType,
2234
+ ObjectType,
2235
+ Property,
2236
+ Scope,
2237
+ ScopeChain,
2238
+ ScopeOutputData,
2239
+ ScopeProvider,
2240
+ StringType,
2241
+ VariableContainerModule,
2242
+ VariableDeclaration,
2243
+ VariableDeclarationList,
2244
+ VariableEngine,
2245
+ VariableEngineProvider,
2246
+ VariableFieldKeyRenameService,
2247
+ WrapArrayExpression,
2248
+ injectToAST,
2249
+ isMatchAST,
2250
+ postConstructAST,
2251
+ useAvailableVariables,
2252
+ useCurrentScope,
2253
+ useScopeAvailable,
2254
+ useScopeContext
2255
+ });
2256
+ //# sourceMappingURL=index.js.map