@nbt-dev/components 0.0.5

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 (66) hide show
  1. package/LICENSE +177 -0
  2. package/README.md +10 -0
  3. package/TRADEMARKS.md +49 -0
  4. package/dist/chunk-3ZM6YOA4.js +704 -0
  5. package/dist/chunk-3ZM6YOA4.js.map +7 -0
  6. package/dist/chunk-7B2T5ZNG.js +467 -0
  7. package/dist/chunk-7B2T5ZNG.js.map +7 -0
  8. package/dist/chunk-S7VBQE6Y.js +636 -0
  9. package/dist/chunk-S7VBQE6Y.js.map +7 -0
  10. package/dist/chunk-UPEOXMLZ.js +625 -0
  11. package/dist/chunk-UPEOXMLZ.js.map +7 -0
  12. package/dist/core/auth.d.ts +13 -0
  13. package/dist/core/bulk-decoder.d.ts +13 -0
  14. package/dist/core/config.d.ts +10 -0
  15. package/dist/core/data-store.d.ts +20 -0
  16. package/dist/core/index.d.ts +9 -0
  17. package/dist/core/use-bulk-stream.d.ts +24 -0
  18. package/dist/core/use-cartridge-info.d.ts +14 -0
  19. package/dist/core/utils.d.ts +2 -0
  20. package/dist/editor/index.d.ts +7 -0
  21. package/dist/editor/index.js +16 -0
  22. package/dist/editor/index.js.map +7 -0
  23. package/dist/editor/lsp-client.d.ts +57 -0
  24. package/dist/editor/lsp-extensions.d.ts +4 -0
  25. package/dist/editor/nbt-editor.d.ts +13 -0
  26. package/dist/editor/nbt-language.d.ts +7 -0
  27. package/dist/generated/bulk-protocol.d.ts +36 -0
  28. package/dist/graph/diagram.d.ts +5 -0
  29. package/dist/graph/entity-graph-utils.d.ts +92 -0
  30. package/dist/graph/entity-node.d.ts +9 -0
  31. package/dist/graph/index.d.ts +5 -0
  32. package/dist/graph/index.js +19 -0
  33. package/dist/graph/index.js.map +7 -0
  34. package/dist/index.d.ts +4 -0
  35. package/dist/index.js +134 -0
  36. package/dist/index.js.map +7 -0
  37. package/dist/styles.css +2 -0
  38. package/dist/table/data-table.d.ts +9 -0
  39. package/dist/table/index.d.ts +3 -0
  40. package/dist/table/index.js +11 -0
  41. package/dist/table/index.js.map +7 -0
  42. package/dist/table/value-popover.d.ts +18 -0
  43. package/package.json +77 -0
  44. package/src/core/auth.ts +100 -0
  45. package/src/core/bulk-decoder.ts +178 -0
  46. package/src/core/config.tsx +39 -0
  47. package/src/core/data-store.ts +113 -0
  48. package/src/core/index.ts +34 -0
  49. package/src/core/use-bulk-stream.ts +412 -0
  50. package/src/core/use-cartridge-info.ts +100 -0
  51. package/src/core/utils.ts +6 -0
  52. package/src/editor/index.ts +13 -0
  53. package/src/editor/lsp-client.ts +227 -0
  54. package/src/editor/lsp-extensions.ts +191 -0
  55. package/src/editor/nbt-editor.tsx +142 -0
  56. package/src/editor/nbt-language.ts +151 -0
  57. package/src/generated/bulk-protocol.ts +63 -0
  58. package/src/graph/diagram.tsx +296 -0
  59. package/src/graph/entity-graph-utils.ts +423 -0
  60. package/src/graph/entity-node.tsx +122 -0
  61. package/src/graph/index.ts +19 -0
  62. package/src/index.ts +7 -0
  63. package/src/styles.css +94 -0
  64. package/src/table/data-table.tsx +274 -0
  65. package/src/table/index.ts +5 -0
  66. package/src/table/value-popover.tsx +230 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/graph/diagram.tsx", "../src/graph/entity-node.tsx", "../src/graph/entity-graph-utils.ts"],
