@nbt-dev/components 0.0.9 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-WBZS7I6V.js → chunk-AI2LKTA4.js} +30 -2
- package/dist/chunk-AI2LKTA4.js.map +7 -0
- package/dist/{chunk-235TYE66.js → chunk-BNA2MLFE.js} +151 -17
- package/dist/chunk-BNA2MLFE.js.map +7 -0
- package/dist/{chunk-VDIHQ2NS.js → chunk-HTAPMIK6.js} +11 -3
- package/dist/chunk-HTAPMIK6.js.map +7 -0
- package/dist/{chunk-S7VBQE6Y.js → chunk-PI7ZMVVU.js} +162 -33
- package/dist/chunk-PI7ZMVVU.js.map +7 -0
- package/dist/core/auth.d.ts +2 -0
- package/dist/core/index.d.ts +1 -1
- package/dist/core/use-cartridge-info.d.ts +1 -0
- package/dist/editor/editor-themes.d.ts +8 -0
- package/dist/editor/index.d.ts +2 -0
- package/dist/editor/index.js +7 -3
- package/dist/editor/nbt-editor.d.ts +4 -0
- package/dist/graph/index.js +2 -2
- package/dist/index.js +20 -8
- package/dist/index.js.map +2 -2
- package/dist/styles.css +1 -1
- package/dist/table/column-widths.d.ts +2 -0
- package/dist/table/index.js +2 -2
- package/package.json +3 -2
- package/src/core/auth.ts +40 -0
- package/src/core/data-store.ts +5 -1
- package/src/core/index.ts +2 -0
- package/src/core/use-cartridge-info.ts +15 -4
- package/src/editor/editor-themes.ts +128 -0
- package/src/editor/index.ts +2 -0
- package/src/editor/nbt-editor.tsx +60 -26
- package/src/graph/diagram.tsx +16 -0
- package/src/table/column-widths.ts +34 -0
- package/src/table/data-table.tsx +141 -15
- package/dist/chunk-235TYE66.js.map +0 -7
- package/dist/chunk-S7VBQE6Y.js.map +0 -7
- package/dist/chunk-VDIHQ2NS.js.map +0 -7
- package/dist/chunk-WBZS7I6V.js.map +0 -7
|
@@ -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 useStore,\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 // Container dimensions tracked by ReactFlow's store; change when the canvas is\n // resized (window, sidebar, or the selection rail opening on the right).\n const width = useStore((s) => s.width);\n const height = useStore((s) => s.height);\n\n React.useEffect(() => {\n if (initialized) fitView({ padding: 0.25, duration: 200 });\n }, [initialized, fitKey, fitView]);\n\n // When the selection rail opens it shrinks the canvas; without a refit a node\n // near the right edge ends up hidden behind the rail. Refit on any resize,\n // debounced so dragging the rail's resize handle stays smooth.\n React.useEffect(() => {\n if (!initialized || width === 0 || height === 0) return;\n const t = setTimeout(() => fitView({ padding: 0.25, duration: 200 }), 120);\n return () => clearTimeout(t);\n }, [width, height, initialized, fitView]);\n\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": ";;;;;;;;AAAA,OAAO,WAAW;AAClB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;;;ACZP,SAAS,QAAQ,gBAAgC;AACjD,SAAS,UAAU,UAAU,UAAU,aAAa;AAmC5C,SA2BU,UA1BR,KADF;AAnBD,SAAS,WAAW,EAAE,MAAM,SAAS,GAAc;AACxD,QAAM,OAAO;AACb,QAAM,YAAY,KAAK;AACvB,QAAM,oBAAoB,IAAI,IAAI,WAAW,UAAU,CAAC,CAAC;AACzD,QAAM,oBAAoB;AAC1B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA,WAAW,UACP,4CACA,WAAW,YACT,+CACA;AAAA,QACN,WAAW,SAAS,eAAe;AAAA,QACnC,YAAY,CAAC,WAAW,UAAU,4BAA4B;AAAA,MAChE,EAAE,KAAK,GAAG;AAAA,MAEV;AAAA,6BAAC,SAAI,WAAU,+DACb;AAAA,+BAAC,SAAI,WAAU,mCACb;AAAA,gCAAC,YAAS,WAAU,sCAAqC;AAAA,YACzD,oBAAC,UAAK,WAAU,+EACb,eAAK,QACR;AAAA,aACF;AAAA,UACA,oBAAC,SAAI,WAAU,2CAA2C,eAAK,WAAU;AAAA,WAC3E;AAAA,QACA,oBAAC,SAAI,WAAU,oBACZ,eAAK,OAAO,WAAW,IACtB,oBAAC,SAAI,WAAU,uCAAsC,uBAAS,IAE9D,KAAK,OAAO,IAAI,CAAC,UAAU;AACzB,gBAAM,OAAO,GAAG,MAAM,IAAI,GAAG,MAAM,QAAQ,OAAO,EAAE,GAAG,MAAM,WAAW,MAAM,EAAE;AAChF,gBAAM,OAAO,MAAM,YAAY,YAAY,MAAM;AACjD,gBAAM,aAAa,MAAM,SAAS;AAClC,gBAAM,aAAa,MAAM,SAAS;AAClC,gBAAM,mBAAmB,kBAAkB,IAAI,MAAM,WAAW;AAChE,iBACE;AAAA,YAAC;AAAA;AAAA,cAEC,WAAW;AAAA,gBACT;AAAA,gBACA,mBAAmB,iCAAiC;AAAA,cACtD,EAAE,KAAK,GAAG;AAAA,cAET;AAAA,uBACC,iCACE;AAAA;AAAA,oBAAC;AAAA;AAAA,sBACC,IAAI,UAAU,MAAM,WAAW;AAAA,sBAC/B,MAAK;AAAA,sBACL,UAAU,SAAS;AAAA,sBACnB,WAAW,WAAW,iBAAiB;AAAA,sBACvC,OAAO,EAAE,KAAK,MAAM;AAAA;AAAA,kBACtB;AAAA,kBACA;AAAA,oBAAC;AAAA;AAAA,sBACC,IAAI,UAAU,MAAM,WAAW;AAAA,sBAC/B,MAAK;AAAA,sBACL,UAAU,SAAS;AAAA,sBACnB,WAAW,YAAY,iBAAiB;AAAA,sBACxC,OAAO,EAAE,KAAK,MAAM;AAAA;AAAA,kBACtB;AAAA,mBACF,IACE;AAAA,gBACH,aACC,iCACE;AAAA;AAAA,oBAAC;AAAA;AAAA,sBACC,IAAI,UAAU,MAAM,WAAW;AAAA,sBAC/B,MAAK;AAAA,sBACL,UAAU,SAAS;AAAA,sBACnB,WAAW,WAAW,iBAAiB;AAAA,sBACvC,OAAO,EAAE,KAAK,MAAM;AAAA;AAAA,kBACtB;AAAA,kBACA;AAAA,oBAAC;AAAA;AAAA,sBACC,IAAI,UAAU,MAAM,WAAW;AAAA,sBAC/B,MAAK;AAAA,sBACL,UAAU,SAAS;AAAA,sBACnB,WAAW,YAAY,iBAAiB;AAAA,sBACxC,OAAO,EAAE,KAAK,MAAM;AAAA;AAAA,kBACtB;AAAA,mBACF,IACE;AAAA,gBACJ,qBAAC,UAAK,WAAU,qCACb;AAAA,yBAAO,oBAAC,YAAS,WAAU,kCAAiC,IAAK;AAAA,kBACjE,aACC,oBAAC,SAAM,WAAW,CAAC,oBAAoB,mBAAmB,kBAAkB,eAAe,EAAE,KAAK,GAAG,GAAG,IACtG;AAAA,kBACH,aAAa,oBAAC,YAAS,WAAU,kCAAiC,IAAK;AAAA,kBACxE,oBAAC,UAAK,WAAU,YAAY,gBAAM,aAAY;AAAA,mBAChD;AAAA,gBACA,oBAAC,UAAK,WAAU,kDAAkD,gBAAK;AAAA;AAAA;AAAA,YAlDlE,GAAG,MAAM,IAAI,IAAI,MAAM,WAAW;AAAA,UAmDzC;AAAA,QAEJ,CAAC,GAEL;AAAA,QACA,qBAAC,SAAI,WAAU,mIACb;AAAA,+BAAC,UAAK,WAAU,gBAAgB;AAAA,iBAAK,SAAS,eAAe;AAAA,YAAE;AAAA,aAAK;AAAA,UACpE,qBAAC,UAAK,WAAU,gBACb;AAAA,iBAAK;AAAA,YAAc;AAAA,YAAQ,KAAK;AAAA,YAAY;AAAA,aAC/C;AAAA,WACF;AAAA;AAAA;AAAA,EACF;AAEJ;;;AC7GA,OAAO,WAAW;AA6ElB,IAAM,aAAa;AACnB,IAAM,kBAAkB;AACxB,IAAM,mBAAmB;AACzB,IAAM,eAAe;AAqBd,SAAS,mBAAmB,WAAyC;AAC1E,QAAM,QAA0B,CAAC;AACjC,aAAW,KAAK,WAAW;AACzB,QAAI,CAAC,EAAE,aAAa,CAAC,EAAE,KAAM;AAC7B,UAAM,WAA+B,CAAC;AACtC,eAAW,CAAC,MAAM,GAAG,KAAK,OAAO,QAAQ,EAAE,IAAI,GAAG;AAChD,YAAM,UAA6B,IAAI,UAAU,CAAC,GAAG,IAAI,CAAC,OAAO;AAAA,QAC/D,MAAM,EAAE;AAAA,QACR,MAAM,EAAE;AAAA,QACR,UAAU,EAAE;AAAA,QACZ,OAAO,EAAE;AAAA,QACT,MAAM,EAAE;AAAA,QACR,QAAQ,EAAE;AAAA,QACV,YAAY,EAAE;AAAA,QACd,cAAc,EAAE;AAAA,QAChB,SAAS,EAAE;AAAA,MACb,EAAE;AACF,eAAS,KAAK,EAAE,MAAM,OAAO,CAAC;AAAA,IAChC;AACA,QAAI,SAAS,SAAS,EAAG,OAAM,KAAK,EAAE,MAAM,EAAE,WAAW,SAAS,CAAC;AAAA,EACrE;AACA,SAAO;AACT;AAEO,SAAS,cAAc,WAAmB,QAAwB;AACvE,SAAO,GAAG,SAAS,IAAI,MAAM;AAC/B;AAEA,SAAS,UAAU,OAAgC;AACjD,SAAO,MAAM,SAAS,MAAM,SAAS,aAAa;AACpD;AAEA,SAAS,WAAW,OAA0C;AAC5D,QAAM,OAAO,UAAU,KAAK;AAC5B,SAAO;AAAA,IACL,MAAM,MAAM;AAAA,IACZ,aAAa,SAAS,aAAc,MAAM,WAAW,MAAM,OAAQ,MAAM;AAAA,IACzE,MAAM,SAAS,cAAc,MAAM,SAAS,MAAM,SAAS,MAAM;AAAA,IACjE;AAAA,IACA,UAAU,MAAM,aAAa;AAAA,IAC7B,OAAO,MAAM,UAAU;AAAA,IACvB,QAAQ,MAAM;AAAA,IACd,YAAY,MAAM;AAAA,IAClB,cAAc,MAAM;AAAA,IACpB,SAAS,MAAM;AAAA,EACjB;AACF;AAEA,SAAS,gBAAgB,QAA+C;AACtE,QAAM,MAAM,OAAO,IAAI,UAAU;AACjC,MAAI,CAAC,IAAI,KAAK,CAAC,UAAU,MAAM,YAAY,YAAY,MAAM,IAAI,GAAG;AAClE,QAAI,QAAQ;AAAA,MACV,MAAM;AAAA,MACN,aAAa;AAAA,MACb,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,OAAO;AAAA,MACP,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,SAAS,cAAc,OAAuB;AAC5C,SAAO,MAAM,QAAQ,iBAAiB,EAAE,EAAE,YAAY;AACxD;AAEA,SAAS,MAAM,OAAyB;AACtC,SAAO,MACJ,QAAQ,sBAAsB,OAAO,EACrC,MAAM,eAAe,EACrB,IAAI,CAAC,SAAS,KAAK,YAAY,CAAC,EAChC,OAAO,OAAO;AACnB;AAEA,SAAS,cAAc,QAA0B;AAC/C,QAAM,QAAQ,MAAM,MAAM;AAC1B,QAAM,UAAU,oBAAI,IAAY,CAAC,cAAc,MAAM,CAAC,CAAC;AACvD,QAAM,OAAO,MAAM,SAAS,IAAI,MAAM,MAAM,SAAS,CAAC,IAAI;AAC1D,MAAI,KAAM,SAAQ,IAAI,IAAI;AAC1B,MAAI,MAAM,SAAS,KAAK,MAAM;AAC5B,YAAQ,IAAI,GAAG,MAAM,MAAM,GAAG,EAAE,EAAE,IAAI,CAAC,SAAS,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE;AAC1E,YAAQ,IAAI,MAAM,IAAI,CAAC,SAAS,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;AAAA,EACnD;AACA,SAAO,CAAC,GAAG,OAAO,EAAE,OAAO,CAAC,UAAU,MAAM,UAAU,CAAC;AACzD;AAEA,SAAS,gBAAgB,WAAmB,OAAkD;AAC5F,MAAI,CAAC,OAAO,KAAK,SAAS,KAAK,QAAQ,KAAK,SAAS,EAAG,QAAO;AAC/D,QAAM,OAAO,cAAc,UAAU,QAAQ,QAAQ,EAAE,CAAC;AACxD,MAAI,KAAK,SAAS,EAAG,QAAO;AAE5B,QAAM,aAAa,MAChB;AAAA,IAAQ,CAAC,SACR,cAAc,KAAK,MAAM,EAAE,IAAI,CAAC,UAAU;AACxC,YAAM,QAAQ,SAAS;AACvB,YAAM,SAAS,CAAC,SAAS,MAAM,UAAU,KAAK,KAAK,SAAS,KAAK;AACjE,UAAI,CAAC,SAAS,CAAC,OAAQ,QAAO;AAC9B,aAAO;AAAA,QACL;AAAA,QACA,QAAQ,QAAQ,MAAO,OAAO,MAAM;AAAA,MACtC;AAAA,IACF,CAAC;AAAA,EACH,EACC,OAAO,CAAC,cAAqE,cAAc,IAAI,EAC/F,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,OAAO,cAAc,EAAE,KAAK,MAAM,CAAC;AAEjF,QAAM,QAAQ,WAAW,CAAC;AAC1B,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,SAAS,WAAW,CAAC;AAC3B,MAAI,UAAU,MAAM,UAAU,OAAO,MAAO,QAAO;AACnD,SAAO,MAAM;AACf;AAEA,SAAS,kBAAkB,MAAmC,WAAmB,QAAyB;AACxG,QAAM,QAAQ,MAAM,OAAO;AAAA,IACzB,CAAC,cAAc,UAAU,gBAAgB,aAAa,UAAU,SAAS;AAAA,EAC3E;AACA,MAAI,CAAC,SAAS,MAAM,YAAY,YAAY,MAAM,KAAM;AACxD,QAAM,OAAO;AACb,QAAM,SAAS,OAAO;AACtB,QAAM,aAAa,OAAO;AAC1B,QAAM,iBAAN,MAAM,eAAiB;AACvB,QAAM,YAAN,MAAM,UAAY;AACpB;AAEA,SAAS,oBAAoB,OAA0B;AACrD,aAAW,QAAQ,OAAO;AACxB,SAAK,cAAc,KAAK,OAAO,OAAO,CAAC,UAAU,MAAM,SAAS,QAAQ,EAAE;AAC1E,SAAK,gBAAgB,KAAK,OAAO,OAAO,CAAC,UAAU,MAAM,SAAS,UAAU,EAAE;AAC9E,SAAK,gBAAgB,KAAK,OAAO,OAAO,CAAC,UAAU,MAAM,SAAS,UAAU,EAAE;AAAA,EAChF;AACF;AAEA,SAAS,WAAW,MAA+B;AACjD,SAAO,KAAK,IAAI,iBAAiB,KAAK,KAAK,OAAO,SAAS,gBAAgB;AAC7E;AAKA,SAAS,YAAY,OAA0B,OAA0B;AACvE,QAAM,SAAS,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAClD,aAAW,QAAQ,OAAO;AACxB,WAAO,IAAI,KAAK,SAAS,OAAO,IAAI,KAAK,MAAM,KAAK,KAAK,CAAC;AAC1D,WAAO,IAAI,KAAK,SAAS,OAAO,IAAI,KAAK,MAAM,KAAK,KAAK,CAAC;AAAA,EAC5D;AAEA,QAAM,YAAY,MAAM,OAAO,CAAC,OAAO,OAAO,IAAI,EAAE,EAAE,KAAK,KAAK,CAAC;AACjE,QAAM,WAAW,MAAM,OAAO,CAAC,OAAO,OAAO,IAAI,EAAE,EAAE,KAAK,OAAO,CAAC;AAClE,QAAM,eAAe,IAAI,IAAI,UAAU,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAEvD,MAAI,OAAO;AACX,MAAI,OAAO;AAEX,MAAI,UAAU,SAAS,GAAG;AACxB,UAAM,IAAI,IAAI,MAAM,SAAS,MAAM;AACnC,MAAE,SAAS,EAAE,SAAS,MAAM,SAAS,KAAK,SAAS,IAAI,SAAS,IAAI,SAAS,GAAG,CAAC;AACjF,MAAE,oBAAoB,OAAO,CAAC,EAAE;AAChC,eAAW,QAAQ,WAAW;AAC5B,QAAE,QAAQ,KAAK,IAAI,EAAE,OAAO,YAAY,QAAQ,WAAW,IAAI,EAAE,CAAC;AAAA,IACpE;AACA,eAAW,QAAQ,OAAO;AAGxB,UAAI,KAAK,WAAW,KAAK,OAAQ;AACjC,UAAI,CAAC,aAAa,IAAI,KAAK,MAAM,KAAK,CAAC,aAAa,IAAI,KAAK,MAAM,EAAG;AACtE,QAAE,QAAQ,KAAK,QAAQ,KAAK,MAAM;AAAA,IACpC;AACA,UAAM,OAAO,CAAC;AACd,eAAW,QAAQ,WAAW;AAC5B,YAAM,IAAI,EAAE,KAAK,KAAK,EAAE;AACxB,YAAM,IAAI,WAAW,IAAI;AACzB,WAAK,WAAW,EAAE,GAAG,EAAE,IAAI,aAAa,GAAG,GAAG,EAAE,IAAI,IAAI,EAAE;AAC1D,aAAO,KAAK,IAAI,MAAM,KAAK,SAAS,IAAI,UAAU;AAClD,aAAO,KAAK,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC;AAAA,IAC3C;AAAA,EACF;AAGA,MAAI,SAAS,SAAS,GAAG;AACvB,aAAS,KAAK,CAAC,GAAG,MAAM,EAAE,OAAO,cAAc,EAAE,MAAM,CAAC;AACxD,UAAM,SAAS,UAAU,SAAS,IAAI,OAAO,eAAe;AAC5D,UAAM,YAAY,KAAK,IAAI,GAAG,KAAK,KAAK,SAAS,SAAS,KAAK,KAAK,SAAS,SAAS,CAAC,CAAC,CAAC;AACzF,QAAI,IAAI;AACR,QAAI,IAAI;AACR,QAAI,WAAW;AACf,eAAW,QAAQ,UAAU;AAC3B,WAAK,WAAW,EAAE,GAAG,EAAE;AACvB,WAAK,WAAW,IAAI,IAAI;AACxB,kBAAY;AACZ,UAAI,YAAY,WAAW;AACzB,mBAAW;AACX,YAAI;AACJ,aAAK;AAAA,MACP;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,WAAW,OAA0B,OAA6C;AACzF,SAAO;AAAA,IACL,UAAU,MAAM;AAAA,IAChB,eAAe,MAAM;AAAA,IACrB,MAAM,MAAM,OAAO,CAAC,KAAK,SAAS,MAAM,KAAK,UAAU,CAAC;AAAA,EAC1D;AACF;AAEO,SAAS,sBAAsB,YAAgD;AACpF,QAAM,cAAc,CAAC,GAAG,UAAU,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAC/E,QAAM,QAA2B,CAAC;AAElC,cAAY,QAAQ,CAAC,MAAM,cAAc;AACvC,UAAM,WAAW,CAAC,GAAG,KAAK,QAAQ,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAC/E,QAAI,IAAI;AACR,aAAS,QAAQ,CAAC,WAAW;AAC3B,YAAM,KAAK,cAAc,KAAK,MAAM,OAAO,IAAI;AAC/C,YAAM,SAAS,OAAO,UAAU,CAAC;AACjC,YAAM,cAAc,gBAAgB,MAAM;AAC1C,YAAM,KAAK;AAAA,QACT;AAAA,QACA,WAAW,KAAK;AAAA,QAChB,QAAQ,OAAO;AAAA,QACf,QAAQ;AAAA,QACR,YAAY,YAAY;AAAA,QACxB,aAAa,YAAY,OAAO,CAAC,UAAU,MAAM,SAAS,QAAQ,EAAE;AAAA,QACpE,eAAe,YAAY,OAAO,CAAC,UAAU,MAAM,SAAS,UAAU,EAAE;AAAA,QACxE,eAAe,YAAY,OAAO,CAAC,UAAU,MAAM,SAAS,UAAU,EAAE;AAAA,QACxE,UAAU;AAAA,QACV,UAAU,EAAE,GAAG,YAAY,cAAc,EAAE;AAAA,MAC7C,CAAC;AACD,WAAK,KAAK,IAAI,iBAAiB,KAAK,YAAY,SAAS,gBAAgB,IAAI;AAAA,IAC/E,CAAC;AAAA,EACH,CAAC;AAED,QAAM,UAAU,IAAI,IAAI,MAAM,IAAI,CAAC,SAAS,KAAK,EAAE,CAAC;AACpD,QAAM,WAAW,IAAI,IAAI,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC;AAC7D,QAAM,QAA2B,CAAC;AAClC,QAAM,WAAW,oBAAI,IAAY;AACjC,aAAW,QAAQ,aAAa;AAC9B,eAAW,UAAU,KAAK,UAAU;AAClC,YAAM,SAAS,cAAc,KAAK,MAAM,OAAO,IAAI;AACnD,YAAM,aAAa,SAAS,IAAI,MAAM;AACtC,iBAAW,SAAS,OAAO,UAAU,CAAC,GAAG;AACvC,cAAM,mBAAmB,UAAU,KAAK,MAAM,cAAc,CAAC,CAAC,MAAM;AACpE,cAAM,qBAAqB,mBAAmB,OAAO,gBAAgB,MAAM,MAAM,KAAK;AACtF,YAAI,CAAC,oBAAoB,CAAC,mBAAoB;AAE9C,cAAM,aAAa,mBACf,MAAM,cAAc,KAAK,OACzB,oBAAoB;AACxB,cAAM,eAAe,mBAAmB,MAAM,SAAS,oBAAoB;AAC3E,YAAI,CAAC,cAAc,CAAC,aAAc;AAClC,cAAM,SAAS,cAAc,YAAY,YAAY;AACrD,YAAI,CAAC,QAAQ,IAAI,MAAM,KAAK,CAAC,QAAQ,IAAI,MAAM,EAAG;AAClD,cAAM,aAAa,SAAS,IAAI,MAAM;AACtC,cAAM,UAAU,YAAY,OAAO,KAAK,CAAC,cAAc,UAAU,YAAY,YAAY,MAAM,IAAI;AACnG,cAAM,cAAc,SAAS,eAAe;AAC5C,cAAM,mBAAmB,YAAY,OAAO;AAAA,UAC1C,CAAC,cAAc,UAAU,SAAS,MAAM,QAAQ,UAAU,gBAAgB,MAAM;AAAA,QAClF;AACA,cAAM,cAAc,kBAAkB,eAAe,MAAM,WAAW,MAAM;AAC5E,cAAM,UAAU,GAAG,MAAM,IAAI,WAAW,KAAK,MAAM,IAAI,WAAW;AAClE,YAAI,SAAS,IAAI,OAAO,EAAG;AAC3B,iBAAS,IAAI,OAAO;AACpB,YAAI,CAAC,oBAAoB,WAAY,mBAAkB,YAAY,aAAa,UAAU;AAC1F,cAAM,KAAK;AAAA,UACT,IAAI,GAAG,MAAM,IAAI,MAAM,IAAI,KAAK,MAAM;AAAA,UACtC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,OAAO,MAAM;AAAA,UACb,cAAc,MAAM,iBAAiB,CAAC,mBAAmB,aAAa;AAAA,UACtE,SAAS,MAAM,YAAY,CAAC,mBAAmB,MAAM,OAAO;AAAA,QAC9D,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,sBAAoB,KAAK;AAEzB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,QAAQ,WAAW,OAAO,KAAK;AAAA,EACjC;AACF;AAMO,SAAS,uBACd,OACA,YACkB;AAClB,QAAM,QAAQ,MAAM,MACjB,OAAO,CAAC,SAAS,WAAW,IAAI,KAAK,EAAE,CAAC,EACxC,IAAI,CAAC,UAAU,EAAE,GAAG,MAAM,UAAU,EAAE,GAAG,KAAK,SAAS,EAAE,EAAE;AAC9D,QAAM,MAAM,IAAI,IAAI,MAAM,IAAI,CAAC,SAAS,KAAK,EAAE,CAAC;AAChD,QAAM,QAAQ,MAAM,MAAM,OAAO,CAAC,SAAS,IAAI,IAAI,KAAK,MAAM,KAAK,IAAI,IAAI,KAAK,MAAM,CAAC;AACvF,cAAY,OAAO,KAAK;AACxB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,QAAQ,WAAW,OAAO,KAAK;AAAA,EACjC;AACF;;;AF/RW,gBAAAA,MAkJC,QAAAC,aAlJD;AAzGX,IAAM,YAAY,EAAE,QAAQ,WAAW;AAKvC,IAAM,aAA2C,CAAC,EAAE,OAAO,MAAM;AAC/D,QAAM,cAAc,oBAAoB;AACxC,QAAM,EAAE,QAAQ,IAAI,aAAa;AAGjC,QAAM,QAAQ,SAAS,CAAC,MAAM,EAAE,KAAK;AACrC,QAAM,SAAS,SAAS,CAAC,MAAM,EAAE,MAAM;AAEvC,QAAM,UAAU,MAAM;AACpB,QAAI,YAAa,SAAQ,EAAE,SAAS,MAAM,UAAU,IAAI,CAAC;AAAA,EAC3D,GAAG,CAAC,aAAa,QAAQ,OAAO,CAAC;AAKjC,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,eAAe,UAAU,KAAK,WAAW,EAAG;AACjD,UAAM,IAAI,WAAW,MAAM,QAAQ,EAAE,SAAS,MAAM,UAAU,IAAI,CAAC,GAAG,GAAG;AACzE,WAAO,MAAM,aAAa,CAAC;AAAA,EAC7B,GAAG,CAAC,OAAO,QAAQ,aAAa,OAAO,CAAC;AAExC,SAAO;AACT;AAMA,SAAS,eAAe;AACtB,QAAM,EAAE,WAAW,IAAI,kBAAkB;AACzC,QAAM,CAAC,WAAW,YAAY,IAAI,MAAM,SAAqB,CAAC,CAAC;AAC/D,QAAM,CAAC,SAAS,UAAU,IAAI,MAAM,SAAS,IAAI;AACjD,QAAM,CAAC,OAAO,QAAQ,IAAI,MAAM,SAAwB,IAAI;AAE5D,QAAM,UAAU,MAAM;AACpB,UAAM,KAAK,IAAI,gBAAgB;AAC/B,QAAI,YAAY;AAChB,KAAC,YAAY;AACX,UAAI;AACF,cAAM,IAAI,MAAM,MAAM,GAAG,UAAU,uBAAuB;AAAA,UACxD,QAAQ,GAAG;AAAA,UACX,aAAa;AAAA,UACb,SAAS,YAAY;AAAA,QACvB,CAAC;AACD,YAAI,CAAC,EAAE,GAAI,OAAM,IAAI,MAAM,QAAQ,EAAE,MAAM,EAAE;AAC7C,cAAM,OAAQ,MAAM,EAAE,KAAK;AAC3B,YAAI,CAAC,MAAM,QAAQ,IAAI,EAAG,OAAM,IAAI,MAAM,8BAA8B;AACxE,YAAI,CAAC,UAAW,cAAa,IAAI;AAAA,MACnC,SAAS,GAAG;AACV,YAAI,aAAc,EAAwB,SAAS,aAAc;AACjE,iBAAS,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC;AAAA,MACrD,UAAE;AACA,YAAI,CAAC,UAAW,YAAW,KAAK;AAAA,MAClC;AAAA,IACF,GAAG;AACH,WAAO,MAAM;AACX,kBAAY;AACZ,SAAG,MAAM;AAAA,IACX;AAAA,EACF,GAAG,CAAC,UAAU,CAAC;AAEf,SAAO,EAAE,WAAW,SAAS,MAAM;AACrC;AAKA,SAAS,sBAAsB,WAAqC;AAClE,QAAM,MAAoB,CAAC;AAC3B,aAAW,KAAK,WAAW;AACzB,QAAI,CAAC,EAAE,aAAa,CAAC,EAAE,KAAM;AAC7B,UAAM,WAAW,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU;AAAA,MAClD;AAAA,MACA,OAAO,aAAa,EAAE,SAAS,IAAI,KAAK,YAAY,CAAC;AAAA,MACrD,cAAc,CAAC;AAAA,IACjB,EAAE;AACF,QAAI,SAAS,SAAS,EAAG,KAAI,EAAE,SAAS,IAAI;AAAA,EAC9C;AACA,SAAO;AACT;AAKO,IAAM,cAGR,CAAC,EAAE,YAAY,aAAa,MAAM;AACrC,QAAM,EAAE,WAAW,SAAS,MAAM,IAAI,aAAa;AAEnD,QAAM,QAAQ,MAAM;AAAA,IAClB,MAAM,sBAAsB,mBAAmB,SAAS,CAAC;AAAA,IACzD,CAAC,SAAS;AAAA,EACZ;AACA,QAAM,WAAW,MAAM,QAAQ,MAAM,sBAAsB,SAAS,GAAG,CAAC,SAAS,CAAC;AAElF,MAAI,MAAM,MAAM,WAAW,GAAG;AAC5B,QAAI,MAAM;AACV,QAAI,QAAS,OAAM;AAAA,aACV,MAAO,OAAM,6BAA6B,KAAK;AACxD,WAAO,gBAAAD,KAAC,SAAI,WAAU,yCAAyC,eAAI;AAAA,EACrE;AAEA,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,EACF;AAEJ;AAEA,IAAM,eAKD,CAAC,EAAE,OAAO,UAAU,YAAY,aAAa,MAAM;AACtD,QAAM,YAAY,iBAAiB,QAAQ;AAC3C,QAAM,CAAC,eAAe,gBAAgB,IAAI,MAAM,SAAwB,IAAI;AAE5E,QAAM,eAAe,MAAM;AAAA,IACzB,MAAM,uBAAuB,OAAO,UAAU;AAAA,IAC9C,CAAC,OAAO,UAAU;AAAA,EACpB;AAEA,QAAM,UAAU,MAAM;AACpB,QAAI,iBAAiB,CAAC,WAAW,IAAI,aAAa,EAAG,kBAAiB,IAAI;AAAA,EAC5E,GAAG,CAAC,eAAe,UAAU,CAAC;AAE9B,QAAM,qBAAqB,MAAM,QAAQ,MAAM;AAC7C,QAAI,CAAC,eAAe;AAClB,aAAO;AAAA,QACL,cAAc,oBAAI,IAAY;AAAA,QAC9B,SAAS,oBAAI,IAAY;AAAA,QACzB,cAAc,oBAAI,IAAyB;AAAA,MAC7C;AAAA,IACF;AACA,UAAM,eAAe,oBAAI,IAAY,CAAC,aAAa,CAAC;AACpD,UAAM,UAAU,oBAAI,IAAY;AAChC,UAAM,eAAe,oBAAI,IAAyB;AAClD,UAAM,WAAW,CAAC,QAAgB,cAAsB;AACtD,YAAM,SAAS,aAAa,IAAI,MAAM,KAAK,oBAAI,IAAY;AAC3D,aAAO,IAAI,SAAS;AACpB,mBAAa,IAAI,QAAQ,MAAM;AAAA,IACjC;AACA,eAAW,QAAQ,aAAa,OAAO;AACrC,UAAI,KAAK,WAAW,iBAAiB,KAAK,WAAW,cAAe;AACpE,cAAQ,IAAI,KAAK,EAAE;AACnB,mBAAa,IAAI,KAAK,MAAM;AAC5B,mBAAa,IAAI,KAAK,MAAM;AAC5B,eAAS,KAAK,QAAQ,KAAK,WAAW;AACtC,eAAS,KAAK,QAAQ,KAAK,WAAW;AAAA,IACxC;AACA,WAAO,EAAE,cAAc,SAAS,aAAa;AAAA,EAC/C,GAAG,CAAC,eAAe,aAAa,KAAK,CAAC;AAEtC,QAAM,QAAgB,MAAM;AAAA,IAC1B,MACE,aAAa,MAAM,IAAI,CAAC,UAAU;AAAA,MAChC,IAAI,KAAK;AAAA,MACT,MAAM;AAAA,MACN,UAAU,KAAK;AAAA,MACf,MAAM;AAAA,QACJ,GAAG;AAAA,QACH,UAAU,UAAU,KAAK,EAAE,KAAK,KAAK;AAAA,QACrC,WAAW,gBACP;AAAA,UACE,SAAS,KAAK,OAAO;AAAA,UACrB,WAAW,mBAAmB,aAAa,IAAI,KAAK,EAAE,KAAK,KAAK,OAAO;AAAA,UACvE,QAAQ,CAAC,mBAAmB,aAAa,IAAI,KAAK,EAAE;AAAA,UACpD,QAAQ,CAAC,GAAI,mBAAmB,aAAa,IAAI,KAAK,EAAE,KAAK,CAAC,CAAE;AAAA,QAClE,IACA;AAAA,MACN;AAAA,IACF,EAAE;AAAA,IACJ,CAAC,oBAAoB,eAAe,aAAa,OAAO,SAAS;AAAA,EACnE;AAEA,QAAM,QAA0B,MAAM,QAAQ,MAAM;AAClD,UAAM,WAAW,IAAI,IAAI,aAAa,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC;AAC1E,UAAM,aAAa,oBAAI,IAAoB;AAC3C,WAAO,aAAa,MAAM,IAAI,CAAC,SAAS;AACtC,YAAM,SAAS,SAAS,IAAI,KAAK,MAAM;AACvC,YAAM,SAAS,SAAS,IAAI,KAAK,MAAM;AACvC,YAAM,aAAa,UAAU,UAAU,OAAO,SAAS,IAAI,OAAO,SAAS,IAAI,SAAS;AACxF,YAAM,aAAa,eAAe,SAAS,UAAU;AACrD,YAAM,UAAU,GAAG,KAAK,MAAM,IAAI,KAAK,WAAW,IAAI,UAAU;AAChE,YAAM,OAAO,WAAW,IAAI,OAAO,KAAK;AACxC,iBAAW,IAAI,SAAS,OAAO,CAAC;AAChC,YAAM,cAAc,CAAC,iBAAiB,mBAAmB,QAAQ,IAAI,KAAK,EAAE;AAC5E,aAAO;AAAA,QACL,IAAI,KAAK;AAAA,QACT,QAAQ,KAAK;AAAA,QACb,QAAQ,KAAK;AAAA,QACb,cAAc,UAAU,KAAK,WAAW,IAAI,UAAU;AAAA,QACtD,cAAc,UAAU,KAAK,WAAW,IAAI,UAAU;AAAA,QACtD,MAAM;AAAA,QACN,aAAa,EAAE,cAAc,GAAG,QAAQ,KAAM,OAAO,IAAK,GAAG;AAAA,QAC7D,WAAW;AAAA,UACT,MAAM,WAAW;AAAA,UACjB,OAAO,cAAc,YAAY;AAAA,QACnC;AAAA,QACA,OAAO;AAAA,UACL,aAAa,iBAAiB,cAAc,MAAM;AAAA,UAClD,QAAQ,cAAc,YAAY;AAAA,UAClC,SAAS,cAAc,IAAI;AAAA,QAC7B;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,mBAAmB,SAAS,eAAe,aAAa,OAAO,aAAa,KAAK,CAAC;AAEtF,QAAM,cAAc,MAAM;AAAA,IACxB,CAAC,GAAY,SAAe;AAC1B,YAAM,OAAO,KAAK;AAClB,YAAM,SAAS,cAAc,KAAK,WAAW,KAAK,MAAM;AACxD,uBAAiB,CAAC,SAAU,SAAS,SAAS,OAAO,MAAO;AAC5D,qBAAe,KAAK,WAAW,KAAK,MAAM;AAAA,IAC5C;AAAA,IACA,CAAC,YAAY;AAAA,EACf;AAIA,QAAM,oBAAoB,MAAM;AAAA,IAC9B,CAAC,GAAqB,SAAe;AACnC,QAAE,eAAe;AACjB,YAAM,OAAO,KAAK;AAClB,uBAAiB,cAAc,KAAK,WAAW,KAAK,MAAM,CAAC;AAC3D,qBAAe,KAAK,WAAW,KAAK,MAAM;AAAA,IAC5C;AAAA,IACA,CAAC,YAAY;AAAA,EACf;AAEA,QAAM,mBAAmB,MAAM,YAAY,MAAM,iBAAiB,IAAI,GAAG,CAAC,CAAC;AAE3E,SACE,gBAAAA,KAAC,SAAI,WAAU,uCACb,0BAAAA,KAAC,SAAI,WAAU,uCACZ,gBAAM,WAAW,IAChB,gBAAAA,KAAC,SAAI,WAAU,qEAAoE,sCAEnF,IAEA,gBAAAA,KAAC,qBACC,0BAAAC;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAO;AAAA,MACP,gBAAgB,EAAE,SAAS,IAAI;AAAA,MAC/B,SAAS;AAAA,MACT,SAAS;AAAA,MACT,gBAAgB;AAAA,MAChB,kBAAkB;AAAA,MAClB,oBAAkB;AAAA,MAClB,WAAS;AAAA,MACT,cAAY;AAAA,MACZ,aAAW;AAAA,MACX,iBAAiB;AAAA,MACjB;AAAA,MACA;AAAA,MACA,aAAa;AAAA,MACb,YAAY,EAAE,iBAAiB,KAAK;AAAA,MAEpC;AAAA,wBAAAD,KAAC,cAAW,QAAQ,CAAC,GAAG,UAAU,EAAE,KAAK,EAAE,KAAK,GAAG,GAAG;AAAA,QACtD,gBAAAA,KAAC,cAAW,SAAS,kBAAkB,MAAM,KAAK,IAAI,MAAM,GAAG,OAAM,WAAU;AAAA,QAC/E,gBAAAA,KAAC,YAAS,iBAAiB,OAAO;AAAA;AAAA;AAAA,EACpC,GACF,GAEJ,GACF;AAEJ;",
|
|
6
|
+
"names": ["jsx", "jsxs"]
|
|
7
|
+
}
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
// src/editor/nbt-editor.tsx
|
|
4
4
|
import React from "react";
|
|
5
|
-
import { EditorState } from "@codemirror/state";
|
|
5
|
+
import { Compartment, EditorState, Prec } from "@codemirror/state";
|
|
6
6
|
import {
|
|
7
|
-
EditorView as
|
|
7
|
+
EditorView as EditorView3,
|
|
8
8
|
keymap as keymap2,
|
|
9
9
|
lineNumbers,
|
|
10
10
|
drawSelection,
|
|
@@ -17,9 +17,10 @@ import {
|
|
|
17
17
|
indentWithTab
|
|
18
18
|
} from "@codemirror/commands";
|
|
19
19
|
import {
|
|
20
|
-
syntaxHighlighting,
|
|
20
|
+
syntaxHighlighting as syntaxHighlighting2,
|
|
21
21
|
defaultHighlightStyle,
|
|
22
|
-
bracketMatching
|
|
22
|
+
bracketMatching,
|
|
23
|
+
indentUnit as indentUnit2
|
|
23
24
|
} from "@codemirror/language";
|
|
24
25
|
import { lintGutter } from "@codemirror/lint";
|
|
25
26
|
import { searchKeymap } from "@codemirror/search";
|
|
@@ -198,6 +199,117 @@ function nbtLanguageSupport() {
|
|
|
198
199
|
return new LanguageSupport(nbtLanguage, [indentUnit.of(" ")]);
|
|
199
200
|
}
|
|
200
201
|
|
|
202
|
+
// src/editor/editor-themes.ts
|
|
203
|
+
import { EditorView } from "@codemirror/view";
|
|
204
|
+
import { HighlightStyle, syntaxHighlighting } from "@codemirror/language";
|
|
205
|
+
import { tags as t } from "@lezer/highlight";
|
|
206
|
+
import {
|
|
207
|
+
amy,
|
|
208
|
+
ayuLight,
|
|
209
|
+
barf,
|
|
210
|
+
bespin,
|
|
211
|
+
birdsOfParadise,
|
|
212
|
+
boysAndGirls,
|
|
213
|
+
clouds,
|
|
214
|
+
cobalt,
|
|
215
|
+
coolGlow,
|
|
216
|
+
dracula,
|
|
217
|
+
espresso,
|
|
218
|
+
noctisLilac,
|
|
219
|
+
rosePineDawn,
|
|
220
|
+
smoothy,
|
|
221
|
+
solarizedLight,
|
|
222
|
+
tomorrow
|
|
223
|
+
} from "thememirror";
|
|
224
|
+
var defaultTheme = EditorView.theme(
|
|
225
|
+
{
|
|
226
|
+
"&": {
|
|
227
|
+
backgroundColor: "var(--background)",
|
|
228
|
+
color: "var(--foreground)"
|
|
229
|
+
},
|
|
230
|
+
".cm-gutters": {
|
|
231
|
+
backgroundColor: "var(--background)",
|
|
232
|
+
color: "var(--muted-foreground)",
|
|
233
|
+
borderRight: "1px solid var(--border)"
|
|
234
|
+
},
|
|
235
|
+
".cm-activeLine": {
|
|
236
|
+
backgroundColor: "color-mix(in srgb, var(--accent) 35%, transparent)"
|
|
237
|
+
},
|
|
238
|
+
".cm-tooltip": {
|
|
239
|
+
backgroundColor: "var(--popover)",
|
|
240
|
+
color: "var(--popover-foreground)",
|
|
241
|
+
border: "1px solid var(--border)"
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
{ dark: true }
|
|
245
|
+
);
|
|
246
|
+
var nimbitDarkChrome = EditorView.theme(
|
|
247
|
+
{
|
|
248
|
+
"&": { backgroundColor: "#0b0b0e", color: "#e4e4e7" },
|
|
249
|
+
".cm-content": { caretColor: "#facc15" },
|
|
250
|
+
".cm-cursor, .cm-dropCursor": { borderLeftColor: "#facc15" },
|
|
251
|
+
"&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection": { backgroundColor: "rgba(250, 204, 21, 0.18)" },
|
|
252
|
+
".cm-gutters": {
|
|
253
|
+
backgroundColor: "#0b0b0e",
|
|
254
|
+
color: "#52525b",
|
|
255
|
+
borderRight: "1px solid rgba(255, 255, 255, 0.06)"
|
|
256
|
+
},
|
|
257
|
+
".cm-activeLine": { backgroundColor: "rgba(250, 204, 21, 0.06)" },
|
|
258
|
+
".cm-activeLineGutter": { backgroundColor: "rgba(250, 204, 21, 0.06)", color: "#a1a1aa" },
|
|
259
|
+
".cm-tooltip": {
|
|
260
|
+
backgroundColor: "#18181b",
|
|
261
|
+
color: "#e4e4e7",
|
|
262
|
+
border: "1px solid rgba(255, 255, 255, 0.1)"
|
|
263
|
+
},
|
|
264
|
+
".cm-tooltip-autocomplete ul li[aria-selected]": {
|
|
265
|
+
backgroundColor: "rgba(250, 204, 21, 0.15)",
|
|
266
|
+
color: "#fafafa"
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
{ dark: true }
|
|
270
|
+
);
|
|
271
|
+
var nimbitDarkHighlight = HighlightStyle.define([
|
|
272
|
+
{ tag: t.keyword, color: "#facc15", fontWeight: "500" },
|
|
273
|
+
// entity, enum, …
|
|
274
|
+
{ tag: [t.typeName, t.className, t.tagName], color: "#e5e7eb", fontWeight: "500" },
|
|
275
|
+
// types + entity refs
|
|
276
|
+
{ tag: [t.propertyName, t.variableName, t.attributeName], color: "#cbd5e1" },
|
|
277
|
+
// field names
|
|
278
|
+
{ tag: [t.string, t.special(t.string)], color: "#fde047" },
|
|
279
|
+
{ tag: [t.number, t.bool, t.atom, t.null], color: "#fbbf24" },
|
|
280
|
+
// numbers, true/false
|
|
281
|
+
{ tag: [t.meta, t.annotation], color: "#f472b6", fontWeight: "500" },
|
|
282
|
+
// @relation, @@index, …
|
|
283
|
+
{ tag: t.comment, color: "#71717a", fontStyle: "italic" },
|
|
284
|
+
{ tag: [t.operator, t.punctuation, t.separator], color: "#a1a1aa" },
|
|
285
|
+
{ tag: t.invalid, color: "#f87171" }
|
|
286
|
+
]);
|
|
287
|
+
var nimbitDark = [nimbitDarkChrome, syntaxHighlighting(nimbitDarkHighlight)];
|
|
288
|
+
var EDITOR_THEMES = [
|
|
289
|
+
{ id: "default", label: "Default (panel)", extension: defaultTheme },
|
|
290
|
+
{ id: "nimbitDark", label: "Nimbit Dark", extension: nimbitDark },
|
|
291
|
+
{ id: "dracula", label: "Dracula", extension: dracula },
|
|
292
|
+
{ id: "tomorrow", label: "Tomorrow", extension: tomorrow },
|
|
293
|
+
{ id: "cobalt", label: "Cobalt", extension: cobalt },
|
|
294
|
+
{ id: "espresso", label: "Espresso", extension: espresso },
|
|
295
|
+
{ id: "barf", label: "Barf", extension: barf },
|
|
296
|
+
{ id: "bespin", label: "Bespin", extension: bespin },
|
|
297
|
+
{ id: "birdsOfParadise", label: "Birds of Paradise", extension: birdsOfParadise },
|
|
298
|
+
{ id: "boysAndGirls", label: "Boys and Girls", extension: boysAndGirls },
|
|
299
|
+
{ id: "coolGlow", label: "Cool Glow", extension: coolGlow },
|
|
300
|
+
{ id: "amy", label: "Amy", extension: amy },
|
|
301
|
+
{ id: "ayuLight", label: "Ayu Light", extension: ayuLight },
|
|
302
|
+
{ id: "clouds", label: "Clouds", extension: clouds },
|
|
303
|
+
{ id: "noctisLilac", label: "Noctis Lilac", extension: noctisLilac },
|
|
304
|
+
{ id: "rosePineDawn", label: "Ros\xE9 Pine Dawn", extension: rosePineDawn },
|
|
305
|
+
{ id: "smoothy", label: "Smoothy", extension: smoothy },
|
|
306
|
+
{ id: "solarizedLight", label: "Solarized Light", extension: solarizedLight }
|
|
307
|
+
];
|
|
308
|
+
var byId = new Map(EDITOR_THEMES.map((t2) => [t2.id, t2.extension]));
|
|
309
|
+
function themeExtension(id) {
|
|
310
|
+
return byId.get(id) ?? EDITOR_THEMES[0].extension;
|
|
311
|
+
}
|
|
312
|
+
|
|
201
313
|
// src/editor/lsp-extensions.ts
|
|
202
314
|
import {
|
|
203
315
|
ViewPlugin,
|
|
@@ -349,30 +461,19 @@ function lspExtensions(client, uri, onGotoDefinition) {
|
|
|
349
461
|
|
|
350
462
|
// src/editor/nbt-editor.tsx
|
|
351
463
|
import { jsx } from "react/jsx-runtime";
|
|
352
|
-
|
|
353
|
-
{
|
|
354
|
-
"&": {
|
|
355
|
-
height: "100%",
|
|
356
|
-
fontSize: "12px",
|
|
357
|
-
backgroundColor: "var(--background)",
|
|
358
|
-
color: "var(--foreground)"
|
|
359
|
-
},
|
|
464
|
+
function sizingTheme(fontSize) {
|
|
465
|
+
return EditorView3.theme({
|
|
466
|
+
"&": { height: "100%", fontSize: `${fontSize}px` },
|
|
360
467
|
".cm-content": { fontFamily: "ui-monospace, monospace" },
|
|
361
|
-
"
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
color: "var(--popover-foreground)",
|
|
371
|
-
border: "1px solid var(--border)"
|
|
372
|
-
}
|
|
373
|
-
},
|
|
374
|
-
{ dark: true }
|
|
375
|
-
);
|
|
468
|
+
"&.cm-focused": { outline: "none" }
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
function indentConfig(tabSize) {
|
|
472
|
+
return Prec.high([
|
|
473
|
+
indentUnit2.of(" ".repeat(tabSize)),
|
|
474
|
+
EditorState.tabSize.of(tabSize)
|
|
475
|
+
]);
|
|
476
|
+
}
|
|
376
477
|
var NbtEditor = ({
|
|
377
478
|
uri,
|
|
378
479
|
value,
|
|
@@ -380,7 +481,11 @@ var NbtEditor = ({
|
|
|
380
481
|
lsp,
|
|
381
482
|
onChange,
|
|
382
483
|
onSave,
|
|
383
|
-
onGotoDefinition
|
|
484
|
+
onGotoDefinition,
|
|
485
|
+
theme = "default",
|
|
486
|
+
fontSize = 12,
|
|
487
|
+
lineWrap = false,
|
|
488
|
+
tabSize = 2
|
|
384
489
|
}) => {
|
|
385
490
|
const hostRef = React.useRef(null);
|
|
386
491
|
const viewRef = React.useRef(null);
|
|
@@ -390,9 +495,15 @@ var NbtEditor = ({
|
|
|
390
495
|
onSaveRef.current = onSave;
|
|
391
496
|
const onGotoRef = React.useRef(onGotoDefinition);
|
|
392
497
|
onGotoRef.current = onGotoDefinition;
|
|
498
|
+
const themeComp = React.useRef(new Compartment());
|
|
499
|
+
const wrapComp = React.useRef(new Compartment());
|
|
500
|
+
const indentComp = React.useRef(new Compartment());
|
|
501
|
+
const settingsRef = React.useRef({ theme, fontSize, lineWrap, tabSize });
|
|
502
|
+
settingsRef.current = { theme, fontSize, lineWrap, tabSize };
|
|
393
503
|
React.useEffect(() => {
|
|
394
504
|
const host = hostRef.current;
|
|
395
505
|
if (!host) return;
|
|
506
|
+
const s = settingsRef.current;
|
|
396
507
|
const extensions = [
|
|
397
508
|
lineNumbers(),
|
|
398
509
|
history(),
|
|
@@ -401,9 +512,11 @@ var NbtEditor = ({
|
|
|
401
512
|
bracketMatching(),
|
|
402
513
|
closeBrackets(),
|
|
403
514
|
lintGutter(),
|
|
404
|
-
|
|
515
|
+
syntaxHighlighting2(defaultHighlightStyle, { fallback: true }),
|
|
405
516
|
nbtLanguageSupport(),
|
|
406
|
-
|
|
517
|
+
indentComp.current.of(indentConfig(s.tabSize)),
|
|
518
|
+
themeComp.current.of([sizingTheme(s.fontSize), themeExtension(s.theme)]),
|
|
519
|
+
wrapComp.current.of(s.lineWrap ? EditorView3.lineWrapping : []),
|
|
407
520
|
keymap2.of([
|
|
408
521
|
{
|
|
409
522
|
key: "Mod-s",
|
|
@@ -418,7 +531,7 @@ var NbtEditor = ({
|
|
|
418
531
|
...completionKeymap,
|
|
419
532
|
indentWithTab
|
|
420
533
|
]),
|
|
421
|
-
|
|
534
|
+
EditorView3.updateListener.of((u) => {
|
|
422
535
|
if (u.docChanged) onChangeRef.current?.(u.state.doc.toString());
|
|
423
536
|
}),
|
|
424
537
|
EditorState.readOnly.of(readOnly)
|
|
@@ -428,7 +541,7 @@ var NbtEditor = ({
|
|
|
428
541
|
lspExtensions(lsp, uri, (defUri, line) => onGotoRef.current?.(defUri, line))
|
|
429
542
|
);
|
|
430
543
|
}
|
|
431
|
-
const view = new
|
|
544
|
+
const view = new EditorView3({
|
|
432
545
|
state: EditorState.create({ doc: value, extensions }),
|
|
433
546
|
parent: host
|
|
434
547
|
});
|
|
@@ -438,6 +551,20 @@ var NbtEditor = ({
|
|
|
438
551
|
viewRef.current = null;
|
|
439
552
|
};
|
|
440
553
|
}, [uri, readOnly, lsp]);
|
|
554
|
+
React.useEffect(() => {
|
|
555
|
+
const view = viewRef.current;
|
|
556
|
+
if (!view) return;
|
|
557
|
+
view.dispatch({
|
|
558
|
+
effects: [
|
|
559
|
+
themeComp.current.reconfigure([
|
|
560
|
+
sizingTheme(fontSize),
|
|
561
|
+
themeExtension(theme)
|
|
562
|
+
]),
|
|
563
|
+
wrapComp.current.reconfigure(lineWrap ? EditorView3.lineWrapping : []),
|
|
564
|
+
indentComp.current.reconfigure(indentConfig(tabSize))
|
|
565
|
+
]
|
|
566
|
+
});
|
|
567
|
+
}, [theme, fontSize, lineWrap, tabSize]);
|
|
441
568
|
return /* @__PURE__ */ jsx("div", { ref: hostRef, className: "h-full min-h-0 overflow-hidden" });
|
|
442
569
|
};
|
|
443
570
|
|
|
@@ -629,8 +756,10 @@ var NbtLspClient = class {
|
|
|
629
756
|
export {
|
|
630
757
|
nbtLanguage,
|
|
631
758
|
nbtLanguageSupport,
|
|
759
|
+
EDITOR_THEMES,
|
|
760
|
+
themeExtension,
|
|
632
761
|
lspExtensions,
|
|
633
762
|
NbtEditor,
|
|
634
763
|
NbtLspClient
|
|
635
764
|
};
|
|
636
|
-
//# sourceMappingURL=chunk-
|
|
765
|
+
//# sourceMappingURL=chunk-PI7ZMVVU.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/editor/nbt-editor.tsx", "../src/editor/nbt-language.ts", "../src/editor/editor-themes.ts", "../src/editor/lsp-extensions.ts", "../src/editor/lsp-client.ts"],
|
|
4
|
+
"sourcesContent": ["// CodeMirror 6 React wrapper for one NBT buffer. Recreated per uri (keyed by\n// the host); owns the EditorView lifecycle, Ctrl+S save, and the LSP wiring.\n// Theme / font size / line-wrap / tab size are live-tunable via compartments so\n// changing a setting doesn't blow away cursor + scroll.\n\nimport React from \"react\";\nimport { Compartment, EditorState, Prec } from \"@codemirror/state\";\nimport {\n EditorView,\n keymap,\n lineNumbers,\n drawSelection,\n highlightActiveLine,\n} from \"@codemirror/view\";\nimport {\n defaultKeymap,\n history,\n historyKeymap,\n indentWithTab,\n} from \"@codemirror/commands\";\nimport {\n syntaxHighlighting,\n defaultHighlightStyle,\n bracketMatching,\n indentUnit,\n} from \"@codemirror/language\";\nimport { lintGutter } from \"@codemirror/lint\";\nimport { searchKeymap } from \"@codemirror/search\";\nimport { completionKeymap, closeBrackets } from \"@codemirror/autocomplete\";\nimport { nbtLanguageSupport } from \"./nbt-language\";\nimport { themeExtension } from \"./editor-themes\";\nimport { lspExtensions, type GotoDefHandler } from \"./lsp-extensions\";\nimport { NbtLspClient } from \"./lsp-client\";\n\n// Sizing only \u2014 the selected color theme owns the rest. Built per font-size so\n// the theme compartment can carry both.\nfunction sizingTheme(fontSize: number) {\n return EditorView.theme({\n \"&\": { height: \"100%\", fontSize: `${fontSize}px` },\n \".cm-content\": { fontFamily: \"ui-monospace, monospace\" },\n \"&.cm-focused\": { outline: \"none\" },\n });\n}\n\n// `Prec.high` so this wins the indentUnit/tabSize facets over the\n// `indentUnit.of(\" \")` baked into nbtLanguageSupport().\nfunction indentConfig(tabSize: number) {\n return Prec.high([\n indentUnit.of(\" \".repeat(tabSize)),\n EditorState.tabSize.of(tabSize),\n ]);\n}\n\nexport type NbtEditorProps = {\n uri: string;\n value: string;\n readOnly?: boolean;\n lsp?: NbtLspClient | null;\n onChange?: (text: string) => void;\n onSave?: (text: string) => void;\n onGotoDefinition?: GotoDefHandler;\n theme?: string;\n fontSize?: number;\n lineWrap?: boolean;\n tabSize?: number;\n};\n\nexport const NbtEditor: React.FC<NbtEditorProps> = ({\n uri,\n value,\n readOnly = false,\n lsp,\n onChange,\n onSave,\n onGotoDefinition,\n theme = \"default\",\n fontSize = 12,\n lineWrap = false,\n tabSize = 2,\n}) => {\n const hostRef = React.useRef<HTMLDivElement | null>(null);\n const viewRef = React.useRef<EditorView | null>(null);\n\n // Latest callbacks without recreating the view.\n const onChangeRef = React.useRef(onChange);\n onChangeRef.current = onChange;\n const onSaveRef = React.useRef(onSave);\n onSaveRef.current = onSave;\n const onGotoRef = React.useRef(onGotoDefinition);\n onGotoRef.current = onGotoDefinition;\n\n // Live-tunable settings live in compartments. Keep the latest values in a ref\n // so a view rebuild (new uri/mode) seeds the right config without listing the\n // settings in the create-effect deps.\n const themeComp = React.useRef(new Compartment());\n const wrapComp = React.useRef(new Compartment());\n const indentComp = React.useRef(new Compartment());\n const settingsRef = React.useRef({ theme, fontSize, lineWrap, tabSize });\n settingsRef.current = { theme, fontSize, lineWrap, tabSize };\n\n React.useEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n\n const s = settingsRef.current;\n const extensions = [\n lineNumbers(),\n history(),\n drawSelection(),\n highlightActiveLine(),\n bracketMatching(),\n closeBrackets(),\n lintGutter(),\n syntaxHighlighting(defaultHighlightStyle, { fallback: true }),\n nbtLanguageSupport(),\n indentComp.current.of(indentConfig(s.tabSize)),\n themeComp.current.of([sizingTheme(s.fontSize), themeExtension(s.theme)]),\n wrapComp.current.of(s.lineWrap ? EditorView.lineWrapping : []),\n keymap.of([\n {\n key: \"Mod-s\",\n run: (view) => {\n onSaveRef.current?.(view.state.doc.toString());\n return true;\n },\n },\n ...defaultKeymap,\n ...historyKeymap,\n ...searchKeymap,\n ...completionKeymap,\n indentWithTab,\n ]),\n EditorView.updateListener.of((u) => {\n if (u.docChanged) onChangeRef.current?.(u.state.doc.toString());\n }),\n EditorState.readOnly.of(readOnly),\n ];\n if (lsp && !readOnly) {\n extensions.push(\n lspExtensions(lsp, uri, (defUri, line) => onGotoRef.current?.(defUri, line)),\n );\n }\n\n const view = new EditorView({\n state: EditorState.create({ doc: value, extensions }),\n parent: host,\n });\n viewRef.current = view;\n return () => {\n view.destroy();\n viewRef.current = null;\n };\n // Recreate per buffer identity / mode; `value` is only the initial doc.\n // Settings changes are handled by the reconfigure effect below.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [uri, readOnly, lsp]);\n\n // Retune the live view when a setting changes \u2014 no destroy, so cursor/scroll\n // survive.\n React.useEffect(() => {\n const view = viewRef.current;\n if (!view) return;\n view.dispatch({\n effects: [\n themeComp.current.reconfigure([\n sizingTheme(fontSize),\n themeExtension(theme),\n ]),\n wrapComp.current.reconfigure(lineWrap ? EditorView.lineWrapping : []),\n indentComp.current.reconfigure(indentConfig(tabSize)),\n ],\n });\n }, [theme, fontSize, lineWrap, tabSize]);\n\n return <div ref={hostRef} className=\"h-full min-h-0 overflow-hidden\" />;\n};\n", "// NBT syntax highlighting for CodeMirror 6 \u2014 a StreamLanguage tokenizer ported\n// from the console tokenizer (modules/lang_common/scan.jai) and the VSCode\n// grammar (editors/vscode/nbt/syntaxes/nbt.tmLanguage.json). Highlighting is\n// local; everything semantic (diagnostics/completion/hover) comes via the LSP.\n\nimport {\n StreamLanguage,\n LanguageSupport,\n indentUnit,\n type StreamParser,\n} from \"@codemirror/language\";\n\nconst KEYWORDS = new Set([\n \"entity\", \"enum\", \"struct\", \"const\", \"export\", \"extends\",\n \"fn\", \"on\", \"action\", \"activity\", \"task\", \"variant\", \"workflow\", \"command\",\n \"middleware\", \"schedule\", \"every\", \"jai\",\n \"migration\", \"test\", \"mock\", \"assert\",\n \"cartridge\", \"service\", \"component\", \"app\", \"route\", \"layout\",\n \"import\", \"from\",\n \"if\", \"elif\", \"else\", \"while\", \"for\", \"in\", \"return\", \"break\", \"continue\",\n \"delete\", \"defer\", \"print\", \"sleep\", \"fail\",\n]);\n\nconst TYPES = new Set([\n \"string\", \"bool\", \"ulid\", \"document\", \"dict\", \"blob\", \"DateTime\",\n \"u8\", \"u16\", \"u32\", \"u64\", \"s8\", \"s16\", \"s32\", \"s64\",\n \"int\", \"integer\", \"float\", \"float64\", \"f32\", \"f64\", \"double\",\n \"time\", \"bytes\", \"any\", \"name\", \"ref\",\n]);\n\ntype NbtState = {\n tripleString: boolean;\n};\n\n// NBT strings carry NO escapes (scan.jai consumes to the bare closing quote),\n// so a backslash before a quote does not extend the string.\nfunction eatSingleLineString(stream: StringStream, quote: string): string {\n while (!stream.eol()) {\n if (stream.next() === quote) break;\n }\n return \"string\";\n}\n\ntype StringStream = Parameters<StreamParser<NbtState>[\"token\"]>[0];\n\nconst nbtParser: StreamParser<NbtState> = {\n name: \"nbt\",\n startState: () => ({ tripleString: false }),\n token(stream, state) {\n if (state.tripleString) {\n while (!stream.eol()) {\n if (stream.match('\"\"\"')) {\n state.tripleString = false;\n return \"string\";\n }\n stream.next();\n }\n return \"string\";\n }\n\n if (stream.eatSpace()) return null;\n\n const ch = stream.peek();\n if (ch == null) return null;\n\n if (ch === \"#\") {\n stream.skipToEnd();\n return \"comment\";\n }\n\n if (stream.match('\"\"\"')) {\n state.tripleString = true;\n // Rest of line is string body unless it closes on the same line.\n while (!stream.eol()) {\n if (stream.match('\"\"\"')) {\n state.tripleString = false;\n return \"string\";\n }\n stream.next();\n }\n return \"string\";\n }\n\n if (ch === '\"') {\n stream.next();\n return eatSingleLineString(stream, '\"');\n }\n if (ch === \"'\") {\n // Like the scanner: only a string opener when not glued to an identifier\n // (lets contractions inside docs pass).\n const before = stream.string.charAt(stream.pos - 1);\n if (!/[A-Za-z0-9_]/.test(before)) {\n stream.next();\n return eatSingleLineString(stream, \"'\");\n }\n stream.next();\n return null;\n }\n\n // f-strings: f\"...\" \u2014 body highlighted as a string (interpolation holes\n // are cosmetic only).\n if (ch === \"f\" && stream.string.charAt(stream.pos + 1) === '\"') {\n stream.next();\n stream.next();\n return eatSingleLineString(stream, '\"');\n }\n\n // @attr / @@attr\n if (ch === \"@\") {\n stream.next();\n stream.eat(\"@\");\n stream.eatWhile(/[A-Za-z0-9_]/);\n return \"meta\";\n }\n\n // Numbers. The optional fraction backtracks on `0..9` ranges (matches \"0\",\n // not \"0.\").\n if (/\\d/.test(ch)) {\n stream.match(/^\\d+(\\.\\d+)?/);\n return \"number\";\n }\n\n if (/[A-Za-z_]/.test(ch)) {\n stream.eatWhile(/[A-Za-z0-9_]/);\n const word = stream.current();\n if (word === \"true\" || word === \"false\") return \"atom\";\n if (KEYWORDS.has(word)) return \"keyword\";\n if (TYPES.has(word)) return \"typeName\";\n if (/^[A-Z]/.test(word)) return \"typeName\"; // entity/enum references\n return \"variableName\";\n }\n\n if (/[+\\-*/=<>!&|?.,:;]/.test(ch)) {\n stream.next();\n stream.eatWhile(/[+\\-*/=<>!&|.]/);\n return \"operator\";\n }\n\n stream.next();\n return null;\n },\n languageData: {\n commentTokens: { line: \"#\" },\n },\n};\n\nexport const nbtLanguage = StreamLanguage.define(nbtParser);\n\nexport function nbtLanguageSupport(): LanguageSupport {\n return new LanguageSupport(nbtLanguage, [indentUnit.of(\" \")]);\n}\n", "// Preloaded CodeMirror color themes for the NBT editor. \"default\" matches the\n// devtools panel chrome via its CSS variables (the editor renders inside the\n// .nimbit-devtools subtree, so these resolve to the scoped tokens); the rest\n// come from `thememirror`. Color only \u2014 sizing (font size/family/height) is\n// applied separately by the editor so it can follow the font-size setting.\n\nimport { EditorView } from \"@codemirror/view\";\nimport type { Extension } from \"@codemirror/state\";\nimport { HighlightStyle, syntaxHighlighting } from \"@codemirror/language\";\nimport { tags as t } from \"@lezer/highlight\";\nimport {\n amy,\n ayuLight,\n barf,\n bespin,\n birdsOfParadise,\n boysAndGirls,\n clouds,\n cobalt,\n coolGlow,\n dracula,\n espresso,\n noctisLilac,\n rosePineDawn,\n smoothy,\n solarizedLight,\n tomorrow,\n} from \"thememirror\";\n\nconst defaultTheme = EditorView.theme(\n {\n \"&\": {\n backgroundColor: \"var(--background)\",\n color: \"var(--foreground)\",\n },\n \".cm-gutters\": {\n backgroundColor: \"var(--background)\",\n color: \"var(--muted-foreground)\",\n borderRight: \"1px solid var(--border)\",\n },\n \".cm-activeLine\": {\n backgroundColor: \"color-mix(in srgb, var(--accent) 35%, transparent)\",\n },\n \".cm-tooltip\": {\n backgroundColor: \"var(--popover)\",\n color: \"var(--popover-foreground)\",\n border: \"1px solid var(--border)\",\n },\n },\n { dark: true },\n);\n\n// \"Nimbit Dark\" \u2014 the brand theme, matching the marketing hero's code panel:\n// brand-yellow keywords, pink @-directives, foreground type names, muted-italic\n// comments. Unlike `default` it ships its own HighlightStyle (so syntax colors\n// are branded, not CodeMirror's fallback) and uses fixed colors so it looks the\n// same regardless of the surrounding CSS variables. The NBT StreamLanguage emits\n// standard token names (\"keyword\"/\"typeName\"/\"meta\"/\u2026 in nbt-language.ts) which\n// map to these Lezer tags.\nconst nimbitDarkChrome = EditorView.theme(\n {\n \"&\": { backgroundColor: \"#0b0b0e\", color: \"#e4e4e7\" },\n \".cm-content\": { caretColor: \"#facc15\" },\n \".cm-cursor, .cm-dropCursor\": { borderLeftColor: \"#facc15\" },\n \"&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection\":\n { backgroundColor: \"rgba(250, 204, 21, 0.18)\" },\n \".cm-gutters\": {\n backgroundColor: \"#0b0b0e\",\n color: \"#52525b\",\n borderRight: \"1px solid rgba(255, 255, 255, 0.06)\",\n },\n \".cm-activeLine\": { backgroundColor: \"rgba(250, 204, 21, 0.06)\" },\n \".cm-activeLineGutter\": { backgroundColor: \"rgba(250, 204, 21, 0.06)\", color: \"#a1a1aa\" },\n \".cm-tooltip\": {\n backgroundColor: \"#18181b\",\n color: \"#e4e4e7\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n },\n \".cm-tooltip-autocomplete ul li[aria-selected]\": {\n backgroundColor: \"rgba(250, 204, 21, 0.15)\",\n color: \"#fafafa\",\n },\n },\n { dark: true },\n);\n\nconst nimbitDarkHighlight = HighlightStyle.define([\n { tag: t.keyword, color: \"#facc15\", fontWeight: \"500\" }, // entity, enum, \u2026\n { tag: [t.typeName, t.className, t.tagName], color: \"#e5e7eb\", fontWeight: \"500\" }, // types + entity refs\n { tag: [t.propertyName, t.variableName, t.attributeName], color: \"#cbd5e1\" }, // field names\n { tag: [t.string, t.special(t.string)], color: \"#fde047\" },\n { tag: [t.number, t.bool, t.atom, t.null], color: \"#fbbf24\" }, // numbers, true/false\n { tag: [t.meta, t.annotation], color: \"#f472b6\", fontWeight: \"500\" }, // @relation, @@index, \u2026\n { tag: t.comment, color: \"#71717a\", fontStyle: \"italic\" },\n { tag: [t.operator, t.punctuation, t.separator], color: \"#a1a1aa\" },\n { tag: t.invalid, color: \"#f87171\" },\n]);\n\nconst nimbitDark: Extension = [nimbitDarkChrome, syntaxHighlighting(nimbitDarkHighlight)];\n\nexport type EditorTheme = { id: string; label: string; extension: Extension };\n\nexport const EDITOR_THEMES: EditorTheme[] = [\n { id: \"default\", label: \"Default (panel)\", extension: defaultTheme },\n { id: \"nimbitDark\", label: \"Nimbit Dark\", extension: nimbitDark },\n { id: \"dracula\", label: \"Dracula\", extension: dracula },\n { id: \"tomorrow\", label: \"Tomorrow\", extension: tomorrow },\n { id: \"cobalt\", label: \"Cobalt\", extension: cobalt },\n { id: \"espresso\", label: \"Espresso\", extension: espresso },\n { id: \"barf\", label: \"Barf\", extension: barf },\n { id: \"bespin\", label: \"Bespin\", extension: bespin },\n { id: \"birdsOfParadise\", label: \"Birds of Paradise\", extension: birdsOfParadise },\n { id: \"boysAndGirls\", label: \"Boys and Girls\", extension: boysAndGirls },\n { id: \"coolGlow\", label: \"Cool Glow\", extension: coolGlow },\n { id: \"amy\", label: \"Amy\", extension: amy },\n { id: \"ayuLight\", label: \"Ayu Light\", extension: ayuLight },\n { id: \"clouds\", label: \"Clouds\", extension: clouds },\n { id: \"noctisLilac\", label: \"Noctis Lilac\", extension: noctisLilac },\n { id: \"rosePineDawn\", label: \"Ros\u00E9 Pine Dawn\", extension: rosePineDawn },\n { id: \"smoothy\", label: \"Smoothy\", extension: smoothy },\n { id: \"solarizedLight\", label: \"Solarized Light\", extension: solarizedLight },\n];\n\nconst byId = new Map(EDITOR_THEMES.map((t) => [t.id, t.extension]));\n\nexport function themeExtension(id: string): Extension {\n return byId.get(id) ?? EDITOR_THEMES[0].extension;\n}\n", "// CodeMirror extensions wiring an editor buffer to the NbtLspClient:\n// full-text didChange sync (debounced), pushed publishDiagnostics \u2192 lint,\n// completion, hover, and F12 go-to-definition.\n\nimport { type Extension, type Text } from \"@codemirror/state\";\nimport {\n EditorView,\n ViewPlugin,\n type ViewUpdate,\n hoverTooltip,\n keymap,\n} from \"@codemirror/view\";\nimport {\n autocompletion,\n type CompletionContext,\n type CompletionResult,\n} from \"@codemirror/autocomplete\";\nimport { setDiagnostics, type Diagnostic } from \"@codemirror/lint\";\nimport {\n NbtLspClient,\n type LspDiagnostic,\n type LspPosition,\n type LspCompletionItem,\n type LspLocation,\n} from \"./lsp-client\";\n\nfunction toLspPos(doc: Text, offset: number): LspPosition {\n const line = doc.lineAt(offset);\n return { line: line.number - 1, character: offset - line.from };\n}\n\nfunction fromLspPos(doc: Text, pos: LspPosition): number {\n const lineNo = Math.min(Math.max(pos.line + 1, 1), doc.lines);\n const line = doc.line(lineNo);\n return Math.min(line.from + Math.max(pos.character, 0), line.to);\n}\n\nfunction toCmDiagnostics(doc: Text, diags: LspDiagnostic[]): Diagnostic[] {\n return diags.map((d) => {\n const from = fromLspPos(doc, d.range.start);\n let to = fromLspPos(doc, d.range.end);\n if (to <= from) to = Math.min(from + 1, doc.length);\n const severity =\n d.severity === 2 ? \"warning\" : d.severity === 3 || d.severity === 4 ? \"info\" : \"error\";\n return { from, to, severity, message: d.message, source: d.source ?? \"nbt\" };\n });\n}\n\n// LSP CompletionItemKind \u2192 CM completion type (drives the icon).\nfunction completionType(kind?: number): string {\n switch (kind) {\n case 3: return \"function\";\n case 5: return \"property\";\n case 13: return \"enum\";\n case 14: return \"keyword\";\n case 22: return \"class\";\n default: return \"variable\";\n }\n}\n\nexport type GotoDefHandler = (uri: string, line: number) => void;\n\nexport function lspExtensions(\n client: NbtLspClient,\n uri: string,\n onGotoDefinition?: GotoDefHandler,\n): Extension[] {\n // Sync + diagnostics plugin. didOpen on create, debounced didChange,\n // diagnostics pushed by the server are dispatched into the lint state.\n const syncPlugin = ViewPlugin.fromClass(\n class {\n private timer: ReturnType<typeof setTimeout> | null = null;\n private unsubscribe: () => void;\n\n constructor(readonly view: EditorView) {\n client.didOpen(uri, view.state.doc.toString());\n this.unsubscribe = client.onDiagnostics(uri, (diags) => {\n const cm = toCmDiagnostics(this.view.state.doc, diags);\n this.view.dispatch(setDiagnostics(this.view.state, cm));\n });\n }\n\n update(u: ViewUpdate) {\n if (!u.docChanged) return;\n if (this.timer) clearTimeout(this.timer);\n this.timer = setTimeout(() => {\n this.timer = null;\n client.didChange(uri, this.view.state.doc.toString());\n }, 200);\n }\n\n destroy() {\n if (this.timer) {\n clearTimeout(this.timer);\n client.didChange(uri, this.view.state.doc.toString());\n }\n this.unsubscribe();\n }\n },\n );\n\n const completionSource = async (\n ctx: CompletionContext,\n ): Promise<CompletionResult | null> => {\n const word = ctx.matchBefore(/\\w*/);\n if (!word) return null;\n if (word.from === word.to && !ctx.explicit) {\n // Only fire automatically right after a trigger character.\n const before = ctx.state.doc.sliceString(Math.max(0, ctx.pos - 1), ctx.pos);\n if (before !== \".\" && before !== \":\" && before !== '\"') return null;\n }\n // Flush any pending edit so the server completes against the live buffer.\n client.didChange(uri, ctx.state.doc.toString());\n let result;\n try {\n result = await client.completion(uri, toLspPos(ctx.state.doc, ctx.pos));\n } catch {\n return null;\n }\n const items: LspCompletionItem[] = Array.isArray(result)\n ? result\n : (result?.items ?? []);\n if (items.length === 0) return null;\n return {\n from: word.from,\n options: items.map((it) => ({\n label: it.label,\n type: completionType(it.kind),\n detail: it.detail,\n })),\n };\n };\n\n const hover = hoverTooltip(async (view, pos) => {\n let result;\n try {\n result = await client.hover(uri, toLspPos(view.state.doc, pos));\n } catch {\n return null;\n }\n const value = result?.contents?.value;\n if (!value) return null;\n return {\n pos,\n create: () => {\n const dom = document.createElement(\"pre\");\n dom.className = \"nbt-hover-tooltip\";\n dom.style.cssText =\n \"margin:0;padding:6px 8px;max-width:480px;white-space:pre-wrap;font-size:11px;\";\n // Server emits fenced markdown code blocks; strip the fences, show text.\n dom.textContent = value.replace(/```\\w*\\n?/g, \"\");\n return { dom };\n },\n };\n });\n\n const gotoDef = keymap.of([\n {\n key: \"F12\",\n run: (view) => {\n const pos = toLspPos(view.state.doc, view.state.selection.main.head);\n client\n .definition(uri, pos)\n .then((result) => {\n const loc: LspLocation | null = Array.isArray(result)\n ? (result[0] ?? null)\n : result;\n if (!loc?.uri) return;\n if (loc.uri === uri) {\n const off = fromLspPos(view.state.doc, loc.range.start);\n view.dispatch({\n selection: { anchor: off },\n scrollIntoView: true,\n });\n } else {\n onGotoDefinition?.(loc.uri, loc.range.start.line);\n }\n })\n .catch(() => {});\n return true;\n },\n },\n ]);\n\n return [\n syncPlugin,\n autocompletion({ override: [completionSource] }),\n hover,\n gotoDef,\n ];\n}\n", "// Minimal LSP client over WebSocket for the console's dev-mode nbt_lsp bridge\n// (/_console/dev/lsp). One JSON-RPC message per WS text frame \u2014 no\n// Content-Length framing (the bridge's write_proc emits bare JSON).\n//\n// Hand-rolled on purpose: the server speaks ~10 methods with full-text sync,\n// and a library client (codemirror-languageserver) would drag transitive\n// runtime deps into every host app.\n\nexport type LspPosition = { line: number; character: number };\nexport type LspRange = { start: LspPosition; end: LspPosition };\nexport type LspDiagnostic = {\n range: LspRange;\n severity?: number; // 1=error 2=warning 3=info 4=hint\n message: string;\n source?: string;\n};\nexport type LspCompletionItem = {\n label: string;\n kind?: number;\n detail?: string;\n};\nexport type LspLocation = { uri: string; range: LspRange };\n\ntype Pending = {\n resolve: (v: unknown) => void;\n reject: (e: Error) => void;\n};\n\nexport class NbtLspClient {\n private url: string;\n private rootUri: string | null = null;\n private ws: WebSocket | null = null;\n private nextId = 1;\n private pending = new Map<number, Pending>();\n private diagHandlers = new Map<string, (d: LspDiagnostic[]) => void>();\n // Open buffers, kept for replay across reconnects.\n private docs = new Map<string, { text: string; version: number }>();\n private ready = false;\n private queue: string[] = [];\n private closed = false;\n private retryMs = 500;\n\n constructor(url: string) {\n this.url = url;\n this.connect();\n }\n\n dispose() {\n this.closed = true;\n this.ws?.close();\n this.pending.forEach((p) => p.reject(new Error(\"lsp client disposed\")));\n this.pending.clear();\n }\n\n private connect() {\n if (this.closed) return;\n const ws = new WebSocket(this.url);\n this.ws = ws;\n ws.onopen = () => {\n this.retryMs = 500;\n if (this.rootUri) this.sendInitialize(this.rootUri);\n };\n ws.onmessage = (ev) => {\n if (typeof ev.data !== \"string\") return;\n this.onMessage(ev.data);\n };\n ws.onclose = () => {\n this.ready = false;\n this.ws = null;\n for (const p of this.pending.values())\n p.reject(new Error(\"lsp connection closed\"));\n this.pending.clear();\n if (!this.closed) {\n setTimeout(() => this.connect(), this.retryMs);\n this.retryMs = Math.min(this.retryMs * 2, 10_000);\n }\n };\n }\n\n // Called once by the host with file://<projectRoot>; also re-sent after every\n // reconnect, followed by didOpen replays for tracked buffers.\n initialize(rootUri: string) {\n this.rootUri = rootUri;\n if (this.ws?.readyState === WebSocket.OPEN) this.sendInitialize(rootUri);\n }\n\n private sendInitialize(rootUri: string) {\n const id = this.nextId++;\n this.pending.set(id, {\n resolve: () => {\n this.sendRaw({ jsonrpc: \"2.0\", method: \"initialized\", params: {} });\n this.ready = true;\n for (const [uri, d] of this.docs) {\n this.sendRaw({\n jsonrpc: \"2.0\",\n method: \"textDocument/didOpen\",\n params: {\n textDocument: {\n uri,\n languageId: \"nbt\",\n version: d.version,\n text: d.text,\n },\n },\n });\n }\n const q = this.queue;\n this.queue = [];\n for (const m of q) this.ws?.send(m);\n },\n reject: () => {},\n });\n this.ws?.send(\n JSON.stringify({\n jsonrpc: \"2.0\",\n id,\n method: \"initialize\",\n params: { rootUri },\n }),\n );\n }\n\n private sendRaw(msg: object) {\n const s = JSON.stringify(msg);\n if (this.ready && this.ws?.readyState === WebSocket.OPEN) this.ws.send(s);\n else this.queue.push(s);\n }\n\n private onMessage(data: string) {\n let msg: any;\n try {\n msg = JSON.parse(data);\n } catch {\n return;\n }\n if (msg.id != null && (msg.result !== undefined || msg.error)) {\n const p = this.pending.get(msg.id);\n if (!p) return;\n this.pending.delete(msg.id);\n if (msg.error) p.reject(new Error(msg.error.message ?? \"lsp error\"));\n else p.resolve(msg.result);\n return;\n }\n if (msg.method === \"textDocument/publishDiagnostics\") {\n const uri = msg.params?.uri as string;\n const handler = this.diagHandlers.get(uri);\n if (handler) handler((msg.params?.diagnostics ?? []) as LspDiagnostic[]);\n }\n }\n\n request<T>(method: string, params: object): Promise<T> {\n const id = this.nextId++;\n const p = new Promise<T>((resolve, reject) => {\n this.pending.set(id, { resolve: resolve as Pending[\"resolve\"], reject });\n });\n this.sendRaw({ jsonrpc: \"2.0\", id, method, params });\n return p;\n }\n\n onDiagnostics(uri: string, handler: (d: LspDiagnostic[]) => void): () => void {\n this.diagHandlers.set(uri, handler);\n return () => {\n if (this.diagHandlers.get(uri) === handler) this.diagHandlers.delete(uri);\n };\n }\n\n didOpen(uri: string, text: string) {\n const existing = this.docs.get(uri);\n if (existing) {\n // Re-opening an already-tracked buffer (tab switch) \u2014 just resync.\n this.didChange(uri, text);\n return;\n }\n this.docs.set(uri, { text, version: 1 });\n this.sendRaw({\n jsonrpc: \"2.0\",\n method: \"textDocument/didOpen\",\n params: { textDocument: { uri, languageId: \"nbt\", version: 1, text } },\n });\n }\n\n didChange(uri: string, text: string) {\n const d = this.docs.get(uri);\n if (!d) return this.didOpen(uri, text);\n if (d.text === text) return;\n d.text = text;\n d.version += 1;\n this.sendRaw({\n jsonrpc: \"2.0\",\n method: \"textDocument/didChange\",\n params: {\n textDocument: { uri, version: d.version },\n contentChanges: [{ text }],\n },\n });\n }\n\n didClose(uri: string) {\n if (!this.docs.delete(uri)) return;\n this.sendRaw({\n jsonrpc: \"2.0\",\n method: \"textDocument/didClose\",\n params: { textDocument: { uri } },\n });\n }\n\n completion(uri: string, pos: LspPosition): Promise<{ items: LspCompletionItem[] } | LspCompletionItem[] | null> {\n return this.request(\"textDocument/completion\", {\n textDocument: { uri },\n position: pos,\n });\n }\n\n hover(uri: string, pos: LspPosition): Promise<{ contents?: { value?: string } } | null> {\n return this.request(\"textDocument/hover\", {\n textDocument: { uri },\n position: pos,\n });\n }\n\n definition(uri: string, pos: LspPosition): Promise<LspLocation | LspLocation[] | null> {\n return this.request(\"textDocument/definition\", {\n textDocument: { uri },\n position: pos,\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["EditorView", "keymap", "syntaxHighlighting", "indentUnit", "t", "EditorView", "indentUnit", "syntaxHighlighting", "keymap", "view"]
|
|
7
|
+
}
|
package/dist/core/auth.d.ts
CHANGED
|
@@ -9,6 +9,8 @@ export type WhoAmI = {
|
|
|
9
9
|
claimed: boolean;
|
|
10
10
|
};
|
|
11
11
|
export declare function fetchWhoAmI(apiBaseUrl: string, signal?: AbortSignal): Promise<WhoAmI>;
|
|
12
|
+
export declare function fetchDevtoolsSettings(apiBaseUrl: string, signal?: AbortSignal): Promise<Record<string, unknown>>;
|
|
13
|
+
export declare function saveDevtoolsSettings(apiBaseUrl: string, blob: Record<string, unknown>): Promise<void>;
|
|
12
14
|
export declare function devToolsSignIn(apiBaseUrl: string, email: string, password: string): Promise<void>;
|
|
13
15
|
export declare function devToolsSignUp(apiBaseUrl: string, name: string, email: string, password: string): Promise<void>;
|
|
14
16
|
export declare function devToolsSignOut(): void;
|
package/dist/core/index.d.ts
CHANGED
|
@@ -7,5 +7,5 @@ export { useLiveBulkRegistry } from "./use-cartridge-info";
|
|
|
7
7
|
export type { BulkEntity, BulkRegistry, LiveRegistryState, } from "./use-cartridge-info";
|
|
8
8
|
export { useGsheetsApi } from "./use-gsheets";
|
|
9
9
|
export type { GsheetSyncConfig, GsheetSaveInput } from "./use-gsheets";
|
|
10
|
-
export { getDevToolsToken, setDevToolsToken, clearDevToolsToken, authHeaders, fetchWhoAmI, devToolsSignIn, devToolsSignUp, devToolsSignOut, wsAuthProtocols, } from "./auth";
|
|
10
|
+
export { getDevToolsToken, setDevToolsToken, clearDevToolsToken, authHeaders, fetchWhoAmI, devToolsSignIn, devToolsSignUp, devToolsSignOut, wsAuthProtocols, fetchDevtoolsSettings, saveDevtoolsSettings, } from "./auth";
|
|
11
11
|
export type { WhoAmI } from "./auth";
|
package/dist/editor/index.d.ts
CHANGED
|
@@ -5,3 +5,5 @@ export { NbtLspClient } from "./lsp-client";
|
|
|
5
5
|
export type { LspPosition, LspRange, LspDiagnostic, LspCompletionItem, LspLocation, } from "./lsp-client";
|
|
6
6
|
export { lspExtensions } from "./lsp-extensions";
|
|
7
7
|
export type { GotoDefHandler } from "./lsp-extensions";
|
|
8
|
+
export { EDITOR_THEMES, themeExtension } from "./editor-themes";
|
|
9
|
+
export type { EditorTheme } from "./editor-themes";
|
package/dist/editor/index.js
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
|
+
EDITOR_THEMES,
|
|
3
4
|
NbtEditor,
|
|
4
5
|
NbtLspClient,
|
|
5
6
|
lspExtensions,
|
|
6
7
|
nbtLanguage,
|
|
7
|
-
nbtLanguageSupport
|
|
8
|
-
|
|
8
|
+
nbtLanguageSupport,
|
|
9
|
+
themeExtension
|
|
10
|
+
} from "../chunk-PI7ZMVVU.js";
|
|
9
11
|
export {
|
|
12
|
+
EDITOR_THEMES,
|
|
10
13
|
NbtEditor,
|
|
11
14
|
NbtLspClient,
|
|
12
15
|
lspExtensions,
|
|
13
16
|
nbtLanguage,
|
|
14
|
-
nbtLanguageSupport
|
|
17
|
+
nbtLanguageSupport,
|
|
18
|
+
themeExtension
|
|
15
19
|
};
|
|
16
20
|
//# sourceMappingURL=index.js.map
|
|
@@ -9,5 +9,9 @@ export type NbtEditorProps = {
|
|
|
9
9
|
onChange?: (text: string) => void;
|
|
10
10
|
onSave?: (text: string) => void;
|
|
11
11
|
onGotoDefinition?: GotoDefHandler;
|
|
12
|
+
theme?: string;
|
|
13
|
+
fontSize?: number;
|
|
14
|
+
lineWrap?: boolean;
|
|
15
|
+
tabSize?: number;
|
|
12
16
|
};
|
|
13
17
|
export declare const NbtEditor: React.FC<NbtEditorProps>;
|
package/dist/graph/index.js
CHANGED
|
@@ -6,8 +6,8 @@ import {
|
|
|
6
6
|
cartsFromContracts,
|
|
7
7
|
entityGraphId,
|
|
8
8
|
filterEntityGraphModel
|
|
9
|
-
} from "../chunk-
|
|
10
|
-
import "../chunk-
|
|
9
|
+
} from "../chunk-HTAPMIK6.js";
|
|
10
|
+
import "../chunk-AI2LKTA4.js";
|
|
11
11
|
export {
|
|
12
12
|
DiagramView as EntityGraph,
|
|
13
13
|
EntityNode,
|