@sqlrooms/mosaic 0.29.0-rc.1 → 0.29.0-rc.3

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 (398) hide show
  1. package/README.md +161 -2
  2. package/dist/MosaicChart.d.ts +20 -0
  3. package/dist/MosaicChart.d.ts.map +1 -0
  4. package/dist/MosaicChart.js +25 -0
  5. package/dist/MosaicChart.js.map +1 -0
  6. package/dist/MosaicChartBuilder.d.ts +67 -0
  7. package/dist/MosaicChartBuilder.d.ts.map +1 -0
  8. package/dist/MosaicChartBuilder.js +33 -0
  9. package/dist/MosaicChartBuilder.js.map +1 -0
  10. package/dist/MosaicColorLegend.d.ts +18 -0
  11. package/dist/MosaicColorLegend.d.ts.map +1 -0
  12. package/dist/MosaicColorLegend.js +117 -0
  13. package/dist/MosaicColorLegend.js.map +1 -0
  14. package/dist/MosaicSlice.d.ts +27 -13
  15. package/dist/MosaicSlice.d.ts.map +1 -1
  16. package/dist/MosaicSlice.js +140 -42
  17. package/dist/MosaicSlice.js.map +1 -1
  18. package/dist/ResponsivePlot.d.ts +23 -0
  19. package/dist/ResponsivePlot.d.ts.map +1 -0
  20. package/dist/ResponsivePlot.js +43 -0
  21. package/dist/ResponsivePlot.js.map +1 -0
  22. package/dist/VgPlotChart.d.ts +24 -0
  23. package/dist/VgPlotChart.d.ts.map +1 -1
  24. package/dist/VgPlotChart.js +127 -21
  25. package/dist/VgPlotChart.js.map +1 -1
  26. package/dist/chart-builders/ChartBuilderActions.d.ts +6 -0
  27. package/dist/chart-builders/ChartBuilderActions.d.ts.map +1 -0
  28. package/dist/chart-builders/ChartBuilderActions.js +28 -0
  29. package/dist/chart-builders/ChartBuilderActions.js.map +1 -0
  30. package/dist/chart-builders/ChartBuilderContent.d.ts +28 -0
  31. package/dist/chart-builders/ChartBuilderContent.d.ts.map +1 -0
  32. package/dist/chart-builders/ChartBuilderContent.js +28 -0
  33. package/dist/chart-builders/ChartBuilderContent.js.map +1 -0
  34. package/dist/chart-builders/ChartBuilderContext.d.ts +16 -0
  35. package/dist/chart-builders/ChartBuilderContext.d.ts.map +1 -0
  36. package/dist/chart-builders/ChartBuilderContext.js +15 -0
  37. package/dist/chart-builders/ChartBuilderContext.js.map +1 -0
  38. package/dist/chart-builders/ChartBuilderDialog.d.ts +48 -0
  39. package/dist/chart-builders/ChartBuilderDialog.d.ts.map +1 -0
  40. package/dist/chart-builders/ChartBuilderDialog.js +30 -0
  41. package/dist/chart-builders/ChartBuilderDialog.js.map +1 -0
  42. package/dist/chart-builders/ChartBuilderFields.d.ts +6 -0
  43. package/dist/chart-builders/ChartBuilderFields.d.ts.map +1 -0
  44. package/dist/chart-builders/ChartBuilderFields.js +25 -0
  45. package/dist/chart-builders/ChartBuilderFields.js.map +1 -0
  46. package/dist/chart-builders/ChartBuilderRoot.d.ts +27 -0
  47. package/dist/chart-builders/ChartBuilderRoot.d.ts.map +1 -0
  48. package/dist/chart-builders/ChartBuilderRoot.js +61 -0
  49. package/dist/chart-builders/ChartBuilderRoot.js.map +1 -0
  50. package/dist/chart-builders/ChartBuilderTypeGrid.d.ts +7 -0
  51. package/dist/chart-builders/ChartBuilderTypeGrid.d.ts.map +1 -0
  52. package/dist/chart-builders/ChartBuilderTypeGrid.js +23 -0
  53. package/dist/chart-builders/ChartBuilderTypeGrid.js.map +1 -0
  54. package/dist/chart-builders/FieldSelectorInput.d.ts +13 -0
  55. package/dist/chart-builders/FieldSelectorInput.d.ts.map +1 -0
  56. package/dist/chart-builders/FieldSelectorInput.js +19 -0
  57. package/dist/chart-builders/FieldSelectorInput.js.map +1 -0
  58. package/dist/chart-builders/builders.d.ts +34 -0
  59. package/dist/chart-builders/builders.d.ts.map +1 -0
  60. package/dist/chart-builders/builders.js +51 -0
  61. package/dist/chart-builders/builders.js.map +1 -0
  62. package/dist/chart-builders/chartSpecTitle.d.ts +6 -0
  63. package/dist/chart-builders/chartSpecTitle.d.ts.map +1 -0
  64. package/dist/chart-builders/chartSpecTitle.js +8 -0
  65. package/dist/chart-builders/chartSpecTitle.js.map +1 -0
  66. package/dist/chart-builders/chartTypeUtils.d.ts +17 -0
  67. package/dist/chart-builders/chartTypeUtils.d.ts.map +1 -0
  68. package/dist/chart-builders/chartTypeUtils.js +55 -0
  69. package/dist/chart-builders/chartTypeUtils.js.map +1 -0
  70. package/dist/chart-builders/constants.d.ts +7 -0
  71. package/dist/chart-builders/constants.d.ts.map +1 -0
  72. package/dist/chart-builders/constants.js +34 -0
  73. package/dist/chart-builders/constants.js.map +1 -0
  74. package/dist/chart-builders/createChartBuilderStore.d.ts +11 -0
  75. package/dist/chart-builders/createChartBuilderStore.d.ts.map +1 -0
  76. package/dist/chart-builders/createChartBuilderStore.js +26 -0
  77. package/dist/chart-builders/createChartBuilderStore.js.map +1 -0
  78. package/dist/chart-builders/describeChartSpecs.d.ts +9 -0
  79. package/dist/chart-builders/describeChartSpecs.d.ts.map +1 -0
  80. package/dist/chart-builders/describeChartSpecs.js +41 -0
  81. package/dist/chart-builders/describeChartSpecs.js.map +1 -0
  82. package/dist/chart-builders/hooks/useChartFieldForm.d.ts +13 -0
  83. package/dist/chart-builders/hooks/useChartFieldForm.d.ts.map +1 -0
  84. package/dist/chart-builders/hooks/useChartFieldForm.js +12 -0
  85. package/dist/chart-builders/hooks/useChartFieldForm.js.map +1 -0
  86. package/dist/chart-builders/types.d.ts +23 -0
  87. package/dist/chart-builders/types.d.ts.map +1 -0
  88. package/dist/chart-builders/types.js +17 -0
  89. package/dist/chart-builders/types.js.map +1 -0
  90. package/dist/chart-types/base-types.d.ts +54 -0
  91. package/dist/chart-types/base-types.d.ts.map +1 -0
  92. package/dist/chart-types/base-types.js +6 -0
  93. package/dist/chart-types/base-types.js.map +1 -0
  94. package/dist/chart-types/box-plot/definition.d.ts +4 -0
  95. package/dist/chart-types/box-plot/definition.d.ts.map +1 -0
  96. package/dist/chart-types/box-plot/definition.js +45 -0
  97. package/dist/chart-types/box-plot/definition.js.map +1 -0
  98. package/dist/chart-types/box-plot/index.d.ts +3 -0
  99. package/dist/chart-types/box-plot/index.d.ts.map +1 -0
  100. package/dist/chart-types/box-plot/index.js +3 -0
  101. package/dist/chart-types/box-plot/index.js.map +1 -0
  102. package/dist/chart-types/box-plot/schema.d.ts +17 -0
  103. package/dist/chart-types/box-plot/schema.d.ts.map +1 -0
  104. package/dist/chart-types/box-plot/schema.js +12 -0
  105. package/dist/chart-types/box-plot/schema.js.map +1 -0
  106. package/dist/chart-types/bubble-chart/definition.d.ts +4 -0
  107. package/dist/chart-types/bubble-chart/definition.d.ts.map +1 -0
  108. package/dist/chart-types/bubble-chart/definition.js +48 -0
  109. package/dist/chart-types/bubble-chart/definition.js.map +1 -0
  110. package/dist/chart-types/bubble-chart/index.d.ts +3 -0
  111. package/dist/chart-types/bubble-chart/index.d.ts.map +1 -0
  112. package/dist/chart-types/bubble-chart/index.js +3 -0
  113. package/dist/chart-types/bubble-chart/index.js.map +1 -0
  114. package/dist/chart-types/bubble-chart/schema.d.ts +17 -0
  115. package/dist/chart-types/bubble-chart/schema.d.ts.map +1 -0
  116. package/dist/chart-types/bubble-chart/schema.js +12 -0
  117. package/dist/chart-types/bubble-chart/schema.js.map +1 -0
  118. package/dist/chart-types/count-plot/definition.d.ts +4 -0
  119. package/dist/chart-types/count-plot/definition.d.ts.map +1 -0
  120. package/dist/chart-types/count-plot/definition.js +50 -0
  121. package/dist/chart-types/count-plot/definition.js.map +1 -0
  122. package/dist/chart-types/count-plot/index.d.ts +3 -0
  123. package/dist/chart-types/count-plot/index.d.ts.map +1 -0
  124. package/dist/chart-types/count-plot/index.js +3 -0
  125. package/dist/chart-types/count-plot/index.js.map +1 -0
  126. package/dist/chart-types/count-plot/schema.d.ts +15 -0
  127. package/dist/chart-types/count-plot/schema.d.ts.map +1 -0
  128. package/dist/chart-types/count-plot/schema.js +11 -0
  129. package/dist/chart-types/count-plot/schema.js.map +1 -0
  130. package/dist/chart-types/custom-spec/definition.d.ts +4 -0
  131. package/dist/chart-types/custom-spec/definition.d.ts.map +1 -0
  132. package/dist/chart-types/custom-spec/definition.js +28 -0
  133. package/dist/chart-types/custom-spec/definition.js.map +1 -0
  134. package/dist/chart-types/custom-spec/index.d.ts +3 -0
  135. package/dist/chart-types/custom-spec/index.d.ts.map +1 -0
  136. package/dist/chart-types/custom-spec/index.js +3 -0
  137. package/dist/chart-types/custom-spec/index.js.map +1 -0
  138. package/dist/chart-types/custom-spec/schema.d.ts +11 -0
  139. package/dist/chart-types/custom-spec/schema.d.ts.map +1 -0
  140. package/dist/chart-types/custom-spec/schema.js +9 -0
  141. package/dist/chart-types/custom-spec/schema.js.map +1 -0
  142. package/dist/chart-types/ecdf/definition.d.ts +4 -0
  143. package/dist/chart-types/ecdf/definition.d.ts.map +1 -0
  144. package/dist/chart-types/ecdf/definition.js +47 -0
  145. package/dist/chart-types/ecdf/definition.js.map +1 -0
  146. package/dist/chart-types/ecdf/index.d.ts +3 -0
  147. package/dist/chart-types/ecdf/index.d.ts.map +1 -0
  148. package/dist/chart-types/ecdf/index.js +3 -0
  149. package/dist/chart-types/ecdf/index.js.map +1 -0
  150. package/dist/chart-types/ecdf/schema.d.ts +15 -0
  151. package/dist/chart-types/ecdf/schema.d.ts.map +1 -0
  152. package/dist/chart-types/ecdf/schema.js +11 -0
  153. package/dist/chart-types/ecdf/schema.js.map +1 -0
  154. package/dist/chart-types/heatmap/definition.d.ts +4 -0
  155. package/dist/chart-types/heatmap/definition.d.ts.map +1 -0
  156. package/dist/chart-types/heatmap/definition.js +49 -0
  157. package/dist/chart-types/heatmap/definition.js.map +1 -0
  158. package/dist/chart-types/heatmap/index.d.ts +3 -0
  159. package/dist/chart-types/heatmap/index.d.ts.map +1 -0
  160. package/dist/chart-types/heatmap/index.js +3 -0
  161. package/dist/chart-types/heatmap/index.js.map +1 -0
  162. package/dist/chart-types/heatmap/schema.d.ts +17 -0
  163. package/dist/chart-types/heatmap/schema.d.ts.map +1 -0
  164. package/dist/chart-types/heatmap/schema.js +12 -0
  165. package/dist/chart-types/heatmap/schema.js.map +1 -0
  166. package/dist/chart-types/histogram/definition.d.ts +4 -0
  167. package/dist/chart-types/histogram/definition.d.ts.map +1 -0
  168. package/dist/chart-types/histogram/definition.js +49 -0
  169. package/dist/chart-types/histogram/definition.js.map +1 -0
  170. package/dist/chart-types/histogram/index.d.ts +3 -0
  171. package/dist/chart-types/histogram/index.d.ts.map +1 -0
  172. package/dist/chart-types/histogram/index.js +3 -0
  173. package/dist/chart-types/histogram/index.js.map +1 -0
  174. package/dist/chart-types/histogram/schema.d.ts +15 -0
  175. package/dist/chart-types/histogram/schema.d.ts.map +1 -0
  176. package/dist/chart-types/histogram/schema.js +11 -0
  177. package/dist/chart-types/histogram/schema.js.map +1 -0
  178. package/dist/chart-types/index.d.ts +109 -0
  179. package/dist/chart-types/index.d.ts.map +1 -0
  180. package/dist/chart-types/index.js +70 -0
  181. package/dist/chart-types/index.js.map +1 -0
  182. package/dist/chart-types/line-chart/definition.d.ts +4 -0
  183. package/dist/chart-types/line-chart/definition.d.ts.map +1 -0
  184. package/dist/chart-types/line-chart/definition.js +46 -0
  185. package/dist/chart-types/line-chart/definition.js.map +1 -0
  186. package/dist/chart-types/line-chart/index.d.ts +3 -0
  187. package/dist/chart-types/line-chart/index.d.ts.map +1 -0
  188. package/dist/chart-types/line-chart/index.js +3 -0
  189. package/dist/chart-types/line-chart/index.js.map +1 -0
  190. package/dist/chart-types/line-chart/schema.d.ts +17 -0
  191. package/dist/chart-types/line-chart/schema.d.ts.map +1 -0
  192. package/dist/chart-types/line-chart/schema.js +12 -0
  193. package/dist/chart-types/line-chart/schema.js.map +1 -0
  194. package/dist/chart-types/registry.d.ts +5 -0
  195. package/dist/chart-types/registry.d.ts.map +1 -0
  196. package/dist/chart-types/registry.js +28 -0
  197. package/dist/chart-types/registry.js.map +1 -0
  198. package/dist/dashboard/DashboardPanelErrorBoundary.d.ts +17 -0
  199. package/dist/dashboard/DashboardPanelErrorBoundary.d.ts.map +1 -0
  200. package/dist/dashboard/DashboardPanelErrorBoundary.js +21 -0
  201. package/dist/dashboard/DashboardPanelErrorBoundary.js.map +1 -0
  202. package/dist/dashboard/MosaicDashboard.d.ts +18 -0
  203. package/dist/dashboard/MosaicDashboard.d.ts.map +1 -0
  204. package/dist/dashboard/MosaicDashboard.js +91 -0
  205. package/dist/dashboard/MosaicDashboard.js.map +1 -0
  206. package/dist/dashboard/MosaicDashboardContext.d.ts +12 -0
  207. package/dist/dashboard/MosaicDashboardContext.d.ts.map +1 -0
  208. package/dist/dashboard/MosaicDashboardContext.js +10 -0
  209. package/dist/dashboard/MosaicDashboardContext.js.map +1 -0
  210. package/dist/dashboard/MosaicDashboardPanel.d.ts +3 -0
  211. package/dist/dashboard/MosaicDashboardPanel.d.ts.map +1 -0
  212. package/dist/dashboard/MosaicDashboardPanel.js +26 -0
  213. package/dist/dashboard/MosaicDashboardPanel.js.map +1 -0
  214. package/dist/dashboard/MosaicDashboardPanelDragOverlay.d.ts +8 -0
  215. package/dist/dashboard/MosaicDashboardPanelDragOverlay.d.ts.map +1 -0
  216. package/dist/dashboard/MosaicDashboardPanelDragOverlay.js +17 -0
  217. package/dist/dashboard/MosaicDashboardPanelDragOverlay.js.map +1 -0
  218. package/dist/dashboard/MosaicDashboardPanelHeader.d.ts +13 -0
  219. package/dist/dashboard/MosaicDashboardPanelHeader.d.ts.map +1 -0
  220. package/dist/dashboard/MosaicDashboardPanelHeader.js +30 -0
  221. package/dist/dashboard/MosaicDashboardPanelHeader.js.map +1 -0
  222. package/dist/dashboard/MosaicDashboardPanelLayout.d.ts +10 -0
  223. package/dist/dashboard/MosaicDashboardPanelLayout.d.ts.map +1 -0
  224. package/dist/dashboard/MosaicDashboardPanelLayout.js +25 -0
  225. package/dist/dashboard/MosaicDashboardPanelLayout.js.map +1 -0
  226. package/dist/dashboard/MosaicDashboardPanels.d.ts +2 -0
  227. package/dist/dashboard/MosaicDashboardPanels.d.ts.map +1 -0
  228. package/dist/dashboard/MosaicDashboardPanels.js +52 -0
  229. package/dist/dashboard/MosaicDashboardPanels.js.map +1 -0
  230. package/dist/dashboard/MosaicDashboardProfilerPanelRenderer.d.ts +3 -0
  231. package/dist/dashboard/MosaicDashboardProfilerPanelRenderer.d.ts.map +1 -0
  232. package/dist/dashboard/MosaicDashboardProfilerPanelRenderer.js +32 -0
  233. package/dist/dashboard/MosaicDashboardProfilerPanelRenderer.js.map +1 -0
  234. package/dist/dashboard/MosaicDashboardSlice.d.ts +523 -0
  235. package/dist/dashboard/MosaicDashboardSlice.d.ts.map +1 -0
  236. package/dist/dashboard/MosaicDashboardSlice.js +615 -0
  237. package/dist/dashboard/MosaicDashboardSlice.js.map +1 -0
  238. package/dist/dashboard/MosaicDashboardToolbar.d.ts +3 -0
  239. package/dist/dashboard/MosaicDashboardToolbar.d.ts.map +1 -0
  240. package/dist/dashboard/MosaicDashboardToolbar.js +81 -0
  241. package/dist/dashboard/MosaicDashboardToolbar.js.map +1 -0
  242. package/dist/dashboard/MosaicDashboardVgPlotHeaderActions.d.ts +4 -0
  243. package/dist/dashboard/MosaicDashboardVgPlotHeaderActions.d.ts.map +1 -0
  244. package/dist/dashboard/MosaicDashboardVgPlotHeaderActions.js +29 -0
  245. package/dist/dashboard/MosaicDashboardVgPlotHeaderActions.js.map +1 -0
  246. package/dist/dashboard/MosaicDashboardVgPlotPanelRenderer.d.ts +3 -0
  247. package/dist/dashboard/MosaicDashboardVgPlotPanelRenderer.d.ts.map +1 -0
  248. package/dist/dashboard/MosaicDashboardVgPlotPanelRenderer.js +68 -0
  249. package/dist/dashboard/MosaicDashboardVgPlotPanelRenderer.js.map +1 -0
  250. package/dist/dashboard/VgPlotSpecPopoverEditor.d.ts +8 -0
  251. package/dist/dashboard/VgPlotSpecPopoverEditor.d.ts.map +1 -0
  252. package/dist/dashboard/VgPlotSpecPopoverEditor.js +40 -0
  253. package/dist/dashboard/VgPlotSpecPopoverEditor.js.map +1 -0
  254. package/dist/dashboard/chart-settings/ChartSettings.d.ts +39 -0
  255. package/dist/dashboard/chart-settings/ChartSettings.d.ts.map +1 -0
  256. package/dist/dashboard/chart-settings/ChartSettings.js +90 -0
  257. package/dist/dashboard/chart-settings/ChartSettings.js.map +1 -0
  258. package/dist/dashboard/chart-settings/ChartSettingsContext.d.ts +20 -0
  259. package/dist/dashboard/chart-settings/ChartSettingsContext.d.ts.map +1 -0
  260. package/dist/dashboard/chart-settings/ChartSettingsContext.js +14 -0
  261. package/dist/dashboard/chart-settings/ChartSettingsContext.js.map +1 -0
  262. package/dist/dashboard/chart-settings/ChartSettingsPanel.d.ts +11 -0
  263. package/dist/dashboard/chart-settings/ChartSettingsPanel.d.ts.map +1 -0
  264. package/dist/dashboard/chart-settings/ChartSettingsPanel.js +8 -0
  265. package/dist/dashboard/chart-settings/ChartSettingsPanel.js.map +1 -0
  266. package/dist/dashboard/chart-settings/ChartTypeSelector.d.ts +11 -0
  267. package/dist/dashboard/chart-settings/ChartTypeSelector.d.ts.map +1 -0
  268. package/dist/dashboard/chart-settings/ChartTypeSelector.js +17 -0
  269. package/dist/dashboard/chart-settings/ChartTypeSelector.js.map +1 -0
  270. package/dist/dashboard/chart-settings/DynamicChartSettings.d.ts +11 -0
  271. package/dist/dashboard/chart-settings/DynamicChartSettings.d.ts.map +1 -0
  272. package/dist/dashboard/chart-settings/DynamicChartSettings.js +19 -0
  273. package/dist/dashboard/chart-settings/DynamicChartSettings.js.map +1 -0
  274. package/dist/dashboard/chart-settings/index.d.ts +6 -0
  275. package/dist/dashboard/chart-settings/index.d.ts.map +1 -0
  276. package/dist/dashboard/chart-settings/index.js +6 -0
  277. package/dist/dashboard/chart-settings/index.js.map +1 -0
  278. package/dist/dashboard/chart-settings/useTableColumns.d.ts +3 -0
  279. package/dist/dashboard/chart-settings/useTableColumns.d.ts.map +1 -0
  280. package/dist/dashboard/chart-settings/useTableColumns.js +12 -0
  281. package/dist/dashboard/chart-settings/useTableColumns.js.map +1 -0
  282. package/dist/dashboard/defaultPanelRenderers.d.ts +3 -0
  283. package/dist/dashboard/defaultPanelRenderers.d.ts.map +1 -0
  284. package/dist/dashboard/defaultPanelRenderers.js +11 -0
  285. package/dist/dashboard/defaultPanelRenderers.js.map +1 -0
  286. package/dist/dashboard/generateMosaicChartSpec.d.ts +15 -0
  287. package/dist/dashboard/generateMosaicChartSpec.d.ts.map +1 -0
  288. package/dist/dashboard/generateMosaicChartSpec.js +30 -0
  289. package/dist/dashboard/generateMosaicChartSpec.js.map +1 -0
  290. package/dist/editor/MosaicChartContainer.d.ts +51 -0
  291. package/dist/editor/MosaicChartContainer.d.ts.map +1 -0
  292. package/dist/editor/MosaicChartContainer.js +39 -0
  293. package/dist/editor/MosaicChartContainer.js.map +1 -0
  294. package/dist/editor/MosaicChartDisplay.d.ts +18 -0
  295. package/dist/editor/MosaicChartDisplay.d.ts.map +1 -0
  296. package/dist/editor/MosaicChartDisplay.js +26 -0
  297. package/dist/editor/MosaicChartDisplay.js.map +1 -0
  298. package/dist/editor/MosaicChartEditorActions.d.ts +20 -0
  299. package/dist/editor/MosaicChartEditorActions.d.ts.map +1 -0
  300. package/dist/editor/MosaicChartEditorActions.js +18 -0
  301. package/dist/editor/MosaicChartEditorActions.js.map +1 -0
  302. package/dist/editor/MosaicCodeMirrorEditor.d.ts +15 -0
  303. package/dist/editor/MosaicCodeMirrorEditor.d.ts.map +1 -0
  304. package/dist/editor/MosaicCodeMirrorEditor.js +26 -0
  305. package/dist/editor/MosaicCodeMirrorEditor.js.map +1 -0
  306. package/dist/editor/MosaicEditorContext.d.ts +8 -0
  307. package/dist/editor/MosaicEditorContext.d.ts.map +1 -0
  308. package/dist/editor/MosaicEditorContext.js +14 -0
  309. package/dist/editor/MosaicEditorContext.js.map +1 -0
  310. package/dist/editor/MosaicSpecEditorPanel.d.ts +20 -0
  311. package/dist/editor/MosaicSpecEditorPanel.d.ts.map +1 -0
  312. package/dist/editor/MosaicSpecEditorPanel.js +25 -0
  313. package/dist/editor/MosaicSpecEditorPanel.js.map +1 -0
  314. package/dist/editor/mosaicSchema.d.ts +20 -0
  315. package/dist/editor/mosaicSchema.d.ts.map +1 -0
  316. package/dist/editor/mosaicSchema.js +57 -0
  317. package/dist/editor/mosaicSchema.js.map +1 -0
  318. package/dist/editor/types.d.ts +72 -0
  319. package/dist/editor/types.d.ts.map +1 -0
  320. package/dist/editor/types.js +2 -0
  321. package/dist/editor/types.js.map +1 -0
  322. package/dist/editor/useMosaicChartEditor.d.ts +9 -0
  323. package/dist/editor/useMosaicChartEditor.d.ts.map +1 -0
  324. package/dist/editor/useMosaicChartEditor.js +199 -0
  325. package/dist/editor/useMosaicChartEditor.js.map +1 -0
  326. package/dist/index.d.ts +53 -2
  327. package/dist/index.d.ts.map +1 -1
  328. package/dist/index.js +37 -1
  329. package/dist/index.js.map +1 -1
  330. package/dist/profiler/MosaicProfiler.d.ts +32 -0
  331. package/dist/profiler/MosaicProfiler.d.ts.map +1 -0
  332. package/dist/profiler/MosaicProfiler.js +57 -0
  333. package/dist/profiler/MosaicProfiler.js.map +1 -0
  334. package/dist/profiler/MosaicProfilerHeader.d.ts +7 -0
  335. package/dist/profiler/MosaicProfilerHeader.d.ts.map +1 -0
  336. package/dist/profiler/MosaicProfilerHeader.js +196 -0
  337. package/dist/profiler/MosaicProfilerHeader.js.map +1 -0
  338. package/dist/profiler/MosaicProfilerRows.d.ts +9 -0
  339. package/dist/profiler/MosaicProfilerRows.d.ts.map +1 -0
  340. package/dist/profiler/MosaicProfilerRows.js +65 -0
  341. package/dist/profiler/MosaicProfilerRows.js.map +1 -0
  342. package/dist/profiler/MosaicProfilerStatusBar.d.ts +9 -0
  343. package/dist/profiler/MosaicProfilerStatusBar.d.ts.map +1 -0
  344. package/dist/profiler/MosaicProfilerStatusBar.js +28 -0
  345. package/dist/profiler/MosaicProfilerStatusBar.js.map +1 -0
  346. package/dist/profiler/ProfilerCategoryClient.d.ts +50 -0
  347. package/dist/profiler/ProfilerCategoryClient.d.ts.map +1 -0
  348. package/dist/profiler/ProfilerCategoryClient.js +121 -0
  349. package/dist/profiler/ProfilerCategoryClient.js.map +1 -0
  350. package/dist/profiler/ProfilerCountClient.d.ts +28 -0
  351. package/dist/profiler/ProfilerCountClient.d.ts.map +1 -0
  352. package/dist/profiler/ProfilerCountClient.js +51 -0
  353. package/dist/profiler/ProfilerCountClient.js.map +1 -0
  354. package/dist/profiler/ProfilerHistogramClient.d.ts +69 -0
  355. package/dist/profiler/ProfilerHistogramClient.d.ts.map +1 -0
  356. package/dist/profiler/ProfilerHistogramClient.js +179 -0
  357. package/dist/profiler/ProfilerHistogramClient.js.map +1 -0
  358. package/dist/profiler/ProfilerPageClient.d.ts +37 -0
  359. package/dist/profiler/ProfilerPageClient.d.ts.map +1 -0
  360. package/dist/profiler/ProfilerPageClient.js +65 -0
  361. package/dist/profiler/ProfilerPageClient.js.map +1 -0
  362. package/dist/profiler/ProfilerUnsupportedSummaryClient.d.ts +24 -0
  363. package/dist/profiler/ProfilerUnsupportedSummaryClient.d.ts.map +1 -0
  364. package/dist/profiler/ProfilerUnsupportedSummaryClient.js +51 -0
  365. package/dist/profiler/ProfilerUnsupportedSummaryClient.js.map +1 -0
  366. package/dist/profiler/createProfilerStore.d.ts +45 -0
  367. package/dist/profiler/createProfilerStore.d.ts.map +1 -0
  368. package/dist/profiler/createProfilerStore.js +120 -0
  369. package/dist/profiler/createProfilerStore.js.map +1 -0
  370. package/dist/profiler/layout.d.ts +7 -0
  371. package/dist/profiler/layout.d.ts.map +1 -0
  372. package/dist/profiler/layout.js +13 -0
  373. package/dist/profiler/layout.js.map +1 -0
  374. package/dist/profiler/profilerController.d.ts +64 -0
  375. package/dist/profiler/profilerController.d.ts.map +1 -0
  376. package/dist/profiler/profilerController.js +123 -0
  377. package/dist/profiler/profilerController.js.map +1 -0
  378. package/dist/profiler/types.d.ts +86 -0
  379. package/dist/profiler/types.d.ts.map +1 -0
  380. package/dist/profiler/types.js +2 -0
  381. package/dist/profiler/types.js.map +1 -0
  382. package/dist/profiler/useMosaicProfiler.d.ts +7 -0
  383. package/dist/profiler/useMosaicProfiler.d.ts.map +1 -0
  384. package/dist/profiler/useMosaicProfiler.js +339 -0
  385. package/dist/profiler/useMosaicProfiler.js.map +1 -0
  386. package/dist/profiler/utils.d.ts +61 -0
  387. package/dist/profiler/utils.d.ts.map +1 -0
  388. package/dist/profiler/utils.js +347 -0
  389. package/dist/profiler/utils.js.map +1 -0
  390. package/dist/tableInterop.d.ts +30 -0
  391. package/dist/tableInterop.d.ts.map +1 -0
  392. package/dist/tableInterop.js +85 -0
  393. package/dist/tableInterop.js.map +1 -0
  394. package/dist/useMosaicClient.d.ts +5 -15
  395. package/dist/useMosaicClient.d.ts.map +1 -1
  396. package/dist/useMosaicClient.js +22 -6
  397. package/dist/useMosaicClient.js.map +1 -1
  398. package/package.json +30 -6
