Skip to content

Commit 570cae2

Browse files
committed
Refactor node resizing checks to ensure safety and prevent errors and get AI Neural net flow working in web-worker with inteaction
1 parent cea4d19 commit 570cae2

27 files changed

+654
-119
lines changed

apps/vps-web/src/app/ai-flow-engine-worker/ai-flow-engine-worker-message.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import {
66

77
export interface AIWorkerMessage {
88
message: string;
9-
flow: Flow<BaseNodeInfo>;
9+
flow?: Flow<BaseNodeInfo>;
10+
nodeId?: string;
11+
input?: any;
1012
}
1113

1214
export interface AIWorkerMessageResponse {

apps/vps-web/src/app/ai-flow-engine-worker/ai-flow-engine-worker.ts

Lines changed: 78 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,98 @@
11
/// <reference lib="webworker" />
22

3-
import { IComputeResult } from '@devhelpr/visual-programming-system';
4-
import { FlowEngine } from '../flow-engine/flow-engine';
3+
import {
4+
IComputeResult,
5+
IRectNodeComponent,
6+
} from '@devhelpr/visual-programming-system';
7+
import { RuntimeFlowEngine } from '../flow-engine/flow-engine';
58
import {
69
AIWorkerMessage,
710
AIWorkerWorkerSelf,
811
} from './ai-flow-engine-worker-message';
9-
import { run } from '@devhelpr/web-flow-executor';
12+
import { NodeInfo, run } from '@devhelpr/web-flow-executor';
13+
import { registerWorkerNodes } from '../custom-nodes/register-worker-nodes';
1014

1115
declare let self: AIWorkerWorkerSelf;
1216
console.log('WORKER RuntimeFlowContext', run);
17+
let flowEngine: RuntimeFlowEngine;
1318
// Message event handler
1419
self.addEventListener('message', (event: MessageEvent<AIWorkerMessage>) => {
1520
try {
1621
const { data } = event;
17-
18-
const flowEngine = new FlowEngine();
19-
flowEngine.onSendUpdateToNode = (data, node) => {
20-
console.log('onSendUpdateToNode', data, node);
21-
self.postMessage({
22-
message: 'node-update',
23-
result: {
24-
result: node.id,
25-
output: data,
26-
} as IComputeResult,
27-
});
28-
};
29-
flowEngine.initialize(data.flow.flows['flow'].nodes);
30-
flowEngine
31-
.run()
32-
.then((output) => {
33-
// Send the result back to the main thread
22+
if (data.message === 'start-node') {
23+
console.log('start-node', data);
24+
const nodeId = data.nodeId;
25+
if (flowEngine && nodeId) {
26+
const node = flowEngine.canvasApp.elements.get(nodeId);
27+
if (node) {
28+
flowEngine.runNode(
29+
node as IRectNodeComponent<NodeInfo>,
30+
() => {
31+
//
32+
},
33+
data.input,
34+
undefined,
35+
undefined,
36+
undefined,
37+
undefined,
38+
undefined,
39+
undefined,
40+
undefined,
41+
undefined,
42+
undefined,
43+
undefined,
44+
(output, node) => {
45+
self.postMessage({
46+
message: 'node-update',
47+
result: {
48+
result: node.id,
49+
output: output,
50+
} as IComputeResult,
51+
});
52+
}
53+
);
54+
}
55+
}
56+
} else if (data.message === 'start') {
57+
if (!data.flow) {
58+
throw new Error('Flow not provided');
59+
}
60+
flowEngine = new RuntimeFlowEngine();
61+
flowEngine.onSendUpdateToNode = (data, node) => {
62+
console.log('onSendUpdateToNode', data, node);
3463
self.postMessage({
35-
message: 'computation-result',
64+
message: 'node-update',
3665
result: {
37-
result: 'success',
38-
output: output,
39-
followPath: undefined,
40-
},
66+
result: node.id,
67+
output: data,
68+
} as IComputeResult,
4169
});
42-
})
43-
.catch((error) => {
44-
self.postMessage({
45-
message: 'error',
46-
result: {
47-
result: error?.toString?.() ?? 'Error in flow engine worker',
48-
output: undefined,
49-
followPath: undefined,
50-
},
70+
};
71+
flowEngine.initialize(data.flow.flows['flow'].nodes, registerWorkerNodes);
72+
flowEngine
73+
.run()
74+
.then((output) => {
75+
// Send the result back to the main thread
76+
self.postMessage({
77+
message: 'computation-result',
78+
result: {
79+
result: 'success',
80+
output: output,
81+
followPath: undefined,
82+
},
83+
});
84+
})
85+
.catch((error) => {
86+
self.postMessage({
87+
message: 'error',
88+
result: {
89+
result: error?.toString?.() ?? 'Error in flow engine worker',
90+
output: undefined,
91+
followPath: undefined,
92+
},
93+
});
5194
});
52-
});
95+
}
5396
} catch (error) {
5497
self.postMessage({
5598
message: 'error',

apps/vps-web/src/app/custom-nodes/classes/base-rect-node-class.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ import {
1010
createElement,
1111
renderElement,
1212
} from '@devhelpr/visual-programming-system';
13-
import { NodeInfo, RunCounter } from '@devhelpr/web-flow-executor';
13+
import { FlowEngine, NodeInfo, RunCounter } from '@devhelpr/web-flow-executor';
1414
import { CorePropertiesSetupEditor } from './core-properties-settings-editor';
15-
import './style.css';
1615

1716
export type CreateRunCounterContext = (
1817
isRunViaRunButton: boolean,
@@ -39,15 +38,17 @@ export class BaseRectNode {
3938
static readonly text: string = 'rect';
4039

4140
static readonly disableManualResize: boolean = true;
42-
41+
flowEngine: FlowEngine | undefined = undefined;
4342
constructor(
4443
id: string,
4544
updated: () => void,
46-
node: IRectNodeComponent<NodeInfo>
45+
node: IRectNodeComponent<NodeInfo>,
46+
flowEngine?: FlowEngine
4747
) {
4848
this.id = id;
4949
this.updated = updated;
5050
this.node = node;
51+
this.flowEngine = flowEngine;
5152
}
5253

5354
getSettingsPopup:

apps/vps-web/src/app/custom-nodes/classes/draw-grid-node.tsx

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
} from '@devhelpr/visual-programming-system';
88
import { getRunIndex, NodeInfo, runNode } from '@devhelpr/web-flow-executor';
99

10-
import './style.css';
1110
import { BaseRectNode } from './base-rect-node-class';
1211

1312
class Label extends HTMLElement {
@@ -635,24 +634,46 @@ export class DrawGridNode extends BaseRectNode {
635634
) {
636635
return;
637636
}
638-
runNode(
639-
this.node,
640-
this.canvasAppInstance,
641-
() => {
642-
//
643-
},
644-
undefined,
645-
undefined,
646-
undefined,
647-
getRunIndex(),
648-
undefined,
649-
undefined,
650-
this.createRunCounterContext(false, false),
651-
false,
652-
{
653-
trigger: true,
654-
}
655-
);
637+
if (this.flowEngine?.runNode) {
638+
this.flowEngine?.runNode(
639+
undefined,
640+
this.node,
641+
this.canvasAppInstance,
642+
() => {
643+
//
644+
},
645+
JSON.stringify(this.drawGrid?.gridValues ?? []),
646+
undefined,
647+
undefined,
648+
getRunIndex(),
649+
undefined,
650+
undefined,
651+
this.createRunCounterContext(false, false),
652+
false,
653+
{
654+
trigger: true,
655+
}
656+
);
657+
} else {
658+
runNode(
659+
this.node,
660+
this.canvasAppInstance,
661+
() => {
662+
//
663+
},
664+
undefined,
665+
undefined,
666+
undefined,
667+
getRunIndex(),
668+
undefined,
669+
undefined,
670+
this.createRunCounterContext(false, false),
671+
false,
672+
{
673+
trigger: true,
674+
}
675+
);
676+
}
656677
//}, 50);
657678
};
658679

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import {
2+
FormField,
3+
IComputeResult,
4+
InitialValues,
5+
NodeTask,
6+
ThumbConnectionType,
7+
ThumbType,
8+
visualNodeFactory,
9+
} from '@devhelpr/visual-programming-system';
10+
import { NodeInfo } from '@devhelpr/web-flow-executor';
11+
12+
const fieldName = 'draw-grid-input';
13+
const nodeTitle = 'Draw grid';
14+
export const drawGridNodeName = 'draw-grid-node';
15+
const familyName = 'flow-canvas';
16+
const thumbs = [
17+
{
18+
thumbType: ThumbType.StartConnectorCenter,
19+
thumbIndex: 0,
20+
connectionType: ThumbConnectionType.start,
21+
color: 'white',
22+
label: ' ',
23+
name: 'output',
24+
maxConnections: -1,
25+
},
26+
{
27+
thumbType: ThumbType.EndConnectorCenter,
28+
thumbIndex: 0,
29+
connectionType: ThumbConnectionType.end,
30+
color: 'white',
31+
label: ' ',
32+
name: 'input',
33+
maxConnections: 1,
34+
},
35+
];
36+
37+
export const getDrawGridNode =
38+
() =>
39+
(_updated: () => void): NodeTask<NodeInfo> => {
40+
const initializeCompute = () => {
41+
return;
42+
};
43+
const computeAsync = (
44+
input: string,
45+
_loopIndex?: number,
46+
_payload?: any
47+
) => {
48+
return new Promise<IComputeResult>((resolve) => {
49+
try {
50+
const cells = JSON.parse(input);
51+
console.log('cells', cells);
52+
resolve({
53+
output: cells,
54+
result: cells,
55+
followPath: undefined,
56+
});
57+
} catch (error) {
58+
resolve({
59+
output: [],
60+
result: [],
61+
followPath: undefined,
62+
stop: true,
63+
});
64+
}
65+
});
66+
};
67+
68+
return visualNodeFactory(
69+
drawGridNodeName,
70+
nodeTitle,
71+
familyName,
72+
fieldName,
73+
computeAsync,
74+
initializeCompute,
75+
false,
76+
200,
77+
100,
78+
thumbs,
79+
(_values?: InitialValues): FormField[] => {
80+
return [];
81+
},
82+
(_nodeInstance) => {
83+
//
84+
},
85+
{
86+
category: 'Diagrams',
87+
},
88+
undefined,
89+
true
90+
);
91+
};

apps/vps-web/src/app/custom-nodes/rect-node.tsx

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
ThumbType,
1313
visualNodeFactory,
1414
} from '@devhelpr/visual-programming-system';
15-
import { NodeInfo } from '@devhelpr/web-flow-executor';
15+
import { FlowEngine, NodeInfo } from '@devhelpr/web-flow-executor';
1616
import {
1717
BaseRectNode,
1818
CreateRunCounterContext,
@@ -22,18 +22,20 @@ const familyName = 'flow-canvas';
2222

2323
export const createNodeFactoryInstance = (
2424
NodeClass: typeof BaseRectNode,
25-
createRunCounterContext: CreateRunCounterContext
25+
createRunCounterContext: CreateRunCounterContext,
26+
flowEngine?: FlowEngine
2627
) => {
2728
return {
2829
name: NodeClass.nodeTypeName,
29-
factory: getRectNode(NodeClass, createRunCounterContext),
30+
factory: getRectNode(NodeClass, createRunCounterContext, flowEngine),
3031
};
3132
};
3233

3334
export const getRectNode =
3435
(
3536
NodeClass: typeof BaseRectNode,
36-
createRunCounterContext: CreateRunCounterContext
37+
createRunCounterContext: CreateRunCounterContext,
38+
flowEngine?: FlowEngine
3739
) =>
3840
(
3941
updated: () => void,
@@ -123,7 +125,7 @@ export const getRectNode =
123125
node.nodeInfo.isOCIFNode = true;
124126
}
125127

126-
rectNode = new NodeClass(node.id, updated, node);
128+
rectNode = new NodeClass(node.id, updated, node, flowEngine);
127129
rectNode.rectInstance = rect;
128130
rectNode.canvasAppInstance = nodeInstance.contextInstance;
129131
rectNode.onResize = (width: number, height: number) => {
@@ -186,7 +188,14 @@ export const getRectNode =
186188
rectNode.setSize(node.width ?? 10, node.height ?? 10);
187189
return;
188190
}
189-
rect.resize(undefined, true, rectNode.childElementSelector, true);
191+
if (rect && rect.resize) {
192+
rect.resize(
193+
undefined,
194+
true,
195+
rectNode.childElementSelector,
196+
true
197+
);
198+
}
190199
}
191200
});
192201
resizeObserver.observe(nodeRenderElement);

0 commit comments

Comments
 (0)