drizzle-cube 0.2.29 → 0.3.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.
Files changed (79) hide show
  1. package/dist/adapters/{compiler-Ddwn99Ja.js → compiler-DwHoCgZU.js} +3813 -3060
  2. package/dist/adapters/compiler-YBGV51-V.cjs +23 -0
  3. package/dist/adapters/express/index.cjs +1 -1
  4. package/dist/adapters/express/index.js +1 -1
  5. package/dist/adapters/fastify/index.cjs +1 -1
  6. package/dist/adapters/fastify/index.js +1 -1
  7. package/dist/adapters/hono/index.cjs +1 -1
  8. package/dist/adapters/hono/index.js +1 -1
  9. package/dist/adapters/nextjs/index.cjs +1 -1
  10. package/dist/adapters/nextjs/index.js +1 -1
  11. package/dist/adapters/utils.d.ts +45 -12
  12. package/dist/client/adapters/adapterRegistry.d.ts +40 -0
  13. package/dist/client/adapters/funnelModeAdapter.d.ts +19 -0
  14. package/dist/client/adapters/index.d.ts +22 -0
  15. package/dist/client/adapters/modeAdapter.d.ts +117 -0
  16. package/dist/client/adapters/queryModeAdapter.d.ts +16 -0
  17. package/dist/client/charts.js +11 -11
  18. package/dist/client/chunks/{charts-nP6WCxHG.js → charts-BudebcSn.js} +2438 -2196
  19. package/dist/client/chunks/charts-BudebcSn.js.map +1 -0
  20. package/dist/client/chunks/{charts-Cr9ec7VQ.js → charts-CdOqkTEj.js} +46 -46
  21. package/dist/client/chunks/{charts-Cr9ec7VQ.js.map → charts-CdOqkTEj.js.map} +1 -1
  22. package/dist/client/chunks/components-Bq8GLyiY.js +17482 -0
  23. package/dist/client/chunks/components-Bq8GLyiY.js.map +1 -0
  24. package/dist/client/chunks/core-CbqoYAM6.js +6 -0
  25. package/dist/client/chunks/core-CbqoYAM6.js.map +1 -0
  26. package/dist/client/chunks/{hooks-CM78mXuP.js → hooks-BVB4L4sl.js} +247 -220
  27. package/dist/client/chunks/hooks-BVB4L4sl.js.map +1 -0
  28. package/dist/client/components/AnalysisBuilder/AnalysisFilterSection.d.ts +3 -1
  29. package/dist/client/components/AnalysisBuilder/AnalysisModeErrorBoundary.d.ts +28 -0
  30. package/dist/client/components/AnalysisBuilder/AnalysisTypeSelector.d.ts +15 -0
  31. package/dist/client/components/AnalysisBuilder/FunnelConfigPanel.d.ts +24 -0
  32. package/dist/client/components/AnalysisBuilder/FunnelModeContent.d.ts +48 -0
  33. package/dist/client/components/AnalysisBuilder/FunnelStepCard.d.ts +25 -0
  34. package/dist/client/components/AnalysisBuilder/FunnelStepList.d.ts +26 -0
  35. package/dist/client/components/AnalysisBuilder/types.d.ts +119 -4
  36. package/dist/client/components/AnalysisBuilder/utils/fieldUtils.d.ts +19 -1
  37. package/dist/client/components/AnalysisBuilder/utils/recentFieldsUtils.d.ts +1 -1
  38. package/dist/client/components/AnalysisBuilder/utils/storageUtils.d.ts +3 -1
  39. package/dist/client/components/ChartTypeSelector.d.ts +3 -1
  40. package/dist/client/components.js +2 -2
  41. package/dist/client/hooks/queries/index.d.ts +1 -1
  42. package/dist/client/hooks/queries/useDryRunQuery.d.ts +29 -0
  43. package/dist/client/hooks/queries/useFunnelQuery.d.ts +4 -9
  44. package/dist/client/hooks/useAnalysisAI.d.ts +13 -1
  45. package/dist/client/hooks/useAnalysisBuilderHook.d.ts +47 -2
  46. package/dist/client/hooks/useAnalysisQueryExecution.d.ts +32 -4
  47. package/dist/client/hooks/useAnalysisShare.d.ts +7 -12
  48. package/dist/client/hooks.js +5 -5
  49. package/dist/client/icons.js +5 -5
  50. package/dist/client/index.d.ts +2 -2
  51. package/dist/client/index.js +105 -104
  52. package/dist/client/providers.js +1 -1
  53. package/dist/client/shared/types.d.ts +9 -0
  54. package/dist/client/stores/analysisBuilderStore.d.ts +168 -33
  55. package/dist/client/stores/index.d.ts +1 -1
  56. package/dist/client/stores/slices/coreSlice.d.ts +96 -0
  57. package/dist/client/stores/slices/funnelSlice.d.ts +61 -0
  58. package/dist/client/stores/slices/index.d.ts +10 -0
  59. package/dist/client/stores/slices/querySlice.d.ts +54 -0
  60. package/dist/client/stores/slices/uiSlice.d.ts +52 -0
  61. package/dist/client/styles.css +1 -1
  62. package/dist/client/types/analysisConfig.d.ts +136 -0
  63. package/dist/client/types/funnel.d.ts +45 -2
  64. package/dist/client/types.d.ts +65 -6
  65. package/dist/client/utils/configMigration.d.ts +71 -0
  66. package/dist/client/utils/funnelExecution.d.ts +102 -2
  67. package/dist/client/utils/shareUtils.d.ts +26 -24
  68. package/dist/client-bundle-stats.html +1 -1
  69. package/dist/server/index.cjs +285 -19
  70. package/dist/server/index.d.ts +355 -9
  71. package/dist/server/index.js +4223 -3237
  72. package/package.json +1 -1
  73. package/dist/adapters/compiler-C6JQHGrF.cjs +0 -22
  74. package/dist/client/chunks/charts-nP6WCxHG.js.map +0 -1
  75. package/dist/client/chunks/components-CCRoi0sB.js +0 -15519
  76. package/dist/client/chunks/components-CCRoi0sB.js.map +0 -1
  77. package/dist/client/chunks/core-DcL8wSpZ.js +0 -6
  78. package/dist/client/chunks/core-DcL8wSpZ.js.map +0 -1
  79. package/dist/client/chunks/hooks-CM78mXuP.js.map +0 -1
