ryugi-artifacts 1.14.0 → 1.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/dist/cli.cjs +22 -4
  2. package/dist/server.cjs +364 -206
  3. package/dist/viewer/{CloudDocument-u1AHTtia.js → CloudDocument-CgM3kbiO.js} +1 -1
  4. package/dist/viewer/CloudLiveDocument-CdN71jfH.js +1 -0
  5. package/dist/viewer/{DocumentLayout-BZVsht5l.js → DocumentLayout-BDQ2bRgn.js} +3 -3
  6. package/dist/viewer/DocumentPage-BBzAFj4H.js +1 -0
  7. package/dist/viewer/{abnfDiagram-VCTEODGH-DOddnTT5.js → abnfDiagram-VCTEODGH-DXcz0DY8.js} +1 -1
  8. package/dist/viewer/{ar-SA-G6X2FPQ2-C4kVNJ25.js → ar-SA-G6X2FPQ2-DaFICdeh.js} +1 -1
  9. package/dist/viewer/{architecture-7GRP2DOG-C7jzHuyU.js → architecture-7GRP2DOG-Bl5CPsMS.js} +1 -1
  10. package/dist/viewer/{architectureDiagram-5GKGNRK7-BLQ8w9r3.js → architectureDiagram-5GKGNRK7-7HwBC9Wz.js} +1 -1
  11. package/dist/viewer/{az-AZ-76LH7QW2-BE_nuJ_w.js → az-AZ-76LH7QW2-ro71YLew.js} +1 -1
  12. package/dist/viewer/{bg-BG-XCXSNQG7-DVnMR_wa.js → bg-BG-XCXSNQG7-BBql1i2c.js} +1 -1
  13. package/dist/viewer/{blockDiagram-I7D4REHJ-CT9zI25c.js → blockDiagram-I7D4REHJ-DN6_CCIZ.js} +1 -1
  14. package/dist/viewer/{bn-BD-2XOGV67Q-DnbZpPkx.js → bn-BD-2XOGV67Q-D0nEk_sk.js} +1 -1
  15. package/dist/viewer/{c4Diagram-7LVT6UL2-B2UHTp3A.js → c4Diagram-7LVT6UL2-BiKuFZ_0.js} +1 -1
  16. package/dist/viewer/{ca-ES-6MX7JW3Y-BBLtwwxQ.js → ca-ES-6MX7JW3Y-BzXg8v5p.js} +1 -1
  17. package/dist/viewer/channel-CoY9xRKf.js +1 -0
  18. package/dist/viewer/{chunk-4HAMMTFA-BqFllWeW.js → chunk-4HAMMTFA-D8wduydj.js} +1 -1
  19. package/dist/viewer/{chunk-75Z2AOVW-DrVMXOXp.js → chunk-75Z2AOVW-A-EObLCy.js} +1 -1
  20. package/dist/viewer/{chunk-DU6HZSFF-BXmcb4Sk.js → chunk-DU6HZSFF-CDWc5UBY.js} +1 -1
  21. package/dist/viewer/{chunk-EIO257PC-CCA1PGmt.js → chunk-EIO257PC-KVQLe9-1.js} +1 -1
  22. package/dist/viewer/{chunk-F27PBJKO-CrQVLXVd.js → chunk-F27PBJKO-qGDpbSI2.js} +1 -1
  23. package/dist/viewer/{chunk-GMAD6QVW-97i2yOl_.js → chunk-GMAD6QVW-BPxTHMTi.js} +1 -1
  24. package/dist/viewer/{chunk-GVQU2GXP-Blvsu0do.js → chunk-GVQU2GXP-C5_2EAAn.js} +1 -1
  25. package/dist/viewer/{chunk-IMKFNOWR-Dcqny5PK.js → chunk-IMKFNOWR-CoST25Zy.js} +1 -1
  26. package/dist/viewer/{chunk-L3NEJ4N5-BFl0y0sr.js → chunk-L3NEJ4N5-DqtaXAcI.js} +1 -1
  27. package/dist/viewer/{chunk-OSK3NFVY-BCb4HvUu.js → chunk-OSK3NFVY-DacvL7tA.js} +1 -1
  28. package/dist/viewer/{chunk-P2QGCYS3-D1vp1a2x.js → chunk-P2QGCYS3-DJOHCBv0.js} +1 -1
  29. package/dist/viewer/{chunk-POPQ4Y6H-DmMVoGMV.js → chunk-POPQ4Y6H-at1Afs_1.js} +1 -1
  30. package/dist/viewer/{chunk-PWAF6VOD-CvuHiA9u.js → chunk-PWAF6VOD-Cxj_hOdt.js} +1 -1
  31. package/dist/viewer/{chunk-SHT3W25Y-C5550mfq.js → chunk-SHT3W25Y-D9pKJ6Au.js} +1 -1
  32. package/dist/viewer/{chunk-SVP7TREG-CmI3HlnO.js → chunk-SVP7TREG-svneeNVA.js} +1 -1
  33. package/dist/viewer/{chunk-TICWLB2K-BiHx1C7K.js → chunk-TICWLB2K-xfr9ROyW.js} +1 -1
  34. package/dist/viewer/classDiagram-ZZMXUADV-lu71gUXJ.js +1 -0
  35. package/dist/viewer/classDiagram-v2-VYDZK3BY-lu71gUXJ.js +1 -0
  36. package/dist/viewer/{cs-CZ-2BRQDIVT-DdgAqB28.js → cs-CZ-2BRQDIVT-bwZx9UIu.js} +1 -1
  37. package/dist/viewer/{cynefin-OW5HDTMX-hyUIYf_a.js → cynefin-OW5HDTMX-B-FRYmfA.js} +1 -1
  38. package/dist/viewer/{cynefinDiagram-5FMLGOSQ-MSO66Kf9.js → cynefinDiagram-5FMLGOSQ-DlNaJbj_.js} +1 -1
  39. package/dist/viewer/{da-DK-5WZEPLOC-B20euANp.js → da-DK-5WZEPLOC-BApDVcwE.js} +1 -1
  40. package/dist/viewer/{dagre-GXQ25YYZ-D1D2MS9i.js → dagre-GXQ25YYZ-DWu2Ycc5.js} +1 -1
  41. package/dist/viewer/{de-DE-XR44H4JA-DtOsjZhQ.js → de-DE-XR44H4JA-COcHc6Zt.js} +1 -1
  42. package/dist/viewer/{diagram-S7CK7UJ4-DkMhbKdp.js → diagram-S7CK7UJ4-D8VO7YKc.js} +1 -1
  43. package/dist/viewer/{diagram-UQ7AKVKN-C158H-FA.js → diagram-UQ7AKVKN-D5OcQNY9.js} +1 -1
  44. package/dist/viewer/{diagram-VSXAHHWV-CNiIQ5MT.js → diagram-VSXAHHWV-D8r4mNUW.js} +1 -1
  45. package/dist/viewer/{diagram-VX7I27RA-Dk9QThUy.js → diagram-VX7I27RA-DRHmiAWI.js} +1 -1
  46. package/dist/viewer/{diagram-Z3DM3KII-BC3jQKJT.js → diagram-Z3DM3KII-ClXzWLem.js} +1 -1
  47. package/dist/viewer/{dist-DdVUlzZ4.js → dist-BKtxxS1a.js} +1 -1
  48. package/dist/viewer/{dist-B5nGwpR_.js → dist-Bgijnk4D.js} +1 -1
  49. package/dist/viewer/{dist-CptRpcua.js → dist-BuKe8NdN.js} +1 -1
  50. package/dist/viewer/{dist-BmKh-rIJ.js → dist-C2adJeNZ.js} +1 -1
  51. package/dist/viewer/{dist-CwBtXhoH.js → dist-CByD4sdq.js} +1 -1
  52. package/dist/viewer/{dist-BR3If-ck.js → dist-CFkCXjQP.js} +1 -1
  53. package/dist/viewer/{dist-vEeJCFeQ.js → dist-CV7QdHTq.js} +1 -1
  54. package/dist/viewer/{dist-CQCnpK-W.js → dist-C_NwF-ep.js} +1 -1
  55. package/dist/viewer/{dist-BRxDmEx_.js → dist-D0Emc84u.js} +1 -1
  56. package/dist/viewer/{dist-DCG7CDqU.js → dist-DB3o8dUU.js} +1 -1
  57. package/dist/viewer/{dist-C9-L2o-Z.js → dist-DLh5uREE.js} +1 -1
  58. package/dist/viewer/{dist-C07Ds6_z.js → dist-DcGUli8O.js} +1 -1
  59. package/dist/viewer/{dist-C-b7WbV_.js → dist-DfWxOyg4.js} +1 -1
  60. package/dist/viewer/{dist-Cp8qF3TY.js → dist-DlANbAUX.js} +1 -1
  61. package/dist/viewer/{dist-aMaYpkgT.js → dist-DzBPEHnz.js} +1 -1
  62. package/dist/viewer/{dist-ClP3mNdb.js → dist-G2JHMLgK.js} +1 -1
  63. package/dist/viewer/{dist-Cgcnnb5W.js → dist-M7Lz5R2v.js} +1 -1
  64. package/dist/viewer/{dist-By1owoGm.js → dist-TX5rYYGW.js} +4 -4
  65. package/dist/viewer/{dist-Cpn0flK8.js → dist-VupXLYv6.js} +1 -1
  66. package/dist/viewer/{dist-BJB4_EoM.js → dist-_3NL_2LS.js} +1 -1
  67. package/dist/viewer/{dist-wioUtWDr.js → dist-a8BuHhYq.js} +1 -1
  68. package/dist/viewer/{dist-y1I2zezv.js → dist-mDWB-P3S.js} +1 -1
  69. package/dist/viewer/{dist-DkajdzVH.js → dist-q1jFGEbP.js} +1 -1
  70. package/dist/viewer/{dist-C4qpMazW.js → dist-rgdCugHI.js} +1 -1
  71. package/dist/viewer/{ebnfDiagram-PWID7BFC-DAOu1q3-.js → ebnfDiagram-PWID7BFC-BOzsyHEk.js} +1 -1
  72. package/dist/viewer/{el-GR-BZB4AONW-BisQn3yU.js → el-GR-BZB4AONW-h1eLQlP7.js} +1 -1
  73. package/dist/viewer/{en-B4ZKOASM--58khTZo.js → en-B4ZKOASM-EdleGu9D.js} +1 -1
  74. package/dist/viewer/{erDiagram-RLTQ6QDP-CGUupV6H.js → erDiagram-RLTQ6QDP-BF_tpcM3.js} +1 -1
  75. package/dist/viewer/{es-ES-U4NZUMDT-B-7GXnKG.js → es-ES-U4NZUMDT-DeaeHEK9.js} +1 -1
  76. package/dist/viewer/{eu-ES-A7QVB2H4-BLq2eo57.js → eu-ES-A7QVB2H4-BzoRNYbw.js} +1 -1
  77. package/dist/viewer/{eventmodeling-NTZA5JFV-tQ2e7ZHw.js → eventmodeling-NTZA5JFV-CUPY4M1x.js} +1 -1
  78. package/dist/viewer/{fa-IR-HGAKTJCU-XoZpcSvx.js → fa-IR-HGAKTJCU-fXYoNuWo.js} +1 -1
  79. package/dist/viewer/{fi-FI-Z5N7JZ37-Ba8QDSQY.js → fi-FI-Z5N7JZ37-CTVEZXqM.js} +1 -1
  80. package/dist/viewer/flowDiagram-HODETNUW-DpY3t4b0.js +1 -0
  81. package/dist/viewer/{fr-FR-RHASNOE6-BG-zh_xI.js → fr-FR-RHASNOE6-BizkpgaG.js} +1 -1
  82. package/dist/viewer/{ganttDiagram-EL5Y4UJY-CjWnjxV0.js → ganttDiagram-EL5Y4UJY-DvL8TKGV.js} +1 -1
  83. package/dist/viewer/{gitGraph-4MIJSDKK-BORKIFEf.js → gitGraph-4MIJSDKK-C3CdCDb5.js} +1 -1
  84. package/dist/viewer/{gitGraphDiagram-WWUBYQGX-40-ninSM.js → gitGraphDiagram-WWUBYQGX-Bm0Pyvyn.js} +1 -1
  85. package/dist/viewer/{gl-ES-HMX3MZ6V-CR1YZSY6.js → gl-ES-HMX3MZ6V-rsfHb2R9.js} +1 -1
  86. package/dist/viewer/{he-IL-6SHJWFNN-BgVLsLzh.js → he-IL-6SHJWFNN-BmWEwAWC.js} +1 -1
  87. package/dist/viewer/{hi-IN-IWLTKZ5I-CrbA8o7p.js → hi-IN-IWLTKZ5I-gzYZTFIt.js} +1 -1
  88. package/dist/viewer/{hu-HU-A5ZG7DT2-CaxQ4jf6.js → hu-HU-A5ZG7DT2-DqXGHJ4g.js} +1 -1
  89. package/dist/viewer/{id-ID-SAP4L64H-1qpg1BFz.js → id-ID-SAP4L64H-CVbSVAc3.js} +1 -1
  90. package/dist/viewer/{image-GAAHSSAO-CgyWW09l.js → image-GAAHSSAO-B0g7YyLf.js} +1 -1
  91. package/dist/viewer/index.js +8 -8
  92. package/dist/viewer/{info-A6RAGUB7-uXhiC65V.js → info-A6RAGUB7-BfTkwG6X.js} +1 -1
  93. package/dist/viewer/{infoDiagram-27XIBGKW-_jQZQZCo.js → infoDiagram-27XIBGKW-DOxIYIRL.js} +1 -1
  94. package/dist/viewer/{ishikawaDiagram-5VMMS53U-BZ6ELkZ3.js → ishikawaDiagram-5VMMS53U-D-U6Fi8F.js} +1 -1
  95. package/dist/viewer/{it-IT-JPQ66NNP-DmtbMg9Z.js → it-IT-JPQ66NNP-6PNiI36L.js} +1 -1
  96. package/dist/viewer/{ja-JP-DBVTYXUO-CGWtfK9Q.js → ja-JP-DBVTYXUO-D3SJtNp5.js} +1 -1
  97. package/dist/viewer/{journeyDiagram-3NMN7TZE-CjDOHXi5.js → journeyDiagram-3NMN7TZE-8Mz0Nae3.js} +1 -1
  98. package/dist/viewer/{kaa-6HZHGXH3-CLmk10fV.js → kaa-6HZHGXH3-Bz3WA5yL.js} +1 -1
  99. package/dist/viewer/{kab-KAB-ZGHBKWFO-DSYbHJql.js → kab-KAB-ZGHBKWFO-W2PtzMEV.js} +1 -1
  100. package/dist/viewer/{kanban-definition-UXKFOSKX-I3Xb7ziC.js → kanban-definition-UXKFOSKX-BP8HwPzL.js} +1 -1
  101. package/dist/viewer/{kk-KZ-P5N5QNE5-CBLAsJFg.js → kk-KZ-P5N5QNE5-Dc1i0Bup.js} +1 -1
  102. package/dist/viewer/{km-KH-HSX4SM5Z-B3Yp7p0U.js → km-KH-HSX4SM5Z-C88_w0rR.js} +1 -1
  103. package/dist/viewer/{ko-KR-MTYHY66A-C0bNkuxW.js → ko-KR-MTYHY66A-DWOt-6As.js} +1 -1
  104. package/dist/viewer/{ku-TR-6OUDTVRD-G0o4BMdg.js → ku-TR-6OUDTVRD-B7qeFzlo.js} +1 -1
  105. package/dist/viewer/{lt-LT-XHIRWOB4-BFU2e8Wz.js → lt-LT-XHIRWOB4-Dc9eguDu.js} +1 -1
  106. package/dist/viewer/{lv-LV-5QDEKY6T-CO07BtT_.js → lv-LV-5QDEKY6T-D9CzWKMj.js} +1 -1
  107. package/dist/viewer/{mermaid-parser.core-BgPQf3s0.js → mermaid-parser.core-Cd74p1Qw.js} +3 -3
  108. package/dist/viewer/{mindmap-definition-YA3MSWOX-11oLNysW.js → mindmap-definition-YA3MSWOX-Bikv3SLv.js} +1 -1
  109. package/dist/viewer/{mr-IN-CRQNXWMA-D9YY18Li.js → mr-IN-CRQNXWMA-CtlsKIl9.js} +1 -1
  110. package/dist/viewer/{my-MM-5M5IBNSE-BEJQqv2W.js → my-MM-5M5IBNSE-CiyAGqHH.js} +1 -1
  111. package/dist/viewer/{nb-NO-T6EIAALU-BB5llrj1.js → nb-NO-T6EIAALU-l9uMRUdk.js} +1 -1
  112. package/dist/viewer/{nl-NL-IS3SIHDZ-c2Y8oJrQ.js → nl-NL-IS3SIHDZ-zja_zaqN.js} +1 -1
  113. package/dist/viewer/{nn-NO-6E72VCQL-DIo77NyZ.js → nn-NO-6E72VCQL-BiP5RLsf.js} +1 -1
  114. package/dist/viewer/{oc-FR-POXYY2M6-8kWWN9mm.js → oc-FR-POXYY2M6-CvKUzwab.js} +1 -1
  115. package/dist/viewer/{pa-IN-N4M65BXN-BMf1XgAH.js → pa-IN-N4M65BXN-DioFchQd.js} +1 -1
  116. package/dist/viewer/{packet-AYTQ26CC-D0eRwWHa.js → packet-AYTQ26CC-Bu-WAKTD.js} +1 -1
  117. package/dist/viewer/{pegDiagram-XKGWAZYB-Bw6hYRIu.js → pegDiagram-XKGWAZYB-BSllNtPI.js} +1 -1
  118. package/dist/viewer/percentages-BXMCSKIN-BRZnWvym.js +1 -0
  119. package/dist/viewer/{pie-WAS4IAKB-CgzdseEz.js → pie-WAS4IAKB-DQReqHvw.js} +1 -1
  120. package/dist/viewer/{pieDiagram-E7YTZNPT-RoGPyUOj.js → pieDiagram-E7YTZNPT-b1-BsaA4.js} +1 -1
  121. package/dist/viewer/{pl-PL-T2D74RX3-DZoIdWkS.js → pl-PL-T2D74RX3-Ci7dAnI8.js} +1 -1
  122. package/dist/viewer/{prod-Bx6GIw_C.js → prod-CPZkgD7t.js} +8 -8
  123. package/dist/viewer/{pt-BR-5N22H2LF-CA4hD8PT.js → pt-BR-5N22H2LF--VT7NYYE.js} +1 -1
  124. package/dist/viewer/{pt-PT-UZXXM6DQ-tGh3Skml.js → pt-PT-UZXXM6DQ-CWdbQilC.js} +1 -1
  125. package/dist/viewer/{quadrantDiagram-AXDQQJYC-CJn6mRcz.js → quadrantDiagram-AXDQQJYC-D0pucWR0.js} +1 -1
  126. package/dist/viewer/{radar-RG4KPBEZ-CT5S71sN.js → radar-RG4KPBEZ-D_r12v0L.js} +1 -1
  127. package/dist/viewer/{railroad-74A4TZTK-CgJHRbOD.js → railroad-74A4TZTK-JLrx94cB.js} +1 -1
  128. package/dist/viewer/{railroad-abnf-HS5TGJTU-CnUkqFdE.js → railroad-abnf-HS5TGJTU-zGEQrPX3.js} +1 -1
  129. package/dist/viewer/{railroad-ebnf-LZEXJU2U-pjipfm_D.js → railroad-ebnf-LZEXJU2U-CwEVA1VE.js} +1 -1
  130. package/dist/viewer/{railroad-peg-WCYAUIDC-CSpqHvBl.js → railroad-peg-WCYAUIDC-aKEE6HSg.js} +1 -1
  131. package/dist/viewer/{railroadDiagram-O6MQD6OU-C-EFZlfh.js → railroadDiagram-O6MQD6OU-DIPJ2PKr.js} +1 -1
  132. package/dist/viewer/{requirementDiagram-BXWQKSXE-BwDCl6Rf.js → requirementDiagram-BXWQKSXE-DEGhiwJ9.js} +1 -1
  133. package/dist/viewer/{ro-RO-JPDTUUEW-C4YorEOB.js → ro-RO-JPDTUUEW-BK4wLUL7.js} +1 -1
  134. package/dist/viewer/{ru-RU-B4JR7IUQ-t1IvQhGY.js → ru-RU-B4JR7IUQ-BDPQ8blU.js} +1 -1
  135. package/dist/viewer/{sankeyDiagram-P5KCCOFB-WuesN3kP.js → sankeyDiagram-P5KCCOFB-DO2JtEMk.js} +1 -1
  136. package/dist/viewer/{sequenceDiagram-WJ2MYXX4-_7JDVftT.js → sequenceDiagram-WJ2MYXX4-D7sLhGYb.js} +1 -1
  137. package/dist/viewer/{si-LK-N5RQ5JYF-DdNAbrWY.js → si-LK-N5RQ5JYF-D5DWsUAA.js} +1 -1
  138. package/dist/viewer/{sk-SK-C5VTKIMK-COhgC7m3.js → sk-SK-C5VTKIMK-Cia9j1Te.js} +1 -1
  139. package/dist/viewer/{sl-SI-NN7IZMDC-_yB_Pj-u.js → sl-SI-NN7IZMDC-CV304k5j.js} +1 -1
  140. package/dist/viewer/{stateDiagram-D77RDMKH-DCZlAvyH.js → stateDiagram-D77RDMKH-BMNx9_M8.js} +1 -1
  141. package/dist/viewer/stateDiagram-v2-MP3YSRHH-CPa9DZs4.js +1 -0
  142. package/dist/viewer/subset-shared.chunk-ChUk9bHw.js +1 -0
  143. package/dist/viewer/{subset-worker.chunk-B-6iEyMR.js → subset-worker.chunk-CHQzlaj3.js} +1 -1
  144. package/dist/viewer/{sv-SE-XGPEYMSR-BiHNNj0z.js → sv-SE-XGPEYMSR-CXdp-XZD.js} +1 -1
  145. package/dist/viewer/{swimlanes-42K2YHIH-BlepjNEl.js → swimlanes-42K2YHIH-BwUyxwi3.js} +1 -1
  146. package/dist/viewer/swimlanesDiagram-VR7AAH4N-BgxS36EG.js +8 -0
  147. package/dist/viewer/{ta-IN-2NMHFXQM-BsRvF0U1.js → ta-IN-2NMHFXQM-CObY6q-8.js} +1 -1
  148. package/dist/viewer/{th-TH-HPSO5L25-CoSWWqYM.js → th-TH-HPSO5L25-CEOiELZN.js} +1 -1
  149. package/dist/viewer/{timeline-definition-24CTP7MA-UYSDRcQv.js → timeline-definition-24CTP7MA-BJ-7Fdfr.js} +1 -1
  150. package/dist/viewer/{tr-TR-DEFEU3FU-BT5kemSo.js → tr-TR-DEFEU3FU-CPj5dFcB.js} +1 -1
  151. package/dist/viewer/{treeView-Q6P3EWNA-jQLNdbCN.js → treeView-Q6P3EWNA-DaAtai94.js} +1 -1
  152. package/dist/viewer/{treemap-WGGIJYW6-BNKkWIxD.js → treemap-WGGIJYW6-BrSC50io.js} +1 -1
  153. package/dist/viewer/{uk-UA-QMV73CPH-CXtURAew.js → uk-UA-QMV73CPH-BkZyFeXP.js} +1 -1
  154. package/dist/viewer/{vennDiagram-4TSXK5OY-BMb8lK68.js → vennDiagram-4TSXK5OY-DnFbjWDw.js} +1 -1
  155. package/dist/viewer/{vi-VN-M7AON7JQ-DjpNauih.js → vi-VN-M7AON7JQ-CkKKOpBQ.js} +1 -1
  156. package/dist/viewer/{wardley-WFR3VGLG-CeQmnc0y.js → wardley-WFR3VGLG-CtJjyNRB.js} +1 -1
  157. package/dist/viewer/{wardleyDiagram-VM6X3IG4-Bbb7d4tJ.js → wardleyDiagram-VM6X3IG4-CN_pm__V.js} +1 -1
  158. package/dist/viewer/{xychartDiagram-S5SC5T6Z-C1jHnaYB.js → xychartDiagram-S5SC5T6Z-C7XLywXm.js} +1 -1
  159. package/dist/viewer/{zh-CN-LNUGB5OW-BtoNDQIl.js → zh-CN-LNUGB5OW-BQcCqsDg.js} +1 -1
  160. package/dist/viewer/{zh-HK-E62DVLB3-Bsj6hYnG.js → zh-HK-E62DVLB3-Bp-jK0zw.js} +1 -1
  161. package/dist/viewer/{zh-TW-RAJ6MFWO-t9wKt4fB.js → zh-TW-RAJ6MFWO-KmFL88Bs.js} +1 -1
  162. package/package.json +1 -1
  163. package/dist/viewer/CloudLiveDocument-BBdd4M0n.js +0 -1
  164. package/dist/viewer/DocumentPage-Ds3kfTmX.js +0 -1
  165. package/dist/viewer/channel-BNc-fhjE.js +0 -1
  166. package/dist/viewer/classDiagram-ZZMXUADV-DBoaKOab.js +0 -1
  167. package/dist/viewer/classDiagram-v2-VYDZK3BY-DBoaKOab.js +0 -1
  168. package/dist/viewer/flowDiagram-HODETNUW-COx-LSVC.js +0 -1
  169. package/dist/viewer/percentages-BXMCSKIN-68g2puYX.js +0 -1
  170. package/dist/viewer/stateDiagram-v2-MP3YSRHH-BBh7KsIF.js +0 -1
  171. package/dist/viewer/subset-shared.chunk-Du7U8n_m.js +0 -1
  172. package/dist/viewer/swimlanesDiagram-VR7AAH4N-Bh8fO2OH.js +0 -8
