@marimo-team/islands 0.25.3-dev170 → 0.25.3-dev175

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 (196) hide show
  1. package/dist/{ConnectedDataExplorerComponent-BbSXV-Xa.js → ConnectedDataExplorerComponent-Le_OBfmt.js} +9 -9
  2. package/dist/{ErrorBoundary-NE86qEWZ.js → ErrorBoundary-DNvcAIsP.js} +8 -8
  3. package/dist/{abnfDiagram-VCTEODGH-D7n07nXf.js → abnfDiagram-VCTEODGH-Tf1ghyQQ.js} +2 -2
  4. package/dist/{any-language-editor-3E24SnCV.js → any-language-editor-BVFHDDQ3.js} +4 -4
  5. package/dist/{architectureDiagram-5GKGNRK7-D6CjRib5.js → architectureDiagram-5GKGNRK7-xlnbTG0T.js} +1 -1
  6. package/dist/{chat-ui-CC7GekpG.js → chat-ui-X-cWrL9u.js} +1218 -1218
  7. package/dist/{check-SpOMoCLP.js → check-C9Mp9eCK.js} +1 -1
  8. package/dist/{chunk-IMKFNOWR-6dtPz7uS.js → chunk-IMKFNOWR-Cmd4a5jy.js} +1 -1
  9. package/dist/{chunk-SHT3W25Y-BwnFNKDA.js → chunk-SHT3W25Y-mSNp-WpO.js} +1 -1
  10. package/dist/{chunk-SVP7TREG-D2eV4vBJ.js → chunk-SVP7TREG-CWC49D8X.js} +1 -1
  11. package/dist/{chunk-TICWLB2K-BDs4-_-r.js → chunk-TICWLB2K-De9FINtG.js} +1 -1
  12. package/dist/{classDiagram-ZZMXUADV-DCJnf_8v.js → classDiagram-ZZMXUADV-DweTkYdp.js} +2 -2
  13. package/dist/{classDiagram-v2-VYDZK3BY-BOmSzPBD.js → classDiagram-v2-VYDZK3BY-A6MR2TiE.js} +2 -2
  14. package/dist/{code-visibility-Bzvc6ajl.js → code-visibility-CH1lmM1h.js} +5 -5
  15. package/dist/{common-Ciw4zkh2.js → common-DIrS1UR9.js} +1081 -1085
  16. package/dist/{copy-icon-C1trdvVt.js → copy-icon-De584pZ4.js} +2 -2
  17. package/dist/{cynefinDiagram-5FMLGOSQ-Bln_Soky.js → cynefinDiagram-5FMLGOSQ-BSvo5le-.js} +1 -1
  18. package/dist/{dagre-GXQ25YYZ-D-nf7WzW.js → dagre-GXQ25YYZ-tXRQslO6.js} +1 -1
  19. package/dist/{data-grid-overlay-editor-AQREmxI7.js → data-grid-overlay-editor-DFLZvFK0.js} +1 -1
  20. package/dist/{diagram-S7CK7UJ4-PsgSMkY2.js → diagram-S7CK7UJ4-r3t5VtwI.js} +1 -1
  21. package/dist/{diagram-UQ7AKVKN-DfwfUuSw.js → diagram-UQ7AKVKN-qgbC8YnT.js} +1 -1
  22. package/dist/{diagram-VX7I27RA-C9_e-oMc.js → diagram-VX7I27RA-CiHxEwtp.js} +1 -1
  23. package/dist/{diagram-Z3DM3KII-CWLa5tuY.js → diagram-Z3DM3KII-D95u15Ev.js} +1 -1
  24. package/dist/{dialog-DgeqyrEZ.js → dialog-DVRfQuhD.js} +24 -24
  25. package/dist/{dist-F8Ep36rk.js → dist-B1M0bGO3.js} +1 -1
  26. package/dist/{dist-D6d86eNJ.js → dist-BA13RJj5.js} +1 -1
  27. package/dist/{dist-Bvs24R_E.js → dist-BJtmSgcE.js} +48 -48
  28. package/dist/{dist-CN_BeG2I.js → dist-Ba2VIn1K.js} +53 -53
  29. package/dist/{dist-PXYI_yuP.js → dist-Bj4bmwUm.js} +12 -12
  30. package/dist/{dist-DoE4XJBC.js → dist-BmS-ZGjl.js} +8626 -8626
  31. package/dist/{dist-BorMD-uX.js → dist-Bzogh7CW.js} +87 -87
  32. package/dist/{dist-CN8zI-XC.js → dist-CThPVKaP.js} +1385 -1382
  33. package/dist/{dist-DiDibOYr.js → dist-CTi5FTiV.js} +87 -87
  34. package/dist/{dist-diIx5qJW.js → dist-Ck_C32ye.js} +2 -2
  35. package/dist/{dist-BLfKmR-l.js → dist-D1fnFp1J.js} +1 -1
  36. package/dist/{dist-OR1OnN-y.js → dist-D3x9__Fu.js} +46 -46
  37. package/dist/{dist-BMQf5zIS.js → dist-D7mrh5sO.js} +36 -36
  38. package/dist/{dist-CSJ0MDRw.js → dist-D9Q3xjiP.js} +1 -1
  39. package/dist/{dist-BuaRHxOc.js → dist-DP60Ubh8.js} +2 -2
  40. package/dist/{dist-CSbh1PNP.js → dist-DTv9KkpW.js} +12 -12
  41. package/dist/{dist-D-wwqlzJ.js → dist-DVVwOfrD.js} +109 -109
  42. package/dist/{dist-C8fAKSH1.js → dist-DYXM73-k.js} +36 -36
  43. package/dist/{dist-DBtSl3sf.js → dist-DjeybPOb.js} +1 -1
  44. package/dist/{dist-CrSP_H1M.js → dist-DtGn9N4h.js} +197 -197
  45. package/dist/{dist-CLdpGQVr.js → dist-KN80qWCP.js} +2 -2
  46. package/dist/{dist-Cg7gzw-a.js → dist-O0qFpEJh.js} +56 -56
  47. package/dist/{dist-CkTTIdBe.js → dist-OUle2RT7.js} +207 -207
  48. package/dist/{dist-BK4Oj99o.js → dist-T5rh6JvL.js} +1 -1
  49. package/dist/{dropdown-menu-B6ftyzOg.js → dropdown-menu-DCMbbQ35.js} +691 -691
  50. package/dist/{ebnfDiagram-PWID7BFC-B1QRM58v.js → ebnfDiagram-PWID7BFC-P7e4bryK.js} +2 -2
  51. package/dist/{erDiagram-RLTQ6QDP-DJK_FqvW.js → erDiagram-RLTQ6QDP-CUHZcmRj.js} +1 -1
  52. package/dist/{error-banner-D40pmfQQ.js → error-banner-DxJ3s8YO.js} +57 -57
  53. package/dist/{error-entries-DgK3wUJR.js → error-entries-mpoD5t79.js} +4985 -5006
  54. package/dist/{esm-D2gTsXEV.js → esm-Bbw_Njjx.js} +575 -575
  55. package/dist/{esm-AMFssoNp.js → esm-mDQNEFe_.js} +354 -354
  56. package/dist/{feedback-button-8a6SETmT.js → feedback-button-DL0DJ-LB.js} +30 -30
  57. package/dist/{flowDiagram-HODETNUW-Uxc25XSJ.js → flowDiagram-HODETNUW-BGZ95AzI.js} +2 -2
  58. package/dist/{formats-DQCyPd5Z.js → formats-DI7HEVv7.js} +1 -1
  59. package/dist/{glide-data-editor-B70oke_v.js → glide-data-editor-n4wnx19S.js} +10 -10
  60. package/dist/{glide-utils-Dz_F4pAY.js → glide-utils-D98laidb.js} +2 -2
  61. package/dist/{globals-Cxd5hNlI.js → globals-NCsYyjpB.js} +3 -3
  62. package/dist/{html-to-image-D4yG5Ru0.js → html-to-image-BoZthB4P.js} +467 -458
  63. package/dist/{infoDiagram-27XIBGKW-DmjxqwL0.js → infoDiagram-27XIBGKW-BF0YX70D.js} +1 -1
  64. package/dist/{ishikawaDiagram-5VMMS53U-NgCLHqQi.js → ishikawaDiagram-5VMMS53U-_itsAAn-.js} +1 -1
  65. package/dist/{kanban-definition-UXKFOSKX-CZaG-iam.js → kanban-definition-UXKFOSKX-VNW2Beqh.js} +1 -1
  66. package/dist/{label-D9_-zSg-.js → label-Qvw1E97W.js} +1 -1
  67. package/dist/main.js +8257 -6606
  68. package/dist/{mermaid-CSvw7c71.js → mermaid-CZ6FrClS.js} +35 -35
  69. package/dist/{mindmap-definition-YA3MSWOX-DJYQBDH_.js → mindmap-definition-YA3MSWOX-DR4ripvd.js} +1 -1
  70. package/dist/{number-overlay-editor-ChK-SKUk.js → number-overlay-editor-rlvo4mo3.js} +1 -1
  71. package/dist/{pegDiagram-XKGWAZYB-CHKO_dAe.js → pegDiagram-XKGWAZYB-CFr3XlGl.js} +2 -2
  72. package/dist/{pieDiagram-E7YTZNPT-DVevbMAo.js → pieDiagram-E7YTZNPT-j91XYSLY.js} +1 -1
  73. package/dist/{process-output-DxvBAeL3.js → process-output-DLS4Mqg_.js} +4 -4
  74. package/dist/{railroadDiagram-O6MQD6OU-Detj1kcB.js → railroadDiagram-O6MQD6OU-Cd47ZV9E.js} +2 -2
  75. package/dist/{requirementDiagram-BXWQKSXE-BLFD0T_Z.js → requirementDiagram-BXWQKSXE-eJH6gLtX.js} +1 -1
  76. package/dist/{reveal-component-CXMXeDZD.js → reveal-component-BJfmRUzb.js} +9 -9
  77. package/dist/{select-CkF_GBxO.js → select-2KOiReNY.js} +324 -324
  78. package/dist/{sequenceDiagram-WJ2MYXX4-BZBgatQV.js → sequenceDiagram-WJ2MYXX4-DdfFEIrm.js} +1 -1
  79. package/dist/{spec-Mnkn3XEr.js → spec-h69nC3SI.js} +4 -4
  80. package/dist/{stateDiagram-D77RDMKH-4BZW9-6_.js → stateDiagram-D77RDMKH-DkjDvip8.js} +2 -2
  81. package/dist/{stateDiagram-v2-MP3YSRHH-C4sKC8Iq.js → stateDiagram-v2-MP3YSRHH-DBHACnOo.js} +2 -2
  82. package/dist/{swimlanes-42K2YHIH-SL5yeGe2.js → swimlanes-42K2YHIH-ogImlOmp.js} +1 -1
  83. package/dist/{swimlanesDiagram-VR7AAH4N-DqPmAYUv.js → swimlanesDiagram-VR7AAH4N-D6x-zsci.js} +2 -2
  84. package/dist/{timeline-definition-24CTP7MA-BfXUMWkq.js → timeline-definition-24CTP7MA-DQpLtsHD.js} +1 -1
  85. package/dist/{toDate-TMubKIVL.js → toDate-CDzoofJo.js} +2 -2
  86. package/dist/{toast-Btbve3Lm.js → toast-B5t9o6s_.js} +47 -47
  87. package/dist/{tooltip-CJ4Rqasp.js → tooltip-s4zZxwKe.js} +67 -67
  88. package/dist/{use-restore-focus-CmGwRNId.js → use-restore-focus-BgDTd2tc.js} +1 -1
  89. package/dist/{useAsyncData-DjMGFzFy.js → useAsyncData-Bn8SxUqM.js} +1 -1
  90. package/dist/{useDateFormatter-eCL_SdeG.js → useDateFormatter-D3Tkfzej.js} +2 -2
  91. package/dist/{useDeepCompareMemoize-BQR5TJot.js → useDeepCompareMemoize-CC2tnPCk.js} +1 -1
  92. package/dist/{useLifecycle-C_GvKWbQ.js → useLifecycle-BJlxHqWa.js} +2 -2
  93. package/dist/{useTheme-Bns2gJZ6.js → useTheme-DMfQYmlG.js} +85 -85
  94. package/dist/{vega-component-BsVptuhz.js → vega-component-CovWHi60.js} +7 -7
  95. package/dist/{vennDiagram-4TSXK5OY-CH65znGa.js → vennDiagram-4TSXK5OY-BD-SL_vq.js} +1 -1
  96. package/dist/{wardleyDiagram-VM6X3IG4-z9pWKb2_.js → wardleyDiagram-VM6X3IG4-BDgJV4ah.js} +1 -1
  97. package/dist/{xychartDiagram-S5SC5T6Z-MxyaWjjq.js → xychartDiagram-S5SC5T6Z-1hIHN6Rl.js} +1 -1
  98. package/package.json +1 -1
  99. package/src/__mocks__/document.tsx +54 -0
  100. package/src/__mocks__/notebook.ts +2 -1
  101. package/src/__mocks__/requests.ts +0 -2
  102. package/src/components/chat/chat-panel.tsx +3 -3
  103. package/src/components/datasources/__tests__/column-preview.test.tsx +6 -8
  104. package/src/components/datasources/column-preview.tsx +4 -8
  105. package/src/components/datasources/datasources.tsx +4 -3
  106. package/src/components/dependency-graph/minimap-content.tsx +2 -6
  107. package/src/components/dependency-graph/panels.tsx +2 -1
  108. package/src/components/editor/__tests__/Output.test.tsx +50 -32
  109. package/src/components/editor/__tests__/data-attributes.test.tsx +22 -11
  110. package/src/components/editor/__tests__/output-persistence.test.tsx +6 -1
  111. package/src/components/editor/actions/__tests__/name-cell-input.test.tsx +69 -0
  112. package/src/components/editor/actions/name-cell-input.tsx +4 -3
  113. package/src/components/editor/actions/useCellActionButton.tsx +20 -26
  114. package/src/components/editor/actions/useNotebookActions.tsx +13 -18
  115. package/src/components/editor/actions/useSetCodeVisibility.ts +10 -11
  116. package/src/components/editor/actions/useSetOutputsExpanded.ts +13 -18
  117. package/src/components/editor/cell/CreateCellButton.tsx +5 -9
  118. package/src/components/editor/cell/__tests__/StagedAICell.test.tsx +3 -1
  119. package/src/components/editor/cell/code/cell-editor.tsx +13 -20
  120. package/src/components/editor/cell/useAddCell.ts +4 -8
  121. package/src/components/editor/cell/useDeleteCell.tsx +10 -36
  122. package/src/components/editor/cell/useRunCells.ts +2 -5
  123. package/src/components/editor/cell/useSplitCell.tsx +2 -1
  124. package/src/components/editor/chrome/panels/logs-panel.tsx +2 -1
  125. package/src/components/editor/chrome/panels/snippets-panel.tsx +5 -11
  126. package/src/components/editor/chrome/wrapper/__tests__/pending-ai-cells.test.tsx +3 -1
  127. package/src/components/editor/columns/sortable-column.tsx +1 -1
  128. package/src/components/editor/connections/components.tsx +4 -9
  129. package/src/components/editor/controls/Controls.tsx +1 -1
  130. package/src/components/editor/controls/__tests__/notebook-menu-dropdown.test.tsx +9 -3
  131. package/src/components/editor/documentation.css +34 -11
  132. package/src/components/editor/errors/auto-fix.tsx +4 -8
  133. package/src/components/editor/file-tree/file-explorer.tsx +3 -7
  134. package/src/components/editor/links/__tests__/cell-link.test.tsx +3 -1
  135. package/src/components/editor/links/cell-link.tsx +2 -1
  136. package/src/components/editor/navigation/__tests__/clipboard.test.ts +60 -38
  137. package/src/components/editor/navigation/__tests__/navigation.test.ts +73 -64
  138. package/src/components/editor/navigation/clipboard.ts +12 -11
  139. package/src/components/editor/navigation/multi-cell-action-toolbar.tsx +11 -20
  140. package/src/components/editor/navigation/navigation.ts +20 -28
  141. package/src/components/editor/notebook-cell.tsx +7 -10
  142. package/src/components/editor/output/console/__tests__/ConsoleOutput.test.tsx +125 -69
  143. package/src/components/editor/renderers/cell-array.tsx +10 -17
  144. package/src/components/markdown/markdown-renderer.tsx +4 -8
  145. package/src/components/pages/edit-page.tsx +32 -17
  146. package/src/components/scratchpad/scratchpad.test.tsx +3 -1
  147. package/src/components/scratchpad/scratchpad.tsx +4 -7
  148. package/src/components/slides/__tests__/minimap-actions.test.tsx +9 -25
  149. package/src/components/slides/minimap.tsx +7 -3
  150. package/src/components/slides/slide-cell-view.tsx +3 -3
  151. package/src/components/sort/SortableCellsProvider.tsx +2 -1
  152. package/src/core/ai/__tests__/staged-cells.test.ts +18 -20
  153. package/src/core/ai/staged-cells.ts +8 -16
  154. package/src/core/ai/tools/__tests__/edit-notebook-tool.test.ts +2 -2
  155. package/src/core/ai/tools/__tests__/run-cells-tool.test.ts +2 -2
  156. package/src/core/ai/tools/base.ts +2 -2
  157. package/src/core/ai/tools/edit-notebook-tool.ts +13 -21
  158. package/src/core/cells/__tests__/actions.test.ts +474 -34
  159. package/src/core/cells/__tests__/add-missing-import.test.ts +7 -8
  160. package/src/core/cells/__tests__/cells.test.ts +251 -861
  161. package/src/core/cells/__tests__/document.test.ts +42 -38
  162. package/src/core/cells/__tests__/notebook-outline.test.ts +7 -1
  163. package/src/core/cells/__tests__/outputs.test.tsx +71 -53
  164. package/src/core/cells/actions.ts +391 -3
  165. package/src/core/cells/add-missing-import.ts +46 -42
  166. package/src/core/cells/cells.ts +73 -444
  167. package/src/core/cells/document.ts +38 -6
  168. package/src/core/cells/outputs.ts +12 -28
  169. package/src/core/codemirror/cells/extensions.ts +6 -6
  170. package/src/core/codemirror/cells/state.ts +1 -1
  171. package/src/core/codemirror/keymaps/vim.ts +2 -2
  172. package/src/core/edit-app.tsx +20 -25
  173. package/src/core/islands/__tests__/bootstrap.test.ts +56 -0
  174. package/src/core/islands/__tests__/bridge.test.ts +42 -0
  175. package/src/core/islands/bootstrap.ts +24 -1
  176. package/src/core/islands/bridge.ts +46 -5
  177. package/src/core/kernel/__tests__/handlers.test.ts +7 -153
  178. package/src/core/kernel/handlers.ts +18 -59
  179. package/src/core/network/__tests__/requests-lazy.test.ts +1 -3
  180. package/src/core/network/requests-lazy.ts +0 -2
  181. package/src/core/network/requests-network.ts +0 -16
  182. package/src/core/network/requests-static.ts +0 -2
  183. package/src/core/network/requests-toasting.tsx +0 -2
  184. package/src/core/network/types.ts +0 -7
  185. package/src/core/notebook/document/__tests__/codemirror.test.ts +5 -0
  186. package/src/core/notebook/document/__tests__/draft.test.ts +41 -0
  187. package/src/core/notebook/document/__tests__/state.test.ts +21 -0
  188. package/src/core/notebook/document/draft.ts +35 -5
  189. package/src/core/notebook/document/index.ts +1 -0
  190. package/src/core/notebook/document/state.ts +6 -2
  191. package/src/core/run-app.tsx +1 -7
  192. package/src/core/session/__tests__/useNotebookSession.hook.test.tsx +0 -6
  193. package/src/core/session/useNotebookSession.tsx +28 -35
  194. package/src/core/wasm/bridge.ts +0 -16
  195. package/src/css/globals.css +56 -22
  196. package/src/stories/runtime-story.tsx +22 -15
