@databricks/appkit-ui 0.1.4 → 0.2.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 (194) hide show
  1. package/AGENTS.md +89 -12
  2. package/CLAUDE.md +89 -12
  3. package/NOTICE.md +4 -0
  4. package/README.md +21 -15
  5. package/dist/js/arrow/arrow-client.js.map +1 -1
  6. package/dist/js/arrow/lazy-arrow.js.map +1 -1
  7. package/dist/js/sse/connect-sse.js.map +1 -1
  8. package/dist/react/charts/area/index.d.ts +2 -2
  9. package/dist/react/charts/bar/index.d.ts +2 -2
  10. package/dist/react/charts/base.d.ts +2 -2
  11. package/dist/react/charts/base.js.map +1 -1
  12. package/dist/react/charts/create-chart.d.ts +2 -2
  13. package/dist/react/charts/create-chart.js +2 -1
  14. package/dist/react/charts/create-chart.js.map +1 -1
  15. package/dist/react/charts/heatmap/index.d.ts +2 -2
  16. package/dist/react/charts/line/index.d.ts +2 -2
  17. package/dist/react/charts/normalize.d.ts +1 -1
  18. package/dist/react/charts/normalize.js +1 -1
  19. package/dist/react/charts/normalize.js.map +1 -1
  20. package/dist/react/charts/pie/index.d.ts +3 -3
  21. package/dist/react/charts/radar/index.d.ts +2 -2
  22. package/dist/react/charts/scatter/index.d.ts +2 -2
  23. package/dist/react/charts/theme.js.map +1 -1
  24. package/dist/react/charts/types.d.ts +5 -0
  25. package/dist/react/charts/types.d.ts.map +1 -1
  26. package/dist/react/charts/types.js.map +1 -1
  27. package/dist/react/charts/utils.js.map +1 -1
  28. package/dist/react/charts/wrapper.d.ts +4 -2
  29. package/dist/react/charts/wrapper.d.ts.map +1 -1
  30. package/dist/react/charts/wrapper.js +4 -2
  31. package/dist/react/charts/wrapper.js.map +1 -1
  32. package/dist/react/hooks/types.d.ts +2 -0
  33. package/dist/react/hooks/types.d.ts.map +1 -1
  34. package/dist/react/hooks/use-analytics-query.js +9 -3
  35. package/dist/react/hooks/use-analytics-query.js.map +1 -1
  36. package/dist/react/hooks/use-chart-data.d.ts +2 -0
  37. package/dist/react/hooks/use-chart-data.d.ts.map +1 -1
  38. package/dist/react/hooks/use-chart-data.js +3 -2
  39. package/dist/react/hooks/use-chart-data.js.map +1 -1
  40. package/dist/react/hooks/use-mobile.js +3 -3
  41. package/dist/react/hooks/use-mobile.js.map +1 -1
  42. package/dist/react/index.d.ts +3 -1
  43. package/dist/react/index.js +3 -1
  44. package/dist/react/lib/utils.d.ts +7 -0
  45. package/dist/react/lib/utils.d.ts.map +1 -0
  46. package/dist/react/portal-container-context.d.ts +48 -0
  47. package/dist/react/portal-container-context.d.ts.map +1 -0
  48. package/dist/react/portal-container-context.js +51 -0
  49. package/dist/react/portal-container-context.js.map +1 -0
  50. package/dist/react/table/data-table.d.ts +2 -2
  51. package/dist/react/table/data-table.d.ts.map +1 -1
  52. package/dist/react/table/table-wrapper.js +3 -2
  53. package/dist/react/table/table-wrapper.js.map +1 -1
  54. package/dist/react/table/types.d.ts.map +1 -1
  55. package/dist/react/ui/accordion.d.ts +6 -6
  56. package/dist/react/ui/accordion.d.ts.map +1 -1
  57. package/dist/react/ui/alert-dialog.d.ts +14 -13
  58. package/dist/react/ui/alert-dialog.d.ts.map +1 -1
  59. package/dist/react/ui/alert-dialog.js +3 -1
  60. package/dist/react/ui/alert-dialog.js.map +1 -1
  61. package/dist/react/ui/alert.d.ts +5 -5
  62. package/dist/react/ui/alert.d.ts.map +1 -1
  63. package/dist/react/ui/aspect-ratio.d.ts +2 -2
  64. package/dist/react/ui/avatar.d.ts +5 -5
  65. package/dist/react/ui/avatar.d.ts.map +1 -1
  66. package/dist/react/ui/badge.d.ts +6 -6
  67. package/dist/react/ui/badge.d.ts.map +1 -1
  68. package/dist/react/ui/breadcrumb.d.ts +10 -10
  69. package/dist/react/ui/breadcrumb.d.ts.map +1 -1
  70. package/dist/react/ui/button-group.d.ts +6 -6
  71. package/dist/react/ui/button.d.ts +6 -6
  72. package/dist/react/ui/button.d.ts.map +1 -1
  73. package/dist/react/ui/calendar.d.ts +6 -6
  74. package/dist/react/ui/calendar.d.ts.map +1 -1
  75. package/dist/react/ui/calendar.js +3 -3
  76. package/dist/react/ui/calendar.js.map +1 -1
  77. package/dist/react/ui/card.d.ts +9 -9
  78. package/dist/react/ui/card.d.ts.map +1 -1
  79. package/dist/react/ui/carousel.d.ts +7 -7
  80. package/dist/react/ui/carousel.d.ts.map +1 -1
  81. package/dist/react/ui/carousel.js +11 -11
  82. package/dist/react/ui/carousel.js.map +1 -1
  83. package/dist/react/ui/chart.d.ts +52 -16
  84. package/dist/react/ui/chart.d.ts.map +1 -1
  85. package/dist/react/ui/chart.js +23 -7
  86. package/dist/react/ui/chart.js.map +1 -1
  87. package/dist/react/ui/checkbox.d.ts +3 -3
  88. package/dist/react/ui/checkbox.d.ts.map +1 -1
  89. package/dist/react/ui/checkbox.js +1 -1
  90. package/dist/react/ui/checkbox.js.map +1 -1
  91. package/dist/react/ui/collapsible.d.ts +4 -4
  92. package/dist/react/ui/command.d.ts +12 -12
  93. package/dist/react/ui/command.d.ts.map +1 -1
  94. package/dist/react/ui/context-menu.d.ts +21 -20
  95. package/dist/react/ui/context-menu.d.ts.map +1 -1
  96. package/dist/react/ui/context-menu.js +11 -6
  97. package/dist/react/ui/context-menu.js.map +1 -1
  98. package/dist/react/ui/dialog.d.ts +14 -13
  99. package/dist/react/ui/dialog.d.ts.map +1 -1
  100. package/dist/react/ui/dialog.js +3 -1
  101. package/dist/react/ui/dialog.js.map +1 -1
  102. package/dist/react/ui/drawer.d.ts +13 -12
  103. package/dist/react/ui/drawer.d.ts.map +1 -1
  104. package/dist/react/ui/drawer.js +3 -1
  105. package/dist/react/ui/drawer.js.map +1 -1
  106. package/dist/react/ui/dropdown-menu.d.ts +21 -20
  107. package/dist/react/ui/dropdown-menu.d.ts.map +1 -1
  108. package/dist/react/ui/dropdown-menu.js +12 -7
  109. package/dist/react/ui/dropdown-menu.js.map +1 -1
  110. package/dist/react/ui/empty.d.ts +7 -7
  111. package/dist/react/ui/field.d.ts +11 -11
  112. package/dist/react/ui/form.d.ts +9 -9
  113. package/dist/react/ui/form.d.ts.map +1 -1
  114. package/dist/react/ui/form.js +6 -6
  115. package/dist/react/ui/form.js.map +1 -1
  116. package/dist/react/ui/hover-card.d.ts +5 -5
  117. package/dist/react/ui/hover-card.d.ts.map +1 -1
  118. package/dist/react/ui/hover-card.js +2 -0
  119. package/dist/react/ui/hover-card.js.map +1 -1
  120. package/dist/react/ui/input-group.d.ts +11 -11
  121. package/dist/react/ui/input-group.d.ts.map +1 -1
  122. package/dist/react/ui/input-otp.d.ts +8 -8
  123. package/dist/react/ui/input-otp.d.ts.map +1 -1
  124. package/dist/react/ui/input-otp.js +2 -2
  125. package/dist/react/ui/input-otp.js.map +1 -1
  126. package/dist/react/ui/input.d.ts +3 -3
  127. package/dist/react/ui/input.d.ts.map +1 -1
  128. package/dist/react/ui/item.d.ts +16 -16
  129. package/dist/react/ui/item.d.ts.map +1 -1
  130. package/dist/react/ui/kbd.d.ts +3 -3
  131. package/dist/react/ui/label.d.ts +3 -3
  132. package/dist/react/ui/label.d.ts.map +1 -1
  133. package/dist/react/ui/menubar.d.ts +22 -21
  134. package/dist/react/ui/menubar.d.ts.map +1 -1
  135. package/dist/react/ui/menubar.js +3 -1
  136. package/dist/react/ui/menubar.js.map +1 -1
  137. package/dist/react/ui/navigation-menu.d.ts +11 -11
  138. package/dist/react/ui/navigation-menu.d.ts.map +1 -1
  139. package/dist/react/ui/pagination.d.ts +10 -10
  140. package/dist/react/ui/pagination.d.ts.map +1 -1
  141. package/dist/react/ui/popover.d.ts +6 -6
  142. package/dist/react/ui/popover.d.ts.map +1 -1
  143. package/dist/react/ui/popover.js +11 -7
  144. package/dist/react/ui/popover.js.map +1 -1
  145. package/dist/react/ui/progress.d.ts +3 -3
  146. package/dist/react/ui/progress.d.ts.map +1 -1
  147. package/dist/react/ui/radio-group.d.ts +4 -4
  148. package/dist/react/ui/radio-group.d.ts.map +1 -1
  149. package/dist/react/ui/resizable.d.ts +6 -6
  150. package/dist/react/ui/resizable.d.ts.map +1 -1
  151. package/dist/react/ui/scroll-area.d.ts +4 -4
  152. package/dist/react/ui/scroll-area.d.ts.map +1 -1
  153. package/dist/react/ui/select.d.ts +13 -13
  154. package/dist/react/ui/select.d.ts.map +1 -1
  155. package/dist/react/ui/select.js +19 -15
  156. package/dist/react/ui/select.js.map +1 -1
  157. package/dist/react/ui/separator.d.ts +3 -3
  158. package/dist/react/ui/separator.d.ts.map +1 -1
  159. package/dist/react/ui/sheet.d.ts +11 -11
  160. package/dist/react/ui/sheet.d.ts.map +1 -1
  161. package/dist/react/ui/sheet.js +3 -1
  162. package/dist/react/ui/sheet.js.map +1 -1
  163. package/dist/react/ui/sidebar.d.ts +34 -34
  164. package/dist/react/ui/sidebar.d.ts.map +1 -1
  165. package/dist/react/ui/sidebar.js +10 -10
  166. package/dist/react/ui/sidebar.js.map +1 -1
  167. package/dist/react/ui/skeleton.d.ts +2 -2
  168. package/dist/react/ui/slider.d.ts +3 -3
  169. package/dist/react/ui/slider.d.ts.map +1 -1
  170. package/dist/react/ui/slider.js +2 -2
  171. package/dist/react/ui/slider.js.map +1 -1
  172. package/dist/react/ui/sonner.d.ts +2 -2
  173. package/dist/react/ui/spinner.d.ts +2 -2
  174. package/dist/react/ui/switch.d.ts +3 -3
  175. package/dist/react/ui/switch.d.ts.map +1 -1
  176. package/dist/react/ui/table.d.ts +10 -10
  177. package/dist/react/ui/table.d.ts.map +1 -1
  178. package/dist/react/ui/tabs.d.ts +6 -6
  179. package/dist/react/ui/tabs.d.ts.map +1 -1
  180. package/dist/react/ui/textarea.d.ts +3 -3
  181. package/dist/react/ui/textarea.d.ts.map +1 -1
  182. package/dist/react/ui/toggle-group.d.ts +5 -5
  183. package/dist/react/ui/toggle-group.d.ts.map +1 -1
  184. package/dist/react/ui/toggle-group.js +3 -3
  185. package/dist/react/ui/toggle-group.js.map +1 -1
  186. package/dist/react/ui/toggle.d.ts +3 -3
  187. package/dist/react/ui/toggle.d.ts.map +1 -1
  188. package/dist/react/ui/tooltip.d.ts +6 -6
  189. package/dist/react/ui/tooltip.d.ts.map +1 -1
  190. package/dist/react/ui/tooltip.js +11 -7
  191. package/dist/react/ui/tooltip.js.map +1 -1
  192. package/dist/shared/src/sql/helpers.js.map +1 -1
  193. package/llms.txt +89 -12
  194. package/package.json +1 -1
@@ -19,7 +19,7 @@ import { jsx } from "react/jsx-runtime";
19
19
  */
