@3dsource/angular-unreal-module 0.0.148 → 0.0.149-dev.0
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/LICENSE +14 -14
- package/README.md +361 -370
- package/fesm2022/3dsource-angular-unreal-module.mjs +571 -140
- package/fesm2022/3dsource-angular-unreal-module.mjs.map +1 -1
- package/js/perf-longtask.js +1 -0
- package/js/stream-prefetch.js +4 -0
- package/package.json +1 -1
- package/types/3dsource-angular-unreal-module.d.ts +253 -36
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(()=>{"use strict";if(window.__streamPerf)return;const t=1e3,e=window.__streamPerf={longTasks:[],supported:!1};try{new PerformanceObserver(o=>{for(const r of o.getEntries()){if(e.longTasks.length>=t)break;e.longTasks.push({start:Math.round(r.startTime),dur:Math.round(r.duration)})}}).observe({type:"longtask",buffered:!0}),e.supported=!0}catch{}})();
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
"use strict";(()=>{"use strict";const f="metabox-configurator",m=/metabox-configurator\/(modular|basic)\/([^/?#]+)/i,g="3dsource:region-ping",k="assets/config.json",w="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 I(o){return o.replace("http://","ws://").replace("https://","wss://")}const h="[stream-prefetch]",s=(...o)=>console.log(h,...o),c=(...o)=>console.warn(h,...o),u=(...o)=>console.error(h,...o);class y{constructor(){const t=document.currentScript||(()=>{const n=document.getElementsByTagName("script");return n[n.length-1]})(),e=t&&t.dataset||{};this.configUrl=e.configUrl||k,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.context=null,this.environmentId=void 0,this.orchestrationType="",this.region="",this.requireEnvironmentId=!0,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))return;if(this.skipRouteCheck){this.context={},this.requireEnvironmentId=!1,c("skipRouteCheck=true \u2014 ignoring URL gate, route, context and environmentId; using fallback polling"),this.publishParked("connecting"),this.connect().catch(e=>this.fail("exception",e));return}if(window.location.href.indexOf(f)===-1){s("skip \u2014 URL does not contain gate",`"${f}"`);return}const t=this.parseConfiguratorUrl();t?(this.context={id:t.contextId,data:{configuratorId:t.configuratorId}},this.requireEnvironmentId=!0,s("start",{contextId:t.contextId,configuratorId:t.configuratorId,ids:this.ids})):(this.context={},this.requireEnvironmentId=!1,c("URL is not a configurator route \u2014 prefetching with empty context {} and no required environmentId",window.location.pathname)),this.publishParked("connecting"),this.connect().catch(e=>this.fail("exception",e))}parseConfiguratorUrl(){const t=window.location.pathname.match(m);return t?{contextId:t[1].toLowerCase()==="modular"?"metaboxModularConfigurator":"metaboxBasicConfigurator",configuratorId:decodeURIComponent(t[2])}:null}connect(){return this.mark("prefetch_start"),this.region=this.readRegion()||"",s("region from cache:",this.region||"(none)"),(this.skipRouteCheck?Promise.resolve(null):this.fetchConfig()).then(e=>{let i;if(e)i=this.chooseEndpoint(e);else if(this.fallbackPollingUrl)c("no app config \u2014 falling back to polling",this.fallbackPollingUrl),i={type:"polling",url:this.fallbackPollingUrl,environmentId:""},this.requireEnvironmentId=!1;else{this.fail("no-config");return}if(!i){this.fail("no-endpoint");return}if(s("endpoint chosen",{type:i.type,url:i.url,environmentId:i.environmentId}),this.requireEnvironmentId&&!i.environmentId){this.fail("no-environment-id");return}this.orchestrationType=i.type,this.environmentId=i.environmentId||void 0;const n=this.adaptUrlToRegion(i.url);return(i.type==="polling"?this.pollOrchestration(n):Promise.resolve(n)).then(a=>{if(!a){this.fail("no-ws-url");return}return this.parked.machineId=a,s("opening socket",a),this.openSocket(a)})})}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.newSignalling,i=this.firstVersionUrl(e&&e.versions);if(i&&/^wss?:\/\//i.test(i))return{type:"direct",url:i,environmentId:e&&e.environmentId||""};const n=t.signalling,r=this.firstVersionUrl(n&&n.versions);return r?(this.requireEnvironmentId=!1,{type:"polling",url:r,environmentId:n&&n.environmentId||""}):null}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?I(`${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"),s("WS open \u2192 sending requestStream",{environmentId:this.environmentId,region:this.region,context:this.context}),this.sendRequestStream()},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"))}}sendRequestStream(){this.send({type:"requestStream",correlationId:this.ids.correlationId,payload:{region:this.region,environmentId:this.environmentId,context:this.context}})}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(s("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,s("PeerConnection created from config"),i.onicecandidate=n=>{n.candidate&&this.send({type:"iceCandidate",candidate:n.candidate})},i.ondatachannel=n=>this.wireDataChannel(n.channel),i.ontrack=n=>{n.track&&n.track.kind==="video"&&n.streams[0]&&(s("video track received"),this.stream=n.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(()=>{s("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=()=>{s("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",s("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 n=this.state;Promise.resolve().then(()=>i(n));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,w);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
|
+
`),n=[];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&&n.push(a)}return n.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),b=[...n.filter(d=>p.includes(d)),...p.filter(d=>!n.includes(d))];return[...x,...b].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())}readRegion(){try{const t=localStorage.getItem(g);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 n=new AbortController;e.signal=n.signal;const r=setTimeout(()=>n.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 y().run()})();
|
package/package.json
CHANGED
|
@@ -231,18 +231,6 @@ interface FreezeFrameMessage {
|
|
|
231
231
|
progress: number | null;
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
-
interface ReconnectConfig {
|
|
235
|
-
/** Enable auto-reconnection when WebRTC or DataChannel connection is lost. Default: true */
|
|
236
|
-
enabled?: boolean;
|
|
237
|
-
/** Maximum number of reconnection attempts before giving up. Default: 3 */
|
|
238
|
-
maxAttempts?: number;
|
|
239
|
-
/** Delay in milliseconds between reconnection attempts. Default: 1000 */
|
|
240
|
-
delayMs?: number;
|
|
241
|
-
/** Reconnect on ICE connection failure (disconnected/failed state). Default: true */
|
|
242
|
-
onIceFailure?: boolean;
|
|
243
|
-
/** Reconnect on DataChannel close. Default: true */
|
|
244
|
-
onDataChannelClose?: boolean;
|
|
245
|
-
}
|
|
246
234
|
interface UnrealInitialConfig {
|
|
247
235
|
playwright?: boolean;
|
|
248
236
|
customErrorsEndpoint?: string;
|
|
@@ -253,8 +241,74 @@ interface UnrealInitialConfig {
|
|
|
253
241
|
streamTelemetryV2Url?: string;
|
|
254
242
|
fpsMonitor?: boolean;
|
|
255
243
|
autoHighResolution?: boolean;
|
|
256
|
-
|
|
257
|
-
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
interface SignalingData {
|
|
247
|
+
instanceType: string;
|
|
248
|
+
branchInfo: string;
|
|
249
|
+
cirrusVersion: string;
|
|
250
|
+
streamerVersion: string;
|
|
251
|
+
streamPath: string;
|
|
252
|
+
streamApp: string;
|
|
253
|
+
connectionId: string;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Live WebRTC connection parked on `window.__stream` by the `stream-prefetch.js`
|
|
258
|
+
* head-script, ready for the Angular services to ADOPT instead of building a
|
|
259
|
+
* connection from scratch. The shape is the handoff contract between that
|
|
260
|
+
* framework-free script and {@link StreamAdoptionService} — keep the two in sync.
|
|
261
|
+
*/
|
|
262
|
+
interface ParkedStream {
|
|
263
|
+
state: 'connecting' | 'ready' | 'failed' | 'adopted';
|
|
264
|
+
pc?: RTCPeerConnection;
|
|
265
|
+
dc?: RTCDataChannel;
|
|
266
|
+
/** video(+audio) MediaStream from the `track` event */
|
|
267
|
+
stream?: MediaStream;
|
|
268
|
+
/** live signalling socket (handshake already done, `requestStream` sent) */
|
|
269
|
+
ws?: WebSocket;
|
|
270
|
+
/** `data` from the streamer's `ssInfo` message — received before adoption */
|
|
271
|
+
ssData?: SignalingData;
|
|
272
|
+
/** = resolved wsUrl of the winning machine */
|
|
273
|
+
machineId?: string;
|
|
274
|
+
/** `peerConnectionOptions` the machine sent in its `config` message */
|
|
275
|
+
config?: RTCConfiguration;
|
|
276
|
+
/** ids the script generated; Angular reuses them (no regeneration) */
|
|
277
|
+
ids: {
|
|
278
|
+
clientId: string;
|
|
279
|
+
viewId: string;
|
|
280
|
+
correlationId: string;
|
|
281
|
+
};
|
|
282
|
+
/** DataChannel messages received before adoption, replayed on adopt */
|
|
283
|
+
dcBuffer: ArrayBuffer[];
|
|
284
|
+
/** `performance.now()` marks for the prefetch waterfall (telemetry) */
|
|
285
|
+
timings: Record<string, number>;
|
|
286
|
+
failReason?: string;
|
|
287
|
+
failError?: string;
|
|
288
|
+
/** Stops the script's watchdog and flips state to `adopted`. */
|
|
289
|
+
adopt: () => ParkedStream;
|
|
290
|
+
/**
|
|
291
|
+
* Register a one-shot callback fired the instant the stream settles
|
|
292
|
+
* (`ready`/`failed`); fires on the next microtask if already settled. This is
|
|
293
|
+
* how {@link StreamAdoptionService} adopts event-driven (no polling) — the
|
|
294
|
+
* head-script must provide it.
|
|
295
|
+
*/
|
|
296
|
+
onSettled: (cb: (state: ParkedStream['state']) => void) => void;
|
|
297
|
+
}
|
|
298
|
+
declare global {
|
|
299
|
+
interface Window {
|
|
300
|
+
__stream?: ParkedStream;
|
|
301
|
+
/** Main-thread long-task log collected by the optional `perf-longtask.js`
|
|
302
|
+
* head-script from page start. Read once at adoption to attribute the
|
|
303
|
+
* boot gap. `start`/`dur` are ms in the page `performance.now()` timebase. */
|
|
304
|
+
__streamPerf?: {
|
|
305
|
+
longTasks: {
|
|
306
|
+
start: number;
|
|
307
|
+
dur: number;
|
|
308
|
+
}[];
|
|
309
|
+
supported: boolean;
|
|
310
|
+
};
|
|
311
|
+
}
|
|
258
312
|
}
|
|
259
313
|
|
|
260
314
|
declare const SpecialKeyCodes: {
|
|
@@ -364,11 +418,11 @@ declare const REGION_PING_CACHE_TTL_MS: number;
|
|
|
364
418
|
declare const REGION_PING_ACCURATE_SAMPLES = 3;
|
|
365
419
|
declare const REGION_PING_WARMUP_DEADLINE_MS = 1500;
|
|
366
420
|
declare const REGION_PING_BACKGROUND_REFRESH_DELAY_MS = 5000;
|
|
367
|
-
declare const
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
421
|
+
declare const RECONNECT_CONFIG: {
|
|
422
|
+
readonly enabled: true;
|
|
423
|
+
readonly maxAttempts: 3;
|
|
424
|
+
readonly delayMs: 1000;
|
|
425
|
+
};
|
|
372
426
|
declare const UnrealStatusMessage: {
|
|
373
427
|
readonly CONNECTING_TO_SESSION: "Connecting to session.";
|
|
374
428
|
readonly STARTING_YOUR_SESSION: "Starting your session";
|
|
@@ -381,16 +435,6 @@ interface InputProps {
|
|
|
381
435
|
|
|
382
436
|
type Quality = 'lime' | 'red' | 'orange';
|
|
383
437
|
|
|
384
|
-
interface SignalingData {
|
|
385
|
-
instanceType: string;
|
|
386
|
-
branchInfo: string;
|
|
387
|
-
cirrusVersion: string;
|
|
388
|
-
streamerVersion: string;
|
|
389
|
-
streamPath: string;
|
|
390
|
-
streamApp: string;
|
|
391
|
-
connectionId: string;
|
|
392
|
-
}
|
|
393
|
-
|
|
394
438
|
declare const OrchestrationMessageTypes: {
|
|
395
439
|
readonly ping: "ping";
|
|
396
440
|
readonly error: "error";
|
|
@@ -879,8 +923,15 @@ declare class RegionsPingService {
|
|
|
879
923
|
* entry is well-formed and still within {@link REGION_PING_CACHE_TTL_MS}.
|
|
880
924
|
* All access is guarded — `localStorage` can throw (private mode, disabled
|
|
881
925
|
* storage) or be absent (non-browser).
|
|
926
|
+
*
|
|
927
|
+
* Public so adopted connections (which skip `getFastest`) can replay the
|
|
928
|
+
* region-resolving telemetry phase from the same cached winner — see
|
|
929
|
+
* `UnrealEffects.regionTelemetryOnAdopt$`.
|
|
882
930
|
*/
|
|
883
|
-
|
|
931
|
+
readCachedWinner(): {
|
|
932
|
+
region_code: string;
|
|
933
|
+
result: number[];
|
|
934
|
+
} | null;
|
|
884
935
|
private writeCachedWinner;
|
|
885
936
|
/**
|
|
886
937
|
* Accurate, OFF-critical-path refresh of the region cache. Mirrors the
|
|
@@ -1002,6 +1053,15 @@ declare class SignallingService extends SubService {
|
|
|
1002
1053
|
private pollLoop;
|
|
1003
1054
|
private connectToCirrus;
|
|
1004
1055
|
private addWsHandlers;
|
|
1056
|
+
/**
|
|
1057
|
+
* Adopt a live signalling socket opened by the `stream-prefetch.js`
|
|
1058
|
+
* head-script. The socket is already OPEN and `requestStream` was already
|
|
1059
|
+
* sent, so — unlike {@link addWsHandlers} — we attach message/close/error
|
|
1060
|
+
* handlers but deliberately skip {@link OnOpenHandler} (which would
|
|
1061
|
+
* `setCirrusConnected` + re-`sendRequestStream`). Reuses the head-script's
|
|
1062
|
+
* `correlationId` so subsequent correlated messages line up.
|
|
1063
|
+
*/
|
|
1064
|
+
adoptSocket(ws: WebSocket, correlationId: string): void;
|
|
1005
1065
|
private showStatusMessage;
|
|
1006
1066
|
/**
|
|
1007
1067
|
* Close the connection with the signaling server
|
|
@@ -1021,6 +1081,64 @@ declare class SignallingService extends SubService {
|
|
|
1021
1081
|
static ɵprov: i0.ɵɵInjectableDeclaration<SignallingService>;
|
|
1022
1082
|
}
|
|
1023
1083
|
|
|
1084
|
+
/**
|
|
1085
|
+
* Adopts a WebRTC connection prefetched by the `stream-prefetch.js` head-script
|
|
1086
|
+
* and parked on `window.__stream`, instead of running `connectToSignaling` from
|
|
1087
|
+
* scratch. Called from the same seam where signalling normally starts
|
|
1088
|
+
* (`connectToSignaling$` effect); if there is nothing ready to adopt it returns
|
|
1089
|
+
* `false` and the caller falls back to the normal connect — strictly additive.
|
|
1090
|
+
*/
|
|
1091
|
+
declare class StreamAdoptionService {
|
|
1092
|
+
private readonly store;
|
|
1093
|
+
private readonly signalling;
|
|
1094
|
+
private readonly webRtc;
|
|
1095
|
+
/**
|
|
1096
|
+
* Decide adoption, WAITING for an in-flight prefetch instead of racing it.
|
|
1097
|
+
*
|
|
1098
|
+
* - nothing parked → emit `false` at once (caller connects normally).
|
|
1099
|
+
* - already settled (`ready`/`failed`/`adopted`) → adopt-if-ready at once.
|
|
1100
|
+
* - still `connecting` → wait for the script's `onSettled` callback and
|
|
1101
|
+
* adopt-if-ready the instant it fires (event-driven, zero polling latency).
|
|
1102
|
+
*
|
|
1103
|
+
* Deliberately NO time budget: for DIRECT orchestration the prefetch holds
|
|
1104
|
+
* the socket open while the orchestrator provisions a machine, which can take
|
|
1105
|
+
* minutes (150–200s+). A fixed deadline would make Angular give up and open a
|
|
1106
|
+
* second connection mid-provisioning — exactly the race/orphan this avoids.
|
|
1107
|
+
* The wait is bounded by liveness instead: the script flips the parked state
|
|
1108
|
+
* to `failed` on a dead socket (`ws.onclose`/`onerror`), and the caller wraps
|
|
1109
|
+
* this in `takeUntil(abortEstablishingConnection)`, so a route change / teardown
|
|
1110
|
+
* cancels it. Emits exactly once. Cancelling runs no adoption — which is what
|
|
1111
|
+
* stops a fast route-switch from starting overlapping connections.
|
|
1112
|
+
*
|
|
1113
|
+
* Wrapped in `defer` so the `tryAdopt()` side effect (which dispatches
|
|
1114
|
+
* `streamAdopted`) runs at SUBSCRIPTION time, not when the observable is
|
|
1115
|
+
* built. The effect prepends `startWith(setEstablishingConnection(true))`,
|
|
1116
|
+
* which starts the telemetry session and subscribes its phase catalog; that
|
|
1117
|
+
* must happen BEFORE `streamAdopted` → `regionTelemetryOnAdopt$` replays
|
|
1118
|
+
* `regionResolved`, or the region phase fires into a session that doesn't
|
|
1119
|
+
* exist yet and is lost. `defer` guarantees that ordering.
|
|
1120
|
+
*/
|
|
1121
|
+
awaitAndAdopt$(): Observable<boolean>;
|
|
1122
|
+
/**
|
|
1123
|
+
* Event-driven wait: the script fires `onSettled` the instant it parks
|
|
1124
|
+
* `ready`/`failed`, so we adopt with zero polling lag. Emits exactly once.
|
|
1125
|
+
*
|
|
1126
|
+
* No timer/budget by design: an indefinitely `connecting` stream is valid
|
|
1127
|
+
* (DIRECT orchestration holds the socket open for minutes while it
|
|
1128
|
+
* provisions), and every terminal state — including a dead socket — flips to
|
|
1129
|
+
* `ready`/`failed` and fires the hook. Teardown (route change → unsubscribe)
|
|
1130
|
+
* sets `done`, so a late callback after cancel can't trigger a stray adoption.
|
|
1131
|
+
*/
|
|
1132
|
+
private awaitSettled$;
|
|
1133
|
+
/**
|
|
1134
|
+
* @returns `true` if a ready parked stream was adopted (caller must NOT
|
|
1135
|
+
* start a fresh connection), `false` otherwise.
|
|
1136
|
+
*/
|
|
1137
|
+
tryAdopt(): boolean;
|
|
1138
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StreamAdoptionService, never>;
|
|
1139
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<StreamAdoptionService>;
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1024
1142
|
declare class StreamStatusTelemetryService extends SubService {
|
|
1025
1143
|
private readonly videoService;
|
|
1026
1144
|
private readonly unrealConfig;
|
|
@@ -1108,6 +1226,17 @@ declare class StreamStatusTelemetryService2 {
|
|
|
1108
1226
|
private readonly disconnectReason$;
|
|
1109
1227
|
private readonly errorMessage$;
|
|
1110
1228
|
private readonly viewPortReady$;
|
|
1229
|
+
/**
|
|
1230
|
+
* Synchronous adoption flag. The `streamAdopted` reducer sets it BEFORE any
|
|
1231
|
+
* action subscriber runs, so the connection-phase closers (which fire inside
|
|
1232
|
+
* the same dispatch, e.g. `ssinfo-received` off the `ssData` state change)
|
|
1233
|
+
* can read it and defer to the prefetch-timed attribution emitted by
|
|
1234
|
+
* {@link emitAdoptedConnection} instead of recording the live wall-clock.
|
|
1235
|
+
*/
|
|
1236
|
+
private readonly adopted$;
|
|
1237
|
+
/** Streamer identity for the adopted signaling phase params. */
|
|
1238
|
+
private readonly ssData$;
|
|
1239
|
+
private readonly awsInstance$;
|
|
1111
1240
|
private session;
|
|
1112
1241
|
/**
|
|
1113
1242
|
* Whether a session has already started during the current page lifetime.
|
|
@@ -1171,6 +1300,36 @@ declare class StreamStatusTelemetryService2 {
|
|
|
1171
1300
|
* are derived from neighbor phases.
|
|
1172
1301
|
*/
|
|
1173
1302
|
private emitPhaseEnded;
|
|
1303
|
+
/**
|
|
1304
|
+
* Emit the region / signaling / webrtc phases for an ADOPTED connection.
|
|
1305
|
+
*
|
|
1306
|
+
* The prefetch script established the connection in PARALLEL with page load,
|
|
1307
|
+
* so the phases are positioned at their real (anchor-relative) spans — shifted
|
|
1308
|
+
* LEFT to overlap the HTML-loading / route-idle rows — rather than sequentially
|
|
1309
|
+
* after them. That's the whole point of the prefetch: the handshake already
|
|
1310
|
+
* happened while the page was loading. Each phase ships:
|
|
1311
|
+
* - `duration` — the real sub-step time the prefetch spent.
|
|
1312
|
+
* - `spanStartMs` — anchor-relative start, so the viewer left-shifts the bar.
|
|
1313
|
+
* - `adoptionAtMs` — where Angular took over (the next phase, Unreal
|
|
1314
|
+
* communication, resumes here on the sequential timeline).
|
|
1315
|
+
* - savings params: `prefetchConnectMs` (full handshake), `prefetchSavedMs`
|
|
1316
|
+
* (done before Angular was ready), `adoptionWaitMs` (real connect→adopted
|
|
1317
|
+
* wait), `adoptionOverheadMs` (prefetch-ready → adopted gap).
|
|
1318
|
+
*/
|
|
1319
|
+
private emitAdoptedConnection;
|
|
1320
|
+
/**
|
|
1321
|
+
* Emit one adopted phase positioned at its real `spanStartMs` (left-shifted
|
|
1322
|
+
* to overlap page load) with its real prefetch `duration`. `prefetched`,
|
|
1323
|
+
* `spanStartMs` and `adoptionAtMs` ride as top-level wire fields the viewer
|
|
1324
|
+
* uses to lay the bar out; the rest become display params.
|
|
1325
|
+
*/
|
|
1326
|
+
private emitAdoptedPhase;
|
|
1327
|
+
/** Streamer identity params for the adopted signaling phase — mirrors the
|
|
1328
|
+
* `ssinfo-received` closer's shape (client / instanceName / …ssData). */
|
|
1329
|
+
private adoptedSignalingParams;
|
|
1330
|
+
/** Read the region-ping cache the prefetch reused (localStorage), so the
|
|
1331
|
+
* adopted region phase can still report the winning region + samples. */
|
|
1332
|
+
private readRegionCache;
|
|
1174
1333
|
private handleWindow;
|
|
1175
1334
|
private evaluateAnomalies;
|
|
1176
1335
|
private updateMaxFpsTarget;
|
|
@@ -1399,6 +1558,16 @@ declare class WebRtcPlayerService extends SubService {
|
|
|
1399
1558
|
* @returns true if reconnection was initiated, false if signaling is not connected
|
|
1400
1559
|
*/
|
|
1401
1560
|
reconnectPeer(): boolean;
|
|
1561
|
+
/**
|
|
1562
|
+
* Adopt a fully-negotiated connection prefetched by `stream-prefetch.js`:
|
|
1563
|
+
* take ownership of its PeerConnection, DataChannel and media stream instead
|
|
1564
|
+
* of running the handshake. The head-script attached property-based handlers
|
|
1565
|
+
* (`pc.onicecandidate`, `dc.onmessage`, …) and buffered inbound DC messages;
|
|
1566
|
+
* here we detach those, wire our own (addEventListener-based) handlers, replay
|
|
1567
|
+
* the buffer in order, then drive `onDataChannelConnected` manually because the
|
|
1568
|
+
* DataChannel is already open (its `open` event won't fire again).
|
|
1569
|
+
*/
|
|
1570
|
+
adopt(pc: RTCPeerConnection, dc: RTCDataChannel, stream: MediaStream, config: RTCConfiguration, dcBuffer: ArrayBuffer[]): void;
|
|
1402
1571
|
private setConfig;
|
|
1403
1572
|
private handlePeerConnectionEvents;
|
|
1404
1573
|
private setupTransceiversAsync;
|
|
@@ -2460,6 +2629,44 @@ declare const showUnrealErrorMessage: node_modules__ngrx_store_types_ngrx_store.
|
|
|
2460
2629
|
error?: string;
|
|
2461
2630
|
} & node_modules__ngrx_store_types_ngrx_store.Action<string>>;
|
|
2462
2631
|
declare const initSignalling: node_modules__ngrx_store_types_ngrx_store.ActionCreator<string, () => node_modules__ngrx_store_types_ngrx_store.Action<string>>;
|
|
2632
|
+
/**
|
|
2633
|
+
* Dispatched when a prefetched connection parked on `window.__stream` by the
|
|
2634
|
+
* `stream-prefetch.js` head-script is adopted instead of opening a fresh
|
|
2635
|
+
* `connectToSignaling`. Marks cirrus connected and records the adopted machine
|
|
2636
|
+
* in one transaction; the data channel / app-init chain then proceeds via
|
|
2637
|
+
* `dataChannelConnected` dispatched from `WebRtcPlayerService`.
|
|
2638
|
+
*
|
|
2639
|
+
* Deliberately does NOT touch `streamClientCompanyId` / `streamViewId`: the host
|
|
2640
|
+
* app (e.g. metabox) sets those authoritatively from its own data before
|
|
2641
|
+
* `initSignalling`, and the prefetch script's ids are connection-internal only.
|
|
2642
|
+
*/
|
|
2643
|
+
declare const streamAdopted: node_modules__ngrx_store_types_ngrx_store.ActionCreator<string, (props: {
|
|
2644
|
+
machineId: string | null;
|
|
2645
|
+
ssData: SignalingData | null;
|
|
2646
|
+
/**
|
|
2647
|
+
* `performance.now()` marks the prefetch script recorded while it
|
|
2648
|
+
* established the connection (`prefetch_start` / `ws_open` / `dc_open` /
|
|
2649
|
+
* `ready`), on the page navigation timeline. The telemetry service uses
|
|
2650
|
+
* them to attribute the signaling / webrtc phase durations to the time the
|
|
2651
|
+
* prefetch actually spent — instead of dumping the whole pre-adoption wait
|
|
2652
|
+
* onto whichever phase closer happens to fire first. `null` when adopting a
|
|
2653
|
+
* stream that carried no timings.
|
|
2654
|
+
*/
|
|
2655
|
+
timings: Record<string, number> | null;
|
|
2656
|
+
}) => {
|
|
2657
|
+
machineId: string | null;
|
|
2658
|
+
ssData: SignalingData | null;
|
|
2659
|
+
/**
|
|
2660
|
+
* `performance.now()` marks the prefetch script recorded while it
|
|
2661
|
+
* established the connection (`prefetch_start` / `ws_open` / `dc_open` /
|
|
2662
|
+
* `ready`), on the page navigation timeline. The telemetry service uses
|
|
2663
|
+
* them to attribute the signaling / webrtc phase durations to the time the
|
|
2664
|
+
* prefetch actually spent — instead of dumping the whole pre-adoption wait
|
|
2665
|
+
* onto whichever phase closer happens to fire first. `null` when adopting a
|
|
2666
|
+
* stream that carried no timings.
|
|
2667
|
+
*/
|
|
2668
|
+
timings: Record<string, number> | null;
|
|
2669
|
+
} & node_modules__ngrx_store_types_ngrx_store.Action<string>>;
|
|
2463
2670
|
declare const startStream: node_modules__ngrx_store_types_ngrx_store.ActionCreator<string, (props: {
|
|
2464
2671
|
config: Partial<StreamConfig>;
|
|
2465
2672
|
}) => {
|
|
@@ -2556,11 +2763,11 @@ declare class UnrealEffects {
|
|
|
2556
2763
|
private readonly commandTelemetryService;
|
|
2557
2764
|
private readonly regionsPingService;
|
|
2558
2765
|
private readonly signallingService;
|
|
2766
|
+
private readonly streamAdoptionService;
|
|
2559
2767
|
private readonly videoService;
|
|
2560
2768
|
private readonly unrealCallbackService;
|
|
2561
2769
|
private dataChannelConnectionTimeout;
|
|
2562
2770
|
private connectionCompleted$;
|
|
2563
|
-
private reconnectConfig;
|
|
2564
2771
|
destroyConnections$: node_modules_rxjs_dist_types.Observable<{
|
|
2565
2772
|
reason: _3dsource_angular_unreal_module.DisconnectReasonType;
|
|
2566
2773
|
} & node_modules__ngrx_store_types_ngrx_store.Action<string>> & node_modules__ngrx_effects_types_ngrx_effects.CreateEffectMetadata;
|
|
@@ -2628,8 +2835,8 @@ declare class UnrealEffects {
|
|
|
2628
2835
|
* Effect: `handleDataChannelClosed$`
|
|
2629
2836
|
*
|
|
2630
2837
|
* Triggers peer reconnection when DataChannel closes unexpectedly.
|
|
2631
|
-
* Only triggers if reconnection is enabled
|
|
2632
|
-
*
|
|
2838
|
+
* Only triggers if reconnection is enabled and the signaling WebSocket
|
|
2839
|
+
* is still connected.
|
|
2633
2840
|
*/
|
|
2634
2841
|
handleDataChannelClosed$: node_modules_rxjs_dist_types.Observable<{
|
|
2635
2842
|
attempt: number;
|
|
@@ -2674,7 +2881,9 @@ declare class UnrealEffects {
|
|
|
2674
2881
|
id: string;
|
|
2675
2882
|
now: number;
|
|
2676
2883
|
} & node_modules__ngrx_store_types_ngrx_store.Action<string>> & node_modules__ngrx_effects_types_ngrx_effects.CreateEffectMetadata;
|
|
2677
|
-
connectToSignaling$: node_modules_rxjs_dist_types.Observable<
|
|
2884
|
+
connectToSignaling$: node_modules_rxjs_dist_types.Observable<{
|
|
2885
|
+
value: boolean;
|
|
2886
|
+
} & node_modules__ngrx_store_types_ngrx_store.Action<string>> & node_modules__ngrx_effects_types_ngrx_effects.CreateEffectMetadata;
|
|
2678
2887
|
private canPeerReconnect;
|
|
2679
2888
|
/**
|
|
2680
2889
|
* Either schedules the next peer-reconnect attempt or gives up with the
|
|
@@ -2691,6 +2900,7 @@ declare const unrealFeature: {
|
|
|
2691
2900
|
name: "unrealFeature";
|
|
2692
2901
|
reducer: node_modules__ngrx_store_types_ngrx_store.ActionReducer<_3dsource_angular_unreal_module.UnrealState, node_modules__ngrx_store_types_ngrx_store.Action<string>>;
|
|
2693
2902
|
selectUnrealFeatureState: node_modules__ngrx_store_types_ngrx_store.MemoizedSelector<Record<string, any>, _3dsource_angular_unreal_module.UnrealState, (featureState: _3dsource_angular_unreal_module.UnrealState) => _3dsource_angular_unreal_module.UnrealState>;
|
|
2903
|
+
selectAdopted: node_modules__ngrx_store_types_ngrx_store.MemoizedSelector<Record<string, any>, boolean, (featureState: _3dsource_angular_unreal_module.UnrealState) => boolean>;
|
|
2694
2904
|
selectFreezeFrame: node_modules__ngrx_store_types_ngrx_store.MemoizedSelector<Record<string, any>, _3dsource_angular_unreal_module.FreezeFrameMessage, (featureState: _3dsource_angular_unreal_module.UnrealState) => _3dsource_angular_unreal_module.FreezeFrameMessage>;
|
|
2695
2905
|
selectIsVideoPlaying: node_modules__ngrx_store_types_ngrx_store.MemoizedSelector<Record<string, any>, boolean, (featureState: _3dsource_angular_unreal_module.UnrealState) => boolean>;
|
|
2696
2906
|
selectStatusMessage: node_modules__ngrx_store_types_ngrx_store.MemoizedSelector<Record<string, any>, string | null, (featureState: _3dsource_angular_unreal_module.UnrealState) => string | null>;
|
|
@@ -2747,6 +2957,13 @@ interface UnrealState {
|
|
|
2747
2957
|
isAfkTimerVisible: boolean;
|
|
2748
2958
|
afkCountdown: number;
|
|
2749
2959
|
cirrusConnected: boolean;
|
|
2960
|
+
/**
|
|
2961
|
+
* True once a prefetched connection has been adopted (`streamAdopted`).
|
|
2962
|
+
* Read synchronously by the telemetry service so the connection-phase
|
|
2963
|
+
* closers know to defer to the prefetch-timed attribution instead of the
|
|
2964
|
+
* live-event one. Reset on every fresh attempt / disconnect.
|
|
2965
|
+
*/
|
|
2966
|
+
adopted: boolean;
|
|
2750
2967
|
viewportReady: boolean;
|
|
2751
2968
|
freezeFrameFromVideo: FreezeFrameMessage;
|
|
2752
2969
|
freezeFrame: FreezeFrameMessage;
|
|
@@ -2832,5 +3049,5 @@ declare const selectUserInactivityDetected: node_modules__ngrx_store_types_ngrx_
|
|
|
2832
3049
|
/** Used by external consumers (e.g., metabox). Do not remove. */
|
|
2833
3050
|
declare const selectIsVideoPlayingAndDataChannelConnected: node_modules__ngrx_store_types_ngrx_store.MemoizedSelector<Record<string, any>, boolean, (s1: boolean, s2: boolean) => boolean>;
|
|
2834
3051
|
|
|
2835
|
-
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,
|
|
2836
|
-
export type { AggregatedStat, AnySignalingMessage, AwsInstance, CandidateMessage, CloseReason, CommandInProgress, ConfigMessage, ConnectionError, ControlSchemeValues, DataFlowCheckResult, DisconnectReasonType, EmittedMilestone, EventId, ForceClientDisconnect, FreezeFrameMessage, InboundVideoStats, InputProps, InstanceReady, InstanceReserved, InterruptClientStream, ListStreamersMessage, MessageBase, MessageTypeValues, OrchestrationErrorMessage, OrchestrationMessageType, P2PEstablishedMessage, PhaseOverlay, PhaseParam, PingMessage, PlayerCountMessage, PollingOrchestrationMessage, Quality, ReceivedFile,
|
|
3052
|
+
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, DataFlowMonitor, DevModeService, DisconnectReason, FULL_HD_HEIGHT, FULL_HD_WIDTH, FileHandlerService, FileReceiverService, FilterSettingsComponent, FpsMonitorService, FreezeFrameComponent, FreezeFrameService, INNER_RETRY_LIMIT, IceCandidateHandler, ImageLoadingSrcComponent, InputOptions, InputService, InstanceReadyHandler, InstanceReservedHandler, IntroSrcComponent, KalmanFilter1D, LatencyTimings, LoadingProgressService, LowBandwidthDetectorComponent, LowBandwidthModalComponent, 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 };
|
|
3053
|
+
export type { AggregatedStat, AnySignalingMessage, AwsInstance, CandidateMessage, CloseReason, CommandInProgress, ConfigMessage, ConnectionError, ControlSchemeValues, DataFlowCheckResult, DisconnectReasonType, EmittedMilestone, EventId, ForceClientDisconnect, FreezeFrameMessage, InboundVideoStats, InputProps, InstanceReady, InstanceReserved, InterruptClientStream, ListStreamersMessage, MessageBase, MessageTypeValues, OrchestrationErrorMessage, OrchestrationMessageType, P2PEstablishedMessage, ParkedStream, PhaseOverlay, PhaseParam, PingMessage, PlayerCountMessage, PollingOrchestrationMessage, Quality, ReceivedFile, RequestStream, SSInfo, SelectedIceCandidatePair, SignalingData, SignalingMessageHandler, SignalingMessageMap, StreamConfig, StreamRequestContext, StreamResolutionProps, StreamerListMessage, TelemetryType, UnknownFields, UnrealCallbackDescriptor, UnrealCallbackEventMap, UnrealCallbackJson, UnrealCallbackJsonWrapped, UnrealInitialConfig, UnrealState, WSCloseCodesValues, streamPreparedForUserInteractionMessage };
|