@@ -9,7 +9,7 @@ import { n as s } from "./chunk-Y2CYZVJY-DKKS1VyV.js";
9
9
  import { D as c, H as l, K as u, U as d, a as f, b as p, c as m, f as h, v as g, w as _, y as v, z as y } from "./chunk-DU6HZSFF-BwiyaNpg.js";
10
10
  import "./chunk-PWAF6VOD-CQw5qATZ.js";
11
11
  import { t as b } from "./chunk-GMAD6QVW-BhaJx0X3.js";
12
- import { p as x } from "./mermaid-CSvw7c71.js";
12
+ import { p as x } from "./mermaid-CZ6FrClS.js";
13
13
  //#region ../node_modules/.pnpm/d3-scale@4.0.2/node_modules/d3-scale/src/band.js
14
14
  function S() {
15
15
  var e = t().unknown(void 0), r = e.domain, i = e.range, o = 0, s = 1, c, l, u = !1, d = 0, f = 0, p = .5;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/islands",
3
- "version": "0.25.3-dev170",
3
+ "version": "0.25.3-dev175",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -0,0 +1,54 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import { atom, type createStore, Provider } from "jotai";
4
+ import type { ReactNode } from "react";
5
+ import {
6
+ createDocumentModel,
7
+ type DocumentModel,
8
+ DocumentProvider,
9
+ } from "@/core/notebook/document";
10
+ import { document as documentFixture } from "@/core/notebook/document/__tests__/fixtures";
11
+ import type { Document } from "@/core/notebook/replica";
12
+ import { fakeBackend } from "@/core/notebook/replica/__tests__/fixtures";
13
+ import { activeDocumentModelAtom } from "@/core/session/active-notebook";
14
+
15
+ /** A started document model over `document`, for components that edit cells. */
16
+ export function mockDocumentModel(
17
+ store: ReturnType<typeof createStore>,
18
+ document: Document | null = documentFixture(),
19
+ ): { model: DocumentModel; stop: () => void } {
20
+ const controller = new AbortController();
21
+ const model = createDocumentModel({
22
+ store,
23
+ documentAtom: atom(document),
24
+ backendAtom: atom(fakeBackend()),
25
+ });
26
+ model.start({ signal: controller.signal });
27
+ store.set(activeDocumentModelAtom, model);
28
+ return {
29
+ model,
30
+ stop: () => {
31
+ controller.abort();
32
+ if (store.get(activeDocumentModelAtom) === model) {
33
+ store.set(activeDocumentModelAtom, null);
34
+ }
35
+ },
36
+ };
37
+ }
38
+
39
+ /** Provide `store` and `model` to a rendered hook or component. */
40
+ export function DocumentWrapper({
41
+ store,
42
+ model,
43
+ children,
44
+ }: {
45
+ store: ReturnType<typeof createStore>;
46
+ model: DocumentModel;
47
+ children?: ReactNode;
48
+ }) {
49
+ return (
50
+ <Provider store={store}>
51
+ <DocumentProvider model={model}>{children}</DocumentProvider>
52
+ </Provider>
53
+ );
54
+ }
@@ -2,7 +2,8 @@
2
2
 
3
3
  import { createRef } from "react";
4
4
  import { vi } from "vitest";
5
- import type { CellActions, NotebookState } from "@/core/cells/cells";
5
+ import type { CellActions } from "@/core/cells/actions";
6
+ import type { NotebookState } from "@/core/cells/cells";
6
7
  import { CellId } from "@/core/cells/ids";
7
8
  import {
8
9
  type CellData,
@@ -26,11 +26,9 @@ export const MockRequestClient = {
26
26
  sendRun: vi.fn().mockResolvedValue({}),
27
27
  sendRunScratchpad: vi.fn().mockResolvedValue({}),
28
28
  sendInstantiate: vi.fn().mockResolvedValue({}),
29
- sendDeleteCell: vi.fn().mockResolvedValue({}),
30
29
  sendCodeCompletionRequest: vi.fn().mockResolvedValue({ items: [] }),
31
30
  saveUserConfig: vi.fn().mockResolvedValue({}),
32
31
  saveAppConfig: vi.fn().mockResolvedValue({}),
33
- saveCellConfig: vi.fn().mockResolvedValue({}),
34
32
  sendFunctionRequest: vi.fn().mockResolvedValue({}),
35
33
  sendInstallMissingPackages: vi.fn().mockResolvedValue({}),
36
34
  readCode: vi.fn().mockResolvedValue({ contents: "" }),
@@ -53,7 +53,7 @@ import {
53
53
  type CopilotMode,
54
54
  FRONTEND_TOOL_REGISTRY,
55
55
  } from "@/core/ai/tools/registry";
56
- import { useCellActions } from "@/core/cells/cells";
56
+ import { useCellActions } from "@/core/cells/actions";
57
57
  import { aiAtom, aiModelConfiguredAtom } from "@/core/config/config";
58
58
  import { DEFAULT_AI_MODEL } from "@/core/config/config-schema";
59
59
  import { useRequestClient } from "@/core/network/requests";
@@ -582,10 +582,10 @@ const ChatPanelBody = () => {
582
582
  const store = useStore();
583
583
 
584
584
  const { addStagedCell } = useStagedAICellsActions();
585
- const { createNewCell, prepareForRun } = useCellActions();
585
+ const { prepareForRun, createCell } = useCellActions();
586
586
  const toolContext: ToolNotebookContext = {
587
587
  addStagedCell,
588
- createNewCell,
588
+ createCell,
589
589
  prepareForRun,
590
590
  sendRun,
591
591
  store,
@@ -12,11 +12,10 @@ import { requestClientAtom } from "@/core/network/requests";
12
12
  import { store } from "@/core/state/jotai";
13
13
  import { DatasetColumnPreview } from "../column-preview";
14
14
 
15
- const { createNewCell } = vi.hoisted(() => ({ createNewCell: vi.fn() }));
15
+ const { createCell } = vi.hoisted(() => ({ createCell: vi.fn() }));
16
16
 
17
- vi.mock("@/core/cells/cells", async (importOriginal) => ({
18
- ...(await importOriginal<typeof import("@/core/cells/cells")>()),
19
- useCellActions: () => ({ createNewCell }),
17
+ vi.mock("@/core/cells/actions", () => ({
18
+ useCellActions: () => ({ createCell }),
20
19
  }));
21
20
 
22
21
  const wrapper = ({ children }: { children: React.ReactNode }) => (
@@ -179,12 +178,11 @@ describe("DatasetColumnPreview chart actions", () => {
179
178
  name: `Add chart to notebook for ${column.name}`,
180
179
  }),
181
180
  );
182
- expect(createNewCell).toHaveBeenLastCalledWith({
181
+ expect(createCell).toHaveBeenLastCalledWith({
182
+ after: null,
183
183
  code: `chart_${column.name}`,
184
- before: false,
185
- cellId: "__end__",
186
184
  });
187
185
  }
188
- expect(createNewCell).toHaveBeenCalledTimes(2);
186
+ expect(createCell).toHaveBeenCalledTimes(2);
189
187
  });
190
188
  });
@@ -5,7 +5,7 @@ import { PlusSquareIcon } from "lucide-react";
5
5
  import React, { Suspense } from "react";
6
6
  import { useLocale } from "react-aria";
7
7
  import { maybeAddAltairImport } from "@/core/cells/add-missing-import";
8
- import { useCellActions } from "@/core/cells/cells";
8
+ import { useCellActions } from "@/core/cells/actions";
9
9
  import { useLastFocusedCellId } from "@/core/cells/focus";
10
10
  import { autoInstantiateAtom } from "@/core/config/config";
11
11
  import type { SQLTableContext } from "@/core/datasets/data-source-connections";
@@ -249,21 +249,17 @@ export const AddDataframeChart: React.FC<{
249
249
  }> = ({ chartCode, columnName }) => {
250
250
  const autoInstantiate = useAtomValue(autoInstantiateAtom);
251
251
  const lastFocusedCellId = useLastFocusedCellId();
252
- const { createNewCell } = useCellActions();
252
+ const { createCell } = useCellActions();
253
253
 
254
254
  const handleAddColumn = (chartCode: string) => {
255
255
  if (chartCode.includes("alt")) {
256
256
  maybeAddAltairImport({
257
257
  autoInstantiate,
258
- createNewCell,
258
+ createCell,
259
259
  fromCellId: lastFocusedCellId,
260
260
  });
261
261
  }
262
- createNewCell({
263
- code: chartCode,
264
- before: false,
265
- cellId: lastFocusedCellId ?? "__end__",
266
- });
262
+ createCell({ after: lastFocusedCellId, code: chartCode });
267
263
  };
268
264
 
269
265
  return (
@@ -17,7 +17,8 @@ import { Button, buttonVariants } from "@/components/ui/button";
17
17
  import { Command, CommandInput, CommandItem } from "@/components/ui/command";
18
18
  import { Tooltip } from "@/components/ui/tooltip";
19
19
  import { maybeAddMarimoImport } from "@/core/cells/add-missing-import";
20
- import { cellIdsAtom, useCellActions } from "@/core/cells/cells";
20
+ import { cellIdsAtom } from "@/core/cells/cells";
21
+ import { useCellActions } from "@/core/cells/actions";
21
22
  import { useLastFocusedCellId } from "@/core/cells/focus";
22
23
  import { autoInstantiateAtom } from "@/core/config/config";
23
24
  import {
@@ -849,13 +850,13 @@ const DatasetTableItem: React.FC<{
849
850
 
850
851
  const autoInstantiate = useAtomValue(autoInstantiateAtom);
851
852
  const lastFocusedCellId = useLastFocusedCellId();
852
- const { createNewCell } = useCellActions();
853
+ const { createCell } = useCellActions();
853
854
  const addCodeToNewCell = useAddCodeToNewCell();
854
855
 
855
856
  const handleAddTable = () => {
856
857
  maybeAddMarimoImport({
857
858
  autoInstantiate,
858
- createNewCell,
859
+ createCell,
859
860
  fromCellId: lastFocusedCellId,
860
861
  });
861
862
  const getCode = () => {
@@ -7,12 +7,8 @@ import {
7
7
  cellGraphsAtom,
8
8
  isVariableAffectedBySelectedCell,
9
9
  } from "@/components/editor/chrome/wrapper/minimap-state";
10
- import {
11
- useCellActions,
12
- useCellData,
13
- useCellIds,
14
- useCellRuntime,
15
- } from "@/core/cells/cells";
10
+ import { useCellData, useCellIds, useCellRuntime } from "@/core/cells/cells";
11
+ import { useCellActions } from "@/core/cells/actions";
16
12
  import { cellFocusAtom, useCellFocusActions } from "@/core/cells/focus";
17
13
  import type { CellId } from "@/core/cells/ids";
18
14
  import { useVariables } from "@/core/variables/state";
@@ -14,7 +14,8 @@ import {
14
14
  } from "lucide-react";
15
15
  import React, { memo, useId } from "react";
16
16
  import { type Edge, Panel } from "reactflow";
17
- import { getCellEditorView, useCellActions } from "@/core/cells/cells";
17
+ import { getCellEditorView } from "@/core/cells/cells";
18
+ import { useCellActions } from "@/core/cells/actions";
18
19
  import type { CellId } from "@/core/cells/ids";
19
20
  import { goToVariableDefinition } from "@/core/codemirror/go-to-definition/commands";
20
21
  import type { Variable, Variables } from "@/core/variables/types";
@@ -1,10 +1,16 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
  import { act, fireEvent, render, screen } from "@testing-library/react";
3
3
  import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
4
+ import { createStore, Provider } from "jotai";
5
+ import { mockDocumentModel } from "@/__mocks__/document";
4
6
  import { cellId } from "@/__tests__/branded";
7
+ import { DocumentProvider } from "@/core/notebook/document";
5
8
  import { TooltipProvider } from "@/components/ui/tooltip";
6
9
  import { OutputArea, OutputRenderer } from "../Output";
7
10
 
11
+ const store = createStore();
12
+ const { model } = mockDocumentModel(store, null);
13
+
8
14
  describe("OutputRenderer renderFallback prop", () => {
9
15
  it("should use renderFallback for unsupported mimetypes", () => {
10
16
  const renderFallback = (mimetype: string) => (
@@ -70,31 +76,39 @@ describe("OutputRenderer renderFallback prop", () => {
70
76
  describe("OutputArea null/undefined handling", () => {
71
77
  it("should render null when output is null", () => {
72
78
  const { container } = render(
73
- <TooltipProvider>
74
- <OutputArea
75
- output={null}
76
- cellId={cellId("test")}
77
- stale={false}
78
- loading={false}
79
- allowExpand={true}
80
- />
81
- </TooltipProvider>,
79
+ <Provider store={store}>
80
+ <DocumentProvider model={model}>
81
+ <TooltipProvider>
82
+ <OutputArea
83
+ output={null}
84
+ cellId={cellId("test")}
85
+ stale={false}
86
+ loading={false}
87
+ allowExpand={true}
88
+ />
89
+ </TooltipProvider>
90
+ </DocumentProvider>
91
+ </Provider>,
82
92
  );
83
93
  expect(container.innerHTML).toBe("");
84
94
  });
85
95
 
86
96
  it("should render null when output is undefined", () => {
87
97
  const { container } = render(
88
- <TooltipProvider>
89
- <OutputArea
90
- // @ts-expect-error -- testing runtime safety for undefined output
91
- output={undefined}
92
- cellId={cellId("test")}
93
- stale={false}
94
- loading={false}
95
- allowExpand={true}
96
- />
97
- </TooltipProvider>,
98
+ <Provider store={store}>
99
+ <DocumentProvider model={model}>
100
+ <TooltipProvider>
101
+ <OutputArea
102
+ // @ts-expect-error -- testing runtime safety for undefined output
103
+ output={undefined}
104
+ cellId={cellId("test")}
105
+ stale={false}
106
+ loading={false}
107
+ allowExpand={true}
108
+ />
109
+ </TooltipProvider>
110
+ </DocumentProvider>
111
+ </Provider>,
98
112
  );
99
113
  expect(container.innerHTML).toBe("");
100
114
  });
@@ -184,19 +198,23 @@ describe("OutputArea fullscreen exit control", () => {
184
198
 
185
199
  const renderOutput = () =>
186
200
  render(
187
- <TooltipProvider>
188
- <OutputArea
189
- output={{
190
- channel: "output",
191
- data: "Hello World",
192
- mimetype: "text/plain",
193
- }}
194
- cellId={cellId("test")}
195
- stale={false}
196
- loading={false}
197
- allowExpand={true}
198
- />
199
- </TooltipProvider>,
201
+ <Provider store={store}>
202
+ <DocumentProvider model={model}>
203
+ <TooltipProvider>
204
+ <OutputArea
205
+ output={{
206
+ channel: "output",
207
+ data: "Hello World",
208
+ mimetype: "text/plain",
209
+ }}
210
+ cellId={cellId("test")}
211
+ stale={false}
212
+ loading={false}
213
+ allowExpand={true}
214
+ />
215
+ </TooltipProvider>
216
+ </DocumentProvider>
217
+ </Provider>,
200
218
  );
201
219
 
202
220
  const enterFullscreen = (container: HTMLElement) => {
@@ -3,11 +3,13 @@ import { render } from "@testing-library/react";
3
3
  import { createStore, Provider } from "jotai";
4
4
  import { beforeAll, describe, expect, it } from "vitest";
5
5
  import { SetupMocks } from "@/__mocks__/common";
6
+ import { mockDocumentModel } from "@/__mocks__/document";
6
7
  import { MockNotebook } from "@/__mocks__/notebook";
7
8
  import { MockRequestClient } from "@/__mocks__/requests";
8
9
  import { cellId } from "@/__tests__/branded";
9
10
  import { TooltipProvider } from "@/components/ui/tooltip";
10
11
  import { notebookAtom } from "@/core/cells/cells";
12
+ import { DocumentProvider } from "@/core/notebook/document";
11
13
  import { createCellRuntimeState } from "@/core/cells/types";
12
14
  import type { UserConfig } from "@/core/config/config-schema";
13
15
  import type { OutputMessage } from "@/core/kernel/messages";
@@ -18,9 +20,12 @@ import { OutputArea } from "../Output";
18
20
 
19
21
  function createTestWrapper() {
20
22
  const store = createStore();
23
+ const { model } = mockDocumentModel(store, null);
21
24
  store.set(requestClientAtom, MockRequestClient.create());
22
25
  const wrapper = ({ children }: { children: React.ReactNode }) => (
23
- <Provider store={store}>{children}</Provider>
26
+ <Provider store={store}>
27
+ <DocumentProvider model={model}>{children}</DocumentProvider>
28
+ </Provider>
24
29
  );
25
30
  return { wrapper, store };
26
31
  }
@@ -150,17 +155,23 @@ describe("Output data attributes", () => {
150
155
  timestamp: 0,
151
156
  };
152
157
 
158
+ const store = createStore();
159
+ const { model } = mockDocumentModel(store, null);
153
160
  const { container } = render(
154
- <TooltipProvider>
155
- <OutputArea
156
- output={output}
157
- cellId={cid}
158
- stale={false}
159
- loading={false}
160
- allowExpand={true}
161
- className="test-output"
162
- />
163
- </TooltipProvider>,
161
+ <Provider store={store}>
162
+ <DocumentProvider model={model}>
163
+ <TooltipProvider>
164
+ <OutputArea
165
+ output={output}
166
+ cellId={cid}
167
+ stale={false}
168
+ loading={false}
169
+ allowExpand={true}
170
+ className="test-output"
171
+ />
172
+ </TooltipProvider>
173
+ </DocumentProvider>
174
+ </Provider>,
164
175
  );
165
176
 
166
177
  const outputElement = container.querySelector('[data-cell-role="output"]');
@@ -3,11 +3,13 @@ import { render } from "@testing-library/react";
3
3
  import { createStore, Provider } from "jotai";
4
4
  import { beforeAll, describe, expect, it } from "vitest";
5
5
  import { SetupMocks } from "@/__mocks__/common";
6
+ import { mockDocumentModel } from "@/__mocks__/document";
6
7
  import { MockNotebook } from "@/__mocks__/notebook";
7
8
  import { MockRequestClient } from "@/__mocks__/requests";
8
9
  import { cellId } from "@/__tests__/branded";
9
10
  import { TooltipProvider } from "@/components/ui/tooltip";
10
11
  import { notebookAtom } from "@/core/cells/cells";
12
+ import { DocumentProvider } from "@/core/notebook/document";
11
13
  import type { CellRuntimeState } from "@/core/cells/types";
12
14
  import { createCellRuntimeState } from "@/core/cells/types";
13
15
  import { defaultUserConfig } from "@/core/config/config-schema";
@@ -19,9 +21,12 @@ const cid = cellId("test");
19
21
 
20
22
  function createTestWrapper() {
21
23
  const store = createStore();
24
+ const { model } = mockDocumentModel(store, null);
22
25
  store.set(requestClientAtom, MockRequestClient.create());
23
26
  const wrapper = ({ children }: { children: React.ReactNode }) => (
24
- <Provider store={store}>{children}</Provider>
27
+ <Provider store={store}>
28
+ <DocumentProvider model={model}>{children}</DocumentProvider>
29
+ </Provider>
25
30
  );
26
31
  return { wrapper, store };
27
32
  }
@@ -0,0 +1,69 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+ // @vitest-environment jsdom
3
+
4
+ import { fireEvent, render, screen } from "@testing-library/react";
5
+ import { atom, createStore, Provider } from "jotai";
6
+ import { afterEach, describe, expect, it } from "vitest";
7
+ import { cellId } from "@/__tests__/branded";
8
+ import { TooltipProvider } from "@/components/ui/tooltip";
9
+ import {
10
+ createDocumentModel,
11
+ DocumentProvider,
12
+ } from "@/core/notebook/document";
13
+ import {
14
+ cell,
15
+ document as documentOf,
16
+ withCells,
17
+ } from "@/core/notebook/document/__tests__/fixtures";
18
+ import { fakeBackend } from "@/core/notebook/replica/__tests__/fixtures";
19
+ import { NameCellContentEditable } from "../name-cell-input";
20
+
21
+ const controllers: AbortController[] = [];
22
+
23
+ afterEach(() => {
24
+ for (const controller of controllers.splice(0)) {
25
+ controller.abort();
26
+ }
27
+ });
28
+
29
+ describe("NameCellContentEditable", () => {
30
+ it("renames the cell in the document when the name is committed", () => {
31
+ const store = createStore();
32
+ const source = atom(
33
+ withCells(documentOf(), {
34
+ c1: cell("c1", "x = 1", { name: "first" }),
35
+ }),
36
+ );
37
+ const model = createDocumentModel({
38
+ store,
39
+ documentAtom: source,
40
+ backendAtom: atom(fakeBackend()),
41
+ });
42
+ const controller = new AbortController();
43
+ controllers.push(controller);
44
+ model.start({ signal: controller.signal });
45
+
46
+ render(
47
+ <Provider store={store}>
48
+ <DocumentProvider model={model}>
49
+ <TooltipProvider>
50
+ <NameCellContentEditable
51
+ cellId={cellId("c1")}
52
+ value="first"
53
+ className=""
54
+ />
55
+ </TooltipProvider>
56
+ </DocumentProvider>
57
+ </Provider>,
58
+ );
59
+
60
+ const field = screen.getByText("first");
61
+ // jsdom does not lay text out, so it has no innerText of its own.
62
+ Object.defineProperty(field, "innerText", { value: " renamed " });
63
+ fireEvent.blur(field);
64
+
65
+ expect(store.get(model.documentAtom)?.cells.get("c1")?.name).toBe(
66
+ "renamed",
67
+ );
68
+ });
69
+ });
@@ -3,13 +3,14 @@
3
3
  import React, { useRef, useState } from "react";
4
4
  import { Input } from "@/components/ui/input";
5
5
  import { Tooltip } from "@/components/ui/tooltip";
6
- import { getCellNames, useCellActions } from "@/core/cells/cells";
6
+ import { getCellNames } from "@/core/cells/cells";
7
7
  import type { CellId } from "@/core/cells/ids";
8
8
  import {
9
9
  getValidName,
10
10
  isInternalCellName,
11
11
  normalizeName,
12
12
  } from "@/core/cells/names";
13
+ import { useNotebookDocumentEdit } from "@/core/notebook/document";
13
14
  import { useOnMount } from "@/hooks/useLifecycle";
14
15
  import { cn } from "@/utils/cn";
15
16
  import { Events } from "@/utils/events";
@@ -71,9 +72,9 @@ export const NameCellContentEditable: React.FC<{
71
72
  value: string;
72
73
  className: string;
73
74
  }> = ({ value, cellId, className }) => {
74
- const { updateCellName } = useCellActions();
75
+ const edit = useNotebookDocumentEdit();
75
76
  const inputProps = useCellNameInput(value, (newName) =>
76
- updateCellName({ cellId, name: newName }),
77
+ edit((tx) => tx.setName(cellId, newName)),
77
78
  );
78
79
 
79
80
  // If the name is the default, don't render the content editable