ryugi-artifacts 1.15.0 → 1.15.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +48 -15
- package/dist/server.cjs +581 -258
- package/dist/viewer/CloudDocument-a-QKYAcP.js +1 -0
- package/dist/viewer/CloudLiveDocument-9iIvfZ3y.js +1 -0
- package/dist/viewer/{DocumentLayout-BDQ2bRgn.js → DocumentLayout-C7DI3nfX.js} +82 -82
- package/dist/viewer/DocumentPage-CN-MKF7P.js +1 -0
- package/dist/viewer/{abnfDiagram-VCTEODGH-DXcz0DY8.js → abnfDiagram-VCTEODGH-BMWz464k.js} +1 -1
- package/dist/viewer/{ar-SA-G6X2FPQ2-DaFICdeh.js → ar-SA-G6X2FPQ2-BbVC-Hlr.js} +1 -1
- package/dist/viewer/{architectureDiagram-5GKGNRK7-7HwBC9Wz.js → architectureDiagram-5GKGNRK7-lX00q8y2.js} +1 -1
- package/dist/viewer/{az-AZ-76LH7QW2-ro71YLew.js → az-AZ-76LH7QW2-kWbxvJoq.js} +1 -1
- package/dist/viewer/{bg-BG-XCXSNQG7-BBql1i2c.js → bg-BG-XCXSNQG7-TWjfBbIo.js} +1 -1
- package/dist/viewer/{blockDiagram-I7D4REHJ-DN6_CCIZ.js → blockDiagram-I7D4REHJ-r6mTM-V-.js} +1 -1
- package/dist/viewer/{bn-BD-2XOGV67Q-D0nEk_sk.js → bn-BD-2XOGV67Q-Dt8TooV0.js} +1 -1
- package/dist/viewer/{c4Diagram-7LVT6UL2-BiKuFZ_0.js → c4Diagram-7LVT6UL2-C-_q-X-w.js} +1 -1
- package/dist/viewer/{ca-ES-6MX7JW3Y-BzXg8v5p.js → ca-ES-6MX7JW3Y-D_8AE5qp.js} +1 -1
- package/dist/viewer/{chunk-4HAMMTFA-D8wduydj.js → chunk-4HAMMTFA-VvmFCZU-.js} +1 -1
- package/dist/viewer/{chunk-EIO257PC-KVQLe9-1.js → chunk-EIO257PC-BD0aoNze.js} +1 -1
- package/dist/viewer/{chunk-GMAD6QVW-BPxTHMTi.js → chunk-GMAD6QVW-DWAZVXaZ.js} +1 -1
- package/dist/viewer/{chunk-GVQU2GXP-C5_2EAAn.js → chunk-GVQU2GXP-BXHdLj9j.js} +1 -1
- package/dist/viewer/{chunk-IMKFNOWR-CoST25Zy.js → chunk-IMKFNOWR-Fyso0OP0.js} +1 -1
- package/dist/viewer/{chunk-L3NEJ4N5-DqtaXAcI.js → chunk-L3NEJ4N5-B4STdBka.js} +1 -1
- package/dist/viewer/{chunk-OSK3NFVY-DacvL7tA.js → chunk-OSK3NFVY-BEwpVZFI.js} +1 -1
- package/dist/viewer/{chunk-PWAF6VOD-Cxj_hOdt.js → chunk-PWAF6VOD-DdxzGU7i.js} +1 -1
- package/dist/viewer/{chunk-SHT3W25Y-D9pKJ6Au.js → chunk-SHT3W25Y-vfyQBaPf.js} +1 -1
- package/dist/viewer/{chunk-SVP7TREG-svneeNVA.js → chunk-SVP7TREG-iglWUDOS.js} +1 -1
- package/dist/viewer/{chunk-TICWLB2K-xfr9ROyW.js → chunk-TICWLB2K-cw2jyncd.js} +1 -1
- package/dist/viewer/{classDiagram-ZZMXUADV-lu71gUXJ.js → classDiagram-ZZMXUADV-2wFXqaaX.js} +1 -1
- package/dist/viewer/{classDiagram-v2-VYDZK3BY-lu71gUXJ.js → classDiagram-v2-VYDZK3BY-2wFXqaaX.js} +1 -1
- package/dist/viewer/{cs-CZ-2BRQDIVT-bwZx9UIu.js → cs-CZ-2BRQDIVT-BYqh8Zl-.js} +1 -1
- package/dist/viewer/{cynefinDiagram-5FMLGOSQ-DlNaJbj_.js → cynefinDiagram-5FMLGOSQ-CHJoO2Gh.js} +1 -1
- package/dist/viewer/{da-DK-5WZEPLOC-BApDVcwE.js → da-DK-5WZEPLOC-DeKrLDAU.js} +1 -1
- package/dist/viewer/{dagre-GXQ25YYZ-DWu2Ycc5.js → dagre-GXQ25YYZ-GWluYfqf.js} +1 -1
- package/dist/viewer/{de-DE-XR44H4JA-COcHc6Zt.js → de-DE-XR44H4JA-D1wSMLDv.js} +1 -1
- package/dist/viewer/{diagram-S7CK7UJ4-D8VO7YKc.js → diagram-S7CK7UJ4-BlgVPVRQ.js} +1 -1
- package/dist/viewer/{diagram-UQ7AKVKN-D5OcQNY9.js → diagram-UQ7AKVKN-ChtP0cpA.js} +1 -1
- package/dist/viewer/{diagram-VX7I27RA-DRHmiAWI.js → diagram-VX7I27RA-vKg6VXhQ.js} +1 -1
- package/dist/viewer/{diagram-Z3DM3KII-ClXzWLem.js → diagram-Z3DM3KII-CuHg0fFk.js} +1 -1
- package/dist/viewer/{dist-BuKe8NdN.js → dist-B0CwGaG1.js} +1 -1
- package/dist/viewer/{dist-BKtxxS1a.js → dist-BPFUf7bl.js} +1 -1
- package/dist/viewer/{dist-_3NL_2LS.js → dist-Bh74XfyN.js} +1 -1
- package/dist/viewer/{dist-TX5rYYGW.js → dist-BsTr5QXe.js} +4 -4
- package/dist/viewer/{dist-CFkCXjQP.js → dist-C0tpKGuj.js} +1 -1
- package/dist/viewer/{dist-DB3o8dUU.js → dist-CKWiXiZi.js} +1 -1
- package/dist/viewer/{dist-CV7QdHTq.js → dist-CSqVlzxR.js} +1 -1
- package/dist/viewer/{dist-DlANbAUX.js → dist-Cn_FmF1G.js} +1 -1
- package/dist/viewer/{dist-DzBPEHnz.js → dist-CtEVZbP8.js} +1 -1
- package/dist/viewer/{dist-C2adJeNZ.js → dist-D2qf-mJJ.js} +1 -1
- package/dist/viewer/{dist-DLh5uREE.js → dist-DM8QiMoo.js} +1 -1
- package/dist/viewer/{dist-DcGUli8O.js → dist-DRSecFjm.js} +1 -1
- package/dist/viewer/{dist-G2JHMLgK.js → dist-DX-BoDBd.js} +1 -1
- package/dist/viewer/{dist-VupXLYv6.js → dist-DY66SSSM.js} +1 -1
- package/dist/viewer/{dist-M7Lz5R2v.js → dist-D_BoFupz.js} +1 -1
- package/dist/viewer/{dist-C_NwF-ep.js → dist-DeIwlPUC.js} +1 -1
- package/dist/viewer/{dist-Bgijnk4D.js → dist-Dnus25TG.js} +1 -1
- package/dist/viewer/{dist-D0Emc84u.js → dist-DqIYAdWh.js} +1 -1
- package/dist/viewer/{dist-rgdCugHI.js → dist-DygF9RCe.js} +1 -1
- package/dist/viewer/{dist-a8BuHhYq.js → dist-aWI_fVHd.js} +1 -1
- package/dist/viewer/{dist-mDWB-P3S.js → dist-k50hDI1z.js} +1 -1
- package/dist/viewer/{dist-DfWxOyg4.js → dist-rnL-4FWR.js} +1 -1
- package/dist/viewer/{dist-q1jFGEbP.js → dist-uFBCfcc5.js} +1 -1
- package/dist/viewer/{dist-CByD4sdq.js → dist-zBXj6chJ.js} +1 -1
- package/dist/viewer/{ebnfDiagram-PWID7BFC-BOzsyHEk.js → ebnfDiagram-PWID7BFC-C5bMbUq0.js} +1 -1
- package/dist/viewer/{el-GR-BZB4AONW-h1eLQlP7.js → el-GR-BZB4AONW-0cbbZg2F.js} +1 -1
- package/dist/viewer/{en-B4ZKOASM-EdleGu9D.js → en-B4ZKOASM-CDTpThHV.js} +1 -1
- package/dist/viewer/{erDiagram-RLTQ6QDP-BF_tpcM3.js → erDiagram-RLTQ6QDP-C6PFBM-5.js} +1 -1
- package/dist/viewer/{es-ES-U4NZUMDT-DeaeHEK9.js → es-ES-U4NZUMDT-8fQP93wk.js} +1 -1
- package/dist/viewer/{eu-ES-A7QVB2H4-BzoRNYbw.js → eu-ES-A7QVB2H4-CnogIziV.js} +1 -1
- package/dist/viewer/{fa-IR-HGAKTJCU-fXYoNuWo.js → fa-IR-HGAKTJCU-CdYOaxCM.js} +1 -1
- package/dist/viewer/{fi-FI-Z5N7JZ37-CTVEZXqM.js → fi-FI-Z5N7JZ37-Ds2DlP3M.js} +1 -1
- package/dist/viewer/flowDiagram-HODETNUW-DFPpbdLC.js +1 -0
- package/dist/viewer/{fr-FR-RHASNOE6-BizkpgaG.js → fr-FR-RHASNOE6-BZT79zkJ.js} +1 -1
- package/dist/viewer/{ganttDiagram-EL5Y4UJY-DvL8TKGV.js → ganttDiagram-EL5Y4UJY-Dj5h1KL5.js} +1 -1
- package/dist/viewer/{gl-ES-HMX3MZ6V-rsfHb2R9.js → gl-ES-HMX3MZ6V-D5SkTUmd.js} +1 -1
- package/dist/viewer/{he-IL-6SHJWFNN-BmWEwAWC.js → he-IL-6SHJWFNN-DAYxQbJv.js} +1 -1
- package/dist/viewer/{hi-IN-IWLTKZ5I-gzYZTFIt.js → hi-IN-IWLTKZ5I-CmTpu_Mh.js} +1 -1
- package/dist/viewer/{hu-HU-A5ZG7DT2-DqXGHJ4g.js → hu-HU-A5ZG7DT2-CCoJDqVh.js} +1 -1
- package/dist/viewer/{id-ID-SAP4L64H-CVbSVAc3.js → id-ID-SAP4L64H-DvB8T5Ih.js} +1 -1
- package/dist/viewer/{image-GAAHSSAO-B0g7YyLf.js → image-GAAHSSAO-lz2X8afW.js} +1 -1
- package/dist/viewer/index.html +1 -1
- package/dist/viewer/index.js +8 -8
- package/dist/viewer/index2.css +66 -18
- package/dist/viewer/{infoDiagram-27XIBGKW-DOxIYIRL.js → infoDiagram-27XIBGKW-CPqqoefO.js} +1 -1
- package/dist/viewer/{ishikawaDiagram-5VMMS53U-D-U6Fi8F.js → ishikawaDiagram-5VMMS53U-CWt0edvi.js} +1 -1
- package/dist/viewer/{it-IT-JPQ66NNP-6PNiI36L.js → it-IT-JPQ66NNP-X0-NsLIF.js} +1 -1
- package/dist/viewer/{ja-JP-DBVTYXUO-D3SJtNp5.js → ja-JP-DBVTYXUO-DXggnPKV.js} +1 -1
- package/dist/viewer/{journeyDiagram-3NMN7TZE-8Mz0Nae3.js → journeyDiagram-3NMN7TZE-CiTGpewC.js} +1 -1
- package/dist/viewer/{kaa-6HZHGXH3-Bz3WA5yL.js → kaa-6HZHGXH3-2DqCJWwE.js} +1 -1
- package/dist/viewer/{kab-KAB-ZGHBKWFO-W2PtzMEV.js → kab-KAB-ZGHBKWFO-BMae-gRZ.js} +1 -1
- package/dist/viewer/{kanban-definition-UXKFOSKX-BP8HwPzL.js → kanban-definition-UXKFOSKX-BdzkoXVg.js} +1 -1
- package/dist/viewer/{kk-KZ-P5N5QNE5-Dc1i0Bup.js → kk-KZ-P5N5QNE5-BrUDCVOJ.js} +1 -1
- package/dist/viewer/{km-KH-HSX4SM5Z-C88_w0rR.js → km-KH-HSX4SM5Z-D8gJ0fJb.js} +1 -1
- package/dist/viewer/{ko-KR-MTYHY66A-DWOt-6As.js → ko-KR-MTYHY66A-BiY1FmA2.js} +1 -1
- package/dist/viewer/{ku-TR-6OUDTVRD-B7qeFzlo.js → ku-TR-6OUDTVRD-CG1Rotv4.js} +1 -1
- package/dist/viewer/{lt-LT-XHIRWOB4-Dc9eguDu.js → lt-LT-XHIRWOB4-BmDMD56e.js} +1 -1
- package/dist/viewer/{lv-LV-5QDEKY6T-D9CzWKMj.js → lv-LV-5QDEKY6T-DDGbepyo.js} +1 -1
- package/dist/viewer/{mindmap-definition-YA3MSWOX-Bikv3SLv.js → mindmap-definition-YA3MSWOX-CQZcwz8L.js} +1 -1
- package/dist/viewer/{mr-IN-CRQNXWMA-CtlsKIl9.js → mr-IN-CRQNXWMA-DGVOXAif.js} +1 -1
- package/dist/viewer/{my-MM-5M5IBNSE-CiyAGqHH.js → my-MM-5M5IBNSE-CE47hNzn.js} +1 -1
- package/dist/viewer/{nb-NO-T6EIAALU-l9uMRUdk.js → nb-NO-T6EIAALU-DWAPtr4M.js} +1 -1
- package/dist/viewer/{nl-NL-IS3SIHDZ-zja_zaqN.js → nl-NL-IS3SIHDZ-CSqbImvS.js} +1 -1
- package/dist/viewer/{nn-NO-6E72VCQL-BiP5RLsf.js → nn-NO-6E72VCQL-CjGcKERL.js} +1 -1
- package/dist/viewer/{oc-FR-POXYY2M6-CvKUzwab.js → oc-FR-POXYY2M6-xGWsukeR.js} +1 -1
- package/dist/viewer/{pa-IN-N4M65BXN-DioFchQd.js → pa-IN-N4M65BXN-BJE8h_ZN.js} +1 -1
- package/dist/viewer/{pegDiagram-XKGWAZYB-BSllNtPI.js → pegDiagram-XKGWAZYB-CcuWZbUH.js} +1 -1
- package/dist/viewer/percentages-BXMCSKIN-PFePCwe-.js +1 -0
- package/dist/viewer/{pieDiagram-E7YTZNPT-b1-BsaA4.js → pieDiagram-E7YTZNPT-DmDiBmYg.js} +1 -1
- package/dist/viewer/{pl-PL-T2D74RX3-Ci7dAnI8.js → pl-PL-T2D74RX3-Uk8kN-ZN.js} +1 -1
- package/dist/viewer/{prod-CPZkgD7t.js → prod-BUf-ByWA.js} +8 -8
- package/dist/viewer/{pt-BR-5N22H2LF--VT7NYYE.js → pt-BR-5N22H2LF-gBczIC_J.js} +1 -1
- package/dist/viewer/{pt-PT-UZXXM6DQ-CWdbQilC.js → pt-PT-UZXXM6DQ-BGwa_O4j.js} +1 -1
- package/dist/viewer/{quadrantDiagram-AXDQQJYC-D0pucWR0.js → quadrantDiagram-AXDQQJYC-T0I-ZZTk.js} +1 -1
- package/dist/viewer/{railroadDiagram-O6MQD6OU-DIPJ2PKr.js → railroadDiagram-O6MQD6OU-BU8Pl_j-.js} +1 -1
- package/dist/viewer/{requirementDiagram-BXWQKSXE-DEGhiwJ9.js → requirementDiagram-BXWQKSXE-BJ8oJEnw.js} +1 -1
- package/dist/viewer/{ro-RO-JPDTUUEW-BK4wLUL7.js → ro-RO-JPDTUUEW-pdcrUiy_.js} +1 -1
- package/dist/viewer/{ru-RU-B4JR7IUQ-BDPQ8blU.js → ru-RU-B4JR7IUQ-CVgnNF41.js} +1 -1
- package/dist/viewer/{sequenceDiagram-WJ2MYXX4-D7sLhGYb.js → sequenceDiagram-WJ2MYXX4-gJZVdUNR.js} +1 -1
- package/dist/viewer/{si-LK-N5RQ5JYF-D5DWsUAA.js → si-LK-N5RQ5JYF-CSt8gCsq.js} +1 -1
- package/dist/viewer/{sk-SK-C5VTKIMK-Cia9j1Te.js → sk-SK-C5VTKIMK-XfhHoKBc.js} +1 -1
- package/dist/viewer/{sl-SI-NN7IZMDC-CV304k5j.js → sl-SI-NN7IZMDC-CCi2FT_f.js} +1 -1
- package/dist/viewer/{stateDiagram-D77RDMKH-BMNx9_M8.js → stateDiagram-D77RDMKH-BdnhW-mL.js} +1 -1
- package/dist/viewer/{stateDiagram-v2-MP3YSRHH-CPa9DZs4.js → stateDiagram-v2-MP3YSRHH-DKQ7Wxmz.js} +1 -1
- package/dist/viewer/subset-shared.chunk-VczM4DdU.js +1 -0
- package/dist/viewer/{subset-worker.chunk-CHQzlaj3.js → subset-worker.chunk-lTXEvH8k.js} +1 -1
- package/dist/viewer/{sv-SE-XGPEYMSR-CXdp-XZD.js → sv-SE-XGPEYMSR-Cyx0oXFg.js} +1 -1
- package/dist/viewer/{swimlanes-42K2YHIH-BwUyxwi3.js → swimlanes-42K2YHIH-BEaqSHwN.js} +1 -1
- package/dist/viewer/{swimlanesDiagram-VR7AAH4N-BgxS36EG.js → swimlanesDiagram-VR7AAH4N-Bed4kux2.js} +1 -1
- package/dist/viewer/{ta-IN-2NMHFXQM-CObY6q-8.js → ta-IN-2NMHFXQM-B7PlQhT2.js} +1 -1
- package/dist/viewer/{th-TH-HPSO5L25-CEOiELZN.js → th-TH-HPSO5L25-CjkmlCNK.js} +1 -1
- package/dist/viewer/{timeline-definition-24CTP7MA-BJ-7Fdfr.js → timeline-definition-24CTP7MA-Bej-g5qJ.js} +1 -1
- package/dist/viewer/{tr-TR-DEFEU3FU-CPj5dFcB.js → tr-TR-DEFEU3FU-Cjo4Cn6F.js} +1 -1
- package/dist/viewer/{uk-UA-QMV73CPH-BkZyFeXP.js → uk-UA-QMV73CPH-XHZw5PVj.js} +1 -1
- package/dist/viewer/useSandboxFrame-CCmB0PzU.js +58 -0
- package/dist/viewer/{vennDiagram-4TSXK5OY-DnFbjWDw.js → vennDiagram-4TSXK5OY-CDh6q_u6.js} +1 -1
- package/dist/viewer/{vi-VN-M7AON7JQ-CkKKOpBQ.js → vi-VN-M7AON7JQ-9gMVxytt.js} +1 -1
- package/dist/viewer/{wardleyDiagram-VM6X3IG4-CN_pm__V.js → wardleyDiagram-VM6X3IG4-DKIOQyM_.js} +1 -1
- package/dist/viewer/{xychartDiagram-S5SC5T6Z-C7XLywXm.js → xychartDiagram-S5SC5T6Z-Cb3e4r6i.js} +1 -1
- package/dist/viewer/{zh-CN-LNUGB5OW-BQcCqsDg.js → zh-CN-LNUGB5OW-6d07k_8d.js} +1 -1
- package/dist/viewer/{zh-HK-E62DVLB3-Bp-jK0zw.js → zh-HK-E62DVLB3-BkpGiC7m.js} +1 -1
- package/dist/viewer/{zh-TW-RAJ6MFWO-KmFL88Bs.js → zh-TW-RAJ6MFWO-Br8z9s4c.js} +1 -1
- package/package.json +1 -1
- package/dist/viewer/CloudDocument-CgM3kbiO.js +0 -1
- package/dist/viewer/CloudLiveDocument-CKVtG8Wd.js +0 -1
- package/dist/viewer/DocumentPage-BBzAFj4H.js +0 -1
- package/dist/viewer/flowDiagram-HODETNUW-DpY3t4b0.js +0 -1
- package/dist/viewer/percentages-BXMCSKIN-BRZnWvym.js +0 -1
- package/dist/viewer/subset-shared.chunk-ChUk9bHw.js +0 -1
- package/dist/viewer/useSandboxFrame-BpJ9uM86.js +0 -58
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
|
|
5174
|
+
var import_node_fs25 = __toESM(require("node:fs"), 1);
|
|
5175
5175
|
var import_node_os = __toESM(require("node:os"), 1);
|
|
5176
|
-
var
|
|
5176
|
+
var import_node_path21 = __toESM(require("node:path"), 1);
|
|
5177
5177
|
|
|
5178
5178
|
// src/server/app.ts
|
|
5179
|
-
var
|
|
5179
|
+
var import_node_fs23 = __toESM(require("node:fs"), 1);
|
|
5180
5180
|
var import_node_http = __toESM(require("node:http"), 1);
|
|
5181
|
-
var
|
|
5181
|
+
var import_node_path20 = __toESM(require("node:path"), 1);
|
|
5182
5182
|
|
|
5183
5183
|
// src/shared/types.ts
|
|
5184
5184
|
var ARTIFACT_TYPES = ["artboard", "document", "html"];
|
|
@@ -5230,7 +5230,7 @@ function artifactKeyOf(relative) {
|
|
|
5230
5230
|
if (!type || !id2 || !isArtifactType(type) || !isArtifactId(id2)) return null;
|
|
5231
5231
|
return { type, id: id2 };
|
|
5232
5232
|
}
|
|
5233
|
-
function artifactSignature(dir) {
|
|
5233
|
+
function artifactSignature(dir, type) {
|
|
5234
5234
|
let count = 0;
|
|
5235
5235
|
let size = 0;
|
|
5236
5236
|
let latest = 0;
|
|
@@ -5243,6 +5243,7 @@ function artifactSignature(dir) {
|
|
|
5243
5243
|
}
|
|
5244
5244
|
for (const entry of entries2) {
|
|
5245
5245
|
if (entry.name.startsWith(".")) continue;
|
|
5246
|
+
if (type === "artboard" && current === dir && entry.name === "comments.json") continue;
|
|
5246
5247
|
const full = import_node_path.default.join(current, entry.name);
|
|
5247
5248
|
try {
|
|
5248
5249
|
const stat = import_node_fs.default.statSync(full);
|
|
@@ -17727,12 +17728,19 @@ function stampBlockIds(state) {
|
|
|
17727
17728
|
return { ...state, root: { ...state.root, children } };
|
|
17728
17729
|
}
|
|
17729
17730
|
|
|
17730
|
-
// src/server/
|
|
17731
|
-
var
|
|
17731
|
+
// src/server/board-comments.ts
|
|
17732
|
+
var import_node_crypto2 = __toESM(require("node:crypto"), 1);
|
|
17733
|
+
var import_node_fs8 = __toESM(require("node:fs"), 1);
|
|
17734
|
+
var import_node_path7 = __toESM(require("node:path"), 1);
|
|
17732
17735
|
|
|
17733
17736
|
// src/shared/comments.ts
|
|
17734
17737
|
var emptyComments = () => ({ version: 1, threads: [] });
|
|
17735
17738
|
var isObject = (value) => typeof value === "object" && value !== null;
|
|
17739
|
+
var documentAnchors = {
|
|
17740
|
+
read: (value) => isObject(value) && typeof value.blockId === "string" && value.blockId ? { blockId: value.blockId, quote: typeof value.quote === "string" ? value.quote : "" } : null,
|
|
17741
|
+
same: (a5, b6) => a5.blockId === b6.blockId && a5.quote === b6.quote,
|
|
17742
|
+
missing: "a new thread needs anchor.blockId; dropped it"
|
|
17743
|
+
};
|
|
17736
17744
|
function parseComments(text2) {
|
|
17737
17745
|
const raw = JSON.parse(text2);
|
|
17738
17746
|
if (!isObject(raw)) throw new Error("comments.json must be an object");
|
|
@@ -17745,13 +17753,14 @@ function parseComments(text2) {
|
|
|
17745
17753
|
return raw;
|
|
17746
17754
|
}
|
|
17747
17755
|
var isSavedMessage = (m11) => !!m11.id && (m11.author === "human" || m11.author === "agent") && typeof m11.text === "string" && typeof m11.at === "string";
|
|
17748
|
-
function savedComments(incoming) {
|
|
17756
|
+
function savedComments(incoming, spec = documentAnchors) {
|
|
17749
17757
|
const threads = [];
|
|
17750
17758
|
for (const t7 of incoming.threads) {
|
|
17751
|
-
|
|
17759
|
+
const anchor = spec.read(t7.anchor);
|
|
17760
|
+
if (!t7.id || !anchor || !t7.statusAt || t7.status !== "open" && t7.status !== "resolved") continue;
|
|
17752
17761
|
const messages = (t7.messages ?? []).filter(isSavedMessage);
|
|
17753
17762
|
const statusBy = t7.statusBy === "human" || t7.statusBy === "agent" ? { statusBy: t7.statusBy } : {};
|
|
17754
|
-
threads.push({ id: t7.id, anchor
|
|
17763
|
+
threads.push({ id: t7.id, anchor, status: t7.status, statusAt: t7.statusAt, ...statusBy, messages });
|
|
17755
17764
|
}
|
|
17756
17765
|
return { version: 1, threads };
|
|
17757
17766
|
}
|
|
@@ -17791,32 +17800,36 @@ function mergeThread(base, incoming, origin, now, newId, warnings, name) {
|
|
|
17791
17800
|
messages.sort((a5, b6) => a5.at < b6.at ? -1 : a5.at > b6.at ? 1 : 0);
|
|
17792
17801
|
let { status, statusAt, statusBy } = base;
|
|
17793
17802
|
if (incoming.status && incoming.status !== base.status) {
|
|
17794
|
-
const
|
|
17795
|
-
if (
|
|
17803
|
+
const stamp2 = incoming.statusAt && incoming.statusAt !== base.statusAt ? incoming.statusAt : now;
|
|
17804
|
+
if (stamp2 >= base.statusAt) {
|
|
17796
17805
|
status = incoming.status;
|
|
17797
|
-
statusAt =
|
|
17806
|
+
statusAt = stamp2;
|
|
17798
17807
|
statusBy = origin;
|
|
17799
17808
|
}
|
|
17800
17809
|
}
|
|
17801
17810
|
return { ...base, status, statusAt, ...statusBy ? { statusBy } : {}, messages };
|
|
17802
17811
|
}
|
|
17803
|
-
|
|
17804
|
-
|
|
17812
|
+
function sameUnsavedThread(existing, incoming, spec) {
|
|
17813
|
+
const anchor = spec.read(incoming.anchor);
|
|
17814
|
+
return !!anchor && spec.same(existing.anchor, anchor) && existing.messages[0]?.text === incoming.messages?.[0]?.text;
|
|
17815
|
+
}
|
|
17816
|
+
function mergeComments(base, incoming, origin, now, newId, name, spec = documentAnchors) {
|
|
17805
17817
|
const warnings = [];
|
|
17806
17818
|
const threads = [...base.threads];
|
|
17807
17819
|
for (const thread of incoming.threads) {
|
|
17808
|
-
const index = thread.id ? threads.findIndex((t7) => t7.id === thread.id) : threads.findIndex((t7) => sameUnsavedThread(t7, thread));
|
|
17820
|
+
const index = thread.id ? threads.findIndex((t7) => t7.id === thread.id) : threads.findIndex((t7) => sameUnsavedThread(t7, thread, spec));
|
|
17809
17821
|
if (index >= 0) {
|
|
17810
17822
|
threads[index] = mergeThread(threads[index], thread, origin, now, newId, warnings, name);
|
|
17811
17823
|
continue;
|
|
17812
17824
|
}
|
|
17813
|
-
|
|
17814
|
-
|
|
17825
|
+
const anchor = spec.read(thread.anchor);
|
|
17826
|
+
if (!anchor) {
|
|
17827
|
+
warnings.push(spec.missing);
|
|
17815
17828
|
continue;
|
|
17816
17829
|
}
|
|
17817
17830
|
const fresh = {
|
|
17818
17831
|
id: thread.id ?? newId(),
|
|
17819
|
-
anchor
|
|
17832
|
+
anchor,
|
|
17820
17833
|
status: "open",
|
|
17821
17834
|
statusAt: now,
|
|
17822
17835
|
statusBy: origin,
|
|
@@ -17834,23 +17847,15 @@ var updateHumanMessage = (thread, messageId, update2) => ({
|
|
|
17834
17847
|
...thread,
|
|
17835
17848
|
messages: thread.messages.map((m11) => m11.id === messageId && m11.author === "human" && !m11.deleted ? update2(m11) : m11)
|
|
17836
17849
|
});
|
|
17850
|
+
function openThread(anchor, author, text2, now, newId, who) {
|
|
17851
|
+
return { id: newId(), anchor, status: "open", statusAt: now, statusBy: author, messages: [{ id: newId(), author, ...personOf(who), text: text2, at: now }] };
|
|
17852
|
+
}
|
|
17837
17853
|
function applyHumanOp(file, op, now, newId, who) {
|
|
17854
|
+
if (op.op === "create") return { ...file, threads: [...file.threads, openThread({ blockId: op.blockId, quote: op.quote }, "human", op.text, now, newId, who)] };
|
|
17855
|
+
return applyThreadOp(file, op, now, newId, who);
|
|
17856
|
+
}
|
|
17857
|
+
function applyThreadOp(file, op, now, newId, who) {
|
|
17838
17858
|
switch (op.op) {
|
|
17839
|
-
case "create":
|
|
17840
|
-
return {
|
|
17841
|
-
...file,
|
|
17842
|
-
threads: [
|
|
17843
|
-
...file.threads,
|
|
17844
|
-
{
|
|
17845
|
-
id: newId(),
|
|
17846
|
-
anchor: { blockId: op.blockId, quote: op.quote },
|
|
17847
|
-
status: "open",
|
|
17848
|
-
statusAt: now,
|
|
17849
|
-
statusBy: "human",
|
|
17850
|
-
messages: [{ id: newId(), author: "human", ...personOf(who), text: op.text, at: now }]
|
|
17851
|
-
}
|
|
17852
|
-
]
|
|
17853
|
-
};
|
|
17854
17859
|
case "reply":
|
|
17855
17860
|
return updateThread(file, op.threadId, (t7) => ({ ...t7, messages: [...t7.messages, { id: newId(), author: "human", ...personOf(who), text: op.text, at: now }] }));
|
|
17856
17861
|
case "edit":
|
|
@@ -17905,7 +17910,7 @@ function unreadThreads(file, cursor) {
|
|
|
17905
17910
|
const threads = [];
|
|
17906
17911
|
let newest = cursor;
|
|
17907
17912
|
for (const thread of file.threads) {
|
|
17908
|
-
for (const
|
|
17913
|
+
for (const stamp2 of humanStamps(thread)) if (!newest || stamp2 > newest) newest = stamp2;
|
|
17909
17914
|
const unread = cursor === null ? waitingOn(thread) === "agent" ? waitingSince(thread) : null : changesSince(thread, cursor);
|
|
17910
17915
|
if (unread && unread.changes.length > 0) threads.push({ ...thread, ...unread });
|
|
17911
17916
|
}
|
|
@@ -17913,16 +17918,12 @@ function unreadThreads(file, cursor) {
|
|
|
17913
17918
|
}
|
|
17914
17919
|
function applyAgentOp(file, op, now, newId, name) {
|
|
17915
17920
|
if (op.op === "add") {
|
|
17916
|
-
const thread = {
|
|
17917
|
-
id: newId(),
|
|
17918
|
-
anchor: { blockId: op.blockId, quote: op.quote },
|
|
17919
|
-
status: "open",
|
|
17920
|
-
statusAt: now,
|
|
17921
|
-
statusBy: "agent",
|
|
17922
|
-
messages: [{ id: newId(), author: "agent", ...personOf({ name }), text: op.text, at: now }]
|
|
17923
|
-
};
|
|
17921
|
+
const thread = openThread({ blockId: op.blockId, quote: op.quote }, "agent", op.text, now, newId, { name });
|
|
17924
17922
|
return { file: { ...file, threads: [...file.threads, thread] }, threadId: thread.id, messageId: thread.messages[0].id };
|
|
17925
17923
|
}
|
|
17924
|
+
return applyAgentThreadOp(file, op, now, newId, name);
|
|
17925
|
+
}
|
|
17926
|
+
function applyAgentThreadOp(file, op, now, newId, name) {
|
|
17926
17927
|
if (!file.threads.some((t7) => t7.id === op.threadId)) throw new Error(`no thread ${op.threadId}`);
|
|
17927
17928
|
if (op.op === "resolve") {
|
|
17928
17929
|
return { file: updateThread(file, op.threadId, (t7) => ({ ...t7, status: "resolved", statusAt: now, statusBy: "agent" })), threadId: op.threadId };
|
|
@@ -17931,6 +17932,76 @@ function applyAgentOp(file, op, now, newId, name) {
|
|
|
17931
17932
|
return { file: updateThread(file, op.threadId, (t7) => ({ ...t7, messages: [...t7.messages, message] })), threadId: op.threadId, messageId: message.id };
|
|
17932
17933
|
}
|
|
17933
17934
|
|
|
17935
|
+
// src/shared/board-comments.ts
|
|
17936
|
+
var MAX_ID = 100;
|
|
17937
|
+
var MAX_PATH = 2e3;
|
|
17938
|
+
var MAX_NODES = 50;
|
|
17939
|
+
var isName = (value, max = MAX_ID) => typeof value === "string" && value.length > 0 && value.length <= max;
|
|
17940
|
+
var isFiniteNumber = (value) => typeof value === "number" && Number.isFinite(value);
|
|
17941
|
+
var isFraction = (value) => isFiniteNumber(value) && value >= 0 && value <= 1;
|
|
17942
|
+
function readNodes(value) {
|
|
17943
|
+
if (!Array.isArray(value) || value.length === 0 || value.length > MAX_NODES) return null;
|
|
17944
|
+
const nodes = [];
|
|
17945
|
+
for (const node of value) {
|
|
17946
|
+
if (!isObject(node) || !isName(node.board) || !isName(node.path, MAX_PATH)) return null;
|
|
17947
|
+
nodes.push({ board: node.board, path: node.path });
|
|
17948
|
+
}
|
|
17949
|
+
return nodes;
|
|
17950
|
+
}
|
|
17951
|
+
function readHashes(value) {
|
|
17952
|
+
if (!isObject(value) || Array.isArray(value)) return null;
|
|
17953
|
+
const entries2 = Object.entries(value);
|
|
17954
|
+
if (entries2.length > MAX_NODES || !entries2.every(([board, hash]) => isName(board) && isName(hash))) return null;
|
|
17955
|
+
return Object.fromEntries(entries2);
|
|
17956
|
+
}
|
|
17957
|
+
function readBoardAnchor(value) {
|
|
17958
|
+
if (!isObject(value) || !isName(value.page) || !isFiniteNumber(value.x) || !isFiniteNumber(value.y)) return null;
|
|
17959
|
+
const anchor = { page: value.page, x: value.x, y: value.y };
|
|
17960
|
+
if (value.board !== void 0) {
|
|
17961
|
+
if (!isName(value.board)) return null;
|
|
17962
|
+
anchor.board = value.board;
|
|
17963
|
+
}
|
|
17964
|
+
if (value.nodes !== void 0) {
|
|
17965
|
+
const nodes = readNodes(value.nodes);
|
|
17966
|
+
if (!nodes) return null;
|
|
17967
|
+
anchor.nodes = nodes;
|
|
17968
|
+
}
|
|
17969
|
+
if (value.offset !== void 0) {
|
|
17970
|
+
const offset = value.offset;
|
|
17971
|
+
if (!anchor.nodes || !isObject(offset) || !isFraction(offset.x) || !isFraction(offset.y)) return null;
|
|
17972
|
+
anchor.offset = { x: offset.x, y: offset.y };
|
|
17973
|
+
}
|
|
17974
|
+
if (value.hashes !== void 0) {
|
|
17975
|
+
const hashes = readHashes(value.hashes);
|
|
17976
|
+
if (!hashes) return null;
|
|
17977
|
+
anchor.hashes = hashes;
|
|
17978
|
+
}
|
|
17979
|
+
return anchor;
|
|
17980
|
+
}
|
|
17981
|
+
var boardAnchors = {
|
|
17982
|
+
read: readBoardAnchor,
|
|
17983
|
+
same: (a5, b6) => a5.page === b6.page && a5.board === b6.board && a5.x === b6.x && a5.y === b6.y,
|
|
17984
|
+
missing: "a new thread needs a board anchor (page, x, y); dropped it"
|
|
17985
|
+
};
|
|
17986
|
+
var emptyBoardComments = () => ({ version: 1, threads: [] });
|
|
17987
|
+
var savedBoardComments = (incoming) => savedComments(incoming, boardAnchors);
|
|
17988
|
+
var mergeBoardComments = (base, incoming, origin, now, newId, name) => mergeComments(base, incoming, origin, now, newId, name, boardAnchors);
|
|
17989
|
+
function applyBoardHumanOp(file, op, now, newId, who) {
|
|
17990
|
+
if (op.op === "create") return { ...file, threads: [...file.threads, openThread(op.anchor, "human", op.text, now, newId, who)] };
|
|
17991
|
+
return applyThreadOp(file, op, now, newId, who);
|
|
17992
|
+
}
|
|
17993
|
+
function applyBoardAgentOp(file, op, now, newId, name) {
|
|
17994
|
+
if (op.op === "add") {
|
|
17995
|
+
const thread = openThread(op.anchor, "agent", op.text, now, newId, { name });
|
|
17996
|
+
return { file: { ...file, threads: [...file.threads, thread] }, threadId: thread.id, messageId: thread.messages[0].id };
|
|
17997
|
+
}
|
|
17998
|
+
return applyAgentThreadOp(file, op, now, newId, name);
|
|
17999
|
+
}
|
|
18000
|
+
|
|
18001
|
+
// src/server/comment-cursors.ts
|
|
18002
|
+
var import_node_fs6 = __toESM(require("node:fs"), 1);
|
|
18003
|
+
var import_node_path6 = __toESM(require("node:path"), 1);
|
|
18004
|
+
|
|
17934
18005
|
// src/server/state.ts
|
|
17935
18006
|
var import_node_fs5 = __toESM(require("node:fs"), 1);
|
|
17936
18007
|
var import_node_path5 = __toESM(require("node:path"), 1);
|
|
@@ -18207,7 +18278,9 @@ function readRaw(boardDir) {
|
|
|
18207
18278
|
}
|
|
18208
18279
|
function boardVersions(boardDir, canvas) {
|
|
18209
18280
|
const versions = {};
|
|
18210
|
-
|
|
18281
|
+
let writing;
|
|
18282
|
+
let latestWrite = -Infinity;
|
|
18283
|
+
for (const [id2, board] of Object.entries(canvas.boards)) {
|
|
18211
18284
|
const target = resolveBoardFile(boardDir, board.file);
|
|
18212
18285
|
if (!target) {
|
|
18213
18286
|
versions[board.file] = 0;
|
|
@@ -18215,12 +18288,19 @@ function boardVersions(boardDir, canvas) {
|
|
|
18215
18288
|
}
|
|
18216
18289
|
try {
|
|
18217
18290
|
const stat = import_node_fs5.default.statSync(target);
|
|
18218
|
-
|
|
18291
|
+
const html = import_node_fs5.default.readFileSync(target, "utf8");
|
|
18292
|
+
const document2 = /<(?:!doctype|html)\b/i.test(html);
|
|
18293
|
+
const ready = html.trim().length > 0 && (!document2 || /<\/html>\s*(?:<!--[\s\S]*?-->\s*)*$/i.test(html));
|
|
18294
|
+
versions[board.file] = ready ? stat.mtimeMs : 0;
|
|
18295
|
+
if (!ready && stat.mtimeMs >= latestWrite) {
|
|
18296
|
+
writing = id2;
|
|
18297
|
+
latestWrite = stat.mtimeMs;
|
|
18298
|
+
}
|
|
18219
18299
|
} catch {
|
|
18220
18300
|
versions[board.file] = 0;
|
|
18221
18301
|
}
|
|
18222
18302
|
}
|
|
18223
|
-
return versions;
|
|
18303
|
+
return { versions, writing };
|
|
18224
18304
|
}
|
|
18225
18305
|
function readCanvas(boardDir) {
|
|
18226
18306
|
const { raw, warning } = readRaw(boardDir);
|
|
@@ -18228,16 +18308,19 @@ function readCanvas(boardDir) {
|
|
|
18228
18308
|
try {
|
|
18229
18309
|
const structural = structuralWarnings(raw);
|
|
18230
18310
|
if (structural.length > 0) return { canvas: null, warnings: structural, pending: [], layout: null, versions: {} };
|
|
18231
|
-
const canvas = raw;
|
|
18311
|
+
const canvas = { ...raw };
|
|
18312
|
+
const { versions, writing } = boardVersions(boardDir, canvas);
|
|
18232
18313
|
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
18314
|
for (const [id2, board] of Object.entries(canvas.boards)) {
|
|
18239
18315
|
if (!versions[board.file]) pending.add(id2);
|
|
18240
18316
|
}
|
|
18317
|
+
canvas.building = pending.size > 0;
|
|
18318
|
+
delete canvas.writing;
|
|
18319
|
+
if (writing) canvas.writing = writing;
|
|
18320
|
+
const warnings = validateCanvas(canvas, (rel) => resolveBoardFile(boardDir, rel) !== null, {
|
|
18321
|
+
pending,
|
|
18322
|
+
allowPending: true
|
|
18323
|
+
});
|
|
18241
18324
|
return { canvas, warnings, pending: [...pending].sort(), layout: computeLayout(canvas), versions };
|
|
18242
18325
|
} catch (err) {
|
|
18243
18326
|
return {
|
|
@@ -18270,7 +18353,31 @@ function writeArtifactState(stateDir, ref, payload, extra = {}) {
|
|
|
18270
18353
|
});
|
|
18271
18354
|
}
|
|
18272
18355
|
|
|
18356
|
+
// src/server/comment-cursors.ts
|
|
18357
|
+
var cursorsFile = (stateDir, id2, type = "document") => import_node_path6.default.join(stateDir, type, id2, "comment-cursors.json");
|
|
18358
|
+
function read(file) {
|
|
18359
|
+
try {
|
|
18360
|
+
const value = JSON.parse(import_node_fs6.default.readFileSync(file, "utf8"));
|
|
18361
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return {};
|
|
18362
|
+
return Object.fromEntries(Object.entries(value).filter((entry) => typeof entry[1] === "string"));
|
|
18363
|
+
} catch {
|
|
18364
|
+
return {};
|
|
18365
|
+
}
|
|
18366
|
+
}
|
|
18367
|
+
function createCommentCursors(stateDir, type = "document") {
|
|
18368
|
+
return {
|
|
18369
|
+
get: (id2, agent) => read(cursorsFile(stateDir, id2, type))[agent] ?? null,
|
|
18370
|
+
set: (id2, agent, stamp2) => {
|
|
18371
|
+
const file = cursorsFile(stateDir, id2, type);
|
|
18372
|
+
const all = read(file);
|
|
18373
|
+
if (all[agent] === stamp2) return;
|
|
18374
|
+
writeJsonAtomic(file, { ...all, [agent]: stamp2 });
|
|
18375
|
+
}
|
|
18376
|
+
};
|
|
18377
|
+
}
|
|
18378
|
+
|
|
18273
18379
|
// src/server/document-comments.ts
|
|
18380
|
+
var import_node_fs7 = __toESM(require("node:fs"), 1);
|
|
18274
18381
|
var MAX_TEXT = 2e4;
|
|
18275
18382
|
var isText3 = (value, max = MAX_TEXT) => typeof value === "string" && value.length <= max;
|
|
18276
18383
|
var isId = (value) => isText3(value, 100) && value.length > 0;
|
|
@@ -18307,20 +18414,30 @@ function asAgentOp(value) {
|
|
|
18307
18414
|
return null;
|
|
18308
18415
|
}
|
|
18309
18416
|
}
|
|
18417
|
+
var documentRules = {
|
|
18418
|
+
empty: emptyComments,
|
|
18419
|
+
saved: savedComments,
|
|
18420
|
+
merge: mergeComments,
|
|
18421
|
+
human: applyHumanOp,
|
|
18422
|
+
agent: applyAgentOp
|
|
18423
|
+
};
|
|
18310
18424
|
var noNames = { human: () => void 0, agent: () => void 0 };
|
|
18311
18425
|
function createCommentStore(file, names = noNames, now = () => (/* @__PURE__ */ new Date()).toISOString(), newId = () => nanoid2(10)) {
|
|
18312
|
-
|
|
18426
|
+
return createStore(file, documentRules, names, now, newId);
|
|
18427
|
+
}
|
|
18428
|
+
function createStore(file, rules, names = noNames, now = () => (/* @__PURE__ */ new Date()).toISOString(), newId = () => nanoid2(10)) {
|
|
18429
|
+
let current = rules.empty();
|
|
18313
18430
|
let lastSeen = null;
|
|
18314
18431
|
let warnings = [];
|
|
18315
18432
|
let loaded = false;
|
|
18316
18433
|
const write = () => {
|
|
18317
18434
|
writeJsonAtomic(file, current);
|
|
18318
|
-
lastSeen =
|
|
18435
|
+
lastSeen = import_node_fs7.default.readFileSync(file, "utf8");
|
|
18319
18436
|
};
|
|
18320
18437
|
const sync = () => {
|
|
18321
18438
|
let text2;
|
|
18322
18439
|
try {
|
|
18323
|
-
text2 =
|
|
18440
|
+
text2 = import_node_fs7.default.readFileSync(file, "utf8");
|
|
18324
18441
|
} catch {
|
|
18325
18442
|
return false;
|
|
18326
18443
|
}
|
|
@@ -18328,8 +18445,8 @@ function createCommentStore(file, names = noNames, now = () => (/* @__PURE__ */
|
|
|
18328
18445
|
lastSeen = text2;
|
|
18329
18446
|
try {
|
|
18330
18447
|
const incoming = parseComments(text2);
|
|
18331
|
-
const base = loaded ? current :
|
|
18332
|
-
const merged =
|
|
18448
|
+
const base = loaded ? current : rules.saved(incoming);
|
|
18449
|
+
const merged = rules.merge(base, incoming, "agent", now(), newId, names.agent());
|
|
18333
18450
|
current = merged.file;
|
|
18334
18451
|
warnings = merged.warnings;
|
|
18335
18452
|
if (`${JSON.stringify(current, null, 2)}
|
|
@@ -18347,13 +18464,13 @@ function createCommentStore(file, names = noNames, now = () => (/* @__PURE__ */
|
|
|
18347
18464
|
sync,
|
|
18348
18465
|
apply: (op) => {
|
|
18349
18466
|
sync();
|
|
18350
|
-
current =
|
|
18467
|
+
current = rules.human(current, op, now(), newId, names.human());
|
|
18351
18468
|
write();
|
|
18352
18469
|
return current;
|
|
18353
18470
|
},
|
|
18354
18471
|
applyAgent: (op, name) => {
|
|
18355
18472
|
sync();
|
|
18356
|
-
const result =
|
|
18473
|
+
const result = rules.agent(current, op, now(), newId, name ?? names.agent());
|
|
18357
18474
|
current = result.file;
|
|
18358
18475
|
write();
|
|
18359
18476
|
return result;
|
|
@@ -18361,38 +18478,166 @@ function createCommentStore(file, names = noNames, now = () => (/* @__PURE__ */
|
|
|
18361
18478
|
};
|
|
18362
18479
|
}
|
|
18363
18480
|
|
|
18364
|
-
// src/server/
|
|
18365
|
-
var
|
|
18366
|
-
|
|
18367
|
-
|
|
18368
|
-
|
|
18369
|
-
|
|
18370
|
-
|
|
18371
|
-
|
|
18372
|
-
|
|
18481
|
+
// src/server/board-comments.ts
|
|
18482
|
+
var boardRules = {
|
|
18483
|
+
empty: emptyBoardComments,
|
|
18484
|
+
saved: savedBoardComments,
|
|
18485
|
+
merge: mergeBoardComments,
|
|
18486
|
+
human: (file, op, now, newId, who) => applyBoardHumanOp(file, op, now, newId, who),
|
|
18487
|
+
agent: applyBoardAgentOp
|
|
18488
|
+
};
|
|
18489
|
+
var withoutHashes = ({ hashes: _hashes, ...anchor }) => anchor;
|
|
18490
|
+
function asBoardHumanOp(value) {
|
|
18491
|
+
if (typeof value !== "object" || value === null) return null;
|
|
18492
|
+
const v6 = value;
|
|
18493
|
+
if (v6.op !== "create") {
|
|
18494
|
+
const op = asHumanOp(value);
|
|
18495
|
+
return op && op.op !== "create" ? op : null;
|
|
18496
|
+
}
|
|
18497
|
+
const anchor = readBoardAnchor(v6.anchor);
|
|
18498
|
+
return anchor && isText3(v6.text) && v6.text.length > 0 ? { op: "create", anchor: withoutHashes(anchor), text: v6.text } : null;
|
|
18499
|
+
}
|
|
18500
|
+
function asBoardAgentOp(value) {
|
|
18501
|
+
if (typeof value !== "object" || value === null) return null;
|
|
18502
|
+
const v6 = value;
|
|
18503
|
+
if (v6.op === "add") {
|
|
18504
|
+
const anchor = readBoardAnchor(v6.anchor);
|
|
18505
|
+
return anchor && isText3(v6.text) && v6.text.length > 0 ? { op: "add", anchor: withoutHashes(anchor), text: v6.text } : null;
|
|
18506
|
+
}
|
|
18507
|
+
if (v6.op === "reply") return isId(v6.threadId) && isText3(v6.text) && v6.text.length > 0 ? { op: "reply", threadId: v6.threadId, text: v6.text } : null;
|
|
18508
|
+
if (v6.op === "resolve") return isId(v6.threadId) ? { op: "resolve", threadId: v6.threadId } : null;
|
|
18509
|
+
return null;
|
|
18510
|
+
}
|
|
18511
|
+
function boardSpecs(dir) {
|
|
18373
18512
|
try {
|
|
18374
|
-
const
|
|
18375
|
-
|
|
18376
|
-
|
|
18513
|
+
const canvas = JSON.parse(import_node_fs8.default.readFileSync(import_node_path7.default.join(dir, "canvas.json"), "utf8"));
|
|
18514
|
+
return Object.fromEntries(Object.entries(canvas.boards ?? {}).flatMap(
|
|
18515
|
+
([id2, board]) => typeof board?.file === "string" ? [[id2, { file: board.file, page: typeof board.page === "string" ? board.page : "", w: typeof board.w === "number" ? board.w : 0 }]] : []
|
|
18516
|
+
));
|
|
18377
18517
|
} catch {
|
|
18378
18518
|
return {};
|
|
18379
18519
|
}
|
|
18380
18520
|
}
|
|
18381
|
-
|
|
18521
|
+
var boardFiles = (dir) => Object.fromEntries(Object.entries(boardSpecs(dir)).map(([id2, spec]) => [id2, spec.file]));
|
|
18522
|
+
function agentAddOnBoard(value, specs) {
|
|
18523
|
+
if (typeof value !== "object" || value === null) return null;
|
|
18524
|
+
const v6 = value;
|
|
18525
|
+
if (v6.op !== "add" || typeof v6.board !== "string" || v6.anchor !== void 0) return null;
|
|
18526
|
+
const spec = specs[v6.board];
|
|
18527
|
+
if (!spec) return { error: `no board ${v6.board}` };
|
|
18528
|
+
return asBoardAgentOp({ op: "add", anchor: { page: spec.page, board: v6.board, x: v6.x ?? spec.w, y: v6.y ?? 0 }, text: v6.text });
|
|
18529
|
+
}
|
|
18530
|
+
function fileHash(dir, relative) {
|
|
18531
|
+
const file = resolveBoardFile(dir, relative);
|
|
18532
|
+
if (!file) return null;
|
|
18533
|
+
try {
|
|
18534
|
+
return import_node_crypto2.default.createHash("sha1").update(import_node_fs8.default.readFileSync(file)).digest("hex").slice(0, 12);
|
|
18535
|
+
} catch {
|
|
18536
|
+
return null;
|
|
18537
|
+
}
|
|
18538
|
+
}
|
|
18539
|
+
function boardHashes(dir) {
|
|
18540
|
+
return Object.fromEntries(Object.entries(boardFiles(dir)).flatMap(([id2, file]) => {
|
|
18541
|
+
const hash = fileHash(dir, file);
|
|
18542
|
+
return hash ? [[id2, hash]] : [];
|
|
18543
|
+
}));
|
|
18544
|
+
}
|
|
18545
|
+
var boardsOf = (anchor) => [.../* @__PURE__ */ new Set([...anchor.board ? [anchor.board] : [], ...(anchor.nodes ?? []).map((node) => node.board)])];
|
|
18546
|
+
function stamp(anchor, hashes) {
|
|
18547
|
+
const boards = boardsOf(anchor);
|
|
18548
|
+
if (!boards.length) return withoutHashes(anchor);
|
|
18549
|
+
return { ...withoutHashes(anchor), hashes: Object.fromEntries(boards.map((board) => [board, hashes[board] ?? "missing"])) };
|
|
18550
|
+
}
|
|
18551
|
+
var isStale = (thread, hashes) => Object.entries(thread.anchor.hashes ?? {}).some(([board, hash]) => hashes[board] !== hash);
|
|
18552
|
+
function createBoardCommentRegistry(options) {
|
|
18553
|
+
const stores = /* @__PURE__ */ new Map();
|
|
18554
|
+
const hashes = /* @__PURE__ */ new Map();
|
|
18555
|
+
const lastStale = /* @__PURE__ */ new Map();
|
|
18556
|
+
const cursors = createCommentCursors(options.stateDir, "artboard");
|
|
18557
|
+
const dirOf = (id2) => import_node_path7.default.join(options.root, "artboard", id2);
|
|
18558
|
+
const store = (id2) => {
|
|
18559
|
+
let found = stores.get(id2);
|
|
18560
|
+
if (!found) {
|
|
18561
|
+
found = createStore(import_node_path7.default.join(dirOf(id2), "comments.json"), boardRules, options.names);
|
|
18562
|
+
stores.set(id2, found);
|
|
18563
|
+
}
|
|
18564
|
+
return found;
|
|
18565
|
+
};
|
|
18566
|
+
const currentHashes = (id2) => {
|
|
18567
|
+
let found = hashes.get(id2);
|
|
18568
|
+
if (!found) {
|
|
18569
|
+
found = boardHashes(dirOf(id2));
|
|
18570
|
+
hashes.set(id2, found);
|
|
18571
|
+
}
|
|
18572
|
+
return found;
|
|
18573
|
+
};
|
|
18574
|
+
const stale = (id2) => {
|
|
18575
|
+
const now = currentHashes(id2);
|
|
18576
|
+
return store(id2).current().threads.filter((thread) => isStale(thread, now)).map((thread) => thread.id);
|
|
18577
|
+
};
|
|
18578
|
+
const push2 = (id2) => {
|
|
18579
|
+
const ids = stale(id2);
|
|
18580
|
+
lastStale.set(id2, JSON.stringify(ids));
|
|
18581
|
+
options.broadcast({ type: "board-comments", artifact: `artboard/${id2}`, comments: store(id2).current(), stale: ids });
|
|
18582
|
+
};
|
|
18583
|
+
const fresh = (id2) => {
|
|
18584
|
+
hashes.delete(id2);
|
|
18585
|
+
return currentHashes(id2);
|
|
18586
|
+
};
|
|
18587
|
+
const forAgent2 = (id2, staleIds) => {
|
|
18588
|
+
const files = boardFiles(dirOf(id2));
|
|
18589
|
+
return (thread) => ({
|
|
18590
|
+
...thread,
|
|
18591
|
+
stale: staleIds.has(thread.id),
|
|
18592
|
+
waitingOn: waitingOn(thread),
|
|
18593
|
+
files: Object.fromEntries(boardsOf(thread.anchor).flatMap((board) => files[board] ? [[board, files[board]]] : [])),
|
|
18594
|
+
messages: thread.messages.map(({ avatar: _avatar, ...message }) => message)
|
|
18595
|
+
});
|
|
18596
|
+
};
|
|
18382
18597
|
return {
|
|
18383
|
-
|
|
18384
|
-
|
|
18385
|
-
|
|
18386
|
-
|
|
18387
|
-
|
|
18388
|
-
|
|
18598
|
+
comments: (id2) => store(id2).current(),
|
|
18599
|
+
stale,
|
|
18600
|
+
warnings: (id2) => store(id2).warnings(),
|
|
18601
|
+
apply: (id2, op) => {
|
|
18602
|
+
const stamped = op.op === "create" ? { ...op, anchor: stamp(op.anchor, fresh(id2)) } : op;
|
|
18603
|
+
store(id2).apply(stamped);
|
|
18604
|
+
push2(id2);
|
|
18605
|
+
return { comments: store(id2).current(), stale: stale(id2) };
|
|
18606
|
+
},
|
|
18607
|
+
applyAgent: (id2, op, agent) => {
|
|
18608
|
+
const stamped = op.op === "add" ? { ...op, anchor: stamp(op.anchor, fresh(id2)) } : op;
|
|
18609
|
+
const { threadId, messageId } = store(id2).applyAgent(stamped, agent);
|
|
18610
|
+
push2(id2);
|
|
18611
|
+
return { threadId, ...messageId ? { messageId } : {} };
|
|
18612
|
+
},
|
|
18613
|
+
list: (id2, agent, all) => {
|
|
18614
|
+
const changed = store(id2).sync();
|
|
18615
|
+
if (changed) push2(id2);
|
|
18616
|
+
const file = store(id2).current();
|
|
18617
|
+
const format = forAgent2(id2, new Set(stale(id2)));
|
|
18618
|
+
if (all) return file.threads.filter((t7) => !t7.messages.every((m11) => m11.deleted)).map(format);
|
|
18619
|
+
const { threads, newest } = unreadThreads(file, cursors.get(id2, agent));
|
|
18620
|
+
if (newest) cursors.set(id2, agent, newest);
|
|
18621
|
+
return threads.map(format);
|
|
18622
|
+
},
|
|
18623
|
+
sync: (id2) => {
|
|
18624
|
+
if (store(id2).sync()) push2(id2);
|
|
18625
|
+
},
|
|
18626
|
+
boardsChanged: (id2) => {
|
|
18627
|
+
fresh(id2);
|
|
18628
|
+
if (!stores.has(id2) && !import_node_fs8.default.existsSync(import_node_path7.default.join(dirOf(id2), "comments.json"))) return;
|
|
18629
|
+
if (JSON.stringify(stale(id2)) !== (lastStale.get(id2) ?? "[]")) push2(id2);
|
|
18389
18630
|
}
|
|
18390
18631
|
};
|
|
18391
18632
|
}
|
|
18392
18633
|
|
|
18634
|
+
// src/server/documents.ts
|
|
18635
|
+
var import_node_fs9 = __toESM(require("node:fs"), 1);
|
|
18636
|
+
var import_node_path9 = __toESM(require("node:path"), 1);
|
|
18637
|
+
|
|
18393
18638
|
// src/server/document-session.ts
|
|
18394
18639
|
var import_promises = __toESM(require("node:fs/promises"), 1);
|
|
18395
|
-
var
|
|
18640
|
+
var import_node_path8 = __toESM(require("node:path"), 1);
|
|
18396
18641
|
|
|
18397
18642
|
// node_modules/.pnpm/lexical@0.52.0_typescript@5.9.3/node_modules/lexical/dist/Lexical.dev.js
|
|
18398
18643
|
var Lexical_dev_exports = {};
|
|
@@ -19250,19 +19495,19 @@ var ElementDOMSlot = class _ElementDOMSlot extends DOMSlot {
|
|
|
19250
19495
|
}
|
|
19251
19496
|
};
|
|
19252
19497
|
function indexPath(root, child) {
|
|
19253
|
-
const
|
|
19498
|
+
const path22 = [];
|
|
19254
19499
|
let node = child;
|
|
19255
19500
|
for (; node !== root && node !== null; node = node.parentNode) {
|
|
19256
19501
|
let i6 = 0;
|
|
19257
19502
|
for (let sibling = node.previousSibling; sibling !== null; sibling = sibling.previousSibling) {
|
|
19258
19503
|
i6++;
|
|
19259
19504
|
}
|
|
19260
|
-
|
|
19505
|
+
path22.push(i6);
|
|
19261
19506
|
}
|
|
19262
19507
|
if (!(node === root)) {
|
|
19263
19508
|
formatDevErrorMessage(`indexPath: root is not a parent of child`);
|
|
19264
19509
|
}
|
|
19265
|
-
return
|
|
19510
|
+
return path22.reverse();
|
|
19266
19511
|
}
|
|
19267
19512
|
// @__NO_SIDE_EFFECTS__
|
|
19268
19513
|
function readLexicalVersion() {
|
|
@@ -34042,9 +34287,9 @@ function getActiveElementDeep(root) {
|
|
|
34042
34287
|
function getComposedEventTarget(event) {
|
|
34043
34288
|
const target = event.target;
|
|
34044
34289
|
if (target !== null && isHTMLElement(target) && target.shadowRoot !== null && typeof event.composedPath === "function") {
|
|
34045
|
-
const
|
|
34046
|
-
if (
|
|
34047
|
-
return
|
|
34290
|
+
const path22 = event.composedPath();
|
|
34291
|
+
if (path22.length > 0) {
|
|
34292
|
+
return path22[0];
|
|
34048
34293
|
}
|
|
34049
34294
|
}
|
|
34050
34295
|
return target;
|
|
@@ -35955,7 +36200,7 @@ __export(Lexical_prod_exports, {
|
|
|
35955
36200
|
$getNodeFromDOMNode: () => Qc,
|
|
35956
36201
|
$getPreviousSelection: () => ds,
|
|
35957
36202
|
$getRoot: () => ra,
|
|
35958
|
-
$getSelection: () =>
|
|
36203
|
+
$getSelection: () => fs9,
|
|
35959
36204
|
$getSelectionSlotFrame: () => Df,
|
|
35960
36205
|
$getSiblingCaret: () => ad,
|
|
35961
36206
|
$getSlot: () => Lf,
|
|
@@ -36695,9 +36940,9 @@ function Ct(t7, e5, n7) {
|
|
|
36695
36940
|
const o8 = performance.now() - _t > 100;
|
|
36696
36941
|
try {
|
|
36697
36942
|
al(t7, () => {
|
|
36698
|
-
const r7 =
|
|
36943
|
+
const r7 = fs9() || (function(t8) {
|
|
36699
36944
|
return t8.read("latest", () => {
|
|
36700
|
-
const t9 =
|
|
36945
|
+
const t9 = fs9();
|
|
36701
36946
|
return null !== t9 ? t9.clone() : null;
|
|
36702
36947
|
});
|
|
36703
36948
|
})(t7), i6 = /* @__PURE__ */ new Map(), s7 = t7._editorState, l8 = t7._blockCursorElement;
|
|
@@ -37977,7 +38222,7 @@ function Yo(t7, n7, o8) {
|
|
|
37977
38222
|
al(n7, () => {
|
|
37978
38223
|
if (!o8) return void sa(null);
|
|
37979
38224
|
if (!Dc(n7, r7, s7)) return;
|
|
37980
|
-
let a5 =
|
|
38225
|
+
let a5 = fs9();
|
|
37981
38226
|
if (c10.postDeleteSelectionToRestore && zi(a5) && a5.isCollapsed()) {
|
|
37982
38227
|
const t8 = a5.anchor, e5 = c10.postDeleteSelectionToRestore.anchor;
|
|
37983
38228
|
(t8.key === e5.key && t8.offset === e5.offset + 1 || 1 === t8.offset && e5.getNode().is(t8.getNode().getPreviousSibling())) && (a5 = c10.postDeleteSelectionToRestore.clone(), sa(a5));
|
|
@@ -38019,7 +38264,7 @@ function Xo(t7, e5) {
|
|
|
38019
38264
|
}
|
|
38020
38265
|
function Qo(t7, e5) {
|
|
38021
38266
|
al(e5, () => {
|
|
38022
|
-
const n7 =
|
|
38267
|
+
const n7 = fs9(), o8 = Qa(Wa(e5)), r7 = ds();
|
|
38023
38268
|
if (o8) {
|
|
38024
38269
|
if (zi(n7)) {
|
|
38025
38270
|
const t8 = n7.anchor, e6 = t8.getNode();
|
|
@@ -38068,7 +38313,7 @@ function er(t7) {
|
|
|
38068
38313
|
if (null == t7 || t7.length <= 1 || null == e5) return;
|
|
38069
38314
|
const n7 = 1 === e5.length ? e5 : "Enter" === e5 ? "\n" : "Tab" === e5 ? " " : null;
|
|
38070
38315
|
if (!n7) return;
|
|
38071
|
-
const o8 =
|
|
38316
|
+
const o8 = fs9();
|
|
38072
38317
|
if (!zi(o8) || !o8.isCollapsed()) return;
|
|
38073
38318
|
const r7 = o8.anchor.getNode();
|
|
38074
38319
|
if (!ki(r7)) return;
|
|
@@ -38100,7 +38345,7 @@ function rr(t7, e5) {
|
|
|
38100
38345
|
return null !== r7 && o8.contains(r7) && Ju(r7, e5);
|
|
38101
38346
|
}
|
|
38102
38347
|
function ir(t7) {
|
|
38103
|
-
const n7 = t7.inputType, o8 = tr(t7), r7 = Vs(), i6 = r7._inputState, s7 =
|
|
38348
|
+
const n7 = t7.inputType, o8 = tr(t7), r7 = Vs(), i6 = r7._inputState, s7 = fs9();
|
|
38104
38349
|
if ("insertText" === n7 && t7.data && i6.isInsertTextAfterHandledSelectionCommand) {
|
|
38105
38350
|
if (nr(i6), t7.preventDefault(), zi(s7) && !s7.isCollapsed()) {
|
|
38106
38351
|
const t8 = s7.isBackward() ? s7.anchor : s7.focus;
|
|
@@ -38134,7 +38379,7 @@ function ir(t7) {
|
|
|
38134
38379
|
let u9 = m && n8 && !a6 && c11;
|
|
38135
38380
|
if (u9 && s7.isCollapsed() && (u9 = !Sl(Ea(s7.anchor, true))), !u9) {
|
|
38136
38381
|
Ma(r7, jn, true);
|
|
38137
|
-
const t8 =
|
|
38382
|
+
const t8 = fs9();
|
|
38138
38383
|
m && zi(t8) && t8.isCollapsed() && (i6.postDeleteSelectionToRestore = t8, setTimeout(() => i6.postDeleteSelectionToRestore = null));
|
|
38139
38384
|
}
|
|
38140
38385
|
}
|
|
@@ -38234,7 +38479,7 @@ function sr(t7, e5) {
|
|
|
38234
38479
|
}, { event: t7 }), n7.unprocessedBeforeInputData = null;
|
|
38235
38480
|
}
|
|
38236
38481
|
function lr(t7) {
|
|
38237
|
-
const e5 = Vs(), n7 = e5._inputState, o8 =
|
|
38482
|
+
const e5 = Vs(), n7 = e5._inputState, o8 = fs9(), r7 = t7.data, i6 = tr(t7);
|
|
38238
38483
|
let s7 = false;
|
|
38239
38484
|
if (null != r7 && zi(o8)) {
|
|
38240
38485
|
const l8 = Qa(Wa(e5)), c10 = null !== l8 ? cu(l8, e5._rootElement) : null, a5 = "insertCompositionText" === t7.inputType && "ending-firefox" !== n7.compositionPhase && !e5.isComposing();
|
|
@@ -38259,13 +38504,13 @@ function cr(t7, e5) {
|
|
|
38259
38504
|
Ma(e5, Wn, t7);
|
|
38260
38505
|
}
|
|
38261
38506
|
function ar(t7) {
|
|
38262
|
-
const e5 = Vs(), n7 = e5._inputState, o8 =
|
|
38507
|
+
const e5 = Vs(), n7 = e5._inputState, o8 = fs9();
|
|
38263
38508
|
if (zi(o8) && !e5.isComposing()) {
|
|
38264
38509
|
n7.compositionPhase = "composing", n7.hadOrphanedCompositionEvents = false;
|
|
38265
38510
|
const r7 = o8.anchor, i6 = o8.anchor.getNode();
|
|
38266
38511
|
if (Yc(r7.key), za(Ur), t7.timeStamp < n7.lastKeyDownTimeStamp + 30 || "element" === r7.type || !o8.isCollapsed() || !m && (i6.getFormat() !== o8.format || ki(i6) && i6.getStyle() !== o8.style) || ki(i6) && (Bc(i6) || 0 === r7.offset && !i6.canInsertTextBefore() || r7.offset === i6.getTextContentSize() && !i6.canInsertTextAfter())) {
|
|
38267
38512
|
Ma(e5, Jn, F);
|
|
38268
|
-
const t8 =
|
|
38513
|
+
const t8 = fs9();
|
|
38269
38514
|
zi(t8) && Yc(t8.anchor.key);
|
|
38270
38515
|
}
|
|
38271
38516
|
}
|
|
@@ -38279,7 +38524,7 @@ function fr(t7) {
|
|
|
38279
38524
|
if (null === t7) return;
|
|
38280
38525
|
const e5 = Xc(t7);
|
|
38281
38526
|
if (!ki(e5) || "text" === e5.getType() || Bc(e5) || !e5.isAttached()) return;
|
|
38282
|
-
const n7 =
|
|
38527
|
+
const n7 = fs9(), o8 = zi(n7) && n7.anchor.key === t7 ? n7.anchor.offset : null, r7 = vi(e5.getTextContent());
|
|
38283
38528
|
if (r7.setFormat(e5.getFormat()), r7.setStyle(e5.getStyle()), e5.replace(r7), null !== o8) {
|
|
38284
38529
|
const t8 = Math.min(o8, r7.getTextContentSize());
|
|
38285
38530
|
r7.select(t8, t8);
|
|
@@ -38298,7 +38543,7 @@ function dr(t7, e5) {
|
|
|
38298
38543
|
return fr(n7), false;
|
|
38299
38544
|
}
|
|
38300
38545
|
if ("\n" === e5[e5.length - 1]) {
|
|
38301
|
-
const e6 =
|
|
38546
|
+
const e6 = fs9();
|
|
38302
38547
|
if (zi(e6) || Bi(e6)) {
|
|
38303
38548
|
if (zi(e6)) {
|
|
38304
38549
|
const t8 = e6.focus;
|
|
@@ -38310,7 +38555,7 @@ function dr(t7, e5) {
|
|
|
38310
38555
|
const o8 = Xc(n7);
|
|
38311
38556
|
if (null !== o8 && ki(o8) && Bc(o8)) {
|
|
38312
38557
|
o8.markDirty();
|
|
38313
|
-
const t8 =
|
|
38558
|
+
const t8 = fs9(), r7 = o8.getTextContentSize(), i6 = zi(t8) && t8.anchor.key === n7 ? t8.anchor.offset : r7;
|
|
38314
38559
|
return o8.select(i6, i6).insertText(e5), true;
|
|
38315
38560
|
}
|
|
38316
38561
|
}
|
|
@@ -38437,7 +38682,7 @@ function wr(t7, n7, o8) {
|
|
|
38437
38682
|
const r7 = t7.__key, i6 = t7.getParent();
|
|
38438
38683
|
if (null === i6) return void (null !== Of(t7) && e(367, r7, String(Of(t7))));
|
|
38439
38684
|
const s7 = (function(t8) {
|
|
38440
|
-
const e5 =
|
|
38685
|
+
const e5 = fs9();
|
|
38441
38686
|
if (!zi(e5) || !yl(t8)) return e5;
|
|
38442
38687
|
const { anchor: n8, focus: o9 } = e5, r8 = n8.getNode(), i7 = o9.getNode();
|
|
38443
38688
|
return Ba(r8, t8) && n8.set(t8.__key, 0, "element"), Ba(i7, t8) && o9.set(t8.__key, 0, "element"), e5;
|
|
@@ -38509,7 +38754,7 @@ var Fr = class {
|
|
|
38509
38754
|
return false;
|
|
38510
38755
|
}
|
|
38511
38756
|
isSelected(t7) {
|
|
38512
|
-
const e5 = t7 ||
|
|
38757
|
+
const e5 = t7 || fs9();
|
|
38513
38758
|
if (null == e5) return false;
|
|
38514
38759
|
const n7 = e5.getNodes().some((t8) => t8.__key === this.__key);
|
|
38515
38760
|
if (ki(this)) return n7;
|
|
@@ -38699,7 +38944,7 @@ var Fr = class {
|
|
|
38699
38944
|
}
|
|
38700
38945
|
replace(t7, n7) {
|
|
38701
38946
|
Ws();
|
|
38702
|
-
let o8 =
|
|
38947
|
+
let o8 = fs9();
|
|
38703
38948
|
null !== o8 && (o8 = o8.clone()), qa(this, t7);
|
|
38704
38949
|
const r7 = this.getLatest(), i6 = this.__key, s7 = Mf(r7);
|
|
38705
38950
|
null !== s7 && e(400, i6, r7.getType(), s7.getKey(), s7.getType());
|
|
@@ -38719,7 +38964,7 @@ var Fr = class {
|
|
|
38719
38964
|
Ws(), qa(this, t7);
|
|
38720
38965
|
const n7 = this.getWritable(), o8 = t7.getWritable();
|
|
38721
38966
|
this.getParentOrThrow();
|
|
38722
|
-
const r7 = o8.getParent(), i6 =
|
|
38967
|
+
const r7 = o8.getParent(), i6 = fs9();
|
|
38723
38968
|
let s7 = false, l8 = false, c10 = -1;
|
|
38724
38969
|
if (null !== r7 && e5 && zi(i6) && hs(i6, r7)) {
|
|
38725
38970
|
const e6 = r7.__key, n8 = i6.anchor, o9 = i6.focus;
|
|
@@ -38740,7 +38985,7 @@ var Fr = class {
|
|
|
38740
38985
|
Ws(), qa(this, t7);
|
|
38741
38986
|
const n7 = this.getWritable(), o8 = t7.getWritable();
|
|
38742
38987
|
this.getParentOrThrow();
|
|
38743
|
-
const r7 = o8.__key, i6 =
|
|
38988
|
+
const r7 = o8.__key, i6 = fs9(), s7 = o8.getParent(), l8 = null !== s7 && e5 && zi(i6) && hs(i6, s7), c10 = l8 ? o8.getIndexWithinParent() : -1;
|
|
38744
38989
|
Jc(o8), l8 && null !== s7 && zi(i6) && gs(i6, s7, c10, -1);
|
|
38745
38990
|
const a5 = this.getPreviousSibling(), u8 = this.getParentOrThrow().getWritable(), f6 = n7.__prev, d9 = e5 && zi(i6) && hs(i6, u8), h9 = d9 ? this.getIndexWithinParent() : -1;
|
|
38746
38991
|
return null === a5 ? u8.__first = r7 : a5.getWritable().__next = r7, u8.__size++, n7.__prev = r7, o8.__prev = f6, o8.__next = n7.__key, o8.__parent = n7.__parent, d9 && zi(i6) && gs(i6, u8, h9), t7;
|
|
@@ -39138,7 +39383,7 @@ var hi = class extends Fr {
|
|
|
39138
39383
|
select(t7, e5) {
|
|
39139
39384
|
Ws();
|
|
39140
39385
|
let n7 = t7, o8 = e5;
|
|
39141
|
-
const r7 =
|
|
39386
|
+
const r7 = fs9(), i6 = this.getTextContent(), s7 = this.__key;
|
|
39142
39387
|
if ("string" == typeof i6) {
|
|
39143
39388
|
const t8 = i6.length;
|
|
39144
39389
|
void 0 === n7 && (n7 = t8), void 0 === o8 && (o8 = t8);
|
|
@@ -39161,7 +39406,7 @@ var hi = class extends Fr {
|
|
|
39161
39406
|
const r7 = this.getWritable(), i6 = r7.__text, s7 = n7.length;
|
|
39162
39407
|
let l8 = t7;
|
|
39163
39408
|
l8 < 0 && (l8 = s7 + l8, l8 < 0 && (l8 = 0));
|
|
39164
|
-
const c10 =
|
|
39409
|
+
const c10 = fs9();
|
|
39165
39410
|
if (o8 && zi(c10)) {
|
|
39166
39411
|
const e6 = t7 + s7;
|
|
39167
39412
|
c10.setTextNodeRange(r7, e6, r7, e6);
|
|
@@ -39192,7 +39437,7 @@ var hi = class extends Fr {
|
|
|
39192
39437
|
let f6;
|
|
39193
39438
|
const d9 = e5.getFormat(), h9 = e5.getStyle(), g8 = e5.__detail;
|
|
39194
39439
|
let _5 = false, p7 = null, y5 = null;
|
|
39195
|
-
const m11 =
|
|
39440
|
+
const m11 = fs9();
|
|
39196
39441
|
if (zi(m11)) {
|
|
39197
39442
|
const [t8, e6] = m11.isBackward() ? [m11.focus, m11.anchor] : [m11.anchor, m11.focus];
|
|
39198
39443
|
"text" === t8.type && t8.key === o8 && (p7 = t8), "text" === e6.type && e6.key === o8 && (y5 = e6);
|
|
@@ -39231,7 +39476,7 @@ var hi = class extends Fr {
|
|
|
39231
39476
|
n7 || t7 === this.getNextSibling() || e(50);
|
|
39232
39477
|
const o8 = this.__key, r7 = t7.__key, i6 = this.__text, s7 = i6.length;
|
|
39233
39478
|
Gc() === r7 && Yc(o8);
|
|
39234
|
-
const l8 =
|
|
39479
|
+
const l8 = fs9();
|
|
39235
39480
|
if (zi(l8)) {
|
|
39236
39481
|
const e5 = l8.anchor, i7 = l8.focus;
|
|
39237
39482
|
null !== e5 && e5.key === r7 && ys(e5, n7, o8, t7, s7), null !== i7 && i7.key === r7 && ys(i7, n7, o8, t7, s7);
|
|
@@ -39518,7 +39763,7 @@ var Ii = class _Ii {
|
|
|
39518
39763
|
}
|
|
39519
39764
|
deleteNodes() {
|
|
39520
39765
|
const t7 = this.getNodes().filter((t8) => null === Of(t8));
|
|
39521
|
-
if ((
|
|
39766
|
+
if ((fs9() || ds()) === this && t7[0]) {
|
|
39522
39767
|
const e5 = ad(t7[0], "next");
|
|
39523
39768
|
Kl(vd(e5, e5));
|
|
39524
39769
|
}
|
|
@@ -39528,7 +39773,7 @@ var Ii = class _Ii {
|
|
|
39528
39773
|
};
|
|
39529
39774
|
function Li() {
|
|
39530
39775
|
const t7 = ra();
|
|
39531
|
-
if (0 === t7.getChildrenSize() && null === Df(
|
|
39776
|
+
if (0 === t7.getChildrenSize() && null === Df(fs9())) {
|
|
39532
39777
|
const e5 = oc();
|
|
39533
39778
|
t7.append(e5), e5.select();
|
|
39534
39779
|
}
|
|
@@ -39655,8 +39900,8 @@ var Ki = class _Ki {
|
|
|
39655
39900
|
else {
|
|
39656
39901
|
const t8 = vi(r7.getTextContent());
|
|
39657
39902
|
t8.setFormat(n7), t8.setStyle(o8);
|
|
39658
|
-
const e6 =
|
|
39659
|
-
r7.replace(t8), this.setTextNodeRange(t8, i6, t8, i6), e6 &&
|
|
39903
|
+
const e6 = fs9() === this;
|
|
39904
|
+
r7.replace(t8), this.setTextNodeRange(t8, i6, t8, i6), e6 && fs9() !== this && sa(this);
|
|
39660
39905
|
}
|
|
39661
39906
|
return void ("" !== t7 && this.insertText(t7));
|
|
39662
39907
|
}
|
|
@@ -39691,14 +39936,14 @@ var Ki = class _Ki {
|
|
|
39691
39936
|
r7.spliceText(i6, 0, t7, true), r7.isComposing() && "text" === this.anchor.type && this.anchor.set(this.anchor.key, this.anchor.offset - t7.length, this.anchor.type);
|
|
39692
39937
|
}
|
|
39693
39938
|
removeText() {
|
|
39694
|
-
const t7 =
|
|
39939
|
+
const t7 = fs9() === this, e5 = this.anchor.key;
|
|
39695
39940
|
Bl(this, Ul(Rl(this))), this.isCollapsed() && (function(t8, e6) {
|
|
39696
39941
|
const n7 = t8.anchor;
|
|
39697
39942
|
if (n7.key === e6) return;
|
|
39698
39943
|
const o8 = n7.getNode();
|
|
39699
39944
|
let r7 = 0, i6 = "";
|
|
39700
39945
|
ki(o8) ? (r7 = o8.getFormat(), i6 = o8.getStyle()) : yl(o8) && (r7 = o8.getTextFormat(), i6 = o8.getTextStyle()), t8.format === r7 && t8.style === i6 || (t8.format = r7, t8.style = i6, t8.dirty = true);
|
|
39701
|
-
})(this, e5), t7 &&
|
|
39946
|
+
})(this, e5), t7 && fs9() !== this && sa(this);
|
|
39702
39947
|
}
|
|
39703
39948
|
formatText(t7, e5 = null) {
|
|
39704
39949
|
$i(this, t7, e5);
|
|
@@ -39715,7 +39960,7 @@ var Ki = class _Ki {
|
|
|
39715
39960
|
}
|
|
39716
39961
|
if (null !== o9) {
|
|
39717
39962
|
o9.selectStart();
|
|
39718
|
-
const n8 =
|
|
39963
|
+
const n8 = fs9();
|
|
39719
39964
|
return zi(n8) || e(369), n8.insertNodes(t7);
|
|
39720
39965
|
}
|
|
39721
39966
|
}
|
|
@@ -40309,7 +40554,7 @@ function us(t7, e5, n7, o8) {
|
|
|
40309
40554
|
const x9 = new Ki(g8, _5, y5, m11);
|
|
40310
40555
|
return p7 && (x9.dirty = true), x9;
|
|
40311
40556
|
}
|
|
40312
|
-
function
|
|
40557
|
+
function fs9() {
|
|
40313
40558
|
return js()._selection;
|
|
40314
40559
|
}
|
|
40315
40560
|
function ds() {
|
|
@@ -40479,7 +40724,7 @@ function Ss(t7, e5, n7, o8, r7, i6) {
|
|
|
40479
40724
|
}
|
|
40480
40725
|
}
|
|
40481
40726
|
function Cs(t7) {
|
|
40482
|
-
let e5 =
|
|
40727
|
+
let e5 = fs9() || ds();
|
|
40483
40728
|
null === e5 && (e5 = ra().selectEnd()), e5.insertNodes(t7);
|
|
40484
40729
|
}
|
|
40485
40730
|
function vs(t7, e5) {
|
|
@@ -40490,7 +40735,7 @@ function ks(t7) {
|
|
|
40490
40735
|
return vs(t7, { linebreak: () => e5.push(Al()), tab: () => e5.push(wi()), text: (t8) => e5.push(vi(t8)) }), e5;
|
|
40491
40736
|
}
|
|
40492
40737
|
function bs() {
|
|
40493
|
-
const t7 =
|
|
40738
|
+
const t7 = fs9();
|
|
40494
40739
|
return null === t7 ? "" : t7.getTextContent();
|
|
40495
40740
|
}
|
|
40496
40741
|
function Ts(t7) {
|
|
@@ -40501,7 +40746,7 @@ function Ts(t7) {
|
|
|
40501
40746
|
function Ns(t7, n7 = false) {
|
|
40502
40747
|
let o8 = t7;
|
|
40503
40748
|
t7.isCollapsed() || o8.removeText();
|
|
40504
|
-
const r7 =
|
|
40749
|
+
const r7 = fs9();
|
|
40505
40750
|
zi(r7) && (o8 = r7), zi(o8) || e(161);
|
|
40506
40751
|
const i6 = o8.anchor;
|
|
40507
40752
|
let s7 = i6.getNode(), l8 = i6.offset;
|
|
@@ -41184,7 +41429,7 @@ var pl = class extends Fr {
|
|
|
41184
41429
|
}
|
|
41185
41430
|
select(t7, e5) {
|
|
41186
41431
|
Ws();
|
|
41187
|
-
const n7 =
|
|
41432
|
+
const n7 = fs9();
|
|
41188
41433
|
let o8 = t7, r7 = e5;
|
|
41189
41434
|
const i6 = this.getChildrenSize();
|
|
41190
41435
|
if (!this.canBeEmpty()) {
|
|
@@ -41281,7 +41526,7 @@ var pl = class extends Fr {
|
|
|
41281
41526
|
} else t8.__prev = null;
|
|
41282
41527
|
}
|
|
41283
41528
|
if (i6.__size = f6, c10.length) {
|
|
41284
|
-
const t8 =
|
|
41529
|
+
const t8 = fs9();
|
|
41285
41530
|
if (zi(t8)) {
|
|
41286
41531
|
const e5 = new Set(c10), n8 = new Set(l8), { anchor: o9, focus: r8 } = t8;
|
|
41287
41532
|
ml(o9, e5, n8) && ps(o9, o9.getNode(), this, u8, a5), ml(r8, e5, n8) && ps(r8, r8.getNode(), this, u8, a5), 0 !== f6 || this.canBeEmpty() || Va(this) || this.remove();
|
|
@@ -41564,7 +41809,7 @@ function zl(t7, n7) {
|
|
|
41564
41809
|
nd(n7) ? t7.set(o8.getKey(), n7.offset, "text") : rd(n7) ? ki(o8) ? t7.set(o8.getKey(), fd(o8, r7), "text") : t7.set(o8.getParentOrThrow().getKey(), o8.getIndexWithinParent() + (i6 ? 1 : 0), "element") : (id(n7) && yl(o8) || e(268), t7.set(o8.getKey(), i6 ? 0 : o8.getChildrenSize(), "element"));
|
|
41565
41810
|
}
|
|
41566
41811
|
function Kl(t7) {
|
|
41567
|
-
const e5 =
|
|
41812
|
+
const e5 = fs9(), n7 = zi(e5) ? e5 : ls();
|
|
41568
41813
|
return Bl(n7, t7), sa(n7), n7;
|
|
41569
41814
|
}
|
|
41570
41815
|
function Bl(t7, e5) {
|
|
@@ -42184,7 +42429,7 @@ var vc = class {
|
|
|
42184
42429
|
focus(t7, e5 = {}) {
|
|
42185
42430
|
const n7 = this._rootElement;
|
|
42186
42431
|
null !== n7 && (n7.setAttribute("autocapitalize", "off"), al(this, () => {
|
|
42187
|
-
const o8 =
|
|
42432
|
+
const o8 = fs9(), r7 = ra();
|
|
42188
42433
|
null !== o8 ? o8.dirty || sa(o8.clone()) : 0 !== r7.getChildrenSize() && ("rootStart" === e5.defaultSelection ? r7.selectStart() : r7.selectEnd()), za("focus"), Ka(() => {
|
|
42189
42434
|
n7.removeAttribute("autocapitalize"), t7 && t7();
|
|
42190
42435
|
});
|
|
@@ -42446,7 +42691,7 @@ function ga(t7, e5, n7, o8, r7) {
|
|
|
42446
42691
|
}
|
|
42447
42692
|
const c10 = i6.getTextContent();
|
|
42448
42693
|
if (r7 || l8 !== c10) {
|
|
42449
|
-
const e6 =
|
|
42694
|
+
const e6 = fs9();
|
|
42450
42695
|
if ("" === l8) {
|
|
42451
42696
|
if (Yc(null), p || g || x) i6.remove();
|
|
42452
42697
|
else {
|
|
@@ -44140,10 +44385,10 @@ function _loadWasmModule(sync, filepath, src, imports2) {
|
|
|
44140
44385
|
var buf = null;
|
|
44141
44386
|
var isNode2 = typeof process !== "undefined" && process.versions != null && process.versions.node != null;
|
|
44142
44387
|
if (filepath && isNode2) {
|
|
44143
|
-
var
|
|
44144
|
-
var
|
|
44388
|
+
var fs28 = null;
|
|
44389
|
+
var path22 = null;
|
|
44145
44390
|
return new Promise((resolve, reject) => {
|
|
44146
|
-
|
|
44391
|
+
fs28.readFile(path22.resolve(__dirname, filepath), (error, buffer) => {
|
|
44147
44392
|
if (error != null) {
|
|
44148
44393
|
reject(error);
|
|
44149
44394
|
} else {
|
|
@@ -45446,10 +45691,10 @@ var LoroDoc = class _LoroDoc {
|
|
|
45446
45691
|
* @param {string} path
|
|
45447
45692
|
* @returns {Value | Container | undefined}
|
|
45448
45693
|
*/
|
|
45449
|
-
getByPath(
|
|
45694
|
+
getByPath(path22) {
|
|
45450
45695
|
try {
|
|
45451
45696
|
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
45452
|
-
const ptr0 = passStringToWasm0(
|
|
45697
|
+
const ptr0 = passStringToWasm0(path22, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
45453
45698
|
const len0 = WASM_VECTOR_LEN;
|
|
45454
45699
|
wasm.lorodoc_getByPath(retptr, this.__wbg_ptr, ptr0, len0);
|
|
45455
45700
|
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
@@ -87424,7 +87669,7 @@ async function readText(file) {
|
|
|
87424
87669
|
}
|
|
87425
87670
|
}
|
|
87426
87671
|
async function writeAtomic(file, data) {
|
|
87427
|
-
await import_promises.default.mkdir(
|
|
87672
|
+
await import_promises.default.mkdir(import_node_path8.default.dirname(file), { recursive: true });
|
|
87428
87673
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
87429
87674
|
await import_promises.default.writeFile(tmp, data);
|
|
87430
87675
|
await import_promises.default.rename(tmp, file);
|
|
@@ -87633,13 +87878,13 @@ function outcomeWarnings(outcome, streaming) {
|
|
|
87633
87878
|
function createDocumentRegistry(options) {
|
|
87634
87879
|
const sessions = /* @__PURE__ */ new Map();
|
|
87635
87880
|
const warnings = /* @__PURE__ */ new Map();
|
|
87636
|
-
const docFile = (id2) =>
|
|
87881
|
+
const docFile = (id2) => import_node_path9.default.join(options.root, "document", id2, "doc.xml");
|
|
87637
87882
|
const commentStores = /* @__PURE__ */ new Map();
|
|
87638
87883
|
const cursors = createCommentCursors(options.stateDir);
|
|
87639
87884
|
const commentStore = (id2) => {
|
|
87640
87885
|
let store = commentStores.get(id2);
|
|
87641
87886
|
if (!store) {
|
|
87642
|
-
store = createCommentStore(
|
|
87887
|
+
store = createCommentStore(import_node_path9.default.join(options.root, "document", id2, "comments.json"), options.names);
|
|
87643
87888
|
commentStores.set(id2, store);
|
|
87644
87889
|
}
|
|
87645
87890
|
return store;
|
|
@@ -87653,10 +87898,10 @@ function createDocumentRegistry(options) {
|
|
|
87653
87898
|
if (JSON.stringify(store.warnings()) !== before2) options.onWarningsChange(id2);
|
|
87654
87899
|
};
|
|
87655
87900
|
const create3 = async (id2) => {
|
|
87656
|
-
if (!
|
|
87901
|
+
if (!import_node_fs9.default.existsSync(docFile(id2))) return null;
|
|
87657
87902
|
const session = await createDocumentSession({
|
|
87658
87903
|
file: docFile(id2),
|
|
87659
|
-
snapshotFile:
|
|
87904
|
+
snapshotFile: import_node_path9.default.join(options.stateDir, "document", id2, "doc.loro"),
|
|
87660
87905
|
...options.timing,
|
|
87661
87906
|
log: options.log
|
|
87662
87907
|
});
|
|
@@ -87699,7 +87944,7 @@ function createDocumentRegistry(options) {
|
|
|
87699
87944
|
const known = sessions.has(id2);
|
|
87700
87945
|
void open(id2).then((session) => {
|
|
87701
87946
|
if (!session || !known) return;
|
|
87702
|
-
|
|
87947
|
+
import_node_fs9.default.readFile(docFile(id2), "utf8", (err, text2) => {
|
|
87703
87948
|
if (!err) session.onFileText(text2);
|
|
87704
87949
|
});
|
|
87705
87950
|
});
|
|
@@ -88263,9 +88508,9 @@ function injectRuntime(html, options = {}) {
|
|
|
88263
88508
|
}
|
|
88264
88509
|
|
|
88265
88510
|
// src/server/http.ts
|
|
88266
|
-
var
|
|
88267
|
-
var
|
|
88268
|
-
var
|
|
88511
|
+
var import_node_crypto3 = __toESM(require("node:crypto"), 1);
|
|
88512
|
+
var import_node_fs10 = __toESM(require("node:fs"), 1);
|
|
88513
|
+
var import_node_path10 = __toESM(require("node:path"), 1);
|
|
88269
88514
|
var MIME2 = {
|
|
88270
88515
|
".html": "text/html; charset=utf-8",
|
|
88271
88516
|
".js": "text/javascript; charset=utf-8",
|
|
@@ -88288,12 +88533,12 @@ var MIME2 = {
|
|
|
88288
88533
|
".mp4": "video/mp4",
|
|
88289
88534
|
".webm": "video/webm"
|
|
88290
88535
|
};
|
|
88291
|
-
var mimeOf = (file) => MIME2[
|
|
88292
|
-
var randomToken = () =>
|
|
88536
|
+
var mimeOf = (file) => MIME2[import_node_path10.default.extname(file).toLowerCase()] ?? "application/octet-stream";
|
|
88537
|
+
var randomToken = () => import_node_crypto3.default.randomBytes(24).toString("base64url");
|
|
88293
88538
|
function safeEqual(a5, b6) {
|
|
88294
88539
|
const ab = Buffer.from(a5);
|
|
88295
88540
|
const bb = Buffer.from(b6);
|
|
88296
|
-
return ab.length === bb.length &&
|
|
88541
|
+
return ab.length === bb.length && import_node_crypto3.default.timingSafeEqual(ab, bb);
|
|
88297
88542
|
}
|
|
88298
88543
|
function parseCookies(header) {
|
|
88299
88544
|
const cookies = {};
|
|
@@ -88305,7 +88550,7 @@ function parseCookies(header) {
|
|
|
88305
88550
|
}
|
|
88306
88551
|
function readPersisted(file) {
|
|
88307
88552
|
try {
|
|
88308
|
-
return
|
|
88553
|
+
return import_node_fs10.default.readFileSync(file, "utf8").trim();
|
|
88309
88554
|
} catch {
|
|
88310
88555
|
return "";
|
|
88311
88556
|
}
|
|
@@ -88334,15 +88579,15 @@ function sendJson(res, status, value) {
|
|
|
88334
88579
|
send(res, status, JSON.stringify(value), { "Content-Type": MIME2[".json"] });
|
|
88335
88580
|
}
|
|
88336
88581
|
function sendFile(res, file, headers = {}) {
|
|
88337
|
-
|
|
88582
|
+
import_node_fs10.default.readFile(file, (err, data) => {
|
|
88338
88583
|
if (err) send(res, 404, "Not found");
|
|
88339
88584
|
else send(res, 200, data, { "Content-Type": mimeOf(file), ...headers });
|
|
88340
88585
|
});
|
|
88341
88586
|
}
|
|
88342
88587
|
|
|
88343
88588
|
// src/server/dynamic-blocks.ts
|
|
88344
|
-
var
|
|
88345
|
-
var
|
|
88589
|
+
var import_node_fs11 = __toESM(require("node:fs"), 1);
|
|
88590
|
+
var import_node_path11 = __toESM(require("node:path"), 1);
|
|
88346
88591
|
function dynamicUrls(xml) {
|
|
88347
88592
|
const urls = /* @__PURE__ */ new Set();
|
|
88348
88593
|
for (const match of stripOpaque(xml).matchAll(TAG)) {
|
|
@@ -88355,7 +88600,7 @@ function dynamicUrls(xml) {
|
|
|
88355
88600
|
}
|
|
88356
88601
|
var mtimeOf = (file) => {
|
|
88357
88602
|
try {
|
|
88358
|
-
return
|
|
88603
|
+
return import_node_fs11.default.statSync(file).mtimeMs;
|
|
88359
88604
|
} catch {
|
|
88360
88605
|
return -1;
|
|
88361
88606
|
}
|
|
@@ -88372,7 +88617,7 @@ function createDynamicBlocks(limits) {
|
|
|
88372
88617
|
};
|
|
88373
88618
|
const entry = (id2, dir, file) => {
|
|
88374
88619
|
const map = files(id2);
|
|
88375
|
-
const mtime = mtimeOf(
|
|
88620
|
+
const mtime = mtimeOf(import_node_path11.default.join(dir, file));
|
|
88376
88621
|
let state = map.get(file);
|
|
88377
88622
|
if (!state || state.mtime !== mtime) {
|
|
88378
88623
|
state = { mtime, errors: [], ran: false };
|
|
@@ -88397,19 +88642,19 @@ function createDynamicBlocks(limits) {
|
|
|
88397
88642
|
state(id2, dir) {
|
|
88398
88643
|
let xml = "";
|
|
88399
88644
|
try {
|
|
88400
|
-
xml =
|
|
88645
|
+
xml = import_node_fs11.default.readFileSync(import_node_path11.default.join(dir, "doc.xml"), "utf8");
|
|
88401
88646
|
} catch {
|
|
88402
88647
|
return { warnings: [], dynamic: {} };
|
|
88403
88648
|
}
|
|
88404
88649
|
const urls = dynamicUrls(xml);
|
|
88405
88650
|
const map = files(id2);
|
|
88406
88651
|
for (const [file, state] of map) {
|
|
88407
|
-
if (!urls.includes(file) || state.mtime !== mtimeOf(
|
|
88652
|
+
if (!urls.includes(file) || state.mtime !== mtimeOf(import_node_path11.default.join(dir, file))) map.delete(file);
|
|
88408
88653
|
}
|
|
88409
88654
|
const warnings = [];
|
|
88410
88655
|
const dynamic = {};
|
|
88411
88656
|
for (const url of urls) {
|
|
88412
|
-
if (!
|
|
88657
|
+
if (!import_node_fs11.default.existsSync(import_node_path11.default.join(dir, url))) warnings.push(`${url} not found`);
|
|
88413
88658
|
const state = map.get(url);
|
|
88414
88659
|
for (const error of state?.errors ?? []) warnings.push(`runtime: ${url}: ${error}`);
|
|
88415
88660
|
dynamic[url] = { ran: state?.ran ?? false };
|
|
@@ -88420,8 +88665,8 @@ function createDynamicBlocks(limits) {
|
|
|
88420
88665
|
}
|
|
88421
88666
|
|
|
88422
88667
|
// src/server/selection.ts
|
|
88423
|
-
var
|
|
88424
|
-
var
|
|
88668
|
+
var import_node_fs12 = __toESM(require("node:fs"), 1);
|
|
88669
|
+
var import_node_path12 = __toESM(require("node:path"), 1);
|
|
88425
88670
|
|
|
88426
88671
|
// src/shared/selection.ts
|
|
88427
88672
|
var SELECTION_FULL_NODES = 20;
|
|
@@ -88496,14 +88741,14 @@ function readAnySelection(value) {
|
|
|
88496
88741
|
function createSelectionStore(stateDir, exists) {
|
|
88497
88742
|
const tabs = /* @__PURE__ */ new Map();
|
|
88498
88743
|
let clock = 0;
|
|
88499
|
-
const fileOf = (kind, id2) =>
|
|
88744
|
+
const fileOf = (kind, id2) => import_node_path12.default.join(stateDir, kind, id2, "selection.json");
|
|
88500
88745
|
const write = (kind, id2) => {
|
|
88501
88746
|
let winner;
|
|
88502
88747
|
for (const tab of tabs.values()) {
|
|
88503
88748
|
if (tab.kind !== kind || tab.id !== id2) continue;
|
|
88504
88749
|
if (!winner || tab.humanAt > winner.humanAt || tab.humanAt === winner.humanAt && tab.seenAt > winner.seenAt) winner = tab;
|
|
88505
88750
|
}
|
|
88506
|
-
if (!winner?.state)
|
|
88751
|
+
if (!winner?.state) import_node_fs12.default.rmSync(fileOf(kind, id2), { force: true });
|
|
88507
88752
|
else writeJsonAtomic(fileOf(kind, id2), { artifact: `${kind}/${id2}`, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), ...winner.state });
|
|
88508
88753
|
};
|
|
88509
88754
|
return {
|
|
@@ -88534,19 +88779,19 @@ function createSelectionStore(stateDir, exists) {
|
|
|
88534
88779
|
for (const kind of ["artboard", "document"]) {
|
|
88535
88780
|
let ids = [];
|
|
88536
88781
|
try {
|
|
88537
|
-
ids =
|
|
88782
|
+
ids = import_node_fs12.default.readdirSync(import_node_path12.default.join(stateDir, kind));
|
|
88538
88783
|
} catch {
|
|
88539
88784
|
continue;
|
|
88540
88785
|
}
|
|
88541
|
-
for (const id2 of ids)
|
|
88786
|
+
for (const id2 of ids) import_node_fs12.default.rmSync(fileOf(kind, id2), { force: true });
|
|
88542
88787
|
}
|
|
88543
88788
|
}
|
|
88544
88789
|
};
|
|
88545
88790
|
}
|
|
88546
88791
|
|
|
88547
88792
|
// src/server/config.ts
|
|
88548
|
-
var
|
|
88549
|
-
var
|
|
88793
|
+
var import_node_fs13 = __toESM(require("node:fs"), 1);
|
|
88794
|
+
var import_node_path13 = __toESM(require("node:path"), 1);
|
|
88550
88795
|
|
|
88551
88796
|
// src/shared/cloud.ts
|
|
88552
88797
|
var ownLink = (url, hostId) => hostId ? `${url}#ryugi-host=${hostId}` : url;
|
|
@@ -88581,7 +88826,7 @@ function normalize(raw) {
|
|
|
88581
88826
|
function readConfig(file) {
|
|
88582
88827
|
let text2;
|
|
88583
88828
|
try {
|
|
88584
|
-
text2 =
|
|
88829
|
+
text2 = import_node_fs13.default.readFileSync(file, "utf8");
|
|
88585
88830
|
} catch {
|
|
88586
88831
|
return { config: defaults() };
|
|
88587
88832
|
}
|
|
@@ -88592,22 +88837,22 @@ function readConfig(file) {
|
|
|
88592
88837
|
}
|
|
88593
88838
|
}
|
|
88594
88839
|
function ensureGitignore(dir) {
|
|
88595
|
-
const file =
|
|
88840
|
+
const file = import_node_path13.default.join(dir, ".gitignore");
|
|
88596
88841
|
let current = "";
|
|
88597
88842
|
try {
|
|
88598
|
-
current =
|
|
88843
|
+
current = import_node_fs13.default.readFileSync(file, "utf8");
|
|
88599
88844
|
} catch {
|
|
88600
|
-
|
|
88845
|
+
import_node_fs13.default.writeFileSync(file, "config.json\n");
|
|
88601
88846
|
return;
|
|
88602
88847
|
}
|
|
88603
88848
|
if (current.split(/\r?\n/).some((line) => line.trim() === "config.json")) return;
|
|
88604
|
-
|
|
88849
|
+
import_node_fs13.default.writeFileSync(file, `${current}${current === "" || current.endsWith("\n") ? "" : "\n"}config.json
|
|
88605
88850
|
`);
|
|
88606
88851
|
}
|
|
88607
88852
|
function ensureConfig(file) {
|
|
88608
|
-
|
|
88609
|
-
ensureGitignore(
|
|
88610
|
-
if (!
|
|
88853
|
+
import_node_fs13.default.mkdirSync(import_node_path13.default.dirname(file), { recursive: true });
|
|
88854
|
+
ensureGitignore(import_node_path13.default.dirname(file));
|
|
88855
|
+
if (!import_node_fs13.default.existsSync(file)) writeJsonAtomic(file, defaults());
|
|
88611
88856
|
}
|
|
88612
88857
|
function updateArtifactConfig(file, key2, patch) {
|
|
88613
88858
|
const { config, warning } = readConfig(file);
|
|
@@ -88627,21 +88872,21 @@ function setProjectAutoPublish(file, value) {
|
|
|
88627
88872
|
if (warning) throw new Error(warning);
|
|
88628
88873
|
if (value === null) delete config.autoPublish;
|
|
88629
88874
|
else config.autoPublish = value;
|
|
88630
|
-
|
|
88875
|
+
import_node_fs13.default.mkdirSync(import_node_path13.default.dirname(file), { recursive: true });
|
|
88631
88876
|
writeJsonAtomic(file, config);
|
|
88632
88877
|
}
|
|
88633
88878
|
|
|
88634
88879
|
// src/server/credentials.ts
|
|
88635
|
-
var
|
|
88636
|
-
var
|
|
88880
|
+
var import_node_fs14 = __toESM(require("node:fs"), 1);
|
|
88881
|
+
var import_node_path14 = __toESM(require("node:path"), 1);
|
|
88637
88882
|
function credentialsFile(env, platform, home) {
|
|
88638
|
-
if (platform === "win32" && env.APPDATA) return
|
|
88639
|
-
return
|
|
88883
|
+
if (platform === "win32" && env.APPDATA) return import_node_path14.default.join(env.APPDATA, "ryugi", "credentials.json");
|
|
88884
|
+
return import_node_path14.default.join(env.XDG_CONFIG_HOME || import_node_path14.default.join(home, ".config"), "ryugi", "credentials.json");
|
|
88640
88885
|
}
|
|
88641
88886
|
function readCredentials(file, origin) {
|
|
88642
88887
|
let raw;
|
|
88643
88888
|
try {
|
|
88644
|
-
raw = JSON.parse(
|
|
88889
|
+
raw = JSON.parse(import_node_fs14.default.readFileSync(file, "utf8"));
|
|
88645
88890
|
} catch {
|
|
88646
88891
|
return null;
|
|
88647
88892
|
}
|
|
@@ -88652,11 +88897,11 @@ function readCredentials(file, origin) {
|
|
|
88652
88897
|
return { origin: savedOrigin, token, login };
|
|
88653
88898
|
}
|
|
88654
88899
|
function writeCredentials(file, credentials) {
|
|
88655
|
-
|
|
88900
|
+
import_node_fs14.default.mkdirSync(import_node_path14.default.dirname(file), { recursive: true, mode: 448 });
|
|
88656
88901
|
writeJsonAtomic(file, credentials);
|
|
88657
88902
|
}
|
|
88658
88903
|
function clearCredentials(file) {
|
|
88659
|
-
|
|
88904
|
+
import_node_fs14.default.rmSync(file, { force: true });
|
|
88660
88905
|
}
|
|
88661
88906
|
|
|
88662
88907
|
// node_modules/.pnpm/ws@8.18.3/node_modules/ws/wrapper.mjs
|
|
@@ -88784,7 +89029,7 @@ function createRelayClient(options) {
|
|
|
88784
89029
|
}
|
|
88785
89030
|
|
|
88786
89031
|
// src/server/ws.ts
|
|
88787
|
-
var
|
|
89032
|
+
var import_node_crypto4 = __toESM(require("node:crypto"), 1);
|
|
88788
89033
|
var WS_MAGIC = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
|
88789
89034
|
var OPCODE_TEXT = 1;
|
|
88790
89035
|
var OPCODE_CLOSE = 8;
|
|
@@ -88792,7 +89037,7 @@ var OPCODE_PING = 9;
|
|
|
88792
89037
|
var OPCODE_PONG = 10;
|
|
88793
89038
|
var MAX_CLIENT_FRAME = 8 * 1024 * 1024;
|
|
88794
89039
|
function acceptKey(clientKey) {
|
|
88795
|
-
return
|
|
89040
|
+
return import_node_crypto4.default.createHash("sha1").update(clientKey + WS_MAGIC).digest("base64");
|
|
88796
89041
|
}
|
|
88797
89042
|
function encodeFrame(opcode, payload) {
|
|
88798
89043
|
const len = payload.length;
|
|
@@ -88917,21 +89162,21 @@ function createDirectRelay(options) {
|
|
|
88917
89162
|
}
|
|
88918
89163
|
|
|
88919
89164
|
// src/server/host-id.ts
|
|
88920
|
-
var
|
|
88921
|
-
var
|
|
89165
|
+
var import_node_fs15 = __toESM(require("node:fs"), 1);
|
|
89166
|
+
var import_node_path15 = __toESM(require("node:path"), 1);
|
|
88922
89167
|
function hostIdFor(credentialsFile2) {
|
|
88923
|
-
const file =
|
|
89168
|
+
const file = import_node_path15.default.join(import_node_path15.default.dirname(credentialsFile2), "host-id");
|
|
88924
89169
|
const saved = readPersisted(file);
|
|
88925
89170
|
if (/^[A-Za-z0-9_-]{16,64}$/.test(saved)) return saved;
|
|
88926
89171
|
const id2 = randomToken();
|
|
88927
|
-
|
|
88928
|
-
|
|
89172
|
+
import_node_fs15.default.mkdirSync(import_node_path15.default.dirname(file), { recursive: true, mode: 448 });
|
|
89173
|
+
import_node_fs15.default.writeFileSync(file, `${id2}
|
|
88929
89174
|
`, { mode: 384 });
|
|
88930
89175
|
return id2;
|
|
88931
89176
|
}
|
|
88932
89177
|
|
|
88933
89178
|
// src/server/avatars.ts
|
|
88934
|
-
var
|
|
89179
|
+
var import_node_crypto5 = require("node:crypto");
|
|
88935
89180
|
var AVATAR_ROUTE = /^\/api\/avatar\/([a-z]+)\/([^/]+)$/;
|
|
88936
89181
|
var MAX_BYTES = 512 * 1024;
|
|
88937
89182
|
var TIMEOUT_MS = 5e3;
|
|
@@ -88940,7 +89185,7 @@ var SOURCES = {
|
|
|
88940
89185
|
gravatar: { valid: /^[0-9a-f]{64}$/, url: (id2) => `https://gravatar.com/avatar/${id2}?s=64&d=404` }
|
|
88941
89186
|
};
|
|
88942
89187
|
var githubAvatar = (login) => `/api/avatar/github/${login}`;
|
|
88943
|
-
var gravatarAvatar = (email) => `/api/avatar/gravatar/${(0,
|
|
89188
|
+
var gravatarAvatar = (email) => `/api/avatar/gravatar/${(0, import_node_crypto5.createHash)("sha256").update(email.trim().toLowerCase()).digest("hex")}`;
|
|
88944
89189
|
function createAvatars(fetchImpl = fetch) {
|
|
88945
89190
|
const cache = /* @__PURE__ */ new Map();
|
|
88946
89191
|
const fetchAvatar = async (url) => {
|
|
@@ -88972,7 +89217,7 @@ function createAvatars(fetchImpl = fetch) {
|
|
|
88972
89217
|
}
|
|
88973
89218
|
|
|
88974
89219
|
// src/server/cloud.ts
|
|
88975
|
-
var
|
|
89220
|
+
var import_node_crypto6 = __toESM(require("node:crypto"), 1);
|
|
88976
89221
|
|
|
88977
89222
|
// src/shared/brand.ts
|
|
88978
89223
|
var RYUGI_MARK_VIEWBOX = "0 0 512 512";
|
|
@@ -89082,32 +89327,32 @@ function callbackPage(result) {
|
|
|
89082
89327
|
}
|
|
89083
89328
|
|
|
89084
89329
|
// src/server/pack.ts
|
|
89085
|
-
var
|
|
89086
|
-
var
|
|
89330
|
+
var import_node_fs16 = __toESM(require("node:fs"), 1);
|
|
89331
|
+
var import_node_path16 = __toESM(require("node:path"), 1);
|
|
89087
89332
|
var MAX_ARTIFACT_BYTES = 20 * 1024 * 1024;
|
|
89088
89333
|
function formatBytes(bytes) {
|
|
89089
89334
|
if (bytes < 1024) return `${bytes} B`;
|
|
89090
89335
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
89091
89336
|
return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
|
|
89092
89337
|
}
|
|
89093
|
-
var excluded = (type, relative) => type === "document" && relative === "comments.json";
|
|
89338
|
+
var excluded = (type, relative) => (type === "document" || type === "artboard") && relative === "comments.json";
|
|
89094
89339
|
function packArtifact(dir, type, { maxBytes = MAX_ARTIFACT_BYTES } = {}) {
|
|
89095
|
-
const rootReal =
|
|
89340
|
+
const rootReal = import_node_fs16.default.realpathSync(dir);
|
|
89096
89341
|
const found = [];
|
|
89097
89342
|
const visited = /* @__PURE__ */ new Set([rootReal]);
|
|
89098
89343
|
let total = 0;
|
|
89099
89344
|
const walk = (current) => {
|
|
89100
|
-
for (const entry of
|
|
89345
|
+
for (const entry of import_node_fs16.default.readdirSync(current, { withFileTypes: true })) {
|
|
89101
89346
|
if (entry.name.startsWith(".")) continue;
|
|
89102
|
-
const full =
|
|
89347
|
+
const full = import_node_path16.default.join(current, entry.name);
|
|
89103
89348
|
let real;
|
|
89104
89349
|
try {
|
|
89105
|
-
real =
|
|
89350
|
+
real = import_node_fs16.default.realpathSync(full);
|
|
89106
89351
|
} catch {
|
|
89107
89352
|
continue;
|
|
89108
89353
|
}
|
|
89109
|
-
if (!real.startsWith(rootReal +
|
|
89110
|
-
const stat =
|
|
89354
|
+
if (!real.startsWith(rootReal + import_node_path16.default.sep)) continue;
|
|
89355
|
+
const stat = import_node_fs16.default.statSync(real);
|
|
89111
89356
|
if (stat.isDirectory()) {
|
|
89112
89357
|
if (visited.has(real)) continue;
|
|
89113
89358
|
visited.add(real);
|
|
@@ -89115,7 +89360,7 @@ function packArtifact(dir, type, { maxBytes = MAX_ARTIFACT_BYTES } = {}) {
|
|
|
89115
89360
|
continue;
|
|
89116
89361
|
}
|
|
89117
89362
|
if (!stat.isFile()) continue;
|
|
89118
|
-
const relative =
|
|
89363
|
+
const relative = import_node_path16.default.relative(dir, full).split(import_node_path16.default.sep).join("/");
|
|
89119
89364
|
if (excluded(type, relative)) continue;
|
|
89120
89365
|
total += stat.size;
|
|
89121
89366
|
found.push({ path: relative, real });
|
|
@@ -89125,12 +89370,12 @@ function packArtifact(dir, type, { maxBytes = MAX_ARTIFACT_BYTES } = {}) {
|
|
|
89125
89370
|
if (total > maxBytes) {
|
|
89126
89371
|
throw new Error(`artifact is ${formatBytes(total)}; the limit is ${formatBytes(maxBytes)}`);
|
|
89127
89372
|
}
|
|
89128
|
-
return found.map((file) => ({ path: file.path, data:
|
|
89373
|
+
return found.map((file) => ({ path: file.path, data: import_node_fs16.default.readFileSync(file.real) }));
|
|
89129
89374
|
}
|
|
89130
89375
|
|
|
89131
89376
|
// src/server/publish-payload.ts
|
|
89132
|
-
var
|
|
89133
|
-
var
|
|
89377
|
+
var import_node_fs17 = __toESM(require("node:fs"), 1);
|
|
89378
|
+
var import_node_path17 = __toESM(require("node:path"), 1);
|
|
89134
89379
|
var CLOUD_RUNTIME_URL = "/_ryugi/runtime/ryugi-ui.js";
|
|
89135
89380
|
function sharedComments(file) {
|
|
89136
89381
|
return {
|
|
@@ -89143,7 +89388,7 @@ function publishPayload(ref, dir, title, payload, comments = emptyComments()) {
|
|
|
89143
89388
|
const { canvas, layout, versions } = payload;
|
|
89144
89389
|
return { canvas, layout, versions };
|
|
89145
89390
|
}
|
|
89146
|
-
if (ref.type === "document") return { title, state: parseDocument2(
|
|
89391
|
+
if (ref.type === "document") return { title, state: parseDocument2(import_node_fs17.default.readFileSync(import_node_path17.default.join(dir, "doc.xml"), "utf8")), comments: sharedComments(comments) };
|
|
89147
89392
|
return { title };
|
|
89148
89393
|
}
|
|
89149
89394
|
var isPage = (type, file) => type === "html" ? file === "index.html" : (type === "document" || type === "artboard") && file.endsWith(".html");
|
|
@@ -89154,12 +89399,12 @@ function withCloudRuntime(type, files) {
|
|
|
89154
89399
|
}
|
|
89155
89400
|
|
|
89156
89401
|
// src/server/settings.ts
|
|
89157
|
-
var
|
|
89158
|
-
var
|
|
89159
|
-
var settingsFileFor = (credentialsFile2) =>
|
|
89402
|
+
var import_node_fs18 = __toESM(require("node:fs"), 1);
|
|
89403
|
+
var import_node_path18 = __toESM(require("node:path"), 1);
|
|
89404
|
+
var settingsFileFor = (credentialsFile2) => import_node_path18.default.join(import_node_path18.default.dirname(credentialsFile2), "config.json");
|
|
89160
89405
|
function readSettings(file) {
|
|
89161
89406
|
try {
|
|
89162
|
-
const raw = JSON.parse(
|
|
89407
|
+
const raw = JSON.parse(import_node_fs18.default.readFileSync(file, "utf8"));
|
|
89163
89408
|
return typeof raw === "object" && raw !== null && !Array.isArray(raw) ? raw : {};
|
|
89164
89409
|
} catch {
|
|
89165
89410
|
return {};
|
|
@@ -89170,7 +89415,7 @@ function readGlobalAutoPublish(file) {
|
|
|
89170
89415
|
return typeof value === "boolean" ? value : void 0;
|
|
89171
89416
|
}
|
|
89172
89417
|
function writeGlobalAutoPublish(file, value) {
|
|
89173
|
-
|
|
89418
|
+
import_node_fs18.default.mkdirSync(import_node_path18.default.dirname(file), { recursive: true, mode: 448 });
|
|
89174
89419
|
writeJsonAtomic(file, { ...readSettings(file), autoPublish: value });
|
|
89175
89420
|
}
|
|
89176
89421
|
function defaultGlobalAutoPublish(file) {
|
|
@@ -89242,10 +89487,10 @@ function createCloudRoutes(options) {
|
|
|
89242
89487
|
const state = randomToken();
|
|
89243
89488
|
const verifier = randomToken();
|
|
89244
89489
|
pendingStates.set(state, { expires: now + LOGIN_STATE_TTL_MS, verifier });
|
|
89245
|
-
const challenge =
|
|
89490
|
+
const challenge = import_node_crypto6.default.createHash("sha256").update(verifier).digest("base64url");
|
|
89246
89491
|
return `${origin}/auth/cli?port=${options.port()}&state=${state}&challenge=${challenge}`;
|
|
89247
89492
|
};
|
|
89248
|
-
const cloudFetch = async (method,
|
|
89493
|
+
const cloudFetch = async (method, path22, body) => {
|
|
89249
89494
|
const credentials = readCredentials(credentialsFile2, origin);
|
|
89250
89495
|
if (!credentials) throw new SignedOut();
|
|
89251
89496
|
const headers = { Authorization: `Bearer ${credentials.token}` };
|
|
@@ -89259,7 +89504,7 @@ function createCloudRoutes(options) {
|
|
|
89259
89504
|
}
|
|
89260
89505
|
let res;
|
|
89261
89506
|
try {
|
|
89262
|
-
res = await fetch(`${origin}${
|
|
89507
|
+
res = await fetch(`${origin}${path22}`, { method, headers, body: payload });
|
|
89263
89508
|
} catch (err) {
|
|
89264
89509
|
throw new CloudRefused(502, `could not reach ${origin}: ${err.message}`);
|
|
89265
89510
|
}
|
|
@@ -89316,9 +89561,9 @@ function createCloudRoutes(options) {
|
|
|
89316
89561
|
}
|
|
89317
89562
|
const key2 = `${ref.type}/${ref.id}`;
|
|
89318
89563
|
const entry = artifactEntry(key2);
|
|
89319
|
-
const hashed = files.map((file) => ({ ...file, hash:
|
|
89564
|
+
const hashed = files.map((file) => ({ ...file, hash: import_node_crypto6.default.createHash("sha256").update(file.data).digest("hex") }));
|
|
89320
89565
|
const byHash = new Map(hashed.map((file) => [file.hash, file.data]));
|
|
89321
|
-
const manifest = hashed.map(({ path:
|
|
89566
|
+
const manifest = hashed.map(({ path: path22, hash }) => ({ path: path22, hash }));
|
|
89322
89567
|
const version2 = (visibility) => ({ title: inspected.title, payload: inspected.payload, files: manifest, project, ...visibility ? { visibility } : {} });
|
|
89323
89568
|
const create3 = () => createRecord2(ref, requested ?? entry.visibility ?? "private");
|
|
89324
89569
|
const upload = async (id2, hashes) => {
|
|
@@ -89541,7 +89786,7 @@ function createCloudRoutes(options) {
|
|
|
89541
89786
|
|
|
89542
89787
|
// src/server/comment-names.ts
|
|
89543
89788
|
var import_node_child_process = require("node:child_process");
|
|
89544
|
-
var
|
|
89789
|
+
var import_node_fs19 = __toESM(require("node:fs"), 1);
|
|
89545
89790
|
|
|
89546
89791
|
// src/server/agent.ts
|
|
89547
89792
|
var NAMES = {
|
|
@@ -89622,7 +89867,7 @@ function commentNames({ agentFile, projectDir, cloud }) {
|
|
|
89622
89867
|
},
|
|
89623
89868
|
agent: () => {
|
|
89624
89869
|
try {
|
|
89625
|
-
return detectAgent(JSON.parse(
|
|
89870
|
+
return detectAgent(JSON.parse(import_node_fs19.default.readFileSync(agentFile, "utf8")));
|
|
89626
89871
|
} catch {
|
|
89627
89872
|
return void 0;
|
|
89628
89873
|
}
|
|
@@ -89650,8 +89895,8 @@ function viewerPage(template, page) {
|
|
|
89650
89895
|
}
|
|
89651
89896
|
|
|
89652
89897
|
// src/server/auto-publish.ts
|
|
89653
|
-
var
|
|
89654
|
-
var
|
|
89898
|
+
var import_node_crypto7 = __toESM(require("node:crypto"), 1);
|
|
89899
|
+
var import_node_fs20 = __toESM(require("node:fs"), 1);
|
|
89655
89900
|
var SIGNED_OUT_MESSAGE = "auto-publish paused: the Ryugi Cloud sign-in expired";
|
|
89656
89901
|
function isNotice(value) {
|
|
89657
89902
|
if (typeof value !== "object" || value === null) return false;
|
|
@@ -89661,7 +89906,7 @@ function isNotice(value) {
|
|
|
89661
89906
|
function readAutoPublishState(file) {
|
|
89662
89907
|
let raw = {};
|
|
89663
89908
|
try {
|
|
89664
|
-
const parsed = JSON.parse(
|
|
89909
|
+
const parsed = JSON.parse(import_node_fs20.default.readFileSync(file, "utf8"));
|
|
89665
89910
|
if (typeof parsed === "object" && parsed !== null) raw = parsed;
|
|
89666
89911
|
} catch {
|
|
89667
89912
|
}
|
|
@@ -89681,7 +89926,7 @@ function createAutoPublisher(options) {
|
|
|
89681
89926
|
const remarked = /* @__PURE__ */ new Set();
|
|
89682
89927
|
const save = () => writeJsonAtomic(options.stateFile, { dirty: [...dirty], notice, paused });
|
|
89683
89928
|
const raise = (kind, message) => {
|
|
89684
|
-
if (notice?.kind !== kind) notice = { id:
|
|
89929
|
+
if (notice?.kind !== kind) notice = { id: import_node_crypto7.default.randomUUID(), kind, message };
|
|
89685
89930
|
};
|
|
89686
89931
|
const run2 = async () => {
|
|
89687
89932
|
if (!options.enabled() || dirty.size === 0) return;
|
|
@@ -89741,7 +89986,7 @@ function createAutoPublisher(options) {
|
|
|
89741
89986
|
}
|
|
89742
89987
|
|
|
89743
89988
|
// src/server/artifact-file.ts
|
|
89744
|
-
var
|
|
89989
|
+
var import_node_fs21 = __toESM(require("node:fs"), 1);
|
|
89745
89990
|
var RESOLVE = { artboard: resolveBoardFile, document: resolveDocumentAsset, html: resolveHtmlFile };
|
|
89746
89991
|
var isArtifactPage = (type, relative) => type === "html" ? relative === "index.html" : relative.endsWith(".html");
|
|
89747
89992
|
function readArtifactFile(dir, type, relative, uiRuntimeUrl) {
|
|
@@ -89750,7 +89995,7 @@ function readArtifactFile(dir, type, relative, uiRuntimeUrl) {
|
|
|
89750
89995
|
if (!target) return null;
|
|
89751
89996
|
let data;
|
|
89752
89997
|
try {
|
|
89753
|
-
data =
|
|
89998
|
+
data = import_node_fs21.default.readFileSync(target);
|
|
89754
89999
|
} catch {
|
|
89755
90000
|
return null;
|
|
89756
90001
|
}
|
|
@@ -89760,25 +90005,25 @@ function readArtifactFile(dir, type, relative, uiRuntimeUrl) {
|
|
|
89760
90005
|
}
|
|
89761
90006
|
|
|
89762
90007
|
// src/server/watch.ts
|
|
89763
|
-
var
|
|
89764
|
-
var
|
|
89765
|
-
var toPosix = (file) => file.split(
|
|
90008
|
+
var import_node_fs22 = __toESM(require("node:fs"), 1);
|
|
90009
|
+
var import_node_path19 = __toESM(require("node:path"), 1);
|
|
90010
|
+
var toPosix = (file) => file.split(import_node_path19.default.sep).join("/");
|
|
89766
90011
|
var ignored = (file) => file === ".state" || file.startsWith(".state/");
|
|
89767
90012
|
function snapshot(root, dir = root, out = /* @__PURE__ */ new Map()) {
|
|
89768
90013
|
let entries2;
|
|
89769
90014
|
try {
|
|
89770
|
-
entries2 =
|
|
90015
|
+
entries2 = import_node_fs22.default.readdirSync(dir, { withFileTypes: true });
|
|
89771
90016
|
} catch {
|
|
89772
90017
|
return out;
|
|
89773
90018
|
}
|
|
89774
90019
|
for (const entry of entries2) {
|
|
89775
|
-
const full =
|
|
89776
|
-
const rel = toPosix(
|
|
90020
|
+
const full = import_node_path19.default.join(dir, entry.name);
|
|
90021
|
+
const rel = toPosix(import_node_path19.default.relative(root, full));
|
|
89777
90022
|
if (ignored(rel)) continue;
|
|
89778
90023
|
if (entry.isDirectory()) snapshot(root, full, out);
|
|
89779
90024
|
else {
|
|
89780
90025
|
try {
|
|
89781
|
-
out.set(rel,
|
|
90026
|
+
out.set(rel, import_node_fs22.default.statSync(full).mtimeMs);
|
|
89782
90027
|
} catch {
|
|
89783
90028
|
}
|
|
89784
90029
|
}
|
|
@@ -89811,7 +90056,7 @@ function watchTree(root, onChange, debounceMs = 120, backupPollMs = 1e3) {
|
|
|
89811
90056
|
}, debounceMs);
|
|
89812
90057
|
};
|
|
89813
90058
|
try {
|
|
89814
|
-
const watcher =
|
|
90059
|
+
const watcher = import_node_fs22.default.watch(root, { recursive: true }, (_event, filename) => {
|
|
89815
90060
|
if (filename) queue([toPosix(filename.toString())]);
|
|
89816
90061
|
});
|
|
89817
90062
|
watcher.on("error", () => {
|
|
@@ -89861,6 +90106,8 @@ var API_PREVIEW_ROUTE = /^\/api\/preview\/([^/]+)\/([^/]+)$/;
|
|
|
89861
90106
|
var API_DOCUMENT_ROUTE = /^\/api\/document\/([^/]+)\/(state|update|comments)$/;
|
|
89862
90107
|
var MAX_COMMENT_OP = 64 * 1024;
|
|
89863
90108
|
var API_AGENT_COMMENTS_ROUTE = /^\/api\/agent\/document\/([^/]+)\/comments$/;
|
|
90109
|
+
var API_BOARD_COMMENTS_ROUTE = /^\/api\/artboard\/([^/]+)\/comments$/;
|
|
90110
|
+
var API_AGENT_BOARD_COMMENTS_ROUTE = /^\/api\/agent\/artboard\/([^/]+)\/comments$/;
|
|
89864
90111
|
var MAX_DOCUMENT_UPDATE = 8 * 1024 * 1024;
|
|
89865
90112
|
var MAX_RELAY_FILE = 8 * 1024 * 1024;
|
|
89866
90113
|
var MAX_RUNTIME_MESSAGE = 2048;
|
|
@@ -89879,17 +90126,17 @@ function titleOf(payload, ref) {
|
|
|
89879
90126
|
return payload.canvas?.title || ref.id;
|
|
89880
90127
|
}
|
|
89881
90128
|
async function startArtifactsServer(options) {
|
|
89882
|
-
const root =
|
|
89883
|
-
const viewerDir =
|
|
89884
|
-
const runtimeDir = options.runtimeDir ?
|
|
89885
|
-
const stateDir =
|
|
89886
|
-
|
|
89887
|
-
|
|
90129
|
+
const root = import_node_path20.default.resolve(options.root);
|
|
90130
|
+
const viewerDir = import_node_path20.default.resolve(options.viewerDir);
|
|
90131
|
+
const runtimeDir = options.runtimeDir ? import_node_path20.default.resolve(options.runtimeDir) : null;
|
|
90132
|
+
const stateDir = import_node_path20.default.join(root, ".state");
|
|
90133
|
+
import_node_fs23.default.mkdirSync(stateDir, { recursive: true, mode: 448 });
|
|
90134
|
+
import_node_fs23.default.writeFileSync(import_node_path20.default.join(stateDir, ".gitignore"), "*\n");
|
|
89888
90135
|
if (options.configFile) ensureConfig(options.configFile);
|
|
89889
|
-
const portFile =
|
|
89890
|
-
const tokenFile =
|
|
90136
|
+
const portFile = import_node_path20.default.join(stateDir, ".last-port");
|
|
90137
|
+
const tokenFile = import_node_path20.default.join(stateDir, ".last-token");
|
|
89891
90138
|
const token = readPersisted(tokenFile) || randomToken();
|
|
89892
|
-
|
|
90139
|
+
import_node_fs23.default.writeFileSync(tokenFile, `${token}
|
|
89893
90140
|
`, { mode: 384 });
|
|
89894
90141
|
const contentToken = randomToken();
|
|
89895
90142
|
const runtimeWarnings = /* @__PURE__ */ new Map();
|
|
@@ -89919,7 +90166,8 @@ async function startArtifactsServer(options) {
|
|
|
89919
90166
|
direct.emit(message.artifact, message);
|
|
89920
90167
|
};
|
|
89921
90168
|
const avatars = createAvatars(options.fetch);
|
|
89922
|
-
const names = commentNames({ agentFile:
|
|
90169
|
+
const names = commentNames({ agentFile: import_node_path20.default.join(stateDir, "agent"), projectDir: import_node_path20.default.resolve(root, "../.."), cloud: options.cloud });
|
|
90170
|
+
const boardComments = createBoardCommentRegistry({ root, stateDir, broadcast, names });
|
|
89923
90171
|
const documents = createDocumentRegistry({
|
|
89924
90172
|
root,
|
|
89925
90173
|
stateDir,
|
|
@@ -89957,8 +90205,8 @@ async function startArtifactsServer(options) {
|
|
|
89957
90205
|
}
|
|
89958
90206
|
return { dir, title, reasons, payload: published };
|
|
89959
90207
|
};
|
|
89960
|
-
const cloud = options.cloud && options.configFile ? createCloudRoutes({ ...options.cloud, configFile: options.configFile, project:
|
|
89961
|
-
const autoPublisher = cloud ? createAutoPublisher({ stateFile:
|
|
90208
|
+
const cloud = options.cloud && options.configFile ? createCloudRoutes({ ...options.cloud, configFile: options.configFile, project: import_node_path20.default.basename(import_node_path20.default.resolve(root, "../..")), port: () => port, inspect }) : null;
|
|
90209
|
+
const autoPublisher = cloud ? createAutoPublisher({ stateFile: import_node_path20.default.join(stateDir, "auto-publish.json"), enabled: cloud.autoPublishEnabled, token: cloud.token, publish: cloud.autoPublish }) : null;
|
|
89962
90210
|
const sameOrigin = (req) => {
|
|
89963
90211
|
const origin2 = req.headers.origin;
|
|
89964
90212
|
const host = req.headers.host ?? "";
|
|
@@ -90037,7 +90285,7 @@ async function startArtifactsServer(options) {
|
|
|
90037
90285
|
};
|
|
90038
90286
|
const blockIdsOf = async (id2, dir) => {
|
|
90039
90287
|
await (await documents.open(id2))?.flush();
|
|
90040
|
-
const state = parseDocument2(
|
|
90288
|
+
const state = parseDocument2(import_node_fs23.default.readFileSync(import_node_path20.default.join(dir, "doc.xml"), "utf8"));
|
|
90041
90289
|
return new Set(state.root.children.flatMap((block) => block.$?.blockId ? [block.$.blockId] : []));
|
|
90042
90290
|
};
|
|
90043
90291
|
const serveAgentComments = async (req, res, id2) => {
|
|
@@ -90077,6 +90325,55 @@ async function startArtifactsServer(options) {
|
|
|
90077
90325
|
sendJson(res, 400, { error: err.message });
|
|
90078
90326
|
}
|
|
90079
90327
|
};
|
|
90328
|
+
const serveBoardComments = async (req, res, id2) => {
|
|
90329
|
+
if (req.method !== "POST" || !sameOrigin(req)) {
|
|
90330
|
+
send(res, 403, "Forbidden");
|
|
90331
|
+
return;
|
|
90332
|
+
}
|
|
90333
|
+
if (!resolveArtifactDir(root, "artboard", id2)) {
|
|
90334
|
+
sendJson(res, 404, { error: `artboard/${id2} not found` });
|
|
90335
|
+
return;
|
|
90336
|
+
}
|
|
90337
|
+
const op = asBoardHumanOp(await readCommentBody(req));
|
|
90338
|
+
if (!op) {
|
|
90339
|
+
sendJson(res, 400, { error: "not a comment op" });
|
|
90340
|
+
return;
|
|
90341
|
+
}
|
|
90342
|
+
sendJson(res, 200, boardComments.apply(id2, op));
|
|
90343
|
+
};
|
|
90344
|
+
const serveAgentBoardComments = async (req, res, id2) => {
|
|
90345
|
+
const dir = resolveArtifactDir(root, "artboard", id2);
|
|
90346
|
+
if (!dir) {
|
|
90347
|
+
sendJson(res, 404, { error: `artboard/${id2} not found` });
|
|
90348
|
+
return;
|
|
90349
|
+
}
|
|
90350
|
+
const body = await readCommentBody(req);
|
|
90351
|
+
const fields = typeof body === "object" && body !== null ? body : {};
|
|
90352
|
+
const agent = typeof fields.agent === "string" && fields.agent.length > 0 && fields.agent.length <= 100 ? fields.agent : void 0;
|
|
90353
|
+
if (fields.op === "list") {
|
|
90354
|
+
sendJson(res, 200, { type: "comments", artifact: `artboard/${id2}`, threads: boardComments.list(id2, agent ?? "Agent", fields.all === true) });
|
|
90355
|
+
return;
|
|
90356
|
+
}
|
|
90357
|
+
const shorthand = agentAddOnBoard(body, boardSpecs(dir));
|
|
90358
|
+
if (shorthand && "error" in shorthand) {
|
|
90359
|
+
sendJson(res, 400, { error: `${shorthand.error} in artboard/${id2}` });
|
|
90360
|
+
return;
|
|
90361
|
+
}
|
|
90362
|
+
const op = shorthand ?? asBoardAgentOp(body);
|
|
90363
|
+
if (!op) {
|
|
90364
|
+
sendJson(res, 400, { error: "not an agent comment op: use list, add {anchor: {page, board, x, y}, text}, reply {threadId, text} or resolve {threadId}; text must not be empty" });
|
|
90365
|
+
return;
|
|
90366
|
+
}
|
|
90367
|
+
if (op.op === "add" && op.anchor.board && !(op.anchor.board in boardFiles(dir))) {
|
|
90368
|
+
sendJson(res, 400, { error: `no board ${op.anchor.board} in artboard/${id2}` });
|
|
90369
|
+
return;
|
|
90370
|
+
}
|
|
90371
|
+
try {
|
|
90372
|
+
sendJson(res, 200, boardComments.applyAgent(id2, op, agent));
|
|
90373
|
+
} catch (err) {
|
|
90374
|
+
sendJson(res, 400, { error: err.message });
|
|
90375
|
+
}
|
|
90376
|
+
};
|
|
90080
90377
|
const isAuthorized = (req, keyFromQuery) => keyFromQuery !== null && safeEqual(keyFromQuery, token) || safeEqual(parseCookies(req.headers.cookie)[cookieName] ?? "", token);
|
|
90081
90378
|
const serveContent = (res, rest) => {
|
|
90082
90379
|
if (rest.startsWith("runtime/")) {
|
|
@@ -90117,7 +90414,7 @@ async function startArtifactsServer(options) {
|
|
|
90117
90414
|
sendFile(res, target, headers);
|
|
90118
90415
|
return;
|
|
90119
90416
|
}
|
|
90120
|
-
|
|
90417
|
+
import_node_fs23.default.readFile(target, "utf8", (err, source) => {
|
|
90121
90418
|
if (err) send(res, 404, "Not found");
|
|
90122
90419
|
else {
|
|
90123
90420
|
const uiRuntimeUrl = runtimeDir ? `${contentPrefix}runtime/ryugi-ui.js` : void 0;
|
|
@@ -90128,6 +90425,7 @@ async function startArtifactsServer(options) {
|
|
|
90128
90425
|
const artifactMeta = (ref, dir, contentOrigin = "") => ({
|
|
90129
90426
|
...readArtifact(dir, ref, runtimeOf(ref, dir)),
|
|
90130
90427
|
...ref.type !== "html" ? { agent: names.agent() } : {},
|
|
90428
|
+
...ref.type === "artboard" ? { comments: boardComments.comments(ref.id), staleThreads: boardComments.stale(ref.id) } : {},
|
|
90131
90429
|
contentBase: `${contentOrigin}${contentPrefix}${ref.type}/${ref.id}/`
|
|
90132
90430
|
});
|
|
90133
90431
|
const serveArtifactApi = (res, type, id2) => {
|
|
@@ -90146,7 +90444,7 @@ async function startArtifactsServer(options) {
|
|
|
90146
90444
|
title: titleOf(readArtifact(entry.dir, entry), entry),
|
|
90147
90445
|
updatedAt: latestMtime(entry.dir)
|
|
90148
90446
|
}));
|
|
90149
|
-
sendJson(res, 200, { project:
|
|
90447
|
+
sendJson(res, 200, { project: import_node_path20.default.basename(import_node_path20.default.dirname(import_node_path20.default.dirname(root))), artifacts: summaries, warnings });
|
|
90150
90448
|
};
|
|
90151
90449
|
function onClientText(socket, text2) {
|
|
90152
90450
|
let message;
|
|
@@ -90208,7 +90506,7 @@ async function startArtifactsServer(options) {
|
|
|
90208
90506
|
return;
|
|
90209
90507
|
}
|
|
90210
90508
|
if (pathname === "/robots.txt") {
|
|
90211
|
-
sendFile(res,
|
|
90509
|
+
sendFile(res, import_node_path20.default.join(viewerDir, "robots.txt"));
|
|
90212
90510
|
return;
|
|
90213
90511
|
}
|
|
90214
90512
|
if (pathname.startsWith("/c/")) {
|
|
@@ -90290,6 +90588,24 @@ async function startArtifactsServer(options) {
|
|
|
90290
90588
|
});
|
|
90291
90589
|
return;
|
|
90292
90590
|
}
|
|
90591
|
+
const agentBoardMatch = API_AGENT_BOARD_COMMENTS_ROUTE.exec(pathname);
|
|
90592
|
+
if (agentBoardMatch) {
|
|
90593
|
+
if (req.method !== "POST" || key2 === null || !safeEqual(key2, token)) {
|
|
90594
|
+
send(res, 403, "Forbidden: agent calls need ?key=");
|
|
90595
|
+
return;
|
|
90596
|
+
}
|
|
90597
|
+
void serveAgentBoardComments(req, res, agentBoardMatch[1]).catch((err) => {
|
|
90598
|
+
if (!res.headersSent) send(res, 500, `Artifacts error: ${err.message}`);
|
|
90599
|
+
});
|
|
90600
|
+
return;
|
|
90601
|
+
}
|
|
90602
|
+
const boardCommentsMatch = API_BOARD_COMMENTS_ROUTE.exec(pathname);
|
|
90603
|
+
if (boardCommentsMatch) {
|
|
90604
|
+
void serveBoardComments(req, res, boardCommentsMatch[1]).catch((err) => {
|
|
90605
|
+
if (!res.headersSent) send(res, 500, `Artifacts error: ${err.message}`);
|
|
90606
|
+
});
|
|
90607
|
+
return;
|
|
90608
|
+
}
|
|
90293
90609
|
const documentMatch = API_DOCUMENT_ROUTE.exec(pathname);
|
|
90294
90610
|
if (documentMatch) {
|
|
90295
90611
|
void serveDocumentApi(req, res, documentMatch[1], documentMatch[2]).catch((err) => {
|
|
@@ -90305,7 +90621,7 @@ async function startArtifactsServer(options) {
|
|
|
90305
90621
|
if (SHELL_ROUTE.test(pathname) || PREVIEW_ROUTE.test(pathname) || pathname === "/index.html") {
|
|
90306
90622
|
const ref = artifactKeyOf(pathname.replace(/^\/(?:preview\/)?/, "").replace(/\/$/, ""));
|
|
90307
90623
|
const dir = ref && resolveArtifactDir(root, ref.type, ref.id);
|
|
90308
|
-
const project =
|
|
90624
|
+
const project = import_node_path20.default.basename(import_node_path20.default.dirname(import_node_path20.default.dirname(root)));
|
|
90309
90625
|
const title = ref ? dir ? titleOf(readArtifact(dir, ref), ref) : ref.id : `${project} \xB7 Artifacts`;
|
|
90310
90626
|
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`;
|
|
90311
90627
|
const canonical = `http://${urlHostForHttp(options.urlHost)}:${port}/${ref ? `${ref.type}/${ref.id}` : ""}`;
|
|
@@ -90314,7 +90630,7 @@ async function startArtifactsServer(options) {
|
|
|
90314
90630
|
"Content-Security-Policy": PREVIEW_ROUTE.test(pathname) ? VIEWER_CSP.replace("frame-ancestors 'none'", "frame-ancestors 'self'") : VIEWER_CSP
|
|
90315
90631
|
};
|
|
90316
90632
|
if (key2 !== null) headers["Set-Cookie"] = `${cookieName}=${token}; HttpOnly; SameSite=Strict; Path=/`;
|
|
90317
|
-
void
|
|
90633
|
+
void import_node_fs23.default.promises.readFile(import_node_path20.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"));
|
|
90318
90634
|
return;
|
|
90319
90635
|
}
|
|
90320
90636
|
const target = resolveInside(viewerDir, pathname.slice(1));
|
|
@@ -90373,7 +90689,7 @@ async function startArtifactsServer(options) {
|
|
|
90373
90689
|
port = await listen(server, options.host, 0);
|
|
90374
90690
|
}
|
|
90375
90691
|
cookieName = `ryugi_artifacts_${port}`;
|
|
90376
|
-
|
|
90692
|
+
import_node_fs23.default.writeFileSync(portFile, `${port}
|
|
90377
90693
|
`, { mode: 384 });
|
|
90378
90694
|
const origin = `http://${urlHostForHttp(options.urlHost)}:${port}`;
|
|
90379
90695
|
const url = `${origin}/?key=${token}`;
|
|
@@ -90390,7 +90706,7 @@ async function startArtifactsServer(options) {
|
|
|
90390
90706
|
return payload;
|
|
90391
90707
|
};
|
|
90392
90708
|
const refreshState = (ref, dir) => {
|
|
90393
|
-
signatures.set(`${ref.type}/${ref.id}`, artifactSignature(dir));
|
|
90709
|
+
signatures.set(`${ref.type}/${ref.id}`, artifactSignature(dir, ref.type));
|
|
90394
90710
|
return writeState(ref, dir);
|
|
90395
90711
|
};
|
|
90396
90712
|
const initialChanges = [];
|
|
@@ -90399,7 +90715,7 @@ async function startArtifactsServer(options) {
|
|
|
90399
90715
|
initialChanges.push({ ref: entry, payload, files: [] });
|
|
90400
90716
|
if (entry.type === "document") void documents.open(entry.id);
|
|
90401
90717
|
}
|
|
90402
|
-
writeJsonAtomic(
|
|
90718
|
+
writeJsonAtomic(import_node_path20.default.join(stateDir, "server-info"), { type: "server-started", url, port, root });
|
|
90403
90719
|
const relayViewers = /* @__PURE__ */ new Map();
|
|
90404
90720
|
const servedArtifacts = () => {
|
|
90405
90721
|
const served = /* @__PURE__ */ new Map();
|
|
@@ -90432,6 +90748,11 @@ async function startArtifactsServer(options) {
|
|
|
90432
90748
|
if (typeof request.message === "object" && request.message !== null) acceptReport({ ...request.message, artifact: key2 });
|
|
90433
90749
|
return null;
|
|
90434
90750
|
}
|
|
90751
|
+
if (request.op === "comment" && ref.type === "artboard") {
|
|
90752
|
+
const op = JSON.stringify(request.comment ?? null).length <= MAX_COMMENT_OP ? asBoardHumanOp(request.comment) : null;
|
|
90753
|
+
if (!op) throw new Error("not a comment op");
|
|
90754
|
+
return boardComments.apply(ref.id, op);
|
|
90755
|
+
}
|
|
90435
90756
|
if ((request.op === "state" || request.op === "update" || request.op === "comment") && ref.type !== "document") throw new Error(`${key2} is not a document`);
|
|
90436
90757
|
if (request.op === "state" || request.op === "update") {
|
|
90437
90758
|
const session = await documents.open(ref.id);
|
|
@@ -90496,7 +90817,9 @@ async function startArtifactsServer(options) {
|
|
|
90496
90817
|
}
|
|
90497
90818
|
if (ref.type === "document" && (changed.includes("doc.xml") || changed.length === 0)) documents.fileChanged(ref.id);
|
|
90498
90819
|
if (ref.type === "document" && changed.includes("comments.json")) documents.commentsChanged(ref.id);
|
|
90499
|
-
if (
|
|
90820
|
+
if (ref.type === "artboard" && changed.includes("comments.json")) boardComments.sync(ref.id);
|
|
90821
|
+
if (ref.type === "artboard" && (changed.some((file) => file !== "comments.json") || changed.length === 0)) boardComments.boardsChanged(ref.id);
|
|
90822
|
+
if (signatures.get(key2) === artifactSignature(dir, ref.type)) continue;
|
|
90500
90823
|
autoPublisher?.changed(key2);
|
|
90501
90824
|
runtimeWarnings.delete(key2);
|
|
90502
90825
|
const payload = refreshState(ref, dir);
|
|
@@ -90540,7 +90863,7 @@ async function startArtifactsServer(options) {
|
|
|
90540
90863
|
}
|
|
90541
90864
|
|
|
90542
90865
|
// src/server/lifecycle.ts
|
|
90543
|
-
var
|
|
90866
|
+
var import_node_fs24 = __toESM(require("node:fs"), 1);
|
|
90544
90867
|
var DEFAULT_IDLE_TIMEOUT_MS = 4 * 60 * 60 * 1e3;
|
|
90545
90868
|
var DEFAULT_LIFECYCLE_CHECK_MS = 60 * 1e3;
|
|
90546
90869
|
var SERVER_ID_ARG = "--artifacts-server-id=";
|
|
@@ -90572,7 +90895,7 @@ function parseEnv(env, argv = []) {
|
|
|
90572
90895
|
function readOwners(file) {
|
|
90573
90896
|
let text2;
|
|
90574
90897
|
try {
|
|
90575
|
-
text2 =
|
|
90898
|
+
text2 = import_node_fs24.default.readFileSync(file, "utf8");
|
|
90576
90899
|
} catch {
|
|
90577
90900
|
return [];
|
|
90578
90901
|
}
|
|
@@ -90635,20 +90958,20 @@ function openReady(payload) {
|
|
|
90635
90958
|
}
|
|
90636
90959
|
|
|
90637
90960
|
// package.json
|
|
90638
|
-
var version = "1.15.
|
|
90961
|
+
var version = "1.15.2";
|
|
90639
90962
|
|
|
90640
90963
|
// src/server/main.ts
|
|
90641
90964
|
async function main() {
|
|
90642
90965
|
const config = parseEnv(process.env, process.argv.slice(2));
|
|
90643
|
-
const root =
|
|
90644
|
-
const stateDir =
|
|
90966
|
+
const root = import_node_path21.default.resolve(config.root);
|
|
90967
|
+
const stateDir = import_node_path21.default.join(root, ".state");
|
|
90645
90968
|
const server = await startArtifactsServer({
|
|
90646
90969
|
root,
|
|
90647
|
-
viewerDir:
|
|
90648
|
-
runtimeDir:
|
|
90970
|
+
viewerDir: import_node_path21.default.join(__dirname, "viewer"),
|
|
90971
|
+
runtimeDir: import_node_path21.default.join(__dirname, "runtime"),
|
|
90649
90972
|
host: config.host,
|
|
90650
90973
|
urlHost: config.urlHost,
|
|
90651
|
-
configFile:
|
|
90974
|
+
configFile: import_node_path21.default.join(import_node_path21.default.dirname(root), "config.json"),
|
|
90652
90975
|
cloud: { origin: config.cloudOrigin, credentialsFile: credentialsFile(process.env, process.platform, import_node_os.default.homedir()) },
|
|
90653
90976
|
relay: { url: `${config.cloudOrigin.replace(/^http/, "ws")}/api/relay/host`, version }
|
|
90654
90977
|
});
|
|
@@ -90678,12 +91001,12 @@ async function main() {
|
|
|
90678
91001
|
if (stopping) return;
|
|
90679
91002
|
stopping = true;
|
|
90680
91003
|
console.log(JSON.stringify({ type: "server-stopped", reason }));
|
|
90681
|
-
|
|
90682
|
-
writeJsonAtomic(
|
|
91004
|
+
import_node_fs25.default.rmSync(import_node_path21.default.join(stateDir, "server-info"), { force: true });
|
|
91005
|
+
writeJsonAtomic(import_node_path21.default.join(stateDir, "server-stopped"), { reason, timestamp: Date.now() });
|
|
90683
91006
|
await server.close();
|
|
90684
91007
|
process.exit(0);
|
|
90685
91008
|
};
|
|
90686
|
-
const ownersFile =
|
|
91009
|
+
const ownersFile = import_node_path21.default.join(stateDir, "owners");
|
|
90687
91010
|
const timer = setInterval(() => {
|
|
90688
91011
|
const owners = readOwners(ownersFile);
|
|
90689
91012
|
const reason = shutdownReason({
|
|
@@ -90697,7 +91020,7 @@ async function main() {
|
|
|
90697
91020
|
timer.unref();
|
|
90698
91021
|
process.on("SIGTERM", () => void shutdown("SIGTERM"));
|
|
90699
91022
|
process.on("SIGINT", () => void shutdown("SIGINT"));
|
|
90700
|
-
|
|
91023
|
+
import_node_fs25.default.rmSync(import_node_path21.default.join(stateDir, "server-stopped"), { force: true });
|
|
90701
91024
|
console.log(JSON.stringify({ type: "server-started", url: server.url, port: server.port, root }));
|
|
90702
91025
|
}
|
|
90703
91026
|
main().catch((err) => {
|