4
+ "sourcesContent": ["import React from \"react\";\nimport {\n Background,\n BackgroundVariant,\n Controls,\n MarkerType,\n ReactFlow,\n ReactFlowProvider,\n useNodesInitialized,\n useReactFlow,\n type Edge,\n type Node,\n} from \"@xyflow/react\";\n// ReactFlow's stylesheet ships inlined in @nbt-dev/devtools/styles.css.\nimport { useDevToolsConfig } from \"../core/config\";\nimport { authHeaders } from \"../core/auth\";\nimport { useBulkRowCounts } from \"../core/use-bulk-stream\";\nimport type { BulkRegistry } from \"../core/use-cartridge-info\";\nimport { EntityNode } from \"./entity-node\";\nimport {\n buildEntityGraphModel,\n cartsFromContracts,\n entityGraphId,\n filterEntityGraphModel,\n type Contract,\n type EntityGraphModel,\n type EntityGraphNodeData,\n} from \"./entity-graph-utils\";\n\nconst nodeTypes = { entity: EntityNode };\n\n// Custom nodes are measured asynchronously after mount, so the `fitView` prop\n// fits to zero-size bounds on first paint (boxes end up off-screen). Refit once\n// nodes report measured dimensions, and again whenever the visible set changes.\nconst FitOnReady: React.FC<{ fitKey: string }> = ({ fitKey }) => {\n const initialized = useNodesInitialized();\n const { fitView } = useReactFlow();\n React.useEffect(() => {\n if (initialized) fitView({ padding: 0.25, duration: 200 });\n }, [initialized, fitKey, fitView]);\n return null;\n};\n\ntype EntityFlowEdge = Edge<Record<string, unknown>, \"smoothstep\"> & {\n pathOptions: { borderRadius: number; offset: number };\n};\n\nfunction useContracts() {\n const { apiBaseUrl } = useDevToolsConfig();\n const [contracts, setContracts] = React.useState<Contract[]>([]);\n const [loading, setLoading] = React.useState(true);\n const [error, setError] = React.useState<string | null>(null);\n\n React.useEffect(() => {\n const ac = new AbortController();\n let cancelled = false;\n (async () => {\n try {\n const r = await fetch(`${apiBaseUrl}/_console/contracts`, {\n signal: ac.signal,\n credentials: \"include\",\n headers: authHeaders(),\n });\n if (!r.ok) throw new Error(`HTTP ${r.status}`);\n const data = (await r.json()) as Contract[];\n if (!Array.isArray(data)) throw new Error(\"malformed contracts response\");\n if (!cancelled) setContracts(data);\n } catch (e) {\n if (cancelled || (e as { name?: string }).name === \"AbortError\") return;\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n if (!cancelled) setLoading(false);\n }\n })();\n return () => {\n cancelled = true;\n ac.abort();\n };\n }, [apiBaseUrl]);\n\n return { contracts, loading, error };\n}\n\n// Derive the bulk WS registry off the same contracts so live row counts work\n// through the shared socket (the provider preloads each entity's SCHEMA, which\n// carries totalRows). Mirrors buildRegistry in use-cartridge-info.\nfunction registryFromContracts(contracts: Contract[]): BulkRegistry {\n const reg: BulkRegistry = {};\n for (const c of contracts) {\n if (!c.cartridge || !c.owns) continue;\n const entities = Object.keys(c.owns).map((name) => ({\n name,\n route: `/_ws/bulk/${c.cartridge}/${name.toLowerCase()}`,\n searchFields: [] as string[],\n }));\n if (entities.length > 0) reg[c.cartridge] = entities;\n }\n return reg;\n}\n\n// Renders the entity graph. Must be mounted inside a <BulkStreamProvider> \u2014 it\n// reads live row counts off that shared socket's SCHEMA preload rather than\n// opening its own connection (the Data tab already provides one).\nexport const DiagramView: React.FC<{\n visibleIds: Set<string>;\n onSelectNode?: (cart: string, entity: string) => void;\n}> = ({ visibleIds, onSelectNode }) => {\n const { contracts, loading, error } = useContracts();\n\n const graph = React.useMemo(\n () => buildEntityGraphModel(cartsFromContracts(contracts)),\n [contracts],\n );\n const registry = React.useMemo(() => registryFromContracts(contracts), [contracts]);\n\n if (graph.nodes.length === 0) {\n let msg = \"No installed cartridges with entities.\";\n if (loading) msg = \"Loading entity graph\u2026\";\n else if (error) msg = `Failed to load contracts: ${error}`;\n return <div className=\"p-3 text-[12px] text-muted-foreground\">{msg}</div>;\n }\n\n return (\n <DiagramInner\n graph={graph}\n registry={registry}\n visibleIds={visibleIds}\n onSelectNode={onSelectNode}\n />\n );\n};\n\nconst DiagramInner: React.FC<{\n graph: EntityGraphModel;\n registry: BulkRegistry;\n visibleIds: Set<string>;\n onSelectNode?: (cart: string, entity: string) => void;\n}> = ({ graph, registry, visibleIds, onSelectNode }) => {\n const rowCounts = useBulkRowCounts(registry);\n const [focusedNodeId, setFocusedNodeId] = React.useState<string | null>(null);\n\n const visibleGraph = React.useMemo(\n () => filterEntityGraphModel(graph, visibleIds),\n [graph, visibleIds],\n );\n\n React.useEffect(() => {\n if (focusedNodeId && !visibleIds.has(focusedNodeId)) setFocusedNodeId(null);\n }, [focusedNodeId, visibleIds]);\n\n const focusedConnections = React.useMemo(() => {\n if (!focusedNodeId) {\n return {\n connectedIds: new Set<string>(),\n edgeIds: new Set<string>(),\n fieldsByNode: new Map<string, Set<string>>(),\n };\n }\n const connectedIds = new Set<string>([focusedNodeId]);\n const edgeIds = new Set<string>();\n const fieldsByNode = new Map<string, Set<string>>();\n const addField = (nodeId: string, fieldName: string) => {\n const fields = fieldsByNode.get(nodeId) ?? new Set<string>();\n fields.add(fieldName);\n fieldsByNode.set(nodeId, fields);\n };\n for (const edge of visibleGraph.edges) {\n if (edge.source !== focusedNodeId && edge.target !== focusedNodeId) continue;\n edgeIds.add(edge.id);\n connectedIds.add(edge.source);\n connectedIds.add(edge.target);\n addField(edge.source, edge.sourceField);\n addField(edge.target, edge.targetField);\n }\n return { connectedIds, edgeIds, fieldsByNode };\n }, [focusedNodeId, visibleGraph.edges]);\n\n const nodes: Node[] = React.useMemo(\n () =>\n visibleGraph.nodes.map((node) => ({\n id: node.id,\n type: \"entity\",\n position: node.position,\n data: {\n ...node,\n rowCount: rowCounts[node.id] ?? node.rowCount,\n highlight: focusedNodeId\n ? {\n focused: node.id === focusedNodeId,\n connected: focusedConnections.connectedIds.has(node.id) && node.id !== focusedNodeId,\n dimmed: !focusedConnections.connectedIds.has(node.id),\n fields: [...(focusedConnections.fieldsByNode.get(node.id) ?? [])],\n }\n : undefined,\n },\n })),\n [focusedConnections, focusedNodeId, visibleGraph.nodes, rowCounts],\n );\n\n const edges: EntityFlowEdge[] = React.useMemo(() => {\n const nodeById = new Map(visibleGraph.nodes.map((node) => [node.id, node]));\n const laneCounts = new Map<string, number>();\n return visibleGraph.edges.map((edge) => {\n const source = nodeById.get(edge.source);\n const target = nodeById.get(edge.target);\n const sourceSide = source && target && source.position.x > target.position.x ? \"left\" : \"right\";\n const targetSide = sourceSide === \"left\" ? \"right\" : \"left\";\n const laneKey = `${edge.target}:${edge.targetField}:${targetSide}`;\n const lane = laneCounts.get(laneKey) ?? 0;\n laneCounts.set(laneKey, lane + 1);\n const highlighted = !focusedNodeId || focusedConnections.edgeIds.has(edge.id);\n return {\n id: edge.id,\n source: edge.source,\n target: edge.target,\n sourceHandle: `source-${edge.sourceField}-${sourceSide}`,\n targetHandle: `target-${edge.targetField}-${targetSide}`,\n type: \"smoothstep\",\n pathOptions: { borderRadius: 8, offset: 22 + (lane % 5) * 12 },\n markerEnd: {\n type: MarkerType.ArrowClosed,\n color: highlighted ? \"#2563eb\" : \"#64748b\",\n },\n style: {\n strokeWidth: focusedNodeId && highlighted ? 2.5 : 1.5,\n stroke: highlighted ? \"#2563eb\" : \"#64748b\",\n opacity: highlighted ? 1 : 0.16,\n },\n };\n });\n }, [focusedConnections.edgeIds, focusedNodeId, visibleGraph.edges, visibleGraph.nodes]);\n\n const onNodeClick = React.useCallback(\n (_: unknown, node: Node) => {\n const data = node.data as EntityGraphNodeData;\n const nodeId = entityGraphId(data.cartridge, data.entity);\n setFocusedNodeId((prev) => (prev === nodeId ? null : nodeId));\n onSelectNode?.(data.cartridge, data.entity);\n },\n [onSelectNode],\n );\n\n // Right-click surfaces the same data panel (and suppresses the browser menu)\n // rather than toggling focus off; selecting also focuses the node.\n const onNodeContextMenu = React.useCallback(\n (e: React.MouseEvent, node: Node) => {\n e.preventDefault();\n const data = node.data as EntityGraphNodeData;\n setFocusedNodeId(entityGraphId(data.cartridge, data.entity));\n onSelectNode?.(data.cartridge, data.entity);\n },\n [onSelectNode],\n );\n\n const clearFocusedNode = React.useCallback(() => setFocusedNodeId(null), []);\n\n return (\n <div className=\"flex h-full min-h-0 w-full flex-col\">\n <div className=\"relative min-h-0 flex-1 bg-zinc-950\">\n {nodes.length === 0 ? (\n <div className=\"flex h-full items-center justify-center text-[12px] text-zinc-500\">\n No entities are visible.\n </div>\n ) : (\n <ReactFlowProvider>\n <ReactFlow\n colorMode=\"dark\"\n nodes={nodes}\n edges={edges}\n nodeTypes={nodeTypes}\n fitView\n fitViewOptions={{ padding: 0.2 }}\n minZoom={0.1}\n maxZoom={1.6}\n nodesDraggable={false}\n nodesConnectable={false}\n elementsSelectable\n panOnDrag\n zoomOnScroll\n zoomOnPinch\n selectionOnDrag={false}\n onNodeClick={onNodeClick}\n onNodeContextMenu={onNodeContextMenu}\n onPaneClick={clearFocusedNode}\n proOptions={{ hideAttribution: true }}\n >\n <FitOnReady fitKey={[...visibleIds].sort().join(\"|\")} />\n <Background variant={BackgroundVariant.Dots} gap={16} size={1} color=\"#3f3f46\" />\n <Controls showInteractive={false} />\n </ReactFlow>\n </ReactFlowProvider>\n )}\n </div>\n </div>\n );\n};\n", "import React from \"react\";\nimport { Handle, Position, type NodeProps } from \"@xyflow/react\";\nimport { Database, FileText, KeyRound, Link2 } from \"lucide-react\";\nimport type { EntityGraphNodeData } from \"./entity-graph-utils\";\n\nexport type EntityNodeHighlight = {\n focused: boolean;\n connected: boolean;\n dimmed: boolean;\n fields: string[];\n};\n\ntype EntityNodeViewData = EntityGraphNodeData & {\n highlight?: EntityNodeHighlight;\n};\n\n// Dark entity card. Colors are pinned (not theme tokens) so the card looks the\n// same regardless of where it mounts; it sits inside the dark devtools panel.\nexport function EntityNode({ data, selected }: NodeProps) {\n const node = data as EntityNodeViewData;\n const highlight = node.highlight;\n const highlightedFields = new Set(highlight?.fields ?? []);\n const hiddenHandleClass = \"!h-1 !w-1 !border-0 !bg-transparent !opacity-0\";\n return (\n <div\n className={[\n \"relative w-[260px] overflow-visible rounded-xl border bg-zinc-900 font-mono text-[11px] text-zinc-100 shadow-lg shadow-black/40 transition-opacity\",\n highlight?.focused\n ? \"border-blue-500 ring-2 ring-blue-500/30\"\n : highlight?.connected\n ? \"border-blue-400/60 ring-2 ring-blue-500/10\"\n : \"border-zinc-700\",\n highlight?.dimmed ? \"opacity-35\" : \"\",\n selected && !highlight?.focused ? \"ring-2 ring-zinc-100/10\" : \"\",\n ].join(\" \")}\n >\n <div className=\"rounded-t-xl border-b border-zinc-700 bg-zinc-800 px-3 py-2\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <Database className=\"h-3.5 w-3.5 shrink-0 text-zinc-400\" />\n <span className=\"min-w-0 flex-1 truncate text-[13px] font-semibold leading-none text-zinc-50\">\n {node.entity}\n </span>\n </div>\n <div className=\"mt-1 truncate text-[10px] text-zinc-500\">{node.cartridge}</div>\n </div>\n <div className=\"bg-zinc-900 py-1\">\n {node.fields.length === 0 ? (\n <div className=\"px-3 py-2 text-[10px] text-zinc-500\">No fields</div>\n ) : (\n node.fields.map((field) => {\n const type = `${field.type}${field.array ? \"[]\" : \"\"}${field.optional ? \"?\" : \"\"}`;\n const isId = field.displayName.toLowerCase() === \"id\";\n const isRelation = field.kind === \"relation\";\n const isDocument = field.kind === \"document\";\n const fieldHighlighted = highlightedFields.has(field.displayName);\n return (\n <div\n key={`${field.name}:${field.displayName}`}\n className={[\n \"relative grid min-h-[26px] grid-cols-[minmax(0,1fr)_auto] items-center gap-3 px-3 py-1 text-zinc-300\",\n fieldHighlighted ? \"bg-blue-500/15 text-blue-200\" : \"\",\n ].join(\" \")}\n >\n {isId ? (\n <>\n <Handle\n id={`target-${field.displayName}-left`}\n type=\"target\"\n position={Position.Left}\n className={`!left-0 ${hiddenHandleClass}`}\n style={{ top: \"50%\" }}\n />\n <Handle\n id={`target-${field.displayName}-right`}\n type=\"target\"\n position={Position.Right}\n className={`!right-0 ${hiddenHandleClass}`}\n style={{ top: \"50%\" }}\n />\n </>\n ) : null}\n {isRelation ? (\n <>\n <Handle\n id={`source-${field.displayName}-left`}\n type=\"source\"\n position={Position.Left}\n className={`!left-0 ${hiddenHandleClass}`}\n style={{ top: \"50%\" }}\n />\n <Handle\n id={`source-${field.displayName}-right`}\n type=\"source\"\n position={Position.Right}\n className={`!right-0 ${hiddenHandleClass}`}\n style={{ top: \"50%\" }}\n />\n </>\n ) : null}\n <span className=\"flex min-w-0 items-center gap-1.5\">\n {isId ? <KeyRound className=\"h-3 w-3 shrink-0 text-zinc-500\" /> : null}\n {isRelation ? (\n <Link2 className={[\"h-3 w-3 shrink-0\", fieldHighlighted ? \"text-blue-300\" : \"text-blue-400\"].join(\" \")} />\n ) : null}\n {isDocument ? <FileText className=\"h-3 w-3 shrink-0 text-zinc-500\" /> : null}\n <span className=\"truncate\">{field.displayName}</span>\n </span>\n <span className=\"max-w-[96px] truncate text-right text-zinc-500\">{type}</span>\n </div>\n );\n })\n )}\n </div>\n <div className=\"flex items-center justify-between gap-2 rounded-b-xl border-t border-zinc-700 bg-zinc-800 px-3 py-1.5 text-[10px] text-zinc-500\">\n <span className=\"tabular-nums\">{node.rowCount.toLocaleString()} rows</span>\n <span className=\"tabular-nums\">\n {node.relationCount} rel \u00B7 {node.scalarCount} scalar\n </span>\n </div>\n </div>\n );\n}\n", "// Entity-relationship graph model for the devtools Diagram tab. Ported from the\n// portal-ui entity-graph (apps/portal/.../systems/entity-graph) but fed off the\n// daemon's `/_console/contracts` directly instead of the portal BFF's\n// cartridges-in-use + resources endpoints. Contract fields use snake_case\n// relation keys (`target_cart`, `fk_field`, `relation_kind`); we normalize to\n// the camelCase model below in `cartsFromContracts`. Row counts are overlaid\n// live from the bulk-stream schema preload, not baked into the model here.\n//\n// Placement uses dagre (layered LR) \u2014 the portal's hand-rolled column stacker\n// sprawled here because the devtools shows every installed cart at once rather\n// than a project-scoped subset.\n\nimport dagre from \"@dagrejs/dagre\";\n\nexport type GraphInputField = {\n name: string;\n type: string;\n optional?: boolean;\n array?: boolean;\n kind?: string;\n target?: string;\n targetCart?: string;\n relationKind?: string;\n fkField?: string;\n};\n\nexport type GraphInputEntity = {\n name: string;\n fields: GraphInputField[];\n};\n\nexport type GraphInputCart = {\n name: string;\n entities: GraphInputEntity[];\n};\n\nexport type EntityGraphField = {\n name: string;\n displayName: string;\n type: string;\n kind: string;\n optional: boolean;\n array: boolean;\n target?: string;\n targetCart?: string;\n relationKind?: string;\n fkField?: string;\n implicit?: boolean;\n};\n\nexport type EntityGraphNodeData = {\n id: string;\n cartridge: string;\n entity: string;\n fields: EntityGraphField[];\n fieldCount: number;\n scalarCount: number;\n relationCount: number;\n documentCount: number;\n rowCount: number;\n};\n\nexport type EntityGraphNode = EntityGraphNodeData & {\n position: { x: number; y: number };\n};\n\nexport type EntityGraphEdge = {\n id: string;\n source: string;\n target: string;\n sourceField: string;\n targetField: string;\n label: string;\n relationKind?: string;\n fkField?: string;\n};\n\nexport type EntityGraphTotals = {\n entities: number;\n relationships: number;\n rows: number;\n};\n\nexport type EntityGraphModel = {\n nodes: EntityGraphNode[];\n edges: EntityGraphEdge[];\n totals: EntityGraphTotals;\n};\n\nconst NODE_WIDTH = 260;\nconst MIN_NODE_HEIGHT = 150;\nconst FIELD_ROW_HEIGHT = 26;\nconst COLUMN_WIDTH = 390; // initial pre-layout spread; dagre overrides positions\n\n// Raw contract shapes (subset). `/_console/contracts` returns one object per\n// running cart with an `owns` map of entity -> { fields, ... }.\ntype ContractField = {\n name: string;\n type: string;\n optional?: boolean;\n array?: boolean;\n kind?: string;\n target?: string;\n target_cart?: string;\n relation_kind?: string;\n fk_field?: string;\n};\ntype ContractEntity = { fields?: ContractField[] };\nexport type Contract = {\n cartridge?: string;\n owns?: Record<string, ContractEntity>;\n};\n\nexport function cartsFromContracts(contracts: Contract[]): GraphInputCart[] {\n const carts: GraphInputCart[] = [];\n for (const c of contracts) {\n if (!c.cartridge || !c.owns) continue;\n const entities: GraphInputEntity[] = [];\n for (const [name, ent] of Object.entries(c.owns)) {\n const fields: GraphInputField[] = (ent.fields ?? []).map((f) => ({\n name: f.name,\n type: f.type,\n optional: f.optional,\n array: f.array,\n kind: f.kind,\n target: f.target,\n targetCart: f.target_cart,\n relationKind: f.relation_kind,\n fkField: f.fk_field,\n }));\n entities.push({ name, fields });\n }\n if (entities.length > 0) carts.push({ name: c.cartridge, entities });\n }\n return carts;\n}\n\nexport function entityGraphId(cartridge: string, entity: string): string {\n return `${cartridge}:${entity}`;\n}\n\nfunction fieldKind(field: GraphInputField): string {\n return field.kind ?? (field.target ? \"relation\" : \"scalar\");\n}\n\nfunction graphField(field: GraphInputField): EntityGraphField {\n const kind = fieldKind(field);\n return {\n name: field.name,\n displayName: kind === \"relation\" ? (field.fkField ?? field.name) : field.name,\n type: kind === \"relation\" && field.target ? field.target : field.type,\n kind,\n optional: field.optional === true,\n array: field.array === true,\n target: field.target,\n targetCart: field.targetCart,\n relationKind: field.relationKind,\n fkField: field.fkField,\n };\n}\n\nfunction makeGraphFields(fields: GraphInputField[]): EntityGraphField[] {\n const out = fields.map(graphField);\n if (!out.some((field) => field.displayName.toLowerCase() === \"id\")) {\n out.unshift({\n name: \"id\",\n displayName: \"id\",\n type: \"id\",\n kind: \"scalar\",\n optional: false,\n array: false,\n implicit: true,\n });\n }\n return out;\n}\n\nfunction normalizeName(value: string): string {\n return value.replace(/[^a-zA-Z0-9]/g, \"\").toLowerCase();\n}\n\nfunction words(value: string): string[] {\n return value\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .split(/[^a-zA-Z0-9]+/)\n .map((part) => part.toLowerCase())\n .filter(Boolean);\n}\n\nfunction entityAliases(entity: string): string[] {\n const parts = words(entity);\n const aliases = new Set<string>([normalizeName(entity)]);\n const last = parts.length > 0 ? parts[parts.length - 1] : undefined;\n if (last) aliases.add(last);\n if (parts.length > 1 && last) {\n aliases.add(`${parts.slice(0, -1).map((part) => part[0]).join(\"\")}${last}`);\n aliases.add(parts.map((part) => part[0]).join(\"\"));\n }\n return [...aliases].filter((alias) => alias.length >= 2);\n}\n\nfunction inferTargetNode(fieldName: string, nodes: EntityGraphNode[]): EntityGraphNode | null {\n if (!/id$/i.test(fieldName) || /^id$/i.test(fieldName)) return null;\n const base = normalizeName(fieldName.replace(/id$/i, \"\"));\n if (base.length < 3) return null;\n\n const candidates = nodes\n .flatMap((node) =>\n entityAliases(node.entity).map((alias) => {\n const exact = base === alias;\n const suffix = !exact && alias.length >= 4 && base.endsWith(alias);\n if (!exact && !suffix) return null;\n return {\n node,\n score: (exact ? 1000 : 500) + alias.length,\n };\n }),\n )\n .filter((candidate): candidate is { node: EntityGraphNode; score: number } => candidate !== null)\n .sort((a, b) => b.score - a.score || a.node.entity.localeCompare(b.node.entity));\n\n const first = candidates[0];\n if (!first) return null;\n const second = candidates[1];\n if (second && first.score === second.score) return null;\n return first.node;\n}\n\nfunction markRelationField(node: EntityGraphNode | undefined, fieldName: string, target: EntityGraphNode) {\n const field = node?.fields.find(\n (candidate) => candidate.displayName === fieldName || candidate.name === fieldName,\n );\n if (!field || field.displayName.toLowerCase() === \"id\") return;\n field.kind = \"relation\";\n field.target = target.entity;\n field.targetCart = target.cartridge;\n field.relationKind ??= \"inferred\";\n field.fkField ??= fieldName;\n}\n\nfunction recomputeNodeCounts(nodes: EntityGraphNode[]) {\n for (const node of nodes) {\n node.scalarCount = node.fields.filter((field) => field.kind === \"scalar\").length;\n node.relationCount = node.fields.filter((field) => field.kind === \"relation\").length;\n node.documentCount = node.fields.filter((field) => field.kind === \"document\").length;\n }\n}\n\nfunction nodeHeight(node: EntityGraphNode): number {\n return Math.max(MIN_NODE_HEIGHT, 74 + node.fields.length * FIELD_ROW_HEIGHT);\n}\n\n// Layered left-to-right placement via dagre. Connected components get clean\n// ranks with minimized crossings; isolated nodes (no edges) are gathered into a\n// trailing grid so they don't inflate dagre's ranks.\nfunction layoutNodes(nodes: EntityGraphNode[], edges: EntityGraphEdge[]) {\n const degree = new Map(nodes.map((n) => [n.id, 0]));\n for (const edge of edges) {\n degree.set(edge.source, (degree.get(edge.source) ?? 0) + 1);\n degree.set(edge.target, (degree.get(edge.target) ?? 0) + 1);\n }\n\n const connected = nodes.filter((n) => (degree.get(n.id) ?? 0) > 0);\n const isolated = nodes.filter((n) => (degree.get(n.id) ?? 0) === 0);\n const connectedIds = new Set(connected.map((n) => n.id));\n\n let maxX = 0;\n let maxY = 0;\n\n if (connected.length > 0) {\n const g = new dagre.graphlib.Graph();\n g.setGraph({ rankdir: \"LR\", ranksep: 160, nodesep: 48, marginx: 40, marginy: 40 });\n g.setDefaultEdgeLabel(() => ({}));\n for (const node of connected) {\n g.setNode(node.id, { width: NODE_WIDTH, height: nodeHeight(node) });\n }\n for (const edge of edges) {\n // dagre can't rank self-loops; the edge still renders (handle picks the\n // same node's left+right). Cross-component edges are all kept.\n if (edge.source === edge.target) continue;\n if (!connectedIds.has(edge.source) || !connectedIds.has(edge.target)) continue;\n g.setEdge(edge.source, edge.target);\n }\n dagre.layout(g);\n for (const node of connected) {\n const p = g.node(node.id);\n const h = nodeHeight(node);\n node.position = { x: p.x - NODE_WIDTH / 2, y: p.y - h / 2 };\n maxX = Math.max(maxX, node.position.x + NODE_WIDTH);\n maxY = Math.max(maxY, node.position.y + h);\n }\n }\n\n // Isolated nodes: a tidy grid to the right of the laid-out graph.\n if (isolated.length > 0) {\n isolated.sort((a, b) => a.entity.localeCompare(b.entity));\n const startX = connected.length > 0 ? maxX + COLUMN_WIDTH : 0;\n const perColumn = Math.max(1, Math.ceil(isolated.length / Math.ceil(isolated.length / 6)));\n let x = startX;\n let y = 0;\n let inColumn = 0;\n for (const node of isolated) {\n node.position = { x, y };\n y += nodeHeight(node) + 48;\n inColumn += 1;\n if (inColumn >= perColumn) {\n inColumn = 0;\n y = 0;\n x += COLUMN_WIDTH;\n }\n }\n }\n}\n\nfunction makeTotals(nodes: EntityGraphNode[], edges: EntityGraphEdge[]): EntityGraphTotals {\n return {\n entities: nodes.length,\n relationships: edges.length,\n rows: nodes.reduce((sum, node) => sum + node.rowCount, 0),\n };\n}\n\nexport function buildEntityGraphModel(cartridges: GraphInputCart[]): EntityGraphModel {\n const sortedCarts = [...cartridges].sort((a, b) => a.name.localeCompare(b.name));\n const nodes: EntityGraphNode[] = [];\n\n sortedCarts.forEach((cart, cartIndex) => {\n const entities = [...cart.entities].sort((a, b) => a.name.localeCompare(b.name));\n let y = 0;\n entities.forEach((entity) => {\n const id = entityGraphId(cart.name, entity.name);\n const fields = entity.fields ?? [];\n const graphFields = makeGraphFields(fields);\n nodes.push({\n id,\n cartridge: cart.name,\n entity: entity.name,\n fields: graphFields,\n fieldCount: graphFields.length,\n scalarCount: graphFields.filter((field) => field.kind === \"scalar\").length,\n relationCount: graphFields.filter((field) => field.kind === \"relation\").length,\n documentCount: graphFields.filter((field) => field.kind === \"document\").length,\n rowCount: 0,\n position: { x: cartIndex * COLUMN_WIDTH, y },\n });\n y += Math.max(MIN_NODE_HEIGHT, 74 + graphFields.length * FIELD_ROW_HEIGHT) + 56;\n });\n });\n\n const nodeIds = new Set(nodes.map((node) => node.id));\n const nodeById = new Map(nodes.map((node) => [node.id, node]));\n const edges: EntityGraphEdge[] = [];\n const edgeKeys = new Set<string>();\n for (const cart of sortedCarts) {\n for (const entity of cart.entities) {\n const source = entityGraphId(cart.name, entity.name);\n const sourceNode = nodeById.get(source);\n for (const field of entity.fields ?? []) {\n const explicitRelation = fieldKind(field) === \"relation\" && !!field.target;\n const inferredTargetNode = explicitRelation ? null : inferTargetNode(field.name, nodes);\n if (!explicitRelation && !inferredTargetNode) continue;\n\n const targetCart = explicitRelation\n ? field.targetCart ?? cart.name\n : inferredTargetNode?.cartridge;\n const targetEntity = explicitRelation ? field.target : inferredTargetNode?.entity;\n if (!targetCart || !targetEntity) continue;\n const target = entityGraphId(targetCart, targetEntity);\n if (!nodeIds.has(source) || !nodeIds.has(target)) continue;\n const targetNode = nodeById.get(target);\n const idField = targetNode?.fields.find((candidate) => candidate.displayName.toLowerCase() === \"id\");\n const targetField = idField?.displayName ?? \"__entity\";\n const sourceGraphField = sourceNode?.fields.find(\n (candidate) => candidate.name === field.name || candidate.displayName === field.name,\n );\n const sourceField = sourceGraphField?.displayName ?? field.fkField ?? field.name;\n const edgeKey = `${source}:${sourceField}->${target}:${targetField}`;\n if (edgeKeys.has(edgeKey)) continue;\n edgeKeys.add(edgeKey);\n if (!explicitRelation && targetNode) markRelationField(sourceNode, sourceField, targetNode);\n edges.push({\n id: `${source}:${field.name}->${target}`,\n source,\n target,\n sourceField,\n targetField,\n label: field.name,\n relationKind: field.relationKind ?? (!explicitRelation ? \"inferred\" : undefined),\n fkField: field.fkField ?? (!explicitRelation ? field.name : undefined),\n });\n }\n }\n }\n\n recomputeNodeCounts(nodes);\n\n return {\n nodes,\n edges,\n totals: makeTotals(nodes, edges),\n };\n}\n\n// Filter to the visible set and re-run layout over exactly those nodes/edges, so\n// toggling entities re-fits the graph rather than leaving stale full-graph gaps.\n// Nodes are cloned before layout mutates their `position`, keeping the cached base\n// model untouched.\nexport function filterEntityGraphModel(\n model: EntityGraphModel,\n visibleIds: Set<string>,\n): EntityGraphModel {\n const nodes = model.nodes\n .filter((node) => visibleIds.has(node.id))\n .map((node) => ({ ...node, position: { ...node.position } }));\n const ids = new Set(nodes.map((node) => node.id));\n const edges = model.edges.filter((edge) => ids.has(edge.source) && ids.has(edge.target));\n layoutNodes(nodes, edges);\n return {\n nodes,\n edges,\n totals: makeTotals(nodes, edges),\n };\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["jsx", "jsxs"]
7
+ }
@@ -0,0 +1,13 @@
1
+ export declare function getDevToolsToken(): string | null;
2
+ export declare function setDevToolsToken(token: string): void;
3
+ export declare function clearDevToolsToken(): void;
4
+ export declare function authHeaders(base?: Record<string, string>): Record<string, string>;
5
+ export type WhoAmI = {
6
+ configured: boolean;
7
+ authenticated: boolean;
8
+ isAdmin: boolean;
9
+ };
10
+ export declare function fetchWhoAmI(apiBaseUrl: string, signal?: AbortSignal): Promise<WhoAmI>;
11
+ export declare function devToolsSignIn(apiBaseUrl: string, email: string, password: string): Promise<void>;
12
+ export declare function devToolsSignOut(): void;
13
+ export declare function wsAuthProtocols(name: string): string[];
@@ -0,0 +1,13 @@
1
+ import { type ColumnDef, type SchemaFrame, type DeltaFrame } from "../generated/bulk-protocol";
2
+ export declare function getFrameType(buf: ArrayBuffer): number;
3
+ export declare function getFrameSid(buf: ArrayBuffer): number;
4
+ export declare function parseSchema(buf: ArrayBuffer): SchemaFrame;
5
+ export declare function parseDataChunk(buf: ArrayBuffer, columns: ColumnDef[]): string[][];
6
+ export declare function parseDelta(buf: ArrayBuffer, columns: ColumnDef[]): DeltaFrame;
7
+ export declare function parseError(buf: ArrayBuffer): string;
8
+ export declare function encodeStreamCmd(sid: number, cart: string, entity: string, opts?: {
9
+ sort?: string;
10
+ sort_desc?: boolean;
11
+ filters?: Record<string, string>;
12
+ }): string;
13
+ export declare function encodeUnsubCmd(sid: number): string;
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ export type DevToolsConfig = {
3
+ apiBaseUrl: string;
4
+ };
5
+ export declare const DevToolsConfigProvider: React.FC<{
6
+ apiBaseUrl?: string;
7
+ children: React.ReactNode;
8
+ }>;
9
+ export declare function useDevToolsConfig(): DevToolsConfig;
10
+ export declare function wsBaseFrom(apiBaseUrl: string): string;
@@ -0,0 +1,20 @@
1
+ import { type ColumnDef, type SchemaFrame, type DeltaFrame } from "../generated/bulk-protocol";
2
+ export declare class BulkDataStore {
3
+ columns: ColumnDef[];
4
+ rows: string[][];
5
+ totalRows: number;
6
+ searchActive: boolean;
7
+ private _fullRows;
8
+ private _fullTotalRows;
9
+ private _idColIndex;
10
+ private _query;
11
+ applySchema(schema: SchemaFrame): void;
12
+ appendChunk(chunk: string[][]): void;
13
+ applyDelta(delta: DeltaFrame): void;
14
+ search(query: string): void;
15
+ exitSearch(): void;
16
+ getRowCount(): number;
17
+ private _findRowById;
18
+ private _findRowByIdStr;
19
+ private _applySearch;
20
+ }
@@ -0,0 +1,9 @@
1
+ export { DevToolsConfigProvider, useDevToolsConfig, wsBaseFrom, } from "./config";
2
+ export type { DevToolsConfig } from "./config";
3
+ export { cn } from "./utils";
4
+ export { BulkStreamProvider, useBulkSubscription, useBulkRowCounts, } from "./use-bulk-stream";
5
+ export type { BulkSubscription } from "./use-bulk-stream";
6
+ export { useLiveBulkRegistry } from "./use-cartridge-info";
7
+ export type { BulkEntity, BulkRegistry, LiveRegistryState, } from "./use-cartridge-info";
8
+ export { getDevToolsToken, setDevToolsToken, clearDevToolsToken, authHeaders, fetchWhoAmI, devToolsSignIn, devToolsSignOut, wsAuthProtocols, } from "./auth";
9
+ export type { WhoAmI } from "./auth";
@@ -0,0 +1,24 @@
1
+ import React from "react";
2
+ import { BulkDataStore } from "./data-store";
3
+ import { type ColumnDef } from "../generated/bulk-protocol";
4
+ import type { BulkRegistry } from "./use-cartridge-info";
5
+ export type BulkSubscription = {
6
+ store: BulkDataStore;
7
+ connected: boolean;
8
+ streaming: boolean;
9
+ error: string | null;
10
+ columns: ColumnDef[];
11
+ totalRows: number;
12
+ loadedRows: number;
13
+ search: (q: string) => void;
14
+ clearSearch: () => void;
15
+ setOnRender: (fn: (() => void) | null) => void;
16
+ };
17
+ type Props = {
18
+ registry: BulkRegistry;
19
+ children: React.ReactNode;
20
+ };
21
+ export declare function BulkStreamProvider({ registry, children }: Props): React.ReactElement;
22
+ export declare function useBulkRowCounts(registry: BulkRegistry): Record<string, number>;
23
+ export declare function useBulkSubscription(cart: string, entity: string): BulkSubscription;
24
+ export {};
@@ -0,0 +1,14 @@
1
+ export type BulkEntity = {
2
+ name: string;
3
+ route: string;
4
+ searchFields: readonly string[];
5
+ };
6
+ export type BulkRegistry = Record<string, BulkEntity[]>;
7
+ export type LiveRegistryState = {
8
+ registry: BulkRegistry;
9
+ carts: string[];
10
+ coreCarts: Set<string>;
11
+ loading: boolean;
12
+ error: string | null;
13
+ };
14
+ export declare function useLiveBulkRegistry(): LiveRegistryState;
@@ -0,0 +1,2 @@
1
+ import { type ClassValue } from "clsx";
2
+ export declare function cn(...inputs: ClassValue[]): string;
@@ -0,0 +1,7 @@
1
+ export { NbtEditor } from "./nbt-editor";
2
+ export type { NbtEditorProps } from "./nbt-editor";
3
+ export { nbtLanguage, nbtLanguageSupport } from "./nbt-language";
4
+ export { NbtLspClient } from "./lsp-client";
5
+ export type { LspPosition, LspRange, LspDiagnostic, LspCompletionItem, LspLocation, } from "./lsp-client";
6
+ export { lspExtensions } from "./lsp-extensions";
7
+ export type { GotoDefHandler } from "./lsp-extensions";
@@ -0,0 +1,16 @@
1
+ "use client";
2
+ import {
3
+ NbtEditor,
4
+ NbtLspClient,
5
+ lspExtensions,
6
+ nbtLanguage,
7
+ nbtLanguageSupport
8
+ } from "../chunk-S7VBQE6Y.js";
9
+ export {
10
+ NbtEditor,
11
+ NbtLspClient,
12
+ lspExtensions,
13
+ nbtLanguage,
14
+ nbtLanguageSupport
15
+ };
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -0,0 +1,57 @@
1
+ export type LspPosition = {
2
+ line: number;
3
+ character: number;
4
+ };
5
+ export type LspRange = {
6
+ start: LspPosition;
7
+ end: LspPosition;
8
+ };
9
+ export type LspDiagnostic = {
10
+ range: LspRange;
11
+ severity?: number;
12
+ message: string;
13
+ source?: string;
14
+ };
15
+ export type LspCompletionItem = {
16
+ label: string;
17
+ kind?: number;
18
+ detail?: string;
19
+ };
20
+ export type LspLocation = {
21
+ uri: string;
22
+ range: LspRange;
23
+ };
24
+ export declare class NbtLspClient {
25
+ private url;
26
+ private rootUri;
27
+ private ws;
28
+ private nextId;
29
+ private pending;
30
+ private diagHandlers;
31
+ private docs;
32
+ private ready;
33
+ private queue;
34
+ private closed;
35
+ private retryMs;
36
+ constructor(url: string);
37
+ dispose(): void;
38
+ private connect;
39
+ initialize(rootUri: string): void;
40
+ private sendInitialize;
41
+ private sendRaw;
42
+ private onMessage;
43
+ request<T>(method: string, params: object): Promise<T>;
44
+ onDiagnostics(uri: string, handler: (d: LspDiagnostic[]) => void): () => void;
45
+ didOpen(uri: string, text: string): void;
46
+ didChange(uri: string, text: string): void;
47
+ didClose(uri: string): void;
48
+ completion(uri: string, pos: LspPosition): Promise<{
49
+ items: LspCompletionItem[];
50
+ } | LspCompletionItem[] | null>;
51
+ hover(uri: string, pos: LspPosition): Promise<{
52
+ contents?: {
53
+ value?: string;
54
+ };
55
+ } | null>;
56
+ definition(uri: string, pos: LspPosition): Promise<LspLocation | LspLocation[] | null>;
57
+ }
@@ -0,0 +1,4 @@
1
+ import { type Extension } from "@codemirror/state";
2
+ import { NbtLspClient } from "./lsp-client";
3
+ export type GotoDefHandler = (uri: string, line: number) => void;
4
+ export declare function lspExtensions(client: NbtLspClient, uri: string, onGotoDefinition?: GotoDefHandler): Extension[];
@@ -0,0 +1,13 @@
1
+ import React from "react";
2
+ import { type GotoDefHandler } from "./lsp-extensions";
3
+ import { NbtLspClient } from "./lsp-client";
4
+ export type NbtEditorProps = {
5
+ uri: string;
6
+ value: string;
7
+ readOnly?: boolean;
8
+ lsp?: NbtLspClient | null;
9
+ onChange?: (text: string) => void;
10
+ onSave?: (text: string) => void;
11
+ onGotoDefinition?: GotoDefHandler;
12
+ };
13
+ export declare const NbtEditor: React.FC<NbtEditorProps>;
@@ -0,0 +1,7 @@
1
+ import { StreamLanguage, LanguageSupport } from "@codemirror/language";
2
+ type NbtState = {
3
+ tripleString: boolean;
4
+ };
5
+ export declare const nbtLanguage: StreamLanguage<NbtState>;
6
+ export declare function nbtLanguageSupport(): LanguageSupport;
7
+ export {};
@@ -0,0 +1,36 @@
1
+ export declare const FRAME_SCHEMA = 1;
2
+ export declare const FRAME_DATA = 2;
3
+ export declare const FRAME_DATA_END = 3;
4
+ export declare const FRAME_DELTA_INS = 4;
5
+ export declare const FRAME_DELTA_UPD = 5;
6
+ export declare const FRAME_DELTA_DEL = 6;
7
+ export declare const FRAME_ERROR = 255;
8
+ export declare const TYPE_U8 = 1;
9
+ export declare const TYPE_U16 = 2;
10
+ export declare const TYPE_U32 = 3;
11
+ export declare const TYPE_U64 = 4;
12
+ export declare const TYPE_S8 = 5;
13
+ export declare const TYPE_S16 = 6;
14
+ export declare const TYPE_S32 = 7;
15
+ export declare const TYPE_S64 = 8;
16
+ export declare const TYPE_BOOL = 9;
17
+ export declare const TYPE_FLOAT32 = 10;
18
+ export declare const TYPE_FLOAT64 = 11;
19
+ export declare const TYPE_STRING = 12;
20
+ export declare const TYPE_DATETIME = 13;
21
+ export declare const TYPE_DOCUMENT = 14;
22
+ export type ColumnDef = {
23
+ name: string;
24
+ type: number;
25
+ fixedSize: number;
26
+ };
27
+ export type SchemaFrame = {
28
+ totalRows: number;
29
+ columns: ColumnDef[];
30
+ };
31
+ export type DeltaFrame = {
32
+ op: number;
33
+ rowData?: string[];
34
+ id?: string;
35
+ };
36
+ export declare function fixedSizeForType(type: number): number;
@@ -0,0 +1,5 @@
1
+ import React from "react";
2
+ export declare const DiagramView: React.FC<{
3
+ visibleIds: Set<string>;
4
+ onSelectNode?: (cart: string, entity: string) => void;
5
+ }>;
@@ -0,0 +1,92 @@
1
+ export type GraphInputField = {
2
+ name: string;
3
+ type: string;
4
+ optional?: boolean;
5
+ array?: boolean;
6
+ kind?: string;
7
+ target?: string;
8
+ targetCart?: string;
9
+ relationKind?: string;
10
+ fkField?: string;
11
+ };
12
+ export type GraphInputEntity = {
13
+ name: string;
14
+ fields: GraphInputField[];
15
+ };
16
+ export type GraphInputCart = {
17
+ name: string;
18
+ entities: GraphInputEntity[];
19
+ };
20
+ export type EntityGraphField = {
21
+ name: string;
22
+ displayName: string;
23
+ type: string;
24
+ kind: string;
25
+ optional: boolean;
26
+ array: boolean;
27
+ target?: string;
28
+ targetCart?: string;
29
+ relationKind?: string;
30
+ fkField?: string;
31
+ implicit?: boolean;
32
+ };
33
+ export type EntityGraphNodeData = {
34
+ id: string;
35
+ cartridge: string;
36
+ entity: string;
37
+ fields: EntityGraphField[];
38
+ fieldCount: number;
39
+ scalarCount: number;
40
+ relationCount: number;
41
+ documentCount: number;
42
+ rowCount: number;
43
+ };
44
+ export type EntityGraphNode = EntityGraphNodeData & {
45
+ position: {
46
+ x: number;
47
+ y: number;
48
+ };
49
+ };
50
+ export type EntityGraphEdge = {
51
+ id: string;
52
+ source: string;
53
+ target: string;
54
+ sourceField: string;
55
+ targetField: string;
56
+ label: string;
57
+ relationKind?: string;
58
+ fkField?: string;
59
+ };
60
+ export type EntityGraphTotals = {
61
+ entities: number;
62
+ relationships: number;
63
+ rows: number;
64
+ };
65
+ export type EntityGraphModel = {
66
+ nodes: EntityGraphNode[];
67
+ edges: EntityGraphEdge[];
68
+ totals: EntityGraphTotals;
69
+ };
70
+ type ContractField = {
71
+ name: string;
72
+ type: string;
73
+ optional?: boolean;
74
+ array?: boolean;
75
+ kind?: string;
76
+ target?: string;
77
+ target_cart?: string;
78
+ relation_kind?: string;
79
+ fk_field?: string;
80
+ };
81
+ type ContractEntity = {
82
+ fields?: ContractField[];
83
+ };
84
+ export type Contract = {
85
+ cartridge?: string;
86
+ owns?: Record<string, ContractEntity>;
87
+ };
88
+ export declare function cartsFromContracts(contracts: Contract[]): GraphInputCart[];
89
+ export declare function entityGraphId(cartridge: string, entity: string): string;
90
+ export declare function buildEntityGraphModel(cartridges: GraphInputCart[]): EntityGraphModel;
91
+ export declare function filterEntityGraphModel(model: EntityGraphModel, visibleIds: Set<string>): EntityGraphModel;
92
+ export {};
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { type NodeProps } from "@xyflow/react";
3
+ export type EntityNodeHighlight = {
4
+ focused: boolean;
5
+ connected: boolean;
6
+ dimmed: boolean;
7
+ fields: string[];
8
+ };
9
+ export declare function EntityNode({ data, selected }: NodeProps): React.JSX.Element;
@@ -0,0 +1,5 @@
1
+ export { DiagramView as EntityGraph } from "./diagram";
2
+ export { EntityNode } from "./entity-node";
3
+ export type { EntityNodeHighlight } from "./entity-node";
4
+ export { cartsFromContracts, entityGraphId, buildEntityGraphModel, filterEntityGraphModel, } from "./entity-graph-utils";
5
+ export type { Contract, EntityGraphField, EntityGraphNodeData, EntityGraphNode, EntityGraphEdge, EntityGraphModel, } from "./entity-graph-utils";
@@ -0,0 +1,19 @@
1
+ "use client";
2
+ import {
3
+ DiagramView,
4
+ EntityNode,
5
+ buildEntityGraphModel,
6
+ cartsFromContracts,
7
+ entityGraphId,
8
+ filterEntityGraphModel
9
+ } from "../chunk-UPEOXMLZ.js";
10
+ import "../chunk-3ZM6YOA4.js";
11
+ export {
12
+ DiagramView as EntityGraph,
13
+ EntityNode,
14
+ buildEntityGraphModel,
15
+ cartsFromContracts,
16
+ entityGraphId,
17
+ filterEntityGraphModel
18
+ };
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -0,0 +1,4 @@
1
+ export * from "./core";
2
+ export * from "./editor";
3
+ export * from "./graph";
4
+ export * from "./table";