collabmd 0.1.45 → 0.1.47
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/README.md +40 -19
- package/bin/collabmd.js +27 -1
- package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-BPH4FJkv.js +1 -0
- package/dist/client/assets/{abnfDiagram-N423BO3Z-CUMTFJhI.js → abnfDiagram-VCTEODGH-BNDLzJ7L.js} +1 -1
- package/dist/client/assets/architecture-7GRP2DOG-BMOPAkUC.js +1 -0
- package/dist/client/assets/{architectureDiagram-T3A2C74G-w25m71oV.js → architectureDiagram-5GKGNRK7-I39sYjHI.js} +1 -1
- package/dist/client/assets/base-BYODPHdS.js +1 -0
- package/dist/client/assets/blockDiagram-NRAW4CY4-C6DtJy5Y.js +129 -0
- package/dist/client/assets/browser-BKLM0ThC-IxjwuOIz-BBqQnUEb.js +1 -0
- package/dist/client/assets/browser-utils--H_DkyEF.js +1 -0
- package/dist/client/assets/c4Diagram-UCG6FXSJ-CtWtxS9_.js +38 -0
- package/dist/client/assets/channel-CaoKA_We.js +1 -0
- package/dist/client/assets/{chunk-U6XO7XAA-BFxjP5U3.js → chunk-2ZTRR5NV-C2qZJila.js} +1 -1
- package/dist/client/assets/{chunk-YOTPTUD7-D0vRKqYp.js → chunk-3Z5EZCMW-DMniOlPd.js} +1 -1
- package/dist/client/assets/{chunk-BIQX33UG-DZEsGuSn.js → chunk-5V3GS4D5-i-ZDOEnP.js} +1 -1
- package/dist/client/assets/{chunk-MOZMSUNE-XVucA-n6.js → chunk-6AZGARVD-BB6FqMl-.js} +1 -1
- package/dist/client/assets/{chunk-5JV3BV7I-Cy5pj3QY.js → chunk-6EIED4P4-DdUJkP0f.js} +1 -1
- package/dist/client/assets/{chunk-R7FJI6CG-Cnn3gE-Y.js → chunk-6K3QC6MW-CqVsVn-y.js} +1 -1
- package/dist/client/assets/{chunk-OSBZ3O6U-CrKZOUOr.js → chunk-6TQVIW2G-DKlLbNIP.js} +1 -1
- package/dist/client/assets/{chunk-JG7HCLWE-BYfiSaVt.js → chunk-747NJXEK-BFkZPlab.js} +1 -1
- package/dist/client/assets/{chunk-NSK5VX7P-TLH37VXI.js → chunk-75Z2AOVW-CdFSaPjz.js} +1 -1
- package/dist/client/assets/chunk-CKBBP62Z-DG26UiBv.js +2 -0
- package/dist/client/assets/{chunk-3NCLNEKW-Y2Jf_LI-.js → chunk-CLGD4ZFX-DQLgbQrv.js} +1 -1
- package/dist/client/assets/chunk-DSNCTWBM-8xkug7fQ.js +2 -0
- package/dist/client/assets/chunk-DU6HZSFF-COXDzJK1.js +127 -0
- package/dist/client/assets/{chunk-2GRJ4B5K-DhnlUv3F.js → chunk-F27PBJKO-CNHIFhjo.js} +1 -1
- package/dist/client/assets/{chunk-YGJVY4SA-CjSe7Bx7.js → chunk-FLYJHZSQ-Be7lKF17.js} +1 -1
- package/dist/client/assets/{chunk-KEIR6QF5-BICK3FdT.js → chunk-FOHPRMQF-DHwB1DNv.js} +2 -2
- package/dist/client/assets/{chunk-5RXB4S5H-BWrwFqMI.js → chunk-G27WJ6UU-D9-eg537.js} +2 -2
- package/dist/client/assets/chunk-GMAD6QVW-CbcBqPM5.js +72 -0
- package/dist/client/assets/{chunk-QBLGF6JB-CxAyS2mW.js → chunk-I5DQTOEV-Hm2LfiYI.js} +1 -1
- package/dist/client/assets/{chunk-5FCAYU7R-Dh5nylU8.js → chunk-ICYGCRZG-749o-pGJ.js} +1 -1
- package/dist/client/assets/{chunk-CQNSW5MT-B8S09OIh.js → chunk-IH6LHLGP-CC6I9F3i.js} +1 -1
- package/dist/client/assets/chunk-JQ64N6SF-DSFNH4bh.js +1 -0
- package/dist/client/assets/{chunk-CYSBUYHQ-C1Rf4art.js → chunk-KI3K4JFJ-Rma-0k_M.js} +1 -1
- package/dist/client/assets/{chunk-GF5L2VYU-DkJpO7ff.js → chunk-LCL6LL3I-DmDkVukh.js} +1 -1
- package/dist/client/assets/chunk-LNGE3PJU-DWpGwHrW.js +34 -0
- package/dist/client/assets/chunk-OBVCFTLP-BJR7u1jh.js +1 -0
- package/dist/client/assets/{chunk-5TONJI2A-DQOY3q1H.js → chunk-OUJLGHUK-D0j2JRSg.js} +1 -1
- package/dist/client/assets/chunk-P2QGCYS3-BRpqY32H.js +1 -0
- package/dist/client/assets/{chunk-KBJHAD2P-CB_3zWUf.js → chunk-POPQ4Y6H-Cb4SlVZF.js} +1 -1
- package/dist/client/assets/{chunk-4I5QYGJK-CCB2YcIH.js → chunk-PWAF6VOD-Cz8IwBB5.js} +1 -1
- package/dist/client/assets/chunk-R7TYR2AO-CTd0Yj98.js +10 -0
- package/dist/client/assets/chunk-RHFEMEQ7-CWY8cf4H.js +168 -0
- package/dist/client/assets/chunk-RM4UPSZO-CWRwxNWJ.js +41 -0
- package/dist/client/assets/{chunk-6Q2QTUOP-CPlWzBtc.js → chunk-SVP7TREG-CyHOmcac.js} +1 -1
- package/dist/client/assets/chunk-TEH6E4GO-DVayPj-q.js +62 -0
- package/dist/client/assets/{chunk-EMLP6XTP-RLD4nXpI.js → chunk-UY3FDG6J-CnmaAkG5.js} +1 -1
- package/dist/client/assets/{chunk-5HE753X5-Bw-yg4kO.js → chunk-XHIXRSVI-BFQ6B8BE.js} +1 -1
- package/dist/client/assets/classDiagram-DTDB5LWJ-7fEmn0zV.js +1 -0
- package/dist/client/assets/classDiagram-v2-JRS7N3AN-7fEmn0zV.js +1 -0
- package/dist/client/assets/comment-thread-store-CdcwrObc.js +1 -0
- package/dist/client/assets/comment-threads-9J6Em-_y.js +4 -0
- package/dist/client/assets/comment-ui-shared-DWkk9Vh3.js +7 -0
- package/dist/client/assets/cynefin-OW5HDTMX-7tP7QfM3.js +1 -0
- package/dist/client/assets/{cynefinDiagram-MW4NZA55-CJxXfJek.js → cynefinDiagram-5FMLGOSQ-CdTPi2yO.js} +1 -1
- package/dist/client/assets/dagre-3AP2YEHR-5gtJtd0O.js +4 -0
- package/dist/client/assets/dagre-PrKaheQc.js +1 -0
- package/dist/client/assets/{diagram-7IWD3JNH-B2d2Bm15.js → diagram-S7CK7UJ4-BudWz9WU.js} +4 -4
- package/dist/client/assets/{diagram-UB23O5K3-DJcKCwv9.js → diagram-UQ7AKVKN-3v4rbH-s.js} +1 -1
- package/dist/client/assets/{diagram-B4RE2ZJO-NP4UAwjR.js → diagram-VSXAHHWV-CQRVEZR7.js} +1 -1
- package/dist/client/assets/{diagram-Q27KOJAE-DylDuwor.js → diagram-VX7I27RA-C_-rj0sw.js} +1 -1
- package/dist/client/assets/{diagram-LBJQPF4R-D1FJQV8t.js → diagram-Z3DM3KII-B4yxavgj.js} +1 -1
- package/dist/client/assets/direct-engine-DdrQKpgq-CtKfQzCt.js +5 -0
- package/dist/client/assets/dist-73RPdcyU.js +1 -0
- package/dist/client/assets/dist-BJ1bJs33.js +1 -0
- package/dist/client/assets/{dist-CYZmbokb.js → dist-BK9QvQrc.js} +9 -9
- package/dist/client/assets/dist-BPHLJ09L.js +11 -0
- package/dist/client/assets/dist-B_yQaEv_.js +6 -0
- package/dist/client/assets/dist-BeajGMhO.js +1 -0
- package/dist/client/assets/{dist-JYEDRrPT.js → dist-Bw3VIE_v.js} +1 -1
- package/dist/client/assets/dist-ByrG2qBA.js +1 -0
- package/dist/client/assets/dist-C5NgpdG5.js +1 -0
- package/dist/client/assets/dist-CH-sQu3r.js +1 -0
- package/dist/client/assets/dist-CKS_-are.js +1 -0
- package/dist/client/assets/{dist-MvcV4190.js → dist-CdmKGRGr.js} +1 -1
- package/dist/client/assets/{dist-DGb27Dl6.js → dist-CietwTVS.js} +1 -1
- package/dist/client/assets/dist-D37Hyu3h.js +9 -0
- package/dist/client/assets/dist-D3fehAZ2.js +2 -0
- package/dist/client/assets/dist-D5wCC32z.js +1 -0
- package/dist/client/assets/{dist-DCzuX1AF.js → dist-DDUn5zTz.js} +1 -1
- package/dist/client/assets/dist-DGEbEfw4.js +1 -0
- package/dist/client/assets/dist-DVy5woUy.js +1 -0
- package/dist/client/assets/{dist-3bgCp7iY.js → dist-DZAAWTG-.js} +1 -1
- package/dist/client/assets/{dist-Drp8uu5J.js → dist-Dir5dDKZ.js} +1 -1
- package/dist/client/assets/dist-Dl_tpDSr.js +1 -0
- package/dist/client/assets/dist-DuH3ZrHo.js +1 -0
- package/dist/client/assets/dist-DutPuFmC.js +1 -0
- package/dist/client/assets/{dist-D2AQ-76g.js → dist-LQ4kDCKz.js} +1 -1
- package/dist/client/assets/{dist-C11hHqv_.js → dist-RKBTaQMb.js} +12 -12
- package/dist/client/assets/dist-Tw-Fxpeb.js +1 -0
- package/dist/client/assets/dist-eBx8q6Sy.js +1 -0
- package/dist/client/assets/{dist-DK5Gs2wa.js → dist-mj2Ht75J.js} +1 -1
- package/dist/client/assets/{dist-CnL7Y2sM.js → dist-netZOQtD.js} +1 -1
- package/dist/client/assets/{drawio-editor-ClE8jpoG.js → drawio-editor-BjrxTe3l.js} +1 -1
- package/dist/client/assets/drawioEditor-DUVZjSSr.js +2 -0
- package/dist/client/assets/{ebnfDiagram-BXEA7PRR-nw0wmA6y.js → ebnfDiagram-PWID7BFC-OXa8VEp1.js} +1 -1
- package/dist/client/assets/editor-session-DfZuRgB_.js +54 -0
- package/dist/client/assets/embedded-editor-base-DvMynhKu.css +1 -0
- package/dist/client/assets/embedpdf-BmE13ZZ0.js +1 -0
- package/dist/client/assets/embedpdf-DA4bA119-BPqZxwjc.js +2363 -0
- package/dist/client/assets/{en-7NFCYGKX-BrgYZAEe.js → en-SJ2YIMFF-CJBL3nkq.js} +1 -1
- package/dist/client/assets/erDiagram-SSCWMZ5O-C-iy6VkX.js +99 -0
- package/dist/client/assets/es-CAsWR6hG.js +22 -0
- package/dist/client/assets/eventmodeling-NTZA5JFV-BR2FzK4R.js +1 -0
- package/dist/client/assets/excalidraw-editor-BlcN6umJ.css +1 -0
- package/dist/client/assets/excalidraw-editor-D7pnUCLH.js +9 -0
- package/dist/client/assets/excalidraw-scene-BOben2gr.js +1 -0
- package/dist/client/assets/excalidrawEditor-B0jOK3lv.js +2 -0
- package/dist/client/assets/export-page-Bs3xE1fg.js +57 -0
- package/dist/client/assets/exportDocument-Dg9MjkIk.js +2 -0
- package/dist/client/assets/exportDocument-PnYU3v1s.css +1 -0
- package/dist/client/assets/file-icon-svg-CQAjlWjK.js +1 -0
- package/dist/client/assets/file-kind-BbqgGzpc.js +1 -0
- package/dist/client/assets/flowDiagram-A5DVABFB-CiW1eN8C.js +1 -0
- package/dist/client/assets/{ganttDiagram-PKOTCBZU-BnM97BCT.js → ganttDiagram-EL5Y4UJY-DtKHAbez.js} +1 -1
- package/dist/client/assets/gitGraph-4MIJSDKK-DYlXv_yJ.js +1 -0
- package/dist/client/assets/{gitGraphDiagram-DS77QQ5N-BQpQhjuN.js → gitGraphDiagram-WWUBYQGX-oue8fQ5o.js} +1 -1
- package/dist/client/assets/github-dark.min-BV82VuKq.css +1 -0
- package/dist/client/assets/github.min-v3dd8CNH.css +1 -0
- package/dist/client/assets/image-ZVKINSPA-0zXSnE7M.js +1 -0
- package/dist/client/assets/index-BIpgxyGZ.css +1 -0
- package/dist/client/assets/index-Z5sI0Bj-.js +2 -0
- package/dist/client/assets/info-A6RAGUB7-BlU-8_xu.js +1 -0
- package/dist/client/assets/{infoDiagram-6WML65LV-DYB8HCDQ.js → infoDiagram-RXCK75RN-BMzo6KIn.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-WSZJBQD7-Coz_P3t6.js → ishikawaDiagram-5VMMS53U-BIM3h287.js} +1 -1
- package/dist/client/assets/{journeyDiagram-NVQOT4AX-B6edChce.js → journeyDiagram-EYS64GPL-mF6Lh8O-.js} +1 -1
- package/dist/client/assets/{kanban-definition-27J2QSJJ-BFd9-cLc.js → kanban-definition-3QL26DDD-DLN2NyoR.js} +2 -2
- package/dist/client/assets/{line-B_S_S8kV.js → line-BfTWJmgf.js} +1 -1
- package/dist/client/assets/main-Dwnj9Gaq.js +903 -0
- package/dist/client/assets/{mermaid-parser.core-CUVdebAV.js → mermaid-parser.core-Bl0efOMt.js} +2 -2
- package/dist/client/assets/mermaid.core-CLZBlpIW.js +11 -0
- package/dist/client/assets/{mindmap-definition-FAOFIHXS-C9PQ38Al.js → mindmap-definition-FBJOCRG2-CRyHaHTk.js} +1 -1
- package/dist/client/assets/packet-AYTQ26CC-BSJEH9Lb.js +1 -0
- package/dist/client/assets/pdfium-RAgkpwfK.wasm +0 -0
- package/dist/client/assets/{pegDiagram-VL7TDLO6-BMZUrSaU.js → pegDiagram-XKGWAZYB-B31fKPR2.js} +1 -1
- package/dist/client/assets/pie-WAS4IAKB-qxv01Y8W.js +1 -0
- package/dist/client/assets/{pieDiagram-7S7Q4E2Y-h8kbCL9o.js → pieDiagram-E7YTZNPT-B5OZPb88.js} +1 -1
- package/dist/client/assets/preview-render-compiler-BApvlLLo.js +35 -0
- package/dist/client/assets/preview-render-compiler-BQ_3h9vD.js +1 -0
- package/dist/client/assets/preview-render-profile-CE-5rVTC.js +1 -0
- package/dist/client/assets/preview-render-worker-BmN79bVc.js +60 -0
- package/dist/client/assets/prod-BiYPMR1i.js +177 -0
- package/dist/client/assets/prod-VxdGZ5Ly.js +1 -0
- package/dist/client/assets/{quadrantDiagram-CIZ2JOQS-CkElyfMi.js → quadrantDiagram-AXDQQJYC-Drrw14YH.js} +1 -1
- package/dist/client/assets/quick-switcher-controller-ButWPmCI.js +12 -0
- package/dist/client/assets/radar-RG4KPBEZ-B6h6pWOs.js +1 -0
- package/dist/client/assets/railroad-74A4TZTK-CGtTWdGc.js +1 -0
- package/dist/client/assets/railroad-abnf-HS5TGJTU-Cq7y22IA.js +1 -0
- package/dist/client/assets/railroad-ebnf-LZEXJU2U-V0aQVv9m.js +1 -0
- package/dist/client/assets/railroad-peg-WCYAUIDC-BQiIsX_p.js +1 -0
- package/dist/client/assets/{railroadDiagram-AXF67PYL-c75gnikD.js → railroadDiagram-O6MQD6OU-BPifP0MB.js} +1 -1
- package/dist/client/assets/{requirementDiagram-LRYGKXZP-mNxKLuHS.js → requirementDiagram-EFPCY7ZU-CRZG6mRB.js} +2 -2
- package/dist/client/assets/runtime-config-BLrEKVO1.js +1 -0
- package/dist/client/assets/{sankeyDiagram-W5VNT64P-0OhplksI.js → sankeyDiagram-P5KCCOFB-DvarEJpo.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-SI44F4Z6-BJ_yAocC.js → sequenceDiagram-WJ2MYXX4-B4oWlb-w.js} +1 -1
- package/dist/client/assets/{stateDiagram-OKZ733FA-Cc83O86s.js → stateDiagram-HBIQ2CUA-qbHIIqRZ.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-4QOOHH4V-B--gjrit.js +1 -0
- package/dist/client/assets/swimlanes-XN3QIQJK-xB6CtUGj.js +1 -0
- package/dist/client/assets/swimlanesDiagram-VK2B7HYN-DO8XNXEg.js +8 -0
- package/dist/client/assets/{timeline-definition-Z64GVDOM-BWDAGTHz.js → timeline-definition-24CTP7MA-Lj_yTNlY.js} +1 -1
- package/dist/client/assets/treeView-Q6P3EWNA-BTTYcvrF.js +1 -0
- package/dist/client/assets/treemap-WGGIJYW6-Cg7tyfH8.js +1 -0
- package/dist/client/assets/vault-api-client-_LpV1aIn.js +6 -0
- package/dist/client/assets/{vennDiagram-T6HMQDX7-LOSsnlMB.js → vennDiagram-4TSXK5OY-BekRp5Y0.js} +1 -1
- package/dist/client/assets/wardley-WFR3VGLG-C6N1rULY.js +1 -0
- package/dist/client/assets/{wardleyDiagram-T6FBY63Y-BxII3foY.js → wardleyDiagram-VM6X3IG4-kdnV_Hdm.js} +1 -1
- package/dist/client/assets/worker-engine-m0rlHn8R-S8mpn_O0.js +17369 -0
- package/dist/client/assets/{xychartDiagram-ELKLHX3M-B-pTEjju.js → xychartDiagram-S5SC5T6Z-DufGwNSB.js} +3 -3
- package/dist/client/drawio-editor.html +1 -1
- package/dist/client/excalidraw-editor.html +1 -1
- package/dist/client/export-document.html +3 -3
- package/dist/client/index.html +30 -8
- package/docker-compose.yml +42 -0
- package/package.json +32 -18
- package/scripts/local-structurizr-compose.mjs +101 -0
- package/src/client/app/index.html +27 -5
- package/src/client/application/app-shell/comments-feature.js +21 -13
- package/src/client/application/app-shell/git-feature.js +14 -2
- package/src/client/application/app-shell/presence-feature.js +4 -3
- package/src/client/application/app-shell/ui-feature-shell.js +109 -2
- package/src/client/application/app-shell/ui-feature-toolbar.js +2 -52
- package/src/client/application/app-shell/workspace-feature.js +5 -1
- package/src/client/application/app-shell-elements.js +3 -0
- package/src/client/application/pdf-preview-controller.js +75 -0
- package/src/client/application/preview-render-compiler.js +3 -0
- package/src/client/application/quick-switcher-loader.js +1 -1
- package/src/client/application/structurizr-preview-controller.js +395 -0
- package/src/client/application/workspace-coordinator.js +25 -3
- package/src/client/application/workspace-preview-controller.js +88 -2
- package/src/client/assets/vendor/highlight/github-dark.min.css +2 -10
- package/src/client/assets/vendor/highlight/github.min.css +2 -10
- package/src/client/bootstrap/collabmd-app-shell.js +39 -6
- package/src/client/browser-utils.js +44 -0
- package/src/client/domain/runtime-paths.js +26 -5
- package/src/client/domain/structurizr-language.js +99 -0
- package/src/client/domain/vault-paths.js +48 -0
- package/src/client/excalidraw-editor.js +844 -51
- package/src/client/export/export-host.js +1 -1
- package/src/client/export/export-page.js +6 -2
- package/src/client/export/export-pipeline.js +60 -1
- package/src/client/infrastructure/browser-preferences-port.js +10 -0
- package/src/client/infrastructure/comment-thread-store.js +34 -13
- package/src/client/infrastructure/editor-session.js +10 -0
- package/src/client/infrastructure/editor-view-adapter.js +46 -2
- package/src/client/infrastructure/excalidraw-room-client.js +103 -14
- package/src/client/infrastructure/git-api-client.js +5 -0
- package/src/client/infrastructure/vault-api-client.js +26 -0
- package/src/client/presentation/comment-ui/comment-ui-render.js +4 -0
- package/src/client/presentation/comment-ui/comment-ui-shared.js +4 -0
- package/src/client/presentation/comment-ui-controller.js +2 -0
- package/src/client/presentation/drawio-embed-controller.js +9 -102
- package/src/client/presentation/drawio-viewer.js +118 -0
- package/src/client/presentation/excalidraw-embed-controller.js +81 -8
- package/src/client/presentation/file-action-controller.js +102 -0
- package/src/client/presentation/file-explorer-controller.js +0 -5
- package/src/client/presentation/file-explorer-view.js +51 -73
- package/src/client/presentation/file-icon-svg.js +40 -0
- package/src/client/presentation/file-tree-state.js +6 -3
- package/src/client/presentation/git-diff-view-controller.js +731 -3
- package/src/client/presentation/git-panel-controller.js +2 -2
- package/src/client/presentation/outline-controller.js +86 -0
- package/src/client/presentation/quick-switcher-controller.js +73 -22
- package/src/client/presentation/quick-switcher-text-search.js +1 -1
- package/src/client/styles/components/navigation.css +11 -1
- package/src/client/styles/features/diagram-preview.css +76 -0
- package/src/client/styles/features/diff-special.css +309 -0
- package/src/client/styles/features/preview-markdown.css +25 -0
- package/src/client/styles/features/quick-switcher.css +8 -0
- package/src/client/styles/foundation/themes.css +7 -0
- package/src/client/styles/layout/shell.css +40 -1
- package/src/client/styles/layout/sidebar.css +42 -4
- package/src/client/styles/layout/view-modes.css +1 -0
- package/src/client/styles/overrides/highlightjs.css +20 -4
- package/src/client/styles/style.css +1 -0
- package/src/client/styles/surfaces/excalidraw-editor.css +294 -0
- package/src/domain/comment-threads.js +63 -5
- package/src/domain/excalidraw-room-codec.js +6 -4
- package/src/domain/file-kind.js +35 -3
- package/src/server/config/env.js +79 -0
- package/src/server/create-app-server.js +12 -0
- package/src/server/domain/bases/base-definition.js +1 -1
- package/src/server/domain/bases/base-expression-runtime.js +1 -4
- package/src/server/domain/bases/base-index-snapshot-store.js +1 -4
- package/src/server/domain/bases/base-transform.js +1 -4
- package/src/server/domain/collaboration/collaboration-room.js +55 -21
- package/src/server/domain/comment-overview.js +15 -5
- package/src/server/domain/ripgrep-search-service.js +4 -0
- package/src/server/infrastructure/git/diff-service.js +5 -0
- package/src/server/infrastructure/git/git-service.js +44 -11
- package/src/server/infrastructure/git/history-service.js +54 -0
- package/src/server/infrastructure/git/image-mime.js +14 -0
- package/src/server/infrastructure/git/untracked-files.js +28 -1
- package/src/server/infrastructure/http/create-git-api-command-handler.js +3 -1
- package/src/server/infrastructure/http/create-git-api-query-handler.js +31 -1
- package/src/server/infrastructure/http/create-request-handler.js +16 -23
- package/src/server/infrastructure/http/create-static-handler.js +5 -2
- package/src/server/infrastructure/http/create-structurizr-api-handler.js +147 -0
- package/src/server/infrastructure/http/create-vault-api-command-handler.js +66 -4
- package/src/server/infrastructure/http/create-vault-api-query-handler.js +51 -3
- package/src/server/infrastructure/http/http-request-helpers.js +22 -0
- package/src/server/infrastructure/persistence/path-utils.js +1 -1
- package/src/server/infrastructure/persistence/vault-file-store.js +3 -0
- package/src/server/infrastructure/structurizr/structurizr-embed.css +43 -0
- package/src/server/infrastructure/structurizr/structurizr-workspace-service.js +400 -0
- package/src/server/infrastructure/websocket/attach-collaboration-gateway.js +4 -22
- package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-CbSISC1w.js +0 -1
- package/dist/client/assets/architecture-TIHT7OUA-CsHfPErM.js +0 -1
- package/dist/client/assets/base-CxPEiHuy.js +0 -1
- package/dist/client/assets/blockDiagram-VBNYF7ZC-CipJt9Jl.js +0 -132
- package/dist/client/assets/browser-utils-CKtI_rZl.js +0 -1
- package/dist/client/assets/c4Diagram-5PPSVZJV-B5ktVx6g.js +0 -10
- package/dist/client/assets/channel-4Jkmq93I.js +0 -1
- package/dist/client/assets/chunk-7BUUIJ7U-Bb538aSH.js +0 -1
- package/dist/client/assets/chunk-7Z6QIM7H-BP9Pdsm9.js +0 -10
- package/dist/client/assets/chunk-ERSWUTIN-ME9RVNel.js +0 -41
- package/dist/client/assets/chunk-I66GZJ75-CVFiiffQ.js +0 -127
- package/dist/client/assets/chunk-J7OUQ5F2-4CEb7pvH.js +0 -2
- package/dist/client/assets/chunk-JQJVKLGR-cx8X_24v.js +0 -156
- package/dist/client/assets/chunk-QR6OTTB3-CDAA_5Ib.js +0 -62
- package/dist/client/assets/chunk-RYQCIY6F-D-a0zH8K.js +0 -1
- package/dist/client/assets/chunk-UBXNYLIW-Bhk-PbFK.js +0 -1
- package/dist/client/assets/chunk-W5SLKNZC-BdNSCxZ9.js +0 -1
- package/dist/client/assets/chunk-WRU74C26-h6_XkD3_.js +0 -70
- package/dist/client/assets/chunk-ZIRB5QZD-O39ZBUk3.js +0 -32
- package/dist/client/assets/classDiagram-JCYQIIEL-L7lsyW_w.js +0 -1
- package/dist/client/assets/classDiagram-v2-OCEON4UE-L7lsyW_w.js +0 -1
- package/dist/client/assets/comment-threads-DDegmaFO.js +0 -4
- package/dist/client/assets/cynefin-VYW2F7L2-Ds2Fw2Y0.js +0 -1
- package/dist/client/assets/dagre-Buvkdvvj.js +0 -1
- package/dist/client/assets/dagre-VZM6K2ZE-L1xArOGs.js +0 -4
- package/dist/client/assets/dist-BH87JoHx.js +0 -11
- package/dist/client/assets/dist-BIkPRZO7.js +0 -6
- package/dist/client/assets/dist-BqCsFpx4.js +0 -1
- package/dist/client/assets/dist-C2JHCt8U.js +0 -1
- package/dist/client/assets/dist-CZjTtmTu.js +0 -1
- package/dist/client/assets/dist-Cig4Ov_X.js +0 -1
- package/dist/client/assets/dist-CqQEC8gR.js +0 -1
- package/dist/client/assets/dist-D4Rzqod1.js +0 -1
- package/dist/client/assets/dist-D5sn-mwk.js +0 -9
- package/dist/client/assets/dist-D7G-n87v.js +0 -1
- package/dist/client/assets/dist-DRqOrNgN.js +0 -1
- package/dist/client/assets/dist-DetkMS_4.js +0 -1
- package/dist/client/assets/dist-DhLvC8DS.js +0 -2
- package/dist/client/assets/dist-Dp6FVkQ1.js +0 -1
- package/dist/client/assets/dist-DtbjNB28.js +0 -1
- package/dist/client/assets/dist-DyrYcvpo2.js +0 -1
- package/dist/client/assets/dist-GrygD2zE.js +0 -1
- package/dist/client/assets/dist-HmEpWUow.js +0 -1
- package/dist/client/assets/dist-RTa81Km7.js +0 -1
- package/dist/client/assets/drawioEditor-CXaTM9Ds.js +0 -2
- package/dist/client/assets/editor-session-GTwZS6Df.js +0 -16
- package/dist/client/assets/embedded-editor-base-CiNEc8vy.css +0 -1
- package/dist/client/assets/erDiagram-JOGREHBK-cYUpEKpf.js +0 -85
- package/dist/client/assets/eventmodeling-45OFAUF4-CLEiVx5s.js +0 -1
- package/dist/client/assets/excalidraw-editor-BZVM81BO.js +0 -9
- package/dist/client/assets/excalidraw-editor-CyGwOhLz.css +0 -1
- package/dist/client/assets/excalidraw-scene-C8n9CHsK.js +0 -176
- package/dist/client/assets/excalidrawEditor-DxJanCze.js +0 -2
- package/dist/client/assets/export-page-CUfws2T-.js +0 -39
- package/dist/client/assets/exportDocument-BCuxqXDY.js +0 -2
- package/dist/client/assets/exportDocument-DV-OX74E.css +0 -1
- package/dist/client/assets/file-kind-BKPOIRPE.js +0 -1
- package/dist/client/assets/flowDiagram-UKHOOZJN-D0ypP0Ez.js +0 -1
- package/dist/client/assets/gitGraph-TEB2WS4Q-CZFBqwW-.js +0 -1
- package/dist/client/assets/github-dark.min-Z5exjX_n.css +0 -1
- package/dist/client/assets/github.min-D2BCvnWf.css +0 -1
- package/dist/client/assets/image-QXRYHUNP-lfTHE3bb.js +0 -1
- package/dist/client/assets/index-C3YnUgMD.css +0 -1
- package/dist/client/assets/index-D2wXraJ1.js +0 -2
- package/dist/client/assets/info-DKCQHKI2--1InqQeT.js +0 -1
- package/dist/client/assets/main-DtiGz7uI.js +0 -795
- package/dist/client/assets/map-BaFkSB1l.js +0 -1
- package/dist/client/assets/mermaid.core-DN-lF51U.js +0 -11
- package/dist/client/assets/packet-7NZHBO7P-BGMXB0XL.js +0 -1
- package/dist/client/assets/pie-RZYD4A2V-DgYg3tCt.js +0 -1
- package/dist/client/assets/preview-render-compiler-BSaQO_p3.js +0 -35
- package/dist/client/assets/preview-render-compiler-csGM5ZFz.js +0 -1
- package/dist/client/assets/preview-render-profile-BZzGSg6K.js +0 -22
- package/dist/client/assets/preview-render-worker-B42LWvrD.js +0 -60
- package/dist/client/assets/quick-switcher-controller-shW_6vPY.js +0 -12
- package/dist/client/assets/radar-I7S5WNFK-Ag-zp_Rq.js +0 -1
- package/dist/client/assets/railroad-3IZDKUUU-aibJDIDV.js +0 -1
- package/dist/client/assets/railroad-abnf-AHOZXSZD-BBMEuvIl.js +0 -1
- package/dist/client/assets/railroad-ebnf-EBAXGLYW-Be1nseej.js +0 -1
- package/dist/client/assets/railroad-peg-LSFZ7HO6-DIvD-Eyb.js +0 -1
- package/dist/client/assets/room-CQLoqtMo.js +0 -1
- package/dist/client/assets/runtime-config-DSGmGE9V.js +0 -1
- package/dist/client/assets/stateDiagram-v2-UEYNNEHI-B1-BufUk.js +0 -1
- package/dist/client/assets/swimlanes-SLNWSIFB-oVTWEJIj.js +0 -2
- package/dist/client/assets/swimlanesDiagram-ULZ7WXOC-C5OTVwEu.js +0 -8
- package/dist/client/assets/treeView-QDETBFTQ-uHZ-3Fz8.js +0 -1
- package/dist/client/assets/treemap-6X3UGDF4-BnUKyy3l.js +0 -1
- package/dist/client/assets/vault-api-client-C6bcGwy-.js +0 -5
- package/dist/client/assets/wardley-OPB4EBWU-Da7TLC2F.js +0 -1
- package/src/server/domain/collaboration/room-persistence-controller.js +0 -80
|
@@ -51,6 +51,10 @@ export function areAnchorsEqual(left, right) {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
export function formatAnchorLabel(anchor) {
|
|
54
|
+
if (getAnchorKind(anchor) === 'diagram-element') {
|
|
55
|
+
return 'Diagram element';
|
|
56
|
+
}
|
|
57
|
+
|
|
54
58
|
const startLine = Number(anchor?.startLine || 0);
|
|
55
59
|
const endLine = Number(anchor?.endLine || startLine);
|
|
56
60
|
if (!Number.isFinite(startLine) || startLine <= 0) {
|
|
@@ -12,6 +12,7 @@ export class CommentUiController {
|
|
|
12
12
|
commentsDrawerList,
|
|
13
13
|
commentsToggleButton,
|
|
14
14
|
editorContainer,
|
|
15
|
+
mobileBreakpointQuery = window.matchMedia('(max-width: 768px)'),
|
|
15
16
|
onWillOpenDrawer,
|
|
16
17
|
onCreateThread,
|
|
17
18
|
onNavigateToLine,
|
|
@@ -27,6 +28,7 @@ export class CommentUiController {
|
|
|
27
28
|
this.commentsDrawerList = commentsDrawerList;
|
|
28
29
|
this.commentsToggleButton = commentsToggleButton;
|
|
29
30
|
this.editorContainer = editorContainer;
|
|
31
|
+
this.mobileBreakpointQuery = mobileBreakpointQuery;
|
|
30
32
|
this.onWillOpenDrawer = onWillOpenDrawer;
|
|
31
33
|
this.onCreateThread = onCreateThread;
|
|
32
34
|
this.onNavigateToLine = onNavigateToLine;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createDrawioLeaseRoomName } from '../../domain/drawio-room.js';
|
|
2
2
|
import { setDiagramActionButtonIcon } from '../domain/diagram-action-icons.js';
|
|
3
3
|
import { resolveAppUrl } from '../domain/runtime-paths.js';
|
|
4
|
+
import { renderDrawioViewer } from './drawio-viewer.js';
|
|
4
5
|
import {
|
|
5
6
|
cancelIdleRender,
|
|
6
7
|
isNearViewport,
|
|
@@ -8,62 +9,6 @@ import {
|
|
|
8
9
|
} from '../browser-utils.js';
|
|
9
10
|
|
|
10
11
|
const HYDRATE_VIEWPORT_MARGIN_PX = 360;
|
|
11
|
-
const DRAWIO_VIEWER_SCRIPT_URL = 'https://viewer.diagrams.net/js/viewer-static.min.js';
|
|
12
|
-
|
|
13
|
-
let drawioViewerLoadPromise = null;
|
|
14
|
-
|
|
15
|
-
function ensureDrawioViewerLoaded() {
|
|
16
|
-
if (window.GraphViewer?.processElements) {
|
|
17
|
-
return Promise.resolve(window.GraphViewer);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
if (drawioViewerLoadPromise) {
|
|
21
|
-
return drawioViewerLoadPromise;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
drawioViewerLoadPromise = new Promise((resolve, reject) => {
|
|
25
|
-
const existingScript = document.querySelector('script[data-collabmd-drawio-viewer]');
|
|
26
|
-
const script = existingScript instanceof HTMLScriptElement
|
|
27
|
-
? existingScript
|
|
28
|
-
: document.createElement('script');
|
|
29
|
-
|
|
30
|
-
const cleanup = () => {
|
|
31
|
-
script.removeEventListener('error', handleError);
|
|
32
|
-
script.removeEventListener('load', handleLoad);
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
const handleError = () => {
|
|
36
|
-
cleanup();
|
|
37
|
-
drawioViewerLoadPromise = null;
|
|
38
|
-
reject(new Error('Failed to load draw.io viewer'));
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const handleLoad = () => {
|
|
42
|
-
cleanup();
|
|
43
|
-
if (!window.GraphViewer?.processElements) {
|
|
44
|
-
drawioViewerLoadPromise = null;
|
|
45
|
-
reject(new Error('draw.io viewer did not initialize'));
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
resolve(window.GraphViewer);
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
script.addEventListener('error', handleError, { once: true });
|
|
53
|
-
script.addEventListener('load', handleLoad, { once: true });
|
|
54
|
-
|
|
55
|
-
if (!existingScript) {
|
|
56
|
-
script.src = DRAWIO_VIEWER_SCRIPT_URL;
|
|
57
|
-
script.async = true;
|
|
58
|
-
script.dataset.collabmdDrawioViewer = 'true';
|
|
59
|
-
document.head.append(script);
|
|
60
|
-
} else if (window.GraphViewer?.processElements) {
|
|
61
|
-
handleLoad();
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
return drawioViewerLoadPromise;
|
|
66
|
-
}
|
|
67
12
|
|
|
68
13
|
export class DrawioEmbedController {
|
|
69
14
|
constructor({
|
|
@@ -350,59 +295,21 @@ export class DrawioEmbedController {
|
|
|
350
295
|
}
|
|
351
296
|
|
|
352
297
|
async renderViewerEntry(entry) {
|
|
353
|
-
const
|
|
354
|
-
this.vaultApiClient.readFile(entry.filePath),
|
|
355
|
-
ensureDrawioViewerLoaded(),
|
|
356
|
-
]);
|
|
298
|
+
const { content } = await this.vaultApiClient.readFile(entry.filePath);
|
|
357
299
|
|
|
358
300
|
if (!entry.wrapper?.isConnected || !entry.viewerElement?.isConnected) {
|
|
359
301
|
return;
|
|
360
302
|
}
|
|
361
303
|
|
|
362
304
|
const theme = this.getTheme?.() === 'light' ? 'light' : 'dark';
|
|
363
|
-
const graphElement = document.createElement('div');
|
|
364
|
-
graphElement.className = 'mxgraph drawio-viewer-frame';
|
|
365
|
-
graphElement.dataset.action = 'open-file';
|
|
366
|
-
graphElement.dataset.filePath = entry.filePath;
|
|
367
|
-
graphElement.setAttribute('role', 'button');
|
|
368
|
-
graphElement.setAttribute('tabindex', '0');
|
|
369
|
-
graphElement.setAttribute('aria-label', `Open ${entry.label.replace(/\.drawio$/i, '')}`);
|
|
370
|
-
graphElement.addEventListener('click', (event) => {
|
|
371
|
-
event.preventDefault();
|
|
372
|
-
this.onOpenFile?.(entry.filePath);
|
|
373
|
-
});
|
|
374
|
-
graphElement.addEventListener('keydown', (event) => {
|
|
375
|
-
if (event.key !== 'Enter' && event.key !== ' ') {
|
|
376
|
-
return;
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
event.preventDefault();
|
|
380
|
-
this.onOpenFile?.(entry.filePath);
|
|
381
|
-
});
|
|
382
|
-
graphElement.dataset.mxgraph = JSON.stringify({
|
|
383
|
-
'check-visible-state': false,
|
|
384
|
-
center: true,
|
|
385
|
-
border: 0,
|
|
386
|
-
'dark-mode': theme,
|
|
387
|
-
editable: false,
|
|
388
|
-
fit: 1,
|
|
389
|
-
lightbox: false,
|
|
390
|
-
nav: false,
|
|
391
|
-
resize: false,
|
|
392
|
-
tooltips: false,
|
|
393
|
-
xml: String(content ?? ''),
|
|
394
|
-
});
|
|
395
|
-
|
|
396
305
|
const viewerHost = entry.wrapper.querySelector('.drawio-viewer-shell') ?? entry.viewerElement;
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
viewer.processElements();
|
|
306
|
+
entry.viewerElement = await renderDrawioViewer(viewerHost, {
|
|
307
|
+
ariaLabel: `Open ${entry.label.replace(/\.drawio$/i, '')}`,
|
|
308
|
+
className: 'mxgraph drawio-viewer-frame',
|
|
309
|
+
onActivate: () => this.onOpenFile?.(entry.filePath),
|
|
310
|
+
source: String(content ?? ''),
|
|
311
|
+
theme,
|
|
312
|
+
});
|
|
406
313
|
}
|
|
407
314
|
|
|
408
315
|
buildIframeUrl(entry) {
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
const DRAWIO_VIEWER_SCRIPT_URL = 'https://viewer.diagrams.net/js/viewer-static.min.js';
|
|
2
|
+
|
|
3
|
+
let drawioViewerLoadPromise = null;
|
|
4
|
+
|
|
5
|
+
export function ensureDrawioViewerLoaded() {
|
|
6
|
+
if (window.GraphViewer?.processElements) {
|
|
7
|
+
return Promise.resolve(window.GraphViewer);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (drawioViewerLoadPromise) {
|
|
11
|
+
return drawioViewerLoadPromise;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
drawioViewerLoadPromise = new Promise((resolve, reject) => {
|
|
15
|
+
const existingScript = document.querySelector('script[data-collabmd-drawio-viewer]');
|
|
16
|
+
const script = existingScript instanceof HTMLScriptElement
|
|
17
|
+
? existingScript
|
|
18
|
+
: document.createElement('script');
|
|
19
|
+
|
|
20
|
+
const cleanup = () => {
|
|
21
|
+
script.removeEventListener('error', handleError);
|
|
22
|
+
script.removeEventListener('load', handleLoad);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const handleError = () => {
|
|
26
|
+
cleanup();
|
|
27
|
+
drawioViewerLoadPromise = null;
|
|
28
|
+
reject(new Error('Failed to load draw.io viewer'));
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const handleLoad = () => {
|
|
32
|
+
cleanup();
|
|
33
|
+
if (!window.GraphViewer?.processElements) {
|
|
34
|
+
drawioViewerLoadPromise = null;
|
|
35
|
+
reject(new Error('draw.io viewer did not initialize'));
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
resolve(window.GraphViewer);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
script.addEventListener('error', handleError, { once: true });
|
|
43
|
+
script.addEventListener('load', handleLoad, { once: true });
|
|
44
|
+
|
|
45
|
+
if (!existingScript) {
|
|
46
|
+
script.src = DRAWIO_VIEWER_SCRIPT_URL;
|
|
47
|
+
script.async = true;
|
|
48
|
+
script.dataset.collabmdDrawioViewer = 'true';
|
|
49
|
+
document.head.append(script);
|
|
50
|
+
} else if (window.GraphViewer?.processElements) {
|
|
51
|
+
handleLoad();
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
return drawioViewerLoadPromise;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function createDrawioViewerElement({
|
|
59
|
+
ariaLabel = '',
|
|
60
|
+
className = 'drawio-viewer-frame',
|
|
61
|
+
onActivate = null,
|
|
62
|
+
source = '',
|
|
63
|
+
theme = 'dark',
|
|
64
|
+
} = {}) {
|
|
65
|
+
const graphElement = document.createElement('div');
|
|
66
|
+
graphElement.className = className;
|
|
67
|
+
if (ariaLabel) {
|
|
68
|
+
graphElement.setAttribute('aria-label', ariaLabel);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (typeof onActivate === 'function') {
|
|
72
|
+
graphElement.dataset.action = 'open-file';
|
|
73
|
+
graphElement.setAttribute('role', 'button');
|
|
74
|
+
graphElement.setAttribute('tabindex', '0');
|
|
75
|
+
graphElement.addEventListener('click', (event) => {
|
|
76
|
+
event.preventDefault();
|
|
77
|
+
onActivate();
|
|
78
|
+
});
|
|
79
|
+
graphElement.addEventListener('keydown', (event) => {
|
|
80
|
+
if (event.key !== 'Enter' && event.key !== ' ') {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
event.preventDefault();
|
|
85
|
+
onActivate();
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
graphElement.dataset.mxgraph = JSON.stringify({
|
|
90
|
+
'check-visible-state': false,
|
|
91
|
+
center: true,
|
|
92
|
+
border: 0,
|
|
93
|
+
'dark-mode': theme === 'light' ? 'light' : 'dark',
|
|
94
|
+
editable: false,
|
|
95
|
+
fit: 1,
|
|
96
|
+
lightbox: false,
|
|
97
|
+
nav: false,
|
|
98
|
+
resize: false,
|
|
99
|
+
tooltips: false,
|
|
100
|
+
xml: String(source ?? ''),
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
return graphElement;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export async function renderDrawioViewer(host, options = {}) {
|
|
107
|
+
const viewer = await ensureDrawioViewerLoaded();
|
|
108
|
+
const graphElement = createDrawioViewerElement(options);
|
|
109
|
+
host.replaceChildren(graphElement);
|
|
110
|
+
|
|
111
|
+
if (typeof viewer.createViewerForElement === 'function') {
|
|
112
|
+
viewer.createViewerForElement(graphElement);
|
|
113
|
+
} else {
|
|
114
|
+
viewer.processElements();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return graphElement;
|
|
118
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { setDiagramActionButtonIcon } from '../domain/diagram-action-icons.js';
|
|
2
2
|
import { reconcileEmbedEntries } from './excalidraw-embed-reconciler.js';
|
|
3
|
-
import { resolveAppUrl } from '../domain/runtime-paths.js';
|
|
3
|
+
import { resolveAppUrl, resolveWsServerOverride } from '../domain/runtime-paths.js';
|
|
4
4
|
import {
|
|
5
5
|
cancelIdleRender,
|
|
6
6
|
isNearViewport,
|
|
@@ -15,11 +15,19 @@ const MAX_IFRAME_BOOT_ATTEMPTS = 3;
|
|
|
15
15
|
const MIN_HEIGHT = 200;
|
|
16
16
|
const EDITOR_IFRAME_PATH = '/excalidraw-editor.html';
|
|
17
17
|
|
|
18
|
+
function findEmbedPlaceholder(previewElement, key) {
|
|
19
|
+
const placeholders = previewElement?.querySelectorAll?.(
|
|
20
|
+
'.excalidraw-embed-placeholder[data-embed-key]',
|
|
21
|
+
);
|
|
22
|
+
return Array.from(placeholders || []).find((placeholder) => placeholder.dataset?.embedKey === key) || null;
|
|
23
|
+
}
|
|
24
|
+
|
|
18
25
|
export class ExcalidrawEmbedController {
|
|
19
26
|
constructor({
|
|
20
27
|
getTheme,
|
|
21
28
|
getLocalUser,
|
|
22
29
|
onOpenFile = null,
|
|
30
|
+
onStopFollowing = null,
|
|
23
31
|
onToggleQuickSwitcher = null,
|
|
24
32
|
previewContainer,
|
|
25
33
|
previewElement,
|
|
@@ -28,6 +36,7 @@ export class ExcalidrawEmbedController {
|
|
|
28
36
|
this.getTheme = getTheme;
|
|
29
37
|
this.getLocalUser = getLocalUser;
|
|
30
38
|
this.onOpenFile = onOpenFile;
|
|
39
|
+
this.onStopFollowing = onStopFollowing;
|
|
31
40
|
this.onToggleQuickSwitcher = onToggleQuickSwitcher;
|
|
32
41
|
this.previewContainer = previewContainer;
|
|
33
42
|
this.previewElement = previewElement;
|
|
@@ -70,12 +79,16 @@ export class ExcalidrawEmbedController {
|
|
|
70
79
|
|
|
71
80
|
this.embedEntries.forEach((entry) => {
|
|
72
81
|
this._clearEntryBootTimeout(entry);
|
|
82
|
+
entry.resizerCleanup?.();
|
|
83
|
+
entry.resizerCleanup = null;
|
|
73
84
|
entry.wrapper?.remove();
|
|
74
85
|
entry.placeholder = null;
|
|
75
86
|
});
|
|
76
87
|
this.embedEntries.clear();
|
|
77
88
|
if (this.warmEntry) {
|
|
78
89
|
this._clearEntryBootTimeout(this.warmEntry);
|
|
90
|
+
this.warmEntry.resizerCleanup?.();
|
|
91
|
+
this.warmEntry.resizerCleanup = null;
|
|
79
92
|
this.warmEntry.wrapper?.remove();
|
|
80
93
|
this.warmEntry = null;
|
|
81
94
|
}
|
|
@@ -219,6 +232,25 @@ export class ExcalidrawEmbedController {
|
|
|
219
232
|
});
|
|
220
233
|
}
|
|
221
234
|
|
|
235
|
+
openCommentThread(filePath, threadId) {
|
|
236
|
+
if (!filePath || !threadId) {
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const entry = this._findEntryByFilePath(filePath);
|
|
241
|
+
if (!entry) {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
entry.pendingCommentThreadId = threadId;
|
|
246
|
+
if (entry.isReady) {
|
|
247
|
+
this._postPendingCommentThread(entry);
|
|
248
|
+
} else if (!entry.wrapper) {
|
|
249
|
+
this._enqueueHydration(entry, { prioritize: true });
|
|
250
|
+
}
|
|
251
|
+
return true;
|
|
252
|
+
}
|
|
253
|
+
|
|
222
254
|
prepareFileDisconnect(filePath, { timeoutMs = 10000 } = {}) {
|
|
223
255
|
const entry = this._findEntryByFilePath(filePath);
|
|
224
256
|
if (!entry?.iframe?.contentWindow) {
|
|
@@ -394,6 +426,7 @@ export class ExcalidrawEmbedController {
|
|
|
394
426
|
entry.maxButton = mount.maxButton;
|
|
395
427
|
entry.openButton = mount.openButton;
|
|
396
428
|
entry.instanceId = mount.instanceId;
|
|
429
|
+
entry.resizerCleanup = mount.resizerCleanup;
|
|
397
430
|
entry.isReady = false;
|
|
398
431
|
entry.bootFilePath = entry.filePath;
|
|
399
432
|
entry.bootMode = this._getEntryMode(entry);
|
|
@@ -414,7 +447,7 @@ export class ExcalidrawEmbedController {
|
|
|
414
447
|
_attachWrapper(entry) {
|
|
415
448
|
const placeholder = entry.placeholder?.isConnected
|
|
416
449
|
? entry.placeholder
|
|
417
|
-
: this.previewElement
|
|
450
|
+
: findEmbedPlaceholder(this.previewElement, entry.key);
|
|
418
451
|
|
|
419
452
|
if (!placeholder) {
|
|
420
453
|
return;
|
|
@@ -476,6 +509,8 @@ export class ExcalidrawEmbedController {
|
|
|
476
509
|
}
|
|
477
510
|
|
|
478
511
|
this._clearEntryBootTimeout(entry);
|
|
512
|
+
entry.resizerCleanup?.();
|
|
513
|
+
entry.resizerCleanup = null;
|
|
479
514
|
if (this.warmEntry === entry) {
|
|
480
515
|
this.warmEntry = null;
|
|
481
516
|
}
|
|
@@ -634,7 +669,7 @@ export class ExcalidrawEmbedController {
|
|
|
634
669
|
}
|
|
635
670
|
|
|
636
671
|
const hostSearchParams = new URLSearchParams(window.location.search);
|
|
637
|
-
const serverOverride =
|
|
672
|
+
const serverOverride = resolveWsServerOverride();
|
|
638
673
|
if (serverOverride) {
|
|
639
674
|
iframeUrl.searchParams.set('server', serverOverride);
|
|
640
675
|
}
|
|
@@ -702,7 +737,7 @@ export class ExcalidrawEmbedController {
|
|
|
702
737
|
const resizer = document.createElement('div');
|
|
703
738
|
resizer.className = 'excalidraw-embed-resizer';
|
|
704
739
|
resizer.title = 'Drag to resize';
|
|
705
|
-
this._setupResizer(resizer, iframe, () => {
|
|
740
|
+
const resizerCleanup = this._setupResizer(resizer, iframe, () => {
|
|
706
741
|
this._syncEntryLayout(entry);
|
|
707
742
|
this._requestPreviewViewportFit(entry);
|
|
708
743
|
});
|
|
@@ -769,6 +804,7 @@ export class ExcalidrawEmbedController {
|
|
|
769
804
|
labelElement: label,
|
|
770
805
|
maxButton: maxBtn,
|
|
771
806
|
openButton: openBtn,
|
|
807
|
+
resizerCleanup,
|
|
772
808
|
wrapper,
|
|
773
809
|
};
|
|
774
810
|
}
|
|
@@ -793,6 +829,7 @@ export class ExcalidrawEmbedController {
|
|
|
793
829
|
_setupResizer(resizer, iframe, onResizeEnd = null) {
|
|
794
830
|
let startY = 0;
|
|
795
831
|
let startHeight = 0;
|
|
832
|
+
let isDragging = false;
|
|
796
833
|
|
|
797
834
|
const onPointerMove = (event) => {
|
|
798
835
|
const delta = event.clientY - startY;
|
|
@@ -801,20 +838,37 @@ export class ExcalidrawEmbedController {
|
|
|
801
838
|
iframe.style.pointerEvents = 'none';
|
|
802
839
|
};
|
|
803
840
|
|
|
804
|
-
const
|
|
841
|
+
const stopDragging = () => {
|
|
842
|
+
if (!isDragging) {
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
isDragging = false;
|
|
805
847
|
iframe.style.pointerEvents = '';
|
|
806
848
|
document.removeEventListener('pointermove', onPointerMove);
|
|
807
849
|
document.removeEventListener('pointerup', onPointerUp);
|
|
850
|
+
};
|
|
851
|
+
|
|
852
|
+
const onPointerUp = () => {
|
|
853
|
+
stopDragging();
|
|
808
854
|
onResizeEnd?.();
|
|
809
855
|
};
|
|
810
856
|
|
|
811
|
-
|
|
857
|
+
const onPointerDown = (event) => {
|
|
812
858
|
event.preventDefault();
|
|
859
|
+
isDragging = true;
|
|
813
860
|
startY = event.clientY;
|
|
814
861
|
startHeight = iframe.offsetHeight;
|
|
815
862
|
document.addEventListener('pointermove', onPointerMove);
|
|
816
863
|
document.addEventListener('pointerup', onPointerUp);
|
|
817
|
-
}
|
|
864
|
+
};
|
|
865
|
+
|
|
866
|
+
resizer.addEventListener('pointerdown', onPointerDown);
|
|
867
|
+
|
|
868
|
+
return () => {
|
|
869
|
+
resizer.removeEventListener?.('pointerdown', onPointerDown);
|
|
870
|
+
stopDragging();
|
|
871
|
+
};
|
|
818
872
|
}
|
|
819
873
|
|
|
820
874
|
_ensureOverlayRoot() {
|
|
@@ -1064,7 +1118,7 @@ export class ExcalidrawEmbedController {
|
|
|
1064
1118
|
|
|
1065
1119
|
const placeholder = entry.placeholder?.isConnected
|
|
1066
1120
|
? entry.placeholder
|
|
1067
|
-
: this.previewElement
|
|
1121
|
+
: findEmbedPlaceholder(this.previewElement, entry.key);
|
|
1068
1122
|
|
|
1069
1123
|
if (!placeholder) {
|
|
1070
1124
|
return;
|
|
@@ -1163,6 +1217,7 @@ export class ExcalidrawEmbedController {
|
|
|
1163
1217
|
theme: this.getTheme?.() || 'dark',
|
|
1164
1218
|
});
|
|
1165
1219
|
this._syncEntryFollowState(entry);
|
|
1220
|
+
this._postPendingCommentThread?.(entry);
|
|
1166
1221
|
if (this._entryNeedsHardReload(entry)) {
|
|
1167
1222
|
void this._hydrateEntry(entry);
|
|
1168
1223
|
}
|
|
@@ -1174,6 +1229,11 @@ export class ExcalidrawEmbedController {
|
|
|
1174
1229
|
return;
|
|
1175
1230
|
}
|
|
1176
1231
|
|
|
1232
|
+
if (msg.type === 'stop-following') {
|
|
1233
|
+
this.onStopFollowing?.();
|
|
1234
|
+
return;
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1177
1237
|
if (msg.type === 'error') {
|
|
1178
1238
|
if (entry.isParked) {
|
|
1179
1239
|
return;
|
|
@@ -1227,6 +1287,19 @@ export class ExcalidrawEmbedController {
|
|
|
1227
1287
|
entry?.iframe?.contentWindow?.postMessage(payload, window.location.origin);
|
|
1228
1288
|
}
|
|
1229
1289
|
|
|
1290
|
+
_postPendingCommentThread(entry) {
|
|
1291
|
+
if (!entry?.isReady || !entry.pendingCommentThreadId) {
|
|
1292
|
+
return;
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
this._postMessageToEntry(entry, {
|
|
1296
|
+
source: 'collabmd-host',
|
|
1297
|
+
threadId: entry.pendingCommentThreadId,
|
|
1298
|
+
type: 'open-comment-thread',
|
|
1299
|
+
});
|
|
1300
|
+
entry.pendingCommentThreadId = null;
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1230
1303
|
_requestPreviewViewportFit(entry) {
|
|
1231
1304
|
if (this._isFilePreviewEntry(entry)) {
|
|
1232
1305
|
return;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getVaultFileExtension,
|
|
3
|
+
isVaultFilePath,
|
|
4
|
+
VAULT_FILE_EXTENSIONS,
|
|
3
5
|
} from '../../domain/file-kind.js';
|
|
6
|
+
import { pickFiles } from '../browser-utils.js';
|
|
4
7
|
import {
|
|
5
8
|
createBaseStarter,
|
|
6
9
|
composeVaultChildPath,
|
|
@@ -8,6 +11,7 @@ import {
|
|
|
8
11
|
createMarkdownStarter,
|
|
9
12
|
createMermaidStarter,
|
|
10
13
|
createPlantUmlStarter,
|
|
14
|
+
createStructurizrStarter,
|
|
11
15
|
ensureVaultExtension,
|
|
12
16
|
getVaultPathLeaf,
|
|
13
17
|
getVaultPathParent,
|
|
@@ -28,6 +32,8 @@ function formatCount(value, singularLabel, pluralLabel) {
|
|
|
28
32
|
return `${value} ${value === 1 ? singularLabel : pluralLabel}`;
|
|
29
33
|
}
|
|
30
34
|
|
|
35
|
+
const VAULT_FILE_PICKER_ACCEPT = VAULT_FILE_EXTENSIONS.join(',');
|
|
36
|
+
|
|
31
37
|
function createEmptyExcalidrawScene() {
|
|
32
38
|
return JSON.stringify({
|
|
33
39
|
type: 'excalidraw',
|
|
@@ -116,6 +122,18 @@ export class FileActionController {
|
|
|
116
122
|
|
|
117
123
|
getCreateActions({ parentDir = '' } = {}) {
|
|
118
124
|
return [
|
|
125
|
+
{
|
|
126
|
+
contextLabel: 'Upload files',
|
|
127
|
+
group: 'File',
|
|
128
|
+
hint: 'Supported vault files',
|
|
129
|
+
icon: this.getCreateActionIcon('upload'),
|
|
130
|
+
id: 'upload',
|
|
131
|
+
label: 'Upload files',
|
|
132
|
+
meta: 'Multiple',
|
|
133
|
+
onSelect: () => {
|
|
134
|
+
void this.handleUploadFiles({ parentDir });
|
|
135
|
+
},
|
|
136
|
+
},
|
|
119
137
|
{
|
|
120
138
|
contextLabel: 'New markdown file',
|
|
121
139
|
group: 'Note',
|
|
@@ -176,6 +194,16 @@ export class FileActionController {
|
|
|
176
194
|
meta: '.puml',
|
|
177
195
|
onSelect: () => this.handleNewPlantUml({ parentDir }),
|
|
178
196
|
},
|
|
197
|
+
{
|
|
198
|
+
contextLabel: 'New Structurizr workspace',
|
|
199
|
+
group: 'Diagram',
|
|
200
|
+
hint: 'Structurizr DSL',
|
|
201
|
+
icon: this.getCreateActionIcon('structurizr'),
|
|
202
|
+
id: 'structurizr',
|
|
203
|
+
label: 'Structurizr workspace',
|
|
204
|
+
meta: '.dsl',
|
|
205
|
+
onSelect: () => this.handleNewStructurizr({ parentDir }),
|
|
206
|
+
},
|
|
179
207
|
{
|
|
180
208
|
contextLabel: 'New folder',
|
|
181
209
|
group: 'Structure',
|
|
@@ -241,10 +269,13 @@ export class FileActionController {
|
|
|
241
269
|
|
|
242
270
|
getCreateActionIcon(kind) {
|
|
243
271
|
switch (kind) {
|
|
272
|
+
case 'upload':
|
|
273
|
+
return '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 16V4"/><path d="m7 9 5-5 5 5"/><path d="M5 20h14"/></svg>';
|
|
244
274
|
case 'base':
|
|
245
275
|
return '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 4h7l5 5v11a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z"/><path d="M14 4v5h5"/><path d="M8 13h8"/><path d="M8 17h6"/><path d="M8 9h3"/></svg>';
|
|
246
276
|
case 'drawio':
|
|
247
277
|
case 'plantuml':
|
|
278
|
+
case 'structurizr':
|
|
248
279
|
return '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="7" height="6" rx="1"/><rect x="14" y="4" width="7" height="6" rx="1"/><rect x="8.5" y="14" width="7" height="6" rx="1"/><path d="M10 7h4"/><path d="M17.5 10v2.5"/><path d="M6.5 10v2.5"/><path d="M6.5 12.5h11"/></svg>';
|
|
249
280
|
case 'excalidraw':
|
|
250
281
|
return '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 19l7-7 3 3-7 7-3-3z"/><path d="M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z"/><path d="M2 2l7.586 7.586"/><circle cx="11" cy="11" r="2"/></svg>';
|
|
@@ -476,6 +507,47 @@ export class FileActionController {
|
|
|
476
507
|
}
|
|
477
508
|
}
|
|
478
509
|
|
|
510
|
+
async uploadVaultFiles(files = [], { parentDir = '' } = {}) {
|
|
511
|
+
const normalizedParentDir = normalizeVaultPathInput(parentDir);
|
|
512
|
+
let uploaded = false;
|
|
513
|
+
|
|
514
|
+
for (const file of Array.from(files ?? [])) {
|
|
515
|
+
const fileName = getVaultPathLeaf(file?.name);
|
|
516
|
+
const filePath = composeVaultChildPath(normalizedParentDir, fileName);
|
|
517
|
+
if (!fileName || !isVaultFilePath(filePath)) {
|
|
518
|
+
this.showToast(`Unsupported file type: ${fileName || 'unnamed file'}`);
|
|
519
|
+
continue;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
try {
|
|
523
|
+
await this.runWorkspaceMutation((requestId) => this.vaultClient.uploadFile({
|
|
524
|
+
file,
|
|
525
|
+
path: filePath,
|
|
526
|
+
requestId,
|
|
527
|
+
}));
|
|
528
|
+
uploaded = true;
|
|
529
|
+
this.state.expandDirectoryPath(filePath, { includeLeaf: false });
|
|
530
|
+
} catch (error) {
|
|
531
|
+
this.showToast(`${fileName}: ${error?.message || 'Failed to upload file'}`);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
if (uploaded) {
|
|
536
|
+
await this.refresh();
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
return uploaded;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
async handleUploadFiles({ parentDir = '' } = {}) {
|
|
543
|
+
const files = await pickFiles({ accept: VAULT_FILE_PICKER_ACCEPT, multiple: true });
|
|
544
|
+
if (files.length === 0) {
|
|
545
|
+
return false;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
return this.uploadVaultFiles(files, { parentDir });
|
|
549
|
+
}
|
|
550
|
+
|
|
479
551
|
async createVaultFile(filePath, content, { openAfterCreate = false, errorMessage = 'Failed to create file' } = {}) {
|
|
480
552
|
try {
|
|
481
553
|
await this.runWorkspaceMutation((requestId) => this.vaultClient.createFile(withRequestId({
|
|
@@ -953,6 +1025,36 @@ export class FileActionController {
|
|
|
953
1025
|
});
|
|
954
1026
|
}
|
|
955
1027
|
|
|
1028
|
+
handleNewStructurizr({ parentDir = '' } = {}) {
|
|
1029
|
+
const context = this.getCreateContext(parentDir);
|
|
1030
|
+
|
|
1031
|
+
this.openActionDialog({
|
|
1032
|
+
title: 'Create Structurizr workspace',
|
|
1033
|
+
copy: context.normalizedParentDir
|
|
1034
|
+
? 'Create a collaborative C4 workspace inside the selected folder.'
|
|
1035
|
+
: 'Create a collaborative C4 workspace in the vault.',
|
|
1036
|
+
label: `Workspace ${context.inputLabelSuffix}`,
|
|
1037
|
+
hint: `${context.hintPrefix} ".dsl" is added automatically. workspace.dsl is conventional; any workspace .dsl file can render.`,
|
|
1038
|
+
note: context.note,
|
|
1039
|
+
placeholder: 'workspace',
|
|
1040
|
+
submitLabel: 'Create workspace',
|
|
1041
|
+
emptyMessage: 'Workspace path is required',
|
|
1042
|
+
onSubmit: (value) => {
|
|
1043
|
+
const normalizedPath = normalizeVaultPathInput(value);
|
|
1044
|
+
if (!normalizedPath) {
|
|
1045
|
+
this.showToast('Workspace path is required');
|
|
1046
|
+
return false;
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
const starter = createStructurizrStarter(composeVaultChildPath(context.normalizedParentDir, normalizedPath));
|
|
1050
|
+
return this.createVaultFile(starter.path, starter.content, {
|
|
1051
|
+
errorMessage: 'Failed to create Structurizr workspace',
|
|
1052
|
+
openAfterCreate: true,
|
|
1053
|
+
});
|
|
1054
|
+
},
|
|
1055
|
+
});
|
|
1056
|
+
}
|
|
1057
|
+
|
|
956
1058
|
handleRenameFile(filePath) {
|
|
957
1059
|
const extension = getVaultFileExtension(filePath) || '.md';
|
|
958
1060
|
|
|
@@ -24,11 +24,6 @@ export class FileExplorerController {
|
|
|
24
24
|
this.threadCounts = new Map();
|
|
25
25
|
this.view = new FileExplorerView({
|
|
26
26
|
mobileBreakpointQuery,
|
|
27
|
-
onDirectorySelect: (pathValue) => {
|
|
28
|
-
this.state.expandDirectoryPath(pathValue);
|
|
29
|
-
this.state.setSearchQuery('');
|
|
30
|
-
this.renderTree({ reset: true });
|
|
31
|
-
},
|
|
32
27
|
onDirectoryToggle: (pathValue) => {
|
|
33
28
|
this.state.toggleDirectory(pathValue);
|
|
34
29
|
if (!this.view.rerenderDirectoryBranch(pathValue, this.state.tree, {
|