@3dsource/angular-unreal-module 0.0.162 → 0.0.163

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.
@@ -1,4 +1,4 @@
1
- "use strict";(()=>{"use strict";const g=/metabox-configurator\/(modular|basic)\//i,m="features",k="3dsource:region-ping",w="assets/config.json",f="https://datacenter.3dsource.com/signallingserver",y="42e01f";function l(){return typeof crypto!="undefined"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,o=>{const t=Math.random()*16|0;return(o==="x"?t:t&3|8).toString(16)})}function b(o){return o.replace("http://","ws://").replace("https://","wss://")}const h="[stream-prefetch]",n=(...o)=>console.log(h,...o),c=(...o)=>console.warn(h,...o),u=(...o)=>console.error(h,...o);class T{constructor(){const t=document.currentScript||(()=>{const s=document.getElementsByTagName("script");return s[s.length-1]})(),e=t&&t.dataset||{};this.configUrl=e.configUrl||w,this.fallbackPollingUrl=e.fallbackUrl||"",this.skipRouteCheck=this.boolOr(e.skipRouteCheck,!1),this.config={ws_timeout:this.numberOr(e.wsTimeout,6e3),poll_timeout:this.numberOr(e.pollTimeout,4e3)};const i=new URLSearchParams(window.location.search);this.forceTURN=i.has("ForceTURN"),this.forceMaxBundle=i.has("ForceMaxBundle"),this.forceMonoAudio=i.has("forceMono"),this.ids={clientId:l(),viewId:l(),correlationId:l()},this.region="",this.pc=null,this.dc=null,this.stream=null,this.ws=null,this.remoteDescriptionSet=!1,this.iceBuffer=[],this.wsTimeoutId=null,this.settled=!1}run(){if(!(typeof window=="undefined"||!("WebSocket"in window)||!("RTCPeerConnection"in window))){if(this.isNewOrchestrationEnabled()){n("skip \u2014 features.newOrchestration is enabled");return}if(this.skipRouteCheck){c("skipRouteCheck=true \u2014 ignoring URL gate; using fallback polling"),this.publishParked("connecting"),this.connect().catch(t=>this.fail("exception",t));return}if(!g.test(window.location.href)){n("skip \u2014 not a metabox-configurator/{modular|basic} route");return}n("start",{ids:this.ids}),this.publishParked("connecting"),this.connect().catch(t=>this.fail("exception",t))}}connect(){return this.mark("prefetch_start"),this.region=this.readRegion()||"",n("region from cache:",this.region||"(none)"),(this.skipRouteCheck?Promise.resolve(null):this.fetchConfig()).then(e=>{let i;if(e){if(i=this.chooseEndpoint(e),i&&!this.isAllowedEndpoint(i.url)){n("skip \u2014 signalling URL not sanctioned for prefetch",i.url),this.fail("endpoint-not-allowed");return}}else if(this.fallbackPollingUrl)c("no app config \u2014 falling back to polling",this.fallbackPollingUrl),i={type:"polling",url:this.fallbackPollingUrl};else{this.fail("no-config");return}if(!i){this.fail("no-endpoint");return}n("endpoint chosen",{type:i.type,url:i.url});const s=this.adaptUrlToRegion(i.url);return this.pollOrchestration(s).then(r=>{if(!r){this.fail("no-ws-url");return}return this.parked.machineId=r,n("opening socket",r),this.openSocket(r)})})}fetchConfig(){const t=new URL(this.configUrl,window.location.origin).href;return this.fetchWithTimeout(t,{credentials:"omit"},this.config.poll_timeout).then(e=>e.ok?e.json().catch(()=>null):null).catch(()=>null)}chooseEndpoint(t){const e=t.signalling,i=this.firstVersionUrl(e&&e.versions);return i?{type:"polling",url:i}:null}isAllowedEndpoint(t){if(typeof t!="string")return!1;const e=t.replace(/\/+$/,"");return e===f||e.startsWith(f+"/")}firstVersionUrl(t){if(!t||typeof t!="object")return"";for(const e of Object.keys(t))if(t[e])return t[e];return""}pollOrchestration(t){const e=`${t}${this.ids.clientId}/${this.ids.viewId}`;return this.fetchWithTimeout(e,{credentials:"omit"},this.config.poll_timeout).then(i=>i.ok?i.json().catch(()=>({})):null).then(i=>i&&i.signallingServer?b(`${window.location.protocol}//${i.signallingServer}`):null).catch(()=>null)}adaptUrlToRegion(t){return this.region&&t.indexOf(":region")===-1?t.replace(/signallingserver/gi,`signallingserver/region:${this.region}`):t}openSocket(t){const e=new WebSocket(t);e.binaryType="arraybuffer",this.ws=e,this.parked.ws=e,this.wsTimeoutId=setTimeout(()=>{e.readyState!==WebSocket.OPEN&&this.fail("ws-timeout")},this.config.ws_timeout),e.onopen=()=>{clearTimeout(this.wsTimeoutId),this.mark("ws_open"),n("WS open \u2014 waiting for config",{region:this.region})},e.onmessage=i=>this.onWsMessage(i),e.onerror=i=>{u("WS error",i),this.fail("ws-error")},e.onclose=i=>{!this.settled&&this.parked.state!=="ready"&&(c("WS closed before ready",{code:i&&i.code}),this.fail("ws-closed"))}}onWsMessage(t){let e;try{const i=typeof t.data=="string"?t.data:null;if(i===null)return;e=JSON.parse(i)}catch{return}switch(n("WS \u2190",e.type),e.type){case"ssInfo":this.parked.ssData=e.data;break;case"config":this.onConfig(e);break;case"offer":this.onOffer(e);break;case"answer":this.onAnswer(e);break;case"iceCandidate":this.onIceCandidate(e.candidate);break;case"ping":this.send({type:"pong",source:"front"});break;case"streamerDisconnected":case"playerDisconnected":this.fail("streamer-disconnected");break;case"error":this.fail("orchestration-error");break;default:break}}onConfig(t){if(this.pc)return;const e=Object.assign({},t.peerConnectionOptions);this.forceTURN&&(e.iceTransportPolicy="relay"),e.bundlePolicy=this.forceMaxBundle?"max-bundle":"balanced",e.iceCandidatePoolSize=1,this.parked.config=e;const i=new RTCPeerConnection(e);this.pc=i,this.parked.pc=i,n("PeerConnection created from config"),i.onicecandidate=s=>{s.candidate&&this.send({type:"iceCandidate",candidate:s.candidate})},i.ondatachannel=s=>this.wireDataChannel(s.channel),i.ontrack=s=>{s.track&&s.track.kind==="video"&&s.streams[0]&&(n("video track received"),this.stream=s.streams[0],this.parked.stream=this.stream,this.maybeReady())}}onOffer(t){return this.pc?(this.remoteDescriptionSet=!1,this.iceBuffer.length=0,this.pc.setRemoteDescription(t).then(()=>(this.remoteDescriptionSet=!0,this.flushIce(),this.pc.createAnswer())).then(e=>(e.sdp=this.mungeSDP(e.sdp||""),this.pc.setLocalDescription(e).then(()=>{n("WS \u2192 answer sent"),this.send(e)}))).catch(e=>this.fail("offer-failed",e))):Promise.resolve()}onAnswer(t){return this.pc?this.pc.setRemoteDescription(t).then(()=>{this.remoteDescriptionSet=!0,this.flushIce()}).catch(e=>this.fail("answer-failed",e)):Promise.resolve()}onIceCandidate(t){t&&(this.forceTURN&&String(t.candidate).indexOf("relay")<0||(this.remoteDescriptionSet&&this.pc?this.pc.addIceCandidate(t).catch(()=>{}):this.iceBuffer.push(t)))}flushIce(){for(const t of this.iceBuffer)this.pc.addIceCandidate(t).catch(()=>{});this.iceBuffer.length=0}wireDataChannel(t){t.binaryType="arraybuffer",this.dc=t,this.parked.dc=t,t.onmessage=e=>{this.parked.dcBuffer.push(e.data)},t.onopen=()=>{n("DataChannel open"),this.mark("dc_open"),this.maybeReady()},t.onclose=()=>{!this.settled&&this.parked.state!=="ready"&&(c("DataChannel closed before ready"),this.fail("dc-closed"))},t.readyState==="open"&&this.maybeReady()}maybeReady(){this.settled||!this.dc||this.dc.readyState!=="open"||this.stream&&(this.settled=!0,this.mark("ready"),this.parked.state="ready",n("READY \u2014 parked on window.__stream",this.parked.timings),this.fireSettled())}publishParked(t){const e=this;this.parked={state:t,pc:null,dc:null,stream:null,ws:null,ssData:void 0,machineId:void 0,config:void 0,ids:this.ids,dcBuffer:[],timings:{},adopt(){return e.clearTimers(),this.state="adopted",this},onSettled(i){if(typeof i=="function"){if(this.state!=="connecting"){const s=this.state;Promise.resolve().then(()=>i(s));return}e.settledCb=i}}},window.__stream=this.parked}fireSettled(){const t=this.settledCb;if(t){this.settledCb=null;try{t(this.parked.state)}catch{}}}clearTimers(){this.wsTimeoutId&&(clearTimeout(this.wsTimeoutId),this.wsTimeoutId=null)}fail(t,e){if(!(this.parked&&(this.parked.state==="adopted"||this.parked.state==="failed"))){u("FAILED:",t,e||""),this.settled=!0,this.clearTimers();try{this.dc&&this.dc.close()}catch{}try{this.pc&&this.pc.close()}catch{}try{this.ws&&this.ws.close()}catch{}this.parked&&(this.parked.state="failed",this.parked.failReason=t,e&&(this.parked.failError=String(e&&e.message||e)),this.fireSettled())}}mungeSDP(t){let e=this.prioritizeH264Profile(t,y);e=e.replace(/(a=fmtp:\d+ .*level-asymmetry-allowed=.*)\r\n/gm,`$1;x-google-start-bitrate=10000;x-google-max-bitrate=100000\r
2
- `);let i="maxaveragebitrate=510000;";return i+=this.forceMonoAudio?"stereo=0;":"stereo=1;",i+="useinbandfec=1",e=e.replace("useinbandfec=1",i),e}prioritizeH264Profile(t,e){const i=t.split(`\r
3
- `),s=[];for(const r of i)if(r.startsWith("a=fmtp:")&&r.toLowerCase().includes(`profile-level-id=${e}`)){const a=r.split(":")[1]&&r.split(":")[1].split(" ")[0];a&&s.push(a)}return s.length===0?t:i.map(r=>{if(!r.startsWith("m=video"))return r;const a=r.split(" "),x=a.slice(0,3),p=a.slice(3),S=[...s.filter(d=>p.includes(d)),...p.filter(d=>!s.includes(d))];return[...x,...S].join(" ")}).join(`\r
4
- `)}send(t){const e=typeof t=="string"?t:JSON.stringify(t);if(this.ws&&this.ws.readyState===WebSocket.OPEN)try{this.ws.send(e)}catch{}}mark(t){this.parked&&(this.parked.timings[t]=performance.now())}isNewOrchestrationEnabled(){try{const t=localStorage.getItem(m);if(!t)return!1;const e=JSON.parse(t);return!!(e&&e.newOrchestration===!0)}catch{return!1}}readRegion(){try{const t=localStorage.getItem(k);if(!t)return null;const e=JSON.parse(t);return!e||typeof e.region_code!="string"||typeof e.ts!="number"||Date.now()-e.ts>=2592e6?null:e.region_code}catch{return null}}fetchWithTimeout(t,e,i){const s=new AbortController;e.signal=s.signal;const r=setTimeout(()=>s.abort(),i);return fetch(t,e).finally(()=>clearTimeout(r))}numberOr(t,e){const i=Number(t);return t!=null&&t!==""&&!Number.isNaN(i)?i:e}boolOr(t,e){return t==="true"||t===""?!0:t==="false"?!1:e}}new T().run()})();
1
+ "use strict";(()=>{"use strict";const g=/metabox-configurator\/(modular|basic)\//i,m="features",k="3dsource:region-ping",w="assets/config.json",f="https://datacenter.3dsource.com/signallingserver",y="42e01f";function l(){return typeof crypto!="undefined"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,o=>{const e=Math.random()*16|0;return(o==="x"?e:e&3|8).toString(16)})}function b(o){return o.replace("http://","ws://").replace("https://","wss://")}const h="[stream-prefetch]",n=(...o)=>console.log(h,...o),c=(...o)=>console.warn(h,...o),u=(...o)=>console.error(h,...o);class T{constructor(){const e=document.currentScript||(()=>{const s=document.getElementsByTagName("script");return s[s.length-1]})(),t=e&&e.dataset||{};this.configUrl=t.configUrl||w,this.fallbackPollingUrl=t.fallbackUrl||"",this.skipRouteCheck=this.boolOr(t.skipRouteCheck,!1),this.config={ws_timeout:this.numberOr(t.wsTimeout,6e3),poll_timeout:this.numberOr(t.pollTimeout,4e3)};const i=new URLSearchParams(window.location.search);this.forceTURN=i.has("ForceTURN"),this.forceMaxBundle=i.has("ForceMaxBundle"),this.forceMonoAudio=i.has("forceMono"),this.ids={clientId:l(),viewId:l(),correlationId:l(),streamRequestId:""},this.region="",this.pc=null,this.dc=null,this.stream=null,this.ws=null,this.remoteDescriptionSet=!1,this.iceBuffer=[],this.wsTimeoutId=null,this.settled=!1}run(){if(!(typeof window=="undefined"||!("WebSocket"in window)||!("RTCPeerConnection"in window))){if(this.isNewOrchestrationEnabled()){n("skip \u2014 features.newOrchestration is enabled");return}if(this.skipRouteCheck){c("skipRouteCheck=true \u2014 ignoring URL gate; using fallback polling"),this.publishParked("connecting"),this.connect().catch(e=>this.fail("exception",e));return}if(!g.test(window.location.href)){n("skip \u2014 not a metabox-configurator/{modular|basic} route");return}n("start",{ids:this.ids}),this.publishParked("connecting"),this.connect().catch(e=>this.fail("exception",e))}}connect(){return this.mark("prefetch_start"),this.region=this.readRegion()||"",n("region from cache:",this.region||"(none)"),(this.skipRouteCheck?Promise.resolve(null):this.fetchConfig()).then(t=>{let i;if(t){if(i=this.chooseEndpoint(t),i&&!this.isAllowedEndpoint(i.url)){n("skip \u2014 signalling URL not sanctioned for prefetch",i.url),this.fail("endpoint-not-allowed");return}}else if(this.fallbackPollingUrl)c("no app config \u2014 falling back to polling",this.fallbackPollingUrl),i={type:"polling",url:this.fallbackPollingUrl};else{this.fail("no-config");return}if(!i){this.fail("no-endpoint");return}n("endpoint chosen",{type:i.type,url:i.url});const s=this.adaptUrlToRegion(i.url);return this.pollOrchestration(s).then(r=>{if(!r){this.fail("no-ws-url");return}return this.parked.machineId=r,n("opening socket",r),this.openSocket(r)})})}fetchConfig(){const e=new URL(this.configUrl,window.location.origin).href;return this.fetchWithTimeout(e,{credentials:"omit"},this.config.poll_timeout).then(t=>t.ok?t.json().catch(()=>null):null).catch(()=>null)}chooseEndpoint(e){const t=e.signalling,i=this.firstVersionUrl(t&&t.versions);return i?{type:"polling",url:i}:null}isAllowedEndpoint(e){if(typeof e!="string")return!1;const t=e.replace(/\/+$/,"");return t===f||t.startsWith(f+"/")}firstVersionUrl(e){if(!e||typeof e!="object")return"";for(const t of Object.keys(e))if(e[t])return e[t];return""}pollOrchestration(e){const t=`${e}${this.ids.clientId}/${this.ids.viewId}`;return this.fetchWithTimeout(t,{credentials:"omit"},this.config.poll_timeout).then(i=>i.ok?i.json().catch(()=>({})):null).then(i=>!i||!i.signallingServer?null:(this.ids.streamRequestId=i.streamRequestId||"",b(`${window.location.protocol}//${i.signallingServer}`))).catch(()=>null)}adaptUrlToRegion(e){return this.region&&e.indexOf(":region")===-1?e.replace(/signallingserver/gi,`signallingserver/region:${this.region}`):e}openSocket(e){const t=this.ids.streamRequestId,i=t?e+(e.indexOf("?")===-1?"?":"&")+"streamRequestId="+encodeURIComponent(t):e,s=new WebSocket(i);s.binaryType="arraybuffer",this.ws=s,this.parked.ws=s,this.wsTimeoutId=setTimeout(()=>{s.readyState!==WebSocket.OPEN&&this.fail("ws-timeout")},this.config.ws_timeout),s.onopen=()=>{clearTimeout(this.wsTimeoutId),this.mark("ws_open"),n("WS open \u2014 waiting for config",{region:this.region,streamRequestId:t||"(none)"})},s.onmessage=r=>this.onWsMessage(r),s.onerror=r=>{u("WS error",r),this.fail("ws-error")},s.onclose=r=>{!this.settled&&this.parked.state!=="ready"&&(c("WS closed before ready",{code:r&&r.code}),this.fail("ws-closed"))}}onWsMessage(e){let t;try{const i=typeof e.data=="string"?e.data:null;if(i===null)return;t=JSON.parse(i)}catch{return}switch(n("WS \u2190",t.type),t.type){case"ssInfo":this.parked.ssData=t.data;break;case"config":this.onConfig(t);break;case"offer":this.onOffer(t);break;case"answer":this.onAnswer(t);break;case"iceCandidate":this.onIceCandidate(t.candidate);break;case"ping":this.send({type:"pong",source:"front"});break;case"streamerDisconnected":case"playerDisconnected":this.fail("streamer-disconnected");break;case"error":this.fail("orchestration-error");break;default:break}}onConfig(e){if(this.pc)return;const t=Object.assign({},e.peerConnectionOptions);this.forceTURN&&(t.iceTransportPolicy="relay"),t.bundlePolicy=this.forceMaxBundle?"max-bundle":"balanced",t.iceCandidatePoolSize=1,this.parked.config=t;const i=new RTCPeerConnection(t);this.pc=i,this.parked.pc=i,n("PeerConnection created from config"),i.onicecandidate=s=>{s.candidate&&this.send({type:"iceCandidate",candidate:s.candidate})},i.ondatachannel=s=>this.wireDataChannel(s.channel),i.ontrack=s=>{s.track&&s.track.kind==="video"&&s.streams[0]&&(n("video track received"),this.stream=s.streams[0],this.parked.stream=this.stream,this.maybeReady())}}onOffer(e){return this.pc?(this.remoteDescriptionSet=!1,this.iceBuffer.length=0,this.pc.setRemoteDescription(e).then(()=>(this.remoteDescriptionSet=!0,this.flushIce(),this.pc.createAnswer())).then(t=>(t.sdp=this.mungeSDP(t.sdp||""),this.pc.setLocalDescription(t).then(()=>{n("WS \u2192 answer sent"),this.send(t)}))).catch(t=>this.fail("offer-failed",t))):Promise.resolve()}onAnswer(e){return this.pc?this.pc.setRemoteDescription(e).then(()=>{this.remoteDescriptionSet=!0,this.flushIce()}).catch(t=>this.fail("answer-failed",t)):Promise.resolve()}onIceCandidate(e){e&&(this.forceTURN&&String(e.candidate).indexOf("relay")<0||(this.remoteDescriptionSet&&this.pc?this.pc.addIceCandidate(e).catch(()=>{}):this.iceBuffer.push(e)))}flushIce(){for(const e of this.iceBuffer)this.pc.addIceCandidate(e).catch(()=>{});this.iceBuffer.length=0}wireDataChannel(e){e.binaryType="arraybuffer",this.dc=e,this.parked.dc=e,e.onmessage=t=>{this.parked.dcBuffer.push(t.data)},e.onopen=()=>{n("DataChannel open"),this.mark("dc_open"),this.maybeReady()},e.onclose=()=>{!this.settled&&this.parked.state!=="ready"&&(c("DataChannel closed before ready"),this.fail("dc-closed"))},e.readyState==="open"&&this.maybeReady()}maybeReady(){this.settled||!this.dc||this.dc.readyState!=="open"||this.stream&&(this.settled=!0,this.mark("ready"),this.parked.state="ready",n("READY \u2014 parked on window.__stream",this.parked.timings),this.fireSettled())}publishParked(e){const t=this;this.parked={state:e,pc:null,dc:null,stream:null,ws:null,ssData:void 0,machineId:void 0,config:void 0,ids:this.ids,dcBuffer:[],timings:{},adopt(){return t.clearTimers(),this.state="adopted",this},onSettled(i){if(typeof i=="function"){if(this.state!=="connecting"){const s=this.state;Promise.resolve().then(()=>i(s));return}t.settledCb=i}}},window.__stream=this.parked}fireSettled(){const e=this.settledCb;if(e){this.settledCb=null;try{e(this.parked.state)}catch{}}}clearTimers(){this.wsTimeoutId&&(clearTimeout(this.wsTimeoutId),this.wsTimeoutId=null)}fail(e,t){if(!(this.parked&&(this.parked.state==="adopted"||this.parked.state==="failed"))){u("FAILED:",e,t||""),this.settled=!0,this.clearTimers();try{this.dc&&this.dc.close()}catch{}try{this.pc&&this.pc.close()}catch{}try{this.ws&&this.ws.close()}catch{}this.parked&&(this.parked.state="failed",this.parked.failReason=e,t&&(this.parked.failError=String(t&&t.message||t)),this.fireSettled())}}mungeSDP(e){let t=this.prioritizeH264Profile(e,y);t=t.replace(/(a=fmtp:\d+ .*level-asymmetry-allowed=.*)\r\n/gm,`$1;x-google-start-bitrate=10000;x-google-max-bitrate=100000\r
2
+ `);let i="maxaveragebitrate=510000;";return i+=this.forceMonoAudio?"stereo=0;":"stereo=1;",i+="useinbandfec=1",t=t.replace("useinbandfec=1",i),t}prioritizeH264Profile(e,t){const i=e.split(`\r
3
+ `),s=[];for(const r of i)if(r.startsWith("a=fmtp:")&&r.toLowerCase().includes(`profile-level-id=${t}`)){const a=r.split(":")[1]&&r.split(":")[1].split(" ")[0];a&&s.push(a)}return s.length===0?e:i.map(r=>{if(!r.startsWith("m=video"))return r;const a=r.split(" "),x=a.slice(0,3),p=a.slice(3),S=[...s.filter(d=>p.includes(d)),...p.filter(d=>!s.includes(d))];return[...x,...S].join(" ")}).join(`\r
4
+ `)}send(e){const t=typeof e=="string"?e:JSON.stringify(e);if(this.ws&&this.ws.readyState===WebSocket.OPEN)try{this.ws.send(t)}catch{}}mark(e){this.parked&&(this.parked.timings[e]=performance.now())}isNewOrchestrationEnabled(){try{const e=localStorage.getItem(m);if(!e)return!1;const t=JSON.parse(e);return!!(t&&t.newOrchestration===!0)}catch{return!1}}readRegion(){try{const e=localStorage.getItem(k);if(!e)return null;const t=JSON.parse(e);return!t||typeof t.region_code!="string"||typeof t.ts!="number"||Date.now()-t.ts>=2592e6?null:t.region_code}catch{return null}}fetchWithTimeout(e,t,i){const s=new AbortController;t.signal=s.signal;const r=setTimeout(()=>s.abort(),i);return fetch(e,t).finally(()=>clearTimeout(r))}numberOr(e,t){const i=Number(e);return e!=null&&e!==""&&!Number.isNaN(i)?i:t}boolOr(e,t){return e==="true"||e===""?!0:e==="false"?!1:t}}new T().run()})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@3dsource/angular-unreal-module",
3
- "version": "0.0.162",
3
+ "version": "0.0.163",
4
4
  "description": "Angular integration for Unreal Engine Pixel Streaming",
5
5
  "keywords": [
6
6
  "3dsource",
@@ -338,11 +338,17 @@ interface ParkedStream {
338
338
  machineId?: string;
339
339
  /** `peerConnectionOptions` the machine sent in its `config` message */
340
340
  config?: RTCConfiguration;
341
- /** ids the script generated; Angular reuses them (no regeneration) */
341
+ /**
342
+ * ids the script generated; Angular reuses them (no regeneration).
343
+ * `streamRequestId` is the exception — it is NOT generated but read from the
344
+ * polling response and passed to Cirrus on the upgrade URL; empty when the
345
+ * backend didn't issue one.
346
+ */
342
347
  ids: {
343
348
  clientId: string;
344
349
  viewId: string;
345
350
  correlationId: string;
351
+ streamRequestId?: string;
346
352
  };
347
353
  /** DataChannel messages received before adoption, replayed on adopt */
348
354
  dcBuffer: ArrayBuffer[];
@@ -554,6 +560,12 @@ type SignalingMessageHandler<T extends keyof SignalingMessageMap> = (msg: Signal
554
560
  interface PollingOrchestrationMessage {
555
561
  mm_message?: string;
556
562
  signallingServer?: string;
563
+ /**
564
+ * Connection id issued by the orchestration for this stream request. Kept
565
+ * internally as `connectionId` and handed to Cirrus on the WS upgrade URL.
566
+ * Absent on older backends — Cirrus then generates one itself.
567
+ */
568
+ streamRequestId?: string;
557
569
  error?: string;
558
570
  info?: {
559
571
  age: number | null;
@@ -1410,8 +1422,15 @@ declare class SignallingService extends SubService {
1410
1422
  *
1411
1423
  * "Just connect" — nothing is sent on open (the machine is already reserved
1412
1424
  * for this session): Cirrus pushes `config` and Unreal sends the `offer`.
1425
+ *
1426
+ * The orchestration-issued `streamRequestId` (from the same `instanceReady`
1427
+ * payload) rides on this upgrade URL: in the new flow THIS is the Cirrus
1428
+ * socket, so it is the one that must carry the id (the first socket is
1429
+ * orchestration-only control and needs nothing). Without it the stream
1430
+ * machine's Cirrus falls back to its own `guid()` and the session can no
1431
+ * longer be correlated. Absent id → URL unchanged.
1413
1432
  */
1414
- connectToStreamMachine(originInstanceUri: string): void;
1433
+ connectToStreamMachine(originInstanceUri: string, streamRequestId?: string | null): void;
1415
1434
  /**
1416
1435
  * The stream-machine (Cirrus) connection failed. Re-request a machine over
1417
1436
  * the still-open orchestration socket: orchestration issues a new
@@ -2568,10 +2587,24 @@ declare const setAwsInstance: _ngrx_store.ActionCreator<string, (props: {
2568
2587
  wsUrl: string | null;
2569
2588
  pollingUrl: string | null;
2570
2589
  instanceName: string | null;
2590
+ /**
2591
+ * Connection id issued by the orchestration in the polling response. Kept
2592
+ * internally as `connectionId` (see `selectCirrusConnectionId`). Undefined
2593
+ * in the new-orchestration flow, where it arrives later via
2594
+ * `instanceReserved` → {@link setOrchestrationParameters}.
2595
+ */
2596
+ streamRequestId?: string;
2571
2597
  }) => {
2572
2598
  wsUrl: string | null;
2573
2599
  pollingUrl: string | null;
2574
2600
  instanceName: string | null;
2601
+ /**
2602
+ * Connection id issued by the orchestration in the polling response. Kept
2603
+ * internally as `connectionId` (see `selectCirrusConnectionId`). Undefined
2604
+ * in the new-orchestration flow, where it arrives later via
2605
+ * `instanceReserved` → {@link setOrchestrationParameters}.
2606
+ */
2607
+ streamRequestId?: string;
2575
2608
  } & _ngrx_store.Action<string>>;
2576
2609
  declare const setStatusMessage: _ngrx_store.ActionCreator<string, (props: {
2577
2610
  statusMessage: string | null;
@@ -2811,6 +2844,12 @@ declare const initSignalling: _ngrx_store.ActionCreator<string, () => _ngrx_stor
2811
2844
  declare const streamAdopted: _ngrx_store.ActionCreator<string, (props: {
2812
2845
  machineId: string | null;
2813
2846
  ssData: SignalingData | null;
2847
+ /**
2848
+ * Orchestration-issued connection id the prefetch script read from the
2849
+ * polling response and already passed to Cirrus. Kept internally as
2850
+ * `connectionId` (see `selectCirrusConnectionId`).
2851
+ */
2852
+ streamRequestId: string | null;
2814
2853
  /**
2815
2854
  * `performance.now()` marks the prefetch script recorded while it
2816
2855
  * established the connection (`prefetch_start` / `ws_open` / `dc_open` /
@@ -2824,6 +2863,12 @@ declare const streamAdopted: _ngrx_store.ActionCreator<string, (props: {
2824
2863
  }) => {
2825
2864
  machineId: string | null;
2826
2865
  ssData: SignalingData | null;
2866
+ /**
2867
+ * Orchestration-issued connection id the prefetch script read from the
2868
+ * polling response and already passed to Cirrus. Kept internally as
2869
+ * `connectionId` (see `selectCirrusConnectionId`).
2870
+ */
2871
+ streamRequestId: string | null;
2827
2872
  /**
2828
2873
  * `performance.now()` marks the prefetch script recorded while it
2829
2874
  * established the connection (`prefetch_start` / `ws_open` / `dc_open` /
@@ -3220,8 +3265,19 @@ declare const selectIsLoaderScreenVisible: _ngrx_store.MemoizedSelector<Record<s
3220
3265
  * producing a small visual step that indicates the WS handshake succeeded.
3221
3266
  */
3222
3267
  declare const selectTotalProgress: _ngrx_store.MemoizedSelector<Record<string, any>, number, (s1: number | null, s2: number, s3: _3dsource_angular_unreal_module.AwsInstance, s4: boolean) => number>;
3223
- /** Used by external consumers (e.g., metabox). Do not remove. */
3224
- declare const selectCirrusConnectionId: _ngrx_store.MemoizedSelector<Record<string, any>, string | undefined, (s1: _3dsource_angular_unreal_module.SignalingData | null) => string | undefined>;
3268
+ /**
3269
+ * The connection id of the current stream session.
3270
+ *
3271
+ * Primary source is the orchestration, which issues it as `streamRequestId` —
3272
+ * in the polling response (legacy flow) or in `instanceReserved`/`instanceReady`
3273
+ * (new orchestration) — and the browser hands it to Cirrus on the WS upgrade
3274
+ * URL. `ssData.connectionId` (the `ssInfo` message) is the fallback for
3275
+ * backends that don't issue one yet: Cirrus then generates it itself and
3276
+ * reports it back here.
3277
+ *
3278
+ * Used by external consumers (e.g., metabox). Do not remove.
3279
+ */
3280
+ declare const selectCirrusConnectionId: _ngrx_store.MemoizedSelector<Record<string, any>, string | undefined, (s1: _3dsource_angular_unreal_module.AwsInstance, s2: _3dsource_angular_unreal_module.SignalingData | null) => string | undefined>;
3225
3281
  /** Used by external consumers (e.g., metabox). Do not remove. */
3226
3282
  declare const selectUserInactivityDetected: _ngrx_store.MemoizedSelector<Record<string, any>, {
3227
3283
  remainingSecondsToDisconnect: number;