@quantumwake/kgraph 0.2.0 → 0.2.1
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/ism/index.cjs +15 -3
- package/dist/ism/index.cjs.map +1 -1
- package/dist/ism/index.d.cts +7 -1
- package/dist/ism/index.d.ts +7 -1
- package/dist/ism/index.js +16 -4
- package/dist/ism/index.js.map +1 -1
- package/package.json +1 -1
package/dist/ism/index.cjs
CHANGED
|
@@ -122,8 +122,19 @@ function CleanEdge({ sourceX, sourceY, targetX, targetY, sourcePosition, targetP
|
|
|
122
122
|
)
|
|
123
123
|
] });
|
|
124
124
|
}
|
|
125
|
-
function
|
|
126
|
-
|
|
125
|
+
function seedCollapsed(nodes) {
|
|
126
|
+
return new Set(nodes.filter((n) => n.data?.collapsed).map((n) => n.id));
|
|
127
|
+
}
|
|
128
|
+
function StudioGraph({ nodes, edges, onNodeClick, collapsible = true, selectedNodeId, className, style }) {
|
|
129
|
+
const [collapsed, setCollapsed] = react.useState(() => seedCollapsed(nodes));
|
|
130
|
+
const seedKey = react.useRef("");
|
|
131
|
+
react.useEffect(() => {
|
|
132
|
+
const key = nodes.map((n) => n.id).sort().join("\0");
|
|
133
|
+
if (key !== seedKey.current) {
|
|
134
|
+
seedKey.current = key;
|
|
135
|
+
setCollapsed(seedCollapsed(nodes));
|
|
136
|
+
}
|
|
137
|
+
}, [nodes]);
|
|
127
138
|
const toggleCollapse = react.useCallback((id) => {
|
|
128
139
|
setCollapsed((prev) => {
|
|
129
140
|
const next = new Set(prev);
|
|
@@ -139,6 +150,7 @@ function StudioGraph({ nodes, edges, onNodeClick, collapsible = true, className,
|
|
|
139
150
|
...n,
|
|
140
151
|
width: isCollapsed ? NODE_COLLAPSED : NODE_WIDTH,
|
|
141
152
|
height: isCollapsed ? NODE_COLLAPSED : NODE_HEIGHT,
|
|
153
|
+
selected: selectedNodeId != null && n.id === selectedNodeId,
|
|
142
154
|
data: {
|
|
143
155
|
...n.data,
|
|
144
156
|
collapsed: isCollapsed,
|
|
@@ -146,7 +158,7 @@ function StudioGraph({ nodes, edges, onNodeClick, collapsible = true, className,
|
|
|
146
158
|
}
|
|
147
159
|
};
|
|
148
160
|
}),
|
|
149
|
-
[nodes, collapsed, collapsible, toggleCollapse]
|
|
161
|
+
[nodes, collapsed, collapsible, toggleCollapse, selectedNodeId]
|
|
150
162
|
);
|
|
151
163
|
const nodeTypes = react.useMemo(() => {
|
|
152
164
|
const m = { state: StudioNode, processor: StudioNode };
|
package/dist/ism/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ism/nodes.tsx","../../src/ism/edges.tsx","../../src/ism/StudioGraph.tsx"],"names":["Database","Cpu","Shuffle","FunctionSquare","Plug","jsxs","jsx","Handle_default","Plus","Minus","getBezierPath","useState","useCallback","useMemo","KGraphCanvas_default"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { MouseEvent } from 'react';\nimport { Handle } from '../index';\nimport type { NodeComponentProps, HandleType, HandlePosition } from '../types';\nimport { Database, Cpu, Shuffle, FunctionSquare, Plug, Minus, Plus, type LucideIcon } from 'lucide-react';\n\n// Footprint matches the Alethic ISM studio so published/exported layouts align.\nexport const NODE_WIDTH = 208;\nexport const NODE_HEIGHT = 120;\nexport const NODE_COLLAPSED = 44;\n\nexport type StudioNodeKind = 'state' | 'processor' | 'transform' | 'function' | 'connector';\n\n// Display fields precomputed by the host and placed on node.data.\nexport interface StudioNodeData {\n kind?: StudioNodeKind;\n typeLabel?: string;\n title?: string;\n subtitle?: string;\n // Injected by StudioGraph for collapse support.\n collapsed?: boolean;\n onToggleCollapse?: () => void;\n [key: string]: unknown;\n}\n\n// Dark studio palette (self-contained — no consumer Tailwind tokens needed).\nconst KIND: Record<StudioNodeKind, { accent: string; glow: string; icon: LucideIcon }> = {\n state: { accent: '#34d399', glow: 'rgba(16,185,129,0.18)', icon: Database }, // emerald\n processor: { accent: '#fbbf24', glow: 'rgba(245,158,11,0.18)', icon: Cpu }, // amber\n transform: { accent: '#a78bfa', glow: 'rgba(139,92,246,0.18)', icon: Shuffle }, // violet\n function: { accent: '#38bdf8', glow: 'rgba(14,165,233,0.18)', icon: FunctionSquare }, // sky\n connector: { accent: '#94a3b8', glow: 'rgba(100,116,139,0.18)', icon: Plug }, // slate\n};\n\nexport function kindForNodeType(nodeType: string): StudioNodeKind {\n if (nodeType === 'state') return 'state';\n if (nodeType.includes('coalescer') || nodeType.includes('composite')) return 'transform';\n if (nodeType.startsWith('function')) return 'function';\n if (nodeType.startsWith('connector')) return 'connector';\n return 'processor';\n}\n\nconst PROCESSOR_LABELS: Record<string, string> = {\n processor_openai: 'OpenAI',\n processor_visual_openai: 'Vision',\n processor_anthropic: 'Anthropic',\n processor_google_ai: 'Google AI',\n processor_llama: 'Llama',\n processor_mistral: 'Mistral',\n processor_python: 'Python',\n processor_provider: 'Provider',\n processor_state_coalescer: 'Coalescer',\n processor_state_composite: 'Composite',\n function_datasource_sql: 'SQL Source',\n connector_source: 'Source',\n connector_sink: 'Sink',\n trainer: 'Trainer',\n processor: 'Processor',\n};\n\nexport function displayType(nodeType: string): string {\n if (PROCESSOR_LABELS[nodeType]) return PROCESSOR_LABELS[nodeType];\n const cleaned = nodeType.replace(/^processor_/, '').replace(/_/g, ' ');\n return cleaned.charAt(0).toUpperCase() + cleaned.slice(1);\n}\n\nconst HANDLES: { id: string; type: HandleType; position: HandlePosition }[] = [\n { id: 'target-1', type: 'target', position: 'top' },\n { id: 'target-2', type: 'target', position: 'left' },\n { id: 'target-3', type: 'target', position: 'right' },\n { id: 'target-4', type: 'target', position: 'bottom' },\n { id: 'source-1', type: 'source', position: 'top' },\n { id: 'source-2', type: 'source', position: 'left' },\n { id: 'source-3', type: 'source', position: 'right' },\n { id: 'source-4', type: 'source', position: 'bottom' },\n];\nconst hiddenHandle = { opacity: 0, width: 8, height: 8, pointerEvents: 'none' as const };\n\n/**\n * StudioNode — read-only kgraph node card in the Alethic ISM studio aesthetic\n * (gradient tinted by type, neon accent header, glowing border when selected).\n * Display fields come from node.data (StudioNodeData).\n */\nexport function StudioNode({ data, selected }: NodeComponentProps) {\n const d = data as StudioNodeData;\n const kind: StudioNodeKind = d.kind && d.kind in KIND ? d.kind : 'processor';\n const cfg = KIND[kind];\n const Icon = cfg.icon;\n const title = d.title || d.typeLabel || kind;\n\n const shellStyle = {\n backgroundImage: `linear-gradient(135deg, ${cfg.glow} 0%, #1e1e22 55%, #161618 100%)`,\n border: `1.5px solid ${selected ? cfg.accent : '#33333a'}`,\n boxShadow: selected ? `0 0 0 1px ${cfg.accent}, 0 0 18px ${cfg.glow}` : '0 1px 3px rgba(0,0,0,0.4)',\n };\n\n const toggle = (e: MouseEvent) => {\n e.stopPropagation();\n d.onToggleCollapse?.();\n };\n\n if (d.collapsed) {\n return (\n <div className=\"group relative flex items-center justify-center rounded-lg\" style={{ width: NODE_COLLAPSED, height: NODE_COLLAPSED, ...shellStyle }} title={`${d.typeLabel ?? ''} · ${title}`}>\n {HANDLES.map((h) => (\n <Handle key={`${h.type}-${h.position}`} id={h.id} type={h.type} position={h.position} style={hiddenHandle} />\n ))}\n <Icon className=\"h-5 w-5\" style={{ color: cfg.accent }} />\n <button\n onClick={toggle}\n title=\"Expand\"\n className=\"absolute right-0.5 top-0.5 hidden rounded p-0.5 text-slate-400 hover:bg-white/10 hover:text-slate-100 group-hover:block\"\n >\n <Plus className=\"h-3 w-3\" />\n </button>\n </div>\n );\n }\n\n return (\n <div className=\"group relative overflow-hidden rounded-lg\" style={{ width: NODE_WIDTH, height: NODE_HEIGHT, ...shellStyle }}>\n {HANDLES.map((h) => (\n <Handle key={`${h.type}-${h.position}`} id={h.id} type={h.type} position={h.position} style={hiddenHandle} />\n ))}\n\n <div className=\"flex items-center gap-2 px-3 py-2\" style={{ borderBottom: '1px solid rgba(255,255,255,0.06)' }}>\n <Icon className=\"h-4 w-4 flex-shrink-0\" style={{ color: cfg.accent }} />\n <span className=\"truncate text-[11px] font-semibold uppercase tracking-wide\" style={{ color: cfg.accent }}>\n {d.typeLabel}\n </span>\n {d.onToggleCollapse ? (\n <button onClick={toggle} title=\"Collapse\" className=\"ml-auto rounded p-0.5 text-slate-500 hover:bg-white/10 hover:text-slate-200\">\n <Minus className=\"h-3.5 w-3.5\" />\n </button>\n ) : null}\n </div>\n\n <div className=\"px-3 py-2\">\n <div className=\"truncate text-sm font-medium\" style={{ color: '#f1f5f9' }} title={title}>\n {title}\n </div>\n {d.subtitle ? (\n <div className=\"mt-0.5 truncate text-xs\" style={{ color: '#94a3b8' }}>\n {d.subtitle}\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n","import { getBezierPath } from '../index';\nimport type { EdgeComponentProps } from '../types';\n\n/**\n * CleanEdge — read-only kgraph edge for the dark studio (kgraph's default edge\n * is hardcoded purple). Dashed bezier that reads on a dark canvas, with an\n * arrowhead; brighter on hover/selection.\n */\nexport function CleanEdge({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, selected }: EdgeComponentProps) {\n const [d] = getBezierPath({ sourceX, sourceY, sourcePosition, targetX, targetY, targetPosition });\n const stroke = selected ? '#c4b5fd' : '#7c8499'; // violet-300 / slate\n return (\n <g>\n <defs>\n <marker id=\"kgraph-ism-arrow\" markerWidth=\"10\" markerHeight=\"10\" refX=\"7\" refY=\"3\" orient=\"auto\" markerUnits=\"strokeWidth\">\n <path d=\"M0,0 L6,3 L0,6 Z\" fill={stroke} />\n </marker>\n </defs>\n <path d={d} fill=\"none\" stroke=\"transparent\" strokeWidth={18} />\n <path\n d={d}\n fill=\"none\"\n stroke={stroke}\n strokeWidth={selected ? 2 : 1.5}\n strokeDasharray=\"6 3\"\n markerEnd=\"url(#kgraph-ism-arrow)\"\n />\n </g>\n );\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport type { CSSProperties } from 'react';\nimport { KGraphCanvas } from '../index';\nimport type { KGraphNode, KGraphEdge } from '../types';\nimport { StudioNode, NODE_WIDTH, NODE_HEIGHT, NODE_COLLAPSED } from './nodes';\nimport { CleanEdge } from './edges';\n\nexport interface StudioGraphProps {\n /** Pre-mapped kgraph nodes; node.data should carry StudioNodeData fields. */\n nodes: KGraphNode[];\n /** Pre-mapped kgraph edges. */\n edges: KGraphEdge[];\n /** Fired when a node is clicked. */\n onNodeClick?: (node: KGraphNode) => void;\n /** Allow per-node collapse (default true). */\n collapsible?: boolean;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * StudioGraph — a read-only kgraph canvas with the Alethic ISM studio look:\n * every node renders as StudioNode, every edge as CleanEdge, non-interactive\n * (no drag/connect), fit-to-view. Manages per-node collapse: collapsed nodes\n * shrink to an icon and their kgraph dimensions/edge anchors shrink with them.\n */\nexport function StudioGraph({ nodes, edges, onNodeClick, collapsible = true, className, style }: StudioGraphProps) {\n const [collapsed, setCollapsed] = useState<Set<string>>(() => new Set());\n\n const toggleCollapse = useCallback((id: string) => {\n setCollapsed((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n }, []);\n\n const renderNodes = useMemo<KGraphNode[]>(\n () =>\n nodes.map((n) => {\n const isCollapsed = collapsed.has(n.id);\n return {\n ...n,\n width: isCollapsed ? NODE_COLLAPSED : NODE_WIDTH,\n height: isCollapsed ? NODE_COLLAPSED : NODE_HEIGHT,\n data: {\n ...n.data,\n collapsed: isCollapsed,\n onToggleCollapse: collapsible ? () => toggleCollapse(n.id) : undefined,\n },\n };\n }),\n [nodes, collapsed, collapsible, toggleCollapse],\n );\n\n const nodeTypes = useMemo(() => {\n const m: Record<string, typeof StudioNode> = { state: StudioNode, processor: StudioNode };\n renderNodes.forEach((n) => {\n m[n.type] = StudioNode;\n });\n return m;\n }, [renderNodes]);\n\n const edgeTypes = useMemo(() => {\n const m: Record<string, typeof CleanEdge> = { default: CleanEdge };\n edges.forEach((e) => {\n if (e.type) m[e.type] = CleanEdge;\n });\n return m;\n }, [edges]);\n\n return (\n <KGraphCanvas\n nodes={renderNodes}\n edges={edges}\n nodeTypes={nodeTypes}\n edgeTypes={edgeTypes}\n nodesDraggable={false}\n nodesConnectable={false}\n elementsSelectable\n fitView\n showMiniMap={false}\n showBackground\n className={className}\n style={{ width: '100%', height: '100%', background: '#0e0e10', ...style }}\n onNodeClick={onNodeClick ? (_evt, node) => onNodeClick(node) : undefined}\n />\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/ism/nodes.tsx","../../src/ism/edges.tsx","../../src/ism/StudioGraph.tsx"],"names":["Database","Cpu","Shuffle","FunctionSquare","Plug","jsxs","jsx","Handle_default","Plus","Minus","getBezierPath","useState","useRef","useEffect","useCallback","useMemo","KGraphCanvas_default"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { MouseEvent } from 'react';\nimport { Handle } from '../index';\nimport type { NodeComponentProps, HandleType, HandlePosition } from '../types';\nimport { Database, Cpu, Shuffle, FunctionSquare, Plug, Minus, Plus, type LucideIcon } from 'lucide-react';\n\n// Footprint matches the Alethic ISM studio so published/exported layouts align.\nexport const NODE_WIDTH = 208;\nexport const NODE_HEIGHT = 120;\nexport const NODE_COLLAPSED = 44;\n\nexport type StudioNodeKind = 'state' | 'processor' | 'transform' | 'function' | 'connector';\n\n// Display fields precomputed by the host and placed on node.data.\nexport interface StudioNodeData {\n kind?: StudioNodeKind;\n typeLabel?: string;\n title?: string;\n subtitle?: string;\n // Injected by StudioGraph for collapse support.\n collapsed?: boolean;\n onToggleCollapse?: () => void;\n [key: string]: unknown;\n}\n\n// Dark studio palette (self-contained — no consumer Tailwind tokens needed).\nconst KIND: Record<StudioNodeKind, { accent: string; glow: string; icon: LucideIcon }> = {\n state: { accent: '#34d399', glow: 'rgba(16,185,129,0.18)', icon: Database }, // emerald\n processor: { accent: '#fbbf24', glow: 'rgba(245,158,11,0.18)', icon: Cpu }, // amber\n transform: { accent: '#a78bfa', glow: 'rgba(139,92,246,0.18)', icon: Shuffle }, // violet\n function: { accent: '#38bdf8', glow: 'rgba(14,165,233,0.18)', icon: FunctionSquare }, // sky\n connector: { accent: '#94a3b8', glow: 'rgba(100,116,139,0.18)', icon: Plug }, // slate\n};\n\nexport function kindForNodeType(nodeType: string): StudioNodeKind {\n if (nodeType === 'state') return 'state';\n if (nodeType.includes('coalescer') || nodeType.includes('composite')) return 'transform';\n if (nodeType.startsWith('function')) return 'function';\n if (nodeType.startsWith('connector')) return 'connector';\n return 'processor';\n}\n\nconst PROCESSOR_LABELS: Record<string, string> = {\n processor_openai: 'OpenAI',\n processor_visual_openai: 'Vision',\n processor_anthropic: 'Anthropic',\n processor_google_ai: 'Google AI',\n processor_llama: 'Llama',\n processor_mistral: 'Mistral',\n processor_python: 'Python',\n processor_provider: 'Provider',\n processor_state_coalescer: 'Coalescer',\n processor_state_composite: 'Composite',\n function_datasource_sql: 'SQL Source',\n connector_source: 'Source',\n connector_sink: 'Sink',\n trainer: 'Trainer',\n processor: 'Processor',\n};\n\nexport function displayType(nodeType: string): string {\n if (PROCESSOR_LABELS[nodeType]) return PROCESSOR_LABELS[nodeType];\n const cleaned = nodeType.replace(/^processor_/, '').replace(/_/g, ' ');\n return cleaned.charAt(0).toUpperCase() + cleaned.slice(1);\n}\n\nconst HANDLES: { id: string; type: HandleType; position: HandlePosition }[] = [\n { id: 'target-1', type: 'target', position: 'top' },\n { id: 'target-2', type: 'target', position: 'left' },\n { id: 'target-3', type: 'target', position: 'right' },\n { id: 'target-4', type: 'target', position: 'bottom' },\n { id: 'source-1', type: 'source', position: 'top' },\n { id: 'source-2', type: 'source', position: 'left' },\n { id: 'source-3', type: 'source', position: 'right' },\n { id: 'source-4', type: 'source', position: 'bottom' },\n];\nconst hiddenHandle = { opacity: 0, width: 8, height: 8, pointerEvents: 'none' as const };\n\n/**\n * StudioNode — read-only kgraph node card in the Alethic ISM studio aesthetic\n * (gradient tinted by type, neon accent header, glowing border when selected).\n * Display fields come from node.data (StudioNodeData).\n */\nexport function StudioNode({ data, selected }: NodeComponentProps) {\n const d = data as StudioNodeData;\n const kind: StudioNodeKind = d.kind && d.kind in KIND ? d.kind : 'processor';\n const cfg = KIND[kind];\n const Icon = cfg.icon;\n const title = d.title || d.typeLabel || kind;\n\n const shellStyle = {\n backgroundImage: `linear-gradient(135deg, ${cfg.glow} 0%, #1e1e22 55%, #161618 100%)`,\n border: `1.5px solid ${selected ? cfg.accent : '#33333a'}`,\n boxShadow: selected ? `0 0 0 1px ${cfg.accent}, 0 0 18px ${cfg.glow}` : '0 1px 3px rgba(0,0,0,0.4)',\n };\n\n const toggle = (e: MouseEvent) => {\n e.stopPropagation();\n d.onToggleCollapse?.();\n };\n\n if (d.collapsed) {\n return (\n <div className=\"group relative flex items-center justify-center rounded-lg\" style={{ width: NODE_COLLAPSED, height: NODE_COLLAPSED, ...shellStyle }} title={`${d.typeLabel ?? ''} · ${title}`}>\n {HANDLES.map((h) => (\n <Handle key={`${h.type}-${h.position}`} id={h.id} type={h.type} position={h.position} style={hiddenHandle} />\n ))}\n <Icon className=\"h-5 w-5\" style={{ color: cfg.accent }} />\n <button\n onClick={toggle}\n title=\"Expand\"\n className=\"absolute right-0.5 top-0.5 hidden rounded p-0.5 text-slate-400 hover:bg-white/10 hover:text-slate-100 group-hover:block\"\n >\n <Plus className=\"h-3 w-3\" />\n </button>\n </div>\n );\n }\n\n return (\n <div className=\"group relative overflow-hidden rounded-lg\" style={{ width: NODE_WIDTH, height: NODE_HEIGHT, ...shellStyle }}>\n {HANDLES.map((h) => (\n <Handle key={`${h.type}-${h.position}`} id={h.id} type={h.type} position={h.position} style={hiddenHandle} />\n ))}\n\n <div className=\"flex items-center gap-2 px-3 py-2\" style={{ borderBottom: '1px solid rgba(255,255,255,0.06)' }}>\n <Icon className=\"h-4 w-4 flex-shrink-0\" style={{ color: cfg.accent }} />\n <span className=\"truncate text-[11px] font-semibold uppercase tracking-wide\" style={{ color: cfg.accent }}>\n {d.typeLabel}\n </span>\n {d.onToggleCollapse ? (\n <button onClick={toggle} title=\"Collapse\" className=\"ml-auto rounded p-0.5 text-slate-500 hover:bg-white/10 hover:text-slate-200\">\n <Minus className=\"h-3.5 w-3.5\" />\n </button>\n ) : null}\n </div>\n\n <div className=\"px-3 py-2\">\n <div className=\"truncate text-sm font-medium\" style={{ color: '#f1f5f9' }} title={title}>\n {title}\n </div>\n {d.subtitle ? (\n <div className=\"mt-0.5 truncate text-xs\" style={{ color: '#94a3b8' }}>\n {d.subtitle}\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n","import { getBezierPath } from '../index';\nimport type { EdgeComponentProps } from '../types';\n\n/**\n * CleanEdge — read-only kgraph edge for the dark studio (kgraph's default edge\n * is hardcoded purple). Dashed bezier that reads on a dark canvas, with an\n * arrowhead; brighter on hover/selection.\n */\nexport function CleanEdge({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, selected }: EdgeComponentProps) {\n const [d] = getBezierPath({ sourceX, sourceY, sourcePosition, targetX, targetY, targetPosition });\n const stroke = selected ? '#c4b5fd' : '#7c8499'; // violet-300 / slate\n return (\n <g>\n <defs>\n <marker id=\"kgraph-ism-arrow\" markerWidth=\"10\" markerHeight=\"10\" refX=\"7\" refY=\"3\" orient=\"auto\" markerUnits=\"strokeWidth\">\n <path d=\"M0,0 L6,3 L0,6 Z\" fill={stroke} />\n </marker>\n </defs>\n <path d={d} fill=\"none\" stroke=\"transparent\" strokeWidth={18} />\n <path\n d={d}\n fill=\"none\"\n stroke={stroke}\n strokeWidth={selected ? 2 : 1.5}\n strokeDasharray=\"6 3\"\n markerEnd=\"url(#kgraph-ism-arrow)\"\n />\n </g>\n );\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type { CSSProperties } from 'react';\nimport { KGraphCanvas } from '../index';\nimport type { KGraphNode, KGraphEdge } from '../types';\nimport { StudioNode, NODE_WIDTH, NODE_HEIGHT, NODE_COLLAPSED } from './nodes';\nimport { CleanEdge } from './edges';\n\nexport interface StudioGraphProps {\n /** Pre-mapped kgraph nodes; node.data should carry StudioNodeData fields. */\n nodes: KGraphNode[];\n /** Pre-mapped kgraph edges. */\n edges: KGraphEdge[];\n /** Fired when a node is clicked. */\n onNodeClick?: (node: KGraphNode) => void;\n /** Allow per-node collapse (default true). */\n collapsible?: boolean;\n /**\n * Id of the node to render as selected (glowing accent border). Selection is\n * host-controlled — clicking a node reports via onNodeClick; the host decides\n * what is selected and passes it back here.\n */\n selectedNodeId?: string;\n className?: string;\n style?: CSSProperties;\n}\n\n/** Node ids whose data carries a truthy `collapsed` flag (seeded from the host). */\nfunction seedCollapsed(nodes: KGraphNode[]): Set<string> {\n return new Set(nodes.filter((n) => (n.data as { collapsed?: boolean })?.collapsed).map((n) => n.id));\n}\n\n/**\n * StudioGraph — a read-only kgraph canvas with the Alethic ISM studio look:\n * every node renders as StudioNode, every edge as CleanEdge, non-interactive\n * (no drag/connect), fit-to-view. Manages per-node collapse: collapsed nodes\n * shrink to an icon and their kgraph dimensions/edge anchors shrink with them.\n */\nexport function StudioGraph({ nodes, edges, onNodeClick, collapsible = true, selectedNodeId, className, style }: StudioGraphProps) {\n // Seed collapse from each node's data.collapsed (carried from the manifest);\n // the user can then toggle. Re-seed only when the node id set changes (a new\n // graph is loaded) so selection re-renders don't discard user toggles.\n const [collapsed, setCollapsed] = useState<Set<string>>(() => seedCollapsed(nodes));\n const seedKey = useRef<string>('');\n useEffect(() => {\n const key = nodes.map((n) => n.id).sort().join('\u0000');\n if (key !== seedKey.current) {\n seedKey.current = key;\n setCollapsed(seedCollapsed(nodes));\n }\n }, [nodes]);\n\n const toggleCollapse = useCallback((id: string) => {\n setCollapsed((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n }, []);\n\n const renderNodes = useMemo<KGraphNode[]>(\n () =>\n nodes.map((n) => {\n const isCollapsed = collapsed.has(n.id);\n return {\n ...n,\n width: isCollapsed ? NODE_COLLAPSED : NODE_WIDTH,\n height: isCollapsed ? NODE_COLLAPSED : NODE_HEIGHT,\n selected: selectedNodeId != null && n.id === selectedNodeId,\n data: {\n ...n.data,\n collapsed: isCollapsed,\n onToggleCollapse: collapsible ? () => toggleCollapse(n.id) : undefined,\n },\n };\n }),\n [nodes, collapsed, collapsible, toggleCollapse, selectedNodeId],\n );\n\n const nodeTypes = useMemo(() => {\n const m: Record<string, typeof StudioNode> = { state: StudioNode, processor: StudioNode };\n renderNodes.forEach((n) => {\n m[n.type] = StudioNode;\n });\n return m;\n }, [renderNodes]);\n\n const edgeTypes = useMemo(() => {\n const m: Record<string, typeof CleanEdge> = { default: CleanEdge };\n edges.forEach((e) => {\n if (e.type) m[e.type] = CleanEdge;\n });\n return m;\n }, [edges]);\n\n return (\n <KGraphCanvas\n nodes={renderNodes}\n edges={edges}\n nodeTypes={nodeTypes}\n edgeTypes={edgeTypes}\n nodesDraggable={false}\n nodesConnectable={false}\n elementsSelectable\n fitView\n showMiniMap={false}\n showBackground\n className={className}\n style={{ width: '100%', height: '100%', background: '#0e0e10', ...style }}\n onNodeClick={onNodeClick ? (_evt, node) => onNodeClick(node) : undefined}\n />\n );\n}\n"]}
|
package/dist/ism/index.d.cts
CHANGED
|
@@ -40,6 +40,12 @@ interface StudioGraphProps {
|
|
|
40
40
|
onNodeClick?: (node: KGraphNode) => void;
|
|
41
41
|
/** Allow per-node collapse (default true). */
|
|
42
42
|
collapsible?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Id of the node to render as selected (glowing accent border). Selection is
|
|
45
|
+
* host-controlled — clicking a node reports via onNodeClick; the host decides
|
|
46
|
+
* what is selected and passes it back here.
|
|
47
|
+
*/
|
|
48
|
+
selectedNodeId?: string;
|
|
43
49
|
className?: string;
|
|
44
50
|
style?: CSSProperties;
|
|
45
51
|
}
|
|
@@ -49,6 +55,6 @@ interface StudioGraphProps {
|
|
|
49
55
|
* (no drag/connect), fit-to-view. Manages per-node collapse: collapsed nodes
|
|
50
56
|
* shrink to an icon and their kgraph dimensions/edge anchors shrink with them.
|
|
51
57
|
*/
|
|
52
|
-
declare function StudioGraph({ nodes, edges, onNodeClick, collapsible, className, style }: StudioGraphProps): react_jsx_runtime.JSX.Element;
|
|
58
|
+
declare function StudioGraph({ nodes, edges, onNodeClick, collapsible, selectedNodeId, className, style }: StudioGraphProps): react_jsx_runtime.JSX.Element;
|
|
53
59
|
|
|
54
60
|
export { CleanEdge, NODE_COLLAPSED, NODE_HEIGHT, NODE_WIDTH, StudioGraph, type StudioGraphProps, StudioNode, type StudioNodeData, type StudioNodeKind, displayType, kindForNodeType };
|
package/dist/ism/index.d.ts
CHANGED
|
@@ -40,6 +40,12 @@ interface StudioGraphProps {
|
|
|
40
40
|
onNodeClick?: (node: KGraphNode) => void;
|
|
41
41
|
/** Allow per-node collapse (default true). */
|
|
42
42
|
collapsible?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Id of the node to render as selected (glowing accent border). Selection is
|
|
45
|
+
* host-controlled — clicking a node reports via onNodeClick; the host decides
|
|
46
|
+
* what is selected and passes it back here.
|
|
47
|
+
*/
|
|
48
|
+
selectedNodeId?: string;
|
|
43
49
|
className?: string;
|
|
44
50
|
style?: CSSProperties;
|
|
45
51
|
}
|
|
@@ -49,6 +55,6 @@ interface StudioGraphProps {
|
|
|
49
55
|
* (no drag/connect), fit-to-view. Manages per-node collapse: collapsed nodes
|
|
50
56
|
* shrink to an icon and their kgraph dimensions/edge anchors shrink with them.
|
|
51
57
|
*/
|
|
52
|
-
declare function StudioGraph({ nodes, edges, onNodeClick, collapsible, className, style }: StudioGraphProps): react_jsx_runtime.JSX.Element;
|
|
58
|
+
declare function StudioGraph({ nodes, edges, onNodeClick, collapsible, selectedNodeId, className, style }: StudioGraphProps): react_jsx_runtime.JSX.Element;
|
|
53
59
|
|
|
54
60
|
export { CleanEdge, NODE_COLLAPSED, NODE_HEIGHT, NODE_WIDTH, StudioGraph, type StudioGraphProps, StudioNode, type StudioNodeData, type StudioNodeKind, displayType, kindForNodeType };
|
package/dist/ism/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Handle_default, getBezierPath, KGraphCanvas_default } from '../chunk-374K6PXA.js';
|
|
2
2
|
import { Plug, FunctionSquare, Shuffle, Cpu, Database, Plus, Minus } from 'lucide-react';
|
|
3
3
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
|
-
import { useState, useCallback, useMemo } from 'react';
|
|
4
|
+
import { useState, useRef, useEffect, useCallback, useMemo } from 'react';
|
|
5
5
|
|
|
6
6
|
var NODE_WIDTH = 208;
|
|
7
7
|
var NODE_HEIGHT = 120;
|
|
@@ -120,8 +120,19 @@ function CleanEdge({ sourceX, sourceY, targetX, targetY, sourcePosition, targetP
|
|
|
120
120
|
)
|
|
121
121
|
] });
|
|
122
122
|
}
|
|
123
|
-
function
|
|
124
|
-
|
|
123
|
+
function seedCollapsed(nodes) {
|
|
124
|
+
return new Set(nodes.filter((n) => n.data?.collapsed).map((n) => n.id));
|
|
125
|
+
}
|
|
126
|
+
function StudioGraph({ nodes, edges, onNodeClick, collapsible = true, selectedNodeId, className, style }) {
|
|
127
|
+
const [collapsed, setCollapsed] = useState(() => seedCollapsed(nodes));
|
|
128
|
+
const seedKey = useRef("");
|
|
129
|
+
useEffect(() => {
|
|
130
|
+
const key = nodes.map((n) => n.id).sort().join("\0");
|
|
131
|
+
if (key !== seedKey.current) {
|
|
132
|
+
seedKey.current = key;
|
|
133
|
+
setCollapsed(seedCollapsed(nodes));
|
|
134
|
+
}
|
|
135
|
+
}, [nodes]);
|
|
125
136
|
const toggleCollapse = useCallback((id) => {
|
|
126
137
|
setCollapsed((prev) => {
|
|
127
138
|
const next = new Set(prev);
|
|
@@ -137,6 +148,7 @@ function StudioGraph({ nodes, edges, onNodeClick, collapsible = true, className,
|
|
|
137
148
|
...n,
|
|
138
149
|
width: isCollapsed ? NODE_COLLAPSED : NODE_WIDTH,
|
|
139
150
|
height: isCollapsed ? NODE_COLLAPSED : NODE_HEIGHT,
|
|
151
|
+
selected: selectedNodeId != null && n.id === selectedNodeId,
|
|
140
152
|
data: {
|
|
141
153
|
...n.data,
|
|
142
154
|
collapsed: isCollapsed,
|
|
@@ -144,7 +156,7 @@ function StudioGraph({ nodes, edges, onNodeClick, collapsible = true, className,
|
|
|
144
156
|
}
|
|
145
157
|
};
|
|
146
158
|
}),
|
|
147
|
-
[nodes, collapsed, collapsible, toggleCollapse]
|
|
159
|
+
[nodes, collapsed, collapsible, toggleCollapse, selectedNodeId]
|
|
148
160
|
);
|
|
149
161
|
const nodeTypes = useMemo(() => {
|
|
150
162
|
const m = { state: StudioNode, processor: StudioNode };
|
package/dist/ism/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ism/nodes.tsx","../../src/ism/edges.tsx","../../src/ism/StudioGraph.tsx"],"names":["jsxs","jsx"],"mappings":"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","file":"index.js","sourcesContent":["import type { MouseEvent } from 'react';\nimport { Handle } from '../index';\nimport type { NodeComponentProps, HandleType, HandlePosition } from '../types';\nimport { Database, Cpu, Shuffle, FunctionSquare, Plug, Minus, Plus, type LucideIcon } from 'lucide-react';\n\n// Footprint matches the Alethic ISM studio so published/exported layouts align.\nexport const NODE_WIDTH = 208;\nexport const NODE_HEIGHT = 120;\nexport const NODE_COLLAPSED = 44;\n\nexport type StudioNodeKind = 'state' | 'processor' | 'transform' | 'function' | 'connector';\n\n// Display fields precomputed by the host and placed on node.data.\nexport interface StudioNodeData {\n kind?: StudioNodeKind;\n typeLabel?: string;\n title?: string;\n subtitle?: string;\n // Injected by StudioGraph for collapse support.\n collapsed?: boolean;\n onToggleCollapse?: () => void;\n [key: string]: unknown;\n}\n\n// Dark studio palette (self-contained — no consumer Tailwind tokens needed).\nconst KIND: Record<StudioNodeKind, { accent: string; glow: string; icon: LucideIcon }> = {\n state: { accent: '#34d399', glow: 'rgba(16,185,129,0.18)', icon: Database }, // emerald\n processor: { accent: '#fbbf24', glow: 'rgba(245,158,11,0.18)', icon: Cpu }, // amber\n transform: { accent: '#a78bfa', glow: 'rgba(139,92,246,0.18)', icon: Shuffle }, // violet\n function: { accent: '#38bdf8', glow: 'rgba(14,165,233,0.18)', icon: FunctionSquare }, // sky\n connector: { accent: '#94a3b8', glow: 'rgba(100,116,139,0.18)', icon: Plug }, // slate\n};\n\nexport function kindForNodeType(nodeType: string): StudioNodeKind {\n if (nodeType === 'state') return 'state';\n if (nodeType.includes('coalescer') || nodeType.includes('composite')) return 'transform';\n if (nodeType.startsWith('function')) return 'function';\n if (nodeType.startsWith('connector')) return 'connector';\n return 'processor';\n}\n\nconst PROCESSOR_LABELS: Record<string, string> = {\n processor_openai: 'OpenAI',\n processor_visual_openai: 'Vision',\n processor_anthropic: 'Anthropic',\n processor_google_ai: 'Google AI',\n processor_llama: 'Llama',\n processor_mistral: 'Mistral',\n processor_python: 'Python',\n processor_provider: 'Provider',\n processor_state_coalescer: 'Coalescer',\n processor_state_composite: 'Composite',\n function_datasource_sql: 'SQL Source',\n connector_source: 'Source',\n connector_sink: 'Sink',\n trainer: 'Trainer',\n processor: 'Processor',\n};\n\nexport function displayType(nodeType: string): string {\n if (PROCESSOR_LABELS[nodeType]) return PROCESSOR_LABELS[nodeType];\n const cleaned = nodeType.replace(/^processor_/, '').replace(/_/g, ' ');\n return cleaned.charAt(0).toUpperCase() + cleaned.slice(1);\n}\n\nconst HANDLES: { id: string; type: HandleType; position: HandlePosition }[] = [\n { id: 'target-1', type: 'target', position: 'top' },\n { id: 'target-2', type: 'target', position: 'left' },\n { id: 'target-3', type: 'target', position: 'right' },\n { id: 'target-4', type: 'target', position: 'bottom' },\n { id: 'source-1', type: 'source', position: 'top' },\n { id: 'source-2', type: 'source', position: 'left' },\n { id: 'source-3', type: 'source', position: 'right' },\n { id: 'source-4', type: 'source', position: 'bottom' },\n];\nconst hiddenHandle = { opacity: 0, width: 8, height: 8, pointerEvents: 'none' as const };\n\n/**\n * StudioNode — read-only kgraph node card in the Alethic ISM studio aesthetic\n * (gradient tinted by type, neon accent header, glowing border when selected).\n * Display fields come from node.data (StudioNodeData).\n */\nexport function StudioNode({ data, selected }: NodeComponentProps) {\n const d = data as StudioNodeData;\n const kind: StudioNodeKind = d.kind && d.kind in KIND ? d.kind : 'processor';\n const cfg = KIND[kind];\n const Icon = cfg.icon;\n const title = d.title || d.typeLabel || kind;\n\n const shellStyle = {\n backgroundImage: `linear-gradient(135deg, ${cfg.glow} 0%, #1e1e22 55%, #161618 100%)`,\n border: `1.5px solid ${selected ? cfg.accent : '#33333a'}`,\n boxShadow: selected ? `0 0 0 1px ${cfg.accent}, 0 0 18px ${cfg.glow}` : '0 1px 3px rgba(0,0,0,0.4)',\n };\n\n const toggle = (e: MouseEvent) => {\n e.stopPropagation();\n d.onToggleCollapse?.();\n };\n\n if (d.collapsed) {\n return (\n <div className=\"group relative flex items-center justify-center rounded-lg\" style={{ width: NODE_COLLAPSED, height: NODE_COLLAPSED, ...shellStyle }} title={`${d.typeLabel ?? ''} · ${title}`}>\n {HANDLES.map((h) => (\n <Handle key={`${h.type}-${h.position}`} id={h.id} type={h.type} position={h.position} style={hiddenHandle} />\n ))}\n <Icon className=\"h-5 w-5\" style={{ color: cfg.accent }} />\n <button\n onClick={toggle}\n title=\"Expand\"\n className=\"absolute right-0.5 top-0.5 hidden rounded p-0.5 text-slate-400 hover:bg-white/10 hover:text-slate-100 group-hover:block\"\n >\n <Plus className=\"h-3 w-3\" />\n </button>\n </div>\n );\n }\n\n return (\n <div className=\"group relative overflow-hidden rounded-lg\" style={{ width: NODE_WIDTH, height: NODE_HEIGHT, ...shellStyle }}>\n {HANDLES.map((h) => (\n <Handle key={`${h.type}-${h.position}`} id={h.id} type={h.type} position={h.position} style={hiddenHandle} />\n ))}\n\n <div className=\"flex items-center gap-2 px-3 py-2\" style={{ borderBottom: '1px solid rgba(255,255,255,0.06)' }}>\n <Icon className=\"h-4 w-4 flex-shrink-0\" style={{ color: cfg.accent }} />\n <span className=\"truncate text-[11px] font-semibold uppercase tracking-wide\" style={{ color: cfg.accent }}>\n {d.typeLabel}\n </span>\n {d.onToggleCollapse ? (\n <button onClick={toggle} title=\"Collapse\" className=\"ml-auto rounded p-0.5 text-slate-500 hover:bg-white/10 hover:text-slate-200\">\n <Minus className=\"h-3.5 w-3.5\" />\n </button>\n ) : null}\n </div>\n\n <div className=\"px-3 py-2\">\n <div className=\"truncate text-sm font-medium\" style={{ color: '#f1f5f9' }} title={title}>\n {title}\n </div>\n {d.subtitle ? (\n <div className=\"mt-0.5 truncate text-xs\" style={{ color: '#94a3b8' }}>\n {d.subtitle}\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n","import { getBezierPath } from '../index';\nimport type { EdgeComponentProps } from '../types';\n\n/**\n * CleanEdge — read-only kgraph edge for the dark studio (kgraph's default edge\n * is hardcoded purple). Dashed bezier that reads on a dark canvas, with an\n * arrowhead; brighter on hover/selection.\n */\nexport function CleanEdge({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, selected }: EdgeComponentProps) {\n const [d] = getBezierPath({ sourceX, sourceY, sourcePosition, targetX, targetY, targetPosition });\n const stroke = selected ? '#c4b5fd' : '#7c8499'; // violet-300 / slate\n return (\n <g>\n <defs>\n <marker id=\"kgraph-ism-arrow\" markerWidth=\"10\" markerHeight=\"10\" refX=\"7\" refY=\"3\" orient=\"auto\" markerUnits=\"strokeWidth\">\n <path d=\"M0,0 L6,3 L0,6 Z\" fill={stroke} />\n </marker>\n </defs>\n <path d={d} fill=\"none\" stroke=\"transparent\" strokeWidth={18} />\n <path\n d={d}\n fill=\"none\"\n stroke={stroke}\n strokeWidth={selected ? 2 : 1.5}\n strokeDasharray=\"6 3\"\n markerEnd=\"url(#kgraph-ism-arrow)\"\n />\n </g>\n );\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport type { CSSProperties } from 'react';\nimport { KGraphCanvas } from '../index';\nimport type { KGraphNode, KGraphEdge } from '../types';\nimport { StudioNode, NODE_WIDTH, NODE_HEIGHT, NODE_COLLAPSED } from './nodes';\nimport { CleanEdge } from './edges';\n\nexport interface StudioGraphProps {\n /** Pre-mapped kgraph nodes; node.data should carry StudioNodeData fields. */\n nodes: KGraphNode[];\n /** Pre-mapped kgraph edges. */\n edges: KGraphEdge[];\n /** Fired when a node is clicked. */\n onNodeClick?: (node: KGraphNode) => void;\n /** Allow per-node collapse (default true). */\n collapsible?: boolean;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * StudioGraph — a read-only kgraph canvas with the Alethic ISM studio look:\n * every node renders as StudioNode, every edge as CleanEdge, non-interactive\n * (no drag/connect), fit-to-view. Manages per-node collapse: collapsed nodes\n * shrink to an icon and their kgraph dimensions/edge anchors shrink with them.\n */\nexport function StudioGraph({ nodes, edges, onNodeClick, collapsible = true, className, style }: StudioGraphProps) {\n const [collapsed, setCollapsed] = useState<Set<string>>(() => new Set());\n\n const toggleCollapse = useCallback((id: string) => {\n setCollapsed((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n }, []);\n\n const renderNodes = useMemo<KGraphNode[]>(\n () =>\n nodes.map((n) => {\n const isCollapsed = collapsed.has(n.id);\n return {\n ...n,\n width: isCollapsed ? NODE_COLLAPSED : NODE_WIDTH,\n height: isCollapsed ? NODE_COLLAPSED : NODE_HEIGHT,\n data: {\n ...n.data,\n collapsed: isCollapsed,\n onToggleCollapse: collapsible ? () => toggleCollapse(n.id) : undefined,\n },\n };\n }),\n [nodes, collapsed, collapsible, toggleCollapse],\n );\n\n const nodeTypes = useMemo(() => {\n const m: Record<string, typeof StudioNode> = { state: StudioNode, processor: StudioNode };\n renderNodes.forEach((n) => {\n m[n.type] = StudioNode;\n });\n return m;\n }, [renderNodes]);\n\n const edgeTypes = useMemo(() => {\n const m: Record<string, typeof CleanEdge> = { default: CleanEdge };\n edges.forEach((e) => {\n if (e.type) m[e.type] = CleanEdge;\n });\n return m;\n }, [edges]);\n\n return (\n <KGraphCanvas\n nodes={renderNodes}\n edges={edges}\n nodeTypes={nodeTypes}\n edgeTypes={edgeTypes}\n nodesDraggable={false}\n nodesConnectable={false}\n elementsSelectable\n fitView\n showMiniMap={false}\n showBackground\n className={className}\n style={{ width: '100%', height: '100%', background: '#0e0e10', ...style }}\n onNodeClick={onNodeClick ? (_evt, node) => onNodeClick(node) : undefined}\n />\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/ism/nodes.tsx","../../src/ism/edges.tsx","../../src/ism/StudioGraph.tsx"],"names":["jsxs","jsx"],"mappings":"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","file":"index.js","sourcesContent":["import type { MouseEvent } from 'react';\nimport { Handle } from '../index';\nimport type { NodeComponentProps, HandleType, HandlePosition } from '../types';\nimport { Database, Cpu, Shuffle, FunctionSquare, Plug, Minus, Plus, type LucideIcon } from 'lucide-react';\n\n// Footprint matches the Alethic ISM studio so published/exported layouts align.\nexport const NODE_WIDTH = 208;\nexport const NODE_HEIGHT = 120;\nexport const NODE_COLLAPSED = 44;\n\nexport type StudioNodeKind = 'state' | 'processor' | 'transform' | 'function' | 'connector';\n\n// Display fields precomputed by the host and placed on node.data.\nexport interface StudioNodeData {\n kind?: StudioNodeKind;\n typeLabel?: string;\n title?: string;\n subtitle?: string;\n // Injected by StudioGraph for collapse support.\n collapsed?: boolean;\n onToggleCollapse?: () => void;\n [key: string]: unknown;\n}\n\n// Dark studio palette (self-contained — no consumer Tailwind tokens needed).\nconst KIND: Record<StudioNodeKind, { accent: string; glow: string; icon: LucideIcon }> = {\n state: { accent: '#34d399', glow: 'rgba(16,185,129,0.18)', icon: Database }, // emerald\n processor: { accent: '#fbbf24', glow: 'rgba(245,158,11,0.18)', icon: Cpu }, // amber\n transform: { accent: '#a78bfa', glow: 'rgba(139,92,246,0.18)', icon: Shuffle }, // violet\n function: { accent: '#38bdf8', glow: 'rgba(14,165,233,0.18)', icon: FunctionSquare }, // sky\n connector: { accent: '#94a3b8', glow: 'rgba(100,116,139,0.18)', icon: Plug }, // slate\n};\n\nexport function kindForNodeType(nodeType: string): StudioNodeKind {\n if (nodeType === 'state') return 'state';\n if (nodeType.includes('coalescer') || nodeType.includes('composite')) return 'transform';\n if (nodeType.startsWith('function')) return 'function';\n if (nodeType.startsWith('connector')) return 'connector';\n return 'processor';\n}\n\nconst PROCESSOR_LABELS: Record<string, string> = {\n processor_openai: 'OpenAI',\n processor_visual_openai: 'Vision',\n processor_anthropic: 'Anthropic',\n processor_google_ai: 'Google AI',\n processor_llama: 'Llama',\n processor_mistral: 'Mistral',\n processor_python: 'Python',\n processor_provider: 'Provider',\n processor_state_coalescer: 'Coalescer',\n processor_state_composite: 'Composite',\n function_datasource_sql: 'SQL Source',\n connector_source: 'Source',\n connector_sink: 'Sink',\n trainer: 'Trainer',\n processor: 'Processor',\n};\n\nexport function displayType(nodeType: string): string {\n if (PROCESSOR_LABELS[nodeType]) return PROCESSOR_LABELS[nodeType];\n const cleaned = nodeType.replace(/^processor_/, '').replace(/_/g, ' ');\n return cleaned.charAt(0).toUpperCase() + cleaned.slice(1);\n}\n\nconst HANDLES: { id: string; type: HandleType; position: HandlePosition }[] = [\n { id: 'target-1', type: 'target', position: 'top' },\n { id: 'target-2', type: 'target', position: 'left' },\n { id: 'target-3', type: 'target', position: 'right' },\n { id: 'target-4', type: 'target', position: 'bottom' },\n { id: 'source-1', type: 'source', position: 'top' },\n { id: 'source-2', type: 'source', position: 'left' },\n { id: 'source-3', type: 'source', position: 'right' },\n { id: 'source-4', type: 'source', position: 'bottom' },\n];\nconst hiddenHandle = { opacity: 0, width: 8, height: 8, pointerEvents: 'none' as const };\n\n/**\n * StudioNode — read-only kgraph node card in the Alethic ISM studio aesthetic\n * (gradient tinted by type, neon accent header, glowing border when selected).\n * Display fields come from node.data (StudioNodeData).\n */\nexport function StudioNode({ data, selected }: NodeComponentProps) {\n const d = data as StudioNodeData;\n const kind: StudioNodeKind = d.kind && d.kind in KIND ? d.kind : 'processor';\n const cfg = KIND[kind];\n const Icon = cfg.icon;\n const title = d.title || d.typeLabel || kind;\n\n const shellStyle = {\n backgroundImage: `linear-gradient(135deg, ${cfg.glow} 0%, #1e1e22 55%, #161618 100%)`,\n border: `1.5px solid ${selected ? cfg.accent : '#33333a'}`,\n boxShadow: selected ? `0 0 0 1px ${cfg.accent}, 0 0 18px ${cfg.glow}` : '0 1px 3px rgba(0,0,0,0.4)',\n };\n\n const toggle = (e: MouseEvent) => {\n e.stopPropagation();\n d.onToggleCollapse?.();\n };\n\n if (d.collapsed) {\n return (\n <div className=\"group relative flex items-center justify-center rounded-lg\" style={{ width: NODE_COLLAPSED, height: NODE_COLLAPSED, ...shellStyle }} title={`${d.typeLabel ?? ''} · ${title}`}>\n {HANDLES.map((h) => (\n <Handle key={`${h.type}-${h.position}`} id={h.id} type={h.type} position={h.position} style={hiddenHandle} />\n ))}\n <Icon className=\"h-5 w-5\" style={{ color: cfg.accent }} />\n <button\n onClick={toggle}\n title=\"Expand\"\n className=\"absolute right-0.5 top-0.5 hidden rounded p-0.5 text-slate-400 hover:bg-white/10 hover:text-slate-100 group-hover:block\"\n >\n <Plus className=\"h-3 w-3\" />\n </button>\n </div>\n );\n }\n\n return (\n <div className=\"group relative overflow-hidden rounded-lg\" style={{ width: NODE_WIDTH, height: NODE_HEIGHT, ...shellStyle }}>\n {HANDLES.map((h) => (\n <Handle key={`${h.type}-${h.position}`} id={h.id} type={h.type} position={h.position} style={hiddenHandle} />\n ))}\n\n <div className=\"flex items-center gap-2 px-3 py-2\" style={{ borderBottom: '1px solid rgba(255,255,255,0.06)' }}>\n <Icon className=\"h-4 w-4 flex-shrink-0\" style={{ color: cfg.accent }} />\n <span className=\"truncate text-[11px] font-semibold uppercase tracking-wide\" style={{ color: cfg.accent }}>\n {d.typeLabel}\n </span>\n {d.onToggleCollapse ? (\n <button onClick={toggle} title=\"Collapse\" className=\"ml-auto rounded p-0.5 text-slate-500 hover:bg-white/10 hover:text-slate-200\">\n <Minus className=\"h-3.5 w-3.5\" />\n </button>\n ) : null}\n </div>\n\n <div className=\"px-3 py-2\">\n <div className=\"truncate text-sm font-medium\" style={{ color: '#f1f5f9' }} title={title}>\n {title}\n </div>\n {d.subtitle ? (\n <div className=\"mt-0.5 truncate text-xs\" style={{ color: '#94a3b8' }}>\n {d.subtitle}\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n","import { getBezierPath } from '../index';\nimport type { EdgeComponentProps } from '../types';\n\n/**\n * CleanEdge — read-only kgraph edge for the dark studio (kgraph's default edge\n * is hardcoded purple). Dashed bezier that reads on a dark canvas, with an\n * arrowhead; brighter on hover/selection.\n */\nexport function CleanEdge({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, selected }: EdgeComponentProps) {\n const [d] = getBezierPath({ sourceX, sourceY, sourcePosition, targetX, targetY, targetPosition });\n const stroke = selected ? '#c4b5fd' : '#7c8499'; // violet-300 / slate\n return (\n <g>\n <defs>\n <marker id=\"kgraph-ism-arrow\" markerWidth=\"10\" markerHeight=\"10\" refX=\"7\" refY=\"3\" orient=\"auto\" markerUnits=\"strokeWidth\">\n <path d=\"M0,0 L6,3 L0,6 Z\" fill={stroke} />\n </marker>\n </defs>\n <path d={d} fill=\"none\" stroke=\"transparent\" strokeWidth={18} />\n <path\n d={d}\n fill=\"none\"\n stroke={stroke}\n strokeWidth={selected ? 2 : 1.5}\n strokeDasharray=\"6 3\"\n markerEnd=\"url(#kgraph-ism-arrow)\"\n />\n </g>\n );\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type { CSSProperties } from 'react';\nimport { KGraphCanvas } from '../index';\nimport type { KGraphNode, KGraphEdge } from '../types';\nimport { StudioNode, NODE_WIDTH, NODE_HEIGHT, NODE_COLLAPSED } from './nodes';\nimport { CleanEdge } from './edges';\n\nexport interface StudioGraphProps {\n /** Pre-mapped kgraph nodes; node.data should carry StudioNodeData fields. */\n nodes: KGraphNode[];\n /** Pre-mapped kgraph edges. */\n edges: KGraphEdge[];\n /** Fired when a node is clicked. */\n onNodeClick?: (node: KGraphNode) => void;\n /** Allow per-node collapse (default true). */\n collapsible?: boolean;\n /**\n * Id of the node to render as selected (glowing accent border). Selection is\n * host-controlled — clicking a node reports via onNodeClick; the host decides\n * what is selected and passes it back here.\n */\n selectedNodeId?: string;\n className?: string;\n style?: CSSProperties;\n}\n\n/** Node ids whose data carries a truthy `collapsed` flag (seeded from the host). */\nfunction seedCollapsed(nodes: KGraphNode[]): Set<string> {\n return new Set(nodes.filter((n) => (n.data as { collapsed?: boolean })?.collapsed).map((n) => n.id));\n}\n\n/**\n * StudioGraph — a read-only kgraph canvas with the Alethic ISM studio look:\n * every node renders as StudioNode, every edge as CleanEdge, non-interactive\n * (no drag/connect), fit-to-view. Manages per-node collapse: collapsed nodes\n * shrink to an icon and their kgraph dimensions/edge anchors shrink with them.\n */\nexport function StudioGraph({ nodes, edges, onNodeClick, collapsible = true, selectedNodeId, className, style }: StudioGraphProps) {\n // Seed collapse from each node's data.collapsed (carried from the manifest);\n // the user can then toggle. Re-seed only when the node id set changes (a new\n // graph is loaded) so selection re-renders don't discard user toggles.\n const [collapsed, setCollapsed] = useState<Set<string>>(() => seedCollapsed(nodes));\n const seedKey = useRef<string>('');\n useEffect(() => {\n const key = nodes.map((n) => n.id).sort().join('\u0000');\n if (key !== seedKey.current) {\n seedKey.current = key;\n setCollapsed(seedCollapsed(nodes));\n }\n }, [nodes]);\n\n const toggleCollapse = useCallback((id: string) => {\n setCollapsed((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n }, []);\n\n const renderNodes = useMemo<KGraphNode[]>(\n () =>\n nodes.map((n) => {\n const isCollapsed = collapsed.has(n.id);\n return {\n ...n,\n width: isCollapsed ? NODE_COLLAPSED : NODE_WIDTH,\n height: isCollapsed ? NODE_COLLAPSED : NODE_HEIGHT,\n selected: selectedNodeId != null && n.id === selectedNodeId,\n data: {\n ...n.data,\n collapsed: isCollapsed,\n onToggleCollapse: collapsible ? () => toggleCollapse(n.id) : undefined,\n },\n };\n }),\n [nodes, collapsed, collapsible, toggleCollapse, selectedNodeId],\n );\n\n const nodeTypes = useMemo(() => {\n const m: Record<string, typeof StudioNode> = { state: StudioNode, processor: StudioNode };\n renderNodes.forEach((n) => {\n m[n.type] = StudioNode;\n });\n return m;\n }, [renderNodes]);\n\n const edgeTypes = useMemo(() => {\n const m: Record<string, typeof CleanEdge> = { default: CleanEdge };\n edges.forEach((e) => {\n if (e.type) m[e.type] = CleanEdge;\n });\n return m;\n }, [edges]);\n\n return (\n <KGraphCanvas\n nodes={renderNodes}\n edges={edges}\n nodeTypes={nodeTypes}\n edgeTypes={edgeTypes}\n nodesDraggable={false}\n nodesConnectable={false}\n elementsSelectable\n fitView\n showMiniMap={false}\n showBackground\n className={className}\n style={{ width: '100%', height: '100%', background: '#0e0e10', ...style }}\n onNodeClick={onNodeClick ? (_evt, node) => onNodeClick(node) : undefined}\n />\n );\n}\n"]}
|
package/package.json
CHANGED