@flowgram.ai/variable-core 0.5.5 → 0.5.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/index.js +690 -263
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +1185 -238
- package/dist/index.d.ts +1185 -238
- package/dist/index.js +703 -266
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/README.md +0 -24
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
|
-
//
|
|
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
|
|
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
|
-
//
|
|
86
|
+
// Activate the share() operator
|
|
85
87
|
this.onAnyVariableChange(() => {
|
|
86
88
|
this.bumpVersion();
|
|
87
89
|
})
|
|
88
90
|
]);
|
|
89
91
|
}
|
|
90
92
|
/**
|
|
91
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
159
|
-
*
|
|
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
|
-
*
|
|
169
|
-
*
|
|
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
|
|
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
|
-
*
|
|
408
|
+
* Node flags, used to record some flag information.
|
|
384
409
|
*/
|
|
385
410
|
this.flags = 0 /* None */;
|
|
386
411
|
/**
|
|
387
|
-
*
|
|
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
|
-
*
|
|
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
|
|
403
|
-
* -
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
|
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
|
|
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
|
-
*
|
|
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
|
-
* -
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
//
|
|
584
|
+
// By default, skip the first trigger of BehaviorSubject.
|
|
555
585
|
triggerOnInit ? tap(() => null) : skip2(1),
|
|
556
|
-
//
|
|
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
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
|
|
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 && //
|
|
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/
|
|
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
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
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 && //
|
|
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
|
-
*
|
|
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 && //
|
|
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
|
|
1045
|
-
import { shallowEqual as
|
|
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
|
|
1069
|
-
var
|
|
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,122 @@ 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
|
-
*
|
|
1114
|
-
*
|
|
1115
|
-
*
|
|
1116
|
-
* @
|
|
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 (!
|
|
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
|
+
*/
|
|
1221
|
+
toJSON() {
|
|
1222
|
+
return {
|
|
1223
|
+
kind: "KeyPathExpression" /* KeyPathExpression */,
|
|
1224
|
+
keyPath: this._keyPath
|
|
1225
|
+
};
|
|
1226
|
+
}
|
|
1227
|
+
};
|
|
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
|
+
*/
|
|
1131
1298
|
toJSON() {
|
|
1132
1299
|
return {
|
|
1133
1300
|
kind: "KeyPathExpression" /* KeyPathExpression */,
|
|
@@ -1135,16 +1302,25 @@ var KeyPathExpressionV2 = class extends BaseExpression {
|
|
|
1135
1302
|
};
|
|
1136
1303
|
}
|
|
1137
1304
|
};
|
|
1138
|
-
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
|
|
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
|
-
*
|
|
1442
|
-
* @param key
|
|
1443
|
-
* @param
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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(
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
1858
|
-
*
|
|
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
|
-
//
|
|
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
|
|
2309
|
+
* Retrieves a variable from the scope by its key.
|
|
1977
2310
|
*
|
|
1978
|
-
* @param key
|
|
1979
|
-
* @returns The
|
|
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
|
|
2318
|
+
* Clears a variable from the scope by its key.
|
|
1986
2319
|
*
|
|
1987
|
-
* @param key
|
|
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
|
-
|
|
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
|
-
*
|
|
2031
|
-
* @param id scope
|
|
2032
|
-
* @param meta scope
|
|
2033
|
-
* @param
|
|
2034
|
-
* @
|
|
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
|
-
|
|
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 =
|
|
2190
|
-
|
|
2191
|
-
|
|
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/
|
|
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() {
|
|
2197
|
-
const
|
|
2599
|
+
function useScopeAvailable(params) {
|
|
2600
|
+
const { autoRefresh = true } = params || {};
|
|
2601
|
+
const scope = useCurrentScope({ strict: true });
|
|
2198
2602
|
const refresh = useRefresh();
|
|
2199
2603
|
useEffect(() => {
|
|
2200
|
-
|
|
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/
|
|
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
|
-
|
|
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
|
-
|
|
2271
|
-
|
|
2697
|
+
useOutputVariables,
|
|
2698
|
+
useScopeAvailable
|
|
2272
2699
|
};
|
|
2273
2700
|
//# sourceMappingURL=index.js.map
|