drizzle-cube 0.4.24 → 0.4.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/client/charts.js +12 -12
  2. package/dist/client/chunks/{RetentionCombinedChart-BK3NPsHP.js → RetentionCombinedChart--SnU4Y_I.js} +2 -2
  3. package/dist/client/chunks/{RetentionCombinedChart-BK3NPsHP.js.map → RetentionCombinedChart--SnU4Y_I.js.map} +1 -1
  4. package/dist/client/chunks/{analysis-builder-KeTsXp1G.js → analysis-builder-C2jqaLZs.js} +2413 -2381
  5. package/dist/client/chunks/analysis-builder-C2jqaLZs.js.map +1 -0
  6. package/dist/client/chunks/{analysis-builder-shared-KSvGUzx6.js → analysis-builder-shared-Bz9oSywd.js} +21 -19
  7. package/dist/client/chunks/analysis-builder-shared-Bz9oSywd.js.map +1 -0
  8. package/dist/client/chunks/{chart-activity-grid-OG6he4YS.js → chart-activity-grid-DCznpK6N.js} +2 -2
  9. package/dist/client/chunks/{chart-activity-grid-OG6he4YS.js.map → chart-activity-grid-DCznpK6N.js.map} +1 -1
  10. package/dist/client/chunks/{chart-area-TawAd2k9.js → chart-area-CqKRIUpj.js} +3 -3
  11. package/dist/client/chunks/{chart-area-TawAd2k9.js.map → chart-area-CqKRIUpj.js.map} +1 -1
  12. package/dist/client/chunks/{chart-bar-D3vtCNQG.js → chart-bar-Bl5jvrU_.js} +2 -2
  13. package/dist/client/chunks/{chart-bar-D3vtCNQG.js.map → chart-bar-Bl5jvrU_.js.map} +1 -1
  14. package/dist/client/chunks/{chart-box-plot-BXwN2rO5.js → chart-box-plot-CzMb00z_.js} +2 -2
  15. package/dist/client/chunks/{chart-box-plot-BXwN2rO5.js.map → chart-box-plot-CzMb00z_.js.map} +1 -1
  16. package/dist/client/chunks/{chart-bubble-ZfNe8t5k.js → chart-bubble-BF8Z52eW.js} +2 -2
  17. package/dist/client/chunks/{chart-bubble-ZfNe8t5k.js.map → chart-bubble-BF8Z52eW.js.map} +1 -1
  18. package/dist/client/chunks/{chart-candlestick-DmF3haFu.js → chart-candlestick-ByWS945g.js} +2 -2
  19. package/dist/client/chunks/{chart-candlestick-DmF3haFu.js.map → chart-candlestick-ByWS945g.js.map} +1 -1
  20. package/dist/client/chunks/{chart-data-table-DJZPkArt.js → chart-data-table-HwfF-Ujv.js} +4 -4
  21. package/dist/client/chunks/{chart-data-table-DJZPkArt.js.map → chart-data-table-HwfF-Ujv.js.map} +1 -1
  22. package/dist/client/chunks/{chart-funnel-CE9x0Io9.js → chart-funnel-WmuoWlCq.js} +2 -2
  23. package/dist/client/chunks/{chart-funnel-CE9x0Io9.js.map → chart-funnel-WmuoWlCq.js.map} +1 -1
  24. package/dist/client/chunks/{chart-gauge-Djs5FWxB.js → chart-gauge-Cot4By-w.js} +2 -2
  25. package/dist/client/chunks/{chart-gauge-Djs5FWxB.js.map → chart-gauge-Cot4By-w.js.map} +1 -1
  26. package/dist/client/chunks/{chart-heat-map-CqtMkdxd.js → chart-heat-map-bGNtsZMr.js} +2 -2
  27. package/dist/client/chunks/{chart-heat-map-CqtMkdxd.js.map → chart-heat-map-bGNtsZMr.js.map} +1 -1
  28. package/dist/client/chunks/{chart-kpi-delta-DEzA74cL.js → chart-kpi-delta-DeyKMxgq.js} +4 -4
  29. package/dist/client/chunks/{chart-kpi-delta-DEzA74cL.js.map → chart-kpi-delta-DeyKMxgq.js.map} +1 -1
  30. package/dist/client/chunks/{chart-kpi-number-Bab-BZtX.js → chart-kpi-number-D1z1gxXO.js} +3 -3
  31. package/dist/client/chunks/{chart-kpi-number-Bab-BZtX.js.map → chart-kpi-number-D1z1gxXO.js.map} +1 -1
  32. package/dist/client/chunks/{chart-kpi-text-BkTgckDJ.js → chart-kpi-text-b7q6KWc0.js} +3 -3
  33. package/dist/client/chunks/{chart-kpi-text-BkTgckDJ.js.map → chart-kpi-text-b7q6KWc0.js.map} +1 -1
  34. package/dist/client/chunks/{chart-line-DhM-Hvu0.js → chart-line-3Nf-EPqJ.js} +3 -3
  35. package/dist/client/chunks/{chart-line-DhM-Hvu0.js.map → chart-line-3Nf-EPqJ.js.map} +1 -1
  36. package/dist/client/chunks/{chart-measure-profile-4vQxFm69.js → chart-measure-profile-BVjUonqU.js} +3 -3
  37. package/dist/client/chunks/{chart-measure-profile-4vQxFm69.js.map → chart-measure-profile-BVjUonqU.js.map} +1 -1
  38. package/dist/client/chunks/{chart-pie-B86KRcHI.js → chart-pie-DblG6w7g.js} +2 -2
  39. package/dist/client/chunks/{chart-pie-B86KRcHI.js.map → chart-pie-DblG6w7g.js.map} +1 -1
  40. package/dist/client/chunks/{chart-radar-BhDBmJRh.js → chart-radar-BHZbeeTg.js} +2 -2
  41. package/dist/client/chunks/{chart-radar-BhDBmJRh.js.map → chart-radar-BHZbeeTg.js.map} +1 -1
  42. package/dist/client/chunks/{chart-radial-bar-Brugya8X.js → chart-radial-bar-AlEJC1Jo.js} +2 -2
  43. package/dist/client/chunks/{chart-radial-bar-Brugya8X.js.map → chart-radial-bar-AlEJC1Jo.js.map} +1 -1
  44. package/dist/client/chunks/{chart-sankey-D2L8ympI.js → chart-sankey-E8vYKjQF.js} +2 -2
  45. package/dist/client/chunks/{chart-sankey-D2L8ympI.js.map → chart-sankey-E8vYKjQF.js.map} +1 -1
  46. package/dist/client/chunks/{chart-scatter-CAkbBDkK.js → chart-scatter-Bbxqi0iw.js} +2 -2
  47. package/dist/client/chunks/{chart-scatter-CAkbBDkK.js.map → chart-scatter-Bbxqi0iw.js.map} +1 -1
  48. package/dist/client/chunks/{chart-sunburst-DaxJ-cob.js → chart-sunburst-BgnTKolT.js} +2 -2
  49. package/dist/client/chunks/{chart-sunburst-DaxJ-cob.js.map → chart-sunburst-BgnTKolT.js.map} +1 -1
  50. package/dist/client/chunks/{chart-tree-map-CrDJAvZU.js → chart-tree-map-i9LGCLwl.js} +2 -2
  51. package/dist/client/chunks/{chart-tree-map-CrDJAvZU.js.map → chart-tree-map-i9LGCLwl.js.map} +1 -1
  52. package/dist/client/chunks/{chart-waterfall-BBwSfEKT.js → chart-waterfall-BeIhCm83.js} +3 -3
  53. package/dist/client/chunks/{chart-waterfall-BBwSfEKT.js.map → chart-waterfall-BeIhCm83.js.map} +1 -1
  54. package/dist/client/chunks/{charts-core-B4Rbfdcn.js → charts-core-BUUO36OM.js} +2 -2
  55. package/dist/client/chunks/{charts-core-B4Rbfdcn.js.map → charts-core-BUUO36OM.js.map} +1 -1
  56. package/dist/client/chunks/{charts-loader-DbrwgvCK.js → charts-loader-Bv-IWHVd.js} +25 -25
  57. package/dist/client/chunks/{charts-loader-DbrwgvCK.js.map → charts-loader-Bv-IWHVd.js.map} +1 -1
  58. package/dist/client/chunks/{components-Dz6XHgnZ.js → components-CPqnw8o8.js} +7 -7
  59. package/dist/client/chunks/components-CPqnw8o8.js.map +1 -0
  60. package/dist/client/chunks/{icons-DFJw-2HU.js → icons-CwvgmdIP.js} +25 -20
  61. package/dist/client/chunks/{icons-DFJw-2HU.js.map → icons-CwvgmdIP.js.map} +1 -1
  62. package/dist/client/chunks/{providers-CCw8Kjlc.js → providers-Ds7DRmnO.js} +4 -4
  63. package/dist/client/chunks/{providers-CCw8Kjlc.js.map → providers-Ds7DRmnO.js.map} +1 -1
  64. package/dist/client/chunks/schema-visualization-CzOuTQDu.js +563 -0
  65. package/dist/client/chunks/schema-visualization-CzOuTQDu.js.map +1 -0
  66. package/dist/client/chunks/{useDirtyStateTracking-CjhwBXRw.js → useDirtyStateTracking-CyAXd07d.js} +2 -2
  67. package/dist/client/chunks/{useDirtyStateTracking-CjhwBXRw.js.map → useDirtyStateTracking-CyAXd07d.js.map} +1 -1
  68. package/dist/client/chunks/{useExplainAI-IiW55BaQ.js → useExplainAI-CfQ_JmF1.js} +3 -3
  69. package/dist/client/chunks/{useExplainAI-IiW55BaQ.js.map → useExplainAI-CfQ_JmF1.js.map} +1 -1
  70. package/dist/client/components/AnalysisBuilder/types.d.ts +6 -0
  71. package/dist/client/components/SchemaVisualization/CubeNode.d.ts +14 -0
  72. package/dist/client/components/SchemaVisualization/RelationshipEdge.d.ts +13 -0
  73. package/dist/client/components/SchemaVisualization/SchemaVisualizationLazy.d.ts +3 -0
  74. package/dist/client/components/SchemaVisualization/index.d.ts +10 -0
  75. package/dist/client/components/SchemaVisualization/useERDLayout.d.ts +39 -0
  76. package/dist/client/components.js +1 -1
  77. package/dist/client/hooks.js +3 -3
  78. package/dist/client/icons/types.d.ts +1 -0
  79. package/dist/client/icons.js +1 -1
  80. package/dist/client/index.d.ts +2 -0
  81. package/dist/client/index.js +64 -62
  82. package/dist/client/index.js.map +1 -1
  83. package/dist/client/providers.js +3 -3
  84. package/dist/client/stores/analysisBuilderStore.d.ts +5 -1
  85. package/dist/client/styles.css +1 -1
  86. package/dist/client/utils.js +9 -9
  87. package/dist/client-bundle-stats.html +1 -1
  88. package/package.json +11 -1
  89. package/dist/client/chunks/analysis-builder-KeTsXp1G.js.map +0 -1
  90. package/dist/client/chunks/analysis-builder-shared-KSvGUzx6.js.map +0 -1
  91. package/dist/client/chunks/components-Dz6XHgnZ.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  import { a as h, c as x, u as A, d as q } from "./vendor-B2EH3V58.js";
