@fincity/kirun-js 3.1.4 → 3.2.0

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.
Files changed (40) hide show
  1. package/__tests__/engine/dsl/GraphDebugTest.ts +316 -0
  2. package/__tests__/engine/runtime/expression/ExpressionParsingTest.ts +402 -14
  3. package/dist/index.js +15 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/module.js +15 -1
  6. package/dist/module.js.map +1 -1
  7. package/dist/types.d.ts +416 -0
  8. package/dist/types.d.ts.map +1 -1
  9. package/package.json +1 -1
  10. package/src/engine/dsl/DSLCompiler.ts +104 -0
  11. package/src/engine/dsl/index.ts +30 -0
  12. package/src/engine/dsl/lexer/DSLLexer.ts +518 -0
  13. package/src/engine/dsl/lexer/DSLToken.ts +74 -0
  14. package/src/engine/dsl/lexer/Keywords.ts +80 -0
  15. package/src/engine/dsl/lexer/LexerError.ts +37 -0
  16. package/src/engine/dsl/monaco/DSLFunctionProvider.ts +187 -0
  17. package/src/engine/dsl/parser/DSLParser.ts +1075 -0
  18. package/src/engine/dsl/parser/DSLParserError.ts +29 -0
  19. package/src/engine/dsl/parser/ast/ASTNode.ts +23 -0
  20. package/src/engine/dsl/parser/ast/ArgumentNode.ts +43 -0
  21. package/src/engine/dsl/parser/ast/ComplexValueNode.ts +22 -0
  22. package/src/engine/dsl/parser/ast/EventDeclNode.ts +27 -0
  23. package/src/engine/dsl/parser/ast/ExpressionNode.ts +33 -0
  24. package/src/engine/dsl/parser/ast/FunctionCallNode.ts +29 -0
  25. package/src/engine/dsl/parser/ast/FunctionDefNode.ts +37 -0
  26. package/src/engine/dsl/parser/ast/ParameterDeclNode.ts +25 -0
  27. package/src/engine/dsl/parser/ast/SchemaLiteralNode.ts +26 -0
  28. package/src/engine/dsl/parser/ast/SchemaNode.ts +23 -0
  29. package/src/engine/dsl/parser/ast/StatementNode.ts +41 -0
  30. package/src/engine/dsl/parser/ast/index.ts +14 -0
  31. package/src/engine/dsl/transformer/ASTToJSON.ts +378 -0
  32. package/src/engine/dsl/transformer/ExpressionHandler.ts +48 -0
  33. package/src/engine/dsl/transformer/JSONToText.ts +694 -0
  34. package/src/engine/dsl/transformer/SchemaTransformer.ts +110 -0
  35. package/src/engine/model/FunctionDefinition.ts +23 -0
  36. package/src/engine/runtime/expression/Expression.ts +5 -1
  37. package/src/engine/runtime/expression/ExpressionEvaluator.ts +152 -139
  38. package/src/engine/runtime/expression/ExpressionParser.ts +80 -27
  39. package/src/engine/util/duplicate.ts +3 -1
  40. package/src/index.ts +1 -0
