geonodes-web-render 0.1.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.
@@ -0,0 +1,12 @@
1
+ export type GraphViewEmbedOptions = {
2
+ /** Raw asset data (e.g. "TreeClipper::H4sI...") */
3
+ payload: string;
4
+ /** Called when user requests close (e.g. modal close button). Use to unmount. */
5
+ onClose?: () => void;
6
+ };
7
+ export declare function GraphView(props: GraphViewEmbedOptions): import("react/jsx-runtime").JSX.Element;
8
+ /**
9
+ * Mount the graph view into a DOM container. Call unmountGraphView() to remove.
10
+ */
11
+ export declare function mountGraphView(container: HTMLElement, options: GraphViewEmbedOptions): () => void;
12
+ export declare function unmountGraphView(): void;
@@ -0,0 +1,2 @@
1
+ import { NodeProps } from '@xyflow/react';
2
+ export declare function GenericGNNode(props: NodeProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,5 @@
1
+ export declare function GeometryNodesFlow(props: {
2
+ jsonText: string;
3
+ /** When false, hide the panel header ("Geometry Nodes Graph" and node count). Default true. */
4
+ showHeader?: boolean;
5
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ import { NodeProps } from '@xyflow/react';
2
+ export declare function RerouteNode(props: NodeProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ import { NodeProps } from '@xyflow/react';
2
+ export declare function SimulationZoneFrame(props: NodeProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,134 @@
1
+ import { FloatCurveData, GraphIR, SocketDefaultValue, SocketDisplayShape } from '../ir/types';
2
+ type BlenderSocket = {
3
+ id: number;
4
+ data: {
5
+ name: string;
6
+ type: string;
7
+ display_shape: SocketDisplayShape;
8
+ default_value?: unknown;
9
+ hide_value?: boolean;
10
+ enabled?: boolean;
11
+ };
12
+ };
13
+ type BlenderNode = {
14
+ id: number;
15
+ data: {
16
+ name: string;
17
+ label: string;
18
+ bl_idname: string;
19
+ width?: number;
20
+ location?: [number, number];
21
+ location_absolute?: [number, number];
22
+ inputs?: {
23
+ data: {
24
+ items: BlenderSocket[];
25
+ };
26
+ };
27
+ outputs?: {
28
+ data: {
29
+ items: BlenderSocket[];
30
+ };
31
+ };
32
+ socket_idname?: string;
33
+ single_input?: number;
34
+ single_output?: number;
35
+ vector?: number[];
36
+ mode?: string;
37
+ operation?: string;
38
+ data_type?: string;
39
+ use_clamp?: boolean;
40
+ mapping?: {
41
+ data: {
42
+ use_clip?: boolean;
43
+ clip_min_x?: number;
44
+ clip_min_y?: number;
45
+ clip_max_x?: number;
46
+ clip_max_y?: number;
47
+ extend?: string;
48
+ curves?: {
49
+ data: {
50
+ items: Array<{
51
+ data: {
52
+ points: {
53
+ data: {
54
+ items: Array<{
55
+ data: {
56
+ location: [number, number];
57
+ handle_type: string;
58
+ };
59
+ }>;
60
+ };
61
+ };
62
+ };
63
+ }>;
64
+ };
65
+ };
66
+ };
67
+ };
68
+ };
69
+ };
70
+ type BlenderLink = {
71
+ id: number;
72
+ data: {
73
+ from_socket: number;
74
+ to_socket: number;
75
+ };
76
+ };
77
+ export type BlenderTreeExport = {
78
+ node_trees: Array<{
79
+ id: number;
80
+ data: {
81
+ name: string;
82
+ nodes: {
83
+ data: {
84
+ items: BlenderNode[];
85
+ };
86
+ };
87
+ links: {
88
+ data: {
89
+ items: BlenderLink[];
90
+ };
91
+ };
92
+ };
93
+ }>;
94
+ };
95
+ export type NormalizedSocket = {
96
+ id: string;
97
+ name: string;
98
+ dataType: string;
99
+ displayShape: SocketDisplayShape;
100
+ color: string;
101
+ defaultValue: SocketDefaultValue | null;
102
+ hideValue: boolean;
103
+ enabled: boolean;
104
+ index: number;
105
+ };
106
+ export type NormalizedNode = {
107
+ id: string;
108
+ type: string;
109
+ label: string;
110
+ position: {
111
+ x: number;
112
+ y: number;
113
+ };
114
+ width: number;
115
+ headerColor: string;
116
+ inputs: NormalizedSocket[];
117
+ outputs: NormalizedSocket[];
118
+ floatCurve?: FloatCurveData;
119
+ properties?: Record<string, string>;
120
+ };
121
+ export type NormalizedLink = {
122
+ id: string;
123
+ fromSocketId: string;
124
+ toSocketId: string;
125
+ };
126
+ export type NormalizedGraph = {
127
+ id: string;
128
+ label: string;
129
+ nodes: NormalizedNode[];
130
+ links: NormalizedLink[];
131
+ };
132
+ export declare function normalizeBlenderGraph(raw: BlenderTreeExport): NormalizedGraph;
133
+ export declare function toGraphIR(normalized: NormalizedGraph): GraphIR;
134
+ export {};
@@ -0,0 +1,22 @@
1
+ import { FloatCurvePoint } from './types';
2
+ type Vec2 = [number, number];
3
+ export type CurvePathResult = {
4
+ /** SVG 'd' attribute for the curve stroke */
5
+ strokePath: string;
6
+ /** SVG 'd' attribute for the filled area (curve + baseline) */
7
+ fillPath: string;
8
+ /** SVG 'd' attribute for the zero-line (y=0) */
9
+ zeroLinePath: string;
10
+ /** mapped control-point positions in SVG space for dot rendering */
11
+ dotPositions: Vec2[];
12
+ };
13
+ /**
14
+ * Build SVG path strings for a float curve.
15
+ *
16
+ * @param pts Ordered control points (sorted by X, as Blender stores them)
17
+ * @param clipMinX/Y Visible range in curve space
18
+ * @param clipMaxX/Y
19
+ * @param svgW/H Output SVG canvas dimensions
20
+ */
21
+ export declare function buildCurvePaths(pts: FloatCurvePoint[], clipMinX: number, clipMinY: number, clipMaxX: number, clipMaxY: number, svgW: number, svgH: number): CurvePathResult;
22
+ export {};
@@ -0,0 +1 @@
1
+ export declare function nodeHeaderColor(blIdname: string): string;
@@ -0,0 +1,2 @@
1
+ export declare const SOCKET_COLORS: Record<string, string>;
2
+ export declare function socketColor(dataType: string): string;
@@ -0,0 +1,64 @@
1
+ export type SocketDirection = 'input' | 'output';
2
+ export type FloatCurvePoint = {
3
+ location: [number, number];
4
+ handleType: string;
5
+ };
6
+ export type FloatCurveData = {
7
+ clipMinX: number;
8
+ clipMinY: number;
9
+ clipMaxX: number;
10
+ clipMaxY: number;
11
+ extend: string;
12
+ points: FloatCurvePoint[];
13
+ };
14
+ export type SocketDisplayShape = 'CIRCLE' | 'DIAMOND' | 'LINE' | 'LIST' | 'VOLUME_GRID';
15
+ export type SocketDefaultValue = {
16
+ kind: 'scalar';
17
+ value: number | boolean | string;
18
+ } | {
19
+ kind: 'vec';
20
+ values: number[];
21
+ };
22
+ export type SocketIR = {
23
+ id: string;
24
+ nodeId: string;
25
+ name: string;
26
+ direction: SocketDirection;
27
+ dataType: string;
28
+ displayShape: SocketDisplayShape;
29
+ color: string;
30
+ defaultValue: SocketDefaultValue | null;
31
+ hideValue: boolean;
32
+ enabled: boolean;
33
+ index: number;
34
+ };
35
+ export type NodeIR = {
36
+ id: string;
37
+ type: string;
38
+ label: string;
39
+ position: {
40
+ x: number;
41
+ y: number;
42
+ };
43
+ width: number;
44
+ headerColor: string;
45
+ inputs: SocketIR[];
46
+ outputs: SocketIR[];
47
+ floatCurve?: FloatCurveData;
48
+ /** Node-type-specific enum properties (e.g. operation, data_type for Compare) */
49
+ properties?: Record<string, string>;
50
+ };
51
+ export type EdgeIR = {
52
+ id: string;
53
+ sourceNodeId: string;
54
+ sourceSocketId: string;
55
+ targetNodeId: string;
56
+ targetSocketId: string;
57
+ color: string;
58
+ };
59
+ export type GraphIR = {
60
+ id: string;
61
+ label: string;
62
+ nodes: NodeIR[];
63
+ edges: EdgeIR[];
64
+ };
@@ -0,0 +1,25 @@
1
+ import { Edge, Node } from '@xyflow/react';
2
+ import { FloatCurveData, GraphIR, SocketIR } from '../ir/types';
3
+ export type GNFlowNodeData = {
4
+ label: string;
5
+ type: string;
6
+ width: number;
7
+ headerColor: string;
8
+ inputs: SocketIR[];
9
+ outputs: SocketIR[];
10
+ connectedInputIds: string[];
11
+ floatCurve?: FloatCurveData;
12
+ properties?: Record<string, string>;
13
+ };
14
+ export type GNRerouteNodeData = {
15
+ color: string;
16
+ inputSocketId: string;
17
+ outputSocketId: string;
18
+ };
19
+ export type SimulationZoneNodeData = {
20
+ label: string;
21
+ };
22
+ export declare function mapGraphIRToFlow(graph: GraphIR): {
23
+ nodes: Node[];
24
+ edges: Edge[];
25
+ };
@@ -0,0 +1,2 @@
1
+ /** Decode Tree Clipper asset data (optional "TreeClipper::" prefix + base64, optionally gzipped) to JSON string. */
2
+ export declare function decodeTreeClipperPayload(raw: string): Promise<string>;
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "geonodes-web-render",
3
+ "version": "0.1.0",
4
+ "description": "Browser-based viewer for Blender Geometry Nodes exported via Tree Clipper. Renders node trees as a read-only, Blender-styled graph.",
5
+ "type": "module",
6
+ "exports": {
7
+ "./embed": {
8
+ "import": "./dist/embed.js",
9
+ "types": "./dist/types/embed.d.ts"
10
+ }
11
+ },
12
+ "files": [
13
+ "dist"
14
+ ],
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/kolibril13/geonodes-web-render"
18
+ },
19
+ "license": "MIT",
20
+ "keywords": [
21
+ "blender",
22
+ "geometry-nodes",
23
+ "node-graph",
24
+ "tree-clipper",
25
+ "react-flow",
26
+ "visualization"
27
+ ],
28
+ "scripts": {
29
+ "dev": "vite",
30
+ "build": "tsc -b && vite build",
31
+ "build:lib": "vite build --config vite.lib.config.ts",
32
+ "lint": "eslint .",
33
+ "preview": "vite preview",
34
+ "prepublishOnly": "npm run build:lib"
35
+ },
36
+ "dependencies": {
37
+ "@codemirror/lang-json": "^6.0.2",
38
+ "@codemirror/state": "^6.6.0",
39
+ "@codemirror/theme-one-dark": "^6.1.3",
40
+ "@codemirror/view": "^6.40.0",
41
+ "@uiw/react-codemirror": "^4.25.8",
42
+ "@xyflow/react": "^12.10.1",
43
+ "react": "^18.0.0 || ^19.0.0",
44
+ "react-dom": "^18.0.0 || ^19.0.0"
45
+ },
46
+ "peerDependencies": {
47
+ "react": "^18.0.0 || ^19.0.0",
48
+ "react-dom": "^18.0.0 || ^19.0.0"
49
+ },
50
+ "devDependencies": {
51
+ "@babel/core": "^7.29.0",
52
+ "@eslint/js": "^9.39.4",
53
+ "@rolldown/plugin-babel": "^0.2.0",
54
+ "@types/babel__core": "^7.20.5",
55
+ "@types/node": "^24.12.0",
56
+ "@types/react": "^19.2.14",
57
+ "@types/react-dom": "^19.2.3",
58
+ "@vitejs/plugin-react": "^6.0.0",
59
+ "babel-plugin-react-compiler": "^1.0.0",
60
+ "eslint": "^9.39.4",
61
+ "eslint-plugin-react-hooks": "^7.0.1",
62
+ "eslint-plugin-react-refresh": "^0.5.2",
63
+ "globals": "^17.4.0",
64
+ "typescript": "~5.9.3",
65
+ "typescript-eslint": "^8.56.1",
66
+ "vite": "^8.0.0",
67
+ "vite-plugin-dts": "^4.5.4"
68
+ }
69
+ }