@@ -1,9 +1,10 @@
1
1
  import { MouseEvent, DragEvent } from 'react';
2
- import { CubeQuery, Filter, ChartType, ChartAxisConfig, ChartDisplayConfig, MultiQueryConfig, QueryMergeStrategy, FunnelBindingKey } from '../../types';
2
+ import { CubeQuery, Filter, ChartType, ChartAxisConfig, ChartDisplayConfig, MultiQueryConfig, QueryMergeStrategy, FunnelBindingKey, AnalysisType, FunnelStepState } from '../../types';
3
3
  import { ColorPalette } from '../../utils/colorPalettes';
4
4
  import { MetaResponse, MetaField, MetaCube, QueryAnalysis } from '../../shared/types';
5
5
  import { ChartAvailabilityMap } from '../../shared/chartDefaults';
6
6
  import { MultiQueryValidationResult } from '../../utils/multiQueryValidation';
7
+ import { ValidationResult } from '../../adapters/modeAdapter';
7
8
  export type { MetaResponse, MetaField, MetaCube, QueryAnalysis };
8
9
  /**
9
10
  * A selected metric (measure) with a letter label (A, B, C, ...)
@@ -76,12 +77,20 @@ export interface AIState {
76
77
  chartType: ChartType;
77
78
  chartConfig: ChartAxisConfig;
78
79
  displayConfig: ChartDisplayConfig;
80
+ /** Analysis type for restoring mode on cancel */
81
+ analysisType?: AnalysisType;
79
82
  } | null;
83
+ /** Full AnalysisConfig snapshot for complete restore (handles funnel mode properly) */
84
+ previousConfig?: import('../../types/analysisConfig').AnalysisConfig | null;
80
85
  }
81
86
  /**
82
87
  * Mode for the field search modal - determines which field types are shown
88
+ * - 'metrics': Only measures
89
+ * - 'breakdown': Only dimensions (including time dimensions)
90
+ * - 'filter': Both measures and dimensions
91
+ * - 'dimensionFilter': Only dimensions (for funnel step filters where measures don't work)
83
92
  */
84
- export type FieldSearchMode = 'metrics' | 'breakdown' | 'filter';
93
+ export type FieldSearchMode = 'metrics' | 'breakdown' | 'filter' | 'dimensionFilter';
85
94
  /**
86
95
  * Field type categorization
87
96
  */
@@ -150,6 +159,10 @@ export interface FieldDetailPanelProps {
150
159
  * Tab options for the query panel
151
160
  */
152
161
  export type QueryPanelTab = 'query' | 'chart' | 'display';
162
+ /**
163
+ * Tab options for the funnel panel
164
+ */
165
+ export type FunnelPanelTab = 'steps' | 'display';
153
166
  /**
154
167
  * Props for the AnalysisQueryPanel component
155
168
  */
@@ -214,10 +227,42 @@ export interface AnalysisQueryPanelProps {
214
227
  combinedBreakdowns?: BreakdownItem[];
215
228
  /** Validation result for multi-query mode (errors and warnings) */
216
229
  multiQueryValidation?: MultiQueryValidationResult | null;
230
+ /** Validation result from adapter (NEW - Phase 5) */
231
+ adapterValidation?: ValidationResult | null;
217
232
  /** Binding key dimension that links funnel steps together */
218
233
  funnelBindingKey?: FunnelBindingKey | null;
219
234
  /** Callback when funnel binding key changes */
220
235
  onFunnelBindingKeyChange?: (bindingKey: FunnelBindingKey | null) => void;
236
+ /** Current analysis type (query, multi, funnel) */
237
+ analysisType?: AnalysisType;
238
+ /** Callback when analysis type changes */
239
+ onAnalysisTypeChange?: (type: AnalysisType) => void;
240
+ /** Selected cube for funnel mode (all steps use this cube) */
241
+ funnelCube?: string | null;
242
+ /** Dedicated funnel steps (separate from queryStates) */
243
+ funnelSteps?: FunnelStepState[];
244
+ /** Index of currently active funnel step */
245
+ activeFunnelStepIndex?: number;
246
+ /** Time dimension for funnel temporal ordering */
247
+ funnelTimeDimension?: string | null;
248
+ /** Callback when funnel cube changes */
249
+ onFunnelCubeChange?: (cube: string | null) => void;
250
+ /** Add a new funnel step */
251
+ onAddFunnelStep?: () => void;
252
+ /** Remove a funnel step by index */
253
+ onRemoveFunnelStep?: (index: number) => void;
254
+ /** Update a funnel step by index */
255
+ onUpdateFunnelStep?: (index: number, updates: Partial<FunnelStepState>) => void;
256
+ /** Set the active funnel step index */
257
+ onSelectFunnelStep?: (index: number) => void;
258
+ /** Reorder funnel steps */
259
+ onReorderFunnelSteps?: (fromIndex: number, toIndex: number) => void;
260
+ /** Set the time dimension for funnel */
261
+ onFunnelTimeDimensionChange?: (dimension: string | null) => void;
262
+ /** Funnel display config (for Display tab in funnel mode) */
263
+ funnelDisplayConfig?: ChartDisplayConfig;
264
+ /** Callback when funnel display config changes */
265
+ onFunnelDisplayConfigChange?: (config: ChartDisplayConfig) => void;
221
266
  }
222
267
  /**
223
268
  * Props for the AnalysisResultsPanel component
@@ -295,6 +340,32 @@ export interface AnalysisResultsPanelProps {
295
340
  activeTableIndex?: number;
296
341
  /** Callback when active table changes */
297
342
  onActiveTableChange?: (index: number) => void;
343
+ /** Current analysis type (query or funnel) - primary way to detect mode */
344
+ analysisType?: AnalysisType;
345
+ /**
346
+ * Whether in funnel mode (always show unified results, no per-query tables)
347
+ * @deprecated Use analysisType === 'funnel' instead
348
+ */
349
+ isFunnelMode?: boolean;
350
+ /**
351
+ * The actual server funnel query { funnel: {...} } sent to the server.
352
+ * Use this for debug display instead of per-query debug data.
353
+ */
354
+ funnelServerQuery?: unknown;
355
+ /**
356
+ * Unified debug data for funnel queries (SQL, analysis, loading/error state).
357
+ * Contains the CTE-based SQL for the entire funnel.
358
+ */
359
+ funnelDebugData?: {
360
+ sql: {
361
+ sql: string;
362
+ params: unknown[];
363
+ } | null;
364
+ analysis: unknown;
365
+ loading: boolean;
366
+ error: Error | null;
367
+ funnelMetadata?: unknown;
368
+ } | null;
298
369
  }
