@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
@@ -16,7 +16,7 @@ import { renderHTML } from "@/plugins/core/RenderHTML";
16
16
  import { initializePlugins } from "@/plugins/plugins";
17
17
  import { logNever } from "@/utils/assertNever";
18
18
  import { Functions } from "@/utils/functions";
19
- import type { Base64String } from "@/utils/json/base64";
19
+ import { safeExtractSetUIElementMessageBuffers } from "@/utils/json/base64";
20
20
  import { jsonParseWithSpecialChar } from "@/utils/json/json-parser";
21
21
  import { Logger } from "@/utils/Logger";
22
22
  import {
@@ -145,7 +145,7 @@ export async function initialize() {
145
145
  UI_ELEMENT_REGISTRY.broadcastMessage(
146
146
  msg.data.ui_element as UIElementId,
147
147
  msg.data.message,
148
- msg.data.buffers as Base64String[],
148
+ safeExtractSetUIElementMessageBuffers(msg.data),
149
149
  );
150
150
  return;
151
151
 
@@ -88,9 +88,7 @@ export function parseMarimoIslandApps(): MarimoIslandApp[] {
88
88
  return [...apps.values()];
89
89
  }
90
90
 
91
- export function createMarimoFile(app: {
92
- cells: Array<{ code: string }>;
93
- }): string {
91
+ export function createMarimoFile(app: { cells: { code: string }[] }): string {
94
92
  const lines = [
95
93
  "import marimo",
96
94
  "app = marimo.App()",
@@ -24,7 +24,7 @@ export type OutputChannel = schemas["CellChannel"];
24
24
  export type CellOutput = schemas["CellOutput"];
25
25
  export type MarimoError = Extract<
26
26
  CellOutput["data"],
27
- Array<{ type: string }>
27
+ { type: string }[]
28
28
  >[number];
29
29
  export type OutputMessage = schemas["CellOutput"];
30
30
  export type CompletionOption = schemas["CompletionResult"]["options"][0];
@@ -0,0 +1,74 @@
1
+ /* Copyright 2024 Marimo. All rights reserved. */
2
+
3
+ import { LRUCache } from "@/utils/lru";
4
+ import type {
5
+ DeferredRequestRegistry,
6
+ RequestId,
7
+ } from "./DeferredRequestRegistry";
8
+
9
+ type ToKey<REQ> = (request: REQ) => string;
10
+
11
+ interface CachingOptions<REQ> {
12
+ toKey?: ToKey<REQ>;
13
+ maxSize?: number;
14
+ }
15
+
16
+ /**
17
+ * Light wrapper adding memoization and in-flight de-duplication on top of
18
+ * DeferredRequestRegistry, keyed by a string representation of the request.
19
+ */
20
+ export class CachingRequestRegistry<REQ, RES> {
21
+ private delegate: DeferredRequestRegistry<REQ, RES>;
22
+ private toKey: ToKey<REQ>;
23
+ private cache: LRUCache<string, Promise<RES>>;
24
+
25
+ static jsonStringifySortKeys<T>(): ToKey<T> {
26
+ return (o: T) => {
27
+ if (typeof o !== "object" || o === null) {
28
+ return String(o);
29
+ }
30
+ return JSON.stringify(o, Object.keys(o).sort(), 2);
31
+ };
32
+ }
33
+
34
+ constructor(
35
+ delegate: DeferredRequestRegistry<REQ, RES>,
36
+ options: CachingOptions<REQ> = {},
37
+ ) {
38
+ this.delegate = delegate;
39
+ this.toKey =
40
+ options.toKey ?? CachingRequestRegistry.jsonStringifySortKeys();
41
+ const maxSize = options.maxSize ?? 128;
42
+ this.cache = new LRUCache<string, Promise<RES>>(maxSize);
43
+ }
44
+
45
+ /**
46
+ * Resolve via cache if present, else delegate; de-duplicates concurrent
47
+ * requests with the same key and stores successful results in the cache.
48
+ */
49
+ public request(req: REQ): Promise<RES> {
50
+ const key = this.toKey(req);
51
+
52
+ const cached = this.cache.get(key);
53
+ if (cached !== undefined) {
54
+ return cached;
55
+ }
56
+
57
+ const promise = this.delegate.request(req);
58
+ this.cache.set(key, promise);
59
+ return promise.catch((err) => {
60
+ this.cache.delete(key);
61
+ throw err;
62
+ });
63
+ }
64
+
65
+ // Path through to the delegate
66
+ public resolve(requestId: RequestId, response: RES) {
67
+ this.delegate.resolve(requestId, response);
68
+ }
69
+
70
+ // Path through to the delegate
71
+ public reject(requestId: RequestId, error: Error) {
72
+ this.delegate.reject(requestId, error);
73
+ }
74
+ }
@@ -45,7 +45,9 @@ export class DeferredRequestRegistry<REQ, RES> {
45
45
  async request(opts: REQ): Promise<RES> {
46
46
  if (this.opts.resolveExistingRequests) {
47
47
  const result = this.opts.resolveExistingRequests();
48
- this.requests.forEach((deferred) => deferred.resolve(result));
48
+ for (const deferred of this.requests.values()) {
49
+ deferred.resolve(result);
50
+ }
49
51
  this.requests.clear();
50
52
  }
51
53
 
@@ -0,0 +1,73 @@
1
+ /* Copyright 2024 Marimo. All rights reserved. */
2
+ import { beforeEach, describe, expect, it, vi } from "vitest";
3
+ import { CachingRequestRegistry } from "../CachingRequestRegistry";
4
+ import {
5
+ DeferredRequestRegistry,
6
+ type RequestId,
7
+ } from "../DeferredRequestRegistry";
8
+
9
+ vi.mock("@/utils/uuid", () => ({
10
+ generateUUID: vi.fn().mockReturnValue("uuid"),
11
+ }));
12
+
13
+ describe("CachingRequestRegistry", () => {
14
+ const REQUEST_ID = "uuid" as RequestId;
15
+ let makeRequestMock = vi.fn();
16
+ let delegate: DeferredRequestRegistry<unknown, unknown>;
17
+ let caching: CachingRequestRegistry<unknown, unknown>;
18
+
19
+ beforeEach(() => {
20
+ makeRequestMock = vi.fn().mockResolvedValue(undefined);
21
+ delegate = new DeferredRequestRegistry("operation", makeRequestMock);
22
+ caching = new CachingRequestRegistry(delegate);
23
+ });
24
+
25
+ it("should cache successful responses for identical requests", async () => {
26
+ const req = { a: 1 };
27
+
28
+ const p1 = caching.request(req);
29
+ expect(makeRequestMock).toHaveBeenCalledTimes(1);
30
+ expect(makeRequestMock).toHaveBeenCalledWith(REQUEST_ID, req);
31
+
32
+ // Resolve first request
33
+ delegate.resolve(REQUEST_ID, "response");
34
+ await expect(p1).resolves.toBe("response");
35
+
36
+ // Second call with equivalent request gets served from cache
37
+ const p2 = caching.request({ a: 1 });
38
+ expect(makeRequestMock).toHaveBeenCalledTimes(1);
39
+ await expect(p2).resolves.toBe("response");
40
+ });
41
+
42
+ it("should de-duplicate in-flight requests with the same key", async () => {
43
+ const req = { q: "select *" };
44
+
45
+ const p1 = caching.request(req);
46
+ const p2 = caching.request({ q: "select *" });
47
+
48
+ // Only one network invocation while in-flight
49
+ expect(makeRequestMock).toHaveBeenCalledTimes(1);
50
+ expect(p1).toStrictEqual(p2);
51
+
52
+ // Resolve and ensure both resolve to same result
53
+ delegate.resolve(REQUEST_ID, "ok");
54
+ await expect(p1).resolves.toBe("ok");
55
+ await expect(p2).resolves.toBe("ok");
56
+ });
57
+
58
+ it("should not cache errors", async () => {
59
+ // First call rejects
60
+ makeRequestMock.mockRejectedValueOnce(new Error("boom"));
61
+
62
+ await expect(caching.request({ x: 1 })).rejects.toThrow("boom");
63
+ expect(makeRequestMock).toHaveBeenCalledTimes(1);
64
+
65
+ // Next call should attempt again (not cached)
66
+ const p2 = caching.request({ x: 1 });
67
+ expect(makeRequestMock).toHaveBeenCalledTimes(2);
68
+
69
+ // Resolve the second request
70
+ delegate.resolve(REQUEST_ID, "ok");
71
+ await expect(p2).resolves.toBe("ok");
72
+ });
73
+ });
@@ -142,7 +142,7 @@ export interface EditRequests {
142
142
  request: PreviewDataSourceConnectionRequest,
143
143
  ) => Promise<null>;
144
144
  validateSQL: (request: ValidateSQLRequest) => Promise<null>;
145
- openFile: (request: { path: string }) => Promise<null>;
145
+ openFile: (request: { path: string; lineNumber?: number }) => Promise<null>;
146
146
  getUsageStats: () => Promise<UsageResponse>;
147
147
  // Debugger
148
148
  sendPdb: (request: PdbRequest) => Promise<null>;
@@ -38,11 +38,11 @@ const {
38
38
  },
39
39
  setMetadata: (
40
40
  state,
41
- metadata: Array<{
41
+ metadata: {
42
42
  name: VariableName;
43
43
  value?: string | null;
44
44
  dataType?: string | null;
45
- }>,
45
+ }[],
46
46
  ) => {
47
47
  const newVariables = { ...state };
48
48
  for (const { name, value, dataType } of metadata) {
@@ -13,7 +13,7 @@ import { hasAnyOutputAtom } from "../state";
13
13
 
14
14
  describe("hasAnyOutputAtom", () => {
15
15
  const createNotebookState = (
16
- outputs: Array<OutputMessage | null>,
16
+ outputs: (OutputMessage | null)[],
17
17
  ): NotebookState => ({
18
18
  ...initialNotebookState(),
19
19
  cellIds: new MultiColumn([
@@ -16,7 +16,10 @@ import {
16
16
  } from "@/plugins/impl/anywidget/model";
17
17
  import { logNever } from "@/utils/assertNever";
18
18
  import { prettyError } from "@/utils/errors";
19
- import type { Base64String, JsonString } from "@/utils/json/base64";
19
+ import {
20
+ type JsonString,
21
+ safeExtractSetUIElementMessageBuffers,
22
+ } from "@/utils/json/base64";
20
23
  import { jsonParseWithSpecialChar } from "@/utils/json/json-parser";
21
24
  import { Logger } from "@/utils/Logger";
22
25
  import { reloadSafe } from "@/utils/reload-safe";
@@ -112,7 +115,7 @@ export function useMarimoWebSocket(opts: {
112
115
  const modelId = msg.data.model_id;
113
116
  const uiElement = msg.data.ui_element;
114
117
  const message = msg.data.message;
115
- const buffers = (msg.data.buffers ?? []) as Base64String[];
118
+ const buffers = safeExtractSetUIElementMessageBuffers(msg.data);
116
119
 
117
120
  if (modelId && isMessageWidgetState(message)) {
118
121
  handleWidgetMessage({
package/src/custom.d.ts CHANGED
@@ -20,5 +20,5 @@ interface JSON {
20
20
 
21
21
  // Improve type inference for Array.filter with BooleanConstructor
22
22
  interface Array<T> {
23
- filter(predicate: BooleanConstructor): Array<NonNullable<T>>;
23
+ filter(predicate: BooleanConstructor): NonNullable<T>[];
24
24
  }
@@ -8,6 +8,7 @@ export function useCellRenderCount() {
8
8
 
9
9
  const currentCount = Number.parseInt(
10
10
  document.body.dataset.cellRenderCount || "0",
11
+ 10,
11
12
  );
12
13
  document.body.dataset.cellRenderCount = (currentCount + 1).toString();
13
14
  },
@@ -29,7 +29,10 @@ export const useResizeHandle = ({
29
29
  return;
30
30
  }
31
31
 
32
- let width = Number.parseInt(window.getComputedStyle(resizableDiv).width);
32
+ let width = Number.parseInt(
33
+ window.getComputedStyle(resizableDiv).width,
34
+ 10,
35
+ );
33
36
  let lastX = 0;
34
37
  let isResizing = false;
35
38
  let activeDirection: "left" | "right" | null = null;
@@ -89,7 +89,7 @@ const replaceSrcScripts = (domNode: DOMNode): JSX.Element | undefined => {
89
89
  script.src = src;
90
90
  document.head.append(script);
91
91
  }
92
- // eslint-disable-next-line react/jsx-no-useless-fragment
92
+ // biome-ignore lint/complexity/noUselessFragments: this is intentional
93
93
  return <></>;
94
94
  }
95
95
  };
@@ -163,7 +163,6 @@ export const renderHTML = ({ html, additionalReplacements = [] }: Options) => {
163
163
  return transformed;
164
164
  }
165
165
  }
166
- // eslint-disable-next-line react/jsx-no-useless-fragment
167
166
  return reactNode as JSX.Element;
168
167
  },
169
168
  });
@@ -112,7 +112,7 @@ export type CalculateTopKRows = (req: {
112
112
  column: string;
113
113
  k: number;
114
114
  }) => Promise<{
115
- data: Array<[unknown, number]>;
115
+ data: [unknown, number][];
116
116
  }>;
117
117
 
118
118
  export type PreviewColumn = (opts: { column: string }) => Promise<{
@@ -172,6 +172,7 @@ interface Data<T> {
172
172
  totalRows: number | TooManyRows;
173
173
  pagination: boolean;
174
174
  pageSize: number;
175
+ maxHeight?: number;
175
176
  selection: DataTableSelection;
176
177
  showDownload: boolean;
177
178
  showFilters: boolean;
@@ -220,7 +221,7 @@ type DataTableFunctions = {
220
221
  preview_column?: PreviewColumn;
221
222
  };
222
223
 
223
- type S = Array<number | string | { rowId: string; columnName?: string }>;
224
+ type S = (number | string | { rowId: string; columnName?: string })[];
224
225
 
225
226
  export const DataTablePlugin = createPlugin<S>("marimo-table")
226
227
  .withData(
@@ -259,6 +260,7 @@ export const DataTablePlugin = createPlugin<S>("marimo-table")
259
260
  totalColumns: z.number(),
260
261
  maxColumns: z.union([z.number(), z.literal("all")]).default("all"),
261
262
  hasStableRowId: z.boolean().default(false),
263
+ maxHeight: z.number().optional(),
262
264
  cellStyles: z.record(z.record(z.object({}).passthrough())).optional(),
263
265
  hoverTemplate: z.string().optional(),
264
266
  // Whether to load the data lazily.
@@ -653,6 +655,7 @@ export const LoadingDataTableComponent = memo(
653
655
  toggleDisplayHeader={toggleDisplayHeader}
654
656
  getRow={getRow}
655
657
  cellId={cellId}
658
+ maxHeight={props.maxHeight}
656
659
  />
657
660
  );
658
661
 
@@ -720,6 +723,7 @@ const DataTableComponent = ({
720
723
  preview_column,
721
724
  getRow,
722
725
  cellId,
726
+ maxHeight,
723
727
  }: DataTableProps<unknown> &
724
728
  DataTableSearchProps & {
725
729
  data: unknown[];
@@ -901,6 +905,7 @@ const DataTableComponent = ({
901
905
  data={data}
902
906
  columns={columns}
903
907
  className={className}
908
+ maxHeight={maxHeight}
904
909
  sorting={sorting}
905
910
  totalRows={totalRows}
906
911
  totalColumns={totalColumns}
@@ -31,7 +31,7 @@ interface Data {
31
31
  max_size: number;
32
32
  }
33
33
 
34
- type T = Array<[string, string]>;
34
+ type T = [string, string][];
35
35
 
36
36
  export class FileUploadPlugin implements IPlugin<T, Data> {
37
37
  tagName = "marimo-file";
@@ -20,7 +20,7 @@ interface Data {
20
20
  * It may also be a human-readable string like "1m" or "1h" or "3h 30m".
21
21
  * These will be converted to seconds.
22
22
  */
23
- options: Array<string | number>;
23
+ options: (string | number)[];
24
24
  /**
25
25
  * The initial value.
26
26
  */
@@ -147,6 +147,10 @@ const SliderComponent = ({
147
147
  <NumberField
148
148
  value={valueMap(internalValue)}
149
149
  onChange={(nextValue) => {
150
+ // If nextValue is null/undefined/NaN (input cleared), set to start
151
+ if (nextValue == null || Number.isNaN(nextValue)) {
152
+ nextValue = Number(start);
153
+ }
150
154
  setInternalValue(nextValue);
151
155
  if (!debounce) {
152
156
  setValue(nextValue);
@@ -2,7 +2,7 @@
2
2
  /* eslint-disable @typescript-eslint/no-explicit-any */
3
3
 
4
4
  import type { AnyWidget, Experimental } from "@anywidget/types";
5
- import { isEqual } from "lodash-es";
5
+ import { get, isEqual, set } from "lodash-es";
6
6
  import { useEffect, useMemo, useRef } from "react";
7
7
  import { z } from "zod";
8
8
  import { MarimoIncomingMessageEvent } from "@/core/dom/events";
@@ -16,7 +16,11 @@ import {
16
16
  import { createPlugin } from "@/plugins/core/builder";
17
17
  import { rpc } from "@/plugins/core/rpc";
18
18
  import type { IPluginProps } from "@/plugins/types";
19
- import { updateBufferPaths } from "@/utils/data-views";
19
+ import {
20
+ type Base64String,
21
+ byteStringToBinary,
22
+ typedAtob,
23
+ } from "@/utils/json/base64";
20
24
  import { Logger } from "@/utils/Logger";
21
25
  import { ErrorBanner } from "../common/error-banner";
22
26
  import { MODEL_MANAGER, Model } from "./model";
@@ -25,7 +29,7 @@ interface Data {
25
29
  jsUrl: string;
26
30
  jsHash: string;
27
31
  css?: string | null;
28
- bufferPaths?: Array<Array<string | number>> | null;
32
+ bufferPaths?: (string | number)[][] | null;
29
33
  initialValue: T;
30
34
  }
31
35
 
@@ -59,6 +63,11 @@ type Props = IPluginProps<T, Data, PluginFunctions>;
59
63
 
60
64
  const AnyWidgetSlot = (props: Props) => {
61
65
  const { css, jsUrl, jsHash, bufferPaths } = props.data;
66
+
67
+ const valueWithBuffers = useMemo(() => {
68
+ return resolveInitialValue(props.value, bufferPaths ?? []);
69
+ }, [props.value, bufferPaths]);
70
+
62
71
  // JS is an ESM file with a render function on it
63
72
  // export function render({ model, el }) {
64
73
  // ...
@@ -85,10 +94,6 @@ const AnyWidgetSlot = (props: Props) => {
85
94
  }
86
95
  }, [hasError, jsUrl]);
87
96
 
88
- const valueWithBuffer = useMemo(() => {
89
- return updateBufferPaths(props.value, bufferPaths);
90
- }, [props.value, bufferPaths]);
91
-
92
97
  // Mount the CSS
93
98
  useEffect(() => {
94
99
  const shadowRoot = props.host.shadowRoot;
@@ -157,7 +162,7 @@ const AnyWidgetSlot = (props: Props) => {
157
162
  key={key}
158
163
  {...props}
159
164
  widget={module.default}
160
- value={valueWithBuffer}
165
+ value={valueWithBuffers}
161
166
  />
162
167
  );
163
168
  };
@@ -174,7 +179,7 @@ async function runAnyWidgetModule(
174
179
  el: HTMLElement,
175
180
  ): Promise<() => void> {
176
181
  const experimental: Experimental = {
177
- invoke: async (name, msg, options) => {
182
+ invoke: async (_name, _msg, _options) => {
178
183
  const message =
179
184
  "anywidget.invoke not supported in marimo. Please file an issue at https://github.com/marimo-team/marimo/issues";
180
185
  Logger.warn(message);
@@ -284,3 +289,16 @@ export const visibleForTesting = {
284
289
  isAnyWidgetModule,
285
290
  getDirtyFields,
286
291
  };
292
+
293
+ export function resolveInitialValue(
294
+ raw: Record<string, any>,
295
+ bufferPaths: readonly (readonly (string | number)[])[],
296
+ ) {
297
+ const out = structuredClone(raw);
298
+ for (const bufferPath of bufferPaths) {
299
+ const base64String: Base64String = get(raw, bufferPath);
300
+ const bytes = byteStringToBinary(typedAtob(base64String));
301
+ set(out, bufferPath, new DataView(bytes.buffer));
302
+ }
303
+ return out;
304
+ }
@@ -5,7 +5,11 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
5
5
  import { TestUtils } from "@/__tests__/test-helpers";
6
6
  import type { UIElementId } from "@/core/cells/ids";
7
7
  import { MarimoIncomingMessageEvent } from "@/core/dom/events";
8
- import { getDirtyFields, visibleForTesting } from "../AnyWidgetPlugin";
8
+ import {
9
+ getDirtyFields,
10
+ resolveInitialValue,
11
+ visibleForTesting,
12
+ } from "../AnyWidgetPlugin";
9
13
  import { Model } from "../model";
10
14
 
11
15
  const { LoadedSlot } = visibleForTesting;
@@ -129,7 +133,7 @@ describe("LoadedSlot", () => {
129
133
  method: "update",
130
134
  state: { count: 10 },
131
135
  },
132
- buffers: undefined,
136
+ buffers: [],
133
137
  },
134
138
  bubbles: false,
135
139
  composed: true,
@@ -179,3 +183,55 @@ describe("LoadedSlot", () => {
179
183
  });
180
184
  });
181
185
  });
186
+
187
+ describe("resolveInitialValue", () => {
188
+ it("should convert base64 strings to DataView at specified paths", () => {
189
+ const result = resolveInitialValue(
190
+ {
191
+ a: 10,
192
+ b: "aGVsbG8=", // "hello" in base64
193
+ c: [1, "d29ybGQ="], // "world" in base64
194
+ d: {
195
+ foo: "bWFyaW1vCg==", // "marimo" in base64
196
+ baz: 20,
197
+ },
198
+ },
199
+ [["b"], ["c", 1], ["d", "foo"]],
200
+ );
201
+
202
+ expect(result).toMatchInlineSnapshot(`
203
+ {
204
+ "a": 10,
205
+ "b": DataView [
206
+ 104,
207
+ 101,
208
+ 108,
209
+ 108,
210
+ 111,
211
+ ],
212
+ "c": [
213
+ 1,
214
+ DataView [
215
+ 119,
216
+ 111,
217
+ 114,
218
+ 108,
219
+ 100,
220
+ ],
221
+ ],
222
+ "d": {
223
+ "baz": 20,
224
+ "foo": DataView [
225
+ 109,
226
+ 97,
227
+ 114,
228
+ 105,
229
+ 109,
230
+ 111,
231
+ 10,
232
+ ],
233
+ },
234
+ }
235
+ `);
236
+ });
237
+ });
@@ -9,7 +9,6 @@ import {
9
9
  vi,
10
10
  } from "vitest";
11
11
  import { TestUtils } from "@/__tests__/test-helpers";
12
- import type { Base64String } from "@/utils/json/base64";
13
12
  import {
14
13
  type AnyWidgetMessage,
15
14
  handleWidgetMessage,
@@ -246,7 +245,7 @@ describe("Model", () => {
246
245
  content,
247
246
  });
248
247
 
249
- expect(callback).toHaveBeenCalledWith(content, undefined);
248
+ expect(callback).toHaveBeenCalledWith(content, []);
250
249
  });
251
250
 
252
251
  it("should handle custom messages with buffers", () => {
@@ -286,7 +285,7 @@ describe("ModelManager", () => {
286
285
  }: {
287
286
  modelId: string;
288
287
  message: AnyWidgetMessage;
289
- buffers: Base64String[];
288
+ buffers: readonly DataView[];
290
289
  }) => {
291
290
  return handleWidgetMessage({
292
291
  modelId,
@@ -353,7 +352,7 @@ describe("ModelManager", () => {
353
352
  message: { method: "custom", content: { count: 1 } },
354
353
  buffers: [],
355
354
  });
356
- expect(callback).toHaveBeenCalledWith({ count: 1 }, undefined);
355
+ expect(callback).toHaveBeenCalledWith({ count: 1 }, []);
357
356
  });
358
357
 
359
358
  it("should handle close messages", async () => {
@@ -10,7 +10,6 @@ import { assertNever } from "@/utils/assertNever";
10
10
  import { Deferred } from "@/utils/Deferred";
11
11
  import { updateBufferPaths } from "@/utils/data-views";
12
12
  import { throwNotImplemented } from "@/utils/functions";
13
- import type { Base64String } from "@/utils/json/base64";
14
13
  import { Logger } from "@/utils/Logger";
15
14
 
16
15
  export type EventHandler = (...args: any[]) => void;
@@ -171,7 +170,7 @@ export class Model<T extends Record<string, any>> implements AnyModel<T> {
171
170
  * When receiving a message from the backend.
172
171
  * We want to notify all listeners with `msg:custom`
173
172
  */
174
- receiveCustomMessage(message: any, buffers?: DataView[]): void {
173
+ receiveCustomMessage(message: any, buffers: readonly DataView[] = []): void {
175
174
  const response = AnyWidgetMessageSchema.safeParse(message);
176
175
  if (response.success) {
177
176
  const data = response.data;
@@ -260,7 +259,7 @@ export async function handleWidgetMessage({
260
259
  }: {
261
260
  modelId: string;
262
261
  msg: AnyWidgetMessage;
263
- buffers: Base64String[];
262
+ buffers: readonly DataView[];
264
263
  modelManager: ModelManager;
265
264
  }): Promise<void> {
266
265
  if (msg.method === "echo_update") {
@@ -30,7 +30,7 @@ export interface ColumnEdit {
30
30
  }
31
31
 
32
32
  export interface Edits {
33
- edits: Array<PositionalEdit | RowEdit | ColumnEdit>;
33
+ edits: (PositionalEdit | RowEdit | ColumnEdit)[];
34
34
  }
35
35
 
36
36
  export type ModifiedGridColumn = GridColumn & {
@@ -238,7 +238,7 @@ const FieldOptions = ({
238
238
  return null;
239
239
  }
240
240
 
241
- let options: Array<[string, FieldFunction[]]> = [];
241
+ let options: [string, FieldFunction[]][] = [];
242
242
 
243
243
  if (field.type === ExpandedType.QUANTITATIVE) {
244
244
  options = [["", QUANTITATIVE_FUNCTIONS]];
@@ -15,7 +15,7 @@ export type NumPyType = string;
15
15
  *
16
16
  * We cannot use a js map, since maps don't preserve keys as ints (e.g. "1" and 1 are the same key)
17
17
  */
18
- export type RawColumnDataTypes = Array<[ColumnId, [DataType, NumPyType]]>;
18
+ export type RawColumnDataTypes = [ColumnId, [DataType, NumPyType]][];
19
19
  /**
20
20
  * Map of column Id and their data types
21
21
  * ES6 maps preserve keys as ints (e.g. "1" and 1 are different keys)
@@ -50,9 +50,9 @@ declare global {
50
50
  consume: (data: ArrayBuffer | string) => void;
51
51
  message: {
52
52
  content: {
53
- events?: Array<{
53
+ events?: {
54
54
  model?: { id?: string };
55
- }>;
55
+ }[];
56
56
  [key: string]: unknown;
57
57
  };
58
58
  buffers: ArrayBuffer[];