doragera commited on
Commit
b4180d6
·
2 Parent(s): 62d700f 1797f18

Merge pull request #121 from biggraph/feat/bionemo-nims

Browse files
lynxkite-app/web/package-lock.json CHANGED
@@ -18,11 +18,13 @@
18
  "@syncedstore/react": "^0.6.0",
19
  "@types/node": "^22.10.1",
20
  "@xyflow/react": "^12.3.5",
 
21
  "axios": "^1.8.2",
22
  "daisyui": "^4.12.20",
23
  "echarts": "^5.5.1",
24
  "fuse.js": "^7.0.0",
25
  "json-schema-to-typescript": "^15.0.3",
 
26
  "react": "^18.3.1",
27
  "react-dom": "^18.3.1",
28
  "react-markdown": "^9.0.1",
@@ -2366,6 +2368,22 @@
2366
  "d3-zoom": "^3.0.0"
2367
  }
2368
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2369
  "node_modules/abstract-leveldown": {
2370
  "version": "6.2.3",
2371
  "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz",
@@ -4187,6 +4205,12 @@
4187
  "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==",
4188
  "license": "MIT"
4189
  },
 
 
 
 
 
 
4190
  "node_modules/is-alphabetical": {
4191
  "version": "2.0.1",
4192
  "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
@@ -5465,8 +5489,7 @@
5465
  "version": "0.52.2",
5466
  "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.52.2.tgz",
5467
  "integrity": "sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==",
5468
- "license": "MIT",
5469
- "peer": true
5470
  },
5471
  "node_modules/ms": {
5472
  "version": "2.1.3",
@@ -5518,6 +5541,15 @@
5518
  "dev": true,
5519
  "license": "MIT"
5520
  },
 
 
 
 
 
 
 
 
 
5521
  "node_modules/no-case": {
5522
  "version": "3.0.4",
5523
  "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
@@ -5649,6 +5681,12 @@
5649
  "integrity": "sha512-g4+387DXDKlZzHkP+9FLt8yKj8+/3tOkPv7DVTJGGRm00RkEWgqbFstX1mXJ4M0VDYhUqsTOiISqNOJnhAu3PQ==",
5650
  "license": "MIT"
5651
  },
 
 
 
 
 
 
5652
  "node_modules/parent-module": {
5653
  "version": "1.0.1",
5654
  "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -7107,6 +7145,21 @@
7107
  "browserslist": ">= 4.21.0"
7108
  }
7109
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7110
  "node_modules/uri-js": {
7111
  "version": "4.4.1",
7112
  "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
 
18
  "@syncedstore/react": "^0.6.0",
19
  "@types/node": "^22.10.1",
20
  "@xyflow/react": "^12.3.5",
21
+ "3dmol": "^2.4.2",
22
  "axios": "^1.8.2",
23
  "daisyui": "^4.12.20",
24
  "echarts": "^5.5.1",
25
  "fuse.js": "^7.0.0",
26
  "json-schema-to-typescript": "^15.0.3",
27
+ "monaco-editor": "^0.52.2",
28
  "react": "^18.3.1",
29
  "react-dom": "^18.3.1",
30
  "react-markdown": "^9.0.1",
 
2368
  "d3-zoom": "^3.0.0"
2369
  }
2370
  },
2371
+ "node_modules/3dmol": {
2372
+ "version": "2.4.2",
2373
+ "resolved": "https://registry.npmjs.org/3dmol/-/3dmol-2.4.2.tgz",
2374
+ "integrity": "sha512-7R6uFaF5++s9EpO+R0a3bs6igi5idI+sgrVhtozaZlOGHg6oourYkAlAwYxWRaeBGlNcAd+oEIhbhJYhNxGyZA==",
2375
+ "license": "BSD-3-Clause",
2376
+ "dependencies": {
2377
+ "iobuffer": "^5.3.1",
2378
+ "netcdfjs": "^3.0.0",
2379
+ "pako": "^2.1.0",
2380
+ "upng-js": "^2.1.0"
2381
+ },
2382
+ "engines": {
2383
+ "node": ">=16.16.0",
2384
+ "npm": ">=8.11"
2385
+ }
2386
+ },
2387
  "node_modules/abstract-leveldown": {
2388
  "version": "6.2.3",
2389
  "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz",
 
4205
  "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==",
4206
  "license": "MIT"
4207
  },