299
370
  /**
300
371
  * Props for the MetricsSection component
@@ -418,6 +489,18 @@ export interface BreakdownItemCardProps {
418
489
  /** Drag end handler */
419
490
  onDragEnd?: () => void;
420
491
  }
492
+ /**
493
+ * Initial funnel state for AnalysisBuilder (matches InitialFunnelState in store)
494
+ */
495
+ export interface AnalysisBuilderInitialFunnelState {
496
+ funnelCube?: string | null;
497
+ funnelSteps?: FunnelStepState[];
498
+ funnelTimeDimension?: string | null;
499
+ funnelBindingKey?: FunnelBindingKey | null;
500
+ funnelChartType?: ChartType;
501
+ funnelChartConfig?: ChartAxisConfig;
502
+ funnelDisplayConfig?: ChartDisplayConfig;
503
+ }
421
504
  /**
422
505
  * Props for the main AnalysisBuilder component
423
506
  */
@@ -438,6 +521,10 @@ export interface AnalysisBuilderProps {
438
521
  chartConfig?: ChartAxisConfig;
439
522
  displayConfig?: ChartDisplayConfig;
440
523
  };
524
+ /** Initial analysis type (query or funnel) - defaults to 'query' */
525
+ initialAnalysisType?: AnalysisType;
526
+ /** Initial funnel state (when initialAnalysisType === 'funnel') */
527
+ initialFunnelState?: AnalysisBuilderInitialFunnelState;
441
528
  /** Initial data to display (avoids re-fetching when editing existing portlets) */
442
529
  initialData?: any[];
443
530
  /** Color palette for chart visualization */
@@ -455,22 +542,46 @@ export interface AnalysisBuilderProps {
455
542
  displayConfig: ChartDisplayConfig;
456
543
  }) => void;
457
544
  }
545
+ /**
546
+ * Funnel state returned by getFunnelState
547
+ */
548
+ export interface FunnelStateSnapshot {
549
+ funnelCube: string | null;
550
+ funnelSteps: FunnelStepState[];
551
+ funnelTimeDimension: string | null;
552
+ funnelBindingKey: FunnelBindingKey | null;
553
+ funnelChartType: ChartType;
554
+ funnelChartConfig: ChartAxisConfig;
555
+ funnelDisplayConfig: ChartDisplayConfig;
556
+ activeFunnelStepIndex: number;
557
+ }
458
558
  /**
459
559
  * Ref interface for AnalysisBuilder (for external access)
460
560
  */