20
20
  function createChart(chartType, displayName) {
21
21
  const Component = (props) => {
22
- const { queryKey, parameters, format, transformer, data, height = 300, className, ariaLabel, testId, ...chartProps } = props;
22
+ const { queryKey, parameters, format, transformer, asUser, data, height = 300, className, ariaLabel, testId, ...chartProps } = props;
23
23
  return /* @__PURE__ */ jsx(ChartWrapper, {
24
24
  ...data !== void 0 ? {
25
25
  data,
@@ -32,6 +32,7 @@ function createChart(chartType, displayName) {
32
32
  parameters,
33
33
  format,
34
34
  transformer,
35
+ asUser,
35
36
  height,
36
37
  className,
37
38
  ariaLabel,
@@ -1 +1 @@
1
- {"version":3,"file":"create-chart.js","names":[],"sources":["../../../src/react/charts/create-chart.tsx"],"sourcesContent":["import { BaseChart } from \"./base\";\nimport type { ChartType, UnifiedChartProps } from \"./types\";\nimport { ChartWrapper } from \"./wrapper\";\n\n/**\n * Factory function to create chart components.\n * Eliminates boilerplate by generating components with the same pattern.\n *\n * @param chartType - The ECharts chart type\n * @param displayName - Component display name for React DevTools\n * @returns A typed chart component\n *\n * @example\n * ```tsx\n * export const BarChart = createChart<BarChartProps>(\"bar\", \"BarChart\");\n * export const LineChart = createChart<LineChartProps>(\"line\", \"LineChart\");\n * ```\n */\nexport function createChart<TProps extends UnifiedChartProps>(\n chartType: ChartType,\n displayName: string,\n) {\n const Component = (props: TProps) => {\n const {\n // Query props\n queryKey,\n parameters,\n format,\n transformer,\n // Data props\n data,\n // Common props\n height = 300,\n className,\n ariaLabel,\n testId,\n // All remaining props pass through to BaseChart\n ...chartProps\n } = props as TProps & {\n queryKey?: string;\n parameters?: Record<string, unknown>;\n format?: string;\n transformer?: unknown;\n data?: unknown;\n height?: number;\n className?: string;\n ariaLabel?: string;\n testId?: string;\n };\n\n const wrapperProps =\n data !== undefined\n ? { data, height, className, ariaLabel, testId }\n : {\n queryKey: queryKey as string,\n parameters,\n format,\n transformer,\n height,\n className,\n ariaLabel,\n testId: testId ?? `${chartType}-chart-${queryKey}`,\n };\n\n return (\n <ChartWrapper {...wrapperProps}>\n {(chartData) => (\n <BaseChart\n data={chartData}\n chartType={chartType}\n height={height}\n className={className}\n {...chartProps}\n />\n )}\n </ChartWrapper>\n );\n };\n\n Component.displayName = displayName;\n return Component;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAkBA,SAAgB,YACd,WACA,aACA;CACA,MAAM,aAAa,UAAkB;EACnC,MAAM,EAEJ,UACA,YACA,QACA,aAEA,MAEA,SAAS,KACT,WACA,WACA,QAEA,GAAG,eACD;AA0BJ,SACE,oBAAC;GAAa,GAdd,SAAS,SACL;IAAE;IAAM;IAAQ;IAAW;IAAW;IAAQ,GAC9C;IACY;IACV;IACA;IACA;IACA;IACA;IACA;IACA,QAAQ,UAAU,GAAG,UAAU,SAAS;IACzC;cAID,cACA,oBAAC;IACC,MAAM;IACK;IACH;IACG;IACX,GAAI;KACJ;IAES;;AAInB,WAAU,cAAc;AACxB,QAAO"}
1
+ {"version":3,"file":"create-chart.js","names":[],"sources":["../../../src/react/charts/create-chart.tsx"],"sourcesContent":["import { BaseChart } from \"./base\";\nimport type { ChartType, UnifiedChartProps } from \"./types\";\nimport { ChartWrapper } from \"./wrapper\";\n\n/**\n * Factory function to create chart components.\n * Eliminates boilerplate by generating components with the same pattern.\n *\n * @param chartType - The ECharts chart type\n * @param displayName - Component display name for React DevTools\n * @returns A typed chart component\n *\n * @example\n * ```tsx\n * export const BarChart = createChart<BarChartProps>(\"bar\", \"BarChart\");\n * export const LineChart = createChart<LineChartProps>(\"line\", \"LineChart\");\n * ```\n */\nexport function createChart<TProps extends UnifiedChartProps>(\n chartType: ChartType,\n displayName: string,\n) {\n const Component = (props: TProps) => {\n const {\n // Query props\n queryKey,\n parameters,\n format,\n transformer,\n asUser,\n // Data props\n data,\n // Common props\n height = 300,\n className,\n ariaLabel,\n testId,\n // All remaining props pass through to BaseChart\n ...chartProps\n } = props as TProps & {\n queryKey?: string;\n parameters?: Record<string, unknown>;\n format?: string;\n transformer?: unknown;\n asUser?: boolean;\n data?: unknown;\n height?: number;\n className?: string;\n ariaLabel?: string;\n testId?: string;\n };\n\n const wrapperProps =\n data !== undefined\n ? { data, height, className, ariaLabel, testId }\n : {\n queryKey: queryKey as string,\n parameters,\n format,\n transformer,\n asUser,\n height,\n className,\n ariaLabel,\n testId: testId ?? `${chartType}-chart-${queryKey}`,\n };\n\n return (\n <ChartWrapper {...wrapperProps}>\n {(chartData) => (\n <BaseChart\n data={chartData}\n chartType={chartType}\n height={height}\n className={className}\n {...chartProps}\n />\n )}\n </ChartWrapper>\n );\n };\n\n Component.displayName = displayName;\n return Component;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAkBA,SAAgB,YACd,WACA,aACA;CACA,MAAM,aAAa,UAAkB;EACnC,MAAM,EAEJ,UACA,YACA,QACA,aACA,QAEA,MAEA,SAAS,KACT,WACA,WACA,QAEA,GAAG,eACD;AA4BJ,SACE,oBAAC;GAAa,GAfd,SAAS,SACL;IAAE;IAAM;IAAQ;IAAW;IAAW;IAAQ,GAC9C;IACY;IACV;IACA;IACA;IACA;IACA;IACA;IACA;IACA,QAAQ,UAAU,GAAG,UAAU,SAAS;IACzC;cAID,cACA,oBAAC;IACC,MAAM;IACK;IACH;IACG;IACX,GAAI;KACJ;IAES;;AAInB,WAAU,cAAc;AACxB,QAAO"}
@@ -1,5 +1,5 @@
1
1
  import { HeatmapChartProps } from "../types.js";
2
- import * as react_jsx_runtime275 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime277 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/react/charts/heatmap/index.d.ts
5
5
 
@@ -34,7 +34,7 @@ import * as react_jsx_runtime275 from "react/jsx-runtime";
34
34
  * ```
35
35
  */
36
36
  declare const HeatmapChart: {
37
- (props: HeatmapChartProps): react_jsx_runtime275.JSX.Element;
37
+ (props: HeatmapChartProps): react_jsx_runtime277.JSX.Element;
38
38
  displayName: string;
39
39
  };
40
40
  //#endregion
@@ -1,5 +1,5 @@
1
1
  import { LineChartProps } from "../types.js";
2
- import * as react_jsx_runtime276 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime278 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/react/charts/line/index.d.ts
5
5
 
@@ -26,7 +26,7 @@ import * as react_jsx_runtime276 from "react/jsx-runtime";
26
26
  * ```
27
27
  */
28
28
  declare const LineChart: {
29
- (props: LineChartProps): react_jsx_runtime276.JSX.Element;
29
+ (props: LineChartProps): react_jsx_runtime278.JSX.Element;
30
30
  displayName: string;
31
31
  };
32
32
  //#endregion
@@ -24,7 +24,7 @@ interface NormalizedHeatmapData extends NormalizedChartDataBase {
24
24
  }
25
25
  /**
26
26
  * Normalizes data specifically for heatmap charts.
27
- * Expects data in format: { xKey: string, yAxisKey: string, valueKey: number }
27
+ * Expects data in format: `{ xKey: string, yAxisKey: string, valueKey: number }`
28
28
  *
29
29
  * @param data - Raw data (Arrow Table or JSON array)
30
30
  * @param xKey - Field key for X-axis (columns)
@@ -161,7 +161,7 @@ function normalizeChartData(data, xKey, yKey, orientation) {
161
161
  }
162
162
  /**
163
163
  * Normalizes data specifically for heatmap charts.
164
- * Expects data in format: { xKey: string, yAxisKey: string, valueKey: number }
164
+ * Expects data in format: `{ xKey: string, yAxisKey: string, valueKey: number }`
165
165
  *
166
166
  * @param data - Raw data (Arrow Table or JSON array)
167
167
  * @param xKey - Field key for X-axis (columns)
@@ -1 +1 @@
1
- {"version":3,"file":"normalize.js","names":["xField","xData: (string | number)[]","yDataMap: Record<string, (string | number)[]>","detected","resolvedXKey","resolvedYKeys","rawXData","rawYDataMap","xData","yDataMap","heatmapData: [number, number, number][]","result: Record<string, unknown>[]","row: Record<string, unknown>"],"sources":["../../../src/react/charts/normalize.ts"],"sourcesContent":["import { ArrowClient } from \"@/js\";\nimport type { Table } from \"apache-arrow\";\nimport { DATE_FIELD_PATTERNS, NAME_FIELD_PATTERNS } from \"./constants\";\nimport type {\n ChartData,\n NormalizedChartData,\n NormalizedChartDataBase,\n Orientation,\n} from \"./types\";\nimport { isArrowTable } from \"./types\";\nimport { sortTimeSeriesAscending, toChartArray } from \"./utils\";\n\n// ============================================================================\n// Type Detection Helpers\n// ============================================================================\n\n/**\n * Checks if a value looks like an ISO date string\n */\nfunction isDateString(value: unknown): boolean {\n if (typeof value !== \"string\") return false;\n return /^\\d{4}-\\d{2}-\\d{2}(T|$)/.test(value);\n}\n\n/**\n * Checks if a value is numeric (number or numeric string)\n */\nfunction isNumericValue(value: unknown): boolean {\n if (typeof value === \"number\") return true;\n if (typeof value === \"bigint\") return true;\n if (typeof value === \"string\") {\n const trimmed = value.trim();\n if (trimmed === \"\" || isDateString(trimmed)) return false;\n const parsed = Number(trimmed);\n return !Number.isNaN(parsed) && Number.isFinite(parsed);\n }\n return false;\n}\n\n/**\n * Checks if a value looks like a category/label (non-numeric string)\n */\nfunction isCategoryValue(value: unknown): boolean {\n if (typeof value !== \"string\") return false;\n const trimmed = value.trim();\n if (trimmed === \"\") return false;\n if (/^\\d{4}-\\d{2}-\\d{2}/.test(trimmed)) return false;\n const parsed = Number(trimmed);\n return Number.isNaN(parsed) || !Number.isFinite(parsed);\n}\n\n// ============================================================================\n// Field Detection\n// ============================================================================\n\n/**\n * Detects fields from JSON data for charting\n */\nfunction detectFieldsFromJson(\n data: Record<string, unknown>[],\n orientation?: Orientation,\n): {\n xField: string;\n yFields: string[];\n chartType: \"timeseries\" | \"categorical\";\n} {\n if (!data || data.length === 0) {\n return { xField: \"x\", yFields: [\"y\"], chartType: \"categorical\" };\n }\n\n const firstRow = data[0];\n const keys = Object.keys(firstRow);\n\n // Detect date fields by key name OR by value being a date string\n const dateFields = keys.filter((key) => {\n const value = firstRow[key];\n const keyMatchesDatePattern = DATE_FIELD_PATTERNS.some((p) =>\n key.toLowerCase().includes(p),\n );\n const valueIsDateString = isDateString(value);\n return keyMatchesDatePattern || valueIsDateString;\n });\n\n // Detect name/category fields by pattern AND value type\n let nameFields = keys.filter((key) => {\n const value = firstRow[key];\n return (\n isCategoryValue(value) &&\n !isDateString(value) &&\n NAME_FIELD_PATTERNS.some((p) => key.toLowerCase().includes(p))\n );\n });\n\n // Fallback: any string field that isn't a date or ID\n if (nameFields.length === 0) {\n nameFields = keys.filter((key) => {\n const value = firstRow[key];\n return (\n isCategoryValue(value) &&\n !isDateString(value) &&\n !dateFields.includes(key) &&\n !key.toLowerCase().endsWith(\"_id\")\n );\n });\n }\n\n // Detect numeric fields\n const numericFields = keys.filter((key) => {\n const value = firstRow[key];\n return isNumericValue(value) && !dateFields.includes(key);\n });\n\n const isHorizontal = orientation === \"horizontal\";\n\n if (isHorizontal || (nameFields.length > 0 && dateFields.length === 0)) {\n const xField = nameFields[0] || dateFields[0] || keys[0];\n const yFields =\n numericFields.length > 0\n ? numericFields\n : keys.filter((k) => k !== xField);\n return { xField, yFields, chartType: \"categorical\" };\n }\n\n const xField = dateFields[0] || nameFields[0] || keys[0];\n const yFields =\n numericFields.length > 0 ? numericFields : keys.filter((k) => k !== xField);\n return {\n xField,\n yFields,\n chartType: dateFields.length > 0 ? \"timeseries\" : \"categorical\",\n };\n}\n\n// ============================================================================\n// Value Conversion\n// ============================================================================\n\n/**\n * Converts a JSON value to a chart-compatible value.\n */\nfunction jsonValueToChartValue(\n value: unknown,\n isYValue: boolean,\n isDateField: boolean,\n): string | number {\n if (value === null || value === undefined) {\n return isYValue ? 0 : \"\";\n }\n if (typeof value === \"number\") {\n return value;\n }\n if (typeof value === \"bigint\") {\n return Number(value);\n }\n if (typeof value === \"string\") {\n if (isDateField && isDateString(value)) {\n const timestamp = new Date(value).getTime();\n if (!Number.isNaN(timestamp)) {\n return timestamp;\n }\n }\n if (isYValue) {\n const trimmed = value.trim();\n const parsed = Number(trimmed);\n if (!Number.isNaN(parsed) && Number.isFinite(parsed)) {\n return parsed;\n }\n }\n return value;\n }\n return String(value);\n}\n\n// ============================================================================\n// Data Extraction\n// ============================================================================\n\n/**\n * Extracts chart data from JSON array\n */\nfunction extractFromJson(\n data: Record<string, unknown>[],\n xField: string,\n yFields: string[],\n): {\n xData: (string | number)[];\n yDataMap: Record<string, (string | number)[]>;\n} {\n const xData: (string | number)[] = [];\n const yDataMap: Record<string, (string | number)[]> = {};\n\n for (const field of yFields) {\n yDataMap[field] = [];\n }\n\n const xIsDateField = data.length > 0 && isDateString(data[0][xField]);\n\n for (const row of data) {\n xData.push(jsonValueToChartValue(row[xField], false, xIsDateField));\n for (const field of yFields) {\n yDataMap[field].push(jsonValueToChartValue(row[field], true, false));\n }\n }\n\n return { xData, yDataMap };\n}\n\n// ============================================================================\n// Main Normalization Function\n// ============================================================================\n\n/**\n * Normalizes chart data from either Arrow or JSON format.\n * Converts BigInt and Date values to chart-compatible types.\n */\nexport function normalizeChartData(\n data: ChartData,\n xKey?: string,\n yKey?: string | string[],\n orientation?: Orientation,\n): NormalizedChartData {\n if (isArrowTable(data)) {\n const table = data as Table;\n const detected = ArrowClient.detectFieldsFromArrow(table, orientation);\n const resolvedXKey = xKey ?? detected.xField;\n const resolvedYKeys = yKey\n ? Array.isArray(yKey)\n ? yKey\n : [yKey]\n : detected.yFields;\n\n const { xData: rawXData, yDataMap: rawYDataMap } =\n ArrowClient.extractChartData(table, resolvedXKey, resolvedYKeys);\n\n let xData = toChartArray(rawXData);\n let yDataMap: Record<string, (string | number)[]> = {};\n for (const key of resolvedYKeys) {\n yDataMap[key] = toChartArray(rawYDataMap[key] ?? []);\n }\n\n if (detected.chartType === \"timeseries\") {\n ({ xData, yDataMap } = sortTimeSeriesAscending(\n xData,\n yDataMap,\n resolvedYKeys,\n ));\n }\n\n return {\n xData,\n yDataMap,\n xField: resolvedXKey,\n yFields: resolvedYKeys,\n chartType: detected.chartType,\n };\n }\n\n // JSON Array\n const jsonData = data as Record<string, unknown>[];\n const detected = detectFieldsFromJson(jsonData, orientation);\n const resolvedXKey = xKey ?? detected.xField;\n const resolvedYKeys = yKey\n ? Array.isArray(yKey)\n ? yKey\n : [yKey]\n : detected.yFields;\n\n const { xData: rawXData, yDataMap: rawYDataMap } = extractFromJson(\n jsonData,\n resolvedXKey,\n resolvedYKeys,\n );\n\n let xData = toChartArray(rawXData);\n let yDataMap: Record<string, (string | number)[]> = {};\n for (const key of resolvedYKeys) {\n yDataMap[key] = toChartArray(rawYDataMap[key] ?? []);\n }\n\n if (detected.chartType === \"timeseries\") {\n ({ xData, yDataMap } = sortTimeSeriesAscending(\n xData,\n yDataMap,\n resolvedYKeys,\n ));\n }\n\n return {\n xData,\n yDataMap,\n xField: resolvedXKey,\n yFields: resolvedYKeys,\n chartType: detected.chartType,\n };\n}\n\n// ============================================================================\n// Heatmap Data Normalization\n// ============================================================================\n\n/**\n * Normalized data for heatmap charts.\n * Extends base (not NormalizedChartData) because heatmaps don't use yDataMap.\n * Instead, they use heatmapData which contains [xIndex, yIndex, value] tuples.\n */\nexport interface NormalizedHeatmapData extends NormalizedChartDataBase {\n /** Y-axis categories (rows) */\n yAxisData: (string | number)[];\n /** Heatmap data as [xIndex, yIndex, value] tuples */\n heatmapData: [number, number, number][];\n /** Min value in the data */\n min: number;\n /** Max value in the data */\n max: number;\n}\n\n/**\n * Normalizes data specifically for heatmap charts.\n * Expects data in format: { xKey: string, yAxisKey: string, valueKey: number }\n *\n * @param data - Raw data (Arrow Table or JSON array)\n * @param xKey - Field key for X-axis (columns)\n * @param yAxisKey - Field key for Y-axis (rows)\n * @param valueKey - Field key for the cell values\n */\nexport function normalizeHeatmapData(\n data: ChartData,\n xKey?: string,\n yAxisKey?: string,\n valueKey?: string | string[],\n): NormalizedHeatmapData {\n // First, get the standard normalization\n const jsonData = isArrowTable(data)\n ? extractJsonFromArrow(data)\n : (data as Record<string, unknown>[]);\n\n if (jsonData.length === 0) {\n return {\n xData: [],\n xField: xKey ?? \"x\",\n yFields: [],\n chartType: \"categorical\",\n yAxisData: [],\n heatmapData: [],\n min: 0,\n max: 0,\n };\n }\n\n // Detect fields if not provided\n const keys = Object.keys(jsonData[0]);\n const resolvedXKey = xKey ?? keys[0];\n const resolvedYAxisKey = yAxisKey ?? keys[1];\n const resolvedValueKey = valueKey\n ? Array.isArray(valueKey)\n ? valueKey[0]\n : valueKey\n : keys[2];\n\n // Extract unique X and Y categories\n const xSet = new Set<string | number>();\n const ySet = new Set<string | number>();\n\n for (const row of jsonData) {\n const xVal = jsonValueToChartValue(row[resolvedXKey], false, false);\n const yVal = jsonValueToChartValue(row[resolvedYAxisKey], false, false);\n xSet.add(xVal);\n ySet.add(yVal);\n }\n\n const xData = Array.from(xSet);\n const yAxisData = Array.from(ySet);\n\n // Create index maps for fast lookup\n const xIndexMap = new Map<string | number, number>();\n const yIndexMap = new Map<string | number, number>();\n xData.forEach((v, i) => {\n xIndexMap.set(v, i);\n });\n yAxisData.forEach((v, i) => {\n yIndexMap.set(v, i);\n });\n\n // Build heatmap data and track min/max\n const heatmapData: [number, number, number][] = [];\n let min = Number.POSITIVE_INFINITY;\n let max = Number.NEGATIVE_INFINITY;\n\n for (const row of jsonData) {\n const xVal = jsonValueToChartValue(row[resolvedXKey], false, false);\n const yVal = jsonValueToChartValue(row[resolvedYAxisKey], false, false);\n const value = jsonValueToChartValue(row[resolvedValueKey], true, false);\n\n const xIdx = xIndexMap.get(xVal);\n const yIdx = yIndexMap.get(yVal);\n const numValue = typeof value === \"number\" ? value : 0;\n\n if (xIdx !== undefined && yIdx !== undefined) {\n heatmapData.push([xIdx, yIdx, numValue]);\n min = Math.min(min, numValue);\n max = Math.max(max, numValue);\n }\n }\n\n // Handle edge case where no valid data was found\n if (heatmapData.length === 0) {\n min = 0;\n max = 0;\n }\n\n return {\n xData,\n xField: resolvedXKey,\n yFields: [resolvedValueKey],\n chartType: \"categorical\",\n yAxisData,\n heatmapData,\n min,\n max,\n };\n}\n\n/**\n * Helper to extract JSON array from Arrow table for heatmap processing.\n */\nfunction extractJsonFromArrow(table: Table): Record<string, unknown>[] {\n const result: Record<string, unknown>[] = [];\n const fields = table.schema.fields.map((f) => f.name);\n\n for (let i = 0; i < table.numRows; i++) {\n const row: Record<string, unknown> = {};\n for (const field of fields) {\n const col = table.getChild(field);\n row[field] = col?.get(i);\n }\n result.push(row);\n }\n\n return result;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"normalize.js","names":["xField","detected","resolvedXKey","resolvedYKeys","rawXData","rawYDataMap","xData","yDataMap"],"sources":["../../../src/react/charts/normalize.ts"],"sourcesContent":["import { ArrowClient } from \"@/js\";\nimport type { Table } from \"apache-arrow\";\nimport { DATE_FIELD_PATTERNS, NAME_FIELD_PATTERNS } from \"./constants\";\nimport type {\n ChartData,\n NormalizedChartData,\n NormalizedChartDataBase,\n Orientation,\n} from \"./types\";\nimport { isArrowTable } from \"./types\";\nimport { sortTimeSeriesAscending, toChartArray } from \"./utils\";\n\n// ============================================================================\n// Type Detection Helpers\n// ============================================================================\n\n/**\n * Checks if a value looks like an ISO date string\n */\nfunction isDateString(value: unknown): boolean {\n if (typeof value !== \"string\") return false;\n return /^\\d{4}-\\d{2}-\\d{2}(T|$)/.test(value);\n}\n\n/**\n * Checks if a value is numeric (number or numeric string)\n */\nfunction isNumericValue(value: unknown): boolean {\n if (typeof value === \"number\") return true;\n if (typeof value === \"bigint\") return true;\n if (typeof value === \"string\") {\n const trimmed = value.trim();\n if (trimmed === \"\" || isDateString(trimmed)) return false;\n const parsed = Number(trimmed);\n return !Number.isNaN(parsed) && Number.isFinite(parsed);\n }\n return false;\n}\n\n/**\n * Checks if a value looks like a category/label (non-numeric string)\n */\nfunction isCategoryValue(value: unknown): boolean {\n if (typeof value !== \"string\") return false;\n const trimmed = value.trim();\n if (trimmed === \"\") return false;\n if (/^\\d{4}-\\d{2}-\\d{2}/.test(trimmed)) return false;\n const parsed = Number(trimmed);\n return Number.isNaN(parsed) || !Number.isFinite(parsed);\n}\n\n// ============================================================================\n// Field Detection\n// ============================================================================\n\n/**\n * Detects fields from JSON data for charting\n */\nfunction detectFieldsFromJson(\n data: Record<string, unknown>[],\n orientation?: Orientation,\n): {\n xField: string;\n yFields: string[];\n chartType: \"timeseries\" | \"categorical\";\n} {\n if (!data || data.length === 0) {\n return { xField: \"x\", yFields: [\"y\"], chartType: \"categorical\" };\n }\n\n const firstRow = data[0];\n const keys = Object.keys(firstRow);\n\n // Detect date fields by key name OR by value being a date string\n const dateFields = keys.filter((key) => {\n const value = firstRow[key];\n const keyMatchesDatePattern = DATE_FIELD_PATTERNS.some((p) =>\n key.toLowerCase().includes(p),\n );\n const valueIsDateString = isDateString(value);\n return keyMatchesDatePattern || valueIsDateString;\n });\n\n // Detect name/category fields by pattern AND value type\n let nameFields = keys.filter((key) => {\n const value = firstRow[key];\n return (\n isCategoryValue(value) &&\n !isDateString(value) &&\n NAME_FIELD_PATTERNS.some((p) => key.toLowerCase().includes(p))\n );\n });\n\n // Fallback: any string field that isn't a date or ID\n if (nameFields.length === 0) {\n nameFields = keys.filter((key) => {\n const value = firstRow[key];\n return (\n isCategoryValue(value) &&\n !isDateString(value) &&\n !dateFields.includes(key) &&\n !key.toLowerCase().endsWith(\"_id\")\n );\n });\n }\n\n // Detect numeric fields\n const numericFields = keys.filter((key) => {\n const value = firstRow[key];\n return isNumericValue(value) && !dateFields.includes(key);\n });\n\n const isHorizontal = orientation === \"horizontal\";\n\n if (isHorizontal || (nameFields.length > 0 && dateFields.length === 0)) {\n const xField = nameFields[0] || dateFields[0] || keys[0];\n const yFields =\n numericFields.length > 0\n ? numericFields\n : keys.filter((k) => k !== xField);\n return { xField, yFields, chartType: \"categorical\" };\n }\n\n const xField = dateFields[0] || nameFields[0] || keys[0];\n const yFields =\n numericFields.length > 0 ? numericFields : keys.filter((k) => k !== xField);\n return {\n xField,\n yFields,\n chartType: dateFields.length > 0 ? \"timeseries\" : \"categorical\",\n };\n}\n\n// ============================================================================\n// Value Conversion\n// ============================================================================\n\n/**\n * Converts a JSON value to a chart-compatible value.\n */\nfunction jsonValueToChartValue(\n value: unknown,\n isYValue: boolean,\n isDateField: boolean,\n): string | number {\n if (value === null || value === undefined) {\n return isYValue ? 0 : \"\";\n }\n if (typeof value === \"number\") {\n return value;\n }\n if (typeof value === \"bigint\") {\n return Number(value);\n }\n if (typeof value === \"string\") {\n if (isDateField && isDateString(value)) {\n const timestamp = new Date(value).getTime();\n if (!Number.isNaN(timestamp)) {\n return timestamp;\n }\n }\n if (isYValue) {\n const trimmed = value.trim();\n const parsed = Number(trimmed);\n if (!Number.isNaN(parsed) && Number.isFinite(parsed)) {\n return parsed;\n }\n }\n return value;\n }\n return String(value);\n}\n\n// ============================================================================\n// Data Extraction\n// ============================================================================\n\n/**\n * Extracts chart data from JSON array\n */\nfunction extractFromJson(\n data: Record<string, unknown>[],\n xField: string,\n yFields: string[],\n): {\n xData: (string | number)[];\n yDataMap: Record<string, (string | number)[]>;\n} {\n const xData: (string | number)[] = [];\n const yDataMap: Record<string, (string | number)[]> = {};\n\n for (const field of yFields) {\n yDataMap[field] = [];\n }\n\n const xIsDateField = data.length > 0 && isDateString(data[0][xField]);\n\n for (const row of data) {\n xData.push(jsonValueToChartValue(row[xField], false, xIsDateField));\n for (const field of yFields) {\n yDataMap[field].push(jsonValueToChartValue(row[field], true, false));\n }\n }\n\n return { xData, yDataMap };\n}\n\n// ============================================================================\n// Main Normalization Function\n// ============================================================================\n\n/**\n * Normalizes chart data from either Arrow or JSON format.\n * Converts BigInt and Date values to chart-compatible types.\n */\nexport function normalizeChartData(\n data: ChartData,\n xKey?: string,\n yKey?: string | string[],\n orientation?: Orientation,\n): NormalizedChartData {\n if (isArrowTable(data)) {\n const table = data as Table;\n const detected = ArrowClient.detectFieldsFromArrow(table, orientation);\n const resolvedXKey = xKey ?? detected.xField;\n const resolvedYKeys = yKey\n ? Array.isArray(yKey)\n ? yKey\n : [yKey]\n : detected.yFields;\n\n const { xData: rawXData, yDataMap: rawYDataMap } =\n ArrowClient.extractChartData(table, resolvedXKey, resolvedYKeys);\n\n let xData = toChartArray(rawXData);\n let yDataMap: Record<string, (string | number)[]> = {};\n for (const key of resolvedYKeys) {\n yDataMap[key] = toChartArray(rawYDataMap[key] ?? []);\n }\n\n if (detected.chartType === \"timeseries\") {\n ({ xData, yDataMap } = sortTimeSeriesAscending(\n xData,\n yDataMap,\n resolvedYKeys,\n ));\n }\n\n return {\n xData,\n yDataMap,\n xField: resolvedXKey,\n yFields: resolvedYKeys,\n chartType: detected.chartType,\n };\n }\n\n // JSON Array\n const jsonData = data as Record<string, unknown>[];\n const detected = detectFieldsFromJson(jsonData, orientation);\n const resolvedXKey = xKey ?? detected.xField;\n const resolvedYKeys = yKey\n ? Array.isArray(yKey)\n ? yKey\n : [yKey]\n : detected.yFields;\n\n const { xData: rawXData, yDataMap: rawYDataMap } = extractFromJson(\n jsonData,\n resolvedXKey,\n resolvedYKeys,\n );\n\n let xData = toChartArray(rawXData);\n let yDataMap: Record<string, (string | number)[]> = {};\n for (const key of resolvedYKeys) {\n yDataMap[key] = toChartArray(rawYDataMap[key] ?? []);\n }\n\n if (detected.chartType === \"timeseries\") {\n ({ xData, yDataMap } = sortTimeSeriesAscending(\n xData,\n yDataMap,\n resolvedYKeys,\n ));\n }\n\n return {\n xData,\n yDataMap,\n xField: resolvedXKey,\n yFields: resolvedYKeys,\n chartType: detected.chartType,\n };\n}\n\n// ============================================================================\n// Heatmap Data Normalization\n// ============================================================================\n\n/**\n * Normalized data for heatmap charts.\n * Extends base (not NormalizedChartData) because heatmaps don't use yDataMap.\n * Instead, they use heatmapData which contains [xIndex, yIndex, value] tuples.\n */\nexport interface NormalizedHeatmapData extends NormalizedChartDataBase {\n /** Y-axis categories (rows) */\n yAxisData: (string | number)[];\n /** Heatmap data as [xIndex, yIndex, value] tuples */\n heatmapData: [number, number, number][];\n /** Min value in the data */\n min: number;\n /** Max value in the data */\n max: number;\n}\n\n/**\n * Normalizes data specifically for heatmap charts.\n * Expects data in format: `{ xKey: string, yAxisKey: string, valueKey: number }`\n *\n * @param data - Raw data (Arrow Table or JSON array)\n * @param xKey - Field key for X-axis (columns)\n * @param yAxisKey - Field key for Y-axis (rows)\n * @param valueKey - Field key for the cell values\n */\nexport function normalizeHeatmapData(\n data: ChartData,\n xKey?: string,\n yAxisKey?: string,\n valueKey?: string | string[],\n): NormalizedHeatmapData {\n // First, get the standard normalization\n const jsonData = isArrowTable(data)\n ? extractJsonFromArrow(data)\n : (data as Record<string, unknown>[]);\n\n if (jsonData.length === 0) {\n return {\n xData: [],\n xField: xKey ?? \"x\",\n yFields: [],\n chartType: \"categorical\",\n yAxisData: [],\n heatmapData: [],\n min: 0,\n max: 0,\n };\n }\n\n // Detect fields if not provided\n const keys = Object.keys(jsonData[0]);\n const resolvedXKey = xKey ?? keys[0];\n const resolvedYAxisKey = yAxisKey ?? keys[1];\n const resolvedValueKey = valueKey\n ? Array.isArray(valueKey)\n ? valueKey[0]\n : valueKey\n : keys[2];\n\n // Extract unique X and Y categories\n const xSet = new Set<string | number>();\n const ySet = new Set<string | number>();\n\n for (const row of jsonData) {\n const xVal = jsonValueToChartValue(row[resolvedXKey], false, false);\n const yVal = jsonValueToChartValue(row[resolvedYAxisKey], false, false);\n xSet.add(xVal);\n ySet.add(yVal);\n }\n\n const xData = Array.from(xSet);\n const yAxisData = Array.from(ySet);\n\n // Create index maps for fast lookup\n const xIndexMap = new Map<string | number, number>();\n const yIndexMap = new Map<string | number, number>();\n xData.forEach((v, i) => {\n xIndexMap.set(v, i);\n });\n yAxisData.forEach((v, i) => {\n yIndexMap.set(v, i);\n });\n\n // Build heatmap data and track min/max\n const heatmapData: [number, number, number][] = [];\n let min = Number.POSITIVE_INFINITY;\n let max = Number.NEGATIVE_INFINITY;\n\n for (const row of jsonData) {\n const xVal = jsonValueToChartValue(row[resolvedXKey], false, false);\n const yVal = jsonValueToChartValue(row[resolvedYAxisKey], false, false);\n const value = jsonValueToChartValue(row[resolvedValueKey], true, false);\n\n const xIdx = xIndexMap.get(xVal);\n const yIdx = yIndexMap.get(yVal);\n const numValue = typeof value === \"number\" ? value : 0;\n\n if (xIdx !== undefined && yIdx !== undefined) {\n heatmapData.push([xIdx, yIdx, numValue]);\n min = Math.min(min, numValue);\n max = Math.max(max, numValue);\n }\n }\n\n // Handle edge case where no valid data was found\n if (heatmapData.length === 0) {\n min = 0;\n max = 0;\n }\n\n return {\n xData,\n xField: resolvedXKey,\n yFields: [resolvedValueKey],\n chartType: \"categorical\",\n yAxisData,\n heatmapData,\n min,\n max,\n };\n}\n\n/**\n * Helper to extract JSON array from Arrow table for heatmap processing.\n */\nfunction extractJsonFromArrow(table: Table): Record<string, unknown>[] {\n const result: Record<string, unknown>[] = [];\n const fields = table.schema.fields.map((f) => f.name);\n\n for (let i = 0; i < table.numRows; i++) {\n const row: Record<string, unknown> = {};\n for (const field of fields) {\n const col = table.getChild(field);\n row[field] = col?.get(i);\n }\n result.push(row);\n }\n\n return result;\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { DonutChartProps, PieChartProps } from "../types.js";
2
- import * as react_jsx_runtime277 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime279 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/react/charts/pie/index.d.ts
5
5
 
@@ -25,7 +25,7 @@ import * as react_jsx_runtime277 from "react/jsx-runtime";
25
25
  * ```
26
26
  */
27
27
  declare const PieChart: {
28
- (props: PieChartProps): react_jsx_runtime277.JSX.Element;
28
+ (props: PieChartProps): react_jsx_runtime279.JSX.Element;
29
29
  displayName: string;
30
30
  };
31
31
  /**
@@ -49,7 +49,7 @@ declare const PieChart: {
49
49
  * ```
50
50
  */
51
51
  declare const DonutChart: {
52
- (props: DonutChartProps): react_jsx_runtime277.JSX.Element;
52
+ (props: DonutChartProps): react_jsx_runtime279.JSX.Element;
53
53
  displayName: string;
54
54
  };
55
55
  //#endregion
@@ -1,5 +1,5 @@
1
1
  import { RadarChartProps } from "../types.js";
2
- import * as react_jsx_runtime279 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime281 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/react/charts/radar/index.d.ts
5
5
 
@@ -24,7 +24,7 @@ import * as react_jsx_runtime279 from "react/jsx-runtime";
24
24
  * ```
25
25
  */
26
26
  declare const RadarChart: {
27
- (props: RadarChartProps): react_jsx_runtime279.JSX.Element;
27
+ (props: RadarChartProps): react_jsx_runtime281.JSX.Element;
28
28
  displayName: string;
29
29
  };
30
30
  //#endregion
@@ -1,5 +1,5 @@
1
1
  import { ScatterChartProps } from "../types.js";
2
- import * as react_jsx_runtime280 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime282 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/react/charts/scatter/index.d.ts
5
5
 
@@ -24,7 +24,7 @@ import * as react_jsx_runtime280 from "react/jsx-runtime";
24
24
  * ```
25
25
  */
26
26
  declare const ScatterChart: {
27
- (props: ScatterChartProps): react_jsx_runtime280.JSX.Element;
27
+ (props: ScatterChartProps): react_jsx_runtime282.JSX.Element;
28
28
  displayName: string;
29
29
  };
30
30
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"theme.js","names":["PALETTE_CONFIG: Record<\n ChartColorPalette,\n { vars: readonly string[]; fallback: string[] }\n>","colors: string[]"],"sources":["../../../src/react/charts/theme.ts"],"sourcesContent":["import { useEffect, useState } from \"react\";\nimport {\n CHART_COLOR_VARS_CATEGORICAL,\n CHART_COLOR_VARS_DIVERGING,\n CHART_COLOR_VARS_SEQUENTIAL,\n FALLBACK_COLORS_CATEGORICAL,\n FALLBACK_COLORS_DIVERGING,\n FALLBACK_COLORS_SEQUENTIAL,\n} from \"./constants\";\nimport type { ChartColorPalette } from \"./types\";\n\n// ============================================================================\n// Theme Colors (resolved from CSS variables)\n// ============================================================================\n\nconst PALETTE_CONFIG: Record<\n ChartColorPalette,\n { vars: readonly string[]; fallback: string[] }\n> = {\n categorical: {\n vars: CHART_COLOR_VARS_CATEGORICAL,\n fallback: FALLBACK_COLORS_CATEGORICAL,\n },\n sequential: {\n vars: CHART_COLOR_VARS_SEQUENTIAL,\n fallback: FALLBACK_COLORS_SEQUENTIAL,\n },\n diverging: {\n vars: CHART_COLOR_VARS_DIVERGING,\n fallback: FALLBACK_COLORS_DIVERGING,\n },\n};\n\n// ============================================================================\n// Module-Level Caching\n// ============================================================================\n\n/**\n * Cache for computed theme colors to avoid repeated CSS variable lookups.\n * Cache is cleared when theme change events fire (MutationObserver/matchMedia).\n */\nconst colorCache = new Map<string, string[]>();\n\n/**\n * Clears the theme color cache.\n * Called when theme change events fire, or for testing when mocks change.\n * @internal\n */\nexport function resetThemeColorCache(): void {\n colorCache.clear();\n}\n\n/**\n * Gets theme colors with module-level caching.\n * Avoids repeated CSS variable lookups for the same palette within a theme.\n */\nfunction getThemeColors(palette: ChartColorPalette = \"categorical\"): string[] {\n const config = PALETTE_CONFIG[palette];\n\n if (typeof window === \"undefined\") return config.fallback;\n\n // Return cached colors if available\n const cached = colorCache.get(palette);\n if (cached) {\n return cached;\n }\n\n // Compute colors from CSS variables\n const styles = getComputedStyle(document.documentElement);\n const colors: string[] = [];\n\n for (const varName of config.vars) {\n const value = styles.getPropertyValue(varName).trim();\n if (value) colors.push(value);\n }\n\n const result = colors.length > 0 ? colors : config.fallback;\n\n // Cache the result\n colorCache.set(palette, result);\n\n return result;\n}\n\n/**\n * Hook to get theme colors with automatic updates on theme change.\n * Re-resolves CSS variables when color scheme or theme attributes change.\n *\n * @param palette - Color palette type: \"categorical\" (default), \"sequential\", or \"diverging\"\n */\nexport function useThemeColors(\n palette: ChartColorPalette = \"categorical\",\n): string[] {\n const [colors, setColors] = useState<string[]>(() =>\n typeof window === \"undefined\"\n ? PALETTE_CONFIG[palette].fallback\n : getThemeColors(palette),\n );\n\n useEffect(() => {\n // Clear cache and re-fetch colors when theme changes\n const updateColors = () => {\n resetThemeColorCache();\n setColors(getThemeColors(palette));\n };\n\n // Listen for system color scheme changes\n const mediaQuery = window.matchMedia(\"(prefers-color-scheme: dark)\");\n mediaQuery.addEventListener(\"change\", updateColors);\n\n // Listen for theme attribute changes (e.g., class=\"dark\", data-theme=\"dark\")\n const observer = new MutationObserver(updateColors);\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: [\"class\", \"data-theme\", \"data-mode\"],\n });\n\n return () => {\n mediaQuery.removeEventListener(\"change\", updateColors);\n observer.disconnect();\n };\n }, [palette]);\n\n return colors;\n}\n\n/**\n * Hook to get all three color palettes at once.\n * Useful when a component needs access to multiple palette types.\n */\nexport function useAllThemeColors(): {\n categorical: string[];\n sequential: string[];\n diverging: string[];\n} {\n const categorical = useThemeColors(\"categorical\");\n const sequential = useThemeColors(\"sequential\");\n const diverging = useThemeColors(\"diverging\");\n\n return { categorical, sequential, diverging };\n}\n"],"mappings":";;;;AAeA,MAAMA,iBAGF;CACF,aAAa;EACX,MAAM;EACN,UAAU;EACX;CACD,YAAY;EACV,MAAM;EACN,UAAU;EACX;CACD,WAAW;EACT,MAAM;EACN,UAAU;EACX;CACF;;;;;AAUD,MAAM,6BAAa,IAAI,KAAuB;;;;;;AAO9C,SAAgB,uBAA6B;AAC3C,YAAW,OAAO;;;;;;AAOpB,SAAS,eAAe,UAA6B,eAAyB;CAC5E,MAAM,SAAS,eAAe;AAE9B,KAAI,OAAO,WAAW,YAAa,QAAO,OAAO;CAGjD,MAAM,SAAS,WAAW,IAAI,QAAQ;AACtC,KAAI,OACF,QAAO;CAIT,MAAM,SAAS,iBAAiB,SAAS,gBAAgB;CACzD,MAAMC,SAAmB,EAAE;AAE3B,MAAK,MAAM,WAAW,OAAO,MAAM;EACjC,MAAM,QAAQ,OAAO,iBAAiB,QAAQ,CAAC,MAAM;AACrD,MAAI,MAAO,QAAO,KAAK,MAAM;;CAG/B,MAAM,SAAS,OAAO,SAAS,IAAI,SAAS,OAAO;AAGnD,YAAW,IAAI,SAAS,OAAO;AAE/B,QAAO;;;;;;;;AAST,SAAgB,eACd,UAA6B,eACnB;CACV,MAAM,CAAC,QAAQ,aAAa,eAC1B,OAAO,WAAW,cACd,eAAe,SAAS,WACxB,eAAe,QAAQ,CAC5B;AAED,iBAAgB;EAEd,MAAM,qBAAqB;AACzB,yBAAsB;AACtB,aAAU,eAAe,QAAQ,CAAC;;EAIpC,MAAM,aAAa,OAAO,WAAW,+BAA+B;AACpE,aAAW,iBAAiB,UAAU,aAAa;EAGnD,MAAM,WAAW,IAAI,iBAAiB,aAAa;AACnD,WAAS,QAAQ,SAAS,iBAAiB;GACzC,YAAY;GACZ,iBAAiB;IAAC;IAAS;IAAc;IAAY;GACtD,CAAC;AAEF,eAAa;AACX,cAAW,oBAAoB,UAAU,aAAa;AACtD,YAAS,YAAY;;IAEtB,CAAC,QAAQ,CAAC;AAEb,QAAO;;;;;;AAOT,SAAgB,oBAId;AAKA,QAAO;EAAE,aAJW,eAAe,cAAc;EAI3B,YAHH,eAAe,aAAa;EAGb,WAFhB,eAAe,YAAY;EAEA"}
1
+ {"version":3,"file":"theme.js","names":[],"sources":["../../../src/react/charts/theme.ts"],"sourcesContent":["import { useEffect, useState } from \"react\";\nimport {\n CHART_COLOR_VARS_CATEGORICAL,\n CHART_COLOR_VARS_DIVERGING,\n CHART_COLOR_VARS_SEQUENTIAL,\n FALLBACK_COLORS_CATEGORICAL,\n FALLBACK_COLORS_DIVERGING,\n FALLBACK_COLORS_SEQUENTIAL,\n} from \"./constants\";\nimport type { ChartColorPalette } from \"./types\";\n\n// ============================================================================\n// Theme Colors (resolved from CSS variables)\n// ============================================================================\n\nconst PALETTE_CONFIG: Record<\n ChartColorPalette,\n { vars: readonly string[]; fallback: string[] }\n> = {\n categorical: {\n vars: CHART_COLOR_VARS_CATEGORICAL,\n fallback: FALLBACK_COLORS_CATEGORICAL,\n },\n sequential: {\n vars: CHART_COLOR_VARS_SEQUENTIAL,\n fallback: FALLBACK_COLORS_SEQUENTIAL,\n },\n diverging: {\n vars: CHART_COLOR_VARS_DIVERGING,\n fallback: FALLBACK_COLORS_DIVERGING,\n },\n};\n\n// ============================================================================\n// Module-Level Caching\n// ============================================================================\n\n/**\n * Cache for computed theme colors to avoid repeated CSS variable lookups.\n * Cache is cleared when theme change events fire (MutationObserver/matchMedia).\n */\nconst colorCache = new Map<string, string[]>();\n\n/**\n * Clears the theme color cache.\n * Called when theme change events fire, or for testing when mocks change.\n * @internal\n */\nexport function resetThemeColorCache(): void {\n colorCache.clear();\n}\n\n/**\n * Gets theme colors with module-level caching.\n * Avoids repeated CSS variable lookups for the same palette within a theme.\n */\nfunction getThemeColors(palette: ChartColorPalette = \"categorical\"): string[] {\n const config = PALETTE_CONFIG[palette];\n\n if (typeof window === \"undefined\") return config.fallback;\n\n // Return cached colors if available\n const cached = colorCache.get(palette);\n if (cached) {\n return cached;\n }\n\n // Compute colors from CSS variables\n const styles = getComputedStyle(document.documentElement);\n const colors: string[] = [];\n\n for (const varName of config.vars) {\n const value = styles.getPropertyValue(varName).trim();\n if (value) colors.push(value);\n }\n\n const result = colors.length > 0 ? colors : config.fallback;\n\n // Cache the result\n colorCache.set(palette, result);\n\n return result;\n}\n\n/**\n * Hook to get theme colors with automatic updates on theme change.\n * Re-resolves CSS variables when color scheme or theme attributes change.\n *\n * @param palette - Color palette type: \"categorical\" (default), \"sequential\", or \"diverging\"\n */\nexport function useThemeColors(\n palette: ChartColorPalette = \"categorical\",\n): string[] {\n const [colors, setColors] = useState<string[]>(() =>\n typeof window === \"undefined\"\n ? PALETTE_CONFIG[palette].fallback\n : getThemeColors(palette),\n );\n\n useEffect(() => {\n // Clear cache and re-fetch colors when theme changes\n const updateColors = () => {\n resetThemeColorCache();\n setColors(getThemeColors(palette));\n };\n\n // Listen for system color scheme changes\n const mediaQuery = window.matchMedia(\"(prefers-color-scheme: dark)\");\n mediaQuery.addEventListener(\"change\", updateColors);\n\n // Listen for theme attribute changes (e.g., class=\"dark\", data-theme=\"dark\")\n const observer = new MutationObserver(updateColors);\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: [\"class\", \"data-theme\", \"data-mode\"],\n });\n\n return () => {\n mediaQuery.removeEventListener(\"change\", updateColors);\n observer.disconnect();\n };\n }, [palette]);\n\n return colors;\n}\n\n/**\n * Hook to get all three color palettes at once.\n * Useful when a component needs access to multiple palette types.\n */\nexport function useAllThemeColors(): {\n categorical: string[];\n sequential: string[];\n diverging: string[];\n} {\n const categorical = useThemeColors(\"categorical\");\n const sequential = useThemeColors(\"sequential\");\n const diverging = useThemeColors(\"diverging\");\n\n return { categorical, sequential, diverging };\n}\n"],"mappings":";;;;AAeA,MAAM,iBAGF;CACF,aAAa;EACX,MAAM;EACN,UAAU;EACX;CACD,YAAY;EACV,MAAM;EACN,UAAU;EACX;CACD,WAAW;EACT,MAAM;EACN,UAAU;EACX;CACF;;;;;AAUD,MAAM,6BAAa,IAAI,KAAuB;;;;;;AAO9C,SAAgB,uBAA6B;AAC3C,YAAW,OAAO;;;;;;AAOpB,SAAS,eAAe,UAA6B,eAAyB;CAC5E,MAAM,SAAS,eAAe;AAE9B,KAAI,OAAO,WAAW,YAAa,QAAO,OAAO;CAGjD,MAAM,SAAS,WAAW,IAAI,QAAQ;AACtC,KAAI,OACF,QAAO;CAIT,MAAM,SAAS,iBAAiB,SAAS,gBAAgB;CACzD,MAAM,SAAmB,EAAE;AAE3B,MAAK,MAAM,WAAW,OAAO,MAAM;EACjC,MAAM,QAAQ,OAAO,iBAAiB,QAAQ,CAAC,MAAM;AACrD,MAAI,MAAO,QAAO,KAAK,MAAM;;CAG/B,MAAM,SAAS,OAAO,SAAS,IAAI,SAAS,OAAO;AAGnD,YAAW,IAAI,SAAS,OAAO;AAE/B,QAAO;;;;;;;;AAST,SAAgB,eACd,UAA6B,eACnB;CACV,MAAM,CAAC,QAAQ,aAAa,eAC1B,OAAO,WAAW,cACd,eAAe,SAAS,WACxB,eAAe,QAAQ,CAC5B;AAED,iBAAgB;EAEd,MAAM,qBAAqB;AACzB,yBAAsB;AACtB,aAAU,eAAe,QAAQ,CAAC;;EAIpC,MAAM,aAAa,OAAO,WAAW,+BAA+B;AACpE,aAAW,iBAAiB,UAAU,aAAa;EAGnD,MAAM,WAAW,IAAI,iBAAiB,aAAa;AACnD,WAAS,QAAQ,SAAS,iBAAiB;GACzC,YAAY;GACZ,iBAAiB;IAAC;IAAS;IAAc;IAAY;GACtD,CAAC;AAEF,eAAa;AACX,cAAW,oBAAoB,UAAU,aAAa;AACtD,YAAS,YAAY;;IAEtB,CAAC,QAAQ,CAAC;AAEb,QAAO;;;;;;AAOT,SAAgB,oBAId;AAKA,QAAO;EAAE,aAJW,eAAe,cAAc;EAI3B,YAHH,eAAe,aAAa;EAGb,WAFhB,eAAe,YAAY;EAEA"}
@@ -57,6 +57,11 @@ interface QueryProps extends ChartBaseProps {
57
57
  format?: DataFormat;
58
58
  /** Transform raw data before rendering */
59
59
  transformer?: <T>(data: T) => T;
60
+ /**
61
+ * Whether to execute the query as the current user
62
+ * @default false
63
+ */
64
+ asUser?: boolean;
60
65
  data?: never;
61
66
  }
62
67
  /** Props for direct data injection */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/react/charts/types.ts"],"sourcesContent":[],"mappings":";;;;KAOY,UAAA;AAAZ;AAGY,KAAA,WAAA,GAAW,UAAA,GAAA,YAAA;AAGvB;AAWY,KAXA,SAAA,GAWS,KAAA,GAAA,MAAA,GAAA,MAAA,GAAA,KAAA,GAAA,OAAA,GAAA,SAAA,GAAA,OAAA,GAAA,SAAA;;AAAG,KAAZ,SAAA,GAAY,KAAA,GAAQ,MAAR,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA;;AAAc,KAO1B,iBAAA,GAP0B,aAAA,GAAA,YAAA,GAAA,WAAA;AAOtC;AAGiB,UAAA,cAAA,CAAc;EAAA;OAWd,CAAA,EAAA,MAAA;;EAmBC,UAAA,CAAA,EAAA,OAAA;EAQD;;;;;;cAAmB,CAAA,EA3BnB,iBA2BmB;EAAc;EAyBjC,MAAA,CAAA,EAAA,MAAU,EAAA;EAAA;QAEnB,CAAA,EAAA,MAAA;;EAFyC,SAAA,CAAA,EAAA,MAAA;EAgBrC;EAAiB,IAAA,CAAA,EAAA,MAAA;;MAAgB,CAAA,EAAA,MAAA,GAAA,MAAA,EAAA;EAAS;EAOrC,SAAA,CAAA,EAAA,MAAA;EAQA;EAUA,MAAA,CAAA,EAAA,MAAA;EAYA;EAMA,OAAA,CAAA,EA5FL,MA4FK,CAAA,MAAA,EAAqB,OAAA,CAAA;AAUtC;AAMA;AAkBY,UAtHK,UAAA,SAAmB,cAsHX,CAAA;EAAA;UAAI,EAAA,MAAA;;YAA0B,CAAA,EAlHxC,MAkHwC,CAAA,MAAA,EAAA,OAAA,CAAA;EAAqB;AAC5E;;;;;;EACY,MAAA,CAAA,EA5GD,UA4Ge;EAAA;aAAI,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,IAAA,EA1GJ,CA0GI,EAAA,GA1GE,CA0GF;MAAa,CAAA,EAAA,KAAA;;;AAC/B,UAhGK,SAAA,SAAkB,cAgGN,CAAA;EAAA;MAAI,EA9FzB,SA8FyB;UAAa,CAAA,EAAA,KAAA;YAC5C,CAAA,EAAA,KAAA;EAAyB,MAAA,CAAA,EAAA,KAAA;EACf,WAAA,CAAA,EAAA,KAAa;;;AAAiB,KAlF9B,iBAAA,GAAoB,UAkFU,GAlFG,SAkFH;;AAAkC,UA3E3D,qBAAA,CA2E2D;EAChE;EAAe,WAAA,CAAA,EA1EX,WA0EW;;SAAiB,CAAA,EAAA,OAAA;;;AAChC,UArEK,sBAAA,CAqEU;EAAA;aAAI,CAAA,EAnEf,WAmEe;;YAC7B,CAAA,EAAA,OAAA;EAAuB;EACb,MAAA,CAAA,EAAA,OAAA;;;AAAkC,UA7D7B,sBAAA,CA6D6B;;EACnB,WAAA,CAAA,EA5DX,WA4DW;EAOV;EAQA,UAAA,CAAA,EAAA,OAAA;EAAoB;QACzB,CAAA,EAAA,OAAA;;EADwD,OAAA,CAAA,EAAA,OAAA;AAKpE;;AAAmC,UAtElB,yBAAA,CAsEkB;;EAAyB,UAAA,CAAA,EAAA,MAAA;AAW5D;;AAAoC,UA3EnB,qBAAA,CA2EmB;;EAAuC,WAAA,CAAA,EAAA,MAAA;EAS3D;EAAW,UAAA,CAAA,EAAA,OAAA;;eAAqC,CAAA,EAAA,SAAA,GAAA,QAAA,GAAA,QAAA;;;UA1E/C,uBAAA;;;;;UAMA,yBAAA;;;;;;;;;;;;;KAkBL,aAAA,IAAiB,aAAa,aAAa;KAC3C,cAAA,IAAkB,aAAa,aAAa;KAC5C,cAAA,IAAkB,aAAa,aAAa;KAC5C,iBAAA,IAAqB,aAAa,aAC5C;KACU,aAAA,IAAiB,aAAa,aAAa;KAC3C,eAAA,IAAmB,aAAa,aAAa;KAC7C,eAAA,IAAmB,aAAa,aAC1C;KACU,iBAAA,IAAqB,aAAa,aAC5C;;UAOe,uBAAA;;;;;;;UAQA,mBAAA,SAA4B;YACjC;;;iBAII,YAAA,OAAmB,oBAAoB;;iBAWvC,YAAA,QAAoB,6BAA6B;;iBASjD,WAAA,QAAmB,6BAA6B"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/react/charts/types.ts"],"sourcesContent":[],"mappings":";;;;KAOY,UAAA;AAAZ;AAGY,KAAA,WAAA,GAAW,UAAA,GAAA,YAAA;AAGvB;AAWY,KAXA,SAAA,GAWS,KAAA,GAAA,MAAA,GAAA,MAAA,GAAA,KAAA,GAAA,OAAA,GAAA,SAAA,GAAA,OAAA,GAAA,SAAA;;AAAG,KAAZ,SAAA,GAAY,KAAA,GAAQ,MAAR,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA;;AAAc,KAO1B,iBAAA,GAP0B,aAAA,GAAA,YAAA,GAAA,WAAA;AAOtC;AAGiB,UAAA,cAAA,CAAc;EAAA;OAWd,CAAA,EAAA,MAAA;;EAmBC,UAAA,CAAA,EAAA,OAAA;EAQD;;;;;;cAAmB,CAAA,EA3BnB,iBA2BmB;EAAc;EA8BjC,MAAA,CAAA,EAAA,MAAU,EAAA;EAAA;QAEnB,CAAA,EAAA,MAAA;;EAFyC,SAAA,CAAA,EAAA,MAAA;EAgBrC;EAAiB,IAAA,CAAA,EAAA,MAAA;;MAAgB,CAAA,EAAA,MAAA,GAAA,MAAA,EAAA;EAAS;EAOrC,SAAA,CAAA,EAAA,MAAA;EAQA;EAUA,MAAA,CAAA,EAAA,MAAA;EAYA;EAMA,OAAA,CAAA,EAjGL,MAiGK,CAAA,MAAA,EAAqB,OAAA,CAAA;AAUtC;AAMA;AAkBY,UA3HK,UAAA,SAAmB,cA2HX,CAAA;EAAA;UAAI,EAAA,MAAA;;YAA0B,CAAA,EAvHxC,MAuHwC,CAAA,MAAA,EAAA,OAAA,CAAA;EAAqB;AAC5E;;;;;;EACY,MAAA,CAAA,EAjHD,UAiHe;EAAA;aAAI,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,IAAA,EA/GJ,CA+GI,EAAA,GA/GE,CA+GF;;;;AAC9B;EAA6B,MAAA,CAAA,EAAA,OAAA;MAAI,CAAA,EAAA,KAAA;;;AACN,UAjGV,SAAA,SAAkB,cAiGR,CAAA;EACf;EAAa,IAAA,EAhGjB,SAgGiB;UAAI,CAAA,EAAA,KAAA;YAAa,CAAA,EAAA,KAAA;QAAa,CAAA,EAAA,KAAA;EAAqB,WAAA,CAAA,EAAA,KAAA;AAC5E;;AAA+B,KAnFnB,iBAAA,GAAoB,UAmFD,GAnFc,SAmFd;;AAA0B,UA5ExC,qBAAA,CA4EwC;EAAqB;EAClE,WAAA,CAAA,EA3EI,WA2EW;EAAA;SAAI,CAAA,EAAA,OAAA;;;AACN,UAtER,sBAAA,CAsEQ;EACb;EAAiB,WAAA,CAAA,EArEb,WAqEa;;YAAiB,CAAA,EAAA,OAAA;;EACnB,MAAA,CAAA,EAAA,OAAA;AAO3B;AAQA;AAAqC,UA7EpB,sBAAA,CA6EoB;;aAAQ,CAAA,EA3E7B,WA2E6B;EAAuB;EAKpD,UAAA,CAAA,EAAA,OAAY;EAAA;QAAO,CAAA,EAAA,OAAA;;EAAyB,OAAA,CAAA,EAAA,OAAA;AAW5D;;AAAoC,UAjFnB,yBAAA,CAiFmB;;EAAuC,UAAA,CAAA,EAAA,MAAA;AAS3E;;AAAmC,UApFlB,qBAAA,CAoFkB;;EAAsC,WAAA,CAAA,EAAA,MAAA;;;;;;;UA1ExD,uBAAA;;;;;UAMA,yBAAA;;;;;;;;;;;;;KAkBL,aAAA,IAAiB,aAAa,aAAa;KAC3C,cAAA,IAAkB,aAAa,aAAa;KAC5C,cAAA,IAAkB,aAAa,aAAa;KAC5C,iBAAA,IAAqB,aAAa,aAC5C;KACU,aAAA,IAAiB,aAAa,aAAa;KAC3C,eAAA,IAAmB,aAAa,aAAa;KAC7C,eAAA,IAAmB,aAAa,aAC1C;KACU,iBAAA,IAAqB,aAAa,aAC5C;;UAOe,uBAAA;;;;;;;UAQA,mBAAA,SAA4B;YACjC;;;iBAII,YAAA,OAAmB,oBAAoB;;iBAWvC,YAAA,QAAoB,6BAA6B;;iBASjD,WAAA,QAAmB,6BAA6B"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":[],"sources":["../../../src/react/charts/types.ts"],"sourcesContent":["import type { Table } from \"apache-arrow\";\n\n// ============================================================================\n// Data Format Types\n// ============================================================================\n\n/** Supported data formats for analytics queries */\nexport type DataFormat = \"json\" | \"arrow\" | \"auto\";\n\n/** Chart orientation */\nexport type Orientation = \"vertical\" | \"horizontal\";\n\n/** Supported chart types */\nexport type ChartType =\n | \"bar\"\n | \"line\"\n | \"area\"\n | \"pie\"\n | \"donut\"\n | \"scatter\"\n | \"radar\"\n | \"heatmap\";\n\n/** Data that can be passed to unified charts */\nexport type ChartData = Table | Record<string, unknown>[];\n\n// ============================================================================\n// Base Props (shared by all charts)\n// ============================================================================\n\n/** Color palette types for different visualization needs */\nexport type ChartColorPalette = \"categorical\" | \"sequential\" | \"diverging\";\n\n/** Common visual and behavior props for all charts */\nexport interface ChartBaseProps {\n /** Chart title */\n title?: string;\n /** Show legend */\n showLegend?: boolean;\n /**\n * Color palette to use. Auto-selected based on chart type if not specified.\n * - \"categorical\": Distinct colors for different categories (bar, pie, line)\n * - \"sequential\": Gradient for magnitude/intensity (heatmap)\n * - \"diverging\": Two-tone for positive/negative values\n */\n colorPalette?: ChartColorPalette;\n /** Custom colors for series (overrides colorPalette) */\n colors?: string[];\n /** Chart height in pixels @default 300 */\n height?: number;\n /** Additional CSS classes */\n className?: string;\n\n /** X-axis field key. Auto-detected from schema if not provided. */\n xKey?: string;\n /** Y-axis field key(s). Auto-detected from schema if not provided. */\n yKey?: string | string[];\n\n /** Accessibility label for screen readers */\n ariaLabel?: string;\n /** Test ID for automated testing */\n testId?: string;\n\n /** Additional ECharts options to merge */\n options?: Record<string, unknown>;\n}\n\n// ============================================================================\n// Query-based Props (chart fetches data)\n// ============================================================================\n\n/** Props for query-based data fetching */\nexport interface QueryProps extends ChartBaseProps {\n /** Analytics query key registered with analytics plugin */\n queryKey: string;\n /** Query parameters passed to the analytics endpoint */\n parameters?: Record<string, unknown>;\n /**\n * Data format to use\n * - \"json\": Use JSON format (smaller payloads, simpler)\n * - \"arrow\": Use Arrow format (faster for large datasets)\n * - \"auto\": Automatically select based on expected data size\n * @default \"auto\"\n */\n format?: DataFormat;\n /** Transform raw data before rendering */\n transformer?: <T>(data: T) => T;\n\n // Discriminator: cannot use direct data with query\n data?: never;\n}\n\n// ============================================================================\n// Data-based Props (chart receives data externally)\n// ============================================================================\n\n/** Props for direct data injection */\nexport interface DataProps extends ChartBaseProps {\n /** Arrow Table or JSON array */\n data: ChartData;\n\n // Discriminator: cannot use query props with direct data\n queryKey?: never;\n parameters?: never;\n format?: never;\n transformer?: never;\n}\n\n// ============================================================================\n// Union Types for Each Chart\n// ============================================================================\n\n/** Base union type - either query-based or data-based */\nexport type UnifiedChartProps = QueryProps | DataProps;\n\n// ============================================================================\n// Chart-Specific Props\n// ============================================================================\n\n/** Props specific to bar charts */\nexport interface BarChartSpecificProps {\n /** Chart orientation @default \"vertical\" */\n orientation?: Orientation;\n /** Stack bars */\n stacked?: boolean;\n}\n\n/** Props specific to line charts */\nexport interface LineChartSpecificProps {\n /** Chart orientation @default \"vertical\" */\n orientation?: Orientation;\n /** Show data point symbols @default false */\n showSymbol?: boolean;\n /** Smooth line curves @default true */\n smooth?: boolean;\n}\n\n/** Props specific to area charts */\nexport interface AreaChartSpecificProps {\n /** Chart orientation @default \"vertical\" */\n orientation?: Orientation;\n /** Show data point symbols @default false */\n showSymbol?: boolean;\n /** Smooth line curves @default true */\n smooth?: boolean;\n /** Stack areas @default false */\n stacked?: boolean;\n}\n\n/** Props specific to scatter charts */\nexport interface ScatterChartSpecificProps {\n /** Symbol size @default 8 */\n symbolSize?: number;\n}\n\n/** Props specific to pie/donut charts */\nexport interface PieChartSpecificProps {\n /** Inner radius for donut charts (0-100%) @default 0 */\n innerRadius?: number;\n /** Show labels on slices @default true */\n showLabels?: boolean;\n /** Label position @default \"outside\" */\n labelPosition?: \"outside\" | \"inside\" | \"center\";\n}\n\n/** Props specific to radar charts */\nexport interface RadarChartSpecificProps {\n /** Show area fill @default true */\n showArea?: boolean;\n}\n\n/** Props specific to heatmap charts */\nexport interface HeatmapChartSpecificProps {\n /**\n * Field key for the Y-axis categories.\n * For heatmaps, data should have: xKey (column), yAxisKey (row), and yKey (value).\n */\n yAxisKey?: string;\n /** Min value for color scale (auto-detected if not provided) */\n min?: number;\n /** Max value for color scale (auto-detected if not provided) */\n max?: number;\n /** Show value labels on cells @default false */\n showLabels?: boolean;\n}\n\n// ============================================================================\n// Complete Chart Props (union + specific)\n// ============================================================================\n\nexport type BarChartProps = (QueryProps | DataProps) & BarChartSpecificProps;\nexport type LineChartProps = (QueryProps | DataProps) & LineChartSpecificProps;\nexport type AreaChartProps = (QueryProps | DataProps) & AreaChartSpecificProps;\nexport type ScatterChartProps = (QueryProps | DataProps) &\n ScatterChartSpecificProps;\nexport type PieChartProps = (QueryProps | DataProps) & PieChartSpecificProps;\nexport type DonutChartProps = (QueryProps | DataProps) & PieChartSpecificProps;\nexport type RadarChartProps = (QueryProps | DataProps) &\n RadarChartSpecificProps;\nexport type HeatmapChartProps = (QueryProps | DataProps) &\n HeatmapChartSpecificProps;\n\n// ============================================================================\n// Internal Types\n// ============================================================================\n\n/** Base normalized data shared by all chart types */\nexport interface NormalizedChartDataBase {\n xData: (string | number)[];\n xField: string;\n yFields: string[];\n chartType: \"timeseries\" | \"categorical\";\n}\n\n/** Normalized chart data for rendering (standard charts) */\nexport interface NormalizedChartData extends NormalizedChartDataBase {\n yDataMap: Record<string, (string | number)[]>;\n}\n\n/** Type guard to check if data is an Arrow Table */\nexport function isArrowTable(data: ChartData): data is Table {\n return (\n data !== null &&\n typeof data === \"object\" &&\n \"schema\" in data &&\n \"numRows\" in data &&\n typeof (data as Table).getChild === \"function\"\n );\n}\n\n/** Type guard to check if props are query-based */\nexport function isQueryProps(props: UnifiedChartProps): props is QueryProps {\n return (\n \"queryKey\" in props &&\n typeof props.queryKey === \"string\" &&\n props.queryKey.length > 0\n );\n}\n\n/** Type guard to check if props are data-based */\nexport function isDataProps(props: UnifiedChartProps): props is DataProps {\n return \"data\" in props && props.data != null;\n}\n"],"mappings":";;AA4NA,SAAgB,aAAa,MAAgC;AAC3D,QACE,SAAS,QACT,OAAO,SAAS,YAChB,YAAY,QACZ,aAAa,QACb,OAAQ,KAAe,aAAa;;;AAKxC,SAAgB,aAAa,OAA+C;AAC1E,QACE,cAAc,SACd,OAAO,MAAM,aAAa,YAC1B,MAAM,SAAS,SAAS;;;AAK5B,SAAgB,YAAY,OAA8C;AACxE,QAAO,UAAU,SAAS,MAAM,QAAQ"}
1
+ {"version":3,"file":"types.js","names":[],"sources":["../../../src/react/charts/types.ts"],"sourcesContent":["import type { Table } from \"apache-arrow\";\n\n// ============================================================================\n// Data Format Types\n// ============================================================================\n\n/** Supported data formats for analytics queries */\nexport type DataFormat = \"json\" | \"arrow\" | \"auto\";\n\n/** Chart orientation */\nexport type Orientation = \"vertical\" | \"horizontal\";\n\n/** Supported chart types */\nexport type ChartType =\n | \"bar\"\n | \"line\"\n | \"area\"\n | \"pie\"\n | \"donut\"\n | \"scatter\"\n | \"radar\"\n | \"heatmap\";\n\n/** Data that can be passed to unified charts */\nexport type ChartData = Table | Record<string, unknown>[];\n\n// ============================================================================\n// Base Props (shared by all charts)\n// ============================================================================\n\n/** Color palette types for different visualization needs */\nexport type ChartColorPalette = \"categorical\" | \"sequential\" | \"diverging\";\n\n/** Common visual and behavior props for all charts */\nexport interface ChartBaseProps {\n /** Chart title */\n title?: string;\n /** Show legend */\n showLegend?: boolean;\n /**\n * Color palette to use. Auto-selected based on chart type if not specified.\n * - \"categorical\": Distinct colors for different categories (bar, pie, line)\n * - \"sequential\": Gradient for magnitude/intensity (heatmap)\n * - \"diverging\": Two-tone for positive/negative values\n */\n colorPalette?: ChartColorPalette;\n /** Custom colors for series (overrides colorPalette) */\n colors?: string[];\n /** Chart height in pixels @default 300 */\n height?: number;\n /** Additional CSS classes */\n className?: string;\n\n /** X-axis field key. Auto-detected from schema if not provided. */\n xKey?: string;\n /** Y-axis field key(s). Auto-detected from schema if not provided. */\n yKey?: string | string[];\n\n /** Accessibility label for screen readers */\n ariaLabel?: string;\n /** Test ID for automated testing */\n testId?: string;\n\n /** Additional ECharts options to merge */\n options?: Record<string, unknown>;\n}\n\n// ============================================================================\n// Query-based Props (chart fetches data)\n// ============================================================================\n\n/** Props for query-based data fetching */\nexport interface QueryProps extends ChartBaseProps {\n /** Analytics query key registered with analytics plugin */\n queryKey: string;\n /** Query parameters passed to the analytics endpoint */\n parameters?: Record<string, unknown>;\n /**\n * Data format to use\n * - \"json\": Use JSON format (smaller payloads, simpler)\n * - \"arrow\": Use Arrow format (faster for large datasets)\n * - \"auto\": Automatically select based on expected data size\n * @default \"auto\"\n */\n format?: DataFormat;\n /** Transform raw data before rendering */\n transformer?: <T>(data: T) => T;\n /**\n * Whether to execute the query as the current user\n * @default false\n */\n asUser?: boolean;\n\n // Discriminator: cannot use direct data with query\n data?: never;\n}\n\n// ============================================================================\n// Data-based Props (chart receives data externally)\n// ============================================================================\n\n/** Props for direct data injection */\nexport interface DataProps extends ChartBaseProps {\n /** Arrow Table or JSON array */\n data: ChartData;\n\n // Discriminator: cannot use query props with direct data\n queryKey?: never;\n parameters?: never;\n format?: never;\n transformer?: never;\n}\n\n// ============================================================================\n// Union Types for Each Chart\n// ============================================================================\n\n/** Base union type - either query-based or data-based */\nexport type UnifiedChartProps = QueryProps | DataProps;\n\n// ============================================================================\n// Chart-Specific Props\n// ============================================================================\n\n/** Props specific to bar charts */\nexport interface BarChartSpecificProps {\n /** Chart orientation @default \"vertical\" */\n orientation?: Orientation;\n /** Stack bars */\n stacked?: boolean;\n}\n\n/** Props specific to line charts */\nexport interface LineChartSpecificProps {\n /** Chart orientation @default \"vertical\" */\n orientation?: Orientation;\n /** Show data point symbols @default false */\n showSymbol?: boolean;\n /** Smooth line curves @default true */\n smooth?: boolean;\n}\n\n/** Props specific to area charts */\nexport interface AreaChartSpecificProps {\n /** Chart orientation @default \"vertical\" */\n orientation?: Orientation;\n /** Show data point symbols @default false */\n showSymbol?: boolean;\n /** Smooth line curves @default true */\n smooth?: boolean;\n /** Stack areas @default false */\n stacked?: boolean;\n}\n\n/** Props specific to scatter charts */\nexport interface ScatterChartSpecificProps {\n /** Symbol size @default 8 */\n symbolSize?: number;\n}\n\n/** Props specific to pie/donut charts */\nexport interface PieChartSpecificProps {\n /** Inner radius for donut charts (0-100%) @default 0 */\n innerRadius?: number;\n /** Show labels on slices @default true */\n showLabels?: boolean;\n /** Label position @default \"outside\" */\n labelPosition?: \"outside\" | \"inside\" | \"center\";\n}\n\n/** Props specific to radar charts */\nexport interface RadarChartSpecificProps {\n /** Show area fill @default true */\n showArea?: boolean;\n}\n\n/** Props specific to heatmap charts */\nexport interface HeatmapChartSpecificProps {\n /**\n * Field key for the Y-axis categories.\n * For heatmaps, data should have: xKey (column), yAxisKey (row), and yKey (value).\n */\n yAxisKey?: string;\n /** Min value for color scale (auto-detected if not provided) */\n min?: number;\n /** Max value for color scale (auto-detected if not provided) */\n max?: number;\n /** Show value labels on cells @default false */\n showLabels?: boolean;\n}\n\n// ============================================================================\n// Complete Chart Props (union + specific)\n// ============================================================================\n\nexport type BarChartProps = (QueryProps | DataProps) & BarChartSpecificProps;\nexport type LineChartProps = (QueryProps | DataProps) & LineChartSpecificProps;\nexport type AreaChartProps = (QueryProps | DataProps) & AreaChartSpecificProps;\nexport type ScatterChartProps = (QueryProps | DataProps) &\n ScatterChartSpecificProps;\nexport type PieChartProps = (QueryProps | DataProps) & PieChartSpecificProps;\nexport type DonutChartProps = (QueryProps | DataProps) & PieChartSpecificProps;\nexport type RadarChartProps = (QueryProps | DataProps) &\n RadarChartSpecificProps;\nexport type HeatmapChartProps = (QueryProps | DataProps) &\n HeatmapChartSpecificProps;\n\n// ============================================================================\n// Internal Types\n// ============================================================================\n\n/** Base normalized data shared by all chart types */\nexport interface NormalizedChartDataBase {\n xData: (string | number)[];\n xField: string;\n yFields: string[];\n chartType: \"timeseries\" | \"categorical\";\n}\n\n/** Normalized chart data for rendering (standard charts) */\nexport interface NormalizedChartData extends NormalizedChartDataBase {\n yDataMap: Record<string, (string | number)[]>;\n}\n\n/** Type guard to check if data is an Arrow Table */\nexport function isArrowTable(data: ChartData): data is Table {\n return (\n data !== null &&\n typeof data === \"object\" &&\n \"schema\" in data &&\n \"numRows\" in data &&\n typeof (data as Table).getChild === \"function\"\n );\n}\n\n/** Type guard to check if props are query-based */\nexport function isQueryProps(props: UnifiedChartProps): props is QueryProps {\n return (\n \"queryKey\" in props &&\n typeof props.queryKey === \"string\" &&\n props.queryKey.length > 0\n );\n}\n\n/** Type guard to check if props are data-based */\nexport function isDataProps(props: UnifiedChartProps): props is DataProps {\n return \"data\" in props && props.data != null;\n}\n"],"mappings":";;AAiOA,SAAgB,aAAa,MAAgC;AAC3D,QACE,SAAS,QACT,OAAO,SAAS,YAChB,YAAY,QACZ,aAAa,QACb,OAAQ,KAAe,aAAa;;;AAKxC,SAAgB,aAAa,OAA+C;AAC1E,QACE,cAAc,SACd,OAAO,MAAM,aAAa,YAC1B,MAAM,SAAS,SAAS;;;AAK5B,SAAgB,YAAY,OAA8C;AACxE,QAAO,UAAU,SAAS,MAAM,QAAQ"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":["result: [string | number, string | number][]","sortedYDataMap: Record<string, (string | number)[]>"],"sources":["../../../src/react/charts/utils.ts"],"sourcesContent":["// ============================================================================\n// Chart Utility Functions\n// ============================================================================\n\n/**\n * Converts a value to a chart-compatible type.\n * Handles BigInt conversion (Arrow can return BigInt64Array values).\n * Handles Date objects by converting to timestamps.\n */\nexport function toChartValue(value: unknown): string | number {\n if (value === null || value === undefined) {\n return 0;\n }\n if (typeof value === \"bigint\") {\n return Number(value);\n }\n if (value instanceof Date) {\n return value.getTime();\n }\n if (typeof value === \"string\" || typeof value === \"number\") {\n return value;\n }\n return String(value);\n}\n\n/**\n * Converts an array of values to chart-compatible types.\n */\nexport function toChartArray(data: unknown[]): (string | number)[] {\n if (data.length === 0) return [];\n return data.map(toChartValue);\n}\n\n/**\n * Formats a field name into a human-readable label.\n * Handles camelCase, snake_case, acronyms, and ALL_CAPS.\n * E.g., \"totalSpend\" -> \"Total Spend\", \"user_name\" -> \"User Name\",\n * \"userID\" -> \"User Id\", \"TOTAL_SPEND\" -> \"Total Spend\"\n */\nexport function formatLabel(field: string): string {\n return (\n field\n // Handle consecutive uppercase followed by lowercase (e.g., HTTPUrl → HTTP Url)\n .replace(/([A-Z]+)([A-Z][a-z])/g, \"$1 $2\")\n // Handle lowercase followed by uppercase (e.g., totalSpend → total Spend)\n .replace(/([a-z])([A-Z])/g, \"$1 $2\")\n // Replace underscores with spaces\n .replace(/_/g, \" \")\n // Collapse multiple spaces into one\n .replace(/\\s+/g, \" \")\n // Normalize to title case\n .toLowerCase()\n .replace(/\\b\\w/g, (l) => l.toUpperCase())\n .trim()\n );\n}\n\n/**\n * Truncates a label to a maximum length with ellipsis.\n */\nexport function truncateLabel(value: string, maxLength = 15): string {\n return value.length > maxLength ? `${value.slice(0, maxLength)}...` : value;\n}\n\n/**\n * Creates time-series data pairs for ECharts.\n */\nexport function createTimeSeriesData(\n xData: (string | number)[],\n yData: (string | number)[],\n): [string | number, string | number][] {\n const len = xData.length;\n const result: [string | number, string | number][] = new Array(len);\n for (let i = 0; i < len; i++) {\n result[i] = [xData[i], yData[i]];\n }\n return result;\n}\n\n/**\n * Sorts time-series data in ascending chronological order.\n */\nexport function sortTimeSeriesAscending(\n xData: (string | number)[],\n yDataMap: Record<string, (string | number)[]>,\n yFields: string[],\n): {\n xData: (string | number)[];\n yDataMap: Record<string, (string | number)[]>;\n} {\n if (xData.length <= 1) {\n return { xData, yDataMap };\n }\n\n const first = xData[0];\n const last = xData[xData.length - 1];\n\n if (typeof first === \"number\" && typeof last === \"number\" && first > last) {\n const indices = xData.map((_, i) => i);\n indices.sort((a, b) => (xData[a] as number) - (xData[b] as number));\n\n const sortedXData = indices.map((i) => xData[i]);\n const sortedYDataMap: Record<string, (string | number)[]> = {};\n for (const key of yFields) {\n const original = yDataMap[key];\n sortedYDataMap[key] = indices.map((i) => original[i]);\n }\n\n return { xData: sortedXData, yDataMap: sortedYDataMap };\n }\n\n return { xData, yDataMap };\n}\n"],"mappings":";;;;;;AASA,SAAgB,aAAa,OAAiC;AAC5D,KAAI,UAAU,QAAQ,UAAU,OAC9B,QAAO;AAET,KAAI,OAAO,UAAU,SACnB,QAAO,OAAO,MAAM;AAEtB,KAAI,iBAAiB,KACnB,QAAO,MAAM,SAAS;AAExB,KAAI,OAAO,UAAU,YAAY,OAAO,UAAU,SAChD,QAAO;AAET,QAAO,OAAO,MAAM;;;;;AAMtB,SAAgB,aAAa,MAAsC;AACjE,KAAI,KAAK,WAAW,EAAG,QAAO,EAAE;AAChC,QAAO,KAAK,IAAI,aAAa;;;;;;;;AAS/B,SAAgB,YAAY,OAAuB;AACjD,QACE,MAEG,QAAQ,yBAAyB,QAAQ,CAEzC,QAAQ,mBAAmB,QAAQ,CAEnC,QAAQ,MAAM,IAAI,CAElB,QAAQ,QAAQ,IAAI,CAEpB,aAAa,CACb,QAAQ,UAAU,MAAM,EAAE,aAAa,CAAC,CACxC,MAAM;;;;;AAOb,SAAgB,cAAc,OAAe,YAAY,IAAY;AACnE,QAAO,MAAM,SAAS,YAAY,GAAG,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO;;;;;AAMxE,SAAgB,qBACd,OACA,OACsC;CACtC,MAAM,MAAM,MAAM;CAClB,MAAMA,SAA+C,IAAI,MAAM,IAAI;AACnE,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,IACvB,QAAO,KAAK,CAAC,MAAM,IAAI,MAAM,GAAG;AAElC,QAAO;;;;;AAMT,SAAgB,wBACd,OACA,UACA,SAIA;AACA,KAAI,MAAM,UAAU,EAClB,QAAO;EAAE;EAAO;EAAU;CAG5B,MAAM,QAAQ,MAAM;CACpB,MAAM,OAAO,MAAM,MAAM,SAAS;AAElC,KAAI,OAAO,UAAU,YAAY,OAAO,SAAS,YAAY,QAAQ,MAAM;EACzE,MAAM,UAAU,MAAM,KAAK,GAAG,MAAM,EAAE;AACtC,UAAQ,MAAM,GAAG,MAAO,MAAM,KAAiB,MAAM,GAAc;EAEnE,MAAM,cAAc,QAAQ,KAAK,MAAM,MAAM,GAAG;EAChD,MAAMC,iBAAsD,EAAE;AAC9D,OAAK,MAAM,OAAO,SAAS;GACzB,MAAM,WAAW,SAAS;AAC1B,kBAAe,OAAO,QAAQ,KAAK,MAAM,SAAS,GAAG;;AAGvD,SAAO;GAAE,OAAO;GAAa,UAAU;GAAgB;;AAGzD,QAAO;EAAE;EAAO;EAAU"}
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../../src/react/charts/utils.ts"],"sourcesContent":["// ============================================================================\n// Chart Utility Functions\n// ============================================================================\n\n/**\n * Converts a value to a chart-compatible type.\n * Handles BigInt conversion (Arrow can return BigInt64Array values).\n * Handles Date objects by converting to timestamps.\n */\nexport function toChartValue(value: unknown): string | number {\n if (value === null || value === undefined) {\n return 0;\n }\n if (typeof value === \"bigint\") {\n return Number(value);\n }\n if (value instanceof Date) {\n return value.getTime();\n }\n if (typeof value === \"string\" || typeof value === \"number\") {\n return value;\n }\n return String(value);\n}\n\n/**\n * Converts an array of values to chart-compatible types.\n */\nexport function toChartArray(data: unknown[]): (string | number)[] {\n if (data.length === 0) return [];\n return data.map(toChartValue);\n}\n\n/**\n * Formats a field name into a human-readable label.\n * Handles camelCase, snake_case, acronyms, and ALL_CAPS.\n * E.g., \"totalSpend\" -> \"Total Spend\", \"user_name\" -> \"User Name\",\n * \"userID\" -> \"User Id\", \"TOTAL_SPEND\" -> \"Total Spend\"\n */\nexport function formatLabel(field: string): string {\n return (\n field\n // Handle consecutive uppercase followed by lowercase (e.g., HTTPUrl → HTTP Url)\n .replace(/([A-Z]+)([A-Z][a-z])/g, \"$1 $2\")\n // Handle lowercase followed by uppercase (e.g., totalSpend → total Spend)\n .replace(/([a-z])([A-Z])/g, \"$1 $2\")\n // Replace underscores with spaces\n .replace(/_/g, \" \")\n // Collapse multiple spaces into one\n .replace(/\\s+/g, \" \")\n // Normalize to title case\n .toLowerCase()\n .replace(/\\b\\w/g, (l) => l.toUpperCase())\n .trim()\n );\n}\n\n/**\n * Truncates a label to a maximum length with ellipsis.\n */\nexport function truncateLabel(value: string, maxLength = 15): string {\n return value.length > maxLength ? `${value.slice(0, maxLength)}...` : value;\n}\n\n/**\n * Creates time-series data pairs for ECharts.\n */\nexport function createTimeSeriesData(\n xData: (string | number)[],\n yData: (string | number)[],\n): [string | number, string | number][] {\n const len = xData.length;\n const result: [string | number, string | number][] = new Array(len);\n for (let i = 0; i < len; i++) {\n result[i] = [xData[i], yData[i]];\n }\n return result;\n}\n\n/**\n * Sorts time-series data in ascending chronological order.\n */\nexport function sortTimeSeriesAscending(\n xData: (string | number)[],\n yDataMap: Record<string, (string | number)[]>,\n yFields: string[],\n): {\n xData: (string | number)[];\n yDataMap: Record<string, (string | number)[]>;\n} {\n if (xData.length <= 1) {\n return { xData, yDataMap };\n }\n\n const first = xData[0];\n const last = xData[xData.length - 1];\n\n if (typeof first === \"number\" && typeof last === \"number\" && first > last) {\n const indices = xData.map((_, i) => i);\n indices.sort((a, b) => (xData[a] as number) - (xData[b] as number));\n\n const sortedXData = indices.map((i) => xData[i]);\n const sortedYDataMap: Record<string, (string | number)[]> = {};\n for (const key of yFields) {\n const original = yDataMap[key];\n sortedYDataMap[key] = indices.map((i) => original[i]);\n }\n\n return { xData: sortedXData, yDataMap: sortedYDataMap };\n }\n\n return { xData, yDataMap };\n}\n"],"mappings":";;;;;;AASA,SAAgB,aAAa,OAAiC;AAC5D,KAAI,UAAU,QAAQ,UAAU,OAC9B,QAAO;AAET,KAAI,OAAO,UAAU,SACnB,QAAO,OAAO,MAAM;AAEtB,KAAI,iBAAiB,KACnB,QAAO,MAAM,SAAS;AAExB,KAAI,OAAO,UAAU,YAAY,OAAO,UAAU,SAChD,QAAO;AAET,QAAO,OAAO,MAAM;;;;;AAMtB,SAAgB,aAAa,MAAsC;AACjE,KAAI,KAAK,WAAW,EAAG,QAAO,EAAE;AAChC,QAAO,KAAK,IAAI,aAAa;;;;;;;;AAS/B,SAAgB,YAAY,OAAuB;AACjD,QACE,MAEG,QAAQ,yBAAyB,QAAQ,CAEzC,QAAQ,mBAAmB,QAAQ,CAEnC,QAAQ,MAAM,IAAI,CAElB,QAAQ,QAAQ,IAAI,CAEpB,aAAa,CACb,QAAQ,UAAU,MAAM,EAAE,aAAa,CAAC,CACxC,MAAM;;;;;AAOb,SAAgB,cAAc,OAAe,YAAY,IAAY;AACnE,QAAO,MAAM,SAAS,YAAY,GAAG,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO;;;;;AAMxE,SAAgB,qBACd,OACA,OACsC;CACtC,MAAM,MAAM,MAAM;CAClB,MAAM,SAA+C,IAAI,MAAM,IAAI;AACnE,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,IACvB,QAAO,KAAK,CAAC,MAAM,IAAI,MAAM,GAAG;AAElC,QAAO;;;;;AAMT,SAAgB,wBACd,OACA,UACA,SAIA;AACA,KAAI,MAAM,UAAU,EAClB,QAAO;EAAE;EAAO;EAAU;CAG5B,MAAM,QAAQ,MAAM;CACpB,MAAM,OAAO,MAAM,MAAM,SAAS;AAElC,KAAI,OAAO,UAAU,YAAY,OAAO,SAAS,YAAY,QAAQ,MAAM;EACzE,MAAM,UAAU,MAAM,KAAK,GAAG,MAAM,EAAE;AACtC,UAAQ,MAAM,GAAG,MAAO,MAAM,KAAiB,MAAM,GAAc;EAEnE,MAAM,cAAc,QAAQ,KAAK,MAAM,MAAM,GAAG;EAChD,MAAM,iBAAsD,EAAE;AAC9D,OAAK,MAAM,OAAO,SAAS;GACzB,MAAM,WAAW,SAAS;AAC1B,kBAAe,OAAO,QAAQ,KAAK,MAAM,SAAS,GAAG;;AAGvD,SAAO;GAAE,OAAO;GAAa,UAAU;GAAgB;;AAGzD,QAAO;EAAE;EAAO;EAAU"}
@@ -1,9 +1,11 @@
1
1
  import { ChartData, DataFormat } from "./types.js";
2
2
  import { ReactNode } from "react";
3
- import * as react_jsx_runtime283 from "react/jsx-runtime";
3
+ import * as react_jsx_runtime285 from "react/jsx-runtime";
4
4
 
5
5
  //#region src/react/charts/wrapper.d.ts
6
6
  interface ChartWrapperQueryProps {
7
+ /** Whether to execute the query as a user. Default is false. */
8
+ asUser?: boolean;
7
9
  /** Analytics query key */
8
10
  queryKey: string;
9
11
  /** Query parameters */
@@ -59,7 +61,7 @@ type ChartWrapperProps = CommonProps & (ChartWrapperQueryProps | ChartWrapperDat
59
61
  * </ChartWrapper>
60
62
  * ```
61
63
  */
62
- declare function ChartWrapper(props: ChartWrapperProps): react_jsx_runtime283.JSX.Element;
64
+ declare function ChartWrapper(props: ChartWrapperProps): react_jsx_runtime285.JSX.Element;
63
65
  //#endregion
64
66
  export { ChartWrapper, ChartWrapperProps };
65
67
  //# sourceMappingURL=wrapper.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wrapper.d.ts","names":[],"sources":["../../../src/react/charts/wrapper.tsx"],"sourcesContent":[],"mappings":";;;;;UAaU,sBAAA;;;EAAA;EAAsB,UAAA,CAAA,EAIjB,MAJiB,CAAA,MAAA,EAAA,OAAA,CAAA;;QAMrB,CAAA,EAAA,UAAA;;aAEqB,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,IAAA,EAAN,CAAM,EAAA,GAAA,CAAA;EAAC;EAKvB,IAAA,CAAA,EAAA,KAAA;AAEO;UAFP,qBAAA,CAUW;;MAUY,EAlBzB,SAkByB;EAAS;EAG9B,QAAA,CAAA,EAAA,KAAA;EAAiB,UAAA,CAAA,EAAA,KAAA;QAAG,CAAA,EAAA,KAAA;aAC7B,CAAA,EAAA,KAAA;;UAdO,WAAA,CAcuC;EA0GjC;EAAY,MAAA,CAAA,EAAA,MAAA;;WAAyB,CAAA,EAAA,MAAA;EAAA;;;;;mBA9GlC,cAAc;;KAGrB,iBAAA,GAAoB,eAC7B,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;iBA0GZ,YAAA,QAAoB,oBAAiB,oBAAA,CAAA,GAAA,CAAA"}
1
+ {"version":3,"file":"wrapper.d.ts","names":[],"sources":["../../../src/react/charts/wrapper.tsx"],"sourcesContent":[],"mappings":";;;;;UAaU,sBAAA;;;EAAA;EAAsB,QAAA,EAAA,MAAA;;YAQrB,CAAA,EAFI,MAEJ,CAAA,MAAA,EAAA,OAAA,CAAA;;QAEqB,CAAA,EAFrB,UAEqB;EAAC;EAKvB,WAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,IAAA,EALgB,CAKK,EAAA,GALC,CAKD;EAUrB;EAAW,IAAA,CAAA,EAAA,KAAA;;UAVX,qBAAA,CAoBuB;EAAS;EAG9B,IAAA,EArBJ,SAqBI;EAAiB;UAAG,CAAA,EAAA,KAAA;YAC7B,CAAA,EAAA,KAAA;QAAyB,CAAA,EAAA,KAAA;EAAqB,WAAA,CAAA,EAAA,KAAA;AA4GjD;UA1HU,WAAA,CA0HkB;;QAAyB,CAAA,EAAA,MAAA;EAAA;;;;;;;mBAhHlC,cAAc;;KAGrB,iBAAA,GAAoB,eAC7B,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;iBA4GZ,YAAA,QAAoB,oBAAiB,oBAAA,CAAA,GAAA,CAAA"}
@@ -7,12 +7,13 @@ import { LoadingSkeleton } from "./loading.js";
7
7
  import { jsx } from "react/jsx-runtime";
8
8
 
9
9
  //#region src/react/charts/wrapper.tsx
10
- function QueryModeContent({ queryKey, parameters, format, transformer, height, className, ariaLabel, testId, children }) {
10
+ function QueryModeContent({ queryKey, parameters, format, transformer, asUser, height, className, ariaLabel, testId, children }) {
11
11
  const { data, loading, error, isEmpty } = useChartData({
12
12
  queryKey,
13
13
  parameters,
14
14
  format,
15
- transformer
15
+ transformer,
16
+ asUser
16
17
  });
17
18
  if (loading) return /* @__PURE__ */ jsx(LoadingSkeleton, { height: height ?? 300 });
18
19
  if (error) return /* @__PURE__ */ jsx(ErrorState, { error });
@@ -80,6 +81,7 @@ function ChartWrapper(props) {
80
81
  parameters: props.parameters,
81
82
  format: props.format,
82
83
  transformer: props.transformer,
84
+ asUser: props.asUser,
83
85
  height,
84
86
  className,
85
87
  ariaLabel,
@@ -1 +1 @@
1
- {"version":3,"file":"wrapper.js","names":[],"sources":["../../../src/react/charts/wrapper.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { useChartData } from \"../hooks/use-chart-data\";\nimport { ChartErrorBoundary } from \"./chart-error-boundary\";\nimport { EmptyState } from \"./empty\";\nimport { ErrorState } from \"./error\";\nimport { LoadingSkeleton } from \"./loading\";\nimport type { ChartData, DataFormat } from \"./types\";\nimport { isArrowTable } from \"./types\";\n\n// ============================================================================\n// Props Types\n// ============================================================================\n\ninterface ChartWrapperQueryProps {\n /** Analytics query key */\n queryKey: string;\n /** Query parameters */\n parameters?: Record<string, unknown>;\n /** Data format preference */\n format?: DataFormat;\n /** Transform data after fetching */\n transformer?: <T>(data: T) => T;\n /** Direct data - not used in query mode */\n data?: never;\n}\n\ninterface ChartWrapperDataProps {\n /** Direct data (Arrow Table or JSON array) */\n data: ChartData;\n /** Not used in data mode */\n queryKey?: never;\n parameters?: never;\n format?: never;\n transformer?: never;\n}\n\ninterface CommonProps {\n /** Chart height in pixels */\n height?: number;\n /** Additional CSS classes */\n className?: string;\n /** Accessibility label */\n ariaLabel?: string;\n /** Test ID for automated testing */\n testId?: string;\n /** Render function receiving the chart data */\n children: (data: ChartData) => ReactNode;\n}\n\nexport type ChartWrapperProps = CommonProps &\n (ChartWrapperQueryProps | ChartWrapperDataProps);\n\n// ============================================================================\n// Query Mode Content\n// ============================================================================\n\nfunction QueryModeContent({\n queryKey,\n parameters,\n format,\n transformer,\n height,\n className,\n ariaLabel,\n testId,\n children,\n}: CommonProps & ChartWrapperQueryProps) {\n const { data, loading, error, isEmpty } = useChartData({\n queryKey,\n parameters,\n format,\n transformer,\n });\n\n if (loading) return <LoadingSkeleton height={height ?? 300} />;\n if (error) return <ErrorState error={error} />;\n if (isEmpty || !data) return <EmptyState />;\n\n return (\n <ChartErrorBoundary\n fallback={<ErrorState error=\"Failed to render chart\" />}\n >\n <div\n className={className}\n style={{ height }}\n aria-label={ariaLabel}\n data-testid={testId}\n role=\"img\"\n >\n {children(data)}\n </div>\n </ChartErrorBoundary>\n );\n}\n\n// ============================================================================\n// Data Mode Content\n// ============================================================================\n\nfunction DataModeContent({\n data,\n height,\n className,\n ariaLabel,\n testId,\n children,\n}: CommonProps & ChartWrapperDataProps) {\n const isEmpty = isArrowTable(data)\n ? data.numRows === 0\n : !Array.isArray(data) || data.length === 0;\n\n if (isEmpty) return <EmptyState />;\n\n return (\n <ChartErrorBoundary\n fallback={<ErrorState error=\"Failed to render chart\" />}\n >\n <div\n className={className}\n style={{ height }}\n aria-label={ariaLabel}\n data-testid={testId}\n role=\"img\"\n >\n {children(data)}\n </div>\n </ChartErrorBoundary>\n );\n}\n\n// ============================================================================\n// Main Wrapper Component\n// ============================================================================\n\n/**\n * Wrapper component for charts.\n * Handles data fetching (query mode) or direct data injection (data mode).\n *\n * @example Query mode - fetches data from analytics endpoint\n * ```tsx\n * <ChartWrapper\n * queryKey=\"spend_data\"\n * parameters={{ limit: 100 }}\n * format=\"auto\"\n * >\n * {(data) => <MyChart data={data} />}\n * </ChartWrapper>\n * ```\n *\n * @example Data mode - uses provided data directly\n * ```tsx\n * <ChartWrapper data={myArrowTable}>\n * {(data) => <MyChart data={data} />}\n * </ChartWrapper>\n * ```\n */\nexport function ChartWrapper(props: ChartWrapperProps) {\n const { height = 300, className, ariaLabel, testId, children } = props;\n\n // Data mode: use provided data directly\n if (\"data\" in props && props.data !== undefined) {\n return (\n <DataModeContent\n data={props.data}\n height={height}\n className={className}\n ariaLabel={ariaLabel}\n testId={testId}\n >\n {children}\n </DataModeContent>\n );\n }\n\n // Query mode: fetch data from analytics endpoint\n if (\"queryKey\" in props && props.queryKey !== undefined) {\n return (\n <QueryModeContent\n queryKey={props.queryKey}\n parameters={props.parameters}\n format={props.format}\n transformer={props.transformer}\n height={height}\n className={className}\n ariaLabel={ariaLabel}\n testId={testId}\n >\n {children}\n </QueryModeContent>\n );\n }\n\n // Should never reach here due to TypeScript, but safety fallback\n return <ErrorState error=\"Chart requires either 'queryKey' or 'data' prop\" />;\n}\n"],"mappings":";;;;;;;;;AAwDA,SAAS,iBAAiB,EACxB,UACA,YACA,QACA,aACA,QACA,WACA,WACA,QACA,YACuC;CACvC,MAAM,EAAE,MAAM,SAAS,OAAO,YAAY,aAAa;EACrD;EACA;EACA;EACA;EACD,CAAC;AAEF,KAAI,QAAS,QAAO,oBAAC,mBAAgB,QAAQ,UAAU,MAAO;AAC9D,KAAI,MAAO,QAAO,oBAAC,cAAkB,QAAS;AAC9C,KAAI,WAAW,CAAC,KAAM,QAAO,oBAAC,eAAa;AAE3C,QACE,oBAAC;EACC,UAAU,oBAAC,cAAW,OAAM,2BAA2B;YAEvD,oBAAC;GACY;GACX,OAAO,EAAE,QAAQ;GACjB,cAAY;GACZ,eAAa;GACb,MAAK;aAEJ,SAAS,KAAK;IACX;GACa;;AAQzB,SAAS,gBAAgB,EACvB,MACA,QACA,WACA,WACA,QACA,YACsC;AAKtC,KAJgB,aAAa,KAAK,GAC9B,KAAK,YAAY,IACjB,CAAC,MAAM,QAAQ,KAAK,IAAI,KAAK,WAAW,EAE/B,QAAO,oBAAC,eAAa;AAElC,QACE,oBAAC;EACC,UAAU,oBAAC,cAAW,OAAM,2BAA2B;YAEvD,oBAAC;GACY;GACX,OAAO,EAAE,QAAQ;GACjB,cAAY;GACZ,eAAa;GACb,MAAK;aAEJ,SAAS,KAAK;IACX;GACa;;;;;;;;;;;;;;;;;;;;;;;;AA8BzB,SAAgB,aAAa,OAA0B;CACrD,MAAM,EAAE,SAAS,KAAK,WAAW,WAAW,QAAQ,aAAa;AAGjE,KAAI,UAAU,SAAS,MAAM,SAAS,OACpC,QACE,oBAAC;EACC,MAAM,MAAM;EACJ;EACG;EACA;EACH;EAEP;GACe;AAKtB,KAAI,cAAc,SAAS,MAAM,aAAa,OAC5C,QACE,oBAAC;EACC,UAAU,MAAM;EAChB,YAAY,MAAM;EAClB,QAAQ,MAAM;EACd,aAAa,MAAM;EACX;EACG;EACA;EACH;EAEP;GACgB;AAKvB,QAAO,oBAAC,cAAW,OAAM,oDAAoD"}
1
+ {"version":3,"file":"wrapper.js","names":[],"sources":["../../../src/react/charts/wrapper.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { useChartData } from \"../hooks/use-chart-data\";\nimport { ChartErrorBoundary } from \"./chart-error-boundary\";\nimport { EmptyState } from \"./empty\";\nimport { ErrorState } from \"./error\";\nimport { LoadingSkeleton } from \"./loading\";\nimport type { ChartData, DataFormat } from \"./types\";\nimport { isArrowTable } from \"./types\";\n\n// ============================================================================\n// Props Types\n// ============================================================================\n\ninterface ChartWrapperQueryProps {\n /** Whether to execute the query as a user. Default is false. */\n asUser?: boolean;\n /** Analytics query key */\n queryKey: string;\n /** Query parameters */\n parameters?: Record<string, unknown>;\n /** Data format preference */\n format?: DataFormat;\n /** Transform data after fetching */\n transformer?: <T>(data: T) => T;\n /** Direct data - not used in query mode */\n data?: never;\n}\n\ninterface ChartWrapperDataProps {\n /** Direct data (Arrow Table or JSON array) */\n data: ChartData;\n /** Not used in data mode */\n queryKey?: never;\n parameters?: never;\n format?: never;\n transformer?: never;\n}\n\ninterface CommonProps {\n /** Chart height in pixels */\n height?: number;\n /** Additional CSS classes */\n className?: string;\n /** Accessibility label */\n ariaLabel?: string;\n /** Test ID for automated testing */\n testId?: string;\n /** Render function receiving the chart data */\n children: (data: ChartData) => ReactNode;\n}\n\nexport type ChartWrapperProps = CommonProps &\n (ChartWrapperQueryProps | ChartWrapperDataProps);\n\n// ============================================================================\n// Query Mode Content\n// ============================================================================\n\nfunction QueryModeContent({\n queryKey,\n parameters,\n format,\n transformer,\n asUser,\n height,\n className,\n ariaLabel,\n testId,\n children,\n}: CommonProps & ChartWrapperQueryProps) {\n const { data, loading, error, isEmpty } = useChartData({\n queryKey,\n parameters,\n format,\n transformer,\n asUser,\n });\n\n if (loading) return <LoadingSkeleton height={height ?? 300} />;\n if (error) return <ErrorState error={error} />;\n if (isEmpty || !data) return <EmptyState />;\n\n return (\n <ChartErrorBoundary\n fallback={<ErrorState error=\"Failed to render chart\" />}\n >\n <div\n className={className}\n style={{ height }}\n aria-label={ariaLabel}\n data-testid={testId}\n role=\"img\"\n >\n {children(data)}\n </div>\n </ChartErrorBoundary>\n );\n}\n\n// ============================================================================\n// Data Mode Content\n// ============================================================================\n\nfunction DataModeContent({\n data,\n height,\n className,\n ariaLabel,\n testId,\n children,\n}: CommonProps & ChartWrapperDataProps) {\n const isEmpty = isArrowTable(data)\n ? data.numRows === 0\n : !Array.isArray(data) || data.length === 0;\n\n if (isEmpty) return <EmptyState />;\n\n return (\n <ChartErrorBoundary\n fallback={<ErrorState error=\"Failed to render chart\" />}\n >\n <div\n className={className}\n style={{ height }}\n aria-label={ariaLabel}\n data-testid={testId}\n role=\"img\"\n >\n {children(data)}\n </div>\n </ChartErrorBoundary>\n );\n}\n\n// ============================================================================\n// Main Wrapper Component\n// ============================================================================\n\n/**\n * Wrapper component for charts.\n * Handles data fetching (query mode) or direct data injection (data mode).\n *\n * @example Query mode - fetches data from analytics endpoint\n * ```tsx\n * <ChartWrapper\n * queryKey=\"spend_data\"\n * parameters={{ limit: 100 }}\n * format=\"auto\"\n * >\n * {(data) => <MyChart data={data} />}\n * </ChartWrapper>\n * ```\n *\n * @example Data mode - uses provided data directly\n * ```tsx\n * <ChartWrapper data={myArrowTable}>\n * {(data) => <MyChart data={data} />}\n * </ChartWrapper>\n * ```\n */\nexport function ChartWrapper(props: ChartWrapperProps) {\n const { height = 300, className, ariaLabel, testId, children } = props;\n\n // Data mode: use provided data directly\n if (\"data\" in props && props.data !== undefined) {\n return (\n <DataModeContent\n data={props.data}\n height={height}\n className={className}\n ariaLabel={ariaLabel}\n testId={testId}\n >\n {children}\n </DataModeContent>\n );\n }\n\n // Query mode: fetch data from analytics endpoint\n if (\"queryKey\" in props && props.queryKey !== undefined) {\n return (\n <QueryModeContent\n queryKey={props.queryKey}\n parameters={props.parameters}\n format={props.format}\n transformer={props.transformer}\n asUser={props.asUser}\n height={height}\n className={className}\n ariaLabel={ariaLabel}\n testId={testId}\n >\n {children}\n </QueryModeContent>\n );\n }\n\n // Should never reach here due to TypeScript, but safety fallback\n return <ErrorState error=\"Chart requires either 'queryKey' or 'data' prop\" />;\n}\n"],"mappings":";;;;;;;;;AA0DA,SAAS,iBAAiB,EACxB,UACA,YACA,QACA,aACA,QACA,QACA,WACA,WACA,QACA,YACuC;CACvC,MAAM,EAAE,MAAM,SAAS,OAAO,YAAY,aAAa;EACrD;EACA;EACA;EACA;EACA;EACD,CAAC;AAEF,KAAI,QAAS,QAAO,oBAAC,mBAAgB,QAAQ,UAAU,MAAO;AAC9D,KAAI,MAAO,QAAO,oBAAC,cAAkB,QAAS;AAC9C,KAAI,WAAW,CAAC,KAAM,QAAO,oBAAC,eAAa;AAE3C,QACE,oBAAC;EACC,UAAU,oBAAC,cAAW,OAAM,2BAA2B;YAEvD,oBAAC;GACY;GACX,OAAO,EAAE,QAAQ;GACjB,cAAY;GACZ,eAAa;GACb,MAAK;aAEJ,SAAS,KAAK;IACX;GACa;;AAQzB,SAAS,gBAAgB,EACvB,MACA,QACA,WACA,WACA,QACA,YACsC;AAKtC,KAJgB,aAAa,KAAK,GAC9B,KAAK,YAAY,IACjB,CAAC,MAAM,QAAQ,KAAK,IAAI,KAAK,WAAW,EAE/B,QAAO,oBAAC,eAAa;AAElC,QACE,oBAAC;EACC,UAAU,oBAAC,cAAW,OAAM,2BAA2B;YAEvD,oBAAC;GACY;GACX,OAAO,EAAE,QAAQ;GACjB,cAAY;GACZ,eAAa;GACb,MAAK;aAEJ,SAAS,KAAK;IACX;GACa;;;;;;;;;;;;;;;;;;;;;;;;AA8BzB,SAAgB,aAAa,OAA0B;CACrD,MAAM,EAAE,SAAS,KAAK,WAAW,WAAW,QAAQ,aAAa;AAGjE,KAAI,UAAU,SAAS,MAAM,SAAS,OACpC,QACE,oBAAC;EACC,MAAM,MAAM;EACJ;EACG;EACA;EACH;EAEP;GACe;AAKtB,KAAI,cAAc,SAAS,MAAM,aAAa,OAC5C,QACE,oBAAC;EACC,UAAU,MAAM;EAChB,YAAY,MAAM;EAClB,QAAQ,MAAM;EACd,aAAa,MAAM;EACnB,QAAQ,MAAM;EACN;EACG;EACA;EACH;EAEP;GACgB;AAKvB,QAAO,oBAAC,cAAW,OAAM,oDAAoD"}
@@ -28,6 +28,8 @@ interface UseAnalyticsQueryOptions<F extends AnalyticsFormat = "JSON"> {
28
28
  maxParametersSize?: number;
29
29
  /** Whether to automatically start the query when the hook is mounted. Default is true. */
30
30
  autoStart?: boolean;
31
+ /** Whether to execute the query as a user. Default is false. */
32
+ asUser?: boolean;
31
33
  }
32
34
  /** Result state returned by useAnalyticsQuery */
33
35
  interface UseAnalyticsQueryResult<T> {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/react/hooks/types.ts"],"sourcesContent":[],"mappings":";;;;KAOY,eAAA;AAAZ;AAYA;;;;;;;AAeA;;AAAoD,UAfnC,eAemC,CAAA,aAdrC,MAcqC,CAAA,MAAA,EAAA,OAAA,CAAA,GAdX,MAcW,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA,SAb1C,KAa0C,CAAA;;;AAYpD;AA2BA;EASY,SAAA,SAAA,CAAA,EAxDW,IAwDM;;;AACK,UAjDjB,wBAiDiB,CAAA,UAjDkB,eAiDlB,GAAA,MAAA,CAAA,CAAA;;QAAgB,CAAA,EA/CvC,CA+CuC;;EAAG,iBAAA,CAAA,EAAA,MAAA;EAIzC;EAAQ,SAAA,CAAA,EAAA,OAAA;;;AAEE,UA3CL,uBA2CK,CAAA,CAAA,CAAA,CAAA;;EAAD,IAAA,EAzCb,CAyCa,GAAA,IAAA;EAMT;EAAW,OAAA,EAAA,OAAA;;OAAqC,EAAA,MAAA,GAAA,IAAA;;;;;;;;AAU5D;;;;;;;;;;;;AAKM,UArCW,aAAA,CAqCX;MACF,EAAA,MAAA,CAAA,EAAA;IAAM,IAAA,EAAA,MAAA;IAOE,UAAA,EA1CI,MA0Ce,CAAA,MAAA,EAAA,OAAA,CAAA;IAAA,MAAA,EAAA,OAAA,EAAA;;;;AAIS,KAxC5B,iBAwC4B,CAAA,CAAA,CAAA,GAAA,MAAA,QAAhB,MAvCV,CAuCU,IAAA,MAAA,SAvCU,CAuCV,GAAA,KAAA,GAvCsB,CAuCtB,GAvC0B,CAuC1B,CAvC4B,CAuC5B,CAAA;;AAAmC,KAnC/C,QAAA,GAAW,iBAmCoC,CAnClB,aAmCkB,CAAA,SAAA,KAAA,GAAA,MAAA,GAjCvD,iBAiCuD,CAjCrC,aAiCqC,CAAA;;AAK3D;;;AAAyD,KAhC7C,WAgC6C,CAAA,CAAA,EAAA,CAAA,CAAA,GAhCzB,CAgCyB,SAhCf,iBAgCe,CAhCG,aAgCH,CAAA,GA/BrD,aA+BqD,CA/BvC,CA+BuC,CAAA,SAAA;QAAlB,EAAA,KAAA,EAAA;IA9BjC,IACA,CA8BF,GA7BA,CA6BA;;;;;AAGM,KA1BE,YA0BF,CAAA,CAAA,CAAA,GA1BoB,CA0BpB,SA1B8B,iBA0B9B,CA1BgD,aA0BhD,CAAA,GAzBN,aAyBM,CAzBQ,CAyBR,CAAA,SAAA;EAEO,MAAA,EA3BsB,KA2BtB,CAAA,KAAc,EAAA,CAAA;IA1BzB,UAAU,0BACR,IACA,0BACF,0BACF;;;;;;KAOQ,oCAGA,mBACR,oBAAoB,gBAAgB,aAAa,MAAM,YAAY,GAAG;;;;KAK9D,iBAAiB,UAAU,kBAAkB,iBACrD,cAAc;;IACZ,IACA,0BACF;UAEa,cAAA;iBACA"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/react/hooks/types.ts"],"sourcesContent":[],"mappings":";;;;KAOY,eAAA;AAAZ;AAYA;;;;;;;AAeA;;AAAoD,UAfnC,eAemC,CAAA,aAdrC,MAcqC,CAAA,MAAA,EAAA,OAAA,CAAA,GAdX,MAcW,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA,SAb1C,KAa0C,CAAA;;;AAepD;AA2BA;EASY,SAAA,SAAA,CAAA,EA3DW,IA2DM;;;AACK,UApDjB,wBAoDiB,CAAA,UApDkB,eAoDlB,GAAA,MAAA,CAAA,CAAA;;QAAgB,CAAA,EAlDvC,CAkDuC;;EAAG,iBAAA,CAAA,EAAA,MAAA;EAIzC;EAAQ,SAAA,CAAA,EAAA,OAAA;;QAAG,CAAA,EAAA,OAAA;;;AAEF,UA3CJ,uBA2CI,CAAA,CAAA,CAAA,CAAA;EAMT;EAAW,IAAA,EA/Cf,CA+Ce,GAAA,IAAA;;SAAqC,EAAA,OAAA;;OACxD,EAAA,MAAA,GAAA,IAAA;;;;;;AASJ;;;;;;;;;;;;;;AAMU,UAtCO,aAAA,CAsCP;EAOE,CAAA,GAAA,EAAA,MAAA,CAAA,EAAA;IAAmB,IAAA,EAAA,MAAA;IAGnB,UAAA,EA7CI,MA6CJ,CAAA,MAAA,EAAA,OAAA,CAAA;IACR,MAAA,EAAA,OAAA,EAAA;;;;AAAmE,KAxC3D,iBAwC2D,CAAA,CAAA,CAAA,GAAA,MAAA,QAAG,MAvC5D,CAuC4D,IAAA,MAAA,SAvCxC,CAuCwC,GAAA,KAAA,GAvC5B,CAuC4B,GAvCxB,CAuCwB,CAvCtB,CAuCsB,CAAA;;AAK9D,KAxCA,QAAA,GAAW,iBAwCA,CAxCkB,aAwClB,CAAA,SAAA,KAAA,GAAA,MAAA,GAtCnB,iBAsCmB,CAtCD,aAsCC,CAAA;;;;;AACnB,KAjCQ,WAiCR,CAAA,CAAA,EAAA,CAAA,CAAA,GAjC4B,CAiC5B,SAjCsC,iBAiCtC,CAjCwD,aAiCxD,CAAA,GAhCA,aAgCA,CAhCc,CAgCd,CAAA,SAAA;QAAc,EAAA,KAAA,EAAA;IA/BZ,IACA,CA+BA,GA9BF,CA8BE;;;;AAIN;KA5BY,kBAAkB,UAAU,kBAAkB,iBACtD,cAAc;UAAqB;IACjC,UAAU,0BACR,IACA,0BACF,0BACF;;;;;;KAOQ,oCAGA,mBACR,oBAAoB,gBAAgB,aAAa,MAAM,YAAY,GAAG;;;;KAK9D,iBAAiB,UAAU,kBAAkB,iBACrD,cAAc;;IACZ,IACA,0BACF;UAEa,cAAA;iBACA"}
@@ -41,6 +41,9 @@ function useAnalyticsQuery(queryKey, parameters, options = {}) {
41
41
  const format = options?.format ?? "JSON";
42
42
  const maxParametersSize = options?.maxParametersSize ?? 100 * 1024;
43
43
  const autoStart = options?.autoStart ?? true;
44
+ const asUser = options?.asUser ?? false;
45
+ const devMode = getDevMode();
46
+ const urlSuffix = asUser ? `/api/analytics/users/me/query/${encodeURIComponent(queryKey)}${devMode}` : `/api/analytics/query/${encodeURIComponent(queryKey)}${devMode}`;
44
47
  const [data, setData] = useState(null);
45
48
  const [loading, setLoading] = useState(false);
46
49
  const [error, setError] = useState(null);
@@ -74,9 +77,8 @@ function useAnalyticsQuery(queryKey, parameters, options = {}) {
74
77
  setData(null);
75
78
  const abortController = new AbortController();
76
79
  abortControllerRef.current = abortController;
77
- const devMode = getDevMode();
78
80
  connectSSE({
79
- url: `/api/analytics/query/${encodeURIComponent(queryKey)}${devMode}`,
81
+ url: urlSuffix,
80
82
  payload,
81
83
  signal: abortController.signal,
82
84
  onMessage: async (message) => {
@@ -126,7 +128,11 @@ function useAnalyticsQuery(queryKey, parameters, options = {}) {
126
128
  setError(userMessage);
127
129
  }
128
130
  });
129
- }, [queryKey, payload]);
131
+ }, [
132
+ queryKey,
133
+ payload,
134
+ urlSuffix
135
+ ]);
130
136
  useEffect(() => {
131
137
  if (autoStart) start();
132
138
  return () => {
@@ -1 +1 @@
1
- {"version":3,"file":"use-analytics-query.js","names":["error"],"sources":["../../../src/react/hooks/use-analytics-query.ts"],"sourcesContent":["import { ArrowClient, connectSSE } from \"@/js\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type {\n AnalyticsFormat,\n InferParams,\n InferResultByFormat,\n QueryKey,\n UseAnalyticsQueryOptions,\n UseAnalyticsQueryResult,\n} from \"./types\";\nimport { useQueryHMR } from \"./use-query-hmr\";\n\nfunction getDevMode() {\n const url = new URL(window.location.href);\n const searchParams = url.searchParams;\n const dev = searchParams.get(\"dev\");\n\n return dev ? `?dev=${dev}` : \"\";\n}\n\nfunction getArrowStreamUrl(id: string) {\n return `/api/analytics/arrow-result/${id}`;\n}\n\n/**\n * Subscribe to an analytics query over SSE and returns its latest result.\n * Integration hook between client and analytics plugin.\n *\n * The return type is automatically inferred based on the format:\n * - `format: \"JSON\"` (default): Returns typed array from QueryRegistry\n * - `format: \"ARROW\"`: Returns TypedArrowTable with row type preserved\n *\n * @param queryKey - Analytics query identifier\n * @param parameters - Query parameters (type-safe based on QueryRegistry)\n * @param options - Analytics query settings including format\n * @returns Query result state with format-appropriate data type\n *\n * @example JSON format (default)\n * ```typescript\n * const { data } = useAnalyticsQuery(\"spend_data\", params);\n * // data: Array<{ group_key: string; cost_usd: number; ... }> | null\n * ```\n *\n * @example Arrow format\n * ```typescript\n * const { data } = useAnalyticsQuery(\"spend_data\", params, { format: \"ARROW\" });\n * // data: TypedArrowTable<{ group_key: string; cost_usd: number; ... }> | null\n * ```\n */\nexport function useAnalyticsQuery<\n T = unknown,\n K extends QueryKey = QueryKey,\n F extends AnalyticsFormat = \"JSON\",\n>(\n queryKey: K,\n parameters?: InferParams<K> | null,\n options: UseAnalyticsQueryOptions<F> = {} as UseAnalyticsQueryOptions<F>,\n): UseAnalyticsQueryResult<InferResultByFormat<T, K, F>> {\n const format = options?.format ?? \"JSON\";\n const maxParametersSize = options?.maxParametersSize ?? 100 * 1024;\n const autoStart = options?.autoStart ?? true;\n\n type ResultType = InferResultByFormat<T, K, F>;\n const [data, setData] = useState<ResultType | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const abortControllerRef = useRef<AbortController | null>(null);\n\n if (!queryKey || queryKey.trim().length === 0) {\n throw new Error(\n \"useAnalyticsQuery: 'queryKey' must be a non-empty string.\",\n );\n }\n\n const payload = useMemo(() => {\n try {\n const serialized = JSON.stringify({ parameters, format });\n const sizeInBytes = new Blob([serialized]).size;\n if (sizeInBytes > maxParametersSize) {\n throw new Error(\n \"useAnalyticsQuery: Parameters size exceeds the maximum allowed size\",\n );\n }\n\n return serialized;\n } catch (error) {\n console.error(\"useAnalyticsQuery: Failed to serialize parameters\", error);\n return null;\n }\n }, [parameters, format, maxParametersSize]);\n\n const start = useCallback(() => {\n if (payload === null) {\n setError(\"Failed to serialize query parameters\");\n return;\n }\n\n // Abort previous request if exists\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n\n setLoading(true);\n setError(null);\n setData(null);\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n const devMode = getDevMode();\n\n connectSSE({\n url: `/api/analytics/query/${encodeURIComponent(queryKey)}${devMode}`,\n payload: payload,\n signal: abortController.signal,\n onMessage: async (message) => {\n try {\n const parsed = JSON.parse(message.data);\n\n // success - JSON format\n if (parsed.type === \"result\") {\n setLoading(false);\n setData(parsed.data as ResultType);\n return;\n }\n\n // success - Arrow format\n if (parsed.type === \"arrow\") {\n try {\n const arrowData = await ArrowClient.fetchArrow(\n getArrowStreamUrl(parsed.statement_id),\n );\n const table = await ArrowClient.processArrowBuffer(arrowData);\n setLoading(false);\n // Table is cast to TypedArrowTable with row type from QueryRegistry\n setData(table as ResultType);\n return;\n } catch (error) {\n console.error(\n \"[useAnalyticsQuery] Failed to fetch Arrow data\",\n error,\n );\n setLoading(false);\n setError(\"Unable to load data, please try again\");\n return;\n }\n }\n\n // error\n if (parsed.type === \"error\" || parsed.error || parsed.code) {\n const errorMsg =\n parsed.error || parsed.message || \"Unable to execute query\";\n\n setLoading(false);\n setError(errorMsg);\n\n if (parsed.code) {\n console.error(\n `[useAnalyticsQuery] Code: ${parsed.code}, Message: ${errorMsg}`,\n );\n }\n return;\n }\n } catch (error) {\n console.warn(\"[useAnalyticsQuery] Malformed message received\", error);\n }\n },\n onError: (error) => {\n if (abortController.signal.aborted) return;\n setLoading(false);\n\n let userMessage = \"Unable to load data, please try again\";\n\n if (error instanceof Error) {\n if (error.name === \"AbortError\") {\n userMessage = \"Request timed out, please try again\";\n } else if (error.message.includes(\"Failed to fetch\")) {\n userMessage = \"Network error. Please check your connection.\";\n }\n\n console.error(\"[useAnalyticsQuery] Error\", {\n queryKey,\n error: error.message,\n stack: error.stack,\n });\n }\n setError(userMessage);\n },\n });\n }, [queryKey, payload]);\n\n useEffect(() => {\n if (autoStart) {\n start();\n }\n\n return () => {\n abortControllerRef.current?.abort();\n };\n }, [start, autoStart]);\n\n // Enable HMR for query updates in dev mode\n useQueryHMR(queryKey, start);\n\n return { data, loading, error };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-analytics-query.js","names":["error"],"sources":["../../../src/react/hooks/use-analytics-query.ts"],"sourcesContent":["import { ArrowClient, connectSSE } from \"@/js\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type {\n AnalyticsFormat,\n InferParams,\n InferResultByFormat,\n QueryKey,\n UseAnalyticsQueryOptions,\n UseAnalyticsQueryResult,\n} from \"./types\";\nimport { useQueryHMR } from \"./use-query-hmr\";\n\nfunction getDevMode() {\n const url = new URL(window.location.href);\n const searchParams = url.searchParams;\n const dev = searchParams.get(\"dev\");\n\n return dev ? `?dev=${dev}` : \"\";\n}\n\nfunction getArrowStreamUrl(id: string) {\n return `/api/analytics/arrow-result/${id}`;\n}\n\n/**\n * Subscribe to an analytics query over SSE and returns its latest result.\n * Integration hook between client and analytics plugin.\n *\n * The return type is automatically inferred based on the format:\n * - `format: \"JSON\"` (default): Returns typed array from QueryRegistry\n * - `format: \"ARROW\"`: Returns TypedArrowTable with row type preserved\n *\n * @param queryKey - Analytics query identifier\n * @param parameters - Query parameters (type-safe based on QueryRegistry)\n * @param options - Analytics query settings including format\n * @returns Query result state with format-appropriate data type\n *\n * @example JSON format (default)\n * ```typescript\n * const { data } = useAnalyticsQuery(\"spend_data\", params);\n * // data: Array<{ group_key: string; cost_usd: number; ... }> | null\n * ```\n *\n * @example Arrow format\n * ```typescript\n * const { data } = useAnalyticsQuery(\"spend_data\", params, { format: \"ARROW\" });\n * // data: TypedArrowTable<{ group_key: string; cost_usd: number; ... }> | null\n * ```\n */\nexport function useAnalyticsQuery<\n T = unknown,\n K extends QueryKey = QueryKey,\n F extends AnalyticsFormat = \"JSON\",\n>(\n queryKey: K,\n parameters?: InferParams<K> | null,\n options: UseAnalyticsQueryOptions<F> = {} as UseAnalyticsQueryOptions<F>,\n): UseAnalyticsQueryResult<InferResultByFormat<T, K, F>> {\n const format = options?.format ?? \"JSON\";\n const maxParametersSize = options?.maxParametersSize ?? 100 * 1024;\n const autoStart = options?.autoStart ?? true;\n const asUser = options?.asUser ?? false;\n\n const devMode = getDevMode();\n const urlSuffix = asUser\n ? `/api/analytics/users/me/query/${encodeURIComponent(queryKey)}${devMode}`\n : `/api/analytics/query/${encodeURIComponent(queryKey)}${devMode}`;\n\n type ResultType = InferResultByFormat<T, K, F>;\n const [data, setData] = useState<ResultType | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const abortControllerRef = useRef<AbortController | null>(null);\n\n if (!queryKey || queryKey.trim().length === 0) {\n throw new Error(\n \"useAnalyticsQuery: 'queryKey' must be a non-empty string.\",\n );\n }\n\n const payload = useMemo(() => {\n try {\n const serialized = JSON.stringify({ parameters, format });\n const sizeInBytes = new Blob([serialized]).size;\n if (sizeInBytes > maxParametersSize) {\n throw new Error(\n \"useAnalyticsQuery: Parameters size exceeds the maximum allowed size\",\n );\n }\n\n return serialized;\n } catch (error) {\n console.error(\"useAnalyticsQuery: Failed to serialize parameters\", error);\n return null;\n }\n }, [parameters, format, maxParametersSize]);\n\n const start = useCallback(() => {\n if (payload === null) {\n setError(\"Failed to serialize query parameters\");\n return;\n }\n\n // Abort previous request if exists\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n\n setLoading(true);\n setError(null);\n setData(null);\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n connectSSE({\n url: urlSuffix,\n payload: payload,\n signal: abortController.signal,\n onMessage: async (message) => {\n try {\n const parsed = JSON.parse(message.data);\n\n // success - JSON format\n if (parsed.type === \"result\") {\n setLoading(false);\n setData(parsed.data as ResultType);\n return;\n }\n\n // success - Arrow format\n if (parsed.type === \"arrow\") {\n try {\n const arrowData = await ArrowClient.fetchArrow(\n getArrowStreamUrl(parsed.statement_id),\n );\n const table = await ArrowClient.processArrowBuffer(arrowData);\n setLoading(false);\n // Table is cast to TypedArrowTable with row type from QueryRegistry\n setData(table as ResultType);\n return;\n } catch (error) {\n console.error(\n \"[useAnalyticsQuery] Failed to fetch Arrow data\",\n error,\n );\n setLoading(false);\n setError(\"Unable to load data, please try again\");\n return;\n }\n }\n\n // error\n if (parsed.type === \"error\" || parsed.error || parsed.code) {\n const errorMsg =\n parsed.error || parsed.message || \"Unable to execute query\";\n\n setLoading(false);\n setError(errorMsg);\n\n if (parsed.code) {\n console.error(\n `[useAnalyticsQuery] Code: ${parsed.code}, Message: ${errorMsg}`,\n );\n }\n return;\n }\n } catch (error) {\n console.warn(\"[useAnalyticsQuery] Malformed message received\", error);\n }\n },\n onError: (error) => {\n if (abortController.signal.aborted) return;\n setLoading(false);\n\n let userMessage = \"Unable to load data, please try again\";\n\n if (error instanceof Error) {\n if (error.name === \"AbortError\") {\n userMessage = \"Request timed out, please try again\";\n } else if (error.message.includes(\"Failed to fetch\")) {\n userMessage = \"Network error. Please check your connection.\";\n }\n\n console.error(\"[useAnalyticsQuery] Error\", {\n queryKey,\n error: error.message,\n stack: error.stack,\n });\n }\n setError(userMessage);\n },\n });\n }, [queryKey, payload, urlSuffix]);\n\n useEffect(() => {\n if (autoStart) {\n start();\n }\n\n return () => {\n abortControllerRef.current?.abort();\n };\n }, [start, autoStart]);\n\n // Enable HMR for query updates in dev mode\n useQueryHMR(queryKey, start);\n\n return { data, loading, error };\n}\n"],"mappings":"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"}
@@ -16,6 +16,8 @@ interface UseChartDataOptions {
16
16
  format?: DataFormat;
17
17
  /** Transform data after fetching */
18
18
  transformer?: <T>(data: T) => T;
19
+ /** Whether to execute the query as the current user. @default false */
20
+ asUser?: boolean;
19
21
  }
20
22
  interface UseChartDataResult {
21
23
  /** The fetched data (Arrow Table or JSON array) */
@@ -1 +1 @@
1
- {"version":3,"file":"use-chart-data.d.ts","names":[],"sources":["../../../src/react/hooks/use-chart-data.ts"],"sourcesContent":[],"mappings":";;;UAYiB,mBAAA;;EAAA,QAAA,EAAA,MAAA;EAAmB;YAIrB,CAAA,EAAA,MAAA,CAAA,MAAA,EAAA,OAAA,CAAA;;;;;AAaf;AA0EA;;QAAsC,CAAA,EA/E3B,UA+E2B;;EAAwC,WAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,IAAA,EA7EpD,CA6EoD,EAAA,GA7E9C,CA6E8C;;UA1E7D,kBAAA;;QAET;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAwEQ,YAAA,UAAsB,sBAAsB"}
1
+ {"version":3,"file":"use-chart-data.d.ts","names":[],"sources":["../../../src/react/hooks/use-chart-data.ts"],"sourcesContent":[],"mappings":";;;UAYiB,mBAAA;;EAAA,QAAA,EAAA,MAAA;EAAmB;YAIrB,CAAA,EAAA,MAAA,CAAA,MAAA,EAAA,OAAA,CAAA;;;;;AAef;AA0EA;;QAAsC,CAAA,EAjF3B,UAiF2B;;EAAwC,WAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,IAAA,EA/EpD,CA+EoD,EAAA,GA/E9C,CA+E8C;;;;UA1E7D,kBAAA;;QAET;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAwEQ,YAAA,UAAsB,sBAAsB"}