@marimo-team/frontend 0.16.2 → 0.16.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 (293) hide show
  1. package/dist/assets/{ConnectedDataExplorerComponent-B5cPvWoQ.js → ConnectedDataExplorerComponent-Brtw1DxF.js} +1 -1
  2. package/dist/assets/{ImageComparisonComponent-CqR26LSv.js → ImageComparisonComponent-Dxl-PbZX.js} +1 -1
  3. package/dist/assets/{VegaLite-DvQDATwI.js → VegaLite-BXQF0Cx_.js} +1 -1
  4. package/dist/assets/_baseEach-BjSm9ht3.js +1 -0
  5. package/dist/assets/_baseMap-CV4Ezmtf.js +1 -0
  6. package/dist/assets/_baseUniq-Ci9yZGxz.js +1 -0
  7. package/dist/assets/{_createAggregator-ZcHkHPNJ.js → _createAggregator-VFK9K2d9.js} +1 -1
  8. package/dist/assets/{agent-panel-B91RoLct.js → agent-panel-BoscVLCT.js} +7 -7
  9. package/dist/assets/{any-language-editor-CxfHcm5h.js → any-language-editor-ChaY_VUU.js} +1 -1
  10. package/dist/assets/{architectureDiagram-W76B3OCA-BQsvK8uR.js → architectureDiagram-W76B3OCA-CueUUFYd.js} +1 -1
  11. package/dist/assets/{between-horizontal-start-BmYToIaM.js → between-horizontal-start-DAHqmLYT.js} +1 -1
  12. package/dist/assets/{blockDiagram-QIGZ2CNN-r3HgCj4w.js → blockDiagram-QIGZ2CNN-BYYygyWn.js} +1 -1
  13. package/dist/assets/{c4Diagram-FPNF74CW-BJbPNt41.js → c4Diagram-FPNF74CW-DAz3xEh1.js} +1 -1
  14. package/dist/assets/channel-6SqQ2U_X.js +1 -0
  15. package/dist/assets/chat-panel-DJkOLrw9.js +3 -0
  16. package/dist/assets/{chunk-4BX2VUAB-Dv4MZ9Hj.js → chunk-4BX2VUAB-8g-RyHdt.js} +1 -1
  17. package/dist/assets/{chunk-55IACEB6-CM4AHquB.js → chunk-55IACEB6-iWZZ8Mt6.js} +1 -1
  18. package/dist/assets/{chunk-FMBD7UC4-C_Zz0ENB.js → chunk-FMBD7UC4-knjss4wk.js} +1 -1
  19. package/dist/assets/{chunk-K7UQS3LO-DYSmiXYq.js → chunk-K7UQS3LO-DVIwPBgZ.js} +1 -1
  20. package/dist/assets/{chunk-QN33PNHL-QM4OPuQP.js → chunk-QN33PNHL-CBU8pN6I.js} +1 -1
  21. package/dist/assets/{chunk-QZHKN3VN-CfAsGyeB.js → chunk-QZHKN3VN-5ljElUF4.js} +1 -1
  22. package/dist/assets/{chunk-TVAH2DTR-6j_Cpjsi.js → chunk-TVAH2DTR-DkIdGINc.js} +1 -1
  23. package/dist/assets/{chunk-TZMSLE5B-BHslFJQE.js → chunk-TZMSLE5B-CIFOSTqh.js} +1 -1
  24. package/dist/assets/{circle-play-CK3UZRYQ.js → circle-play-BOdsbq5u.js} +1 -1
  25. package/dist/assets/classDiagram-KNZD7YFC-DVqXcTYf.js +1 -0
  26. package/dist/assets/classDiagram-v2-RKCZMP56-DVqXcTYf.js +1 -0
  27. package/dist/assets/{clear-button-C4fDVSv8.js → clear-button-GAjXl0CQ.js} +1 -1
  28. package/dist/assets/clone-DSDb0xen.js +1 -0
  29. package/dist/assets/command-palette-BUXkqoLh.js +1 -0
  30. package/dist/assets/{common-D-lbuUwz.js → common-DahoYqdi.js} +1 -1
  31. package/dist/assets/{compile-DVQe1Mzk.js → compile-Bg8uJ7vm.js} +1 -1
  32. package/dist/assets/{cose-bilkent-S5V4N54A-D-IS7WC8.js → cose-bilkent-S5V4N54A-z_0gqD9K.js} +1 -1
  33. package/dist/assets/{dagre-5GWH7T2D-lYu-tEWT.js → dagre-5GWH7T2D-BMt7CNXL.js} +1 -1
  34. package/dist/assets/{data-grid-overlay-editor-C5peOCit.js → data-grid-overlay-editor-Ctn4XtXx.js} +1 -1
  35. package/dist/assets/{datasources-panel-D3NA20uZ.js → datasources-panel-C7sqRIHs.js} +1 -1
  36. package/dist/assets/{dependency-graph-panel-BGVYOfkV.js → dependency-graph-panel-DNajptzv.js} +4 -4
  37. package/dist/assets/{diagram-N5W7TBWH-BnvIuYUp.js → diagram-N5W7TBWH-BzwvLvAy.js} +1 -1
  38. package/dist/assets/{diagram-QEK2KX5R-DemedRK3.js → diagram-QEK2KX5R-DRLJ56FS.js} +1 -1
  39. package/dist/assets/{diagram-S2PKOQOG-iiY7AuyH.js → diagram-S2PKOQOG-Bf8x4KTU.js} +1 -1
  40. package/dist/assets/{documentation-panel-C3dSwOSQ.js → documentation-panel-Dm6Ozl67.js} +1 -1
  41. package/dist/assets/edit-page-CGc9EjuG.js +140 -0
  42. package/dist/assets/{ellipsis-vertical-CazJl8M7.js → ellipsis-vertical-Bj1YXvZe.js} +1 -1
  43. package/dist/assets/{empty-state-DW308mFO.js → empty-state-CYev-D31.js} +1 -1
  44. package/dist/assets/{erDiagram-AWTI2OKA-6wQ8Ugg0.js → erDiagram-AWTI2OKA-DmgzgN_I.js} +1 -1
  45. package/dist/assets/{error-panel-D1VnJ1yP.js → error-panel-BYG4twCa.js} +1 -1
  46. package/dist/assets/{file-explorer-panel-0oVd4t-D.js → file-explorer-panel-BSMiOApi.js} +1 -1
  47. package/dist/assets/{flowDiagram-PVAE7QVJ-C55IUWjm.js → flowDiagram-PVAE7QVJ-BdRKkajr.js} +1 -1
  48. package/dist/assets/{ganttDiagram-OWAHRB6G-DmqCM6ME.js → ganttDiagram-OWAHRB6G-lfRAMnq_.js} +5 -5
  49. package/dist/assets/{gitGraphDiagram-NY62KEGX-DBvhAeM_.js → gitGraphDiagram-NY62KEGX-CQVTIrHF.js} +1 -1
  50. package/dist/assets/{glide-data-editor-CHNuHidQ.js → glide-data-editor-D5A4pou7.js} +11 -11
  51. package/dist/assets/{graph-CG6BgUWQ.js → graph-CBNo279v.js} +1 -1
  52. package/dist/assets/{home-page-dgivXuSR.js → home-page-CmdznBJR.js} +3 -3
  53. package/dist/assets/{index-BTGpssVX.js → index-0dfGh-Gj.js} +1 -1
  54. package/dist/assets/{index-C7dtgr9A.js → index-BDYVSSzB.js} +1 -1
  55. package/dist/assets/{index-C02SqeRj.js → index-B_KyDZ94.js} +1 -1
  56. package/dist/assets/{index-mkubqy9-.js → index-Bfy-I_lW.js} +1 -1
  57. package/dist/assets/{index-BelfnXwL.js → index-Bh98Tp-z.js} +1 -1
  58. package/dist/assets/{index-CAQvMTzM.js → index-BhroIwBL.js} +1 -1
  59. package/dist/assets/{index-BneyUujp.js → index-BtQtesaI.js} +1 -1
  60. package/dist/assets/index-C0iXCvyY.css +1 -0
  61. package/dist/assets/index-C1SHFMCp.js +581 -0
  62. package/dist/assets/{index-Csd6QrCV.js → index-C6DWtSls.js} +1 -1
  63. package/dist/assets/{index-BYVZlBF8.js → index-C71cdkH-.js} +1 -1
  64. package/dist/assets/{index-z4krxQ4j.js → index-CT_FTqvK.js} +1 -1
  65. package/dist/assets/{index-Db36XTG_.js → index-CU5rRr66.js} +1 -1
  66. package/dist/assets/{index-CtPksxf0.js → index-Cb6duXQm.js} +1 -1
  67. package/dist/assets/{index-DAZ-9ri2.js → index-D23e9zQj.js} +1 -1
  68. package/dist/assets/index-DUGecC2Z.js +68 -0
  69. package/dist/assets/{index-M_pBKDSe.js → index-DcGIOAQi.js} +1 -1
  70. package/dist/assets/{index-DONRrmA2.js → index-PJfa9qXY.js} +1 -1
  71. package/dist/assets/{index-sbO9UaUU.js → index-SPslPC2B.js} +1 -1
  72. package/dist/assets/{index-DdIhdEVw.js → index-VPQlo4Uz.js} +1 -1
  73. package/dist/assets/{index-_luCZMLM.js → index-qbTLKWyG.js} +1 -1
  74. package/dist/assets/infoDiagram-STP46IZ2-DBu8p9gd.js +2 -0
  75. package/dist/assets/{isEmpty-CqX_YTIf.js → isEmpty-CnOLuQIv.js} +1 -1
  76. package/dist/assets/{journeyDiagram-BIP6EPQ6-Y5w_Tqe_.js → journeyDiagram-BIP6EPQ6-6U_vHJBH.js} +1 -1
  77. package/dist/assets/{kanban-definition-6OIFK2YF-DbXs5Rxi.js → kanban-definition-6OIFK2YF-DgnR14ys.js} +1 -1
  78. package/dist/assets/{layout-BCNPDACj.js → layout-RHmq4fP9.js} +1 -1
  79. package/dist/assets/{linear-uO6UVhXt.js → linear-CLdOVPGV.js} +1 -1
  80. package/dist/assets/links-Dd1icsEk.js +7 -0
  81. package/dist/assets/{logs-panel-BEQ1eRUp.js → logs-panel-CjbuhBLx.js} +1 -1
  82. package/dist/assets/{markdown-renderer-Dmzbb00W.js → markdown-renderer-X5YJvAZq.js} +3 -3
  83. package/dist/assets/{mermaid-qRc4MXIj.js → mermaid-Bl2T5oEC.js} +1 -1
  84. package/dist/assets/{mermaid.core-CvvJtCRj.js → mermaid.core-CfukBvGI.js} +4 -4
  85. package/dist/assets/min-BXIes1Za.js +1 -0
  86. package/dist/assets/{mindmap-definition-Q6HEUPPD-G5NognM-.js → mindmap-definition-Q6HEUPPD-BXCjP4Lu.js} +1 -1
  87. package/dist/assets/{number-overlay-editor-DPr5sHFu.js → number-overlay-editor-BUyqkSes.js} +1 -1
  88. package/dist/assets/{outline-panel-gxQXvVi4.js → outline-panel-BvGcPKdd.js} +1 -1
  89. package/dist/assets/{packages-panel-B1T0VPlg.js → packages-panel-BichDQWG.js} +1 -1
  90. package/dist/assets/{pieDiagram-ADFJNKIX-DK9SHkfc.js → pieDiagram-ADFJNKIX-CMzJFIJM.js} +1 -1
  91. package/dist/assets/{quadrantDiagram-LMRXKWRM-D1DdWF8C.js → quadrantDiagram-LMRXKWRM-CfGssUlO.js} +1 -1
  92. package/dist/assets/{react-plotly-CTwajqCb.js → react-plotly-DR3hV0HW.js} +1 -1
  93. package/dist/assets/{requirementDiagram-4UW4RH46-DnjDAypr.js → requirementDiagram-4UW4RH46-CfrFolth.js} +1 -1
  94. package/dist/assets/{run-page-CQY9im22.js → run-page-Bqd_4ePD.js} +1 -1
  95. package/dist/assets/{sankeyDiagram-GR3RE2ED-B67Va-ER.js → sankeyDiagram-GR3RE2ED-D_UttKU0.js} +1 -1
  96. package/dist/assets/scratchpad-panel-D5N15ji1.js +1 -0
  97. package/dist/assets/secrets-panel-BpbnAO4R.js +1 -0
  98. package/dist/assets/{sequenceDiagram-C3RYC4MD-DiWgZPtN.js → sequenceDiagram-C3RYC4MD-MdfQQApP.js} +1 -1
  99. package/dist/assets/{slides-component-DhpPRtQp.js → slides-component-C0z7rXmk.js} +1 -1
  100. package/dist/assets/{snippets-panel-CLkBXhJ2.js → snippets-panel-wlpZ_Wzx.js} +1 -1
  101. package/dist/assets/{sortBy-D4OG7w4O.js → sortBy-BW_zNHP6.js} +1 -1
  102. package/dist/assets/{state-Dz_3JyED.js → state-CDooX-dk.js} +1 -1
  103. package/dist/assets/{stateDiagram-KXAO66HF-ByF2AULw.js → stateDiagram-KXAO66HF-H7kfw3ot.js} +1 -1
  104. package/dist/assets/stateDiagram-v2-UMBNRL4Z-YMeb9qMR.js +1 -0
  105. package/dist/assets/{storage-Dr0CC44z.js → storage-b1QCapTq.js} +6 -6
  106. package/dist/assets/{terminal-BtdissBf.js → terminal-CPV44BXz.js} +1 -1
  107. package/dist/assets/{time-DKdOTnQg.js → time-DDy3xv5Y.js} +1 -1
  108. package/dist/assets/{timeline-definition-XQNQX7LJ-DzER9bf6.js → timeline-definition-XQNQX7LJ-J-cPRT2_.js} +1 -1
  109. package/dist/assets/{tracing-Dpx5M-u3.js → tracing-3eHHRUiJ.js} +2 -2
  110. package/dist/assets/{tracing-panel-hCjBkSER.js → tracing-panel-BMgy3D7d.js} +2 -2
  111. package/dist/assets/{trash-C6Ko-g5q.js → trash--tonOuDe.js} +1 -1
  112. package/dist/assets/{tree-BHN2gcCF.js → tree-ouIGEsVg.js} +6 -6
  113. package/dist/assets/{treemap-75Q7IDZK-DR79Mhzt.js → treemap-75Q7IDZK-CzJTJ_3R.js} +20 -20
  114. package/dist/assets/{variable-panel-PFBCFz36.js → variable-panel-sFTn4Oih.js} +1 -1
  115. package/dist/assets/{vega-component-Db6-uY4C.js → vega-component-BkPkzX9r.js} +1 -1
  116. package/dist/assets/{xychartDiagram-6GGTOJPD-DWzBP3tZ.js → xychartDiagram-6GGTOJPD-BZ8WOb_8.js} +1 -1
  117. package/dist/index.html +10 -3
  118. package/package.json +6 -6
  119. package/src/__mocks__/common.ts +5 -3
  120. package/src/__mocks__/notebook.ts +2 -2
  121. package/src/__tests__/main.test.tsx +2 -2
  122. package/src/components/ai/ai-provider-icon.tsx +2 -0
  123. package/src/components/app-config/ai-config.tsx +32 -1
  124. package/src/components/app-config/common.tsx +2 -2
  125. package/src/components/app-config/user-config-form.tsx +26 -0
  126. package/src/components/audio/audio-recorder.tsx +0 -1
  127. package/src/components/chat/acp/blocks.tsx +2 -2
  128. package/src/components/chat/acp/thread.tsx +3 -5
  129. package/src/components/chat/acp/utils.ts +5 -5
  130. package/src/components/chat/chat-panel.tsx +1 -1
  131. package/src/components/data-table/__tests__/data-table.test.tsx +2 -2
  132. package/src/components/data-table/charts/__tests__/altair-generator.test.ts +1 -1
  133. package/src/components/data-table/charts/chart-spec/tooltips.ts +3 -3
  134. package/src/components/data-table/charts/components/chart-items.tsx +1 -1
  135. package/src/components/data-table/charts/components/form-fields.tsx +2 -2
  136. package/src/components/data-table/charts/constants.ts +1 -1
  137. package/src/components/data-table/column-explorer-panel/column-explorer.tsx +1 -1
  138. package/src/components/data-table/column-summary/chart-spec-model.tsx +2 -2
  139. package/src/components/data-table/columns.tsx +1 -1
  140. package/src/components/data-table/data-table.tsx +35 -3
  141. package/src/components/data-table/date-popover.tsx +1 -1
  142. package/src/components/data-table/download-actions.tsx +1 -1
  143. package/src/components/data-table/range-focus/__tests__/utils.test.ts +5 -5
  144. package/src/components/data-table/renderers.tsx +6 -5
  145. package/src/components/data-table/row-viewer-panel/row-viewer.tsx +1 -1
  146. package/src/components/data-table/types.ts +4 -3
  147. package/src/components/datasources/column-preview.tsx +9 -6
  148. package/src/components/debugger/debugger-code.tsx +1 -1
  149. package/src/components/dependency-graph/custom-node.tsx +15 -6
  150. package/src/components/dependency-graph/dependency-graph-minimap.tsx +2 -2
  151. package/src/components/dependency-graph/dependency-graph-tree.tsx +2 -2
  152. package/src/components/dependency-graph/dependency-graph.tsx +1 -1
  153. package/src/components/dependency-graph/elements.ts +7 -7
  154. package/src/components/dependency-graph/utils/changes.ts +4 -4
  155. package/src/components/editor/Cell.tsx +6 -2
  156. package/src/components/editor/ai/transport/chat-transport.tsx +1 -1
  157. package/src/components/editor/chrome/panels/outline/useActiveOutline.tsx +1 -1
  158. package/src/components/editor/chrome/panels/packages-panel.tsx +1 -1
  159. package/src/components/editor/columns/storage.ts +1 -1
  160. package/src/components/editor/database/__tests__/__snapshots__/as-code.test.ts.snap +36 -0
  161. package/src/components/editor/database/__tests__/as-code.test.ts +30 -7
  162. package/src/components/editor/database/add-database-form.tsx +11 -0
  163. package/src/components/editor/database/as-code.ts +104 -5
  164. package/src/components/editor/database/schemas.ts +36 -18
  165. package/src/components/editor/errors/auto-fix.tsx +12 -2
  166. package/src/components/editor/errors/sql-validation-errors.tsx +12 -6
  167. package/src/components/editor/navigation/clipboard.ts +2 -2
  168. package/src/components/editor/output/ConsoleOutput.tsx +1 -1
  169. package/src/components/editor/output/JsonOutput.tsx +1 -1
  170. package/src/components/editor/output/MarimoErrorOutput.tsx +25 -25
  171. package/src/components/editor/output/MarimoTracebackOutput.tsx +17 -2
  172. package/src/components/editor/renderers/grid-layout/types.ts +2 -2
  173. package/src/components/editor/renderers/plugins.ts +1 -1
  174. package/src/components/editor/renderers/types.ts +1 -1
  175. package/src/components/editor/renderers/vertical-layout/vertical-layout.tsx +7 -7
  176. package/src/components/forms/form.tsx +5 -5
  177. package/src/components/ui/links.tsx +1 -0
  178. package/src/core/ai/__tests__/model-registry.test.ts +0 -10
  179. package/src/core/ai/context/providers/error.ts +2 -2
  180. package/src/core/ai/ids/ids.ts +1 -0
  181. package/src/core/ai/model-registry.ts +2 -1
  182. package/src/core/cells/cells.ts +5 -5
  183. package/src/core/cells/logs.ts +1 -1
  184. package/src/core/cells/types.ts +1 -1
  185. package/src/core/codemirror/__tests__/format.test.ts +6 -0
  186. package/src/core/codemirror/cells/traceback-decorations.ts +1 -1
  187. package/src/core/codemirror/editing/commands.ts +2 -2
  188. package/src/core/codemirror/find-replace/navigate.ts +1 -1
  189. package/src/core/codemirror/language/__tests__/extension.test.ts +1 -1
  190. package/src/core/codemirror/language/__tests__/sql-validation.test.ts +1 -1
  191. package/src/core/codemirror/language/__tests__/sql.test.ts +764 -79
  192. package/src/core/codemirror/language/languages/markdown.ts +4 -1
  193. package/src/core/codemirror/language/languages/sql/{validation-errors.ts → banner-validation-errors.ts} +9 -3
  194. package/src/core/codemirror/language/languages/sql/completion-builder.ts +160 -0
  195. package/src/core/codemirror/language/languages/sql/completion-sources.tsx +9 -3
  196. package/src/core/codemirror/language/languages/sql/completion-store.ts +46 -50
  197. package/src/core/codemirror/language/languages/sql/renderers.tsx +485 -0
  198. package/src/core/codemirror/language/languages/sql/sql.ts +151 -24
  199. package/src/core/codemirror/language/languages/sql/utils.ts +4 -1
  200. package/src/core/codemirror/language/panel/sql.tsx +6 -1
  201. package/src/core/codemirror/language/utils/ast.ts +3 -3
  202. package/src/core/codemirror/lsp/federated-lsp.ts +4 -4
  203. package/src/core/codemirror/lsp/lens.ts +4 -4
  204. package/src/core/codemirror/lsp/notebook-lsp.ts +1 -1
  205. package/src/core/codemirror/lsp/types.ts +1 -1
  206. package/src/core/codemirror/markdown/completions.ts +1 -1
  207. package/src/core/codemirror/reactive-references/analyzer.ts +2 -2
  208. package/src/core/codemirror/rtc/loro/awareness.ts +1 -1
  209. package/src/core/config/config-schema.ts +1 -0
  210. package/src/core/config/feature-flag.tsx +3 -1
  211. package/src/core/datasets/request-registry.ts +17 -10
  212. package/src/core/dom/events.ts +1 -1
  213. package/src/core/dom/outline.ts +2 -2
  214. package/src/core/dom/uiregistry.ts +2 -8
  215. package/src/core/errors/__tests__/errors.test.ts +22 -4
  216. package/src/core/errors/errors.ts +29 -1
  217. package/src/core/errors/state.ts +1 -1
  218. package/src/core/islands/main.ts +2 -2
  219. package/src/core/islands/parse.ts +1 -3
  220. package/src/core/kernel/messages.ts +1 -1
  221. package/src/core/network/CachingRequestRegistry.ts +74 -0
  222. package/src/core/network/DeferredRequestRegistry.ts +3 -1
  223. package/src/core/network/__tests__/CachingRequestRegistry.test.ts +73 -0
  224. package/src/core/network/types.ts +1 -1
  225. package/src/core/variables/state.ts +2 -2
  226. package/src/core/wasm/__tests__/state.test.ts +1 -1
  227. package/src/core/websocket/useMarimoWebSocket.tsx +5 -2
  228. package/src/custom.d.ts +1 -1
  229. package/src/hooks/useCellRenderCount.ts +1 -0
  230. package/src/hooks/useResizeHandle.ts +4 -1
  231. package/src/plugins/core/RenderHTML.tsx +1 -2
  232. package/src/plugins/impl/DataTablePlugin.tsx +7 -2
  233. package/src/plugins/impl/FileUploadPlugin.tsx +1 -1
  234. package/src/plugins/impl/RefreshPlugin.tsx +1 -1
  235. package/src/plugins/impl/SliderPlugin.tsx +4 -0
  236. package/src/plugins/impl/anywidget/AnyWidgetPlugin.tsx +27 -9
  237. package/src/plugins/impl/anywidget/__tests__/AnyWidgetPlugin.test.tsx +58 -2
  238. package/src/plugins/impl/anywidget/__tests__/model.test.ts +3 -4
  239. package/src/plugins/impl/anywidget/model.ts +2 -3
  240. package/src/plugins/impl/data-editor/types.ts +1 -1
  241. package/src/plugins/impl/data-explorer/components/query-form.tsx +1 -1
  242. package/src/plugins/impl/data-frames/types.ts +1 -1
  243. package/src/plugins/impl/panel/PanelPlugin.tsx +2 -2
  244. package/src/plugins/impl/plotly/PlotlyPlugin.tsx +3 -3
  245. package/src/plugins/impl/vega/__tests__/loader.test.ts +2 -2
  246. package/src/plugins/impl/vega/loader.ts +1 -1
  247. package/src/plugins/impl/vega/vega-component.tsx +1 -1
  248. package/src/plugins/impl/vega/vega-loader.ts +2 -2
  249. package/src/plugins/layout/NavigationMenuPlugin.tsx +1 -1
  250. package/src/plugins/layout/RoutesPlugin.tsx +1 -2
  251. package/src/plugins/plugins.ts +2 -2
  252. package/src/utils/Logger.ts +1 -1
  253. package/src/utils/__tests__/data-views.test.ts +30 -68
  254. package/src/utils/__tests__/dom.test.ts +10 -10
  255. package/src/utils/__tests__/id-tree.test.ts +49 -1
  256. package/src/utils/__tests__/storage.test.ts +1 -1
  257. package/src/utils/__tests__/traceback.test.ts +13 -2
  258. package/src/utils/arrays.ts +1 -1
  259. package/src/utils/createReducer.ts +1 -5
  260. package/src/utils/data-views.ts +6 -19
  261. package/src/utils/edit-distance.ts +1 -1
  262. package/src/utils/fileToBase64.ts +1 -1
  263. package/src/utils/id-tree.tsx +20 -18
  264. package/src/utils/json/base64.ts +13 -0
  265. package/src/utils/json/json-parser.ts +2 -2
  266. package/src/utils/lru.ts +4 -0
  267. package/src/utils/mergeRefs.ts +1 -1
  268. package/src/utils/objects.ts +3 -3
  269. package/src/utils/pluralize.ts +1 -1
  270. package/src/utils/routes.ts +2 -2
  271. package/src/utils/sets.ts +1 -1
  272. package/src/utils/traceback.ts +45 -15
  273. package/src/utils/tracer.ts +11 -9
  274. package/dist/assets/_baseEach--KDTwKbG.js +0 -1
  275. package/dist/assets/_baseMap-Cu3o-eyO.js +0 -1
  276. package/dist/assets/_baseUniq-y7ZXnMo1.js +0 -1
  277. package/dist/assets/channel-DFaEx1fu.js +0 -1
  278. package/dist/assets/chat-panel-IoPMv8e2.js +0 -3
  279. package/dist/assets/classDiagram-KNZD7YFC-BsZtvV5O.js +0 -1
  280. package/dist/assets/classDiagram-v2-RKCZMP56-BsZtvV5O.js +0 -1
  281. package/dist/assets/clone-YBEvPE-s.js +0 -1
  282. package/dist/assets/command-palette-D7hOfvf6.js +0 -1
  283. package/dist/assets/edit-page-C5TsEeSo.js +0 -129
  284. package/dist/assets/index-CGDMlQfO.css +0 -1
  285. package/dist/assets/index-CelXfcd8.js +0 -580
  286. package/dist/assets/index-Cxyk7pt-.js +0 -68
  287. package/dist/assets/infoDiagram-STP46IZ2-wTALjfPc.js +0 -2
  288. package/dist/assets/links-Drv7cJgN.js +0 -7
  289. package/dist/assets/min-DYUOb1RR.js +0 -1
  290. package/dist/assets/scratchpad-panel-DlDfcDtW.js +0 -1
  291. package/dist/assets/secrets-panel-BDGyuGZA.js +0 -1
  292. package/dist/assets/stateDiagram-v2-UMBNRL4Z-CtBJqosP.js +0 -1
  293. package/src/__tests__/lru.test.ts +0 -74
