ryugi-artifacts 1.15.1 → 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 +560 -249
- 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-CdN71jfH.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);
|
|
@@ -18282,7 +18353,31 @@ function writeArtifactState(stateDir, ref, payload, extra = {}) {
|
|
|
18282
18353
|
});
|
|
18283
18354
|
}
|
|
18284
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
|
+
|
|
18285
18379
|
// src/server/document-comments.ts
|
|
18380
|
+
var import_node_fs7 = __toESM(require("node:fs"), 1);
|
|
18286
18381
|
var MAX_TEXT = 2e4;
|
|
18287
18382
|
var isText3 = (value, max = MAX_TEXT) => typeof value === "string" && value.length <= max;
|
|
18288
18383
|
var isId = (value) => isText3(value, 100) && value.length > 0;
|
|
@@ -18319,20 +18414,30 @@ function asAgentOp(value) {
|
|
|
18319
18414
|
return null;
|
|
18320
18415
|
}
|
|
18321
18416
|
}
|
|
18417
|
+
var documentRules = {
|
|
18418
|
+
empty: emptyComments,
|
|
18419
|
+
saved: savedComments,
|
|
18420
|
+
merge: mergeComments,
|
|
18421
|
+
human: applyHumanOp,
|
|
18422
|
+
agent: applyAgentOp
|
|
18423
|
+
};
|
|
18322
18424
|
var noNames = { human: () => void 0, agent: () => void 0 };
|
|
18323
18425
|
function createCommentStore(file, names = noNames, now = () => (/* @__PURE__ */ new Date()).toISOString(), newId = () => nanoid2(10)) {
|
|
18324
|
-
|
|
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();
|
|
18325
18430
|
let lastSeen = null;
|
|
18326
18431
|
let warnings = [];
|
|
18327
18432
|
let loaded = false;
|
|
18328
18433
|
const write = () => {
|
|
18329
18434
|
writeJsonAtomic(file, current);
|
|
18330
|
-
lastSeen =
|
|
18435
|
+
lastSeen = import_node_fs7.default.readFileSync(file, "utf8");
|
|
18331
18436
|
};
|
|
18332
18437
|
const sync = () => {
|
|
18333
18438
|
let text2;
|
|
18334
18439
|
try {
|
|
18335
|
-
text2 =
|
|
18440
|
+
text2 = import_node_fs7.default.readFileSync(file, "utf8");
|
|
18336
18441
|
} catch {
|
|
18337
18442
|
return false;
|
|
18338
18443
|
}
|
|
@@ -18340,8 +18445,8 @@ function createCommentStore(file, names = noNames, now = () => (/* @__PURE__ */
|
|
|
18340
18445
|
lastSeen = text2;
|
|
18341
18446
|
try {
|
|
18342
18447
|
const incoming = parseComments(text2);
|
|
18343
|
-
const base = loaded ? current :
|
|
18344
|
-
const merged =
|
|
18448
|
+
const base = loaded ? current : rules.saved(incoming);
|
|
18449
|
+
const merged = rules.merge(base, incoming, "agent", now(), newId, names.agent());
|
|
18345
18450
|
current = merged.file;
|
|
18346
18451
|
warnings = merged.warnings;
|
|
18347
18452
|
if (`${JSON.stringify(current, null, 2)}
|
|
@@ -18359,13 +18464,13 @@ function createCommentStore(file, names = noNames, now = () => (/* @__PURE__ */
|
|
|
18359
18464
|
sync,
|
|
18360
18465
|
apply: (op) => {
|
|
18361
18466
|
sync();
|
|
18362
|
-
current =
|
|
18467
|
+
current = rules.human(current, op, now(), newId, names.human());
|
|
18363
18468
|
write();
|
|
18364
18469
|
return current;
|
|
18365
18470
|
},
|
|
18366
18471
|
applyAgent: (op, name) => {
|
|
18367
18472
|
sync();
|
|
18368
|
-
const result =
|
|
18473
|
+
const result = rules.agent(current, op, now(), newId, name ?? names.agent());
|
|
18369
18474
|
current = result.file;
|
|
18370
18475
|
write();
|
|
18371
18476
|
return result;
|
|
@@ -18373,38 +18478,166 @@ function createCommentStore(file, names = noNames, now = () => (/* @__PURE__ */
|
|
|
18373
18478
|
};
|
|
18374
18479
|
}
|
|
18375
18480
|
|
|
18376
|
-
// src/server/
|
|
18377
|
-
var
|
|
18378
|
-
|
|
18379
|
-
|
|
18380
|
-
|
|
18381
|
-
|
|
18382
|
-
|
|
18383
|
-
|
|
18384
|
-
|
|
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) {
|
|
18385
18512
|
try {
|
|
18386
|
-
const
|
|
18387
|
-
|
|
18388
|
-
|
|
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
|
+
));
|
|
18389
18517
|
} catch {
|
|
18390
18518
|
return {};
|
|
18391
18519
|
}
|
|
18392
18520
|
}
|
|
18393
|
-
|
|
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
|
+
};
|
|
18394
18597
|
return {
|
|
18395
|
-
|
|
18396
|
-
|
|
18397
|
-
|
|
18398
|
-
|
|
18399
|
-
|
|
18400
|
-
|
|
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);
|
|
18401
18630
|
}
|
|
18402
18631
|
};
|
|
18403
18632
|
}
|
|
18404
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
|
+
|
|
18405
18638
|
// src/server/document-session.ts
|
|
18406
18639
|
var import_promises = __toESM(require("node:fs/promises"), 1);
|
|
18407
|
-
var
|
|
18640
|
+
var import_node_path8 = __toESM(require("node:path"), 1);
|
|
18408
18641
|
|
|
18409
18642
|
// node_modules/.pnpm/lexical@0.52.0_typescript@5.9.3/node_modules/lexical/dist/Lexical.dev.js
|
|
18410
18643
|
var Lexical_dev_exports = {};
|
|
@@ -19262,19 +19495,19 @@ var ElementDOMSlot = class _ElementDOMSlot extends DOMSlot {
|
|
|
19262
19495
|
}
|
|
19263
19496
|
};
|
|
19264
19497
|
function indexPath(root, child) {
|
|
19265
|
-
const
|
|
19498
|
+
const path22 = [];
|
|
19266
19499
|
let node = child;
|
|
19267
19500
|
for (; node !== root && node !== null; node = node.parentNode) {
|
|
19268
19501
|
let i6 = 0;
|
|
19269
19502
|
for (let sibling = node.previousSibling; sibling !== null; sibling = sibling.previousSibling) {
|
|
19270
19503
|
i6++;
|
|
19271
19504
|
}
|
|
19272
|
-
|
|
19505
|
+
path22.push(i6);
|
|
19273
19506
|
}
|
|
19274
19507
|
if (!(node === root)) {
|
|
19275
19508
|
formatDevErrorMessage(`indexPath: root is not a parent of child`);
|
|
19276
19509
|
}
|
|
19277
|
-
return
|
|
19510
|
+
return path22.reverse();
|
|
19278
19511
|
}
|
|
19279
19512
|
// @__NO_SIDE_EFFECTS__
|
|
19280
19513
|
function readLexicalVersion() {
|
|
@@ -34054,9 +34287,9 @@ function getActiveElementDeep(root) {
|
|
|
34054
34287
|
function getComposedEventTarget(event) {
|
|
34055
34288
|
const target = event.target;
|
|
34056
34289
|
if (target !== null && isHTMLElement(target) && target.shadowRoot !== null && typeof event.composedPath === "function") {
|
|
34057
|
-
const
|
|
34058
|
-
if (
|
|
34059
|
-
return
|
|
34290
|
+
const path22 = event.composedPath();
|
|
34291
|
+
if (path22.length > 0) {
|
|
34292
|
+
return path22[0];
|
|
34060
34293
|
}
|
|
34061
34294
|
}
|
|
34062
34295
|
return target;
|
|
@@ -35967,7 +36200,7 @@ __export(Lexical_prod_exports, {
|
|
|
35967
36200
|
$getNodeFromDOMNode: () => Qc,
|
|
35968
36201
|
$getPreviousSelection: () => ds,
|
|
35969
36202
|
$getRoot: () => ra,
|
|
35970
|
-
$getSelection: () =>
|
|
36203
|
+
$getSelection: () => fs9,
|
|
35971
36204
|
$getSelectionSlotFrame: () => Df,
|
|
35972
36205
|
$getSiblingCaret: () => ad,
|
|
35973
36206
|
$getSlot: () => Lf,
|
|
@@ -36707,9 +36940,9 @@ function Ct(t7, e5, n7) {
|
|
|
36707
36940
|
const o8 = performance.now() - _t > 100;
|
|
36708
36941
|
try {
|
|
36709
36942
|
al(t7, () => {
|
|
36710
|
-
const r7 =
|
|
36943
|
+
const r7 = fs9() || (function(t8) {
|
|
36711
36944
|
return t8.read("latest", () => {
|
|
36712
|
-
const t9 =
|
|
36945
|
+
const t9 = fs9();
|
|
36713
36946
|
return null !== t9 ? t9.clone() : null;
|
|
36714
36947
|
});
|
|
36715
36948
|
})(t7), i6 = /* @__PURE__ */ new Map(), s7 = t7._editorState, l8 = t7._blockCursorElement;
|
|
@@ -37989,7 +38222,7 @@ function Yo(t7, n7, o8) {
|
|
|
37989
38222
|
al(n7, () => {
|
|
37990
38223
|
if (!o8) return void sa(null);
|
|
37991
38224
|
if (!Dc(n7, r7, s7)) return;
|
|
37992
|
-
let a5 =
|
|
38225
|
+
let a5 = fs9();
|
|
37993
38226
|
if (c10.postDeleteSelectionToRestore && zi(a5) && a5.isCollapsed()) {
|
|
37994
38227
|
const t8 = a5.anchor, e5 = c10.postDeleteSelectionToRestore.anchor;
|
|
37995
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));
|
|
@@ -38031,7 +38264,7 @@ function Xo(t7, e5) {
|
|
|
38031
38264
|
}
|
|
38032
38265
|
function Qo(t7, e5) {
|
|
38033
38266
|
al(e5, () => {
|
|
38034
|
-
const n7 =
|
|
38267
|
+
const n7 = fs9(), o8 = Qa(Wa(e5)), r7 = ds();
|
|
38035
38268
|
if (o8) {
|
|
38036
38269
|
if (zi(n7)) {
|
|
38037
38270
|
const t8 = n7.anchor, e6 = t8.getNode();
|
|
@@ -38080,7 +38313,7 @@ function er(t7) {
|
|
|
38080
38313
|
if (null == t7 || t7.length <= 1 || null == e5) return;
|
|
38081
38314
|
const n7 = 1 === e5.length ? e5 : "Enter" === e5 ? "\n" : "Tab" === e5 ? " " : null;
|
|
38082
38315
|
if (!n7) return;
|
|
38083
|
-
const o8 =
|
|
38316
|
+
const o8 = fs9();
|
|
38084
38317
|
if (!zi(o8) || !o8.isCollapsed()) return;
|
|
38085
38318
|
const r7 = o8.anchor.getNode();
|
|
38086
38319
|
if (!ki(r7)) return;
|
|
@@ -38112,7 +38345,7 @@ function rr(t7, e5) {
|
|
|
38112
38345
|
return null !== r7 && o8.contains(r7) && Ju(r7, e5);
|
|
38113
38346
|
}
|
|
38114
38347
|
function ir(t7) {
|
|
38115
|
-
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();
|
|
38116
38349
|
if ("insertText" === n7 && t7.data && i6.isInsertTextAfterHandledSelectionCommand) {
|
|
38117
38350
|
if (nr(i6), t7.preventDefault(), zi(s7) && !s7.isCollapsed()) {
|
|
38118
38351
|
const t8 = s7.isBackward() ? s7.anchor : s7.focus;
|
|
@@ -38146,7 +38379,7 @@ function ir(t7) {
|
|
|
38146
38379
|
let u9 = m && n8 && !a6 && c11;
|
|
38147
38380
|
if (u9 && s7.isCollapsed() && (u9 = !Sl(Ea(s7.anchor, true))), !u9) {
|
|
38148
38381
|
Ma(r7, jn, true);
|
|
38149
|
-
const t8 =
|
|
38382
|
+
const t8 = fs9();
|
|
38150
38383
|
m && zi(t8) && t8.isCollapsed() && (i6.postDeleteSelectionToRestore = t8, setTimeout(() => i6.postDeleteSelectionToRestore = null));
|
|
38151
38384
|
}
|
|
38152
38385
|
}
|
|
@@ -38246,7 +38479,7 @@ function sr(t7, e5) {
|
|
|
38246
38479
|
}, { event: t7 }), n7.unprocessedBeforeInputData = null;
|
|
38247
38480
|
}
|
|
38248
38481
|
function lr(t7) {
|
|
38249
|
-
const e5 = Vs(), n7 = e5._inputState, o8 =
|
|
38482
|
+
const e5 = Vs(), n7 = e5._inputState, o8 = fs9(), r7 = t7.data, i6 = tr(t7);
|
|
38250
38483
|
let s7 = false;
|
|
38251
38484
|
if (null != r7 && zi(o8)) {
|
|
38252
38485
|
const l8 = Qa(Wa(e5)), c10 = null !== l8 ? cu(l8, e5._rootElement) : null, a5 = "insertCompositionText" === t7.inputType && "ending-firefox" !== n7.compositionPhase && !e5.isComposing();
|
|
@@ -38271,13 +38504,13 @@ function cr(t7, e5) {
|
|
|
38271
38504
|
Ma(e5, Wn, t7);
|
|
38272
38505
|
}
|
|
38273
38506
|
function ar(t7) {
|
|
38274
|
-
const e5 = Vs(), n7 = e5._inputState, o8 =
|
|
38507
|
+
const e5 = Vs(), n7 = e5._inputState, o8 = fs9();
|
|
38275
38508
|
if (zi(o8) && !e5.isComposing()) {
|
|
38276
38509
|
n7.compositionPhase = "composing", n7.hadOrphanedCompositionEvents = false;
|
|
38277
38510
|
const r7 = o8.anchor, i6 = o8.anchor.getNode();
|
|
38278
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())) {
|
|
38279
38512
|
Ma(e5, Jn, F);
|
|
38280
|
-
const t8 =
|
|
38513
|
+
const t8 = fs9();
|
|
38281
38514
|
zi(t8) && Yc(t8.anchor.key);
|
|
38282
38515
|
}
|
|
38283
38516
|
}
|
|
@@ -38291,7 +38524,7 @@ function fr(t7) {
|
|
|
38291
38524
|
if (null === t7) return;
|
|
38292
38525
|
const e5 = Xc(t7);
|
|
38293
38526
|
if (!ki(e5) || "text" === e5.getType() || Bc(e5) || !e5.isAttached()) return;
|
|
38294
|
-
const n7 =
|
|
38527
|
+
const n7 = fs9(), o8 = zi(n7) && n7.anchor.key === t7 ? n7.anchor.offset : null, r7 = vi(e5.getTextContent());
|
|
38295
38528
|
if (r7.setFormat(e5.getFormat()), r7.setStyle(e5.getStyle()), e5.replace(r7), null !== o8) {
|
|
38296
38529
|
const t8 = Math.min(o8, r7.getTextContentSize());
|
|
38297
38530
|
r7.select(t8, t8);
|
|
@@ -38310,7 +38543,7 @@ function dr(t7, e5) {
|
|
|
38310
38543
|
return fr(n7), false;
|
|
38311
38544
|
}
|
|
38312
38545
|
if ("\n" === e5[e5.length - 1]) {
|
|
38313
|
-
const e6 =
|
|
38546
|
+
const e6 = fs9();
|
|
38314
38547
|
if (zi(e6) || Bi(e6)) {
|
|
38315
38548
|
if (zi(e6)) {
|
|
38316
38549
|
const t8 = e6.focus;
|
|
@@ -38322,7 +38555,7 @@ function dr(t7, e5) {
|
|
|
38322
38555
|
const o8 = Xc(n7);
|
|
38323
38556
|
if (null !== o8 && ki(o8) && Bc(o8)) {
|
|
38324
38557
|
o8.markDirty();
|
|
38325
|
-
const t8 =
|
|
38558
|
+
const t8 = fs9(), r7 = o8.getTextContentSize(), i6 = zi(t8) && t8.anchor.key === n7 ? t8.anchor.offset : r7;
|
|
38326
38559
|
return o8.select(i6, i6).insertText(e5), true;
|
|
38327
38560
|
}
|
|
38328
38561
|
}
|
|
@@ -38449,7 +38682,7 @@ function wr(t7, n7, o8) {
|
|
|
38449
38682
|
const r7 = t7.__key, i6 = t7.getParent();
|
|
38450
38683
|
if (null === i6) return void (null !== Of(t7) && e(367, r7, String(Of(t7))));
|
|
38451
38684
|
const s7 = (function(t8) {
|
|
38452
|
-
const e5 =
|
|
38685
|
+
const e5 = fs9();
|
|
38453
38686
|
if (!zi(e5) || !yl(t8)) return e5;
|
|
38454
38687
|
const { anchor: n8, focus: o9 } = e5, r8 = n8.getNode(), i7 = o9.getNode();
|
|
38455
38688
|
return Ba(r8, t8) && n8.set(t8.__key, 0, "element"), Ba(i7, t8) && o9.set(t8.__key, 0, "element"), e5;
|
|
@@ -38521,7 +38754,7 @@ var Fr = class {
|
|
|
38521
38754
|
return false;
|
|
38522
38755
|
}
|
|
38523
38756
|
isSelected(t7) {
|
|
38524
|
-
const e5 = t7 ||
|
|
38757
|
+
const e5 = t7 || fs9();
|
|
38525
38758
|
if (null == e5) return false;
|
|
38526
38759
|
const n7 = e5.getNodes().some((t8) => t8.__key === this.__key);
|
|
38527
38760
|
if (ki(this)) return n7;
|
|
@@ -38711,7 +38944,7 @@ var Fr = class {
|
|
|
38711
38944
|
}
|
|
38712
38945
|
replace(t7, n7) {
|
|
38713
38946
|
Ws();
|
|
38714
|
-
let o8 =
|
|
38947
|
+
let o8 = fs9();
|
|
38715
38948
|
null !== o8 && (o8 = o8.clone()), qa(this, t7);
|
|
38716
38949
|
const r7 = this.getLatest(), i6 = this.__key, s7 = Mf(r7);
|
|
38717
38950
|
null !== s7 && e(400, i6, r7.getType(), s7.getKey(), s7.getType());
|
|
@@ -38731,7 +38964,7 @@ var Fr = class {
|
|
|
38731
38964
|
Ws(), qa(this, t7);
|
|
38732
38965
|
const n7 = this.getWritable(), o8 = t7.getWritable();
|
|
38733
38966
|
this.getParentOrThrow();
|
|
38734
|
-
const r7 = o8.getParent(), i6 =
|
|
38967
|
+
const r7 = o8.getParent(), i6 = fs9();
|
|
38735
38968
|
let s7 = false, l8 = false, c10 = -1;
|
|
38736
38969
|
if (null !== r7 && e5 && zi(i6) && hs(i6, r7)) {
|
|
38737
38970
|
const e6 = r7.__key, n8 = i6.anchor, o9 = i6.focus;
|
|
@@ -38752,7 +38985,7 @@ var Fr = class {
|
|
|
38752
38985
|
Ws(), qa(this, t7);
|
|
38753
38986
|
const n7 = this.getWritable(), o8 = t7.getWritable();
|
|
38754
38987
|
this.getParentOrThrow();
|
|
38755
|
-
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;
|
|
38756
38989
|
Jc(o8), l8 && null !== s7 && zi(i6) && gs(i6, s7, c10, -1);
|
|
38757
38990
|
const a5 = this.getPreviousSibling(), u8 = this.getParentOrThrow().getWritable(), f6 = n7.__prev, d9 = e5 && zi(i6) && hs(i6, u8), h9 = d9 ? this.getIndexWithinParent() : -1;
|
|
38758
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;
|
|
@@ -39150,7 +39383,7 @@ var hi = class extends Fr {
|
|
|
39150
39383
|
select(t7, e5) {
|
|
39151
39384
|
Ws();
|
|
39152
39385
|
let n7 = t7, o8 = e5;
|
|
39153
|
-
const r7 =
|
|
39386
|
+
const r7 = fs9(), i6 = this.getTextContent(), s7 = this.__key;
|
|
39154
39387
|
if ("string" == typeof i6) {
|
|
39155
39388
|
const t8 = i6.length;
|
|
39156
39389
|
void 0 === n7 && (n7 = t8), void 0 === o8 && (o8 = t8);
|
|
@@ -39173,7 +39406,7 @@ var hi = class extends Fr {
|
|
|
39173
39406
|
const r7 = this.getWritable(), i6 = r7.__text, s7 = n7.length;
|
|
39174
39407
|
let l8 = t7;
|
|
39175
39408
|
l8 < 0 && (l8 = s7 + l8, l8 < 0 && (l8 = 0));
|
|
39176
|
-
const c10 =
|
|
39409
|
+
const c10 = fs9();
|
|
39177
39410
|
if (o8 && zi(c10)) {
|
|
39178
39411
|
const e6 = t7 + s7;
|
|
39179
39412
|
c10.setTextNodeRange(r7, e6, r7, e6);
|
|
@@ -39204,7 +39437,7 @@ var hi = class extends Fr {
|
|
|
39204
39437
|
let f6;
|
|
39205
39438
|
const d9 = e5.getFormat(), h9 = e5.getStyle(), g8 = e5.__detail;
|
|
39206
39439
|
let _5 = false, p7 = null, y5 = null;
|
|
39207
|
-
const m11 =
|
|
39440
|
+
const m11 = fs9();
|
|
39208
39441
|
if (zi(m11)) {
|
|
39209
39442
|
const [t8, e6] = m11.isBackward() ? [m11.focus, m11.anchor] : [m11.anchor, m11.focus];
|
|
39210
39443
|
"text" === t8.type && t8.key === o8 && (p7 = t8), "text" === e6.type && e6.key === o8 && (y5 = e6);
|
|
@@ -39243,7 +39476,7 @@ var hi = class extends Fr {
|
|
|
39243
39476
|
n7 || t7 === this.getNextSibling() || e(50);
|
|
39244
39477
|
const o8 = this.__key, r7 = t7.__key, i6 = this.__text, s7 = i6.length;
|
|
39245
39478
|
Gc() === r7 && Yc(o8);
|
|
39246
|
-
const l8 =
|
|
39479
|
+
const l8 = fs9();
|
|
39247
39480
|
if (zi(l8)) {
|
|
39248
39481
|
const e5 = l8.anchor, i7 = l8.focus;
|
|
39249
39482
|
null !== e5 && e5.key === r7 && ys(e5, n7, o8, t7, s7), null !== i7 && i7.key === r7 && ys(i7, n7, o8, t7, s7);
|
|
@@ -39530,7 +39763,7 @@ var Ii = class _Ii {
|
|
|
39530
39763
|
}
|
|
39531
39764
|
deleteNodes() {
|
|
39532
39765
|
const t7 = this.getNodes().filter((t8) => null === Of(t8));
|
|
39533
|
-
if ((
|
|
39766
|
+
if ((fs9() || ds()) === this && t7[0]) {
|
|
39534
39767
|
const e5 = ad(t7[0], "next");
|
|
39535
39768
|
Kl(vd(e5, e5));
|
|
39536
39769
|
}
|
|
@@ -39540,7 +39773,7 @@ var Ii = class _Ii {
|
|
|
39540
39773
|
};
|
|
39541
39774
|
function Li() {
|
|
39542
39775
|
const t7 = ra();
|
|
39543
|
-
if (0 === t7.getChildrenSize() && null === Df(
|
|
39776
|
+
if (0 === t7.getChildrenSize() && null === Df(fs9())) {
|
|
39544
39777
|
const e5 = oc();
|
|
39545
39778
|
t7.append(e5), e5.select();
|
|
39546
39779
|
}
|
|
@@ -39667,8 +39900,8 @@ var Ki = class _Ki {
|
|
|
39667
39900
|
else {
|
|
39668
39901
|
const t8 = vi(r7.getTextContent());
|
|
39669
39902
|
t8.setFormat(n7), t8.setStyle(o8);
|
|
39670
|
-
const e6 =
|
|
39671
|
-
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);
|
|
39672
39905
|
}
|
|
39673
39906
|
return void ("" !== t7 && this.insertText(t7));
|
|
39674
39907
|
}
|
|
@@ -39703,14 +39936,14 @@ var Ki = class _Ki {
|
|
|
39703
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);
|
|
39704
39937
|
}
|
|
39705
39938
|
removeText() {
|
|
39706
|
-
const t7 =
|
|
39939
|
+
const t7 = fs9() === this, e5 = this.anchor.key;
|
|
39707
39940
|
Bl(this, Ul(Rl(this))), this.isCollapsed() && (function(t8, e6) {
|
|
39708
39941
|
const n7 = t8.anchor;
|
|
39709
39942
|
if (n7.key === e6) return;
|
|
39710
39943
|
const o8 = n7.getNode();
|
|
39711
39944
|
let r7 = 0, i6 = "";
|
|
39712
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);
|
|
39713
|
-
})(this, e5), t7 &&
|
|
39946
|
+
})(this, e5), t7 && fs9() !== this && sa(this);
|
|
39714
39947
|
}
|
|
39715
39948
|
formatText(t7, e5 = null) {
|
|
39716
39949
|
$i(this, t7, e5);
|
|
@@ -39727,7 +39960,7 @@ var Ki = class _Ki {
|
|
|
39727
39960
|
}
|
|
39728
39961
|
if (null !== o9) {
|
|
39729
39962
|
o9.selectStart();
|
|
39730
|
-
const n8 =
|
|
39963
|
+
const n8 = fs9();
|
|
39731
39964
|
return zi(n8) || e(369), n8.insertNodes(t7);
|
|
39732
39965
|
}
|
|
39733
39966
|
}
|
|
@@ -40321,7 +40554,7 @@ function us(t7, e5, n7, o8) {
|
|
|
40321
40554
|
const x9 = new Ki(g8, _5, y5, m11);
|
|
40322
40555
|
return p7 && (x9.dirty = true), x9;
|
|
40323
40556
|
}
|
|
40324
|
-
function
|
|
40557
|
+
function fs9() {
|
|
40325
40558
|
return js()._selection;
|
|
40326
40559
|
}
|
|
40327
40560
|
function ds() {
|
|
@@ -40491,7 +40724,7 @@ function Ss(t7, e5, n7, o8, r7, i6) {
|
|
|
40491
40724
|
}
|
|
40492
40725
|
}
|
|
40493
40726
|
function Cs(t7) {
|
|
40494
|
-
let e5 =
|
|
40727
|
+
let e5 = fs9() || ds();
|
|
40495
40728
|
null === e5 && (e5 = ra().selectEnd()), e5.insertNodes(t7);
|
|
40496
40729
|
}
|
|
40497
40730
|
function vs(t7, e5) {
|
|
@@ -40502,7 +40735,7 @@ function ks(t7) {
|
|
|
40502
40735
|
return vs(t7, { linebreak: () => e5.push(Al()), tab: () => e5.push(wi()), text: (t8) => e5.push(vi(t8)) }), e5;
|
|
40503
40736
|
}
|
|
40504
40737
|
function bs() {
|
|
40505
|
-
const t7 =
|
|
40738
|
+
const t7 = fs9();
|
|
40506
40739
|
return null === t7 ? "" : t7.getTextContent();
|
|
40507
40740
|
}
|
|
40508
40741
|
function Ts(t7) {
|
|
@@ -40513,7 +40746,7 @@ function Ts(t7) {
|
|
|
40513
40746
|
function Ns(t7, n7 = false) {
|
|
40514
40747
|
let o8 = t7;
|
|
40515
40748
|
t7.isCollapsed() || o8.removeText();
|
|
40516
|
-
const r7 =
|
|
40749
|
+
const r7 = fs9();
|
|
40517
40750
|
zi(r7) && (o8 = r7), zi(o8) || e(161);
|
|
40518
40751
|
const i6 = o8.anchor;
|
|
40519
40752
|
let s7 = i6.getNode(), l8 = i6.offset;
|
|
@@ -41196,7 +41429,7 @@ var pl = class extends Fr {
|
|
|
41196
41429
|
}
|
|
41197
41430
|
select(t7, e5) {
|
|
41198
41431
|
Ws();
|
|
41199
|
-
const n7 =
|
|
41432
|
+
const n7 = fs9();
|
|
41200
41433
|
let o8 = t7, r7 = e5;
|
|
41201
41434
|
const i6 = this.getChildrenSize();
|
|
41202
41435
|
if (!this.canBeEmpty()) {
|
|
@@ -41293,7 +41526,7 @@ var pl = class extends Fr {
|
|
|
41293
41526
|
} else t8.__prev = null;
|
|
41294
41527
|
}
|
|
41295
41528
|
if (i6.__size = f6, c10.length) {
|
|
41296
|
-
const t8 =
|
|
41529
|
+
const t8 = fs9();
|
|
41297
41530
|
if (zi(t8)) {
|
|
41298
41531
|
const e5 = new Set(c10), n8 = new Set(l8), { anchor: o9, focus: r8 } = t8;
|
|
41299
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();
|
|
@@ -41576,7 +41809,7 @@ function zl(t7, n7) {
|
|
|
41576
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"));
|
|
41577
41810
|
}
|
|
41578
41811
|
function Kl(t7) {
|
|
41579
|
-
const e5 =
|
|
41812
|
+
const e5 = fs9(), n7 = zi(e5) ? e5 : ls();
|
|
41580
41813
|
return Bl(n7, t7), sa(n7), n7;
|
|
41581
41814
|
}
|
|
41582
41815
|
function Bl(t7, e5) {
|
|
@@ -42196,7 +42429,7 @@ var vc = class {
|
|
|
42196
42429
|
focus(t7, e5 = {}) {
|
|
42197
42430
|
const n7 = this._rootElement;
|
|
42198
42431
|
null !== n7 && (n7.setAttribute("autocapitalize", "off"), al(this, () => {
|
|
42199
|
-
const o8 =
|
|
42432
|
+
const o8 = fs9(), r7 = ra();
|
|
42200
42433
|
null !== o8 ? o8.dirty || sa(o8.clone()) : 0 !== r7.getChildrenSize() && ("rootStart" === e5.defaultSelection ? r7.selectStart() : r7.selectEnd()), za("focus"), Ka(() => {
|
|
42201
42434
|
n7.removeAttribute("autocapitalize"), t7 && t7();
|
|
42202
42435
|
});
|
|
@@ -42458,7 +42691,7 @@ function ga(t7, e5, n7, o8, r7) {
|
|
|
42458
42691
|
}
|
|
42459
42692
|
const c10 = i6.getTextContent();
|
|
42460
42693
|
if (r7 || l8 !== c10) {
|
|
42461
|
-
const e6 =
|
|
42694
|
+
const e6 = fs9();
|
|
42462
42695
|
if ("" === l8) {
|
|
42463
42696
|
if (Yc(null), p || g || x) i6.remove();
|
|
42464
42697
|
else {
|
|
@@ -44152,10 +44385,10 @@ function _loadWasmModule(sync, filepath, src, imports2) {
|
|
|
44152
44385
|
var buf = null;
|
|
44153
44386
|
var isNode2 = typeof process !== "undefined" && process.versions != null && process.versions.node != null;
|
|
44154
44387
|
if (filepath && isNode2) {
|
|
44155
|
-
var
|
|
44156
|
-
var
|
|
44388
|
+
var fs28 = null;
|
|
44389
|
+
var path22 = null;
|
|
44157
44390
|
return new Promise((resolve, reject) => {
|
|
44158
|
-
|
|
44391
|
+
fs28.readFile(path22.resolve(__dirname, filepath), (error, buffer) => {
|
|
44159
44392
|
if (error != null) {
|
|
44160
44393
|
reject(error);
|
|
44161
44394
|
} else {
|
|
@@ -45458,10 +45691,10 @@ var LoroDoc = class _LoroDoc {
|
|
|
45458
45691
|
* @param {string} path
|
|
45459
45692
|
* @returns {Value | Container | undefined}
|
|
45460
45693
|
*/
|
|
45461
|
-
getByPath(
|
|
45694
|
+
getByPath(path22) {
|
|
45462
45695
|
try {
|
|
45463
45696
|
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
45464
|
-
const ptr0 = passStringToWasm0(
|
|
45697
|
+
const ptr0 = passStringToWasm0(path22, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
45465
45698
|
const len0 = WASM_VECTOR_LEN;
|
|
45466
45699
|
wasm.lorodoc_getByPath(retptr, this.__wbg_ptr, ptr0, len0);
|
|
45467
45700
|
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
@@ -87436,7 +87669,7 @@ async function readText(file) {
|
|
|
87436
87669
|
}
|
|
87437
87670
|
}
|
|
87438
87671
|
async function writeAtomic(file, data) {
|
|
87439
|
-
await import_promises.default.mkdir(
|
|
87672
|
+
await import_promises.default.mkdir(import_node_path8.default.dirname(file), { recursive: true });
|
|
87440
87673
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
87441
87674
|
await import_promises.default.writeFile(tmp, data);
|
|
87442
87675
|
await import_promises.default.rename(tmp, file);
|
|
@@ -87645,13 +87878,13 @@ function outcomeWarnings(outcome, streaming) {
|
|
|
87645
87878
|
function createDocumentRegistry(options) {
|
|
87646
87879
|
const sessions = /* @__PURE__ */ new Map();
|
|
87647
87880
|
const warnings = /* @__PURE__ */ new Map();
|
|
87648
|
-
const docFile = (id2) =>
|
|
87881
|
+
const docFile = (id2) => import_node_path9.default.join(options.root, "document", id2, "doc.xml");
|
|
87649
87882
|
const commentStores = /* @__PURE__ */ new Map();
|
|
87650
87883
|
const cursors = createCommentCursors(options.stateDir);
|
|
87651
87884
|
const commentStore = (id2) => {
|
|
87652
87885
|
let store = commentStores.get(id2);
|
|
87653
87886
|
if (!store) {
|
|
87654
|
-
store = createCommentStore(
|
|
87887
|
+
store = createCommentStore(import_node_path9.default.join(options.root, "document", id2, "comments.json"), options.names);
|
|
87655
87888
|
commentStores.set(id2, store);
|
|
87656
87889
|
}
|
|
87657
87890
|
return store;
|
|
@@ -87665,10 +87898,10 @@ function createDocumentRegistry(options) {
|
|
|
87665
87898
|
if (JSON.stringify(store.warnings()) !== before2) options.onWarningsChange(id2);
|
|
87666
87899
|
};
|
|
87667
87900
|
const create3 = async (id2) => {
|
|
87668
|
-
if (!
|
|
87901
|
+
if (!import_node_fs9.default.existsSync(docFile(id2))) return null;
|
|
87669
87902
|
const session = await createDocumentSession({
|
|
87670
87903
|
file: docFile(id2),
|
|
87671
|
-
snapshotFile:
|
|
87904
|
+
snapshotFile: import_node_path9.default.join(options.stateDir, "document", id2, "doc.loro"),
|
|
87672
87905
|
...options.timing,
|
|
87673
87906
|
log: options.log
|
|
87674
87907
|
});
|
|
@@ -87711,7 +87944,7 @@ function createDocumentRegistry(options) {
|
|
|
87711
87944
|
const known = sessions.has(id2);
|
|
87712
87945
|
void open(id2).then((session) => {
|
|
87713
87946
|
if (!session || !known) return;
|
|
87714
|
-
|
|
87947
|
+
import_node_fs9.default.readFile(docFile(id2), "utf8", (err, text2) => {
|
|
87715
87948
|
if (!err) session.onFileText(text2);
|
|
87716
87949
|
});
|
|
87717
87950
|
});
|
|
@@ -88275,9 +88508,9 @@ function injectRuntime(html, options = {}) {
|
|
|
88275
88508
|
}
|
|
88276
88509
|
|
|
88277
88510
|
// src/server/http.ts
|
|
88278
|
-
var
|
|
88279
|
-
var
|
|
88280
|
-
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);
|
|
88281
88514
|
var MIME2 = {
|
|
88282
88515
|
".html": "text/html; charset=utf-8",
|
|
88283
88516
|
".js": "text/javascript; charset=utf-8",
|
|
@@ -88300,12 +88533,12 @@ var MIME2 = {
|
|
|
88300
88533
|
".mp4": "video/mp4",
|
|
88301
88534
|
".webm": "video/webm"
|
|
88302
88535
|
};
|
|
88303
|
-
var mimeOf = (file) => MIME2[
|
|
88304
|
-
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");
|
|
88305
88538
|
function safeEqual(a5, b6) {
|
|
88306
88539
|
const ab = Buffer.from(a5);
|
|
88307
88540
|
const bb = Buffer.from(b6);
|
|
88308
|
-
return ab.length === bb.length &&
|
|
88541
|
+
return ab.length === bb.length && import_node_crypto3.default.timingSafeEqual(ab, bb);
|
|
88309
88542
|
}
|
|
88310
88543
|
function parseCookies(header) {
|
|
88311
88544
|
const cookies = {};
|
|
@@ -88317,7 +88550,7 @@ function parseCookies(header) {
|
|
|
88317
88550
|
}
|
|
88318
88551
|
function readPersisted(file) {
|
|
88319
88552
|
try {
|
|
88320
|
-
return
|
|
88553
|
+
return import_node_fs10.default.readFileSync(file, "utf8").trim();
|
|
88321
88554
|
} catch {
|
|
88322
88555
|
return "";
|
|
88323
88556
|
}
|
|
@@ -88346,15 +88579,15 @@ function sendJson(res, status, value) {
|
|
|
88346
88579
|
send(res, status, JSON.stringify(value), { "Content-Type": MIME2[".json"] });
|
|
88347
88580
|
}
|
|
88348
88581
|
function sendFile(res, file, headers = {}) {
|
|
88349
|
-
|
|
88582
|
+
import_node_fs10.default.readFile(file, (err, data) => {
|
|
88350
88583
|
if (err) send(res, 404, "Not found");
|
|
88351
88584
|
else send(res, 200, data, { "Content-Type": mimeOf(file), ...headers });
|
|
88352
88585
|
});
|
|
88353
88586
|
}
|
|
88354
88587
|
|
|
88355
88588
|
// src/server/dynamic-blocks.ts
|
|
88356
|
-
var
|
|
88357
|
-
var
|
|
88589
|
+
var import_node_fs11 = __toESM(require("node:fs"), 1);
|
|
88590
|
+
var import_node_path11 = __toESM(require("node:path"), 1);
|
|
88358
88591
|
function dynamicUrls(xml) {
|
|
88359
88592
|
const urls = /* @__PURE__ */ new Set();
|
|
88360
88593
|
for (const match of stripOpaque(xml).matchAll(TAG)) {
|
|
@@ -88367,7 +88600,7 @@ function dynamicUrls(xml) {
|
|
|
88367
88600
|
}
|
|
88368
88601
|
var mtimeOf = (file) => {
|
|
88369
88602
|
try {
|
|
88370
|
-
return
|
|
88603
|
+
return import_node_fs11.default.statSync(file).mtimeMs;
|
|
88371
88604
|
} catch {
|
|
88372
88605
|
return -1;
|
|
88373
88606
|
}
|
|
@@ -88384,7 +88617,7 @@ function createDynamicBlocks(limits) {
|
|
|
88384
88617
|
};
|
|
88385
88618
|
const entry = (id2, dir, file) => {
|
|
88386
88619
|
const map = files(id2);
|
|
88387
|
-
const mtime = mtimeOf(
|
|
88620
|
+
const mtime = mtimeOf(import_node_path11.default.join(dir, file));
|
|
88388
88621
|
let state = map.get(file);
|
|
88389
88622
|
if (!state || state.mtime !== mtime) {
|
|
88390
88623
|
state = { mtime, errors: [], ran: false };
|
|
@@ -88409,19 +88642,19 @@ function createDynamicBlocks(limits) {
|
|
|
88409
88642
|
state(id2, dir) {
|
|
88410
88643
|
let xml = "";
|
|
88411
88644
|
try {
|
|
88412
|
-
xml =
|
|
88645
|
+
xml = import_node_fs11.default.readFileSync(import_node_path11.default.join(dir, "doc.xml"), "utf8");
|
|
88413
88646
|
} catch {
|
|
88414
88647
|
return { warnings: [], dynamic: {} };
|
|
88415
88648
|
}
|
|
88416
88649
|
const urls = dynamicUrls(xml);
|
|
88417
88650
|
const map = files(id2);
|
|
88418
88651
|
for (const [file, state] of map) {
|
|
88419
|
-
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);
|
|
88420
88653
|
}
|
|
88421
88654
|
const warnings = [];
|
|
88422
88655
|
const dynamic = {};
|
|
88423
88656
|
for (const url of urls) {
|
|
88424
|
-
if (!
|
|
88657
|
+
if (!import_node_fs11.default.existsSync(import_node_path11.default.join(dir, url))) warnings.push(`${url} not found`);
|
|
88425
88658
|
const state = map.get(url);
|
|
88426
88659
|
for (const error of state?.errors ?? []) warnings.push(`runtime: ${url}: ${error}`);
|
|
88427
88660
|
dynamic[url] = { ran: state?.ran ?? false };
|
|
@@ -88432,8 +88665,8 @@ function createDynamicBlocks(limits) {
|
|
|
88432
88665
|
}
|
|
88433
88666
|
|
|
88434
88667
|
// src/server/selection.ts
|
|
88435
|
-
var
|
|
88436
|
-
var
|
|
88668
|
+
var import_node_fs12 = __toESM(require("node:fs"), 1);
|
|
88669
|
+
var import_node_path12 = __toESM(require("node:path"), 1);
|
|
88437
88670
|
|
|
88438
88671
|
// src/shared/selection.ts
|
|
88439
88672
|
var SELECTION_FULL_NODES = 20;
|
|
@@ -88508,14 +88741,14 @@ function readAnySelection(value) {
|
|
|
88508
88741
|
function createSelectionStore(stateDir, exists) {
|
|
88509
88742
|
const tabs = /* @__PURE__ */ new Map();
|
|
88510
88743
|
let clock = 0;
|
|
88511
|
-
const fileOf = (kind, id2) =>
|
|
88744
|
+
const fileOf = (kind, id2) => import_node_path12.default.join(stateDir, kind, id2, "selection.json");
|
|
88512
88745
|
const write = (kind, id2) => {
|
|
88513
88746
|
let winner;
|
|
88514
88747
|
for (const tab of tabs.values()) {
|
|
88515
88748
|
if (tab.kind !== kind || tab.id !== id2) continue;
|
|
88516
88749
|
if (!winner || tab.humanAt > winner.humanAt || tab.humanAt === winner.humanAt && tab.seenAt > winner.seenAt) winner = tab;
|
|
88517
88750
|
}
|
|
88518
|
-
if (!winner?.state)
|
|
88751
|
+
if (!winner?.state) import_node_fs12.default.rmSync(fileOf(kind, id2), { force: true });
|
|
88519
88752
|
else writeJsonAtomic(fileOf(kind, id2), { artifact: `${kind}/${id2}`, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), ...winner.state });
|
|
88520
88753
|
};
|
|
88521
88754
|
return {
|
|
@@ -88546,19 +88779,19 @@ function createSelectionStore(stateDir, exists) {
|
|
|
88546
88779
|
for (const kind of ["artboard", "document"]) {
|
|
88547
88780
|
let ids = [];
|
|
88548
88781
|
try {
|
|
88549
|
-
ids =
|
|
88782
|
+
ids = import_node_fs12.default.readdirSync(import_node_path12.default.join(stateDir, kind));
|
|
88550
88783
|
} catch {
|
|
88551
88784
|
continue;
|
|
88552
88785
|
}
|
|
88553
|
-
for (const id2 of ids)
|
|
88786
|
+
for (const id2 of ids) import_node_fs12.default.rmSync(fileOf(kind, id2), { force: true });
|
|
88554
88787
|
}
|
|
88555
88788
|
}
|
|
88556
88789
|
};
|
|
88557
88790
|
}
|
|
88558
88791
|
|
|
88559
88792
|
// src/server/config.ts
|
|
88560
|
-
var
|
|
88561
|
-
var
|
|
88793
|
+
var import_node_fs13 = __toESM(require("node:fs"), 1);
|
|
88794
|
+
var import_node_path13 = __toESM(require("node:path"), 1);
|
|
88562
88795
|
|
|
88563
88796
|
// src/shared/cloud.ts
|
|
88564
88797
|
var ownLink = (url, hostId) => hostId ? `${url}#ryugi-host=${hostId}` : url;
|
|
@@ -88593,7 +88826,7 @@ function normalize(raw) {
|
|
|
88593
88826
|
function readConfig(file) {
|
|
88594
88827
|
let text2;
|
|
88595
88828
|
try {
|
|
88596
|
-
text2 =
|
|
88829
|
+
text2 = import_node_fs13.default.readFileSync(file, "utf8");
|
|
88597
88830
|
} catch {
|
|
88598
88831
|
return { config: defaults() };
|
|
88599
88832
|
}
|
|
@@ -88604,22 +88837,22 @@ function readConfig(file) {
|
|
|
88604
88837
|
}
|
|
88605
88838
|
}
|
|
88606
88839
|
function ensureGitignore(dir) {
|
|
88607
|
-
const file =
|
|
88840
|
+
const file = import_node_path13.default.join(dir, ".gitignore");
|
|
88608
88841
|
let current = "";
|
|
88609
88842
|
try {
|
|
88610
|
-
current =
|
|
88843
|
+
current = import_node_fs13.default.readFileSync(file, "utf8");
|
|
88611
88844
|
} catch {
|
|
88612
|
-
|
|
88845
|
+
import_node_fs13.default.writeFileSync(file, "config.json\n");
|
|
88613
88846
|
return;
|
|
88614
88847
|
}
|
|
88615
88848
|
if (current.split(/\r?\n/).some((line) => line.trim() === "config.json")) return;
|
|
88616
|
-
|
|
88849
|
+
import_node_fs13.default.writeFileSync(file, `${current}${current === "" || current.endsWith("\n") ? "" : "\n"}config.json
|
|
88617
88850
|
`);
|
|
88618
88851
|
}
|
|
88619
88852
|
function ensureConfig(file) {
|
|
88620
|
-
|
|
88621
|
-
ensureGitignore(
|
|
88622
|
-
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());
|
|
88623
88856
|
}
|
|
88624
88857
|
function updateArtifactConfig(file, key2, patch) {
|
|
88625
88858
|
const { config, warning } = readConfig(file);
|
|
@@ -88639,21 +88872,21 @@ function setProjectAutoPublish(file, value) {
|
|
|
88639
88872
|
if (warning) throw new Error(warning);
|
|
88640
88873
|
if (value === null) delete config.autoPublish;
|
|
88641
88874
|
else config.autoPublish = value;
|
|
88642
|
-
|
|
88875
|
+
import_node_fs13.default.mkdirSync(import_node_path13.default.dirname(file), { recursive: true });
|
|
88643
88876
|
writeJsonAtomic(file, config);
|
|
88644
88877
|
}
|
|
88645
88878
|
|
|
88646
88879
|
// src/server/credentials.ts
|
|
88647
|
-
var
|
|
88648
|
-
var
|
|
88880
|
+
var import_node_fs14 = __toESM(require("node:fs"), 1);
|
|
88881
|
+
var import_node_path14 = __toESM(require("node:path"), 1);
|
|
88649
88882
|
function credentialsFile(env, platform, home) {
|
|
88650
|
-
if (platform === "win32" && env.APPDATA) return
|
|
88651
|
-
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");
|
|
88652
88885
|
}
|
|
88653
88886
|
function readCredentials(file, origin) {
|
|
88654
88887
|
let raw;
|
|
88655
88888
|
try {
|
|
88656
|
-
raw = JSON.parse(
|
|
88889
|
+
raw = JSON.parse(import_node_fs14.default.readFileSync(file, "utf8"));
|
|
88657
88890
|
} catch {
|
|
88658
88891
|
return null;
|
|
88659
88892
|
}
|
|
@@ -88664,11 +88897,11 @@ function readCredentials(file, origin) {
|
|
|
88664
88897
|
return { origin: savedOrigin, token, login };
|
|
88665
88898
|
}
|
|
88666
88899
|
function writeCredentials(file, credentials) {
|
|
88667
|
-
|
|
88900
|
+
import_node_fs14.default.mkdirSync(import_node_path14.default.dirname(file), { recursive: true, mode: 448 });
|
|
88668
88901
|
writeJsonAtomic(file, credentials);
|
|
88669
88902
|
}
|
|
88670
88903
|
function clearCredentials(file) {
|
|
88671
|
-
|
|
88904
|
+
import_node_fs14.default.rmSync(file, { force: true });
|
|
88672
88905
|
}
|
|
88673
88906
|
|
|
88674
88907
|
// node_modules/.pnpm/ws@8.18.3/node_modules/ws/wrapper.mjs
|
|
@@ -88796,7 +89029,7 @@ function createRelayClient(options) {
|
|
|
88796
89029
|
}
|
|
88797
89030
|
|
|
88798
89031
|
// src/server/ws.ts
|
|
88799
|
-
var
|
|
89032
|
+
var import_node_crypto4 = __toESM(require("node:crypto"), 1);
|
|
88800
89033
|
var WS_MAGIC = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
|
88801
89034
|
var OPCODE_TEXT = 1;
|
|
88802
89035
|
var OPCODE_CLOSE = 8;
|
|
@@ -88804,7 +89037,7 @@ var OPCODE_PING = 9;
|
|
|
88804
89037
|
var OPCODE_PONG = 10;
|
|
88805
89038
|
var MAX_CLIENT_FRAME = 8 * 1024 * 1024;
|
|
88806
89039
|
function acceptKey(clientKey) {
|
|
88807
|
-
return
|
|
89040
|
+
return import_node_crypto4.default.createHash("sha1").update(clientKey + WS_MAGIC).digest("base64");
|
|
88808
89041
|
}
|
|
88809
89042
|
function encodeFrame(opcode, payload) {
|
|
88810
89043
|
const len = payload.length;
|
|
@@ -88929,21 +89162,21 @@ function createDirectRelay(options) {
|
|
|
88929
89162
|
}
|
|
88930
89163
|
|
|
88931
89164
|
// src/server/host-id.ts
|
|
88932
|
-
var
|
|
88933
|
-
var
|
|
89165
|
+
var import_node_fs15 = __toESM(require("node:fs"), 1);
|
|
89166
|
+
var import_node_path15 = __toESM(require("node:path"), 1);
|
|
88934
89167
|
function hostIdFor(credentialsFile2) {
|
|
88935
|
-
const file =
|
|
89168
|
+
const file = import_node_path15.default.join(import_node_path15.default.dirname(credentialsFile2), "host-id");
|
|
88936
89169
|
const saved = readPersisted(file);
|
|
88937
89170
|
if (/^[A-Za-z0-9_-]{16,64}$/.test(saved)) return saved;
|
|
88938
89171
|
const id2 = randomToken();
|
|
88939
|
-
|
|
88940
|
-
|
|
89172
|
+
import_node_fs15.default.mkdirSync(import_node_path15.default.dirname(file), { recursive: true, mode: 448 });
|
|
89173
|
+
import_node_fs15.default.writeFileSync(file, `${id2}
|
|
88941
89174
|
`, { mode: 384 });
|
|
88942
89175
|
return id2;
|
|
88943
89176
|
}
|
|
88944
89177
|
|
|
88945
89178
|
// src/server/avatars.ts
|
|
88946
|
-
var
|
|
89179
|
+
var import_node_crypto5 = require("node:crypto");
|
|
88947
89180
|
var AVATAR_ROUTE = /^\/api\/avatar\/([a-z]+)\/([^/]+)$/;
|
|
88948
89181
|
var MAX_BYTES = 512 * 1024;
|
|
88949
89182
|
var TIMEOUT_MS = 5e3;
|
|
@@ -88952,7 +89185,7 @@ var SOURCES = {
|
|
|
88952
89185
|
gravatar: { valid: /^[0-9a-f]{64}$/, url: (id2) => `https://gravatar.com/avatar/${id2}?s=64&d=404` }
|
|
88953
89186
|
};
|
|
88954
89187
|
var githubAvatar = (login) => `/api/avatar/github/${login}`;
|
|
88955
|
-
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")}`;
|
|
88956
89189
|
function createAvatars(fetchImpl = fetch) {
|
|
88957
89190
|
const cache = /* @__PURE__ */ new Map();
|
|
88958
89191
|
const fetchAvatar = async (url) => {
|
|
@@ -88984,7 +89217,7 @@ function createAvatars(fetchImpl = fetch) {
|
|
|
88984
89217
|
}
|
|
88985
89218
|
|
|
88986
89219
|
// src/server/cloud.ts
|
|
88987
|
-
var
|
|
89220
|
+
var import_node_crypto6 = __toESM(require("node:crypto"), 1);
|
|
88988
89221
|
|
|
88989
89222
|
// src/shared/brand.ts
|
|
88990
89223
|
var RYUGI_MARK_VIEWBOX = "0 0 512 512";
|
|
@@ -89094,32 +89327,32 @@ function callbackPage(result) {
|
|
|
89094
89327
|
}
|
|
89095
89328
|
|
|
89096
89329
|
// src/server/pack.ts
|
|
89097
|
-
var
|
|
89098
|
-
var
|
|
89330
|
+
var import_node_fs16 = __toESM(require("node:fs"), 1);
|
|
89331
|
+
var import_node_path16 = __toESM(require("node:path"), 1);
|
|
89099
89332
|
var MAX_ARTIFACT_BYTES = 20 * 1024 * 1024;
|
|
89100
89333
|
function formatBytes(bytes) {
|
|
89101
89334
|
if (bytes < 1024) return `${bytes} B`;
|
|
89102
89335
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
89103
89336
|
return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
|
|
89104
89337
|
}
|
|
89105
|
-
var excluded = (type, relative) => type === "document" && relative === "comments.json";
|
|
89338
|
+
var excluded = (type, relative) => (type === "document" || type === "artboard") && relative === "comments.json";
|
|
89106
89339
|
function packArtifact(dir, type, { maxBytes = MAX_ARTIFACT_BYTES } = {}) {
|
|
89107
|
-
const rootReal =
|
|
89340
|
+
const rootReal = import_node_fs16.default.realpathSync(dir);
|
|
89108
89341
|
const found = [];
|
|
89109
89342
|
const visited = /* @__PURE__ */ new Set([rootReal]);
|
|
89110
89343
|
let total = 0;
|
|
89111
89344
|
const walk = (current) => {
|
|
89112
|
-
for (const entry of
|
|
89345
|
+
for (const entry of import_node_fs16.default.readdirSync(current, { withFileTypes: true })) {
|
|
89113
89346
|
if (entry.name.startsWith(".")) continue;
|
|
89114
|
-
const full =
|
|
89347
|
+
const full = import_node_path16.default.join(current, entry.name);
|
|
89115
89348
|
let real;
|
|
89116
89349
|
try {
|
|
89117
|
-
real =
|
|
89350
|
+
real = import_node_fs16.default.realpathSync(full);
|
|
89118
89351
|
} catch {
|
|
89119
89352
|
continue;
|
|
89120
89353
|
}
|
|
89121
|
-
if (!real.startsWith(rootReal +
|
|
89122
|
-
const stat =
|
|
89354
|
+
if (!real.startsWith(rootReal + import_node_path16.default.sep)) continue;
|
|
89355
|
+
const stat = import_node_fs16.default.statSync(real);
|
|
89123
89356
|
if (stat.isDirectory()) {
|
|
89124
89357
|
if (visited.has(real)) continue;
|
|
89125
89358
|
visited.add(real);
|
|
@@ -89127,7 +89360,7 @@ function packArtifact(dir, type, { maxBytes = MAX_ARTIFACT_BYTES } = {}) {
|
|
|
89127
89360
|
continue;
|
|
89128
89361
|
}
|
|
89129
89362
|
if (!stat.isFile()) continue;
|
|
89130
|
-
const relative =
|
|
89363
|
+
const relative = import_node_path16.default.relative(dir, full).split(import_node_path16.default.sep).join("/");
|
|
89131
89364
|
if (excluded(type, relative)) continue;
|
|
89132
89365
|
total += stat.size;
|
|
89133
89366
|
found.push({ path: relative, real });
|
|
@@ -89137,12 +89370,12 @@ function packArtifact(dir, type, { maxBytes = MAX_ARTIFACT_BYTES } = {}) {
|
|
|
89137
89370
|
if (total > maxBytes) {
|
|
89138
89371
|
throw new Error(`artifact is ${formatBytes(total)}; the limit is ${formatBytes(maxBytes)}`);
|
|
89139
89372
|
}
|
|
89140
|
-
return found.map((file) => ({ path: file.path, data:
|
|
89373
|
+
return found.map((file) => ({ path: file.path, data: import_node_fs16.default.readFileSync(file.real) }));
|
|
89141
89374
|
}
|
|
89142
89375
|
|
|
89143
89376
|
// src/server/publish-payload.ts
|
|
89144
|
-
var
|
|
89145
|
-
var
|
|
89377
|
+
var import_node_fs17 = __toESM(require("node:fs"), 1);
|
|
89378
|
+
var import_node_path17 = __toESM(require("node:path"), 1);
|
|
89146
89379
|
var CLOUD_RUNTIME_URL = "/_ryugi/runtime/ryugi-ui.js";
|
|
89147
89380
|
function sharedComments(file) {
|
|
89148
89381
|
return {
|
|
@@ -89155,7 +89388,7 @@ function publishPayload(ref, dir, title, payload, comments = emptyComments()) {
|
|
|
89155
89388
|
const { canvas, layout, versions } = payload;
|
|
89156
89389
|
return { canvas, layout, versions };
|
|
89157
89390
|
}
|
|
89158
|
-
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) };
|
|
89159
89392
|
return { title };
|
|
89160
89393
|
}
|
|
89161
89394
|
var isPage = (type, file) => type === "html" ? file === "index.html" : (type === "document" || type === "artboard") && file.endsWith(".html");
|
|
@@ -89166,12 +89399,12 @@ function withCloudRuntime(type, files) {
|
|
|
89166
89399
|
}
|
|
89167
89400
|
|
|
89168
89401
|
// src/server/settings.ts
|
|
89169
|
-
var
|
|
89170
|
-
var
|
|
89171
|
-
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");
|
|
89172
89405
|
function readSettings(file) {
|
|
89173
89406
|
try {
|
|
89174
|
-
const raw = JSON.parse(
|
|
89407
|
+
const raw = JSON.parse(import_node_fs18.default.readFileSync(file, "utf8"));
|
|
89175
89408
|
return typeof raw === "object" && raw !== null && !Array.isArray(raw) ? raw : {};
|
|
89176
89409
|
} catch {
|
|
89177
89410
|
return {};
|
|
@@ -89182,7 +89415,7 @@ function readGlobalAutoPublish(file) {
|
|
|
89182
89415
|
return typeof value === "boolean" ? value : void 0;
|
|
89183
89416
|
}
|
|
89184
89417
|
function writeGlobalAutoPublish(file, value) {
|
|
89185
|
-
|
|
89418
|
+
import_node_fs18.default.mkdirSync(import_node_path18.default.dirname(file), { recursive: true, mode: 448 });
|
|
89186
89419
|
writeJsonAtomic(file, { ...readSettings(file), autoPublish: value });
|
|
89187
89420
|
}
|
|
89188
89421
|
function defaultGlobalAutoPublish(file) {
|
|
@@ -89254,10 +89487,10 @@ function createCloudRoutes(options) {
|
|
|
89254
89487
|
const state = randomToken();
|
|
89255
89488
|
const verifier = randomToken();
|
|
89256
89489
|
pendingStates.set(state, { expires: now + LOGIN_STATE_TTL_MS, verifier });
|
|
89257
|
-
const challenge =
|
|
89490
|
+
const challenge = import_node_crypto6.default.createHash("sha256").update(verifier).digest("base64url");
|
|
89258
89491
|
return `${origin}/auth/cli?port=${options.port()}&state=${state}&challenge=${challenge}`;
|
|
89259
89492
|
};
|
|
89260
|
-
const cloudFetch = async (method,
|
|
89493
|
+
const cloudFetch = async (method, path22, body) => {
|
|
89261
89494
|
const credentials = readCredentials(credentialsFile2, origin);
|
|
89262
89495
|
if (!credentials) throw new SignedOut();
|
|
89263
89496
|
const headers = { Authorization: `Bearer ${credentials.token}` };
|
|
@@ -89271,7 +89504,7 @@ function createCloudRoutes(options) {
|
|
|
89271
89504
|
}
|
|
89272
89505
|
let res;
|
|
89273
89506
|
try {
|
|
89274
|
-
res = await fetch(`${origin}${
|
|
89507
|
+
res = await fetch(`${origin}${path22}`, { method, headers, body: payload });
|
|
89275
89508
|
} catch (err) {
|
|
89276
89509
|
throw new CloudRefused(502, `could not reach ${origin}: ${err.message}`);
|
|
89277
89510
|
}
|
|
@@ -89328,9 +89561,9 @@ function createCloudRoutes(options) {
|
|
|
89328
89561
|
}
|
|
89329
89562
|
const key2 = `${ref.type}/${ref.id}`;
|
|
89330
89563
|
const entry = artifactEntry(key2);
|
|
89331
|
-
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") }));
|
|
89332
89565
|
const byHash = new Map(hashed.map((file) => [file.hash, file.data]));
|
|
89333
|
-
const manifest = hashed.map(({ path:
|
|
89566
|
+
const manifest = hashed.map(({ path: path22, hash }) => ({ path: path22, hash }));
|
|
89334
89567
|
const version2 = (visibility) => ({ title: inspected.title, payload: inspected.payload, files: manifest, project, ...visibility ? { visibility } : {} });
|
|
89335
89568
|
const create3 = () => createRecord2(ref, requested ?? entry.visibility ?? "private");
|
|
89336
89569
|
const upload = async (id2, hashes) => {
|
|
@@ -89553,7 +89786,7 @@ function createCloudRoutes(options) {
|
|
|
89553
89786
|
|
|
89554
89787
|
// src/server/comment-names.ts
|
|
89555
89788
|
var import_node_child_process = require("node:child_process");
|
|
89556
|
-
var
|
|
89789
|
+
var import_node_fs19 = __toESM(require("node:fs"), 1);
|
|
89557
89790
|
|
|
89558
89791
|
// src/server/agent.ts
|
|
89559
89792
|
var NAMES = {
|
|
@@ -89634,7 +89867,7 @@ function commentNames({ agentFile, projectDir, cloud }) {
|
|
|
89634
89867
|
},
|
|
89635
89868
|
agent: () => {
|
|
89636
89869
|
try {
|
|
89637
|
-
return detectAgent(JSON.parse(
|
|
89870
|
+
return detectAgent(JSON.parse(import_node_fs19.default.readFileSync(agentFile, "utf8")));
|
|
89638
89871
|
} catch {
|
|
89639
89872
|
return void 0;
|
|
89640
89873
|
}
|
|
@@ -89662,8 +89895,8 @@ function viewerPage(template, page) {
|
|
|
89662
89895
|
}
|
|
89663
89896
|
|
|
89664
89897
|
// src/server/auto-publish.ts
|
|
89665
|
-
var
|
|
89666
|
-
var
|
|
89898
|
+
var import_node_crypto7 = __toESM(require("node:crypto"), 1);
|
|
89899
|
+
var import_node_fs20 = __toESM(require("node:fs"), 1);
|
|
89667
89900
|
var SIGNED_OUT_MESSAGE = "auto-publish paused: the Ryugi Cloud sign-in expired";
|
|
89668
89901
|
function isNotice(value) {
|
|
89669
89902
|
if (typeof value !== "object" || value === null) return false;
|
|
@@ -89673,7 +89906,7 @@ function isNotice(value) {
|
|
|
89673
89906
|
function readAutoPublishState(file) {
|
|
89674
89907
|
let raw = {};
|
|
89675
89908
|
try {
|
|
89676
|
-
const parsed = JSON.parse(
|
|
89909
|
+
const parsed = JSON.parse(import_node_fs20.default.readFileSync(file, "utf8"));
|
|
89677
89910
|
if (typeof parsed === "object" && parsed !== null) raw = parsed;
|
|
89678
89911
|
} catch {
|
|
89679
89912
|
}
|
|
@@ -89693,7 +89926,7 @@ function createAutoPublisher(options) {
|
|
|
89693
89926
|
const remarked = /* @__PURE__ */ new Set();
|
|
89694
89927
|
const save = () => writeJsonAtomic(options.stateFile, { dirty: [...dirty], notice, paused });
|
|
89695
89928
|
const raise = (kind, message) => {
|
|
89696
|
-
if (notice?.kind !== kind) notice = { id:
|
|
89929
|
+
if (notice?.kind !== kind) notice = { id: import_node_crypto7.default.randomUUID(), kind, message };
|
|
89697
89930
|
};
|
|
89698
89931
|
const run2 = async () => {
|
|
89699
89932
|
if (!options.enabled() || dirty.size === 0) return;
|
|
@@ -89753,7 +89986,7 @@ function createAutoPublisher(options) {
|
|
|
89753
89986
|
}
|
|
89754
89987
|
|
|
89755
89988
|
// src/server/artifact-file.ts
|
|
89756
|
-
var
|
|
89989
|
+
var import_node_fs21 = __toESM(require("node:fs"), 1);
|
|
89757
89990
|
var RESOLVE = { artboard: resolveBoardFile, document: resolveDocumentAsset, html: resolveHtmlFile };
|
|
89758
89991
|
var isArtifactPage = (type, relative) => type === "html" ? relative === "index.html" : relative.endsWith(".html");
|
|
89759
89992
|
function readArtifactFile(dir, type, relative, uiRuntimeUrl) {
|
|
@@ -89762,7 +89995,7 @@ function readArtifactFile(dir, type, relative, uiRuntimeUrl) {
|
|
|
89762
89995
|
if (!target) return null;
|
|
89763
89996
|
let data;
|
|
89764
89997
|
try {
|
|
89765
|
-
data =
|
|
89998
|
+
data = import_node_fs21.default.readFileSync(target);
|
|
89766
89999
|
} catch {
|
|
89767
90000
|
return null;
|
|
89768
90001
|
}
|
|
@@ -89772,25 +90005,25 @@ function readArtifactFile(dir, type, relative, uiRuntimeUrl) {
|
|
|
89772
90005
|
}
|
|
89773
90006
|
|
|
89774
90007
|
// src/server/watch.ts
|
|
89775
|
-
var
|
|
89776
|
-
var
|
|
89777
|
-
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("/");
|
|
89778
90011
|
var ignored = (file) => file === ".state" || file.startsWith(".state/");
|
|
89779
90012
|
function snapshot(root, dir = root, out = /* @__PURE__ */ new Map()) {
|
|
89780
90013
|
let entries2;
|
|
89781
90014
|
try {
|
|
89782
|
-
entries2 =
|
|
90015
|
+
entries2 = import_node_fs22.default.readdirSync(dir, { withFileTypes: true });
|
|
89783
90016
|
} catch {
|
|
89784
90017
|
return out;
|
|
89785
90018
|
}
|
|
89786
90019
|
for (const entry of entries2) {
|
|
89787
|
-
const full =
|
|
89788
|
-
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));
|
|
89789
90022
|
if (ignored(rel)) continue;
|
|
89790
90023
|
if (entry.isDirectory()) snapshot(root, full, out);
|
|
89791
90024
|
else {
|
|
89792
90025
|
try {
|
|
89793
|
-
out.set(rel,
|
|
90026
|
+
out.set(rel, import_node_fs22.default.statSync(full).mtimeMs);
|
|
89794
90027
|
} catch {
|
|
89795
90028
|
}
|
|
89796
90029
|
}
|
|
@@ -89823,7 +90056,7 @@ function watchTree(root, onChange, debounceMs = 120, backupPollMs = 1e3) {
|
|
|
89823
90056
|
}, debounceMs);
|
|
89824
90057
|
};
|
|
89825
90058
|
try {
|
|
89826
|
-
const watcher =
|
|
90059
|
+
const watcher = import_node_fs22.default.watch(root, { recursive: true }, (_event, filename) => {
|
|
89827
90060
|
if (filename) queue([toPosix(filename.toString())]);
|
|
89828
90061
|
});
|
|
89829
90062
|
watcher.on("error", () => {
|
|
@@ -89873,6 +90106,8 @@ var API_PREVIEW_ROUTE = /^\/api\/preview\/([^/]+)\/([^/]+)$/;
|
|
|
89873
90106
|
var API_DOCUMENT_ROUTE = /^\/api\/document\/([^/]+)\/(state|update|comments)$/;
|
|
89874
90107
|
var MAX_COMMENT_OP = 64 * 1024;
|
|
89875
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$/;
|
|
89876
90111
|
var MAX_DOCUMENT_UPDATE = 8 * 1024 * 1024;
|
|
89877
90112
|
var MAX_RELAY_FILE = 8 * 1024 * 1024;
|
|
89878
90113
|
var MAX_RUNTIME_MESSAGE = 2048;
|
|
@@ -89891,17 +90126,17 @@ function titleOf(payload, ref) {
|
|
|
89891
90126
|
return payload.canvas?.title || ref.id;
|
|
89892
90127
|
}
|
|
89893
90128
|
async function startArtifactsServer(options) {
|
|
89894
|
-
const root =
|
|
89895
|
-
const viewerDir =
|
|
89896
|
-
const runtimeDir = options.runtimeDir ?
|
|
89897
|
-
const stateDir =
|
|
89898
|
-
|
|
89899
|
-
|
|
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");
|
|
89900
90135
|
if (options.configFile) ensureConfig(options.configFile);
|
|
89901
|
-
const portFile =
|
|
89902
|
-
const tokenFile =
|
|
90136
|
+
const portFile = import_node_path20.default.join(stateDir, ".last-port");
|
|
90137
|
+
const tokenFile = import_node_path20.default.join(stateDir, ".last-token");
|
|
89903
90138
|
const token = readPersisted(tokenFile) || randomToken();
|
|
89904
|
-
|
|
90139
|
+
import_node_fs23.default.writeFileSync(tokenFile, `${token}
|
|
89905
90140
|
`, { mode: 384 });
|
|
89906
90141
|
const contentToken = randomToken();
|
|
89907
90142
|
const runtimeWarnings = /* @__PURE__ */ new Map();
|
|
@@ -89931,7 +90166,8 @@ async function startArtifactsServer(options) {
|
|
|
89931
90166
|
direct.emit(message.artifact, message);
|
|
89932
90167
|
};
|
|
89933
90168
|
const avatars = createAvatars(options.fetch);
|
|
89934
|
-
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 });
|
|
89935
90171
|
const documents = createDocumentRegistry({
|
|
89936
90172
|
root,
|
|
89937
90173
|
stateDir,
|
|
@@ -89969,8 +90205,8 @@ async function startArtifactsServer(options) {
|
|
|
89969
90205
|
}
|
|
89970
90206
|
return { dir, title, reasons, payload: published };
|
|
89971
90207
|
};
|
|
89972
|
-
const cloud = options.cloud && options.configFile ? createCloudRoutes({ ...options.cloud, configFile: options.configFile, project:
|
|
89973
|
-
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;
|
|
89974
90210
|
const sameOrigin = (req) => {
|
|
89975
90211
|
const origin2 = req.headers.origin;
|
|
89976
90212
|
const host = req.headers.host ?? "";
|
|
@@ -90049,7 +90285,7 @@ async function startArtifactsServer(options) {
|
|
|
90049
90285
|
};
|
|
90050
90286
|
const blockIdsOf = async (id2, dir) => {
|
|
90051
90287
|
await (await documents.open(id2))?.flush();
|
|
90052
|
-
const state = parseDocument2(
|
|
90288
|
+
const state = parseDocument2(import_node_fs23.default.readFileSync(import_node_path20.default.join(dir, "doc.xml"), "utf8"));
|
|
90053
90289
|
return new Set(state.root.children.flatMap((block) => block.$?.blockId ? [block.$.blockId] : []));
|
|
90054
90290
|
};
|
|
90055
90291
|
const serveAgentComments = async (req, res, id2) => {
|
|
@@ -90089,6 +90325,55 @@ async function startArtifactsServer(options) {
|
|
|
90089
90325
|
sendJson(res, 400, { error: err.message });
|
|
90090
90326
|
}
|
|
90091
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
|
+
};
|
|
90092
90377
|
const isAuthorized = (req, keyFromQuery) => keyFromQuery !== null && safeEqual(keyFromQuery, token) || safeEqual(parseCookies(req.headers.cookie)[cookieName] ?? "", token);
|
|
90093
90378
|
const serveContent = (res, rest) => {
|
|
90094
90379
|
if (rest.startsWith("runtime/")) {
|
|
@@ -90129,7 +90414,7 @@ async function startArtifactsServer(options) {
|
|
|
90129
90414
|
sendFile(res, target, headers);
|
|
90130
90415
|
return;
|
|
90131
90416
|
}
|
|
90132
|
-
|
|
90417
|
+
import_node_fs23.default.readFile(target, "utf8", (err, source) => {
|
|
90133
90418
|
if (err) send(res, 404, "Not found");
|
|
90134
90419
|
else {
|
|
90135
90420
|
const uiRuntimeUrl = runtimeDir ? `${contentPrefix}runtime/ryugi-ui.js` : void 0;
|
|
@@ -90140,6 +90425,7 @@ async function startArtifactsServer(options) {
|
|
|
90140
90425
|
const artifactMeta = (ref, dir, contentOrigin = "") => ({
|
|
90141
90426
|
...readArtifact(dir, ref, runtimeOf(ref, dir)),
|
|
90142
90427
|
...ref.type !== "html" ? { agent: names.agent() } : {},
|
|
90428
|
+
...ref.type === "artboard" ? { comments: boardComments.comments(ref.id), staleThreads: boardComments.stale(ref.id) } : {},
|
|
90143
90429
|
contentBase: `${contentOrigin}${contentPrefix}${ref.type}/${ref.id}/`
|
|
90144
90430
|
});
|
|
90145
90431
|
const serveArtifactApi = (res, type, id2) => {
|
|
@@ -90158,7 +90444,7 @@ async function startArtifactsServer(options) {
|
|
|
90158
90444
|
title: titleOf(readArtifact(entry.dir, entry), entry),
|
|
90159
90445
|
updatedAt: latestMtime(entry.dir)
|
|
90160
90446
|
}));
|
|
90161
|
-
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 });
|
|
90162
90448
|
};
|
|
90163
90449
|
function onClientText(socket, text2) {
|
|
90164
90450
|
let message;
|
|
@@ -90220,7 +90506,7 @@ async function startArtifactsServer(options) {
|
|
|
90220
90506
|
return;
|
|
90221
90507
|
}
|
|
90222
90508
|
if (pathname === "/robots.txt") {
|
|
90223
|
-
sendFile(res,
|
|
90509
|
+
sendFile(res, import_node_path20.default.join(viewerDir, "robots.txt"));
|
|
90224
90510
|
return;
|
|
90225
90511
|
}
|
|
90226
90512
|
if (pathname.startsWith("/c/")) {
|
|
@@ -90302,6 +90588,24 @@ async function startArtifactsServer(options) {
|
|
|
90302
90588
|
});
|
|
90303
90589
|
return;
|
|
90304
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
|
+
}
|
|
90305
90609
|
const documentMatch = API_DOCUMENT_ROUTE.exec(pathname);
|
|
90306
90610
|
if (documentMatch) {
|
|
90307
90611
|
void serveDocumentApi(req, res, documentMatch[1], documentMatch[2]).catch((err) => {
|
|
@@ -90317,7 +90621,7 @@ async function startArtifactsServer(options) {
|
|
|
90317
90621
|
if (SHELL_ROUTE.test(pathname) || PREVIEW_ROUTE.test(pathname) || pathname === "/index.html") {
|
|
90318
90622
|
const ref = artifactKeyOf(pathname.replace(/^\/(?:preview\/)?/, "").replace(/\/$/, ""));
|
|
90319
90623
|
const dir = ref && resolveArtifactDir(root, ref.type, ref.id);
|
|
90320
|
-
const project =
|
|
90624
|
+
const project = import_node_path20.default.basename(import_node_path20.default.dirname(import_node_path20.default.dirname(root)));
|
|
90321
90625
|
const title = ref ? dir ? titleOf(readArtifact(dir, ref), ref) : ref.id : `${project} \xB7 Artifacts`;
|
|
90322
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`;
|
|
90323
90627
|
const canonical = `http://${urlHostForHttp(options.urlHost)}:${port}/${ref ? `${ref.type}/${ref.id}` : ""}`;
|
|
@@ -90326,7 +90630,7 @@ async function startArtifactsServer(options) {
|
|
|
90326
90630
|
"Content-Security-Policy": PREVIEW_ROUTE.test(pathname) ? VIEWER_CSP.replace("frame-ancestors 'none'", "frame-ancestors 'self'") : VIEWER_CSP
|
|
90327
90631
|
};
|
|
90328
90632
|
if (key2 !== null) headers["Set-Cookie"] = `${cookieName}=${token}; HttpOnly; SameSite=Strict; Path=/`;
|
|
90329
|
-
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"));
|
|
90330
90634
|
return;
|
|
90331
90635
|
}
|
|
90332
90636
|
const target = resolveInside(viewerDir, pathname.slice(1));
|
|
@@ -90385,7 +90689,7 @@ async function startArtifactsServer(options) {
|
|
|
90385
90689
|
port = await listen(server, options.host, 0);
|
|
90386
90690
|
}
|
|
90387
90691
|
cookieName = `ryugi_artifacts_${port}`;
|
|
90388
|
-
|
|
90692
|
+
import_node_fs23.default.writeFileSync(portFile, `${port}
|
|
90389
90693
|
`, { mode: 384 });
|
|
90390
90694
|
const origin = `http://${urlHostForHttp(options.urlHost)}:${port}`;
|
|
90391
90695
|
const url = `${origin}/?key=${token}`;
|
|
@@ -90402,7 +90706,7 @@ async function startArtifactsServer(options) {
|
|
|
90402
90706
|
return payload;
|
|
90403
90707
|
};
|
|
90404
90708
|
const refreshState = (ref, dir) => {
|
|
90405
|
-
signatures.set(`${ref.type}/${ref.id}`, artifactSignature(dir));
|
|
90709
|
+
signatures.set(`${ref.type}/${ref.id}`, artifactSignature(dir, ref.type));
|
|
90406
90710
|
return writeState(ref, dir);
|
|
90407
90711
|
};
|
|
90408
90712
|
const initialChanges = [];
|
|
@@ -90411,7 +90715,7 @@ async function startArtifactsServer(options) {
|
|
|
90411
90715
|
initialChanges.push({ ref: entry, payload, files: [] });
|
|
90412
90716
|
if (entry.type === "document") void documents.open(entry.id);
|
|
90413
90717
|
}
|
|
90414
|
-
writeJsonAtomic(
|
|
90718
|
+
writeJsonAtomic(import_node_path20.default.join(stateDir, "server-info"), { type: "server-started", url, port, root });
|
|
90415
90719
|
const relayViewers = /* @__PURE__ */ new Map();
|
|
90416
90720
|
const servedArtifacts = () => {
|
|
90417
90721
|
const served = /* @__PURE__ */ new Map();
|
|
@@ -90444,6 +90748,11 @@ async function startArtifactsServer(options) {
|
|
|
90444
90748
|
if (typeof request.message === "object" && request.message !== null) acceptReport({ ...request.message, artifact: key2 });
|
|
90445
90749
|
return null;
|
|
90446
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
|
+
}
|
|
90447
90756
|
if ((request.op === "state" || request.op === "update" || request.op === "comment") && ref.type !== "document") throw new Error(`${key2} is not a document`);
|
|
90448
90757
|
if (request.op === "state" || request.op === "update") {
|
|
90449
90758
|
const session = await documents.open(ref.id);
|
|
@@ -90508,7 +90817,9 @@ async function startArtifactsServer(options) {
|
|
|
90508
90817
|
}
|
|
90509
90818
|
if (ref.type === "document" && (changed.includes("doc.xml") || changed.length === 0)) documents.fileChanged(ref.id);
|
|
90510
90819
|
if (ref.type === "document" && changed.includes("comments.json")) documents.commentsChanged(ref.id);
|
|
90511
|
-
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;
|
|
90512
90823
|
autoPublisher?.changed(key2);
|
|
90513
90824
|
runtimeWarnings.delete(key2);
|
|
90514
90825
|
const payload = refreshState(ref, dir);
|
|
@@ -90552,7 +90863,7 @@ async function startArtifactsServer(options) {
|
|
|
90552
90863
|
}
|
|
90553
90864
|
|
|
90554
90865
|
// src/server/lifecycle.ts
|
|
90555
|
-
var
|
|
90866
|
+
var import_node_fs24 = __toESM(require("node:fs"), 1);
|
|
90556
90867
|
var DEFAULT_IDLE_TIMEOUT_MS = 4 * 60 * 60 * 1e3;
|
|
90557
90868
|
var DEFAULT_LIFECYCLE_CHECK_MS = 60 * 1e3;
|
|
90558
90869
|
var SERVER_ID_ARG = "--artifacts-server-id=";
|
|
@@ -90584,7 +90895,7 @@ function parseEnv(env, argv = []) {
|
|
|
90584
90895
|
function readOwners(file) {
|
|
90585
90896
|
let text2;
|
|
90586
90897
|
try {
|
|
90587
|
-
text2 =
|
|
90898
|
+
text2 = import_node_fs24.default.readFileSync(file, "utf8");
|
|
90588
90899
|
} catch {
|
|
90589
90900
|
return [];
|
|
90590
90901
|
}
|
|
@@ -90647,20 +90958,20 @@ function openReady(payload) {
|
|
|
90647
90958
|
}
|
|
90648
90959
|
|
|
90649
90960
|
// package.json
|
|
90650
|
-
var version = "1.15.
|
|
90961
|
+
var version = "1.15.2";
|
|
90651
90962
|
|
|
90652
90963
|
// src/server/main.ts
|
|
90653
90964
|
async function main() {
|
|
90654
90965
|
const config = parseEnv(process.env, process.argv.slice(2));
|
|
90655
|
-
const root =
|
|
90656
|
-
const stateDir =
|
|
90966
|
+
const root = import_node_path21.default.resolve(config.root);
|
|
90967
|
+
const stateDir = import_node_path21.default.join(root, ".state");
|
|
90657
90968
|
const server = await startArtifactsServer({
|
|
90658
90969
|
root,
|
|
90659
|
-
viewerDir:
|
|
90660
|
-
runtimeDir:
|
|
90970
|
+
viewerDir: import_node_path21.default.join(__dirname, "viewer"),
|
|
90971
|
+
runtimeDir: import_node_path21.default.join(__dirname, "runtime"),
|
|
90661
90972
|
host: config.host,
|
|
90662
90973
|
urlHost: config.urlHost,
|
|
90663
|
-
configFile:
|
|
90974
|
+
configFile: import_node_path21.default.join(import_node_path21.default.dirname(root), "config.json"),
|
|
90664
90975
|
cloud: { origin: config.cloudOrigin, credentialsFile: credentialsFile(process.env, process.platform, import_node_os.default.homedir()) },
|
|
90665
90976
|
relay: { url: `${config.cloudOrigin.replace(/^http/, "ws")}/api/relay/host`, version }
|
|
90666
90977
|
});
|
|
@@ -90690,12 +91001,12 @@ async function main() {
|
|
|
90690
91001
|
if (stopping) return;
|
|
90691
91002
|
stopping = true;
|
|
90692
91003
|
console.log(JSON.stringify({ type: "server-stopped", reason }));
|
|
90693
|
-
|
|
90694
|
-
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() });
|
|
90695
91006
|
await server.close();
|
|
90696
91007
|
process.exit(0);
|
|
90697
91008
|
};
|
|
90698
|
-
const ownersFile =
|
|
91009
|
+
const ownersFile = import_node_path21.default.join(stateDir, "owners");
|
|
90699
91010
|
const timer = setInterval(() => {
|
|
90700
91011
|
const owners = readOwners(ownersFile);
|
|
90701
91012
|
const reason = shutdownReason({
|
|
@@ -90709,7 +91020,7 @@ async function main() {
|
|
|
90709
91020
|
timer.unref();
|
|
90710
91021
|
process.on("SIGTERM", () => void shutdown("SIGTERM"));
|
|
90711
91022
|
process.on("SIGINT", () => void shutdown("SIGINT"));
|
|
90712
|
-
|
|
91023
|
+
import_node_fs25.default.rmSync(import_node_path21.default.join(stateDir, "server-stopped"), { force: true });
|
|
90713
91024
|
console.log(JSON.stringify({ type: "server-started", url: server.url, port: server.port, root }));
|
|
90714
91025
|
}
|
|
90715
91026
|
main().catch((err) => {
|