package/dist/server.cjs CHANGED
@@ -5171,14 +5171,14 @@ var require_websocket_server = __commonJS({
5171
5171
 
5172
5172
  // src/server/main.ts
5173
5173
  var import_node_child_process2 = require("node:child_process");
5174
- var import_node_fs22 = __toESM(require("node:fs"), 1);
5174
+ var import_node_fs24 = __toESM(require("node:fs"), 1);
5175
5175
  var import_node_os = __toESM(require("node:os"), 1);
5176
- var import_node_path19 = __toESM(require("node:path"), 1);
5176
+ var import_node_path20 = __toESM(require("node:path"), 1);
5177
5177
 
5178
5178
  // src/server/app.ts
5179
- var import_node_fs20 = __toESM(require("node:fs"), 1);
5179
+ var import_node_fs22 = __toESM(require("node:fs"), 1);
5180
5180
  var import_node_http = __toESM(require("node:http"), 1);
5181
- var import_node_path18 = __toESM(require("node:path"), 1);
5181
+ var import_node_path19 = __toESM(require("node:path"), 1);
5182
5182
 
5183
5183
  // src/shared/types.ts
5184
5184
  var ARTIFACT_TYPES = ["artboard", "document", "html"];
@@ -18207,7 +18207,9 @@ function readRaw(boardDir) {
18207
18207
  }
18208
18208
  function boardVersions(boardDir, canvas) {
18209
18209
  const versions = {};
18210
- for (const board of Object.values(canvas.boards)) {
18210
+ let writing;
18211
+ let latestWrite = -Infinity;
18212
+ for (const [id2, board] of Object.entries(canvas.boards)) {
18211
18213
  const target = resolveBoardFile(boardDir, board.file);
18212
18214
  if (!target) {
18213
18215
  versions[board.file] = 0;
@@ -18215,12 +18217,19 @@ function boardVersions(boardDir, canvas) {
18215
18217
  }
18216
18218
  try {
18217
18219
  const stat = import_node_fs5.default.statSync(target);
18218
- versions[board.file] = stat.size > 0 ? stat.mtimeMs : 0;
18220
+ const html = import_node_fs5.default.readFileSync(target, "utf8");
18221
+ const document2 = /<(?:!doctype|html)\b/i.test(html);
18222
+ const ready = html.trim().length > 0 && (!document2 || /<\/html>\s*(?:<!--[\s\S]*?-->\s*)*$/i.test(html));
18223
+ versions[board.file] = ready ? stat.mtimeMs : 0;
18224
+ if (!ready && stat.mtimeMs >= latestWrite) {
18225
+ writing = id2;
18226
+ latestWrite = stat.mtimeMs;
18227
+ }
18219
18228
  } catch {
18220
18229
  versions[board.file] = 0;
18221
18230
  }
18222
18231
  }
18223
- return versions;
18232
+ return { versions, writing };
18224
18233
  }
18225
18234
  function readCanvas(boardDir) {
18226
18235
  const { raw, warning } = readRaw(boardDir);
@@ -18228,16 +18237,19 @@ function readCanvas(boardDir) {
18228
18237
  try {
18229
18238
  const structural = structuralWarnings(raw);
18230
18239
  if (structural.length > 0) return { canvas: null, warnings: structural, pending: [], layout: null, versions: {} };
18231
- const canvas = raw;
18240
+ const canvas = { ...raw };
18241
+ const { versions, writing } = boardVersions(boardDir, canvas);
18232
18242
  const pending = /* @__PURE__ */ new Set();
18233
- const warnings = validateCanvas(canvas, (rel) => resolveBoardFile(boardDir, rel) !== null, {
18234
- pending,
18235
- allowPending: canvas.building === true
18236
- });
18237
- const versions = boardVersions(boardDir, canvas);
18238
18243
  for (const [id2, board] of Object.entries(canvas.boards)) {
18239
18244
  if (!versions[board.file]) pending.add(id2);
18240
18245
  }
18246
+ canvas.building = pending.size > 0;
18247
+ delete canvas.writing;
18248
+ if (writing) canvas.writing = writing;
18249
+ const warnings = validateCanvas(canvas, (rel) => resolveBoardFile(boardDir, rel) !== null, {
18250
+ pending,
18251
+ allowPending: true
18252
+ });
18241
18253
  return { canvas, warnings, pending: [...pending].sort(), layout: computeLayout(canvas), versions };
18242
18254
  } catch (err) {
18243
18255
  return {
@@ -19250,19 +19262,19 @@ var ElementDOMSlot = class _ElementDOMSlot extends DOMSlot {
19250
19262
  }
19251
19263
  };
19252
19264
  function indexPath(root, child) {
19253
- const path20 = [];
19265
+ const path21 = [];
19254
19266
  let node = child;
19255
19267
  for (; node !== root && node !== null; node = node.parentNode) {
19256
19268
  let i6 = 0;
19257
19269
  for (let sibling = node.previousSibling; sibling !== null; sibling = sibling.previousSibling) {
19258
19270
  i6++;
19259
19271
  }
19260
- path20.push(i6);
19272
+ path21.push(i6);
19261
19273
  }
19262
19274
  if (!(node === root)) {
19263
19275
  formatDevErrorMessage(`indexPath: root is not a parent of child`);
19264
19276
  }
19265
- return path20.reverse();
19277
+ return path21.reverse();
19266
19278
  }
19267
19279
  // @__NO_SIDE_EFFECTS__
19268
19280
  function readLexicalVersion() {
@@ -34042,9 +34054,9 @@ function getActiveElementDeep(root) {
34042
34054
  function getComposedEventTarget(event) {
34043
34055
  const target = event.target;
34044
34056
  if (target !== null && isHTMLElement(target) && target.shadowRoot !== null && typeof event.composedPath === "function") {
34045
- const path20 = event.composedPath();
34046
- if (path20.length > 0) {
34047
- return path20[0];
34057
+ const path21 = event.composedPath();
34058
+ if (path21.length > 0) {
34059
+ return path21[0];
34048
34060
  }
34049
34061
  }
34050
34062
  return target;
@@ -44140,10 +44152,10 @@ function _loadWasmModule(sync, filepath, src, imports2) {
44140
44152
  var buf = null;
44141
44153
  var isNode2 = typeof process !== "undefined" && process.versions != null && process.versions.node != null;
44142
44154
  if (filepath && isNode2) {
44143
- var fs25 = null;
44144
- var path20 = null;
44155
+ var fs27 = null;
44156
+ var path21 = null;
44145
44157
  return new Promise((resolve, reject) => {
44146
- fs25.readFile(path20.resolve(__dirname, filepath), (error, buffer) => {
44158
+ fs27.readFile(path21.resolve(__dirname, filepath), (error, buffer) => {
44147
44159
  if (error != null) {
44148
44160
  reject(error);
44149
44161
  } else {
@@ -45446,10 +45458,10 @@ var LoroDoc = class _LoroDoc {
45446
45458
  * @param {string} path
45447
45459
  * @returns {Value | Container | undefined}
45448
45460
  */
45449
- getByPath(path20) {
45461
+ getByPath(path21) {
45450
45462
  try {
45451
45463
  const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
45452
- const ptr0 = passStringToWasm0(path20, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
45464
+ const ptr0 = passStringToWasm0(path21, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
45453
45465
  const len0 = WASM_VECTOR_LEN;
45454
45466
  wasm.lorodoc_getByPath(retptr, this.__wbg_ptr, ptr0, len0);
45455
45467
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
@@ -88549,6 +88561,7 @@ var import_node_fs12 = __toESM(require("node:fs"), 1);
88549
88561
  var import_node_path12 = __toESM(require("node:path"), 1);
88550
88562
 
88551
88563
  // src/shared/cloud.ts
88564
+ var ownLink = (url, hostId) => hostId ? `${url}#ryugi-host=${hostId}` : url;
88552
88565
  var isVisibility = (value) => value === "private" || value === "public";
88553
88566
 
88554
88567
  // src/server/config.ts
@@ -88714,7 +88727,7 @@ function createRelayClient(options) {
88714
88727
  ws2.on("open", () => {
88715
88728
  backoff = 1e3;
88716
88729
  announced = idsOf(served).join("\n");
88717
- send2({ t: "hello", version: options.version, ids: idsOf(served) });
88730
+ send2({ t: "hello", version: options.version, ids: idsOf(served), ...options.local ? { local: options.local() } : {} });
88718
88731
  heartbeat = setInterval(() => {
88719
88732
  if (watched.size > 0) options.onActivity();
88720
88733
  ws2.send("ping");
@@ -88782,8 +88795,155 @@ function createRelayClient(options) {
88782
88795
  };
88783
88796
  }
88784
88797
 
88798
+ // src/server/ws.ts
88799
+ var import_node_crypto3 = __toESM(require("node:crypto"), 1);
88800
+ var WS_MAGIC = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
88801
+ var OPCODE_TEXT = 1;
88802
+ var OPCODE_CLOSE = 8;
88803
+ var OPCODE_PING = 9;
88804
+ var OPCODE_PONG = 10;
88805
+ var MAX_CLIENT_FRAME = 8 * 1024 * 1024;
88806
+ function acceptKey(clientKey) {
88807
+ return import_node_crypto3.default.createHash("sha1").update(clientKey + WS_MAGIC).digest("base64");
88808
+ }
88809
+ function encodeFrame(opcode, payload) {
88810
+ const len = payload.length;
88811
+ let header;
88812
+ if (len < 126) {
88813
+ header = Buffer.from([128 | opcode, len]);
88814
+ } else if (len < 65536) {
88815
+ header = Buffer.alloc(4);
88816
+ header[0] = 128 | opcode;
88817
+ header[1] = 126;
88818
+ header.writeUInt16BE(len, 2);
88819
+ } else {
88820
+ header = Buffer.alloc(10);
88821
+ header[0] = 128 | opcode;
88822
+ header[1] = 127;
88823
+ header.writeBigUInt64BE(BigInt(len), 2);
88824
+ }
88825
+ return Buffer.concat([header, payload]);
88826
+ }
88827
+ var textFrame = (text2) => encodeFrame(OPCODE_TEXT, Buffer.from(text2));
88828
+ function completeHandshake(socket, clientKey) {
88829
+ socket.write(
88830
+ `HTTP/1.1 101 Switching Protocols\r
88831
+ Upgrade: websocket\r
88832
+ Connection: Upgrade\r
88833
+ Sec-WebSocket-Accept: ${acceptKey(clientKey)}\r
88834
+ \r
88835
+ `
88836
+ );
88837
+ }
88838
+ function rejectUpgrade(socket, status, reason) {
88839
+ socket.end(`HTTP/1.1 ${status} ${reason}\r
88840
+ Connection: close\r
88841
+ Content-Length: 0\r
88842
+ \r
88843
+ `);
88844
+ }
88845
+ function handleClientFrames(socket, onText) {
88846
+ let buffer = Buffer.alloc(0);
88847
+ socket.on("data", (chunk) => {
88848
+ buffer = Buffer.concat([buffer, chunk]);
88849
+ while (buffer.length >= 2) {
88850
+ const fin = (buffer[0] & 128) !== 0;
88851
+ const opcode = buffer[0] & 15;
88852
+ let len = buffer[1] & 127;
88853
+ let offset = 2;
88854
+ if (len === 126) {
88855
+ if (buffer.length < 4) return;
88856
+ len = buffer.readUInt16BE(2);
88857
+ offset = 4;
88858
+ } else if (len === 127) {
88859
+ if (buffer.length < 10) return;
88860
+ const big = buffer.readBigUInt64BE(2);
88861
+ if (big > BigInt(MAX_CLIENT_FRAME)) {
88862
+ socket.destroy();
88863
+ return;
88864
+ }
88865
+ len = Number(big);
88866
+ offset = 10;
88867
+ }
88868
+ const total = offset + 4 + len;
88869
+ if (buffer.length < total) return;
88870
+ const mask = buffer.subarray(offset, offset + 4);
88871
+ const payload = Buffer.from(buffer.subarray(offset + 4, total));
88872
+ for (let i6 = 0; i6 < payload.length; i6++) payload[i6] = payload[i6] ^ mask[i6 % 4];
88873
+ buffer = buffer.subarray(total);
88874
+ if (opcode === OPCODE_CLOSE) {
88875
+ socket.end(encodeFrame(OPCODE_CLOSE, Buffer.alloc(0)));
88876
+ return;
88877
+ }
88878
+ if (opcode === OPCODE_PING) socket.write(encodeFrame(OPCODE_PONG, payload));
88879
+ else if (opcode === OPCODE_TEXT && fin) onText?.(payload.toString("utf8"));
88880
+ }
88881
+ });
88882
+ }
88883
+
88884
+ // src/server/direct-relay.ts
88885
+ function createDirectRelay(options) {
88886
+ const sockets = /* @__PURE__ */ new Map();
88887
+ let opened = 0;
88888
+ const write = (socket, message) => socket.write(textFrame(JSON.stringify(message)));
88889
+ const onText = async (socket, key2, conn, text2) => {
88890
+ let message;
88891
+ try {
88892
+ message = JSON.parse(text2);
88893
+ } catch {
88894
+ return;
88895
+ }
88896
+ if (message.t !== "request" || typeof message.rid !== "number" && typeof message.rid !== "string") return;
88897
+ options.onActivity();
88898
+ try {
88899
+ write(socket, { t: "reply", rid: message.rid, body: { ok: true, data: await options.handle(key2, message.body, conn) } });
88900
+ } catch (err) {
88901
+ write(socket, { t: "reply", rid: message.rid, body: { ok: false, error: err.message } });
88902
+ }
88903
+ };
88904
+ return {
88905
+ accept(socket, clientKey, key2) {
88906
+ completeHandshake(socket, clientKey);
88907
+ const conn = `direct:${++opened}`;
88908
+ sockets.set(socket, { key: key2, conn });
88909
+ write(socket, { t: "presence", online: true, version: options.version });
88910
+ handleClientFrames(socket, (text2) => void onText(socket, key2, conn, text2));
88911
+ const forget = () => {
88912
+ if (sockets.delete(socket)) options.onClose(conn);
88913
+ };
88914
+ socket.on("end", () => {
88915
+ forget();
88916
+ socket.end();
88917
+ });
88918
+ socket.on("close", forget);
88919
+ socket.on("error", forget);
88920
+ options.onActivity();
88921
+ },
88922
+ emit(key2, body) {
88923
+ for (const [socket, entry] of sockets) if (entry.key === key2) write(socket, { t: "event", body });
88924
+ },
88925
+ close() {
88926
+ for (const socket of sockets.keys()) socket.destroy();
88927
+ }
88928
+ };
88929
+ }
88930
+
88931
+ // src/server/host-id.ts
88932
+ var import_node_fs14 = __toESM(require("node:fs"), 1);
88933
+ var import_node_path14 = __toESM(require("node:path"), 1);
88934
+ function hostIdFor(credentialsFile2) {
88935
+ const file = import_node_path14.default.join(import_node_path14.default.dirname(credentialsFile2), "host-id");
88936
+ const saved = readPersisted(file);
88937
+ if (/^[A-Za-z0-9_-]{16,64}$/.test(saved)) return saved;
88938
+ const id2 = randomToken();
88939
+ import_node_fs14.default.mkdirSync(import_node_path14.default.dirname(file), { recursive: true, mode: 448 });
88940
+ import_node_fs14.default.writeFileSync(file, `${id2}
88941
+ `, { mode: 384 });
88942
+ return id2;
88943
+ }
88944
+
88785
88945
  // src/server/avatars.ts
88786
- var import_node_crypto3 = require("node:crypto");
88946
+ var import_node_crypto4 = require("node:crypto");
88787
88947
  var AVATAR_ROUTE = /^\/api\/avatar\/([a-z]+)\/([^/]+)$/;
88788
88948
  var MAX_BYTES = 512 * 1024;
88789
88949
  var TIMEOUT_MS = 5e3;
@@ -88792,7 +88952,7 @@ var SOURCES = {
88792
88952
  gravatar: { valid: /^[0-9a-f]{64}$/, url: (id2) => `https://gravatar.com/avatar/${id2}?s=64&d=404` }
88793
88953
  };
88794
88954
  var githubAvatar = (login) => `/api/avatar/github/${login}`;
88795
- var gravatarAvatar = (email) => `/api/avatar/gravatar/${(0, import_node_crypto3.createHash)("sha256").update(email.trim().toLowerCase()).digest("hex")}`;
88955
+ var gravatarAvatar = (email) => `/api/avatar/gravatar/${(0, import_node_crypto4.createHash)("sha256").update(email.trim().toLowerCase()).digest("hex")}`;
88796
88956
  function createAvatars(fetchImpl = fetch) {
88797
88957
  const cache = /* @__PURE__ */ new Map();
88798
88958
  const fetchAvatar = async (url) => {
@@ -88824,7 +88984,7 @@ function createAvatars(fetchImpl = fetch) {
88824
88984
  }
88825
88985
 
88826
88986
  // src/server/cloud.ts
88827
- var import_node_crypto4 = __toESM(require("node:crypto"), 1);
88987
+ var import_node_crypto5 = __toESM(require("node:crypto"), 1);
88828
88988
 
88829
88989
  // src/shared/brand.ts
88830
88990
  var RYUGI_MARK_VIEWBOX = "0 0 512 512";
@@ -88934,8 +89094,8 @@ function callbackPage(result) {
88934
89094
  }
88935
89095
 
88936
89096
  // src/server/pack.ts
88937
- var import_node_fs14 = __toESM(require("node:fs"), 1);
88938
- var import_node_path14 = __toESM(require("node:path"), 1);
89097
+ var import_node_fs15 = __toESM(require("node:fs"), 1);
89098
+ var import_node_path15 = __toESM(require("node:path"), 1);
88939
89099
  var MAX_ARTIFACT_BYTES = 20 * 1024 * 1024;
88940
89100
  function formatBytes(bytes) {
88941
89101
  if (bytes < 1024) return `${bytes} B`;
@@ -88944,22 +89104,22 @@ function formatBytes(bytes) {
88944
89104
  }
88945
89105
  var excluded = (type, relative) => type === "document" && relative === "comments.json";
88946
89106
  function packArtifact(dir, type, { maxBytes = MAX_ARTIFACT_BYTES } = {}) {
88947
- const rootReal = import_node_fs14.default.realpathSync(dir);
89107
+ const rootReal = import_node_fs15.default.realpathSync(dir);
88948
89108
  const found = [];
88949
89109
  const visited = /* @__PURE__ */ new Set([rootReal]);
88950
89110
  let total = 0;
88951
89111
  const walk = (current) => {
88952
- for (const entry of import_node_fs14.default.readdirSync(current, { withFileTypes: true })) {
89112
+ for (const entry of import_node_fs15.default.readdirSync(current, { withFileTypes: true })) {
88953
89113
  if (entry.name.startsWith(".")) continue;
88954
- const full = import_node_path14.default.join(current, entry.name);
89114
+ const full = import_node_path15.default.join(current, entry.name);
88955
89115
  let real;
88956
89116
  try {
88957
- real = import_node_fs14.default.realpathSync(full);
89117
+ real = import_node_fs15.default.realpathSync(full);
88958
89118
  } catch {
88959
89119
  continue;
88960
89120
  }
88961
- if (!real.startsWith(rootReal + import_node_path14.default.sep)) continue;
88962
- const stat = import_node_fs14.default.statSync(real);
89121
+ if (!real.startsWith(rootReal + import_node_path15.default.sep)) continue;
89122
+ const stat = import_node_fs15.default.statSync(real);
88963
89123
  if (stat.isDirectory()) {
88964
89124
  if (visited.has(real)) continue;
88965
89125
  visited.add(real);
@@ -88967,7 +89127,7 @@ function packArtifact(dir, type, { maxBytes = MAX_ARTIFACT_BYTES } = {}) {
88967
89127
  continue;
88968
89128
  }
88969
89129
  if (!stat.isFile()) continue;
88970
- const relative = import_node_path14.default.relative(dir, full).split(import_node_path14.default.sep).join("/");
89130
+ const relative = import_node_path15.default.relative(dir, full).split(import_node_path15.default.sep).join("/");
88971
89131
  if (excluded(type, relative)) continue;
88972
89132
  total += stat.size;
88973
89133
  found.push({ path: relative, real });
@@ -88977,12 +89137,12 @@ function packArtifact(dir, type, { maxBytes = MAX_ARTIFACT_BYTES } = {}) {
88977
89137
  if (total > maxBytes) {
88978
89138
  throw new Error(`artifact is ${formatBytes(total)}; the limit is ${formatBytes(maxBytes)}`);
88979
89139
  }
88980
- return found.map((file) => ({ path: file.path, data: import_node_fs14.default.readFileSync(file.real) }));
89140
+ return found.map((file) => ({ path: file.path, data: import_node_fs15.default.readFileSync(file.real) }));
88981
89141
  }
88982
89142
 
88983
89143
  // src/server/publish-payload.ts
88984
- var import_node_fs15 = __toESM(require("node:fs"), 1);
88985
- var import_node_path15 = __toESM(require("node:path"), 1);
89144
+ var import_node_fs16 = __toESM(require("node:fs"), 1);
89145
+ var import_node_path16 = __toESM(require("node:path"), 1);
88986
89146
  var CLOUD_RUNTIME_URL = "/_ryugi/runtime/ryugi-ui.js";
88987
89147
  function sharedComments(file) {
88988
89148
  return {
@@ -88995,7 +89155,7 @@ function publishPayload(ref, dir, title, payload, comments = emptyComments()) {
88995
89155
  const { canvas, layout, versions } = payload;
88996
89156
  return { canvas, layout, versions };
88997
89157
  }
88998
- if (ref.type === "document") return { title, state: parseDocument2(import_node_fs15.default.readFileSync(import_node_path15.default.join(dir, "doc.xml"), "utf8")), comments: sharedComments(comments) };
89158
+ if (ref.type === "document") return { title, state: parseDocument2(import_node_fs16.default.readFileSync(import_node_path16.default.join(dir, "doc.xml"), "utf8")), comments: sharedComments(comments) };
88999
89159
  return { title };
89000
89160
  }
89001
89161
  var isPage = (type, file) => type === "html" ? file === "index.html" : (type === "document" || type === "artboard") && file.endsWith(".html");
@@ -89006,12 +89166,12 @@ function withCloudRuntime(type, files) {
89006
89166
  }
89007
89167
 
89008
89168
  // src/server/settings.ts
89009
- var import_node_fs16 = __toESM(require("node:fs"), 1);
89010
- var import_node_path16 = __toESM(require("node:path"), 1);
89011
- var settingsFileFor = (credentialsFile2) => import_node_path16.default.join(import_node_path16.default.dirname(credentialsFile2), "config.json");
89169
+ var import_node_fs17 = __toESM(require("node:fs"), 1);
89170
+ var import_node_path17 = __toESM(require("node:path"), 1);
89171
+ var settingsFileFor = (credentialsFile2) => import_node_path17.default.join(import_node_path17.default.dirname(credentialsFile2), "config.json");
89012
89172
  function readSettings(file) {
89013
89173
  try {
89014
- const raw = JSON.parse(import_node_fs16.default.readFileSync(file, "utf8"));
89174
+ const raw = JSON.parse(import_node_fs17.default.readFileSync(file, "utf8"));
89015
89175
  return typeof raw === "object" && raw !== null && !Array.isArray(raw) ? raw : {};
89016
89176
  } catch {
89017
89177
  return {};
@@ -89022,7 +89182,7 @@ function readGlobalAutoPublish(file) {
89022
89182
  return typeof value === "boolean" ? value : void 0;
89023
89183
  }
89024
89184
  function writeGlobalAutoPublish(file, value) {
89025
- import_node_fs16.default.mkdirSync(import_node_path16.default.dirname(file), { recursive: true, mode: 448 });
89185
+ import_node_fs17.default.mkdirSync(import_node_path17.default.dirname(file), { recursive: true, mode: 448 });
89026
89186
  writeJsonAtomic(file, { ...readSettings(file), autoPublish: value });
89027
89187
  }
89028
89188
  function defaultGlobalAutoPublish(file) {
@@ -89037,7 +89197,7 @@ var LOGIN_STATE_TTL_MS = 10 * 60 * 1e3;
89037
89197
  var UPLOAD_CONCURRENCY = 6;
89038
89198
  var MAX_JSON_BODY = 4096;
89039
89199
  var CLOUD_ID = /^[A-Za-z0-9_-]{1,64}$/;
89040
- var ROUTE = /^\/api\/cloud\/(status|login|logout|artifacts|publish|visibility|auto-publish)(?:\/([^/]+)(?:\/([^/]+))?)?$/;
89200
+ var ROUTE = /^\/api\/cloud\/(status|login|logout|artifacts|publish|reserve|visibility|auto-publish)(?:\/([^/]+)(?:\/([^/]+))?)?$/;
89041
89201
  var SignedOut = class extends Error {
89042
89202
  };
89043
89203
  var CloudRefused = class extends Error {
@@ -89094,10 +89254,10 @@ function createCloudRoutes(options) {
89094
89254
  const state = randomToken();
89095
89255
  const verifier = randomToken();
89096
89256
  pendingStates.set(state, { expires: now + LOGIN_STATE_TTL_MS, verifier });
89097
- const challenge = import_node_crypto4.default.createHash("sha256").update(verifier).digest("base64url");
89257
+ const challenge = import_node_crypto5.default.createHash("sha256").update(verifier).digest("base64url");
89098
89258
  return `${origin}/auth/cli?port=${options.port()}&state=${state}&challenge=${challenge}`;
89099
89259
  };
89100
- const cloudFetch = async (method, path20, body) => {
89260
+ const cloudFetch = async (method, path21, body) => {
89101
89261
  const credentials = readCredentials(credentialsFile2, origin);
89102
89262
  if (!credentials) throw new SignedOut();
89103
89263
  const headers = { Authorization: `Bearer ${credentials.token}` };
@@ -89111,7 +89271,7 @@ function createCloudRoutes(options) {
89111
89271
  }
89112
89272
  let res;
89113
89273
  try {
89114
- res = await fetch(`${origin}${path20}`, { method, headers, body: payload });
89274
+ res = await fetch(`${origin}${path21}`, { method, headers, body: payload });
89115
89275
  } catch (err) {
89116
89276
  throw new CloudRefused(502, `could not reach ${origin}: ${err.message}`);
89117
89277
  }
@@ -89134,6 +89294,28 @@ function createCloudRoutes(options) {
89134
89294
  return run2;
89135
89295
  };
89136
89296
  const keyOfCloudId = (cloudId) => Object.entries(readConfig(configFile).config.artifacts).find(([, entry]) => entry.cloud?.id === cloudId)?.[0] ?? `cloud:${cloudId}`;
89297
+ const createRecord2 = async (ref, visibility) => {
89298
+ const res = await cloudFetch("POST", "/api/artifacts", { type: ref.type, visibility, project });
89299
+ if (res.status === 403) throw new CreateRefused(await errorMessage(res));
89300
+ const created = await (await expectOk(res)).json();
89301
+ updateArtifactConfig(configFile, `${ref.type}/${ref.id}`, {
89302
+ visibility: created.visibility,
89303
+ cloud: { id: created.id, url: created.url, publishedAt: null, visibility: created.visibility }
89304
+ });
89305
+ return created.id;
89306
+ };
89307
+ const reserve = async (ref) => {
89308
+ const key2 = `${ref.type}/${ref.id}`;
89309
+ const entry = artifactEntry(key2);
89310
+ if (entry.cloud) return entry.cloud.url;
89311
+ if (entry.autoPublish === false || !autoPublishState().enabled) return null;
89312
+ try {
89313
+ await createRecord2(ref, entry.visibility ?? "private");
89314
+ } catch {
89315
+ return null;
89316
+ }
89317
+ return artifactEntry(key2).cloud?.url ?? null;
89318
+ };
89137
89319
  const publish = async (ref, requested, { recreate = true } = {}) => {
89138
89320
  const inspected = await options.inspect(ref);
89139
89321
  if (!inspected) throw new CloudRefused(404, `${ref.type}/${ref.id} not found`);
@@ -89146,20 +89328,11 @@ function createCloudRoutes(options) {
89146
89328
  }
89147
89329
  const key2 = `${ref.type}/${ref.id}`;
89148
89330
  const entry = artifactEntry(key2);
89149
- const hashed = files.map((file) => ({ ...file, hash: import_node_crypto4.default.createHash("sha256").update(file.data).digest("hex") }));
89331
+ const hashed = files.map((file) => ({ ...file, hash: import_node_crypto5.default.createHash("sha256").update(file.data).digest("hex") }));
89150
89332
  const byHash = new Map(hashed.map((file) => [file.hash, file.data]));
89151
- const manifest = hashed.map(({ path: path20, hash }) => ({ path: path20, hash }));
89333
+ const manifest = hashed.map(({ path: path21, hash }) => ({ path: path21, hash }));
89152
89334
  const version2 = (visibility) => ({ title: inspected.title, payload: inspected.payload, files: manifest, project, ...visibility ? { visibility } : {} });
89153
- const create3 = async () => {
89154
- const res2 = await cloudFetch("POST", "/api/artifacts", { type: ref.type, visibility: requested ?? entry.visibility ?? "private", project });
89155
- if (res2.status === 403) throw new CreateRefused(await errorMessage(res2));
89156
- const created = await (await expectOk(res2)).json();
89157
- updateArtifactConfig(configFile, key2, {
89158
- visibility: created.visibility,
89159
- cloud: { id: created.id, url: created.url, publishedAt: null, visibility: created.visibility }
89160
- });
89161
- return created.id;
89162
- };
89335
+ const create3 = () => createRecord2(ref, requested ?? entry.visibility ?? "private");
89163
89336
  const upload = async (id2, hashes) => {
89164
89337
  for (let i6 = 0; i6 < hashes.length; i6 += UPLOAD_CONCURRENCY) {
89165
89338
  await Promise.all(
@@ -89249,7 +89422,7 @@ function createCloudRoutes(options) {
89249
89422
  if (action === "status" && method === "GET" && !first) {
89250
89423
  const credentials = readCredentials(credentialsFile2, origin);
89251
89424
  const { config, warning } = readConfig(configFile);
89252
- sendJson(res, 200, { signedIn: !!credentials, login: credentials?.login ?? null, origin, artifacts: config.artifacts, autoPublish: autoPublishState(), warning: warning ?? null });
89425
+ sendJson(res, 200, { signedIn: !!credentials, login: credentials?.login ?? null, origin, hostId: hostIdFor(credentialsFile2), artifacts: config.artifacts, autoPublish: autoPublishState(), warning: warning ?? null });
89253
89426
  return;
89254
89427
  }
89255
89428
  if (action === "login" && method === "POST" && !first) {
@@ -89290,6 +89463,10 @@ function createCloudRoutes(options) {
89290
89463
  sendJson(res, result.status, result.body);
89291
89464
  return;
89292
89465
  }
89466
+ if (action === "reserve" && ref && method === "POST") {
89467
+ sendJson(res, 200, { url: await serialized(`${ref.type}/${ref.id}`, () => reserve(ref)) });
89468
+ return;
89469
+ }
89293
89470
  if (action === "publish" && ref && method === "DELETE") {
89294
89471
  const key2 = `${ref.type}/${ref.id}`;
89295
89472
  await serialized(key2, async () => {
@@ -89376,7 +89553,7 @@ function createCloudRoutes(options) {
89376
89553
 
89377
89554
  // src/server/comment-names.ts
89378
89555
  var import_node_child_process = require("node:child_process");
89379
- var import_node_fs17 = __toESM(require("node:fs"), 1);
89556
+ var import_node_fs18 = __toESM(require("node:fs"), 1);
89380
89557
 
89381
89558
  // src/server/agent.ts
89382
89559
  var NAMES = {
@@ -89457,7 +89634,7 @@ function commentNames({ agentFile, projectDir, cloud }) {
89457
89634
  },
89458
89635
  agent: () => {
89459
89636
  try {
89460
- return detectAgent(JSON.parse(import_node_fs17.default.readFileSync(agentFile, "utf8")));
89637
+ return detectAgent(JSON.parse(import_node_fs18.default.readFileSync(agentFile, "utf8")));
89461
89638
  } catch {
89462
89639
  return void 0;
89463
89640
  }
@@ -89485,8 +89662,8 @@ function viewerPage(template, page) {
89485
89662
  }
89486
89663
 
89487
89664
  // src/server/auto-publish.ts
89488
- var import_node_crypto5 = __toESM(require("node:crypto"), 1);
89489
- var import_node_fs18 = __toESM(require("node:fs"), 1);
89665
+ var import_node_crypto6 = __toESM(require("node:crypto"), 1);
89666
+ var import_node_fs19 = __toESM(require("node:fs"), 1);
89490
89667
  var SIGNED_OUT_MESSAGE = "auto-publish paused: the Ryugi Cloud sign-in expired";
89491
89668
  function isNotice(value) {
89492
89669
  if (typeof value !== "object" || value === null) return false;
@@ -89496,7 +89673,7 @@ function isNotice(value) {
89496
89673
  function readAutoPublishState(file) {
89497
89674
  let raw = {};
89498
89675
  try {
89499
- const parsed = JSON.parse(import_node_fs18.default.readFileSync(file, "utf8"));
89676
+ const parsed = JSON.parse(import_node_fs19.default.readFileSync(file, "utf8"));
89500
89677
  if (typeof parsed === "object" && parsed !== null) raw = parsed;
89501
89678
  } catch {
89502
89679
  }
@@ -89516,7 +89693,7 @@ function createAutoPublisher(options) {
89516
89693
  const remarked = /* @__PURE__ */ new Set();
89517
89694
  const save = () => writeJsonAtomic(options.stateFile, { dirty: [...dirty], notice, paused });
89518
89695
  const raise = (kind, message) => {
89519
- if (notice?.kind !== kind) notice = { id: import_node_crypto5.default.randomUUID(), kind, message };
89696
+ if (notice?.kind !== kind) notice = { id: import_node_crypto6.default.randomUUID(), kind, message };
89520
89697
  };
89521
89698
  const run2 = async () => {
89522
89699
  if (!options.enabled() || dirty.size === 0) return;
@@ -89575,26 +89752,45 @@ function createAutoPublisher(options) {
89575
89752
  };
89576
89753
  }
89577
89754
 
89755
+ // src/server/artifact-file.ts
89756
+ var import_node_fs20 = __toESM(require("node:fs"), 1);
89757
+ var RESOLVE = { artboard: resolveBoardFile, document: resolveDocumentAsset, html: resolveHtmlFile };
89758
+ var isArtifactPage = (type, relative) => type === "html" ? relative === "index.html" : relative.endsWith(".html");
89759
+ function readArtifactFile(dir, type, relative, uiRuntimeUrl) {
89760
+ if (!resolveInside(dir, relative)) return null;
89761
+ const target = RESOLVE[type](dir, relative);
89762
+ if (!target) return null;
89763
+ let data;
89764
+ try {
89765
+ data = import_node_fs20.default.readFileSync(target);
89766
+ } catch {
89767
+ return null;
89768
+ }
89769
+ if (!isArtifactPage(type, relative)) return { contentType: mimeOf(target), data };
89770
+ const page = injectRuntime(data.toString("utf8"), { uiRuntimeUrl, embedded: type === "document", inspector: type === "artboard" });
89771
+ return { contentType: "text/html; charset=utf-8", data: Buffer.from(page) };
89772
+ }
89773
+
89578
89774
  // src/server/watch.ts
89579
- var import_node_fs19 = __toESM(require("node:fs"), 1);
89580
- var import_node_path17 = __toESM(require("node:path"), 1);
89581
- var toPosix = (file) => file.split(import_node_path17.default.sep).join("/");
89775
+ var import_node_fs21 = __toESM(require("node:fs"), 1);
89776
+ var import_node_path18 = __toESM(require("node:path"), 1);
89777
+ var toPosix = (file) => file.split(import_node_path18.default.sep).join("/");
89582
89778
  var ignored = (file) => file === ".state" || file.startsWith(".state/");
89583
89779
  function snapshot(root, dir = root, out = /* @__PURE__ */ new Map()) {
89584
89780
  let entries2;
89585
89781
  try {
89586
- entries2 = import_node_fs19.default.readdirSync(dir, { withFileTypes: true });
89782
+ entries2 = import_node_fs21.default.readdirSync(dir, { withFileTypes: true });
89587
89783
  } catch {
89588
89784
  return out;
89589
89785
  }
89590
89786
  for (const entry of entries2) {
89591
- const full = import_node_path17.default.join(dir, entry.name);
89592
- const rel = toPosix(import_node_path17.default.relative(root, full));
89787
+ const full = import_node_path18.default.join(dir, entry.name);
89788
+ const rel = toPosix(import_node_path18.default.relative(root, full));
89593
89789
  if (ignored(rel)) continue;
89594
89790
  if (entry.isDirectory()) snapshot(root, full, out);
89595
89791
  else {
89596
89792
  try {
89597
- out.set(rel, import_node_fs19.default.statSync(full).mtimeMs);
89793
+ out.set(rel, import_node_fs21.default.statSync(full).mtimeMs);
89598
89794
  } catch {
89599
89795
  }
89600
89796
  }
@@ -89627,7 +89823,7 @@ function watchTree(root, onChange, debounceMs = 120, backupPollMs = 1e3) {
89627
89823
  }, debounceMs);
89628
89824
  };
89629
89825
  try {
89630
- const watcher = import_node_fs19.default.watch(root, { recursive: true }, (_event, filename) => {
89826
+ const watcher = import_node_fs21.default.watch(root, { recursive: true }, (_event, filename) => {
89631
89827
  if (filename) queue([toPosix(filename.toString())]);
89632
89828
  });
89633
89829
  watcher.on("error", () => {
@@ -89651,92 +89847,6 @@ function watchTree(root, onChange, debounceMs = 120, backupPollMs = 1e3) {
89651
89847
  }
89652
89848
  }
89653
89849
 
89654
- // src/server/ws.ts
89655
- var import_node_crypto6 = __toESM(require("node:crypto"), 1);
89656
- var WS_MAGIC = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
89657
- var OPCODE_TEXT = 1;
89658
- var OPCODE_CLOSE = 8;
89659
- var OPCODE_PING = 9;
89660
- var OPCODE_PONG = 10;
89661
- var MAX_CLIENT_FRAME = 8 * 1024 * 1024;
89662
- function acceptKey(clientKey) {
89663
- return import_node_crypto6.default.createHash("sha1").update(clientKey + WS_MAGIC).digest("base64");
89664
- }
89665
- function encodeFrame(opcode, payload) {
89666
- const len = payload.length;
89667
- let header;
89668
- if (len < 126) {
89669
- header = Buffer.from([128 | opcode, len]);
89670
- } else if (len < 65536) {
89671
- header = Buffer.alloc(4);
89672
- header[0] = 128 | opcode;
89673
- header[1] = 126;
89674
- header.writeUInt16BE(len, 2);
89675
- } else {
89676
- header = Buffer.alloc(10);
89677
- header[0] = 128 | opcode;
89678
- header[1] = 127;
89679
- header.writeBigUInt64BE(BigInt(len), 2);
89680
- }
89681
- return Buffer.concat([header, payload]);
89682
- }
89683
- var textFrame = (text2) => encodeFrame(OPCODE_TEXT, Buffer.from(text2));
89684
- function completeHandshake(socket, clientKey) {
89685
- socket.write(
89686
- `HTTP/1.1 101 Switching Protocols\r
89687
- Upgrade: websocket\r
89688
- Connection: Upgrade\r
89689
- Sec-WebSocket-Accept: ${acceptKey(clientKey)}\r
89690
- \r
89691
- `
89692
- );
89693
- }
89694
- function rejectUpgrade(socket, status, reason) {
89695
- socket.end(`HTTP/1.1 ${status} ${reason}\r
89696
- Connection: close\r
89697
- Content-Length: 0\r
89698
- \r
89699
- `);
89700
- }
89701
- function handleClientFrames(socket, onText) {
89702
- let buffer = Buffer.alloc(0);
89703
- socket.on("data", (chunk) => {
89704
- buffer = Buffer.concat([buffer, chunk]);
89705
- while (buffer.length >= 2) {
89706
- const fin = (buffer[0] & 128) !== 0;
89707
- const opcode = buffer[0] & 15;
89708
- let len = buffer[1] & 127;
89709
- let offset = 2;
89710
- if (len === 126) {
89711
- if (buffer.length < 4) return;
89712
- len = buffer.readUInt16BE(2);
89713
- offset = 4;
89714
- } else if (len === 127) {
89715
- if (buffer.length < 10) return;
89716
- const big = buffer.readBigUInt64BE(2);
89717
- if (big > BigInt(MAX_CLIENT_FRAME)) {
89718
- socket.destroy();
89719
- return;
89720
- }
89721
- len = Number(big);
89722
- offset = 10;
89723
- }
89724
- const total = offset + 4 + len;
89725
- if (buffer.length < total) return;
89726
- const mask = buffer.subarray(offset, offset + 4);
89727
- const payload = Buffer.from(buffer.subarray(offset + 4, total));
89728
- for (let i6 = 0; i6 < payload.length; i6++) payload[i6] = payload[i6] ^ mask[i6 % 4];
89729
- buffer = buffer.subarray(total);
89730
- if (opcode === OPCODE_CLOSE) {
89731
- socket.end(encodeFrame(OPCODE_CLOSE, Buffer.alloc(0)));
89732
- return;
89733
- }
89734
- if (opcode === OPCODE_PING) socket.write(encodeFrame(OPCODE_PONG, payload));
89735
- else if (opcode === OPCODE_TEXT && fin) onText?.(payload.toString("utf8"));
89736
- }
89737
- });
89738
- }
89739
-
89740
89850
  // src/server/app.ts
89741
89851
  var VIEWER_CSP = [
89742
89852
  "default-src 'self'",
@@ -89755,6 +89865,7 @@ var CONTENT_CSP = {
89755
89865
  document: "sandbox; default-src 'none'",
89756
89866
  html: "sandbox allow-scripts allow-modals allow-forms allow-popups allow-downloads"
89757
89867
  };
89868
+ var DIRECT_RELAY_ROUTE = /^\/relay\/a\/([A-Za-z0-9_-]{1,64})$/;
89758
89869
  var SHELL_ROUTE = new RegExp(`^/(?:(${ARTIFACT_TYPES.join("|")})/([^/]+)/?)?$`);
89759
89870
  var API_ARTIFACT_ROUTE = /^\/api\/artifacts\/([^/]+)\/([^/]+)$/;
89760
89871
  var PREVIEW_ROUTE = /^\/preview\/(artboard|document|html)\/([a-z0-9][a-z0-9-]*)\/?$/;
@@ -89763,6 +89874,7 @@ var API_DOCUMENT_ROUTE = /^\/api\/document\/([^/]+)\/(state|update|comments)$/;
89763
89874
  var MAX_COMMENT_OP = 64 * 1024;
89764
89875
  var API_AGENT_COMMENTS_ROUTE = /^\/api\/agent\/document\/([^/]+)\/comments$/;
89765
89876
  var MAX_DOCUMENT_UPDATE = 8 * 1024 * 1024;
89877
+ var MAX_RELAY_FILE = 8 * 1024 * 1024;
89766
89878
  var MAX_RUNTIME_MESSAGE = 2048;
89767
89879
  var MAX_RUNTIME_WARNINGS = 20;
89768
89880
  function readArtifact(dir, ref, runtime = []) {
@@ -89779,17 +89891,17 @@ function titleOf(payload, ref) {
89779
89891
  return payload.canvas?.title || ref.id;
89780
89892
  }
89781
89893
  async function startArtifactsServer(options) {
89782
- const root = import_node_path18.default.resolve(options.root);
89783
- const viewerDir = import_node_path18.default.resolve(options.viewerDir);
89784
- const runtimeDir = options.runtimeDir ? import_node_path18.default.resolve(options.runtimeDir) : null;
89785
- const stateDir = import_node_path18.default.join(root, ".state");
89786
- import_node_fs20.default.mkdirSync(stateDir, { recursive: true, mode: 448 });
89787
- import_node_fs20.default.writeFileSync(import_node_path18.default.join(stateDir, ".gitignore"), "*\n");
89894
+ const root = import_node_path19.default.resolve(options.root);
89895
+ const viewerDir = import_node_path19.default.resolve(options.viewerDir);
89896
+ const runtimeDir = options.runtimeDir ? import_node_path19.default.resolve(options.runtimeDir) : null;
89897
+ const stateDir = import_node_path19.default.join(root, ".state");
89898
+ import_node_fs22.default.mkdirSync(stateDir, { recursive: true, mode: 448 });
89899
+ import_node_fs22.default.writeFileSync(import_node_path19.default.join(stateDir, ".gitignore"), "*\n");
89788
89900
  if (options.configFile) ensureConfig(options.configFile);
89789
- const portFile = import_node_path18.default.join(stateDir, ".last-port");
89790
- const tokenFile = import_node_path18.default.join(stateDir, ".last-token");
89901
+ const portFile = import_node_path19.default.join(stateDir, ".last-port");
89902
+ const tokenFile = import_node_path19.default.join(stateDir, ".last-token");
89791
89903
  const token = readPersisted(tokenFile) || randomToken();
89792
- import_node_fs20.default.writeFileSync(tokenFile, `${token}
89904
+ import_node_fs22.default.writeFileSync(tokenFile, `${token}
89793
89905
  `, { mode: 384 });
89794
89906
  const contentToken = randomToken();
89795
89907
  const runtimeWarnings = /* @__PURE__ */ new Map();
@@ -89806,13 +89918,20 @@ async function startArtifactsServer(options) {
89806
89918
  let port = 0;
89807
89919
  let cookieName = "";
89808
89920
  let relay = null;
89921
+ const direct = createDirectRelay({
89922
+ version: options.relay?.version ?? "",
89923
+ handle: (key2, body, conn) => handleRelay(key2, body, conn, `http://127.0.0.1:${port}`),
89924
+ onActivity: () => touch(),
89925
+ onClose: (conn) => dropRelayViewer(conn)
89926
+ });
89809
89927
  const broadcast = (message) => {
89810
89928
  const frame = textFrame(JSON.stringify(message));
89811
89929
  for (const socket of clients) socket.write(frame);
89812
89930
  relay?.emit(message.artifact, message);
89931
+ direct.emit(message.artifact, message);
89813
89932
  };
89814
89933
  const avatars = createAvatars(options.fetch);
89815
- const names = commentNames({ agentFile: import_node_path18.default.join(stateDir, "agent"), projectDir: import_node_path18.default.resolve(root, "../.."), cloud: options.cloud });
89934
+ const names = commentNames({ agentFile: import_node_path19.default.join(stateDir, "agent"), projectDir: import_node_path19.default.resolve(root, "../.."), cloud: options.cloud });
89816
89935
  const documents = createDocumentRegistry({
89817
89936
  root,
89818
89937
  stateDir,
@@ -89850,8 +89969,8 @@ async function startArtifactsServer(options) {
89850
89969
  }
89851
89970
  return { dir, title, reasons, payload: published };
89852
89971
  };
89853
- const cloud = options.cloud && options.configFile ? createCloudRoutes({ ...options.cloud, configFile: options.configFile, project: import_node_path18.default.basename(import_node_path18.default.resolve(root, "../..")), port: () => port, inspect }) : null;
89854
- const autoPublisher = cloud ? createAutoPublisher({ stateFile: import_node_path18.default.join(stateDir, "auto-publish.json"), enabled: cloud.autoPublishEnabled, token: cloud.token, publish: cloud.autoPublish }) : null;
89972
+ const cloud = options.cloud && options.configFile ? createCloudRoutes({ ...options.cloud, configFile: options.configFile, project: import_node_path19.default.basename(import_node_path19.default.resolve(root, "../..")), port: () => port, inspect }) : null;
89973
+ const autoPublisher = cloud ? createAutoPublisher({ stateFile: import_node_path19.default.join(stateDir, "auto-publish.json"), enabled: cloud.autoPublishEnabled, token: cloud.token, publish: cloud.autoPublish }) : null;
89855
89974
  const sameOrigin = (req) => {
89856
89975
  const origin2 = req.headers.origin;
89857
89976
  const host = req.headers.host ?? "";
@@ -89930,7 +90049,7 @@ async function startArtifactsServer(options) {
89930
90049
  };
89931
90050
  const blockIdsOf = async (id2, dir) => {
89932
90051
  await (await documents.open(id2))?.flush();
89933
- const state = parseDocument2(import_node_fs20.default.readFileSync(import_node_path18.default.join(dir, "doc.xml"), "utf8"));
90052
+ const state = parseDocument2(import_node_fs22.default.readFileSync(import_node_path19.default.join(dir, "doc.xml"), "utf8"));
89934
90053
  return new Set(state.root.children.flatMap((block) => block.$?.blockId ? [block.$.blockId] : []));
89935
90054
  };
89936
90055
  const serveAgentComments = async (req, res, id2) => {
@@ -90010,7 +90129,7 @@ async function startArtifactsServer(options) {
90010
90129
  sendFile(res, target, headers);
90011
90130
  return;
90012
90131
  }
90013
- import_node_fs20.default.readFile(target, "utf8", (err, source) => {
90132
+ import_node_fs22.default.readFile(target, "utf8", (err, source) => {
90014
90133
  if (err) send(res, 404, "Not found");
90015
90134
  else {
90016
90135
  const uiRuntimeUrl = runtimeDir ? `${contentPrefix}runtime/ryugi-ui.js` : void 0;
@@ -90018,10 +90137,10 @@ async function startArtifactsServer(options) {
90018
90137
  }
90019
90138
  });
90020
90139
  };
90021
- const artifactMeta = (ref, dir) => ({
90140
+ const artifactMeta = (ref, dir, contentOrigin = "") => ({
90022
90141
  ...readArtifact(dir, ref, runtimeOf(ref, dir)),
90023
90142
  ...ref.type !== "html" ? { agent: names.agent() } : {},
90024
- contentBase: `${contentPrefix}${ref.type}/${ref.id}/`
90143
+ contentBase: `${contentOrigin}${contentPrefix}${ref.type}/${ref.id}/`
90025
90144
  });
90026
90145
  const serveArtifactApi = (res, type, id2) => {
90027
90146
  const dir = resolveArtifactDir(root, type, id2);
@@ -90039,7 +90158,7 @@ async function startArtifactsServer(options) {
90039
90158
  title: titleOf(readArtifact(entry.dir, entry), entry),
90040
90159
  updatedAt: latestMtime(entry.dir)
90041
90160
  }));
90042
- sendJson(res, 200, { project: import_node_path18.default.basename(import_node_path18.default.dirname(import_node_path18.default.dirname(root))), artifacts: summaries, warnings });
90161
+ sendJson(res, 200, { project: import_node_path19.default.basename(import_node_path19.default.dirname(import_node_path19.default.dirname(root))), artifacts: summaries, warnings });
90043
90162
  };
90044
90163
  function onClientText(socket, text2) {
90045
90164
  let message;
@@ -90053,7 +90172,9 @@ async function startArtifactsServer(options) {
90053
90172
  selections.accept(socket, message);
90054
90173
  return;
90055
90174
  }
90056
- const { type, artifact, message: detail, version: version2, file } = message;
90175
+ acceptReport(message);
90176
+ }
90177
+ function acceptReport({ type, artifact, message: detail, version: version2, file }) {
90057
90178
  if (typeof artifact !== "string") return;
90058
90179
  const ref = artifactKeyOf(artifact);
90059
90180
  if (!ref || ref.type === "artboard" || artifact !== `${ref.type}/${ref.id}`) return;
@@ -90085,7 +90206,7 @@ async function startArtifactsServer(options) {
90085
90206
  runtimeWarnings.set(artifact, [...list2, detail]);
90086
90207
  writeState(ref, dir);
90087
90208
  const frame = textFrame(JSON.stringify({ type: "change", artifact, files: [] }));
90088
- for (const socket2 of clients) socket2.write(frame);
90209
+ for (const socket of clients) socket.write(frame);
90089
90210
  }
90090
90211
  const handleRequest = (req, res) => {
90091
90212
  touch();
@@ -90099,7 +90220,7 @@ async function startArtifactsServer(options) {
90099
90220
  return;
90100
90221
  }
90101
90222
  if (pathname === "/robots.txt") {
90102
- sendFile(res, import_node_path18.default.join(viewerDir, "robots.txt"));
90223
+ sendFile(res, import_node_path19.default.join(viewerDir, "robots.txt"));
90103
90224
  return;
90104
90225
  }
90105
90226
  if (pathname.startsWith("/c/")) {
@@ -90196,7 +90317,7 @@ async function startArtifactsServer(options) {
90196
90317
  if (SHELL_ROUTE.test(pathname) || PREVIEW_ROUTE.test(pathname) || pathname === "/index.html") {
90197
90318
  const ref = artifactKeyOf(pathname.replace(/^\/(?:preview\/)?/, "").replace(/\/$/, ""));
90198
90319
  const dir = ref && resolveArtifactDir(root, ref.type, ref.id);
90199
- const project = import_node_path18.default.basename(import_node_path18.default.dirname(import_node_path18.default.dirname(root)));
90320
+ const project = import_node_path19.default.basename(import_node_path19.default.dirname(import_node_path19.default.dirname(root)));
90200
90321
  const title = ref ? dir ? titleOf(readArtifact(dir, ref), ref) : ref.id : `${project} \xB7 Artifacts`;
90201
90322
  const description = ref ? `\u5728 ${project} \u9879\u76EE\u4E2D\u67E5\u770B ${title}\uFF0C\u8FD9\u662F\u4E00\u4E2A ${ref.type === "artboard" ? "Artboard" : ref.type === "document" ? "Document" : "HTML"} Artifact\u3002` : `\u6D4F\u89C8 ${project} \u9879\u76EE\u7684\u5168\u90E8 Artboard\u3001Document \u548C HTML Artifact\uFF0C\u9884\u89C8\u771F\u5B9E\u5185\u5BB9\uFF0C\u6309\u7C7B\u578B\u3001\u540D\u79F0\u548C\u66F4\u65B0\u65F6\u95F4\u67E5\u627E\u4F5C\u54C1\u3002`;
90202
90323
  const canonical = `http://${urlHostForHttp(options.urlHost)}:${port}/${ref ? `${ref.type}/${ref.id}` : ""}`;
@@ -90205,7 +90326,7 @@ async function startArtifactsServer(options) {
90205
90326
  "Content-Security-Policy": PREVIEW_ROUTE.test(pathname) ? VIEWER_CSP.replace("frame-ancestors 'none'", "frame-ancestors 'self'") : VIEWER_CSP
90206
90327
  };
90207
90328
  if (key2 !== null) headers["Set-Cookie"] = `${cookieName}=${token}; HttpOnly; SameSite=Strict; Path=/`;
90208
- void import_node_fs20.default.promises.readFile(import_node_path18.default.join(viewerDir, "index.html"), "utf8").then((template) => send(res, 200, viewerPage(template, { title, description, url: canonical }), headers)).catch((err) => send(res, err.code === "ENOENT" ? 404 : 500, "Viewer unavailable"));
90329
+ void import_node_fs22.default.promises.readFile(import_node_path19.default.join(viewerDir, "index.html"), "utf8").then((template) => send(res, 200, viewerPage(template, { title, description, url: canonical }), headers)).catch((err) => send(res, err.code === "ENOENT" ? 404 : 500, "Viewer unavailable"));
90209
90330
  return;
90210
90331
  }
90211
90332
  const target = resolveInside(viewerDir, pathname.slice(1));
@@ -90222,6 +90343,18 @@ async function startArtifactsServer(options) {
90222
90343
  server.on("upgrade", (req, socket) => {
90223
90344
  const url2 = new URL(req.url ?? "/", "http://artifacts.local");
90224
90345
  const clientKey = req.headers["sec-websocket-key"];
90346
+ const directMatch = DIRECT_RELAY_ROUTE.exec(url2.pathname);
90347
+ if (directMatch && typeof clientKey === "string") {
90348
+ const fromCloud = options.cloud !== void 0 && req.headers.origin === options.cloud.origin;
90349
+ if (!safeEqual(url2.searchParams.get("key") ?? "", token) || !(fromCloud || sameOrigin(req))) {
90350
+ rejectUpgrade(socket, 403, "Forbidden");
90351
+ return;
90352
+ }
90353
+ const key2 = servedArtifacts().get(directMatch[1]);
90354
+ if (!key2) rejectUpgrade(socket, 404, "Not Found");
90355
+ else direct.accept(socket, clientKey, key2);
90356
+ return;
90357
+ }
90225
90358
  if (url2.pathname !== "/ws" || typeof clientKey !== "string") {
90226
90359
  rejectUpgrade(socket, 400, "Bad Request");
90227
90360
  return;
@@ -90252,7 +90385,7 @@ async function startArtifactsServer(options) {
90252
90385
  port = await listen(server, options.host, 0);
90253
90386
  }
90254
90387
  cookieName = `ryugi_artifacts_${port}`;
90255
- import_node_fs20.default.writeFileSync(portFile, `${port}
90388
+ import_node_fs22.default.writeFileSync(portFile, `${port}
90256
90389
  `, { mode: 384 });
90257
90390
  const origin = `http://${urlHostForHttp(options.urlHost)}:${port}`;
90258
90391
  const url = `${origin}/?key=${token}`;
@@ -90278,23 +90411,40 @@ async function startArtifactsServer(options) {
90278
90411
  initialChanges.push({ ref: entry, payload, files: [] });
90279
90412
  if (entry.type === "document") void documents.open(entry.id);
90280
90413
  }
90281
- writeJsonAtomic(import_node_path18.default.join(stateDir, "server-info"), { type: "server-started", url, port, root });
90414
+ writeJsonAtomic(import_node_path19.default.join(stateDir, "server-info"), { type: "server-started", url, port, root });
90282
90415
  const relayViewers = /* @__PURE__ */ new Map();
90283
- const servedDocuments = () => {
90416
+ const servedArtifacts = () => {
90284
90417
  const served = /* @__PURE__ */ new Map();
90285
90418
  if (!options.configFile) return served;
90286
90419
  for (const [key2, entry] of Object.entries(readConfig(options.configFile).config.artifacts)) {
90287
90420
  const ref = artifactKeyOf(key2);
90288
- if (entry.cloud && ref?.type === "document" && resolveArtifactDir(root, "document", ref.id)) served.set(entry.cloud.id, key2);
90421
+ if (entry.cloud && ref && resolveArtifactDir(root, ref.type, ref.id)) served.set(entry.cloud.id, key2);
90289
90422
  }
90290
90423
  return served;
90291
90424
  };
90292
- const handleRelay = async (key2, body, conn) => {
90425
+ const dropRelayViewer = (conn) => {
90426
+ const viewer = relayViewers.get(conn);
90427
+ if (!viewer) return;
90428
+ selections.drop(viewer.tab);
90429
+ relayViewers.delete(conn);
90430
+ };
90431
+ const handleRelay = async (key2, body, conn, contentOrigin = "") => {
90293
90432
  const ref = artifactKeyOf(key2);
90294
90433
  const dir = resolveArtifactDir(root, ref.type, ref.id);
90295
90434
  if (!dir) throw new Error(`${key2} not found`);
90296
90435
  const request = typeof body === "object" && body !== null ? body : {};
90297
- if (request.op === "meta") return artifactMeta(ref, dir);
90436
+ if (request.op === "meta") return artifactMeta(ref, dir, contentOrigin);
90437
+ if (request.op === "file") {
90438
+ const file = typeof request.path === "string" ? readArtifactFile(dir, ref.type, request.path, CLOUD_RUNTIME_URL) : null;
90439
+ if (!file) throw new Error("not found");
90440
+ if (file.data.length > MAX_RELAY_FILE) throw new Error("too large");
90441
+ return { contentType: file.contentType, data: file.data.toString("base64") };
90442
+ }
90443
+ if (request.op === "client") {
90444
+ if (typeof request.message === "object" && request.message !== null) acceptReport({ ...request.message, artifact: key2 });
90445
+ return null;
90446
+ }
90447
+ if ((request.op === "state" || request.op === "update" || request.op === "comment") && ref.type !== "document") throw new Error(`${key2} is not a document`);
90298
90448
  if (request.op === "state" || request.op === "update") {
90299
90449
  const session = await documents.open(ref.id);
90300
90450
  if (!session) throw new Error(`${key2} has no doc.xml`);
@@ -90322,12 +90472,13 @@ async function startArtifactsServer(options) {
90322
90472
  relay = options.relay && options.cloud ? createRelayClient({
90323
90473
  ...options.relay,
90324
90474
  token: () => readCredentials(options.cloud.credentialsFile, options.cloud.origin)?.token ?? null,
90325
- served: servedDocuments,
90475
+ served: servedArtifacts,
90476
+ local: () => ({ hostId: hostIdFor(options.cloud.credentialsFile), port, key: token }),
90326
90477
  handle: handleRelay,
90327
90478
  onActivity: touch,
90328
90479
  onWatch: (keys2) => {
90329
90480
  for (const [conn, viewer] of relayViewers) {
90330
- if (keys2.has(viewer.key)) continue;
90481
+ if (keys2.has(viewer.key) || conn.startsWith("direct:")) continue;
90331
90482
  selections.drop(viewer.tab);
90332
90483
  relayViewers.delete(conn);
90333
90484
  }
@@ -90364,6 +90515,7 @@ async function startArtifactsServer(options) {
90364
90515
  const frame = textFrame(JSON.stringify({ type: "change", artifact: key2, files: changed }));
90365
90516
  for (const socket of clients) socket.write(frame);
90366
90517
  relay?.emit(key2, { type: "change", artifact: key2, files: changed });
90518
+ direct.emit(key2, { type: "change", artifact: key2, files: changed });
90367
90519
  changeListeners.forEach((listener) => listener(ref, payload, changed));
90368
90520
  }
90369
90521
  touch();
@@ -90376,6 +90528,11 @@ async function startArtifactsServer(options) {
90376
90528
  contentToken,
90377
90529
  url,
90378
90530
  linkFor,
90531
+ cloudLinkFor: (type, id2) => {
90532
+ if (!options.cloud || !options.configFile || !readCredentials(options.cloud.credentialsFile, options.cloud.origin)) return null;
90533
+ const url2 = readConfig(options.configFile).config.artifacts[`${type}/${id2}`]?.cloud?.url;
90534
+ return url2 ? ownLink(url2, hostIdFor(options.cloud.credentialsFile)) : null;
90535
+ },
90379
90536
  clientCount: () => clients.size,
90380
90537
  onArtifactChange: (listener) => {
90381
90538
  changeListeners.push(listener);
@@ -90385,6 +90542,7 @@ async function startArtifactsServer(options) {
90385
90542
  close: () => new Promise((resolve) => {
90386
90543
  watcher.close();
90387
90544
  relay?.close();
90545
+ direct.close();
90388
90546
  selections.clearAll();
90389
90547
  for (const socket of clients) socket.destroy();
90390
90548
  server.close(() => resolve());
@@ -90394,7 +90552,7 @@ async function startArtifactsServer(options) {
90394
90552
  }
90395
90553
 
90396
90554
  // src/server/lifecycle.ts
90397
- var import_node_fs21 = __toESM(require("node:fs"), 1);
90555
+ var import_node_fs23 = __toESM(require("node:fs"), 1);
90398
90556
  var DEFAULT_IDLE_TIMEOUT_MS = 4 * 60 * 60 * 1e3;
90399
90557
  var DEFAULT_LIFECYCLE_CHECK_MS = 60 * 1e3;
90400
90558
  var SERVER_ID_ARG = "--artifacts-server-id=";
@@ -90426,7 +90584,7 @@ function parseEnv(env, argv = []) {
90426
90584
  function readOwners(file) {
90427
90585
  let text2;
90428
90586
  try {
90429
- text2 = import_node_fs21.default.readFileSync(file, "utf8");
90587
+ text2 = import_node_fs23.default.readFileSync(file, "utf8");
90430
90588
  } catch {
90431
90589
  return [];
90432
90590
  }
@@ -90489,20 +90647,20 @@ function openReady(payload) {
90489
90647
  }
90490
90648
 
90491
90649
  // package.json
90492
- var version = "1.14.0";
90650
+ var version = "1.15.1";
90493
90651
 
90494
90652
  // src/server/main.ts
90495
90653
  async function main() {
90496
90654
  const config = parseEnv(process.env, process.argv.slice(2));
90497
- const root = import_node_path19.default.resolve(config.root);
90498
- const stateDir = import_node_path19.default.join(root, ".state");
90655
+ const root = import_node_path20.default.resolve(config.root);
90656
+ const stateDir = import_node_path20.default.join(root, ".state");
90499
90657
  const server = await startArtifactsServer({
90500
90658
  root,
90501
- viewerDir: import_node_path19.default.join(__dirname, "viewer"),
90502
- runtimeDir: import_node_path19.default.join(__dirname, "runtime"),
90659
+ viewerDir: import_node_path20.default.join(__dirname, "viewer"),
90660
+ runtimeDir: import_node_path20.default.join(__dirname, "runtime"),
90503
90661
  host: config.host,
90504
90662
  urlHost: config.urlHost,
90505
- configFile: import_node_path19.default.join(import_node_path19.default.dirname(root), "config.json"),
90663
+ configFile: import_node_path20.default.join(import_node_path20.default.dirname(root), "config.json"),
90506
90664
  cloud: { origin: config.cloudOrigin, credentialsFile: credentialsFile(process.env, process.platform, import_node_os.default.homedir()) },
90507
90665
  relay: { url: `${config.cloudOrigin.replace(/^http/, "ws")}/api/relay/host`, version }
90508
90666
  });
@@ -90517,7 +90675,7 @@ async function main() {
90517
90675
  if ("canvas" in payload ? !openReady(payload) : payload.warnings.length > 0) return;
90518
90676
  browserOpened = true;
90519
90677
  if (server.clientCount() > 0) return;
90520
- const link = server.linkFor(ref.type, ref.id);
90678
+ const link = server.cloudLinkFor(ref.type, ref.id) ?? server.linkFor(ref.type, ref.id);
90521
90679
  if (config.openCmd) {
90522
90680
  (0, import_node_child_process2.exec)(`${config.openCmd} ${JSON.stringify(link)}`, () => {
90523
90681
  });
@@ -90532,12 +90690,12 @@ async function main() {
90532
90690
  if (stopping) return;
90533
90691
  stopping = true;
90534
90692
  console.log(JSON.stringify({ type: "server-stopped", reason }));
90535
- import_node_fs22.default.rmSync(import_node_path19.default.join(stateDir, "server-info"), { force: true });
90536
- writeJsonAtomic(import_node_path19.default.join(stateDir, "server-stopped"), { reason, timestamp: Date.now() });
90693
+ import_node_fs24.default.rmSync(import_node_path20.default.join(stateDir, "server-info"), { force: true });
90694
+ writeJsonAtomic(import_node_path20.default.join(stateDir, "server-stopped"), { reason, timestamp: Date.now() });
90537
90695
  await server.close();
90538
90696
  process.exit(0);
90539
90697
  };
90540
- const ownersFile = import_node_path19.default.join(stateDir, "owners");
90698
+ const ownersFile = import_node_path20.default.join(stateDir, "owners");
90541
90699
  const timer = setInterval(() => {
90542
90700
  const owners = readOwners(ownersFile);
90543
90701
  const reason = shutdownReason({
@@ -90551,7 +90709,7 @@ async function main() {
90551
90709
  timer.unref();
90552
90710
  process.on("SIGTERM", () => void shutdown("SIGTERM"));
90553
90711
  process.on("SIGINT", () => void shutdown("SIGINT"));
90554
- import_node_fs22.default.rmSync(import_node_path19.default.join(stateDir, "server-stopped"), { force: true });
90712
+ import_node_fs24.default.rmSync(import_node_path20.default.join(stateDir, "server-stopped"), { force: true });
90555
90713
  console.log(JSON.stringify({ type: "server-started", url: server.url, port: server.port, root }));
90556
90714
  }
90557
90715
  main().catch((err) => {