@sqlrooms/mosaic 0.29.0-rc.5 → 0.29.0-rc.6

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 (334) hide show
  1. package/README.md +43 -39
  2. package/dist/DataPointLimitError.d.ts +9 -0
  3. package/dist/DataPointLimitError.d.ts.map +1 -0
  4. package/dist/DataPointLimitError.js +14 -0
  5. package/dist/DataPointLimitError.js.map +1 -0
  6. package/dist/MosaicSlice.d.ts.map +1 -1
  7. package/dist/MosaicSlice.js +3 -3
  8. package/dist/MosaicSlice.js.map +1 -1
  9. package/dist/VgPlotChart.d.ts +8 -11
  10. package/dist/VgPlotChart.d.ts.map +1 -1
  11. package/dist/VgPlotChart.js +74 -90
  12. package/dist/VgPlotChart.js.map +1 -1
  13. package/dist/VgPlotChartError.d.ts +7 -0
  14. package/dist/VgPlotChartError.d.ts.map +1 -0
  15. package/dist/VgPlotChartError.js +9 -0
  16. package/dist/VgPlotChartError.js.map +1 -0
  17. package/dist/ai.d.ts +103 -0
  18. package/dist/ai.d.ts.map +1 -0
  19. package/dist/ai.js +445 -0
  20. package/dist/ai.js.map +1 -0
  21. package/dist/boxplot/BoxPlotClient.d.ts +7 -0
  22. package/dist/boxplot/BoxPlotClient.d.ts.map +1 -1
  23. package/dist/boxplot/BoxPlotClient.js +22 -0
  24. package/dist/boxplot/BoxPlotClient.js.map +1 -1
  25. package/dist/chart/ChartRuntimeIssuePanel.d.ts +7 -0
  26. package/dist/chart/ChartRuntimeIssuePanel.d.ts.map +1 -0
  27. package/dist/chart/ChartRuntimeIssuePanel.js +10 -0
  28. package/dist/chart/ChartRuntimeIssuePanel.js.map +1 -0
  29. package/dist/chart/MosaicDashboardChart.d.ts +1 -1
  30. package/dist/chart/MosaicDashboardChart.d.ts.map +1 -1
  31. package/dist/chart/MosaicDashboardChart.js +1 -1
  32. package/dist/chart/MosaicDashboardChart.js.map +1 -1
  33. package/dist/chart/MosaicDashboardChartContent.d.ts +1 -1
  34. package/dist/chart/MosaicDashboardChartContent.d.ts.map +1 -1
  35. package/dist/chart/MosaicDashboardChartContent.js +29 -2
  36. package/dist/chart/MosaicDashboardChartContent.js.map +1 -1
  37. package/dist/chart/MosaicDashboardChartRenderer.d.ts +2 -1
  38. package/dist/chart/MosaicDashboardChartRenderer.d.ts.map +1 -1
  39. package/dist/chart/MosaicDashboardChartRenderer.js +2 -2
  40. package/dist/chart/MosaicDashboardChartRenderer.js.map +1 -1
  41. package/dist/chart/MosaicDashboardComponentChart.d.ts +5 -1
  42. package/dist/chart/MosaicDashboardComponentChart.d.ts.map +1 -1
  43. package/dist/chart/MosaicDashboardComponentChart.js +4 -1
  44. package/dist/chart/MosaicDashboardComponentChart.js.map +1 -1
  45. package/dist/chart/MosaicDashboardVgPlotChart.d.ts +4 -0
  46. package/dist/chart/MosaicDashboardVgPlotChart.d.ts.map +1 -1
  47. package/dist/chart/MosaicDashboardVgPlotChart.js +2 -2
  48. package/dist/chart/MosaicDashboardVgPlotChart.js.map +1 -1
  49. package/dist/chart/addChartPanelAction.d.ts +3 -0
  50. package/dist/chart/addChartPanelAction.d.ts.map +1 -0
  51. package/dist/chart/addChartPanelAction.js +14 -0
  52. package/dist/chart/addChartPanelAction.js.map +1 -0
  53. package/dist/chart/chart-settings/ChartSettings.d.ts.map +1 -1
  54. package/dist/chart/chart-settings/ChartSettings.js +7 -4
  55. package/dist/chart/chart-settings/ChartSettings.js.map +1 -1
  56. package/dist/chart/chart-settings/ChartSettingsContent.d.ts +1 -1
  57. package/dist/chart/chart-settings/ChartSettingsContent.d.ts.map +1 -1
  58. package/dist/chart/chart-settings/ChartSettingsContent.js.map +1 -1
  59. package/dist/chart/chart-settings/ChartSettingsContext.d.ts +0 -2
  60. package/dist/chart/chart-settings/ChartSettingsContext.d.ts.map +1 -1
  61. package/dist/chart/chart-settings/ChartSettingsContext.js +6 -7
  62. package/dist/chart/chart-settings/ChartSettingsContext.js.map +1 -1
  63. package/dist/chart/chart-settings/ChartSettingsPanel.d.ts +1 -1
  64. package/dist/chart/chart-settings/ChartSettingsPanel.d.ts.map +1 -1
  65. package/dist/chart/chart-settings/ChartSettingsPanel.js +1 -1
  66. package/dist/chart/chart-settings/ChartSettingsPanel.js.map +1 -1
  67. package/dist/chart/chart-settings/ChartTypeSelector.d.ts.map +1 -1
  68. package/dist/chart/chart-settings/ChartTypeSelector.js +5 -5
  69. package/dist/chart/chart-settings/ChartTypeSelector.js.map +1 -1
  70. package/dist/chart-builders/ColumnSelector.d.ts +0 -2
  71. package/dist/chart-builders/ColumnSelector.d.ts.map +1 -1
  72. package/dist/chart-builders/ColumnSelector.js +4 -5
  73. package/dist/chart-builders/ColumnSelector.js.map +1 -1
  74. package/dist/chart-builders/ColumnsContext.d.ts +13 -0
  75. package/dist/chart-builders/ColumnsContext.d.ts.map +1 -0
  76. package/dist/chart-builders/ColumnsContext.js +15 -0
  77. package/dist/chart-builders/ColumnsContext.js.map +1 -0
  78. package/dist/chart-builders/MultiFieldSelector.js +4 -4
  79. package/dist/chart-builders/MultiFieldSelector.js.map +1 -1
  80. package/dist/chart-builders/TableSelector.d.ts +14 -0
  81. package/dist/chart-builders/TableSelector.d.ts.map +1 -0
  82. package/dist/chart-builders/TableSelector.js +23 -0
  83. package/dist/chart-builders/TableSelector.js.map +1 -0
  84. package/dist/chart-runtime.d.ts +50 -0
  85. package/dist/chart-runtime.d.ts.map +1 -0
  86. package/dist/chart-runtime.js +76 -0
  87. package/dist/chart-runtime.js.map +1 -0
  88. package/dist/chart-types/base-types.d.ts +45 -25
  89. package/dist/chart-types/base-types.d.ts.map +1 -1
  90. package/dist/chart-types/base-types.js.map +1 -1
  91. package/dist/chart-types/box-plot/definition.d.ts.map +1 -1
  92. package/dist/chart-types/box-plot/definition.js +5 -0
  93. package/dist/chart-types/box-plot/definition.js.map +1 -1
  94. package/dist/chart-types/box-plot/renderer/BoxPlotPanelRenderer.d.ts.map +1 -1
  95. package/dist/chart-types/box-plot/renderer/BoxPlotPanelRenderer.js +4 -1
  96. package/dist/chart-types/box-plot/renderer/BoxPlotPanelRenderer.js.map +1 -1
  97. package/dist/chart-types/box-plot/renderer/useBoxPlotClient.d.ts +4 -0
  98. package/dist/chart-types/box-plot/renderer/useBoxPlotClient.d.ts.map +1 -1
  99. package/dist/chart-types/box-plot/renderer/useBoxPlotClient.js +13 -2
  100. package/dist/chart-types/box-plot/renderer/useBoxPlotClient.js.map +1 -1
  101. package/dist/chart-types/box-plot/schema.d.ts +5 -0
  102. package/dist/chart-types/box-plot/schema.d.ts.map +1 -1
  103. package/dist/chart-types/box-plot/schema.js +2 -0
  104. package/dist/chart-types/box-plot/schema.js.map +1 -1
  105. package/dist/chart-types/box-plot/tool.d.ts +5 -9
  106. package/dist/chart-types/box-plot/tool.d.ts.map +1 -1
  107. package/dist/chart-types/box-plot/tool.js +14 -6
  108. package/dist/chart-types/box-plot/tool.js.map +1 -1
  109. package/dist/chart-types/bubble-chart/definition.d.ts.map +1 -1
  110. package/dist/chart-types/bubble-chart/definition.js +5 -0
  111. package/dist/chart-types/bubble-chart/definition.js.map +1 -1
  112. package/dist/chart-types/bubble-chart/schema.d.ts +5 -0
  113. package/dist/chart-types/bubble-chart/schema.d.ts.map +1 -1
  114. package/dist/chart-types/bubble-chart/schema.js +2 -0
  115. package/dist/chart-types/bubble-chart/schema.js.map +1 -1
  116. package/dist/chart-types/bubble-chart/tool.d.ts +5 -9
  117. package/dist/chart-types/bubble-chart/tool.d.ts.map +1 -1
  118. package/dist/chart-types/bubble-chart/tool.js +17 -9
  119. package/dist/chart-types/bubble-chart/tool.js.map +1 -1
  120. package/dist/chart-types/chart-config.d.ts +46 -0
  121. package/dist/chart-types/chart-config.d.ts.map +1 -1
  122. package/dist/chart-types/chart-config.js +2 -0
  123. package/dist/chart-types/chart-config.js.map +1 -1
  124. package/dist/chart-types/count-plot/schema.d.ts +5 -0
  125. package/dist/chart-types/count-plot/schema.d.ts.map +1 -1
  126. package/dist/chart-types/count-plot/schema.js +2 -0
  127. package/dist/chart-types/count-plot/schema.js.map +1 -1
  128. package/dist/chart-types/count-plot/tool.d.ts +5 -9
  129. package/dist/chart-types/count-plot/tool.d.ts.map +1 -1
  130. package/dist/chart-types/count-plot/tool.js +14 -6
  131. package/dist/chart-types/count-plot/tool.js.map +1 -1
  132. package/dist/chart-types/custom-spec/definition.d.ts.map +1 -1
  133. package/dist/chart-types/custom-spec/definition.js +5 -0
  134. package/dist/chart-types/custom-spec/definition.js.map +1 -1
  135. package/dist/chart-types/custom-spec/schema.d.ts +5 -0
  136. package/dist/chart-types/custom-spec/schema.d.ts.map +1 -1
  137. package/dist/chart-types/custom-spec/schema.js +2 -0
  138. package/dist/chart-types/custom-spec/schema.js.map +1 -1
  139. package/dist/chart-types/data-policy-schema.d.ts +8 -0
  140. package/dist/chart-types/data-policy-schema.d.ts.map +1 -0
  141. package/dist/chart-types/data-policy-schema.js +7 -0
  142. package/dist/chart-types/data-policy-schema.js.map +1 -0
  143. package/dist/chart-types/heatmap/schema.d.ts +5 -0
  144. package/dist/chart-types/heatmap/schema.d.ts.map +1 -1
  145. package/dist/chart-types/heatmap/schema.js +2 -0
  146. package/dist/chart-types/heatmap/schema.js.map +1 -1
  147. package/dist/chart-types/heatmap/tool.d.ts +5 -9
  148. package/dist/chart-types/heatmap/tool.d.ts.map +1 -1
  149. package/dist/chart-types/heatmap/tool.js +16 -8
  150. package/dist/chart-types/heatmap/tool.js.map +1 -1
  151. package/dist/chart-types/histogram/HistogramSettings.d.ts.map +1 -1
  152. package/dist/chart-types/histogram/HistogramSettings.js +4 -2
  153. package/dist/chart-types/histogram/HistogramSettings.js.map +1 -1
  154. package/dist/chart-types/histogram/schema.d.ts +10 -0
  155. package/dist/chart-types/histogram/schema.d.ts.map +1 -1
  156. package/dist/chart-types/histogram/schema.js +13 -0
  157. package/dist/chart-types/histogram/schema.js.map +1 -1
  158. package/dist/chart-types/histogram/spec.d.ts +1 -1
  159. package/dist/chart-types/histogram/spec.d.ts.map +1 -1
  160. package/dist/chart-types/histogram/spec.js +4 -3
  161. package/dist/chart-types/histogram/spec.js.map +1 -1
  162. package/dist/chart-types/histogram/tool.d.ts +7 -9
  163. package/dist/chart-types/histogram/tool.d.ts.map +1 -1
  164. package/dist/chart-types/histogram/tool.js +17 -7
  165. package/dist/chart-types/histogram/tool.js.map +1 -1
  166. package/dist/chart-types/index.d.ts +45 -3
  167. package/dist/chart-types/index.d.ts.map +1 -1
  168. package/dist/chart-types/index.js +8 -2
  169. package/dist/chart-types/index.js.map +1 -1
  170. package/dist/chart-types/line-chart/LineChartSettings.d.ts.map +1 -1
  171. package/dist/chart-types/line-chart/LineChartSettings.js +3 -1
  172. package/dist/chart-types/line-chart/LineChartSettings.js.map +1 -1
  173. package/dist/chart-types/line-chart/definition.d.ts.map +1 -1
  174. package/dist/chart-types/line-chart/definition.js +7 -0
  175. package/dist/chart-types/line-chart/definition.js.map +1 -1
  176. package/dist/chart-types/line-chart/schema.d.ts +5 -0
  177. package/dist/chart-types/line-chart/schema.d.ts.map +1 -1
  178. package/dist/chart-types/line-chart/schema.js +2 -0
  179. package/dist/chart-types/line-chart/schema.js.map +1 -1
  180. package/dist/chart-types/line-chart/tool.d.ts +5 -9
  181. package/dist/chart-types/line-chart/tool.d.ts.map +1 -1
  182. package/dist/chart-types/line-chart/tool.js +16 -8
  183. package/dist/chart-types/line-chart/tool.js.map +1 -1
  184. package/dist/chart-types/list-panels-tool.d.ts +35 -0
  185. package/dist/chart-types/list-panels-tool.d.ts.map +1 -0
  186. package/dist/chart-types/list-panels-tool.js +66 -0
  187. package/dist/chart-types/list-panels-tool.js.map +1 -0
  188. package/dist/chart-types/profiler-tool.d.ts +40 -0
  189. package/dist/chart-types/profiler-tool.d.ts.map +1 -0
  190. package/dist/chart-types/profiler-tool.js +73 -0
  191. package/dist/chart-types/profiler-tool.js.map +1 -0
  192. package/dist/chart-types/remove-panel-tool.d.ts +31 -0
  193. package/dist/chart-types/remove-panel-tool.d.ts.map +1 -0
  194. package/dist/chart-types/remove-panel-tool.js +55 -0
  195. package/dist/chart-types/remove-panel-tool.js.map +1 -0
  196. package/dist/chart-types/text-panel-tool.d.ts +42 -0
  197. package/dist/chart-types/text-panel-tool.d.ts.map +1 -0
  198. package/dist/chart-types/text-panel-tool.js +71 -0
  199. package/dist/chart-types/text-panel-tool.js.map +1 -0
  200. package/dist/chart-types/tool-helpers.d.ts +44 -0
  201. package/dist/chart-types/tool-helpers.d.ts.map +1 -0
  202. package/dist/chart-types/tool-helpers.js +129 -0
  203. package/dist/chart-types/tool-helpers.js.map +1 -0
  204. package/dist/chart-types/tool-schemas.d.ts +1 -0
  205. package/dist/chart-types/tool-schemas.d.ts.map +1 -1
  206. package/dist/chart-types/tool-schemas.js +5 -1
  207. package/dist/chart-types/tool-schemas.js.map +1 -1
  208. package/dist/dashboard/MosaicDashboard.d.ts +5 -2
  209. package/dist/dashboard/MosaicDashboard.d.ts.map +1 -1
  210. package/dist/dashboard/MosaicDashboard.js +20 -39
  211. package/dist/dashboard/MosaicDashboard.js.map +1 -1
  212. package/dist/dashboard/MosaicDashboardContext.d.ts +2 -0
  213. package/dist/dashboard/MosaicDashboardContext.d.ts.map +1 -1
  214. package/dist/dashboard/MosaicDashboardContext.js.map +1 -1
  215. package/dist/dashboard/MosaicDashboardEmptyState.d.ts.map +1 -1
  216. package/dist/dashboard/MosaicDashboardEmptyState.js +8 -44
  217. package/dist/dashboard/MosaicDashboardEmptyState.js.map +1 -1
  218. package/dist/dashboard/MosaicDashboardPanel.d.ts.map +1 -1
  219. package/dist/dashboard/MosaicDashboardPanel.js +2 -5
  220. package/dist/dashboard/MosaicDashboardPanel.js.map +1 -1
  221. package/dist/dashboard/MosaicDashboardPanelHeader.d.ts +2 -2
  222. package/dist/dashboard/MosaicDashboardPanelHeader.d.ts.map +1 -1
  223. package/dist/dashboard/MosaicDashboardPanelHeader.js +2 -2
  224. package/dist/dashboard/MosaicDashboardPanelHeader.js.map +1 -1
  225. package/dist/dashboard/MosaicDashboardPanels.d.ts.map +1 -1
  226. package/dist/dashboard/MosaicDashboardPanels.js +3 -2
  227. package/dist/dashboard/MosaicDashboardPanels.js.map +1 -1
  228. package/dist/dashboard/MosaicDashboardSlice.d.ts +185 -107
  229. package/dist/dashboard/MosaicDashboardSlice.d.ts.map +1 -1
  230. package/dist/dashboard/MosaicDashboardSlice.js +80 -57
  231. package/dist/dashboard/MosaicDashboardSlice.js.map +1 -1
  232. package/dist/dashboard/action-types.d.ts +25 -0
  233. package/dist/dashboard/action-types.d.ts.map +1 -0
  234. package/dist/dashboard/action-types.js +5 -0
  235. package/dist/dashboard/action-types.js.map +1 -0
  236. package/dist/dashboard/core-types.d.ts +26 -0
  237. package/dist/dashboard/core-types.d.ts.map +1 -0
  238. package/dist/dashboard/core-types.js +21 -0
  239. package/dist/dashboard/core-types.js.map +1 -0
  240. package/dist/dashboard/dashboard-types.d.ts +491 -0
  241. package/dist/dashboard/dashboard-types.d.ts.map +1 -0
  242. package/dist/dashboard/dashboard-types.js +54 -0
  243. package/dist/dashboard/dashboard-types.js.map +1 -0
  244. package/dist/dashboard/defaultPanelActions.d.ts +3 -0
  245. package/dist/dashboard/defaultPanelActions.d.ts.map +1 -0
  246. package/dist/dashboard/defaultPanelActions.js +9 -0
  247. package/dist/dashboard/defaultPanelActions.js.map +1 -0
  248. package/dist/dashboard/defaultPanelRenderers.d.ts.map +1 -1
  249. package/dist/dashboard/defaultPanelRenderers.js +1 -1
  250. package/dist/dashboard/defaultPanelRenderers.js.map +1 -1
  251. package/dist/dashboard/initial-state/BuildDashboardManuallyPanel.d.ts +6 -0
  252. package/dist/dashboard/initial-state/BuildDashboardManuallyPanel.d.ts.map +1 -0
  253. package/dist/dashboard/initial-state/BuildDashboardManuallyPanel.js +46 -0
  254. package/dist/dashboard/initial-state/BuildDashboardManuallyPanel.js.map +1 -0
  255. package/dist/dashboard/initial-state/BuildDashboardWithAIPanel.d.ts +7 -0
  256. package/dist/dashboard/initial-state/BuildDashboardWithAIPanel.d.ts.map +1 -0
  257. package/dist/dashboard/initial-state/BuildDashboardWithAIPanel.js +29 -0
  258. package/dist/dashboard/initial-state/BuildDashboardWithAIPanel.js.map +1 -0
  259. package/dist/dashboard/initial-state/MosaicDashboardInitialState.d.ts +6 -0
  260. package/dist/dashboard/initial-state/MosaicDashboardInitialState.d.ts.map +1 -0
  261. package/dist/dashboard/initial-state/MosaicDashboardInitialState.js +9 -0
  262. package/dist/dashboard/initial-state/MosaicDashboardInitialState.js.map +1 -0
  263. package/dist/dashboard/toolbar/MosaicDashboardAddPanelDropdown.d.ts +7 -0
  264. package/dist/dashboard/toolbar/MosaicDashboardAddPanelDropdown.d.ts.map +1 -0
  265. package/dist/dashboard/toolbar/MosaicDashboardAddPanelDropdown.js +12 -0
  266. package/dist/dashboard/toolbar/MosaicDashboardAddPanelDropdown.js.map +1 -0
  267. package/dist/dashboard/toolbar/MosaicDashboardResetFiltersButton.d.ts +7 -0
  268. package/dist/dashboard/toolbar/MosaicDashboardResetFiltersButton.d.ts.map +1 -0
  269. package/dist/dashboard/toolbar/MosaicDashboardResetFiltersButton.js +36 -0
  270. package/dist/dashboard/toolbar/MosaicDashboardResetFiltersButton.js.map +1 -0
  271. package/dist/dashboard/toolbar/MosaicDashboardToolbar.d.ts.map +1 -0
  272. package/dist/dashboard/toolbar/MosaicDashboardToolbar.js +15 -0
  273. package/dist/dashboard/toolbar/MosaicDashboardToolbar.js.map +1 -0
  274. package/dist/dashboard/useAddPanelActions.d.ts +10 -0
  275. package/dist/dashboard/useAddPanelActions.d.ts.map +1 -0
  276. package/dist/dashboard/useAddPanelActions.js +26 -0
  277. package/dist/dashboard/useAddPanelActions.js.map +1 -0
  278. package/dist/dashboard/useMosaicDashboardAddPanelActionContext.d.ts +3 -0
  279. package/dist/dashboard/useMosaicDashboardAddPanelActionContext.d.ts.map +1 -0
  280. package/dist/dashboard/useMosaicDashboardAddPanelActionContext.js +18 -0
  281. package/dist/dashboard/useMosaicDashboardAddPanelActionContext.js.map +1 -0
  282. package/dist/dashboard/useSelectedOrFirstTable.d.ts +10 -0
  283. package/dist/dashboard/useSelectedOrFirstTable.d.ts.map +1 -0
  284. package/dist/dashboard/useSelectedOrFirstTable.js +25 -0
  285. package/dist/dashboard/useSelectedOrFirstTable.js.map +1 -0
  286. package/dist/dashboard/useTablesWithColumns.d.ts +9 -0
  287. package/dist/dashboard/useTablesWithColumns.d.ts.map +1 -0
  288. package/dist/dashboard/useTablesWithColumns.js +13 -0
  289. package/dist/dashboard/useTablesWithColumns.js.map +1 -0
  290. package/dist/index.d.ts +25 -4
  291. package/dist/index.d.ts.map +1 -1
  292. package/dist/index.js +22 -2
  293. package/dist/index.js.map +1 -1
  294. package/dist/profiler/MosaicDashboardProfilerPanelRenderer.d.ts +2 -1
  295. package/dist/profiler/MosaicDashboardProfilerPanelRenderer.d.ts.map +1 -1
  296. package/dist/profiler/MosaicDashboardProfilerPanelRenderer.js +3 -3
  297. package/dist/profiler/MosaicDashboardProfilerPanelRenderer.js.map +1 -1
  298. package/dist/profiler/addProfilerPanelAction.d.ts +3 -0
  299. package/dist/profiler/addProfilerPanelAction.d.ts.map +1 -0
  300. package/dist/profiler/addProfilerPanelAction.js +9 -0
  301. package/dist/profiler/addProfilerPanelAction.js.map +1 -0
  302. package/dist/text/MosaicDashboardTextRenderer.d.ts +2 -1
  303. package/dist/text/MosaicDashboardTextRenderer.d.ts.map +1 -1
  304. package/dist/text/MosaicDashboardTextRenderer.js +4 -4
  305. package/dist/text/MosaicDashboardTextRenderer.js.map +1 -1
  306. package/dist/text/addTextPanelAction.d.ts +3 -0
  307. package/dist/text/addTextPanelAction.d.ts.map +1 -0
  308. package/dist/text/addTextPanelAction.js +9 -0
  309. package/dist/text/addTextPanelAction.js.map +1 -0
  310. package/dist/useMosaicClient.d.ts +4 -0
  311. package/dist/useMosaicClient.d.ts.map +1 -1
  312. package/dist/useMosaicClient.js +33 -3
  313. package/dist/useMosaicClient.js.map +1 -1
  314. package/dist/useVgPlotChartError.d.ts +13 -0
  315. package/dist/useVgPlotChartError.d.ts.map +1 -0
  316. package/dist/useVgPlotChartError.js +18 -0
  317. package/dist/useVgPlotChartError.js.map +1 -0
  318. package/dist/useVgPlotChartRender.d.ts +24 -0
  319. package/dist/useVgPlotChartRender.d.ts.map +1 -0
  320. package/dist/useVgPlotChartRender.js +152 -0
  321. package/dist/useVgPlotChartRender.js.map +1 -0
  322. package/dist/useVgPlotChartRetention.d.ts +21 -0
  323. package/dist/useVgPlotChartRetention.d.ts.map +1 -0
  324. package/dist/useVgPlotChartRetention.js +63 -0
  325. package/dist/useVgPlotChartRetention.js.map +1 -0
  326. package/dist/wrapCoordinatorWithValidation.d.ts +11 -0
  327. package/dist/wrapCoordinatorWithValidation.d.ts.map +1 -0
  328. package/dist/wrapCoordinatorWithValidation.js +23 -0
  329. package/dist/wrapCoordinatorWithValidation.js.map +1 -0
  330. package/package.json +31 -13
  331. package/dist/dashboard/MosaicDashboardToolbar.d.ts.map +0 -1
  332. package/dist/dashboard/MosaicDashboardToolbar.js +0 -86
  333. package/dist/dashboard/MosaicDashboardToolbar.js.map +0 -1
  334. /package/dist/dashboard/{MosaicDashboardToolbar.d.ts → toolbar/MosaicDashboardToolbar.d.ts} +0 -0
