@malloy-publisher/sdk 0.0.137 → 0.0.139

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 (586) hide show
  1. package/README.md +122 -1
  2. package/dist/ServerProvider-Bzid56gJ.cjs.js +1 -0
  3. package/dist/{ServerProvider-BGGK1ZQ_.es.js → ServerProvider-D-y63tG0.es.js} +550 -478
  4. package/dist/client/api.d.ts +144 -53
  5. package/dist/client/index.cjs.js +1 -1
  6. package/dist/client/index.es.js +22 -21
  7. package/dist/components/Notebook/Notebook.d.ts +4 -1
  8. package/dist/components/Notebook/NotebookCell.d.ts +2 -2
  9. package/dist/components/Notebook/types.d.ts +21 -0
  10. package/dist/components/filter/DimensionFilter.d.ts +43 -0
  11. package/dist/components/filter/index.d.ts +4 -0
  12. package/dist/components/filter/utils.d.ts +75 -0
  13. package/dist/components/index.d.ts +7 -6
  14. package/dist/components/styles.d.ts +3 -3
  15. package/dist/hooks/index.d.ts +4 -0
  16. package/dist/hooks/useDimensionFilters.d.ts +84 -0
  17. package/dist/hooks/useDimensionFiltersFromSpec.d.ts +52 -0
  18. package/dist/hooks/useDimensionFiltersQuery.d.ts +79 -0
  19. package/dist/hooks/useDimensionalFilterRangeData.d.ts +106 -0
  20. package/dist/index.cjs.js +141 -112
  21. package/dist/index.d.ts +3 -2
  22. package/dist/index.es.js +47903 -39798
  23. package/dist/sdk.css +1 -1
  24. package/package.json +16 -11
  25. package/src/components/Home/Home.tsx +15 -11
  26. package/src/components/Notebook/Notebook.tsx +391 -6
  27. package/src/components/Notebook/NotebookCell.tsx +2 -2
  28. package/src/components/Notebook/types.ts +24 -0
  29. package/src/components/Package/Connections.tsx +3 -6
  30. package/src/components/RenderedResult/RenderedResult.tsx +22 -3
  31. package/src/components/filter/DimensionFilter.tsx +738 -0
  32. package/src/components/filter/index.ts +20 -0
  33. package/src/components/filter/utils.ts +354 -0
  34. package/src/components/highlighter.ts +14 -6
  35. package/src/components/index.ts +7 -6
  36. package/src/hooks/index.ts +31 -0
  37. package/src/hooks/useDimensionFilters.ts +322 -0
  38. package/src/hooks/useDimensionFiltersFromSpec.ts +117 -0
  39. package/src/hooks/useDimensionFiltersQuery.ts +300 -0
  40. package/src/hooks/useDimensionalFilterRangeData.ts +758 -0
  41. package/src/index.ts +3 -2
  42. package/dist/ServerProvider-lXAaPKBb.cjs.js +0 -1
  43. package/dist/abap-BmBUA35e.es.js +0 -6
  44. package/dist/abap-Dwt2rH6y.cjs.js +0 -1
  45. package/dist/actionscript-3-mj8Uhnsc.cjs.js +0 -1
  46. package/dist/actionscript-3-zFUbzQa9.es.js +0 -6
  47. package/dist/ada-CBvPkFpZ.es.js +0 -6
  48. package/dist/ada-DZM58Vqs.cjs.js +0 -1
  49. package/dist/andromeeda-BXc5FOIb.cjs.js +0 -1
  50. package/dist/andromeeda-uXNdzNpk.es.js +0 -4
  51. package/dist/angular-html-B60m4jt-.cjs.js +0 -1
  52. package/dist/angular-html-D3aW1y6T.es.js +0 -32
  53. package/dist/angular-ts-Jud40GrY.es.js +0 -21
  54. package/dist/angular-ts-SIlYrqkG.cjs.js +0 -1
  55. package/dist/apache-CVNlsSDc.es.js +0 -6
  56. package/dist/apache-D7v5fxtZ.cjs.js +0 -1
  57. package/dist/apex-4hrAnw0a.cjs.js +0 -1
  58. package/dist/apex-DFk3KRB1.es.js +0 -6
  59. package/dist/apl-CKSaOFbt.cjs.js +0 -1
  60. package/dist/apl-pE3PRTDr.es.js +0 -16
  61. package/dist/applescript-CYMR_y0g.es.js +0 -6
  62. package/dist/applescript-Cnd3Dxju.cjs.js +0 -1
  63. package/dist/ara-4QmU5e04.es.js +0 -6
  64. package/dist/ara-BQ2aGbFQ.cjs.js +0 -1
  65. package/dist/asciidoc-C6nYvw8K.cjs.js +0 -1
  66. package/dist/asciidoc-v_1bjgUg.es.js +0 -6
  67. package/dist/asm-CQnBVCj-.cjs.js +0 -1
  68. package/dist/asm-RC0Yh-NZ.es.js +0 -6
  69. package/dist/astro-Be6fybGX.es.js +0 -16
  70. package/dist/astro-KhYkz6Xu.cjs.js +0 -1
  71. package/dist/aurora-x-BwoVEUWZ.es.js +0 -4
  72. package/dist/aurora-x-C5IpmIOG.cjs.js +0 -1
  73. package/dist/awk-DUx4h__E.cjs.js +0 -1
  74. package/dist/awk-gPH8MVMW.es.js +0 -6
  75. package/dist/ayu-dark-Cv7nTiif.cjs.js +0 -1
  76. package/dist/ayu-dark-CxPZkpb2.es.js +0 -4
  77. package/dist/ballerina-CXlzbmzl.cjs.js +0 -1
  78. package/dist/ballerina-kvLnRU_e.es.js +0 -6
  79. package/dist/bat-BHYy44sT.es.js +0 -6
  80. package/dist/bat-DlMT9sut.cjs.js +0 -1
  81. package/dist/beancount-CyyiuUzM.cjs.js +0 -1
  82. package/dist/beancount-D-MADTs_.es.js +0 -6
  83. package/dist/berry-B0EjuzrL.cjs.js +0 -1
  84. package/dist/berry-Ci9U0o4h.es.js +0 -6
  85. package/dist/bibtex-CX618D15.es.js +0 -6
  86. package/dist/bibtex-CfoG9xRq.cjs.js +0 -1
  87. package/dist/bicep-D6PH_9IY.cjs.js +0 -1
  88. package/dist/bicep-iuYiPopT.es.js +0 -6
  89. package/dist/blade-C0tMuk8f.cjs.js +0 -1
  90. package/dist/blade-DmXp5Zcz.es.js +0 -18
  91. package/dist/bsl-CfHcite8.cjs.js +0 -1
  92. package/dist/bsl-NPX_d-bb.es.js +0 -8
  93. package/dist/c-C4sXGJZM.cjs.js +0 -1
  94. package/dist/c-DASdrs7p.es.js +0 -6
  95. package/dist/cadence-BDALQi26.es.js +0 -6
  96. package/dist/cadence-Dq2CYzXG.cjs.js +0 -1
  97. package/dist/cairo-17kO8-kb.es.js +0 -8
  98. package/dist/cairo-CcKpJkyf.cjs.js +0 -1
  99. package/dist/catppuccin-frappe-BrTOiad2.es.js +0 -4
  100. package/dist/catppuccin-frappe-DXAedND3.cjs.js +0 -1
  101. package/dist/catppuccin-latte-D-dc_R4m.es.js +0 -4
  102. package/dist/catppuccin-latte-mwGw3-Ej.cjs.js +0 -1
  103. package/dist/catppuccin-macchiato-DN4jOp0G.es.js +0 -4
  104. package/dist/catppuccin-macchiato-cQCk9ADg.cjs.js +0 -1
  105. package/dist/catppuccin-mocha-B8yCE3-3.es.js +0 -4
  106. package/dist/catppuccin-mocha-ClSzDZSl.cjs.js +0 -1
  107. package/dist/clarity-CNgV2Ths.es.js +0 -6
  108. package/dist/clarity-ytMkUD5Q.cjs.js +0 -1
  109. package/dist/clojure-B_Wv414H.cjs.js +0 -1
  110. package/dist/clojure-CsKKFGwv.es.js +0 -6
  111. package/dist/cmake-Dr-A3iJx.es.js +0 -6
  112. package/dist/cmake-TBUaQXYY.cjs.js +0 -1
  113. package/dist/cobol-BzcJm6ie.es.js +0 -10
  114. package/dist/cobol-DXFNH4EH.cjs.js +0 -1
  115. package/dist/codeowners-Bt9yU6NX.es.js +0 -6
  116. package/dist/codeowners-QhPK6lIJ.cjs.js +0 -1
  117. package/dist/codeql-B7Q9tkDJ.cjs.js +0 -1
  118. package/dist/codeql-DBNTqJi1.es.js +0 -6
  119. package/dist/coffee-GRRSkgX1.cjs.js +0 -1
  120. package/dist/coffee-q2iaxUnQ.es.js +0 -8
  121. package/dist/common-lisp-Ced3ctK5.cjs.js +0 -1
  122. package/dist/common-lisp-r7ZEOG7T.es.js +0 -6
  123. package/dist/coq-BTRB4iqi.cjs.js +0 -1
  124. package/dist/coq-CB6Pv_W9.es.js +0 -6
  125. package/dist/cpp-CPOvHZqs.cjs.js +0 -1
  126. package/dist/cpp-CPQtoCcU.es.js +0 -18
  127. package/dist/crystal-BY_Cg265.es.js +0 -18
  128. package/dist/crystal-C6AG-iew.cjs.js +0 -1
  129. package/dist/csharp-CYWRhZ2R.es.js +0 -6
  130. package/dist/csharp-TKds-MhG.cjs.js +0 -1
  131. package/dist/css-B0kbn78J.cjs.js +0 -1
  132. package/dist/css-D1aVdRIU.es.js +0 -6
  133. package/dist/csv-BVJjiaC3.cjs.js +0 -1
  134. package/dist/csv-DvCncUGQ.es.js +0 -6
  135. package/dist/cue-BXMrmvay.es.js +0 -6
  136. package/dist/cue-Cz4J-rnd.cjs.js +0 -1
  137. package/dist/cypher-DTm5zNR1.es.js +0 -6
  138. package/dist/cypher-DuKTiyez.cjs.js +0 -1
  139. package/dist/d-BW9Wd7aK.cjs.js +0 -1
  140. package/dist/d-D6ZXmn3l.es.js +0 -6
  141. package/dist/dark-plus-Cd5emcYO.cjs.js +0 -1
  142. package/dist/dark-plus-pUHDTVV0.es.js +0 -4
  143. package/dist/dart-CWs-er6b.cjs.js +0 -1
  144. package/dist/dart-Dz59Is3F.es.js +0 -6
  145. package/dist/dax-CDxFL2Kb.cjs.js +0 -1
  146. package/dist/dax-DTVGzydb.es.js +0 -6
  147. package/dist/desktop-CFgo0jo7.cjs.js +0 -1
  148. package/dist/desktop-Db9vb-dl.es.js +0 -6
  149. package/dist/diff-BsEkKwI8.cjs.js +0 -1
  150. package/dist/diff-XmNrvgM1.es.js +0 -6
  151. package/dist/docker-DWH2onkn.es.js +0 -6
  152. package/dist/docker-hwiw4W8I.cjs.js +0 -1
  153. package/dist/dotenv-4337wvzu.es.js +0 -6
  154. package/dist/dotenv-CJ5o3G1C.cjs.js +0 -1
  155. package/dist/dracula-BNgwAJ-d.cjs.js +0 -1
  156. package/dist/dracula-BtZx2Kac.es.js +0 -4
  157. package/dist/dracula-soft-BHZ7sHFu.cjs.js +0 -1
  158. package/dist/dracula-soft-BKa-aqBv.es.js +0 -4
  159. package/dist/dream-maker-CvvfrJSx.es.js +0 -6
  160. package/dist/dream-maker-DBharE9Q.cjs.js +0 -1
  161. package/dist/edge-DI6_BHKG.es.js +0 -12
  162. package/dist/edge-i77KJtJz.cjs.js +0 -1
  163. package/dist/elixir-D00NoPSM.cjs.js +0 -1
  164. package/dist/elixir-ic9y5jcd.es.js +0 -8
  165. package/dist/elm-Bhj5Vf-e.cjs.js +0 -1
  166. package/dist/elm-DxnUqUaW.es.js +0 -8
  167. package/dist/emacs-lisp-BAefI874.es.js +0 -6
  168. package/dist/emacs-lisp-CDDyFsvQ.cjs.js +0 -1
  169. package/dist/erb-Cbj2YePa.es.js +0 -10
  170. package/dist/erb-Dybaw01v.cjs.js +0 -1
  171. package/dist/erlang-3VgdrQXV.cjs.js +0 -1
  172. package/dist/erlang-CmIiwF3I.es.js +0 -6
  173. package/dist/everforest-dark-DMCBqXCK.es.js +0 -4
  174. package/dist/everforest-dark-_sBMomR1.cjs.js +0 -1
  175. package/dist/everforest-light-BbXl82Em.es.js +0 -4
  176. package/dist/everforest-light-H0xoYxl0.cjs.js +0 -1
  177. package/dist/fennel-BvcDRFAV.cjs.js +0 -1
  178. package/dist/fennel-DNqkz9pE.es.js +0 -6
  179. package/dist/fish-CnamI0Ar.cjs.js +0 -1
  180. package/dist/fish-DIm72t2T.es.js +0 -6
  181. package/dist/fluent-BapTxJsC.es.js +0 -6
  182. package/dist/fluent-DFpT66K8.cjs.js +0 -1
  183. package/dist/fortran-fixed-form-DECY15PY.es.js +0 -8
  184. package/dist/fortran-fixed-form-u_RcUPMu.cjs.js +0 -1
  185. package/dist/fortran-free-form-CNDsBFUj.es.js +0 -6
  186. package/dist/fortran-free-form-IaGrWIda.cjs.js +0 -1
  187. package/dist/fsharp-B-aK2rr3.cjs.js +0 -1
  188. package/dist/fsharp-D2ZqviWP.es.js +0 -8
  189. package/dist/gdresource-BBAqNWe4.cjs.js +0 -1
  190. package/dist/gdresource-RIsK8sku.es.js +0 -10
  191. package/dist/gdscript-5N_43TPQ.cjs.js +0 -1
  192. package/dist/gdscript-D7aheHm-.es.js +0 -6
  193. package/dist/gdshader-BGJEsM2Z.es.js +0 -6
  194. package/dist/gdshader-Bl85Hrm5.cjs.js +0 -1
  195. package/dist/genie-C9gPjc6J.es.js +0 -6
  196. package/dist/genie-DGsxMAbQ.cjs.js +0 -1
  197. package/dist/gherkin-CVV6nEUH.cjs.js +0 -1
  198. package/dist/gherkin-bka1Exbx.es.js +0 -6
  199. package/dist/git-commit-BRJ1E4Bx.es.js +0 -8
  200. package/dist/git-commit-CwfgI4fD.cjs.js +0 -1
  201. package/dist/git-rebase-C3X7aMpn.es.js +0 -8
  202. package/dist/git-rebase-DUvbIQDw.cjs.js +0 -1
  203. package/dist/github-dark-BKL9xNgN.cjs.js +0 -1
  204. package/dist/github-dark-DenFmJkN.es.js +0 -4
  205. package/dist/github-dark-default-BJPUVz4H.es.js +0 -4
  206. package/dist/github-dark-default-Dsv5MuSi.cjs.js +0 -1
  207. package/dist/github-dark-dimmed-CtB9hz8U.cjs.js +0 -1
  208. package/dist/github-dark-dimmed-DUshB20C.es.js +0 -4
  209. package/dist/github-dark-high-contrast-BqZVM-jF.cjs.js +0 -1
  210. package/dist/github-dark-high-contrast-D3aGCnF8.es.js +0 -4
  211. package/dist/github-light-BFTOhCbz.cjs.js +0 -1
  212. package/dist/github-light-JYsPkUQd.es.js +0 -4
  213. package/dist/github-light-default-BZoWH9dH.cjs.js +0 -1
  214. package/dist/github-light-default-D99KPAby.es.js +0 -4
  215. package/dist/github-light-high-contrast-BbmZE-Mp.es.js +0 -4
  216. package/dist/github-light-high-contrast-Ks3kPGJU.cjs.js +0 -1
  217. package/dist/gleam-B4k9YFGD.es.js +0 -6
  218. package/dist/gleam-nR4mjrhK.cjs.js +0 -1
  219. package/dist/glimmer-js-C4MQf3Na.es.js +0 -14
  220. package/dist/glimmer-js-CNfyUqSb.cjs.js +0 -1
  221. package/dist/glimmer-ts-Bp7_dELi.cjs.js +0 -1
  222. package/dist/glimmer-ts-CoYpqZrZ.es.js +0 -14
  223. package/dist/glsl-BYTq1Tfl.es.js +0 -8
  224. package/dist/glsl-CIu1PL9X.cjs.js +0 -1
  225. package/dist/gnuplot-CurtDYoJ.cjs.js +0 -1
  226. package/dist/gnuplot-DnWoRZt-.es.js +0 -6
  227. package/dist/go-BErP6iv1.es.js +0 -6
  228. package/dist/go-CM9_GlwL.cjs.js +0 -1
  229. package/dist/graphql-BnnSMMC2.cjs.js +0 -1
  230. package/dist/graphql-g3nHRc0M.es.js +0 -14
  231. package/dist/groovy-BaVp9Il5.cjs.js +0 -1
  232. package/dist/groovy-IWs5-NIO.es.js +0 -6
  233. package/dist/hack-BVxH3fsq.cjs.js +0 -1
  234. package/dist/hack-wPAsyujS.es.js +0 -10
  235. package/dist/haml-4TJ757dz.es.js +0 -10
  236. package/dist/haml-vutdexHh.cjs.js +0 -1
  237. package/dist/handlebars-7GDLw__F.es.js +0 -14
  238. package/dist/handlebars-COmZnO8P.cjs.js +0 -1
  239. package/dist/haskell-CtlGos0K.es.js +0 -6
  240. package/dist/haskell-suhyCHEm.cjs.js +0 -1
  241. package/dist/haxe-BIQU1qHi.cjs.js +0 -1
  242. package/dist/haxe-CZZ33vZw.es.js +0 -6
  243. package/dist/hcl-6hOg9WP4.es.js +0 -6
  244. package/dist/hcl-CbQ1yCnz.cjs.js +0 -1
  245. package/dist/hjson-CgwED-oz.es.js +0 -6
  246. package/dist/hjson-Ddklb4QM.cjs.js +0 -1
  247. package/dist/hlsl-3-lv4gi7.es.js +0 -6
  248. package/dist/hlsl-B4NkiBfC.cjs.js +0 -1
  249. package/dist/houston-BDYrDoDW.es.js +0 -4
  250. package/dist/houston-T57H3gQZ.cjs.js +0 -1
  251. package/dist/html-Dc-Bg17s.cjs.js +0 -1
  252. package/dist/html-PSPajZka.es.js +0 -10
  253. package/dist/html-derivative-Brb3b4aI.es.js +0 -8
  254. package/dist/html-derivative-CY9mJeT0.cjs.js +0 -1
  255. package/dist/http-BrKsebcH.cjs.js +0 -1
  256. package/dist/http-CWBcr-Ch.es.js +0 -14
  257. package/dist/hxml-DLduiIv3.es.js +0 -8
  258. package/dist/hxml-DbGPHkY4.cjs.js +0 -1
  259. package/dist/hy-C2xHhR6I.es.js +0 -6
  260. package/dist/hy-DpyTdO3T.cjs.js +0 -1
  261. package/dist/imba-BEYqRZzB.es.js +0 -8
  262. package/dist/imba-CAIkF-GD.cjs.js +0 -1
  263. package/dist/ini-BUcvsX-U.es.js +0 -6
  264. package/dist/ini-CymULaw_.cjs.js +0 -1
  265. package/dist/java-B7odJ7Ap.es.js +0 -6
  266. package/dist/java-Bn1Lvoni.cjs.js +0 -1
  267. package/dist/javascript-Bnnicc83.cjs.js +0 -1
  268. package/dist/javascript-fa8UlHZE.es.js +0 -6
  269. package/dist/jinja-BoeZymy4.cjs.js +0 -1
  270. package/dist/jinja-DKLHYjK0.es.js +0 -11
  271. package/dist/jison-C0DlFEjB.cjs.js +0 -1
  272. package/dist/jison-CzPfUIvM.es.js +0 -8
  273. package/dist/json-71t8ZF9g.es.js +0 -6
  274. package/dist/json-y-J1j5EW.cjs.js +0 -1
  275. package/dist/json5-CzvlWgZ7.cjs.js +0 -1
  276. package/dist/json5-Z7F6rA6a.es.js +0 -6
  277. package/dist/jsonc-BnhWfmQw.cjs.js +0 -1
  278. package/dist/jsonc-Dphhs4m2.es.js +0 -6
  279. package/dist/jsonl-BbGkWPJz.cjs.js +0 -1
  280. package/dist/jsonl-D9jj92Gg.es.js +0 -6
  281. package/dist/jsonnet-Bn--UDZ1.cjs.js +0 -1
  282. package/dist/jsonnet-DEQ7IUoJ.es.js +0 -6
  283. package/dist/jssm-4CSVp8lc.cjs.js +0 -1
  284. package/dist/jssm-j74e88UX.es.js +0 -6
  285. package/dist/jsx-Bkesy5tT.es.js +0 -6
  286. package/dist/jsx-D8YwVp-7.cjs.js +0 -1
  287. package/dist/julia-B_r6juN7.es.js +0 -16
  288. package/dist/julia-DLxGoAlk.cjs.js +0 -1
  289. package/dist/kanagawa-dragon-BJZF7xDr.cjs.js +0 -1
  290. package/dist/kanagawa-dragon-CiKur4Hl.es.js +0 -4
  291. package/dist/kanagawa-lotus-BKu-smKu.es.js +0 -4
  292. package/dist/kanagawa-lotus-BhgzmRV4.cjs.js +0 -1
  293. package/dist/kanagawa-wave-BgJip59C.cjs.js +0 -1
  294. package/dist/kanagawa-wave-CQwozSzG.es.js +0 -4
  295. package/dist/kotlin-DCgZY7Ii.es.js +0 -6
  296. package/dist/kotlin-DDI6myF6.cjs.js +0 -1
  297. package/dist/kusto-Cw029H-v.es.js +0 -6
  298. package/dist/kusto-OZxALJZT.cjs.js +0 -1
  299. package/dist/laserwave--izBLY1I.cjs.js +0 -1
  300. package/dist/laserwave-6a00oqik.es.js +0 -4
  301. package/dist/latex-CXOK56Uv.cjs.js +0 -1
  302. package/dist/latex-GxBxlqbc.es.js +0 -8
  303. package/dist/lean-CYSet4vs.es.js +0 -6
  304. package/dist/lean-D1iY-35j.cjs.js +0 -1
  305. package/dist/less-DIaY7vQJ.cjs.js +0 -1
  306. package/dist/less-DQA4v-Nm.es.js +0 -6
  307. package/dist/light-plus-B5D0le0o.cjs.js +0 -1
  308. package/dist/light-plus-CZuVqSLX.es.js +0 -4
  309. package/dist/liquid-BYouVITI.cjs.js +0 -1
  310. package/dist/liquid-BxBkR-z5.es.js +0 -14
  311. package/dist/log-BIXUeBaj.cjs.js +0 -1
  312. package/dist/log-D2eRfqDn.es.js +0 -6
  313. package/dist/logo-B2d3b27P.cjs.js +0 -1
  314. package/dist/logo-QEAtGWZ9.es.js +0 -6
  315. package/dist/lua-B2_GGnC5.cjs.js +0 -1
  316. package/dist/lua-DeXVjwzF.es.js +0 -8
  317. package/dist/luau-BjYGiqID.es.js +0 -6
  318. package/dist/luau-CvqAeq4F.cjs.js +0 -1
  319. package/dist/make-BjuHP00g.es.js +0 -6
  320. package/dist/make-Oob5Z9Pk.cjs.js +0 -1
  321. package/dist/markdown-B6guhLWd.es.js +0 -6
  322. package/dist/markdown-BGBuj4LZ.cjs.js +0 -1
  323. package/dist/marko-CS7eEGs3.cjs.js +0 -1
  324. package/dist/marko-DwPYPpB3.es.js +0 -14
  325. package/dist/material-theme-D6KBX41T.es.js +0 -4
  326. package/dist/material-theme-Dj0-OyRN.cjs.js +0 -1
  327. package/dist/material-theme-darker-CkRroheE.es.js +0 -4
  328. package/dist/material-theme-darker-Dvfs29ir.cjs.js +0 -1
  329. package/dist/material-theme-lighter-BUBw43Yz.es.js +0 -4
  330. package/dist/material-theme-lighter-EU3ZGl_r.cjs.js +0 -1
  331. package/dist/material-theme-ocean-ClGX14Ja.es.js +0 -4
  332. package/dist/material-theme-ocean-px_3Pwqa.cjs.js +0 -1
  333. package/dist/material-theme-palenight-38jxvsGX.cjs.js +0 -1
  334. package/dist/material-theme-palenight-C1RVm8K1.es.js +0 -4
  335. package/dist/matlab-BpQlIJiw.es.js +0 -6
  336. package/dist/matlab-CbN2rF6P.cjs.js +0 -1
  337. package/dist/mdc-Bkl-bu_Z.cjs.js +0 -1
  338. package/dist/mdc-X4YjkufV.es.js +0 -12
  339. package/dist/mdx-Cl31h8mi.cjs.js +0 -1
  340. package/dist/mdx-DIoECIFU.es.js +0 -6
  341. package/dist/mermaid-BZ7WHNIe.es.js +0 -6
  342. package/dist/mermaid-CSogK_LM.cjs.js +0 -1
  343. package/dist/min-dark-C7ak0t6c.es.js +0 -4
  344. package/dist/min-dark-tt5o_I5e.cjs.js +0 -1
  345. package/dist/min-light-CKFxVcPp.es.js +0 -4
  346. package/dist/min-light-tmTHl_CQ.cjs.js +0 -1
  347. package/dist/mipsasm-BseoYJQp.cjs.js +0 -1
  348. package/dist/mipsasm-DusDYkFc.es.js +0 -6
  349. package/dist/mojo-CY9jaezJ.es.js +0 -6
  350. package/dist/mojo-D8QAG3Ze.cjs.js +0 -1
  351. package/dist/monokai-C1KBYcO0.es.js +0 -4
  352. package/dist/monokai-DMIxv6MM.cjs.js +0 -1
  353. package/dist/move-ChphFumd.es.js +0 -6
  354. package/dist/move-DaBrcjat.cjs.js +0 -1
  355. package/dist/narrat-Dz4d7OmN.es.js +0 -6
  356. package/dist/narrat-oOfAO4q8.cjs.js +0 -1
  357. package/dist/nextflow-BxJSKvPb.cjs.js +0 -1
  358. package/dist/nextflow-DW0Yq9a2.es.js +0 -6
  359. package/dist/nginx-ChI-VqNT.es.js +0 -8
  360. package/dist/nginx-LuyFICzP.cjs.js +0 -1
  361. package/dist/night-owl-BN78kThQ.cjs.js +0 -1
  362. package/dist/night-owl-Bm2rzalh.es.js +0 -4
  363. package/dist/nim-BiJA-5u7.es.js +0 -20
  364. package/dist/nim-DkC83hsN.cjs.js +0 -1
  365. package/dist/nix-Cg5uV_xg.es.js +0 -6
  366. package/dist/nix-DNME0Ea7.cjs.js +0 -1
  367. package/dist/nord-CC5OiUXg.es.js +0 -4
  368. package/dist/nord-Ca5AGUWc.cjs.js +0 -1
  369. package/dist/nushell-BfRnzRWn.es.js +0 -6
  370. package/dist/nushell-DI9Z3l3M.cjs.js +0 -1
  371. package/dist/objective-c-BGg9R27G.es.js +0 -6
  372. package/dist/objective-c-DVx8Rcni.cjs.js +0 -1
  373. package/dist/objective-cpp-CJ3y3V_5.es.js +0 -6
  374. package/dist/objective-cpp-s6XI7Jvk.cjs.js +0 -1
  375. package/dist/ocaml-BZLsfx_o.es.js +0 -6
  376. package/dist/ocaml-kUzDDUf2.cjs.js +0 -1
  377. package/dist/one-dark-pro-D7-kP8fv.es.js +0 -4
  378. package/dist/one-dark-pro-JOzzHStv.cjs.js +0 -1
  379. package/dist/one-light-020-h_lv.cjs.js +0 -1
  380. package/dist/one-light-D9sNaUtq.es.js +0 -4
  381. package/dist/pascal-D509_I72.cjs.js +0 -1
  382. package/dist/pascal-l2bqd7Dz.es.js +0 -6
  383. package/dist/perl-CkXYjL3t.es.js +0 -16
  384. package/dist/perl-DUnCLRB_.cjs.js +0 -1
  385. package/dist/php-D0k1sQr6.cjs.js +0 -1
  386. package/dist/php-q40Yjh5d.es.js +0 -18
  387. package/dist/plastic-CSTz3KZp.es.js +0 -4
  388. package/dist/plastic-r5piqq-S.cjs.js +0 -1
  389. package/dist/plsql-C_qH_YOK.cjs.js +0 -1
  390. package/dist/plsql-oVq_K_wH.es.js +0 -6
  391. package/dist/po-5jaeIyVd.es.js +0 -6
  392. package/dist/po-CBsLQIcu.cjs.js +0 -1
  393. package/dist/poimandres-BLP3NNjc.cjs.js +0 -1
  394. package/dist/poimandres-C-VADXHD.es.js +0 -4
  395. package/dist/polar-De-CDeYv.cjs.js +0 -1
  396. package/dist/polar-wcLp8ci7.es.js +0 -6
  397. package/dist/postcss-BZ3MNRIJ.es.js +0 -6
  398. package/dist/postcss-BtcsgaYj.cjs.js +0 -1
  399. package/dist/powerquery-B0rHn13V.cjs.js +0 -1
  400. package/dist/powerquery-CgRa2XRw.es.js +0 -6
  401. package/dist/powershell-Diwyv8Eh.es.js +0 -6
  402. package/dist/powershell-rCX2OYXT.cjs.js +0 -1
  403. package/dist/prisma-BaaUHYMp.cjs.js +0 -1
  404. package/dist/prisma-COL_v1x4.es.js +0 -6
  405. package/dist/prolog-CuvJOxqT.es.js +0 -6
  406. package/dist/prolog-DrXD2tGS.cjs.js +0 -1
  407. package/dist/proto-BtmQjBQu.cjs.js +0 -1
  408. package/dist/proto-o9HLmF90.es.js +0 -6
  409. package/dist/pug-Br4hpvIv.es.js +0 -12
  410. package/dist/pug-CFQMpTUe.cjs.js +0 -1
  411. package/dist/puppet-cIrXIuy8.cjs.js +0 -1
  412. package/dist/puppet-wpGOnQp5.es.js +0 -6
  413. package/dist/purescript-B_1NgE2N.es.js +0 -6
  414. package/dist/purescript-CX9QPs2N.cjs.js +0 -1
  415. package/dist/python-B9x3euv6.cjs.js +0 -1
  416. package/dist/python-xYxLFJY-.es.js +0 -6
  417. package/dist/qml-CzqrIM5W.cjs.js +0 -1
  418. package/dist/qml-D5gi21kK.es.js +0 -8
  419. package/dist/qmldir-BInDYbpo.es.js +0 -6
  420. package/dist/qmldir-DNF9H2ir.cjs.js +0 -1
  421. package/dist/qss-C744dLby.cjs.js +0 -1
  422. package/dist/qss-D-h4NdUG.es.js +0 -6
  423. package/dist/r-DgOc9oMe.cjs.js +0 -1
  424. package/dist/r-F-9I-ITZ.es.js +0 -6
  425. package/dist/racket-BoD1TBFT.es.js +0 -6
  426. package/dist/racket-Do9_vqnd.cjs.js +0 -1
  427. package/dist/raku-BW8wAUIz.cjs.js +0 -1
  428. package/dist/raku-IaYcw19m.es.js +0 -6
  429. package/dist/razor-Bt_t1YJb.es.js +0 -10
  430. package/dist/razor-COQhlwWF.cjs.js +0 -1
  431. package/dist/red-7y8PH7HH.es.js +0 -4
  432. package/dist/red-BQGOv1D5.cjs.js +0 -1
  433. package/dist/reg-CGWN_v-z.cjs.js +0 -1
  434. package/dist/reg-CMUdAgIP.es.js +0 -6
  435. package/dist/regexp-GiFkbxS-.es.js +0 -6
  436. package/dist/regexp-N7Z4hEeU.cjs.js +0 -1
  437. package/dist/rel-BYqA7mnV.cjs.js +0 -1
  438. package/dist/rel-BaRn3QX7.es.js +0 -6
  439. package/dist/riscv-B9V3SsvW.es.js +0 -6
  440. package/dist/riscv-ayQMUpo9.cjs.js +0 -1
  441. package/dist/rose-pine-DKEdv1Oe.cjs.js +0 -1
  442. package/dist/rose-pine-DhT-HZE9.es.js +0 -4
  443. package/dist/rose-pine-dawn-Bvt6DtVH.cjs.js +0 -1
  444. package/dist/rose-pine-dawn-DiCjL2i4.es.js +0 -4
  445. package/dist/rose-pine-moon-BNmGHlcn.es.js +0 -4
  446. package/dist/rose-pine-moon-cHuJy0Ng.cjs.js +0 -1
  447. package/dist/rst-BmKw97ch.es.js +0 -22
  448. package/dist/rst-Bq-h_T5U.cjs.js +0 -1
  449. package/dist/ruby-Bw5IEIKD.cjs.js +0 -1
  450. package/dist/ruby-cs7BSa_9.es.js +0 -30
  451. package/dist/rust-BnFKGEfa.cjs.js +0 -1
  452. package/dist/rust-Pc7DCsZD.es.js +0 -6
  453. package/dist/sas-BWKaSYkZ.cjs.js +0 -1
  454. package/dist/sas-DgvHx4mL.es.js +0 -8
  455. package/dist/sass-B9gYryDE.cjs.js +0 -1
  456. package/dist/sass-iCyS6eP9.es.js +0 -6
  457. package/dist/scala-C85dOwSU.cjs.js +0 -1
  458. package/dist/scala-Cly-fENF.es.js +0 -6
  459. package/dist/scheme-B_XUaARm.cjs.js +0 -1
  460. package/dist/scheme-Zi24oEYu.es.js +0 -6
  461. package/dist/scss-B_hSZppj.es.js +0 -8
  462. package/dist/scss-CV3c8_Y7.cjs.js +0 -1
  463. package/dist/sdbl-7Y5u0OW0.cjs.js +0 -1
  464. package/dist/sdbl-BBamrXFL.es.js +0 -6
  465. package/dist/shaderlab-CJ8U2E2w.cjs.js +0 -1
  466. package/dist/shaderlab-U9mqcu_f.es.js +0 -8
  467. package/dist/shellscript-3DYM9fut.cjs.js +0 -1
  468. package/dist/shellscript-Dn0-btNd.es.js +0 -6
  469. package/dist/shellsession-CbKmorC3.cjs.js +0 -1
  470. package/dist/shellsession-LvXGClmj.es.js +0 -8
  471. package/dist/slack-dark-akqwQ7ED.cjs.js +0 -1
  472. package/dist/slack-dark-i7wN4OET.es.js +0 -4
  473. package/dist/slack-ochin-BoQQWmTv.cjs.js +0 -1
  474. package/dist/slack-ochin-ndHf0LoP.es.js +0 -4
  475. package/dist/smalltalk-CCvytUuW.cjs.js +0 -1
  476. package/dist/smalltalk-Cns31tKw.es.js +0 -6
  477. package/dist/snazzy-light-BlSJXAu4.es.js +0 -4
  478. package/dist/snazzy-light-D_IwRieF.cjs.js +0 -1
  479. package/dist/solarized-dark-UTmkh7lw.es.js +0 -4
  480. package/dist/solarized-dark-gmm-WbDC.cjs.js +0 -1
  481. package/dist/solarized-light-BheCkDPT.es.js +0 -4
  482. package/dist/solarized-light-DzcxRSZP.cjs.js +0 -1
  483. package/dist/solidity-BG_k8fA_.es.js +0 -6
  484. package/dist/solidity-BcNcjFC4.cjs.js +0 -1
  485. package/dist/soy-B2d9ZydM.cjs.js +0 -1
  486. package/dist/soy-C0yEn39K.es.js +0 -8
  487. package/dist/sparql-CiBxIK0g.cjs.js +0 -1
  488. package/dist/sparql-CuZaxpno.es.js +0 -8
  489. package/dist/splunk-CTqDjQdo.es.js +0 -6
  490. package/dist/splunk-CzITjJj7.cjs.js +0 -1
  491. package/dist/sql-BqWZrLHB.cjs.js +0 -1
  492. package/dist/sql-DCkt643-.es.js +0 -6
  493. package/dist/ssh-config-DHHGll-v.es.js +0 -6
  494. package/dist/ssh-config-DUPeuEdB.cjs.js +0 -1
  495. package/dist/stata-B8m3qL-x.cjs.js +0 -1
  496. package/dist/stata-Dv81f34z.es.js +0 -8
  497. package/dist/stylus-ByHs6N-o.cjs.js +0 -1
  498. package/dist/stylus-n_9f0QQ5.es.js +0 -6
  499. package/dist/svelte-CfLoBBrI.cjs.js +0 -1
  500. package/dist/svelte-SoJd35Jr.es.js +0 -14
  501. package/dist/swift-BAWqNR8A.es.js +0 -6
  502. package/dist/swift-C5DnOriA.cjs.js +0 -1
  503. package/dist/synthwave-84-BBRLOmNT.cjs.js +0 -1
  504. package/dist/synthwave-84-NU3C_KFZ.es.js +0 -4
  505. package/dist/system-verilog-ClPLYLwh.cjs.js +0 -1
  506. package/dist/system-verilog-Cui-g-ut.es.js +0 -6
  507. package/dist/systemd-BASX0DlX.cjs.js +0 -1
  508. package/dist/systemd-CsKYQIQK.es.js +0 -6
  509. package/dist/talonscript-D2dGh8FO.es.js +0 -6
  510. package/dist/talonscript-DkCSnLHD.cjs.js +0 -1
  511. package/dist/tasl-BAQJK7KZ.cjs.js +0 -1
  512. package/dist/tasl-D3W8HMV6.es.js +0 -6
  513. package/dist/tcl-2y0Fuc4S.es.js +0 -6
  514. package/dist/tcl-CwJAYTvh.cjs.js +0 -1
  515. package/dist/templ-BSMv2wKZ.cjs.js +0 -1
  516. package/dist/templ-C7he2afp.es.js +0 -12
  517. package/dist/terraform-BGW6Oerf.es.js +0 -6
  518. package/dist/terraform-s-pzyVvp.cjs.js +0 -1
  519. package/dist/tex-B0y3cEZp.es.js +0 -8
  520. package/dist/tex-DwtFCA08.cjs.js +0 -1
  521. package/dist/tokyo-night-9T7_vGSy.cjs.js +0 -1
  522. package/dist/tokyo-night-LhP3hHhi.es.js +0 -4
  523. package/dist/toml-CQSfOn0e.es.js +0 -6
  524. package/dist/toml-CyMM7IXy.cjs.js +0 -1
  525. package/dist/ts-tags-C5-4VQhf.es.js +0 -41
  526. package/dist/ts-tags-MIr66hKK.cjs.js +0 -1
  527. package/dist/tsv-BtvSkaG0.es.js +0 -6
  528. package/dist/tsv-DqNGnuVj.cjs.js +0 -1
  529. package/dist/tsx-DiGsgWT8.es.js +0 -6
  530. package/dist/tsx-DpBRUnKC.cjs.js +0 -1
  531. package/dist/turtle-BJ2wmjPc.es.js +0 -6
  532. package/dist/turtle-DfO3eAsu.cjs.js +0 -1
  533. package/dist/twig-BzjoX4ZJ.cjs.js +0 -1
  534. package/dist/twig-OmkATFdv.es.js +0 -18
  535. package/dist/typescript-BqvpT6pB.cjs.js +0 -1
  536. package/dist/typescript-buWNZFwO.es.js +0 -6
  537. package/dist/typespec-P-ZVy8yC.cjs.js +0 -1
  538. package/dist/typespec-bLbdsxJL.es.js +0 -6
  539. package/dist/typst-BVh2IsT9.cjs.js +0 -1
  540. package/dist/typst-Y9_SmXTs.es.js +0 -6
  541. package/dist/v-BUlE9136.cjs.js +0 -1
  542. package/dist/v-wa8Orrdd.es.js +0 -6
  543. package/dist/vala-BIymb2K_.cjs.js +0 -1
  544. package/dist/vala-DRdriFr_.es.js +0 -6
  545. package/dist/vb-E2_-jk4M.es.js +0 -6
  546. package/dist/vb-IXOh8mqV.cjs.js +0 -1
  547. package/dist/verilog-B1iBoR5_.es.js +0 -6
  548. package/dist/verilog-BiglCqvO.cjs.js +0 -1
  549. package/dist/vesper-CJsaOsSM.es.js +0 -4
  550. package/dist/vesper-DqLWLxOu.cjs.js +0 -1
  551. package/dist/vhdl-CJUzuS2t.cjs.js +0 -1
  552. package/dist/vhdl-CRVaAhXk.es.js +0 -6
  553. package/dist/viml-B-zWOd7Z.es.js +0 -6
  554. package/dist/viml-B1nKLcgt.cjs.js +0 -1
  555. package/dist/vitesse-black-BoGvW84i.es.js +0 -4
  556. package/dist/vitesse-black-MF-1S1MG.cjs.js +0 -1
  557. package/dist/vitesse-dark-Cym-eLtO.es.js +0 -4
  558. package/dist/vitesse-dark-SIffJYSe.cjs.js +0 -1
  559. package/dist/vitesse-light-CcmG315c.es.js +0 -4
  560. package/dist/vitesse-light-U63SkYGT.cjs.js +0 -1
  561. package/dist/vue-DCwwWMGI.es.js +0 -31
  562. package/dist/vue-DYZqcRaZ.cjs.js +0 -1
  563. package/dist/vue-html-CdPbyrq1.cjs.js +0 -1
  564. package/dist/vue-html-sRE_Ny23.es.js +0 -10
  565. package/dist/vyper-CO9xUkIY.cjs.js +0 -1
  566. package/dist/vyper-DWutKXpa.es.js +0 -6
  567. package/dist/wasm-Bv5f0gKv.es.js +0 -6
  568. package/dist/wasm-CdIThIat.cjs.js +0 -1
  569. package/dist/wenyan-BMYnfus1.es.js +0 -6
  570. package/dist/wenyan-BSJ3fk7e.cjs.js +0 -1
  571. package/dist/wgsl-DnPoPGDU.es.js +0 -6
  572. package/dist/wgsl-d3zZE7ZN.cjs.js +0 -1
  573. package/dist/wikitext-BRCqXN2g.cjs.js +0 -1
  574. package/dist/wikitext-CntM04PE.es.js +0 -6
  575. package/dist/wolfram-C3rR92zj.cjs.js +0 -1
  576. package/dist/wolfram-Ws5qPlX9.es.js +0 -6
  577. package/dist/xml-BRLTD55J.cjs.js +0 -1
  578. package/dist/xml-Ch1q_kJp.es.js +0 -8
  579. package/dist/xsl-DyL8yqXw.es.js +0 -8
  580. package/dist/xsl-ETbYGV_-.cjs.js +0 -1
  581. package/dist/yaml-7DV6pRKj.cjs.js +0 -1
  582. package/dist/yaml-Bbg74JKr.es.js +0 -6
  583. package/dist/zenscript-BWMxwjeH.cjs.js +0 -1
  584. package/dist/zenscript-C0RKE4nU.es.js +0 -6
  585. package/dist/zig-D6SXBGNm.es.js +0 -6
  586. package/dist/zig-yAcNfpgW.cjs.js +0 -1
