@rebasepro/studio 0.0.1-canary.94dff14 → 0.0.1-canary.bbcb8b4

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.
@@ -3,7 +3,7 @@ import { c } from "react-compiler-runtime";
3
3
  import { useState, useCallback, useEffect, useMemo, memo, useRef } from "react";
4
4
  import { MarkerType, Position, Handle, getSmoothStepPath, EdgeLabelRenderer, BaseEdge, ReactFlowProvider, useReactFlow, applyNodeChanges, applyEdgeChanges, ReactFlow, Background, BackgroundVariant, Controls, MiniMap } from "@xyflow/react";
5
5
  import "@xyflow/react/dist/style.css";
6
- import { cls, Tooltip, Typography, Chip, CircularProgress, ResizablePanels, IconButton, defaultBorderMixin, TextField } from "@rebasepro/ui";
6
+ import { cls, Tooltip, Typography, Chip, CircularProgress, ResizablePanels, IconButton, defaultBorderMixin, SearchBar } from "@rebasepro/ui";
7
7
  import { IconForView, useStudioCollectionRegistry } from "@rebasepro/core";
8
8
  import { isPostgresCollection } from "@rebasepro/types";
9
9
  import { resolveCollectionRelations } from "@rebasepro/common";
@@ -913,7 +913,7 @@ function SchemaVisualizerCanvas({
913
913
  /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "font-bold uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark", children: "Tables" }),
914
914
  /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-[10px] text-text-disabled dark:text-text-disabled-dark font-mono", children: stats.tables })
915
915
  ] }),