@@ -0,0 +1,316 @@
1
+ import { FunctionDefinition } from '../../../src/engine/model/FunctionDefinition';
2
+ import { KIRuntime } from '../../../src/engine/runtime/KIRuntime';
3
+ import { KIRunFunctionRepository } from '../../../src/engine/repository/KIRunFunctionRepository';
4
+ import { KIRunSchemaRepository } from '../../../src/engine/repository/KIRunSchemaRepository';
5
+
6
+ // Fibonacci function from test-data
7
+ const fibonacciJson = {
8
+ name: 'fibonaccii',
9
+ namespace: 'TestUI',
10
+ parameters: {
11
+ n: {
12
+ parameterName: 'n',
13
+ schema: {
14
+ type: ['INTEGER'],
15
+ version: 1,
16
+ },
17
+ },
18
+ },
19
+ events: {
20
+ output: {
21
+ name: 'output',
22
+ parameters: {
23
+ result: {
24
+ type: ['ARRAY'],
25
+ version: 1,
26
+ items: {
27
+ type: ['INTEGER'],
28
+ },
29
+ },
30
+ },
31
+ },
32
+ },
33
+ steps: {
34
+ create: {
35
+ statementName: 'create',
36
+ name: 'Create',
37
+ namespace: 'System.Context',
38
+ parameterMap: {
39
+ name: {
40
+ '2JUURU6NHj9voaArLv0pS8': {
41
+ key: '2JUURU6NHj9voaArLv0pS8',
42
+ type: 'VALUE',
43
+ order: 1,
44
+ value: 'a',
45
+ },
46
+ },
47
+ schema: {
48
+ '2vxDXyOakSmhiUmH4CuDED': {
49
+ key: '2vxDXyOakSmhiUmH4CuDED',
50
+ type: 'VALUE',
51
+ order: 1,
52
+ value: {
53
+ type: 'ARRAY',
54
+ items: {
55
+ type: 'INTEGER',
56
+ },
57
+ },
58
+ },
59
+ },
60
+ },
61
+ },
62
+ rangeLoop: {
63
+ statementName: 'rangeLoop',
64
+ name: 'RangeLoop',
65
+ namespace: 'System.Loop',
66
+ parameterMap: {
67
+ to: {
68
+ '6RAIEdM1OAek2AKf64ucqM': {
69
+ key: '6RAIEdM1OAek2AKf64ucqM',
70
+ type: 'EXPRESSION',
71
+ expression: 'Arguments.n',
72
+ value: 1,
73
+ },
74
+ },
75
+ },
76
+ dependentStatements: {
77
+ 'Steps.create.output': false,
78
+ 'Steps.set2.output': true,
79
+ },
80
+ },
81
+ if: {
82
+ statementName: 'if',
83
+ name: 'If',
84
+ namespace: 'System',
85
+ parameterMap: {
86
+ condition: {
87
+ C2FB54BobtFXTmLKv4v6s: {
88
+ key: 'C2FB54BobtFXTmLKv4v6s',
89
+ type: 'EXPRESSION',
90
+ expression: 'Steps.rangeLoop.iteration.index < 2',
91
+ order: 1,
92
+ },
93
+ },
94
+ },
95
+ },
96
+ trueInsert: {
97
+ statementName: 'trueInsert',
98
+ name: 'InsertLast',
99
+ namespace: 'System.Array',
100
+ parameterMap: {
101
+ source: {
102
+ '4DzS3icjwGl7nUPvk7QUST': {
103
+ key: '4DzS3icjwGl7nUPvk7QUST',
104
+ type: 'EXPRESSION',
105
+ expression: 'Context.a',
106
+ order: 1,
107
+ },
108
+ },
109
+ element: {
110
+ '1sWH8NKqkdKevU7vQJk9jn': {
111
+ key: '1sWH8NKqkdKevU7vQJk9jn',
112
+ type: 'EXPRESSION',
113
+ expression: 'Steps.rangeLoop.iteration.index',
114
+ order: 1,
115
+ },
116
+ },
117
+ },
118
+ dependentStatements: {
119
+ 'Steps.if.true': true,
120
+ },
121
+ },
122
+ set: {
123
+ statementName: 'set',
124
+ name: 'Set',
125
+ namespace: 'System.Context',
126
+ parameterMap: {
127
+ name: {
128
+ UPMhlPSuFHCygh0DYa7Zc: {
129
+ key: 'UPMhlPSuFHCygh0DYa7Zc',
130
+ type: 'VALUE',
131
+ order: 1,
132
+ value: 'Context.a',
133
+ },
134
+ },
135
+ value: {
136
+ '1B8Bfavmym6BmbdsDesmNX': {
137
+ key: '1B8Bfavmym6BmbdsDesmNX',
138
+ type: 'EXPRESSION',
139
+ expression: 'Steps.trueInsert.output.result',
140
+ order: 1,
141
+ },
142
+ },
143
+ },
144
+ dependentStatements: {
145
+ 'Steps.if.true': false,
146
+ },
147
+ },
148
+ set1: {
149
+ statementName: 'set1',
150
+ name: 'Set',
151
+ namespace: 'System.Context',
152
+ parameterMap: {
153
+ name: {
154
+ '6dYVAyspJbF82O8qJm3f2O': {
155
+ key: '6dYVAyspJbF82O8qJm3f2O',
156
+ type: 'VALUE',
157
+ order: 1,
158
+ value: 'Context.a',
159
+ },
160
+ },
161
+ value: {
162
+ fVB75EKlR6It0i7iho3oQ: {
163
+ key: 'fVB75EKlR6It0i7iho3oQ',
164
+ type: 'EXPRESSION',
165
+ expression: 'Steps.falseInsert.output.result',
166
+ order: 1,
167
+ },
168
+ },
169
+ },
170
+ dependentStatements: {
171
+ 'Steps.if.false': false,
172
+ },
173
+ },
174
+ falseInsert: {
175
+ statementName: 'falseInsert',
176
+ name: 'InsertLast',
177
+ namespace: 'System.Array',
178
+ parameterMap: {
179
+ source: {
180
+ '1GsJu3FbuponBIcaqI48rF': {
181
+ key: '1GsJu3FbuponBIcaqI48rF',
182
+ type: 'EXPRESSION',
183
+ expression: 'Context.a',
184
+ order: 1,
185
+ },
186
+ },
187
+ element: {
188
+ '53vsp50RjvhS94xdCtWWx0': {
189
+ key: '53vsp50RjvhS94xdCtWWx0',
190
+ type: 'EXPRESSION',
191
+ expression:
192
+ 'Context.a[Steps.rangeLoop.iteration.index - 1] + Context.a[Steps.rangeLoop.iteration.index - 2]',
193
+ order: 1,
194
+ },
195
+ },
196
+ },
197
+ dependentStatements: {
198
+ 'Steps.if.false': true,
199
+ },
200
+ },
201
+ set2: {
202
+ statementName: 'set2',
203
+ name: 'Set',
204
+ namespace: 'System.Context',
205
+ parameterMap: {
206
+ name: {
207
+ '2XVsWDK0VUQhZJ0VnJllrQ': {
208
+ key: '2XVsWDK0VUQhZJ0VnJllrQ',
209
+ type: 'VALUE',
210
+ order: 1,
211
+ value: 'Context.a',
212
+ },
213
+ },
214
+ value: {
215
+ '1ksRfalqqgGfh4uZcLXDy9': {
216
+ key: '1ksRfalqqgGfh4uZcLXDy9',
217
+ type: 'VALUE',
218
+ order: 1,
219
+ value: [],
220
+ },
221
+ },
222
+ },
223
+ dependentStatements: {
224
+ 'Steps.create.output': true,
225
+ },
226
+ },
227
+ generateEvent: {
228
+ statementName: 'generateEvent',
229
+ name: 'GenerateEvent',
230
+ namespace: 'System',
231
+ parameterMap: {
232
+ results: {
233
+ '8brcu20HciA9rYDPOFeef': {
234
+ key: '8brcu20HciA9rYDPOFeef',
235
+ type: 'VALUE',
236
+ order: 1,
237
+ value: {
238
+ name: 'result',
239
+ value: {
240
+ isExpression: true,
241
+ value: 'Context.a',
242
+ },
243
+ },
244
+ },
245
+ },
246
+ },
247
+ dependentStatements: {
248
+ 'Steps.rangeLoop.output': true,
249
+ },
250
+ },
251
+ },
252
+ };
253
+
254
+ import { JSONToTextTransformer } from '../../../src/engine/dsl/transformer/JSONToText';
255
+
256
+ describe('Execution Graph Debug', () => {
257
+ test('should transform fibonacci to DSL with nested blocks', async () => {
258
+ const transformer = new JSONToTextTransformer();
259
+ const dslText = await transformer.transform(fibonacciJson);
260
+ console.log('\n=== GENERATED DSL ===');
261
+ console.log(dslText);
262
+
263
+ // Verify nesting
264
+ expect(dslText).toContain('rangeLoop:');
265
+ expect(dslText).toContain('iteration');
266
+ expect(dslText).toContain('if:');
267
+ expect(dslText).toContain('true');
268
+ expect(dslText).toContain('false');
269
+ expect(dslText).toContain('trueInsert:');
270
+ expect(dslText).toContain('falseInsert:');
271
+ });
272
+
273
+ test('should show graph edges for fibonacci', async () => {
274
+ const funcDef = FunctionDefinition.from(fibonacciJson);
275
+ const runtime = new KIRuntime(funcDef);
276
+ const functionRepo = new KIRunFunctionRepository();
277
+ const schemaRepo = new KIRunSchemaRepository();
278
+
279
+ const graph = await runtime.getExecutionPlan(functionRepo, schemaRepo);
280
+ console.log('Graph created successfully');
281
+ console.log('Nodes:', Array.from(graph.getNodeMap().keys()));
282
+
283
+ console.log('\n=== EXPECTED NESTING ===');
284
+ console.log('if -> nested under rangeLoop.iteration (uses Steps.rangeLoop.iteration.index)');
285
+ console.log('trueInsert -> nested under if.true (dependentStatements["Steps.if.true"])');
286
+ console.log('set -> nested under if.true (has dep on trueInsert.output which is under if.true)');
287
+ console.log('falseInsert -> nested under if.false (dependentStatements["Steps.if.false"])');
288
+ console.log('set1 -> nested under if.false (has dep on falseInsert.output which is under if.false)');
289
+ console.log('generateEvent -> nested under rangeLoop.output (dependentStatements["Steps.rangeLoop.output"])');
290
+ console.log('set2 -> nested under create.output (dependentStatements["Steps.create.output"])');
291
+
292
+ console.log('\n=== ACTUAL GRAPH EDGES ===');
293
+ const validBlockNames = new Set(['true', 'false', 'iteration', 'output', 'error']);
294
+
295
+ for (const [stepName, vertex] of graph.getNodeMap()) {
296
+ console.log(`\nStep: ${stepName}`);
297
+ const inVertices = vertex.getInVertices();
298
+ console.log(` InVertices count: ${inVertices.size}`);
299
+
300
+ const blockDeps: { parent: string; blockName: string }[] = [];
301
+ for (const tuple of Array.from(inVertices)) {
302
+ const parentKey = tuple.getT1().getKey();
303
+ const edgeType = tuple.getT2();
304
+ console.log(` - Parent: ${parentKey}, EdgeType: "${edgeType}"`);
305
+ if (validBlockNames.has(edgeType)) {
306
+ blockDeps.push({ parent: parentKey, blockName: edgeType });
307
+ }
308
+ }
309
+ if (blockDeps.length > 0) {
310
+ console.log(` -> Should be nested under: ${blockDeps.map((d) => `${d.parent}.${d.blockName}`).join(', ')}`);
311
+ }
312
+ }
313
+
314
+ expect(graph.getNodeMap().size).toBeGreaterThan(0);
315
+ });
316
+ });