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

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 (123) hide show
  1. package/dist/{ConnectedDataExplorerComponent-BbDrlHvG.js → ConnectedDataExplorerComponent-BbSXV-Xa.js} +8 -8
  2. package/dist/{ErrorBoundary-RaIwGWT3.js → ErrorBoundary-NE86qEWZ.js} +4 -4
  3. package/dist/{abnfDiagram-VCTEODGH-Dr-fo8_z.js → abnfDiagram-VCTEODGH-D7n07nXf.js} +2 -2
  4. package/dist/{architectureDiagram-5GKGNRK7-ByKIl9GG.js → architectureDiagram-5GKGNRK7-D6CjRib5.js} +1 -1
  5. package/dist/{chat-ui-BsV2WH-4.js → chat-ui-CC7GekpG.js} +34 -34
  6. package/dist/{chunk-IMKFNOWR-IKDP18MQ.js → chunk-IMKFNOWR-6dtPz7uS.js} +1 -1
  7. package/dist/{chunk-SHT3W25Y-LkIgegwh.js → chunk-SHT3W25Y-BwnFNKDA.js} +1 -1
  8. package/dist/{chunk-SVP7TREG-DReBYtnB.js → chunk-SVP7TREG-D2eV4vBJ.js} +1 -1
  9. package/dist/{chunk-TICWLB2K-DQ0A0-1D.js → chunk-TICWLB2K-BDs4-_-r.js} +1 -1
  10. package/dist/{classDiagram-ZZMXUADV-CwvXdCNE.js → classDiagram-ZZMXUADV-DCJnf_8v.js} +2 -2
  11. package/dist/{classDiagram-v2-VYDZK3BY-D0XAxDsc.js → classDiagram-v2-VYDZK3BY-BOmSzPBD.js} +2 -2
  12. package/dist/{code-visibility-BMi0KLAQ.js → code-visibility-Bzvc6ajl.js} +23 -23
  13. package/dist/{common-BMkJrZsD.js → common-Ciw4zkh2.js} +3412 -3412
  14. package/dist/{cynefinDiagram-5FMLGOSQ-BFN68nHr.js → cynefinDiagram-5FMLGOSQ-Bln_Soky.js} +1 -1
  15. package/dist/{dagre-GXQ25YYZ-CZt4rtLq.js → dagre-GXQ25YYZ-D-nf7WzW.js} +1 -1
  16. package/dist/{data-grid-overlay-editor-CCc1P42P.js → data-grid-overlay-editor-AQREmxI7.js} +1 -1
  17. package/dist/{diagram-S7CK7UJ4-D5cOz47_.js → diagram-S7CK7UJ4-PsgSMkY2.js} +1 -1
  18. package/dist/{diagram-UQ7AKVKN-Qgdppb4a.js → diagram-UQ7AKVKN-DfwfUuSw.js} +1 -1
  19. package/dist/{diagram-VX7I27RA-BsDCvily.js → diagram-VX7I27RA-C9_e-oMc.js} +1 -1
  20. package/dist/{diagram-Z3DM3KII-igTkGjKI.js → diagram-Z3DM3KII-CWLa5tuY.js} +1 -1
  21. package/dist/{dropdown-menu-BWnnAstC.js → dropdown-menu-B6ftyzOg.js} +1 -1
  22. package/dist/{ebnfDiagram-PWID7BFC-BHuZGjIr.js → ebnfDiagram-PWID7BFC-B1QRM58v.js} +2 -2
  23. package/dist/{erDiagram-RLTQ6QDP-DKObXTVE.js → erDiagram-RLTQ6QDP-DJK_FqvW.js} +1 -1
  24. package/dist/{error-entries-BpUJSLUZ.js → error-entries-DgK3wUJR.js} +5640 -5591
  25. package/dist/{feedback-button-CMVkEos_.js → feedback-button-8a6SETmT.js} +24 -24
  26. package/dist/{flowDiagram-HODETNUW-DZI_kit0.js → flowDiagram-HODETNUW-Uxc25XSJ.js} +2 -2
  27. package/dist/{formats-CwJHWasD.js → formats-DQCyPd5Z.js} +1 -1
  28. package/dist/{glide-data-editor-BA2pcHSV.js → glide-data-editor-B70oke_v.js} +5 -5
  29. package/dist/{globals-B5jjJ0ms.js → globals-Cxd5hNlI.js} +2 -2
  30. package/dist/{html-to-image-CQr2-IDA.js → html-to-image-D4yG5Ru0.js} +25 -25
  31. package/dist/{infoDiagram-27XIBGKW-DdPl-7-n.js → infoDiagram-27XIBGKW-DmjxqwL0.js} +1 -1
  32. package/dist/{ishikawaDiagram-5VMMS53U-DbyW6l59.js → ishikawaDiagram-5VMMS53U-NgCLHqQi.js} +1 -1
  33. package/dist/{kanban-definition-UXKFOSKX-BMX9SyBS.js → kanban-definition-UXKFOSKX-CZaG-iam.js} +1 -1
  34. package/dist/main.js +187 -188
  35. package/dist/{mermaid-C8W8mTbA.js → mermaid-CSvw7c71.js} +34 -34
  36. package/dist/{mindmap-definition-YA3MSWOX-Zd_tAxWL.js → mindmap-definition-YA3MSWOX-DJYQBDH_.js} +1 -1
  37. package/dist/{number-overlay-editor-BIWiV-TU.js → number-overlay-editor-ChK-SKUk.js} +1 -1
  38. package/dist/{pegDiagram-XKGWAZYB-DjYydPdo.js → pegDiagram-XKGWAZYB-CHKO_dAe.js} +2 -2
  39. package/dist/{pieDiagram-E7YTZNPT-R5LKjO2n.js → pieDiagram-E7YTZNPT-DVevbMAo.js} +1 -1
  40. package/dist/{process-output-Uw-VJE5V.js → process-output-DxvBAeL3.js} +3 -3
  41. package/dist/{railroadDiagram-O6MQD6OU-C7uNKtfm.js → railroadDiagram-O6MQD6OU-Detj1kcB.js} +2 -2
  42. package/dist/{requirementDiagram-BXWQKSXE-CxAIzQfl.js → requirementDiagram-BXWQKSXE-BLFD0T_Z.js} +1 -1
  43. package/dist/{reveal-component-XiecZ3Ua.js → reveal-component-CXMXeDZD.js} +6 -6
  44. package/dist/{sequenceDiagram-WJ2MYXX4-B5tmlPd5.js → sequenceDiagram-WJ2MYXX4-BZBgatQV.js} +1 -1
  45. package/dist/{spec-45FnujvG.js → spec-Mnkn3XEr.js} +1 -1
  46. package/dist/{stateDiagram-D77RDMKH-C1hc5H7Y.js → stateDiagram-D77RDMKH-4BZW9-6_.js} +2 -2
  47. package/dist/{stateDiagram-v2-MP3YSRHH-DRWeqQTn.js → stateDiagram-v2-MP3YSRHH-C4sKC8Iq.js} +2 -2
  48. package/dist/style.css +1 -1
  49. package/dist/{swimlanes-42K2YHIH-NTLas--s.js → swimlanes-42K2YHIH-SL5yeGe2.js} +1 -1
  50. package/dist/{swimlanesDiagram-VR7AAH4N-ChPggljD.js → swimlanesDiagram-VR7AAH4N-DqPmAYUv.js} +2 -2
  51. package/dist/{timeline-definition-24CTP7MA-B4CZ9srJ.js → timeline-definition-24CTP7MA-BfXUMWkq.js} +1 -1
  52. package/dist/{toDate-rySyYxqk.js → toDate-TMubKIVL.js} +22 -22
  53. package/dist/{useAsyncData-B7MiltyV.js → useAsyncData-DjMGFzFy.js} +1 -1
  54. package/dist/{useDeepCompareMemoize-DZmHBD_1.js → useDeepCompareMemoize-BQR5TJot.js} +1 -1
  55. package/dist/{useLifecycle-DRbRhzxg.js → useLifecycle-C_GvKWbQ.js} +26 -23
  56. package/dist/{useTheme-TLkqJsvo.js → useTheme-Bns2gJZ6.js} +179 -178
  57. package/dist/{vega-component-DC6P127L.js → vega-component-BsVptuhz.js} +5 -5
  58. package/dist/{vennDiagram-4TSXK5OY-DJIvMt44.js → vennDiagram-4TSXK5OY-CH65znGa.js} +1 -1
  59. package/dist/{wardleyDiagram-VM6X3IG4-45H0zg0u.js → wardleyDiagram-VM6X3IG4-z9pWKb2_.js} +1 -1
  60. package/dist/{xychartDiagram-S5SC5T6Z-ZT-XzcPN.js → xychartDiagram-S5SC5T6Z-MxyaWjjq.js} +1 -1
  61. package/package.json +1 -1
  62. package/src/__mocks__/requests.ts +0 -1
  63. package/src/components/editor/cell/StagedAICell.tsx +10 -2
  64. package/src/components/editor/cell/code/cell-editor.tsx +7 -14
  65. package/src/components/editor/chrome/wrapper/__tests__/document-sync-status.test.tsx +92 -0
  66. package/src/components/editor/chrome/wrapper/footer-items/document-sync-status.tsx +54 -0
  67. package/src/components/editor/chrome/wrapper/footer.tsx +2 -0
  68. package/src/core/ai/__tests__/staged-cells.test.ts +8 -5
  69. package/src/core/ai/staged-cells.ts +7 -2
  70. package/src/core/ai/tools/__tests__/edit-notebook-tool.test.ts +3 -15
  71. package/src/core/ai/tools/edit-notebook-tool.ts +14 -3
  72. package/src/core/cells/__tests__/cells.test.ts +0 -297
  73. package/src/core/cells/__tests__/document.test.ts +410 -0
  74. package/src/core/cells/__tests__/flush-document.test.ts +40 -0
  75. package/src/core/cells/__tests__/notebook-outline.test.ts +1 -6
  76. package/src/core/cells/__tests__/with-document-save.test.ts +67 -0
  77. package/src/core/cells/cells.ts +27 -158
  78. package/src/core/cells/columns.ts +38 -0
  79. package/src/core/cells/document.ts +360 -0
  80. package/src/core/cells/types.ts +12 -0
  81. package/src/core/codemirror/cells/__tests__/extensions.test.ts +27 -1
  82. package/src/core/codemirror/cells/extensions.ts +14 -0
  83. package/src/core/codemirror/format.ts +6 -5
  84. package/src/core/codemirror/language/__tests__/utils.test.ts +187 -15
  85. package/src/core/codemirror/language/cell-code.ts +114 -0
  86. package/src/core/codemirror/language/extension.ts +47 -30
  87. package/src/core/codemirror/language/languages/sql/sql.ts +7 -17
  88. package/src/core/codemirror/language/utils.ts +9 -39
  89. package/src/core/codemirror/lsp/notebook-lsp.ts +6 -5
  90. package/src/core/codemirror/rtc/extension.ts +0 -1
  91. package/src/core/edit-app.tsx +4 -3
  92. package/src/core/export/layout.ts +2 -2
  93. package/src/core/islands/bridge.ts +0 -1
  94. package/src/core/network/requests-lazy.ts +0 -1
  95. package/src/core/network/requests-network.ts +0 -9
  96. package/src/core/network/requests-static.ts +0 -1
  97. package/src/core/network/requests-toasting.tsx +0 -1
  98. package/src/core/network/types.ts +0 -5
  99. package/src/core/notebook/document/__tests__/codemirror.test.ts +76 -14
  100. package/src/core/notebook/document/__tests__/hold.test.ts +88 -0
  101. package/src/core/notebook/document/__tests__/hooks.test.tsx +3 -3
  102. package/src/core/notebook/document/__tests__/lifecycle-scenarios.test.ts +3 -3
  103. package/src/core/notebook/document/__tests__/model.test.ts +71 -15
  104. package/src/core/notebook/document/__tests__/scenario-fixture.ts +1 -1
  105. package/src/core/notebook/document/codemirror.ts +27 -122
  106. package/src/core/notebook/document/hooks.tsx +2 -2
  107. package/src/core/notebook/document/index.ts +9 -1
  108. package/src/core/notebook/document/model.ts +74 -24
  109. package/src/core/notebook/document/sync.ts +53 -4
  110. package/src/core/run-app.tsx +44 -41
  111. package/src/core/saving/save-component.tsx +2 -5
  112. package/src/core/session/__tests__/useNotebookSession.hook.test.tsx +63 -3
  113. package/src/core/session/active-notebook.ts +4 -0
  114. package/src/core/session/useNotebookSession.tsx +39 -19
  115. package/src/core/wasm/__tests__/bridge.test.ts +3 -3
  116. package/src/core/wasm/bridge.ts +5 -12
  117. package/src/core/wasm/worker/worker.ts +0 -9
  118. package/src/utils/__tests__/{createReducer.test.ts → createReducer.test.tsx} +28 -0
  119. package/src/utils/createReducer.ts +42 -21
  120. package/src/core/cells/__tests__/apply-transaction.test.ts +0 -991
  121. package/src/core/cells/__tests__/document-changes.test.ts +0 -1140
  122. package/src/core/cells/__tests__/document-roundtrip.test.ts +0 -392
  123. package/src/core/cells/document-changes.ts +0 -944