916
- /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 border-b border-surface-200/40 dark:border-surface-700/40", children: /* @__PURE__ */ jsx(TextField, { size: "smallest", placeholder: "Filter tables…", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), inputClassName: "text-xs" }) }),
916
+ /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 border-b border-surface-200/40 dark:border-surface-700/40", children: /* @__PURE__ */ jsx(SearchBar, { size: "smallest", placeholder: "Filter tables…", onTextSearch: (val) => setSearchQuery(val || ""), innerClassName: "text-xs" }) }),
917
917
  /* @__PURE__ */ jsxs("div", { className: "flex-grow overflow-y-auto no-scrollbar p-1", children: [
918
918
  /* @__PURE__ */ jsx("div", { className: "space-y-0.5", children: filteredCollections.map((collection) => {
919
919
  const table = collection.table ?? collection.slug;
@@ -1066,4 +1066,4 @@ const SchemaVisualizer = () => {
1066
1066
  export {
1067
1067
  SchemaVisualizer
1068
1068
  };
1069
- //# sourceMappingURL=SchemaVisualizer-BgD5Zb77.js.map
1069
+ //# sourceMappingURL=SchemaVisualizer-CM8lbrcq.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SchemaVisualizer-CM8lbrcq.js","sources":["../src/components/SchemaVisualizer/schema-visualizer.utils.ts","../src/components/SchemaVisualizer/useSchemaGraph.ts","../src/components/SchemaVisualizer/TableNode.tsx","../src/components/SchemaVisualizer/RelationEdge.tsx","../src/components/SchemaVisualizer/SchemaVisualizer.tsx"],"sourcesContent":["import dagre from \"dagre\";\nimport type { Node, Edge } from \"@xyflow/react\";\n\n// ─── Layout Constants ─────────────────────────────────────────────────\nexport const NODE_WIDTH = 280;\n/** Header with a single line of text (junction tables or tableName === collectionName). */\nexport const HEADER_HEIGHT_SINGLE = 33;\n/** Header with two lines (name + subtitle when collectionName !== tableName). */\nexport const HEADER_HEIGHT_DOUBLE = 47;\nconst ROW_HEIGHT = 28; // height per column row\n\n/**\n * Compute the correct header height for a table node.\n */\nexport const getHeaderHeight = (opts: {\n isJunction: boolean;\n collectionName: string;\n tableName: string;\n}): number => {\n if (opts.isJunction) return HEADER_HEIGHT_SINGLE;\n return opts.collectionName !== opts.tableName\n ? HEADER_HEIGHT_DOUBLE\n : HEADER_HEIGHT_SINGLE;\n};\n\n/**\n * Estimate the pixel height of a table node based on column count.\n */\nexport const estimateNodeHeight = (columnCount: number, headerHeight: number = HEADER_HEIGHT_DOUBLE): number =>\n headerHeight + Math.max(columnCount, 1) * ROW_HEIGHT + 4; // +4 for bottom padding\n\n/**\n * Get the vertical center Y of a specific column row (0-indexed)\n * relative to the top of the node.\n */\nexport const getColumnRowY = (rowIndex: number, headerHeight: number = HEADER_HEIGHT_DOUBLE): number =>\n headerHeight + rowIndex * ROW_HEIGHT + ROW_HEIGHT / 2;\n\n// ─── Auto-Layout via Dagre ────────────────────────────────────────────\n\nexport type LayoutDirection = \"TB\" | \"LR\";\n\n/**\n * Compute node positions using the dagre graph layout engine.\n * Returns a new array of nodes with updated `position`.\n */\nexport const getLayoutedElements = (\n nodes: Node[],\n edges: Edge[],\n direction: LayoutDirection = \"LR\"\n): { nodes: Node[]; edges: Edge[] } => {\n const g = new dagre.graphlib.Graph();\n g.setGraph({\n rankdir: direction,\n nodesep: 100,\n ranksep: 180,\n edgesep: 60,\n marginx: 60,\n marginy: 60\n });\n g.setDefaultEdgeLabel(() => ({}));\n\n const nodeHeights = new Map<string, number>();\n\n nodes.forEach((node) => {\n const data = node.data as { columns?: unknown[]; isJunction?: boolean; collectionName?: string; tableName?: string };\n const columnCount = data.columns?.length ?? 3;\n const headerH = getHeaderHeight({\n isJunction: Boolean(data.isJunction),\n collectionName: data.collectionName ?? \"\",\n tableName: data.tableName ?? \"\"\n });\n const h = estimateNodeHeight(columnCount, headerH);\n nodeHeights.set(node.id, h);\n g.setNode(node.id, {\n width: NODE_WIDTH,\n height: h\n });\n });\n\n edges.forEach((edge) => {\n g.setEdge(edge.source, edge.target);\n });\n\n dagre.layout(g);\n\n const layoutedNodes = nodes.map((node) => {\n const nodeWithPosition = g.node(node.id);\n const h = nodeHeights.get(node.id) ?? estimateNodeHeight(3);\n return {\n ...node,\n data: {\n ...node.data,\n layoutDirection: direction\n },\n position: {\n x: nodeWithPosition.x - NODE_WIDTH / 2,\n y: nodeWithPosition.y - h / 2\n }\n };\n });\n\n return { nodes: layoutedNodes,\nedges };\n};\n\n// ─── Column type → display label ──────────────────────────────────────\n\nconst TYPE_LABELS: Record<string, string> = {\n string: \"varchar\",\n number: \"integer\",\n boolean: \"boolean\",\n date: \"timestamp\",\n map: \"jsonb\",\n array: \"jsonb\",\n relation: \"FK\"\n};\n\nexport const getTypeLabel = (type: string): string =>\n TYPE_LABELS[type] ?? type;\n\n// ─── Edge styling by relation type ────────────────────────────────────\n\nexport interface RelationEdgeData {\n cardinality: \"one\" | \"many\";\n direction: \"owning\" | \"inverse\";\n relationName: string;\n hasJunction: boolean;\n hasJoinPath: boolean;\n label: string;\n}\n\nexport const getCardinalityLabel = (\n cardinality: \"one\" | \"many\",\n direction: \"owning\" | \"inverse\"\n): string => {\n if (cardinality === \"many\") return \"M:N\";\n if (direction === \"inverse\") return \"1:1 ←\";\n return \"N:1\";\n};\n","import { useMemo, useState, useCallback, useEffect } from \"react\";\nimport type { Node, Edge } from \"@xyflow/react\";\nimport { MarkerType } from \"@xyflow/react\";\nimport { isPostgresCollection } from \"@rebasepro/types\";\nimport type { EntityCollection, PostgresCollection, Relation } from \"@rebasepro/types\";\nimport { resolveCollectionRelations } from \"@rebasepro/common\";\nimport { getLayoutedElements, getCardinalityLabel, getTypeLabel, NODE_WIDTH } from \"./schema-visualizer.utils\";\nimport type { LayoutDirection, RelationEdgeData } from \"./schema-visualizer.utils\";\n\n// ─── Column info extracted from a collection ──────────────────────────\n\nexport interface ColumnInfo {\n name: string;\n type: string;\n typeLabel: string;\n isPrimaryKey: boolean;\n isForeignKey: boolean;\n isRequired: boolean;\n isEnum: boolean;\n enumValues?: string[];\n relationName?: string;\n}\n\n// ─── Node data shape ──────────────────────────────────────────────────\n\nexport interface TableNodeData {\n tableName: string;\n collectionName: string;\n slug: string;\n columns: ColumnInfo[];\n isJunction: boolean;\n isUnmanaged: boolean;\n rlsEnabled: boolean;\n historyEnabled: boolean;\n icon?: string;\n [key: string]: unknown;\n}\n\n// ─── Extract columns from an EntityCollection ─────────────────────────\n\nconst extractColumns = (collection: EntityCollection): ColumnInfo[] => {\n const columns: ColumnInfo[] = [];\n const properties = collection.properties ?? {};\n\n for (const [propName, prop] of Object.entries(properties)) {\n if (prop.type === \"relation\") continue; // Relations are shown as edges, not columns\n\n const isPk =\n (\"isId\" in prop && Boolean((prop as unknown as Record<string, unknown>).isId)) ||\n (!Object.values(properties).some(\n (p) => \"isId\" in p && Boolean((p as unknown as Record<string, unknown>).isId)\n ) &&\n propName === \"id\");\n\n const isEnum = prop.type === \"string\" && \"enum\" in prop && Boolean(prop.enum);\n\n let enumValues: string[] | undefined;\n if (isEnum && \"enum\" in prop && prop.enum) {\n const enumProp = prop.enum;\n if (Array.isArray(enumProp)) {\n enumValues = enumProp.map((v: unknown) =>\n typeof v === \"string\" ? v : String((v as Record<string, unknown>)?.id ?? v)\n );\n } else if (typeof enumProp === \"object\" && enumProp !== null) {\n enumValues = Object.keys(enumProp);\n }\n }\n\n columns.push({\n name: propName,\n type: prop.type,\n typeLabel: getTypeLabel(prop.type),\n isPrimaryKey: isPk,\n isForeignKey: false,\n isRequired: Boolean(prop.validation?.required),\n isEnum,\n enumValues\n });\n }\n\n // Add FK columns from owning relations\n if (isPostgresCollection(collection)) {\n try {\n const resolvedRelations = resolveCollectionRelations(collection);\n for (const rel of Object.values(resolvedRelations)) {\n if (rel.direction === \"owning\" && rel.cardinality === \"one\" && rel.localKey) {\n // Only add if not already present as a regular column\n if (!columns.some((c) => c.name === rel.localKey)) {\n columns.push({\n name: rel.localKey,\n type: \"number\",\n typeLabel: \"FK\",\n isPrimaryKey: false,\n isForeignKey: true,\n isRequired: false,\n isEnum: false,\n relationName: rel.relationName\n });\n } else {\n // Mark existing column as FK\n const existing = columns.find((c) => c.name === rel.localKey);\n if (existing) {\n existing.isForeignKey = true;\n existing.relationName = rel.relationName;\n }\n }\n }\n }\n } catch {\n // Ignore resolution errors\n }\n }\n\n return columns;\n};\n\n// ─── Build graph from collections ─────────────────────────────────────\n\nconst buildGraph = (\n collections: EntityCollection[],\n direction: LayoutDirection\n): { nodes: Node[]; edges: Edge[] } => {\n const nodes: Node[] = [];\n const edges: Edge[] = [];\n const tableToNodeId = new Map<string, string>();\n // Track columns per node so we can resolve handle IDs for edges\n const nodeColumns = new Map<string, ColumnInfo[]>();\n\n // Helper: find the PK column name for a node (falls back to \"id\")\n const getPkHandle = (nodeId: string): string => {\n const cols = nodeColumns.get(nodeId);\n const pk = cols?.find((c) => c.isPrimaryKey);\n return pk ? `target-${pk.name}` : \"target-default\";\n };\n\n // Helper: find the FK column name for a node pointing to a relation\n const getFkHandle = (nodeId: string, localKey: string | undefined): string => {\n if (!localKey) return \"source-default\";\n const cols = nodeColumns.get(nodeId);\n const fk = cols?.find((c) => c.name === localKey);\n return fk ? `source-${fk.name}` : \"source-default\";\n };\n\n // 1. Create nodes for each collection\n for (const collection of collections) {\n if (!isPostgresCollection(collection)) continue;\n\n const tableName = collection.table ?? collection.slug;\n const nodeId = `table-${tableName}`;\n tableToNodeId.set(tableName, nodeId);\n\n const columns = extractColumns(collection);\n nodeColumns.set(nodeId, columns);\n\n const nodeData: TableNodeData = {\n tableName,\n collectionName: collection.name,\n slug: collection.slug,\n columns,\n isJunction: false,\n isUnmanaged: false,\n rlsEnabled: Boolean(collection.securityRules && collection.securityRules.length > 0),\n historyEnabled: Boolean(collection.history),\n icon: typeof collection.icon === \"string\" ? collection.icon : undefined\n };\n\n nodes.push({\n id: nodeId,\n type: \"tableNode\",\n position: { x: 0,\ny: 0 },\n data: nodeData\n });\n }\n\n // 2. Create junction table nodes and edges\n const processedJunctions = new Set<string>();\n\n for (const collection of collections) {\n if (!isPostgresCollection(collection)) continue;\n\n const tableName = collection.table ?? collection.slug;\n const sourceNodeId = tableToNodeId.get(tableName);\n if (!sourceNodeId) continue;\n\n let resolvedRelations: Record<string, Relation>;\n try {\n resolvedRelations = resolveCollectionRelations(collection);\n } catch {\n continue;\n }\n\n for (const [relationKey, rel] of Object.entries(resolvedRelations)) {\n let targetCollection: EntityCollection;\n try {\n targetCollection = rel.target();\n } catch {\n continue;\n }\n\n if (!isPostgresCollection(targetCollection)) continue;\n\n const targetTable = targetCollection.table ?? targetCollection.slug;\n const targetNodeId = tableToNodeId.get(targetTable);\n if (!targetNodeId) continue;\n\n // Skip inverse relations (we only draw owning ones)\n if (rel.direction === \"inverse\") continue;\n\n const edgeData: RelationEdgeData = {\n cardinality: rel.cardinality,\n direction: rel.direction ?? \"owning\",\n relationName: rel.relationName ?? relationKey,\n hasJunction: Boolean(rel.through),\n hasJoinPath: Boolean(rel.joinPath),\n label: getCardinalityLabel(rel.cardinality, rel.direction ?? \"owning\")\n };\n\n if (rel.through && !processedJunctions.has(rel.through.table)) {\n // Many-to-many: create junction node + two edges\n processedJunctions.add(rel.through.table);\n const junctionNodeId = `junction-${rel.through.table}`;\n\n const junctionColumns: ColumnInfo[] = [\n {\n name: rel.through.sourceColumn,\n type: \"number\",\n typeLabel: \"FK\",\n isPrimaryKey: true,\n isForeignKey: true,\n isRequired: true,\n isEnum: false\n },\n {\n name: rel.through.targetColumn,\n type: \"number\",\n typeLabel: \"FK\",\n isPrimaryKey: true,\n isForeignKey: true,\n isRequired: true,\n isEnum: false\n }\n ];\n nodeColumns.set(junctionNodeId, junctionColumns);\n\n nodes.push({\n id: junctionNodeId,\n type: \"tableNode\",\n position: { x: 0,\ny: 0 },\n data: {\n tableName: rel.through.table,\n collectionName: rel.through.table,\n slug: rel.through.table,\n columns: junctionColumns,\n isJunction: true,\n isUnmanaged: false,\n rlsEnabled: false,\n historyEnabled: false\n } satisfies TableNodeData\n });\n\n // Source table → junction (junction references source PK)\n const sourcePk = nodeColumns.get(sourceNodeId)?.find((c) => c.isPrimaryKey);\n edges.push({\n id: `edge-${sourceNodeId}-${junctionNodeId}`,\n source: sourceNodeId,\n target: junctionNodeId,\n sourceHandle: sourcePk ? `source-${sourcePk.name}` : \"source-default\",\n targetHandle: `target-${rel.through.sourceColumn}`,\n type: \"relationEdge\",\n data: { ...edgeData,\nlabel: \"1:N\" } as Record<string, unknown>,\n markerEnd: { type: MarkerType.ArrowClosed,\nwidth: 16,\nheight: 16 }\n });\n\n // Junction → target table\n edges.push({\n id: `edge-${junctionNodeId}-${targetNodeId}`,\n source: junctionNodeId,\n target: targetNodeId,\n sourceHandle: `source-${rel.through.targetColumn}`,\n targetHandle: getPkHandle(targetNodeId),\n type: \"relationEdge\",\n data: { ...edgeData,\nlabel: \"N:1\" } as Record<string, unknown>,\n markerEnd: { type: MarkerType.ArrowClosed,\nwidth: 16,\nheight: 16 }\n });\n } else if (!rel.through) {\n // Direct relation (one-to-one or many-to-one)\n edges.push({\n id: `edge-${sourceNodeId}-${targetNodeId}-${relationKey}`,\n source: sourceNodeId,\n target: targetNodeId,\n sourceHandle: getFkHandle(sourceNodeId, rel.localKey),\n targetHandle: getPkHandle(targetNodeId),\n type: \"relationEdge\",\n data: { ...edgeData } as Record<string, unknown>,\n markerEnd: { type: MarkerType.ArrowClosed,\nwidth: 16,\nheight: 16 }\n });\n }\n }\n }\n // 3. Apply dagre layout first to get node positions\n const layoutResult = getLayoutedElements(nodes, edges, direction);\n\n // 4. Build a position lookup from the laid-out nodes\n const nodePositions = new Map<string, { x: number }>();\n for (const node of layoutResult.nodes) {\n nodePositions.set(node.id, { x: node.position.x });\n }\n\n // 5. Resolve handle sides based on relative node positions.\n // If source is left of target → source exits Right, target enters Left.\n // If source is right of target → source exits Left, target enters Right.\n for (const edge of layoutResult.edges) {\n const srcPos = nodePositions.get(edge.source);\n const tgtPos = nodePositions.get(edge.target);\n\n const srcBaseHandle = (edge.sourceHandle ?? \"source-default\") as string;\n const tgtBaseHandle = (edge.targetHandle ?? \"target-default\") as string;\n\n if (srcPos && tgtPos) {\n const srcCenterX = srcPos.x + NODE_WIDTH / 2;\n const tgtCenterX = tgtPos.x + NODE_WIDTH / 2;\n const sourceIsLeft = srcCenterX <= tgtCenterX;\n\n edge.sourceHandle = `${srcBaseHandle}-${sourceIsLeft ? \"right\" : \"left\"}`;\n edge.targetHandle = `${tgtBaseHandle}-${sourceIsLeft ? \"left\" : \"right\"}`;\n } else {\n edge.sourceHandle = `${srcBaseHandle}-right`;\n edge.targetHandle = `${tgtBaseHandle}-left`;\n }\n }\n\n return layoutResult;\n};\n\n// ─── Hook ─────────────────────────────────────────────────────────────\n\nexport interface UseSchemaGraphResult {\n nodes: Node[];\n edges: Edge[];\n direction: LayoutDirection;\n setDirection: (dir: LayoutDirection) => void;\n relayout: () => void;\n isLoading: boolean;\n tableCount: number;\n relationCount: number;\n}\n\nexport const useSchemaGraph = (\n collections: EntityCollection[] | undefined\n): UseSchemaGraphResult => {\n const [direction, setDirection] = useState<LayoutDirection>(\"LR\");\n const [version, setVersion] = useState(0);\n\n const relayout = useCallback(() => setVersion((v) => v + 1), []);\n\n // Re-layout on direction change\n useEffect(() => {\n setVersion((v) => v + 1);\n }, [direction]);\n\n const { nodes, edges, tableCount, relationCount } = useMemo(() => {\n if (!collections || collections.length === 0) {\n return { nodes: [],\nedges: [],\ntableCount: 0,\nrelationCount: 0 };\n }\n const result = buildGraph(collections, direction);\n return {\n ...result,\n tableCount: result.nodes.length,\n relationCount: result.edges.length\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [collections, direction, version]);\n\n return {\n nodes,\n edges,\n direction,\n setDirection,\n relayout,\n isLoading: !collections,\n tableCount,\n relationCount\n };\n};\n","import React, { memo, useMemo } from \"react\";\nimport { Handle, Position } from \"@xyflow/react\";\nimport type { NodeProps } from \"@xyflow/react\";\nimport { Typography, Chip, Tooltip, cls } from \"@rebasepro/ui\";\nimport { IconForView } from \"@rebasepro/core\";\nimport type { TableNodeData, ColumnInfo } from \"./useSchemaGraph\";\nimport { getColumnRowY, getHeaderHeight } from \"./schema-visualizer.utils\";\n\n/**\n * Custom React Flow node that renders a database table as a card.\n *\n * Every PK and FK column renders handles on BOTH Left and Right sides.\n * The edge builder picks which side to use based on relative node position.\n */\nconst TableNodeInner = ({ data, selected }: NodeProps) => {\n const {\n tableName,\n collectionName,\n columns,\n isJunction,\n rlsEnabled,\n historyEnabled,\n icon\n } = data as TableNodeData;\n\n // Build handles: every PK/FK column gets Left + Right handles\n const handles = useMemo(() => {\n const result: { id: string; type: \"source\" | \"target\"; position: Position; top: number }[] = [];\n const cols = columns as ColumnInfo[];\n const headerH = getHeaderHeight({\n isJunction: Boolean(isJunction),\n collectionName: collectionName as string,\n tableName: tableName as string\n });\n const midY = cols.length > 0 ? getColumnRowY(Math.floor(cols.length / 2), headerH) : 30;\n\n cols.forEach((col, idx) => {\n const y = getColumnRowY(idx, headerH);\n\n if (col.isForeignKey && !col.isPrimaryKey) {\n // FK: source handles on both sides\n result.push({ id: `source-${col.name}-right`,\ntype: \"source\",\nposition: Position.Right,\ntop: y });\n result.push({ id: `source-${col.name}-left`,\ntype: \"source\",\nposition: Position.Left,\ntop: y });\n }\n if (col.isPrimaryKey) {\n // PK: target + source handles on both sides\n result.push({ id: `target-${col.name}-right`,\ntype: \"target\",\nposition: Position.Right,\ntop: y });\n result.push({ id: `target-${col.name}-left`,\ntype: \"target\",\nposition: Position.Left,\ntop: y });\n result.push({ id: `source-${col.name}-right`,\ntype: \"source\",\nposition: Position.Right,\ntop: y });\n result.push({ id: `source-${col.name}-left`,\ntype: \"source\",\nposition: Position.Left,\ntop: y });\n }\n });\n\n // Default handles on both sides\n result.push({ id: \"target-default-right\",\ntype: \"target\",\nposition: Position.Right,\ntop: midY });\n result.push({ id: \"target-default-left\",\ntype: \"target\",\nposition: Position.Left,\ntop: midY });\n result.push({ id: \"source-default-right\",\ntype: \"source\",\nposition: Position.Right,\ntop: midY });\n result.push({ id: \"source-default-left\",\ntype: \"source\",\nposition: Position.Left,\ntop: midY });\n\n return result;\n }, [columns, isJunction, collectionName, tableName]);\n\n return (\n <div\n className={cls(\n \"relative rounded-lg border bg-white dark:bg-surface-900 shadow-sm transition-all duration-200 min-w-[240px] max-w-[320px]\",\n selected\n ? \"border-primary ring-2 ring-primary/20 shadow-md\"\n : \"border-surface-200/40 dark:border-surface-700/40 hover:shadow-md hover:border-surface-300 dark:hover:border-surface-600\",\n isJunction && \"border-dashed\"\n )}\n >\n {/* ── Header ── */}\n <div\n className={cls(\n \"flex items-center gap-2 px-3 py-2 border-b rounded-t-lg\",\n isJunction\n ? \"bg-surface-50 dark:bg-surface-950/50 border-surface-200/30 dark:border-surface-700/30\"\n : \"bg-surface-50 dark:bg-surface-950 border-surface-200/40 dark:border-surface-700/40\"\n )}\n >\n {icon && !isJunction && (\n <div className=\"text-primary shrink-0\">\n <IconForView\n collectionOrView={{ slug: tableName,\nname: collectionName,\nicon }}\n size=\"smallest\"\n />\n </div>\n )}\n {isJunction && (\n <svg\n className=\"w-3.5 h-3.5 text-text-disabled dark:text-text-disabled-dark shrink-0\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4\"\n />\n </svg>\n )}\n <div className=\"flex flex-col min-w-0\">\n <Typography\n variant=\"caption\"\n className={cls(\n \"font-semibold truncate text-[12px]\",\n isJunction\n ? \"text-text-secondary dark:text-text-secondary-dark\"\n : \"text-text-primary dark:text-text-primary-dark\"\n )}\n >\n {tableName}\n </Typography>\n {collectionName !== tableName && !isJunction && (\n <Typography\n variant=\"caption\"\n className=\"text-[10px] text-text-disabled dark:text-text-disabled-dark truncate\"\n >\n {collectionName}\n </Typography>\n )}\n </div>\n\n {/* Badges */}\n <div className=\"ml-auto flex items-center gap-1 shrink-0\">\n {rlsEnabled && (\n <Tooltip title=\"RLS enabled\">\n <div className=\"w-1.5 h-1.5 rounded-full bg-green-500\"/>\n </Tooltip>\n )}\n {historyEnabled && (\n <Tooltip title=\"History enabled\">\n <div className=\"w-1.5 h-1.5 rounded-full bg-blue-400\"/>\n </Tooltip>\n )}\n </div>\n </div>\n\n {/* ── Columns ── */}\n <div className=\"divide-y divide-surface-100 dark:divide-surface-950/60\">\n {(columns as ColumnInfo[]).map((col: ColumnInfo) => (\n <div\n key={col.name}\n className={cls(\n \"flex items-center gap-2 px-3 py-1.5 text-xs transition-colors\",\n col.isPrimaryKey && \"bg-amber-50/50 dark:bg-amber-950/10\",\n col.isForeignKey &&\n !col.isPrimaryKey &&\n \"bg-blue-50/40 dark:bg-blue-950/10\"\n )}\n >\n <span className=\"w-3 shrink-0 text-center\">\n {col.isPrimaryKey && (\n <Tooltip title=\"Primary Key\">\n <span className=\"text-amber-500 text-[10px] font-bold\">🔑</span>\n </Tooltip>\n )}\n {col.isForeignKey && !col.isPrimaryKey && (\n <Tooltip title={`FK → ${col.relationName ?? \"?\"}`}>\n <span className=\"text-blue-400 text-[10px] font-bold\">🔗</span>\n </Tooltip>\n )}\n </span>\n\n <Typography\n variant=\"caption\"\n className={cls(\n \"font-mono text-[11px] truncate flex-1 min-w-0\",\n col.isPrimaryKey\n ? \"font-semibold text-amber-700 dark:text-amber-400\"\n : col.isForeignKey\n ? \"text-blue-600 dark:text-blue-400\"\n : \"text-text-primary dark:text-text-primary-dark\"\n )}\n >\n {col.name}\n </Typography>\n\n {col.isEnum ? (\n <Chip\n size=\"smallest\"\n className=\"bg-violet-100 text-violet-700 dark:bg-violet-900/30 dark:text-violet-400 border-violet-200 dark:border-violet-800 text-[9px] py-0\"\n >\n enum\n </Chip>\n ) : (\n <Typography\n variant=\"caption\"\n className=\"text-[10px] text-text-disabled dark:text-text-disabled-dark font-mono shrink-0\"\n >\n {col.typeLabel}\n </Typography>\n )}\n\n {col.isRequired && !col.isPrimaryKey && (\n <Tooltip title=\"Required\">\n <span className=\"text-red-400 text-[9px]\">•</span>\n </Tooltip>\n )}\n </div>\n ))}\n </div>\n\n {/* ── Handles at node root ── */}\n {handles.map((h) => (\n <Handle\n key={h.id}\n id={h.id}\n type={h.type}\n position={h.position}\n style={{ top: h.top }}\n className={cls(\n \"!w-2 !h-2 !border-2 !border-white dark:!border-surface-900\",\n h.type === \"source\" ? \"!bg-blue-400\" : \"!bg-amber-400\"\n )}\n />\n ))}\n </div>\n );\n};\n\nexport const TableNode = memo(TableNodeInner);\n","import React, { memo } from \"react\";\nimport { BaseEdge, getSmoothStepPath, EdgeLabelRenderer } from \"@xyflow/react\";\nimport type { EdgeProps } from \"@xyflow/react\";\nimport { cls } from \"@rebasepro/ui\";\nimport type { RelationEdgeData } from \"./schema-visualizer.utils\";\n\n/**\n * Custom React Flow edge that renders relations with style variations\n * based on cardinality and direction.\n *\n * - Owning one-to-one: solid, primary color\n * - Many-to-many (junction): solid, violet\n * - Inverse: dashed, muted\n * - Join path: dotted, muted\n */\nconst RelationEdgeInner = ({\n id,\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourcePosition,\n targetPosition,\n data,\n selected\n}: EdgeProps) => {\n const edgeData = data as RelationEdgeData | undefined;\n\n const [edgePath, labelX, labelY] = getSmoothStepPath({\n sourceX,\n sourceY,\n sourcePosition,\n targetX,\n targetY,\n targetPosition,\n borderRadius: 8\n });\n\n const isInverse = edgeData?.direction === \"inverse\";\n const isJoinPath = edgeData?.hasJoinPath;\n const isJunction = edgeData?.hasJunction;\n\n // Determine stroke style\n let strokeColor = \"var(--rf-edge-stroke, #94a3b8)\";\n let strokeDasharray: string | undefined;\n let strokeWidth = 1.5;\n\n if (selected) {\n strokeColor = \"var(--rf-edge-stroke-selected, #6366f1)\";\n strokeWidth = 2.5;\n } else if (isJunction) {\n strokeColor = \"#8b5cf6\"; // violet\n } else if (isInverse) {\n strokeDasharray = \"6 3\";\n strokeColor = \"#94a3b8\";\n } else if (isJoinPath) {\n strokeDasharray = \"3 3\";\n strokeColor = \"#94a3b8\";\n } else {\n strokeColor = \"#6366f1\"; // primary/indigo\n }\n\n return (\n <>\n <BaseEdge\n id={id}\n path={edgePath}\n style={{\n stroke: strokeColor,\n strokeWidth,\n strokeDasharray\n }}\n />\n {edgeData?.label && (\n <EdgeLabelRenderer>\n <div\n style={{\n position: \"absolute\",\n transform: `translate(-50%, -50%) translate(${labelX}px,${labelY}px)`,\n pointerEvents: \"all\"\n }}\n className={cls(\n \"px-1.5 py-0.5 rounded text-[9px] font-mono font-semibold leading-none\",\n \"bg-white dark:bg-surface-900 border\",\n selected\n ? \"border-primary text-primary\"\n : isJunction\n ? \"border-violet-200 dark:border-violet-800 text-violet-600 dark:text-violet-400\"\n : isInverse || isJoinPath\n ? \"border-surface-200 dark:border-surface-700 text-text-disabled dark:text-text-disabled-dark\"\n : \"border-primary/30 dark:border-primary/30 text-primary\"\n )}\n >\n {edgeData.label}\n </div>\n </EdgeLabelRenderer>\n )}\n </>\n );\n};\n\nexport const RelationEdge = memo(RelationEdgeInner);\n","import React, { useState, useCallback, useMemo, useEffect, useRef } from \"react\";\nimport {\n ReactFlow,\n Controls,\n MiniMap,\n Background,\n BackgroundVariant,\n useReactFlow,\n ReactFlowProvider,\n applyNodeChanges,\n applyEdgeChanges\n} from \"@xyflow/react\";\nimport type { Node, Edge, NodeChange, EdgeChange } from \"@xyflow/react\";\nimport \"@xyflow/react/dist/style.css\";\nimport {\n Button,\n SearchBar,\n TextField,\n Tooltip,\n Alert,\n Typography,\n cls,\n defaultBorderMixin,\n CircularProgress,\n ResizablePanels,\n IconButton\n} from \"@rebasepro/ui\";\nimport {\n useStudioCollectionRegistry,\n IconForView\n} from \"@rebasepro/core\";\nimport type { EntityCollection } from \"@rebasepro/types\";\nimport { isPostgresCollection } from \"@rebasepro/types\";\nimport { useSchemaGraph } from \"./useSchemaGraph\";\nimport type { TableNodeData } from \"./useSchemaGraph\";\nimport { TableNode } from \"./TableNode\";\nimport { RelationEdge } from \"./RelationEdge\";\n\n\n// ─── Custom node / edge type registrations ────────────────────────────\n\nconst nodeTypes = {\n tableNode: TableNode\n};\n\nconst edgeTypes = {\n relationEdge: RelationEdge\n};\n\n// ─── Inner component (needs ReactFlowProvider) ─────────────────────────\n\nfunction SchemaVisualizerCanvas({\n collections\n}: {\n collections: EntityCollection[];\n}) {\n const reactFlowInstance = useReactFlow();\n const {\n nodes: layoutedNodes,\n edges: layoutedEdges,\n direction,\n setDirection,\n relayout,\n tableCount,\n relationCount\n } = useSchemaGraph(collections);\n\n const [nodes, setNodes] = useState<Node[]>([]);\n const [edges, setEdges] = useState<Edge[]>([]);\n const [selectedTable, setSelectedTable] = useState<string | null>(null);\n const [searchQuery, setSearchQuery] = useState(\"\");\n const initialFitDone = useRef(false);\n\n // Sync layouted data into state\n useEffect(() => {\n setNodes(layoutedNodes);\n setEdges(layoutedEdges);\n }, [layoutedNodes, layoutedEdges]);\n\n const onNodesChange = useCallback(\n (changes: NodeChange[]) => setNodes((nds) => applyNodeChanges(changes, nds)),\n []\n );\n const onEdgesChange = useCallback(\n (changes: EdgeChange[]) => setEdges((eds) => applyEdgeChanges(changes, eds)),\n []\n );\n\n // Fit view on first load\n useEffect(() => {\n if (nodes.length > 0 && !initialFitDone.current) {\n const timer = setTimeout(() => {\n reactFlowInstance.fitView({ padding: 0.15,\nduration: 400 });\n initialFitDone.current = true;\n }, 200);\n return () => clearTimeout(timer);\n }\n return undefined;\n }, [nodes.length, reactFlowInstance]);\n\n const handleFitView = useCallback(() => {\n reactFlowInstance.fitView({ padding: 0.15,\nduration: 400 });\n }, [reactFlowInstance]);\n\n const handleNodeClick = useCallback((_: React.MouseEvent, node: Node) => {\n setSelectedTable(node.id);\n }, []);\n\n const handlePaneClick = useCallback(() => {\n setSelectedTable(null);\n }, []);\n\n // Focus on a table from the sidebar\n const handleTableSelect = useCallback(\n (nodeId: string) => {\n setSelectedTable(nodeId);\n const node = nodes.find((n) => n.id === nodeId);\n if (node) {\n reactFlowInstance.setCenter(\n node.position.x + 140,\n node.position.y + 60,\n { zoom: 1.2,\nduration: 400 }\n );\n }\n },\n [nodes, reactFlowInstance]\n );\n\n // Sidebar panel size\n const [sidebarSize, setSidebarSize] = useState(() => {\n try {\n const saved = localStorage.getItem(\"rebase_schema_viz_sidebar_size\");\n return saved !== null ? parseFloat(saved) : 20;\n } catch {\n return 20;\n }\n });\n\n useEffect(() => {\n try {\n localStorage.setItem(\n \"rebase_schema_viz_sidebar_size\",\n sidebarSize.toString()\n );\n } catch {\n // Ignore\n }\n }, [sidebarSize]);\n\n // Group collections for sidebar\n const postgresCollections = useMemo(\n () => collections.filter(isPostgresCollection),\n [collections]\n );\n\n const filteredCollections = useMemo(() => {\n if (!searchQuery.trim()) return postgresCollections;\n const q = searchQuery.toLowerCase();\n return postgresCollections.filter(\n (c) =>\n c.name.toLowerCase().includes(q) ||\n c.table?.toLowerCase().includes(q) ||\n c.slug?.toLowerCase().includes(q)\n );\n }, [postgresCollections, searchQuery]);\n\n // Junction table nodes\n const junctionNodes = useMemo(\n () =>\n nodes.filter(\n (n) => (n.data as TableNodeData).isJunction\n ),\n [nodes]\n );\n\n // Stats\n const stats = useMemo(\n () => ({\n tables: tableCount,\n relations: relationCount,\n junctions: junctionNodes.length,\n withRls: postgresCollections.filter(\n (c) =>\n isPostgresCollection(c) &&\n c.securityRules &&\n c.securityRules.length > 0\n ).length\n }),\n [\n tableCount,\n relationCount,\n junctionNodes.length,\n postgresCollections\n ]\n );\n\n return (\n <ResizablePanels\n orientation=\"horizontal\"\n panelSizePercent={sidebarSize}\n onPanelSizeChange={setSidebarSize}\n minPanelSizePx={220}\n firstPanel={\n <div\n className={cls(\n \"flex flex-col h-full w-full bg-white dark:bg-surface-950 border-r\",\n defaultBorderMixin\n )}\n >\n {/* Sidebar header */}\n <div\n className={cls(\n \"flex items-center justify-between px-3 py-2 border-b bg-surface-50 dark:bg-surface-900 min-h-[48px]\",\n defaultBorderMixin\n )}\n >\n <Typography\n variant=\"caption\"\n className=\"font-bold uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark\"\n >\n Tables\n </Typography>\n <Typography\n variant=\"caption\"\n className=\"text-[10px] text-text-disabled dark:text-text-disabled-dark font-mono\"\n >\n {stats.tables}\n </Typography>\n </div>\n\n {/* Search */}\n <div className=\"px-2 py-1.5 border-b border-surface-200/40 dark:border-surface-700/40\">\n <SearchBar\n size=\"smallest\"\n placeholder=\"Filter tables…\"\n onTextSearch={(val) => setSearchQuery(val || \"\")}\n innerClassName=\"text-xs\"\n />\n </div>\n\n {/* Table list */}\n <div className=\"flex-grow overflow-y-auto no-scrollbar p-1\">\n {/* Regular collections */}\n <div className=\"space-y-0.5\">\n {filteredCollections.map((collection) => {\n const table = collection.table ?? collection.slug;\n const nodeId = `table-${table}`;\n const isSelected = selectedTable === nodeId;\n return (\n <div\n key={nodeId}\n onClick={() =>\n handleTableSelect(nodeId)\n }\n className={cls(\n \"flex items-center p-1.5 cursor-pointer rounded transition-colors group\",\n isSelected\n ? \"bg-primary/10 text-primary dark:bg-primary/20 dark:text-primary-light\"\n : \"hover:bg-surface-100 dark:hover:bg-surface-950 text-text-secondary dark:text-text-secondary-dark\"\n )}\n >\n <div className=\"shrink-0 mr-1.5 text-text-disabled dark:text-text-disabled-dark\">\n <IconForView\n collectionOrView={{\n slug: collection.slug,\n name: collection.name,\n icon:\n typeof collection.icon ===\n \"string\"\n ? collection.icon\n : undefined\n }}\n size=\"smallest\"\n />\n </div>\n <div className=\"flex flex-col min-w-0 flex-1\">\n <Typography\n variant=\"caption\"\n className=\"text-xs truncate font-medium\"\n >\n {collection.name}\n </Typography>\n {table !== collection.name && (\n <Typography\n variant=\"caption\"\n className=\"text-[10px] text-text-disabled dark:text-text-disabled-dark font-mono truncate\"\n >\n {table}\n </Typography>\n )}\n </div>\n <div className=\"flex items-center gap-1 shrink-0 ml-1\">\n {isPostgresCollection(collection) &&\n collection.securityRules &&\n collection.securityRules\n .length > 0 && (\n <Tooltip title=\"RLS enabled\">\n <div className=\"w-1.5 h-1.5 rounded-full bg-green-500\"/>\n </Tooltip>\n )}\n {collection.history && (\n <Tooltip title=\"History enabled\">\n <div className=\"w-1.5 h-1.5 rounded-full bg-blue-400\"/>\n </Tooltip>\n )}\n </div>\n </div>\n );\n })}\n </div>\n\n {/* Junction tables */}\n {junctionNodes.length > 0 && (\n <div className=\"mt-3\">\n <Typography\n variant=\"caption\"\n className=\"px-1.5 text-[10px] uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark font-medium\"\n >\n Junction Tables\n </Typography>\n <div className=\"mt-1 space-y-0.5\">\n {junctionNodes.map((node) => {\n const d =\n node.data as TableNodeData;\n const isSelected =\n selectedTable === node.id;\n return (\n <div\n key={node.id}\n onClick={() =>\n handleTableSelect(\n node.id\n )\n }\n className={cls(\n \"flex items-center p-1.5 cursor-pointer rounded transition-colors\",\n isSelected\n ? \"bg-primary/10 text-primary dark:bg-primary/20\"\n : \"hover:bg-surface-100 dark:hover:bg-surface-950 text-text-disabled dark:text-text-disabled-dark\"\n )}\n >\n <svg\n className=\"w-3.5 h-3.5 mr-1.5 shrink-0\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4\"\n />\n </svg>\n <Typography\n variant=\"caption\"\n className=\"text-xs font-mono truncate\"\n >\n {d.tableName}\n </Typography>\n </div>\n );\n })}\n </div>\n </div>\n )}\n </div>\n\n {/* Stats footer */}\n <div\n className={cls(\n \"px-3 py-2 border-t bg-surface-50 dark:bg-surface-900 space-y-1\",\n defaultBorderMixin\n )}\n >\n <div className=\"flex items-center justify-between\">\n <Typography\n variant=\"caption\"\n className=\"text-[10px] text-text-disabled dark:text-text-disabled-dark\"\n >\n Tables\n </Typography>\n <Typography\n variant=\"caption\"\n className=\"text-[10px] font-mono font-medium\"\n >\n {stats.tables}\n </Typography>\n </div>\n <div className=\"flex items-center justify-between\">\n <Typography\n variant=\"caption\"\n className=\"text-[10px] text-text-disabled dark:text-text-disabled-dark\"\n >\n Relations\n </Typography>\n <Typography\n variant=\"caption\"\n className=\"text-[10px] font-mono font-medium\"\n >\n {stats.relations}\n </Typography>\n </div>\n <div className=\"flex items-center justify-between\">\n <Typography\n variant=\"caption\"\n className=\"text-[10px] text-text-disabled dark:text-text-disabled-dark\"\n >\n RLS protected\n </Typography>\n <div className=\"flex items-center gap-1\">\n <div className=\"w-1.5 h-1.5 rounded-full bg-green-500\"/>\n <Typography\n variant=\"caption\"\n className=\"text-[10px] font-mono font-medium\"\n >\n {stats.withRls}\n </Typography>\n </div>\n </div>\n </div>\n </div>\n }\n secondPanel={\n <div className=\"flex-grow flex flex-col min-w-0 h-full w-full bg-white dark:bg-surface-950\">\n {/* Toolbar */}\n <div\n className={cls(\n \"flex items-center justify-between pr-2 border-b bg-white dark:bg-surface-950 min-h-[46px]\",\n defaultBorderMixin\n )}\n >\n <div className=\"flex items-center gap-2 px-4\">\n <Typography\n variant=\"subtitle2\"\n className=\"font-mono text-text-secondary dark:text-text-secondary-dark\"\n >\n Schema Visualizer\n </Typography>\n </div>\n <div className=\"flex shrink-0 items-center gap-1.5\">\n {/* Direction toggle */}\n <div className=\"flex items-center bg-surface-100 dark:bg-surface-950 rounded-md border border-surface-200/40 dark:border-surface-700/40\">\n <Tooltip title=\"Left to right layout\">\n <button\n onClick={() => setDirection(\"LR\")}\n className={cls(\n \"px-2 py-1 text-[10px] font-mono rounded-l-md transition-colors\",\n direction === \"LR\"\n ? \"bg-primary text-white\"\n : \"text-text-secondary dark:text-text-secondary-dark hover:bg-surface-200 dark:hover:bg-surface-700\"\n )}\n >\n LR\n </button>\n </Tooltip>\n <Tooltip title=\"Top to bottom layout\">\n <button\n onClick={() => setDirection(\"TB\")}\n className={cls(\n \"px-2 py-1 text-[10px] font-mono rounded-r-md transition-colors\",\n direction === \"TB\"\n ? \"bg-primary text-white\"\n : \"text-text-secondary dark:text-text-secondary-dark hover:bg-surface-200 dark:hover:bg-surface-700\"\n )}\n >\n TB\n </button>\n </Tooltip>\n </div>\n\n <div className=\"h-4 w-px bg-surface-200 dark:bg-surface-950 mx-0.5\"/>\n\n {/* Fit view */}\n <Tooltip title=\"Fit to view\">\n <IconButton\n size=\"small\"\n onClick={handleFitView}\n >\n <svg\n className=\"w-4 h-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4\"\n />\n </svg>\n </IconButton>\n </Tooltip>\n\n {/* Re-layout */}\n <Tooltip title=\"Re-layout\">\n <IconButton\n size=\"small\"\n onClick={relayout}\n >\n <svg\n className=\"w-4 h-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15\"\n />\n </svg>\n </IconButton>\n </Tooltip>\n </div>\n </div>\n\n {/* Canvas */}\n <div className=\"flex-grow relative\">\n <ReactFlow\n nodes={nodes}\n edges={edges}\n onNodesChange={onNodesChange}\n onEdgesChange={onEdgesChange}\n onNodeClick={handleNodeClick}\n onPaneClick={handlePaneClick}\n nodeTypes={nodeTypes}\n edgeTypes={edgeTypes}\n fitView\n fitViewOptions={{ padding: 0.15 }}\n minZoom={0.1}\n maxZoom={2}\n proOptions={{ hideAttribution: true }}\n className=\"bg-surface-50 dark:bg-surface-950\"\n >\n <Background\n variant={BackgroundVariant.Dots}\n gap={20}\n size={1}\n className=\"!bg-surface-50 dark:!bg-surface-950\"\n color=\"var(--rf-bg-dot, #d4d4d8)\"\n />\n <Controls\n showInteractive={false}\n className=\"!bg-white dark:!bg-surface-900 !border !border-surface-200/40 dark:!border-surface-700/40 !shadow-sm !rounded-lg\"\n />\n <MiniMap\n nodeStrokeColor={(n) => {\n const d = n.data as TableNodeData;\n if (d.isJunction) return \"#a78bfa\";\n if (d.rlsEnabled) return \"#22c55e\";\n return \"#6366f1\";\n }}\n nodeColor={(n) => {\n const d = n.data as TableNodeData;\n if (d.isJunction) return \"#ede9fe\";\n return \"#eef2ff\";\n }}\n maskColor=\"rgba(0,0,0,0.08)\"\n className=\"!bg-white dark:!bg-surface-900 !border !border-surface-200/40 dark:!border-surface-700/40 !shadow-sm !rounded-lg\"\n />\n </ReactFlow>\n\n {/* Legend overlay */}\n <div className=\"absolute bottom-4 left-4 flex items-center gap-3 px-3 py-2 bg-white/90 dark:bg-surface-900/90 backdrop-blur-sm rounded-lg border border-surface-200/40 dark:border-surface-700/40 shadow-sm\">\n <div className=\"flex items-center gap-1.5\">\n <div className=\"w-6 h-0.5 bg-indigo-500 rounded\"/>\n <Typography\n variant=\"caption\"\n className=\"text-[10px] text-text-disabled dark:text-text-disabled-dark\"\n >\n Owning\n </Typography>\n </div>\n <div className=\"flex items-center gap-1.5\">\n <div className=\"w-6 h-0.5 bg-violet-500 rounded\"/>\n <Typography\n variant=\"caption\"\n className=\"text-[10px] text-text-disabled dark:text-text-disabled-dark\"\n >\n M:N\n </Typography>\n </div>\n <div className=\"flex items-center gap-1.5\">\n <div\n className=\"w-6 h-0.5 rounded\"\n style={{\n backgroundImage:\n \"repeating-linear-gradient(90deg, #94a3b8, #94a3b8 4px, transparent 4px, transparent 7px)\"\n }}\n />\n <Typography\n variant=\"caption\"\n className=\"text-[10px] text-text-disabled dark:text-text-disabled-dark\"\n >\n Inverse\n </Typography>\n </div>\n <div className=\"h-3 w-px bg-surface-200 dark:bg-surface-700\"/>\n <div className=\"flex items-center gap-1\">\n <span className=\"text-[9px]\">🔑</span>\n <Typography\n variant=\"caption\"\n className=\"text-[10px] text-text-disabled dark:text-text-disabled-dark\"\n >\n PK\n </Typography>\n </div>\n <div className=\"flex items-center gap-1\">\n <span className=\"text-[9px]\">🔗</span>\n <Typography\n variant=\"caption\"\n className=\"text-[10px] text-text-disabled dark:text-text-disabled-dark\"\n >\n FK\n </Typography>\n </div>\n </div>\n </div>\n </div>\n }\n />\n );\n}\n\n// ─── Outer wrapper (provides ReactFlowProvider) ────────────────────────\n\nexport const SchemaVisualizer = () => {\n const { collections: registryCollections } =\n useStudioCollectionRegistry() as {\n collections?: EntityCollection[];\n };\n\n // Merge registry collections with any passed collections\n const collections = useMemo(() => {\n return registryCollections ?? [];\n }, [registryCollections]);\n\n if (!collections || collections.length === 0) {\n return (\n <div className=\"flex items-center justify-center h-full w-full\">\n <div className=\"text-center space-y-3\">\n <CircularProgress size=\"small\"/>\n <Typography\n variant=\"body2\"\n color=\"secondary\"\n >\n Loading schema…\n </Typography>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex h-full w-full bg-white dark:bg-surface-950 overflow-hidden text-text-primary dark:text-text-primary-dark\">\n <ReactFlowProvider>\n <SchemaVisualizerCanvas collections={collections}/>\n </ReactFlowProvider>\n </div>\n );\n};\n"],"names":["NODE_WIDTH","HEADER_HEIGHT_SINGLE","HEADER_HEIGHT_DOUBLE","ROW_HEIGHT","getHeaderHeight","opts","isJunction","collectionName","tableName","estimateNodeHeight","columnCount","headerHeight","Math","max","getColumnRowY","rowIndex","getLayoutedElements","nodes","edges","direction","g","dagre","graphlib","Graph","setGraph","rankdir","nodesep","ranksep","edgesep","marginx","marginy","setDefaultEdgeLabel","nodeHeights","Map","forEach","node","data","columns","length","headerH","Boolean","h","set","id","setNode","width","height","edge","setEdge","source","target","layout","layoutedNodes","map","nodeWithPosition","get","layoutDirection","position","x","y","TYPE_LABELS","string","number","boolean","date","array","relation","getTypeLabel","type","getCardinalityLabel","cardinality","extractColumns","collection","properties","propName","prop","Object","entries","isPk","isId","values","some","p","isEnum","enum","enumValues","enumProp","Array","isArray","v","String","keys","push","name","typeLabel","isPrimaryKey","isForeignKey","isRequired","validation","required","isPostgresCollection","resolvedRelations","resolveCollectionRelations","rel","localKey","c","relationName","existing","find","buildGraph","collections","tableToNodeId","nodeColumns","getPkHandle","nodeId","cols","pk","getFkHandle","fk","table","slug","nodeData","isUnmanaged","rlsEnabled","securityRules","historyEnabled","history","icon","undefined","processedJunctions","Set","sourceNodeId","relationKey","targetCollection","targetTable","targetNodeId","edgeData","hasJunction","through","hasJoinPath","joinPath","label","has","add","junctionNodeId","junctionColumns","sourceColumn","targetColumn","sourcePk","sourceHandle","targetHandle","markerEnd","MarkerType","ArrowClosed","layoutResult","nodePositions","srcPos","tgtPos","srcBaseHandle","tgtBaseHandle","srcCenterX","tgtCenterX","sourceIsLeft","useSchemaGraph","setDirection","useState","version","setVersion","relayout","useCallback","useEffect","tableCount","relationCount","useMemo","result","isLoading","TableNodeInner","t0","$","_c","selected","t1","midY","floor","col","idx","Position","Right","top","Left","t2","t3","t4","t5","handles","cls","t6","t7","t8","t9","t10","t11","t12","t13","t14","t15","t16","t17","t18","t19","_temp","t20","t21","_temp2","t22","TableNode","memo","col_0","RelationEdgeInner","sourceX","sourceY","targetX","targetY","sourcePosition","targetPosition","getSmoothStepPath","borderRadius","edgePath","labelX","labelY","isInverse","isJoinPath","strokeColor","strokeDasharray","strokeWidth","stroke","transform","pointerEvents","RelationEdge","nodeTypes","tableNode","edgeTypes","relationEdge","SchemaVisualizerCanvas","reactFlowInstance","useReactFlow","layoutedEdges","setNodes","setEdges","selectedTable","setSelectedTable","searchQuery","setSearchQuery","initialFitDone","useRef","onNodesChange","changes","nds","applyNodeChanges","onEdgesChange","eds","applyEdgeChanges","current","timer","setTimeout","fitView","padding","duration","clearTimeout","handleFitView","handleNodeClick","_","handlePaneClick","handleTableSelect","n","setCenter","zoom","sidebarSize","setSidebarSize","saved","localStorage","getItem","parseFloat","setItem","toString","postgresCollections","filter","filteredCollections","trim","q","toLowerCase","includes","junctionNodes","stats","tables","relations","junctions","withRls","defaultBorderMixin","val","isSelected","d","hideAttribution","BackgroundVariant","Dots","backgroundImage","SchemaVisualizer","registryCollections","useStudioCollectionRegistry","Symbol","for"],"mappings":"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"}
package/dist/index.es.js CHANGED
@@ -598,7 +598,7 @@ const StorageView = lazy(() => import("./StorageView-CTqGFhY9.js").then((m) => (
598
598
  const CronJobsView = lazy(() => import("./CronJobsView-CijCToeK.js").then((m) => ({
599
599
  default: m.CronJobsView
600
600
  })));
601
- const SchemaVisualizer = lazy(() => import("./SchemaVisualizer-BgD5Zb77.js").then((m) => ({
601
+ const SchemaVisualizer = lazy(() => import("./SchemaVisualizer-CM8lbrcq.js").then((m) => ({
602
602
  default: m.SchemaVisualizer
603
603
  })));
604
604
  const BranchesView = lazy(() => import("./BranchesView-DcHZtvXo.js").then((m) => ({
package/dist/index.umd.js CHANGED
@@ -8127,7 +8127,7 @@ return result;
8127
8127
  /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "caption", className: "font-bold uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark", children: "Tables" }),
8128
8128
  /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "caption", className: "text-[10px] text-text-disabled dark:text-text-disabled-dark font-mono", children: stats.tables })
8129
8129
  ] }),
8130
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2 py-1.5 border-b border-surface-200/40 dark:border-surface-700/40", children: /* @__PURE__ */ jsxRuntime.jsx(ui.TextField, { size: "smallest", placeholder: "Filter tables…", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), inputClassName: "text-xs" }) }),
8130
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2 py-1.5 border-b border-surface-200/40 dark:border-surface-700/40", children: /* @__PURE__ */ jsxRuntime.jsx(ui.SearchBar, { size: "smallest", placeholder: "Filter tables…", onTextSearch: (val) => setSearchQuery(val || ""), innerClassName: "text-xs" }) }),
8131
8131
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-grow overflow-y-auto no-scrollbar p-1", children: [
8132
8132
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-0.5", children: filteredCollections.map((collection) => {
8133
8133
  const table = collection.table ?? collection.slug;