@@ -0,0 +1,152 @@
1
+ import { astToDOM, parseSpec } from '@uwdata/mosaic-spec';
2
+ import { useEffect, useRef } from 'react';
3
+ import { assertChartDataPolicy, createChartRuntimeIssueFromError, } from './chart-runtime';
4
+ function getPlotInstance(element) {
5
+ const plot = element.value;
6
+ return plot && typeof plot === 'object' ? plot : null;
7
+ }
8
+ function resizeChartElement(element, size) {
9
+ const plot = getPlotInstance(element);
10
+ if (!plot?.setAttribute || !plot.render) {
11
+ return false;
12
+ }
13
+ const widthChanged = plot.setAttribute('width', size.width);
14
+ const heightChanged = plot.setAttribute('height', size.height);
15
+ if (widthChanged || heightChanged) {
16
+ void plot.render();
17
+ }
18
+ return true;
19
+ }
20
+ async function createSpecChartElement(spec, size, params) {
21
+ const sizedSpec = {
22
+ ...spec,
23
+ width: size.width,
24
+ height: size.height,
25
+ };
26
+ const ast = await parseSpec(sizedSpec);
27
+ const options = params
28
+ ? { params: params }
29
+ : undefined;
30
+ return (await astToDOM(ast, options)).element;
31
+ }
32
+ function asPlotDomElement(element) {
33
+ return element;
34
+ }
35
+ function wrapMarkHandlers(chart, onError, dataPolicy, runtimeIssueContext, runtimeIssueReporter) {
36
+ const plot = getPlotInstance(chart.element);
37
+ if (!plot?.marks) {
38
+ return;
39
+ }
40
+ plot.marks.forEach((mark) => {
41
+ if (mark.queryResult) {
42
+ const originalQueryResult = mark.queryResult;
43
+ mark.queryResult = (data) => {
44
+ try {
45
+ assertChartDataPolicy(dataPolicy, data);
46
+ runtimeIssueReporter?.clearIssue();
47
+ return originalQueryResult.call(mark, data);
48
+ }
49
+ catch (error) {
50
+ const normalizedError = error instanceof Error ? error : new Error(String(error));
51
+ onError(normalizedError);
52
+ chart.error = normalizedError;
53
+ if (runtimeIssueContext) {
54
+ runtimeIssueReporter?.reportIssue(createChartRuntimeIssueFromError(normalizedError, runtimeIssueContext, dataPolicy));
55
+ }
56
+ if (mark.queryError) {
57
+ return mark.queryError(normalizedError);
58
+ }
59
+ return undefined;
60
+ }
61
+ };
62
+ }
63
+ if (mark.queryError) {
64
+ const originalQueryError = mark.queryError;
65
+ mark.queryError = (error) => {
66
+ const normalizedError = error instanceof Error ? error : new Error(String(error));
67
+ onError(normalizedError);
68
+ chart.error = normalizedError;
69
+ if (runtimeIssueContext) {
70
+ runtimeIssueReporter?.reportIssue(createChartRuntimeIssueFromError(normalizedError, runtimeIssueContext, dataPolicy));
71
+ }
72
+ originalQueryError.call(mark, error);
73
+ };
74
+ }
75
+ });
76
+ }
77
+ /**
78
+ * Hook to handle chart rendering lifecycle: creating, caching, and displaying vgplot charts.
79
+ */
80
+ export function useVgPlotChartRender({ containerRef, spec, specKey, params, containerSize, cachedChart, onChartCreated, onError, dataPolicy, runtimeIssueContext, runtimeIssueReporter, }) {
81
+ const renderVersionRef = useRef(0);
82
+ useEffect(() => {
83
+ const container = containerRef.current;
84
+ if (!container || !containerSize) {
85
+ return;
86
+ }
87
+ // Use cached chart if available
88
+ if (cachedChart) {
89
+ container.replaceChildren(asPlotDomElement(cachedChart.element));
90
+ resizeChartElement(cachedChart.element, containerSize);
91
+ // Re-wrap mark handlers with fresh closures for dataPolicy/runtimeIssue reporting
92
+ wrapMarkHandlers(cachedChart, onError, dataPolicy, runtimeIssueContext, runtimeIssueReporter);
93
+ // Restore error state from cached chart
94
+ if (cachedChart.error) {
95
+ onError(cachedChart.error);
96
+ }
97
+ return;
98
+ }
99
+ // Create new chart
100
+ const renderVersion = ++renderVersionRef.current;
101
+ let cancelled = false;
102
+ void createSpecChartElement(spec, containerSize, params)
103
+ .then((element) => {
104
+ if (cancelled ||
105
+ renderVersion !== renderVersionRef.current ||
106
+ !containerRef.current) {
107
+ return;
108
+ }
109
+ const nextChart = {
110
+ element,
111
+ params,
112
+ specKey: specKey ?? JSON.stringify(spec),
113
+ };
114
+ onChartCreated(nextChart);
115
+ containerRef.current.replaceChildren(element);
116
+ // Wrap marks with runtime handlers
117
+ wrapMarkHandlers(nextChart, onError, dataPolicy, runtimeIssueContext, runtimeIssueReporter);
118
+ })
119
+ .catch((error) => {
120
+ if (cancelled) {
121
+ return;
122
+ }
123
+ // Normalize error to Error instance
124
+ const normalizedError = error instanceof Error ? error : new Error(String(error));
125
+ onError(normalizedError);
126
+ if (runtimeIssueContext) {
127
+ runtimeIssueReporter?.reportIssue({
128
+ kind: 'render-error',
129
+ panelId: runtimeIssueContext.panelId,
130
+ chartType: runtimeIssueContext.chartType,
131
+ message: normalizedError.message,
132
+ recoverable: false,
133
+ });
134
+ }
135
+ console.error('[VgPlotChart] Error rendering chart:', normalizedError);
136
+ });
137
+ return () => {
138
+ cancelled = true;
139
+ };
140
+ // eslint-disable-next-line react-hooks/exhaustive-deps
141
+ }, [
142
+ containerSize,
143
+ specKey,
144
+ cachedChart,
145
+ onChartCreated,
146
+ onError,
147
+ dataPolicy,
148
+ runtimeIssueContext,
149
+ runtimeIssueReporter,
150
+ ]);
151
+ }
152
+ //# sourceMappingURL=useVgPlotChartRender.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useVgPlotChartRender.js","sourceRoot":"","sources":["../src/useVgPlotChartRender.ts"],"names":[],"mappings":"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","sourcesContent":["import {Param, Selection} from '@uwdata/mosaic-core';\nimport {astToDOM, parseSpec, Spec} from '@uwdata/mosaic-spec';\nimport {useEffect, useRef} from 'react';\nimport {PlotSize} from './ResponsivePlot';\nimport {RetainedVgPlotChart} from './useVgPlotChartRetention';\nimport {\n assertChartDataPolicy,\n createChartRuntimeIssueFromError,\n type ChartDataPolicy,\n type ChartRuntimeIssueContext,\n type ChartRuntimeIssueReporter,\n} from './chart-runtime';\n\ntype PlotDomElement = HTMLElement | SVGSVGElement;\n\ntype QueryableMark = {\n queryResult?: (data: unknown) => unknown;\n queryError?: (error: unknown) => unknown;\n};\n\ntype PlotInstance = {\n marks?: Array<{destroy?: () => void} & QueryableMark>;\n render?: () => Promise<unknown> | unknown;\n setAttribute?: (name: string, value: unknown) => boolean;\n};\n\nfunction getPlotInstance(element: object): PlotInstance | null {\n const plot = (element as HTMLElement & {value?: unknown}).value;\n return plot && typeof plot === 'object' ? (plot as PlotInstance) : null;\n}\n\nfunction resizeChartElement(element: object, size: PlotSize): boolean {\n const plot = getPlotInstance(element);\n if (!plot?.setAttribute || !plot.render) {\n return false;\n }\n\n const widthChanged = plot.setAttribute('width', size.width);\n const heightChanged = plot.setAttribute('height', size.height);\n if (widthChanged || heightChanged) {\n void plot.render();\n }\n return true;\n}\n\nasync function createSpecChartElement(\n spec: Spec,\n size: PlotSize,\n params?: Map<string, Param<any> | Selection>,\n): Promise<PlotDomElement> {\n const sizedSpec = {\n ...spec,\n width: size.width,\n height: size.height,\n } as Spec;\n\n const ast = await parseSpec(sizedSpec);\n const options = params\n ? {params: params as unknown as Map<string, Param<any>>}\n : undefined;\n\n return (await astToDOM(ast, options)).element;\n}\n\nfunction asPlotDomElement(element: object): PlotDomElement {\n return element as PlotDomElement;\n}\n\nfunction wrapMarkHandlers(\n chart: RetainedVgPlotChart,\n onError: (error: Error) => void,\n dataPolicy?: ChartDataPolicy | null,\n runtimeIssueContext?: ChartRuntimeIssueContext,\n runtimeIssueReporter?: ChartRuntimeIssueReporter,\n) {\n const plot = getPlotInstance(chart.element);\n if (!plot?.marks) {\n return;\n }\n\n plot.marks.forEach((mark: QueryableMark) => {\n if (mark.queryResult) {\n const originalQueryResult = mark.queryResult;\n mark.queryResult = (data: unknown) => {\n try {\n assertChartDataPolicy(dataPolicy, data);\n runtimeIssueReporter?.clearIssue();\n return originalQueryResult.call(mark, data);\n } catch (error) {\n const normalizedError =\n error instanceof Error ? error : new Error(String(error));\n onError(normalizedError);\n chart.error = normalizedError;\n if (runtimeIssueContext) {\n runtimeIssueReporter?.reportIssue(\n createChartRuntimeIssueFromError(\n normalizedError,\n runtimeIssueContext,\n dataPolicy,\n ),\n );\n }\n if (mark.queryError) {\n return mark.queryError(normalizedError);\n }\n return undefined;\n }\n };\n }\n if (mark.queryError) {\n const originalQueryError = mark.queryError;\n mark.queryError = (error: unknown) => {\n const normalizedError =\n error instanceof Error ? error : new Error(String(error));\n onError(normalizedError);\n chart.error = normalizedError;\n if (runtimeIssueContext) {\n runtimeIssueReporter?.reportIssue(\n createChartRuntimeIssueFromError(\n normalizedError,\n runtimeIssueContext,\n dataPolicy,\n ),\n );\n }\n originalQueryError.call(mark, error);\n };\n }\n });\n}\n\ntype UseVgPlotChartRenderParams = {\n containerRef: React.RefObject<HTMLDivElement | null>;\n spec: Spec;\n specKey: string | null;\n params?: Map<string, Param<any> | Selection>;\n containerSize: PlotSize | null;\n cachedChart: RetainedVgPlotChart | null;\n onChartCreated: (chart: RetainedVgPlotChart) => void;\n onError: (error: Error) => void;\n dataPolicy?: ChartDataPolicy | null;\n runtimeIssueContext?: ChartRuntimeIssueContext;\n runtimeIssueReporter?: ChartRuntimeIssueReporter;\n};\n\n/**\n * Hook to handle chart rendering lifecycle: creating, caching, and displaying vgplot charts.\n */\nexport function useVgPlotChartRender({\n containerRef,\n spec,\n specKey,\n params,\n containerSize,\n cachedChart,\n onChartCreated,\n onError,\n dataPolicy,\n runtimeIssueContext,\n runtimeIssueReporter,\n}: UseVgPlotChartRenderParams) {\n const renderVersionRef = useRef(0);\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container || !containerSize) {\n return;\n }\n\n // Use cached chart if available\n if (cachedChart) {\n container.replaceChildren(asPlotDomElement(cachedChart.element));\n resizeChartElement(cachedChart.element, containerSize);\n\n // Re-wrap mark handlers with fresh closures for dataPolicy/runtimeIssue reporting\n wrapMarkHandlers(\n cachedChart,\n onError,\n dataPolicy,\n runtimeIssueContext,\n runtimeIssueReporter,\n );\n\n // Restore error state from cached chart\n if (cachedChart.error) {\n onError(cachedChart.error);\n }\n\n return;\n }\n\n // Create new chart\n const renderVersion = ++renderVersionRef.current;\n let cancelled = false;\n\n void createSpecChartElement(spec, containerSize, params)\n .then((element) => {\n if (\n cancelled ||\n renderVersion !== renderVersionRef.current ||\n !containerRef.current\n ) {\n return;\n }\n\n const nextChart: RetainedVgPlotChart = {\n element,\n params,\n specKey: specKey ?? JSON.stringify(spec),\n };\n\n onChartCreated(nextChart);\n containerRef.current.replaceChildren(element);\n\n // Wrap marks with runtime handlers\n wrapMarkHandlers(\n nextChart,\n onError,\n dataPolicy,\n runtimeIssueContext,\n runtimeIssueReporter,\n );\n })\n .catch((error) => {\n if (cancelled) {\n return;\n }\n\n // Normalize error to Error instance\n const normalizedError =\n error instanceof Error ? error : new Error(String(error));\n onError(normalizedError);\n if (runtimeIssueContext) {\n runtimeIssueReporter?.reportIssue({\n kind: 'render-error',\n panelId: runtimeIssueContext.panelId,\n chartType: runtimeIssueContext.chartType,\n message: normalizedError.message,\n recoverable: false,\n });\n }\n console.error('[VgPlotChart] Error rendering chart:', normalizedError);\n });\n\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n containerSize,\n specKey,\n cachedChart,\n onChartCreated,\n onError,\n dataPolicy,\n runtimeIssueContext,\n runtimeIssueReporter,\n ]);\n}\n"]}
@@ -0,0 +1,21 @@
1
+ import { Param, Selection } from '@uwdata/mosaic-core';
2
+ export type RetainedVgPlotChart = {
3
+ element: object;
4
+ params?: Map<string, Param<any> | Selection>;
5
+ specKey: string;
6
+ error?: Error;
7
+ };
8
+ export type VgPlotChartRetention = {
9
+ chart?: RetainedVgPlotChart;
10
+ setChart: (chart: RetainedVgPlotChart) => void;
11
+ };
12
+ export declare function destroyRetainedVgPlotChart(chart: RetainedVgPlotChart): void;
13
+ /**
14
+ * Hook to manage chart retention (caching) across spec changes.
15
+ * Handles chart lifecycle: retrieval, storage, and cleanup.
16
+ */
17
+ export declare function useVgPlotChartRetention(specKey: string | null, params: Map<string, Param<any> | Selection> | undefined, externalRetention?: VgPlotChartRetention): {
18
+ getCachedChart: () => RetainedVgPlotChart | null;
19
+ setCachedChart: (chart: RetainedVgPlotChart) => void;
20
+ };
21
+ //# sourceMappingURL=useVgPlotChartRetention.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useVgPlotChartRetention.d.ts","sourceRoot":"","sources":["../src/useVgPlotChartRetention.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAE,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAGrD,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,CAAC,EAAE,mBAAmB,CAAC;IAC5B,QAAQ,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAC;CAChD,CAAC;AAaF,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,mBAAmB,QAKpE;AAoBD;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,GAAG,SAAS,EACvD,iBAAiB,CAAC,EAAE,oBAAoB;0BAaD,mBAAmB,GAAG,IAAI;4BA0BvD,mBAAmB;EAQ9B"}
@@ -0,0 +1,63 @@
1
+ import { useCallback, useEffect, useRef } from 'react';
2
+ function getPlotInstance(element) {
3
+ const plot = element.value;
4
+ return plot && typeof plot === 'object' ? plot : null;
5
+ }
6
+ export function destroyRetainedVgPlotChart(chart) {
7
+ const plot = getPlotInstance(chart.element);
8
+ plot?.marks?.forEach((mark) => {
9
+ mark.destroy?.();
10
+ });
11
+ }
12
+ function areEquivalentParams(left, right) {
13
+ if (left === right) {
14
+ return true;
15
+ }
16
+ if (!left || !right || left.size !== right.size) {
17
+ return false;
18
+ }
19
+ for (const [key, value] of left) {
20
+ if (right.get(key) !== value) {
21
+ return false;
22
+ }
23
+ }
24
+ return true;
25
+ }
26
+ /**
27
+ * Hook to manage chart retention (caching) across spec changes.
28
+ * Handles chart lifecycle: retrieval, storage, and cleanup.
29
+ */
30
+ export function useVgPlotChartRetention(specKey, params, externalRetention) {
31
+ const localChartRef = useRef(null);
32
+ // Clean up old chart when spec changes
33
+ useEffect(() => {
34
+ const local = localChartRef.current;
35
+ if (local && local.specKey !== specKey) {
36
+ destroyRetainedVgPlotChart(local);
37
+ localChartRef.current = null;
38
+ }
39
+ }, [specKey]);
40
+ const getCachedChart = useCallback(() => {
41
+ const cached = externalRetention?.chart;
42
+ const local = localChartRef.current;
43
+ // Try local cache first
44
+ if (local &&
45
+ local.specKey === specKey &&
46
+ areEquivalentParams(local.params, params)) {
47
+ return local;
48
+ }
49
+ // Try external cache
50
+ if (cached &&
51
+ cached.specKey === specKey &&
52
+ areEquivalentParams(cached.params, params)) {
53
+ return cached;
54
+ }
55
+ return null;
56
+ }, [specKey, params, externalRetention]);
57
+ const setCachedChart = useCallback((chart) => {
58
+ localChartRef.current = chart;
59
+ externalRetention?.setChart(chart);
60
+ }, [externalRetention]);
61
+ return { getCachedChart, setCachedChart };
62
+ }
63
+ //# sourceMappingURL=useVgPlotChartRetention.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useVgPlotChartRetention.js","sourceRoot":"","sources":["../src/useVgPlotChartRetention.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,WAAW,EAAE,SAAS,EAAE,MAAM,EAAC,MAAM,OAAO,CAAC;AAoBrD,SAAS,eAAe,CAAC,OAAe;IACtC,MAAM,IAAI,GAAI,OAA2C,CAAC,KAAK,CAAC;IAChE,OAAO,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAE,IAAqB,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,KAA0B;IACnE,MAAM,IAAI,GAAG,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC5C,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QAC5B,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;IACnB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,mBAAmB,CAC1B,IAA0C,EAC1C,KAA2C;IAE3C,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC;QAChD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;QAChC,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC;YAC7B,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CACrC,OAAsB,EACtB,MAAuD,EACvD,iBAAwC;IAExC,MAAM,aAAa,GAAG,MAAM,CAA6B,IAAI,CAAC,CAAC;IAE/D,uCAAuC;IACvC,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,CAAC;QACpC,IAAI,KAAK,IAAI,KAAK,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;YACvC,0BAA0B,CAAC,KAAK,CAAC,CAAC;YAClC,aAAa,CAAC,OAAO,GAAG,IAAI,CAAC;QAC/B,CAAC;IACH,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,MAAM,cAAc,GAAG,WAAW,CAAC,GAA+B,EAAE;QAClE,MAAM,MAAM,GAAG,iBAAiB,EAAE,KAAK,CAAC;QACxC,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,CAAC;QAEpC,wBAAwB;QACxB,IACE,KAAK;YACL,KAAK,CAAC,OAAO,KAAK,OAAO;YACzB,mBAAmB,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,EACzC,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,qBAAqB;QACrB,IACE,MAAM;YACN,MAAM,CAAC,OAAO,KAAK,OAAO;YAC1B,mBAAmB,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC1C,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAEzC,MAAM,cAAc,GAAG,WAAW,CAChC,CAAC,KAA0B,EAAE,EAAE;QAC7B,aAAa,CAAC,OAAO,GAAG,KAAK,CAAC;QAC9B,iBAAiB,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC,EACD,CAAC,iBAAiB,CAAC,CACpB,CAAC;IAEF,OAAO,EAAC,cAAc,EAAE,cAAc,EAAC,CAAC;AAC1C,CAAC","sourcesContent":["import {Param, Selection} from '@uwdata/mosaic-core';\nimport {useCallback, useEffect, useRef} from 'react';\n\nexport type RetainedVgPlotChart = {\n element: object;\n params?: Map<string, Param<any> | Selection>;\n specKey: string;\n error?: Error;\n};\n\nexport type VgPlotChartRetention = {\n chart?: RetainedVgPlotChart;\n setChart: (chart: RetainedVgPlotChart) => void;\n};\n\ntype PlotInstance = {\n marks?: Array<{destroy?: () => void}>;\n render?: () => Promise<unknown> | unknown;\n setAttribute?: (name: string, value: unknown) => boolean;\n};\n\nfunction getPlotInstance(element: object): PlotInstance | null {\n const plot = (element as HTMLElement & {value?: unknown}).value;\n return plot && typeof plot === 'object' ? (plot as PlotInstance) : null;\n}\n\nexport function destroyRetainedVgPlotChart(chart: RetainedVgPlotChart) {\n const plot = getPlotInstance(chart.element);\n plot?.marks?.forEach((mark) => {\n mark.destroy?.();\n });\n}\n\nfunction areEquivalentParams(\n left?: Map<string, Param<any> | Selection>,\n right?: Map<string, Param<any> | Selection>,\n) {\n if (left === right) {\n return true;\n }\n if (!left || !right || left.size !== right.size) {\n return false;\n }\n for (const [key, value] of left) {\n if (right.get(key) !== value) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Hook to manage chart retention (caching) across spec changes.\n * Handles chart lifecycle: retrieval, storage, and cleanup.\n */\nexport function useVgPlotChartRetention(\n specKey: string | null,\n params: Map<string, Param<any> | Selection> | undefined,\n externalRetention?: VgPlotChartRetention,\n) {\n const localChartRef = useRef<RetainedVgPlotChart | null>(null);\n\n // Clean up old chart when spec changes\n useEffect(() => {\n const local = localChartRef.current;\n if (local && local.specKey !== specKey) {\n destroyRetainedVgPlotChart(local);\n localChartRef.current = null;\n }\n }, [specKey]);\n\n const getCachedChart = useCallback((): RetainedVgPlotChart | null => {\n const cached = externalRetention?.chart;\n const local = localChartRef.current;\n\n // Try local cache first\n if (\n local &&\n local.specKey === specKey &&\n areEquivalentParams(local.params, params)\n ) {\n return local;\n }\n\n // Try external cache\n if (\n cached &&\n cached.specKey === specKey &&\n areEquivalentParams(cached.params, params)\n ) {\n return cached;\n }\n\n return null;\n }, [specKey, params, externalRetention]);\n\n const setCachedChart = useCallback(\n (chart: RetainedVgPlotChart) => {\n localChartRef.current = chart;\n externalRetention?.setChart(chart);\n },\n [externalRetention],\n );\n\n return {getCachedChart, setCachedChart};\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import { Coordinator } from '@uwdata/mosaic-core';
2
+ /**
3
+ * Wraps coordinator's query method to validate result sizes.
4
+ * This prevents rendering charts with too many data points.
5
+ *
6
+ * @deprecated Prefer chart-owned `ChartDataPolicy` validation in renderer
7
+ * query-result lifecycles. A coordinator-wide limit cannot distinguish raw
8
+ * point charts from aggregate charts.
9
+ */
10
+ export declare function wrapCoordinatorWithValidation(coordinator: Coordinator, maxDataPoints: number): void;
11
+ //# sourceMappingURL=wrapCoordinatorWithValidation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrapCoordinatorWithValidation.d.ts","sourceRoot":"","sources":["../src/wrapCoordinatorWithValidation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,qBAAqB,CAAC;AAIhD;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CAC3C,WAAW,EAAE,WAAW,EACxB,aAAa,EAAE,MAAM,GACpB,IAAI,CAcN"}
@@ -0,0 +1,23 @@
1
+ import { DataPointLimitError } from './DataPointLimitError';
2
+ import { getQueryResultRowCount } from './chart-runtime';
3
+ /**
4
+ * Wraps coordinator's query method to validate result sizes.
5
+ * This prevents rendering charts with too many data points.
6
+ *
7
+ * @deprecated Prefer chart-owned `ChartDataPolicy` validation in renderer
8
+ * query-result lifecycles. A coordinator-wide limit cannot distinguish raw
9
+ * point charts from aggregate charts.
10
+ */
11
+ export function wrapCoordinatorWithValidation(coordinator, maxDataPoints) {
12
+ const originalQuery = coordinator.query.bind(coordinator);
13
+ coordinator.query = async function (request, options) {
14
+ const result = await originalQuery(request, options);
15
+ // Validate all queries that return data
16
+ const rowCount = getQueryResultRowCount(result);
17
+ if (rowCount > maxDataPoints) {
18
+ throw new DataPointLimitError(rowCount, maxDataPoints);
19
+ }
20
+ return result;
21
+ };
22
+ }
23
+ //# sourceMappingURL=wrapCoordinatorWithValidation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrapCoordinatorWithValidation.js","sourceRoot":"","sources":["../src/wrapCoordinatorWithValidation.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,mBAAmB,EAAC,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAC,sBAAsB,EAAC,MAAM,iBAAiB,CAAC;AAEvD;;;;;;;GAOG;AACH,MAAM,UAAU,6BAA6B,CAC3C,WAAwB,EACxB,aAAqB;IAErB,MAAM,aAAa,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAEzD,WAAmB,CAAC,KAAK,GAAG,KAAK,WAAW,OAAY,EAAE,OAAa;QACtE,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAErD,wCAAwC;QACxC,MAAM,QAAQ,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;QAChD,IAAI,QAAQ,GAAG,aAAa,EAAE,CAAC;YAC7B,MAAM,IAAI,mBAAmB,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QACzD,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import {Coordinator} from '@uwdata/mosaic-core';\nimport {DataPointLimitError} from './DataPointLimitError';\nimport {getQueryResultRowCount} from './chart-runtime';\n\n/**\n * Wraps coordinator's query method to validate result sizes.\n * This prevents rendering charts with too many data points.\n *\n * @deprecated Prefer chart-owned `ChartDataPolicy` validation in renderer\n * query-result lifecycles. A coordinator-wide limit cannot distinguish raw\n * point charts from aggregate charts.\n */\nexport function wrapCoordinatorWithValidation(\n coordinator: Coordinator,\n maxDataPoints: number,\n): void {\n const originalQuery = coordinator.query.bind(coordinator);\n\n (coordinator as any).query = async function (request: any, options?: any) {\n const result = await originalQuery(request, options);\n\n // Validate all queries that return data\n const rowCount = getQueryResultRowCount(result);\n if (rowCount > maxDataPoints) {\n throw new DataPointLimitError(rowCount, maxDataPoints);\n }\n\n return result;\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sqlrooms/mosaic",
3
- "version": "0.29.0-rc.5",
3
+ "version": "0.29.0-rc.6",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/sqlrooms/sqlrooms.git"
@@ -9,6 +9,24 @@
9
9
  "author": "SQLRooms Contributors",