2
2
  import { useMemo as p, useState as Q, useCallback as d } from "react";
3
- import { f as m, g as F } from "./providers-CCw8Kjlc.js";
4
- import { c as b, s as w } from "./useDirtyStateTracking-CjhwBXRw.js";
3
+ import { f as m, g as F } from "./providers-Ds7DRmnO.js";
4
+ import { c as b, s as w } from "./useDirtyStateTracking-CyAXd07d.js";
5
5
  function R(e) {
6
6
  return e ? ["cube", "dryRun", w(e)] : ["cube", "dryRun", null];
7
7
  }
@@ -179,4 +179,4 @@ export {
179
179
  U as e,
180
180
  z as u
181
181
  };
182
- //# sourceMappingURL=useExplainAI-IiW55BaQ.js.map
182
+ //# sourceMappingURL=useExplainAI-CfQ_JmF1.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useExplainAI-IiW55BaQ.js","sources":["../../../src/client/hooks/queries/useDryRunQuery.ts","../../../src/client/hooks/queries/useExplainQuery.ts","../../../src/client/hooks/queries/useExplainAI.ts"],"sourcesContent":["/**\n * useDryRunQuery - TanStack Query hook for dry-run (debug) data\n *\n * Features:\n * - Fetch SQL and analysis data for query debugging\n * - Support for single and multi-query modes\n * - Built-in caching with TanStack Query\n * - Parallel fetching for multiple queries\n *\n * This hook replaces the debug data useEffect in AnalysisBuilder.\n */\n\nimport { useQuery, useQueries } from '@tanstack/react-query'\nimport { useMemo } from 'react'\nimport { useCubeApi } from '../../providers/CubeApiProvider'\nimport type { CubeQuery } from '../../types'\nimport type { QueryAnalysis } from '../../components/AnalysisBuilder/types'\nimport { cleanQueryForServer } from '../../shared/utils'\nimport { stableStringify } from '../../shared/queryKey'\n\nexport type DryRunMode = 'regular' | 'comparison' | 'funnel' | 'flow' | 'retention'\n\ninterface DryRunResponsePayload {\n sql?: { sql: string; params?: unknown[] }\n analysis?: QueryAnalysis | null\n mode?: DryRunMode\n queryType?: string\n joinType?: string\n cubesUsed?: string[]\n modeMetadata?: unknown\n}\n\n/**\n * Debug data entry for a single query\n */\nexport interface DebugDataEntry {\n /** Generated SQL and parameters */\n sql: { sql: string; params: unknown[] } | null\n /** Query analysis (dimensions, measures, complexity, etc.) */\n analysis: QueryAnalysis | null\n /** Server-reported dry-run mode */\n mode?: DryRunMode | null\n /** Query type label from server */\n queryType?: string | null\n /** Join strategy label from server */\n joinType?: string | null\n /** Referenced cubes from server */\n cubesUsed?: string[]\n /** Mode-specific metadata (replaces funnel/flow/retention split) */\n modeMetadata?: unknown\n /** Whether this entry is loading */\n loading: boolean\n /** Error if fetch failed */\n error: Error | null\n}\n\n/**\n * Create a stable query key for dry-run\n */\nexport function createDryRunQueryKey(\n query: CubeQuery | null\n): readonly unknown[] {\n if (!query) return ['cube', 'dryRun', null] as const\n return ['cube', 'dryRun', stableStringify(query)] as const\n}\n\nexport interface UseDryRunQueryOptions {\n /**\n * Whether to skip the query\n * @default false\n */\n skip?: boolean\n /**\n * Stale time in milliseconds\n * @default 5 * 60 * 1000 (5 minutes)\n */\n staleTime?: number\n}\n\nexport interface UseDryRunQueryResult {\n /** Debug data for the query */\n debugData: DebugDataEntry\n /** Manually refetch */\n refetch: () => void\n}\n\nfunction inferModeFromPayload(payload: DryRunResponsePayload): DryRunMode | null {\n if (payload.mode) return payload.mode\n if (payload.queryType === 'comparisonQuery') return 'comparison'\n if (payload.queryType === 'funnelQuery') return 'funnel'\n if (payload.queryType === 'flowQuery') return 'flow'\n if (payload.queryType === 'retentionQuery') return 'retention'\n if (payload.queryType === 'regularQuery') return 'regular'\n return null\n}\n\nfunction normalizeDryRunResult(payload: DryRunResponsePayload): Omit<DebugDataEntry, 'loading' | 'error'> {\n const mode = inferModeFromPayload(payload)\n return {\n sql: payload.sql ? { sql: payload.sql.sql, params: payload.sql.params || [] } : null,\n analysis: (payload.analysis || null) as QueryAnalysis | null,\n mode,\n queryType: payload.queryType || null,\n joinType: payload.joinType || null,\n cubesUsed: payload.cubesUsed || [],\n modeMetadata: payload.modeMetadata\n }\n}\n\n/**\n * TanStack Query hook for single query dry-run (debug) data\n *\n * Usage:\n * ```tsx\n * const { debugData } = useDryRunQuery(query, { skip: !isValidQuery })\n * ```\n */\nexport function useDryRunQuery(\n query: CubeQuery | null,\n options: UseDryRunQueryOptions = {}\n): UseDryRunQueryResult {\n const { skip = false, staleTime = 5 * 60 * 1000 } = options\n const { cubeApi } = useCubeApi()\n\n // Transform query for server\n const serverQuery = useMemo(() => {\n if (!query) return null\n const modeQuery = query as CubeQuery & { funnel?: unknown; flow?: unknown; retention?: unknown }\n // Preserve specialized mode payloads as-is; cleanQueryForServer strips non-Cube.js keys.\n if (modeQuery.funnel || modeQuery.flow || modeQuery.retention) {\n return query\n }\n return cleanQueryForServer(query)\n }, [query])\n\n const queryResult = useQuery({\n queryKey: createDryRunQueryKey(serverQuery),\n queryFn: async () => {\n if (!serverQuery) throw new Error('No query provided')\n const result = await cubeApi.dryRun(serverQuery)\n return normalizeDryRunResult(result as DryRunResponsePayload)\n },\n enabled: !!serverQuery && !skip,\n staleTime,\n })\n\n const debugData: DebugDataEntry = {\n ...(queryResult.data || {\n sql: null,\n analysis: null,\n mode: null,\n queryType: null,\n joinType: null,\n cubesUsed: [],\n modeMetadata: undefined\n }),\n loading: queryResult.isLoading,\n error: queryResult.error ?? null,\n }\n\n return {\n debugData,\n refetch: () => queryResult.refetch(),\n }\n}\n\nexport interface UseMultiDryRunQueriesOptions {\n /**\n * Whether to skip all queries\n * @default false\n */\n skip?: boolean\n /**\n * Stale time in milliseconds\n * @default 5 * 60 * 1000 (5 minutes)\n */\n staleTime?: number\n}\n\nexport interface UseMultiDryRunQueriesResult {\n /** Debug data for each query */\n debugDataPerQuery: DebugDataEntry[]\n /** Whether any query is loading */\n isLoading: boolean\n /** Manually refetch all */\n refetchAll: () => void\n}\n\n/**\n * TanStack Query hook for multiple query dry-runs (debug) data\n *\n * Fetches debug data for multiple queries in parallel.\n *\n * Usage:\n * ```tsx\n * const { debugDataPerQuery, isLoading } = useMultiDryRunQueries(queries, {\n * skip: !isMultiQueryMode\n * })\n * ```\n */\nexport function useMultiDryRunQueries(\n queries: CubeQuery[],\n options: UseMultiDryRunQueriesOptions = {}\n): UseMultiDryRunQueriesResult {\n const { skip = false, staleTime = 5 * 60 * 1000 } = options\n const { cubeApi } = useCubeApi()\n\n // Transform queries for server\n const serverQueries = useMemo(() => {\n return queries.map((q) => cleanQueryForServer(q))\n }, [queries])\n\n // Use useQueries for parallel fetching\n const queryResults = useQueries({\n queries: serverQueries.map((query) => ({\n queryKey: createDryRunQueryKey(query),\n queryFn: async () => {\n const result = await cubeApi.dryRun(query)\n return normalizeDryRunResult(result as DryRunResponsePayload)\n },\n enabled: !skip,\n staleTime,\n })),\n })\n\n // Transform results to DebugDataEntry array\n const debugDataPerQuery: DebugDataEntry[] = queryResults.map((result) => ({\n ...(result.data || {\n sql: null,\n analysis: null,\n mode: null,\n queryType: null,\n joinType: null,\n cubesUsed: [],\n modeMetadata: undefined\n }),\n loading: result.isLoading,\n error: result.error ?? null,\n }))\n\n // Check if any query is loading\n const isLoading = queryResults.some((r) => r.isLoading)\n\n // Refetch all queries\n const refetchAll = () => {\n queryResults.forEach((r) => r.refetch())\n }\n\n return {\n debugDataPerQuery,\n isLoading,\n refetchAll,\n }\n}\n\n/**\n * Combined hook for single or multi-query dry-run based on mode\n *\n * This is a convenience wrapper that automatically chooses between\n * single and multi-query dry-run based on the number of queries.\n *\n * Usage:\n * ```tsx\n * const { debugDataPerQuery } = useDryRunQueries({\n * queries: isMultiQueryMode ? allQueries : [currentQuery],\n * isMultiQueryMode,\n * skip: !isValidQuery\n * })\n * ```\n */\nexport function useDryRunQueries(options: {\n queries: CubeQuery[]\n isMultiQueryMode: boolean\n skip?: boolean\n staleTime?: number\n}): UseMultiDryRunQueriesResult {\n const { queries, isMultiQueryMode, skip = false, staleTime } = options\n\n // For single query mode, wrap in array for consistent interface\n const queriesToFetch = isMultiQueryMode ? queries : queries.slice(0, 1)\n\n return useMultiDryRunQueries(queriesToFetch, { skip, staleTime })\n}\n\nexport type FunnelDebugDataEntry = DebugDataEntry\n\n/**\n * TanStack Query hook for funnel query dry-run (debug) data\n *\n * Usage:\n * ```tsx\n * const { debugData } = useFunnelDryRunQuery(serverQuery, { skip: !isFunnelMode })\n * ```\n */\nexport function useFunnelDryRunQuery(\n serverQuery: unknown | null,\n options: UseDryRunQueryOptions = {}\n): { debugData: FunnelDebugDataEntry; refetch: () => void } {\n return useDryRunQuery(serverQuery as CubeQuery | null, options)\n}\n\nexport type FlowDebugDataEntry = DebugDataEntry\n\n/**\n * TanStack Query hook for flow query dry-run (debug) data\n *\n * Usage:\n * ```tsx\n * const { debugData } = useFlowDryRunQuery(serverQuery, { skip: !isFlowMode })\n * ```\n */\nexport function useFlowDryRunQuery(\n serverQuery: unknown | null,\n options: UseDryRunQueryOptions = {}\n): { debugData: FlowDebugDataEntry; refetch: () => void } {\n return useDryRunQuery(serverQuery as CubeQuery | null, options)\n}\n\nexport type RetentionDebugDataEntry = DebugDataEntry\n\n/**\n * TanStack Query hook for retention query dry-run (debug) data\n *\n * Usage:\n * ```tsx\n * const { debugData } = useRetentionDryRunQuery(serverQuery, { skip: !isRetentionMode })\n * ```\n */\nexport function useRetentionDryRunQuery(\n serverQuery: unknown | null,\n options: UseDryRunQueryOptions = {}\n): { debugData: RetentionDebugDataEntry; refetch: () => void } {\n return useDryRunQuery(serverQuery as CubeQuery | null, options)\n}\n","/**\n * useExplainQuery - TanStack Query hook for EXPLAIN PLAN execution\n *\n * Features:\n * - Manually triggered (not automatic like useCubeLoadQuery)\n * - Returns normalized execution plan across PostgreSQL, MySQL, and SQLite\n * - Supports EXPLAIN ANALYZE for actual timing data\n * - No caching - always fetches fresh data to reflect schema/index changes\n *\n * Usage:\n * ```tsx\n * const { explainResult, isLoading, error, runExplain } = useExplainQuery(query)\n *\n * // Trigger explain manually\n * <button onClick={() => runExplain({ analyze: true })}>Explain with Timing</button>\n * ```\n */\n\nimport { useQuery } from '@tanstack/react-query'\nimport { useCallback, useMemo, useState } from 'react'\nimport { useCubeApi } from '../../providers/CubeApiProvider'\nimport type { CubeQuery, ExplainResult, ExplainOptions } from '../../types'\nimport { cleanQueryForServer } from '../../shared/utils'\nimport { stableStringify } from '../../shared/queryKey'\n\n/**\n * Query type that can be explained - includes standard queries, funnel queries, flow queries, and retention queries\n */\nexport type ExplainableQuery = CubeQuery | { funnel: unknown } | { flow: unknown } | { retention: unknown } | unknown\n\n/**\n * Create a stable query key for explain\n */\nexport function createExplainQueryKey(\n query: ExplainableQuery | null,\n options?: ExplainOptions\n): readonly unknown[] {\n if (!query) return ['cube', 'explain', null, null] as const\n return ['cube', 'explain', stableStringify(query), options?.analyze ?? false] as const\n}\n\nexport interface UseExplainQueryOptions {\n /**\n * Whether to skip the query (prevent execution even when triggered)\n * @default false\n */\n skip?: boolean\n}\n\nexport interface UseExplainQueryResult {\n /** The explain result from the server */\n explainResult: ExplainResult | null\n /** Whether the explain query is loading */\n isLoading: boolean\n /** Whether an explain has been triggered */\n hasRun: boolean\n /** Error if explain failed */\n error: Error | null\n /**\n * Manually trigger the explain query\n * @param options - Optional explain options (e.g., { analyze: true } for actual timing)\n */\n runExplain: (options?: ExplainOptions) => void\n /** Clear the explain result */\n clearExplain: () => void\n}\n\n/**\n * Check if query is a funnel query\n */\nfunction isFunnelQuery(query: unknown): query is { funnel: unknown } {\n return typeof query === 'object' && query !== null && 'funnel' in query\n}\n\n/**\n * Check if query is a flow query\n */\nfunction isFlowQuery(query: unknown): query is { flow: unknown } {\n return typeof query === 'object' && query !== null && 'flow' in query\n}\n\n/**\n * Check if query is a retention query\n */\nfunction isRetentionQuery(query: unknown): query is { retention: unknown } {\n return typeof query === 'object' && query !== null && 'retention' in query\n}\n\n/**\n * TanStack Query hook for EXPLAIN PLAN execution\n *\n * Unlike useDryRunQuery, this hook is manually triggered via `runExplain()`.\n * This is intentional because:\n * 1. EXPLAIN queries have performance overhead\n * 2. EXPLAIN ANALYZE actually executes the query\n * 3. Users should explicitly choose when to run explain\n *\n * Supports standard queries, funnel queries, and flow queries.\n *\n * Usage:\n * ```tsx\n * const { explainResult, isLoading, runExplain } = useExplainQuery(query, { skip: !isValidQuery })\n *\n * // Trigger explain\n * <button onClick={() => runExplain()}>Explain Plan</button>\n *\n * // Trigger explain with timing\n * <button onClick={() => runExplain({ analyze: true })}>Explain with Timing</button>\n * ```\n */\nexport function useExplainQuery(\n query: ExplainableQuery | null,\n options: UseExplainQueryOptions = {}\n): UseExplainQueryResult {\n const { skip = false } = options\n const { cubeApi } = useCubeApi()\n\n // Track whether explain has been triggered and with what options\n const [explainOptions, setExplainOptions] = useState<ExplainOptions | null>(null)\n const [hasTriggered, setHasTriggered] = useState(false)\n\n // Transform query for server\n // For funnel/flow/retention queries, pass them directly without cleaning\n const serverQuery = useMemo(() => {\n if (!query) return null\n // Funnel, flow, and retention queries have their own format, don't clean them\n if (isFunnelQuery(query) || isFlowQuery(query) || isRetentionQuery(query)) {\n return query\n }\n // Standard queries get cleaned\n return cleanQueryForServer(query as CubeQuery)\n }, [query])\n\n // Query is enabled only when:\n // 1. We have a query\n // 2. Skip is false\n // 3. User has triggered the explain\n const queryEnabled = !!serverQuery && !skip && hasTriggered\n\n const queryResult = useQuery({\n queryKey: createExplainQueryKey(serverQuery, explainOptions ?? undefined),\n queryFn: async () => {\n if (!serverQuery) throw new Error('No query provided')\n const result = await cubeApi.explain(serverQuery, explainOptions ?? undefined)\n return result\n },\n enabled: queryEnabled,\n // EXPLAIN queries should never be cached - always fetch fresh data\n // This ensures users see the latest execution plan after schema/index changes\n staleTime: 0,\n gcTime: 0,\n // Don't refetch automatically - this is manually triggered\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n refetchOnMount: false,\n })\n\n // Manual trigger function\n const runExplain = useCallback((opts?: ExplainOptions) => {\n if (skip || !serverQuery) return\n setExplainOptions(opts ?? null)\n setHasTriggered(true)\n // If already triggered with same options, refetch\n if (hasTriggered) {\n queryResult.refetch()\n }\n }, [skip, serverQuery, hasTriggered, queryResult])\n\n // Clear function\n const clearExplain = useCallback(() => {\n setHasTriggered(false)\n setExplainOptions(null)\n }, [])\n\n return {\n explainResult: queryResult.data ?? null,\n isLoading: queryResult.isLoading || queryResult.isFetching,\n hasRun: hasTriggered,\n error: queryResult.error ?? null,\n runExplain,\n clearExplain,\n }\n}\n","/**\n * useExplainAI - TanStack Query hook for AI analysis of EXPLAIN plans\n *\n * Features:\n * - Manually triggered via useMutation (not automatic)\n * - Analyzes execution plans and provides actionable recommendations\n * - Returns structured recommendations (indexes, table changes, cube improvements)\n * - No caching - always fetches fresh analysis\n * - Uses the /api/ai/explain/analyze endpoint\n *\n * Usage:\n * ```tsx\n * const { analysis, isAnalyzing, error, analyze, clearAnalysis } = useExplainAI()\n *\n * // After getting an explain result, trigger AI analysis\n * <button onClick={() => analyze(explainResult, query)}>Analyze with AI</button>\n * ```\n */\n\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { useCallback } from 'react'\nimport type { ExplainResult, AIExplainAnalysis } from '../../types'\nimport { useCubeFeatures } from '../../providers/CubeFeaturesProvider'\n\nexport interface UseExplainAIOptions {\n /**\n * Custom AI endpoint for explain analysis\n * @default '/api/ai/explain/analyze'\n */\n aiEndpoint?: string\n}\n\nexport interface UseExplainAIResult {\n /** The AI analysis result */\n analysis: AIExplainAnalysis | null\n /** Whether AI analysis is in progress */\n isAnalyzing: boolean\n /** Error if AI analysis failed */\n error: Error | null\n /**\n * Trigger AI analysis of an explain result\n * @param explainResult - The EXPLAIN result to analyze\n * @param query - The original semantic query\n */\n analyze: (explainResult: ExplainResult, query: unknown) => void\n /** Clear the analysis result */\n clearAnalysis: () => void\n}\n\n/**\n * Query key for AI explain analysis\n */\nexport const EXPLAIN_AI_QUERY_KEY = ['cube', 'explain', 'ai'] as const\n\n/**\n * TanStack Query hook for AI analysis of EXPLAIN plans\n *\n * This hook uses useMutation to call the AI endpoint and analyze execution plans,\n * providing actionable recommendations for performance improvement.\n *\n * Recommendations focus on what users CAN control:\n * - Index creation (with CREATE INDEX statements)\n * - Table structure changes\n * - Cube definition improvements (segments, pre-aggregations, joins)\n *\n * Usage:\n * ```tsx\n * const { analysis, isAnalyzing, analyze } = useExplainAI()\n *\n * // After running EXPLAIN\n * if (explainResult) {\n * <button onClick={() => analyze(explainResult, query)}>\n * {isAnalyzing ? 'Analyzing...' : 'Analyze with AI'}\n * </button>\n * }\n *\n * // Display recommendations\n * {analysis?.recommendations.map(rec => (\n * <div key={rec.title}>\n * <h4>{rec.title}</h4>\n * <p>{rec.description}</p>\n * {rec.sql && <pre>{rec.sql}</pre>}\n * {rec.cubeCode && <pre>{rec.cubeCode}</pre>}\n * </div>\n * ))}\n * ```\n */\nexport function useExplainAI(options: UseExplainAIOptions = {}): UseExplainAIResult {\n const { features } = useCubeFeatures()\n const enableAI = features.enableAI ?? true\n const queryClient = useQueryClient()\n\n // AI endpoint - defaults to /api/ai/explain/analyze\n // This is the standard path for AI routes in the dev server\n const aiEndpoint = options.aiEndpoint ?? '/api/ai/explain/analyze'\n\n const mutation = useMutation({\n mutationKey: EXPLAIN_AI_QUERY_KEY,\n mutationFn: async ({ explainResult, query }: { explainResult: ExplainResult; query: unknown }) => {\n // Check if AI is enabled\n if (!enableAI) {\n throw new Error('AI features are disabled')\n }\n\n const response = await fetch(aiEndpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n credentials: 'include',\n body: JSON.stringify({\n explainResult,\n query,\n }),\n })\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}))\n throw new Error(\n errorData.error ||\n errorData.message ||\n `AI analysis failed: ${response.status} ${response.statusText}`\n )\n }\n\n const result: AIExplainAnalysis = await response.json()\n return result\n },\n // No caching - each mutation is independent\n gcTime: 0,\n })\n\n const analyze = useCallback((explainResult: ExplainResult, query: unknown) => {\n mutation.mutate({ explainResult, query })\n }, [mutation])\n\n const clearAnalysis = useCallback(() => {\n mutation.reset()\n // Also invalidate any cached queries\n queryClient.removeQueries({ queryKey: EXPLAIN_AI_QUERY_KEY })\n }, [mutation, queryClient])\n\n return {\n analysis: mutation.data ?? null,\n isAnalyzing: mutation.isPending,\n error: mutation.error ?? null,\n analyze,\n clearAnalysis,\n }\n}\n"],"names":["createDryRunQueryKey","query","stableStringify","inferModeFromPayload","payload","normalizeDryRunResult","mode","useDryRunQuery","options","skip","staleTime","cubeApi","useCubeApi","serverQuery","useMemo","modeQuery","cleanQueryForServer","queryResult","useQuery","result","useMultiDryRunQueries","queries","serverQueries","q","queryResults","useQueries","debugDataPerQuery","isLoading","r","useDryRunQueries","isMultiQueryMode","queriesToFetch","createExplainQueryKey","isFunnelQuery","isFlowQuery","isRetentionQuery","useExplainQuery","explainOptions","setExplainOptions","useState","hasTriggered","setHasTriggered","queryEnabled","runExplain","useCallback","opts","clearExplain","EXPLAIN_AI_QUERY_KEY","useExplainAI","features","useCubeFeatures","enableAI","queryClient","useQueryClient","aiEndpoint","mutation","useMutation","explainResult","response","errorData","analyze","clearAnalysis"],"mappings":"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"}
1
+ {"version":3,"file":"useExplainAI-CfQ_JmF1.js","sources":["../../../src/client/hooks/queries/useDryRunQuery.ts","../../../src/client/hooks/queries/useExplainQuery.ts","../../../src/client/hooks/queries/useExplainAI.ts"],"sourcesContent":["/**\n * useDryRunQuery - TanStack Query hook for dry-run (debug) data\n *\n * Features:\n * - Fetch SQL and analysis data for query debugging\n * - Support for single and multi-query modes\n * - Built-in caching with TanStack Query\n * - Parallel fetching for multiple queries\n *\n * This hook replaces the debug data useEffect in AnalysisBuilder.\n */\n\nimport { useQuery, useQueries } from '@tanstack/react-query'\nimport { useMemo } from 'react'\nimport { useCubeApi } from '../../providers/CubeApiProvider'\nimport type { CubeQuery } from '../../types'\nimport type { QueryAnalysis } from '../../components/AnalysisBuilder/types'\nimport { cleanQueryForServer } from '../../shared/utils'\nimport { stableStringify } from '../../shared/queryKey'\n\nexport type DryRunMode = 'regular' | 'comparison' | 'funnel' | 'flow' | 'retention'\n\ninterface DryRunResponsePayload {\n sql?: { sql: string; params?: unknown[] }\n analysis?: QueryAnalysis | null\n mode?: DryRunMode\n queryType?: string\n joinType?: string\n cubesUsed?: string[]\n modeMetadata?: unknown\n}\n\n/**\n * Debug data entry for a single query\n */\nexport interface DebugDataEntry {\n /** Generated SQL and parameters */\n sql: { sql: string; params: unknown[] } | null\n /** Query analysis (dimensions, measures, complexity, etc.) */\n analysis: QueryAnalysis | null\n /** Server-reported dry-run mode */\n mode?: DryRunMode | null\n /** Query type label from server */\n queryType?: string | null\n /** Join strategy label from server */\n joinType?: string | null\n /** Referenced cubes from server */\n cubesUsed?: string[]\n /** Mode-specific metadata (replaces funnel/flow/retention split) */\n modeMetadata?: unknown\n /** Whether this entry is loading */\n loading: boolean\n /** Error if fetch failed */\n error: Error | null\n}\n\n/**\n * Create a stable query key for dry-run\n */\nexport function createDryRunQueryKey(\n query: CubeQuery | null\n): readonly unknown[] {\n if (!query) return ['cube', 'dryRun', null] as const\n return ['cube', 'dryRun', stableStringify(query)] as const\n}\n\nexport interface UseDryRunQueryOptions {\n /**\n * Whether to skip the query\n * @default false\n */\n skip?: boolean\n /**\n * Stale time in milliseconds\n * @default 5 * 60 * 1000 (5 minutes)\n */\n staleTime?: number\n}\n\nexport interface UseDryRunQueryResult {\n /** Debug data for the query */\n debugData: DebugDataEntry\n /** Manually refetch */\n refetch: () => void\n}\n\nfunction inferModeFromPayload(payload: DryRunResponsePayload): DryRunMode | null {\n if (payload.mode) return payload.mode\n if (payload.queryType === 'comparisonQuery') return 'comparison'\n if (payload.queryType === 'funnelQuery') return 'funnel'\n if (payload.queryType === 'flowQuery') return 'flow'\n if (payload.queryType === 'retentionQuery') return 'retention'\n if (payload.queryType === 'regularQuery') return 'regular'\n return null\n}\n\nfunction normalizeDryRunResult(payload: DryRunResponsePayload): Omit<DebugDataEntry, 'loading' | 'error'> {\n const mode = inferModeFromPayload(payload)\n return {\n sql: payload.sql ? { sql: payload.sql.sql, params: payload.sql.params || [] } : null,\n analysis: (payload.analysis || null) as QueryAnalysis | null,\n mode,\n queryType: payload.queryType || null,\n joinType: payload.joinType || null,\n cubesUsed: payload.cubesUsed || [],\n modeMetadata: payload.modeMetadata\n }\n}\n\n/**\n * TanStack Query hook for single query dry-run (debug) data\n *\n * Usage:\n * ```tsx\n * const { debugData } = useDryRunQuery(query, { skip: !isValidQuery })\n * ```\n */\nexport function useDryRunQuery(\n query: CubeQuery | null,\n options: UseDryRunQueryOptions = {}\n): UseDryRunQueryResult {\n const { skip = false, staleTime = 5 * 60 * 1000 } = options\n const { cubeApi } = useCubeApi()\n\n // Transform query for server\n const serverQuery = useMemo(() => {\n if (!query) return null\n const modeQuery = query as CubeQuery & { funnel?: unknown; flow?: unknown; retention?: unknown }\n // Preserve specialized mode payloads as-is; cleanQueryForServer strips non-Cube.js keys.\n if (modeQuery.funnel || modeQuery.flow || modeQuery.retention) {\n return query\n }\n return cleanQueryForServer(query)\n }, [query])\n\n const queryResult = useQuery({\n queryKey: createDryRunQueryKey(serverQuery),\n queryFn: async () => {\n if (!serverQuery) throw new Error('No query provided')\n const result = await cubeApi.dryRun(serverQuery)\n return normalizeDryRunResult(result as DryRunResponsePayload)\n },\n enabled: !!serverQuery && !skip,\n staleTime,\n })\n\n const debugData: DebugDataEntry = {\n ...(queryResult.data || {\n sql: null,\n analysis: null,\n mode: null,\n queryType: null,\n joinType: null,\n cubesUsed: [],\n modeMetadata: undefined\n }),\n loading: queryResult.isLoading,\n error: queryResult.error ?? null,\n }\n\n return {\n debugData,\n refetch: () => queryResult.refetch(),\n }\n}\n\nexport interface UseMultiDryRunQueriesOptions {\n /**\n * Whether to skip all queries\n * @default false\n */\n skip?: boolean\n /**\n * Stale time in milliseconds\n * @default 5 * 60 * 1000 (5 minutes)\n */\n staleTime?: number\n}\n\nexport interface UseMultiDryRunQueriesResult {\n /** Debug data for each query */\n debugDataPerQuery: DebugDataEntry[]\n /** Whether any query is loading */\n isLoading: boolean\n /** Manually refetch all */\n refetchAll: () => void\n}\n\n/**\n * TanStack Query hook for multiple query dry-runs (debug) data\n *\n * Fetches debug data for multiple queries in parallel.\n *\n * Usage:\n * ```tsx\n * const { debugDataPerQuery, isLoading } = useMultiDryRunQueries(queries, {\n * skip: !isMultiQueryMode\n * })\n * ```\n */\nexport function useMultiDryRunQueries(\n queries: CubeQuery[],\n options: UseMultiDryRunQueriesOptions = {}\n): UseMultiDryRunQueriesResult {\n const { skip = false, staleTime = 5 * 60 * 1000 } = options\n const { cubeApi } = useCubeApi()\n\n // Transform queries for server\n const serverQueries = useMemo(() => {\n return queries.map((q) => cleanQueryForServer(q))\n }, [queries])\n\n // Use useQueries for parallel fetching\n const queryResults = useQueries({\n queries: serverQueries.map((query) => ({\n queryKey: createDryRunQueryKey(query),\n queryFn: async () => {\n const result = await cubeApi.dryRun(query)\n return normalizeDryRunResult(result as DryRunResponsePayload)\n },\n enabled: !skip,\n staleTime,\n })),\n })\n\n // Transform results to DebugDataEntry array\n const debugDataPerQuery: DebugDataEntry[] = queryResults.map((result) => ({\n ...(result.data || {\n sql: null,\n analysis: null,\n mode: null,\n queryType: null,\n joinType: null,\n cubesUsed: [],\n modeMetadata: undefined\n }),\n loading: result.isLoading,\n error: result.error ?? null,\n }))\n\n // Check if any query is loading\n const isLoading = queryResults.some((r) => r.isLoading)\n\n // Refetch all queries\n const refetchAll = () => {\n queryResults.forEach((r) => r.refetch())\n }\n\n return {\n debugDataPerQuery,\n isLoading,\n refetchAll,\n }\n}\n\n/**\n * Combined hook for single or multi-query dry-run based on mode\n *\n * This is a convenience wrapper that automatically chooses between\n * single and multi-query dry-run based on the number of queries.\n *\n * Usage:\n * ```tsx\n * const { debugDataPerQuery } = useDryRunQueries({\n * queries: isMultiQueryMode ? allQueries : [currentQuery],\n * isMultiQueryMode,\n * skip: !isValidQuery\n * })\n * ```\n */\nexport function useDryRunQueries(options: {\n queries: CubeQuery[]\n isMultiQueryMode: boolean\n skip?: boolean\n staleTime?: number\n}): UseMultiDryRunQueriesResult {\n const { queries, isMultiQueryMode, skip = false, staleTime } = options\n\n // For single query mode, wrap in array for consistent interface\n const queriesToFetch = isMultiQueryMode ? queries : queries.slice(0, 1)\n\n return useMultiDryRunQueries(queriesToFetch, { skip, staleTime })\n}\n\nexport type FunnelDebugDataEntry = DebugDataEntry\n\n/**\n * TanStack Query hook for funnel query dry-run (debug) data\n *\n * Usage:\n * ```tsx\n * const { debugData } = useFunnelDryRunQuery(serverQuery, { skip: !isFunnelMode })\n * ```\n */\nexport function useFunnelDryRunQuery(\n serverQuery: unknown | null,\n options: UseDryRunQueryOptions = {}\n): { debugData: FunnelDebugDataEntry; refetch: () => void } {\n return useDryRunQuery(serverQuery as CubeQuery | null, options)\n}\n\nexport type FlowDebugDataEntry = DebugDataEntry\n\n/**\n * TanStack Query hook for flow query dry-run (debug) data\n *\n * Usage:\n * ```tsx\n * const { debugData } = useFlowDryRunQuery(serverQuery, { skip: !isFlowMode })\n * ```\n */\nexport function useFlowDryRunQuery(\n serverQuery: unknown | null,\n options: UseDryRunQueryOptions = {}\n): { debugData: FlowDebugDataEntry; refetch: () => void } {\n return useDryRunQuery(serverQuery as CubeQuery | null, options)\n}\n\nexport type RetentionDebugDataEntry = DebugDataEntry\n\n/**\n * TanStack Query hook for retention query dry-run (debug) data\n *\n * Usage:\n * ```tsx\n * const { debugData } = useRetentionDryRunQuery(serverQuery, { skip: !isRetentionMode })\n * ```\n */\nexport function useRetentionDryRunQuery(\n serverQuery: unknown | null,\n options: UseDryRunQueryOptions = {}\n): { debugData: RetentionDebugDataEntry; refetch: () => void } {\n return useDryRunQuery(serverQuery as CubeQuery | null, options)\n}\n","/**\n * useExplainQuery - TanStack Query hook for EXPLAIN PLAN execution\n *\n * Features:\n * - Manually triggered (not automatic like useCubeLoadQuery)\n * - Returns normalized execution plan across PostgreSQL, MySQL, and SQLite\n * - Supports EXPLAIN ANALYZE for actual timing data\n * - No caching - always fetches fresh data to reflect schema/index changes\n *\n * Usage:\n * ```tsx\n * const { explainResult, isLoading, error, runExplain } = useExplainQuery(query)\n *\n * // Trigger explain manually\n * <button onClick={() => runExplain({ analyze: true })}>Explain with Timing</button>\n * ```\n */\n\nimport { useQuery } from '@tanstack/react-query'\nimport { useCallback, useMemo, useState } from 'react'\nimport { useCubeApi } from '../../providers/CubeApiProvider'\nimport type { CubeQuery, ExplainResult, ExplainOptions } from '../../types'\nimport { cleanQueryForServer } from '../../shared/utils'\nimport { stableStringify } from '../../shared/queryKey'\n\n/**\n * Query type that can be explained - includes standard queries, funnel queries, flow queries, and retention queries\n */\nexport type ExplainableQuery = CubeQuery | { funnel: unknown } | { flow: unknown } | { retention: unknown } | unknown\n\n/**\n * Create a stable query key for explain\n */\nexport function createExplainQueryKey(\n query: ExplainableQuery | null,\n options?: ExplainOptions\n): readonly unknown[] {\n if (!query) return ['cube', 'explain', null, null] as const\n return ['cube', 'explain', stableStringify(query), options?.analyze ?? false] as const\n}\n\nexport interface UseExplainQueryOptions {\n /**\n * Whether to skip the query (prevent execution even when triggered)\n * @default false\n */\n skip?: boolean\n}\n\nexport interface UseExplainQueryResult {\n /** The explain result from the server */\n explainResult: ExplainResult | null\n /** Whether the explain query is loading */\n isLoading: boolean\n /** Whether an explain has been triggered */\n hasRun: boolean\n /** Error if explain failed */\n error: Error | null\n /**\n * Manually trigger the explain query\n * @param options - Optional explain options (e.g., { analyze: true } for actual timing)\n */\n runExplain: (options?: ExplainOptions) => void\n /** Clear the explain result */\n clearExplain: () => void\n}\n\n/**\n * Check if query is a funnel query\n */\nfunction isFunnelQuery(query: unknown): query is { funnel: unknown } {\n return typeof query === 'object' && query !== null && 'funnel' in query\n}\n\n/**\n * Check if query is a flow query\n */\nfunction isFlowQuery(query: unknown): query is { flow: unknown } {\n return typeof query === 'object' && query !== null && 'flow' in query\n}\n\n/**\n * Check if query is a retention query\n */\nfunction isRetentionQuery(query: unknown): query is { retention: unknown } {\n return typeof query === 'object' && query !== null && 'retention' in query\n}\n\n/**\n * TanStack Query hook for EXPLAIN PLAN execution\n *\n * Unlike useDryRunQuery, this hook is manually triggered via `runExplain()`.\n * This is intentional because:\n * 1. EXPLAIN queries have performance overhead\n * 2. EXPLAIN ANALYZE actually executes the query\n * 3. Users should explicitly choose when to run explain\n *\n * Supports standard queries, funnel queries, and flow queries.\n *\n * Usage:\n * ```tsx\n * const { explainResult, isLoading, runExplain } = useExplainQuery(query, { skip: !isValidQuery })\n *\n * // Trigger explain\n * <button onClick={() => runExplain()}>Explain Plan</button>\n *\n * // Trigger explain with timing\n * <button onClick={() => runExplain({ analyze: true })}>Explain with Timing</button>\n * ```\n */\nexport function useExplainQuery(\n query: ExplainableQuery | null,\n options: UseExplainQueryOptions = {}\n): UseExplainQueryResult {\n const { skip = false } = options\n const { cubeApi } = useCubeApi()\n\n // Track whether explain has been triggered and with what options\n const [explainOptions, setExplainOptions] = useState<ExplainOptions | null>(null)\n const [hasTriggered, setHasTriggered] = useState(false)\n\n // Transform query for server\n // For funnel/flow/retention queries, pass them directly without cleaning\n const serverQuery = useMemo(() => {\n if (!query) return null\n // Funnel, flow, and retention queries have their own format, don't clean them\n if (isFunnelQuery(query) || isFlowQuery(query) || isRetentionQuery(query)) {\n return query\n }\n // Standard queries get cleaned\n return cleanQueryForServer(query as CubeQuery)\n }, [query])\n\n // Query is enabled only when:\n // 1. We have a query\n // 2. Skip is false\n // 3. User has triggered the explain\n const queryEnabled = !!serverQuery && !skip && hasTriggered\n\n const queryResult = useQuery({\n queryKey: createExplainQueryKey(serverQuery, explainOptions ?? undefined),\n queryFn: async () => {\n if (!serverQuery) throw new Error('No query provided')\n const result = await cubeApi.explain(serverQuery, explainOptions ?? undefined)\n return result\n },\n enabled: queryEnabled,\n // EXPLAIN queries should never be cached - always fetch fresh data\n // This ensures users see the latest execution plan after schema/index changes\n staleTime: 0,\n gcTime: 0,\n // Don't refetch automatically - this is manually triggered\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n refetchOnMount: false,\n })\n\n // Manual trigger function\n const runExplain = useCallback((opts?: ExplainOptions) => {\n if (skip || !serverQuery) return\n setExplainOptions(opts ?? null)\n setHasTriggered(true)\n // If already triggered with same options, refetch\n if (hasTriggered) {\n queryResult.refetch()\n }\n }, [skip, serverQuery, hasTriggered, queryResult])\n\n // Clear function\n const clearExplain = useCallback(() => {\n setHasTriggered(false)\n setExplainOptions(null)\n }, [])\n\n return {\n explainResult: queryResult.data ?? null,\n isLoading: queryResult.isLoading || queryResult.isFetching,\n hasRun: hasTriggered,\n error: queryResult.error ?? null,\n runExplain,\n clearExplain,\n }\n}\n","/**\n * useExplainAI - TanStack Query hook for AI analysis of EXPLAIN plans\n *\n * Features:\n * - Manually triggered via useMutation (not automatic)\n * - Analyzes execution plans and provides actionable recommendations\n * - Returns structured recommendations (indexes, table changes, cube improvements)\n * - No caching - always fetches fresh analysis\n * - Uses the /api/ai/explain/analyze endpoint\n *\n * Usage:\n * ```tsx\n * const { analysis, isAnalyzing, error, analyze, clearAnalysis } = useExplainAI()\n *\n * // After getting an explain result, trigger AI analysis\n * <button onClick={() => analyze(explainResult, query)}>Analyze with AI</button>\n * ```\n */\n\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { useCallback } from 'react'\nimport type { ExplainResult, AIExplainAnalysis } from '../../types'\nimport { useCubeFeatures } from '../../providers/CubeFeaturesProvider'\n\nexport interface UseExplainAIOptions {\n /**\n * Custom AI endpoint for explain analysis\n * @default '/api/ai/explain/analyze'\n */\n aiEndpoint?: string\n}\n\nexport interface UseExplainAIResult {\n /** The AI analysis result */\n analysis: AIExplainAnalysis | null\n /** Whether AI analysis is in progress */\n isAnalyzing: boolean\n /** Error if AI analysis failed */\n error: Error | null\n /**\n * Trigger AI analysis of an explain result\n * @param explainResult - The EXPLAIN result to analyze\n * @param query - The original semantic query\n */\n analyze: (explainResult: ExplainResult, query: unknown) => void\n /** Clear the analysis result */\n clearAnalysis: () => void\n}\n\n/**\n * Query key for AI explain analysis\n */\nexport const EXPLAIN_AI_QUERY_KEY = ['cube', 'explain', 'ai'] as const\n\n/**\n * TanStack Query hook for AI analysis of EXPLAIN plans\n *\n * This hook uses useMutation to call the AI endpoint and analyze execution plans,\n * providing actionable recommendations for performance improvement.\n *\n * Recommendations focus on what users CAN control:\n * - Index creation (with CREATE INDEX statements)\n * - Table structure changes\n * - Cube definition improvements (segments, pre-aggregations, joins)\n *\n * Usage:\n * ```tsx\n * const { analysis, isAnalyzing, analyze } = useExplainAI()\n *\n * // After running EXPLAIN\n * if (explainResult) {\n * <button onClick={() => analyze(explainResult, query)}>\n * {isAnalyzing ? 'Analyzing...' : 'Analyze with AI'}\n * </button>\n * }\n *\n * // Display recommendations\n * {analysis?.recommendations.map(rec => (\n * <div key={rec.title}>\n * <h4>{rec.title}</h4>\n * <p>{rec.description}</p>\n * {rec.sql && <pre>{rec.sql}</pre>}\n * {rec.cubeCode && <pre>{rec.cubeCode}</pre>}\n * </div>\n * ))}\n * ```\n */\nexport function useExplainAI(options: UseExplainAIOptions = {}): UseExplainAIResult {\n const { features } = useCubeFeatures()\n const enableAI = features.enableAI ?? true\n const queryClient = useQueryClient()\n\n // AI endpoint - defaults to /api/ai/explain/analyze\n // This is the standard path for AI routes in the dev server\n const aiEndpoint = options.aiEndpoint ?? '/api/ai/explain/analyze'\n\n const mutation = useMutation({\n mutationKey: EXPLAIN_AI_QUERY_KEY,\n mutationFn: async ({ explainResult, query }: { explainResult: ExplainResult; query: unknown }) => {\n // Check if AI is enabled\n if (!enableAI) {\n throw new Error('AI features are disabled')\n }\n\n const response = await fetch(aiEndpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n credentials: 'include',\n body: JSON.stringify({\n explainResult,\n query,\n }),\n })\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}))\n throw new Error(\n errorData.error ||\n errorData.message ||\n `AI analysis failed: ${response.status} ${response.statusText}`\n )\n }\n\n const result: AIExplainAnalysis = await response.json()\n return result\n },\n // No caching - each mutation is independent\n gcTime: 0,\n })\n\n const analyze = useCallback((explainResult: ExplainResult, query: unknown) => {\n mutation.mutate({ explainResult, query })\n }, [mutation])\n\n const clearAnalysis = useCallback(() => {\n mutation.reset()\n // Also invalidate any cached queries\n queryClient.removeQueries({ queryKey: EXPLAIN_AI_QUERY_KEY })\n }, [mutation, queryClient])\n\n return {\n analysis: mutation.data ?? null,\n isAnalyzing: mutation.isPending,\n error: mutation.error ?? null,\n analyze,\n clearAnalysis,\n }\n}\n"],"names":["createDryRunQueryKey","query","stableStringify","inferModeFromPayload","payload","normalizeDryRunResult","mode","useDryRunQuery","options","skip","staleTime","cubeApi","useCubeApi","serverQuery","useMemo","modeQuery","cleanQueryForServer","queryResult","useQuery","result","useMultiDryRunQueries","queries","serverQueries","q","queryResults","useQueries","debugDataPerQuery","isLoading","r","useDryRunQueries","isMultiQueryMode","queriesToFetch","createExplainQueryKey","isFunnelQuery","isFlowQuery","isRetentionQuery","useExplainQuery","explainOptions","setExplainOptions","useState","hasTriggered","setHasTriggered","queryEnabled","runExplain","useCallback","opts","clearExplain","EXPLAIN_AI_QUERY_KEY","useExplainAI","features","useCubeFeatures","enableAI","queryClient","useQueryClient","aiEndpoint","mutation","useMutation","explainResult","response","errorData","analyze","clearAnalysis"],"mappings":"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"}
@@ -525,6 +525,10 @@ export interface AnalysisResultsPanelProps {
525
525
  * Displayed as a banner above results.
526
526
  */
527
527
  warnings?: import('../../shared/types').QueryWarning[];
528
+ /** Fields currently selected in the query (for highlighting in schema diagram) */
529
+ highlightedFields?: string[];
530
+ /** Callback when a field is clicked in the schema diagram */
531
+ onSchemaFieldClick?: (cubeName: string, fieldName: string, fieldType: 'measure' | 'dimension') => void;
528
532
  }