4208
+ "node_modules/iobuffer": {
4209
+ "version": "5.4.0",
4210
+ "resolved": "https://registry.npmjs.org/iobuffer/-/iobuffer-5.4.0.tgz",
4211
+ "integrity": "sha512-DRebOWuqDvxunfkNJAlc3IzWIPD5xVxwUNbHr7xKB8E6aLJxIPfNX3CoMJghcFjpv6RWQsrcJbghtEwSPoJqMA==",
4212
+ "license": "MIT"
4213
+ },
4214
  "node_modules/is-alphabetical": {
4215
  "version": "2.0.1",
4216
  "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
 
5489
  "version": "0.52.2",
5490
  "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.52.2.tgz",
5491
  "integrity": "sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==",
5492
+ "license": "MIT"
 
5493
  },
5494
  "node_modules/ms": {
5495
  "version": "2.1.3",
 
5541
  "dev": true,
5542
  "license": "MIT"
5543
  },
5544
+ "node_modules/netcdfjs": {
5545
+ "version": "3.0.0",
5546
+ "resolved": "https://registry.npmjs.org/netcdfjs/-/netcdfjs-3.0.0.tgz",
5547
+ "integrity": "sha512-LOvT8KkC308qtpUkcBPiCMBtii7ZQCN6LxcVheWgyUeZ6DQWcpSRFV9dcVXLj/2eHZ/bre9tV5HTH4Sf93vrFw==",
5548
+ "license": "MIT",
5549
+ "dependencies": {
5550
+ "iobuffer": "^5.3.2"
5551
+ }
5552
+ },
5553
  "node_modules/no-case": {
5554
  "version": "3.0.4",
5555
  "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
 
5681
  "integrity": "sha512-g4+387DXDKlZzHkP+9FLt8yKj8+/3tOkPv7DVTJGGRm00RkEWgqbFstX1mXJ4M0VDYhUqsTOiISqNOJnhAu3PQ==",
5682
  "license": "MIT"
5683
  },
5684
+ "node_modules/pako": {
5685
+ "version": "2.1.0",
5686
+ "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz",
5687
+ "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==",
5688
+ "license": "(MIT AND Zlib)"
5689
+ },
5690
  "node_modules/parent-module": {
5691
  "version": "1.0.1",
5692
  "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
 
7145
  "browserslist": ">= 4.21.0"
7146
  }
7147
  },
7148
+ "node_modules/upng-js": {
7149
+ "version": "2.1.0",
7150
+ "resolved": "https://registry.npmjs.org/upng-js/-/upng-js-2.1.0.tgz",
7151
+ "integrity": "sha512-d3xzZzpMP64YkjP5pr8gNyvBt7dLk/uGI67EctzDuVp4lCZyVMo0aJO6l/VDlgbInJYDY6cnClLoBp29eKWI6g==",
7152
+ "license": "MIT",
7153
+ "dependencies": {
7154
+ "pako": "^1.0.5"
7155
+ }
7156
+ },
7157
+ "node_modules/upng-js/node_modules/pako": {
7158
+ "version": "1.0.11",
7159
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
7160
+ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
7161
+ "license": "(MIT AND Zlib)"
7162
+ },
7163
  "node_modules/uri-js": {
7164
  "version": "4.4.1",
7165
  "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
lynxkite-app/web/package.json CHANGED
@@ -21,11 +21,13 @@
21
  "@syncedstore/react": "^0.6.0",
22
  "@types/node": "^22.10.1",
23
  "@xyflow/react": "^12.3.5",
 
24
  "axios": "^1.8.2",
25
  "daisyui": "^4.12.20",
26
  "echarts": "^5.5.1",
27
  "fuse.js": "^7.0.0",
28
  "json-schema-to-typescript": "^15.0.3",
 
29
  "react": "^18.3.1",
30
  "react-dom": "^18.3.1",
31
  "react-markdown": "^9.0.1",
 
21
  "@syncedstore/react": "^0.6.0",
22
  "@types/node": "^22.10.1",
23
  "@xyflow/react": "^12.3.5",
24
+ "3dmol": "^2.4.2",
25
  "axios": "^1.8.2",
26
  "daisyui": "^4.12.20",
27
  "echarts": "^5.5.1",
28
  "fuse.js": "^7.0.0",
29
  "json-schema-to-typescript": "^15.0.3",
30
+ "monaco-editor": "^0.52.2",
31
  "react": "^18.3.1",
32
  "react-dom": "^18.3.1",
33
  "react-markdown": "^9.0.1",
lynxkite-app/web/src/workspace/Workspace.tsx CHANGED
@@ -37,6 +37,7 @@ import { LynxKiteState } from "./LynxKiteState";
37
  import NodeSearch, { type OpsOp, type Catalog, type Catalogs } from "./NodeSearch.tsx";
38
  import NodeWithGraphCreationView from "./nodes/GraphCreationNode.tsx";
39
  import NodeWithImage from "./nodes/NodeWithImage.tsx";
 
40
  import NodeWithParams from "./nodes/NodeWithParams";
41
  import NodeWithTableView from "./nodes/NodeWithTableView.tsx";
42
  import NodeWithVisualization from "./nodes/NodeWithVisualization.tsx";
@@ -175,6 +176,7 @@ function LynxKiteFlow() {
175
  image: NodeWithImage,
176
  table_view: NodeWithTableView,
177
  graph_creation_view: NodeWithGraphCreationView,
 
178
  }),