@@ -0,0 +1,758 @@
1
+ import { useMemo } from "react";
2
+ import { useServer } from "../components/ServerProvider";
3
+ import { FilterSelection, FilterValuePrimitive } from "./useDimensionFilters";
4
+ import { useQueryWithApiError } from "./useQueryWithApiError";
5
+
6
+ /**
7
+ * Filter types for dimensions
8
+ */
9
+ export type FilterType =
10
+ | "NONE"
11
+ | "Star"
12
+ | "MinMax"
13
+ | "DateMinMax"
14
+ | "Retrieval"
15
+ | "Boolean";
16
+
17
+ /**
18
+ * Specification for a dimension to filter
19
+ */
20
+ export interface DimensionSpec {
21
+ /** Name of the dimension field */
22
+ dimensionName: string;
23
+ /** Type of filter to apply */
24
+ filterType: FilterType;
25
+ /** Source name within the model */
26
+ source: string;
27
+ /** Model path */
28
+ model: string;
29
+ /** Minimum similarity score for Retrieval filter type (default: 0.1) */
30
+ minSimilarityScore?: number;
31
+ /** Optional list of static values to use for the dropdown instead of querying */
32
+ values?: string[];
33
+ }
34
+
35
+ /**
36
+ * Value information for a dimension
37
+ */
38
+ export interface DimensionValue {
39
+ value: FilterValuePrimitive;
40
+ count?: number;
41
+ }
42
+
43
+ /**
44
+ * Result type mapping dimension names to their values
45
+ */
46
+ export type DimensionValues = Map<string, DimensionValue[]>;
47
+
48
+ /**
49
+ * Parameters for the useDimensionalFilterRangeData hook
50
+ */
51
+ export interface UseDimensionalFilterRangeDataParams {
52
+ /** Project name */
53
+ project: string;
54
+ /** Package name */
55
+ package: string;
56
+ /** List of dimension specifications (each includes source and model) */
57
+ dimensionSpecs: DimensionSpec[];
58
+ /** Version ID (optional) */
59
+ versionId?: string;
60
+ /** Whether the query should be enabled */
61
+ enabled?: boolean;
62
+ /** Maximum number of index results to return (default: 1000) */
63
+ indexLimit?: number;
64
+ /** Active filter selections to apply when fetching dimension values (optional) */
65
+ activeFilters?: FilterSelection[];
66
+ }
67
+
68
+ /**
69
+ * Result from the useDimensionalFilterRangeData hook
70
+ */
71
+ export interface DimensionalFilterRangeDataResult {
72
+ /** Map of dimension names to their values */
73
+ data: DimensionValues | undefined;
74
+ /** Whether no rows matched the filter */
75
+ noRowsMatchedFilter: boolean;
76
+ /** Whether the query is loading */
77
+ isLoading: boolean;
78
+ /** Whether the query encountered an error */
79
+ isError: boolean;
80
+ /** Error object if query failed */
81
+ error: Error | null;
82
+ /** Refetch function to manually trigger the query */
83
+ refetch: () => void;
84
+ }
85
+
86
+ /**
87
+ * Escapes special characters in strings for Malloy queries
88
+ */
89
+ function escapeMalloyString(value: string): string {
90
+ return value.replace(/'/g, "\\'").replace(/\\/g, "\\\\");
91
+ }
92
+
93
+ /**
94
+ * Formats a value for use in Malloy query
95
+ */
96
+ function formatMalloyValue(
97
+ value: FilterValuePrimitive | null | undefined,
98
+ isDate: boolean = false,
99
+ ): string {
100
+ if (value === null || value === undefined) {
101
+ return "null";
102
+ }
103
+
104
+ if (isDate) {
105
+ if (value instanceof Date) {
106
+ // Format as YYYY-MM-DD
107
+ return `@${value.getFullYear()}-${String(value.getMonth() + 1).padStart(2, "0")}-${String(value.getDate()).padStart(2, "0")}`;
108
+ }
109
+ // If it's a string, assume it's already in ISO format
110
+ return `@${value}`;
111
+ }
112
+
113
+ if (typeof value === "string") {
114
+ return `'${escapeMalloyString(value)}'`;
115
+ }
116
+
117
+ if (typeof value === "number") {
118
+ return String(value);
119
+ }
120
+
121
+ if (typeof value === "boolean") {
122
+ return value ? "true" : "false";
123
+ }
124
+
125
+ return String(value);
126
+ }
127
+
128
+ /**
129
+ * Generates a Malloy filter condition for a single filter selection
130
+ */
131
+ function generateFilterCondition(selection: FilterSelection): string {
132
+ const { dimensionName, matchType, value, value2 } = selection;
133
+ const fieldName = `\`${dimensionName}\``;
134
+
135
+ // Determine if this is a date field based on the value
136
+ const isDate = value instanceof Date;
137
+
138
+ switch (matchType) {
139
+ case "Equals":
140
+ case "Concept Search":
141
+ if (Array.isArray(value) && value.length > 0) {
142
+ // Handle multi-select: (field = val1 or field = val2)
143
+ const conditions = value.map(
144
+ (v) => `${fieldName} = ${formatMalloyValue(v, isDate)}`,
145
+ );
146
+ return `(${conditions.join(" or ")})`;
147
+ }
148
+ // Empty array or single value
149
+ if (Array.isArray(value)) return "";
150
+ return `${fieldName} = ${formatMalloyValue(value, isDate)}`;
151
+
152
+ case "Contains":
153
+ if (typeof value === "string") {
154
+ return `${fieldName} ~ f'%${escapeMalloyString(value)}%'`;
155
+ }
156
+ if (Array.isArray(value)) return "";
157
+ return `${fieldName} = ${formatMalloyValue(value)}`;
158
+
159
+ case "After":
160
+ if (Array.isArray(value)) return "";
161
+ return `${fieldName} > ${formatMalloyValue(value, isDate)}`;
162
+
163
+ case "Before":
164
+ if (Array.isArray(value)) return "";
165
+ return `${fieldName} < ${formatMalloyValue(value, isDate)}`;
166
+
167
+ case "Greater Than":
168
+ if (Array.isArray(value)) return "";
169
+ return `${fieldName} > ${formatMalloyValue(value)}`;
170
+
171
+ case "Less Than":
172
+ if (Array.isArray(value)) return "";
173
+ return `${fieldName} < ${formatMalloyValue(value)}`;
174
+
175
+ case "Between":
176
+ if (Array.isArray(value)) return "";
177
+ if (value2 !== undefined) {
178
+ return `${fieldName} >= ${formatMalloyValue(value, isDate)} and ${fieldName} <= ${formatMalloyValue(value2, isDate)}`;
179
+ }
180
+ return `${fieldName} >= ${formatMalloyValue(value, isDate)}`;
181
+
182
+ default:
183
+ return "";
184
+ }
185
+ }
186
+
187
+ /**
188
+ * Groups dimension specs by source/model combination
189
+ * Returns a map where key is "source|model" and value is array of specs for that combo
190
+ */
191
+ function groupSpecsBySourceModel(
192
+ dimensionSpecs: DimensionSpec[],
193
+ ): Map<string, DimensionSpec[]> {
194
+ const groups = new Map<string, DimensionSpec[]>();
195
+
196
+ for (const spec of dimensionSpecs) {
197
+ const key = `${spec.source}|${spec.model}`;
198
+ const existing = groups.get(key) || [];
199
+ existing.push(spec);
200
+ groups.set(key, existing);
201
+ }
202
+
203
+ return groups;
204
+ }
205
+
206
+ /**
207
+ * Builds a Malloy index query to fetch dimension values for a single source
208
+ * Uses Malloy's built-in index operator for dimensional search
209
+ * Reference: https://docs.malloydata.dev/documentation/patterns/dim_index
210
+ */
211
+ function buildDimensionalIndexQuery(
212
+ source: string,
213
+ dimensionSpecs: DimensionSpec[],
214
+ indexLimit: number,
215
+ activeFilters?: FilterSelection[],
216
+ ): string {
217
+ // Filter out specs that don't need data fetching
218
+ const specsToFetch = dimensionSpecs.filter(
219
+ (spec) =>
220
+ (spec.filterType === "Star" ||
221
+ spec.filterType === "MinMax" ||
222
+ spec.filterType === "DateMinMax") &&
223
+ !spec.values,
224
+ );
225
+
226
+ if (specsToFetch.length === 0) {
227
+ return "";
228
+ }
229
+
230
+ // Build list of dimensions to index
231
+ const dimensionsToIndex = specsToFetch
232
+ .map((spec) => `\`${spec.dimensionName}\``)
233
+ .join(", ");
234
+
235
+ // Filter activeFilters to only include those for this source
236
+ const filtersForSource =
237
+ activeFilters?.filter((f) => {
238
+ // Find the spec for this filter's dimension
239
+ const spec = dimensionSpecs.find(
240
+ (s) => s.dimensionName === f.dimensionName,
241
+ );
242
+ return spec?.source === source;
243
+ }) || [];
244
+
245
+ // Generate WHERE conditions from active filters (without 'where' keyword)
246
+ const whereConditions =
247
+ filtersForSource.length > 0
248
+ ? filtersForSource
249
+ .map((selection) => generateFilterCondition(selection))
250
+ .filter((condition) => condition.length > 0)
251
+ .join(" and ")
252
+ : "";
253
+
254
+ // Use Malloy's index operator to create a dimensional search index
255
+ // The index operator returns: fieldName, fieldPath, fieldType, fieldValue, weight
256
+ // For strings: returns distinct values with weights (counts)
257
+ // For numbers/dates: returns ranges (min to max)
258
+ //
259
+ // Important: where clause and index must be in the SAME query stage
260
+ // Use a two-stage query: first stage creates the filtered index, second stage orders by weight
261
+ return `
262
+ run: ${source} -> {
263
+ ${whereConditions ? `where: ${whereConditions}` : ""}
264
+ index: ${dimensionsToIndex}
265
+ } -> {
266
+ select: *
267
+ order_by: weight desc
268
+
269
+ limit: ${indexLimit}
270
+ }
271
+ `;
272
+ }
273
+
274
+ /**
275
+ * Cell types from Malloy query results
276
+ */
277
+ interface MalloyCell {
278
+ kind: string;
279
+ string_value?: string;
280
+ number_value?: number;
281
+ boolean_value?: boolean;
282
+ }
283
+
284
+ /**
285
+ * Record cell from Malloy query results
286
+ */
287
+ interface MalloyRecordCell {
288
+ kind: "record_cell";
289
+ record_value: MalloyCell[];
290
+ }
291
+
292
+ /**
293
+ * Schema field from Malloy query results
294
+ */
295
+ interface MalloySchemaField {
296
+ name: string;
297
+ }
298
+
299
+ /**
300
+ * Malloy index query result entry
301
+ */
302
+ interface MalloyIndexEntry {
303
+ fieldName?: string;
304
+ fieldPath?: string;
305
+ fieldType?: string;
306
+ fieldValue?: string;
307
+ weight?: number;
308
+ }
309
+
310
+ /**
311
+ * Parsed Malloy query result structure
312
+ */
313
+ interface MalloyQueryResult {
314
+ schema: {
315
+ fields: MalloySchemaField[];
316
+ };
317
+ data?: {
318
+ array_value?: MalloyRecordCell[];
319
+ };
320
+ }
321
+
322
+ /**
323
+ * Parses the Malloy index query result and converts it to a DimensionValues map
324
+ * The index operator returns: fieldName, fieldPath, fieldType, fieldValue, weight
325
+ * Reference: https://docs.malloydata.dev/documentation/patterns/dim_index
326
+ */
327
+ function parseIndexQueryResult(
328
+ result: string,
329
+ dimensionSpecs: DimensionSpec[],
330
+ ): { values: DimensionValues; noRowsMatchedFilter: boolean } {
331
+ const dimensionValues = new Map<string, DimensionValue[]>();
332
+
333
+ // Initialize empty arrays for all dimensions
334
+ for (const spec of dimensionSpecs) {
335
+ dimensionValues.set(spec.dimensionName, []);
336
+ }
337
+
338
+ // Parse the result JSON if it's a string
339
+ const parsedResult = JSON.parse(result) as MalloyQueryResult;
340
+
341
+ // Parse schema to understand field positions
342
+ const schema = parsedResult.schema.fields;
343
+ const fieldMap = new Map<string, number>();
344
+
345
+ schema.forEach((field: MalloySchemaField, index: number) => {
346
+ fieldMap.set(field.name, index);
347
+ });
348
+
349
+ // Helper function to extract value from a cell based on its kind
350
+ const extractCellValue = (
351
+ cell: MalloyCell | undefined,
352
+ ): string | number | boolean | null => {
353
+ if (!cell) return null;
354
+
355
+ switch (cell.kind) {
356
+ case "string_cell":
357
+ return cell.string_value ?? null;
358
+ case "number_cell":
359
+ return cell.number_value ?? null;
360
+ case "boolean_cell":
361
+ return cell.boolean_value ?? null;
362
+ default:
363
+ console.log("Unknown cell kind: " + cell.kind);
364
+ return null;
365
+ }
366
+ };
367
+
368
+ // Convert array_value records to objects using schema
369
+ const rawData = parsedResult.data?.array_value || [];
370
+ const indexData: MalloyIndexEntry[] = rawData.map(
371
+ (record: MalloyRecordCell) => {
372
+ const obj: MalloyIndexEntry = {};
373
+
374
+ if (record.kind === "record_cell" && record.record_value) {
375
+ record.record_value.forEach((cell: MalloyCell, index: number) => {
376
+ const fieldName = schema[index]?.name;
377
+ if (fieldName) {
378
+ const value = extractCellValue(cell);
379
+ if (fieldName === "fieldName" && typeof value === "string") {
380
+ obj.fieldName = value;
381
+ } else if (
382
+ fieldName === "fieldPath" &&
383
+ typeof value === "string"
384
+ ) {
385
+ obj.fieldPath = value;
386
+ } else if (
387
+ fieldName === "fieldType" &&
388
+ typeof value === "string"
389
+ ) {
390
+ obj.fieldType = value;
391
+ } else if (
392
+ fieldName === "fieldValue" &&
393
+ typeof value === "string"
394
+ ) {
395
+ obj.fieldValue = value;
396
+ } else if (
397
+ fieldName === "weight" &&
398
+ typeof value === "number"
399
+ ) {
400
+ obj.weight = value;
401
+ }
402
+ }
403
+ });
404
+ }
405
+
406
+ return obj;
407
+ },
408
+ );
409
+
410
+ const noRowsMatchedFilter =
411
+ indexData.length === 0 ||
412
+ indexData.every((entry: MalloyIndexEntry) => !entry.fieldName);
413
+
414
+ // Group index results by fieldName/dimensionName
415
+ for (const spec of dimensionSpecs) {
416
+ if (spec.filterType === "NONE" || spec.filterType === "Retrieval") {
417
+ // These types don't fetch values
418
+ continue;
419
+ }
420
+
421
+ // Find all index entries for this dimension
422
+ // Try multiple matching strategies since field naming can vary
423
+ const dimensionEntries = indexData.filter((entry: MalloyIndexEntry) => {
424
+ const fieldName = entry.fieldName || "";
425
+ const fieldPath = entry.fieldPath || "";
426
+
427
+ // Try exact match
428
+ if (
429
+ fieldName === spec.dimensionName ||
430
+ fieldPath === spec.dimensionName
431
+ ) {
432
+ return true;
433
+ }
434
+
435
+ // Try case-insensitive match
436
+ if (
437
+ fieldName.toLowerCase() === spec.dimensionName.toLowerCase() ||
438
+ fieldPath.toLowerCase() === spec.dimensionName.toLowerCase()
439
+ ) {
440
+ return true;
441
+ }
442
+
443
+ // Try matching the last part of a path (e.g., "source.field" matches "field")
444
+ const lastPathPart = fieldPath.split(".").pop() || "";
445
+ if (
446
+ lastPathPart === spec.dimensionName ||
447
+ lastPathPart.toLowerCase() === spec.dimensionName.toLowerCase()
448
+ ) {
449
+ return true;
450
+ }
451
+
452
+ return false;
453
+ });
454
+
455
+ if (dimensionEntries.length === 0) {
456
+ continue;
457
+ }
458
+
459
+ if (spec.filterType === "Star") {
460
+ // For Star filter, we want all distinct values with their weights
461
+ // String fields return individual fieldValue entries
462
+ const values = dimensionEntries
463
+ .filter((entry: MalloyIndexEntry) => entry.fieldType === "string")
464
+ .map((entry: MalloyIndexEntry) => ({
465
+ value: entry.fieldValue ?? "",
466
+ count: entry.weight,
467
+ }))
468
+ .sort(
469
+ (a: DimensionValue, b: DimensionValue) =>
470
+ (b.count ?? 0) - (a.count ?? 0),
471
+ ); // Sort by count descending
472
+
473
+ dimensionValues.set(spec.dimensionName, values);
474
+ } else if (spec.filterType === "MinMax") {
475
+ // For MinMax filter, numeric fields return a range in fieldValue
476
+ // Format is typically "min to max"
477
+ console.log(
478
+ "MinMax dimensionEntries: " +
479
+ JSON.stringify(dimensionEntries, null, 2),
480
+ );
481
+ console.log(
482
+ "All MinMax dimension entries fieldTypes:",
483
+ dimensionEntries.map((e: MalloyIndexEntry) => e.fieldType),
484
+ );
485
+
486
+ const numericEntry = dimensionEntries.find(
487
+ (entry: MalloyIndexEntry) => entry.fieldType === "number",
488
+ );
489
+
490
+ console.log("numericEntry: " + JSON.stringify(numericEntry, null, 2));
491
+ if (numericEntry?.fieldValue) {
492
+ const rangeString = numericEntry.fieldValue;
493
+ // Parse "min to max" format
494
+ const rangeParts = rangeString.split(" to ");
495
+
496
+ console.log("rangeParts: " + rangeParts);
497
+
498
+ if (rangeParts.length === 2) {
499
+ const values = [
500
+ { value: parseFloat(rangeParts[0]) },
501
+ { value: parseFloat(rangeParts[1]) },
502
+ ];
503
+ dimensionValues.set(spec.dimensionName, values);
504
+ } else {
505
+ console.warn(
506
+ `Could not parse numeric range for ${spec.dimensionName}: ${rangeString}`,
507
+ );
508
+ }
509
+ } else {
510
+ console.warn(
511
+ `No numeric entry found for ${spec.dimensionName}. Available entries:`,
512
+ dimensionEntries,
513
+ );
514
+ }
515
+ } else if (spec.filterType === "DateMinMax") {
516
+ // For DateMinMax filter, date/timestamp fields return a range in fieldValue
517
+ // Format is typically "YYYY-MM-DD to YYYY-MM-DD"
518
+
519
+ // Look for date, timestamp, or string type entries (dates can come back in various formats)
520
+ const dateEntry = dimensionEntries.find(
521
+ (entry: MalloyIndexEntry) =>
522
+ entry.fieldType === "date" ||
523
+ entry.fieldType === "timestamp" ||
524
+ entry.fieldType === "string",
525
+ );
526
+
527
+ console.log("dateEntry: " + JSON.stringify(dateEntry, null, 2));
528
+ console.log(
529
+ "All date dimension entries fieldTypes:",
530
+ dimensionEntries.map((e: MalloyIndexEntry) => e.fieldType),
531
+ );
532
+
533
+ if (dateEntry?.fieldValue) {
534
+ const rangeString = dateEntry.fieldValue;
535
+ // Parse "YYYY-MM-DD to YYYY-MM-DD" format
536
+ const rangeParts = rangeString.split(" to ");
537
+
538
+ console.log("date rangeParts: " + rangeParts);
539
+
540
+ if (rangeParts.length === 2) {
541
+ const values = [
542
+ { value: new Date(rangeParts[0].trim()) },
543
+ { value: new Date(rangeParts[1].trim()) },
544
+ ];
545
+ dimensionValues.set(spec.dimensionName, values);
546
+ } else {
547
+ console.warn(
548
+ `Could not parse date range for ${spec.dimensionName}: ${rangeString}`,
549
+ );
550
+ }
551
+ } else {
552
+ console.warn(
553
+ `No date entry found for ${spec.dimensionName}. Available entries:`,
554
+ dimensionEntries,
555
+ );
556
+ }
557
+ }
558
+ }
559
+
560
+ return { values: dimensionValues, noRowsMatchedFilter };
561
+ }
562
+
563
+ /**
564
+ * Custom hook to fetch dimensional filter values from a Malloy model
565
+ *
566
+ * This hook uses Malloy's built-in `index` operator to create dimensional search indexes
567
+ * for the specified dimensions. The index operator efficiently returns distinct values
568
+ * and ranges for dimensions in a single query.
569
+ *
570
+ * Filter types:
571
+ * - NONE: Display only, no values fetched
572
+ * - Star: Fetches all distinct values with counts (for string fields)
573
+ * - MinMax: Fetches minimum and maximum values (for numeric fields as ranges)
574
+ * - DateMinMax: Fetches minimum and maximum values (for date fields as Date objects)
575
+ * - Retrieval: Uses retrieval, no values fetched
576
+ *
577
+ * Reference: https://docs.malloydata.dev/documentation/patterns/dim_index
578
+ *
579
+ * The hook groups dimension specs by source/model combination and runs separate
580
+ * index queries for each group, then merges the results.
581
+ *
582
+ * @param params - Parameters including project, package, and dimension specs (each with source/model)
583
+ * @returns Query result with dimension values map, loading state, and error information
584
+ *
585
+ * @example
586
+ * ```tsx
587
+ * const { data, isLoading, error } = useDimensionalFilterRangeData({
588
+ * project: "my-project",
589
+ * package: "my-package",
590
+ * dimensionSpecs: [
591
+ * { dimensionName: "category", filterType: "Star", source: "my_source", model: "model.malloy" },
592
+ * { dimensionName: "price", filterType: "MinMax", source: "my_source", model: "model.malloy" },
593
+ * { dimensionName: "status", filterType: "Star", source: "other_source", model: "other.malloy" },
594
+ * ],
595
+ * indexLimit: 1000, // Optional: set higher if needed for many Star dimensions
596
+ * });
597
+ * ```
598
+ */
599
+ export function useDimensionalFilterRangeData(
600
+ params: UseDimensionalFilterRangeDataParams,
601
+ ): DimensionalFilterRangeDataResult {
602
+ const {
603
+ project,
604
+ package: packageName,
605
+ dimensionSpecs,
606
+ versionId,
607
+ enabled = true,
608
+ indexLimit = 10000,
609
+ activeFilters = [],
610
+ } = params;
611
+
612
+ // Group dimension specs by source/model combination
613
+ const sourceModelGroups = useMemo(
614
+ () => groupSpecsBySourceModel(dimensionSpecs),
615
+ [dimensionSpecs],
616
+ );
617
+
618
+ // Build query strings for each source/model combo
619
+ const queryConfigs = useMemo(() => {
620
+ const configs: Array<{
621
+ key: string;
622
+ source: string;
623
+ model: string;
624
+ query: string;
625
+ specs: DimensionSpec[];
626
+ }> = [];
627
+
628
+ for (const [key, specs] of sourceModelGroups) {
629
+ const [source, model] = key.split("|");
630
+ const query = buildDimensionalIndexQuery(
631
+ source,
632
+ specs,
633
+ indexLimit,
634
+ activeFilters,
635
+ );
636
+ if (query) {
637
+ configs.push({ key, source, model, query, specs });
638
+ } else {
639
+ console.log("No query for source: ", source, "model: ", model);
640
+ }
641
+ }
642
+
643
+ return configs;
644
+ }, [sourceModelGroups, indexLimit, activeFilters]);
645
+
646
+ // Determine if we need to execute queries
647
+ const shouldExecuteQuery = useMemo(() => {
648
+ return (
649
+ enabled &&
650
+ queryConfigs.length > 0 &&
651
+ dimensionSpecs.some(
652
+ (spec) =>
653
+ spec.filterType === "Star" ||
654
+ spec.filterType === "MinMax" ||
655
+ spec.filterType === "DateMinMax",
656
+ )
657
+ );
658
+ }, [enabled, queryConfigs, dimensionSpecs]);
659
+
660
+ // Execute the query using the API client
661
+ const { apiClients } = useServer();
662
+
663
+ const queryResult = useQueryWithApiError({
664
+ queryKey: [
665
+ "dimensionalFilter",
666
+ project,
667
+ packageName,
668
+ dimensionSpecs,
669
+ versionId,
670
+ activeFilters,
671
+ ],
672
+ queryFn: async () => {
673
+ if (!shouldExecuteQuery) {
674
+ // Return empty map if no query needed
675
+ const emptyMap = new Map<string, DimensionValue[]>();
676
+ for (const spec of dimensionSpecs) {
677
+ emptyMap.set(spec.dimensionName, []);
678
+ }
679
+ return { values: emptyMap, noRowsMatchedFilter: false };
680
+ }
681
+
682
+ // Execute queries for each source/model combo in parallel
683
+ const results = await Promise.all(
684
+ queryConfigs.map(async (config) => {
685
+ const response = await apiClients.models.executeQueryModel(
686
+ project,
687
+ packageName,
688
+ config.model,
689
+ {
690
+ query: config.query,
691
+ versionId: versionId,
692
+ },
693
+ );
694
+ return {
695
+ config,
696
+ result: parseIndexQueryResult(
697
+ response.data.result,
698
+ config.specs,
699
+ ),
700
+ };
701
+ }),
702
+ );
703
+
704
+ // Merge all results into a single DimensionValues map
705
+ const mergedValues = new Map<string, DimensionValue[]>();
706
+ let anyNoRowsMatched = false;
707
+
708
+ for (const { result } of results) {
709
+ for (const [key, val] of result.values) {
710
+ mergedValues.set(key, val);
711
+ }
712
+ if (result.noRowsMatchedFilter) {
713
+ anyNoRowsMatched = true;
714
+ }
715
+ }
716
+
717
+ return { values: mergedValues, noRowsMatchedFilter: anyNoRowsMatched };
718
+ },
719
+ enabled: shouldExecuteQuery,
720
+ staleTime: 5 * 60 * 1000, // 5 minutes
721
+ placeholderData: (previousData) => previousData, // Keep showing previous data during refetch
722
+ });
723
+ const fetchedValues = queryResult.data?.values;
724
+ const mergedData = useMemo(() => {
725
+ const result = new Map<string, DimensionValue[]>();
726
+
727
+ // Initialize with static values or empty arrays
728
+ for (const spec of dimensionSpecs) {
729
+ if (spec.values) {
730
+ result.set(
731
+ spec.dimensionName,
732
+ spec.values.map((v) => ({ value: v })),
733
+ );
734
+ } else {
735
+ result.set(spec.dimensionName, []);
736
+ }
737
+ }
738
+
739
+ // Merge fetched values
740
+ if (fetchedValues) {
741
+ for (const [key, val] of fetchedValues) {
742
+ if (val.length > 0) {
743
+ result.set(key, val);
744
+ }
745
+ }
746
+ }
747
+ return result;
748
+ }, [dimensionSpecs, fetchedValues]);
749
+
750
+ return {
751
+ data: mergedData,
752
+ noRowsMatchedFilter: queryResult.data?.noRowsMatchedFilter ?? false,
753
+ isLoading: shouldExecuteQuery ? queryResult.isPending : false,
754
+ isError: shouldExecuteQuery ? queryResult.isError : false,
755
+ error: shouldExecuteQuery ? (queryResult.error as Error | null) : null,
756
+ refetch: queryResult.refetch,
757
+ };
758
+ }