529
533
  /**
530
534
  * Props for the MetricsSection component
@@ -728,6 +732,8 @@ export interface AnalysisBuilderProps {
728
732
  colorPalette?: ColorPalette;
729
733
  /** Disable localStorage persistence */
730
734
  disableLocalStorage?: boolean;
735
+ /** Custom localStorage key (for scoping persistence per connection/context) */
736
+ storageKey?: string;
731
737
  /** Hide settings button */
732
738
  hideSettings?: boolean;
733
739
  /** Callback when query changes (for modal integration) */
@@ -0,0 +1,14 @@
1
+ import { CubeMetaCube } from '../../types';
2
+ interface CubeNodeData {
3
+ cube: CubeMetaCube;
4
+ onFieldClick?: (cubeName: string, fieldName: string, fieldType: 'measure' | 'dimension') => void;
5
+ isHighlighted: boolean;
6
+ highlightedFields: string[];
7
+ searchTerm?: string;
8
+ [key: string]: unknown;
9
+ }
10
+ interface CubeNodeProps {
11
+ data: CubeNodeData;
12
+ }
13
+ export declare function CubeNode({ data }: CubeNodeProps): import("react/jsx-runtime").JSX.Element;
14
+ export {};
@@ -0,0 +1,13 @@
1
+ import { Edge, EdgeProps } from '@xyflow/react';
2
+ import { CubeMetaRelationship } from '../../types';
3
+ interface RelationshipEdgeData {
4
+ relationship: CubeMetaRelationship;
5
+ joinFields: Array<{
6
+ sourceField: string;
7
+ targetField: string;
8
+ }>;
9
+ [key: string]: unknown;
10
+ }
11
+ export type RelationshipEdgeType = Edge<RelationshipEdgeData, 'relationshipEdge'>;
12
+ export declare function RelationshipEdge({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, style, data, markerEnd, }: EdgeProps<RelationshipEdgeType>): import("react/jsx-runtime").JSX.Element | null;
13
+ export {};
@@ -0,0 +1,3 @@
1
+ import { SchemaVisualizationProps } from './index';
2
+ export declare function SchemaVisualizationLazy(props: SchemaVisualizationProps): import("react/jsx-runtime").JSX.Element;
3
+ export declare function isSchemaVisualizationAvailable(): boolean;
@@ -0,0 +1,10 @@
1
+ export interface SchemaVisualizationProps {
2
+ className?: string;
3
+ onFieldClick?: (cubeName: string, fieldName: string, fieldType: 'measure' | 'dimension') => void;
4
+ highlightedCubes?: string[];
5
+ highlightedFields?: string[];
6
+ searchTerm?: string;
7
+ height?: string | number;
8
+ }
9
+ export declare function SchemaVisualization({ className, onFieldClick, highlightedCubes, highlightedFields, searchTerm, height, }: SchemaVisualizationProps): import("react/jsx-runtime").JSX.Element;
10
+ export default SchemaVisualization;
@@ -0,0 +1,39 @@
1
+ import { Node, Edge } from '@xyflow/react';
2
+ export interface LayoutOptions {
3
+ direction: 'TB' | 'LR';
4
+ nodeWidth: number;
5
+ nodeSep: number;
6
+ rankSep: number;
7
+ }
8
+ export declare const defaultLayoutOptions: LayoutOptions;
9
+ /**
10
+ * Layout state machine phases:
11
+ * waiting → ELK not loaded yet, nothing to show
12
+ * computing → ELK loaded, running layout algorithm
13
+ * ready → layout complete, node positions available
14
+ */
15
+ export type LayoutPhase = 'waiting' | 'computing' | 'ready';
16
+ interface ELKInstance {
17
+ layout(graph: unknown): Promise<unknown>;
18
+ }
19
+ declare const elkLoadPromise: Promise<ELKInstance | null>;
20
+ export { elkLoadPromise as _elkLoadPromise };
21
+ export interface ElkLayoutResult {
22
+ nodes: Node[];
23
+ edges: Edge[];
24
+ }
25
+ /**
26
+ * Layout hook with explicit state machine.
27
+ *
28
+ * - Waits for ELK to load (phase: 'waiting')
29
+ * - Runs layout once per unique node/edge structure (phase: 'computing')
30
+ * - Returns stable result (phase: 'ready')
31
+ *
32
+ * The effect only depends on a string structure key, NOT object references.
33
+ * This prevents re-renders from cancelling in-flight computations.
34
+ */
35
+ export declare function useERDLayout(nodes: Node[], edges: Edge[], options?: Partial<LayoutOptions>): {
36
+ nodes: Node[];
37
+ edges: Edge[];
38
+ phase: LayoutPhase;
39
+ };
@@ -1,4 +1,4 @@
1
- import { ab as e, a as t, A as o, h as r, b as i, M as l, c as d } from "./chunks/components-Dz6XHgnZ.js";
1
+ import { ab as e, a as t, A as o, h as r, b as i, M as l, c as d } from "./chunks/components-CPqnw8o8.js";
2
2
  import { c as b, d as y, b as c, a as P, g as h, v as p } from "./chunks/index-CApFCBF9.js";