@@ -1,40 +1,47 @@
1
1
  import { createId } from '@paralleldrive/cuid2';
2
- import { isWasmDuckDbConnector } from '@sqlrooms/duckdb';
2
+ import { isWasmDuckDbConnector, } from '@sqlrooms/duckdb';
3
3
  import { createSlice, useBaseRoomStore, } from '@sqlrooms/room-store';
4
4
  import { coordinator, makeClient, Selection, wasmConnector, } from '@uwdata/mosaic-core';
5
5
  import { produce } from 'immer';
6
6
  import { z } from 'zod';
7
+ import { createMosaicTableFromArrowTable, toArrowClientResult, } from './tableInterop';
7
8
  export const MosaicSliceConfig = z.object({});
8
9
  export function createDefaultMosaicConfig(props) {
9
10
  return {
10
11
  ...props,
11
12
  };
12
13
  }
13
- export function createMosaicSlice(props) {
14
+ export function createMosaicSlice(props = {}) {
14
15
  return createSlice((set, get, store) => ({
15
16
  mosaic: {
16
17
  config: createDefaultMosaicConfig(props?.config),
17
- connection: {
18
- status: 'idle',
19
- connector: undefined,
20
- },
18
+ connection: { status: 'idle' },
21
19
  clients: {},
22
20
  selections: {},
23
21
  async initialize() {
24
22
  let mosaicConnector;
23
+ let resolvedCoordinator;
25
24
  set((state) => produce(state, (draft) => {
26
25
  draft.mosaic.connection = { status: 'loading' };
27
26
  }));
28
27
  try {
29
- const dbConnector = await get().db.getConnector();
30
- if (!isWasmDuckDbConnector(dbConnector)) {
31
- throw new Error('Only WasmDuckDbConnector is currently supported');
28
+ if (props.coordinator) {
29
+ resolvedCoordinator = props.coordinator;
30
+ applyMosaicPreAggregateOptions(resolvedCoordinator, props.preagg);
31
+ }
32
+ else {
33
+ const dbConnector = await get().db.getConnector();
34
+ resolvedCoordinator = coordinator();
35
+ mosaicConnector = isWasmDuckDbConnector(dbConnector)
36
+ ? await wasmConnector({
37
+ // @ts-expect-error - We install a different version of duckdb-wasm
38
+ duckDb: dbConnector.getDb(),
39
+ connection: dbConnector.getConnection(),
40
+ })
41
+ : createDuckDbMosaicConnector(dbConnector);
42
+ applyMosaicPreAggregateOptions(resolvedCoordinator, props.preagg);
43
+ resolvedCoordinator.databaseConnector(mosaicConnector);
32
44
  }
33
- mosaicConnector = await coordinator().databaseConnector(wasmConnector({
34
- // @ts-expect-error - We install a different version of duckdb-wasm
35
- duckDb: dbConnector.getDb(),
36
- connection: dbConnector.getConnection(),
37
- }));
38
45
  }
39
46
  catch (error) {
40
47
  set((state) => produce(state, (draft) => {
@@ -42,19 +49,22 @@ export function createMosaicSlice(props) {
42
49
  }));
43
50
  throw error;
44
51
  }
45
- finally {
46
- set((state) => produce(state, (draft) => {
47
- draft.mosaic.connection = {
48
- status: 'ready',
49
- connector: mosaicConnector,
50
- coordinator: coordinator(),
51
- };
52
- }));
53
- }
52
+ set((state) => produce(state, (draft) => {
53
+ draft.mosaic.connection = {
54
+ status: 'ready',
55
+ connector: mosaicConnector,
56
+ coordinator: resolvedCoordinator,
57
+ };
58
+ }));
54
59
  },
55
60
  async destroy() {
56
61
  get().mosaic.destroyAllClients();
57
62
  },
63
+ setConfig(config) {
64
+ set((state) => produce(state, (draft) => {
65
+ draft.mosaic.config = config;
66
+ }));
67
+ },
58
68
  getSelection(name, type = 'crossfilter') {
59
69
  const existing = get().mosaic.selections[name];
60
70
  if (existing)
@@ -82,22 +92,44 @@ export function createMosaicSlice(props) {
82
92
  : undefined);
83
93
  // Wrap queryResult to update store state AND call external callback
84
94
  const wrappedQueryResult = (data) => {
85
- const typedData = data;
86
95
  set((state) => produce(state, (draft) => {
87
96
  const tracked = draft.mosaic.clients[id];
88
97
  if (tracked) {
89
- tracked.data = typedData;
98
+ tracked.data = data;
90
99
  tracked.isLoading = false;
100
+ tracked.error = undefined;
91
101
  }
92
102
  }));
93
103
  // Call external callback if provided
94
- options.queryResult?.(typedData);
104
+ options.queryResult?.(toArrowClientResult(data));
105
+ };
106
+ const wrappedQueryPending = () => {
107
+ set((state) => produce(state, (draft) => {
108
+ const tracked = draft.mosaic.clients[id];
109
+ if (tracked) {
110
+ tracked.isLoading = true;
111
+ tracked.error = undefined;
112
+ }
113
+ }));
114
+ };
115
+ const wrappedQueryError = (error) => {
116
+ set((state) => produce(state, (draft) => {
117
+ const tracked = draft.mosaic.clients[id];
118
+ if (tracked) {
119
+ tracked.isLoading = false;
120
+ tracked.error = error;
121
+ }
122
+ }));
123
+ client.enabled = false;
124
+ options.queryError?.(error);
95
125
  };
96
126
  const client = makeClient({
97
127
  coordinator: connection.coordinator,
98
128
  selection,
99
129
  query: options.query,
100
130
  queryResult: wrappedQueryResult,
131
+ queryPending: wrappedQueryPending,
132
+ queryError: wrappedQueryError,
101
133
  });
102
134
  set((state) => produce(state, (draft) => {
103
135
  draft.mosaic.clients[id] = {
@@ -106,9 +138,10 @@ export function createMosaicSlice(props) {
106
138
  createdAt: Date.now(),
107
139
  isLoading: true,
108
140
  data: null,
141
+ error: undefined,
109
142
  selection,
110
143
  queryResultCallback: options.queryResult
111
- ? (result) => options.queryResult(result)
144
+ ? (result) => options.queryResult(toArrowClientResult(result))
112
145
  : undefined,
113
146
  };
114
147
  }));
@@ -138,24 +171,48 @@ export function createMosaicSlice(props) {
138
171
  }
139
172
  // Create new client with wrapped queryResult that calls both store update and external callback
140
173
  const wrappedQueryResult = (data) => {
141
- const typedData = data;
142
174
  set((state) => produce(state, (draft) => {
143
175
  const tracked = draft.mosaic.clients[options.id];
144
176
  if (tracked) {
145
- tracked.data = typedData;
177
+ tracked.data = data;
146
178
  tracked.isLoading = false;
179
+ tracked.error = undefined;
147
180
  }
148
181
  }));
182
+ const arrowData = toArrowClientResult(data);
149
183
  // Call external callback if provided
150
- options.onQueryResult?.(typedData);
184
+ options.onQueryResult?.(arrowData);
151
185
  // Also call original queryResult if provided
152
- options.queryResult?.(typedData);
186
+ options.queryResult?.(arrowData);
187
+ };
188
+ const wrappedQueryPending = () => {
189
+ set((state) => produce(state, (draft) => {
190
+ const tracked = draft.mosaic.clients[options.id];
191
+ if (tracked) {
192
+ tracked.isLoading = true;
193
+ tracked.error = undefined;
194
+ }
195
+ }));
196
+ };
197
+ const wrappedQueryError = (error) => {
198
+ set((state) => produce(state, (draft) => {
199
+ const tracked = draft.mosaic.clients[options.id];
200
+ if (tracked) {
201
+ tracked.isLoading = false;
202
+ tracked.error = error;
203
+ }
204
+ }));
205
+ client.enabled = false;
206
+ options.onQueryError?.(error);
207
+ options.queryError?.(error);
153
208
  };
154
209
  const client = makeClient({
155
210
  coordinator: connection.coordinator,
156
211
  selection,
157
212
  query: options.query,
158
213
  queryResult: wrappedQueryResult,
214
+ queryPending: wrappedQueryPending,
215
+ queryError: wrappedQueryError,
159
216
  });
160
217
  set((state) => produce(state, (draft) => {
161
218
  draft.mosaic.clients[options.id] = {
@@ -164,30 +221,29 @@ export function createMosaicSlice(props) {
164
221
  createdAt: Date.now(),
165
222
  isLoading: true,
166
223
  data: null,
224
+ error: undefined,
167
225
  selection,
168
- queryResultCallback: options.onQueryResult,
226
+ queryResultCallback: options.onQueryResult
227
+ ? (result) => options.onQueryResult(toArrowClientResult(result))
228
+ : undefined,
169
229
  };
170
230
  }));
171
231
  },
172
232
  destroyClient(id) {
173
- const { connection, clients } = get().mosaic;
233
+ const { clients } = get().mosaic;
174
234
  const tracked = clients[id];
175
235
  if (!tracked)
176
236
  return;
177
- if (connection.status === 'ready') {
178
- connection.coordinator.disconnect(tracked.client);
179
- }
237
+ tracked.client.destroy();
180
238
  set((state) => produce(state, (draft) => {
181
239
  delete draft.mosaic.clients[id];
182
240
  }));
183
241
  },
184
242
  destroyAllClients() {
185
- const { connection, clients } = get().mosaic;
186
- if (connection.status === 'ready') {
187
- Object.values(clients).forEach((tracked) => {
188
- connection.coordinator.disconnect(tracked.client);
189
- });
190
- }
243
+ const { clients } = get().mosaic;
244
+ Object.values(clients).forEach((tracked) => {
245
+ tracked.client.destroy();
246
+ });
191
247
  set((state) => produce(state, (draft) => {
192
248
  draft.mosaic.clients = {};
193
249
  }));
@@ -195,7 +251,49 @@ export function createMosaicSlice(props) {
195
251
  },
196
252
  }));
197
253
  }
254
+ function applyMosaicPreAggregateOptions(mosaicCoordinator, options) {
255
+ if (!options) {
256
+ return;
257
+ }
258
+ if (options.schema !== undefined) {
259
+ mosaicCoordinator.preaggregator.schema = options.schema;
260
+ }
261
+ if (options.enabled !== undefined) {
262
+ mosaicCoordinator.preaggregator.enabled = options.enabled;
263
+ }
264
+ }
198
265
  export function useStoreWithMosaic(selector) {
199
266
  return useBaseRoomStore((state) => selector(state));
200
267
  }
268
+ /**
269
+ * Adapts a {@link DuckDbConnector} to the Mosaic {@link Connector} interface.
270
+ *
271
+ * For `'arrow'` queries the Apache Arrow table returned by the connector is
272
+ * converted via {@link createMosaicTableFromArrowTable} into a flechette
273
+ * `Table`, which is the shape Mosaic consumers expect (with `.toColumns()`).
274
+ * For `'json'` queries, rows are materialized with {@link Array.from} which
275
+ * may have performance/memory implications for very large result sets.
276
+ * The `as any` casts on the return type are an intentional adapter trade-off
277
+ * to satisfy the polymorphic {@link Connector['query']} signature.
278
+ */
279
+ function createDuckDbMosaicConnector(connector) {
280
+ return {
281
+ query: (async (query) => {
282
+ const queryType = query.type ?? 'arrow';
283
+ if (queryType === 'exec') {
284
+ await connector.execute(query.sql);
285
+ return undefined;
286
+ }
287
+ if (queryType === 'json') {
288
+ const rows = await connector.queryJson(query.sql);
289
+ return Array.from(rows);
290
+ }
291
+ if (queryType === 'arrow') {
292
+ const arrowTable = await connector.query(query.sql);
293
+ return createMosaicTableFromArrowTable(arrowTable);
294
+ }
295
+ throw new Error(`Unsupported Mosaic query type "${queryType}".`);
296
+ }),
297
+ };
298
+ }
201
299
  //# sourceMappingURL=MosaicSlice.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MosaicSlice.js","sourceRoot":"","sources":["../src/MosaicSlice.ts"],"names":[],"mappings":"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","sourcesContent":["import {createId} from '@paralleldrive/cuid2';\nimport {DuckDbSliceState, isWasmDuckDbConnector} from '@sqlrooms/duckdb';\nimport {\n BaseRoomStoreState,\n createSlice,\n useBaseRoomStore,\n type SliceFunctions,\n} from '@sqlrooms/room-store';\nimport {\n Connector,\n Coordinator,\n coordinator,\n makeClient,\n Selection,\n wasmConnector,\n} from '@uwdata/mosaic-core';\nimport {Query} from '@uwdata/mosaic-sql';\nimport {produce} from 'immer';\nimport {z} from 'zod';\n\nexport const MosaicSliceConfig = z.object({});\nexport type MosaicSliceConfig = z.infer<typeof MosaicSliceConfig>;\n\n// Client configuration options\nexport type MosaicClientOptions<T = unknown> = {\n /** Unique identifier for this client */\n id?: string;\n /** Selection name for cross-filtering (will create if doesn't exist) */\n selectionName?: string;\n /** The selection to subscribe to for cross-filtering */\n selection?: Selection;\n /** Query builder function that receives the current filter */\n query: (filter: unknown) => ReturnType<typeof Query.from>;\n /** Callback when query results are received */\n queryResult?: (result: T) => void;\n};\n\n// Tracked client info\nexport type TrackedClient<T = unknown> = {\n id: string;\n client: ReturnType<typeof makeClient>;\n createdAt: number;\n isLoading: boolean;\n data: T | null;\n selection?: Selection; // Track for change detection\n queryResultCallback?: (result: T) => void; // External callback\n};\n\nexport type MosaicSliceState = {\n mosaic: SliceFunctions & {\n connection:\n | {status: 'idle' | 'loading'}\n | {status: 'ready'; connector: Connector; coordinator: Coordinator}\n | {status: 'error'; error: unknown};\n config: MosaicSliceConfig;\n /** Record of registered clients by id */\n clients: Record<string, TrackedClient<unknown>>;\n /** Named selections for cross-filtering (e.g., 'brush', 'hover') */\n selections: Record<string, Selection>;\n initialize: () => Promise<void>;\n /** Get or create a named selection for cross-filtering */\n getSelection: (\n name: string,\n type?: 'crossfilter' | 'single' | 'union',\n ) => Selection;\n /** Create a mosaic client and register it */\n createClient: <T>(options: MosaicClientOptions<T>) => string;\n /** Ensure a client exists with given options (idempotent - creates or updates as needed) */\n ensureClient: <T>(\n options: MosaicClientOptions<T> & {\n id: string;\n onQueryResult?: (result: T) => void;\n },\n ) => void;\n /** Disconnect and remove a client by id */\n destroyClient: (id: string) => void;\n /** Disconnect all clients (useful for cleanup) */\n destroyAllClients: () => void;\n };\n};\n\nexport function createDefaultMosaicConfig(\n props?: Partial<MosaicSliceConfig>,\n): MosaicSliceConfig {\n return {\n ...props,\n } as MosaicSliceConfig;\n}\n\nexport function createMosaicSlice(props?: {\n config?: Partial<MosaicSliceConfig>;\n}) {\n return createSlice<\n MosaicSliceState,\n BaseRoomStoreState & DuckDbSliceState & MosaicSliceState\n >((set, get, store) => ({\n mosaic: {\n config: createDefaultMosaicConfig(props?.config),\n connection: {\n status: 'idle',\n connector: undefined,\n },\n clients: {},\n selections: {},\n\n async initialize() {\n let mosaicConnector: Connector | undefined;\n set((state) =>\n produce(state, (draft) => {\n draft.mosaic.connection = {status: 'loading'};\n }),\n );\n try {\n const dbConnector = await get().db.getConnector();\n if (!isWasmDuckDbConnector(dbConnector)) {\n throw new Error('Only WasmDuckDbConnector is currently supported');\n }\n mosaicConnector = await coordinator().databaseConnector(\n wasmConnector({\n // @ts-expect-error - We install a different version of duckdb-wasm\n duckDb: dbConnector.getDb(),\n connection: dbConnector.getConnection(),\n }),\n );\n } catch (error) {\n set((state) =>\n produce(state, (draft) => {\n draft.mosaic.connection = {status: 'error', error};\n }),\n );\n throw error;\n } finally {\n set((state) =>\n produce(state, (draft) => {\n draft.mosaic.connection = {\n status: 'ready',\n connector: mosaicConnector!,\n coordinator: coordinator(),\n };\n }),\n );\n }\n },\n\n async destroy() {\n get().mosaic.destroyAllClients();\n },\n\n getSelection(\n name: string,\n type: 'crossfilter' | 'single' | 'union' = 'crossfilter',\n ) {\n const existing = get().mosaic.selections[name];\n if (existing) return existing;\n\n const selection =\n type === 'crossfilter'\n ? Selection.crossfilter()\n : type === 'single'\n ? Selection.single()\n : Selection.union();\n\n set((state) =>\n produce(state, (draft) => {\n draft.mosaic.selections[name] = selection;\n }),\n );\n return selection;\n },\n\n createClient<T>(options: MosaicClientOptions<T>) {\n const {connection} = get().mosaic;\n if (connection.status !== 'ready') {\n throw new Error('Mosaic connection not ready');\n }\n\n const id = options.id ?? createId();\n\n // Determine which selection to use\n const selection =\n options.selection ??\n (options.selectionName\n ? get().mosaic.getSelection(options.selectionName)\n : undefined);\n\n // Wrap queryResult to update store state AND call external callback\n const wrappedQueryResult = (data: unknown) => {\n const typedData = data as T;\n set((state) =>\n produce(state, (draft) => {\n const tracked = draft.mosaic.clients[id];\n if (tracked) {\n tracked.data = typedData;\n tracked.isLoading = false;\n }\n }),\n );\n // Call external callback if provided\n options.queryResult?.(typedData);\n };\n\n const client = makeClient({\n coordinator: connection.coordinator,\n selection,\n query: options.query,\n queryResult: wrappedQueryResult,\n });\n\n set((state) =>\n produce(state, (draft) => {\n draft.mosaic.clients[id] = {\n id,\n client,\n createdAt: Date.now(),\n isLoading: true,\n data: null,\n selection,\n queryResultCallback: options.queryResult\n ? (result: unknown) => options.queryResult!(result as T)\n : undefined,\n };\n }),\n );\n\n return id;\n },\n\n ensureClient<T>(\n options: MosaicClientOptions<T> & {\n id: string;\n onQueryResult?: (result: T) => void;\n },\n ) {\n const {connection, clients} = get().mosaic;\n if (connection.status !== 'ready') {\n return; // Silently return if not ready - hook will handle retry\n }\n\n const existing = clients[options.id];\n\n // Determine which selection to use\n const selection =\n options.selection ??\n (options.selectionName\n ? get().mosaic.getSelection(options.selectionName)\n : undefined);\n\n // Check if client exists and selection matches\n // Note: If query or callback changes, we recreate the client to ensure\n // the latest versions are used. This is simpler than trying to update\n // the bound queryResult callback in makeClient.\n if (existing && existing.selection === selection) {\n return; // No-op - client already exists with same selection\n }\n\n // If exists but selection changed, destroy it first\n if (existing) {\n get().mosaic.destroyClient(options.id);\n }\n\n // Create new client with wrapped queryResult that calls both store update and external callback\n const wrappedQueryResult = (data: unknown) => {\n const typedData = data as T;\n set((state) =>\n produce(state, (draft) => {\n const tracked = draft.mosaic.clients[options.id];\n if (tracked) {\n tracked.data = typedData;\n tracked.isLoading = false;\n }\n }),\n );\n // Call external callback if provided\n options.onQueryResult?.(typedData);\n // Also call original queryResult if provided\n options.queryResult?.(typedData);\n };\n\n const client = makeClient({\n coordinator: connection.coordinator,\n selection,\n query: options.query,\n queryResult: wrappedQueryResult,\n });\n\n set((state) =>\n produce(state, (draft) => {\n draft.mosaic.clients[options.id] = {\n id: options.id,\n client,\n createdAt: Date.now(),\n isLoading: true,\n data: null,\n selection,\n queryResultCallback: options.onQueryResult as\n | ((result: unknown) => void)\n | undefined,\n };\n }),\n );\n },\n\n destroyClient(id: string) {\n const {connection, clients} = get().mosaic;\n const tracked = clients[id];\n if (!tracked) return;\n\n if (connection.status === 'ready') {\n connection.coordinator.disconnect(tracked.client);\n }\n\n set((state) =>\n produce(state, (draft) => {\n delete draft.mosaic.clients[id];\n }),\n );\n },\n\n destroyAllClients() {\n const {connection, clients} = get().mosaic;\n\n if (connection.status === 'ready') {\n Object.values(clients).forEach((tracked) => {\n connection.coordinator.disconnect(tracked.client);\n });\n }\n\n set((state) =>\n produce(state, (draft) => {\n draft.mosaic.clients = {};\n }),\n );\n },\n },\n }));\n}\n\nexport type DuckDbSliceStateWithMosaic = DuckDbSliceState & MosaicSliceState;\n\nexport function useStoreWithMosaic<T>(\n selector: (state: DuckDbSliceStateWithMosaic) => T,\n): T {\n return useBaseRoomStore<BaseRoomStoreState, T>((state) =>\n selector(state as unknown as DuckDbSliceStateWithMosaic),\n );\n}\n"]}
1
+ {"version":3,"file":"MosaicSlice.js","sourceRoot":"","sources":["../src/MosaicSlice.ts"],"names":[],"mappings":"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","sourcesContent":["import {createId} from '@paralleldrive/cuid2';\nimport {\n isWasmDuckDbConnector,\n type DuckDbConnector,\n type DuckDbSliceState,\n} from '@sqlrooms/duckdb';\nimport {\n BaseRoomStoreState,\n createSlice,\n useBaseRoomStore,\n type SliceFunctions,\n} from '@sqlrooms/room-store';\nimport type {\n ArrowQueryRequest,\n ExecQueryRequest,\n JSONQueryRequest,\n} from '@uwdata/mosaic-core';\nimport {\n Connector,\n Coordinator,\n coordinator,\n makeClient,\n Selection,\n wasmConnector,\n} from '@uwdata/mosaic-core';\nimport {Query} from '@uwdata/mosaic-sql';\nimport type {Table as ArrowTable} from 'apache-arrow';\nimport {produce} from 'immer';\nimport {z} from 'zod';\nimport {\n createMosaicTableFromArrowTable,\n toArrowClientResult,\n} from './tableInterop';\n\nexport const MosaicSliceConfig = z.object({});\nexport type MosaicSliceConfig = z.infer<typeof MosaicSliceConfig>;\n\nexport type MosaicPreAggregateOptions = {\n /** Database schema/namespace for Mosaic pre-aggregate tables. */\n schema?: string;\n /** Enable or disable Mosaic's pre-aggregation optimization. */\n enabled?: boolean;\n};\n\n// Client configuration options\nexport type MosaicClientOptions = {\n /** Unique identifier for this client */\n id?: string;\n /** Selection name for cross-filtering (will create if doesn't exist) */\n selectionName?: string;\n /** The selection to subscribe to for cross-filtering */\n selection?: Selection;\n /** Query builder function that receives the current filter */\n query: (filter: unknown) => ReturnType<typeof Query.from>;\n /** Callback when query results are received */\n queryResult?: (result: ArrowTable) => void;\n /** Callback when query execution fails */\n queryError?: (error: Error) => void;\n};\n\n// Tracked client info\nexport type TrackedClient = {\n id: string;\n client: ReturnType<typeof makeClient>;\n createdAt: number;\n isLoading: boolean;\n data: unknown | null;\n error?: Error;\n selection?: Selection; // Track for change detection\n queryResultCallback?: (result: ArrowTable) => void; // External callback\n};\n\nexport type MosaicSliceState = {\n mosaic: SliceFunctions & {\n connection:\n | {status: 'idle' | 'loading'}\n | {status: 'ready'; connector?: Connector; coordinator: Coordinator}\n | {status: 'error'; error: unknown};\n config: MosaicSliceConfig;\n /** Record of registered clients by id */\n clients: Record<string, TrackedClient>;\n /** Named selections for cross-filtering (e.g., 'brush', 'hover') */\n selections: Record<string, Selection>;\n initialize: () => Promise<void>;\n /** Get or create a named selection for cross-filtering */\n getSelection: (\n name: string,\n type?: 'crossfilter' | 'single' | 'union',\n ) => Selection;\n /** Create a mosaic client and register it */\n createClient: (options: MosaicClientOptions) => string;\n /** Ensure a client exists with given options (idempotent - creates or updates as needed) */\n ensureClient: (\n options: MosaicClientOptions & {\n id: string;\n onQueryResult?: (result: ArrowTable) => void;\n onQueryError?: (error: Error) => void;\n },\n ) => void;\n /** Disconnect and remove a client by id */\n destroyClient: (id: string) => void;\n /** Disconnect all clients (useful for cleanup) */\n destroyAllClients: () => void;\n };\n};\n\nexport function createDefaultMosaicConfig(\n props?: Partial<MosaicSliceConfig>,\n): MosaicSliceConfig {\n return {\n ...props,\n } as MosaicSliceConfig;\n}\n\nexport type CreateMosaicSliceProps = {\n config?: Partial<MosaicSliceConfig>;\n coordinator?: Coordinator;\n preagg?: MosaicPreAggregateOptions;\n};\n\nexport function createMosaicSlice(props: CreateMosaicSliceProps = {}) {\n return createSlice<\n MosaicSliceState,\n BaseRoomStoreState & DuckDbSliceState & MosaicSliceState\n >((set, get, store) => ({\n mosaic: {\n config: createDefaultMosaicConfig(props?.config),\n connection: {status: 'idle'},\n clients: {},\n selections: {},\n\n async initialize() {\n let mosaicConnector: Connector | undefined;\n let resolvedCoordinator!: Coordinator;\n set((state) =>\n produce(state, (draft) => {\n draft.mosaic.connection = {status: 'loading'};\n }),\n );\n try {\n if (props.coordinator) {\n resolvedCoordinator = props.coordinator;\n applyMosaicPreAggregateOptions(resolvedCoordinator, props.preagg);\n } else {\n const dbConnector = await get().db.getConnector();\n resolvedCoordinator = coordinator();\n mosaicConnector = isWasmDuckDbConnector(dbConnector)\n ? await wasmConnector({\n // @ts-expect-error - We install a different version of duckdb-wasm\n duckDb: dbConnector.getDb(),\n connection: dbConnector.getConnection(),\n })\n : createDuckDbMosaicConnector(dbConnector);\n applyMosaicPreAggregateOptions(resolvedCoordinator, props.preagg);\n resolvedCoordinator.databaseConnector(mosaicConnector);\n }\n } catch (error) {\n set((state) =>\n produce(state, (draft) => {\n draft.mosaic.connection = {status: 'error', error};\n }),\n );\n throw error;\n }\n set((state) =>\n produce(state, (draft) => {\n draft.mosaic.connection = {\n status: 'ready',\n connector: mosaicConnector,\n coordinator: resolvedCoordinator,\n };\n }),\n );\n },\n\n async destroy() {\n get().mosaic.destroyAllClients();\n },\n\n setConfig(config: MosaicSliceConfig) {\n set((state) =>\n produce(state, (draft) => {\n draft.mosaic.config = config;\n }),\n );\n },\n\n getSelection(\n name: string,\n type: 'crossfilter' | 'single' | 'union' = 'crossfilter',\n ) {\n const existing = get().mosaic.selections[name];\n if (existing) return existing;\n\n const selection =\n type === 'crossfilter'\n ? Selection.crossfilter()\n : type === 'single'\n ? Selection.single()\n : Selection.union();\n\n set((state) =>\n produce(state, (draft) => {\n draft.mosaic.selections[name] = selection;\n }),\n );\n return selection;\n },\n\n createClient(options: MosaicClientOptions) {\n const {connection} = get().mosaic;\n if (connection.status !== 'ready') {\n throw new Error('Mosaic connection not ready');\n }\n\n const id = options.id ?? createId();\n\n // Determine which selection to use\n const selection =\n options.selection ??\n (options.selectionName\n ? get().mosaic.getSelection(options.selectionName)\n : undefined);\n\n // Wrap queryResult to update store state AND call external callback\n const wrappedQueryResult = (data: unknown) => {\n set((state) =>\n produce(state, (draft) => {\n const tracked = draft.mosaic.clients[id];\n if (tracked) {\n tracked.data = data;\n tracked.isLoading = false;\n tracked.error = undefined;\n }\n }),\n );\n // Call external callback if provided\n options.queryResult?.(toArrowClientResult(data));\n };\n const wrappedQueryPending = () => {\n set((state) =>\n produce(state, (draft) => {\n const tracked = draft.mosaic.clients[id];\n if (tracked) {\n tracked.isLoading = true;\n tracked.error = undefined;\n }\n }),\n );\n };\n const wrappedQueryError = (error: Error) => {\n set((state) =>\n produce(state, (draft) => {\n const tracked = draft.mosaic.clients[id];\n if (tracked) {\n tracked.isLoading = false;\n tracked.error = error;\n }\n }),\n );\n client.enabled = false;\n options.queryError?.(error);\n };\n\n const client = makeClient({\n coordinator: connection.coordinator,\n selection,\n query: options.query,\n queryResult: wrappedQueryResult,\n queryPending: wrappedQueryPending,\n queryError: wrappedQueryError,\n });\n\n set((state) =>\n produce(state, (draft) => {\n draft.mosaic.clients[id] = {\n id,\n client,\n createdAt: Date.now(),\n isLoading: true,\n data: null,\n error: undefined,\n selection,\n queryResultCallback: options.queryResult\n ? (result: unknown) =>\n options.queryResult!(toArrowClientResult(result))\n : undefined,\n };\n }),\n );\n\n return id;\n },\n\n ensureClient(\n options: MosaicClientOptions & {\n id: string;\n onQueryResult?: (result: ArrowTable) => void;\n onQueryError?: (error: Error) => void;\n },\n ) {\n const {connection, clients} = get().mosaic;\n if (connection.status !== 'ready') {\n return; // Silently return if not ready - hook will handle retry\n }\n\n const existing = clients[options.id];\n\n // Determine which selection to use\n const selection =\n options.selection ??\n (options.selectionName\n ? get().mosaic.getSelection(options.selectionName)\n : undefined);\n\n // Check if client exists and selection matches\n // Note: If query or callback changes, we recreate the client to ensure\n // the latest versions are used. This is simpler than trying to update\n // the bound queryResult callback in makeClient.\n if (existing && existing.selection === selection) {\n return; // No-op - client already exists with same selection\n }\n\n // If exists but selection changed, destroy it first\n if (existing) {\n get().mosaic.destroyClient(options.id);\n }\n\n // Create new client with wrapped queryResult that calls both store update and external callback\n const wrappedQueryResult = (data: unknown) => {\n set((state) =>\n produce(state, (draft) => {\n const tracked = draft.mosaic.clients[options.id];\n if (tracked) {\n tracked.data = data;\n tracked.isLoading = false;\n tracked.error = undefined;\n }\n }),\n );\n const arrowData = toArrowClientResult(data);\n // Call external callback if provided\n options.onQueryResult?.(arrowData);\n // Also call original queryResult if provided\n options.queryResult?.(arrowData);\n };\n const wrappedQueryPending = () => {\n set((state) =>\n produce(state, (draft) => {\n const tracked = draft.mosaic.clients[options.id];\n if (tracked) {\n tracked.isLoading = true;\n tracked.error = undefined;\n }\n }),\n );\n };\n const wrappedQueryError = (error: Error) => {\n set((state) =>\n produce(state, (draft) => {\n const tracked = draft.mosaic.clients[options.id];\n if (tracked) {\n tracked.isLoading = false;\n tracked.error = error;\n }\n }),\n );\n client.enabled = false;\n options.onQueryError?.(error);\n options.queryError?.(error);\n };\n\n const client = makeClient({\n coordinator: connection.coordinator,\n selection,\n query: options.query,\n queryResult: wrappedQueryResult,\n queryPending: wrappedQueryPending,\n queryError: wrappedQueryError,\n });\n\n set((state) =>\n produce(state, (draft) => {\n draft.mosaic.clients[options.id] = {\n id: options.id,\n client,\n createdAt: Date.now(),\n isLoading: true,\n data: null,\n error: undefined,\n selection,\n queryResultCallback: options.onQueryResult\n ? (result: unknown) =>\n options.onQueryResult!(toArrowClientResult(result))\n : undefined,\n };\n }),\n );\n },\n\n destroyClient(id: string) {\n const {clients} = get().mosaic;\n const tracked = clients[id];\n if (!tracked) return;\n\n tracked.client.destroy();\n\n set((state) =>\n produce(state, (draft) => {\n delete draft.mosaic.clients[id];\n }),\n );\n },\n\n destroyAllClients() {\n const {clients} = get().mosaic;\n Object.values(clients).forEach((tracked) => {\n tracked.client.destroy();\n });\n\n set((state) =>\n produce(state, (draft) => {\n draft.mosaic.clients = {};\n }),\n );\n },\n },\n }));\n}\n\nfunction applyMosaicPreAggregateOptions(\n mosaicCoordinator: Coordinator,\n options?: MosaicPreAggregateOptions,\n) {\n if (!options) {\n return;\n }\n if (options.schema !== undefined) {\n mosaicCoordinator.preaggregator.schema = options.schema;\n }\n if (options.enabled !== undefined) {\n mosaicCoordinator.preaggregator.enabled = options.enabled;\n }\n}\n\nexport type DuckDbSliceStateWithMosaic = DuckDbSliceState & MosaicSliceState;\n\nexport function useStoreWithMosaic<T>(\n selector: (state: DuckDbSliceStateWithMosaic) => T,\n): T {\n return useBaseRoomStore<BaseRoomStoreState, T>((state) =>\n selector(state as unknown as DuckDbSliceStateWithMosaic),\n );\n}\n\n/**\n * Adapts a {@link DuckDbConnector} to the Mosaic {@link Connector} interface.\n *\n * For `'arrow'` queries the Apache Arrow table returned by the connector is\n * converted via {@link createMosaicTableFromArrowTable} into a flechette\n * `Table`, which is the shape Mosaic consumers expect (with `.toColumns()`).\n * For `'json'` queries, rows are materialized with {@link Array.from} which\n * may have performance/memory implications for very large result sets.\n * The `as any` casts on the return type are an intentional adapter trade-off\n * to satisfy the polymorphic {@link Connector['query']} signature.\n */\nfunction createDuckDbMosaicConnector(connector: DuckDbConnector): Connector {\n return {\n query: (async (\n query: ArrowQueryRequest | ExecQueryRequest | JSONQueryRequest,\n ) => {\n const queryType = query.type ?? 'arrow';\n if (queryType === 'exec') {\n await connector.execute(query.sql);\n return undefined as any;\n }\n if (queryType === 'json') {\n const rows = await connector.queryJson<Record<string, unknown>>(\n query.sql,\n );\n return Array.from(rows) as any;\n }\n if (queryType === 'arrow') {\n const arrowTable = await connector.query(query.sql);\n return createMosaicTableFromArrowTable(arrowTable) as any;\n }\n throw new Error(`Unsupported Mosaic query type \"${queryType}\".`);\n }) as Connector['query'],\n };\n}\n"]}
@@ -0,0 +1,23 @@
1
+ import { PropsWithChildren } from 'react';
2
+ export type PlotSize = {
3
+ width: number;
4
+ height: number;
5
+ };
6
+ export type ResponsivePlotProps = PropsWithChildren<{
7
+ onResize: (size: PlotSize) => void;
8
+ debounceMs?: number;
9
+ className?: string;
10
+ }>;
11
+ /**
12
+ * Container component that measures its size and notifies parent via callback.
13
+ * Uses ResizeObserver with debouncing to reduce update frequency.
14
+ * Exposes ref to the container div for direct DOM access.
15
+ */
16
+ export declare const ResponsivePlot: import("react").ForwardRefExoticComponent<{
17
+ onResize: (size: PlotSize) => void;
18
+ debounceMs?: number;
19
+ className?: string;
20
+ } & {
21
+ children?: import("react").ReactNode | undefined;
22
+ } & import("react").RefAttributes<HTMLDivElement>>;
23
+ //# sourceMappingURL=ResponsivePlot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResponsivePlot.d.ts","sourceRoot":"","sources":["../src/ResponsivePlot.tsx"],"names":[],"mappings":"AACA,OAAO,EAEL,iBAAiB,EAIlB,MAAM,OAAO,CAAC;AAEf,MAAM,MAAM,QAAQ,GAAG;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,iBAAiB,CAAC;IAClD,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,cAAc;cAVf,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI;iBACrB,MAAM;gBACP,MAAM;;;kDAqDnB,CAAC"}
@@ -0,0 +1,43 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cn, useDebouncedCallback } from '@sqlrooms/ui';
3
+ import { forwardRef, useEffect, useImperativeHandle, useRef, } from 'react';
4
+ /**
5
+ * Container component that measures its size and notifies parent via callback.
6
+ * Uses ResizeObserver with debouncing to reduce update frequency.
7
+ * Exposes ref to the container div for direct DOM access.
8
+ */
9
+ export const ResponsivePlot = forwardRef(({ onResize, debounceMs = 150, className, children }, ref) => {
10
+ const containerRef = useRef(null);
11
+ const lastSizeRef = useRef(null);
12
+ // Expose the internal ref to parent
13
+ useImperativeHandle(ref, () => containerRef.current, []);
14
+ // Debounced callback to reduce re-render frequency during resizing
15
+ const onResizeDebounced = useDebouncedCallback((size) => {
16
+ // Only call onResize if size actually changed
17
+ if (!lastSizeRef.current ||
18
+ lastSizeRef.current.width !== size.width ||
19
+ lastSizeRef.current.height !== size.height) {
20
+ lastSizeRef.current = size;
21
+ onResize(size);
22
+ }
23
+ }, debounceMs);
24
+ // Measure container size with ResizeObserver
25
+ useEffect(() => {
26
+ const container = containerRef.current;
27
+ if (!container)
28
+ return;
29
+ const resizeObserver = new ResizeObserver((entries) => {
30
+ for (const entry of entries) {
31
+ const { width, height } = entry.contentRect;
32
+ if (width > 0 && height > 0) {
33
+ onResizeDebounced({ width, height });
34
+ }
35
+ }
36
+ });
37
+ resizeObserver.observe(container);
38
+ return () => resizeObserver.disconnect();
39
+ }, [onResizeDebounced]);
40
+ return (_jsx("div", { ref: containerRef, className: cn('h-full w-full', className), children: children }));
41
+ });
42
+ ResponsivePlot.displayName = 'ResponsivePlot';
43
+ //# sourceMappingURL=ResponsivePlot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResponsivePlot.js","sourceRoot":"","sources":["../src/ResponsivePlot.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,EAAE,EAAE,oBAAoB,EAAC,MAAM,cAAc,CAAC;AACtD,OAAO,EACL,UAAU,EAEV,SAAS,EACT,mBAAmB,EACnB,MAAM,GACP,MAAM,OAAO,CAAC;AAaf;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CACtC,CAAC,EAAC,QAAQ,EAAE,UAAU,GAAG,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAC,EAAE,GAAG,EAAE,EAAE;IACzD,MAAM,YAAY,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAClD,MAAM,WAAW,GAAG,MAAM,CAAkB,IAAI,CAAC,CAAC;IAElD,oCAAoC;IACpC,mBAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,OAAQ,EAAE,EAAE,CAAC,CAAC;IAE1D,mEAAmE;IACnE,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,CAAC,IAAc,EAAE,EAAE;QAChE,8CAA8C;QAC9C,IACE,CAAC,WAAW,CAAC,OAAO;YACpB,WAAW,CAAC,OAAO,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK;YACxC,WAAW,CAAC,OAAO,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,EAC1C,CAAC;YACD,WAAW,CAAC,OAAO,GAAG,IAAI,CAAC;YAC3B,QAAQ,CAAC,IAAI,CAAC,CAAC;QACjB,CAAC;IACH,CAAC,EAAE,UAAU,CAAC,CAAC;IAEf,6CAA6C;IAC7C,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC;QACvC,IAAI,CAAC,SAAS;YAAE,OAAO;QAEvB,MAAM,cAAc,GAAG,IAAI,cAAc,CAAC,CAAC,OAAO,EAAE,EAAE;YACpD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,MAAM,EAAC,KAAK,EAAE,MAAM,EAAC,GAAG,KAAK,CAAC,WAAW,CAAC;gBAC1C,IAAI,KAAK,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC5B,iBAAiB,CAAC,EAAC,KAAK,EAAE,MAAM,EAAC,CAAC,CAAC;gBACrC,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,cAAc,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAClC,OAAO,GAAG,EAAE,CAAC,cAAc,CAAC,UAAU,EAAE,CAAC;IAC3C,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAExB,OAAO,CACL,cAAK,GAAG,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,CAAC,eAAe,EAAE,SAAS,CAAC,YAC9D,QAAQ,GACL,CACP,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,cAAc,CAAC,WAAW,GAAG,gBAAgB,CAAC","sourcesContent":["import {cn, useDebouncedCallback} from '@sqlrooms/ui';\nimport {\n forwardRef,\n PropsWithChildren,\n useEffect,\n useImperativeHandle,\n useRef,\n} from 'react';\n\nexport type PlotSize = {\n width: number;\n height: number;\n};\n\nexport type ResponsivePlotProps = PropsWithChildren<{\n onResize: (size: PlotSize) => void;\n debounceMs?: number;\n className?: string;\n}>;\n\n/**\n * Container component that measures its size and notifies parent via callback.\n * Uses ResizeObserver with debouncing to reduce update frequency.\n * Exposes ref to the container div for direct DOM access.\n */\nexport const ResponsivePlot = forwardRef<HTMLDivElement, ResponsivePlotProps>(\n ({onResize, debounceMs = 150, className, children}, ref) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const lastSizeRef = useRef<PlotSize | null>(null);\n\n // Expose the internal ref to parent\n useImperativeHandle(ref, () => containerRef.current!, []);\n\n // Debounced callback to reduce re-render frequency during resizing\n const onResizeDebounced = useDebouncedCallback((size: PlotSize) => {\n // Only call onResize if size actually changed\n if (\n !lastSizeRef.current ||\n lastSizeRef.current.width !== size.width ||\n lastSizeRef.current.height !== size.height\n ) {\n lastSizeRef.current = size;\n onResize(size);\n }\n }, debounceMs);\n\n // Measure container size with ResizeObserver\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const {width, height} = entry.contentRect;\n if (width > 0 && height > 0) {\n onResizeDebounced({width, height});\n }\n }\n });\n\n resizeObserver.observe(container);\n return () => resizeObserver.disconnect();\n }, [onResizeDebounced]);\n\n return (\n <div ref={containerRef} className={cn('h-full w-full', className)}>\n {children}\n </div>\n );\n },\n);\n\nResponsivePlot.displayName = 'ResponsivePlot';\n"]}
@@ -1,14 +1,38 @@
1
+ import { Param, Selection } from '@uwdata/mosaic-core';
1
2
  import { Spec } from '@uwdata/mosaic-spec';
2
3
  import { FC } from 'react';
3
4
  type SpecProps = {
4
5
  spec: Spec;
6
+ /**
7
+ * Pre-defined params/selections to inject when rendering the spec.
8
+ * Keys are param names (without $), values are Param or Selection instances.
9
+ * This allows multiple independently-rendered specs to share the same
10
+ * Selection objects for cross-filtering.
11
+ */
12
+ params?: Map<string, Param<any> | Selection>;
13
+ /**
14
+ * Optional retention adapter for preserving the underlying vgplot
15
+ * instance across temporary unmount/remount cycles, such as dashboard tab
16
+ * switches.
17
+ */
18
+ retention?: VgPlotChartRetention;
5
19
  };
6
20
  type PlotProps = {
7
21
  plot: HTMLElement | SVGSVGElement;
8
22
  };
9
23
  type VgPlotChartProps = SpecProps | PlotProps;
24
+ export type RetainedVgPlotChart = {
25
+ element: object;
26
+ params?: Map<string, Param<any> | Selection>;
27
+ specKey: string;
28
+ };
29
+ export type VgPlotChartRetention = {
30
+ chart?: RetainedVgPlotChart;
31
+ setChart: (chart: RetainedVgPlotChart) => void;
32
+ };
10
33
  export declare function isSpecProps(props: VgPlotChartProps): props is SpecProps;
11
34
  export declare function isPlotProps(props: VgPlotChartProps): props is PlotProps;
35
+ export declare function destroyRetainedVgPlotChart(chart: RetainedVgPlotChart): void;
12
36
  /**
13
37
  * Renders a Vega-Lite chart using the Mosaic library.
14
38
  *
@@ -1 +1 @@
1
- {"version":3,"file":"VgPlotChart.d.ts","sourceRoot":"","sources":["../src/VgPlotChart.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAsB,IAAI,EAAC,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAC,EAAE,EAAoB,MAAM,OAAO,CAAC;AAE5C,KAAK,SAAS,GAAG;IAAC,IAAI,EAAE,IAAI,CAAA;CAAC,CAAC;AAC9B,KAAK,SAAS,GAAG;IAAC,IAAI,EAAE,WAAW,GAAG,aAAa,CAAA;CAAC,CAAC;AACrD,KAAK,gBAAgB,GAAG,SAAS,GAAG,SAAS,CAAC;AAE9C,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,KAAK,IAAI,SAAS,CAEvE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,KAAK,IAAI,SAAS,CAEvE;AAED;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CAqB5C,CAAC"}
1
+ {"version":3,"file":"VgPlotChart.d.ts","sourceRoot":"","sources":["../src/VgPlotChart.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAE,SAAS,EAAC,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAsB,IAAI,EAAC,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EACL,EAAE,EAOH,MAAM,OAAO,CAAC;AAGf,KAAK,SAAS,GAAG;IACf,IAAI,EAAE,IAAI,CAAC;IACX;;;;;OAKG;IACH,MAAM,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC;IAC7C;;;;OAIG;IACH,SAAS,CAAC,EAAE,oBAAoB,CAAC;CAClC,CAAC;AACF,KAAK,SAAS,GAAG;IAAC,IAAI,EAAE,WAAW,GAAG,aAAa,CAAA;CAAC,CAAC;AACrD,KAAK,gBAAgB,GAAG,SAAS,GAAG,SAAS,CAAC;AAG9C,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;CACjB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,CAAC,EAAE,mBAAmB,CAAC;IAC5B,QAAQ,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAC;CAChD,CAAC;AA0BF,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,KAAK,IAAI,SAAS,CAEvE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,KAAK,IAAI,SAAS,CAEvE;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,mBAAmB,QAKpE;AA4CD;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CA4G5C,CAAC"}