179
  [],
180
  );
 
37
  import NodeSearch, { type OpsOp, type Catalog, type Catalogs } from "./NodeSearch.tsx";
38
  import NodeWithGraphCreationView from "./nodes/GraphCreationNode.tsx";
39
  import NodeWithImage from "./nodes/NodeWithImage.tsx";
40
+ import NodeWithMolecule from "./nodes/NodeWithMolecule.tsx";
41
  import NodeWithParams from "./nodes/NodeWithParams";
42
  import NodeWithTableView from "./nodes/NodeWithTableView.tsx";
43
  import NodeWithVisualization from "./nodes/NodeWithVisualization.tsx";
 
176
  image: NodeWithImage,
177
  table_view: NodeWithTableView,
178
  graph_creation_view: NodeWithGraphCreationView,
179
+ molecule: NodeWithMolecule,
180
  }),
181
  [],
182
  );
lynxkite-app/web/src/workspace/nodes/NodeWithMolecule.tsx ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useEffect, type CSSProperties } from "react";
2
+ import NodeWithParams from "./NodeWithParams";
3
+
4
+ const NodeWithMolecule = (props: any) => {
5
+ const containerRef = React.useRef<HTMLDivElement>(null);
6
+ const viewerRef = React.useRef<any>(null);
7
+
8
+ useEffect(() => {
9
+ const config = props.data?.display?.value;
10
+ if (!config || !containerRef.current) return;
11
+ async function run() {
12
+ const $3Dmol = await import("3dmol");
13
+
14
+ try {
15
+ // Initialize viewer only once
16
+ if (!viewerRef.current) {
17
+ viewerRef.current = $3Dmol.createViewer(containerRef.current, {
18
+ backgroundColor: "white",
19
+ });
20
+ }
21
+
22
+ const viewer = viewerRef.current;
23
+
24
+ // Clear previous models
25
+ viewer.clear();
26
+
27
+ // Add new model and style it
28
+ viewer.addModel(config.data, config.format);
29
+ viewer.setStyle({}, { stick: {} });
30
+ viewer.zoomTo();
31
+ viewer.render();
32
+ } catch (error) {
33
+ console.error("Error rendering 3D molecule:", error);
34
+ }
35
+ }
36
+ run();
37
+ const resizeObserver = new ResizeObserver(() => {
38
+ viewerRef.current?.resize();
39
+ });
40
+
41
+ const observed = containerRef.current;
42
+ resizeObserver.observe(observed);
43
+ return () => {
44
+ resizeObserver.unobserve(observed);
45
+ if (viewerRef.current) {
46
+ viewerRef.current.clear();
47
+ }
48
+ };
49
+ }, [props.data?.display?.value]);
50
+
51
+ const nodeStyle: CSSProperties = {
52
+ display: "flex",
53
+ flexDirection: "column",
54
+ height: "100%",
55
+ };
56
+
57
+ const vizStyle: CSSProperties = {
58
+ flex: 1,
59
+ minHeight: "300px",
60
+ border: "1px solid #ddd",
61
+ borderRadius: "4px",
62
+ overflow: "hidden",
63
+ position: "relative",
64
+ };
65
+
66
+ return (
67
+ <NodeWithParams nodeStyle={nodeStyle} collapsed {...props}>
68
+ <div style={vizStyle} ref={containerRef} />
69
+ </NodeWithParams>
70
+ );
71
+ };
72
+
73
+ export default NodeWithMolecule;
lynxkite-core/src/lynxkite/core/ops.py CHANGED
@@ -180,6 +180,7 @@ class Op(BaseConfig):
180
  "table_view",
181
  "graph_creation_view",
182
  "image",
 
183
  ]:
184
  # If the operation is some kind of visualization, we use the output as the
185
  # value to display by default.
 
180
  "table_view",
181
  "graph_creation_view",
182
  "image",
183
+ "molecule",
184
  ]:
185
  # If the operation is some kind of visualization, we use the output as the
186
  # value to display by default.