461
561
  export interface AnalysisBuilderRef {
462
562
  /**
463
563
  * Get the current query configuration.
464
- * Returns either a CubeQuery (single query) or MultiQueryConfig (multiple queries).
564
+ * Returns CubeQuery (single query), MultiQueryConfig (multiple queries), or ServerFunnelQuery (funnel mode).
465
565
  * Consumers should just JSON.stringify the result - no need to check the type.
566
+ * @deprecated Use getAnalysisConfig() for Phase 3+ integrations
466
567
  */
467
- getQueryConfig: () => CubeQuery | MultiQueryConfig;
568
+ getQueryConfig: () => CubeQuery | MultiQueryConfig | import('../../types/funnel').ServerFunnelQuery;
468
569
  /** Get current chart configuration */
469
570
  getChartConfig: () => {
470
571
  chartType: ChartType;
471
572
  chartConfig: ChartAxisConfig;
472
573
  displayConfig: ChartDisplayConfig;
473
574
  };
575
+ /** Get the current analysis type (query or funnel) */
576
+ getAnalysisType: () => AnalysisType;
577
+ /** Get the current funnel state (for persisting funnel mode configuration) */
578
+ getFunnelState: () => FunnelStateSnapshot;
579
+ /**
580
+ * Phase 3: Get the complete AnalysisConfig.
581
+ * This is the canonical format for persisting analysis state.
582
+ * Replaces getQueryConfig + getChartConfig + getAnalysisType.
583
+ */
584
+ getAnalysisConfig: () => import('../../types/analysisConfig').AnalysisConfig;
474
585
  /** Execute the current query */
475
586
  executeQuery: () => void;
476
587
  /** Clear the current query */
@@ -493,6 +604,10 @@ export interface AnalysisBuilderStorageState {
493
604
  mergeStrategy?: QueryMergeStrategy;
494
605
  /** Dimension keys used for merging in 'merge' strategy */
495
606
  mergeKeys?: string[];
607
+ /** Binding key for funnel strategy (links steps together) */
608
+ funnelBindingKey?: FunnelBindingKey | null;
609
+ /** Time window per step for funnel strategy (ISO 8601 duration) */
610
+ stepTimeToConvert?: (string | null)[];
496
611
  }
497
612
  /**
498
613
  * Recent fields storage shape
@@ -27,7 +27,7 @@ export declare function getFieldType(field: MetaField): FieldType;
27
27
  /**
28
28
  * Convert schema to flat list of field options
29
29
  */
30
- export declare function schemaToFieldOptions(schema: MetaResponse | null, mode: 'metrics' | 'breakdown' | 'filter'): FieldOption[];
30
+ export declare function schemaToFieldOptions(schema: MetaResponse | null, mode: 'metrics' | 'breakdown' | 'filter' | 'dimensionFilter'): FieldOption[];
31
31
  /**
32
32
  * Filter field options by search term
33
33
  */
@@ -44,3 +44,21 @@ export declare function getCubeNames(schema: MetaResponse | null): string[];
44
44
  * Get cube title by name
45
45
  */
46
46
  export declare function getCubeTitle(cubeName: string, schema: MetaResponse | null): string;
47
+ /**
48
+ * Get all cubes reachable from a source cube via join relationships
49
+ * Includes the source cube itself plus all cubes it has joins to
50
+ *
51
+ * @param sourceCube - Name of the cube to find related cubes for
52
+ * @param schema - Full schema with all cubes
53
+ * @returns Set of cube names that are reachable from the source
54
+ */
55
+ export declare function getRelatedCubeNames(sourceCube: string, schema: MetaResponse | null): Set<string>;
56
+ /**
57
+ * Filter schema to include only cubes reachable from a source cube
58
+ * This is used for funnel step filters where cross-cube filtering is supported
59
+ *
60
+ * @param sourceCube - Name of the cube to find related cubes for
61
+ * @param schema - Full schema with all cubes
62
+ * @returns Filtered schema containing only reachable cubes
63
+ */
64
+ export declare function getRelatedCubesSchema(sourceCube: string, schema: MetaResponse | null): MetaResponse | null;
@@ -11,4 +11,4 @@ export declare function addRecentField(fieldName: string, mode: 'metrics' | 'bre
11
11
  /**
12
12
  * Get recent field options from schema
13
13
  */
14
- export declare function getRecentFieldOptions(schema: MetaResponse | null, mode: 'metrics' | 'breakdown' | 'filter', recentFieldNames: string[]): FieldOption[];
14
+ export declare function getRecentFieldOptions(schema: MetaResponse | null, mode: 'metrics' | 'breakdown' | 'filter' | 'dimensionFilter', recentFieldNames: string[]): FieldOption[];
@@ -1,6 +1,8 @@
1
1
  import { Filter } from '../../../types';
2
2
  import { MetricItem, BreakdownItem, AnalysisBuilderState, AnalysisBuilderStorageState } from '../types';
3
- export declare const STORAGE_KEY = "drizzle-cube-analysis-builder-state";
3
+ export declare const STORAGE_KEY = "drizzle-cube-analysis-builder-v3";
4
+ /** @deprecated Use STORAGE_KEY instead */
5
+ export declare const STORAGE_KEY_V2 = "drizzle-cube-analysis-builder-v2";
4
6
  /**
5
7
  * Create initial empty state for AnalysisBuilder
6
8
  *
@@ -8,6 +8,8 @@ interface ChartTypeSelectorProps {
8
8
  compact?: boolean;
9
9
  /** Map of chart type availability - when provided, unavailable charts are disabled */
10
10
  availability?: ChartAvailabilityMap;
11
+ /** Chart types to exclude from the list (e.g., ['funnel'] to hide funnel in query mode) */
12
+ excludeTypes?: ChartType[];
11
13
  }
12
- export default function ChartTypeSelector({ selectedType, onTypeChange, className, compact, availability }: ChartTypeSelectorProps): import("react/jsx-runtime").JSX.Element;
14
+ export default function ChartTypeSelector({ selectedType, onTypeChange, className, compact, availability, excludeTypes }: ChartTypeSelectorProps): import("react/jsx-runtime").JSX.Element;
13
15
  export {};
@@ -1,5 +1,5 @@
1
- import { a as s, A as t, c as r, D as o, M as d, P as i, Q as l } from "./chunks/components-CCRoi0sB.js";
2
- import { c, j as u, h as y, e as P, d as b, v as h } from "./chunks/charts-Cr9ec7VQ.js";
1
+ import { a as s, A as t, c as r, D as o, M as d, P as i, Q as l } from "./chunks/components-Bq8GLyiY.js";
2
+ import { c, j as u, h as y, e as P, d as b, v as h } from "./chunks/charts-CdOqkTEj.js";
3
3
  export {
4
4
  s as AnalyticsDashboard,
5
5
  t as AnalyticsPortlet,
@@ -12,5 +12,5 @@
12
12
  export { useCubeMetaQuery, prefetchCubeMeta, CUBE_META_QUERY_KEY, type UseCubeMetaQueryOptions, type UseCubeMetaQueryResult, } from './useCubeMetaQuery';
13
13
  export { useCubeLoadQuery, useCubeLoadQuery as useCubeQuery, createQueryKey, type UseCubeLoadQueryOptions, type UseCubeLoadQueryResult, } from './useCubeLoadQuery';
14
14
  export { useMultiCubeLoadQuery, createMultiQueryKey, type UseMultiCubeLoadQueryOptions, type UseMultiCubeLoadQueryResult, } from './useMultiCubeLoadQuery';
15
- export { useDryRunQuery, useMultiDryRunQueries, useDryRunQueries, createDryRunQueryKey, type DebugDataEntry, type UseDryRunQueryOptions, type UseDryRunQueryResult, type UseMultiDryRunQueriesOptions, type UseMultiDryRunQueriesResult, } from './useDryRunQuery';
15
+ export { useDryRunQuery, useMultiDryRunQueries, useDryRunQueries, useFunnelDryRunQuery, createDryRunQueryKey, type DebugDataEntry, type FunnelDebugDataEntry, type UseDryRunQueryOptions, type UseDryRunQueryResult, type UseMultiDryRunQueriesOptions, type UseMultiDryRunQueriesResult, } from './useDryRunQuery';
16
16
  export { useFunnelQuery, createFunnelQueryKey, } from './useFunnelQuery';
@@ -101,3 +101,32 @@ export declare function useDryRunQueries(options: {
101
101
  skip?: boolean;
102
102
  staleTime?: number;
103
103
  }): UseMultiDryRunQueriesResult;
104
+ /**
105
+ * Debug data entry for funnel queries
106
+ */
107
+ export interface FunnelDebugDataEntry extends DebugDataEntry {
108
+ /** Funnel-specific metadata from server */
109
+ funnelMetadata?: {
110
+ stepCount: number;
111
+ steps: Array<{
112
+ index: number;
113
+ name: string;
114
+ timeToConvert?: string;
115
+ cube?: string;
116
+ }>;
117
+ bindingKey: unknown;
118
+ timeDimension: unknown;
119
+ };
120
+ }
121
+ /**
122
+ * TanStack Query hook for funnel query dry-run (debug) data
123
+ *
124
+ * Usage:
125
+ * ```tsx
126
+ * const { debugData } = useFunnelDryRunQuery(serverQuery, { skip: !isFunnelMode })
127
+ * ```
128
+ */
129
+ export declare function useFunnelDryRunQuery(serverQuery: unknown | null, options?: UseDryRunQueryOptions): {
130
+ debugData: FunnelDebugDataEntry;
131
+ refetch: () => void;
132
+ };
@@ -1,25 +1,20 @@
1
1
  import { FunnelConfig, UseFunnelQueryOptions, UseFunnelQueryResult } from '../../types/funnel';
2
2
  /**
3
- * Hook for sequential funnel query execution
3
+ * Hook for server-side funnel query execution
4
4
  *
5
5
  * Usage:
6
6
  * ```tsx
7
- * const { result, isExecuting, execute, stepResults, chartData } = useFunnelQuery(config, {
7
+ * const { chartData, isExecuting, error } = useFunnelQuery(config, {
8
8
  * debounceMs: 300,
9
9
  * skip: !hasBindingKey
10
10
  * })
11
11
  *
12
- * // Results show progressively as each step completes
13
- * {stepResults.map((step, i) => (
14
- * <div key={i}>
15
- * {step.stepName}: {step.count} ({step.conversionRate}% from previous)
16
- * </div>
17
- * ))}
12
+ * // Results available after single server request
13
+ * <FunnelChart data={chartData} />
18
14
  * ```
19
15
  */
20
16
  export declare function useFunnelQuery(config: FunnelConfig | null, options?: UseFunnelQueryOptions): UseFunnelQueryResult;
21
17
  /**
22
18
  * Create a stable query key for funnel queries
23
- * (useful if we want to integrate with TanStack Query in the future)
24
19
  */
25
20
  export declare function createFunnelQueryKey(config: FunnelConfig | null): readonly unknown[];
@@ -1,5 +1,7 @@
1
1
  import { AnalysisBuilderState, AIState } from '../components/AnalysisBuilder/types';
2
2
  import { ChartType, ChartAxisConfig, ChartDisplayConfig } from '../types';
3
+ import { ServerFunnelQuery } from '../types/funnel';
4
+ import { AnalysisType, AnalysisConfig } from '../types/analysisConfig';
3
5
  interface UseAnalysisAIOptions {
4
6
  /** Current state for snapshotting */
5
7
  state: AnalysisBuilderState;
@@ -23,6 +25,16 @@ interface UseAnalysisAIOptions {
23
25
  setActiveView: (view: 'table' | 'chart') => void;
24
26
  /** AI endpoint URL */
25
27
  aiEndpoint?: string;
28
+ /** Current analysis type */
29
+ analysisType?: AnalysisType;
30
+ /** Set analysis type (for switching to funnel mode) */
31
+ setAnalysisType?: (type: AnalysisType) => void;
32
+ /** Load funnel config from ServerFunnelQuery */
33
+ loadFunnelFromServerQuery?: (query: ServerFunnelQuery) => void;
34
+ /** Get full AnalysisConfig for snapshotting (for complete undo) */
35
+ getFullConfig?: () => AnalysisConfig;
36
+ /** Load full AnalysisConfig (for restoring on cancel) */
37
+ loadFullConfig?: (config: AnalysisConfig) => void;
26
38
  }
27
39
  interface UseAnalysisAIResult {
28
40
  /** Current AI state */
@@ -40,5 +52,5 @@ interface UseAnalysisAIResult {
40
52
  /** Cancel and restore previous state */
41
53
  handleCancelAI: () => void;
42
54
  }
43
- export declare function useAnalysisAI({ state, setState, chartType, setChartType, chartConfig, setChartConfig, displayConfig, setDisplayConfig, setUserManuallySelectedChart, setActiveView, aiEndpoint }: UseAnalysisAIOptions): UseAnalysisAIResult;
55
+ export declare function useAnalysisAI({ state, setState, chartType, setChartType, chartConfig, setChartConfig, displayConfig, setDisplayConfig, setUserManuallySelectedChart, setActiveView, aiEndpoint, analysisType, setAnalysisType, loadFunnelFromServerQuery, getFullConfig, loadFullConfig }: UseAnalysisAIOptions): UseAnalysisAIResult;
44
56
  export {};
@@ -1,10 +1,11 @@
1
1
  import { ColorPalette } from '../utils/colorPalettes';
2
- import { CubeQuery, MultiQueryConfig, ChartType, ChartAxisConfig, ChartDisplayConfig, Filter, QueryMergeStrategy, FunnelBindingKey } from '../types';
2
+ import { CubeQuery, MultiQueryConfig, ChartType, ChartAxisConfig, ChartDisplayConfig, Filter, QueryMergeStrategy, FunnelBindingKey, AnalysisType, FunnelStepState } from '../types';
3
3
  import { AnalysisBuilderState, MetricItem, BreakdownItem, ExecutionStatus, QueryPanelTab } from '../components/AnalysisBuilder/types';
4
4
  import { ChartAvailabilityMap } from '../shared/chartDefaults';
5
5
  import { DebugDataEntry } from './queries';
6
6
  import { MultiQueryValidationResult } from '../utils/multiQueryValidation';
7
7
  import { MetaField } from '../shared/types';
8
+ import { ValidationResult } from '../adapters/modeAdapter';
8
9
  export interface UseAnalysisBuilderOptions {
9
10
  /** External color palette (overrides local) */
10
11
  externalColorPalette?: string[] | ColorPalette;
@@ -31,6 +32,24 @@ export interface UseAnalysisBuilderResult {
31
32
  multiQueryConfig: MultiQueryConfig | null;
32
33
  multiQueryValidation: MultiQueryValidationResult | null;
33
34
  funnelBindingKey: FunnelBindingKey | null;
35
+ /** Whether funnel mode is properly configured and ready for execution */
36
+ isFunnelModeEnabled: boolean;
37
+ /** Current analysis type (query, multi, funnel) */
38
+ analysisType: AnalysisType;
39
+ /** Selected cube for funnel mode (all steps use this cube) */
40
+ funnelCube: string | null;
41
+ /** Dedicated funnel steps (when analysisType === 'funnel') */
42
+ funnelSteps: FunnelStepState[];
43
+ /** Index of currently active funnel step */
44
+ activeFunnelStepIndex: number;
45
+ /** Time dimension for funnel temporal ordering */
46
+ funnelTimeDimension: string | null;
47
+ /** Chart type for funnel mode (separate from query mode) */
48
+ funnelChartType: ChartType;
49
+ /** Chart config for funnel mode (separate from query mode) */
50
+ funnelChartConfig: ChartAxisConfig;
51
+ /** Display config for funnel mode (separate from query mode) */
52
+ funnelDisplayConfig: ChartDisplayConfig;
34
53
  executionStatus: ExecutionStatus;
35
54
  executionResults: unknown[] | null;
36
55
  perQueryResults: (unknown[] | null)[] | null;
@@ -41,6 +60,19 @@ export interface UseAnalysisBuilderResult {
41
60
  debugDataPerQuery: DebugDataEntry[];
42
61
  /** In funnel mode, the actually executed queries with binding key dimension and IN filters */
43
62
  funnelExecutedQueries: CubeQuery[] | null;
63
+ /** In funnel mode, the actual server query { funnel: {...} } sent to the API */
64
+ funnelServerQuery: unknown | null;
65
+ /** In funnel mode, unified debug data (SQL, analysis, funnel metadata) */
66
+ funnelDebugData: {
67
+ sql: {
68
+ sql: string;
69
+ params: unknown[];
70
+ } | null;
71
+ analysis: unknown | null;
72
+ loading: boolean;
73
+ error: Error | null;
74
+ funnelMetadata?: unknown;
75
+ } | null;
44
76
  chartType: ChartType;
45
77
  chartConfig: ChartAxisConfig;
46
78
  displayConfig: ChartDisplayConfig;
@@ -66,6 +98,8 @@ export interface UseAnalysisBuilderResult {
66
98
  };
67
99
  shareButtonState: 'idle' | 'copied' | 'copied-no-chart';
68
100
  canShare: boolean;
101
+ /** Validation result from the adapter for the current analysis type */
102
+ adapterValidation: ValidationResult;
69
103
  actions: {
70
104
  setActiveQueryIndex: (index: number) => void;
71
105
  setMergeStrategy: (strategy: QueryMergeStrategy) => void;
@@ -87,6 +121,15 @@ export interface UseAnalysisBuilderResult {
87
121
  addQuery: () => void;
88
122
  removeQuery: (index: number) => void;
89
123
  setFunnelBindingKey: (bindingKey: FunnelBindingKey | null) => void;
124
+ setAnalysisType: (type: AnalysisType) => void;
125
+ setFunnelCube: (cube: string | null) => void;
126
+ addFunnelStep: () => void;
127
+ removeFunnelStep: (index: number) => void;
128
+ updateFunnelStep: (index: number, updates: Partial<FunnelStepState>) => void;
129
+ setActiveFunnelStepIndex: (index: number) => void;
130
+ reorderFunnelSteps: (fromIndex: number, toIndex: number) => void;
131
+ setFunnelTimeDimension: (dimension: string | null) => void;
132
+ setFunnelDisplayConfig: (config: ChartDisplayConfig) => void;
90
133
  setChartType: (type: ChartType) => void;
91
134
  setChartConfig: (config: ChartAxisConfig) => void;
92
135
  setDisplayConfig: (config: ChartDisplayConfig) => void;
@@ -104,14 +147,16 @@ export interface UseAnalysisBuilderResult {
104
147
  cancelAI: () => void;
105
148
  share: () => Promise<void>;
106
149
  clearQuery: () => void;
150
+ clearCurrentMode: () => void;
107
151
  refetch: () => void;
108
152
  handleFieldSelected: (field: MetaField, fieldType: 'measure' | 'dimension' | 'timeDimension', cubeName: string, keepOpen?: boolean) => void;
109
153
  };
110
- getQueryConfig: () => CubeQuery | MultiQueryConfig;
154
+ getQueryConfig: () => CubeQuery | MultiQueryConfig | import('../types/funnel').ServerFunnelQuery;
111
155
  getChartConfig: () => {
112
156
  chartType: ChartType;
113
157
  chartConfig: ChartAxisConfig;
114
158
  displayConfig: ChartDisplayConfig;
115
159
  };
160
+ getAnalysisType: () => AnalysisType;
116
161
  }
117
162
  export declare function useAnalysisBuilder(options?: UseAnalysisBuilderOptions): UseAnalysisBuilderResult;
@@ -1,6 +1,7 @@
1
- import { DebugDataEntry } from './queries';
2
- import { CubeQuery, MultiQueryConfig, FunnelBindingKey, QueryMergeStrategy } from '../types';
1
+ import { DebugDataEntry, FunnelDebugDataEntry } from './queries';
2
+ import { CubeQuery, MultiQueryConfig, FunnelBindingKey, QueryMergeStrategy, AnalysisType } from '../types';
3
3
  import { ExecutionStatus } from '../components/AnalysisBuilder/types';
4
+ import { ServerFunnelQuery } from '../types/funnel';
4
5
  export interface UseAnalysisQueryExecutionOptions {
5
6
  /** Current query (for single-query mode) */
6
7
  currentQuery: CubeQuery;
@@ -14,10 +15,26 @@ export interface UseAnalysisQueryExecutionOptions {
14
15
  isValidQuery: boolean;
15
16
  /** Initial data (skip first fetch) */
16
17
  initialData?: unknown[];
17
- /** Merge strategy (for detecting funnel mode) */
18
+ /** Merge strategy (for detecting funnel mode - legacy) */
18
19
  mergeStrategy?: QueryMergeStrategy;
19
20
  /** Funnel binding key (required for funnel mode) */
20
21
  funnelBindingKey?: FunnelBindingKey | null;
22
+ /**
23
+ * Whether funnel mode is properly configured (from store).
24
+ * This includes filter-only step validation that isMultiQueryMode doesn't provide.
25
+ * @deprecated Use analysisType === 'funnel' instead
26
+ */
27
+ isFunnelModeEnabled?: boolean;
28
+ /**
29
+ * Analysis type for explicit mode routing.
30
+ * When provided, takes precedence over legacy mode detection.
31
+ */
32
+ analysisType?: AnalysisType;
33
+ /**
34
+ * Pre-built server funnel query from store's buildFunnelQueryFromSteps().
35
+ * Used when analysisType === 'funnel' with the new dedicated funnel state.
36
+ */
37
+ serverFunnelQuery?: ServerFunnelQuery | null;
21
38
  }
22
39
  export interface UseAnalysisQueryExecutionResult {
23
40
  /** Query execution status */
@@ -32,7 +49,7 @@ export interface UseAnalysisQueryExecutionResult {
32
49
  isFetching: boolean;
33
50
  /** Query error */
34
51
  error: Error | null;
35
- /** Debug data per query */
52
+ /** Debug data per query (for non-funnel modes) */
36
53
  debugDataPerQuery: DebugDataEntry[];
37
54
  /** Whether query has been debounced (for smart defaults trigger) */
38
55
  hasDebounced: boolean;
@@ -43,7 +60,18 @@ export interface UseAnalysisQueryExecutionResult {
43
60
  * - Binding key dimension auto-added
44
61
  * - IN filter applied for steps 2+
45
62
  * Use these for debug display instead of the original queries.
63
+ * @deprecated Server-side funnel uses a unified query. Use funnelServerQuery instead.
46
64
  */
47
65
  funnelExecutedQueries: CubeQuery[] | null;
66
+ /**
67
+ * The actual server funnel query { funnel: {...} }
68
+ * This is the unified query sent to the server (not per-step queries).
69
+ */
70
+ funnelServerQuery: ServerFunnelQuery | null;
71
+ /**
72
+ * Debug data specifically for funnel mode
73
+ * Contains the funnel SQL and funnel-specific metadata
74
+ */
75
+ funnelDebugData: FunnelDebugDataEntry | null;
48
76
  }
49
77
  export declare function useAnalysisQueryExecution(options: UseAnalysisQueryExecutionOptions): UseAnalysisQueryExecutionResult;
@@ -1,17 +1,12 @@
1
- import { CubeQuery, ChartType, ChartAxisConfig, ChartDisplayConfig, MultiQueryConfig } from '../types';
1
+ import { AnalysisConfig } from '../types/analysisConfig';
2
2
  interface UseAnalysisShareOptions {
3
3
  /** Whether the current query is valid */
4
4
  isValidQuery: boolean;
5
- /** Getter for the query config (matches AnalysisBuilder save format) */
6
- getQueryConfig: () => CubeQuery | MultiQueryConfig;
7
- /** Current chart type */
8
- chartType: ChartType;
9
- /** Current chart config */
10
- chartConfig: ChartAxisConfig;
11
- /** Current display config */
12
- displayConfig: ChartDisplayConfig;
13
- /** Current active view */
14
- activeView: 'table' | 'chart';
5
+ /**
6
+ * Getter for the AnalysisConfig (from store.save())
7
+ * This is the new Phase 3 API - returns complete AnalysisConfig
8
+ */
9
+ getAnalysisConfig: () => AnalysisConfig;
15
10
  }
16
11
  interface UseAnalysisShareResult {
17
12
  /** Current share button state */
@@ -19,5 +14,5 @@ interface UseAnalysisShareResult {
19
14
  /** Handle share button click */
20
15
  handleShare: () => Promise<void>;
21
16
  }
22
- export declare function useAnalysisShare({ isValidQuery, getQueryConfig, chartType, chartConfig, displayConfig, activeView }: UseAnalysisShareOptions): UseAnalysisShareResult;
17
+ export declare function useAnalysisShare({ isValidQuery, getAnalysisConfig, }: UseAnalysisShareOptions): UseAnalysisShareResult;
23
18
  export {};
@@ -1,13 +1,13 @@
1
- import { u as s, u as a, r, z as t, d as y, b as o, t as i, a as b, c as Q, y as n } from "./chunks/hooks-CM78mXuP.js";
2
- import { f as d } from "./chunks/charts-nP6WCxHG.js";
1
+ import { u as s, u as a, s as r, A as o, d as t, b as y, w as i, a as b, c as Q, z as n } from "./chunks/hooks-BVB4L4sl.js";
2
+ import { f as d } from "./chunks/charts-BudebcSn.js";
3
3
  export {
4
4
  s as useCubeLoadQuery,
5
5
  d as useCubeMetaQuery,
6
6
  a as useCubeQuery,
7
7
  r as useDebounce,
8
- t as useDirtyStateTracking,
9
- y as useDryRunQueries,
10
- o as useDryRunQuery,
8
+ o as useDirtyStateTracking,
9
+ t as useDryRunQueries,
10
+ y as useDryRunQuery,
11
11
  i as useFilterValues,
12
12
  b as useMultiCubeLoadQuery,
13
13
  Q as useMultiDryRunQueries,
@@ -1,12 +1,12 @@
1
- import { D as a, y as t, z as o, m as n, n as I, t as c, v as g, x as r, p as y, q as p, o as T } from "./chunks/charts-nP6WCxHG.js";
1
+ import { I as a, G as t, H as o, x as I, y as c, D as g, E as n, F as r, A as y, B as p, z as T } from "./chunks/charts-BudebcSn.js";
2
2
  export {
3
3
  a as DEFAULT_ICONS,
4
4
  t as getChartTypeIcon,
5
5
  o as getFieldTypeIcon,
6
- n as getIcon,
7
- I as getIconData,
8
- c as getIconRegistry,
9
- g as getIconsByCategory,
6
+ I as getIcon,
7
+ c as getIconData,
8
+ g as getIconRegistry,
9
+ n as getIconsByCategory,
10
10
  r as getMeasureTypeIcon,
11
11
  y as registerIcons,
12
12
  p as resetIcons,
@@ -25,7 +25,7 @@ export type { UseAnalysisBuilderOptions, UseAnalysisBuilderResult, } from './hoo
25
25
  export { useDashboard } from './hooks/useDashboardHook';
26
26
  export type { UseDashboardOptions, UseDashboardResult, UseDashboardActions, } from './hooks/useDashboardHook';
27
27
  export { useAnalysisBuilderStore, selectCurrentState, selectMetrics, selectBreakdowns, selectFilters, selectChartConfig, selectUIState, selectMultiQueryState, selectFunnelState, } from './stores/analysisBuilderStore';
28
- export type { AnalysisBuilderStore, AnalysisBuilderStoreState, AnalysisBuilderStoreActions, FieldModalMode, SharedState, } from './stores/analysisBuilderStore';
28
+ export type { AnalysisBuilderStore, AnalysisBuilderStoreState, AnalysisBuilderStoreActions, FieldModalMode, } from './stores/analysisBuilderStore';
29
29
  export { DashboardStoreProvider, useDashboardStore, useDashboardStoreApi, useDashboardStoreOptional, createDashboardStore, selectEditModeState, selectModalState, selectLayoutState, selectDebugData, selectPortletDebugData, selectEditModeActions, selectModalActions, selectLayoutActions, selectDebugDataActions, selectAllActions, } from './stores/dashboardStore';
30
30
  export type { DashboardStore, DashboardStoreState, DashboardStoreActions, PortletDebugDataEntry, DragState, CreateDashboardStoreOptions, DashboardStoreProviderProps, } from './stores/dashboardStore';
31
31
  export { validateMultiQueryConfig, validateTimeDimensionAlignment, validateMergeKeys, detectMeasureCollisions, detectAsymmetricDateRanges, isMultiQueryValid, getValidationSummary } from './utils/multiQueryValidation';
@@ -39,7 +39,7 @@ export type { ChartTypeConfig, DisplayOptionConfig, AxisDropZoneConfig } from '.
39
39
  export { createDashboardLayout, formatChartData, highlightCodeBlocks } from './utils/index';
40
40
  export { isMultiQueryData, mergeQueryResults, mergeResultsConcat, mergeResultsByKey, getCombinedFields, getQueryLabels, getQueryIndices, generateQueryLabel, validateMergeKey } from './utils/multiQueryUtils';
41
41
  export { validateFunnelConfig, validateBindingKeyExists, validateStepQueries, validateBindingKeyForSteps, isMinimumFunnelConfigValid, getAvailableBindingKeyDimensions, getBindingKeyLabel, } from './utils/funnelValidation';
42
- export { getBindingKeyField, extractBindingKeyValues, buildStepQuery, buildFunnelConfigFromQueries, buildFunnelChartData, isFunnelData, } from './utils/funnelExecution';
42
+ export { getBindingKeyField, getCubeNameFromQuery, formatDuration, transformServerFunnelResult, buildServerFunnelQuery, isFunnelData, buildFunnelConfigFromQueries, } from './utils/funnelExecution';
43
43
  export { getThemeVariable, setThemeVariable, applyTheme, resetTheme, getTheme, setTheme, isDarkMode, watchThemeChanges, THEME_PRESETS } from './theme';
44
44
  export type { ThemeColorTokens, ThemeConfig, Theme } from './theme';
45
45
  export { getIcon, getIconData, setIcon, registerIcons, resetIcons, getIconRegistry, getIconsByCategory, getMeasureTypeIcon, getChartTypeIcon, getFieldTypeIcon, DEFAULT_ICONS } from './icons';