@@ -778,14 +778,14 @@ export class ColumnChartSpecModel<T> {
778
778
  const yField = "value";
779
779
 
780
780
  // Calculate xStart and xEnd for each value count
781
- const newValueCounts: Array<{
781
+ const newValueCounts: {
782
782
  count: number;
783
783
  value: string;
784
784
  xStart: number;
785
785
  xEnd: number;
786
786
  xMid: number;
787
787
  proportion: number;
788
- }> = [];
788
+ }[] = [];
789
789
  let xStart = 0;
790
790
  for (const valueCount of valueCounts) {
791
791
  const xEnd = xStart + valueCount.count;
@@ -117,7 +117,7 @@ export function generateColumns<T>({
117
117
  headerTooltip?: Record<string, string>;
118
118
  showDataTypes?: boolean;
119
119
  calculateTopKRows?: CalculateTopKRows;
120
- }): Array<ColumnDef<T>> {
120
+ }): ColumnDef<T>[] {
121
121
  // Row-headers are typically index columns
122
122
  const rowHeadersSet = new Set(rowHeaders.map(([columnName]) => columnName));
123
123
 
@@ -47,7 +47,8 @@ import { getStableRowId } from "./utils";
47
47
  interface DataTableProps<TData> extends Partial<DownloadActionProps> {
48
48
  wrapperClassName?: string;
49
49
  className?: string;
50
- columns: Array<ColumnDef<TData>>;
50
+ maxHeight?: number;
51
+ columns: ColumnDef<TData>[];
51
52
  data: TData[];
52
53
  // Sorting
53
54
  manualSorting?: boolean; // server-side sorting
@@ -95,6 +96,7 @@ interface DataTableProps<TData> extends Partial<DownloadActionProps> {
95
96
  const DataTableInternal = <TData,>({
96
97
  wrapperClassName,
97
98
  className,
99
+ maxHeight,
98
100
  columns,
99
101
  data,
100
102
  selection,
@@ -250,6 +252,36 @@ const DataTableInternal = <TData,>({
250
252
 
251
253
  const rowViewerPanelOpen = isPanelOpen?.("row-viewer") ?? false;
252
254
 
255
+ const tableRef = React.useRef<HTMLTableElement | null>(null);
256
+
257
+ // Why use a ref to set max-height on the wrapper?
258
+ // - position: sticky only works when the sticky element's nearest scrollable
259
+ // ancestor is its immediate container. If max-height/overflow are applied
260
+ // on a grandparent, sticky table headers (th) will not stick.
261
+ // - We keep the scroll wrapper colocated with the base Table component, but
262
+ // derive the scroll boundary from maxHeight here to avoid coupling UI base
263
+ // components to data-table specifics or expanding their API surface.
264
+ // - Setting styles on the table's direct wrapper ensures the header sticks
265
+ // reliably across browsers without changing upstream components.
266
+ React.useEffect(() => {
267
+ if (!tableRef.current) {
268
+ return;
269
+ }
270
+ const wrapper = tableRef.current.parentElement as HTMLDivElement | null;
271
+ if (!wrapper) {
272
+ return;
273
+ }
274
+ if (maxHeight) {
275
+ wrapper.style.maxHeight = `${maxHeight}px`;
276
+ // Ensure wrapper scrolls
277
+ if (!wrapper.style.overflow) {
278
+ wrapper.style.overflow = "auto";
279
+ }
280
+ } else {
281
+ wrapper.style.removeProperty("max-height");
282
+ }
283
+ }, [maxHeight]);
284
+
253
285
  return (
254
286
  <div className={cn(wrapperClassName, "flex flex-col space-y-1")}>
255
287
  <FilterPills filters={filters} table={table} />
@@ -263,11 +295,11 @@ const DataTableInternal = <TData,>({
263
295
  reloading={reloading}
264
296
  />
265
297
  )}
266
- <Table className="relative">
298
+ <Table className="relative" ref={tableRef}>
267
299
  {showLoadingBar && (
268
300
  <div className="absolute top-0 left-0 h-[3px] w-1/2 bg-primary animate-slide" />
269
301
  )}
270
- {renderTableHeader(table)}
302
+ {renderTableHeader(table, Boolean(maxHeight))}
271
303
  <CellSelectionProvider>
272
304
  <DataTableBody
273
305
  table={table}
@@ -124,7 +124,7 @@ const RelativeTime = ({ date }: { date: Date }) => {
124
124
  const differenceInSeconds = (currentTime.getTime() - date.getTime()) / 1000;
125
125
 
126
126
  // Define time units with their thresholds and conversion factors
127
- const timeUnits: Array<[number, number, string]> = [
127
+ const timeUnits: [number, number, string][] = [
128
128
  [60, 1, "second"], // Less than 60 seconds
129
129
  [60, 60, "minute"], // Less than 60 minutes
130
130
  [24, 3600, "hour"], // Less than 24 hours
@@ -167,7 +167,7 @@ export const DownloadAs: React.FC<DownloadActionProps> = (props) => {
167
167
  );
168
168
  };
169
169
 
170
- function fetchJson(url: string): Promise<Array<Record<string, unknown>>> {
170
+ function fetchJson(url: string): Promise<Record<string, unknown>[]> {
171
171
  return fetch(url).then((res) => {
172
172
  if (!res.ok) {
173
173
  throw new Error(res.statusText);
@@ -20,17 +20,17 @@ function createMockCell(id: string, value: unknown): Cell<unknown, unknown> {
20
20
  function createMockColumn(id: string): Column<unknown> {
21
21
  return {
22
22
  id: id,
23
- getIndex: () => Number.parseInt(id),
23
+ getIndex: () => Number.parseInt(id, 10),
24
24
  } as unknown as Column<unknown>;
25
25
  }
26
26
 
27
27
  function createMockRow(
28
28
  id: string,
29
- cells: Array<Cell<unknown, unknown>>,
29
+ cells: Cell<unknown, unknown>[],
30
30
  ): Row<unknown> {
31
31
  return {
32
32
  id,
33
- index: Number.parseInt(id),
33
+ index: Number.parseInt(id, 10),
34
34
  getAllCells: () => cells,
35
35
  original: {},
36
36
  depth: 0,
@@ -43,8 +43,8 @@ function createMockRow(
43
43
  }
44
44
 
45
45
  function createMockTable(
46
- rows: Array<Row<unknown>>,
47
- columns: Array<Column<unknown>>,
46
+ rows: Row<unknown>[],
47
+ columns: Column<unknown>[],
48
48
  ): Table<unknown> {
49
49
  return {
50
50
  getRow: (id: string) => rows.find((row) => row.id === id),
@@ -26,12 +26,13 @@ import { useScrollIntoViewOnFocus } from "./range-focus/use-scroll-into-view";
26
26
 
27
27
  export function renderTableHeader<TData>(
28
28
  table: Table<TData>,
29
+ isSticky?: boolean,
29
30
  ): JSX.Element | null {
30
31
  if (!table.getRowModel().rows?.length) {
31
32
  return null;
32
33
  }
33
34
 
34
- const renderHeaderGroup = (headerGroups: Array<HeaderGroup<TData>>) => {
35
+ const renderHeaderGroup = (headerGroups: HeaderGroup<TData>[]) => {
35
36
  return headerGroups.map((headerGroup) =>
36
37
  headerGroup.headers.map((header) => {
37
38
  const { className, style } = getPinningStyles(header.column);
@@ -57,7 +58,7 @@ export function renderTableHeader<TData>(
57
58
  };
58
59
 
59
60
  return (
60
- <TableHeader>
61
+ <TableHeader className={cn(isSticky && "sticky top-0 z-10")}>
61
62
  <TableRow>
62
63
  {renderHeaderGroup(table.getLeftHeaderGroups())}
63
64
  {renderHeaderGroup(table.getCenterHeaderGroups())}
@@ -69,7 +70,7 @@ export function renderTableHeader<TData>(
69
70
 
70
71
  interface DataTableBodyProps<TData> {
71
72
  table: Table<TData>;
72
- columns: Array<ColumnDef<TData>>;
73
+ columns: ColumnDef<TData>[];
73
74
  rowViewerPanelOpen: boolean;
74
75
  getRowIndex?: (row: TData, idx: number) => number;
75
76
  viewedRowIdx?: number;
@@ -95,7 +96,7 @@ export const DataTableBody = <TData,>({
95
96
 
96
97
  function applyHoverTemplate(
97
98
  template: string,
98
- cells: Array<Cell<TData, unknown>>,
99
+ cells: Cell<TData, unknown>[],
99
100
  ): string {
100
101
  const variableRegex = /{{(\w+)}}/g;
101
102
  // Map column id -> stringified value
@@ -112,7 +113,7 @@ export const DataTableBody = <TData,>({
112
113
  });
113
114
  }
114
115
 
115
- const renderCells = (cells: Array<Cell<TData, unknown>>) => {
116
+ const renderCells = (cells: Cell<TData, unknown>[]) => {
116
117
  return cells.map((cell) => {
117
118
  const { className, style: pinningstyle } = getPinningStyles(cell.column);
118
119
  const style = Object.assign(
@@ -188,7 +188,7 @@ export const RowViewerPanel: React.FC<RowViewerPanelProps> = ({
188
188
  </TableRow>
189
189
  </TableHeader>
190
190
  <TableBody>
191
- {fieldTypes?.map(([columnName, [dataType, externalType]]) => {
191
+ {fieldTypes?.map(([columnName, [dataType, _externalType]]) => {
192
192
  const columnValue = rowValues[columnName];
193
193
 
194
194
  if (!inSearchQuery({ columnName, columnValue, searchQuery })) {
@@ -27,9 +27,10 @@ export type ColumnHeaderStats = Record<
27
27
  number | string | null
28
28
  >;
29
29
 
30
- export type FieldTypesWithExternalType = Array<
31
- [columnName: string, [dataType: DataType, externalType: string]]
32
- >;
30
+ export type FieldTypesWithExternalType = [
31
+ columnName: string,
32
+ [dataType: DataType, externalType: string],
33
+ ][];
33
34
  export type FieldTypes = Record<string, DataType>;
34
35
 
35
36
  export function toFieldTypes(
@@ -110,7 +110,8 @@ export const DatasetColumnPreview: React.FC<{
110
110
  });
111
111
 
112
112
  const stats =
113
- preview.stats && renderStats(preview.stats, column.type, locale);
113
+ preview.stats &&
114
+ renderStats({ stats: preview.stats, dataType: column.type, locale });
114
115
 
115
116
  const chart = preview.chart_spec && renderChart(preview.chart_spec, theme);
116
117
 
@@ -175,11 +176,13 @@ export function renderPreviewError({
175
176
  );
176
177
  }
177
178
 
178
- export function renderStats(
179
- stats: Partial<Record<ColumnHeaderStatsKey, unknown>>,
180
- dataType: DataType,
181
- locale: string,
182
- ) {
179
+ interface RenderStatsProps {
180
+ stats: Partial<Record<ColumnHeaderStatsKey, unknown>>;
181
+ dataType: DataType;
182
+ locale: string;
183
+ }
184
+
185
+ export function renderStats({ stats, dataType, locale }: RenderStatsProps) {
183
186
  return (
184
187
  <div className="gap-x-16 gap-y-1 grid grid-cols-2-fit border rounded p-2 empty:hidden">
185
188
  {Object.entries(stats).map(([key, value]) => {
@@ -106,7 +106,7 @@ const DebuggerInput: React.FC<{
106
106
  key: "Enter",
107
107
  preventDefault: true,
108
108
  stopPropagation: true,
109
- run: (view: EditorView) => {
109
+ run: () => {
110
110
  const v = value.trim().replaceAll("\n", "\\n");
111
111
  if (!v) {
112
112
  return true;
@@ -1,7 +1,7 @@
1
1
  /* Copyright 2024 Marimo. All rights reserved. */
2
2
 
3
3
  import { useAtomValue } from "jotai";
4
- import React, { memo, use } from "react";
4
+ import React, { memo, use, useId } from "react";
5
5
  import { Handle, Position, useStore } from "reactflow";
6
6
  import { TinyCode } from "@/components/editor/cell/TinyCode";
7
7
  import { useCellIds } from "@/core/cells/cells";
@@ -23,7 +23,7 @@ const EQUALITY_CHECK = (
23
23
  prevProps: CustomNodeProps,
24
24
  nextProps: CustomNodeProps,
25
25
  ) => {
26
- const keys: Array<keyof CustomNodeProps> = ["data", "selected", "id"];
26
+ const keys: (keyof CustomNodeProps)[] = ["data", "selected", "id"];
27
27
  return keys.every((key) => prevProps[key] === nextProps[key]);
28
28
  };
29
29
 
@@ -37,18 +37,25 @@ export const CustomNode = memo((props: CustomNodeProps) => {
37
37
  const reactFlowWidth = useStore(({ width }) => width);
38
38
  const edgeMarkers = use(EdgeMarkerContext);
39
39
 
40
+ const inputOneId = useId();
41
+ const inputTwoId = useId();
42
+ const outputOneId = useId();
43
+ const outputTwoId = useId();
44
+
40
45
  const linesOfCode = cell.code.split("\n").length;
41
46
  return (
42
47
  <div>
43
48
  <Handle
44
49
  type="target"
45
- id="inputs"
50
+ id={inputOneId}
51
+ data-testid="input-one"
46
52
  position={edgeMarkers === "LR" ? Position.Left : Position.Top}
47
53
  style={{ background: color }}
48
54
  />
49
55
  <Handle
50
56
  type="source"
51
- id="inputs"
57
+ id={inputTwoId}
58
+ data-testid="input-two"
52
59
  position={edgeMarkers === "LR" ? Position.Left : Position.Top}
53
60
  style={{ background: color }}
54
61
  />
@@ -69,13 +76,15 @@ export const CustomNode = memo((props: CustomNodeProps) => {
69
76
  </div>
70
77
  <Handle
71
78
  type="source"
72
- id="outputs"
79
+ id={outputOneId}
80
+ data-testid="output-one"
73
81
  position={edgeMarkers === "LR" ? Position.Right : Position.Bottom}
74
82
  style={{ background: color }}
75
83
  />
76
84
  <Handle
77
85
  type="target"
78
- id="outputs"
86
+ id={outputTwoId}
87
+ data-testid="output-two"
79
88
  position={edgeMarkers === "LR" ? Position.Right : Position.Bottom}
80
89
  style={{ background: color }}
81
90
  />
@@ -31,7 +31,7 @@ import { useFitToViewOnDimensionChange } from "./utils/useFitToViewOnDimensionCh
31
31
  interface Props {
32
32
  cellIds: CellId[];
33
33
  variables: Variables;
34
- cellAtoms: Array<Atom<CellData>>;
34
+ cellAtoms: Atom<CellData>[];
35
35
  }
36
36
 
37
37
  const elementsBuilder = new VerticalElementsBuilder();
@@ -57,7 +57,7 @@ export const DependencyGraphMinimap: React.FC<PropsWithChildren<Props>> = ({
57
57
 
58
58
  // If the cellIds change, update the nodes.
59
59
  const syncChanges = useEvent(
60
- (elements: { nodes: Array<Node<NodeData>>; edges: Edge[] }) => {
60
+ (elements: { nodes: Node<NodeData>[]; edges: Edge[] }) => {
61
61
  setNodes(elements.nodes);
62
62
  setEdges([]);
63
63
  },
@@ -36,7 +36,7 @@ import { useFitToViewOnDimensionChange } from "./utils/useFitToViewOnDimensionCh
36
36
  interface Props {
37
37
  cellIds: CellId[];
38
38
  variables: Variables;
39
- cellAtoms: Array<Atom<CellData>>;
39
+ cellAtoms: Atom<CellData>[];
40
40
  layoutDirection: LayoutDirection;
41
41
  settings: GraphSettings;
42
42
  }
@@ -74,7 +74,7 @@ export const DependencyGraphTree: React.FC<PropsWithChildren<Props>> = ({
74
74
  const api = useReactFlow();
75
75
 
76
76
  const syncChanges = useEvent(
77
- (elements: { nodes: Array<Node<NodeData>>; edges: Edge[] }) => {
77
+ (elements: { nodes: Node<NodeData>[]; edges: Edge[] }) => {
78
78
  // Layout the elements
79
79
  const result = layoutElements({
80
80
  nodes: elements.nodes,
@@ -18,7 +18,7 @@ import "./dependency-graph.css";
18
18
  interface Props {
19
19
  cellIds: CellId[];
20
20
  variables: Variables;
21
- cellAtoms: Array<Atom<CellData>>;
21
+ cellAtoms: Atom<CellData>[];
22
22
  children?: React.ReactNode;
23
23
  }
24
24
 
@@ -22,10 +22,10 @@ export function getNodeHeight(linesOfCode: number) {
22
22
  interface ElementsBuilder {
23
23
  createElements: (
24
24
  cellIds: CellId[],
25
- cellAtoms: Array<Atom<CellData>>,
25
+ cellAtoms: Atom<CellData>[],
26
26
  variables: Variables,
27
27
  hidePureMarkdown: boolean,
28
- ) => { nodes: Array<Node<NodeData>>; edges: Edge[] };
28
+ ) => { nodes: Node<NodeData>[]; edges: Edge[] };
29
29
  }
30
30
 
31
31
  export class VerticalElementsBuilder implements ElementsBuilder {
@@ -69,12 +69,12 @@ export class VerticalElementsBuilder implements ElementsBuilder {
69
69
 
70
70
  createElements(
71
71
  cellIds: CellId[],
72
- cellAtoms: Array<Atom<CellData>>,
72
+ cellAtoms: Atom<CellData>[],
73
73
  variables: Variables,
74
- hidePureMarkdown: boolean,
74
+ _hidePureMarkdown: boolean,
75
75
  ) {
76
76
  let prevY = 0;
77
- const nodes: Array<Node<NodeData>> = [];
77
+ const nodes: Node<NodeData>[] = [];
78
78
  const edges: Edge[] = [];
79
79
  for (const [cellId, cellAtom] of Arrays.zip(cellIds, cellAtoms)) {
80
80
  const node = this.createNode(cellId, cellAtom, prevY);
@@ -135,11 +135,11 @@ export class TreeElementsBuilder implements ElementsBuilder {
135
135
 
136
136
  createElements(
137
137
  cellIds: CellId[],
138
- cellAtoms: Array<Atom<CellData>>,
138
+ cellAtoms: Atom<CellData>[],
139
139
  variables: Variables,
140
140
  hidePureMarkdown: boolean,
141
141
  ) {
142
- const nodes: Array<Node<NodeData>> = [];
142
+ const nodes: Node<NodeData>[] = [];
143
143
  const edges: Edge[] = [];
144
144
 
145
145
  const nodesWithEdges = new Set<CellId>();
@@ -11,8 +11,8 @@ import type {
11
11
  export function getNodeChanges(
12
12
  prevNodes: Node[],
13
13
  nextNodes: Node[],
14
- ): Array<NodeAddChange | NodeRemoveChange> {
15
- const changes: Array<NodeAddChange | NodeRemoveChange> = [];
14
+ ): (NodeAddChange | NodeRemoveChange)[] {
15
+ const changes: (NodeAddChange | NodeRemoveChange)[] = [];
16
16
  const prevNodeIds = new Set(prevNodes.map((node) => node.id));
17
17
  const nextNodeIds = new Set(nextNodes.map((node) => node.id));
18
18
 
@@ -33,8 +33,8 @@ export function getNodeChanges(
33
33
  export function getEdgeChanges(
34
34
  prevEdges: Edge[],
35
35
  nextEdges: Edge[],
36
- ): Array<EdgeAddChange | EdgeRemoveChange> {
37
- const changes: Array<EdgeAddChange | EdgeRemoveChange> = [];
36
+ ): (EdgeAddChange | EdgeRemoveChange)[] {
37
+ const changes: (EdgeAddChange | EdgeRemoveChange)[] = [];
38
38
  const prevEdgeIds = new Set(prevEdges.map((edge) => edge.id));
39
39
  const nextEdgeIds = new Set(nextEdges.map((edge) => edge.id));
40
40
 
@@ -451,6 +451,7 @@ const EditableCellComponent = ({
451
451
  });
452
452
  const canCollapse = canCollapseOutline(cellRuntime.outline);
453
453
  const hasOutput = !isOutputEmpty(cellRuntime.output);
454
+ const isStaleCell = outputIsStale(cellRuntime, cellData.edited);
454
455
  const hasConsoleOutput = cellRuntime.consoleOutputs.length > 0;
455
456
  const cellOutput = userConfig.display.cell_output;
456
457
 
@@ -511,7 +512,7 @@ const EditableCellComponent = ({
511
512
  className="output-area"
512
513
  cellId={cellId}
513
514
  output={cellRuntime.output}
514
- stale={outputIsStale(cellRuntime, cellData.edited)}
515
+ stale={isStaleCell}
515
516
  loading={outputIsLoading(cellRuntime.status)}
516
517
  />
517
518
  {isMarkdownCodeHidden &&
@@ -654,7 +655,10 @@ const EditableCellComponent = ({
654
655
  )}
655
656
  </div>
656
657
  </div>
657
- <SqlValidationErrorBanner cellId={cellId} />
658
+ <SqlValidationErrorBanner
659
+ cellId={cellId}
660
+ hide={cellRuntime.errored && !isStaleCell}
661
+ />
658
662
  {cellOutput === "below" && outputArea}
659
663
  {cellRuntime.serialization && (
660
664
  <div className="py-1 px-2 flex items-center justify-end gap-2 last:rounded-b">
@@ -16,7 +16,7 @@ export class StreamingChunkTransport<
16
16
  private onChunkReceived: (chunk: UIMessageChunk) => void;
17
17
 
18
18
  constructor(
19
- options: HttpChatTransportInitOptions<UI_MESSAGE> = {},
19
+ options: HttpChatTransportInitOptions<UI_MESSAGE>,
20
20
  onChunkReceived: (chunk: UIMessageChunk) => void,
21
21
  ) {
22
22
  super(options);
@@ -18,7 +18,7 @@ function getRootScrollableElement() {
18
18
  * React hook to find the active header in the outline
19
19
  */
20
20
  export function useActiveOutline(
21
- headerElements: Array<readonly [HTMLElement, string]>,
21
+ headerElements: (readonly [HTMLElement, string])[],
22
22
  ) {
23
23
  const [activeHeaderId, setActiveHeaderId] = useState<string | undefined>(
24
24
  undefined,
@@ -300,7 +300,7 @@ const InstallPackageForm: React.FC<{
300
300
 
301
301
  const PackagesList: React.FC<{
302
302
  onSuccess: () => void;
303
- packages: Array<{ name: string; version: string }>;
303
+ packages: { name: string; version: string }[];
304
304
  }> = ({ onSuccess, packages }) => {
305
305
  if (packages.length === 0) {
306
306
  return (
@@ -7,7 +7,7 @@ import { NotebookScopedLocalStorage } from "@/utils/localStorage";
7
7
  const BASE_KEY = "marimo:notebook-col-sizes";
8
8
 
9
9
  interface ColumnSizes {
10
- widths: Array<number | "contentWidth">;
10
+ widths: (number | "contentWidth")[];
11
11
  }
12
12
 
13
13
  function initialState(): ColumnSizes {
@@ -28,6 +28,42 @@ engine = clickhouse_connect.get_client(
28
28
  )"
29
29
  `;
30
30
 
31
+ exports[`generateDatabaseCode > basic connections > databricks 1`] = `
32
+ "import os
33
+ import sqlalchemy
34
+
35
+ _access_token = os.environ.get("DATABRICKS_ACCESS_TOKEN", "my_access_token")
36
+ _server_hostname = os.environ.get("DATABRICKS_SERVER_HOSTNAME", "localhost")
37
+ _http_path = os.environ.get("DATABRICKS_HTTP_PATH", "http://localhost:8080")
38
+ DATABASE_URL = f"databricks://token:{_access_token}@{_server_hostname}?http_path={_http_path}"
39
+ engine = sqlalchemy.create_engine(DATABASE_URL)"
40
+ `;
41
+
42
+ exports[`generateDatabaseCode > basic connections > databricks with catalog and schema 1`] = `
43
+ "import os
44
+ import sqlalchemy
45
+
46
+ _access_token = os.environ.get("DATABRICKS_ACCESS_TOKEN", "my_access_token")
47
+ _server_hostname = os.environ.get("DATABRICKS_SERVER_HOSTNAME", "localhost")
48
+ _http_path = os.environ.get("DATABRICKS_HTTP_PATH", "http://localhost:8080")
49
+ DATABASE_URL = f"databricks://token:{_access_token}@{_server_hostname}?http_path={_http_path}&catalog=my_catalog&schema=my_schema"
50
+ engine = sqlalchemy.create_engine(DATABASE_URL)"
51
+ `;
52
+
53
+ exports[`generateDatabaseCode > basic connections > databricks with ibis 1`] = `
54
+ "import ibis
55
+ import os
56
+
57
+ _access_token = os.environ.get("DATABRICKS_ACCESS_TOKEN", "my_access_token")
58
+ _server_hostname = os.environ.get("DATABRICKS_SERVER_HOSTNAME", "localhost")
59
+ _http_path = os.environ.get("DATABRICKS_HTTP_PATH", "http://localhost:8080")
60
+ engine = ibis.databricks.connect(
61
+ server_hostname=_server_hostname,
62
+ http_path=_http_path,
63
+ access_token=_access_token
64
+ )"
65
+ `;
66
+
31
67
  exports[`generateDatabaseCode > basic connections > datafusion 1`] = `
32
68
  "from datafusion import SessionContext
33
69
  import ibis
@@ -192,8 +192,24 @@ describe("generateDatabaseCode", () => {
192
192
  },
193
193
  };
194
194
 
195
+ const databricksConnection: DatabaseConnection = {
196
+ type: "databricks",
197
+ access_token: "my_access_token",
198
+ server_hostname: "localhost",
199
+ http_path: "http://localhost:8080",
200
+ };
201
+
202
+ const databricksWithCatalogSchema: DatabaseConnection = {
203
+ type: "databricks",
204
+ access_token: "my_access_token",
205
+ server_hostname: "localhost",
206
+ http_path: "http://localhost:8080",
207
+ catalog: "my_catalog",
208
+ schema: "my_schema",
209
+ };
210
+
195
211
  describe("basic connections", () => {
196
- const testCases: Array<[string, DatabaseConnection, ConnectionLibrary]> = [
212
+ const testCases: [string, DatabaseConnection, ConnectionLibrary][] = [
197
213
  ["postgres with SQLModel", basePostgres, "sqlmodel"],
198
214
  ["postgres with SQLAlchemy", basePostgres, "sqlalchemy"],
199
215
  ["mysql with SQLModel", baseMysql, "sqlmodel"],
@@ -218,9 +234,16 @@ describe("generateDatabaseCode", () => {
218
234
  ["pyspark with session", pysparkConnSession, "ibis"],
219
235
  ["redshift with DB credentials", redshiftDBConnection, "redshift"],
220
236
  ["redshift with IAM credentials", redshiftIAMConnection, "redshift"],
237
+ ["databricks", databricksConnection, "sqlalchemy"],
238
+ [
239
+ "databricks with catalog and schema",
240
+ databricksWithCatalogSchema,
241
+ "sqlalchemy",
242
+ ],
243
+ ["databricks with ibis", databricksConnection, "ibis"],
221
244
  ];
222
245
 
223
- it.each(testCases)("%s", (name, connection, orm) => {
246
+ it.each(testCases)("%s", (_name, connection, orm) => {
224
247
  expect(generateDatabaseCode(connection, orm)).toMatchSnapshot();
225
248
  });
226
249
  });
@@ -292,7 +315,7 @@ describe("generateDatabaseCode", () => {
292
315
  },
293
316
  "duckdb",
294
317
  ],
295
- ])("%s", (name, connection, orm) => {
318
+ ])("%s", (_name, connection, orm) => {
296
319
  expect(
297
320
  generateDatabaseCode(connection, orm as ConnectionLibrary),
298
321
  ).toMatchSnapshot();
@@ -300,7 +323,7 @@ describe("generateDatabaseCode", () => {
300
323
  });
301
324
 
302
325
  describe("edge cases", () => {
303
- const testCases: Array<[string, DatabaseConnection, string]> = [
326
+ const testCases: [string, DatabaseConnection, string][] = [
304
327
  [
305
328
  "ENV with special chars SQLModel",
306
329
  {
@@ -504,7 +527,7 @@ describe("generateDatabaseCode", () => {
504
527
  ],
505
528
  ];
506
529
 
507
- it.each(testCases)("%s", (name, connection, orm) => {
530
+ it.each(testCases)("%s", (_name, connection, orm) => {
508
531
  expect(
509
532
  generateDatabaseCode(connection, orm as ConnectionLibrary),
510
533
  ).toMatchSnapshot();
@@ -548,7 +571,7 @@ describe("generateDatabaseCode", () => {
548
571
  credentials_json: '{"type": "service_account", "project_id": "test"',
549
572
  },
550
573
  ],
551
- ])("%s", (name, connection) => {
574
+ ])("%s", (_name, connection) => {
552
575
  expect(generateDatabaseCode(connection, "sqlmodel")).toMatchSnapshot();
553
576
  expect(generateDatabaseCode(connection, "sqlalchemy")).toMatchSnapshot();
554
577
  });
@@ -591,7 +614,7 @@ describe("generateDatabaseCode", () => {
591
614
  "sqlmodel",
592
615
  ),
593
616
  ],
594
- ])("%s", (name, fn) => {
617
+ ])("%s", (_name, fn) => {
595
618
  expect(fn).toThrow();
596
619
  });
597
620
  });