@marimo-team/islands 0.25.3-dev30 → 0.25.3-dev301
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.
- package/dist/{ConnectedDataExplorerComponent-7EaP9VWb.js → ConnectedDataExplorerComponent-X-_Gsw0B.js} +153 -177
- package/dist/{ErrorBoundary-2Tp_7IgE.js → ErrorBoundary-D2XuUNty.js} +79 -85
- package/dist/{ImageComparisonComponent-uU8FSKZE.js → ImageComparisonComponent-DgvSuY9B.js} +20 -20
- package/dist/{Plot-DdYOe1UK.js → Plot-Bfd0pJea.js} +2474 -3107
- package/dist/_baseSet-Bd5zh2yg.js +327 -0
- package/dist/{abnfDiagram-VCTEODGH-z_OSynK8.js → abnfDiagram-VCTEODGH-B8nNWmL7.js} +5 -5
- package/dist/any-language-editor-DhAtCzlx.js +75 -0
- package/dist/{apl-GEW9-ZP1.js → apl-stFrI2NB.js} +1 -1
- package/dist/{arc-7ra3iNdN.js → arc-4W6H62B5.js} +1 -1
- package/dist/architecture-7GRP2DOG-GlkXha5_.js +2 -0
- package/dist/{architectureDiagram-5GKGNRK7-Cs8J8BZr.js → architectureDiagram-5GKGNRK7-DcfTzRDz.js} +48 -64
- package/dist/{arrays-CN1djC4k.js → arrays-DoQ-AILx.js} +15 -27
- package/dist/{asciiarmor-BWNxzkG7.js → asciiarmor-DHwFuaIC.js} +1 -1
- package/dist/{asn1-Bcn2QutK.js → asn1-KIH4fwAq.js} +1 -1
- package/dist/assertNever-De6m1Aro.js +507 -0
- package/dist/assets/__vite-browser-external-BzfoKXxV.js +1 -0
- package/dist/assets/worker-DVG30pr3.js +171 -0
- package/dist/{blockDiagram-I7D4REHJ-Cg25UrxT.js → blockDiagram-I7D4REHJ-B4cvqWJn.js} +28 -39
- package/dist/{brainfuck-BQCYDheZ.js → brainfuck-UPAij4U9.js} +1 -1
- package/dist/{button-CvjkwdSk.js → button-BuSV-mLI.js} +64 -64
- package/dist/{c4Diagram-7LVT6UL2-BxFgrnNV.js → c4Diagram-7LVT6UL2-k-4SLDdM.js} +8 -8
- package/dist/{capabilities-CQ5IjhzL.js → capabilities-BiN90k7v.js} +2 -2
- package/dist/{channel-CPObtJXj.js → channel-CuTaWMxU.js} +1 -1
- package/dist/{chat-ui-BeKQyQQI.js → chat-ui-CtbON6Zl.js} +2142 -1869
- package/dist/{check-BMKBBrdc.js → check-C7fmwkwt.js} +1 -1
- package/dist/{chunk-4HAMMTFA-D4eFPyFh.js → chunk-4HAMMTFA-Bk_5S_m9.js} +6 -6
- package/dist/{chunk-75Z2AOVW-D7gxIs2Q.js → chunk-75Z2AOVW-9jQIEAxd.js} +4 -4
- package/dist/{chunk-DU6HZSFF-BwiyaNpg.js → chunk-DU6HZSFF-B20LZ-hE.js} +14 -22
- package/dist/{chunk-F27PBJKO-ufseIn5y.js → chunk-F27PBJKO-YjRXlNkT.js} +3 -3
- package/dist/{chunk-FOHPRMQF-BpYR8RqP.js → chunk-FOHPRMQF-ezmr_yWy.js} +49 -58
- package/dist/{chunk-GMAD6QVW-BhaJx0X3.js → chunk-GMAD6QVW-DokpSFdf.js} +16 -75
- package/dist/{chunk-GVQU2GXP-Cwbt-lF0.js → chunk-GVQU2GXP-DGvySV5W.js} +3 -3
- package/dist/{chunk-IMKFNOWR-aoSFasqF.js → chunk-IMKFNOWR-BHJ3ZxAy.js} +8 -8
- package/dist/{chunk-L3NEJ4N5-n-zgIVSy.js → chunk-L3NEJ4N5-D9-ekjZc.js} +6 -6
- package/dist/{chunk-OSK3NFVY-DXa-Cxbn.js → chunk-OSK3NFVY-p7meGiY-.js} +8 -8
- package/dist/{chunk-P2QGCYS3-B_Zd3-X0.js → chunk-P2QGCYS3-74rxrEwb.js} +1 -1
- package/dist/{chunk-POPQ4Y6H-hYOXbYH_.js → chunk-POPQ4Y6H-EOTPk9Tj.js} +2 -2
- package/dist/{chunk-PWAF6VOD-CQw5qATZ.js → chunk-PWAF6VOD-oT_Qd2OU.js} +2 -2
- package/dist/{chunk-SHT3W25Y-CMaybO3O.js → chunk-SHT3W25Y-CkOPJgVC.js} +10 -10
- package/dist/{chunk-SVP7TREG-BNBrTAw1.js → chunk-SVP7TREG-rDd35EZ7.js} +3 -3
- package/dist/{chunk-TICWLB2K-DXNxvUJn.js → chunk-TICWLB2K-uKdr5PNy.js} +10 -10
- package/dist/{chunk-XXDRQBXY-Dnl5VBqG.js → chunk-XXDRQBXY-BM-YIt-_.js} +1 -1
- package/dist/{chunk-YOKDWASO-DKplTrBY.js → chunk-YOKDWASO-KxncHymC.js} +153 -378
- package/dist/classDiagram-ZZMXUADV-DctWoMRF.js +30 -0
- package/dist/classDiagram-v2-VYDZK3BY-DyanDjSq.js +30 -0
- package/dist/{clike-CxK9W55Z.js → clike-xU8sCVU1.js} +2 -6
- package/dist/{clojure-Dzcvwpxk.js → clojure-psoSEo36.js} +1 -1
- package/dist/{cmake-DYr-71zp.js → cmake-DDHBwlE7.js} +1 -1
- package/dist/{cobol-DC3g37Kq.js → cobol-C4qjDcIq.js} +1 -1
- package/dist/{code-visibility-891-xGjh.js → code-visibility-Y0zfGGT1.js} +43 -50
- package/dist/{coffeescript-C-eFwH5N.js → coffeescript-D6UgrGgo.js} +1 -1
- package/dist/{common-_IunO2z-.js → common-B_rBSwAA.js} +10624 -10120
- package/dist/{commonlisp-CyaNXrJR.js → commonlisp-B0ChVjnu.js} +1 -1
- package/dist/{compiler-runtime-CldRdSsv.js → compiler-runtime-DNezxW8I.js} +2 -2
- package/dist/config-C4oddKcw.js +633 -0
- package/dist/{copy-icon-BgUO8jsi.js → copy-icon-CVrC6aa6.js} +21 -22
- package/dist/{cose-bilkent-JH36ORCC-_LyRKVqm.js → cose-bilkent-JH36ORCC-B_Oz4vMP.js} +58 -71
- package/dist/createReducer-DzlYBqjn.js +67 -0
- package/dist/{crystal-ih5ax5tQ.js → crystal-DZsc9Ue0.js} +1 -1
- package/dist/{css-CN_wP7_R.js → css-DkYRnQ9U.js} +1 -1
- package/dist/{cubic-OaEBhQPK.js → cubic-CA80xY_e.js} +6 -7
- package/dist/cynefin-OW5HDTMX-0-HehVvH.js +2 -0
- package/dist/{cynefinDiagram-5FMLGOSQ-DWHuKJs8.js → cynefinDiagram-5FMLGOSQ-uEhVcLHR.js} +5 -5
- package/dist/{cypher-CqGRcmZo.js → cypher-CpWPqgvy.js} +1 -1
- package/dist/{cytoscape.esm-jJhXJpLB.js → cytoscape.esm-BbeMznK5.js} +411 -512
- package/dist/{d-Cj0sOW2z.js → d-Bx2ggfYO.js} +1 -1
- package/dist/{dagre-BGSfXNEb.js → dagre-CpjuekF1.js} +550 -700
- package/dist/{dagre-GXQ25YYZ-DYLu-OCU.js → dagre-GXQ25YYZ-B_NBKhOr.js} +14 -16
- package/dist/{data-grid-overlay-editor-TVf1Kaxm.js → data-grid-overlay-editor-04SWN9ol.js} +5 -5
- package/dist/{data-grid-types-0PJ-9N5n.js → data-grid-types-CSElxhxo.js} +1 -1
- package/dist/{debounce-C3jyATpc.js → debounce-DrhhziJv.js} +2 -2
- package/dist/{diagram-S7CK7UJ4-PwwcUOHP.js → diagram-S7CK7UJ4-BQr1iw91.js} +7 -15
- package/dist/{diagram-UQ7AKVKN-CvJbL_IM.js → diagram-UQ7AKVKN-DsAjdQ2j.js} +5 -5
- package/dist/{diagram-VSXAHHWV-BJWcVVJY.js → diagram-VSXAHHWV-CodTjaL3.js} +6 -6
- package/dist/{diagram-VX7I27RA-B5RkqnzN.js → diagram-VX7I27RA-0VAUrHmz.js} +7 -7
- package/dist/{diagram-Z3DM3KII-CyijwTR2.js → diagram-Z3DM3KII-C1aEuADo.js} +5 -5
- package/dist/{dialog-Cc479ZEH.js → dialog-U3stKkkL.js} +36 -36
- package/dist/{diff-B_hUkiat.js → diff-DNXaJS8v.js} +1 -1
- package/dist/{dist-D6d86eNJ.js → dist-B-Id1kt3.js} +48 -47
- package/dist/{dist-DiDibOYr.js → dist-BDw9g6PC.js} +152 -151
- package/dist/{dist-diIx5qJW.js → dist-B_EswY8r.js} +33 -32
- package/dist/{dist-DoE4XJBC.js → dist-B_xgcU0N.js} +9800 -10654
- package/dist/{dist-CLdpGQVr.js → dist-BcGGwW1q.js} +119 -121
- package/dist/dist-BdZQUzPS.js +850 -0
- package/dist/{dist-CN_BeG2I.js → dist-Bj8s59mu.js} +59 -58
- package/dist/{dist-CkTTIdBe.js → dist-C3dYgyiI.js} +337 -337
- package/dist/{dist-PXYI_yuP.js → dist-C6ttp2Iy.js} +24 -23
- package/dist/{dist-DUAh96QY.js → dist-CB9MzCXv.js} +1 -1
- package/dist/{dist-CSbh1PNP.js → dist-CCYz0qJ2.js} +24 -23
- package/dist/{dist-BMQf5zIS.js → dist-CDjivQ67.js} +124 -123
- package/dist/{dist-D-wwqlzJ.js → dist-CNT4u03u.js} +159 -158
- package/dist/{dist-F8Ep36rk.js → dist-DVVzH9mP.js} +60 -59
- package/dist/{dist-OR1OnN-y.js → dist-DlniJvh2.js} +32 -31
- package/dist/{dist-CSJ0MDRw.js → dist-Dq-hanx8.js} +57 -56
- package/dist/{dist-Lm-D-Vr6.js → dist-Du4PgaYp.js} +2 -2
- package/dist/{dist-C8fAKSH1.js → dist-FakvNY2e.js} +54 -53
- package/dist/{dist-BuaRHxOc.js → dist-K-qmZv0f.js} +45 -44
- package/dist/{dist-Cg7gzw-a.js → dist-NPImE_g9.js} +79 -78
- package/dist/{dist-CN8zI-XC.js → dist-PKX4HaX5.js} +239 -239
- package/dist/{dist-CrSP_H1M.js → dist-U4WlxEDL.js} +243 -243
- package/dist/{dist-BK4Oj99o.js → dist-UKKHsqHo.js} +19 -18
- package/dist/{dist-Bvs24R_E.js → dist-VRN9rDqa.js} +32 -31
- package/dist/{dist-BorMD-uX.js → dist-f1h5p-fp.js} +76 -75
- package/dist/{dist-BLfKmR-l.js → dist-h8Te4SvD.js} +17 -16
- package/dist/{dist-DBtSl3sf.js → dist-ymIUQ4tH.js} +48 -50
- package/dist/dropdown-menu-BMtxnyHc.js +5982 -0
- package/dist/{dtd-B8FGSWWe.js → dtd-D1YZQCVT.js} +1 -1
- package/dist/{dylan-DbIBYIrw.js → dylan-CxbG-PUm.js} +2 -2
- package/dist/{ebnfDiagram-PWID7BFC-DG90ELFp.js → ebnfDiagram-PWID7BFC-oBie_-vi.js} +5 -5
- package/dist/{ecl-DBmkdWAd.js → ecl-DIXH6vul.js} +1 -1
- package/dist/{eiffel-CcWSDDzK.js → eiffel-D0de-eQr.js} +1 -1
- package/dist/{elm-MC-b8a6C.js → elm-DrQrn4VD.js} +1 -1
- package/dist/{erDiagram-RLTQ6QDP-FMo_SpyX.js → erDiagram-RLTQ6QDP-DtWDCiaw.js} +14 -14
- package/dist/{erlang-AdO1-xtV.js → erlang-2KpKpfC7.js} +1 -1
- package/dist/{error-banner-CFPHFw4h.js → error-banner-CfIck83X.js} +91 -91
- package/dist/error-entries-CjsQY6ym.js +2581 -0
- package/dist/{esm-G4Fhsgng.js → esm-BUoz9Vvv.js} +4 -4
- package/dist/{esm-AMFssoNp.js → esm-BvhFNYzM.js} +333 -333
- package/dist/{esm-D2gTsXEV.js → esm-wKplZtOX.js} +580 -581
- package/dist/eventmodeling-NTZA5JFV-DoBvB4Lj.js +2 -0
- package/dist/{factor-Ys-13HOP.js → factor-Bwu3ZGOk.js} +1 -1
- package/dist/feedback-button-DoriP8b7.js +370 -0
- package/dist/flowDiagram-HODETNUW-EXK7bg_t.js +15 -0
- package/dist/{formats-DRHUWwSK.js → formats-G0-mQsFy.js} +9 -9
- package/dist/{forth-DiMuIXFe.js → forth-DYatDpr6.js} +2 -3
- package/dist/{fortran-hkrF2eM4.js → fortran-n8mcQPkL.js} +1 -1
- package/dist/{ganttDiagram-EL5Y4UJY-Dh_4cBJZ.js → ganttDiagram-EL5Y4UJY-DyUab7aO.js} +17 -17
- package/dist/{gas-DlhqN9k8.js → gas-BUZOHBVw.js} +1 -1
- package/dist/{gherkin-0SlhEZ3t.js → gherkin-CrSjX26K.js} +1 -1
- package/dist/gitGraph-4MIJSDKK-Ch7kj-d2.js +2 -0
- package/dist/{gitGraphDiagram-WWUBYQGX-D5nSIzdE.js → gitGraphDiagram-WWUBYQGX-BPeDECwG.js} +4 -4
- package/dist/{glide-data-editor-ugYWecYd.js → glide-data-editor-BU_jOTDv.js} +6619 -2875
- package/dist/{glide-utils-pisbYVjH.js → glide-utils-BkcGyXLQ.js} +109 -78
- package/dist/{globals-BdBjL67a.js → globals-DziKJCFY.js} +3 -3
- package/dist/{graphlib-BmY_CCV9.js → graphlib-nlwT3Wvy.js} +177 -220
- package/dist/{groovy-YhcTMyvX.js → groovy-IgGNjeU9.js} +1 -1
- package/dist/hasIn-C20JsQ2m.js +28 -0
- package/dist/{haskell-CodLxrtT.js → haskell-Bs1k3a9s.js} +1 -1
- package/dist/{haxe-CiRWNFkH.js → haxe-CQ8Yb3XF.js} +1 -1
- package/dist/{highlighted-body-KPVGNVTW-3Ziwfz-V.js → highlighted-body-KPVGNVTW-XbLtWlYz.js} +4 -4
- package/dist/{error-entries-CnqKxhU9.js → html-to-image-CIm3PqDi.js} +26032 -26377
- package/dist/{idl-DZgBq75I.js → idl-DjnxoAWx.js} +1 -1
- package/dist/info-A6RAGUB7-DCz_Egh9.js +2 -0
- package/dist/{infoDiagram-27XIBGKW-CRSDtRrd.js → infoDiagram-27XIBGKW-N4ajFTXv.js} +4 -4
- package/dist/isArrayLikeObject-B-HXCsex.js +626 -0
- package/dist/isEmpty-CdX7MTE1.js +14 -0
- package/dist/{ishikawaDiagram-5VMMS53U-DxLEUldB.js → ishikawaDiagram-5VMMS53U-Bb2itmv5.js} +5 -7
- package/dist/{javascript-BfNytHiM.js → javascript-BQtCoAFy.js} +2 -2
- package/dist/{journeyDiagram-3NMN7TZE-BaLqn-dZ.js → journeyDiagram-3NMN7TZE-D7hcb3Vx.js} +4 -4
- package/dist/{jsx-runtime-3BD1kT0s.js → jsx-runtime-6ZiU38At.js} +1 -1
- package/dist/{julia--tLIAG7q.js → julia-BfgtHJE5.js} +1 -1
- package/dist/{kanban-definition-UXKFOSKX-BLhvu8o4.js → kanban-definition-UXKFOSKX-DWfkIEDX.js} +10 -10
- package/dist/{katex-BIdZGsyO.js → katex-BmPSeP5t.js} +15 -24
- package/dist/{linear-DWERh7eI.js → linear-BhKepphY.js} +2 -3
- package/dist/{livescript-CVPfYnY_.js → livescript-gIdRPKtg.js} +1 -1
- package/dist/{loader-BPdQhmlq.js → loader-BIlwkY0d.js} +3 -3
- package/dist/{lua-4Fa-T-qq.js → lua-CxFpWvnv.js} +2 -2
- package/dist/main.js +10380 -8501
- package/dist/{mathematica-CtYAy6GG.js → mathematica-QSveeEoW.js} +1 -1
- package/dist/{mbox-D0w9Ah1C.js → mbox-2JtaCPNT.js} +1 -1
- package/dist/{mermaid-Bjm6C1qN.js → mermaid-BEBd0PHi.js} +170 -176
- package/dist/mermaid-HWGCJPDP-_lKUMvTM.js +1 -0
- package/dist/{mermaid-parser.core-DxuSfYwJ.js → mermaid-parser.core-DtOnl7m4.js} +19 -25
- package/dist/{mhchem-CdWPJK6g.js → mhchem-CjWbCsjZ.js} +1 -1
- package/dist/{micromark-factory-space-DGxAzmw8.js → micromark-factory-space-C5soVmaM.js} +1 -1
- package/dist/{mindmap-definition-YA3MSWOX-g2LwxnYQ.js → mindmap-definition-YA3MSWOX-CmGSiRxU.js} +13 -13
- package/dist/{mirc-De9aSAZM.js → mirc-BqD6ade4.js} +1 -1
- package/dist/{mllike-BbugeaY_.js → mllike-CT0hgEOO.js} +1 -1
- package/dist/{modelica-BjJwWw1F.js → modelica-DKKebcvq.js} +1 -1
- package/dist/{mscgen-DwiRH5ma.js → mscgen-BJCCsWjR.js} +1 -1
- package/dist/{mumps--plbDM9o.js → mumps-DVQAXZkU.js} +1 -1
- package/dist/{nginx-C4Df7REc.js → nginx-AP4LH2NN.js} +1 -1
- package/dist/{node-sql-parser-BiZOJ-FS.js → node-sql-parser-C9dndbfr.js} +7184 -7195
- package/dist/{now-jM8-M7IR.js → now-BKZCLE5P.js} +12 -13
- package/dist/{nsis-fiiOqLc3.js → nsis-Cah9xkdT.js} +1 -1
- package/dist/{ntriples-jV77I4k8.js → ntriples-CQoaLOV6.js} +2 -2
- package/dist/{number-overlay-editor-I4AHjcHG.js → number-overlay-editor-BaZBWVbO.js} +14 -19
- package/dist/{objects-CzUgoMIF.js → objects-DCmMvZtn.js} +1 -3
- package/dist/{octave-Cztd01tF.js → octave-CeDj2bTn.js} +1 -1
- package/dist/{once-BtE-wKRL.js → once-NnpX_HnX.js} +1 -1
- package/dist/{oz-Bl8o3BDl.js → oz-BksQrg3k.js} +1 -1
- package/dist/packet-AYTQ26CC-DEMHgLPq.js +2 -0
- package/dist/{pascal-BO5JqysR.js → pascal-BKL17mpl.js} +1 -1
- package/dist/{pegDiagram-XKGWAZYB-CpMAt3Qs.js → pegDiagram-XKGWAZYB-dXflGNi0.js} +5 -5
- package/dist/pencil-BGy5pfXo.js +10 -0
- package/dist/{perl-Drlh9s6m.js → perl-CacqJ-Ss.js} +1 -1
- package/dist/pick-DgpAbcwP.js +35 -0
- package/dist/pie-WAS4IAKB-DMjTEeHd.js +2 -0
- package/dist/{pieDiagram-E7YTZNPT-CVTthoZo.js → pieDiagram-E7YTZNPT-Bl9G_NNa.js} +7 -7
- package/dist/{pig-BWGR8wZw.js → pig-CXSGZ_K9.js} +1 -1
- package/dist/{powershell-DT99xlz_.js → powershell-DY_yIxBM.js} +3 -6
- package/dist/{process-output-DgQrilBD.js → process-output-DAVapIAQ.js} +5 -5
- package/dist/{properties-Q-rkxld0.js → properties-Om0IDE07.js} +1 -1
- package/dist/{protobuf-DKyWZbs7.js → protobuf-B8nxxb4Q.js} +1 -1
- package/dist/{pug-42ZJUbEC.js → pug-lkUBPvVS.js} +3 -7
- package/dist/{puppet-B4UozHhh.js → puppet-DMkXsi4d.js} +1 -1
- package/dist/purify.es-DmnrIjg4.js +877 -0
- package/dist/{python-DREjAV__.js → python-JQVycMgr.js} +1 -1
- package/dist/{q-Bi63IpBO.js → q-DqE__nNB.js} +1 -1
- package/dist/{quadrantDiagram-AXDQQJYC-Blrm7V7_.js → quadrantDiagram-AXDQQJYC-DLJJzlPi.js} +3 -3
- package/dist/{r-DSwXWKMR.js → r-Cbliap7Q.js} +1 -1
- package/dist/radar-RG4KPBEZ-9PwdCvai.js +2 -0
- package/dist/railroad-74A4TZTK-8N9kF5jl.js +2 -0
- package/dist/railroad-abnf-HS5TGJTU-Sg6YmzlR.js +2 -0
- package/dist/railroad-ebnf-LZEXJU2U-CYwp2Oee.js +2 -0
- package/dist/railroad-peg-WCYAUIDC-BfDkAuQ3.js +2 -0
- package/dist/{railroadDiagram-O6MQD6OU-ao8cqqFB.js → railroadDiagram-O6MQD6OU-Dg7GUHj4.js} +5 -5
- package/dist/{react-sHtZdjeP.js → react-CHbZqgBF.js} +1 -1
- package/dist/{react-dom-DUmH0GXv.js → react-dom-DhWGW7e0.js} +3 -3
- package/dist/{react-vega-BDpbvBCb.js → react-vega-DVr24mNk.js} +8514 -8597
- package/dist/{requirementDiagram-BXWQKSXE--J8vyfm-.js → requirementDiagram-BXWQKSXE-JNZB3XKK.js} +13 -13
- package/dist/{reveal-component-Bb5vzlMs.js → reveal-component-vRQ0ZbEq.js} +1171 -1284
- package/dist/{rolldown-runtime-Cb76FRpK.js → rolldown-runtime-BPCzCO3I.js} +1 -1
- package/dist/{rpm-DPb1DeKM.js → rpm-DmT_LNpE.js} +1 -1
- package/dist/{ruby-U7fZA4DP.js → ruby-BHVZTtLW.js} +1 -1
- package/dist/{sankeyDiagram-P5KCCOFB-ELvOcnZH.js → sankeyDiagram-P5KCCOFB-Bd7wvmbF.js} +2 -2
- package/dist/{sas-CLk1JpTn.js → sas-CrG5N1he.js} +1 -1
- package/dist/{scheme-CT-2k2Tl.js → scheme-BHUnz-IB.js} +1 -1
- package/dist/select-Ba_tMQWZ.js +1200 -0
- package/dist/{semaphore-89jsoHtS.js → semaphore-8KhQouXt.js} +4 -5
- package/dist/{sequenceDiagram-WJ2MYXX4-CiQbn62x.js → sequenceDiagram-WJ2MYXX4-DekbwWOI.js} +6 -6
- package/dist/{shell-BLO7fcsk.js → shell-C5IBmRU5.js} +1 -1
- package/dist/{sieve-nG3C7WNH.js → sieve-BzCnt_E6.js} +2 -2
- package/dist/{sizeCapture-INFHLROL-Dx5SpkQF.js → sizeCapture-INFHLROL-DBeZ20mI.js} +1 -1
- package/dist/{smalltalk-BROcZybA.js → smalltalk-DQFAQul3.js} +1 -1
- package/dist/{solr-mVltHNc5.js → solr-BiapYPCk.js} +1 -1
- package/dist/{sparql-Cv1Ksr4v.js → sparql-BcUKO1is.js} +1 -1
- package/dist/{spec-D_u2ipzF.js → spec-CN3OxHz7.js} +42 -12
- package/dist/{src-CA_m4ONl.js → src-D5uZaZib.js} +8 -14
- package/dist/{stateDiagram-D77RDMKH-DVEeGs5b.js → stateDiagram-D77RDMKH-COzvSaN-.js} +18 -18
- package/dist/stateDiagram-v2-MP3YSRHH-rCvxZ0L8.js +30 -0
- package/dist/static-state-BJdfR8Bn.js +68 -0
- package/dist/{stex-Btf3omL8.js → stex-CQ_aCGTF.js} +1 -1
- package/dist/style.css +1 -1
- package/dist/{stylus-Dt4VvLXL.js → stylus-D4gHF5lg.js} +1 -1
- package/dist/{swift-DHsn_CVI.js → swift-CnvIBnbt.js} +1 -1
- package/dist/{swimlanes-42K2YHIH-CqkGoGqn.js → swimlanes-42K2YHIH-DX2mMlXc.js} +37 -59
- package/dist/swimlanesDiagram-VR7AAH4N-DswSPZ5e.js +30 -0
- package/dist/{swiper-component-DKntyn8p.js → swiper-component-FBPvIqLf.js} +45 -78
- package/dist/{tcl-CV0OLBOl.js → tcl-DkOjjZYO.js} +1 -1
- package/dist/{textile-D320oKVM.js → textile-DgzBVSEW.js} +1 -1
- package/dist/{tiki-BF2aDPlB.js → tiki-MighF8A_.js} +1 -1
- package/dist/{time-BaMbJs4z.js → time-Cc-G3e31.js} +2 -2
- package/dist/{timeline-definition-24CTP7MA-DLRUNVAx.js → timeline-definition-24CTP7MA-DAT9AlwV.js} +5 -5
- package/dist/toast-BRd_eTIj.js +491 -0
- package/dist/{toml-CaUN7UHo.js → toml-B0B7UAba.js} +1 -1
- package/dist/{tooltip-CtBZ5q8p.js → tooltip-CHvXUQVs.js} +326 -302
- package/dist/treeView-Q6P3EWNA-BQywp0E1.js +2 -0
- package/dist/treemap-WGGIJYW6-P2ZJnldw.js +2 -0
- package/dist/{troff-DQUFcClZ.js → troff-B4IRX71y.js} +1 -1
- package/dist/{ttcn-CQL1duJS.js → ttcn-B4tpvdJD.js} +1 -1
- package/dist/{ttcn-cfg-BMmEFJPu.js → ttcn-cfg-pfE-1FV8.js} +1 -1
- package/dist/{turtle-C3esgsRr.js → turtle-Bc97ufp6.js} +1 -1
- package/dist/use-restore-focus-Ckq0jQzc.js +7534 -0
- package/dist/{use-vega-container-remeasure-Bz4PZMtt.js → use-vega-container-remeasure-DFBTESqc.js} +4 -8
- package/dist/{useAsyncData-BneN349z.js → useAsyncData-DMBliR6D.js} +21 -20
- package/dist/{useDateFormatter-DkajGwwd.js → useDateFormatter-CIPe17AG.js} +4 -4
- package/dist/{useDeepCompareMemoize-Z_7R8wTt.js → useDeepCompareMemoize-Kg-7A4b-.js} +3 -3
- package/dist/useEvent-xDnF2X04.js +19 -0
- package/dist/{useIframeCapabilities-DBETvvPl.js → useIframeCapabilities--px_wpZL.js} +2 -2
- package/dist/useLifecycle-BKVRcyGu.js +112 -0
- package/dist/{vb-RK1eDXRl.js → vb-C5kpOY_q.js} +1 -1
- package/dist/{vbscript-BCOeM0de.js → vbscript-Ck0hgOg5.js} +1 -1
- package/dist/{vega-component-1lFfDE_8.js → vega-component-C23pVuni.js} +167 -172
- package/dist/{vega-embed-container-BgKnsDbB.js → vega-embed-container-DAT8OHp9.js} +7 -7
- package/dist/{vega-loader.browser-CpbZAXub.js → vega-loader.browser-Cnf7IHA8.js} +236 -239
- package/dist/{velocity-CZKOFbOI.js → velocity-2Doc6dgJ.js} +1 -1
- package/dist/{vennDiagram-4TSXK5OY-CypgoBVZ.js → vennDiagram-4TSXK5OY-E7CMtY2M.js} +4 -4
- package/dist/{verilog-DqQTzVn8.js → verilog-CmZmYe4R.js} +2 -2
- package/dist/{vhdl-vQr2bfmi.js → vhdl-esMnUHZm.js} +1 -1
- package/dist/wardley-WFR3VGLG-CIBJ6O2G.js +2 -0
- package/dist/{wardleyDiagram-VM6X3IG4-B6xjiQ_g.js → wardleyDiagram-VM6X3IG4-BjtOazpV.js} +5 -5
- package/dist/{webidl-DzX7N40e.js → webidl-G_RlXG7G.js} +1 -1
- package/dist/{xquery-Cw_Q_hGR.js → xquery-IUQpMoMl.js} +1 -1
- package/dist/{xychartDiagram-S5SC5T6Z-e0PefDVs.js → xychartDiagram-S5SC5T6Z-DC09jtph.js} +8 -8
- package/dist/{yacas-DiC4jJBE.js → yacas-ObL0t2h9.js} +1 -1
- package/dist/{z80-CUOQDEJO.js → z80-jyuJhy0k.js} +1 -1
- package/package.json +17 -21
- package/src/__mocks__/document.tsx +63 -0
- package/src/__mocks__/executions.ts +197 -0
- package/src/__mocks__/notebook.ts +3 -7
- package/src/__mocks__/partial.ts +26 -0
- package/src/__mocks__/requests.ts +1 -4
- package/src/__tests__/CellStatus.test.tsx +25 -26
- package/src/__tests__/fixtures/pair-config.ts +1 -1
- package/src/__tests__/main.test.tsx +24 -1
- package/src/__tests__/module-entry.test.ts +44 -0
- package/src/__tests__/mount.test.ts +1 -21
- package/src/__tests__/{host-imports.test.ts → replica-imports.test.ts} +12 -11
- package/src/components/ai/__tests__/ai-model-dropdown.test.tsx +63 -0
- package/src/components/ai/ai-model-dropdown.tsx +11 -6
- package/src/components/app-config/__tests__/state.test.tsx +50 -0
- package/src/components/app-config/ai-config.tsx +156 -150
- package/src/components/app-config/app-config-button.tsx +6 -5
- package/src/components/app-config/app-config-form.tsx +5 -9
- package/src/components/app-config/common.tsx +7 -9
- package/src/components/app-config/data-form.tsx +112 -113
- package/src/components/app-config/mcp-config.tsx +30 -53
- package/src/components/app-config/user-config-form.css +91 -0
- package/src/components/app-config/user-config-form.tsx +266 -349
- package/src/components/chat/__tests__/capabilities-popover.test.tsx +0 -1
- package/src/components/chat/__tests__/chat-display.test.tsx +196 -0
- package/src/components/chat/__tests__/chat-markdown.test.tsx +43 -0
- package/src/components/chat/__tests__/chat-utils.test.ts +93 -1
- package/src/components/chat/__tests__/message-queue.test.tsx +17 -0
- package/src/components/chat/__tests__/notebook-access-selector.test.tsx +64 -0
- package/src/components/chat/__tests__/turn-timing.test.ts +84 -0
- package/src/components/chat/__tests__/use-assistant-turn.test.ts +95 -0
- package/src/components/chat/__tests__/user-message.test.tsx +27 -0
- package/src/components/chat/acp/__tests__/agent-panel-initialization.test.tsx +1 -1
- package/src/components/chat/acp/__tests__/agent-panel.test.tsx +22 -17
- package/src/components/chat/acp/__tests__/session-tabs.test.tsx +43 -0
- package/src/components/chat/acp/__tests__/state.test.ts +2 -2
- package/src/components/chat/acp/agent-panel.tsx +6 -3
- package/src/components/chat/acp/blocks.tsx +13 -12
- package/src/components/chat/acp/common.tsx +4 -5
- package/src/components/chat/acp/model-selector.tsx +1 -1
- package/src/components/chat/acp/session-tabs.tsx +8 -3
- package/src/components/chat/agent-activity.tsx +132 -0
- package/src/components/chat/capabilities-popover.tsx +2 -11
- package/src/components/chat/chat-components.tsx +9 -4
- package/src/components/chat/chat-display.tsx +131 -57
- package/src/components/chat/chat-history-popover.tsx +6 -1
- package/src/components/chat/chat-markdown.tsx +15 -0
- package/src/components/chat/chat-panel.tsx +216 -294
- package/src/components/chat/chat-typography.css +108 -0
- package/src/components/chat/chat-utils.ts +24 -35
- package/src/components/chat/notebook-access-selector.stories.tsx +22 -0
- package/src/components/chat/notebook-access-selector.tsx +100 -0
- package/src/components/chat/tool-call/__tests__/tool-labels.test.ts +76 -0
- package/src/components/chat/tool-call/__tests__/tool-step.test.tsx +57 -0
- package/src/components/chat/tool-call/shared.ts +6 -0
- package/src/components/chat/tool-call/tool-call-view.tsx +22 -76
- package/src/components/chat/tool-call/tool-labels.ts +172 -0
- package/src/components/chat/tool-call/tool-result.tsx +1 -1
- package/src/components/chat/tool-call/tool-step.tsx +145 -0
- package/src/components/chat/turn-timing.ts +73 -0
- package/src/components/chat/use-assistant-turn.ts +65 -0
- package/src/components/chat/use-chat-generation.ts +20 -0
- package/src/components/chat/user-message.tsx +145 -0
- package/src/components/data-table/TableBottomBar.tsx +4 -1
- package/src/components/data-table/TableTopBar.tsx +2 -0
- package/src/components/data-table/__tests__/chart-spec-model.test.ts +195 -195
- package/src/components/data-table/__tests__/column-explorer.test.tsx +27 -1
- package/src/components/data-table/__tests__/columns.test.tsx +105 -0
- package/src/components/data-table/__tests__/context-menu-interaction.test.tsx +130 -0
- package/src/components/data-table/__tests__/data-table.test.tsx +1 -0
- package/src/components/data-table/__tests__/date-popover.test.tsx +72 -0
- package/src/components/data-table/__tests__/export-actions.test.tsx +105 -0
- package/src/components/data-table/__tests__/keyboard-selection.test.tsx +188 -0
- package/src/components/data-table/__tests__/pagination.test.tsx +28 -1
- package/src/components/data-table/__tests__/search-highlight.test.tsx +109 -0
- package/src/components/data-table/__tests__/url-detector.test.tsx +74 -0
- package/src/components/data-table/cell-selection/feature.ts +2 -2
- package/src/components/data-table/cell-selection/types.ts +2 -2
- package/src/components/data-table/charts/__tests__/chart-panel.test.tsx +74 -1
- package/src/components/data-table/charts/__tests__/spec-snapshot.test.ts +20 -20
- package/src/components/data-table/charts/__tests__/spec.test.ts +78 -52
- package/src/components/data-table/charts/__tests__/storage.test.ts +4 -1
- package/src/components/data-table/charts/chart-spec/spec.ts +68 -43
- package/src/components/data-table/charts/charts.tsx +40 -30
- package/src/components/data-table/charts/storage.ts +16 -5
- package/src/components/data-table/column-explorer-panel/column-explorer.tsx +1 -1
- package/src/components/data-table/column-formatting/types.ts +1 -2
- package/src/components/data-table/column-summary/chart-spec-model.tsx +23 -16
- package/src/components/data-table/column-summary/column-summary.tsx +2 -4
- package/src/components/data-table/column-visibility-dropdown.tsx +8 -13
- package/src/components/data-table/columns.tsx +45 -46
- package/src/components/data-table/context-menu.tsx +36 -20
- package/src/components/data-table/data-table.tsx +17 -1
- package/src/components/data-table/date-popover.tsx +6 -4
- package/src/components/data-table/export-actions.tsx +76 -48
- package/src/components/data-table/pagination.tsx +44 -33
- package/src/components/data-table/range-focus/atoms.ts +4 -6
- package/src/components/data-table/range-focus/use-cell-range-selection.ts +65 -38
- package/src/components/data-table/range-focus/use-scroll-into-view.ts +21 -2
- package/src/components/data-table/renderers.tsx +16 -7
- package/src/components/data-table/row-viewer-panel/__tests__/row-viewer.test.tsx +24 -1
- package/src/components/data-table/row-viewer-panel/row-viewer.tsx +4 -4
- package/src/components/data-table/search-highlight.tsx +79 -0
- package/src/components/data-table/types.ts +1 -0
- package/src/components/data-table/url-detector.tsx +49 -9
- package/src/components/datasources/__tests__/column-actions.test.tsx +97 -0
- package/src/components/datasources/__tests__/column-preview.test.tsx +96 -5
- package/src/components/datasources/__tests__/datasources-interactions.test.tsx +181 -0
- package/src/components/datasources/__tests__/table-list.test.tsx +118 -0
- package/src/components/datasources/__tests__/utils.test.ts +57 -6
- package/src/components/datasources/column-preview.tsx +17 -12
- package/src/components/datasources/datasources.tsx +56 -43
- package/src/components/datasources/utils.ts +32 -23
- package/src/components/debugger/debugger-code.tsx +5 -0
- package/src/components/dependency-graph/custom-node.tsx +1 -1
- package/src/components/dependency-graph/dependency-graph-tree.tsx +8 -8
- package/src/components/dependency-graph/elements.ts +24 -21
- package/src/components/dependency-graph/minimap-content.tsx +15 -20
- package/src/components/dependency-graph/panels.tsx +4 -2
- package/src/components/dependency-graph/utils/__tests__/layout.test.ts +18 -11
- package/src/components/editor/SortableCell.tsx +1 -3
- package/src/components/editor/__tests__/Output.test.tsx +50 -32
- package/src/{core/attachments/__tests__/toast.test.tsx → components/editor/__tests__/agent-toast.test.tsx} +1 -1
- package/src/components/editor/__tests__/data-attributes.test.tsx +28 -23
- package/src/components/editor/__tests__/output-persistence.test.tsx +28 -9
- package/src/components/editor/__tests__/package-alert.test.tsx +22 -1
- package/src/components/editor/actions/__tests__/name-cell-input.test.tsx +69 -0
- package/src/components/editor/actions/__tests__/pair-with-agent-commands.test.ts +21 -40
- package/src/components/editor/actions/__tests__/pair-with-agent-modal.test.tsx +41 -14
- package/src/components/editor/actions/__tests__/pair-with-agent.test.tsx +6 -24
- package/src/components/editor/actions/__tests__/useCellActionButton.test.tsx +131 -0
- package/src/components/editor/actions/name-cell-input.tsx +4 -3
- package/src/components/editor/actions/pair-with-agent-commands.ts +10 -7
- package/src/components/editor/actions/pair-with-agent-modal.tsx +29 -30
- package/src/components/editor/actions/pair-with-agent.tsx +16 -39
- package/src/components/editor/actions/useCellActionButton.tsx +47 -35
- package/src/components/editor/actions/useConfigActions.tsx +3 -4
- package/src/components/editor/actions/useNotebookActions.tsx +25 -29
- package/src/components/editor/actions/useRestartKernel.tsx +1 -1
- package/src/components/editor/actions/useSetCodeVisibility.ts +11 -12
- package/src/components/editor/actions/useSetOutputsExpanded.ts +14 -19
- package/src/components/editor/ai/ai-completion-editor.tsx +2 -1
- package/src/components/editor/ai/completion-handlers.tsx +0 -37
- package/src/components/editor/ai/prompt-input.tsx +189 -0
- package/src/components/editor/alerts/__tests__/connection-notice.test.tsx +1 -1
- package/src/components/editor/alerts/connection-notice.tsx +1 -1
- package/src/components/editor/alerts/startup-logs-alert.tsx +1 -0
- package/src/components/editor/alerts/stdin-blocking-alert.tsx +4 -2
- package/src/components/editor/app-container.tsx +1 -1
- package/src/components/editor/boundary/__tests__/ErrorBoundary.test.tsx +1 -1
- package/src/components/editor/cell/CellStatus.tsx +28 -23
- package/src/components/editor/cell/CreateCellButton.tsx +15 -21
- package/src/components/editor/cell/DeleteButton.tsx +3 -2
- package/src/components/editor/cell/RunButton.tsx +18 -8
- package/src/components/editor/cell/StagedAICell.tsx +52 -137
- package/src/components/editor/cell/StopButton.tsx +2 -2
- package/src/components/editor/cell/__tests__/useRunCells.test.tsx +169 -0
- package/src/components/editor/cell/__tests__/useShouldShowInterrupt.test.ts +39 -0
- package/src/components/editor/cell/cell-actions.tsx +12 -1
- package/src/components/editor/cell/cell-context-menu.tsx +4 -1
- package/src/components/editor/cell/code/__tests__/language-toggle.test.tsx +54 -0
- package/src/components/editor/cell/code/cell-editor.tsx +65 -169
- package/src/components/editor/cell/code/language-toggle.tsx +8 -7
- package/src/components/editor/cell/collapse.tsx +16 -6
- package/src/components/editor/cell/useAddCell.ts +4 -8
- package/src/components/editor/cell/useDeleteCell.tsx +10 -36
- package/src/components/editor/cell/useRunCells.ts +49 -8
- package/src/components/editor/cell/useShouldShowInterrupt.ts +2 -12
- package/src/components/editor/cell/useSplitCell.tsx +10 -6
- package/src/components/editor/chrome/components/__tests__/feedback-button.test.tsx +1 -1
- package/src/components/editor/chrome/components/feedback-button.tsx +2 -8
- package/src/components/editor/chrome/panels/__tests__/packages-panel.test.tsx +31 -2
- package/src/components/editor/chrome/panels/__tests__/runtime-details.test.tsx +1 -1
- package/src/components/editor/chrome/panels/__tests__/sandbox-recovery.test.tsx +1 -1
- package/src/components/editor/chrome/panels/cache-panel.tsx +1 -0
- package/src/components/editor/chrome/panels/dependency-graph-panel.tsx +1 -1
- package/src/components/editor/chrome/panels/logs-panel.tsx +2 -1
- package/src/components/editor/chrome/panels/outline/__tests__/outline-keyboard.test.tsx +84 -0
- package/src/components/editor/chrome/panels/outline/floating-outline.tsx +39 -14
- package/src/components/editor/chrome/panels/outline/useActiveOutline.tsx +3 -2
- package/src/components/editor/chrome/panels/packages-panel.tsx +4 -7
- package/src/components/editor/chrome/panels/panel-header.tsx +13 -0
- package/src/components/editor/chrome/panels/secrets-panel.tsx +1 -0
- package/src/components/editor/chrome/panels/session-panel.tsx +1 -1
- package/src/components/editor/chrome/panels/snippets-panel.tsx +10 -12
- package/src/components/editor/chrome/panels/variable-panel.tsx +1 -5
- package/src/components/editor/chrome/types.ts +1 -1
- package/src/components/editor/chrome/wrapper/__tests__/attachment-status.test.tsx +7 -9
- package/src/components/editor/chrome/wrapper/__tests__/document-sync-status.test.tsx +92 -0
- package/src/components/editor/chrome/wrapper/__tests__/pending-ai-cells.test.tsx +265 -37
- package/src/components/editor/chrome/wrapper/__tests__/useAskAiAboutCell.test.tsx +58 -0
- package/src/components/editor/chrome/wrapper/app-chrome.tsx +91 -74
- package/src/components/editor/chrome/wrapper/footer-items/attachment-status.tsx +4 -4
- package/src/components/editor/chrome/wrapper/footer-items/backend-status.tsx +1 -1
- package/src/components/editor/chrome/wrapper/footer-items/document-sync-status.tsx +54 -0
- package/src/components/editor/chrome/wrapper/footer-items/lsp-status.tsx +1 -1
- package/src/components/editor/chrome/wrapper/footer-items/machine-stats.tsx +1 -1
- package/src/components/editor/chrome/wrapper/footer-items/runtime-settings.tsx +1 -7
- package/src/components/editor/chrome/wrapper/footer.tsx +2 -2
- package/src/components/editor/chrome/wrapper/minimap-state.ts +1 -1
- package/src/components/editor/chrome/wrapper/pending-ai-cells.tsx +143 -72
- package/src/components/editor/chrome/wrapper/pending-ai-changes-badge.tsx +25 -0
- package/src/components/editor/chrome/wrapper/sidebar.tsx +8 -4
- package/src/components/editor/chrome/wrapper/storage.ts +1 -1
- package/src/components/editor/chrome/wrapper/useAskAiAboutCell.ts +36 -0
- package/src/components/editor/columns/__tests__/cell-column.test.tsx +1 -1
- package/src/components/editor/columns/cell-column.tsx +1 -1
- package/src/components/editor/columns/sortable-column.tsx +2 -2
- package/src/components/editor/connections/components.tsx +5 -10
- package/src/components/editor/controls/Controls.tsx +4 -4
- package/src/components/editor/controls/__tests__/keyboard-shortcuts.test.tsx +61 -0
- package/src/components/editor/controls/__tests__/notebook-menu-dropdown.test.tsx +10 -4
- package/src/components/editor/controls/keyboard-shortcuts.tsx +14 -5
- package/src/components/editor/documentation.css +34 -11
- package/src/components/editor/errors/__tests__/send-error-report-button.test.tsx +26 -22
- package/src/components/editor/errors/auto-fix.tsx +4 -8
- package/src/components/editor/errors/send-error-report-button.tsx +3 -6
- package/src/components/editor/file-tree/__tests__/file-explorer-interactions.test.tsx +6 -0
- package/src/components/editor/file-tree/__tests__/file-explorer-navigation.test.tsx +47 -0
- package/src/components/editor/file-tree/__tests__/use-file-search.test.tsx +91 -0
- package/src/components/editor/file-tree/file-explorer.tsx +48 -15
- package/src/components/editor/file-tree/file-name-input.tsx +1 -0
- package/src/components/editor/file-tree/file-viewer.tsx +4 -2
- package/src/components/editor/file-tree/use-file-search.ts +35 -21
- package/src/components/editor/header/__tests__/filename-form.test.tsx +1 -4
- package/src/components/editor/header/__tests__/status.test.tsx +5 -3
- package/src/components/editor/header/app-header.tsx +1 -1
- package/src/components/editor/header/filename-form.tsx +1 -1
- package/src/components/editor/header/status.tsx +44 -22
- package/src/components/editor/links/__tests__/cell-link.test.tsx +148 -0
- package/src/components/editor/links/cell-link-list.tsx +1 -1
- package/src/components/editor/links/cell-link.tsx +21 -11
- package/src/components/editor/navigation/__tests__/clipboard.test.ts +60 -38
- package/src/components/editor/navigation/__tests__/navigation.test.ts +108 -85
- package/src/components/editor/navigation/__tests__/selection.test.ts +43 -21
- package/src/components/editor/navigation/clipboard.ts +17 -14
- package/src/components/editor/navigation/focus-utils.ts +23 -4
- package/src/components/editor/navigation/multi-cell-action-toolbar.tsx +17 -33
- package/src/components/editor/navigation/navigation.ts +74 -72
- package/src/components/editor/navigation/selection.ts +30 -29
- package/src/components/editor/notebook-banner.tsx +1 -0
- package/src/components/editor/notebook-cell.tsx +126 -152
- package/src/components/editor/output/MarimoErrorOutput.tsx +41 -4
- package/src/components/editor/output/MarimoTracebackOutput.tsx +19 -17
- package/src/components/editor/output/Outputs.css +8 -0
- package/src/components/editor/output/VideoOutput.tsx +6 -0
- package/src/components/editor/output/__tests__/VideoOutput.test.tsx +131 -0
- package/src/components/editor/output/__tests__/traceback.test.tsx +27 -1
- package/src/components/editor/output/ansi-reduce.ts +33 -20
- package/src/components/editor/output/console/ConsoleOutput.tsx +19 -25
- package/src/components/editor/output/console/__tests__/ConsoleOutput.test.tsx +125 -69
- package/src/components/editor/package-alert.tsx +14 -7
- package/src/components/editor/renderers/__tests__/add-cell-buttons.test.tsx +18 -0
- package/src/components/editor/renderers/cell-array.tsx +32 -100
- package/src/components/editor/renderers/grid-layout/__tests__/grid-layout.test.tsx +75 -0
- package/src/components/editor/renderers/grid-layout/grid-layout.tsx +28 -22
- package/src/components/editor/renderers/slides-layout/__tests__/plugin.test.ts +0 -4
- package/src/components/editor/renderers/slides-layout/slides-layout.tsx +1 -1
- package/src/components/editor/renderers/vertical-layout/__tests__/useFocusFirstEditor.test.ts +4 -4
- package/src/components/editor/renderers/vertical-layout/sidebar/toggle.tsx +7 -1
- package/src/components/editor/renderers/vertical-layout/useFocusFirstEditor.ts +1 -1
- package/src/components/editor/renderers/vertical-layout/vertical-layout.tsx +19 -37
- package/src/components/editor/stdin-blocking-alert.tsx +4 -2
- package/src/components/home/components.tsx +17 -31
- package/src/components/icons/__tests__/large-spinner.test.tsx +39 -0
- package/src/components/icons/large-spinner.tsx +3 -14
- package/src/components/icons/spinner.tsx +1 -1
- package/src/components/markdown/__tests__/markdown-renderer.test.tsx +32 -2
- package/src/components/markdown/markdown-renderer.tsx +43 -28
- package/src/components/mcp/mcp-status-indicator.tsx +18 -14
- package/src/components/pages/__tests__/home-page.test.tsx +116 -0
- package/src/components/pages/edit-page.tsx +19 -17
- package/src/components/pages/home-page.tsx +164 -91
- package/src/components/scratchpad/scratchpad.test.tsx +89 -0
- package/src/components/scratchpad/scratchpad.tsx +47 -33
- package/src/components/scratchpad/state.ts +7 -0
- package/src/components/slides/__tests__/minimap-actions.test.tsx +22 -29
- package/src/components/slides/__tests__/minimap.test.ts +38 -19
- package/src/components/slides/__tests__/slide-scroll-hint.test.tsx +37 -0
- package/src/components/slides/minimap.tsx +22 -14
- package/src/components/slides/reveal-component.tsx +73 -36
- package/src/components/slides/reveal-slides.css +5 -4
- package/src/components/slides/slide-cell-view.tsx +37 -34
- package/src/components/slides/slide-form.tsx +1 -0
- package/src/components/slides/slide-scroll-hint.tsx +3 -1
- package/src/components/slides/slide.tsx +3 -4
- package/src/components/sort/SortableCellsProvider.tsx +8 -25
- package/src/components/tracing/tracing-keyboard.test.tsx +85 -0
- package/src/components/tracing/tracing.tsx +46 -42
- package/src/components/ui/__tests__/draggable-popover.test.tsx +24 -0
- package/src/components/ui/__tests__/fullscreen.test.tsx +44 -2
- package/src/components/ui/__tests__/range-slider.test.tsx +165 -0
- package/src/components/ui/alert-dialog.tsx +1 -1
- package/src/components/ui/draggable-popover.tsx +24 -2
- package/src/components/ui/fullscreen.tsx +25 -1
- package/src/components/ui/range-slider.tsx +22 -9
- package/src/components/ui/toast.tsx +1 -1
- package/src/core/MarimoApp.tsx +3 -1
- package/src/core/ai/__tests__/staged-cells.test.ts +89 -608
- package/src/core/ai/context/context.ts +2 -0
- package/src/core/ai/context/providers/__tests__/cell-output.test.ts +8 -12
- package/src/core/ai/context/providers/__tests__/cell.test.ts +49 -0
- package/src/core/ai/context/providers/cell-output.ts +2 -2
- package/src/core/ai/context/providers/cell.ts +54 -0
- package/src/core/ai/context/providers/datasource.ts +6 -2
- package/src/core/ai/staged-cells.ts +56 -323
- package/src/core/ai/state.ts +3 -0
- package/src/core/ai/tools/__tests__/edit-notebook-tool.test.ts +40 -88
- package/src/core/ai/tools/__tests__/registry.test.ts +17 -0
- package/src/core/ai/tools/base.ts +18 -15
- package/src/core/ai/tools/edit-notebook-tool.ts +86 -80
- package/src/core/ai/tools/registry.ts +13 -10
- package/src/core/ai/tools/sample-tool.ts +6 -7
- package/src/core/cells/__tests__/__snapshots__/cells.test.ts.snap +4 -529
- package/src/core/cells/__tests__/actions.test.ts +623 -35
- package/src/core/cells/__tests__/add-missing-import.test.ts +7 -8
- package/src/core/cells/__tests__/arrange.test.ts +432 -0
- package/src/core/cells/__tests__/cell.test.ts +148 -150
- package/src/core/cells/__tests__/cells.test.ts +390 -2925
- package/src/core/cells/__tests__/collapseConsoleOutputs.test.ts +54 -0
- package/src/core/cells/__tests__/document.test.ts +158 -0
- package/src/core/cells/__tests__/editor.test.ts +57 -0
- package/src/core/cells/__tests__/flush-document.test.ts +40 -0
- package/src/core/cells/__tests__/harness.ts +106 -0
- package/src/core/cells/__tests__/layout.test.ts +176 -0
- package/src/core/cells/__tests__/logs.test.ts +0 -13
- package/src/core/cells/__tests__/notebook-outline.test.ts +23 -14
- package/src/core/cells/__tests__/outputs.test.tsx +71 -53
- package/src/core/cells/__tests__/pending-delete-service.test.tsx +11 -20
- package/src/core/cells/__tests__/session.test.ts +546 -211
- package/src/core/cells/__tests__/utils.test.ts +135 -337
- package/src/core/cells/actions.ts +677 -6
- package/src/core/cells/add-missing-import.ts +47 -43
- package/src/core/cells/arrange.ts +529 -0
- package/src/core/cells/cell.ts +78 -146
- package/src/core/cells/cells.ts +107 -1459
- package/src/core/cells/columns.ts +38 -0
- package/src/core/cells/document.ts +167 -0
- package/src/core/cells/edit.ts +30 -0
- package/src/core/cells/editor.ts +82 -0
- package/src/core/cells/focus.ts +27 -6
- package/src/core/cells/layout.ts +221 -0
- package/src/core/cells/outputs.ts +12 -28
- package/src/core/cells/pending-delete-service.ts +8 -14
- package/src/core/cells/scrollCellIntoView.ts +6 -0
- package/src/core/cells/session.ts +166 -68
- package/src/core/cells/types.ts +21 -51
- package/src/core/cells/utils.ts +85 -87
- package/src/core/codemirror/__tests__/format.test.ts +0 -34
- package/src/core/codemirror/__tests__/setup.test.ts +61 -29
- package/src/core/codemirror/ai/__tests__/resources.test.ts +117 -0
- package/src/core/codemirror/ai/resources.ts +1 -1
- package/src/core/codemirror/cells/__tests__/extensions.test.ts +2 -6
- package/src/core/codemirror/cells/extensions.ts +18 -30
- package/src/core/codemirror/cells/state.ts +2 -6
- package/src/core/codemirror/cm.ts +5 -1
- package/src/core/codemirror/config/types.ts +1 -1
- package/src/core/codemirror/copilot/__tests__/getCodes.test.ts +6 -7
- package/src/core/codemirror/copilot/getCodes.ts +2 -2
- package/src/core/codemirror/format.ts +6 -23
- package/src/core/codemirror/keymaps/vim.ts +4 -8
- package/src/core/codemirror/language/__tests__/sql.test.ts +22 -20
- package/src/core/codemirror/language/__tests__/utils.test.ts +187 -15
- package/src/core/codemirror/language/cell-code.ts +114 -0
- package/src/core/codemirror/language/extension.ts +52 -35
- package/src/core/codemirror/language/languages/markdown.ts +8 -6
- package/src/core/codemirror/language/languages/python.ts +19 -13
- package/src/core/codemirror/language/languages/sql/sql.ts +16 -24
- package/src/core/codemirror/language/panel/panel.tsx +1 -0
- package/src/core/codemirror/language/types.ts +7 -7
- package/src/core/codemirror/language/utils.ts +9 -39
- package/src/core/codemirror/lsp/__tests__/notebook-lsp.test.ts +1 -2
- package/src/core/codemirror/lsp/notebook-lsp.ts +6 -5
- package/src/core/codemirror/lsp/utils.ts +1 -1
- package/src/core/codemirror/misc/__tests__/paste.test.ts +3 -1
- package/src/core/codemirror/misc/paste.ts +1 -1
- package/src/core/codemirror/placeholder/__tests__/extensions.test.ts +75 -0
- package/src/core/codemirror/placeholder/extensions.ts +80 -19
- package/src/core/codemirror/readonly/__tests__/extension.test.ts +1 -1
- package/src/core/codemirror/readonly/extension.ts +2 -2
- package/src/core/codemirror/utils.ts +1 -0
- package/src/core/config/__tests__/app-config.test.ts +64 -0
- package/src/core/config/__tests__/config-schema.test.ts +56 -6
- package/src/core/config/config-schema.ts +17 -4
- package/src/core/config/config.ts +65 -20
- package/src/core/config/feature-flag.tsx +0 -2
- package/src/core/datasets/__tests__/data-source-discovery.test.ts +5 -5
- package/src/core/datasets/data-source-discovery.ts +4 -6
- package/src/core/documentation/doc-lookup.ts +1 -1
- package/src/core/dom/outline.ts +4 -1
- package/src/core/edit-app.tsx +22 -28
- package/src/core/errors/__tests__/error-entries.test.ts +40 -1
- package/src/core/errors/error-entries.ts +6 -4
- package/src/core/executions/__tests__/atoms.test.ts +98 -0
- package/src/core/executions/__tests__/freshness.test.ts +482 -0
- package/src/core/executions/__tests__/hooks.test.tsx +151 -0
- package/src/core/executions/__tests__/output.test.ts +266 -0
- package/src/core/executions/__tests__/select.test.ts +268 -0
- package/src/core/executions/atoms.ts +263 -0
- package/src/core/executions/freshness.ts +171 -0
- package/src/core/executions/hooks.ts +86 -0
- package/src/core/executions/index.ts +48 -0
- package/src/core/executions/output.ts +242 -0
- package/src/core/executions/select.ts +175 -0
- package/src/core/export/__tests__/hooks.test.ts +0 -5
- package/src/core/export/hooks.ts +1 -1
- package/src/core/export/layout.ts +2 -2
- package/src/core/hotkeys/actions.ts +2 -4
- package/src/core/hotkeys/hotkeys.ts +2 -1
- package/src/core/islands/__tests__/bootstrap.test.ts +69 -17
- package/src/core/islands/__tests__/bridge.test.ts +85 -27
- package/src/core/islands/bootstrap.ts +49 -54
- package/src/core/islands/bridge.ts +84 -25
- package/src/core/islands/components/__tests__/IslandControls.test.tsx +7 -5
- package/src/core/islands/components/__tests__/web-components.test.tsx +63 -0
- package/src/core/islands/components/output-wrapper.tsx +5 -5
- package/src/core/islands/components/web-components.tsx +12 -1
- package/src/core/islands/worker/__tests__/controller.test.ts +62 -4
- package/src/core/islands/worker/controller.ts +4 -10
- package/src/core/islands/worker/worker.tsx +33 -33
- package/src/core/kernel/__tests__/RuntimeState.test.ts +1 -1
- package/src/core/kernel/__tests__/handlers.test.ts +7 -157
- package/src/core/kernel/handlers.ts +13 -79
- package/src/core/kernel/state.ts +0 -15
- package/src/core/lifecycle/render-policy.ts +12 -26
- package/src/core/meta/__tests__/code-visibility.test.tsx +78 -70
- package/src/core/meta/code-visibility.ts +18 -9
- package/src/core/network/__tests__/connection.test.ts +1 -1
- package/src/core/network/__tests__/requests-lazy.test.ts +6 -8
- package/src/core/network/connection-notice.ts +1 -1
- package/src/core/network/connection.ts +1 -1
- package/src/core/network/requests-lazy.ts +5 -8
- package/src/core/network/requests-network.ts +5 -31
- package/src/core/network/requests-static.ts +1 -4
- package/src/core/network/requests-toasting.tsx +1 -4
- package/src/core/network/types.ts +6 -14
- package/src/core/network/useConnectionNotice.ts +8 -2
- package/src/core/notebook/__tests__/operations.test.ts +51 -0
- package/src/core/notebook/attachments.ts +38 -0
- package/src/core/notebook/document/__tests__/codemirror.test.ts +759 -0
- package/src/core/notebook/document/__tests__/draft.test.ts +363 -0
- package/src/core/notebook/document/__tests__/fixtures.ts +92 -0
- package/src/core/notebook/document/__tests__/hooks.test.tsx +391 -0
- package/src/core/notebook/document/__tests__/lifecycle-scenarios.test.ts +61 -0
- package/src/core/notebook/document/__tests__/model.test.ts +247 -0
- package/src/core/notebook/document/__tests__/protocol-fixtures.ts +38 -0
- package/src/core/notebook/document/__tests__/recovery-scenarios.test.ts +230 -0
- package/src/core/notebook/document/__tests__/scenario-fixture.ts +43 -0
- package/src/core/notebook/document/__tests__/scenarios.test.ts +205 -0
- package/src/core/notebook/document/__tests__/state.test.ts +459 -0
- package/src/core/notebook/document/__tests__/submission.test.ts +203 -0
- package/src/core/notebook/document/__tests__/test-host.test.ts +92 -0
- package/src/core/notebook/document/__tests__/test-host.ts +247 -0
- package/src/core/notebook/document/__tests__/test-notebook.ts +149 -0
- package/src/core/notebook/document/__tests__/user.ts +61 -0
- package/src/core/notebook/document/codemirror.ts +216 -0
- package/src/core/notebook/document/draft.ts +502 -0
- package/src/core/notebook/document/hooks.tsx +118 -0
- package/src/core/notebook/document/index.ts +24 -0
- package/src/core/notebook/document/model.ts +102 -0
- package/src/core/notebook/document/select.ts +41 -0
- package/src/core/notebook/document/state.ts +378 -0
- package/src/core/notebook/document/sync.ts +369 -0
- package/src/core/notebook/index.ts +19 -0
- package/src/core/notebook/operations.ts +30 -0
- package/src/core/notebook/replica/AGENTS.md +11 -0
- package/src/core/{host → notebook/replica}/__tests__/attachments.test.ts +9 -10
- package/src/core/{host → notebook/replica}/__tests__/document.test.ts +18 -16
- package/src/core/notebook/replica/__tests__/executions.test.ts +200 -0
- package/src/core/notebook/replica/__tests__/fixtures.ts +79 -0
- package/src/core/notebook/replica/__tests__/replica.test.ts +559 -0
- package/src/core/notebook/replica/__tests__/results.test.ts +193 -0
- package/src/core/notebook/replica/__tests__/runtime.test.ts +78 -0
- package/src/core/notebook/replica/backend.ts +19 -0
- package/src/core/notebook/replica/connection.ts +42 -0
- package/src/core/notebook/replica/index.ts +20 -0
- package/src/core/notebook/replica/replica.ts +336 -0
- package/src/core/{host → notebook/replica}/resources/attachments.ts +6 -3
- package/src/core/{host → notebook/replica}/resources/document.ts +3 -3
- package/src/core/notebook/replica/resources/executions.ts +157 -0
- package/src/core/notebook/replica/resources/results.ts +48 -0
- package/src/core/notebook/replica/resources/runtime.ts +14 -0
- package/src/core/packages/__tests__/useSandboxController.test.tsx +1 -1
- package/src/core/packages/useSandboxController.ts +1 -1
- package/src/core/run-app.tsx +49 -51
- package/src/core/runtime/__tests__/adapter.test.ts +4 -4
- package/src/core/runtime/__tests__/createWsUrl.test.ts +77 -7
- package/src/core/runtime/__tests__/runtime.test.ts +32 -74
- package/src/core/runtime/adapter.ts +5 -5
- package/src/core/runtime/config.ts +2 -2
- package/src/core/runtime/runtime.ts +33 -46
- package/src/core/runtime/types.ts +0 -2
- package/src/core/saving/__tests__/document.test.tsx +123 -0
- package/src/core/saving/__tests__/state.test.ts +111 -0
- package/src/core/saving/__tests__/useAutoSave.test.tsx +67 -0
- package/src/core/saving/document.ts +33 -0
- package/src/core/saving/filename.ts +1 -1
- package/src/core/saving/save-component.tsx +39 -60
- package/src/core/saving/state.ts +38 -39
- package/src/core/saving/useAutoSave.ts +17 -53
- package/src/core/session/__tests__/backend.test.ts +236 -0
- package/src/core/session/__tests__/useNotebookReplica.hook.test.tsx +186 -0
- package/src/core/{websocket → session}/__tests__/useNotebookSession.hook.test.tsx +245 -262
- package/src/core/session/active-notebook.ts +28 -0
- package/src/core/session/backend.ts +123 -0
- package/src/core/session/embedded.ts +7 -0
- package/src/core/{websocket → session}/types.ts +2 -2
- package/src/core/session/useNotebookReplica.ts +74 -0
- package/src/core/{websocket → session}/useNotebookSession.tsx +80 -67
- package/src/core/state/__tests__/jotai.test.tsx +108 -0
- package/src/core/state/jotai.ts +1 -1
- package/src/core/static/__tests__/files.test.ts +38 -10
- package/src/core/static/files.ts +2 -0
- package/src/core/{websocket → transports}/__tests__/connection-state.test.ts +1 -13
- package/src/core/transports/__tests__/server.test.ts +408 -0
- package/src/core/transports/__tests__/static.test.ts +340 -0
- package/src/core/transports/__tests__/wasm.test.ts +166 -0
- package/src/core/{websocket → transports}/connection-state.ts +9 -16
- package/src/core/transports/server.ts +152 -0
- package/src/core/transports/static.ts +173 -0
- package/src/core/transports/wasm.ts +97 -0
- package/src/core/vscode/__tests__/vscode-bindings.test.ts +125 -0
- package/src/core/vscode/vscode-bindings.ts +14 -2
- package/src/core/wasm/__tests__/bridge.test.ts +210 -64
- package/src/core/wasm/__tests__/worker.test.ts +188 -0
- package/src/core/wasm/bridge.ts +120 -73
- package/src/core/wasm/rpc.ts +15 -3
- package/src/core/wasm/store.ts +3 -3
- package/src/core/wasm/worker/bootstrap.ts +55 -51
- package/src/core/wasm/worker/getMarimoWheel.ts +1 -1
- package/src/core/wasm/worker/save-worker.ts +9 -10
- package/src/core/wasm/worker/types.ts +30 -18
- package/src/core/wasm/worker/worker.ts +118 -72
- package/src/css/app/Cell.css +7 -36
- package/src/css/app/codemirror.css +1 -1
- package/src/css/common.css +1 -1
- package/src/css/globals.css +72 -24
- package/src/hooks/__tests__/useAsyncData.test.tsx +148 -0
- package/src/hooks/__tests__/useDebounce.test.tsx +51 -0
- package/src/hooks/__tests__/useDeepCompareMemoize.test.tsx +39 -0
- package/src/hooks/__tests__/useDelayElapsed.test.tsx +28 -0
- package/src/hooks/__tests__/useInternalStateWithSync.test.tsx +20 -0
- package/src/hooks/__tests__/useScript.test.tsx +77 -0
- package/src/hooks/__tests__/useStateForKey.test.tsx +257 -0
- package/src/hooks/useAsyncData.ts +3 -3
- package/src/hooks/useDataSourceDiscovery.ts +6 -4
- package/src/hooks/useDebounce.ts +6 -10
- package/src/hooks/useDeepCompareMemoize.ts +1 -1
- package/src/hooks/useDelayElapsed.ts +14 -10
- package/src/hooks/useElapsedTime.ts +3 -3
- package/src/hooks/useEventListener.ts +1 -2
- package/src/hooks/useInputHistory.ts +4 -7
- package/src/hooks/useInternalStateWithSync.ts +6 -6
- package/src/hooks/useResizeObserver.ts +4 -7
- package/src/hooks/useScript.ts +67 -70
- package/src/hooks/useStateForKey.ts +93 -0
- package/src/mount.tsx +20 -15
- package/src/plugins/__tests__/plugin-object-schemas.test.ts +104 -0
- package/src/plugins/core/RenderHTML.tsx +3 -5
- package/src/plugins/core/__test__/PluginSlot.test.tsx +202 -0
- package/src/plugins/core/__test__/RenderHTML-copy.test.tsx +60 -0
- package/src/plugins/core/__test__/registerReactComponent.test.ts +45 -0
- package/src/plugins/core/__test__/sanitize.test.ts +8 -0
- package/src/plugins/core/registerReactComponent.tsx +29 -29
- package/src/plugins/core/sanitize-html.ts +6 -0
- package/src/plugins/impl/CodeEditorPlugin.tsx +1 -1
- package/src/plugins/impl/DataEditorPlugin.tsx +34 -13
- package/src/plugins/impl/DataTablePlugin.tsx +69 -37
- package/src/plugins/impl/DropdownPlugin.tsx +2 -6
- package/src/plugins/impl/FileBrowserPlugin.tsx +4 -16
- package/src/plugins/impl/FormPlugin.tsx +1 -1
- package/src/plugins/impl/RangeSliderPlugin.tsx +16 -2
- package/src/plugins/impl/RefreshPlugin.tsx +1 -0
- package/src/plugins/impl/SliderPlugin.tsx +6 -8
- package/src/plugins/impl/__tests__/DataEditorPlugin.test.ts +93 -4
- package/src/plugins/impl/__tests__/DataTablePlugin.test.tsx +387 -1
- package/src/plugins/impl/__tests__/FileBrowserPlugin.test.tsx +45 -0
- package/src/plugins/impl/__tests__/RangeSliderPlugin.test.tsx +109 -0
- package/src/plugins/impl/__tests__/SliderPlugin.test.tsx +24 -3
- package/src/plugins/impl/anywidget/__tests__/registry.test.ts +153 -0
- package/src/plugins/impl/anywidget/__tests__/widget-binding.test.ts +241 -2
- package/src/plugins/impl/anywidget/model.ts +3 -1
- package/src/plugins/impl/anywidget/registry.ts +18 -14
- package/src/plugins/impl/anywidget/runtime.ts +21 -9
- package/src/plugins/impl/anywidget/widget-binding.ts +160 -82
- package/src/plugins/impl/chat/__tests__/chat-prompts.test.tsx +93 -0
- package/src/plugins/impl/chat/chat-ui.tsx +17 -15
- package/src/plugins/impl/code/any-language-editor.tsx +2 -2
- package/src/plugins/impl/common/error-banner.tsx +5 -3
- package/src/plugins/impl/data-editor/__tests__/column-types.test.ts +42 -0
- package/src/plugins/impl/data-editor/__tests__/editor-state.test.ts +52 -1
- package/src/plugins/impl/data-editor/__tests__/glide-data-editor.test.tsx +120 -4
- package/src/plugins/impl/data-editor/__tests__/glide-utils.test.ts +116 -0
- package/src/plugins/impl/data-editor/column-types.ts +55 -0
- package/src/plugins/impl/data-editor/editor-state.ts +18 -2
- package/src/plugins/impl/data-editor/glide-data-editor.tsx +74 -12
- package/src/plugins/impl/data-editor/glide-utils.ts +39 -38
- package/src/plugins/impl/data-editor/types.ts +5 -0
- package/src/plugins/impl/data-explorer/ConnectedDataExplorerComponent.tsx +1 -1
- package/src/plugins/impl/data-explorer/components/column-summary.tsx +4 -2
- package/src/plugins/impl/data-explorer/state/reducer.ts +1 -1
- package/src/plugins/impl/data-frames/DataFramePlugin.tsx +1 -2
- package/src/plugins/impl/data-frames/__tests__/sidebar.test.tsx +160 -0
- package/src/plugins/impl/data-frames/forms/__tests__/__snapshots__/form.test.tsx.snap +66 -66
- package/src/plugins/impl/data-frames/panel.tsx +44 -16
- package/src/plugins/impl/mpl-interactive/MplInteractivePlugin.tsx +5 -3
- package/src/plugins/impl/panel/PanelPlugin.tsx +16 -17
- package/src/plugins/impl/panel/__tests__/utils.test.ts +39 -1
- package/src/plugins/impl/panel/utils.ts +17 -0
- package/src/plugins/impl/plotly/PlotlyPlugin.tsx +2 -5
- package/src/plugins/impl/plotly/selection.ts +25 -19
- package/src/plugins/impl/vega/VegaPlugin.tsx +2 -3
- package/src/plugins/impl/vega/make-selectable.ts +4 -7
- package/src/plugins/layout/DownloadPlugin.tsx +7 -11
- package/src/plugins/layout/LazyPlugin.tsx +7 -4
- package/src/plugins/layout/RoutesPlugin.tsx +1 -1
- package/src/plugins/layout/__test__/DownloadPlugin.test.tsx +205 -0
- package/src/plugins/layout/__tests__/LazyPlugin.test.tsx +98 -0
- package/src/stories/__tests__/editor-story.test.tsx +33 -0
- package/src/stories/button.stories.tsx +1 -0
- package/src/stories/cell-status.stories.tsx +29 -24
- package/src/stories/cell.stories.tsx +46 -46
- package/src/stories/data-table.stories.tsx +31 -0
- package/src/stories/editor.stories.tsx +24 -17
- package/src/stories/form-wrapper.stories.tsx +2 -2
- package/src/stories/layout/vertical/one-column.stories.tsx +28 -42
- package/src/stories/runtime-story.tsx +23 -17
- package/src/stories/select.stories.tsx +2 -2
- package/src/stories/switchable-multi-select.stories.tsx +1 -1
- package/src/theme/__tests__/islands-theme.test.tsx +276 -0
- package/src/theme/namespace.tsx +4 -3
- package/src/theme/useTheme.ts +71 -41
- package/src/utils/__tests__/arrays.test.ts +35 -0
- package/src/utils/__tests__/batch-requests.test.ts +3 -3
- package/src/utils/__tests__/{createReducer.test.ts → createReducer.test.tsx} +127 -1
- package/src/utils/__tests__/download.test.tsx +183 -23
- package/src/utils/__tests__/numbers.test.ts +105 -1
- package/src/utils/__tests__/objects.test.ts +21 -0
- package/src/utils/arrays.ts +11 -2
- package/src/utils/blob.ts +1 -1
- package/src/utils/createReducer.ts +115 -79
- package/src/utils/download.ts +67 -6
- package/src/utils/maps.ts +0 -3
- package/src/utils/numbers.ts +79 -18
- package/src/utils/objects.ts +4 -9
- package/src/utils/time.ts +10 -0
- package/src/utils/tracer.ts +9 -5
- package/src/utils/zod-utils.ts +1 -3
- package/dist/_baseMerge-BiGRwuqv.js +0 -165
- package/dist/any-language-editor-D4q-IFcM.js +0 -76
- package/dist/architecture-7GRP2DOG-BWLylgiA.js +0 -3
- package/dist/assets/__vite-browser-external-BXYkiFsk.js +0 -1
- package/dist/assets/worker-HPY9fbhz.js +0 -114
- package/dist/classDiagram-ZZMXUADV-DXdCCDOg.js +0 -30
- package/dist/classDiagram-v2-VYDZK3BY-DyZqrtLP.js +0 -30
- package/dist/cynefin-OW5HDTMX-obq-i80l.js +0 -3
- package/dist/dropdown-menu-BuE2b8Yb.js +0 -4678
- package/dist/eventmodeling-NTZA5JFV-D7nP7Uyu.js +0 -3
- package/dist/feedback-button-DlBBr16w.js +0 -379
- package/dist/flowDiagram-HODETNUW-DQ4JuadE.js +0 -16
- package/dist/gitGraph-4MIJSDKK-Dy9uQXGh.js +0 -3
- package/dist/hasIn-o2Us0uVx.js +0 -132
- package/dist/html-to-image-BsG_zyNW.js +0 -3251
- package/dist/info-A6RAGUB7-DKoayiHY.js +0 -3
- package/dist/isArrayLikeObject-BZl-15ir.js +0 -450
- package/dist/isEmpty-BSZ1LaUo.js +0 -35
- package/dist/isSymbol-kQcfYbNX.js +0 -8
- package/dist/label-DoysmLMW.js +0 -281
- package/dist/mermaid-HWGCJPDP-Du3-HPQA.js +0 -2
- package/dist/packet-AYTQ26CC-Yw7ajchJ.js +0 -3
- package/dist/pick-CJeoxYOS.js +0 -51
- package/dist/pie-WAS4IAKB-BKdKOAkL.js +0 -3
- package/dist/purify.es-DMv5zIkJ.js +0 -866
- package/dist/radar-RG4KPBEZ-ScR_D_Ts.js +0 -3
- package/dist/railroad-74A4TZTK-DQvPSdo5.js +0 -3
- package/dist/railroad-abnf-HS5TGJTU-CsJQG2O8.js +0 -3
- package/dist/railroad-ebnf-LZEXJU2U-BgEobkSn.js +0 -3
- package/dist/railroad-peg-WCYAUIDC-DjLAjofI.js +0 -3
- package/dist/select-DemoKT4G.js +0 -1344
- package/dist/stateDiagram-v2-MP3YSRHH-1OQRe6iA.js +0 -30
- package/dist/swimlanesDiagram-VR7AAH4N-CszjkrKo.js +0 -30
- package/dist/toDate-gyi35XS2.js +0 -1185
- package/dist/toast-PkdZraM8.js +0 -1830
- package/dist/treeView-Q6P3EWNA-DuRV97YF.js +0 -3
- package/dist/treemap-WGGIJYW6-AsLq-uwC.js +0 -3
- package/dist/use-restore-focus-CKjfFjLM.js +0 -6369
- package/dist/useLifecycle-Dfq8UD-b.js +0 -169
- package/dist/useTheme-Bu5bBgrh.js +0 -904
- package/dist/wardley-WFR3VGLG-Na-tFhQJ.js +0 -3
- package/src/components/chat/reasoning-accordion.tsx +0 -61
- package/src/components/chat/tool-call/tool-error-card.tsx +0 -81
- package/src/components/chat/tool-call/tool-history-row.tsx +0 -174
- package/src/components/editor/ai/__tests__/staged-cell-submission.test.ts +0 -106
- package/src/components/editor/ai/add-cell-with-ai.tsx +0 -506
- package/src/components/editor/ai/staged-cell-submission.ts +0 -46
- package/src/components/editor/cell/__tests__/StagedAICell.test.tsx +0 -64
- package/src/components/editor/cell/code/__tests__/rtc-editor-config.test.ts +0 -50
- package/src/components/editor/chrome/wrapper/footer-items/rtc-status.tsx +0 -65
- package/src/components/editor/navigation/__tests__/state.test.ts +0 -81
- package/src/components/editor/navigation/state.ts +0 -65
- package/src/components/icons/loading-ellipsis.tsx +0 -46
- package/src/core/ai/tools/__tests__/run-cells-tool.test.ts +0 -656
- package/src/core/ai/tools/run-cells-tool.ts +0 -303
- package/src/core/attachments/state.ts +0 -18
- package/src/core/cells/__tests__/apply-transaction.test.ts +0 -991
- package/src/core/cells/__tests__/document-changes.test.ts +0 -1140
- package/src/core/cells/__tests__/document-roundtrip.test.ts +0 -392
- package/src/core/cells/document-changes.ts +0 -944
- package/src/core/codemirror/rtc/extension.ts +0 -453
- package/src/core/codemirror/rtc/loro/__tests__/sync.test.ts +0 -52
- package/src/core/codemirror/rtc/loro/awareness.ts +0 -531
- package/src/core/codemirror/rtc/loro/colors.ts +0 -38
- package/src/core/codemirror/rtc/loro/sync.ts +0 -168
- package/src/core/host/AGENTS.md +0 -11
- package/src/core/host/__tests__/events.test.ts +0 -46
- package/src/core/host/__tests__/fixtures.ts +0 -39
- package/src/core/host/__tests__/notebook-client.test.ts +0 -433
- package/src/core/host/__tests__/protocol.test.ts +0 -229
- package/src/core/host/__tests__/stream.test.ts +0 -209
- package/src/core/host/connection.ts +0 -81
- package/src/core/host/events.ts +0 -61
- package/src/core/host/notebook-client.ts +0 -290
- package/src/core/host/protocol.ts +0 -1948
- package/src/core/host/resources/resource.ts +0 -47
- package/src/core/host/stream.ts +0 -211
- package/src/core/rtc/state.ts +0 -34
- package/src/core/state/__tests__/jotai.test.ts +0 -25
- package/src/core/wasm/worker/message-buffer.ts +0 -33
- package/src/core/websocket/__tests__/createConnectionTransport.test.ts +0 -49
- package/src/core/websocket/__tests__/useNotebookClient.hook.test.tsx +0 -170
- package/src/core/websocket/state.ts +0 -7
- package/src/core/websocket/transports/__tests__/basic.test.ts +0 -275
- package/src/core/websocket/transports/__tests__/sse.test.ts +0 -335
- package/src/core/websocket/transports/__tests__/transport.test.ts +0 -308
- package/src/core/websocket/transports/__tests__/ws.test.ts +0 -125
- package/src/core/websocket/transports/basic.ts +0 -102
- package/src/core/websocket/transports/create.ts +0 -31
- package/src/core/websocket/transports/sse.ts +0 -308
- package/src/core/websocket/transports/transport.ts +0 -50
- package/src/core/websocket/transports/ws.ts +0 -98
- package/src/core/websocket/useNotebookClient.ts +0 -88
- package/src/utils/__tests__/id-tree.test.ts +0 -2145
- package/src/utils/id-tree.tsx +0 -1134
- /package/src/{core/attachments/toast.ts → components/editor/agent-toast.ts} +0 -0
- /package/src/core/{websocket → session}/connection-utils.ts +0 -0
|
@@ -1,2145 +0,0 @@
|
|
|
1
|
-
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
-
import { beforeEach, describe, expect, it } from "vitest";
|
|
3
|
-
import { SETUP_CELL_ID } from "@/core/cells/ids";
|
|
4
|
-
import {
|
|
5
|
-
type CellColumnId,
|
|
6
|
-
type CellIndex,
|
|
7
|
-
CollapsibleTree,
|
|
8
|
-
MultiColumn,
|
|
9
|
-
} from "../id-tree";
|
|
10
|
-
|
|
11
|
-
let tree: CollapsibleTree<string>;
|
|
12
|
-
|
|
13
|
-
describe("CollapsibleTree", () => {
|
|
14
|
-
beforeEach(() => {
|
|
15
|
-
tree = CollapsibleTree.from(["one", "two", "three", "four"]);
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it("initializes correctly", () => {
|
|
19
|
-
expect(tree.toString()).toMatchInlineSnapshot(`
|
|
20
|
-
"one
|
|
21
|
-
two
|
|
22
|
-
three
|
|
23
|
-
four
|
|
24
|
-
"
|
|
25
|
-
`);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it("collapses nodes correctly with no end", () => {
|
|
29
|
-
const collapsedTree = tree.collapse("two", undefined);
|
|
30
|
-
expect(collapsedTree.nodes[1].isCollapsed).toBe(true);
|
|
31
|
-
expect(collapsedTree.isCollapsed("two")).toBe(true);
|
|
32
|
-
expect(collapsedTree.toString()).toMatchInlineSnapshot(`
|
|
33
|
-
"one
|
|
34
|
-
two (collapsed)
|
|
35
|
-
three
|
|
36
|
-
four
|
|
37
|
-
"
|
|
38
|
-
`);
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it("collapses nodes correctly with an 'until' in the middle", () => {
|
|
42
|
-
const collapsedTree = tree.collapse("two", "three");
|
|
43
|
-
expect(collapsedTree.nodes[1].isCollapsed).toBe(true);
|
|
44
|
-
expect(collapsedTree.toString()).toMatchInlineSnapshot(`
|
|
45
|
-
"one
|
|
46
|
-
two (collapsed)
|
|
47
|
-
three
|
|
48
|
-
four
|
|
49
|
-
"
|
|
50
|
-
`);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it("collapses nodes correctly with an 'until' at the end", () => {
|
|
54
|
-
const collapsedTree = tree.collapse("two", "four");
|
|
55
|
-
expect(collapsedTree.nodes[1].isCollapsed).toBe(true);
|
|
56
|
-
expect(collapsedTree.toString()).toMatchInlineSnapshot(`
|
|
57
|
-
"one
|
|
58
|
-
two (collapsed)
|
|
59
|
-
three
|
|
60
|
-
four
|
|
61
|
-
"
|
|
62
|
-
`);
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it("collapses nodes correctly if just the last node", () => {
|
|
66
|
-
const collapsedTree = tree.collapse("four", undefined);
|
|
67
|
-
expect(collapsedTree.nodes[3].isCollapsed).toBe(true);
|
|
68
|
-
expect(collapsedTree.toString()).toMatchInlineSnapshot(`
|
|
69
|
-
"one
|
|
70
|
-
two
|
|
71
|
-
three
|
|
72
|
-
four (collapsed)
|
|
73
|
-
"
|
|
74
|
-
`);
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it("collapses nodes correctly if just the first node", () => {
|
|
78
|
-
const collapsedTree = tree.collapse("one", undefined);
|
|
79
|
-
expect(collapsedTree.nodes[0].isCollapsed).toBe(true);
|
|
80
|
-
expect(collapsedTree.toString()).toMatchInlineSnapshot(`
|
|
81
|
-
"one (collapsed)
|
|
82
|
-
two
|
|
83
|
-
three
|
|
84
|
-
four
|
|
85
|
-
"
|
|
86
|
-
`);
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
it("can double collapse", () => {
|
|
90
|
-
const collapsedTree = tree
|
|
91
|
-
.collapse("three", undefined)
|
|
92
|
-
.collapse("two", undefined);
|
|
93
|
-
expect(collapsedTree.toString()).toMatchInlineSnapshot(`
|
|
94
|
-
"one
|
|
95
|
-
two (collapsed)
|
|
96
|
-
three (collapsed)
|
|
97
|
-
four
|
|
98
|
-
"
|
|
99
|
-
`);
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it("failures to collapse", () => {
|
|
103
|
-
expect(() =>
|
|
104
|
-
tree.collapse("five", undefined),
|
|
105
|
-
).toThrowErrorMatchingInlineSnapshot(
|
|
106
|
-
"[Error: Node five not found in tree. Valid ids: one,two,three,four]",
|
|
107
|
-
);
|
|
108
|
-
expect(() =>
|
|
109
|
-
tree.collapse("one", "five"),
|
|
110
|
-
).toThrowErrorMatchingInlineSnapshot(
|
|
111
|
-
"[Error: Node five not found in tree]",
|
|
112
|
-
);
|
|
113
|
-
expect(() =>
|
|
114
|
-
tree.collapse("two", "one"),
|
|
115
|
-
).toThrowErrorMatchingInlineSnapshot(
|
|
116
|
-
"[Error: Node one is before node two]",
|
|
117
|
-
);
|
|
118
|
-
expect(() => {
|
|
119
|
-
tree = tree.collapse("two", undefined);
|
|
120
|
-
tree = tree.collapse("two", undefined);
|
|
121
|
-
}).toThrowErrorMatchingInlineSnapshot(
|
|
122
|
-
"[Error: Node two is already collapsed]",
|
|
123
|
-
);
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
it("collapses all nodes from leaves to root in one call", () => {
|
|
127
|
-
const collapsedTree = tree.collapseAll([
|
|
128
|
-
{ id: "one", until: undefined },
|
|
129
|
-
{ id: "two", until: undefined },
|
|
130
|
-
{ id: "three", until: undefined },
|
|
131
|
-
{ id: "four", until: undefined },
|
|
132
|
-
]);
|
|
133
|
-
expect(collapsedTree.toString()).toMatchInlineSnapshot(`
|
|
134
|
-
"one (collapsed)
|
|
135
|
-
two (collapsed)
|
|
136
|
-
three (collapsed)
|
|
137
|
-
four (collapsed)
|
|
138
|
-
"
|
|
139
|
-
`);
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
it("collapses some nodes from leaves to root in one call", () => {
|
|
143
|
-
const collapsedTree = tree.collapseAll([
|
|
144
|
-
{ id: "one", until: undefined },
|
|
145
|
-
null,
|
|
146
|
-
{ id: "three", until: "four" },
|
|
147
|
-
null,
|
|
148
|
-
]);
|
|
149
|
-
expect(collapsedTree.toString()).toMatchInlineSnapshot(`
|
|
150
|
-
"one (collapsed)
|
|
151
|
-
two
|
|
152
|
-
three (collapsed)
|
|
153
|
-
four
|
|
154
|
-
"
|
|
155
|
-
`);
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
it("failures to collapse all", () => {
|
|
159
|
-
expect(() => tree.collapseAll([])).toThrowErrorMatchingInlineSnapshot(
|
|
160
|
-
"[Error: No collapse ranges provided]",
|
|
161
|
-
);
|
|
162
|
-
expect(() =>
|
|
163
|
-
tree.collapseAll([
|
|
164
|
-
{ id: "one", until: undefined },
|
|
165
|
-
{ id: "two", until: undefined },
|
|
166
|
-
]),
|
|
167
|
-
).toThrowErrorMatchingInlineSnapshot(
|
|
168
|
-
"[Error: Collapse ranges length 2 does not match tree length 4]",
|
|
169
|
-
);
|
|
170
|
-
expect(() =>
|
|
171
|
-
tree.collapseAll([null, { id: "one", until: undefined }, null, null]),
|
|
172
|
-
).toThrowErrorMatchingInlineSnapshot(
|
|
173
|
-
"[Error: Node two does not match collapse range id one]",
|
|
174
|
-
);
|
|
175
|
-
expect(() =>
|
|
176
|
-
tree.collapseAll([{ id: "one", until: "five" }, null, null, null]),
|
|
177
|
-
).toThrowErrorMatchingInlineSnapshot(
|
|
178
|
-
"[Error: Node five not found in tree]",
|
|
179
|
-
);
|
|
180
|
-
expect(() =>
|
|
181
|
-
tree.collapseAll([null, { id: "two", until: "one" }, null, null]),
|
|
182
|
-
).toThrowErrorMatchingInlineSnapshot(
|
|
183
|
-
"[Error: Node one is before node two]",
|
|
184
|
-
);
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
it("expands nodes correctly", () => {
|
|
188
|
-
const collapsed = tree.collapse("two", undefined);
|
|
189
|
-
expect(collapsed.nodes[1].isCollapsed).toBe(true);
|
|
190
|
-
const expandedTree = collapsed.expand("two");
|
|
191
|
-
expect(expandedTree.nodes[1].isCollapsed).toBe(false);
|
|
192
|
-
expect(expandedTree.toString()).toMatchInlineSnapshot(`
|
|
193
|
-
"one
|
|
194
|
-
two
|
|
195
|
-
three
|
|
196
|
-
four
|
|
197
|
-
"
|
|
198
|
-
`);
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
it("expands all nested collapsed nodes correctly in one call", () => {
|
|
202
|
-
let collapsed = tree.collapse("three", undefined);
|
|
203
|
-
expect(collapsed.nodes[2].isCollapsed).toBe(true);
|
|
204
|
-
collapsed = collapsed.collapse("two", undefined);
|
|
205
|
-
expect(collapsed.nodes[1].isCollapsed).toBe(true);
|
|
206
|
-
const expandedTree = collapsed.expandAll();
|
|
207
|
-
expect(expandedTree.nodes[1].isCollapsed).toBe(false);
|
|
208
|
-
expect(expandedTree.toString()).toMatchInlineSnapshot(`
|
|
209
|
-
"one
|
|
210
|
-
two
|
|
211
|
-
three
|
|
212
|
-
four
|
|
213
|
-
"
|
|
214
|
-
`);
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
it("fails to expand when node not found", () => {
|
|
218
|
-
expect(() => tree.expand("five")).toThrowErrorMatchingInlineSnapshot(
|
|
219
|
-
"[Error: Node five not found in tree. Valid ids: one,two,three,four]",
|
|
220
|
-
);
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
it("expand on already expanded node is a no-op", () => {
|
|
224
|
-
// Expanding an already expanded node should return the same tree (no-op)
|
|
225
|
-
const result = tree.expand("one");
|
|
226
|
-
expect(result).toBe(tree);
|
|
227
|
-
// Can call multiple times without error
|
|
228
|
-
const result2 = tree.expand("one");
|
|
229
|
-
expect(result2).toBe(tree);
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
it("moves nodes correctly", () => {
|
|
233
|
-
const movedTree = tree.move(0, 1);
|
|
234
|
-
expect(movedTree.toString()).toMatchInlineSnapshot(`
|
|
235
|
-
"two
|
|
236
|
-
one
|
|
237
|
-
three
|
|
238
|
-
four
|
|
239
|
-
"
|
|
240
|
-
`);
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
it("moves a collapsed node correctly", () => {
|
|
244
|
-
const collapsed = tree.collapse("two", "three");
|
|
245
|
-
expect(collapsed.toString()).toMatchInlineSnapshot(`
|
|
246
|
-
"one
|
|
247
|
-
two (collapsed)
|
|
248
|
-
three
|
|
249
|
-
four
|
|
250
|
-
"
|
|
251
|
-
`);
|
|
252
|
-
const movedTree = collapsed.move(1, 2);
|
|
253
|
-
expect(movedTree.toString()).toMatchInlineSnapshot(`
|
|
254
|
-
"one
|
|
255
|
-
four
|
|
256
|
-
two (collapsed)
|
|
257
|
-
three
|
|
258
|
-
"
|
|
259
|
-
`);
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
it("inserts nodes correctly", () => {
|
|
263
|
-
tree = tree.insert("newNode", 1);
|
|
264
|
-
expect(tree.toString()).toMatchInlineSnapshot(`
|
|
265
|
-
"one
|
|
266
|
-
newNode
|
|
267
|
-
two
|
|
268
|
-
three
|
|
269
|
-
four
|
|
270
|
-
"
|
|
271
|
-
`);
|
|
272
|
-
|
|
273
|
-
tree = tree.insert("newNode2", tree.length - 1);
|
|
274
|
-
expect(tree.toString()).toMatchInlineSnapshot(`
|
|
275
|
-
"one
|
|
276
|
-
newNode
|
|
277
|
-
two
|
|
278
|
-
three
|
|
279
|
-
newNode2
|
|
280
|
-
four
|
|
281
|
-
"
|
|
282
|
-
`);
|
|
283
|
-
|
|
284
|
-
tree = tree.insert("newNode3", 10_000);
|
|
285
|
-
expect(tree.toString()).toMatchInlineSnapshot(`
|
|
286
|
-
"one
|
|
287
|
-
newNode
|
|
288
|
-
two
|
|
289
|
-
three
|
|
290
|
-
newNode2
|
|
291
|
-
four
|
|
292
|
-
newNode3
|
|
293
|
-
"
|
|
294
|
-
`);
|
|
295
|
-
});
|
|
296
|
-
|
|
297
|
-
it("counts children correctly", () => {
|
|
298
|
-
expect(tree.getCount("who")).toBe(0);
|
|
299
|
-
expect(tree.getCount("one")).toBe(0);
|
|
300
|
-
// Collapse three and get count
|
|
301
|
-
tree = tree.collapse("three", undefined);
|
|
302
|
-
expect(tree.getCount("three")).toBe(1);
|
|
303
|
-
// Collapse two and get count
|
|
304
|
-
tree = tree.collapse("two", undefined);
|
|
305
|
-
expect(tree.getCount("two")).toBe(2);
|
|
306
|
-
});
|
|
307
|
-
|
|
308
|
-
it("finds deep correctly", () => {
|
|
309
|
-
expect(tree.find("three")).toEqual(["three"]);
|
|
310
|
-
tree = tree.collapse("three", undefined).collapse("two", undefined);
|
|
311
|
-
expect(tree.find("three")).toEqual(["two", "three"]);
|
|
312
|
-
expect(tree.find("four")).toEqual(["two", "three", "four"]);
|
|
313
|
-
expect(tree.toString()).toMatchInlineSnapshot(`
|
|
314
|
-
"one
|
|
315
|
-
two (collapsed)
|
|
316
|
-
three (collapsed)
|
|
317
|
-
four
|
|
318
|
-
"
|
|
319
|
-
`);
|
|
320
|
-
});
|
|
321
|
-
|
|
322
|
-
it("finds and expands correctly at a leaf", () => {
|
|
323
|
-
tree = tree.collapse("three", undefined).collapse("two", undefined);
|
|
324
|
-
expect(tree.toString()).toMatchInlineSnapshot(`
|
|
325
|
-
"one
|
|
326
|
-
two (collapsed)
|
|
327
|
-
three (collapsed)
|
|
328
|
-
four
|
|
329
|
-
"
|
|
330
|
-
`);
|
|
331
|
-
const prevTree = tree;
|
|
332
|
-
tree = tree.findAndExpandDeep("four");
|
|
333
|
-
expect(tree.toString()).toMatchInlineSnapshot(`
|
|
334
|
-
"one
|
|
335
|
-
two
|
|
336
|
-
three
|
|
337
|
-
four
|
|
338
|
-
"
|
|
339
|
-
`);
|
|
340
|
-
// doesn't mutate
|
|
341
|
-
expect(prevTree.toString()).not.toEqual(tree.toString());
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
it("finds and expands correctly at a non-leaf", () => {
|
|
345
|
-
tree = tree.collapse("three", undefined).collapse("two", undefined);
|
|
346
|
-
expect(tree.toString()).toMatchInlineSnapshot(`
|
|
347
|
-
"one
|
|
348
|
-
two (collapsed)
|
|
349
|
-
three (collapsed)
|
|
350
|
-
four
|
|
351
|
-
"
|
|
352
|
-
`);
|
|
353
|
-
const prevTree = tree;
|
|
354
|
-
tree = tree.findAndExpandDeep("three");
|
|
355
|
-
expect(tree.toString()).toMatchInlineSnapshot(`
|
|
356
|
-
"one
|
|
357
|
-
two
|
|
358
|
-
three
|
|
359
|
-
four
|
|
360
|
-
"
|
|
361
|
-
`);
|
|
362
|
-
// doesn't mutate
|
|
363
|
-
expect(prevTree.toString()).not.toEqual(tree.toString());
|
|
364
|
-
});
|
|
365
|
-
|
|
366
|
-
it("can delete nodes", () => {
|
|
367
|
-
tree = tree.collapse("three", undefined).collapse("two", undefined);
|
|
368
|
-
expect(tree.toString()).toMatchInlineSnapshot(`
|
|
369
|
-
"one
|
|
370
|
-
two (collapsed)
|
|
371
|
-
three (collapsed)
|
|
372
|
-
four
|
|
373
|
-
"
|
|
374
|
-
`);
|
|
375
|
-
tree = tree.deleteAtIndex(1);
|
|
376
|
-
expect(tree.toString()).toMatchInlineSnapshot(`
|
|
377
|
-
"one
|
|
378
|
-
three (collapsed)
|
|
379
|
-
four
|
|
380
|
-
"
|
|
381
|
-
`);
|
|
382
|
-
});
|
|
383
|
-
|
|
384
|
-
it("can delete non-collapsed nodes without throwing", () => {
|
|
385
|
-
// Deleting a non-collapsed node should not throw
|
|
386
|
-
// (previously this would throw "Node is already expanded" internally)
|
|
387
|
-
const result = tree.deleteAtIndex(1);
|
|
388
|
-
expect(result.toString()).toMatchInlineSnapshot(`
|
|
389
|
-
"one
|
|
390
|
-
three
|
|
391
|
-
four
|
|
392
|
-
"
|
|
393
|
-
`);
|
|
394
|
-
});
|
|
395
|
-
|
|
396
|
-
it("fails to delete nodes", () => {
|
|
397
|
-
expect(() => tree.deleteAtIndex(5)).toThrowErrorMatchingInlineSnapshot(
|
|
398
|
-
"[Error: Node at index 5 not found in tree]",
|
|
399
|
-
);
|
|
400
|
-
});
|
|
401
|
-
|
|
402
|
-
it("top-level ids are correct", () => {
|
|
403
|
-
expect(tree.topLevelIds).toMatchInlineSnapshot(`
|
|
404
|
-
[
|
|
405
|
-
"one",
|
|
406
|
-
"two",
|
|
407
|
-
"three",
|
|
408
|
-
"four",
|
|
409
|
-
]
|
|
410
|
-
`);
|
|
411
|
-
|
|
412
|
-
const collapsed = tree.collapse("two", undefined);
|
|
413
|
-
expect(collapsed.topLevelIds).toMatchInlineSnapshot(`
|
|
414
|
-
[
|
|
415
|
-
"one",
|
|
416
|
-
"two",
|
|
417
|
-
]
|
|
418
|
-
`);
|
|
419
|
-
});
|
|
420
|
-
|
|
421
|
-
it("in order ids are correct", () => {
|
|
422
|
-
expect(tree.inOrderIds).toMatchInlineSnapshot(`
|
|
423
|
-
[
|
|
424
|
-
"one",
|
|
425
|
-
"two",
|
|
426
|
-
"three",
|
|
427
|
-
"four",
|
|
428
|
-
]
|
|
429
|
-
`);
|
|
430
|
-
|
|
431
|
-
const collapsed = tree.collapse("two", undefined);
|
|
432
|
-
|
|
433
|
-
// Not mutable
|
|
434
|
-
expect(tree.inOrderIds).toEqual(tree.inOrderIds);
|
|
435
|
-
|
|
436
|
-
expect(collapsed.inOrderIds).toMatchInlineSnapshot(`
|
|
437
|
-
[
|
|
438
|
-
"one",
|
|
439
|
-
"two",
|
|
440
|
-
"three",
|
|
441
|
-
"four",
|
|
442
|
-
]
|
|
443
|
-
`);
|
|
444
|
-
});
|
|
445
|
-
|
|
446
|
-
it("atOrThrow throws if not found", () => {
|
|
447
|
-
expect(() => tree.atOrThrow(5)).toThrowErrorMatchingInlineSnapshot(
|
|
448
|
-
"[Error: Node at index 5 not found in tree]",
|
|
449
|
-
);
|
|
450
|
-
});
|
|
451
|
-
|
|
452
|
-
it("first and last are correct", () => {
|
|
453
|
-
expect(tree.first()).toBe("one");
|
|
454
|
-
expect(tree.last()).toBe("four");
|
|
455
|
-
});
|
|
456
|
-
|
|
457
|
-
it("length is correct", () => {
|
|
458
|
-
expect(tree.length).toBe(4);
|
|
459
|
-
|
|
460
|
-
const collapsed = tree.collapse("two", undefined);
|
|
461
|
-
expect(collapsed.length).toBe(2);
|
|
462
|
-
});
|
|
463
|
-
|
|
464
|
-
it("moves to front and back correctly", () => {
|
|
465
|
-
tree = tree.collapse("three", undefined).moveToBack("three");
|
|
466
|
-
expect(tree.toString()).toMatchInlineSnapshot(`
|
|
467
|
-
"one
|
|
468
|
-
two
|
|
469
|
-
three (collapsed)
|
|
470
|
-
four
|
|
471
|
-
"
|
|
472
|
-
`);
|
|
473
|
-
|
|
474
|
-
tree = tree.moveToFront("two");
|
|
475
|
-
expect(tree.toString()).toMatchInlineSnapshot(`
|
|
476
|
-
"two
|
|
477
|
-
one
|
|
478
|
-
three (collapsed)
|
|
479
|
-
four
|
|
480
|
-
"
|
|
481
|
-
`);
|
|
482
|
-
});
|
|
483
|
-
|
|
484
|
-
it("getDescendants correctly", () => {
|
|
485
|
-
expect(tree.getDescendants("two")).toEqual([]);
|
|
486
|
-
expect(tree.getDescendants("who")).toEqual([]);
|
|
487
|
-
|
|
488
|
-
tree = tree.collapse("three", undefined).collapse("two", undefined);
|
|
489
|
-
expect(tree.getDescendants("two")).toMatchInlineSnapshot(`
|
|
490
|
-
[
|
|
491
|
-
"three",
|
|
492
|
-
"four",
|
|
493
|
-
]
|
|
494
|
-
`);
|
|
495
|
-
|
|
496
|
-
// We only get descendants of the top level
|
|
497
|
-
expect(tree.getDescendants("three")).toMatchInlineSnapshot("[]");
|
|
498
|
-
});
|
|
499
|
-
|
|
500
|
-
it("handles slice correctly", () => {
|
|
501
|
-
// Normal slice in middle
|
|
502
|
-
expect(tree.slice(1, 3)).toEqual(["two", "three"]);
|
|
503
|
-
|
|
504
|
-
// Slice from beginning
|
|
505
|
-
expect(tree.slice(0, 2)).toEqual(["one", "two"]);
|
|
506
|
-
|
|
507
|
-
// Slice to end
|
|
508
|
-
expect(tree.slice(2, 4)).toEqual(["three", "four"]);
|
|
509
|
-
|
|
510
|
-
// Slice entire array
|
|
511
|
-
expect(tree.slice(0, 4)).toEqual(["one", "two", "three", "four"]);
|
|
512
|
-
|
|
513
|
-
// Slice with out-of-bounds end
|
|
514
|
-
expect(tree.slice(2, 10)).toEqual(["three", "four"]);
|
|
515
|
-
|
|
516
|
-
// Slice with negative start (should work like normal array slice)
|
|
517
|
-
expect(tree.slice(-2, 4)).toEqual(["three", "four"]);
|
|
518
|
-
|
|
519
|
-
// Slice with start > end (should return empty array)
|
|
520
|
-
expect(tree.slice(3, 1)).toEqual([]);
|
|
521
|
-
|
|
522
|
-
// Slice with same start and end
|
|
523
|
-
expect(tree.slice(2, 2)).toEqual([]);
|
|
524
|
-
|
|
525
|
-
// Slice single element
|
|
526
|
-
expect(tree.slice(1, 2)).toEqual(["two"]);
|
|
527
|
-
});
|
|
528
|
-
|
|
529
|
-
it("handles slice with collapsed nodes", () => {
|
|
530
|
-
const collapsed = tree.collapse("two", "three");
|
|
531
|
-
|
|
532
|
-
// Should only return top-level nodes, not descendants
|
|
533
|
-
expect(collapsed.slice(0, 2)).toEqual(["one", "two"]);
|
|
534
|
-
expect(collapsed.slice(1, 3)).toEqual(["two", "four"]);
|
|
535
|
-
});
|
|
536
|
-
|
|
537
|
-
it("handles after correctly", () => {
|
|
538
|
-
// Normal case - get next node
|
|
539
|
-
expect(tree.after("one")).toBe("two");
|
|
540
|
-
expect(tree.after("two")).toBe("three");
|
|
541
|
-
expect(tree.after("three")).toBe("four");
|
|
542
|
-
|
|
543
|
-
// Edge case - last node should return undefined
|
|
544
|
-
expect(tree.after("four")).toBeUndefined();
|
|
545
|
-
|
|
546
|
-
// Edge case - non-existent node should throw
|
|
547
|
-
expect(() => tree.after("nonexistent")).toThrow(
|
|
548
|
-
"Node nonexistent not found in tree. Valid ids: one,two,three,four",
|
|
549
|
-
);
|
|
550
|
-
});
|
|
551
|
-
|
|
552
|
-
it("handles after with collapsed nodes", () => {
|
|
553
|
-
const collapsed = tree.collapse("two", "three");
|
|
554
|
-
|
|
555
|
-
// Should return next top-level node
|
|
556
|
-
expect(collapsed.after("one")).toBe("two");
|
|
557
|
-
expect(collapsed.after("two")).toBe("four");
|
|
558
|
-
expect(collapsed.after("four")).toBeUndefined();
|
|
559
|
-
|
|
560
|
-
// Should throw for collapsed children that aren't top-level
|
|
561
|
-
expect(() => collapsed.after("three")).toThrow(
|
|
562
|
-
"Node three not found in tree. Valid ids: one,two,four",
|
|
563
|
-
);
|
|
564
|
-
});
|
|
565
|
-
|
|
566
|
-
it("handles before correctly", () => {
|
|
567
|
-
// Normal case - get previous node
|
|
568
|
-
expect(tree.before("two")).toBe("one");
|
|
569
|
-
expect(tree.before("three")).toBe("two");
|
|
570
|
-
expect(tree.before("four")).toBe("three");
|
|
571
|
-
|
|
572
|
-
// Edge case - first node should return undefined
|
|
573
|
-
expect(tree.before("one")).toBeUndefined();
|
|
574
|
-
|
|
575
|
-
// Edge case - non-existent node should throw
|
|
576
|
-
expect(() => tree.before("nonexistent")).toThrow(
|
|
577
|
-
"Node nonexistent not found in tree. Valid ids: one,two,three,four",
|
|
578
|
-
);
|
|
579
|
-
});
|
|
580
|
-
|
|
581
|
-
it("handles before with collapsed nodes", () => {
|
|
582
|
-
const collapsed = tree.collapse("two", "three");
|
|
583
|
-
|
|
584
|
-
// Should return previous top-level node
|
|
585
|
-
expect(collapsed.before("two")).toBe("one");
|
|
586
|
-
expect(collapsed.before("four")).toBe("two");
|
|
587
|
-
expect(collapsed.before("one")).toBeUndefined();
|
|
588
|
-
|
|
589
|
-
// Should throw for collapsed children that aren't top-level
|
|
590
|
-
expect(() => collapsed.before("three")).toThrow(
|
|
591
|
-
"Node three not found in tree. Valid ids: one,two,four",
|
|
592
|
-
);
|
|
593
|
-
});
|
|
594
|
-
|
|
595
|
-
it("handles slice on empty tree", () => {
|
|
596
|
-
const emptyTree = CollapsibleTree.from([]);
|
|
597
|
-
expect(emptyTree.slice(0, 1)).toEqual([]);
|
|
598
|
-
expect(emptyTree.slice(0, 0)).toEqual([]);
|
|
599
|
-
});
|
|
600
|
-
|
|
601
|
-
it("handles after/before on single element tree", () => {
|
|
602
|
-
const singleTree = CollapsibleTree.from(["single"]);
|
|
603
|
-
expect(singleTree.after("single")).toBeUndefined();
|
|
604
|
-
expect(singleTree.before("single")).toBeUndefined();
|
|
605
|
-
});
|
|
606
|
-
|
|
607
|
-
it("handles split correctly", () => {
|
|
608
|
-
const [left, right] = tree.split("two");
|
|
609
|
-
expect(left.toString()).toMatchInlineSnapshot(`
|
|
610
|
-
"one
|
|
611
|
-
"
|
|
612
|
-
`);
|
|
613
|
-
expect(right?.toString()).toMatchInlineSnapshot(`
|
|
614
|
-
"two
|
|
615
|
-
three
|
|
616
|
-
four
|
|
617
|
-
"
|
|
618
|
-
`);
|
|
619
|
-
});
|
|
620
|
-
|
|
621
|
-
it("handles split at the beginning", () => {
|
|
622
|
-
const [left, right] = tree.split("one");
|
|
623
|
-
expect(left.toString()).toMatchInlineSnapshot(`
|
|
624
|
-
""
|
|
625
|
-
`);
|
|
626
|
-
expect(right?.toString()).toMatchInlineSnapshot(`
|
|
627
|
-
"one
|
|
628
|
-
two
|
|
629
|
-
three
|
|
630
|
-
four
|
|
631
|
-
"
|
|
632
|
-
`);
|
|
633
|
-
});
|
|
634
|
-
|
|
635
|
-
it("handles split at the end", () => {
|
|
636
|
-
const [left, right] = tree.split("four");
|
|
637
|
-
expect(left.toString()).toMatchInlineSnapshot(`
|
|
638
|
-
"one
|
|
639
|
-
two
|
|
640
|
-
three
|
|
641
|
-
"
|
|
642
|
-
`);
|
|
643
|
-
expect(right?.toString()).toMatchInlineSnapshot(`
|
|
644
|
-
"four
|
|
645
|
-
"
|
|
646
|
-
`);
|
|
647
|
-
});
|
|
648
|
-
|
|
649
|
-
it("throws when splitting on non-existent node", () => {
|
|
650
|
-
expect(() => tree.split("five")).toThrow("Node five not found in tree");
|
|
651
|
-
});
|
|
652
|
-
});
|
|
653
|
-
|
|
654
|
-
describe("CollapsibleTree edge cases", () => {
|
|
655
|
-
let tree: CollapsibleTree<string>;
|
|
656
|
-
|
|
657
|
-
beforeEach(() => {
|
|
658
|
-
tree = CollapsibleTree.from(["A", "B", "C", "D"]);
|
|
659
|
-
});
|
|
660
|
-
|
|
661
|
-
it("handles insert at start and end", () => {
|
|
662
|
-
tree = tree.insertAtStart("Z");
|
|
663
|
-
expect(tree.topLevelIds).toEqual(["Z", "A", "B", "C", "D"]);
|
|
664
|
-
tree = tree.insertAtEnd("Y");
|
|
665
|
-
expect(tree.topLevelIds).toEqual(["Z", "A", "B", "C", "D", "Y"]);
|
|
666
|
-
});
|
|
667
|
-
|
|
668
|
-
it("handles delete with expand", () => {
|
|
669
|
-
tree = tree.collapse("B", "D");
|
|
670
|
-
tree = tree.deleteAtIndex(1);
|
|
671
|
-
expect(tree.topLevelIds).toEqual(["A", "C", "D"]);
|
|
672
|
-
});
|
|
673
|
-
|
|
674
|
-
it("finds nodes correctly", () => {
|
|
675
|
-
tree = tree.collapse("B", "D");
|
|
676
|
-
expect(tree.find("C")).toEqual(["B", "C"]);
|
|
677
|
-
expect(tree.find("E")).toEqual([]);
|
|
678
|
-
});
|
|
679
|
-
|
|
680
|
-
it("handles equality check", () => {
|
|
681
|
-
const tree2 = CollapsibleTree.from(["A", "B", "C", "D"]);
|
|
682
|
-
expect(tree.equals(tree2)).toBe(true);
|
|
683
|
-
tree2.collapse("B", "C");
|
|
684
|
-
expect(tree.equals(tree2)).toBe(true);
|
|
685
|
-
});
|
|
686
|
-
|
|
687
|
-
it("handles getCount correctly", () => {
|
|
688
|
-
tree = tree.collapse("B", "D");
|
|
689
|
-
expect(tree.getCount("A")).toBe(0);
|
|
690
|
-
expect(tree.getCount("B")).toBe(2);
|
|
691
|
-
expect(tree.getCount("C")).toBe(0);
|
|
692
|
-
});
|
|
693
|
-
|
|
694
|
-
it("handles findAndExpandDeep", () => {
|
|
695
|
-
tree = tree.collapse("B", "D");
|
|
696
|
-
tree = tree.findAndExpandDeep("C");
|
|
697
|
-
expect(tree.topLevelIds).toEqual(["A", "B", "C", "D"]);
|
|
698
|
-
});
|
|
699
|
-
|
|
700
|
-
it("handles multiple collapses and expands", () => {
|
|
701
|
-
tree = tree.collapse("B", "C").collapse("A", "D");
|
|
702
|
-
expect(tree.topLevelIds).toEqual(["A"]);
|
|
703
|
-
tree = tree.expand("A").expand("B");
|
|
704
|
-
expect(tree.topLevelIds).toEqual(["A", "B", "C", "D"]);
|
|
705
|
-
});
|
|
706
|
-
|
|
707
|
-
it("handles edge cases for first and last", () => {
|
|
708
|
-
expect(tree.first()).toBe("A");
|
|
709
|
-
expect(tree.last()).toBe("D");
|
|
710
|
-
tree = CollapsibleTree.from([]);
|
|
711
|
-
expect(() => tree.first()).toThrow("Node at index 0 not found in tree");
|
|
712
|
-
expect(() => tree.last()).toThrow("Node at index -1 not found in tree");
|
|
713
|
-
});
|
|
714
|
-
|
|
715
|
-
it("handles inOrderIds with nested structure", () => {
|
|
716
|
-
tree = tree.collapse("B", "C");
|
|
717
|
-
expect(tree.inOrderIds).toEqual(["A", "B", "C", "D"]);
|
|
718
|
-
});
|
|
719
|
-
|
|
720
|
-
it("handles moving within bounds", () => {
|
|
721
|
-
tree = tree.move(0, 2);
|
|
722
|
-
expect(tree.topLevelIds).toEqual(["B", "C", "A", "D"]);
|
|
723
|
-
});
|
|
724
|
-
|
|
725
|
-
it("handles moving out of bounds", () => {
|
|
726
|
-
tree = tree.move(0, 10);
|
|
727
|
-
expect(tree.topLevelIds).toEqual(["B", "C", "D", "A"]);
|
|
728
|
-
});
|
|
729
|
-
});
|
|
730
|
-
|
|
731
|
-
describe("MultiColumn", () => {
|
|
732
|
-
let multiColumn: MultiColumn<string>;
|
|
733
|
-
let columnIds: CellColumnId[];
|
|
734
|
-
|
|
735
|
-
beforeEach(() => {
|
|
736
|
-
multiColumn = MultiColumn.from([
|
|
737
|
-
["A1", "A2", "A3"],
|
|
738
|
-
["B1", "B2"],
|
|
739
|
-
["C1", "C2", "C3", "C4"],
|
|
740
|
-
]);
|
|
741
|
-
|
|
742
|
-
columnIds = multiColumn.getColumns().map((c) => c.id);
|
|
743
|
-
});
|
|
744
|
-
|
|
745
|
-
it("initializes correctly", () => {
|
|
746
|
-
expect(multiColumn.colLength).toBe(3);
|
|
747
|
-
expect(multiColumn.idLength).toBe(9);
|
|
748
|
-
expect(multiColumn.topLevelIds).toEqual([
|
|
749
|
-
["A1", "A2", "A3"],
|
|
750
|
-
["B1", "B2"],
|
|
751
|
-
["C1", "C2", "C3", "C4"],
|
|
752
|
-
]);
|
|
753
|
-
});
|
|
754
|
-
|
|
755
|
-
it("creates from empty array", () => {
|
|
756
|
-
const emptyMultiColumn = MultiColumn.from([]);
|
|
757
|
-
expect(emptyMultiColumn.colLength).toBe(1);
|
|
758
|
-
expect(emptyMultiColumn.idLength).toBe(0);
|
|
759
|
-
expect(emptyMultiColumn.isEmpty()).toBe(true);
|
|
760
|
-
});
|
|
761
|
-
|
|
762
|
-
it("creates from ids and columns", () => {
|
|
763
|
-
const idAndColumns: [string, number | undefined | null][] = [
|
|
764
|
-
["A1", 0],
|
|
765
|
-
["A2", 0],
|
|
766
|
-
["B1", 1],
|
|
767
|
-
["C1", 2],
|
|
768
|
-
["C2", undefined],
|
|
769
|
-
["D1", null],
|
|
770
|
-
["E1", -1],
|
|
771
|
-
];
|
|
772
|
-
const fromIdsAndColumns = MultiColumn.fromIdsAndColumns(idAndColumns);
|
|
773
|
-
expect(fromIdsAndColumns.colLength).toBe(3);
|
|
774
|
-
expect(fromIdsAndColumns.topLevelIds).toEqual([
|
|
775
|
-
["A1", "A2"],
|
|
776
|
-
["B1"],
|
|
777
|
-
["C1", "C2", "D1", "E1"],
|
|
778
|
-
]);
|
|
779
|
-
});
|
|
780
|
-
|
|
781
|
-
it("iterates top-level ids", () => {
|
|
782
|
-
const ids = [...multiColumn.iterateTopLevelIds];
|
|
783
|
-
expect(ids).toEqual(["A1", "A2", "A3", "B1", "B2", "C1", "C2", "C3", "C4"]);
|
|
784
|
-
});
|
|
785
|
-
|
|
786
|
-
it("gets in-order ids", () => {
|
|
787
|
-
expect(multiColumn.inOrderIds).toEqual([
|
|
788
|
-
"A1",
|
|
789
|
-
"A2",
|
|
790
|
-
"A3",
|
|
791
|
-
"B1",
|
|
792
|
-
"B2",
|
|
793
|
-
"C1",
|
|
794
|
-
"C2",
|
|
795
|
-
"C3",
|
|
796
|
-
"C4",
|
|
797
|
-
]);
|
|
798
|
-
});
|
|
799
|
-
|
|
800
|
-
it("checks if it has only one column", () => {
|
|
801
|
-
expect(multiColumn.hasOnlyOneColumn()).toBe(false);
|
|
802
|
-
const singleColumn = MultiColumn.from([["A1", "A2"]]);
|
|
803
|
-
expect(singleColumn.hasOnlyOneColumn()).toBe(true);
|
|
804
|
-
});
|
|
805
|
-
|
|
806
|
-
it("checks if it has only one id", () => {
|
|
807
|
-
expect(multiColumn.hasOnlyOneId()).toBe(false);
|
|
808
|
-
const singleId = MultiColumn.from([["A1"], ["B1"], ["C1"]]);
|
|
809
|
-
expect(singleId.hasOnlyOneId()).toBe(false);
|
|
810
|
-
const singleIdSingleColumn = MultiColumn.from([["A1"]]);
|
|
811
|
-
expect(singleIdSingleColumn.hasOnlyOneId()).toBe(true);
|
|
812
|
-
});
|
|
813
|
-
|
|
814
|
-
it("adds a column", () => {
|
|
815
|
-
const columnId = multiColumn.getColumns()[0].id;
|
|
816
|
-
const newMultiColumn = multiColumn.addColumn(columnId);
|
|
817
|
-
expect(newMultiColumn.colLength).toBe(4);
|
|
818
|
-
expect(newMultiColumn.topLevelIds[1]).toEqual([]);
|
|
819
|
-
});
|
|
820
|
-
|
|
821
|
-
it("inserts a breakpoint", () => {
|
|
822
|
-
const withBreakpoint = multiColumn.insertBreakpoint("C3");
|
|
823
|
-
expect(withBreakpoint.colLength).toBe(4);
|
|
824
|
-
expect(withBreakpoint.topLevelIds).toEqual([
|
|
825
|
-
["A1", "A2", "A3"],
|
|
826
|
-
["B1", "B2"],
|
|
827
|
-
["C1", "C2"],
|
|
828
|
-
["C3", "C4"],
|
|
829
|
-
]);
|
|
830
|
-
});
|
|
831
|
-
|
|
832
|
-
it("deletes a column", () => {
|
|
833
|
-
const withoutBreakpoint = multiColumn.delete(columnIds[1]);
|
|
834
|
-
expect(withoutBreakpoint.colLength).toBe(2);
|
|
835
|
-
expect(withoutBreakpoint.topLevelIds).toEqual([
|
|
836
|
-
["A1", "A2", "A3", "B1", "B2"],
|
|
837
|
-
["C1", "C2", "C3", "C4"],
|
|
838
|
-
]);
|
|
839
|
-
});
|
|
840
|
-
|
|
841
|
-
it("deletes a column with only one column", () => {
|
|
842
|
-
const singleColumn = MultiColumn.from([["A1", "A2"]]);
|
|
843
|
-
const deleted = singleColumn.delete(columnIds[0]);
|
|
844
|
-
expect(deleted.colLength).toBe(1);
|
|
845
|
-
expect(deleted.topLevelIds).toEqual([["A1", "A2"]]);
|
|
846
|
-
});
|
|
847
|
-
|
|
848
|
-
it("deletes the first column", () => {
|
|
849
|
-
const deleted = multiColumn.delete(columnIds[0]);
|
|
850
|
-
expect(deleted.colLength).toBe(2);
|
|
851
|
-
expect(deleted.topLevelIds).toEqual([
|
|
852
|
-
["B1", "B2", "A1", "A2", "A3"],
|
|
853
|
-
["C1", "C2", "C3", "C4"],
|
|
854
|
-
]);
|
|
855
|
-
});
|
|
856
|
-
|
|
857
|
-
it("merges all columns", () => {
|
|
858
|
-
const merged = multiColumn.mergeAllColumns();
|
|
859
|
-
expect(merged.colLength).toBe(1);
|
|
860
|
-
expect(merged.topLevelIds).toEqual([
|
|
861
|
-
["A1", "A2", "A3", "B1", "B2", "C1", "C2", "C3", "C4"],
|
|
862
|
-
]);
|
|
863
|
-
});
|
|
864
|
-
|
|
865
|
-
it("moves within a column", () => {
|
|
866
|
-
const moved = multiColumn.moveWithinColumn(
|
|
867
|
-
columnIds[0],
|
|
868
|
-
0 as CellIndex,
|
|
869
|
-
2 as CellIndex,
|
|
870
|
-
);
|
|
871
|
-
expect(moved.topLevelIds[0]).toEqual(["A2", "A3", "A1"]);
|
|
872
|
-
});
|
|
873
|
-
|
|
874
|
-
it("moves across columns", () => {
|
|
875
|
-
const moved = multiColumn.moveAcrossColumns(
|
|
876
|
-
columnIds[0],
|
|
877
|
-
"A1",
|
|
878
|
-
columnIds[1],
|
|
879
|
-
"B1",
|
|
880
|
-
);
|
|
881
|
-
expect(moved.topLevelIds).toEqual([
|
|
882
|
-
["A2", "A3"],
|
|
883
|
-
["A1", "B1", "B2"],
|
|
884
|
-
["C1", "C2", "C3", "C4"],
|
|
885
|
-
]);
|
|
886
|
-
});
|
|
887
|
-
|
|
888
|
-
it("moves a column", () => {
|
|
889
|
-
const moved = multiColumn.moveColumn(columnIds[0], columnIds[2]);
|
|
890
|
-
expect(moved.topLevelIds).toEqual([
|
|
891
|
-
["B1", "B2"],
|
|
892
|
-
["C1", "C2", "C3", "C4"],
|
|
893
|
-
["A1", "A2", "A3"],
|
|
894
|
-
]);
|
|
895
|
-
});
|
|
896
|
-
|
|
897
|
-
it("moves a column before", () => {
|
|
898
|
-
const moved = multiColumn.moveColumn(columnIds[1], columnIds[0]);
|
|
899
|
-
expect(moved.topLevelIds).toEqual([
|
|
900
|
-
["B1", "B2"],
|
|
901
|
-
["A1", "A2", "A3"],
|
|
902
|
-
["C1", "C2", "C3", "C4"],
|
|
903
|
-
]);
|
|
904
|
-
});
|
|
905
|
-
|
|
906
|
-
it("moves to the left", () => {
|
|
907
|
-
const moved = multiColumn.moveColumn(columnIds[1], "_left_");
|
|
908
|
-
expect(moved.topLevelIds).toEqual([
|
|
909
|
-
["B1", "B2"],
|
|
910
|
-
["A1", "A2", "A3"],
|
|
911
|
-
["C1", "C2", "C3", "C4"],
|
|
912
|
-
]);
|
|
913
|
-
});
|
|
914
|
-
|
|
915
|
-
it("moves to the right", () => {
|
|
916
|
-
const moved = multiColumn.moveColumn(columnIds[1], "_right_");
|
|
917
|
-
expect(moved.topLevelIds).toEqual([
|
|
918
|
-
["A1", "A2", "A3"],
|
|
919
|
-
["C1", "C2", "C3", "C4"],
|
|
920
|
-
["B1", "B2"],
|
|
921
|
-
]);
|
|
922
|
-
});
|
|
923
|
-
|
|
924
|
-
it("moves to a new column", () => {
|
|
925
|
-
const newColumn = multiColumn.moveToNewColumn("B1");
|
|
926
|
-
expect(newColumn.colLength).toBe(4);
|
|
927
|
-
expect(newColumn.topLevelIds).toEqual([
|
|
928
|
-
["A1", "A2", "A3"],
|
|
929
|
-
["B2"],
|
|
930
|
-
["C1", "C2", "C3", "C4"],
|
|
931
|
-
["B1"],
|
|
932
|
-
]);
|
|
933
|
-
});
|
|
934
|
-
|
|
935
|
-
it("gets column with id", () => {
|
|
936
|
-
const column = multiColumn.findWithId("B2");
|
|
937
|
-
expect(multiColumn.indexOf(column)).toBe(1);
|
|
938
|
-
expect(column.topLevelIds).toEqual(["B1", "B2"]);
|
|
939
|
-
});
|
|
940
|
-
|
|
941
|
-
it("transforms by id", () => {
|
|
942
|
-
const transformed = multiColumn.transformWithCellId("B1", (tree) =>
|
|
943
|
-
tree.moveToFront("B2"),
|
|
944
|
-
);
|
|
945
|
-
expect(transformed.topLevelIds[1]).toEqual(["B2", "B1"]);
|
|
946
|
-
});
|
|
947
|
-
|
|
948
|
-
it("transforms all columns", () => {
|
|
949
|
-
const transformed = multiColumn.transformAll((tree) =>
|
|
950
|
-
tree.insertAtStart("NEW"),
|
|
951
|
-
);
|
|
952
|
-
expect(transformed.topLevelIds).toEqual([
|
|
953
|
-
["NEW", "A1", "A2", "A3"],
|
|
954
|
-
["NEW", "B1", "B2"],
|
|
955
|
-
["NEW", "C1", "C2", "C3", "C4"],
|
|
956
|
-
]);
|
|
957
|
-
});
|
|
958
|
-
|
|
959
|
-
it("inserts an id", () => {
|
|
960
|
-
const inserted = multiColumn.insertId("D1", columnIds[1], 1 as CellIndex);
|
|
961
|
-
expect(inserted.topLevelIds[1]).toEqual(["B1", "D1", "B2"]);
|
|
962
|
-
});
|
|
963
|
-
|
|
964
|
-
describe("moveCellsRelativeTo", () => {
|
|
965
|
-
it("moves a single cell before target in same column", () => {
|
|
966
|
-
const moved = multiColumn.moveCellsRelativeTo(["A3"], "A1", "before");
|
|
967
|
-
expect(moved.topLevelIds).toEqual([
|
|
968
|
-
["A3", "A1", "A2"],
|
|
969
|
-
["B1", "B2"],
|
|
970
|
-
["C1", "C2", "C3", "C4"],
|
|
971
|
-
]);
|
|
972
|
-
});
|
|
973
|
-
|
|
974
|
-
it("moves a single cell after target in same column", () => {
|
|
975
|
-
const moved = multiColumn.moveCellsRelativeTo(["A1"], "A3", "after");
|
|
976
|
-
expect(moved.topLevelIds).toEqual([
|
|
977
|
-
["A2", "A3", "A1"],
|
|
978
|
-
["B1", "B2"],
|
|
979
|
-
["C1", "C2", "C3", "C4"],
|
|
980
|
-
]);
|
|
981
|
-
});
|
|
982
|
-
|
|
983
|
-
it("moves multiple cells before target", () => {
|
|
984
|
-
const moved = multiColumn.moveCellsRelativeTo(
|
|
985
|
-
["A1", "A2"],
|
|
986
|
-
"B2",
|
|
987
|
-
"before",
|
|
988
|
-
);
|
|
989
|
-
expect(moved.topLevelIds).toEqual([
|
|
990
|
-
["A3"],
|
|
991
|
-
["B1", "A1", "A2", "B2"],
|
|
992
|
-
["C1", "C2", "C3", "C4"],
|
|
993
|
-
]);
|
|
994
|
-
});
|
|
995
|
-
|
|
996
|
-
it("moves multiple cells after target", () => {
|
|
997
|
-
const moved = multiColumn.moveCellsRelativeTo(
|
|
998
|
-
["A2", "A3"],
|
|
999
|
-
"B1",
|
|
1000
|
-
"after",
|
|
1001
|
-
);
|
|
1002
|
-
expect(moved.topLevelIds).toEqual([
|
|
1003
|
-
["A1"],
|
|
1004
|
-
["B1", "A2", "A3", "B2"],
|
|
1005
|
-
["C1", "C2", "C3", "C4"],
|
|
1006
|
-
]);
|
|
1007
|
-
});
|
|
1008
|
-
|
|
1009
|
-
it("returns same MultiColumn when cellIds is empty", () => {
|
|
1010
|
-
const moved = multiColumn.moveCellsRelativeTo([], "A1", "before");
|
|
1011
|
-
expect(moved).toBe(multiColumn);
|
|
1012
|
-
});
|
|
1013
|
-
|
|
1014
|
-
it("inserts at end when target is among moved cells", () => {
|
|
1015
|
-
const moved = multiColumn.moveCellsRelativeTo(
|
|
1016
|
-
["A1", "A2"],
|
|
1017
|
-
"A2",
|
|
1018
|
-
"after",
|
|
1019
|
-
);
|
|
1020
|
-
// Target A2 was removed; insert at end of column 0
|
|
1021
|
-
expect(moved.topLevelIds).toEqual([
|
|
1022
|
-
["A3", "A1", "A2"],
|
|
1023
|
-
["B1", "B2"],
|
|
1024
|
-
["C1", "C2", "C3", "C4"],
|
|
1025
|
-
]);
|
|
1026
|
-
});
|
|
1027
|
-
|
|
1028
|
-
it("throws when node not found", () => {
|
|
1029
|
-
expect(() =>
|
|
1030
|
-
multiColumn.moveCellsRelativeTo(["Z1"], "A1", "before"),
|
|
1031
|
-
).toThrow("Cell Z1 not found in any column");
|
|
1032
|
-
});
|
|
1033
|
-
});
|
|
1034
|
-
|
|
1035
|
-
it("deletes by id", () => {
|
|
1036
|
-
const deleted = multiColumn.deleteById("B1");
|
|
1037
|
-
expect(deleted.topLevelIds[1]).toEqual(["B2"]);
|
|
1038
|
-
});
|
|
1039
|
-
|
|
1040
|
-
it("compacts", () => {
|
|
1041
|
-
const withEmpty = MultiColumn.from([["A1"], [], ["C1"], []]);
|
|
1042
|
-
const compacted = withEmpty.compact();
|
|
1043
|
-
expect(compacted.colLength).toBe(2);
|
|
1044
|
-
expect(compacted.topLevelIds).toEqual([["A1"], ["C1"]]);
|
|
1045
|
-
});
|
|
1046
|
-
|
|
1047
|
-
it("handles errors", () => {
|
|
1048
|
-
expect(() => multiColumn.findWithId("Z1")).toThrow(
|
|
1049
|
-
"Cell Z1 not found in any column",
|
|
1050
|
-
);
|
|
1051
|
-
expect(multiColumn.colLength).toBeGreaterThan(2);
|
|
1052
|
-
expect(() => multiColumn.delete("123" as CellColumnId)).toThrow(
|
|
1053
|
-
/Column 123 not found/,
|
|
1054
|
-
);
|
|
1055
|
-
});
|
|
1056
|
-
|
|
1057
|
-
it("checks if it's empty", () => {
|
|
1058
|
-
expect(multiColumn.isEmpty()).toBe(false);
|
|
1059
|
-
const emptyMultiColumn = MultiColumn.from([[]]);
|
|
1060
|
-
expect(emptyMultiColumn.isEmpty()).toBe(true);
|
|
1061
|
-
});
|
|
1062
|
-
|
|
1063
|
-
it("gets columns", () => {
|
|
1064
|
-
const columns = multiColumn.getColumns();
|
|
1065
|
-
expect(columns.length).toBe(3);
|
|
1066
|
-
expect(columns[0].topLevelIds).toEqual(["A1", "A2", "A3"]);
|
|
1067
|
-
});
|
|
1068
|
-
|
|
1069
|
-
it("gets index of a column", () => {
|
|
1070
|
-
const column = multiColumn.atOrThrow(1);
|
|
1071
|
-
const index = multiColumn.indexOf(column);
|
|
1072
|
-
expect(index).toBe(1);
|
|
1073
|
-
});
|
|
1074
|
-
|
|
1075
|
-
it("handles at and atOrThrow", () => {
|
|
1076
|
-
expect(multiColumn.at(1)?.topLevelIds).toEqual(["B1", "B2"]);
|
|
1077
|
-
expect(multiColumn.atOrThrow(1).topLevelIds).toEqual(["B1", "B2"]);
|
|
1078
|
-
expect(multiColumn.at(5)).toBeUndefined();
|
|
1079
|
-
expect(() => multiColumn.atOrThrow(5)).toThrow("Column 5 not found");
|
|
1080
|
-
});
|
|
1081
|
-
|
|
1082
|
-
it("handles moving the last item in a column", () => {
|
|
1083
|
-
const multiColumn = MultiColumn.from([["A1", "A2"], ["B1"]]);
|
|
1084
|
-
const columnIds = multiColumn.getColumns().map((c) => c.id);
|
|
1085
|
-
const moved = multiColumn.moveAcrossColumns(
|
|
1086
|
-
columnIds[1],
|
|
1087
|
-
"B1",
|
|
1088
|
-
columnIds[0],
|
|
1089
|
-
"A2",
|
|
1090
|
-
);
|
|
1091
|
-
expect(moved.topLevelIds).toEqual([["A1", "B1", "A2"], []]);
|
|
1092
|
-
expect(moved.colLength).toBe(2);
|
|
1093
|
-
});
|
|
1094
|
-
|
|
1095
|
-
it("handles moving all items from a column", () => {
|
|
1096
|
-
const multiColumn = MultiColumn.from([
|
|
1097
|
-
["A1", "A2"],
|
|
1098
|
-
["B1", "B2"],
|
|
1099
|
-
]);
|
|
1100
|
-
const columnIds = multiColumn.getColumns().map((c) => c.id);
|
|
1101
|
-
let moved = multiColumn.moveAcrossColumns(
|
|
1102
|
-
columnIds[1],
|
|
1103
|
-
"B1",
|
|
1104
|
-
columnIds[0],
|
|
1105
|
-
"A2",
|
|
1106
|
-
);
|
|
1107
|
-
moved = moved.moveAcrossColumns(columnIds[1], "B2", columnIds[0], "A2");
|
|
1108
|
-
expect(moved.topLevelIds).toEqual([["A1", "B1", "B2", "A2"], []]);
|
|
1109
|
-
expect(moved.colLength).toBe(2);
|
|
1110
|
-
});
|
|
1111
|
-
|
|
1112
|
-
it("handles inserting at out-of-bounds indices", () => {
|
|
1113
|
-
const multiColumn = MultiColumn.from([["A1"], ["B1"]]);
|
|
1114
|
-
const columnId = multiColumn.atOrThrow(1).id;
|
|
1115
|
-
const inserted = multiColumn.insertId("C1", columnId, 10 as CellIndex);
|
|
1116
|
-
expect(inserted.topLevelIds).toEqual([["A1"], ["B1", "C1"]]);
|
|
1117
|
-
});
|
|
1118
|
-
|
|
1119
|
-
it("handles collapsing and expanding in multi-column setup", () => {
|
|
1120
|
-
let multiColumn = MultiColumn.from([
|
|
1121
|
-
["A1", "A2", "A3"],
|
|
1122
|
-
["B1", "B2"],
|
|
1123
|
-
]);
|
|
1124
|
-
multiColumn = multiColumn.transformWithCellId("A1", (tree) =>
|
|
1125
|
-
tree.collapse("A1", "A3"),
|
|
1126
|
-
);
|
|
1127
|
-
expect(multiColumn.topLevelIds).toEqual([["A1"], ["B1", "B2"]]);
|
|
1128
|
-
multiColumn = multiColumn.transformWithCellId("A1", (tree) =>
|
|
1129
|
-
tree.expand("A1"),
|
|
1130
|
-
);
|
|
1131
|
-
expect(multiColumn.topLevelIds).toEqual([
|
|
1132
|
-
["A1", "A2", "A3"],
|
|
1133
|
-
["B1", "B2"],
|
|
1134
|
-
]);
|
|
1135
|
-
});
|
|
1136
|
-
|
|
1137
|
-
it("handles moving a column to its own position", () => {
|
|
1138
|
-
const multiColumn = MultiColumn.from([["A1"], ["B1"], ["C1"]]);
|
|
1139
|
-
const moved = multiColumn.moveColumn(columnIds[1], columnIds[1]);
|
|
1140
|
-
expect(moved.topLevelIds).toEqual([["A1"], ["B1"], ["C1"]]);
|
|
1141
|
-
});
|
|
1142
|
-
|
|
1143
|
-
it("handles compacting when all columns are empty", () => {
|
|
1144
|
-
const multiColumn = MultiColumn.from([[], [], []]);
|
|
1145
|
-
const compacted = multiColumn.compact();
|
|
1146
|
-
expect(compacted.colLength).toBe(1);
|
|
1147
|
-
expect(compacted.isEmpty()).toBe(true);
|
|
1148
|
-
});
|
|
1149
|
-
|
|
1150
|
-
it("handles transformById when id is not found", () => {
|
|
1151
|
-
const multiColumn = MultiColumn.from([["A1"], ["B1"]]);
|
|
1152
|
-
const transformed = multiColumn.transformWithCellId("C1", (tree) =>
|
|
1153
|
-
tree.insertAtEnd("C2"),
|
|
1154
|
-
);
|
|
1155
|
-
expect(transformed).toBe(multiColumn);
|
|
1156
|
-
});
|
|
1157
|
-
|
|
1158
|
-
it("handles nested collapses and expands", () => {
|
|
1159
|
-
let multiColumn = MultiColumn.from([["A1", "A2", "A3", "A4", "A5"]]);
|
|
1160
|
-
multiColumn = multiColumn.transformWithCellId("A1", (tree) =>
|
|
1161
|
-
tree.collapse("A2", "A4"),
|
|
1162
|
-
);
|
|
1163
|
-
multiColumn = multiColumn.transformWithCellId("A1", (tree) =>
|
|
1164
|
-
tree.collapse("A1", undefined),
|
|
1165
|
-
);
|
|
1166
|
-
expect(multiColumn.topLevelIds).toEqual([["A1"]]);
|
|
1167
|
-
multiColumn = multiColumn.transformWithCellId("A1", (tree) =>
|
|
1168
|
-
tree.expand("A1"),
|
|
1169
|
-
);
|
|
1170
|
-
expect(multiColumn.topLevelIds).toEqual([["A1", "A2", "A5"]]);
|
|
1171
|
-
multiColumn = multiColumn.transformWithCellId("A1", (tree) =>
|
|
1172
|
-
tree.expand("A2"),
|
|
1173
|
-
);
|
|
1174
|
-
expect(multiColumn.topLevelIds).toEqual([["A1", "A2", "A3", "A4", "A5"]]);
|
|
1175
|
-
});
|
|
1176
|
-
|
|
1177
|
-
it("handles moving to a new column when it's the last item", () => {
|
|
1178
|
-
let multiColumn = MultiColumn.from([["A1"], ["B1"]]);
|
|
1179
|
-
multiColumn = multiColumn.moveToNewColumn("B1");
|
|
1180
|
-
expect(multiColumn.colLength).toBe(3);
|
|
1181
|
-
expect(multiColumn.topLevelIds).toEqual([["A1"], [], ["B1"]]);
|
|
1182
|
-
});
|
|
1183
|
-
|
|
1184
|
-
it("handles deleting the last item in a column", () => {
|
|
1185
|
-
let multiColumn = MultiColumn.from([["A1"], ["B1"], ["C1"]]);
|
|
1186
|
-
multiColumn = multiColumn.deleteById("B1");
|
|
1187
|
-
expect(multiColumn.colLength).toBe(3);
|
|
1188
|
-
expect(multiColumn.topLevelIds).toEqual([["A1"], [], ["C1"]]);
|
|
1189
|
-
});
|
|
1190
|
-
|
|
1191
|
-
it("handles multiple operations in sequence", () => {
|
|
1192
|
-
let multiColumn = MultiColumn.from([
|
|
1193
|
-
["A1", "A2"],
|
|
1194
|
-
["B1", "B2"],
|
|
1195
|
-
["C1", "C2"],
|
|
1196
|
-
]);
|
|
1197
|
-
const columnIds = multiColumn.getColumns().map((c) => c.id);
|
|
1198
|
-
multiColumn = multiColumn.moveAcrossColumns(
|
|
1199
|
-
columnIds[0],
|
|
1200
|
-
"A2",
|
|
1201
|
-
columnIds[1],
|
|
1202
|
-
"B1",
|
|
1203
|
-
);
|
|
1204
|
-
expect(multiColumn.topLevelIds).toEqual([
|
|
1205
|
-
["A1"],
|
|
1206
|
-
["A2", "B1", "B2"],
|
|
1207
|
-
["C1", "C2"],
|
|
1208
|
-
]);
|
|
1209
|
-
multiColumn = multiColumn.insertId("D1", columnIds[2], 1 as CellIndex);
|
|
1210
|
-
expect(multiColumn.topLevelIds).toEqual([
|
|
1211
|
-
["A1"],
|
|
1212
|
-
["A2", "B1", "B2"],
|
|
1213
|
-
["C1", "D1", "C2"],
|
|
1214
|
-
]);
|
|
1215
|
-
multiColumn = multiColumn.deleteById("B1");
|
|
1216
|
-
expect(multiColumn.topLevelIds).toEqual([
|
|
1217
|
-
["A1"],
|
|
1218
|
-
["A2", "B2"],
|
|
1219
|
-
["C1", "D1", "C2"],
|
|
1220
|
-
]);
|
|
1221
|
-
multiColumn = multiColumn.moveColumn(columnIds[0], columnIds[2]);
|
|
1222
|
-
expect(multiColumn.topLevelIds).toEqual([
|
|
1223
|
-
["A2", "B2"],
|
|
1224
|
-
["C1", "D1", "C2"],
|
|
1225
|
-
["A1"],
|
|
1226
|
-
]);
|
|
1227
|
-
multiColumn = multiColumn.compact();
|
|
1228
|
-
expect(multiColumn.topLevelIds).toEqual([
|
|
1229
|
-
["A2", "B2"],
|
|
1230
|
-
["C1", "D1", "C2"],
|
|
1231
|
-
["A1"],
|
|
1232
|
-
]);
|
|
1233
|
-
});
|
|
1234
|
-
|
|
1235
|
-
it("handles setup cell existence", () => {
|
|
1236
|
-
const multiColumn = MultiColumn.from([["A1"], ["B1"], ["C1"]]);
|
|
1237
|
-
const columnIds = multiColumn.getColumnIds();
|
|
1238
|
-
expect(multiColumn.setupCellExists()).toBe(false);
|
|
1239
|
-
const multiColumn2 = multiColumn.insertId(SETUP_CELL_ID, columnIds[0], 0);
|
|
1240
|
-
expect(multiColumn2.setupCellExists()).toBe(true);
|
|
1241
|
-
const multiColumn3 = multiColumn2.deleteById(SETUP_CELL_ID);
|
|
1242
|
-
expect(multiColumn3.setupCellExists()).toBe(false);
|
|
1243
|
-
});
|
|
1244
|
-
|
|
1245
|
-
it("handles get method", () => {
|
|
1246
|
-
const column = multiColumn.get(columnIds[1]);
|
|
1247
|
-
expect(column?.topLevelIds).toEqual(["B1", "B2"]);
|
|
1248
|
-
});
|
|
1249
|
-
|
|
1250
|
-
it("handles get method with non-existent column id", () => {
|
|
1251
|
-
const column = multiColumn.get("non-existent-id" as CellColumnId);
|
|
1252
|
-
expect(column).toBeUndefined();
|
|
1253
|
-
});
|
|
1254
|
-
|
|
1255
|
-
it("handles indexOfOrThrow method", () => {
|
|
1256
|
-
expect(multiColumn.indexOfOrThrow(columnIds[1])).toBe(1);
|
|
1257
|
-
});
|
|
1258
|
-
|
|
1259
|
-
it("handles indexOfOrThrow method with non-existent column id", () => {
|
|
1260
|
-
expect(() =>
|
|
1261
|
-
multiColumn.indexOfOrThrow("non-existent-id" as CellColumnId),
|
|
1262
|
-
).toThrow("Column non-existent-id not found. Possible values: ");
|
|
1263
|
-
});
|
|
1264
|
-
|
|
1265
|
-
it("handles transform method", () => {
|
|
1266
|
-
const transformed = multiColumn.transform(columnIds[1], (tree) =>
|
|
1267
|
-
tree.moveToFront("B2"),
|
|
1268
|
-
);
|
|
1269
|
-
expect(transformed.topLevelIds[1]).toEqual(["B2", "B1"]);
|
|
1270
|
-
});
|
|
1271
|
-
|
|
1272
|
-
it("handles transform method with non-existent column id", () => {
|
|
1273
|
-
const transformed = multiColumn.transform(
|
|
1274
|
-
"non-existent-id" as CellColumnId,
|
|
1275
|
-
(tree) => tree.moveToFront("B2"),
|
|
1276
|
-
);
|
|
1277
|
-
const columns1 = multiColumn.getColumns();
|
|
1278
|
-
const columns2 = transformed.getColumns();
|
|
1279
|
-
const allEqual = columns1.every((c, i) => c.equals(columns2[i]));
|
|
1280
|
-
expect(allEqual).toBe(true);
|
|
1281
|
-
expect(transformed).toBe(multiColumn);
|
|
1282
|
-
});
|
|
1283
|
-
|
|
1284
|
-
it("handles moving across columns with undefined toId", () => {
|
|
1285
|
-
const moved = multiColumn.moveAcrossColumns(
|
|
1286
|
-
columnIds[0],
|
|
1287
|
-
"A1",
|
|
1288
|
-
columnIds[1],
|
|
1289
|
-
undefined,
|
|
1290
|
-
);
|
|
1291
|
-
expect(moved.topLevelIds).toEqual([
|
|
1292
|
-
["A2", "A3"],
|
|
1293
|
-
["A1", "B1", "B2"],
|
|
1294
|
-
["C1", "C2", "C3", "C4"],
|
|
1295
|
-
]);
|
|
1296
|
-
});
|
|
1297
|
-
|
|
1298
|
-
it("handles moving across columns to an empty column", () => {
|
|
1299
|
-
const emptyColumnMultiColumn = multiColumn
|
|
1300
|
-
.deleteById("B1")
|
|
1301
|
-
.deleteById("B2");
|
|
1302
|
-
const moved = emptyColumnMultiColumn.moveAcrossColumns(
|
|
1303
|
-
columnIds[0],
|
|
1304
|
-
"A1",
|
|
1305
|
-
columnIds[1],
|
|
1306
|
-
undefined,
|
|
1307
|
-
);
|
|
1308
|
-
expect(moved.topLevelIds).toEqual([
|
|
1309
|
-
["A2", "A3"],
|
|
1310
|
-
["A1"],
|
|
1311
|
-
["C1", "C2", "C3", "C4"],
|
|
1312
|
-
]);
|
|
1313
|
-
});
|
|
1314
|
-
|
|
1315
|
-
it("handles inserting a breakpoint at the start of a column", () => {
|
|
1316
|
-
const withBreakpoint = multiColumn.insertBreakpoint("A1");
|
|
1317
|
-
expect(withBreakpoint.colLength).toBe(4);
|
|
1318
|
-
expect(withBreakpoint.topLevelIds).toEqual([
|
|
1319
|
-
[],
|
|
1320
|
-
["A1", "A2", "A3"],
|
|
1321
|
-
["B1", "B2"],
|
|
1322
|
-
["C1", "C2", "C3", "C4"],
|
|
1323
|
-
]);
|
|
1324
|
-
});
|
|
1325
|
-
|
|
1326
|
-
it("handles inserting a breakpoint at the end of a column", () => {
|
|
1327
|
-
const withBreakpoint = multiColumn.insertBreakpoint("A3");
|
|
1328
|
-
expect(withBreakpoint.colLength).toBe(4);
|
|
1329
|
-
expect(withBreakpoint.topLevelIds).toEqual([
|
|
1330
|
-
["A1", "A2"],
|
|
1331
|
-
["A3"],
|
|
1332
|
-
["B1", "B2"],
|
|
1333
|
-
["C1", "C2", "C3", "C4"],
|
|
1334
|
-
]);
|
|
1335
|
-
});
|
|
1336
|
-
|
|
1337
|
-
it("handles inserting a breakpoint in a single-item column", () => {
|
|
1338
|
-
const singleItemColumn = MultiColumn.from([["A1"], ["B1"], ["C1"]]);
|
|
1339
|
-
const withBreakpoint = singleItemColumn.insertBreakpoint("B1");
|
|
1340
|
-
expect(withBreakpoint.colLength).toBe(4);
|
|
1341
|
-
expect(withBreakpoint.topLevelIds).toEqual([["A1"], [], ["B1"], ["C1"]]);
|
|
1342
|
-
});
|
|
1343
|
-
});
|
|
1344
|
-
|
|
1345
|
-
describe("MultiColumn.fromWithPreviousShape", () => {
|
|
1346
|
-
it("creates a new MultiColumn with a single column when no previous shape is provided", () => {
|
|
1347
|
-
const ids = ["A1", "A2", "A3"];
|
|
1348
|
-
const multiColumn = MultiColumn.fromWithPreviousShape(
|
|
1349
|
-
ids,
|
|
1350
|
-
MultiColumn.from([]),
|
|
1351
|
-
);
|
|
1352
|
-
|
|
1353
|
-
expect(multiColumn.colLength).toBe(1);
|
|
1354
|
-
expect(multiColumn.topLevelIds).toEqual([ids]);
|
|
1355
|
-
expect(multiColumn.inOrderIds).toEqual(ids);
|
|
1356
|
-
});
|
|
1357
|
-
|
|
1358
|
-
it("preserves column structure when ids exist in previous columns", () => {
|
|
1359
|
-
const previousMultiColumn = MultiColumn.from([
|
|
1360
|
-
["A1", "A2"],
|
|
1361
|
-
["B1", "B2"],
|
|
1362
|
-
["C1", "C2"],
|
|
1363
|
-
]);
|
|
1364
|
-
|
|
1365
|
-
// Subset of ids from different columns
|
|
1366
|
-
const ids = ["A1", "B2", "C1"];
|
|
1367
|
-
const multiColumn = MultiColumn.fromWithPreviousShape(
|
|
1368
|
-
ids,
|
|
1369
|
-
previousMultiColumn,
|
|
1370
|
-
);
|
|
1371
|
-
|
|
1372
|
-
expect(multiColumn.colLength).toBe(3);
|
|
1373
|
-
expect(multiColumn.topLevelIds).toEqual([["A1"], ["B2"], ["C1"]]);
|
|
1374
|
-
});
|
|
1375
|
-
|
|
1376
|
-
it("preserves column structure with different ordering", () => {
|
|
1377
|
-
const previousMultiColumn = MultiColumn.from([
|
|
1378
|
-
["A1", "A2", "A3"],
|
|
1379
|
-
["B1", "B2", "B3"],
|
|
1380
|
-
]);
|
|
1381
|
-
|
|
1382
|
-
// Same ids but different order
|
|
1383
|
-
const ids = ["A3", "B1", "A1", "B3"];
|
|
1384
|
-
const multiColumn = MultiColumn.fromWithPreviousShape(
|
|
1385
|
-
ids,
|
|
1386
|
-
previousMultiColumn,
|
|
1387
|
-
);
|
|
1388
|
-
|
|
1389
|
-
expect(multiColumn.colLength).toBe(2);
|
|
1390
|
-
expect(multiColumn.topLevelIds).toEqual([
|
|
1391
|
-
["A3", "A1"],
|
|
1392
|
-
["B1", "B3"],
|
|
1393
|
-
]);
|
|
1394
|
-
});
|
|
1395
|
-
|
|
1396
|
-
it("handles ids not present in previous shape", () => {
|
|
1397
|
-
const previousMultiColumn = MultiColumn.from([
|
|
1398
|
-
["A1", "A2"],
|
|
1399
|
-
["B1", "B2"],
|
|
1400
|
-
]);
|
|
1401
|
-
|
|
1402
|
-
// Include new ids not in previous shape
|
|
1403
|
-
const ids = ["A1", "B1", "C1", "D1"];
|
|
1404
|
-
const multiColumn = MultiColumn.fromWithPreviousShape(
|
|
1405
|
-
ids,
|
|
1406
|
-
previousMultiColumn,
|
|
1407
|
-
);
|
|
1408
|
-
|
|
1409
|
-
// New ids should be added to the last column
|
|
1410
|
-
expect(multiColumn.colLength).toBe(2);
|
|
1411
|
-
expect(multiColumn.topLevelIds).toEqual([["A1"], ["B1", "C1", "D1"]]);
|
|
1412
|
-
expect(multiColumn.inOrderIds).toEqual(["A1", "B1", "C1", "D1"]);
|
|
1413
|
-
});
|
|
1414
|
-
|
|
1415
|
-
it("preserves collapsed state from previous shape", () => {
|
|
1416
|
-
// Create a previous shape with collapsed nodes
|
|
1417
|
-
let previousMultiColumn = MultiColumn.from([
|
|
1418
|
-
["A1", "A2", "A3"],
|
|
1419
|
-
["B1", "B2", "B3"],
|
|
1420
|
-
]);
|
|
1421
|
-
|
|
1422
|
-
// Collapse A1 to include A2
|
|
1423
|
-
const columnIds = previousMultiColumn.getColumnIds();
|
|
1424
|
-
previousMultiColumn = previousMultiColumn.transform(columnIds[0], (tree) =>
|
|
1425
|
-
tree.collapse("A1", "A2"),
|
|
1426
|
-
);
|
|
1427
|
-
|
|
1428
|
-
// Create new shape with same ids
|
|
1429
|
-
const ids = ["A1", "A2", "A3", "B1", "B2", "B3"];
|
|
1430
|
-
const multiColumn = MultiColumn.fromWithPreviousShape(
|
|
1431
|
-
ids,
|
|
1432
|
-
previousMultiColumn,
|
|
1433
|
-
);
|
|
1434
|
-
|
|
1435
|
-
// Check that A1 is still collapsed
|
|
1436
|
-
const column = multiColumn.atOrThrow(0);
|
|
1437
|
-
expect(column.isCollapsed("A1")).toBe(true);
|
|
1438
|
-
|
|
1439
|
-
// Check that the structure is preserved
|
|
1440
|
-
expect(multiColumn.colLength).toBe(2);
|
|
1441
|
-
expect(multiColumn.topLevelIds).toEqual([
|
|
1442
|
-
["A1", "A3"],
|
|
1443
|
-
["B1", "B2", "B3"],
|
|
1444
|
-
]);
|
|
1445
|
-
});
|
|
1446
|
-
|
|
1447
|
-
it("handles empty columns in previous shape", () => {
|
|
1448
|
-
// Create a previous shape with an empty column
|
|
1449
|
-
const previousMultiColumn = MultiColumn.from([
|
|
1450
|
-
["A1", "A2"],
|
|
1451
|
-
[],
|
|
1452
|
-
["C1", "C2"],
|
|
1453
|
-
]);
|
|
1454
|
-
|
|
1455
|
-
const ids = ["A1", "C2"];
|
|
1456
|
-
const multiColumn = MultiColumn.fromWithPreviousShape(
|
|
1457
|
-
ids,
|
|
1458
|
-
previousMultiColumn,
|
|
1459
|
-
);
|
|
1460
|
-
|
|
1461
|
-
// Should preserve the column structure
|
|
1462
|
-
expect(multiColumn.colLength).toBe(3);
|
|
1463
|
-
expect(multiColumn.topLevelIds).toEqual([["A1"], [], ["C2"]]);
|
|
1464
|
-
});
|
|
1465
|
-
|
|
1466
|
-
it("handles subset of ids with nested collapsed structure", () => {
|
|
1467
|
-
// Create a previous shape with nested collapsed structure
|
|
1468
|
-
let previousMultiColumn = MultiColumn.from([
|
|
1469
|
-
["A1", "A2", "A3", "A4", "A5"],
|
|
1470
|
-
["B1", "B2", "B3"],
|
|
1471
|
-
]);
|
|
1472
|
-
|
|
1473
|
-
// Collapse A1 to include A2, A3
|
|
1474
|
-
const columnIds = previousMultiColumn.getColumnIds();
|
|
1475
|
-
previousMultiColumn = previousMultiColumn.transform(columnIds[0], (tree) =>
|
|
1476
|
-
tree.collapse("A1", "A3"),
|
|
1477
|
-
);
|
|
1478
|
-
|
|
1479
|
-
// Create new shape with subset of ids
|
|
1480
|
-
const ids = ["A1", "A2", "A3", "A4", "B1"];
|
|
1481
|
-
const multiColumn = MultiColumn.fromWithPreviousShape(
|
|
1482
|
-
ids,
|
|
1483
|
-
previousMultiColumn,
|
|
1484
|
-
);
|
|
1485
|
-
|
|
1486
|
-
// Check that collapsed state is preserved
|
|
1487
|
-
const column = multiColumn.atOrThrow(0);
|
|
1488
|
-
expect(column.isCollapsed("A1")).toBe(true);
|
|
1489
|
-
|
|
1490
|
-
// Check that the structure is preserved
|
|
1491
|
-
expect(multiColumn.colLength).toBe(2);
|
|
1492
|
-
expect(multiColumn.topLevelIds).toEqual([["A1", "A4"], ["B1"]]);
|
|
1493
|
-
expect(multiColumn.inOrderIds).toEqual(["A1", "A2", "A3", "A4", "B1"]);
|
|
1494
|
-
});
|
|
1495
|
-
|
|
1496
|
-
it("handles reordering of columns", () => {
|
|
1497
|
-
// Create a previous shape with specific column order
|
|
1498
|
-
const previousMultiColumn = MultiColumn.from([
|
|
1499
|
-
["A1", "A2"],
|
|
1500
|
-
["B1", "B2"],
|
|
1501
|
-
["C1", "C2"],
|
|
1502
|
-
]);
|
|
1503
|
-
|
|
1504
|
-
// Create new shape with ids in different order
|
|
1505
|
-
const ids = ["C1", "A1", "B1"];
|
|
1506
|
-
const multiColumn = MultiColumn.fromWithPreviousShape(
|
|
1507
|
-
ids,
|
|
1508
|
-
previousMultiColumn,
|
|
1509
|
-
);
|
|
1510
|
-
|
|
1511
|
-
// Column order should be preserved
|
|
1512
|
-
expect(multiColumn.colLength).toBe(3);
|
|
1513
|
-
expect(multiColumn.topLevelIds).toEqual([["A1"], ["B1"], ["C1"]]);
|
|
1514
|
-
});
|
|
1515
|
-
|
|
1516
|
-
it("handles completely different set of ids", () => {
|
|
1517
|
-
const previousMultiColumn = MultiColumn.from([
|
|
1518
|
-
["A1", "A2"],
|
|
1519
|
-
["B1", "B2"],
|
|
1520
|
-
]);
|
|
1521
|
-
|
|
1522
|
-
// Completely different set of ids
|
|
1523
|
-
const ids = ["X1", "X2", "X3"];
|
|
1524
|
-
const multiColumn = MultiColumn.fromWithPreviousShape(
|
|
1525
|
-
ids,
|
|
1526
|
-
previousMultiColumn,
|
|
1527
|
-
);
|
|
1528
|
-
|
|
1529
|
-
// New ids should be added to the last column
|
|
1530
|
-
expect(multiColumn.colLength).toBe(2);
|
|
1531
|
-
expect(multiColumn.topLevelIds).toEqual([["X1", "X2", "X3"], []]);
|
|
1532
|
-
expect(multiColumn.inOrderIds).toEqual(["X1", "X2", "X3"]);
|
|
1533
|
-
});
|
|
1534
|
-
|
|
1535
|
-
it("preserves tree structure within columns", () => {
|
|
1536
|
-
// Create a previous shape with complex tree structure
|
|
1537
|
-
let previousMultiColumn = MultiColumn.from([
|
|
1538
|
-
["A1", "A2", "A3", "A4"],
|
|
1539
|
-
["B1", "B2", "B3"],
|
|
1540
|
-
]);
|
|
1541
|
-
|
|
1542
|
-
// Create complex tree structure by collapsing nodes
|
|
1543
|
-
const columnIds = previousMultiColumn.getColumnIds();
|
|
1544
|
-
previousMultiColumn = previousMultiColumn.transform(columnIds[0], (tree) =>
|
|
1545
|
-
tree.collapse("A1", "A2"),
|
|
1546
|
-
);
|
|
1547
|
-
previousMultiColumn = previousMultiColumn.transform(columnIds[1], (tree) =>
|
|
1548
|
-
tree.collapse("B1", "B2"),
|
|
1549
|
-
);
|
|
1550
|
-
|
|
1551
|
-
// Create new shape with same ids
|
|
1552
|
-
const ids = ["A1", "A2", "A3", "A4", "B1", "B2", "B3"];
|
|
1553
|
-
const multiColumn = MultiColumn.fromWithPreviousShape(
|
|
1554
|
-
ids,
|
|
1555
|
-
previousMultiColumn,
|
|
1556
|
-
);
|
|
1557
|
-
|
|
1558
|
-
// Check that collapsed state is preserved in both columns
|
|
1559
|
-
expect(multiColumn.atOrThrow(0).isCollapsed("A1")).toBe(true);
|
|
1560
|
-
expect(multiColumn.atOrThrow(1).isCollapsed("B1")).toBe(true);
|
|
1561
|
-
|
|
1562
|
-
// Check that the structure is preserved
|
|
1563
|
-
expect(multiColumn.colLength).toBe(2);
|
|
1564
|
-
expect(multiColumn.topLevelIds).toEqual([
|
|
1565
|
-
["A1", "A3", "A4"],
|
|
1566
|
-
["B1", "B3"],
|
|
1567
|
-
]);
|
|
1568
|
-
});
|
|
1569
|
-
|
|
1570
|
-
it("handles empty array of ids", () => {
|
|
1571
|
-
const previousMultiColumn = MultiColumn.from([
|
|
1572
|
-
["A1", "A2"],
|
|
1573
|
-
["B1", "B2"],
|
|
1574
|
-
]);
|
|
1575
|
-
|
|
1576
|
-
const multiColumn = MultiColumn.fromWithPreviousShape(
|
|
1577
|
-
[],
|
|
1578
|
-
previousMultiColumn,
|
|
1579
|
-
);
|
|
1580
|
-
|
|
1581
|
-
expect(multiColumn.colLength).toBe(2);
|
|
1582
|
-
expect(multiColumn.topLevelIds).toEqual([[], []]);
|
|
1583
|
-
expect(multiColumn.inOrderIds).toEqual([]);
|
|
1584
|
-
});
|
|
1585
|
-
|
|
1586
|
-
it("handles single id", () => {
|
|
1587
|
-
const previousMultiColumn = MultiColumn.from([
|
|
1588
|
-
["A1", "A2"],
|
|
1589
|
-
["B1", "B2"],
|
|
1590
|
-
]);
|
|
1591
|
-
|
|
1592
|
-
const multiColumn = MultiColumn.fromWithPreviousShape(
|
|
1593
|
-
["A1"],
|
|
1594
|
-
previousMultiColumn,
|
|
1595
|
-
);
|
|
1596
|
-
|
|
1597
|
-
expect(multiColumn.colLength).toBe(2);
|
|
1598
|
-
expect(multiColumn.topLevelIds).toEqual([["A1"], []]);
|
|
1599
|
-
expect(multiColumn.inOrderIds).toEqual(["A1"]);
|
|
1600
|
-
});
|
|
1601
|
-
|
|
1602
|
-
it("preserves complex nested structure across multiple columns", () => {
|
|
1603
|
-
// Create a complex structure with multiple columns and nested collapsed nodes
|
|
1604
|
-
let previousMultiColumn = MultiColumn.from([
|
|
1605
|
-
["A1", "A2", "A3", "A4", "A5"],
|
|
1606
|
-
["B1", "B2", "B3", "B4"],
|
|
1607
|
-
["C1", "C2", "C3"],
|
|
1608
|
-
]);
|
|
1609
|
-
|
|
1610
|
-
// Create complex nested structure
|
|
1611
|
-
const columnIds = previousMultiColumn.getColumnIds();
|
|
1612
|
-
|
|
1613
|
-
// Collapse in first column
|
|
1614
|
-
previousMultiColumn = previousMultiColumn.transform(columnIds[0], (tree) =>
|
|
1615
|
-
tree.collapse("A1", "A2"),
|
|
1616
|
-
);
|
|
1617
|
-
previousMultiColumn = previousMultiColumn.transform(columnIds[0], (tree) =>
|
|
1618
|
-
tree.collapse("A3", "A4"),
|
|
1619
|
-
);
|
|
1620
|
-
|
|
1621
|
-
// Collapse in second column
|
|
1622
|
-
previousMultiColumn = previousMultiColumn.transform(columnIds[1], (tree) =>
|
|
1623
|
-
tree.collapse("B1", "B2"),
|
|
1624
|
-
);
|
|
1625
|
-
|
|
1626
|
-
// Collapse in third column
|
|
1627
|
-
previousMultiColumn = previousMultiColumn.transform(columnIds[2], (tree) =>
|
|
1628
|
-
tree.collapse("C1", "C2"),
|
|
1629
|
-
);
|
|
1630
|
-
|
|
1631
|
-
// Create new shape with all ids
|
|
1632
|
-
const ids = [
|
|
1633
|
-
"A1",
|
|
1634
|
-
"A2",
|
|
1635
|
-
"A3",
|
|
1636
|
-
"A4",
|
|
1637
|
-
"A5",
|
|
1638
|
-
"B1",
|
|
1639
|
-
"B2",
|
|
1640
|
-
"B3",
|
|
1641
|
-
"B4",
|
|
1642
|
-
"C1",
|
|
1643
|
-
"C2",
|
|
1644
|
-
"C3",
|
|
1645
|
-
];
|
|
1646
|
-
|
|
1647
|
-
const multiColumn = MultiColumn.fromWithPreviousShape(
|
|
1648
|
-
ids,
|
|
1649
|
-
previousMultiColumn,
|
|
1650
|
-
);
|
|
1651
|
-
|
|
1652
|
-
// Check that all collapsed states are preserved
|
|
1653
|
-
expect(multiColumn.atOrThrow(0).isCollapsed("A1")).toBe(true);
|
|
1654
|
-
expect(multiColumn.atOrThrow(0).isCollapsed("A3")).toBe(true);
|
|
1655
|
-
expect(multiColumn.atOrThrow(1).isCollapsed("B1")).toBe(true);
|
|
1656
|
-
expect(multiColumn.atOrThrow(2).isCollapsed("C1")).toBe(true);
|
|
1657
|
-
|
|
1658
|
-
// Check that the structure is preserved
|
|
1659
|
-
expect(multiColumn.colLength).toBe(3);
|
|
1660
|
-
expect(multiColumn.topLevelIds).toEqual([
|
|
1661
|
-
["A1", "A3", "A5"],
|
|
1662
|
-
["B1", "B3", "B4"],
|
|
1663
|
-
["C1", "C3"],
|
|
1664
|
-
]);
|
|
1665
|
-
});
|
|
1666
|
-
|
|
1667
|
-
it("handles case where ids are distributed differently than in previous shape", () => {
|
|
1668
|
-
const previousMultiColumn = MultiColumn.from([
|
|
1669
|
-
["A1", "A2"],
|
|
1670
|
-
["B1", "B2"],
|
|
1671
|
-
["C1", "C2"],
|
|
1672
|
-
]);
|
|
1673
|
-
|
|
1674
|
-
// Create new shape with ids from different columns grouped together
|
|
1675
|
-
const ids = ["A1", "B1", "C1", "A2", "B2", "C2"];
|
|
1676
|
-
const multiColumn = MultiColumn.fromWithPreviousShape(
|
|
1677
|
-
ids,
|
|
1678
|
-
previousMultiColumn,
|
|
1679
|
-
);
|
|
1680
|
-
|
|
1681
|
-
// Should preserve the original column structure
|
|
1682
|
-
expect(multiColumn.colLength).toBe(3);
|
|
1683
|
-
expect(multiColumn.topLevelIds).toEqual([
|
|
1684
|
-
["A1", "A2"],
|
|
1685
|
-
["B1", "B2"],
|
|
1686
|
-
["C1", "C2"],
|
|
1687
|
-
]);
|
|
1688
|
-
});
|
|
1689
|
-
|
|
1690
|
-
it("handles case where previous shape has collapsed nodes but new ids don't include children", () => {
|
|
1691
|
-
// Create a previous shape with collapsed nodes
|
|
1692
|
-
let previousMultiColumn = MultiColumn.from([
|
|
1693
|
-
["A1", "A2", "A3"],
|
|
1694
|
-
["B1", "B2", "B3"],
|
|
1695
|
-
]);
|
|
1696
|
-
|
|
1697
|
-
// Collapse nodes in both columns
|
|
1698
|
-
const columnIds = previousMultiColumn.getColumnIds();
|
|
1699
|
-
previousMultiColumn = previousMultiColumn.transform(columnIds[0], (tree) =>
|
|
1700
|
-
tree.collapse("A1", "A2"),
|
|
1701
|
-
);
|
|
1702
|
-
previousMultiColumn = previousMultiColumn.transform(columnIds[1], (tree) =>
|
|
1703
|
-
tree.collapse("B1", "B2"),
|
|
1704
|
-
);
|
|
1705
|
-
|
|
1706
|
-
// Create new shape without the collapsed children
|
|
1707
|
-
const ids = ["A1", "A3", "B1", "B3"];
|
|
1708
|
-
const multiColumn = MultiColumn.fromWithPreviousShape(
|
|
1709
|
-
ids,
|
|
1710
|
-
previousMultiColumn,
|
|
1711
|
-
);
|
|
1712
|
-
|
|
1713
|
-
// Nodes should not be collapsed since children are missing
|
|
1714
|
-
expect(multiColumn.atOrThrow(0).isCollapsed("A1")).toBe(false);
|
|
1715
|
-
expect(multiColumn.atOrThrow(1).isCollapsed("B1")).toBe(false);
|
|
1716
|
-
|
|
1717
|
-
// Check that the structure is preserved
|
|
1718
|
-
expect(multiColumn.colLength).toBe(2);
|
|
1719
|
-
expect(multiColumn.topLevelIds).toEqual([
|
|
1720
|
-
["A1", "A3"],
|
|
1721
|
-
["B1", "B3"],
|
|
1722
|
-
]);
|
|
1723
|
-
});
|
|
1724
|
-
|
|
1725
|
-
it("handles deeply nested collapsed structure", () => {
|
|
1726
|
-
// Create a tree with deeply nested collapsed structure
|
|
1727
|
-
let previousTree = CollapsibleTree.from([
|
|
1728
|
-
"one",
|
|
1729
|
-
"two",
|
|
1730
|
-
"three",
|
|
1731
|
-
"four",
|
|
1732
|
-
"five",
|
|
1733
|
-
"six",
|
|
1734
|
-
"seven",
|
|
1735
|
-
"eight",
|
|
1736
|
-
]);
|
|
1737
|
-
|
|
1738
|
-
// Create nested collapses
|
|
1739
|
-
previousTree = previousTree.collapse("one", "two");
|
|
1740
|
-
|
|
1741
|
-
// Get the collapsed node and collapse its children
|
|
1742
|
-
const oneNode = previousTree._nodeMap.get("one");
|
|
1743
|
-
expect(oneNode).toBeDefined();
|
|
1744
|
-
|
|
1745
|
-
// Create a new tree with the same structure
|
|
1746
|
-
const tree = CollapsibleTree.fromWithPreviousShape(
|
|
1747
|
-
["one", "two", "three", "four", "five", "six", "seven", "eight"],
|
|
1748
|
-
previousTree,
|
|
1749
|
-
);
|
|
1750
|
-
|
|
1751
|
-
// Check that collapsed state is preserved
|
|
1752
|
-
expect(tree.isCollapsed("one")).toBe(true);
|
|
1753
|
-
expect(tree.topLevelIds).toEqual([
|
|
1754
|
-
"one",
|
|
1755
|
-
"three",
|
|
1756
|
-
"four",
|
|
1757
|
-
"five",
|
|
1758
|
-
"six",
|
|
1759
|
-
"seven",
|
|
1760
|
-
"eight",
|
|
1761
|
-
]);
|
|
1762
|
-
});
|
|
1763
|
-
|
|
1764
|
-
it("handles case where collapsed node is at the end", () => {
|
|
1765
|
-
// Create a tree with collapsed node at the end
|
|
1766
|
-
let previousTree = CollapsibleTree.from([
|
|
1767
|
-
"one",
|
|
1768
|
-
"two",
|
|
1769
|
-
"three",
|
|
1770
|
-
"four",
|
|
1771
|
-
"five",
|
|
1772
|
-
]);
|
|
1773
|
-
previousTree = previousTree.collapse("four", "five");
|
|
1774
|
-
|
|
1775
|
-
// Create new tree with same ids
|
|
1776
|
-
const tree = CollapsibleTree.fromWithPreviousShape(
|
|
1777
|
-
["one", "two", "three", "four", "five"],
|
|
1778
|
-
previousTree,
|
|
1779
|
-
);
|
|
1780
|
-
|
|
1781
|
-
// Check that collapsed state is preserved
|
|
1782
|
-
expect(tree.isCollapsed("four")).toBe(true);
|
|
1783
|
-
expect(tree.topLevelIds).toEqual(["one", "two", "three", "four"]);
|
|
1784
|
-
});
|
|
1785
|
-
|
|
1786
|
-
it("handles case with multiple collapsed nodes in the same column", () => {
|
|
1787
|
-
// Create a previous shape with multiple collapsed nodes in the same column
|
|
1788
|
-
let previousMultiColumn = MultiColumn.from([
|
|
1789
|
-
["A1", "A2", "A3", "A4", "A5", "A6"],
|
|
1790
|
-
["B1", "B2"],
|
|
1791
|
-
]);
|
|
1792
|
-
|
|
1793
|
-
// Collapse multiple nodes in the first column
|
|
1794
|
-
const columnIds = previousMultiColumn.getColumnIds();
|
|
1795
|
-
previousMultiColumn = previousMultiColumn.transform(columnIds[0], (tree) =>
|
|
1796
|
-
tree.collapse("A1", "A2"),
|
|
1797
|
-
);
|
|
1798
|
-
previousMultiColumn = previousMultiColumn.transform(columnIds[0], (tree) =>
|
|
1799
|
-
tree.collapse("A3", "A4"),
|
|
1800
|
-
);
|
|
1801
|
-
previousMultiColumn = previousMultiColumn.transform(columnIds[0], (tree) =>
|
|
1802
|
-
tree.collapse("A5", "A6"),
|
|
1803
|
-
);
|
|
1804
|
-
|
|
1805
|
-
// Create new shape with same ids
|
|
1806
|
-
const ids = ["A1", "A2", "A3", "A4", "A5", "A6", "B1", "B2"];
|
|
1807
|
-
const multiColumn = MultiColumn.fromWithPreviousShape(
|
|
1808
|
-
ids,
|
|
1809
|
-
previousMultiColumn,
|
|
1810
|
-
);
|
|
1811
|
-
|
|
1812
|
-
// Check that all collapsed states are preserved
|
|
1813
|
-
expect(multiColumn.atOrThrow(0).isCollapsed("A1")).toBe(true);
|
|
1814
|
-
expect(multiColumn.atOrThrow(0).isCollapsed("A3")).toBe(true);
|
|
1815
|
-
expect(multiColumn.atOrThrow(0).isCollapsed("A5")).toBe(true);
|
|
1816
|
-
|
|
1817
|
-
// Check that the structure is preserved
|
|
1818
|
-
expect(multiColumn.colLength).toBe(2);
|
|
1819
|
-
expect(multiColumn.topLevelIds).toEqual([
|
|
1820
|
-
["A1", "A3", "A5"],
|
|
1821
|
-
["B1", "B2"],
|
|
1822
|
-
]);
|
|
1823
|
-
});
|
|
1824
|
-
|
|
1825
|
-
it("handles case where all columns are empty in previous shape", () => {
|
|
1826
|
-
// Create a previous shape with all empty columns
|
|
1827
|
-
const previousMultiColumn = MultiColumn.from([[], [], []]);
|
|
1828
|
-
|
|
1829
|
-
// Create new shape with new ids
|
|
1830
|
-
const ids = ["A1", "B1", "C1"];
|
|
1831
|
-
const multiColumn = MultiColumn.fromWithPreviousShape(
|
|
1832
|
-
ids,
|
|
1833
|
-
previousMultiColumn,
|
|
1834
|
-
);
|
|
1835
|
-
|
|
1836
|
-
// New ids should be added to the last column
|
|
1837
|
-
expect(multiColumn.colLength).toBe(3);
|
|
1838
|
-
expect(multiColumn.topLevelIds).toEqual([["A1", "B1", "C1"], [], []]);
|
|
1839
|
-
expect(multiColumn.inOrderIds).toEqual(["A1", "B1", "C1"]);
|
|
1840
|
-
});
|
|
1841
|
-
|
|
1842
|
-
it("handles case with very large number of ids", () => {
|
|
1843
|
-
// Create a previous shape with a reasonable number of ids
|
|
1844
|
-
const previousIds1 = Array.from({ length: 50 }, (_, i) => `A${i}`);
|
|
1845
|
-
const previousIds2 = Array.from({ length: 50 }, (_, i) => `B${i}`);
|
|
1846
|
-
const previousMultiColumn = MultiColumn.from([previousIds1, previousIds2]);
|
|
1847
|
-
|
|
1848
|
-
// Create a large set of ids
|
|
1849
|
-
const ids = [
|
|
1850
|
-
...Array.from({ length: 50 }, (_, i) => `A${i}`),
|
|
1851
|
-
...Array.from({ length: 50 }, (_, i) => `B${i}`),
|
|
1852
|
-
...Array.from({ length: 50 }, (_, i) => `C${i}`),
|
|
1853
|
-
];
|
|
1854
|
-
|
|
1855
|
-
const multiColumn = MultiColumn.fromWithPreviousShape(
|
|
1856
|
-
ids,
|
|
1857
|
-
previousMultiColumn,
|
|
1858
|
-
);
|
|
1859
|
-
|
|
1860
|
-
// Should preserve the column structure for existing ids and add new ids to last column
|
|
1861
|
-
expect(multiColumn.colLength).toBe(2);
|
|
1862
|
-
expect(multiColumn.topLevelIds[0].length).toBe(50);
|
|
1863
|
-
expect(multiColumn.topLevelIds[1].length).toBe(100); // 50 B ids + 50 C ids
|
|
1864
|
-
expect(multiColumn.inOrderIds.length).toBe(150); // All ids should be included
|
|
1865
|
-
});
|
|
1866
|
-
});
|
|
1867
|
-
|
|
1868
|
-
describe("CollapsibleTree.fromWithPreviousShape", () => {
|
|
1869
|
-
it("creates a new tree when no previous tree is provided", () => {
|
|
1870
|
-
const ids = ["one", "two", "three"];
|
|
1871
|
-
const tree = CollapsibleTree.fromWithPreviousShape(ids);
|
|
1872
|
-
|
|
1873
|
-
expect(tree.topLevelIds).toEqual(ids);
|
|
1874
|
-
expect(tree.inOrderIds).toEqual(ids);
|
|
1875
|
-
expect(tree.nodes.length).toBe(3);
|
|
1876
|
-
expect(tree.nodes.every((node) => !node.isCollapsed)).toBe(true);
|
|
1877
|
-
});
|
|
1878
|
-
|
|
1879
|
-
it("preserves the tree ID when previous tree is provided", () => {
|
|
1880
|
-
const previousTree = CollapsibleTree.from(["one", "two", "three"]);
|
|
1881
|
-
const tree = CollapsibleTree.fromWithPreviousShape(
|
|
1882
|
-
["one", "two"],
|
|
1883
|
-
previousTree,
|
|
1884
|
-
);
|
|
1885
|
-
|
|
1886
|
-
expect(tree.id).toBe(previousTree.id);
|
|
1887
|
-
});
|
|
1888
|
-
|
|
1889
|
-
it("preserves collapsed state from previous tree", () => {
|
|
1890
|
-
// Create a tree with collapsed nodes
|
|
1891
|
-
let previousTree = CollapsibleTree.from(["one", "two", "three", "four"]);
|
|
1892
|
-
previousTree = previousTree.collapse("one", "two");
|
|
1893
|
-
|
|
1894
|
-
// Create new tree with same ids
|
|
1895
|
-
const tree = CollapsibleTree.fromWithPreviousShape(
|
|
1896
|
-
["one", "two", "three", "four"],
|
|
1897
|
-
previousTree,
|
|
1898
|
-
);
|
|
1899
|
-
|
|
1900
|
-
// Check that one is still collapsed
|
|
1901
|
-
expect(tree.isCollapsed("one")).toBe(true);
|
|
1902
|
-
expect(tree.topLevelIds).toEqual(["one", "three", "four"]);
|
|
1903
|
-
});
|
|
1904
|
-
|
|
1905
|
-
it("handles subset of ids from previous tree", () => {
|
|
1906
|
-
// Create a tree with collapsed nodes
|
|
1907
|
-
let previousTree = CollapsibleTree.from([
|
|
1908
|
-
"one",
|
|
1909
|
-
"two",
|
|
1910
|
-
"three",
|
|
1911
|
-
"four",
|
|
1912
|
-
"five",
|
|
1913
|
-
]);
|
|
1914
|
-
previousTree = previousTree.collapse("one", "two");
|
|
1915
|
-
previousTree = previousTree.collapse("three", "four");
|
|
1916
|
-
|
|
1917
|
-
// Create new tree with subset of ids
|
|
1918
|
-
const tree = CollapsibleTree.fromWithPreviousShape(
|
|
1919
|
-
["one", "two", "three"],
|
|
1920
|
-
previousTree,
|
|
1921
|
-
);
|
|
1922
|
-
|
|
1923
|
-
// Check that collapsed state is preserved for existing nodes
|
|
1924
|
-
expect(tree.isCollapsed("one")).toBe(true);
|
|
1925
|
-
expect(tree.topLevelIds).toEqual(["one", "three"]);
|
|
1926
|
-
});
|
|
1927
|
-
|
|
1928
|
-
it("handles different ordering of ids", () => {
|
|
1929
|
-
// Create a tree with collapsed nodes
|
|
1930
|
-
let previousTree = CollapsibleTree.from(["one", "two", "three", "four"]);
|
|
1931
|
-
previousTree = previousTree.collapse("one", "two");
|
|
1932
|
-
|
|
1933
|
-
// Create new tree with different order
|
|
1934
|
-
const tree = CollapsibleTree.fromWithPreviousShape(
|
|
1935
|
-
["three", "one", "two", "four"],
|
|
1936
|
-
previousTree,
|
|
1937
|
-
);
|
|
1938
|
-
|
|
1939
|
-
// Check that collapsed state is preserved
|
|
1940
|
-
expect(tree.isCollapsed("one")).toBe(true);
|
|
1941
|
-
expect(tree.topLevelIds).toEqual(["three", "one", "four"]);
|
|
1942
|
-
});
|
|
1943
|
-
|
|
1944
|
-
it("handles new ids not in previous tree", () => {
|
|
1945
|
-
// Create a tree with collapsed nodes
|
|
1946
|
-
let previousTree = CollapsibleTree.from(["one", "two", "three"]);
|
|
1947
|
-
previousTree = previousTree.collapse("one", "two");
|
|
1948
|
-
|
|
1949
|
-
// Create new tree with new ids
|
|
1950
|
-
const tree = CollapsibleTree.fromWithPreviousShape(
|
|
1951
|
-
["one", "two", "three", "four", "five"],
|
|
1952
|
-
previousTree,
|
|
1953
|
-
);
|
|
1954
|
-
|
|
1955
|
-
// Check that collapsed state is preserved for existing nodes
|
|
1956
|
-
expect(tree.isCollapsed("one")).toBe(true);
|
|
1957
|
-
expect(tree.topLevelIds).toEqual(["one", "three", "four", "five"]);
|
|
1958
|
-
});
|
|
1959
|
-
|
|
1960
|
-
it("handles completely different set of ids", () => {
|
|
1961
|
-
// Create a tree with collapsed nodes
|
|
1962
|
-
let previousTree = CollapsibleTree.from(["one", "two", "three"]);
|
|
1963
|
-
previousTree = previousTree.collapse("one", "two");
|
|
1964
|
-
|
|
1965
|
-
// Create new tree with completely different ids
|
|
1966
|
-
const tree = CollapsibleTree.fromWithPreviousShape(
|
|
1967
|
-
["four", "five", "six"],
|
|
1968
|
-
previousTree,
|
|
1969
|
-
);
|
|
1970
|
-
|
|
1971
|
-
// Should have no collapsed nodes
|
|
1972
|
-
expect(tree.nodes.every((node) => !node.isCollapsed)).toBe(true);
|
|
1973
|
-
expect(tree.topLevelIds).toEqual(["four", "five", "six"]);
|
|
1974
|
-
});
|
|
1975
|
-
|
|
1976
|
-
it("preserves nested collapsed structure", () => {
|
|
1977
|
-
// Create a tree with nested collapsed structure
|
|
1978
|
-
let previousTree = CollapsibleTree.from([
|
|
1979
|
-
"one",
|
|
1980
|
-
"two",
|
|
1981
|
-
"three",
|
|
1982
|
-
"four",
|
|
1983
|
-
"five",
|
|
1984
|
-
"six",
|
|
1985
|
-
]);
|
|
1986
|
-
previousTree = previousTree.collapse("one", "two");
|
|
1987
|
-
|
|
1988
|
-
// Collapse the node that contains the collapsed children
|
|
1989
|
-
const oneNode = previousTree.nodes.find((n) => n.value === "one");
|
|
1990
|
-
expect(oneNode).toBeDefined();
|
|
1991
|
-
expect(oneNode?.children.length).toBeGreaterThan(0);
|
|
1992
|
-
|
|
1993
|
-
// Create a new tree with the same structure
|
|
1994
|
-
const tree = CollapsibleTree.fromWithPreviousShape(
|
|
1995
|
-
["one", "two", "three", "four", "five", "six"],
|
|
1996
|
-
previousTree,
|
|
1997
|
-
);
|
|
1998
|
-
|
|
1999
|
-
// Check that collapsed state is preserved
|
|
2000
|
-
expect(tree.isCollapsed("one")).toBe(true);
|
|
2001
|
-
expect(tree.topLevelIds).toEqual(["one", "three", "four", "five", "six"]);
|
|
2002
|
-
});
|
|
2003
|
-
|
|
2004
|
-
it("collapses using the last available child when some children are missing", () => {
|
|
2005
|
-
// Create a tree with collapsed nodes
|
|
2006
|
-
let previousTree = CollapsibleTree.from(["one", "two", "three", "four"]);
|
|
2007
|
-
previousTree = previousTree.collapse("one", "three");
|
|
2008
|
-
|
|
2009
|
-
// Create new tree without "two" but with "three"
|
|
2010
|
-
const tree = CollapsibleTree.fromWithPreviousShape(
|
|
2011
|
-
["one", "three", "four"],
|
|
2012
|
-
previousTree,
|
|
2013
|
-
);
|
|
2014
|
-
|
|
2015
|
-
// Should still collapse "one" with "three" as the child
|
|
2016
|
-
expect(tree.isCollapsed("one")).toBe(true);
|
|
2017
|
-
expect(tree.topLevelIds).toEqual(["one", "four"]);
|
|
2018
|
-
});
|
|
2019
|
-
|
|
2020
|
-
it("preserves collapse state when children order changes", () => {
|
|
2021
|
-
// Create a tree with collapsed nodes
|
|
2022
|
-
let previousTree = CollapsibleTree.from(["one", "two", "three", "four"]);
|
|
2023
|
-
previousTree = previousTree.collapse("one", "two");
|
|
2024
|
-
|
|
2025
|
-
// Create new tree with children in different order
|
|
2026
|
-
const tree = CollapsibleTree.fromWithPreviousShape(
|
|
2027
|
-
["one", "three", "two", "four"],
|
|
2028
|
-
previousTree,
|
|
2029
|
-
);
|
|
2030
|
-
|
|
2031
|
-
// Should still be collapsed
|
|
2032
|
-
expect(tree.isCollapsed("one")).toBe(true);
|
|
2033
|
-
// But the topLevelIds will be different because the children order changed
|
|
2034
|
-
expect(tree.topLevelIds).toEqual(["one", "four"]);
|
|
2035
|
-
});
|
|
2036
|
-
|
|
2037
|
-
it("handles empty arrays correctly", () => {
|
|
2038
|
-
const previousTree = CollapsibleTree.from(["one", "two", "three"]);
|
|
2039
|
-
const tree = CollapsibleTree.fromWithPreviousShape([], previousTree);
|
|
2040
|
-
|
|
2041
|
-
expect(tree.nodes.length).toBe(0);
|
|
2042
|
-
expect(tree.topLevelIds).toEqual([]);
|
|
2043
|
-
expect(tree.inOrderIds).toEqual([]);
|
|
2044
|
-
});
|
|
2045
|
-
|
|
2046
|
-
it("handles single item arrays correctly", () => {
|
|
2047
|
-
let previousTree = CollapsibleTree.from(["one", "two", "three"]);
|
|
2048
|
-
previousTree = previousTree.collapse("one", "two");
|
|
2049
|
-
|
|
2050
|
-
const tree = CollapsibleTree.fromWithPreviousShape(["one"], previousTree);
|
|
2051
|
-
|
|
2052
|
-
expect(tree.nodes.length).toBe(1);
|
|
2053
|
-
expect(tree.topLevelIds).toEqual(["one"]);
|
|
2054
|
-
expect(tree.inOrderIds).toEqual(["one"]);
|
|
2055
|
-
// Should not be collapsed since there are no children
|
|
2056
|
-
expect(tree.isCollapsed("one")).toBe(false);
|
|
2057
|
-
});
|
|
2058
|
-
|
|
2059
|
-
it("handles multiple collapsed nodes in sequence", () => {
|
|
2060
|
-
let previousTree = CollapsibleTree.from([
|
|
2061
|
-
"one",
|
|
2062
|
-
"two",
|
|
2063
|
-
"three",
|
|
2064
|
-
"four",
|
|
2065
|
-
"five",
|
|
2066
|
-
"six",
|
|
2067
|
-
]);
|
|
2068
|
-
previousTree = previousTree.collapse("one", "two");
|
|
2069
|
-
previousTree = previousTree.collapse("three", "four");
|
|
2070
|
-
previousTree = previousTree.collapse("five", "six");
|
|
2071
|
-
|
|
2072
|
-
const tree = CollapsibleTree.fromWithPreviousShape(
|
|
2073
|
-
["one", "two", "three", "four", "five", "six"],
|
|
2074
|
-
previousTree,
|
|
2075
|
-
);
|
|
2076
|
-
|
|
2077
|
-
expect(tree.isCollapsed("one")).toBe(true);
|
|
2078
|
-
expect(tree.isCollapsed("three")).toBe(true);
|
|
2079
|
-
expect(tree.isCollapsed("five")).toBe(true);
|
|
2080
|
-
expect(tree.topLevelIds).toEqual(["one", "three", "five"]);
|
|
2081
|
-
});
|
|
2082
|
-
|
|
2083
|
-
it("handles case where collapsed node's children are not in new ids", () => {
|
|
2084
|
-
let previousTree = CollapsibleTree.from(["one", "two", "three", "four"]);
|
|
2085
|
-
previousTree = previousTree.collapse("one", "two");
|
|
2086
|
-
|
|
2087
|
-
// Create new tree without the collapsed child
|
|
2088
|
-
const tree = CollapsibleTree.fromWithPreviousShape(
|
|
2089
|
-
["one", "three", "four"],
|
|
2090
|
-
previousTree,
|
|
2091
|
-
);
|
|
2092
|
-
|
|
2093
|
-
// Should not be collapsed since the child is missing
|
|
2094
|
-
expect(tree.isCollapsed("one")).toBe(false);
|
|
2095
|
-
expect(tree.topLevelIds).toEqual(["one", "three", "four"]);
|
|
2096
|
-
});
|
|
2097
|
-
|
|
2098
|
-
it("reproduces GitHub issue #6188: inOrderIds with nested collapses", () => {
|
|
2099
|
-
// Simplified reproduction case:
|
|
2100
|
-
// Cell A (markdown): # Section 1 Header
|
|
2101
|
-
// Cell B (markdown): ## Subsection 1.1 Header
|
|
2102
|
-
// Cell C (python): print("This cell should be in Subsection 1.1")
|
|
2103
|
-
// Cell D (python): print("This cell should also be in Subsection 1.1")
|
|
2104
|
-
// Cell E (markdown): ## Subsection 1.2 Header
|
|
2105
|
-
// Cell F (python): print("This cell should be in Subsection 1.2")
|
|
2106
|
-
|
|
2107
|
-
const originalOrder = [
|
|
2108
|
-
"CellA", // # Section 1 Header
|
|
2109
|
-
"CellB", // ## Subsection 1.1 Header
|
|
2110
|
-
"CellC", // print("This cell should be in Subsection 1.1")
|
|
2111
|
-
"CellD", // print("This cell should also be in Subsection 1.1")
|
|
2112
|
-
"CellE", // ## Subsection 1.2 Header
|
|
2113
|
-
"CellF", // print("This cell should be in Subsection 1.2")
|
|
2114
|
-
];
|
|
2115
|
-
|
|
2116
|
-
// Create notebook with one column
|
|
2117
|
-
let notebook = MultiColumn.from([originalOrder]);
|
|
2118
|
-
|
|
2119
|
-
// Before collapsing, order should be correct
|
|
2120
|
-
expect(notebook.inOrderIds).toEqual(originalOrder);
|
|
2121
|
-
|
|
2122
|
-
const columnId = notebook.getColumnIds()[0];
|
|
2123
|
-
|
|
2124
|
-
// Follow the exact reproduction steps from the GitHub issue:
|
|
2125
|
-
// 1. Collapse B (subsection 1.1) - includes C, D (stops before E)
|
|
2126
|
-
notebook = notebook.transform(columnId, (tree) =>
|
|
2127
|
-
tree.collapse("CellB", "CellD"),
|
|
2128
|
-
);
|
|
2129
|
-
|
|
2130
|
-
// 2. Collapse E (subsection 1.2) - includes F (to end)
|
|
2131
|
-
notebook = notebook.transform(columnId, (tree) =>
|
|
2132
|
-
tree.collapse("CellE", undefined),
|
|
2133
|
-
);
|
|
2134
|
-
|
|
2135
|
-
// 3. Collapse A (section 1) - includes all the rest (B, E and their children)
|
|
2136
|
-
notebook = notebook.transform(columnId, (tree) =>
|
|
2137
|
-
tree.collapse("CellA", undefined),
|
|
2138
|
-
);
|
|
2139
|
-
|
|
2140
|
-
const finalOrder = notebook.inOrderIds;
|
|
2141
|
-
|
|
2142
|
-
// inOrderIds now correctly preserves logical order even with nested collapses
|
|
2143
|
-
expect(finalOrder).toEqual(originalOrder);
|
|
2144
|
-
});
|
|
2145
|
-
});
|