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

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 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()})();
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]",r=(...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(),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()){r("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)){r("skip \u2014 not a metabox-configurator/{modular|basic} route");return}r("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()||"",r("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)){r("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}r("endpoint chosen",{type:i.type,url:i.url});const s=this.adaptUrlToRegion(i.url);return this.pollOrchestration(s).then(n=>{if(!n){this.fail("no-ws-url");return}return this.parked.machineId=n,this.parked.pollingUrl=s,r("opening socket",n),this.openSocket(n)})})}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?null:(this.ids.streamRequestId=i.streamRequestId||"",b(`${window.location.protocol}//${i.signallingServer}`))).catch(()=>null)}adaptUrlToRegion(t){return this.region&&t.indexOf(":region")===-1?t.replace(/signallingserver/gi,`signallingserver/region:${this.region}`):t}openSocket(t){const e=this.ids.streamRequestId,i=e?t+(t.indexOf("?")===-1?"?":"&")+"streamRequestId="+encodeURIComponent(e):t,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"),r("WS open \u2014 waiting for config",{region:this.region,streamRequestId:e||"(none)"})},s.onmessage=n=>this.onWsMessage(n),s.onerror=n=>{u("WS error",n),this.fail("ws-error")},s.onclose=n=>{!this.settled&&this.parked.state!=="ready"&&(c("WS closed before ready",{code:n&&n.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(r("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;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,r("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]&&(r("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(()=>{r("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=()=>{r("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",r("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,pollingUrl: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 n of i)if(n.startsWith("a=fmtp:")&&n.toLowerCase().includes(`profile-level-id=${e}`)){const a=n.split(":")[1]&&n.split(":")[1].split(" ")[0];a&&s.push(a)}return s.length===0?t:i.map(n=>{if(!n.startsWith("m=video"))return n;const a=n.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 n=setTimeout(()=>s.abort(),i);return fetch(t,e).finally(()=>clearTimeout(n))}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()})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@3dsource/angular-unreal-module",
3
- "version": "0.0.163",
3
+ "version": "0.0.165",
4
4
  "description": "Angular integration for Unreal Engine Pixel Streaming",
5
5
  "keywords": [
6
6
  "3dsource",
@@ -336,6 +336,8 @@ interface ParkedStream {
336
336
  ssData?: SignalingData;
337
337
  /** = resolved wsUrl of the winning machine */
338
338
  machineId?: string;
339
+ /** orchestration endpoint the script polled to get `machineId` */
340
+ pollingUrl?: string;
339
341
  /** `peerConnectionOptions` the machine sent in its `config` message */
340
342
  config?: RTCConfiguration;
341
343
  /**
@@ -380,7 +382,6 @@ interface InputProps {
380
382
  type Quality = 'lime' | 'red' | 'orange';
381
383
 
382
384
  declare const OrchestrationMessageTypes: {
383
- readonly ping: "ping";
384
385
  readonly error: "error";
385
386
  readonly offer: "offer";
386
387
  readonly answer: "answer";
@@ -394,8 +395,6 @@ declare const OrchestrationMessageTypes: {
394
395
  readonly instanceReady: "instanceReady";
395
396
  readonly p2pEstablished: "p2pEstablished";
396
397
  readonly instanceReserved: "instanceReserved";
397
- readonly playerDisconnected: "playerDisconnected";
398
- readonly streamerDisconnected: "streamerDisconnected";
399
398
  readonly interruptClientStream: "interruptClientStream";
400
399
  };
401
400
  interface InstanceReady extends MessageBase {
@@ -451,11 +450,6 @@ interface CandidateMessage extends MessageBase {
451
450
  type: 'iceCandidate';
452
451
  candidate: RTCIceCandidate;
453
452
  }
454
- interface PingMessage extends MessageBase {
455
- type: 'ping';
456
- playerId: string;
457
- appConnectionCounter: number;
458
- }
459
453
  type UnknownFields = Record<string, unknown>;
460
454
  interface InterruptClientStream extends MessageBase {
461
455
  type: 'interruptClientStream';
@@ -464,10 +458,6 @@ interface InterruptClientStream extends MessageBase {
464
458
  environmentId: string;
465
459
  };
466
460
  }
467
- interface ForceClientDisconnect extends MessageBase {
468
- type: 'streamerDisconnected' | 'playerDisconnected';
469
- connectionId: string;
470
- }
471
461
  interface ListStreamersMessage extends MessageBase {
472
462
  type: 'listStreamers';
473
463
  correlationId: string;
@@ -536,7 +526,6 @@ interface MetaboxCustomApplicationContext {
536
526
  }
537
527
  type StreamRequestContext = MetaboxStudioContext | MetaboxProductContext | CustomApplicationContext | MetaboxCustomApplicationContext | MetaboxEnvironmentContext | MetaboxBasicConfiguratorContext | MetaboxModularConfiguratorContext;
538
528
  interface SignalingMessageMap {
539
- [OrchestrationMessageTypes.ping]: PingMessage;
540
529
  [OrchestrationMessageTypes.offer]: RTCSessionDescriptionInit;
541
530
  [OrchestrationMessageTypes.error]: OrchestrationErrorMessage;
542
531
  [OrchestrationMessageTypes.ssInfo]: SSInfo;
@@ -550,8 +539,6 @@ interface SignalingMessageMap {
550
539
  [OrchestrationMessageTypes.listStreamers]: ListStreamersMessage;
551
540
  [OrchestrationMessageTypes.p2pEstablished]: P2PEstablishedMessage;
552
541
  [OrchestrationMessageTypes.instanceReserved]: InstanceReserved;
553
- [OrchestrationMessageTypes.playerDisconnected]: ForceClientDisconnect;
554
- [OrchestrationMessageTypes.streamerDisconnected]: ForceClientDisconnect;
555
542
  [OrchestrationMessageTypes.interruptClientStream]: InterruptClientStream;
556
543
  }
557
544
  type OrchestrationMessageType = keyof SignalingMessageMap;
@@ -889,11 +876,29 @@ interface InboundVideoStats extends RTCInboundRtpStreamStats {
889
876
  receiveToCompositeMs: number;
890
877
  bitrate: number;
891
878
  }
879
+ /**
880
+ * Which orchestration transport was asked for the Cirrus endpoint:
881
+ * - `polling` — HTTP orchestration poll (`requestCirrusViaPolling`)
882
+ * - `socket` — orchestration control socket + `instanceReady`
883
+ * (`requestCirrusViaSocket`)
884
+ *
885
+ * Undefined when nothing was requested at all — a `ws://` URL that already points
886
+ * at Cirrus (`requestCirrusDirect`, dev/playwright) or an adopted prefetched
887
+ * stream. Those are not request kinds, they are the absence of a request.
888
+ *
889
+ * Replaces the previous hostname sniffing (`/^wss:\/\/orchestration-websocket/`)
890
+ * in `selectTotalProgress` — the flow is now stated, not guessed.
891
+ */
892
+ type CirrusRequestKind = 'polling' | 'socket';
892
893
  interface AwsInstance {
893
894
  /**
894
- * WebSocket URL for connecting to the Cirrus (polling mode) or Orchestration (direct mode).
895
+ * WebSocket URL of the CIRRUS the player connects to. In the socket flow
896
+ * this is the stream machine's `originInstanceUri`, NOT the orchestration
897
+ * URL (the control socket is tracked separately by `SignallingService`).
895
898
  */
896
899
  wsUrl: string | null;
900
+ /** See {@link CirrusRequestKind}. */
901
+ kind?: CirrusRequestKind;
897
902
  pollingUrl: string | null;
898
903
  instanceName: string | null;
899
904
  /**
@@ -936,6 +941,7 @@ declare const POLLING_TIME = 4000;
936
941
  declare const INNER_RETRY_LIMIT = 3;
937
942
  declare const OUTER_RETRY_DELAY: number;
938
943
  declare const WS_RETRY_PER_INSTANCE = 1;
944
+ declare const INSTANCE_READY_TIMEOUT = 180000;
939
945
  declare const WS_OPEN_STATE = 1;
940
946
  declare const DEFAULT_AFK_TIMEOUT_PERIOD = 15;
941
947
  declare const DEFAULT_AFK_TIMEOUT = 300;
@@ -1332,13 +1338,18 @@ declare class SignallingService extends SubService {
1332
1338
  onConfig$: Subject<ConfigMessage>;
1333
1339
  onWebRtcIce$: Subject<RTCIceCandidate>;
1334
1340
  onWebRtcAnswer$: Subject<RTCSessionDescriptionInit | null>;
1341
+ onInstanceReady$: Subject<{
1342
+ instanceId: string;
1343
+ originInstanceId: string;
1344
+ ipAddress: string;
1345
+ streamRequestId: string;
1346
+ originInstanceUri: string;
1347
+ }>;
1335
1348
  abort$: Observable<_ngrx_store.Action<string>>;
1336
1349
  private ws;
1337
- private streamWs;
1338
- private streamMachineConnected;
1339
- private streamMachineRetryCount;
1340
- private streamWsSub?;
1350
+ private controlWs;
1341
1351
  orchestrationRetrySub?: Subscription;
1352
+ orchestrationRetryCount: number;
1342
1353
  private wsMsgHandlers;
1343
1354
  protected correlationId: string;
1344
1355
  constructor();
@@ -1346,7 +1357,7 @@ declare class SignallingService extends SubService {
1346
1357
  connectToSignaling(urlList: string[]): Observable<WebSocket>;
1347
1358
  /**
1348
1359
  * One inner cycle: rotate `urlGen` over the pool, resolve via
1349
- * {@link getAwsInstance}, open WS via {@link connectToCirrus},
1360
+ * {@link requestCirrus}, open WS via {@link connectToCirrus},
1350
1361
  * retry up to {@link INNER_RETRY_LIMIT} on any hard failure. The
1351
1362
  * urlGen lives in this closure so retries advance through the
1352
1363
  * pool. Exhaustion bubbles to {@link connectToSignaling}'s outer
@@ -1366,17 +1377,37 @@ declare class SignallingService extends SubService {
1366
1377
  protected startEstablishingConnection(): void;
1367
1378
  private adaptUrlsToRegion;
1368
1379
  /**
1369
- * Resolve one URL to an `AwsInstance`. Dispatches to
1370
- * {@link directWsInstance} for `ws://` / `wss://` URLs, otherwise
1371
- * to {@link pollOrchestration}.
1380
+ * Ask the orchestration for a Cirrus to connect to. All three
1381
+ * implementations answer the same question — "which Cirrus, and with which
1382
+ * `streamRequestId`?" — and emit ONE `AwsInstance` whose `wsUrl` is a Cirrus
1383
+ * address. What differs is only how the answer is obtained and therefore how
1384
+ * it can fail:
1385
+ *
1386
+ * | Method | Transport | Fails on |
1387
+ * | -------------------------- | -------------------- | ------------------------------ |
1388
+ * | {@link requestCirrusViaPolling} | HTTP poll loop | HTTP 4xx (dead URL) |
1389
+ * | {@link requestCirrusViaSocket} | control WS | socket drop / no `instanceReady` in {@link INSTANCE_READY_TIMEOUT} |
1390
+ * | {@link requestCirrusDirect} | none (dev) | never — nothing is requested |
1391
+ *
1392
+ * Whatever they return goes through the SAME downstream in
1393
+ * {@link connectAttempt}: `setAwsInstance` → `connectToCirrus` → the WS-only
1394
+ * and URL-rotating retry tiers. A failure inside any of them is just an
1395
+ * error on this observable, so those tiers handle it uniformly.
1396
+ */
1397
+ private requestCirrus;
1398
+ /** True when `requestStream` can be composed → new orchestration. */
1399
+ private hasOrchestrationContext;
1400
+ /**
1401
+ * Wait until `clientId` and `viewId` are known — every request method needs
1402
+ * them before it may talk to the backend.
1372
1403
  */
1373
- private getAwsInstance;
1404
+ private waitForClientAndViewIds;
1374
1405
  /**
1375
- * Direct `ws://` / `wss://` short-circuit — no HTTP orchestration.
1376
- * Waits for `clientId` and `viewId` to be truthy in the store, then
1377
- * emits a `Direct Connection` `AwsInstance` and completes.
1406
+ * Direct `ws://` / `wss://` short-circuit — no orchestration at all, the URL
1407
+ * already points at Cirrus. Dev/playwright convenience, hence no
1408
+ * `kind`: nothing was requested.
1378
1409
  */
1379
- private directWsInstance;
1410
+ private requestCirrusDirect;
1380
1411
  /**
1381
1412
  * HTTP-orchestration path. Brackets {@link pollLoop} with the
1382
1413
  * `pollingStarted`/`pollingEnded` actions and the `EXT-getSignaling`
@@ -1384,7 +1415,34 @@ declare class SignallingService extends SubService {
1384
1415
  * last response captured in the closure). Maps the final ready
1385
1416
  * response to an `AwsInstance`.
1386
1417
  */
1387
- private pollOrchestration;
1418
+ private requestCirrusViaPolling;
1419
+ /**
1420
+ * WS-orchestration path — the socket-transport twin of
1421
+ * {@link requestCirrusViaPolling}. Opens the control socket, sends
1422
+ * `requestStream` and waits for `instanceReady`, whose `originInstanceUri`
1423
+ * IS the Cirrus address.
1424
+ *
1425
+ * Failure modes are handled here so they surface as a plain error and reach
1426
+ * `connectAttempt`'s retry tiers (previously this branch lived outside them
1427
+ * and a dead control socket silently hung the session):
1428
+ * - control socket closes/errors before `instanceReady` → error
1429
+ * - no `instanceReady` within {@link INSTANCE_READY_TIMEOUT} → error
1430
+ *
1431
+ * The control socket lives exactly as long as this wait — see
1432
+ * {@link awaitInstanceReady}.
1433
+ */
1434
+ private requestCirrusViaSocket;
1435
+ /**
1436
+ * Send `requestStream` on the freshly opened control socket and resolve with
1437
+ * the machine coordinates from `instanceReady`.
1438
+ *
1439
+ * The socket lives exactly as long as this wait: its close/error are HARD
1440
+ * failures of the request, and on resolution it is closed with every handler
1441
+ * detached (the backend does not use it after the handover). So the control
1442
+ * socket has no post-handover state at all — nothing that could report a stale
1443
+ * "disconnect" against a live stream.
1444
+ */
1445
+ private awaitInstanceReady;
1388
1446
  /**
1389
1447
  * Poll the SAME `url` until ready, or until HTTP 4xx says the URL
1390
1448
  * is dead.
@@ -1402,9 +1460,12 @@ declare class SignallingService extends SubService {
1402
1460
  */
1403
1461
  private pollLoop;
1404
1462
  private connectToCirrus;
1463
+ /**
1464
+ * Handlers for the CIRRUS socket — the only long-lived socket. Its close/error
1465
+ * are real stream events (`setCirrusDisconnected` / `dropConnection`), unlike
1466
+ * the control socket's, which never outlives {@link awaitInstanceReady}.
1467
+ */
1405
1468
  private addWsHandlers;
1406
- private onOrchestrationClose;
1407
- private onOrchestrationError;
1408
1469
  /**
1409
1470
  * Adopt a live signalling socket opened by the `stream-prefetch.js`
1410
1471
  * head-script. The socket is already OPEN and `requestStream` was already
@@ -1414,61 +1475,53 @@ declare class SignallingService extends SubService {
1414
1475
  * `correlationId` so subsequent correlated messages line up.
1415
1476
  */
1416
1477
  adoptSocket(ws: WebSocket, correlationId: string): void;
1417
- /**
1418
- * Open the SECOND socket, directly to the stream machine's Cirrus
1419
- * (`originInstanceUri` from `instanceReady`). The whole WebRTC signalling
1420
- * (config/offer/answer/iceCandidate/ping) flows over this socket; the
1421
- * orchestration socket (`this.ws`) stays open for control/lifecycle.
1422
- *
1423
- * "Just connect" — nothing is sent on open (the machine is already reserved
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.
1432
- */
1433
- connectToStreamMachine(originInstanceUri: string, streamRequestId?: string | null): void;
1434
- /**
1435
- * The stream-machine (Cirrus) connection failed. Re-request a machine over
1436
- * the still-open orchestration socket: orchestration issues a new
1437
- * streamRequestId and a fresh `instanceReady(originInstanceUri)`, which calls
1438
- * {@link connectToStreamMachine} again on a different machine. Bounded by
1439
- * {@link INNER_RETRY_LIMIT}; on exhaustion the stream is dropped.
1440
- */
1441
- private retryStreamMachine;
1442
- private addStreamWsHandlers;
1443
- private teardownStreamWs;
1444
1478
  private showStatusMessage;
1445
1479
  /**
1446
- * Close the connection with the signaling server
1447
- * @param data
1480
+ * Close everything: the Cirrus socket AND the orchestration control socket.
1481
+ * Used on abort/teardown. A new connection attempt inside a live cycle uses
1482
+ * {@link closeCirrus} instead, so it does not kill the control socket that
1483
+ * produced the address it is about to connect to.
1448
1484
  */
1449
1485
  close(data: CloseReason): void;
1486
+ /** Close only the Cirrus signalling socket. */
1487
+ private closeCirrus;
1488
+ private teardownControlWs;
1450
1489
  private teardownSocket;
1451
- send(data: AnySignalingMessage): void;
1452
1490
  /**
1453
- * Send player signalling (offer/answer/iceCandidate/pong/p2pEstablished/
1454
- * subscribe) over the ACTIVE signalling socket: the stream-machine socket in
1455
- * the new flow (once connected), or the orchestration/relay socket in the old
1456
- * polling flow (where there is no separate stream socket).
1491
+ * Player signalling (offer/answer/iceCandidate/pong/p2pEstablished/subscribe)
1492
+ * — always the Cirrus socket, in every flow.
1457
1493
  */
1458
- sendPlayerSignal(data: AnySignalingMessage): void;
1494
+ send(data: AnySignalingMessage): void;
1495
+ /** Orchestration control messages (`requestStream`) — the control socket. */
1496
+ sendToOrchestration(data: AnySignalingMessage): void;
1459
1497
  private sendTo;
1460
1498
  protected handleMessage(msg: MessageBase): void;
1461
- private setHandlersFromStream;
1499
+ /**
1500
+ * One handler map shared by both sockets — `handleMessage` dispatches purely by
1501
+ * message type. Which socket a type can arrive on is fixed, so registration is
1502
+ * split by origin: {@link setOrchestrationHandlers} (control socket) and
1503
+ * {@link setStreamHandlers} (Cirrus).
1504
+ *
1505
+ * Keepalive is deliberately absent: both servers ping at the WS **protocol**
1506
+ * level (`ws.ping()`), which the browser answers on its own — the page never
1507
+ * sees a ping and must never reply with an application-level `pong`. An
1508
+ * unregistered type is dropped silently by `handleMessage`, so a `ping` from a
1509
+ * not-yet-updated backend is simply ignored.
1510
+ */
1511
+ private setMessageHandlers;
1512
+ /**
1513
+ * Messages from the ORCHESTRATION control socket. Only reachable during the
1514
+ * provisioning wait — `requestCirrusViaSocket` closes that socket the moment
1515
+ * `instanceReady` lands.
1516
+ */
1517
+ private setOrchestrationHandlers;
1518
+ /** Messages from the CIRRUS socket — the actual stream signalling. */
1519
+ private setStreamHandlers;
1462
1520
  protected sendRequestStream(): void;
1463
1521
  /**
1464
- * Check if the ACTIVE player-signalling socket is open and ready. Mirrors
1465
- * {@link sendPlayerSignal}'s socket choice so peer-reconnect gating is correct
1466
- * in both flows:
1467
- * - NEW flow (`streamMachineConnected`): the stream-machine socket
1468
- * (`streamWs`). The orchestration socket (`this.ws`) is intentionally
1469
- * closed after occupancy, so checking it would wrongly report "not
1470
- * connected" and block reconnect.
1471
- * - OLD polling flow: the single relay socket (`this.ws`) — unchanged.
1522
+ * Is the player-signalling socket open? Always the Cirrus socket — the
1523
+ * control socket's state is irrelevant to the stream (orchestration closes it
1524
+ * once the instance is occupied), so it must not be part of this gate.
1472
1525
  */
1473
1526
  isConnected(): boolean;
1474
1527
  private getRegion;
@@ -2323,8 +2376,6 @@ declare function InstanceReadyHandler(this: SignallingService, msg: InstanceRead
2323
2376
 
2324
2377
  declare function InstanceReservedHandler(this: SignallingService, msg: InstanceReserved): void;
2325
2378
 
2326
- declare function PingHandler(this: SignallingService): void;
2327
-
2328
2379
  declare function PlayerCountHandler(this: SignallingService, msg: PlayerCountMessage): void;
2329
2380
 
2330
2381
  declare function SSInfoHandler(this: SignallingService, msg: SSInfo): null;
@@ -2335,6 +2386,14 @@ declare function OnErrorHandler(this: SignallingService, e: Event): void;
2335
2386
 
2336
2387
  declare function OnMessageHandler(this: SignallingService, e: MessageEvent<string | Blob>): void;
2337
2388
 
2389
+ /**
2390
+ * Open handler of the CIRRUS socket only (`addWsHandlers`), so
2391
+ * `setCirrusConnected` now means what it says. It used to also send
2392
+ * `requestStream` here, which made the flag fire on the orchestration control
2393
+ * socket — a whole provisioning wait (`eta`, ~150 s) before any Cirrus existed.
2394
+ * `requestStream` belongs to the control socket and is sent by
2395
+ * `requestCirrusViaSocket`.
2396
+ */
2338
2397
  declare function OnOpenHandler(this: SignallingService): void;
2339
2398
 
2340
2399
  /**
@@ -2594,6 +2653,11 @@ declare const setAwsInstance: _ngrx_store.ActionCreator<string, (props: {
2594
2653
  * `instanceReserved` → {@link setOrchestrationParameters}.
2595
2654
  */
2596
2655
  streamRequestId?: string;
2656
+ /**
2657
+ * Which request method produced this endpoint. Stated by the service instead
2658
+ * of being guessed downstream from the URL's hostname.
2659
+ */
2660
+ kind?: CirrusRequestKind;
2597
2661
  }) => {
2598
2662
  wsUrl: string | null;
2599
2663
  pollingUrl: string | null;
@@ -2605,6 +2669,11 @@ declare const setAwsInstance: _ngrx_store.ActionCreator<string, (props: {
2605
2669
  * `instanceReserved` → {@link setOrchestrationParameters}.
2606
2670
  */
2607
2671
  streamRequestId?: string;
2672
+ /**
2673
+ * Which request method produced this endpoint. Stated by the service instead
2674
+ * of being guessed downstream from the URL's hostname.
2675
+ */
2676
+ kind?: CirrusRequestKind;
2608
2677
  } & _ngrx_store.Action<string>>;
2609
2678
  declare const setStatusMessage: _ngrx_store.ActionCreator<string, (props: {
2610
2679
  statusMessage: string | null;
@@ -2843,6 +2912,8 @@ declare const initSignalling: _ngrx_store.ActionCreator<string, () => _ngrx_stor
2843
2912
  */
2844
2913
  declare const streamAdopted: _ngrx_store.ActionCreator<string, (props: {
2845
2914
  machineId: string | null;
2915
+ /** Orchestration endpoint the prefetch polled to resolve `machineId`. */
2916
+ pollingUrl: string | null;
2846
2917
  ssData: SignalingData | null;
2847
2918
  /**
2848
2919
  * Orchestration-issued connection id the prefetch script read from the
@@ -2862,6 +2933,8 @@ declare const streamAdopted: _ngrx_store.ActionCreator<string, (props: {
2862
2933
  timings: Record<string, number> | null;
2863
2934
  }) => {
2864
2935
  machineId: string | null;
2936
+ /** Orchestration endpoint the prefetch polled to resolve `machineId`. */
2937
+ pollingUrl: string | null;
2865
2938
  ssData: SignalingData | null;
2866
2939
  /**
2867
2940
  * Orchestration-issued connection id the prefetch script read from the
@@ -2981,23 +3054,23 @@ declare class UnrealEffects {
2981
3054
  private readonly unrealCallbackService;
2982
3055
  private dataChannelConnectionTimeout;
2983
3056
  private connectionCompleted$;
2984
- destroyConnections$: rxjs.Observable<{
3057
+ destroyConnections$: Observable<{
2985
3058
  reason: _3dsource_angular_unreal_module.DisconnectReasonType;
2986
3059
  } & _ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
2987
- refreshRegionCache$: rxjs.Observable<{
3060
+ refreshRegionCache$: Observable<{
2988
3061
  region_code: string;
2989
3062
  result: number[];
2990
3063
  } | null> & _ngrx_effects.CreateEffectMetadata;
2991
- abortEstablishingConnection$: rxjs.Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
2992
- resetAfk$: rxjs.Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
2993
- iframeMessaging$: rxjs.Observable<string | null> & _ngrx_effects.CreateEffectMetadata;
2994
- setSignalingTo100$: rxjs.Observable<{
3064
+ abortEstablishingConnection$: Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3065
+ resetAfk$: Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3066
+ iframeMessaging$: Observable<string | null> & _ngrx_effects.CreateEffectMetadata;
3067
+ setSignalingTo100$: Observable<{
2995
3068
  percent: number | null;
2996
3069
  } & _ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
2997
- setOrchestrationParameters$: rxjs.Observable<{
3070
+ setOrchestrationParameters$: Observable<{
2998
3071
  progressComplete: number;
2999
3072
  } & _ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3000
- setDataChannelTimeoutCheck$: rxjs.Observable<{
3073
+ setDataChannelTimeoutCheck$: Observable<{
3001
3074
  reason: _3dsource_angular_unreal_module.DisconnectReasonType;
3002
3075
  message: string;
3003
3076
  } & _ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
@@ -3016,11 +3089,11 @@ declare class UnrealEffects {
3016
3089
  * Without this effect, the order of these events may cause
3017
3090
  * a visible flicker (video flashing to black).
3018
3091
  */
3019
- forceViewportNotReady$: rxjs.Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3020
- resetCirrusOnDestroy$: rxjs.Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3021
- destroyRemoteConnections$: rxjs.Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3022
- destroyConnectionAndRestart$: rxjs.Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3023
- showUnrealError$: rxjs.Observable<{
3092
+ forceViewportNotReady$: Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3093
+ resetCirrusOnDestroy$: Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3094
+ destroyRemoteConnections$: Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3095
+ destroyConnectionAndRestart$: Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3096
+ showUnrealError$: Observable<{
3024
3097
  code: number | null;
3025
3098
  error?: string;
3026
3099
  } & _ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
@@ -3040,11 +3113,11 @@ declare class UnrealEffects {
3040
3113
  * cirrus drop, a scene destroy, or the start of a peer reconnect (which is
3041
3114
  * where the pre-existing `isReconnecting` filter hands over).
3042
3115
  */
3043
- unrealReceiverReady$: rxjs.Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3044
- initAppByDataChannelReady$: rxjs.Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3045
- setViewportReadyBySetLoopBackCommandIsCompleted$: rxjs.Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3046
- startStream$: rxjs.Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3047
- resetAfkOnPausedVideoInit$: rxjs.Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3116
+ unrealReceiverReady$: Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3117
+ initAppByDataChannelReady$: Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3118
+ setViewportReadyBySetLoopBackCommandIsCompleted$: Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3119
+ startStream$: Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3120
+ resetAfkOnPausedVideoInit$: Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3048
3121
  /**
3049
3122
  * Effect: `disconnectReasonHandling$`
3050
3123
  *
@@ -3057,7 +3130,7 @@ declare class UnrealEffects {
3057
3130
  * Skip `DataChannelClosed` when peer reconnection can handle it — that
3058
3131
  * path is owned by `handleDataChannelClosed$` instead.
3059
3132
  */
3060
- disconnectReasonHandling$: rxjs.Observable<{
3133
+ disconnectReasonHandling$: Observable<{
3061
3134
  reason: _3dsource_angular_unreal_module.DisconnectReasonType;
3062
3135
  } & _ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3063
3136
  /**
@@ -3067,25 +3140,25 @@ declare class UnrealEffects {
3067
3140
  * Only triggers if reconnection is enabled and the signaling WebSocket
3068
3141
  * is still connected.
3069
3142
  */
3070
- handleDataChannelClosed$: rxjs.Observable<{
3143
+ handleDataChannelClosed$: Observable<{
3071
3144
  attempt: number;
3072
3145
  maxAttempts: number;
3073
3146
  delay?: number;
3074
3147
  } & _ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3075
- webrtcErrorModalComponent$: rxjs.Observable<false> & _ngrx_effects.CreateEffectMetadata;
3148
+ webrtcErrorModalComponent$: Observable<false> & _ngrx_effects.CreateEffectMetadata;
3076
3149
  /**
3077
3150
  * Effect: `resetStateForPeerReconnect$`
3078
3151
  *
3079
3152
  * Resets the data channel state when peer reconnection starts.
3080
3153
  */
3081
- resetStateForPeerReconnect$: rxjs.Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3154
+ resetStateForPeerReconnect$: Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3082
3155
  /**
3083
3156
  * Effect: `executePeerReconnect$`
3084
3157
  *
3085
3158
  * Executes the actual peer reconnection attempt.
3086
3159
  * This only re-establishes the WebRTC connection, not the signaling.
3087
3160
  */
3088
- executePeerReconnect$: rxjs.Observable<_ngrx_store.Action<string> | ({
3161
+ executePeerReconnect$: Observable<_ngrx_store.Action<string> | ({
3089
3162
  attempt: number;
3090
3163
  maxAttempts: number;
3091
3164
  delay?: number;
@@ -3098,19 +3171,19 @@ declare class UnrealEffects {
3098
3171
  * Handles the case when all peer reconnection attempts have failed.
3099
3172
  * Falls back to full disconnection which may trigger full reconnection.
3100
3173
  */
3101
- handlePeerReconnectFailed$: rxjs.Observable<{
3174
+ handlePeerReconnectFailed$: Observable<{
3102
3175
  reason: _3dsource_angular_unreal_module.DisconnectReasonType;
3103
3176
  message: string;
3104
3177
  } & _ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3105
- setMaxFps$: rxjs.Observable<{
3178
+ setMaxFps$: Observable<{
3106
3179
  maxFps: number;
3107
3180
  } & _ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3108
- sendStatisticsToUnreal$: rxjs.Observable<Object> & _ngrx_effects.CreateEffectMetadata;
3109
- listenUnrealCallbackByInitSignalling$: rxjs.Observable<{
3181
+ sendStatisticsToUnreal$: Observable<Object> & _ngrx_effects.CreateEffectMetadata;
3182
+ listenUnrealCallbackByInitSignalling$: Observable<{
3110
3183
  id: string;
3111
3184
  now: number;
3112
3185
  } & _ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3113
- connectToSignaling$: rxjs.Observable<{
3186
+ connectToSignaling$: Observable<{
3114
3187
  value: boolean;
3115
3188
  } & _ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3116
3189
  private canPeerReconnect;
@@ -3289,5 +3362,5 @@ declare const selectUserInactivityDetected: _ngrx_store.MemoizedSelector<Record<
3289
3362
  /** Used by external consumers (e.g., metabox). Do not remove. */
3290
3363
  declare const selectIsVideoPlayingAndDataChannelConnected: _ngrx_store.MemoizedSelector<Record<string, any>, boolean, (s1: boolean, s2: boolean) => boolean>;
3291
3364
 
3292
- export { AFKService, AUTO_HIGH_RESOLUTION_IDLE_MS, AfkTimeoutModalComponent, AggregatorService, AnalyticsService, AnswerHandler, CommandTelemetryService, ConfigHandler, ConsoleExtensionsService, ControlScheme, DATA_CHANNEL_CONNECTION_TIMEOUT, DEBOUNCE_TO_MANY_RESIZE_CALLS, DEFAULT_AFK_TIMEOUT, DEFAULT_AFK_TIMEOUT_PERIOD, DESTROY_DISCONNECT_REASONS, DevModeService, DisconnectReason, FULL_HD_HEIGHT, FULL_HD_WIDTH, FileHandlerService, FileReceiverService, FpsMonitorService, FreezeFrameComponent, FreezeFrameService, INNER_RETRY_LIMIT, IceCandidateHandler, ImageLoadingSrcComponent, InputOptions, InputService, InstanceReadyHandler, InstanceReservedHandler, IntroSrcComponent, LatencyTimings, LoadingProgressService, MINIMAL_FPS, MIN_CONTAINER_SIZE, MessageType, MouseButton, MouseButtonsMask, OUTER_RETRY_DELAY, OnCloseHandler, OnErrorHandler, OnMessageHandler, OnOpenHandler, OrchestrationMessageTypes, POLLING_TIME, PingHandler, PlayerCountHandler, RECONNECT_CONFIG, REGION_PING_ACCURATE_SAMPLES, REGION_PING_BACKGROUND_REFRESH_DELAY_MS, REGION_PING_CACHE_KEY, REGION_PING_CACHE_TTL_MS, REGION_PING_WARMUP_DEADLINE_MS, RegionsPingService, SAME_SIZE_THRESHOLD, SCREEN_LOCKER_CONTAINER_ID, SIGNALLING_PERCENT_VALUE, SSInfoHandler, STREAMING_AUDIO_ID, STREAMING_VIDEO_ID, SafePipe, SignallingService, SpecialKeyCodes, StatGraphComponent, StreamAdoptionService, StreamStatusTelemetryService, StreamStatusTelemetryService2, SubService, ToClientMessage, UNREAL_CONFIG, UnrealCallbackService, UnrealCommunicatorService, UnrealEffects, UnrealSceneComponent, UnrealStatusMessage, VideoService, VideoStatsComponent, WSCloseCode_CIRRUS_ABNORMAL_CLOSURE, WSCloseCode_CIRRUS_MAX_PLAYERS_ERROR, WSCloseCode_CIRRUS_PLAYER_DISCONNECTED, WSCloseCode_CIRRUS_STREAMER_KIKED_PLAYER, WSCloseCode_FORCE_CIRRUS_CLOSE, WSCloseCode_NORMAL_AFK_TIMEOUT, WSCloseCode_NORMAL_CLOSURE, WSCloseCode_NORMAL_MANUAL_DISCONNECT, WSCloseCode_UNKNOWN, WSCloseCodes, WS_OPEN_STATE, WS_RETRY_PER_INSTANCE, WS_TIMEOUT, WebRtcPlayerService, WebrtcErrorModalComponent, abortEstablishingConnection, answerSent, changeStatusMainVideoOnScene, changeStreamResolutionAction, commandCompleted, commandStarted, dataChannelConnected, dataChannelReady, decodeData, destroyRemoteConnections, destroyUnrealScene, disconnectStream, dispatchResize, dropConnection, dropDC, dropPC, floatToPercents, floatToSmoothPercents, forceResizeViewport, fromResizeObserver, getActiveUrl, getImageFromVideoStream, getResizeStudioValues, getResizeValuesUniversal, getRtcErrorMessage, iceConnectionFailed, initSignalling, instanceReady, keepMaxUntilReset, makeEven, pollingEnded, pollingStarted, provideUnrealModule, provideUnrealState, qpToQuality, reconnectPeer, reconnectPeerFailed, reconnectPeerSuccess, regionPingFetchEnd, regionPingFetchStart, regionResolved, resetAfk, resetConfig, resetDataChannelForReconnect, resetIntroSrc, resetUserInactivityTimeout, resetWarnTimeout, saveAnalyticsEvent, selectCirrusConnectionId, selectClientAndViewIds, selectCommandProgress, selectFreezeFrameCombinedDataUrl, selectFreezeFrameDataUrl, selectFreezeFrameDataUrlFromVideo, selectFreezeFrameProgressMessageFromVideo, selectIsAutostart, selectIsExistMatchUrls, selectIsFreezeFrameLoading, selectIsFullyConnected, selectIsLoaderScreenVisible, selectIsVideoPlayingAndDataChannelConnected, selectShowLoader, selectShowReconnectPopup, selectSignalingParameters, selectStreamConfig, selectTotalProgress, selectUserInactivityDetected, selectWarnTimeout, setAfkTimerCountdown, setAfkTimerHide, setAfkTimerVisible, setAwsInstance, setCirrusConnected, setCirrusDisconnected, setConfig, setEstablishingConnection, setFreezeFrame, setFreezeFrameFromVideo, setIntroImageSrc, setIntroVideoSrc, setLoadingImageSrc, setLoopBackCommandIsCompleted, setMaxFps, setOrchestrationContext, setOrchestrationMessage, setOrchestrationParameters, setOrchestrationProgress, setSignalingName, setStatusMessage, setStatusPercentSignallingServer, setStreamClientCompanyId, setStreamViewId, setUnrealPlaywrightConfig, setUserInactivityTimeout, setViewportNotReady, setViewportReady, showLoadingProgress, showResumeStreamPopup, showUnrealErrorMessage, showUserInactivityTimeoutPopup, signalingRetryAttempted, smoothTransition, startStream, streamAdopted, trackMixpanelEvent, trackTelemetryData, uint8ToBase64, unrealCommandCallback, unrealFeature, unrealReducer, updateCirrusInfo, videoAdaptedToContainer, videoStreamInitialized };
3293
- export type { AggregatedStat, AnySignalingMessage, AwsInstance, BootstrapInfo, CandidateMessage, CloseReason, CommandInProgress, ConfigMessage, ConnectionError, ControlSchemeValues, DisconnectReasonType, EmittedMilestone, EventId, ForceClientDisconnect, FpsLowData, FreezeFrameMessage, InboundVideoStats, InputProps, InstanceReady, InstanceReserved, InterruptClientStream, ListStreamersMessage, MessageBase, MessageTypeValues, OrchestrationErrorMessage, OrchestrationMessageType, P2PEstablishedMessage, ParkedStream, PhaseEndedData, PhaseOverlay, PhaseParam, PingMessage, PlayerCountMessage, PollingOrchestrationMessage, Quality, QualityAnomalyData, ReceivedFile, RequestStream, ResourceBucket, ResourceTotals, SSInfo, SampleData, SelectedIceCandidatePair, SessionEndReason, SessionEndedData, SessionStartedData, SignalingData, SignalingMessageHandler, SignalingMessageMap, SignalingRetryData, SignalingRetryKind, SlowResource, StreamConfig, StreamRequestContext, StreamResolutionProps, StreamTelemetryEvent, StreamTelemetryEventMap, StreamTelemetryEventName, StreamTelemetryLifecycleData, StreamTelemetryLifecycleEventName, StreamTelemetryTrackData, StreamerListMessage, TelemetryEventEnvelope, TelemetryLifecycleEnvelope, TelemetryType, UnknownFields, UnrealCallbackDescriptor, UnrealCallbackEventMap, UnrealCallbackJson, UnrealCallbackJsonWrapped, UnrealInitialConfig, UnrealState, WSCloseCodesValues, WindowAggregate };
3365
+ export { AFKService, AUTO_HIGH_RESOLUTION_IDLE_MS, AfkTimeoutModalComponent, AggregatorService, AnalyticsService, AnswerHandler, CommandTelemetryService, ConfigHandler, ConsoleExtensionsService, ControlScheme, DATA_CHANNEL_CONNECTION_TIMEOUT, DEBOUNCE_TO_MANY_RESIZE_CALLS, DEFAULT_AFK_TIMEOUT, DEFAULT_AFK_TIMEOUT_PERIOD, DESTROY_DISCONNECT_REASONS, DevModeService, DisconnectReason, FULL_HD_HEIGHT, FULL_HD_WIDTH, FileHandlerService, FileReceiverService, FpsMonitorService, FreezeFrameComponent, FreezeFrameService, INNER_RETRY_LIMIT, INSTANCE_READY_TIMEOUT, IceCandidateHandler, ImageLoadingSrcComponent, InputOptions, InputService, InstanceReadyHandler, InstanceReservedHandler, IntroSrcComponent, LatencyTimings, LoadingProgressService, MINIMAL_FPS, MIN_CONTAINER_SIZE, MessageType, MouseButton, MouseButtonsMask, OUTER_RETRY_DELAY, OnCloseHandler, OnErrorHandler, OnMessageHandler, OnOpenHandler, OrchestrationMessageTypes, POLLING_TIME, PlayerCountHandler, RECONNECT_CONFIG, REGION_PING_ACCURATE_SAMPLES, REGION_PING_BACKGROUND_REFRESH_DELAY_MS, REGION_PING_CACHE_KEY, REGION_PING_CACHE_TTL_MS, REGION_PING_WARMUP_DEADLINE_MS, RegionsPingService, SAME_SIZE_THRESHOLD, SCREEN_LOCKER_CONTAINER_ID, SIGNALLING_PERCENT_VALUE, SSInfoHandler, STREAMING_AUDIO_ID, STREAMING_VIDEO_ID, SafePipe, SignallingService, SpecialKeyCodes, StatGraphComponent, StreamAdoptionService, StreamStatusTelemetryService, StreamStatusTelemetryService2, SubService, ToClientMessage, UNREAL_CONFIG, UnrealCallbackService, UnrealCommunicatorService, UnrealEffects, UnrealSceneComponent, UnrealStatusMessage, VideoService, VideoStatsComponent, WSCloseCode_CIRRUS_ABNORMAL_CLOSURE, WSCloseCode_CIRRUS_MAX_PLAYERS_ERROR, WSCloseCode_CIRRUS_PLAYER_DISCONNECTED, WSCloseCode_CIRRUS_STREAMER_KIKED_PLAYER, WSCloseCode_FORCE_CIRRUS_CLOSE, WSCloseCode_NORMAL_AFK_TIMEOUT, WSCloseCode_NORMAL_CLOSURE, WSCloseCode_NORMAL_MANUAL_DISCONNECT, WSCloseCode_UNKNOWN, WSCloseCodes, WS_OPEN_STATE, WS_RETRY_PER_INSTANCE, WS_TIMEOUT, WebRtcPlayerService, WebrtcErrorModalComponent, abortEstablishingConnection, answerSent, changeStatusMainVideoOnScene, changeStreamResolutionAction, commandCompleted, commandStarted, dataChannelConnected, dataChannelReady, decodeData, destroyRemoteConnections, destroyUnrealScene, disconnectStream, dispatchResize, dropConnection, dropDC, dropPC, floatToPercents, floatToSmoothPercents, forceResizeViewport, fromResizeObserver, getActiveUrl, getImageFromVideoStream, getResizeStudioValues, getResizeValuesUniversal, getRtcErrorMessage, iceConnectionFailed, initSignalling, instanceReady, keepMaxUntilReset, makeEven, pollingEnded, pollingStarted, provideUnrealModule, provideUnrealState, qpToQuality, reconnectPeer, reconnectPeerFailed, reconnectPeerSuccess, regionPingFetchEnd, regionPingFetchStart, regionResolved, resetAfk, resetConfig, resetDataChannelForReconnect, resetIntroSrc, resetUserInactivityTimeout, resetWarnTimeout, saveAnalyticsEvent, selectCirrusConnectionId, selectClientAndViewIds, selectCommandProgress, selectFreezeFrameCombinedDataUrl, selectFreezeFrameDataUrl, selectFreezeFrameDataUrlFromVideo, selectFreezeFrameProgressMessageFromVideo, selectIsAutostart, selectIsExistMatchUrls, selectIsFreezeFrameLoading, selectIsFullyConnected, selectIsLoaderScreenVisible, selectIsVideoPlayingAndDataChannelConnected, selectShowLoader, selectShowReconnectPopup, selectSignalingParameters, selectStreamConfig, selectTotalProgress, selectUserInactivityDetected, selectWarnTimeout, setAfkTimerCountdown, setAfkTimerHide, setAfkTimerVisible, setAwsInstance, setCirrusConnected, setCirrusDisconnected, setConfig, setEstablishingConnection, setFreezeFrame, setFreezeFrameFromVideo, setIntroImageSrc, setIntroVideoSrc, setLoadingImageSrc, setLoopBackCommandIsCompleted, setMaxFps, setOrchestrationContext, setOrchestrationMessage, setOrchestrationParameters, setOrchestrationProgress, setSignalingName, setStatusMessage, setStatusPercentSignallingServer, setStreamClientCompanyId, setStreamViewId, setUnrealPlaywrightConfig, setUserInactivityTimeout, setViewportNotReady, setViewportReady, showLoadingProgress, showResumeStreamPopup, showUnrealErrorMessage, showUserInactivityTimeoutPopup, signalingRetryAttempted, smoothTransition, startStream, streamAdopted, trackMixpanelEvent, trackTelemetryData, uint8ToBase64, unrealCommandCallback, unrealFeature, unrealReducer, updateCirrusInfo, videoAdaptedToContainer, videoStreamInitialized };
3366
+ export type { AggregatedStat, AnySignalingMessage, AwsInstance, BootstrapInfo, CandidateMessage, CirrusRequestKind, CloseReason, CommandInProgress, ConfigMessage, ConnectionError, ControlSchemeValues, DisconnectReasonType, EmittedMilestone, EventId, FpsLowData, FreezeFrameMessage, InboundVideoStats, InputProps, InstanceReady, InstanceReserved, InterruptClientStream, ListStreamersMessage, MessageBase, MessageTypeValues, OrchestrationErrorMessage, OrchestrationMessageType, P2PEstablishedMessage, ParkedStream, PhaseEndedData, PhaseOverlay, PhaseParam, PlayerCountMessage, PollingOrchestrationMessage, Quality, QualityAnomalyData, ReceivedFile, RequestStream, ResourceBucket, ResourceTotals, SSInfo, SampleData, SelectedIceCandidatePair, SessionEndReason, SessionEndedData, SessionStartedData, SignalingData, SignalingMessageHandler, SignalingMessageMap, SignalingRetryData, SignalingRetryKind, SlowResource, StreamConfig, StreamRequestContext, StreamResolutionProps, StreamTelemetryEvent, StreamTelemetryEventMap, StreamTelemetryEventName, StreamTelemetryLifecycleData, StreamTelemetryLifecycleEventName, StreamTelemetryTrackData, StreamerListMessage, TelemetryEventEnvelope, TelemetryLifecycleEnvelope, TelemetryType, UnknownFields, UnrealCallbackDescriptor, UnrealCallbackEventMap, UnrealCallbackJson, UnrealCallbackJsonWrapped, UnrealInitialConfig, UnrealState, WSCloseCodesValues, WindowAggregate };