10
10
  "sideEffects": false,
11
11
  "type": "module",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js",
16
+ "default": "./dist/index.js"
17
+ },
18
+ "./ai": {
19
+ "types": "./dist/ai.d.ts",
20
+ "import": "./dist/ai.js",
21
+ "default": "./dist/ai.js"
22
+ },
23
+ "./dist/*": {
24
+ "types": "./dist/*.d.ts",
25
+ "import": "./dist/*.js",
26
+ "default": "./dist/*.js"
27
+ },
28
+ "./package.json": "./package.json"
29
+ },
12
30
  "main": "dist/index.js",
13
31
  "module": "dist/index.js",
14
32
  "types": "dist/index.d.ts",
@@ -26,17 +44,17 @@
26
44
  "dependencies": {
27
45
  "@observablehq/plot": "^0.6.17",
28
46
  "@paralleldrive/cuid2": "^3.0.0",
29
- "@sqlrooms/codemirror": "0.29.0-rc.5",
30
- "@sqlrooms/color-scales": "0.29.0-rc.5",
31
- "@sqlrooms/data-table": "0.29.0-rc.5",
32
- "@sqlrooms/db": "0.29.0-rc.5",
33
- "@sqlrooms/documents": "0.29.0-rc.5",
34
- "@sqlrooms/duckdb": "0.29.0-rc.5",
35
- "@sqlrooms/layout": "0.29.0-rc.5",
36
- "@sqlrooms/layout-config": "0.29.0-rc.5",
37
- "@sqlrooms/room-store": "0.29.0-rc.5",
38
- "@sqlrooms/ui": "0.29.0-rc.5",
39
- "@sqlrooms/utils": "0.29.0-rc.5",
47
+ "@sqlrooms/codemirror": "0.29.0-rc.6",
48
+ "@sqlrooms/color-scales": "0.29.0-rc.6",
49
+ "@sqlrooms/data-table": "0.29.0-rc.6",
50
+ "@sqlrooms/db": "0.29.0-rc.6",
51
+ "@sqlrooms/documents": "0.29.0-rc.6",
52
+ "@sqlrooms/duckdb": "0.29.0-rc.6",
53
+ "@sqlrooms/layout": "0.29.0-rc.6",
54
+ "@sqlrooms/layout-config": "0.29.0-rc.6",
55
+ "@sqlrooms/room-store": "0.29.0-rc.6",
56
+ "@sqlrooms/ui": "0.29.0-rc.6",
57
+ "@sqlrooms/utils": "0.29.0-rc.6",
40
58
  "@uwdata/flechette": "^2.2.6",
41
59
  "@uwdata/mosaic-core": "^0.21.0",
42
60
  "@uwdata/mosaic-plot": "^0.21.0",
@@ -67,5 +85,5 @@
67
85
  "publishConfig": {
68
86
  "access": "public"
69
87
  },
70
- "gitHead": "2763a4d37b79117916c988a8350f87dc926b33d5"
88
+ "gitHead": "fbf5ee8897c5c06306b5433d26378cf658b5b298"
71
89
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"MosaicDashboardToolbar.d.ts","sourceRoot":"","sources":["../../src/dashboard/MosaicDashboardToolbar.tsx"],"names":[],"mappings":"AAwBA,OAAO,KAAqC,MAAM,OAAO,CAAC;AAa1D,eAAO,MAAM,sBAAsB,EAAE,KAAK,CAAC,EA2N1C,CAAC"}
@@ -1,86 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Button, Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, Popover, PopoverContent, PopoverTrigger, } from '@sqlrooms/ui';
3
- import { BarChart3, Check, ChevronsUpDown, FileText, Plus, TableProperties, } from 'lucide-react';
4
- import { useEffect, useMemo, useState } from 'react';
5
- import { useMosaicDashboardContext } from './MosaicDashboardContext';
6
- import { createMosaicDashboardProfilerPanelConfig, createMosaicDashboardTextPanelConfig, getMosaicDashboardSelectionName, MOSAIC_DASHBOARD_PROFILER_PANEL_TYPE, MOSAIC_DASHBOARD_TEXT_PANEL_TYPE, useStoreWithMosaicDashboard, } from './MosaicDashboardSlice';
7
- export const MosaicDashboardToolbar = () => {
8
- const { dashboardId, canCreateChart, addDefaultChart } = useMosaicDashboardContext();
9
- const dashboard = useStoreWithMosaicDashboard((state) => state.mosaicDashboard.config.dashboardsById[dashboardId]);
10
- const setSelectedTable = useStoreWithMosaicDashboard((state) => state.mosaicDashboard.setSelectedTable);
11
- const addPanel = useStoreWithMosaicDashboard((state) => state.mosaicDashboard.addPanel);
12
- const panelRenderers = useStoreWithMosaicDashboard((state) => state.mosaicDashboard.panelRenderers);
13
- const addPanelActions = useStoreWithMosaicDashboard((state) => state.mosaicDashboard.addPanelActions);
14
- const getSelection = useStoreWithMosaicDashboard((state) => state.mosaic.getSelection);
15
- const dashboardSelectionName = getMosaicDashboardSelectionName(dashboardId);
16
- const dashboardSelection = useStoreWithMosaicDashboard((state) => state.mosaic.selections[dashboardSelectionName]);
17
- const tables = useStoreWithMosaicDashboard((state) => state.db.tables);
18
- const tablesWithColumns = useMemo(() => tables.filter((table) => table.columns && table.columns.length > 0), [tables]);
19
- const selectedTable = useMemo(() => tablesWithColumns.find((table) => table.tableName === dashboard?.selectedTable), [dashboard?.selectedTable, tablesWithColumns]);
20
- const [tablePickerOpen, setTablePickerOpen] = useState(false);
21
- const canAddProfiler = Boolean(dashboard?.selectedTable &&
22
- panelRenderers[MOSAIC_DASHBOARD_PROFILER_PANEL_TYPE]);
23
- const canAddText = Boolean(panelRenderers[MOSAIC_DASHBOARD_TEXT_PANEL_TYPE]);
24
- const addPanelActionContext = useMemo(() => ({
25
- dashboardId,
26
- dashboard,
27
- selectedTable,
28
- tables: tablesWithColumns,
29
- }), [dashboard, dashboardId, selectedTable, tablesWithColumns]);
30
- const addPanelActionEntries = useMemo(() => addPanelActions.map((action) => ({
31
- action,
32
- enabled: action.isEnabled
33
- ? action.isEnabled(addPanelActionContext)
34
- : true,
35
- })), [addPanelActionContext, addPanelActions]);
36
- const canAddCustomPanel = addPanelActionEntries.some((entry) => entry.enabled);
37
- const canAddAnyPanel = canCreateChart || canAddProfiler || canAddText || canAddCustomPanel;
38
- const [selectionVersion, setSelectionVersion] = useState(0);
39
- useEffect(() => {
40
- if (!dashboardSelection) {
41
- getSelection(dashboardSelectionName, 'crossfilter');
42
- }
43
- }, [dashboardSelection, dashboardSelectionName, getSelection]);
44
- useEffect(() => {
45
- if (!dashboardSelection) {
46
- return;
47
- }
48
- const handleSelectionChange = () => {
49
- setSelectionVersion((value) => value + 1);
50
- };
51
- dashboardSelection.addEventListener('value', handleSelectionChange);
52
- return () => {
53
- dashboardSelection.removeEventListener('value', handleSelectionChange);
54
- };
55
- }, [dashboardSelection]);
56
- const hasActiveFilters = useMemo(() => Boolean(dashboardSelection?.clauses.length), [dashboardSelection, selectionVersion]);
57
- const handleAddProfiler = () => {
58
- const panel = dashboard?.selectedTable
59
- ? createMosaicDashboardProfilerPanelConfig({
60
- source: { tableName: dashboard.selectedTable },
61
- })
62
- : createMosaicDashboardProfilerPanelConfig();
63
- addPanel(dashboardId, panel);
64
- };
65
- const handleAddText = () => {
66
- const panel = createMosaicDashboardTextPanelConfig();
67
- addPanel(dashboardId, panel);
68
- };
69
- const handleAddCustomPanel = (action) => {
70
- const panel = action.createPanel(addPanelActionContext);
71
- if (panel) {
72
- addPanel(dashboardId, panel);
73
- }
74
- };
75
- const handleResetFilters = () => {
76
- dashboardSelection?.reset();
77
- };
78
- return (_jsxs("div", { className: "flex items-center justify-between border-b px-5 py-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsxs(Popover, { open: tablePickerOpen, onOpenChange: setTablePickerOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline", size: "sm", role: "combobox", "aria-expanded": tablePickerOpen, className: "w-[200px] justify-between", children: [_jsx("span", { className: "truncate", children: dashboard?.selectedTable || 'Select table…' }), _jsx(ChevronsUpDown, { className: "ml-1 h-3.5 w-3.5 shrink-0 opacity-50" })] }) }), _jsx(PopoverContent, { className: "w-[220px] p-0", align: "start", children: _jsxs(Command, { children: [_jsx(CommandInput, { placeholder: "Search tables\u2026" }), _jsxs(CommandList, { children: [_jsx(CommandEmpty, { children: "No tables found." }), _jsx(CommandGroup, { children: tablesWithColumns.map((table) => (_jsxs(CommandItem, { value: table.tableName, onSelect: (value) => {
79
- setSelectedTable(dashboardId, value);
80
- setTablePickerOpen(false);
81
- }, children: [_jsx(Check, { className: `mr-2 h-3.5 w-3.5 ${dashboard?.selectedTable === table.tableName ? 'opacity-100' : 'opacity-0'}` }), table.tableName] }, table.tableName))) })] })] }) })] }), _jsx(Button, { variant: "link", size: "sm", className: "h-8 px-0", disabled: !hasActiveFilters, onClick: handleResetFilters, children: "Reset filters" })] }), _jsx("div", { className: "flex items-center gap-2", children: _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs(Button, { size: "sm", variant: "outline", disabled: !canAddAnyPanel, children: [_jsx(Plus, { className: "mr-1 h-4 w-4" }), "Add"] }) }), _jsxs(DropdownMenuContent, { align: "end", children: [_jsxs(DropdownMenuItem, { onClick: addDefaultChart, disabled: !canCreateChart, children: [_jsx(BarChart3, { className: "mr-2 h-4 w-4" }), "Chart"] }), _jsxs(DropdownMenuItem, { onClick: handleAddProfiler, disabled: !canAddProfiler, children: [_jsx(TableProperties, { className: "mr-2 h-4 w-4" }), "Profiler"] }), _jsxs(DropdownMenuItem, { onClick: handleAddText, disabled: !canAddText, children: [_jsx(FileText, { className: "mr-2 h-4 w-4" }), "Text"] }), addPanelActionEntries.map(({ action, enabled }) => {
82
- const Icon = action.icon;
83
- return (_jsxs(DropdownMenuItem, { onClick: () => handleAddCustomPanel(action), disabled: !enabled, children: [Icon ? _jsx(Icon, { className: "mr-2 h-4 w-4" }) : null, action.label] }, action.type));
84
- })] })] }) })] }));
85
- };
86
- //# sourceMappingURL=MosaicDashboardToolbar.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"MosaicDashboardToolbar.js","sourceRoot":"","sources":["../../src/dashboard/MosaicDashboardToolbar.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Button,\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@sqlrooms/ui';\nimport {\n BarChart3,\n Check,\n ChevronsUpDown,\n FileText,\n Plus,\n TableProperties,\n} from 'lucide-react';\nimport React, {useEffect, useMemo, useState} from 'react';\nimport {useMosaicDashboardContext} from './MosaicDashboardContext';\nimport {\n type MosaicDashboardAddPanelAction,\n type MosaicDashboardAddPanelActionContext,\n createMosaicDashboardProfilerPanelConfig,\n createMosaicDashboardTextPanelConfig,\n getMosaicDashboardSelectionName,\n MOSAIC_DASHBOARD_PROFILER_PANEL_TYPE,\n MOSAIC_DASHBOARD_TEXT_PANEL_TYPE,\n useStoreWithMosaicDashboard,\n} from './MosaicDashboardSlice';\n\nexport const MosaicDashboardToolbar: React.FC = () => {\n const {dashboardId, canCreateChart, addDefaultChart} =\n useMosaicDashboardContext();\n const dashboard = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.config.dashboardsById[dashboardId],\n );\n const setSelectedTable = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.setSelectedTable,\n );\n const addPanel = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.addPanel,\n );\n const panelRenderers = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.panelRenderers,\n );\n const addPanelActions = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.addPanelActions,\n );\n const getSelection = useStoreWithMosaicDashboard(\n (state) => state.mosaic.getSelection,\n );\n const dashboardSelectionName = getMosaicDashboardSelectionName(dashboardId);\n const dashboardSelection = useStoreWithMosaicDashboard(\n (state) => state.mosaic.selections[dashboardSelectionName],\n );\n const tables = useStoreWithMosaicDashboard((state) => state.db.tables);\n const tablesWithColumns = useMemo(\n () => tables.filter((table) => table.columns && table.columns.length > 0),\n [tables],\n );\n const selectedTable = useMemo(\n () =>\n tablesWithColumns.find(\n (table) => table.tableName === dashboard?.selectedTable,\n ),\n [dashboard?.selectedTable, tablesWithColumns],\n );\n const [tablePickerOpen, setTablePickerOpen] = useState(false);\n const canAddProfiler = Boolean(\n dashboard?.selectedTable &&\n panelRenderers[MOSAIC_DASHBOARD_PROFILER_PANEL_TYPE],\n );\n const canAddText = Boolean(panelRenderers[MOSAIC_DASHBOARD_TEXT_PANEL_TYPE]);\n const addPanelActionContext = useMemo<MosaicDashboardAddPanelActionContext>(\n () => ({\n dashboardId,\n dashboard,\n selectedTable,\n tables: tablesWithColumns,\n }),\n [dashboard, dashboardId, selectedTable, tablesWithColumns],\n );\n const addPanelActionEntries = useMemo(\n () =>\n addPanelActions.map((action) => ({\n action,\n enabled: action.isEnabled\n ? action.isEnabled(addPanelActionContext)\n : true,\n })),\n [addPanelActionContext, addPanelActions],\n );\n const canAddCustomPanel = addPanelActionEntries.some(\n (entry) => entry.enabled,\n );\n const canAddAnyPanel =\n canCreateChart || canAddProfiler || canAddText || canAddCustomPanel;\n const [selectionVersion, setSelectionVersion] = useState(0);\n\n useEffect(() => {\n if (!dashboardSelection) {\n getSelection(dashboardSelectionName, 'crossfilter');\n }\n }, [dashboardSelection, dashboardSelectionName, getSelection]);\n\n useEffect(() => {\n if (!dashboardSelection) {\n return;\n }\n\n const handleSelectionChange = () => {\n setSelectionVersion((value) => value + 1);\n };\n\n dashboardSelection.addEventListener('value', handleSelectionChange);\n return () => {\n dashboardSelection.removeEventListener('value', handleSelectionChange);\n };\n }, [dashboardSelection]);\n\n const hasActiveFilters = useMemo(\n () => Boolean(dashboardSelection?.clauses.length),\n [dashboardSelection, selectionVersion],\n );\n\n const handleAddProfiler = () => {\n const panel = dashboard?.selectedTable\n ? createMosaicDashboardProfilerPanelConfig({\n source: {tableName: dashboard.selectedTable},\n })\n : createMosaicDashboardProfilerPanelConfig();\n addPanel(dashboardId, panel);\n };\n\n const handleAddText = () => {\n const panel = createMosaicDashboardTextPanelConfig();\n addPanel(dashboardId, panel);\n };\n\n const handleAddCustomPanel = (action: MosaicDashboardAddPanelAction) => {\n const panel = action.createPanel(addPanelActionContext);\n if (panel) {\n addPanel(dashboardId, panel);\n }\n };\n\n const handleResetFilters = () => {\n dashboardSelection?.reset();\n };\n\n return (\n <div className=\"flex items-center justify-between border-b px-5 py-2\">\n <div className=\"flex items-center gap-2\">\n <Popover open={tablePickerOpen} onOpenChange={setTablePickerOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n size=\"sm\"\n role=\"combobox\"\n aria-expanded={tablePickerOpen}\n className=\"w-[200px] justify-between\"\n >\n <span className=\"truncate\">\n {dashboard?.selectedTable || 'Select table…'}\n </span>\n <ChevronsUpDown className=\"ml-1 h-3.5 w-3.5 shrink-0 opacity-50\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-[220px] p-0\" align=\"start\">\n <Command>\n <CommandInput placeholder=\"Search tables…\" />\n <CommandList>\n <CommandEmpty>No tables found.</CommandEmpty>\n <CommandGroup>\n {tablesWithColumns.map((table) => (\n <CommandItem\n key={table.tableName}\n value={table.tableName}\n onSelect={(value) => {\n setSelectedTable(dashboardId, value);\n setTablePickerOpen(false);\n }}\n >\n <Check\n className={`mr-2 h-3.5 w-3.5 ${dashboard?.selectedTable === table.tableName ? 'opacity-100' : 'opacity-0'}`}\n />\n {table.tableName}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n <Button\n variant=\"link\"\n size=\"sm\"\n className=\"h-8 px-0\"\n disabled={!hasActiveFilters}\n onClick={handleResetFilters}\n >\n Reset filters\n </Button>\n </div>\n <div className=\"flex items-center gap-2\">\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button size=\"sm\" variant=\"outline\" disabled={!canAddAnyPanel}>\n <Plus className=\"mr-1 h-4 w-4\" />\n Add\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem\n onClick={addDefaultChart}\n disabled={!canCreateChart}\n >\n <BarChart3 className=\"mr-2 h-4 w-4\" />\n Chart\n </DropdownMenuItem>\n <DropdownMenuItem\n onClick={handleAddProfiler}\n disabled={!canAddProfiler}\n >\n <TableProperties className=\"mr-2 h-4 w-4\" />\n Profiler\n </DropdownMenuItem>\n <DropdownMenuItem onClick={handleAddText} disabled={!canAddText}>\n <FileText className=\"mr-2 h-4 w-4\" />\n Text\n </DropdownMenuItem>\n {addPanelActionEntries.map(({action, enabled}) => {\n const Icon = action.icon;\n return (\n <DropdownMenuItem\n key={action.type}\n onClick={() => handleAddCustomPanel(action)}\n disabled={!enabled}\n >\n {Icon ? <Icon className=\"mr-2 h-4 w-4\" /> : null}\n {action.label}\n </DropdownMenuItem>\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </div>\n );\n};\n"]}