3
3
  export {
4
4
  e as AnalysisDisplayConfigPanel,
@@ -1,7 +1,7 @@
1
- import { f as p, d as m, u as x, u as W, q as v, x as D, t as E, e as C, b as L, a as F, y as z, p as M } from "./chunks/useDirtyStateTracking-CjhwBXRw.js";
1
+ import { f as p, d as m, u as x, u as W, q as v, x as D, t as E, e as C, b as L, a as F, y as z, p as M } from "./chunks/useDirtyStateTracking-CyAXd07d.js";
2
2
  import { useState as y, useRef as a, useCallback as w, useEffect as c } from "react";
3
- import { j as k } from "./chunks/providers-CCw8Kjlc.js";
4
- import { d as O, b as S, u as A, e as H, c as I, a as N } from "./chunks/useExplainAI-IiW55BaQ.js";
3
+ import { j as k } from "./chunks/providers-Ds7DRmnO.js";
4
+ import { d as O, b as S, u as A, e as H, c as I, a as N } from "./chunks/useExplainAI-CfQ_JmF1.js";
5
5
  const d = 768;
6
6
  function Q() {
7
7
  const [o, s] = y(
@@ -63,6 +63,7 @@ export interface IconRegistry {
63
63
  camera: IconDefinition;
64
64
  thumbUp: IconDefinition;
65
65
  thumbDown: IconDefinition;
66
+ schemaGraph: IconDefinition;
66
67
  measure: IconDefinition;
67
68
  dimension: IconDefinition;
68
69
  timeDimension: IconDefinition;
@@ -1,4 +1,4 @@
1
- import { D as a, b as t, i as o, a as c, c as g, f as I, h as n, g as r, r as y, e as i, s as p } from "./chunks/icons-DFJw-2HU.js";
1
+ import { D as a, b as t, i as o, g as c, c as g, f as I, h as n, a as r, r as y, e as i, s as p } from "./chunks/icons-CwvgmdIP.js";
2
2
  export {
3
3
  a as DEFAULT_ICONS,
4
4
  t as getChartTypeIcon,
@@ -22,6 +22,8 @@ export { default as AnalysisBuilder } from './components/AnalysisBuilderLazy';
22
22
  export type { AnalysisBuilderRef } from './components/AnalysisBuilder/types';
23
23
  export { ExecutionPlanPanel } from './components/AnalysisBuilder/ExecutionPlanPanel';
24
24
  export { ExplainAIPanel } from './components/AnalysisBuilder/ExplainAIPanel';
25
+ export { SchemaVisualizationLazy as SchemaVisualization } from './components/SchemaVisualization/SchemaVisualizationLazy';
26
+ export type { SchemaVisualizationProps } from './components/SchemaVisualization/index';
25
27
  export { CubeProvider, useCubeContext, useCubeApi, // Only re-renders on API/auth changes
26
28
  useCubeMeta, // Only re-renders on metadata changes
27
29
  useCubeFeatures } from './providers/CubeProvider';
@@ -1,26 +1,27 @@
1
- import { D as ve, A as Ce, e as we, g as Ne, P as ke } from "./chunks/components-Dz6XHgnZ.js";
2
- import { j as Lt, a as Qt, C as Ft, i as _t, h as Vt, b as jt, k as Ut, f as Ot, d as $t, M as qt, c as Kt, o as zt, U as Wt, S as Jt, R as Xt, Q as Yt, T as Gt, W as Ht, J as Zt, I as es, L as ts, X as ss, H as cs, K as rs, Y as ns, N as as, O as os, V as ds, Z as ls, _ as is, B as us, r as ms, y as hs, v as fs, s as ps, x as gs, q as bs, w as xs, p as ys, t as vs, z as Cs, u as ws, l as Ns, m as ks, n as Ss, G as Ts, F as Ds, E as As } from "./chunks/components-Dz6XHgnZ.js";
1
+ import { D as ve, A as Ce, e as we, g as Ne, P as ke } from "./chunks/components-CPqnw8o8.js";
2
+ import { j as Lt, a as Qt, C as Ft, i as _t, h as Vt, b as jt, k as Ut, f as Ot, d as $t, M as qt, c as Kt, o as zt, U as Wt, S as Jt, R as Xt, Q as Yt, T as Gt, W as Ht, J as Zt, I as es, L as ts, X as ss, H as cs, K as rs, Y as ns, N as as, O as os, V as ds, Z as ls, _ as is, B as us, r as ms, y as hs, v as fs, s as ps, x as gs, q as bs, w as xs, p as ys, t as vs, z as Cs, u as ws, l as Ns, m as ks, n as Ss, G as Ts, F as Ds, E as As } from "./chunks/components-CPqnw8o8.js";
3
3
  import { jsx as e, jsxs as u, Fragment as ae } from "react/jsx-runtime";
4
4
  import G, { useRef as x, createContext as Se, useContext as Te, useState as _, useCallback as p, useEffect as F } from "react";
5
5
  import { e as De, f as Ae, h as Ie, s as Me, i as le } from "./chunks/vendor-B2EH3V58.js";
6
- import { a as M, b as Ee } from "./chunks/icons-DFJw-2HU.js";
7
- import { D as Ms, i as Es, c as Rs, f as Bs, h as Ps, g as Ls, r as Qs, e as Fs, s as _s } from "./chunks/icons-DFJw-2HU.js";
6
+ import { g as M, b as Ee } from "./chunks/icons-CwvgmdIP.js";
7
+ import { D as Ms, i as Es, c as Rs, f as Bs, h as Ps, a as Ls, r as Qs, e as Fs, s as _s } from "./chunks/icons-CwvgmdIP.js";
8
8
  import { Q as Re } from "./chunks/chart-markdown-Du4Z2iqK.js";
9
- import { f as Be } from "./chunks/providers-CCw8Kjlc.js";
10
- import { h as js, a as Us, S as Os, e as $s, d as qs, i as Ks, b as zs, g as Ws, u as Js, j as Xs, c as Ys, w as Gs } from "./chunks/providers-CCw8Kjlc.js";
11
- import { L as he } from "./chunks/charts-core-B4Rbfdcn.js";
12
- import { u as Zs } from "./chunks/charts-core-B4Rbfdcn.js";
9
+ import { f as Be } from "./chunks/providers-Ds7DRmnO.js";
10
+ import { h as js, b as Us, S as Os, e as $s, d as qs, i as Ks, u as zs, g as Ws, a as Js, j as Xs, c as Ys, w as Gs } from "./chunks/providers-Ds7DRmnO.js";
11
+ import { L as he } from "./chunks/charts-core-BUUO36OM.js";
12
+ import { u as Zs } from "./chunks/charts-core-BUUO36OM.js";
13
13
  import { useNotebookLayout as Pe } from "./hooks.js";
14
- import { L as tc, g as sc, c as cc, b as rc, i as nc, p as ac, a as oc } from "./chunks/charts-loader-DbrwgvCK.js";
15
- import { E as lc, a as ic, p as uc, q as mc, m as hc, l as fc, r as pc, C as gc, D as bc, o as xc, B as yc, n as vc, w as Cc, t as wc, d as Nc, f as kc, s as Sc, e as Tc, i as Dc, c as Ac, h as Ic, g as Mc, u as Ec, b as Rc, y as Bc, A as Pc, x as Lc, k as Qc, v as Fc, z as _c, j as Vc } from "./chunks/analysis-builder-shared-KSvGUzx6.js";
16
- import { u as Uc } from "./chunks/chart-bubble-ZfNe8t5k.js";
17
- import { c as $c, f as qc } from "./chunks/index-CApFCBF9.js";
18
- import { f as zc, d as Wc, n as Jc, j as Xc, l as Yc, k as Gc, i as Hc, m as Zc, h as er, g as tr, u as sr, u as cr, e as rr, b as nr, a as ar, v as or } from "./chunks/useDirtyStateTracking-CjhwBXRw.js";
19
- import { c as lr, b as ir, f as ur, g as mr, a as hr, i as fr, t as pr } from "./chunks/funnel-utils-CyonoNeC.js";
20
- import { T as br, c as xr, g as yr, a as vr, i as Cr, r as wr, s as Nr, b as kr, w as Sr } from "./chunks/theme-Dp3hFed1.js";
21
- import { d as Dr, b as Ar, u as Ir, e as Mr, c as Er, a as Rr } from "./chunks/useExplainAI-IiW55BaQ.js";
22
- import { i as Pr, a as Lr } from "./chunks/flow-utils-CjQZG5qq.js";
23
- import { h as Fr } from "./chunks/syntaxHighlighting-DAMSW_A6.js";
14
+ import { L as tc, g as sc, c as cc, b as rc, i as nc, p as ac, a as oc } from "./chunks/charts-loader-Bv-IWHVd.js";
15
+ import { E as lc, a as ic, p as uc, q as mc, m as hc, l as fc, r as pc, C as gc, D as bc, o as xc, B as yc, n as vc, w as Cc, t as wc, d as Nc, f as kc, s as Sc, e as Tc, i as Dc, c as Ac, h as Ic, g as Mc, u as Ec, b as Rc, y as Bc, A as Pc, x as Lc, k as Qc, v as Fc, z as _c, j as Vc } from "./chunks/analysis-builder-shared-Bz9oSywd.js";
16
+ import { S as Uc } from "./chunks/schema-visualization-CzOuTQDu.js";
17
+ import { u as $c } from "./chunks/chart-bubble-BF8Z52eW.js";
18
+ import { c as Kc, f as zc } from "./chunks/index-CApFCBF9.js";
19
+ import { f as Jc, d as Xc, n as Yc, j as Gc, l as Hc, k as Zc, i as er, m as tr, h as sr, g as cr, u as rr, u as nr, e as ar, b as or, a as dr, v as lr } from "./chunks/useDirtyStateTracking-CyAXd07d.js";
20
+ import { c as ur, b as mr, f as hr, g as fr, a as pr, i as gr, t as br } from "./chunks/funnel-utils-CyonoNeC.js";
21
+ import { T as yr, c as vr, g as Cr, a as wr, i as Nr, r as kr, s as Sr, b as Tr, w as Dr } from "./chunks/theme-Dp3hFed1.js";
22
+ import { d as Ir, b as Mr, u as Er, e as Rr, c as Br, a as Pr } from "./chunks/useExplainAI-CfQ_JmF1.js";
23
+ import { i as Qr, a as Fr } from "./chunks/flow-utils-CjQZG5qq.js";
24
+ import { h as Vr } from "./chunks/syntaxHighlighting-DAMSW_A6.js";
24
25
  const fe = () => ({
25
26
  blocks: [],
26
27
  messages: [],
@@ -1161,15 +1162,16 @@ export {
1161
1162
  Fe as NotebookStoreProvider,
1162
1163
  ke as PortletAnalysisModal,
1163
1164
  Kt as PortletContainer,
1165
+ Uc as SchemaVisualization,
1164
1166
  Os as ScrollContainerProvider,
1165
- br as THEME_PRESETS,
1166
- xr as applyTheme,
1167
- lr as buildFunnelConfigFromQueries,
1168
- ir as buildServerFunnelQuery,
1167
+ yr as THEME_PRESETS,
1168
+ vr as applyTheme,
1169
+ ur as buildFunnelConfigFromQueries,
1170
+ mr as buildServerFunnelQuery,
1169
1171
  $s as captureThumbnail,
1170
1172
  uc as compressAndEncode,
1171
1173
  qs as createCubeClient,
1172
- $c as createDashboardLayout,
1174
+ Kc as createDashboardLayout,
1173
1175
  zt as createDashboardStore,
1174
1176
  Wt as createDefaultConfig,
1175
1177
  Jt as createDefaultFlowConfig,
@@ -1177,51 +1179,51 @@ export {
1177
1179
  Yt as createDefaultQueryConfig,
1178
1180
  Gt as createDefaultRetentionConfig,
1179
1181
  Ht as createDefaultWorkspace,
1180
- Dr as createExplainQueryKey,
1181
- zc as createFlowQueryKey,
1182
- Wc as createFunnelQueryKey,
1182
+ Ir as createExplainQueryKey,
1183
+ Jc as createFlowQueryKey,
1184
+ Xc as createFunnelQueryKey,
1183
1185
  Qe as createNotebookStore,
1184
1186
  mc as decodeAndDecompress,
1185
1187
  hc as detectAsymmetricDateRanges,
1186
1188
  fc as detectMeasureCollisions,
1187
- qc as formatChartData,
1188
- ur as formatDuration,
1189
- Jc as generateQueryLabel,
1189
+ zc as formatChartData,
1190
+ hr as formatDuration,
1191
+ Yc as generateQueryLabel,
1190
1192
  pc as generateShareUrl,
1191
1193
  gc as getAvailableBindingKeyDimensions,
1192
1194
  sc as getAvailableChartTypes,
1193
- mr as getBindingKeyField,
1195
+ fr as getBindingKeyField,
1194
1196
  bc as getBindingKeyLabel,
1195
1197
  Ee as getChartTypeIcon,
1196
- Xc as getCombinedFields,
1197
- hr as getCubeNameFromQuery,
1198
+ Gc as getCombinedFields,
1199
+ pr as getCubeNameFromQuery,
1198
1200
  Es as getFieldTypeIcon,
1199
1201
  M as getIcon,
1200
1202
  Rs as getIconData,
1201
1203
  Bs as getIconRegistry,
1202
1204
  Ps as getIconsByCategory,
1203
1205
  Ls as getMeasureTypeIcon,
1204
- Yc as getQueryIndices,
1205
- Gc as getQueryLabels,
1206
- yr as getTheme,
1207
- vr as getThemeVariable,
1206
+ Hc as getQueryIndices,
1207
+ Zc as getQueryLabels,
1208
+ Cr as getTheme,
1209
+ wr as getThemeVariable,
1208
1210
  cc as getUnavailableChartTypes,
1209
1211
  xc as getValidationSummary,
1210
- Fr as highlightCodeBlocks,
1212
+ Vr as highlightCodeBlocks,
1211
1213
  rc as isChartTypeAvailable,
1212
- Cr as isDarkMode,
1214
+ Nr as isDarkMode,
1213
1215
  Zt as isFlowConfig,
1214
1216
  es as isFunnelConfig,
1215
- fr as isFunnelData,
1217
+ gr as isFunnelData,
1216
1218
  yc as isMinimumFunnelConfigValid,
1217
1219
  ts as isMultiQuery,
1218
1220
  ss as isMultiQueryConfig,
1219
- Hc as isMultiQueryData,
1221
+ er as isMultiQueryData,
1220
1222
  vc as isMultiQueryValid,
1221
1223
  cs as isQueryConfig,
1222
1224
  rs as isRetentionConfig,
1223
- Pr as isSankeyData,
1224
- Lr as isServerFlowQuery,
1225
+ Qr as isSankeyData,
1226
+ Fr as isServerFlowQuery,
1225
1227
  ns as isServerFunnelQuery,
1226
1228
  Cc as isShareableSize,
1227
1229
  as as isSingleQuery,
@@ -1229,9 +1231,9 @@ export {
1229
1231
  os as isValidAnalysisConfig,
1230
1232
  ds as isValidAnalysisWorkspace,
1231
1233
  nc as isValidChartType,
1232
- Zc as mergeQueryResults,
1233
- er as mergeResultsByKey,
1234
- tr as mergeResultsConcat,
1234
+ tr as mergeQueryResults,
1235
+ sr as mergeResultsByKey,
1236
+ cr as mergeResultsConcat,
1235
1237
  ls as migrateConfig,
1236
1238
  is as migrateLegacyPortlet,
1237
1239
  wc as parseShareUrl,
@@ -1239,7 +1241,7 @@ export {
1239
1241
  oc as preloadCharts,
1240
1242
  Qs as registerIcons,
1241
1243
  Fs as resetIcons,
1242
- wr as resetTheme,
1244
+ kr as resetTheme,
1243
1245
  us as selectAllActions,
1244
1246
  Ue as selectBlockActions,
1245
1247
  _e as selectBlocks,
@@ -1268,9 +1270,9 @@ export {
1268
1270
  Cs as selectThumbnailDirty,
1269
1271
  Mc as selectUIState,
1270
1272
  _s as setIcon,
1271
- Nr as setTheme,
1272
- kr as setThemeVariable,
1273
- pr as transformServerFunnelResult,
1273
+ Sr as setTheme,
1274
+ Tr as setThemeVariable,
1275
+ br as transformServerFunnelResult,
1274
1276
  tt as useAgentChat,
1275
1277
  Ec as useAnalysisBuilder,
1276
1278
  Rc as useAnalysisBuilderStore,
@@ -1278,37 +1280,37 @@ export {
1278
1280
  zs as useCubeContext,
1279
1281
  Ws as useCubeFeatures,
1280
1282
  Zs as useCubeFieldLabel,
1281
- sr as useCubeLoadQuery,
1283
+ rr as useCubeLoadQuery,
1282
1284
  Js as useCubeMeta,
1283
1285
  Xs as useCubeMetaQuery,
1284
- cr as useCubeQuery,
1286
+ nr as useCubeQuery,
1285
1287
  ws as useDashboard,
1286
1288
  Ns as useDashboardStore,
1287
1289
  ks as useDashboardStoreApi,
1288
1290
  Ss as useDashboardStoreOptional,
1289
1291
  Ts as useDrillInteraction,
1290
- Ar as useDryRunQueries,
1291
- Ir as useDryRunQuery,
1292
+ Mr as useDryRunQueries,
1293
+ Er as useDryRunQuery,
1292
1294
  Ds as useElementVisibility,
1293
- Mr as useExplainAI,
1294
- Er as useExplainQuery,
1295
- rr as useFlowQuery,
1296
- nr as useFunnelQuery,
1297
- ar as useMultiCubeLoadQuery,
1298
- Rr as useMultiDryRunQueries,
1295
+ Rr as useExplainAI,
1296
+ Br as useExplainQuery,
1297
+ ar as useFlowQuery,
1298
+ or as useFunnelQuery,
1299
+ dr as useMultiCubeLoadQuery,
1300
+ Pr as useMultiDryRunQueries,
1299
1301
  B as useNotebookStore,
1300
1302
  Ys as useScrollContainer,
1301
1303
  As as useScrollDetection,
1302
- Uc as useTheme,
1304
+ $c as useTheme,
1303
1305
  Bc as validateBindingKeyExists,
1304
1306
  Pc as validateBindingKeyForSteps,
1305
1307
  Lc as validateFunnelConfig,
1306
- or as validateMergeKey,
1308
+ lr as validateMergeKey,
1307
1309
  Qc as validateMergeKeys,
1308
1310
  Fc as validateMultiQueryConfig,
1309
1311
  _c as validateStepQueries,
1310
1312
  Vc as validateTimeDimensionAlignment,
1311
1313
  Gs as warnIfScreenshotLibMissing,
1312
- Sr as watchThemeChanges
1314
+ Dr as watchThemeChanges
1313
1315
  };
1314
1316
  //# sourceMappingURL=index.js.map