collabmd 0.1.52 → 0.1.55
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/bin/collabmd.js +22 -40
- package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-cMeDxAEL.js +1 -0
- package/dist/client/assets/{abnfDiagram-VCTEODGH-DxNxad6-.js → abnfDiagram-VCTEODGH-D2UdmYvj.js} +1 -1
- package/dist/client/assets/{abnfDiagram-O67JEVCF-Dwt6a0Ds.js → abnfDiagram-YUKMZFIV-DbmU4Q-X.js} +1 -1
- package/dist/client/assets/api-client-utils-C5ESDKMG.js +1 -0
- package/dist/client/assets/architecture-7GRP2DOG-BBwRXFv3.js +1 -1
- package/dist/client/assets/architecture-WOLXFQ4H-C0NxYiG7.js +1 -0
- package/dist/client/assets/{architectureDiagram-NJMV4G6O-D5CGiX3G.js → architectureDiagram-47P4ROYG-C7OjXK9S.js} +3 -3
- package/dist/client/assets/{architectureDiagram-5GKGNRK7-C1uvg5id.js → architectureDiagram-5GKGNRK7-CSiUzzeN.js} +1 -1
- package/dist/client/assets/base-CaIEJUF9.css +1 -0
- package/dist/client/assets/{blockDiagram-BEXU5L5S-BgTM0var.js → blockDiagram-E7TT5TSB-DMG-YlZw.js} +3 -3
- package/dist/client/assets/{blockDiagram-I7D4REHJ-B2YonsoG.js → blockDiagram-I7D4REHJ-sXfAgK2w.js} +1 -1
- package/dist/client/assets/{browser-BKLM0ThC-IxjwuOIz-C0mP17s1.js → browser-BKLM0ThC-BCLQGPD6-CcMAHZXi.js} +1 -1
- package/dist/client/assets/{c4Diagram-7LVT6UL2-r4IwomZm.js → c4Diagram-7LVT6UL2-C88V_K-8.js} +1 -1
- package/dist/client/assets/{c4Diagram-YGBWAQC7-_xZPrNkB.js → c4Diagram-CRA5TL53-D3F9ElJv.js} +2 -2
- package/dist/client/assets/canvasEditor-BJkwGzO1.css +1 -0
- package/dist/client/assets/canvasEditor-sBK7KfrD.js +1 -0
- package/dist/client/assets/{chunk-6AZGARVD--pTGpDnx.js → chunk-24IY7LWP-flnn6SWX.js} +1 -1
- package/dist/client/assets/chunk-2BW5OAIV-CNFO1U_e.js +10 -0
- package/dist/client/assets/{chunk-2E4U76K2-CIQUuV9n.js → chunk-2E4U76K2-DEnS5IbF.js} +1 -1
- package/dist/client/assets/{chunk-5V3GS4D5-B5uC2oxu.js → chunk-3M4EKCLJ-D-sZGCtO.js} +1 -1
- package/dist/client/assets/chunk-3YJQHVM4-Ctp__8EK.js +2 -0
- package/dist/client/assets/{chunk-7PRAP22T-9uTvtc_-.js → chunk-4EA7E6EY-bU4wRJot.js} +1 -1
- package/dist/client/assets/{chunk-4HAMMTFA-q0ldNVvr.js → chunk-4HAMMTFA-CQy6Skzw.js} +1 -1
- package/dist/client/assets/{chunk-6K3QC6MW-JnuvEGV4.js → chunk-4S7OKTRW-BpUW13a3.js} +1 -1
- package/dist/client/assets/{chunk-ICYGCRZG-odvlDZyA.js → chunk-53FOQ5SW-5lPdGYP4.js} +1 -1
- package/dist/client/assets/{chunk-75Z2AOVW-DitkSoSG.js → chunk-75Z2AOVW-BRdhvVTZ.js} +1 -1
- package/dist/client/assets/{chunk-GWA4HPMP-CGmv2yIq.js → chunk-7TKQ45FW-rA2u-WUl.js} +1 -1
- package/dist/client/assets/{chunk-GTNCS2PH-ChgkzEIi.js → chunk-AW2ZBBNX-DL0KGAdi.js} +3 -3
- package/dist/client/assets/{chunk-747NJXEK-BjqqAsS9.js → chunk-BP2KR52E-DAQ1pzDV.js} +1 -1
- package/dist/client/assets/{chunk-CLGD4ZFX-BfYJtJm1.js → chunk-CLGD4ZFX-DJiSE0gD.js} +1 -1
- package/dist/client/assets/{chunk-5DYCD2WN-BKWCKnK-.js → chunk-DBDB3WZW-CXleNlok.js} +1 -1
- package/dist/client/assets/{chunk-DU6HZSFF-CWlP1Dk_.js → chunk-DU6HZSFF-C-18UZkS.js} +1 -1
- package/dist/client/assets/{chunk-MBY4JIJT-DTJ4UcAm.js → chunk-E2ZNV5FY-D_07zfWd.js} +3 -3
- package/dist/client/assets/chunk-EU5HNXII-CETVNUXF.js +213 -0
- package/dist/client/assets/{chunk-F27PBJKO-DPcsPcEs.js → chunk-F27PBJKO-_beIJos4.js} +1 -1
- package/dist/client/assets/{chunk-2ZTRR5NV-DcPRfelM.js → chunk-F6S3BTY2-DVWKCAHp.js} +1 -1
- package/dist/client/assets/{chunk-RUX4WMZV-BGnd3s_C.js → chunk-FLFP27SU-CydzbSsY.js} +2 -2
- package/dist/client/assets/chunk-FVRAUYC3-C7b9SJ81.js +1 -0
- package/dist/client/assets/{chunk-GMAD6QVW-Bgk8qnty.js → chunk-GMAD6QVW-DnZH7DxV.js} +1 -1
- package/dist/client/assets/{chunk-GVQU2GXP-CQ8cl-Uu.js → chunk-GVQU2GXP-B0Vm415C.js} +1 -1
- package/dist/client/assets/chunk-H5A3YXKD-ChP7mNJq.js +41 -0
- package/dist/client/assets/{chunk-742MDFTN-D1nh6vNv.js → chunk-HJ2JQQFS-DQX7RePR.js} +1 -1
- package/dist/client/assets/{chunk-NETBCI7D-CmUwDWUZ.js → chunk-HTAEGDNF-C0PA_N-c.js} +1 -1
- package/dist/client/assets/{chunk-IMKFNOWR-CBqxfpcP.js → chunk-IMKFNOWR-DoO8IHzF.js} +1 -1
- package/dist/client/assets/{chunk-IH6LHLGP-BNevEHZK.js → chunk-KPI5JJXK-B2ld5-w4.js} +1 -1
- package/dist/client/assets/{chunk-WEXAMYUT-DDlVNp8J.js → chunk-KQW6MTUR-OQ4MyMr_.js} +1 -1
- package/dist/client/assets/{chunk-L3NEJ4N5-BflzkdTI.js → chunk-L3NEJ4N5-CvHossEU.js} +1 -1
- package/dist/client/assets/chunk-NGNAAXSQ-DqoPQk1a.js +136 -0
- package/dist/client/assets/{chunk-UA2S7LBM-DicYDjDM.js → chunk-NTY3LDVX-CVWLK_fh.js} +1 -1
- package/dist/client/assets/{chunk-UY3FDG6J-QT-rkt0y.js → chunk-OD3NTWWA-Dz9nCUGX.js} +1 -1
- package/dist/client/assets/{chunk-OSK3NFVY-DqeKV_pg.js → chunk-OSK3NFVY-C3JOcBao.js} +1 -1
- package/dist/client/assets/{chunk-P2QGCYS3-BA--DhpW.js → chunk-P2QGCYS3-Bfo8qS8r.js} +1 -1
- package/dist/client/assets/{chunk-POPQ4Y6H-V_NEc45n.js → chunk-POPQ4Y6H-sv6rCftH.js} +1 -1
- package/dist/client/assets/{chunk-PWAF6VOD-D_kLse-N.js → chunk-PWAF6VOD-B-AT-L2H.js} +1 -1
- package/dist/client/assets/{chunk-3Z5EZCMW-BAnA6eQ7.js → chunk-QNH66VMT-Cb9xxTwQ.js} +1 -1
- package/dist/client/assets/{chunk-SHT3W25Y-YM3S-A_M.js → chunk-SHT3W25Y-C1lu518T.js} +1 -1
- package/dist/client/assets/{chunk-GNY47TPC-CTrH5O5R.js → chunk-SVEVUXB4-BnM-LXop.js} +1 -1
- package/dist/client/assets/{chunk-SVP7TREG-DdNhDOmW.js → chunk-SVP7TREG-CKqt0syj.js} +1 -1
- package/dist/client/assets/{chunk-TICWLB2K-BGGgCr4x.js → chunk-TICWLB2K-D2ZnWAfF.js} +1 -1
- package/dist/client/assets/{chunk-TLUHSLCS-DCZhIDYA.js → chunk-TLUHSLCS-BMIhqv1X.js} +1 -1
- package/dist/client/assets/{chunk-6EIED4P4-DBVWq7Tz.js → chunk-TPMEZKFX-DIPHIqGb.js} +1 -1
- package/dist/client/assets/{chunk-6TQVIW2G-BSj0l_pu.js → chunk-VPELOWWC-DXayM28-.js} +1 -1
- package/dist/client/assets/chunk-VPRB5NB3-BqaJfj_v.js +127 -0
- package/dist/client/assets/{chunk-I5DQTOEV-aBZooNp1.js → chunk-VTWWFHGB-SZnJiyWY.js} +1 -1
- package/dist/client/assets/{chunk-KI3K4JFJ-FTtDwx3-.js → chunk-VZTHESGH-eHyXmK8W.js} +1 -1
- package/dist/client/assets/{chunk-7INBJB4K-CDmiHbaX.js → chunk-XC4XBNZT-D9oehSn8.js} +20 -20
- package/dist/client/assets/{chunk-XHIXRSVI-DN_fEwws.js → chunk-YK26KJH5-DVy3MGMd.js} +1 -1
- package/dist/client/assets/{chunk-6AEJRKK7-DTVZj5bY.js → chunk-Z6ETV63D-DOcrnz-P.js} +1 -1
- package/dist/client/assets/{chunk-OUJLGHUK-75UXlPjl.js → chunk-ZO67DCNQ-BAOMIkLF.js} +1 -1
- package/dist/client/assets/classDiagram-ZZMXUADV-BmETdFmC.js +1 -0
- package/dist/client/assets/{classDiagram-v2-NBCMYWYE-3TQORq33.js → classDiagram-v2-K4WV4PDN-eaadfJDB.js} +3 -3
- package/dist/client/assets/classDiagram-v2-VYDZK3BY-BmETdFmC.js +1 -0
- package/dist/client/assets/{comment-markdown-renderer-Bxi_JRSR.js → comment-markdown-renderer-CpBKaj7H.js} +1 -1
- package/dist/client/assets/comment-thread-store-DUQsWtnu.js +1 -0
- package/dist/client/assets/comment-threads-DnfkLVJA.js +4 -0
- package/dist/client/assets/comment-ui-shared-D_pgPUti.js +7 -0
- package/dist/client/assets/cynefin-EF2NZ3EQ-DVkJeZ8i.js +1 -0
- package/dist/client/assets/cynefin-OW5HDTMX-CF3N9j1_.js +1 -1
- package/dist/client/assets/{cynefinDiagram-VND7K2PF-DwfMZ3vk.js → cynefinDiagram-3GCD6N5R-DjpAsBHC.js} +1 -1
- package/dist/client/assets/{cynefinDiagram-5FMLGOSQ-DTnLZaO7.js → cynefinDiagram-5FMLGOSQ-D2rFQG67.js} +1 -1
- package/dist/client/assets/dagre-C-rnJpZF.js +1 -0
- package/dist/client/assets/{dagre-GXQ25YYZ-Vtyx08Qh.js → dagre-GXQ25YYZ-Cku9eia9.js} +2 -2
- package/dist/client/assets/{dagre-6A5THRUB-DewyAGK6.js → dagre-W4DXFKR2-DOMOIsPd.js} +2 -2
- package/dist/client/assets/deferred-collab-C9aa9cvT.css +1 -0
- package/dist/client/assets/deferred-git-BPQ-UgrN.css +1 -0
- package/dist/client/assets/deferred-preview-B-RebLry.css +1 -0
- package/dist/client/assets/{diagram-22UHCM2B-DbZirFfl.js → diagram-2UJZ2QOL-D8WvnEyx.js} +6 -6
- package/dist/client/assets/{diagram-3UASUU5V-DmhdYv6_.js → diagram-OVF4WLC6-D8_escYE.js} +2 -2
- package/dist/client/assets/{diagram-CDSNMT55-D_qyS11R.js → diagram-PFPMY2P6-B1izZfrN.js} +3 -3
- package/dist/client/assets/{diagram-S7CK7UJ4-CGTzfo2f.js → diagram-S7CK7UJ4-BzicH2t-.js} +1 -1
- package/dist/client/assets/{diagram-MLGK6HIB-DIBG6Ivu.js → diagram-UMYRVEAY-Djf7WDjZ.js} +1 -1
- package/dist/client/assets/{diagram-UQ7AKVKN-CWZS8QtB.js → diagram-UQ7AKVKN-DqX4zTtr.js} +1 -1
- package/dist/client/assets/{diagram-VSXAHHWV-DaO1nOZF.js → diagram-VSXAHHWV-DnVbfI4Y.js} +1 -1
- package/dist/client/assets/{diagram-VX7I27RA-B54P6Cyf.js → diagram-VX7I27RA-D-Dj0TQC.js} +1 -1
- package/dist/client/assets/{diagram-MPIPVDR6-D9XsALDV.js → diagram-YEKJPTXX-B40bP3Yr.js} +2 -2
- package/dist/client/assets/{diagram-Z3DM3KII-Cl2EXiXp.js → diagram-Z3DM3KII-_iT7Uz5p.js} +1 -1
- package/dist/client/assets/diagram-ZIFT7M5P-BUUK0oNw.js +3 -0
- package/dist/client/assets/{direct-engine-DdrQKpgq-4QysbH_V.js → direct-engine-DVLMOJWp-DWtWIifK.js} +1 -1
- package/dist/client/assets/dist-26Ce-5t4.js +1 -0
- package/dist/client/assets/dist-8MLNn-I6.js +1 -0
- package/dist/client/assets/dist-Amm5Pr1C.js +1 -0
- package/dist/client/assets/dist-BXXPaoUV.js +1 -0
- package/dist/client/assets/{dist-zHDLm1oE.js → dist-Bkb-_VdB.js} +1 -1
- package/dist/client/assets/dist-Bl4yuUS9.js +1 -0
- package/dist/client/assets/{dist-CKf7LlAo.js → dist-C2CGvCPd.js} +1 -1
- package/dist/client/assets/dist-C2niyEh0.js +1 -0
- package/dist/client/assets/{dist-Y6zYRI-A.js → dist-CFCSUmJk.js} +1 -1
- package/dist/client/assets/dist-CHUI56fT.js +6 -0
- package/dist/client/assets/dist-CJh3Qrid.js +13 -0
- package/dist/client/assets/{dist-Ch6Sr9KF.js → dist-CKxETpSC.js} +3 -3
- package/dist/client/assets/dist-CSHJthAI.js +2 -0
- package/dist/client/assets/dist-CbKnZGN4.js +1 -0
- package/dist/client/assets/{dist-BVCNc-Es.js → dist-Cik4RJXj.js} +1 -1
- package/dist/client/assets/{dist-DGa-2MNX.js → dist-CqkAY6Ot.js} +2 -2
- package/dist/client/assets/dist-D2ql2LCd.js +1 -0
- package/dist/client/assets/{dist-CvVoyTRF.js → dist-D47MOYFN.js} +1 -1
- package/dist/client/assets/dist-DBhUaexM.js +1 -0
- package/dist/client/assets/dist-DJux6Vc5.js +1 -0
- package/dist/client/assets/{dist-CXOUa90Q.js → dist-DLNdMWPH.js} +1 -1
- package/dist/client/assets/dist-DPJj-Y3l.js +1 -0
- package/dist/client/assets/{dist-DI6c02Da.js → dist-DRYFMufe.js} +6 -6
- package/dist/client/assets/{dist-CUsXdnU4.js → dist-DTGcVSU8.js} +1 -1
- package/dist/client/assets/dist-DlOxjzWi.js +9 -0
- package/dist/client/assets/{dist-BfpAc922.js → dist-DogjjM_B.js} +1 -1
- package/dist/client/assets/dist-Dyv_RvyB.js +23 -0
- package/dist/client/assets/dist-FUFeH5Cx.js +1 -0
- package/dist/client/assets/dist-It70ktCU.js +1 -0
- package/dist/client/assets/dist-QMvcnJHf.js +1 -0
- package/dist/client/assets/dist-QN1K2czv.js +11 -0
- package/dist/client/assets/dist-W8ilOKl3.js +1 -0
- package/dist/client/assets/dist-_17-t9qP.js +1 -0
- package/dist/client/assets/{dist-CsQTfQFi.js → dist-uE774WWs.js} +1 -1
- package/dist/client/assets/document-formatter-DtXmKZcy.js +1 -0
- package/dist/client/assets/drawioEditor-DO6IOaJ1.js +9 -0
- package/dist/client/assets/{ebnfDiagram-PWID7BFC-PfC84FyI.js → ebnfDiagram-PWID7BFC-IemGPf9X.js} +1 -1
- package/dist/client/assets/{ebnfDiagram-ZINNZB2B-DYvm_QtE.js → ebnfDiagram-VR2GEFS7-9fXqy1DI.js} +1 -1
- package/dist/client/assets/editor-session-CPsqXY_A.js +13 -0
- package/dist/client/assets/elk-IJKZMXRS-DsbrbBYg.js +27 -0
- package/dist/client/assets/embedded-editor-base-C44ZcCZv.css +1 -0
- package/dist/client/assets/{embedpdf-DyOonRvx.js → embedpdf-BfUI-3pv.js} +1 -1
- package/dist/client/assets/{embedpdf-DA4bA119-DsoNiPlQ.js → embedpdf-cl9qiF45-CLMxJTMP.js} +3 -3
- package/dist/client/assets/en-7ZVUCEYH-C_VXKxxb.js +1 -0
- package/dist/client/assets/{erDiagram-OPXOYQCR-o8GRv8A_.js → erDiagram-O2IAPWRE-Cdadm-HN.js} +2 -2
- package/dist/client/assets/{erDiagram-RLTQ6QDP-C9cJl5NB.js → erDiagram-RLTQ6QDP-CGGmjm8t.js} +1 -1
- package/dist/client/assets/{estree-DCT3Jm65.js → estree-DGmLqopC.js} +17 -17
- package/dist/client/assets/eventmodeling-K75KTNOO-BWBlZ5cR.js +1 -0
- package/dist/client/assets/eventmodeling-NTZA5JFV-CDy1bN6j.js +1 -1
- package/dist/client/assets/excalidraw-element-link-NQnskRkm.js +1 -0
- package/dist/client/assets/excalidraw-scene-DLlw4jyc.js +1 -0
- package/dist/client/assets/excalidrawEditor-DiKOIudt.css +1 -0
- package/dist/client/assets/excalidrawEditor-W2lZ5Mej.js +9 -0
- package/dist/client/assets/export-page-Bomh9oEr.js +46 -0
- package/dist/client/assets/exportDocument-BFIOECJ3.js +2 -0
- package/dist/client/assets/exportDocument-D0mONgQ4.css +1 -0
- package/dist/client/assets/file-kind-BGxTVHan.js +1 -0
- package/dist/client/assets/{file-search-3hYF4cYa.js → file-search-Dk2O14Vw.js} +1 -1
- package/dist/client/assets/flowDiagram-HODETNUW-DcVVYJUZ.js +1 -0
- package/dist/client/assets/flowDiagram-OXPTDLAJ-Dy6y46oF.js +1 -0
- package/dist/client/assets/{ganttDiagram-EL5Y4UJY-x40PW0Ah.js → ganttDiagram-EL5Y4UJY-Duu4KnsU.js} +1 -1
- package/dist/client/assets/ganttDiagram-R7TSEDQI-BWy52pjn.js +292 -0
- package/dist/client/assets/gitGraph-4MIJSDKK-B-rpDYbz.js +1 -1
- package/dist/client/assets/gitGraph-VSP46ZUC-1499lQAI.js +1 -0
- package/dist/client/assets/{gitGraphDiagram-WWUBYQGX-ahsNaZsp.js → gitGraphDiagram-WWUBYQGX-CaJ0vC1a.js} +1 -1
- package/dist/client/assets/gitGraphDiagram-XJZIOB7I-DJwp9ilx.js +106 -0
- package/dist/client/assets/graphlib-DS17s2tU.js +1 -0
- package/dist/client/assets/{html-CBXMuS97.js → html-BryNQ_yx.js} +6 -6
- package/dist/client/assets/image-6XY3GD3F-DCWbu6d4.js +1 -0
- package/dist/client/assets/image-lightbox-controller-DAcXEXxT.js +184 -0
- package/dist/client/assets/index-CglpXOg7.css +1 -0
- package/dist/client/assets/index-D3WGkxfI.js +960 -0
- package/dist/client/assets/info-A6RAGUB7-BlutK7BT.js +1 -1
- package/dist/client/assets/info-OHQRW6UA-BDFQOo4H.js +1 -0
- package/dist/client/assets/{infoDiagram-27XIBGKW-MrZyptIy.js → infoDiagram-27XIBGKW-DBJh7QOu.js} +1 -1
- package/dist/client/assets/{infoDiagram-VRGFBTTK-KkUjDRAQ.js → infoDiagram-5W2HQ5XZ-DmWsqJ0w.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-5VMMS53U-Bnt9yM0O.js → ishikawaDiagram-5VMMS53U-CeEbSJem.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-OU5B5YK6-Di9BcpOY.js → ishikawaDiagram-K3B6WC7H-DH1NI35G.js} +2 -2
- package/dist/client/assets/{journeyDiagram-3NMN7TZE-Bl0abK1r.js → journeyDiagram-3NMN7TZE-BoIEEr6U.js} +1 -1
- package/dist/client/assets/{journeyDiagram-ZHPQQLJL-J-sGrs9e.js → journeyDiagram-COXZFDF6-CnHV2f9V.js} +3 -3
- package/dist/client/assets/{kanban-definition-PNTS6WVX-5ZDV_yIa.js → kanban-definition-P3RFRI5V-Cxvn5ZAG.js} +4 -4
- package/dist/client/assets/{kanban-definition-UXKFOSKX-DMgUfNt0.js → kanban-definition-UXKFOSKX-BY16Tgbr.js} +1 -1
- package/dist/client/assets/keyboard-shortcuts-BWNCBJqw.js +1 -0
- package/dist/client/assets/lobby-presence-DNNXcuwR.js +1 -0
- package/dist/client/assets/{markdown-Bo71X2X2.js → markdown-DU84620G.js} +17 -17
- package/dist/client/assets/markdown-headings-zYEUahfW.js +41 -0
- package/dist/client/assets/{markdown-math-CyyBVuDO.js → markdown-math-B96cnrz1.js} +11 -11
- package/dist/client/assets/{mermaid-parser.core-Bpogunsh.js → mermaid-parser.core-R-uwU5kf.js} +3 -3
- package/dist/client/assets/{mermaid-parser.core-DBy--Jc0.js → mermaid-parser.core-mE6t1qEO.js} +1 -1
- package/dist/client/assets/mermaid.core-D8Z6LN7O.js +10 -0
- package/dist/client/assets/{mindmap-definition-NLK3R4M7-ByVb-0vj.js → mindmap-definition-LZFPQGKD-DVfFenfJ.js} +3 -3
- package/dist/client/assets/{mindmap-definition-YA3MSWOX-DBZN5_GH.js → mindmap-definition-YA3MSWOX-DtiE80UJ.js} +1 -1
- package/dist/client/assets/packet-AYTQ26CC-DvbY8dI6.js +1 -1
- package/dist/client/assets/packet-JDAUHWVQ-DJ9K2MA4.js +1 -0
- package/dist/client/assets/{pdfium-RAgkpwfK.wasm → pdfium-BJ2Yip8Q.wasm} +0 -0
- package/dist/client/assets/{pegDiagram-GJSIUBJH-aost1sSO.js → pegDiagram-BGZESJAR-DxfvEcwv.js} +1 -1
- package/dist/client/assets/{pegDiagram-XKGWAZYB-DRo8CZu3.js → pegDiagram-XKGWAZYB-CyozY-Kt.js} +1 -1
- package/dist/client/assets/pie-WAS4IAKB-DWSm9SSD.js +1 -1
- package/dist/client/assets/pie-XZMESJXO-CQIQasY-.js +1 -0
- package/dist/client/assets/{pieDiagram-5QR66LMP-BICdpEuz.js → pieDiagram-CAPJLFHJ-CRlMcrv3.js} +2 -2
- package/dist/client/assets/{pieDiagram-E7YTZNPT-CZThaHsc.js → pieDiagram-E7YTZNPT-BRdmTkDq.js} +1 -1
- package/dist/client/assets/preload-helper-CYtfOYgs.js +1 -0
- package/dist/client/assets/preview-render-compiler-D_aJv7Ew.js +3 -0
- package/dist/client/assets/{preview-render-worker-BI2bFVqM.js → preview-render-worker-dFNyrVyB.js} +47 -43
- package/dist/client/assets/prod-ItolaHmf.js +145 -0
- package/dist/client/assets/prod-rdly4JJQ.js +1 -0
- package/dist/client/assets/{quadrantDiagram-AXDQQJYC-C5iowkl_.js → quadrantDiagram-AXDQQJYC-7QyPIXkF.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-O4NWA36T-Bgx5bF97.js → quadrantDiagram-GDMTTRAM-DE30uqTl.js} +3 -3
- package/dist/client/assets/quick-switcher-controller-DsK70I7K.js +1 -0
- package/dist/client/assets/radar-ABXABTNO-ByfpCXh9.js +1 -0
- package/dist/client/assets/radar-RG4KPBEZ-BfNQUEQy.js +1 -1
- package/dist/client/assets/railroad-74A4TZTK-BaQ6U6eJ.js +1 -1
- package/dist/client/assets/railroad-I3PHUGI6-CTUn9HhI.js +1 -0
- package/dist/client/assets/railroad-abnf-HS5TGJTU-BJ3KZw7J.js +1 -1
- package/dist/client/assets/railroad-abnf-LNEFI6M7-Ct-b-y0F.js +1 -0
- package/dist/client/assets/railroad-ebnf-DWYD2UWJ-BZMYMWOe.js +1 -0
- package/dist/client/assets/railroad-ebnf-LZEXJU2U-DA0sEq7w.js +1 -1
- package/dist/client/assets/railroad-peg-JR7BVNR7-Dj23PxYc.js +1 -0
- package/dist/client/assets/railroad-peg-WCYAUIDC-DCmlICzO.js +1 -1
- package/dist/client/assets/{railroadDiagram-O6MQD6OU-BTt_rKjT.js → railroadDiagram-O6MQD6OU-BPk3RS2D.js} +1 -1
- package/dist/client/assets/{railroadDiagram-XR7U4H2S-DbVoNgSz.js → railroadDiagram-SM67HX2B-CZRXJ647.js} +1 -1
- package/dist/client/assets/{requirementDiagram-BXWQKSXE-BkvazG7r.js → requirementDiagram-BXWQKSXE-BRwfym6z.js} +1 -1
- package/dist/client/assets/{requirementDiagram-PLB6GJNP-BT0j9C40.js → requirementDiagram-X7JNWC4A-BofCuLJA.js} +4 -4
- package/dist/client/assets/runtime-config-CvrkHb0n.js +1 -0
- package/dist/client/assets/runtime-paths-qQGhzNx4.js +1 -0
- package/dist/client/assets/{sankeyDiagram-P5KCCOFB-C_IemB9h.js → sankeyDiagram-P5KCCOFB-D4LcrKpW.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-IPEJSGJF-X1BCUIrf.js → sankeyDiagram-UM26HJRW-CLKMDbej.js} +3 -3
- package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-CxFBgLGd.js → sequenceDiagram-WJ2MYXX4-DQjtv-Bs.js} +1 -1
- package/dist/client/assets/sequenceDiagram-ZO4K6R2Y-CDP_m6ma.js +169 -0
- package/dist/client/assets/sizeCapture-INFHLROL-3uHXrFqA.js +1 -0
- package/dist/client/assets/sizeCapture-INFHLROL-BMR1ovSU.js +1 -0
- package/dist/client/assets/src-D5mvpivG.js +2 -0
- package/dist/client/assets/{standalone-6z5x8CWe.js → standalone-D_lg5NC9.js} +1 -1
- package/dist/client/assets/{stateDiagram-D77RDMKH-BaSQ6Owj.js → stateDiagram-D77RDMKH-DSMvV-kF.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-MP3YSRHH-ClmOOUsT.js +1 -0
- package/dist/client/assets/{stateDiagram-v2-GCMORJYK-CsVcfwVp.js → stateDiagram-v2-TBUQTH76-Dc5-FKzd.js} +2 -2
- package/dist/client/assets/{swimlanes-42K2YHIH-CALFEmiS.js → swimlanes-42K2YHIH-BUz31lO3.js} +1 -1
- package/dist/client/assets/{swimlanes-2SLR337P-CnYTVqRX.js → swimlanes-N4OXWK64-Dd3dFdPD.js} +1 -1
- package/dist/client/assets/swimlanesDiagram-K3J5GTZL-Bz9gFdls.js +8 -0
- package/dist/client/assets/swimlanesDiagram-VR7AAH4N-DoDs3zod.js +8 -0
- package/dist/client/assets/{timeline-definition-24CTP7MA-zse-5Dbm.js → timeline-definition-24CTP7MA-BvqCvSjy.js} +1 -1
- package/dist/client/assets/{timeline-definition-EJHVYXUP-BhqPlKkN.js → timeline-definition-YOQAKGHF-D2XWPSLs.js} +3 -3
- package/dist/client/assets/treeView-D4JQ5SDB-DcX7Bx0H.js +1 -0
- package/dist/client/assets/treeView-Q6P3EWNA-BvHOzbu9.js +1 -1
- package/dist/client/assets/treemap-SAJKECNS-BcCHmcAX.js +1 -0
- package/dist/client/assets/treemap-WGGIJYW6-oety7paS.js +1 -1
- package/dist/client/assets/usecaseDiagram-VIAY4XPW-CDe-IMjS.js +328 -0
- package/dist/client/assets/vault-api-client-DrRW0QwO.js +7 -0
- package/dist/client/assets/{vennDiagram-4TSXK5OY-DgHr6cJD.js → vennDiagram-4TSXK5OY-BW6Qp12d.js} +1 -1
- package/dist/client/assets/{vennDiagram-UO4OBE2U-BRwLn2Q1.js → vennDiagram-BLWOH2XV-KxIPKpHi.js} +3 -3
- package/dist/client/assets/wardley-7MLQ67FV-DOahSwbZ.js +1 -0
- package/dist/client/assets/wardley-WFR3VGLG-BdwDpX_I.js +1 -1
- package/dist/client/assets/{wardleyDiagram-VM6X3IG4-9A60XZis.js → wardleyDiagram-VM6X3IG4-BoCETVsK.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-VNRHLVJA-B_tMcVFG.js → wardleyDiagram-YMQ3BMBF-BNYqEy7M.js} +4 -4
- package/dist/client/assets/{wiki-link-resolver-Dch88erO.js → wiki-link-resolver-BCdGUpdu.js} +1 -1
- package/dist/client/assets/{worker-engine-m0rlHn8R-5h66k403.js → worker-engine-BCCrxWYm-1fphds7O.js} +1 -1
- package/dist/client/assets/workspace-sync-client-C_P9wtjf.js +1 -0
- package/dist/client/assets/{xychartDiagram-S5SC5T6Z-D00iy-wB.js → xychartDiagram-S5SC5T6Z-eB5Fu9P7.js} +1 -1
- package/dist/client/assets/xychartDiagram-TAQBALBS-Sv6aaptV.js +7 -0
- package/dist/client/assets/yjs-Jd9fna_Y.js +4 -0
- package/dist/client/assets/yjs-provider-reset-guard-Cqu0Z6xH.js +1 -0
- package/dist/client/canvas-editor.html +16 -0
- package/dist/client/drawio-editor.html +9 -8
- package/dist/client/excalidraw-editor.html +33 -32
- package/dist/client/export-document.html +4 -3
- package/dist/client/index.html +13 -2
- package/package.json +31 -33
- package/scripts/local-compose.mjs +101 -0
- package/src/client/app/canvas-editor.html +13 -0
- package/src/client/app/index.html +11 -0
- package/src/client/app/main-entry.js +30 -4
- package/src/client/application/app-shell/git-feature.js +3 -2
- package/src/client/application/app-shell/ui-feature-identity.js +1 -0
- package/src/client/application/app-shell/ui-feature-shell.js +2 -0
- package/src/client/application/app-shell/ui-feature-tab-activity.js +4 -0
- package/src/client/application/app-shell/workspace-feature.js +8 -34
- package/src/client/application/diagram-chrome.js +8 -11
- package/src/client/application/diagram-preview-hydrator.js +5 -5
- package/src/client/application/mermaid-preview-hydrator.js +3 -2
- package/src/client/application/plantuml-preview-hydrator.js +6 -0
- package/src/client/application/preview-render-compiler.js +34 -98
- package/src/client/application/preview-render-executor.js +3 -0
- package/src/client/application/preview-render-worker.js +2 -0
- package/src/client/application/preview-renderer.js +9 -5
- package/src/client/application/workspace-coordinator.js +18 -10
- package/src/client/application/workspace-preview-controller.js +105 -158
- package/src/client/application/workspace-route-controller.js +29 -54
- package/src/client/bootstrap/canvas-markdown-preview.js +87 -0
- package/src/client/bootstrap/collabmd-app-shell.js +31 -14
- package/src/client/browser-utils.js +21 -0
- package/src/client/canvas-editor.js +143 -0
- package/src/client/domain/canvas-view.js +50 -0
- package/src/client/domain/excalidraw-scene.js +4 -49
- package/src/client/domain/file-search.js +1 -1
- package/src/client/domain/highlight-runtime.js +0 -4
- package/src/client/domain/markdown-formatting.js +12 -94
- package/src/client/domain/markdown-headings.js +98 -0
- package/src/client/domain/runtime-paths.js +4 -0
- package/src/client/domain/wiki-link-completions.js +42 -10
- package/src/client/infrastructure/browser-preferences-port.js +27 -33
- package/src/client/infrastructure/canvas-room-client.js +210 -0
- package/src/client/infrastructure/canvas-text-editor.js +36 -0
- package/src/client/infrastructure/comment-thread-store.js +19 -77
- package/src/client/infrastructure/editor-view-adapter.js +0 -30
- package/src/client/infrastructure/excalidraw-room-client.js +22 -10
- package/src/client/infrastructure/hosted-api-client.js +4 -2
- package/src/client/infrastructure/runtime-config.js +14 -0
- package/src/client/infrastructure/vault-api-client.js +4 -4
- package/src/client/presentation/canvas-editor-view.js +1028 -0
- package/src/client/presentation/canvas-embed-controller.js +116 -0
- package/src/client/presentation/canvas-picker.js +111 -0
- package/src/client/presentation/drawio-embed-controller.js +4 -4
- package/src/client/presentation/excalidraw-embed-controller.js +13 -4
- package/src/client/presentation/file-action-controller.js +58 -1
- package/src/client/presentation/file-explorer-controller.js +1 -2
- package/src/client/presentation/file-explorer-view.js +31 -7
- package/src/client/presentation/file-icon-svg.js +1 -1
- package/src/client/presentation/file-tree-state.js +4 -1
- package/src/client/presentation/image-lightbox-controller.js +1 -5
- package/src/client/presentation/team-settings-controller.js +44 -10
- package/src/client/presentation/vault-dashboard.js +63 -0
- package/src/client/styles/components/actions.css +4 -16
- package/src/client/styles/components/surfaces.css +0 -7
- package/src/client/styles/features/comment-card.css +1 -2
- package/src/client/styles/features/comment-markdown.css +0 -18
- package/src/client/styles/features/diagram-preview.css +0 -18
- package/src/client/styles/features/git-branch.css +0 -4
- package/src/client/styles/foundation/themes.css +6 -0
- package/src/client/styles/foundation/utilities.css +3 -2
- package/src/client/styles/layout/editor-page.css +0 -13
- package/src/client/styles/layout/overlays.css +5 -0
- package/src/client/styles/layout/responsive.css +2 -7
- package/src/client/styles/layout/shell.css +165 -1
- package/src/client/styles/layout/view-modes.css +1 -0
- package/src/client/styles/surfaces/canvas-editor.css +239 -0
- package/src/domain/canvas-room-codec.js +359 -0
- package/src/domain/collabmd-content-capabilities.js +10 -1
- package/src/domain/comment-threads.js +49 -5
- package/src/domain/excalidraw-room-codec.js +23 -73
- package/src/domain/excalidraw-scene.js +48 -0
- package/src/domain/file-kind.js +13 -1
- package/src/server/application/workspace-reconciliation.js +0 -14
- package/src/server/config/env.js +39 -6
- package/src/server/domain/backlink-index.js +1 -36
- package/src/server/domain/bases/base-index-snapshot-store.js +41 -24
- package/src/server/domain/bases/base-query-service.js +1 -47
- package/src/server/domain/collaboration/collaboration-room.js +149 -15
- package/src/server/domain/collaboration/room-registry.js +7 -7
- package/src/server/domain/hosted-workspace.js +29 -2
- package/src/server/domain/plantuml-encoder.js +7 -43
- package/src/server/infrastructure/git/diff-service.js +1 -5
- package/src/server/infrastructure/git/history-service.js +18 -2
- package/src/server/infrastructure/git/untracked-files.js +1 -1
- package/src/server/infrastructure/http/create-git-api-command-handler.js +60 -149
- package/src/server/infrastructure/http/create-hosted-api-handler.js +5 -2
- package/src/server/infrastructure/http/create-static-handler.js +3 -1
- package/src/server/infrastructure/http/create-vault-api-query-handler.js +3 -3
- package/src/server/infrastructure/http/http-response.js +2 -36
- package/src/server/infrastructure/http/request-body.js +14 -49
- package/src/server/infrastructure/persistence/hosted-metadata-store.js +12 -3
- package/src/server/infrastructure/persistence/path-utils.js +8 -2
- package/src/server/infrastructure/persistence/vault-file-store.js +26 -60
- package/src/server/{infrastructure/git → shared}/image-mime.js +2 -2
- package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-BEz2BKN1.js +0 -1
- package/dist/client/assets/_basePickBy-QJXUw_pr.js +0 -1
- package/dist/client/assets/_baseUniq-DR4vVjyC.js +0 -1
- package/dist/client/assets/architecture-7GRP2DOG-DJVtYNt-.js +0 -1
- package/dist/client/assets/browser-utils-vlHL9goC.js +0 -1
- package/dist/client/assets/chunk-3FUC2YCW-8tZlhTGX.js +0 -1
- package/dist/client/assets/chunk-4SOEAONT-C3fufoVl.js +0 -40
- package/dist/client/assets/chunk-7M6MHVWA-BDakkknV.js +0 -213
- package/dist/client/assets/chunk-FOHPRMQF-Dmmo5Kak.js +0 -161
- package/dist/client/assets/chunk-O7XYJQB3-D0_ZY2za.js +0 -126
- package/dist/client/assets/chunk-Z7XXMR3K-P4Vaq8hD.js +0 -10
- package/dist/client/assets/chunk-ZIGJFQKS-b8OUHKK5.js +0 -2
- package/dist/client/assets/classDiagram-ZZMXUADV-QLbh_Nkf.js +0 -1
- package/dist/client/assets/classDiagram-v2-VYDZK3BY-QLbh_Nkf.js +0 -1
- package/dist/client/assets/comment-thread-store-CHvy8GF8.js +0 -1
- package/dist/client/assets/comment-threads-nJhK1yfc.js +0 -4
- package/dist/client/assets/cynefin-OW5HDTMX-e-Quc9Yl.js +0 -1
- package/dist/client/assets/dagre-D7FiCLLP.js +0 -1
- package/dist/client/assets/deferred-collab-D4cxEdad.css +0 -1
- package/dist/client/assets/deferred-git-BHKtkFYi.css +0 -1
- package/dist/client/assets/deferred-preview-BAXYgf4T.css +0 -1
- package/dist/client/assets/diagram-ATOU4E4O-B5uX-jVO.js +0 -3
- package/dist/client/assets/dist-B7fBbwrO.js +0 -1
- package/dist/client/assets/dist-BYBF4LtZ.js +0 -1
- package/dist/client/assets/dist-B_1hMrc6.js +0 -1
- package/dist/client/assets/dist-BnVaoRgZ.js +0 -1
- package/dist/client/assets/dist-Bog8M5U3.js +0 -13
- package/dist/client/assets/dist-CAG5sIOj.js +0 -1
- package/dist/client/assets/dist-CYMCikZo.js +0 -1
- package/dist/client/assets/dist-CYfPeupF.js +0 -1
- package/dist/client/assets/dist-Ck-B8onw.js +0 -2
- package/dist/client/assets/dist-CrkYYcOU.js +0 -1
- package/dist/client/assets/dist-Cu5Ze2cs.js +0 -6
- package/dist/client/assets/dist-D4kDR0g8.js +0 -1
- package/dist/client/assets/dist-D8LnhZzy.js +0 -1
- package/dist/client/assets/dist-DNONgI1P.js +0 -11
- package/dist/client/assets/dist-DVBYH83t.js +0 -1
- package/dist/client/assets/dist-DX6qtdxv.js +0 -1
- package/dist/client/assets/dist-Da-jLrCf.js +0 -1
- package/dist/client/assets/dist-DofvCYzJ.js +0 -1
- package/dist/client/assets/dist-Dx37MHWs.js +0 -1
- package/dist/client/assets/dist-GTGhtpyW.js +0 -9
- package/dist/client/assets/dist-W0FoeIxk.js +0 -23
- package/dist/client/assets/dist-jVKfryIL.js +0 -1
- package/dist/client/assets/document-formatter-gO8qM2qY.js +0 -1
- package/dist/client/assets/drawioEditor-DCkWweiy.js +0 -9
- package/dist/client/assets/editor-session-DxRyr4EM.js +0 -14
- package/dist/client/assets/elk-276RUBZZ-B8LB3Pac.js +0 -27
- package/dist/client/assets/embedded-editor-base-elU0Avik.css +0 -1
- package/dist/client/assets/en-GNC3RJIS-CEy_oGTd.js +0 -1
- package/dist/client/assets/eventmodeling-NTZA5JFV-Dxtv5D-P.js +0 -1
- package/dist/client/assets/excalidraw-element-link-CGZ5934B.js +0 -7
- package/dist/client/assets/excalidraw-scene-6uROebca.js +0 -1
- package/dist/client/assets/excalidrawEditor-BCTFp_CV.css +0 -1
- package/dist/client/assets/excalidrawEditor-BVfSxjSO.js +0 -9
- package/dist/client/assets/export-page-BCo_e15t.js +0 -46
- package/dist/client/assets/exportDocument-Ba-n1X4U.css +0 -1
- package/dist/client/assets/exportDocument-DP6oE_or.js +0 -2
- package/dist/client/assets/file-kind-BwMIcZbi.js +0 -1
- package/dist/client/assets/flowDiagram-HODETNUW-Bq4470NR.js +0 -1
- package/dist/client/assets/flowDiagram-KWPJA3E3-DQG9qGiU.js +0 -1
- package/dist/client/assets/ganttDiagram-FUAMR5RP-BQpsI7gQ.js +0 -292
- package/dist/client/assets/gitGraph-4MIJSDKK-ZaBIE4Lb.js +0 -1
- package/dist/client/assets/gitGraphDiagram-X574FWY7-wbs_2m9f.js +0 -106
- package/dist/client/assets/graphlib-C9Tl7QrK.js +0 -1
- package/dist/client/assets/image-EJJKRVD3-BQfi5nWJ.js +0 -1
- package/dist/client/assets/index-BxAuGDoN.css +0 -1
- package/dist/client/assets/index-uw9O0z1c.js +0 -1112
- package/dist/client/assets/info-A6RAGUB7-BcGxhjED.js +0 -1
- package/dist/client/assets/lobby-presence-Cz5jGOPg.js +0 -1
- package/dist/client/assets/mermaid.core-BeOUPE3Q.js +0 -10
- package/dist/client/assets/packet-AYTQ26CC-CqpSjTWl.js +0 -1
- package/dist/client/assets/pie-WAS4IAKB-Bg2eCNl5.js +0 -1
- package/dist/client/assets/preload-helper-BAlEavIC.js +0 -1
- package/dist/client/assets/preview-render-compiler-ktU0SXxY.js +0 -43
- package/dist/client/assets/prod-DU-0VfI7.js +0 -145
- package/dist/client/assets/prod-cXUNdmYV.js +0 -1
- package/dist/client/assets/quick-switcher-controller-DSlOwOsU.js +0 -1
- package/dist/client/assets/radar-RG4KPBEZ-DxExotg6.js +0 -1
- package/dist/client/assets/railroad-74A4TZTK-FfHmeIQk.js +0 -1
- package/dist/client/assets/railroad-abnf-HS5TGJTU-CLkdDRsJ.js +0 -1
- package/dist/client/assets/railroad-ebnf-LZEXJU2U-B162zvcG.js +0 -1
- package/dist/client/assets/railroad-peg-WCYAUIDC-CGs5GeJ5.js +0 -1
- package/dist/client/assets/runtime-config-BFVdhnJu.js +0 -1
- package/dist/client/assets/runtime-paths-Cn0snt_9.js +0 -1
- package/dist/client/assets/sequenceDiagram-PO4LG4MO-B-2QfXhV.js +0 -169
- package/dist/client/assets/sizeCapture-INFHLROL-B0uUizjq.js +0 -1
- package/dist/client/assets/sizeCapture-INFHLROL-DrzwYt5z.js +0 -1
- package/dist/client/assets/stateDiagram-v2-MP3YSRHH-CLlwrdvU.js +0 -1
- package/dist/client/assets/swimlanesDiagram-TC7HE7FX-Bh4tmz27.js +0 -8
- package/dist/client/assets/swimlanesDiagram-VR7AAH4N-xhehUG9e.js +0 -8
- package/dist/client/assets/treeView-Q6P3EWNA-Cccy0ngL.js +0 -1
- package/dist/client/assets/treemap-WGGIJYW6-sMRCjCtX.js +0 -1
- package/dist/client/assets/usecaseDiagram-POWQR4AR-DR2LHQYs.js +0 -328
- package/dist/client/assets/vault-api-client-BQxLVPeF.js +0 -7
- package/dist/client/assets/wardley-WFR3VGLG-Y7xty_3m.js +0 -1
- package/dist/client/assets/workspace-sync-client-C2pdaQUN.js +0 -1
- package/dist/client/assets/xychartDiagram-PMCCYNJV-fRpZ1MA5.js +0 -7
- package/dist/client/assets/yjs-B41tM6Sz.js +0 -4
- package/dist/client/assets/yjs-provider-reset-guard-DpntzUDR.js +0 -1
- package/scripts/local-plantuml-compose.mjs +0 -92
- package/scripts/local-structurizr-compose.mjs +0 -101
|
@@ -6,6 +6,7 @@ export const COMMENT_ANCHOR_QUOTE_MAX_LENGTH = 280;
|
|
|
6
6
|
export const COMMENT_REACTION_EMOJI_MAX_LENGTH = 16;
|
|
7
7
|
|
|
8
8
|
const COMMENT_ANCHOR_KINDS = new Set(['diagram-element', 'line', 'text']);
|
|
9
|
+
const REACTION_KEY_PREFIX = 'reaction:';
|
|
9
10
|
|
|
10
11
|
function asFiniteNumber(value) {
|
|
11
12
|
return Number.isFinite(value) ? value : null;
|
|
@@ -125,12 +126,16 @@ export function summarizeCommentExcerpt(value, maxLength = COMMENT_EXCERPT_MAX_L
|
|
|
125
126
|
return `${normalized.slice(0, Math.max(maxLength - 1, 1)).trimEnd()}…`;
|
|
126
127
|
}
|
|
127
128
|
|
|
128
|
-
function
|
|
129
|
+
export function normalizeCommentReactionEmoji(value) {
|
|
129
130
|
return Array.from(String(value ?? '').trim())
|
|
130
131
|
.slice(0, COMMENT_REACTION_EMOJI_MAX_LENGTH)
|
|
131
132
|
.join('');
|
|
132
133
|
}
|
|
133
134
|
|
|
135
|
+
export function createCommentReactionKey(messageId, emoji, userId) {
|
|
136
|
+
return `${REACTION_KEY_PREFIX}${JSON.stringify([messageId, emoji, userId])}`;
|
|
137
|
+
}
|
|
138
|
+
|
|
134
139
|
function createReactionUserRecord(user) {
|
|
135
140
|
const userId = asString(readRecordValue(user, 'userId')).trim();
|
|
136
141
|
if (!userId) {
|
|
@@ -146,7 +151,7 @@ function createReactionUserRecord(user) {
|
|
|
146
151
|
}
|
|
147
152
|
|
|
148
153
|
function createReactionGroupRecord(group) {
|
|
149
|
-
const emoji =
|
|
154
|
+
const emoji = normalizeCommentReactionEmoji(readRecordValue(group, 'emoji'));
|
|
150
155
|
if (!emoji) {
|
|
151
156
|
return null;
|
|
152
157
|
}
|
|
@@ -212,10 +217,49 @@ function createMessageRecord(message) {
|
|
|
212
217
|
};
|
|
213
218
|
}
|
|
214
219
|
|
|
215
|
-
function serializeMessages(messages) {
|
|
216
|
-
|
|
220
|
+
function serializeMessages(messages, thread) {
|
|
221
|
+
const records = asArray(messages)
|
|
217
222
|
.map((message) => createMessageRecord(message))
|
|
218
223
|
.filter(Boolean);
|
|
224
|
+
if (!(thread instanceof Y.Map)) {
|
|
225
|
+
return records;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const byId = new Map(records.map((message) => [message.id, message]));
|
|
229
|
+
const overrides = [...thread.entries()]
|
|
230
|
+
.filter(([key]) => key.startsWith(REACTION_KEY_PREFIX))
|
|
231
|
+
.sort(([left], [right]) => left.localeCompare(right));
|
|
232
|
+
for (const [key, value] of overrides) {
|
|
233
|
+
let identity;
|
|
234
|
+
try {
|
|
235
|
+
identity = JSON.parse(key.slice(REACTION_KEY_PREFIX.length));
|
|
236
|
+
} catch {
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
if (!Array.isArray(identity) || identity.length !== 3 || !identity.every((part) => typeof part === 'string')) {
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
const [messageId, rawEmoji, userId] = identity;
|
|
243
|
+
const emoji = normalizeCommentReactionEmoji(rawEmoji);
|
|
244
|
+
const message = byId.get(messageId);
|
|
245
|
+
const user = value === null ? null : createReactionUserRecord(value);
|
|
246
|
+
if (!message || !emoji || !userId || (value !== null && user?.userId !== userId)) {
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const groupIndex = message.reactions.findIndex((group) => group.emoji === emoji);
|
|
251
|
+
const users = new Map((message.reactions[groupIndex]?.users ?? []).map((entry) => [entry.userId, entry]));
|
|
252
|
+
if (user) users.set(userId, user);
|
|
253
|
+
else users.delete(userId);
|
|
254
|
+
if (users.size > 0) {
|
|
255
|
+
const group = { emoji, users: [...users.values()] };
|
|
256
|
+
if (groupIndex < 0) message.reactions.push(group);
|
|
257
|
+
else message.reactions[groupIndex] = group;
|
|
258
|
+
} else if (groupIndex >= 0) {
|
|
259
|
+
message.reactions.splice(groupIndex, 1);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return records;
|
|
219
263
|
}
|
|
220
264
|
|
|
221
265
|
export function createCommentId(prefix = 'comment') {
|
|
@@ -323,7 +367,7 @@ export function serializeCommentThread(thread) {
|
|
|
323
367
|
anchorSnapshot: readThreadValue(thread, 'anchorSnapshot'),
|
|
324
368
|
elementId: readThreadValue(thread, 'elementId'),
|
|
325
369
|
});
|
|
326
|
-
const messages = serializeMessages(readThreadValue(thread, 'messages'));
|
|
370
|
+
const messages = serializeMessages(readThreadValue(thread, 'messages'), thread);
|
|
327
371
|
|
|
328
372
|
if (!anchor || messages.length === 0) {
|
|
329
373
|
return null;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as Y from 'yjs';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import { createEmptyScene, normalizeScene, tryParseSceneJson } from './excalidraw-scene.js';
|
|
4
|
+
|
|
5
|
+
export { tryParseSceneJson as tryParseExcalidrawSceneJson } from './excalidraw-scene.js';
|
|
6
6
|
|
|
7
7
|
export const EXCALIDRAW_APP_STATE_KEY = 'excalidraw-app-state';
|
|
8
8
|
export const EXCALIDRAW_ELEMENTS_KEY = 'excalidraw-elements';
|
|
@@ -13,65 +13,10 @@ export const EXCALIDRAW_ROOM_TEXT_KEY = 'codemirror';
|
|
|
13
13
|
export const EXCALIDRAW_SCHEMA_VERSION_KEY = 'schemaVersion';
|
|
14
14
|
export const EXCALIDRAW_REPLACE_GENERATION_KEY = 'replaceGeneration';
|
|
15
15
|
|
|
16
|
-
function createEmptyScene() {
|
|
17
|
-
return {
|
|
18
|
-
type: EXCALIDRAW_TYPE,
|
|
19
|
-
version: EXCALIDRAW_VERSION,
|
|
20
|
-
source: EXCALIDRAW_SOURCE,
|
|
21
|
-
elements: [],
|
|
22
|
-
appState: {
|
|
23
|
-
gridSize: null,
|
|
24
|
-
viewBackgroundColor: '#ffffff',
|
|
25
|
-
},
|
|
26
|
-
files: {},
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function normalizeAppState(appState = {}) {
|
|
31
|
-
return {
|
|
32
|
-
gridSize: appState?.gridSize ?? null,
|
|
33
|
-
viewBackgroundColor: appState?.viewBackgroundColor ?? '#ffffff',
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function normalizeScene(raw) {
|
|
38
|
-
if (!raw || typeof raw !== 'object') {
|
|
39
|
-
return createEmptyScene();
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return {
|
|
43
|
-
type: EXCALIDRAW_TYPE,
|
|
44
|
-
version: EXCALIDRAW_VERSION,
|
|
45
|
-
source: EXCALIDRAW_SOURCE,
|
|
46
|
-
elements: Array.isArray(raw.elements) ? raw.elements : [],
|
|
47
|
-
appState: normalizeAppState(raw.appState),
|
|
48
|
-
files: raw.files && typeof raw.files === 'object' ? raw.files : {},
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function parseSceneJson(rawJson, { fallbackToEmpty = true } = {}) {
|
|
53
|
-
if (!rawJson) {
|
|
54
|
-
return fallbackToEmpty ? createEmptyScene() : null;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
try {
|
|
58
|
-
return normalizeScene(JSON.parse(rawJson));
|
|
59
|
-
} catch {
|
|
60
|
-
return fallbackToEmpty ? createEmptyScene() : null;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
16
|
function cloneJsonValue(value) {
|
|
65
17
|
return structuredClone(value);
|
|
66
18
|
}
|
|
67
19
|
|
|
68
|
-
function getRevisionKey(element) {
|
|
69
|
-
const version = Number.isFinite(Number(element?.version)) ? Number(element.version) : 0;
|
|
70
|
-
const versionNonce = Number.isFinite(Number(element?.versionNonce)) ? Number(element.versionNonce) : 0;
|
|
71
|
-
const updated = Number.isFinite(Number(element?.updated)) ? Number(element.updated) : 0;
|
|
72
|
-
return `${version}:${versionNonce}:${updated}`;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
20
|
function compareElementVersions(left, right) {
|
|
76
21
|
const leftVersion = Number(left?.version) || 0;
|
|
77
22
|
const rightVersion = Number(right?.version) || 0;
|
|
@@ -143,14 +88,18 @@ function selectWinningElementFromSlot(slot) {
|
|
|
143
88
|
}
|
|
144
89
|
|
|
145
90
|
let winningElement = null;
|
|
146
|
-
|
|
91
|
+
let winningKey = '';
|
|
92
|
+
slot.forEach((value, key) => {
|
|
147
93
|
const candidate = readRevisionEntry(value);
|
|
148
94
|
if (!candidate || !candidate.id) {
|
|
149
95
|
return;
|
|
150
96
|
}
|
|
151
97
|
|
|
152
|
-
|
|
98
|
+
// Y.Map iteration order can differ across replicas; equal revisions need a stable tie-break.
|
|
99
|
+
const comparison = winningElement ? compareElementVersions(candidate, winningElement) : 1;
|
|
100
|
+
if (comparison > 0 || (comparison === 0 && key > winningKey)) {
|
|
153
101
|
winningElement = candidate;
|
|
102
|
+
winningKey = key;
|
|
154
103
|
}
|
|
155
104
|
});
|
|
156
105
|
|
|
@@ -160,12 +109,16 @@ function selectWinningElementFromSlot(slot) {
|
|
|
160
109
|
function writeElementSlot(slot, element, {
|
|
161
110
|
maxRevisions = 2,
|
|
162
111
|
} = {}) {
|
|
163
|
-
|
|
112
|
+
// Each writer keeps its own candidate so concurrent version/nonce winners survive.
|
|
113
|
+
// ponytail: metadata grows with writers, not edits; authoritative replace compacts
|
|
114
|
+
// legacy keys. Never replace a live slot while reconnecting peers can edit it.
|
|
115
|
+
const revisionKey = `writer:${slot.doc.clientID}`;
|
|
116
|
+
const previous = readRevisionEntry(slot.get(revisionKey));
|
|
117
|
+
if (previous && compareElementVersions(element, previous) < 0) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
164
120
|
const serialized = cloneJsonValue(element);
|
|
165
|
-
const
|
|
166
|
-
const previousSerialized = previous && typeof previous === 'object'
|
|
167
|
-
? JSON.stringify(previous)
|
|
168
|
-
: '';
|
|
121
|
+
const previousSerialized = previous ? JSON.stringify(previous) : '';
|
|
169
122
|
const nextSerialized = JSON.stringify(serialized);
|
|
170
123
|
if (previousSerialized === nextSerialized) {
|
|
171
124
|
return false;
|
|
@@ -199,7 +152,8 @@ function pruneElementSlot(slot, maxRevisions = 2) {
|
|
|
199
152
|
if (!right.element) {
|
|
200
153
|
return 1;
|
|
201
154
|
}
|
|
202
|
-
return compareElementVersions(left.element, right.element)
|
|
155
|
+
return compareElementVersions(left.element, right.element)
|
|
156
|
+
|| (left.key < right.key ? -1 : left.key > right.key ? 1 : 0);
|
|
203
157
|
});
|
|
204
158
|
|
|
205
159
|
while (revisions.length > maxRevisions) {
|
|
@@ -328,7 +282,7 @@ export function replaceExcalidrawRoomScene(ydoc, rawScene, {
|
|
|
328
282
|
filesMap.set(key, cloneJsonValue(value));
|
|
329
283
|
});
|
|
330
284
|
|
|
331
|
-
const nextAppState =
|
|
285
|
+
const nextAppState = scene.appState;
|
|
332
286
|
appStateMap.set('gridSize', nextAppState.gridSize);
|
|
333
287
|
appStateMap.set('viewBackgroundColor', nextAppState.viewBackgroundColor);
|
|
334
288
|
meta.set(EXCALIDRAW_REPLACE_GENERATION_KEY, readExcalidrawReplaceGeneration(ydoc) + 1);
|
|
@@ -372,7 +326,7 @@ export function applySceneDiffToExcalidrawRoom(ydoc, rawScene, {
|
|
|
372
326
|
changed = true;
|
|
373
327
|
});
|
|
374
328
|
|
|
375
|
-
const nextAppState =
|
|
329
|
+
const nextAppState = scene.appState;
|
|
376
330
|
Object.entries(nextAppState).forEach(([key, value]) => {
|
|
377
331
|
if (appStateMap.get(key) === value) {
|
|
378
332
|
return;
|
|
@@ -398,7 +352,7 @@ export function readLegacyExcalidrawRoomScene(ydoc) {
|
|
|
398
352
|
}
|
|
399
353
|
|
|
400
354
|
const rawJson = ydoc.getText(EXCALIDRAW_ROOM_TEXT_KEY).toString();
|
|
401
|
-
return
|
|
355
|
+
return tryParseSceneJson(rawJson);
|
|
402
356
|
}
|
|
403
357
|
|
|
404
358
|
export function migrateLegacyExcalidrawRoomData(ydoc, rawScene, options = {}) {
|
|
@@ -406,7 +360,3 @@ export function migrateLegacyExcalidrawRoomData(ydoc, rawScene, options = {}) {
|
|
|
406
360
|
replaceExcalidrawRoomScene(ydoc, scene, options);
|
|
407
361
|
return scene;
|
|
408
362
|
}
|
|
409
|
-
|
|
410
|
-
export function tryParseExcalidrawSceneJson(rawJson) {
|
|
411
|
-
return parseSceneJson(rawJson, { fallbackToEmpty: false });
|
|
412
|
-
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export function createEmptyScene() {
|
|
2
|
+
return {
|
|
3
|
+
type: 'excalidraw',
|
|
4
|
+
version: 2,
|
|
5
|
+
source: 'collabmd',
|
|
6
|
+
elements: [],
|
|
7
|
+
appState: {
|
|
8
|
+
gridSize: null,
|
|
9
|
+
viewBackgroundColor: '#ffffff',
|
|
10
|
+
},
|
|
11
|
+
files: {},
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function normalizeScene(raw) {
|
|
16
|
+
if (!raw || typeof raw !== 'object') {
|
|
17
|
+
return createEmptyScene();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
type: 'excalidraw',
|
|
22
|
+
version: 2,
|
|
23
|
+
source: 'collabmd',
|
|
24
|
+
elements: Array.isArray(raw.elements) ? raw.elements : [],
|
|
25
|
+
appState: {
|
|
26
|
+
gridSize: raw.appState?.gridSize ?? null,
|
|
27
|
+
viewBackgroundColor: raw.appState?.viewBackgroundColor ?? '#ffffff',
|
|
28
|
+
},
|
|
29
|
+
files: raw.files && typeof raw.files === 'object' ? raw.files : {},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function parseSceneJson(rawJson) {
|
|
34
|
+
const parsed = tryParseSceneJson(rawJson);
|
|
35
|
+
return parsed || createEmptyScene();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function tryParseSceneJson(rawJson) {
|
|
39
|
+
if (!rawJson) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
return normalizeScene(JSON.parse(rawJson));
|
|
45
|
+
} catch {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
}
|
package/src/domain/file-kind.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const MARKDOWN_FILE_EXTENSIONS = Object.freeze(['.md', '.markdown', '.mdx']);
|
|
2
2
|
const HTML_FILE_EXTENSIONS = Object.freeze(['.html', '.htm']);
|
|
3
3
|
const BASE_FILE_EXTENSION = '.base';
|
|
4
|
+
const CANVAS_FILE_EXTENSION = '.canvas';
|
|
4
5
|
const EXCALIDRAW_FILE_EXTENSION = '.excalidraw';
|
|
5
6
|
const DRAWIO_FILE_EXTENSION = '.drawio';
|
|
6
7
|
const MERMAID_FILE_EXTENSIONS = Object.freeze(['.mmd', '.mermaid']);
|
|
@@ -10,6 +11,7 @@ const STRUCTURIZR_FILE_EXTENSIONS = Object.freeze([STRUCTURIZR_FILE_EXTENSION]);
|
|
|
10
11
|
const PDF_FILE_EXTENSION = '.pdf';
|
|
11
12
|
const IMAGE_ATTACHMENT_EXTENSIONS = Object.freeze(['.png', '.jpg', '.jpeg', '.webp', '.gif', '.svg']);
|
|
12
13
|
const DIAGRAM_FILE_EXTENSIONS = Object.freeze([
|
|
14
|
+
CANVAS_FILE_EXTENSION,
|
|
13
15
|
EXCALIDRAW_FILE_EXTENSION,
|
|
14
16
|
DRAWIO_FILE_EXTENSION,
|
|
15
17
|
...MERMAID_FILE_EXTENSIONS,
|
|
@@ -24,7 +26,7 @@ const VAULT_FILE_EXTENSIONS = Object.freeze([
|
|
|
24
26
|
PDF_FILE_EXTENSION,
|
|
25
27
|
...IMAGE_ATTACHMENT_EXTENSIONS,
|
|
26
28
|
]);
|
|
27
|
-
const STRIP_VAULT_EXTENSION_PATTERN = /\.(?:md|markdown|mdx|html?|base|excalidraw|drawio|mmd|mermaid|puml|plantuml|dsl|pdf|png|jpe?g|webp|gif|svg)$/i;
|
|
29
|
+
const STRIP_VAULT_EXTENSION_PATTERN = /\.(?:md|markdown|mdx|html?|base|canvas|excalidraw|drawio|mmd|mermaid|puml|plantuml|dsl|pdf|png|jpe?g|webp|gif|svg)$/i;
|
|
28
30
|
|
|
29
31
|
function normalizeFilePath(filePath) {
|
|
30
32
|
return String(filePath ?? '').trim().toLowerCase();
|
|
@@ -37,6 +39,7 @@ function hasFileExtension(filePath, extensions) {
|
|
|
37
39
|
|
|
38
40
|
export {
|
|
39
41
|
BASE_FILE_EXTENSION,
|
|
42
|
+
CANVAS_FILE_EXTENSION,
|
|
40
43
|
DIAGRAM_FILE_EXTENSIONS,
|
|
41
44
|
DRAWIO_FILE_EXTENSION,
|
|
42
45
|
EXCALIDRAW_FILE_EXTENSION,
|
|
@@ -64,6 +67,10 @@ export function getVaultFileKind(filePath) {
|
|
|
64
67
|
return 'base';
|
|
65
68
|
}
|
|
66
69
|
|
|
70
|
+
if (hasFileExtension(filePath, [CANVAS_FILE_EXTENSION])) {
|
|
71
|
+
return 'canvas';
|
|
72
|
+
}
|
|
73
|
+
|
|
67
74
|
if (hasFileExtension(filePath, [EXCALIDRAW_FILE_EXTENSION])) {
|
|
68
75
|
return 'excalidraw';
|
|
69
76
|
}
|
|
@@ -129,6 +136,10 @@ export function isExcalidrawFilePath(filePath) {
|
|
|
129
136
|
return getVaultFileKind(filePath) === 'excalidraw';
|
|
130
137
|
}
|
|
131
138
|
|
|
139
|
+
export function isCanvasFilePath(filePath) {
|
|
140
|
+
return getVaultFileKind(filePath) === 'canvas';
|
|
141
|
+
}
|
|
142
|
+
|
|
132
143
|
export function isBaseFilePath(filePath) {
|
|
133
144
|
return getVaultFileKind(filePath) === 'base';
|
|
134
145
|
}
|
|
@@ -160,6 +171,7 @@ export function isImageAttachmentFilePath(filePath) {
|
|
|
160
171
|
export function isDiagramFilePath(filePath) {
|
|
161
172
|
const kind = getVaultFileKind(filePath);
|
|
162
173
|
return kind === 'excalidraw'
|
|
174
|
+
|| kind === 'canvas'
|
|
163
175
|
|| kind === 'drawio'
|
|
164
176
|
|| kind === 'mermaid'
|
|
165
177
|
|| kind === 'plantuml'
|
|
@@ -11,8 +11,6 @@ import {
|
|
|
11
11
|
createWorkspaceTree,
|
|
12
12
|
deriveNextWorkspaceStateForApiMutation as deriveNextWorkspaceStateFromApiMutation,
|
|
13
13
|
diffWorkspaceEntries,
|
|
14
|
-
isIncrementalWorkspaceMutationAction,
|
|
15
|
-
readWorkspacePathState as readWorkspacePathStateFromAdapter,
|
|
16
14
|
} from '../domain/workspace-state.js';
|
|
17
15
|
|
|
18
16
|
function createEventId() {
|
|
@@ -87,18 +85,6 @@ export class WorkspaceReconciliation {
|
|
|
87
85
|
return this.workspaceTree;
|
|
88
86
|
}
|
|
89
87
|
|
|
90
|
-
isIncrementalApiAction(action) {
|
|
91
|
-
return isIncrementalWorkspaceMutationAction(action);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
async readWorkspacePathState(pathValue, {
|
|
95
|
-
expectDirectory = null,
|
|
96
|
-
} = {}) {
|
|
97
|
-
return readWorkspacePathStateFromAdapter(this.workspaceStateAdapter, pathValue, {
|
|
98
|
-
expectDirectory,
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
|
|
102
88
|
async deriveNextWorkspaceStateForApiMutation(action, workspaceChange = {}) {
|
|
103
89
|
return deriveNextWorkspaceStateFromApiMutation(this.workspaceStateAdapter, {
|
|
104
90
|
action,
|
package/src/server/config/env.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { basename, isAbsolute, relative, resolve } from 'path';
|
|
2
|
-
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { lstatSync, readdirSync, readFileSync } from 'node:fs';
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
4
|
|
|
5
5
|
import {
|
|
@@ -222,11 +222,11 @@ export function parseVaultList(rawValue) {
|
|
|
222
222
|
|
|
223
223
|
export function resolveConfiguredVaults(overrides = {}, env = process.env) {
|
|
224
224
|
if (Array.isArray(overrides.vaults)) {
|
|
225
|
-
return overrides.vaults.map(({ id, dir, repoUrl }) => {
|
|
225
|
+
return overrides.vaults.map(({ id, dir, name, repoUrl }) => {
|
|
226
226
|
if (!VAULT_ID_PATTERN.test(String(id ?? ''))) {
|
|
227
227
|
throw new Error(`Invalid vault id "${id}". ${VAULT_ID_HINT}`);
|
|
228
228
|
}
|
|
229
|
-
return { id, dir: resolve(dir), repoUrl: normalizeOptionalString(repoUrl) };
|
|
229
|
+
return { id, dir: resolve(dir), ...(name ? { name: normalizeOptionalString(name) } : {}), repoUrl: normalizeOptionalString(repoUrl) };
|
|
230
230
|
});
|
|
231
231
|
}
|
|
232
232
|
// ponytail: explicit directory (CLI positional) wins over the operator list
|
|
@@ -235,13 +235,34 @@ export function resolveConfiguredVaults(overrides = {}, env = process.env) {
|
|
|
235
235
|
return [{ id: basename(dir), dir }];
|
|
236
236
|
}
|
|
237
237
|
const rawList = normalizeOptionalString(env.COLLABMD_VAULTS);
|
|
238
|
-
|
|
238
|
+
const discovery = normalizeOptionalString(env.COLLABMD_VAULT_DISCOVERY);
|
|
239
|
+
if (!rawList && !discovery) {
|
|
239
240
|
const dir = resolveConfiguredVaultDir(overrides, env);
|
|
240
241
|
return [{ id: basename(dir), dir }];
|
|
241
242
|
}
|
|
242
|
-
|
|
243
|
+
let vaults;
|
|
244
|
+
if (rawList) {
|
|
245
|
+
vaults = parseVaultList(rawList);
|
|
246
|
+
} else {
|
|
247
|
+
if (!['all', 'marked'].includes(discovery)) {
|
|
248
|
+
throw new Error('COLLABMD_VAULT_DISCOVERY must be "all" or "marked".');
|
|
249
|
+
}
|
|
250
|
+
const root = resolve(env.COLLABMD_VAULT_DIR || '.');
|
|
251
|
+
// ponytail: discover immediate real directories at startup; restart to pick up additions.
|
|
252
|
+
vaults = readdirSync(root, { withFileTypes: true })
|
|
253
|
+
.filter((entry) => entry.isDirectory() && !entry.name.startsWith('.')
|
|
254
|
+
&& (discovery === 'all' || lstatSync(resolve(root, entry.name, '.collabmd'), { throwIfNoEntry: false })?.isDirectory()))
|
|
255
|
+
.sort((a, b) => a.name.localeCompare(b.name, 'en'))
|
|
256
|
+
.map((entry) => ({ id: entry.name, dir: resolve(root, entry.name) }));
|
|
257
|
+
if (vaults.length === 0) {
|
|
258
|
+
throw new Error('No vaults found. Check COLLABMD_VAULT_DIR and COLLABMD_VAULT_DISCOVERY.');
|
|
259
|
+
}
|
|
260
|
+
}
|
|
243
261
|
const seenIds = new Set();
|
|
244
262
|
for (const vault of vaults) {
|
|
263
|
+
if (!VAULT_ID_PATTERN.test(vault.id)) {
|
|
264
|
+
throw new Error(`Invalid vault id "${vault.id}". ${VAULT_ID_HINT}`);
|
|
265
|
+
}
|
|
245
266
|
if (seenIds.has(vault.id)) {
|
|
246
267
|
throw new Error(`Duplicate vault id "${vault.id}" in COLLABMD_VAULTS.`);
|
|
247
268
|
}
|
|
@@ -262,6 +283,17 @@ export function mangleVaultIdForEnv(vaultId) {
|
|
|
262
283
|
return String(vaultId ?? '').toUpperCase().replace(/[^A-Z0-9]/g, '_');
|
|
263
284
|
}
|
|
264
285
|
|
|
286
|
+
export function resolveVaultNames(vaults, env = process.env) {
|
|
287
|
+
return vaults.map((vault) => {
|
|
288
|
+
const suffix = mangleVaultIdForEnv(vault.id);
|
|
289
|
+
const name = normalizeOptionalString(env[`COLLABMD_VAULT_NAME_${suffix}`]);
|
|
290
|
+
if (name && vaults.filter((entry) => mangleVaultIdForEnv(entry.id) === suffix).length > 1) {
|
|
291
|
+
throw new Error(`Ambiguous vault name: multiple vaults share COLLABMD_VAULT_NAME_${suffix}.`);
|
|
292
|
+
}
|
|
293
|
+
return { ...vault, name: vault.name || name || vault.id };
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
|
|
265
297
|
// ponytail: explicit repoUrl wins, then COLLABMD_GIT_REPO_URL_<ID>, then the shared URL for the primary
|
|
266
298
|
export function resolveVaultRepoUrls(vaultDefs = [], overrides = {}, env = process.env) {
|
|
267
299
|
const globalRepoUrl = normalizeOptionalString(overrides.remote?.repoUrl ?? overrides.git?.remote?.repoUrl ?? env.COLLABMD_GIT_REPO_URL);
|
|
@@ -540,7 +572,7 @@ function resolvePublicDir(nodeEnv) {
|
|
|
540
572
|
|
|
541
573
|
export function loadConfig(overrides = {}) {
|
|
542
574
|
const nodeEnv = process.env.NODE_ENV || 'development';
|
|
543
|
-
const vaults = resolveVaultRepoUrls(resolveConfiguredVaults(overrides), overrides);
|
|
575
|
+
const vaults = resolveVaultNames(resolveVaultRepoUrls(resolveConfiguredVaults(overrides), overrides));
|
|
544
576
|
// ponytail: vaultDir stays the primary vault; other vaults resolve through the registry
|
|
545
577
|
const vaultDir = overrides.vaultDir || vaults[0].dir;
|
|
546
578
|
const basePath = normalizeAppBasePath(process.env.BASE_PATH || '');
|
|
@@ -622,6 +654,7 @@ export function loadConfig(overrides = {}) {
|
|
|
622
654
|
publicDir,
|
|
623
655
|
vaultDir,
|
|
624
656
|
vaults,
|
|
657
|
+
vaultDashboard: overrides.vaultDashboard ?? parseBooleanFlag(process.env.COLLABMD_VAULT_DASHBOARD),
|
|
625
658
|
publicWsBaseUrl: process.env.PUBLIC_WS_BASE_URL || '',
|
|
626
659
|
testWsRoomHydrateDelayMs: parsePositiveInt(process.env.TEST_WS_ROOM_HYDRATE_DELAY_MS, 0),
|
|
627
660
|
wikiLinkAutoCreate: process.env.COLLABMD_WIKI_LINK_AUTO_CREATE !== 'false',
|
|
@@ -49,7 +49,6 @@ export class BacklinkIndex {
|
|
|
49
49
|
/** @type {Set<string>} file path membership set */
|
|
50
50
|
this._fileSet = new Set();
|
|
51
51
|
this._wikiTargetIndex = createWikiTargetIndex(this._fileList);
|
|
52
|
-
this._built = false;
|
|
53
52
|
this._requestedBuildVersion = 0;
|
|
54
53
|
this._completedBuildVersion = 0;
|
|
55
54
|
this._buildPromise = null;
|
|
@@ -141,7 +140,7 @@ export class BacklinkIndex {
|
|
|
141
140
|
this.rawTargetKeysBySource.clear();
|
|
142
141
|
this.rawTargetSources.clear();
|
|
143
142
|
|
|
144
|
-
const snapshot = workspaceState ?? await this.
|
|
143
|
+
const snapshot = workspaceState ?? await this.vaultFileStore.scanWorkspaceState();
|
|
145
144
|
this._fileList = Array.from(snapshot?.filePaths ?? snapshot?.markdownPaths ?? []);
|
|
146
145
|
this._fileSet = new Set(this._fileList);
|
|
147
146
|
this._sourceFileList = Array.from(
|
|
@@ -165,23 +164,9 @@ export class BacklinkIndex {
|
|
|
165
164
|
}
|
|
166
165
|
}
|
|
167
166
|
|
|
168
|
-
this._built = true;
|
|
169
167
|
console.log(`[backlinks] Index built: ${this._sourceFileList.length} markdown sources, ${this._fileList.length} targets, ${this.reverse.size} targets with backlinks`);
|
|
170
168
|
}
|
|
171
169
|
|
|
172
|
-
async _resolveWorkspaceState() {
|
|
173
|
-
if (typeof this.vaultFileStore.scanWorkspaceState === 'function') {
|
|
174
|
-
return this.vaultFileStore.scanWorkspaceState();
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const tree = await this.vaultFileStore.tree();
|
|
178
|
-
const filePaths = flattenTree(tree);
|
|
179
|
-
return {
|
|
180
|
-
filePaths,
|
|
181
|
-
markdownPaths: filePaths.filter((filePath) => isMarkdownFilePath(filePath)),
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
|
|
185
170
|
/**
|
|
186
171
|
* Incrementally update the index when a file's content changes.
|
|
187
172
|
* Call this after every persist / write.
|
|
@@ -469,13 +454,6 @@ export class BacklinkIndex {
|
|
|
469
454
|
return results;
|
|
470
455
|
}
|
|
471
456
|
|
|
472
|
-
/**
|
|
473
|
-
* Get the count of backlinks for a file (cheap — no I/O).
|
|
474
|
-
*/
|
|
475
|
-
getBacklinkCount(filePath) {
|
|
476
|
-
return this.reverse.get(filePath)?.size ?? 0;
|
|
477
|
-
}
|
|
478
|
-
|
|
479
457
|
// --- Private methods ---
|
|
480
458
|
|
|
481
459
|
_indexFile(filePath, content, { targetPathAliases = new Map() } = {}) {
|
|
@@ -621,16 +599,3 @@ export class BacklinkIndex {
|
|
|
621
599
|
}
|
|
622
600
|
}
|
|
623
601
|
}
|
|
624
|
-
|
|
625
|
-
/** Flatten a vault tree into an array of file paths. */
|
|
626
|
-
function flattenTree(nodes) {
|
|
627
|
-
const files = [];
|
|
628
|
-
for (const node of nodes) {
|
|
629
|
-
if (node.type && node.type !== 'directory') {
|
|
630
|
-
files.push(node.path);
|
|
631
|
-
} else if (node.children) {
|
|
632
|
-
files.push(...flattenTree(node.children));
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
return files;
|
|
636
|
-
}
|
|
@@ -26,17 +26,11 @@ function cloneSnapshotRowRecord(rowRecord) {
|
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
function
|
|
30
|
-
return fileEntries.join('\n');
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function createRowCacheKey(filePath, workspaceState, fileSetSignature) {
|
|
29
|
+
function createRowMetadataSignature(filePath, workspaceState) {
|
|
34
30
|
const metadata = workspaceState?.metadata?.get(filePath) ?? null;
|
|
35
31
|
return [
|
|
36
|
-
filePath,
|
|
37
32
|
Number.isFinite(metadata?.mtimeMs) ? metadata.mtimeMs : '',
|
|
38
33
|
Number.isFinite(metadata?.size) ? metadata.size : '',
|
|
39
|
-
fileSetSignature,
|
|
40
34
|
].join('\0');
|
|
41
35
|
}
|
|
42
36
|
|
|
@@ -139,6 +133,8 @@ export class BaseIndexSnapshotStore {
|
|
|
139
133
|
this.indexSnapshot = null;
|
|
140
134
|
this.lastWorkspaceState = null;
|
|
141
135
|
this.rowRecordCache = new Map();
|
|
136
|
+
this.rowRecordCacheFileSetSignature = '';
|
|
137
|
+
this.rowRecordCacheGeneration = 0;
|
|
142
138
|
}
|
|
143
139
|
|
|
144
140
|
async getWorkspaceState() {
|
|
@@ -305,13 +301,16 @@ export class BaseIndexSnapshotStore {
|
|
|
305
301
|
async buildIndexSnapshot(workspaceState = null) {
|
|
306
302
|
const resolvedWorkspaceState = workspaceState ?? await this.getWorkspaceState();
|
|
307
303
|
const fileEntries = listWorkspaceFilePaths(resolvedWorkspaceState);
|
|
308
|
-
const
|
|
304
|
+
const cacheGeneration = this.prepareRowRecordCache(fileEntries);
|
|
309
305
|
const wikiTargetIndex = createWikiTargetIndex(fileEntries);
|
|
310
306
|
const markdownContents = new Map();
|
|
307
|
+
// Keep reused rows available if another build replaces the shared cache during I/O.
|
|
308
|
+
const cachedRowRecords = new Map(fileEntries.map((filePath) => [
|
|
309
|
+
filePath, this.getCachedRowRecord(filePath, resolvedWorkspaceState, cacheGeneration),
|
|
310
|
+
]));
|
|
311
311
|
|
|
312
312
|
await mapWithConcurrency(resolvedWorkspaceState.markdownPaths ?? [], INDEX_READ_CONCURRENCY, async (filePath) => {
|
|
313
|
-
|
|
314
|
-
if (!this.rowRecordCache.has(cacheKey)) {
|
|
313
|
+
if (!cachedRowRecords.get(filePath)) {
|
|
315
314
|
markdownContents.set(filePath, await this.vaultFileStore.readMarkdownFile(filePath));
|
|
316
315
|
}
|
|
317
316
|
});
|
|
@@ -322,13 +321,16 @@ export class BaseIndexSnapshotStore {
|
|
|
322
321
|
const rawTargetSourcesByKey = new Map();
|
|
323
322
|
const nextRowRecordCache = new Map();
|
|
324
323
|
fileEntries.forEach((filePath) => {
|
|
325
|
-
const
|
|
326
|
-
const cachedRowRecord = this.rowRecordCache.get(cacheKey);
|
|
324
|
+
const cachedRowRecord = cachedRowRecords.get(filePath);
|
|
327
325
|
const markdownContent = markdownContents.get(filePath) ?? null;
|
|
328
326
|
const rowRecord = cachedRowRecord
|
|
329
327
|
? cloneSnapshotRowRecord(cachedRowRecord)
|
|
330
328
|
: this.createSnapshotRow(filePath, resolvedWorkspaceState, wikiTargetIndex, markdownContent);
|
|
331
|
-
nextRowRecordCache.set(
|
|
329
|
+
nextRowRecordCache.set(filePath, {
|
|
330
|
+
generation: cacheGeneration,
|
|
331
|
+
metadataSignature: createRowMetadataSignature(filePath, resolvedWorkspaceState),
|
|
332
|
+
rowRecord: cloneSnapshotRowRecord(rowRecord),
|
|
333
|
+
});
|
|
332
334
|
rowsByPath.set(filePath, rowRecord.row);
|
|
333
335
|
forwardLinksByPath.set(filePath, rowRecord.forwardLinks);
|
|
334
336
|
rawTargetKeysBySourcePath.set(filePath, rowRecord.rawTargetKeys);
|
|
@@ -411,7 +413,7 @@ export class BaseIndexSnapshotStore {
|
|
|
411
413
|
return pathValue && isWorkspaceFileEntry(entry);
|
|
412
414
|
});
|
|
413
415
|
|
|
414
|
-
const
|
|
416
|
+
const cacheGeneration = this.prepareRowRecordCache(snapshot.filePaths);
|
|
415
417
|
await mapWithConcurrency(filePathsToRefresh, INDEX_READ_CONCURRENCY, async (filePath) => {
|
|
416
418
|
const markdownContent = isMarkdownFilePath(filePath)
|
|
417
419
|
? await this.vaultFileStore.readMarkdownFile(filePath)
|
|
@@ -419,11 +421,11 @@ export class BaseIndexSnapshotStore {
|
|
|
419
421
|
const rowRecord = this.createSnapshotRow(filePath, workspaceState, snapshot.wikiTargetIndex, markdownContent, {
|
|
420
422
|
targetPathAliases,
|
|
421
423
|
});
|
|
422
|
-
this.
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
cloneSnapshotRowRecord(rowRecord),
|
|
426
|
-
);
|
|
424
|
+
this.rowRecordCache.set(filePath, {
|
|
425
|
+
generation: cacheGeneration,
|
|
426
|
+
metadataSignature: createRowMetadataSignature(filePath, workspaceState),
|
|
427
|
+
rowRecord: cloneSnapshotRowRecord(rowRecord),
|
|
428
|
+
});
|
|
427
429
|
this.removeRawTargetSourceContributions(snapshot, filePath);
|
|
428
430
|
snapshot.rowsByPath.set(filePath, rowRecord.row);
|
|
429
431
|
snapshot.forwardLinksByPath.set(filePath, rowRecord.forwardLinks);
|
|
@@ -431,12 +433,27 @@ export class BaseIndexSnapshotStore {
|
|
|
431
433
|
});
|
|
432
434
|
}
|
|
433
435
|
|
|
436
|
+
prepareRowRecordCache(filePaths) {
|
|
437
|
+
const signature = JSON.stringify(filePaths);
|
|
438
|
+
if (signature !== this.rowRecordCacheFileSetSignature) {
|
|
439
|
+
// Link resolution depends on every target path, including previously missing files.
|
|
440
|
+
this.rowRecordCache.clear();
|
|
441
|
+
this.rowRecordCacheFileSetSignature = signature;
|
|
442
|
+
this.rowRecordCacheGeneration += 1;
|
|
443
|
+
}
|
|
444
|
+
return this.rowRecordCacheGeneration;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
getCachedRowRecord(filePath, workspaceState, generation) {
|
|
448
|
+
const cached = this.rowRecordCache.get(filePath);
|
|
449
|
+
return cached?.generation === generation
|
|
450
|
+
&& cached.metadataSignature === createRowMetadataSignature(filePath, workspaceState)
|
|
451
|
+
? cached.rowRecord
|
|
452
|
+
: null;
|
|
453
|
+
}
|
|
454
|
+
|
|
434
455
|
invalidateRowRecordCachePath(filePath) {
|
|
435
|
-
|
|
436
|
-
if (cacheKey === filePath || cacheKey.startsWith(`${filePath}\0`)) {
|
|
437
|
-
this.rowRecordCache.delete(cacheKey);
|
|
438
|
-
}
|
|
439
|
-
});
|
|
456
|
+
this.rowRecordCache.delete(filePath);
|
|
440
457
|
}
|
|
441
458
|
|
|
442
459
|
async ensureIndexSnapshot({ basePath = '', sourcePath = '' } = {}) {
|