@fps-games/editor-deployment 0.2.3-beta.5 → 0.2.3-beta.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/fps-editor-agent.mjs +5 -0
- package/bin/fps-editor-prepare.mjs +3 -3
- package/bin/fps-editor-project.mjs +14 -14
- package/bin/fps-editor-server.mjs +1 -1
- package/licenses/THIRD_PARTY_NOTICES.txt +2 -2
- package/manifest.json +225 -219
- package/npm-shrinkwrap.json +4 -3
- package/package.json +7 -6
- package/public/assets/animation-BJ8XM1EP.js.gz +0 -0
- package/public/assets/animationGroup-nIU37qTl.js.gz +0 -0
- package/public/assets/arcRotateCamera-Bpb6_-jM.js.gz +0 -0
- package/public/assets/babylon-core-B6Ot-GOK.js.gz +0 -0
- package/public/assets/babylon-core-DBdQTkWG.js.gz +0 -0
- package/public/assets/basisTextureLoader-xaH1TU2T.js.gz +0 -0
- package/public/assets/bumpVertex-CydMViY3.js.gz +0 -0
- package/public/assets/bumpVertex-bM0VcD-v.js.gz +0 -0
- package/public/assets/chromaticAberration.fragment-2LQpSY6n.js.gz +0 -0
- package/public/assets/chromaticAberration.fragment-CPC2jGBk.js.gz +0 -0
- package/public/assets/circleOfConfusion.fragment-DWehhKOk.js.gz +0 -0
- package/public/assets/circleOfConfusion.fragment-WIeIzKLd.js.gz +0 -0
- package/public/assets/clipPlaneFragment-BQiHvjzo.js.gz +0 -0
- package/public/assets/clipPlaneVertex-D5EB-X5S.js.gz +0 -0
- package/public/assets/color.fragment-0xZe_dSa.js.gz +0 -0
- package/public/assets/color.fragment-BQNpLnxa.js.gz +0 -0
- package/public/assets/color.vertex-0geH1BI8.js.gz +0 -0
- package/public/assets/color.vertex-qtb2-mc5.js.gz +0 -0
- package/public/assets/dds-IzbrFkh8.js.gz +0 -0
- package/public/assets/ddsTextureLoader-D3ROWbwv.js.gz +0 -0
- package/public/assets/default.fragment-BAHNlmD5.js.gz +0 -0
- package/public/assets/default.fragment-D3MA9CRV.js.gz +0 -0
- package/public/assets/default.vertex-B1KwtIUb.js.gz +0 -0
- package/public/assets/default.vertex-Mne8Sq_G.js.gz +0 -0
- package/public/assets/defaultUboDeclaration-00t3po2f.js.gz +0 -0
- package/public/assets/defaultUboDeclaration-DAuovVEA.js.gz +0 -0
- package/public/assets/depth.fragment-Da86gbwP.js.gz +0 -0
- package/public/assets/depth.vertex-DPT_V_9f.js.gz +0 -0
- package/public/assets/depthBoxBlur.fragment-tYNfbhdh.js.gz +0 -0
- package/public/assets/depthBoxBlur.fragment-zrJ9DLe5.js.gz +0 -0
- package/public/assets/depthOfFieldMerge.fragment-Car-ami-.js.gz +0 -0
- package/public/assets/depthOfFieldMerge.fragment-eO7Ot6AR.js.gz +0 -0
- package/public/assets/easing-BdugUZqW.js.gz +0 -0
- package/public/assets/editor-core-plugin-host-c2002442.js.gz +0 -0
- package/public/assets/exrTextureLoader-DYq9r93V.js.gz +0 -0
- package/public/assets/flowGraphArrayIndexBlock-C3zDMjuo.js.gz +0 -0
- package/public/assets/flowGraphBezierCurveEasingBlock-DDoK8_8l.js.gz +0 -0
- package/public/assets/flowGraphBinaryOperationBlock-BKlR9DS-.js.gz +0 -0
- package/public/assets/flowGraphBranchBlock-Bup839Qd.js.gz +0 -0
- package/public/assets/flowGraphCachedOperationBlock-DnmbMTY7.js.gz +0 -0
- package/public/assets/flowGraphCancelDelayBlock-B9MfNdwj.js.gz +0 -0
- package/public/assets/flowGraphCodeExecutionBlock-auEOflkO.js.gz +0 -0
- package/public/assets/flowGraphConditionalDataBlock-BAia9WED.js.gz +0 -0
- package/public/assets/flowGraphConsoleLogBlock--6MvrOCG.js.gz +0 -0
- package/public/assets/flowGraphConstantBlock-FOfDeLIf.js.gz +0 -0
- package/public/assets/flowGraphContextBlock-BP5dmyKZ.js.gz +0 -0
- package/public/assets/flowGraphCounterBlock-DjKMvUGB.js.gz +0 -0
- package/public/assets/flowGraphDataSwitchBlock-gSJm410f.js.gz +0 -0
- package/public/assets/flowGraphDebounceBlock-CO5ptvWG.js.gz +0 -0
- package/public/assets/flowGraphDoNBlock-Bf26kum1.js.gz +0 -0
- package/public/assets/flowGraphEasingBlock-DtnL-aP_.js.gz +0 -0
- package/public/assets/flowGraphFlipFlopBlock-Bh_IN41P.js.gz +0 -0
- package/public/assets/flowGraphForLoopBlock-C3CLz9Iv.js.gz +0 -0
- package/public/assets/flowGraphFunctionReferenceBlock-Bz40tn10.js.gz +0 -0
- package/public/assets/flowGraphGetAssetBlock-DYP1H9Hj.js.gz +0 -0
- package/public/assets/flowGraphGetPropertyBlock-B6XVNxDR.js.gz +0 -0
- package/public/assets/flowGraphGetVariableBlock-BvaNDTu7.js.gz +0 -0
- package/public/assets/flowGraphIndexOfBlock-qm1Ab3oN.js.gz +0 -0
- package/public/assets/flowGraphInterpolationBlock-CmG25tSZ.js.gz +0 -0
- package/public/assets/flowGraphJsonPointerParserBlock-C8rfhc4j.js.gz +0 -0
- package/public/assets/flowGraphMathBlocks-BdiMH3MQ.js.gz +0 -0
- package/public/assets/flowGraphMathCombineExtractBlocks-CXvPWL3b.js.gz +0 -0
- package/public/assets/flowGraphMatrixMathBlocks-Cal7WQ7i.js.gz +0 -0
- package/public/assets/flowGraphMeshPickEventBlock-B8EU7KmL.js.gz +0 -0
- package/public/assets/flowGraphMultiGateBlock-GMcU5jv7.js.gz +0 -0
- package/public/assets/flowGraphPauseAnimationBlock-BKUeGFEQ.js.gz +0 -0
- package/public/assets/flowGraphPlayAnimationBlock-vvCkTY_Z.js.gz +0 -0
- package/public/assets/flowGraphPointerOutEventBlock-EEJ78HAF.js.gz +0 -0
- package/public/assets/flowGraphPointerOverEventBlock-QMzEzISN.js.gz +0 -0
- package/public/assets/flowGraphReceiveCustomEventBlock-B5jEx7xE.js.gz +0 -0
- package/public/assets/flowGraphSceneReadyEventBlock-MjViOZsL.js.gz +0 -0
- package/public/assets/flowGraphSceneTickEventBlock-lyjGPNYo.js.gz +0 -0
- package/public/assets/flowGraphSendCustomEventBlock-M0LLhV7D.js.gz +0 -0
- package/public/assets/flowGraphSequenceBlock-DocFLI4M.js.gz +0 -0
- package/public/assets/flowGraphSetDelayBlock-BDoJj0I_.js.gz +0 -0
- package/public/assets/flowGraphSetPropertyBlock-9jao3AHa.js.gz +0 -0
- package/public/assets/flowGraphSetVariableBlock-buwJMv9v.js.gz +0 -0
- package/public/assets/flowGraphStopAnimationBlock-CDWhmsC8.js.gz +0 -0
- package/public/assets/flowGraphSwitchBlock-DG5ReWET.js.gz +0 -0
- package/public/assets/flowGraphThrottleBlock-Bgyx9UOo.js.gz +0 -0
- package/public/assets/flowGraphTransformCoordinatesSystemBlock-CUUmRj2j.js.gz +0 -0
- package/public/assets/flowGraphTypeToTypeBlocks-D7N8ZT_V.js.gz +0 -0
- package/public/assets/flowGraphUnaryOperationBlock-Bu73VxMC.js.gz +0 -0
- package/public/assets/flowGraphVectorMathBlocks-CqVzbdAw.js.gz +0 -0
- package/public/assets/flowGraphWaitAllBlock-xmBmiluG.js.gz +0 -0
- package/public/assets/flowGraphWhileLoopBlock-Ct2rHXgO.js.gz +0 -0
- package/public/assets/fogFragmentDeclaration-C-9jZMBi.js.gz +0 -0
- package/public/assets/fogFragmentDeclaration-CpAbKvc3.js.gz +0 -0
- package/public/assets/glowBlurPostProcess.fragment-C77x1kl1.js.gz +0 -0
- package/public/assets/glowBlurPostProcess.fragment-C7miknry.js.gz +0 -0
- package/public/assets/glowMapGeneration.fragment-BAqrUGS4.js.gz +0 -0
- package/public/assets/glowMapGeneration.fragment-CMvy-ILZ.js.gz +0 -0
- package/public/assets/glowMapGeneration.vertex-BThT8Jce.js.gz +0 -0
- package/public/assets/glowMapGeneration.vertex-mq9WR5EZ.js.gz +0 -0
- package/public/assets/glowMapMerge.fragment-BtMIQDli.js.gz +0 -0
- package/public/assets/glowMapMerge.fragment-CYj1SIfc.js.gz +0 -0
- package/public/assets/glowMapMerge.vertex-BilMgMCX.js.gz +0 -0
- package/public/assets/glowMapMerge.vertex-ChJNqQPz.js.gz +0 -0
- package/public/assets/grain.fragment-D6WdAOpZ.js.gz +0 -0
- package/public/assets/grain.fragment-DCpxKIZw.js.gz +0 -0
- package/public/assets/harmonicsFunctions-B5nauyTb.js.gz +0 -0
- package/public/assets/harmonicsFunctions-DVIRrUZs.js.gz +0 -0
- package/public/assets/hdrTextureLoader-Dfs_Fv5B.js.gz +0 -0
- package/public/assets/hemisphericLight-BkYyeXbK.js.gz +0 -0
- package/public/assets/iesTextureLoader-I2E-BXCc.js.gz +0 -0
- package/public/assets/index-CzHwtW4R.js.gz +0 -0
- package/public/assets/index-Dk6-vu7X.js +1 -0
- package/public/assets/index-Dk6-vu7X.js.br +0 -0
- package/public/assets/index-Dk6-vu7X.js.gz +0 -0
- package/public/assets/instancesDeclaration-DcwHJpHY.js.gz +0 -0
- package/public/assets/ktxTextureLoader-zpgT--10.js.gz +0 -0
- package/public/assets/lazy-CI-V5lCV.js.gz +0 -0
- package/public/assets/lod.fragment-B28SQFUx.js.gz +0 -0
- package/public/assets/lod.fragment-DOjU_E37.js.gz +0 -0
- package/public/assets/lodCube.fragment-B_ALsGmh.js.gz +0 -0
- package/public/assets/lodCube.fragment-CzeVIOa3.js.gz +0 -0
- package/public/assets/logDepthFragment-BaJ2YjZ0.js.gz +0 -0
- package/public/assets/logDepthVertex-B8jNoEwN.js.gz +0 -0
- package/public/assets/logDepthVertex-xgQTn7wg.js.gz +0 -0
- package/public/assets/mesh.vertexData.functions-BXkNVxNr.js.gz +0 -0
- package/public/assets/meshUboDeclaration-C5p-TivH.js.gz +0 -0
- package/public/assets/meshUboDeclaration-DKldQKni.js.gz +0 -0
- package/public/assets/morphTargetsVertex-BDbfSote.js.gz +0 -0
- package/public/assets/oitFinalSimpleBlend.fragment-DtE63qrD.js.gz +0 -0
- package/public/assets/oitFinalSimpleBlend.fragment-ZwpH3v_v.js.gz +0 -0
- package/public/assets/oitFragment-B8hFhX-8.js.gz +0 -0
- package/public/assets/oitFragment-B_HlWcYZ.js.gz +0 -0
- package/public/assets/openpbrMaterial-t_lYoXh4.js.gz +0 -0
- package/public/assets/outline.fragment-DEsg98mo.js.gz +0 -0
- package/public/assets/outline.fragment-WqsugjI-.js.gz +0 -0
- package/public/assets/outline.vertex-CVL3AfNh.js.gz +0 -0
- package/public/assets/outline.vertex-CtQ-HC3X.js.gz +0 -0
- package/public/assets/passCube.fragment-CHI4OPgd.js.gz +0 -0
- package/public/assets/passCube.fragment-DLbzh6pI.js.gz +0 -0
- package/public/assets/pbr.fragment-DHPEcGrm.js.gz +0 -0
- package/public/assets/pbr.fragment-KiX_RvyZ.js.gz +0 -0
- package/public/assets/pbr.vertex-CVSRg4tx.js.gz +0 -0
- package/public/assets/pbr.vertex-Dp30Rtkl.js.gz +0 -0
- package/public/assets/playable-sdk-Cz5ms1M8.js +8 -0
- package/public/assets/playable-sdk-Cz5ms1M8.js.br +0 -0
- package/public/assets/playable-sdk-Cz5ms1M8.js.gz +0 -0
- package/public/assets/playable-standard-project-CgBNJ6kY.js +5070 -0
- package/public/assets/playable-standard-project-CgBNJ6kY.js.br +0 -0
- package/public/assets/playable-standard-project-CgBNJ6kY.js.gz +0 -0
- package/public/assets/rgbdDecode.fragment-CU4ChTYE.js.gz +0 -0
- package/public/assets/rgbdDecode.fragment-DhrCd3U4.js.gz +0 -0
- package/public/assets/rgbdEncode.fragment-Bt1zaovT.js.gz +0 -0
- package/public/assets/rgbdEncode.fragment-CfKDkRU3.js.gz +0 -0
- package/public/assets/sceneLoader-DS5g2vTC.js.gz +0 -0
- package/public/assets/screenSpaceCurvature.fragment-Od67z-rQ.js.gz +0 -0
- package/public/assets/selection.fragment-CRMhdE35.js.gz +0 -0
- package/public/assets/selection.fragment-cSqXB6nx.js.gz +0 -0
- package/public/assets/selection.vertex-B5sPJWi2.js.gz +0 -0
- package/public/assets/selection.vertex-Dp4qd1GF.js.gz +0 -0
- package/public/assets/selectionOutline.fragment-CaYdhbIY.js.gz +0 -0
- package/public/assets/selectionOutline.fragment-RBpUe89m.js.gz +0 -0
- package/public/assets/shadowMap.fragment-BecpzSny.js.gz +0 -0
- package/public/assets/shadowMap.fragment-BhrOFpmK.js.gz +0 -0
- package/public/assets/shadowMap.vertex-DV4Ec23Y.js.gz +0 -0
- package/public/assets/shadowMap.vertex-Dpx2-6XS.js.gz +0 -0
- package/public/assets/shadowMapFragmentSoftTransparentShadow-BHumE7-J.js.gz +0 -0
- package/public/assets/shadowMapFragmentSoftTransparentShadow-CrPC6Hns.js.gz +0 -0
- package/public/assets/sharpen.fragment-CPdQPlDe.js.gz +0 -0
- package/public/assets/textureMerger.fragment-BNxx2w1v.js.gz +0 -0
- package/public/assets/textureMerger.fragment-CPq4n9w5.js.gz +0 -0
- package/public/assets/tgaTextureLoader-B7dlONGx.js.gz +0 -0
- package/public/assets/vertexColorMixing-BUQkJeP0.js.gz +0 -0
- package/public/assets/vertexColorMixing-Co5x3WYA.js.gz +0 -0
- package/public/assets/volumetricLightingBlendVolume.fragment-D01l1w1u.js.gz +0 -0
- package/public/assets/volumetricLightingBlendVolume.fragment-Dq5kceRW.js.gz +0 -0
- package/public/assets/volumetricLightingRenderVolume.fragment-BCxtzv0C.js.gz +0 -0
- package/public/assets/volumetricLightingRenderVolume.fragment-DwEKCs2S.js.gz +0 -0
- package/public/assets/volumetricLightingRenderVolume.vertex-CNPaSIo7.js.gz +0 -0
- package/public/assets/volumetricLightingRenderVolume.vertex-EiQlWi_X.js.gz +0 -0
- package/public/assets/webAudioBus-DYpSKoOA.js.gz +0 -0
- package/public/assets/webAudioMainBus-CP3f56US.js.gz +0 -0
- package/public/assets/workerPool-H9Ji3mCo.js.gz +0 -0
- package/public/index.html +3 -3
- package/public/index.html.br +0 -0
- package/public/index.html.gz +0 -0
- package/runtime/editor-control-plane.mjs +3 -3
- package/worker/editor-service-worker.mjs +23 -23
- package/public/assets/index-ZnhNI5EO.js +0 -1
- package/public/assets/index-ZnhNI5EO.js.br +0 -0
- package/public/assets/index-ZnhNI5EO.js.gz +0 -0
- package/public/assets/playable-sdk-D6RL-8B7.js +0 -135
- package/public/assets/playable-sdk-D6RL-8B7.js.br +0 -0
- package/public/assets/playable-sdk-D6RL-8B7.js.gz +0 -0
- package/public/assets/playable-standard-project-CkKWpnr-.js +0 -4943
- package/public/assets/playable-standard-project-CkKWpnr-.js.br +0 -0
- package/public/assets/playable-standard-project-CkKWpnr-.js.gz +0 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/public/index.html
CHANGED
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
html, body { width: 100%; height: 100%; margin: 0; overflow: hidden; background: #101018; }
|
|
11
11
|
#renderCanvas { width: 100%; height: 100%; display: block; outline: none; }
|
|
12
12
|
</style>
|
|
13
|
-
<script type="importmap">{"imports":{"@fps-games/editor/playable-sdk":"./assets/playable-sdk-
|
|
14
|
-
<script type="module" crossorigin src="./assets/index-
|
|
13
|
+
<script type="importmap">{"imports":{"@fps-games/editor/playable-sdk":"./assets/playable-sdk-Cz5ms1M8.js","@babylonjs/core":"./assets/babylon-core-B6Ot-GOK.js","@fps-games/editor-core/plugin-host":"./assets/editor-core-plugin-host-c2002442.js"}}</script>
|
|
14
|
+
<script type="module" crossorigin src="./assets/index-Dk6-vu7X.js"></script>
|
|
15
15
|
<link rel="modulepreload" crossorigin href="./assets/hemisphericLight-BkYyeXbK.js">
|
|
16
|
-
<link rel="modulepreload" crossorigin href="./assets/playable-standard-project-
|
|
16
|
+
<link rel="modulepreload" crossorigin href="./assets/playable-standard-project-CgBNJ6kY.js">
|
|
17
17
|
</head>
|
|
18
18
|
<body>
|
|
19
19
|
<canvas id="renderCanvas"></canvas>
|
package/public/index.html.br
CHANGED
|
Binary file
|
package/public/index.html.gz
CHANGED
|
Binary file
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{readFile as qe}from"node:fs/promises";import Ee from"node:path";var N="/__fps_editor_agent/v1";var rt=8*1024*1024;var nt=256*1024;import{createHash as at,randomBytes as X,randomUUID as ue}from"node:crypto";import{once as ie}from"node:events";import{createReadStream as Ce}from"node:fs";import{mkdir as fe,open as ae,readFile as j,realpath as He,rename as xe,rm as F,stat as Q,writeFile as Le}from"node:fs/promises";import{createServer as je}from"node:http";import{spawn as Ue}from"node:child_process";import _ from"node:path";async function pe(e){let n=await He(e.projectRoot),i=e.host?.trim()||"127.0.0.1",a=Xe(e.port??3012),d=_.resolve(n,e.workerEntry);if(_e(n,d,"worker entry"),!(await Q(d).catch(()=>null))?.isFile())throw new Error(`Editor worker entry is missing: ${d}`);let m=$e(e.projectDefinition),f=new Map(e.builds.map(t=>[t.release,Ge(n,t)]));if(f.size===0||f.size!==e.builds.length)throw new Error("Editor Server requires uniquely named built Editor releases.");let s=e.activeRelease?.trim()||e.builds[0].release;if(!f.has(s))throw new Error(`Unknown active Editor release: ${s}`);let T=e.logger??console,S=ue(),ee=new Date().toISOString(),V=X(32).toString("base64url"),W=X(32).toString("base64url"),he=await Fe(_.resolve(n,e.runtimeBridgeTokenPath??".fps-editor/state/runtime-bridge-token")),B=e.testControl?e.controlToken?.trim()||X(32).toString("base64url"):null,te=e.runtimeUrl?.trim()||"http://127.0.0.1:3011",U=_.join(n,".fps-editor/state/agent-runtime.json"),J=`${U}.owner`,re=await Ve(J,S),we=Z(e.workerReadyTimeoutMs,3e4),ne=Z(e.workerHeartbeatTimeoutMs,1e4),Re=Z(e.workerRestartLimit,3),h=null,A=new WeakSet,D=!1,p="starting",v=0,g=null,y=null,C=0,k=null,z,H=null,b=null,x=null,P=je((t,r)=>{ge(t,r).catch(o=>{T.error?.(`[fps-editor-server] request failed: ${L(o)}`),r.headersSent?r.destroy(o instanceof Error?o:void 0):u(r,500,{ok:!1,error:L(o)})})});P.on("error",t=>T.error?.(`[fps-editor-server] ${L(t)}`));try{await new Promise((t,r)=>{P.once("error",r),P.listen(a,i,()=>{P.off("error",r),t()})}),await K()}catch(t){throw await le(P).catch(()=>{}),await ce(J,re).catch(()=>{}),t}H=setInterval(()=>{D||p!=="ready"||!k||!h||Date.now()-Date.parse(k)<=ne||(T.warn?.("[fps-editor-server] Editor worker heartbeat timed out; restarting worker."),p="restarting",h.kill("SIGKILL"))},Math.min(1e3,Math.max(100,Math.floor(ne/3)))),H.unref?.();let oe=`http://${i}:${a}`;T.info?.(`[fps-editor-server] ready at ${oe}`);function G(){let t=f.get(s);return{ok:p==="ready",serverInstanceId:S,pid:process.pid,startedAt:ee,host:i,port:a,worker:{status:p,generation:v,pid:h?.pid??null,serviceInstanceId:g,restartCount:C,lastHeartbeatAt:k,...z?{lastExit:z}:{}},editor:{activeRelease:s,artifactId:t.artifactId,build:t.build}}}async function K(){if(D)return;v+=1,p=v===1?"starting":"restarting",g=null,y=null,k=null;let t=f.get(s),r=Ue(process.execPath,[d],{cwd:n,stdio:["ignore","inherit","inherit","ipc"],env:{...process.env,FPS_EDITOR_WORKER_AGENT_TOKEN:V,FPS_EDITOR_WORKER_BROWSER_TOKEN:W,FPS_EDITOR_WORKER_RUNTIME_DEBUG_TOKEN:he,FPS_EDITOR_WORKER_RUNTIME_URL:te,FPS_EDITOR_WORKER_BUILD:JSON.stringify(t.build),FPS_EDITOR_WORKER_GENERATION:String(v),FPS_EDITOR_WORKER_PROJECT_DEFINITION:JSON.stringify(m),...e.workerJournalPath?.trim()?{FPS_EDITOR_WORKER_JOURNAL_PATH:e.workerJournalPath.trim()}:{}}});h=r,r.on("message",c=>{Te(r,c).catch(l=>{T.error?.(`[fps-editor-server] invalid worker message: ${L(l)}`),r.kill("SIGKILL")})}),r.once("exit",(c,l)=>{Se(r,c,l)});let o=Date.now()+we;for(;!D&&h===r&&p!=="ready"&&Date.now()<o;)await new Promise(c=>setTimeout(c,25));if(p!=="ready")throw A.add(r),r.kill("SIGKILL"),new Error("Editor Service worker did not become ready before the startup deadline.")}async function Te(t,r){if(t!==h||!Je(r))return;if(r.type==="heartbeat"){r.serviceInstanceId===g&&(k=new Date().toISOString());return}let o=new URL(r.internalUrl);if(o.protocol!=="http:"||o.hostname!=="127.0.0.1")throw new Error("Editor worker internal URL must use loopback HTTP.");g=r.serviceInstanceId,y=o.toString(),k=new Date().toISOString(),p="ready",x={schemaVersion:1,protocolVersion:2,canonicalProjectRoot:n,serviceInstanceId:r.serviceInstanceId,pid:process.pid,endpoint:`${Ze(i,a)}${N}`,startedAt:ee,packageName:"@fps-games/editor",packageVersion:f.get(s).build.version,buildKey:f.get(s).build.buildId,token:V,tokenScopes:["read","write"]},await Be(U,x)}async function Se(t,r,o){let c=A.has(t);if(A.delete(t),h===t&&(h=null),z={code:r,signal:o,at:new Date().toISOString()},y=null,g=null,await de(U,x),x=null,D||c){p="stopped";return}if(C+=1,C>Re){p="fused",T.error?.("[fps-editor-server] Editor worker restart fuse opened.");return}p="restarting";let l=[100,500,2e3][Math.min(C-1,2)];b=setTimeout(()=>{b=null,K().catch(E=>{T.error?.(`[fps-editor-server] worker restart failed: ${L(E)}`)})},l),b.unref?.()}async function ge(t,r){let o=new URL(t.url??"/",`http://${i}:${a}`);if(Ke(r),t.method==="GET"&&o.pathname==="/__fps_editor/health"){u(r,p==="ready"?200:503,G());return}if(t.method==="GET"&&o.pathname==="/__fps_editor/status"){u(r,200,G());return}if(t.method==="GET"&&o.pathname==="/__fps_editor/bootstrap.json"){if(!g){u(r,503,{ok:!1,error:"editor_worker_unavailable"});return}let c=f.get(s);u(r,200,{ok:!0,serverInstanceId:S,workerGeneration:v,runtime:{protocolVersion:2,serviceInstanceId:g,gatewayPath:N,token:W},build:c.build});return}if((t.method==="GET"||t.method==="HEAD")&&(o.pathname==="/"||o.pathname==="/index.html"||o.pathname==="/__fps_editor/document")){await ye(r,o.searchParams.get("instanceId"),o.searchParams.get("release"),t.method==="HEAD");return}if((t.method==="GET"||t.method==="HEAD")&&o.pathname.startsWith("/__fps_editor/build/")){await Oe(t,r,o);return}if((t.method==="GET"||t.method==="HEAD")&&o.pathname.startsWith("/src/")){await ve(t,r,o);return}if(t.method==="POST"&&o.pathname.startsWith("/__fps_editor/control/")){await be(t,r,o.pathname);return}if(o.pathname===N||o.pathname.startsWith("/__fps_editor_authoring")||o.pathname.startsWith("/__fps_editor/assets/")){await ke(t,r,o);return}u(r,404,{ok:!1,error:"not_found"})}async function ye(t,r,o,c=!1){if(!g){u(t,503,{ok:!1,error:"editor_worker_unavailable"});return}let l=f.get(s);if(o?.trim()&&o.trim()!==s){u(t,409,{ok:!1,error:"editor_build_incompatible",activeRelease:s,requestedRelease:o.trim(),activeBuild:l.build});return}let E=await j(_.join(l.rootPath,"index.html"),"utf8"),w=`/__fps_editor/build/${encodeURIComponent(l.artifactId)}/`,R=[`<base href="${Qe(w)}">`,"<script>","window.__FPS_EDITOR_HOSTED_SANDBOX__=true;",'window.__BOOT_MODE="edit";',`window.__FPS_EDITOR_AGENT_RUNTIME__=${M({protocolVersion:2,serviceInstanceId:g,gatewayPath:N,token:W})};`,`window.__FPS_EDITOR_SERVER__=${M({serverInstanceId:S,workerGeneration:v,instanceId:r?.trim()||null,release:l.release,artifactId:l.artifactId,build:l.build})};`,`window.__FPS_EDITOR_PROJECT_DEFINITION__=${M(m)};`,`window.__FPS_EDITOR_RUNTIME_URL__=${M(te)};`,"window.__FPS_EDITOR_SERVER_MONITOR__=setInterval(async()=>{",'try{const response=await fetch("/__fps_editor/bootstrap.json",{cache:"no-store"});',"if(!response.ok)return;const next=await response.json();","if(next.serverInstanceId!==window.__FPS_EDITOR_SERVER__.serverInstanceId","||next.workerGeneration!==window.__FPS_EDITOR_SERVER__.workerGeneration){",'const url=new URL(location.href);url.searchParams.set("__fpsWorkerGeneration",String(next.workerGeneration));','url.searchParams.set("__fpsServerInstance",String(next.serverInstanceId));',"location.replace(url);}","}catch{}","},1000);",'addEventListener("pagehide",()=>clearInterval(window.__FPS_EDITOR_SERVER_MONITOR__),{once:true});',"</script>"].join(""),Ne=/<head[^>]*>/i.test(E)?E.replace(/<head[^>]*>/i,Ae=>`${Ae}${R}`):`${R}${E}`;t.statusCode=200,t.setHeader("Cache-Control","no-store"),t.setHeader("Content-Type","text/html; charset=utf-8"),t.end(c?void 0:Ne)}async function Oe(t,r,o){let c=o.pathname.split("/").filter(Boolean),l=decodeURIComponent(c[2]??""),E=[...f.values()].find(R=>R.artifactId===l);if(!E){u(r,404,{ok:!1,error:"editor_build_not_found"});return}let w=c.slice(3).map(decodeURIComponent).join("/");await se(t,r,E.rootPath,w,!0)}async function ve(t,r,o){let c=decodeURIComponent(o.pathname.slice(1));await se(t,r,n,c,!1,o.searchParams.has("v"))}async function ke(t,r,o){if(!y||p!=="ready"){u(r,503,{ok:!1,error:"editor_worker_unavailable"});return}let c=t.method==="GET"||t.method==="HEAD"?void 0:await ze(t,32*1024*1024),l={};for(let w of["accept","authorization","content-type","if-none-match","range"]){let R=t.headers[w];typeof R=="string"&&(l[w]=R)}let E=await fetch(new URL(`${o.pathname}${o.search}`,y),{method:t.method,headers:l,...c?{body:new Uint8Array(c)}:{}});r.statusCode=E.status;for(let w of["content-type","content-length","etag","content-range","accept-ranges"]){let R=E.headers.get(w);R&&r.setHeader(w,R)}r.setHeader("Cache-Control","no-store"),r.end(t.method==="HEAD"?void 0:Buffer.from(await E.arrayBuffer()))}async function be(t,r,o){if(!B||t.headers["x-fps-editor-control-token"]!==B){u(r,404,{ok:!1,error:"not_found"});return}if(o==="/__fps_editor/control/worker/crash"){if(!h){u(r,409,{ok:!1,error:"worker_unavailable"});return}h.kill("SIGKILL"),u(r,202,{ok:!0});return}let c=decodeURIComponent(o.slice(31));if(o.startsWith("/__fps_editor/control/activate/")&&f.has(c)){let l=await Pe();if(l.dirty){u(r,409,{ok:!1,error:"editor_document_dirty",documentRevision:l.documentRevision,activeRelease:s,requestedRelease:c});return}let E=s;if(s=c,C=0,h){let w=h;p="restarting",A.add(w);let R=ie(w,"exit");w.kill("SIGTERM"),await R}await K(),u(r,200,{ok:!0,previousRelease:E,activeRelease:s,status:G()});return}u(r,404,{ok:!1,error:"control_not_found"})}async function Pe(){if(!y||p!=="ready")throw new Error("Editor worker is unavailable for release compatibility checks.");let t=await fetch(new URL(N,y),{method:"POST",headers:{authorization:`Bearer ${V}`,"content-type":"application/json"},body:JSON.stringify({kind:"status"})}),r=await t.json();if(!t.ok||r.ok!==!0||r.kind!=="status"||typeof r.status?.dirty!="boolean"||!Number.isSafeInteger(r.status.documentRevision))throw new Error("Editor worker returned an invalid status during release compatibility checks.");return{dirty:r.status.dirty,documentRevision:r.status.documentRevision}}let $=null;return Object.freeze({url:oe,controlToken:B,status:G,dispose(){return $||($=(async()=>{D=!0,H&&clearInterval(H),b&&clearTimeout(b),H=null,b=null;let t=h;if(t){A.add(t);let r=ie(t,"exit").catch(()=>[]);t.kill("SIGTERM"),await Promise.race([r,new Promise(o=>setTimeout(o,5e3))]),t.exitCode===null&&t.signalCode===null&&t.kill("SIGKILL")}await le(P),await de(U,x),await ce(J,re)})(),$)}})}function Ge(e,n){let i=_.resolve(e,n.rootPath);if(_e(e,i,"built Editor root"),!n.release.trim()||!n.artifactId.trim())throw new Error("Editor build identity is incomplete.");return Object.freeze({...n,rootPath:i,build:Object.freeze({...n.build})})}function $e(e){if(!e||typeof e!="object"||Array.isArray(e)||e.schemaVersion!==1||typeof e.projectId!="string"||typeof e.projectName!="string"||!e.authoring||!Array.isArray(e.plugins))throw new Error("Editor Server Project definition is invalid.");return structuredClone(e)}async function se(e,n,i,a,d,I=!1){if(!a||a.includes("\\")||a.split("/").includes("..")){u(n,404,{ok:!1,error:"file_not_found"});return}let m=_.resolve(i,a),f=_.relative(i,m);if(!f||f===".."||f.startsWith(`..${_.sep}`)||_.isAbsolute(f)){u(n,404,{ok:!1,error:"file_not_found"});return}let s=await Q(m).catch(()=>null);if(!s?.isFile()){u(n,404,{ok:!1,error:"file_not_found"});return}let T=e.headers["accept-encoding"]??"",S=await Me(m,T);n.statusCode=200,n.setHeader("Cache-Control",d||I?"public, max-age=31536000, immutable":"no-cache"),n.setHeader("Content-Type",Ye(m)),n.setHeader("Content-Length",String(S?.stat.size??s.size)),S&&(n.setHeader("Content-Encoding",S.encoding),n.setHeader("Vary","Accept-Encoding")),e.method==="HEAD"?n.end():Ce(S?.path??m).pipe(n)}async function Me(e,n){let i=n.toLowerCase().split(",").map(d=>d.trim()),a=d=>i.some(I=>{let[m,...f]=I.split(";").map(s=>s.trim());return m!==d&&m!=="*"?!1:!f.some(s=>s==="q=0"||s==="q=0.0")});for(let d of a("br")?[{suffix:".br",encoding:"br"},{suffix:".gz",encoding:"gzip"}]:[{suffix:".gz",encoding:"gzip"}]){if(d.encoding==="gzip"&&!a("gzip"))continue;let I=`${e}${d.suffix}`,m=await Q(I).catch(()=>null);if(m?.isFile())return{path:I,encoding:d.encoding,stat:m}}return null}async function Fe(e){let n=(await j(e,"utf8")).trim();if(!n)throw new Error(`Editor Server secret is empty: ${e}`);return n}async function Ve(e,n){await fe(_.dirname(e),{recursive:!0,mode:448});let i={pid:process.pid,serverInstanceId:n,createdAt:new Date().toISOString()};try{let a=await ae(e,"wx",384);return await a.writeFile(`${JSON.stringify(i)}
|
|
1
|
+
import{readFile as qe}from"node:fs/promises";import Ee from"node:path";var N="/__fps_editor_agent/v1";var rt=8*1024*1024;var nt=256*1024;import{createHash as at,randomBytes as Z,randomUUID as ue}from"node:crypto";import{once as ie}from"node:events";import{createReadStream as Ce}from"node:fs";import{mkdir as fe,open as ae,readFile as j,realpath as He,rename as xe,rm as F,stat as q,writeFile as Le}from"node:fs/promises";import{createServer as je}from"node:http";import{spawn as Ue}from"node:child_process";import m from"node:path";async function pe(e){let n=await He(e.projectRoot),i=e.host?.trim()||"127.0.0.1",a=Xe(e.port??3012),d=m.resolve(n,e.workerEntry);if(_e(n,d,"worker entry"),!(await q(d).catch(()=>null))?.isFile())throw new Error(`Editor worker entry is missing: ${d}`);let p=$e(e.projectDefinition),f=new Map(e.builds.map(t=>[t.release,Ge(n,t)]));if(f.size===0||f.size!==e.builds.length)throw new Error("Editor Server requires uniquely named built Editor releases.");let s=e.activeRelease?.trim()||e.builds[0].release;if(!f.has(s))throw new Error(`Unknown active Editor release: ${s}`);let T=e.logger??console,S=ue(),te=new Date().toISOString(),V=Z(32).toString("base64url"),W=Z(32).toString("base64url"),he=await Fe(m.resolve(n,e.runtimeBridgeTokenPath??".fps-editor/state/runtime-bridge-token")),B=e.testControl?e.controlToken?.trim()||Z(32).toString("base64url"):null,J=e.runtimeUrl?.trim()||"http://127.0.0.1:3011",U=m.join(n,".fps-editor/state/agent-runtime.json"),z=`${U}.owner`,re=await Ve(z,S),we=Q(e.workerReadyTimeoutMs,3e4),ne=Q(e.workerHeartbeatTimeoutMs,1e4),Re=Q(e.workerRestartLimit,3),h=null,A=new WeakSet,D=!1,_="starting",v=0,g=null,y=null,C=0,k=null,K,H=null,b=null,x=null,P=je((t,r)=>{ge(t,r).catch(o=>{T.error?.(`[fps-editor-server] request failed: ${L(o)}`),r.headersSent?r.destroy(o instanceof Error?o:void 0):u(r,500,{ok:!1,error:L(o)})})});P.on("error",t=>T.error?.(`[fps-editor-server] ${L(t)}`));try{await new Promise((t,r)=>{P.once("error",r),P.listen(a,i,()=>{P.off("error",r),t()})}),await Y()}catch(t){throw await le(P).catch(()=>{}),await ce(z,re).catch(()=>{}),t}H=setInterval(()=>{D||_!=="ready"||!k||!h||Date.now()-Date.parse(k)<=ne||(T.warn?.("[fps-editor-server] Editor worker heartbeat timed out; restarting worker."),_="restarting",h.kill("SIGKILL"))},Math.min(1e3,Math.max(100,Math.floor(ne/3)))),H.unref?.();let oe=`http://${i}:${a}`;T.info?.(`[fps-editor-server] ready at ${oe}`);function G(){let t=f.get(s);return{ok:_==="ready",serverInstanceId:S,pid:process.pid,startedAt:te,host:i,port:a,worker:{status:_,generation:v,pid:h?.pid??null,serviceInstanceId:g,restartCount:C,lastHeartbeatAt:k,...K?{lastExit:K}:{}},editor:{activeRelease:s,artifactId:t.artifactId,build:t.build}}}async function Y(){if(D)return;v+=1,_=v===1?"starting":"restarting",g=null,y=null,k=null;let t=f.get(s),r=Ue(process.execPath,[d],{cwd:n,stdio:["ignore","inherit","inherit","ipc"],env:{...process.env,FPS_EDITOR_WORKER_AGENT_TOKEN:V,FPS_EDITOR_WORKER_BROWSER_TOKEN:W,FPS_EDITOR_WORKER_RUNTIME_DEBUG_TOKEN:he,FPS_EDITOR_WORKER_RUNTIME_URL:J,FPS_EDITOR_WORKER_BUILD:JSON.stringify(t.build),FPS_EDITOR_WORKER_GENERATION:String(v),FPS_EDITOR_WORKER_PROJECT_DEFINITION:JSON.stringify(p),...e.workerJournalPath?.trim()?{FPS_EDITOR_WORKER_JOURNAL_PATH:e.workerJournalPath.trim()}:{}}});h=r,r.on("message",c=>{Te(r,c).catch(l=>{T.error?.(`[fps-editor-server] invalid worker message: ${L(l)}`),r.kill("SIGKILL")})}),r.once("exit",(c,l)=>{Se(r,c,l)});let o=Date.now()+we;for(;!D&&h===r&&_!=="ready"&&Date.now()<o;)await new Promise(c=>setTimeout(c,25));if(_!=="ready")throw A.add(r),r.kill("SIGKILL"),new Error("Editor Service worker did not become ready before the startup deadline.")}async function Te(t,r){if(t!==h||!Je(r))return;if(r.type==="heartbeat"){r.serviceInstanceId===g&&(k=new Date().toISOString());return}let o=new URL(r.internalUrl);if(o.protocol!=="http:"||o.hostname!=="127.0.0.1")throw new Error("Editor worker internal URL must use loopback HTTP.");g=r.serviceInstanceId,y=o.toString(),k=new Date().toISOString(),_="ready",x={schemaVersion:1,protocolVersion:2,canonicalProjectRoot:n,serviceInstanceId:r.serviceInstanceId,pid:process.pid,endpoint:`${Ze(i,a)}${N}`,startedAt:te,packageName:"@fps-games/editor",packageVersion:f.get(s).build.version,buildKey:f.get(s).build.buildId,token:V,tokenScopes:["read","write"]},await Be(U,x)}async function Se(t,r,o){let c=A.has(t);if(A.delete(t),h===t&&(h=null),K={code:r,signal:o,at:new Date().toISOString()},y=null,g=null,await de(U,x),x=null,D||c){_="stopped";return}if(C+=1,C>Re){_="fused",T.error?.("[fps-editor-server] Editor worker restart fuse opened.");return}_="restarting";let l=[100,500,2e3][Math.min(C-1,2)];b=setTimeout(()=>{b=null,Y().catch(E=>{T.error?.(`[fps-editor-server] worker restart failed: ${L(E)}`)})},l),b.unref?.()}async function ge(t,r){let o=new URL(t.url??"/",`http://${i}:${a}`);if(Ke(r),t.method==="GET"&&o.pathname==="/__fps_editor/health"){u(r,_==="ready"?200:503,G());return}if(t.method==="GET"&&o.pathname==="/__fps_editor/status"){u(r,200,G());return}if(t.method==="GET"&&o.pathname==="/__fps_editor/bootstrap.json"){if(!g){u(r,503,{ok:!1,error:"editor_worker_unavailable"});return}let c=f.get(s);u(r,200,{ok:!0,serverInstanceId:S,workerGeneration:v,runtime:{protocolVersion:2,serviceInstanceId:g,gatewayPath:N,token:W},projectDefinition:p,runtimeUrl:J,build:c.build});return}if((t.method==="GET"||t.method==="HEAD")&&(o.pathname==="/"||o.pathname==="/index.html"||o.pathname==="/__fps_editor/document")){await ye(r,o.searchParams.get("instanceId"),o.searchParams.get("release"),t.method==="HEAD");return}if((t.method==="GET"||t.method==="HEAD")&&o.pathname.startsWith("/__fps_editor/build/")){await Oe(t,r,o);return}if((t.method==="GET"||t.method==="HEAD")&&o.pathname.startsWith("/src/")){await ve(t,r,o);return}if(t.method==="POST"&&o.pathname.startsWith("/__fps_editor/control/")){await be(t,r,o.pathname);return}if(o.pathname===N||o.pathname.startsWith("/__fps_editor_authoring")||o.pathname.startsWith("/__fps_editor/assets/")){await ke(t,r,o);return}u(r,404,{ok:!1,error:"not_found"})}async function ye(t,r,o,c=!1){if(!g){u(t,503,{ok:!1,error:"editor_worker_unavailable"});return}let l=f.get(s);if(o?.trim()&&o.trim()!==s){u(t,409,{ok:!1,error:"editor_build_incompatible",activeRelease:s,requestedRelease:o.trim(),activeBuild:l.build});return}let E=await j(m.join(l.rootPath,"index.html"),"utf8"),w=`/__fps_editor/build/${encodeURIComponent(l.artifactId)}/`,R=[`<base href="${Qe(w)}">`,"<script>","window.__FPS_EDITOR_HOSTED_SANDBOX__=true;",'window.__BOOT_MODE="edit";',`window.__FPS_EDITOR_AGENT_RUNTIME__=${M({protocolVersion:2,serviceInstanceId:g,gatewayPath:N,token:W})};`,`window.__FPS_EDITOR_SERVER__=${M({serverInstanceId:S,workerGeneration:v,instanceId:r?.trim()||null,release:l.release,artifactId:l.artifactId,build:l.build})};`,`window.__FPS_EDITOR_PROJECT_DEFINITION__=${M(p)};`,`window.__FPS_EDITOR_RUNTIME_URL__=${M(J)};`,"window.__FPS_EDITOR_SERVER_MONITOR__=setInterval(async()=>{",'try{const response=await fetch("/__fps_editor/bootstrap.json",{cache:"no-store"});',"if(!response.ok)return;const next=await response.json();","if(next.serverInstanceId!==window.__FPS_EDITOR_SERVER__.serverInstanceId","||next.workerGeneration!==window.__FPS_EDITOR_SERVER__.workerGeneration){",'const url=new URL(location.href);url.searchParams.set("__fpsWorkerGeneration",String(next.workerGeneration));','url.searchParams.set("__fpsServerInstance",String(next.serverInstanceId));',"location.replace(url);}","}catch{}","},1000);",'addEventListener("pagehide",()=>clearInterval(window.__FPS_EDITOR_SERVER_MONITOR__),{once:true});',"</script>"].join(""),Ne=/<head[^>]*>/i.test(E)?E.replace(/<head[^>]*>/i,Ae=>`${Ae}${R}`):`${R}${E}`;t.statusCode=200,t.setHeader("Cache-Control","no-store"),t.setHeader("Content-Type","text/html; charset=utf-8"),t.end(c?void 0:Ne)}async function Oe(t,r,o){let c=o.pathname.split("/").filter(Boolean),l=decodeURIComponent(c[2]??""),E=[...f.values()].find(R=>R.artifactId===l);if(!E){u(r,404,{ok:!1,error:"editor_build_not_found"});return}let w=c.slice(3).map(decodeURIComponent).join("/");await se(t,r,E.rootPath,w,!0)}async function ve(t,r,o){let c=decodeURIComponent(o.pathname.slice(1));await se(t,r,n,c,!1,o.searchParams.has("v"))}async function ke(t,r,o){if(!y||_!=="ready"){u(r,503,{ok:!1,error:"editor_worker_unavailable"});return}let c=t.method==="GET"||t.method==="HEAD"?void 0:await ze(t,32*1024*1024),l={};for(let w of["accept","authorization","content-type","if-none-match","range"]){let R=t.headers[w];typeof R=="string"&&(l[w]=R)}let E=await fetch(new URL(`${o.pathname}${o.search}`,y),{method:t.method,headers:l,...c?{body:new Uint8Array(c)}:{}});r.statusCode=E.status;for(let w of["content-type","content-length","etag","content-range","accept-ranges"]){let R=E.headers.get(w);R&&r.setHeader(w,R)}r.setHeader("Cache-Control","no-store"),r.end(t.method==="HEAD"?void 0:Buffer.from(await E.arrayBuffer()))}async function be(t,r,o){if(!B||t.headers["x-fps-editor-control-token"]!==B){u(r,404,{ok:!1,error:"not_found"});return}if(o==="/__fps_editor/control/worker/crash"){if(!h){u(r,409,{ok:!1,error:"worker_unavailable"});return}h.kill("SIGKILL"),u(r,202,{ok:!0});return}let c=decodeURIComponent(o.slice(31));if(o.startsWith("/__fps_editor/control/activate/")&&f.has(c)){let l=await Pe();if(l.dirty){u(r,409,{ok:!1,error:"editor_document_dirty",documentRevision:l.documentRevision,activeRelease:s,requestedRelease:c});return}let E=s;if(s=c,C=0,h){let w=h;_="restarting",A.add(w);let R=ie(w,"exit");w.kill("SIGTERM"),await R}await Y(),u(r,200,{ok:!0,previousRelease:E,activeRelease:s,status:G()});return}u(r,404,{ok:!1,error:"control_not_found"})}async function Pe(){if(!y||_!=="ready")throw new Error("Editor worker is unavailable for release compatibility checks.");let t=await fetch(new URL(N,y),{method:"POST",headers:{authorization:`Bearer ${V}`,"content-type":"application/json"},body:JSON.stringify({kind:"status"})}),r=await t.json();if(!t.ok||r.ok!==!0||r.kind!=="status"||typeof r.status?.dirty!="boolean"||!Number.isSafeInteger(r.status.documentRevision))throw new Error("Editor worker returned an invalid status during release compatibility checks.");return{dirty:r.status.dirty,documentRevision:r.status.documentRevision}}let $=null;return Object.freeze({url:oe,controlToken:B,status:G,dispose(){return $||($=(async()=>{D=!0,H&&clearInterval(H),b&&clearTimeout(b),H=null,b=null;let t=h;if(t){A.add(t);let r=ie(t,"exit").catch(()=>[]);t.kill("SIGTERM"),await Promise.race([r,new Promise(o=>setTimeout(o,5e3))]),t.exitCode===null&&t.signalCode===null&&t.kill("SIGKILL")}await le(P),await de(U,x),await ce(z,re)})(),$)}})}function Ge(e,n){let i=m.resolve(e,n.rootPath);if(_e(e,i,"built Editor root"),!n.release.trim()||!n.artifactId.trim())throw new Error("Editor build identity is incomplete.");return Object.freeze({...n,rootPath:i,build:Object.freeze({...n.build})})}function $e(e){if(!e||typeof e!="object"||Array.isArray(e)||e.schemaVersion!==1||typeof e.projectId!="string"||typeof e.projectName!="string"||!e.authoring||!Array.isArray(e.plugins))throw new Error("Editor Server Project definition is invalid.");return structuredClone(e)}async function se(e,n,i,a,d,I=!1){if(!a||a.includes("\\")||a.split("/").includes("..")){u(n,404,{ok:!1,error:"file_not_found"});return}let p=m.resolve(i,a),f=m.relative(i,p);if(!f||f===".."||f.startsWith(`..${m.sep}`)||m.isAbsolute(f)){u(n,404,{ok:!1,error:"file_not_found"});return}let s=await q(p).catch(()=>null);if(!s?.isFile()){u(n,404,{ok:!1,error:"file_not_found"});return}let T=e.headers["accept-encoding"]??"",S=await Me(p,T);n.statusCode=200,n.setHeader("Cache-Control",d||I?"public, max-age=31536000, immutable":"no-cache"),n.setHeader("Content-Type",Ye(p)),n.setHeader("Content-Length",String(S?.stat.size??s.size)),S&&(n.setHeader("Content-Encoding",S.encoding),n.setHeader("Vary","Accept-Encoding")),e.method==="HEAD"?n.end():Ce(S?.path??p).pipe(n)}async function Me(e,n){let i=n.toLowerCase().split(",").map(d=>d.trim()),a=d=>i.some(I=>{let[p,...f]=I.split(";").map(s=>s.trim());return p!==d&&p!=="*"?!1:!f.some(s=>s==="q=0"||s==="q=0.0")});for(let d of a("br")?[{suffix:".br",encoding:"br"},{suffix:".gz",encoding:"gzip"}]:[{suffix:".gz",encoding:"gzip"}]){if(d.encoding==="gzip"&&!a("gzip"))continue;let I=`${e}${d.suffix}`,p=await q(I).catch(()=>null);if(p?.isFile())return{path:I,encoding:d.encoding,stat:p}}return null}async function Fe(e){let n=(await j(e,"utf8")).trim();if(!n)throw new Error(`Editor Server secret is empty: ${e}`);return n}async function Ve(e,n){await fe(m.dirname(e),{recursive:!0,mode:448});let i={pid:process.pid,serverInstanceId:n,createdAt:new Date().toISOString()};try{let a=await ae(e,"wx",384);return await a.writeFile(`${JSON.stringify(i)}
|
|
2
2
|
`,"utf8"),await a.close(),i}catch{let d=await j(e,"utf8").then(JSON.parse).catch(()=>null);if(typeof d?.pid=="number"&&We(d.pid))throw new Error(`Editor Server project lock is already owned by PID ${d.pid}.`);await F(e,{force:!0});let I=await ae(e,"wx",384);return await I.writeFile(`${JSON.stringify(i)}
|
|
3
|
-
`,"utf8"),await I.close(),i}}async function ce(e,n){(await j(e,"utf8").then(JSON.parse).catch(()=>null))?.serverInstanceId===n.serverInstanceId&&await F(e,{force:!0})}function We(e){try{return process.kill(e,0),!0}catch{return!1}}async function Be(e,n){await fe(
|
|
3
|
+
`,"utf8"),await I.close(),i}}async function ce(e,n){(await j(e,"utf8").then(JSON.parse).catch(()=>null))?.serverInstanceId===n.serverInstanceId&&await F(e,{force:!0})}function We(e){try{return process.kill(e,0),!0}catch{return!1}}async function Be(e,n){await fe(m.dirname(e),{recursive:!0,mode:448});let i=`${e}.${process.pid}.${ue()}.tmp`;try{await Le(i,`${JSON.stringify(n,null,2)}
|
|
4
4
|
`,{encoding:"utf8",mode:384}),await xe(i,e)}finally{await F(i,{force:!0}).catch(()=>{})}}async function de(e,n){if(!n)return;let i=await j(e,"utf8").then(JSON.parse).catch(()=>null);i?.serviceInstanceId===n.serviceInstanceId&&i.pid===n.pid&&await F(e,{force:!0})}function Je(e){if(!e||typeof e!="object")return!1;let n=e;return n.type==="heartbeat"?typeof n.serviceInstanceId=="string":n.type==="ready"&&typeof n.serviceInstanceId=="string"&&typeof n.internalUrl=="string"}async function ze(e,n){let i=[],a=0;for await(let d of e){let I=Buffer.isBuffer(d)?d:Buffer.from(d);if(a+=I.byteLength,a>n)throw new Error("Editor Server request body is too large.");i.push(I)}return Buffer.concat(i)}function Ke(e){e.setHeader("Access-Control-Allow-Origin","*"),e.setHeader("Cross-Origin-Resource-Policy","cross-origin"),e.setHeader("Cross-Origin-Embedder-Policy","credentialless"),e.setHeader("X-Content-Type-Options","nosniff")}function u(e,n,i){e.statusCode=n,e.setHeader("Cache-Control","no-store"),e.setHeader("Content-Type","application/json; charset=utf-8"),e.end(`${JSON.stringify(i)}
|
|
5
|
-
`)}function Ye(e){switch(
|
|
5
|
+
`)}function Ye(e){switch(m.extname(e).toLowerCase()){case".js":case".mjs":return"text/javascript; charset=utf-8";case".css":return"text/css; charset=utf-8";case".json":return"application/json; charset=utf-8";case".html":return"text/html; charset=utf-8";case".svg":return"image/svg+xml";case".png":return"image/png";case".jpg":case".jpeg":return"image/jpeg";case".webp":return"image/webp";case".glb":return"model/gltf-binary";case".gltf":return"model/gltf+json";default:return"application/octet-stream"}}function _e(e,n,i){let a=m.relative(e,n);if(!a||a===".."||a.startsWith(`..${m.sep}`)||m.isAbsolute(a))throw new Error(`Editor Server ${i} must be inside the canonical project root.`)}function Xe(e){if(!Number.isSafeInteger(e)||e<1||e>65535)throw new Error("Editor Server port is invalid.");return e}function Q(e,n){return Number.isSafeInteger(e)&&e>0?e:n}function Ze(e,n){return`http://${e==="0.0.0.0"?"127.0.0.1":e}:${n}`}function M(e){return JSON.stringify(e).replace(/</g,"\\u003c").replace(/>/g,"\\u003e")}function Qe(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<")}async function le(e){e.listening&&await new Promise((n,i)=>e.close(a=>a?i(a):n()))}function L(e){return e instanceof Error?e.message:String(e)}et();var Ie=Ee.resolve(process.cwd()),O=JSON.parse(await qe(Ee.join(Ie,".fps-editor/current.json"),"utf8").catch(e=>{throw new Error("Editor deployment is not prepared. Run npm run prepare:server first.",{cause:e})}));if(O.schemaVersion!==3||typeof O.workerEntry!="string"||!O.projectDefinition||!Array.isArray(O.builds))throw new Error("Editor deployment state is invalid. Run npm run prepare:server again.");var ee=await pe({projectRoot:Ie,workerEntry:O.workerEntry,projectDefinition:O.projectDefinition,builds:O.builds,activeRelease:process.env.FPS_EDITOR_RELEASE?.trim()||"a",host:process.env.FPS_EDITOR_SERVER_HOST?.trim()||"127.0.0.1",port:tt(process.env.FPS_EDITOR_SERVER_PORT,3012),runtimeUrl:process.env.FPS_EDITOR_RUNTIME_URL?.trim()||"http://127.0.0.1:3011",runtimeBridgeTokenPath:".fps-editor/state/runtime-bridge-token",workerJournalPath:process.env.FPS_EDITOR_SERVER_JOURNAL_PATH,workerReadyTimeoutMs:6e4,workerHeartbeatTimeoutMs:1e4,workerRestartLimit:3,testControl:process.env.FPS_EDITOR_SERVER_TEST_CONTROL==="true",controlToken:process.env.FPS_EDITOR_SERVER_CONTROL_TOKEN});ee.controlToken&&console.log(`[fps-editor-server] test control token: ${ee.controlToken}`);var me=!1;for(let e of["SIGINT","SIGTERM"])process.once(e,()=>{me||(me=!0,ee.dispose().finally(()=>{process.exitCode=e==="SIGINT"?130:143}))});function et(){let e=Number.parseInt(process.versions.node.split(".")[0]??"",10);if(!Number.isSafeInteger(e)||e<24||e>=27)throw new Error(`fps-editor-server requires Node.js >=24 <27; current version is ${process.versions.node}.`)}function tt(e,n){if(!e?.trim())return n;let i=Number(e);if(!Number.isSafeInteger(i)||i<1||i>65535)throw new Error(`FPS_EDITOR_SERVER_PORT must be a valid port, got ${e}.`);return i}
|