@@ -6,7 +6,6 @@ import { EditorView } from "@codemirror/view";
6
6
  import { createStore } from "jotai";
7
7
  import {
8
8
  afterAll,
9
- afterEach,
10
9
  beforeAll,
11
10
  beforeEach,
12
11
  describe,
@@ -34,7 +33,6 @@ import {
34
33
  type NotebookState,
35
34
  notebookAtom,
36
35
  } from "../cells";
37
- import { exportedForTesting as documentTransactionTestExports } from "../document-changes";
38
36
  import {
39
37
  focusAndScrollCellIntoView,
40
38
  scrollToBottom,
@@ -156,10 +154,6 @@ describe("cell reducer", () => {
156
154
  firstCellId = state.cellIds.inOrderIds[0];
157
155
  });
158
156
 
159
- afterEach(() => {
160
- documentTransactionTestExports.cancelPendingChanges();
161
- });
162
-
163
157
  afterAll(() => {
164
158
  CellId.create = originalCreate;
165
159
  });
@@ -1761,187 +1755,6 @@ describe("cell reducer", () => {
1761
1755
  expect(state.cellData[firstCellId].name).toBe("Test Cell");
1762
1756
  });
1763
1757
 
1764
- it("can set cell IDs and codes", () => {
1765
- const newIds = [cellId("3"), cellId("4"), cellId("5")];
1766
- const newCodes = ["code1", "code2", "code3"];
1767
-
1768
- actions.setCellIds({ cellIds: newIds });
1769
- expect(state.cellIds.atOrThrow(FIRST_COLUMN).topLevelIds).toEqual(newIds);
1770
-
1771
- // When codeIsStale is false, lastCodeRun should match code
1772
- actions.setCellCodes({
1773
- codes: newCodes,
1774
- ids: newIds,
1775
- codeIsStale: false,
1776
- });
1777
- newIds.forEach((id, index) => {
1778
- expect(state.cellData[id].code).toBe(newCodes[index]);
1779
- expect(state.cellData[id].lastCodeRun).toBe(newCodes[index]);
1780
- expect(state.cellData[id].edited).toBe(false);
1781
- });
1782
-
1783
- // When codeIsStale is true, lastCodeRun should not change
1784
- const staleCodes = ["stale1", "stale2", "stale3"];
1785
- actions.setCellCodes({
1786
- codes: staleCodes,
1787
- ids: newIds,
1788
- codeIsStale: true,
1789
- });
1790
- newIds.forEach((id, index) => {
1791
- expect(state.cellData[id].code).toBe(staleCodes[index]);
1792
- expect(state.cellData[id].lastCodeRun).toBe(newCodes[index]);
1793
- expect(state.cellData[id].edited).toBe(true);
1794
- });
1795
- });
1796
-
1797
- it("can can add a new cell with/without stale code", () => {
1798
- actions.setCellCodes({
1799
- codes: ["new code"],
1800
- ids: [cellId("2")],
1801
- codeIsStale: false,
1802
- });
1803
-
1804
- expect(state.cellData[cellId("2")].code).toBe("new code");
1805
- expect(state.cellData[cellId("2")].edited).toBe(false);
1806
- expect(state.cellData[cellId("2")].lastCodeRun).toBe("new code");
1807
-
1808
- actions.setCellCodes({
1809
- codes: ["new code 2"],
1810
- ids: [cellId("9")],
1811
- codeIsStale: true,
1812
- });
1813
-
1814
- expect(state.cellData[cellId("9")].code).toBe("new code 2");
1815
- expect(state.cellData[cellId("9")].edited).toBe(true);
1816
- expect(state.cellData[cellId("9")].lastCodeRun).toBe(null);
1817
- });
1818
-
1819
- it("can partial update cell codes", () => {
1820
- actions.createNewCell({ cellId: firstCellId, before: false });
1821
- actions.createNewCell({ cellId: cellId("1"), before: false });
1822
-
1823
- expect(state.cellIds.inOrderIds).toEqual([
1824
- cellId("0"),
1825
- cellId("1"),
1826
- cellId("2"),
1827
- ]);
1828
- expect(state.cellData[cellId("0")].code).toBe("");
1829
- expect(state.cellData[cellId("1")].code).toBe("");
1830
- expect(state.cellData[cellId("2")].code).toBe("");
1831
-
1832
- // Update cell 1
1833
- actions.setCellCodes({
1834
- codes: ["new code 2"],
1835
- ids: [cellId("1")],
1836
- codeIsStale: false,
1837
- });
1838
-
1839
- expect(state.cellIds.inOrderIds).toEqual([
1840
- cellId("0"),
1841
- cellId("1"),
1842
- cellId("2"),
1843
- ]);
1844
- expect(state.cellData[cellId("0")].code).toBe("");
1845
- expect(state.cellData[cellId("1")].code).toBe("new code 2");
1846
- expect(state.cellData[cellId("1")].edited).toBe(false);
1847
- expect(state.cellData[cellId("2")].code).toBe("");
1848
- });
1849
-
1850
- it("can set cell codes with new cell ids, while preserving the old cell data", () => {
1851
- actions.setCellCodes({
1852
- codes: ["code1", "code2", "code3"],
1853
- ids: [cellId("3"), cellId("4"), cellId("5")],
1854
- codeIsStale: false,
1855
- });
1856
- expect(state.cellData[cellId("3")].code).toBe("code1");
1857
- expect(state.cellData[cellId("4")].code).toBe("code2");
1858
- expect(state.cellData[cellId("5")].code).toBe("code3");
1859
-
1860
- // Update with some new cell ids and some old cell ids
1861
- actions.setCellIds({
1862
- cellIds: [cellId("1"), cellId("2"), cellId("3"), cellId("4")],
1863
- });
1864
- actions.setCellCodes({
1865
- codes: ["new1", "new2", "code1", "code2"],
1866
- ids: [cellId("1"), cellId("2"), cellId("3"), cellId("4")],
1867
- codeIsStale: false,
1868
- });
1869
- expect(state.cellData[cellId("1")].code).toBe("new1");
1870
- expect(state.cellData[cellId("2")].code).toBe("new2");
1871
- expect(state.cellData[cellId("3")].code).toBe("code1");
1872
- expect(state.cellData[cellId("4")].code).toBe("code2");
1873
- expect(state.cellIds.inOrderIds).toEqual([
1874
- cellId("1"),
1875
- cellId("2"),
1876
- cellId("3"),
1877
- cellId("4"),
1878
- ]);
1879
- // Cell 5 data is preserved (possibly used for tracing), but it's not in the cellIds
1880
- expect(state.cellData[cellId("5")]).not.toBeUndefined();
1881
- });
1882
-
1883
- it("can set cell codes with names and configs", () => {
1884
- const newIds = [cellId("3"), cellId("4")];
1885
- actions.setCellIds({ cellIds: newIds });
1886
- actions.setCellCodes({
1887
- codes: ["code1", "code2"],
1888
- ids: newIds,
1889
- codeIsStale: false,
1890
- names: ["setup_cell", "analysis"],
1891
- configs: [
1892
- { hide_code: true, disabled: false, column: null },
1893
- { hide_code: false, disabled: true, column: null },
1894
- ],
1895
- });
1896
-
1897
- expect(state.cellData[cellId("3")].name).toBe("setup_cell");
1898
- expect(state.cellData[cellId("3")].config.hide_code).toBe(true);
1899
- expect(state.cellData[cellId("3")].config.disabled).toBe(false);
1900
-
1901
- expect(state.cellData[cellId("4")].name).toBe("analysis");
1902
- expect(state.cellData[cellId("4")].config.hide_code).toBe(false);
1903
- expect(state.cellData[cellId("4")].config.disabled).toBe(true);
1904
- });
1905
-
1906
- it("can set cell codes without names/configs (backward compat)", () => {
1907
- const newIds = [cellId("3")];
1908
- actions.setCellIds({ cellIds: newIds });
1909
- actions.setCellCodes({
1910
- codes: ["code1"],
1911
- ids: newIds,
1912
- codeIsStale: false,
1913
- });
1914
-
1915
- // Should use defaults when names/configs not provided
1916
- expect(state.cellData[cellId("3")].code).toBe("code1");
1917
- expect(state.cellData[cellId("3")].config.hide_code).toBe(false);
1918
- expect(state.cellData[cellId("3")].config.disabled).toBe(false);
1919
- });
1920
-
1921
- it("can update names and configs on existing cells via setCellCodes", () => {
1922
- // Set initial state
1923
- actions.setCellCodes({
1924
- codes: ["x = 1"],
1925
- ids: [firstCellId],
1926
- codeIsStale: false,
1927
- names: ["old_name"],
1928
- configs: [{ hide_code: false, disabled: false, column: null }],
1929
- });
1930
- expect(state.cellData[firstCellId].name).toBe("old_name");
1931
- expect(state.cellData[firstCellId].config.hide_code).toBe(false);
1932
-
1933
- // Update with new name and config (same code)
1934
- actions.setCellCodes({
1935
- codes: ["x = 1"],
1936
- ids: [firstCellId],
1937
- codeIsStale: true,
1938
- names: ["new_name"],
1939
- configs: [{ hide_code: true, disabled: false, column: null }],
1940
- });
1941
- expect(state.cellData[firstCellId].name).toBe("new_name");
1942
- expect(state.cellData[firstCellId].config.hide_code).toBe(true);
1943
- });
1944
-
1945
1758
  it("can fold and unfold all cells", () => {
1946
1759
  actions.foldAll();
1947
1760
  expect(foldAllBulk).toHaveBeenCalled();
@@ -2632,116 +2445,6 @@ describe("cell reducer", () => {
2632
2445
  expect(state.cellIds.getColumns()[2].topLevelIds).toEqual([cellId("2")]);
2633
2446
  });
2634
2447
 
2635
- it("rebuildCellColumns regroups cells by config.column", () => {
2636
- // Create four cells in a single column.
2637
- actions.createNewCell({ cellId: firstCellId, before: false });
2638
- actions.createNewCell({ cellId: cellId("1"), before: false });
2639
- actions.createNewCell({ cellId: cellId("2"), before: false });
2640
- expect(state.cellIds.getColumns().length).toBe(1);
2641
-
2642
- // Explicitly set config.column on each cell. This ONLY updates metadata —
2643
- // updateCellConfig does not touch the MultiColumn tree.
2644
- actions.updateCellConfig({
2645
- cellId: cellId("0"),
2646
- config: { column: 0 },
2647
- });
2648
- actions.updateCellConfig({
2649
- cellId: cellId("2"),
2650
- config: { column: 1 },
2651
- });
2652
-
2653
- // Tree is still a single column at this point.
2654
- expect(state.cellIds.getColumns().length).toBe(1);
2655
-
2656
- // Now rebuild the column tree from metadata.
2657
- actions.rebuildCellColumns({
2658
- cellIds: [cellId("0"), cellId("1"), cellId("2"), cellId("3")],
2659
- });
2660
-
2661
- expect(state.cellIds.getColumns().length).toBe(2);
2662
- // Cell 1 inherits from 0 (col 0), cell 3 inherits from 2 (col 1).
2663
- expect(state.cellIds.getColumns()[0].topLevelIds).toEqual([
2664
- cellId("0"),
2665
- cellId("1"),
2666
- ]);
2667
- expect(state.cellIds.getColumns()[1].topLevelIds).toEqual([
2668
- cellId("2"),
2669
- cellId("3"),
2670
- ]);
2671
- });
2672
-
2673
- it("rebuildCellColumns with explicit column on every cell", () => {
2674
- actions.createNewCell({ cellId: firstCellId, before: false });
2675
- actions.createNewCell({ cellId: cellId("1"), before: false });
2676
- actions.createNewCell({ cellId: cellId("2"), before: false });
2677
-
2678
- for (const [id, col] of [
2679
- ["0", 1],
2680
- ["1", 0],
2681
- ["2", 1],
2682
- ["3", 0],
2683
- ] as const) {
2684
- actions.updateCellConfig({ cellId: cellId(id), config: { column: col } });
2685
- }
2686
-
2687
- actions.rebuildCellColumns({
2688
- cellIds: [cellId("0"), cellId("1"), cellId("2"), cellId("3")],
2689
- });
2690
-
2691
- expect(state.cellIds.getColumns().length).toBe(2);
2692
- expect(state.cellIds.getColumns()[0].topLevelIds).toEqual([
2693
- cellId("1"),
2694
- cellId("3"),
2695
- ]);
2696
- expect(state.cellIds.getColumns()[1].topLevelIds).toEqual([
2697
- cellId("0"),
2698
- cellId("2"),
2699
- ]);
2700
- });
2701
-
2702
- it("rebuildCellColumns collapses to one column when all cells are col 0", () => {
2703
- actions.createNewCell({ cellId: firstCellId, before: false });
2704
- actions.addColumnBreakpoint({ cellId: cellId("1") });
2705
- expect(state.cellIds.getColumns().length).toBe(2);
2706
-
2707
- // Wipe column metadata back to 0 for both cells.
2708
- actions.updateCellConfig({ cellId: cellId("0"), config: { column: 0 } });
2709
- actions.updateCellConfig({ cellId: cellId("1"), config: { column: 0 } });
2710
-
2711
- actions.rebuildCellColumns({
2712
- cellIds: [cellId("0"), cellId("1")],
2713
- });
2714
-
2715
- expect(state.cellIds.getColumns().length).toBe(1);
2716
- expect(state.cellIds.getColumns()[0].topLevelIds).toEqual([
2717
- cellId("0"),
2718
- cellId("1"),
2719
- ]);
2720
- });
2721
-
2722
- it("rebuildCellColumns follows the provided order, not current tree order", () => {
2723
- // Start with a single column.
2724
- actions.createNewCell({ cellId: firstCellId, before: false });
2725
- actions.createNewCell({ cellId: cellId("1"), before: false });
2726
- actions.updateCellConfig({ cellId: cellId("0"), config: { column: 0 } });
2727
- actions.updateCellConfig({ cellId: cellId("2"), config: { column: 1 } });
2728
-
2729
- // Pass the reversed order. The rebuild should honor it.
2730
- actions.rebuildCellColumns({
2731
- cellIds: [cellId("2"), cellId("1"), cellId("0")],
2732
- });
2733
-
2734
- // cellIds iteration:
2735
- // 2 → col=1, pushed to col1, prev=1
2736
- // 1 → col=null, pushed to col[prev=1] = col1
2737
- // 0 → col=0, pushed to col0
2738
- expect(state.cellIds.getColumns()[0].topLevelIds).toEqual([cellId("0")]);
2739
- expect(state.cellIds.getColumns()[1].topLevelIds).toEqual([
2740
- cellId("2"),
2741
- cellId("1"),
2742
- ]);
2743
- });
2744
-
2745
2448
  it("can clear output of a single cell", () => {
2746
2449
  // Set up initial state with output
2747
2450
  actions.handleCellMessage({