@3dsource/angular-unreal-module 0.0.187 → 0.0.189

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.
@@ -214,18 +214,12 @@ declare class VideoStatsComponent {
214
214
  readonly videoQP: Signal<{
215
215
  value: number;
216
216
  }>;
217
+ /** What the window shows: the raw stats plus the few display-only values
218
+ * derived here. Shared by the text rows and the graphs. */
219
+ private readonly view;
217
220
  readonly videoStatus: Signal<{
218
221
  key: string;
219
- value: string | number | Record<string, string> | {
220
- local: {
221
- type: string;
222
- url: string;
223
- };
224
- remote: {
225
- type: string;
226
- url: string;
227
- };
228
- } | null | undefined;
222
+ value: unknown;
229
223
  }[] | undefined>;
230
224
  readonly fields: string[];
231
225
  private readonly elementsToShow;
@@ -568,6 +562,374 @@ interface SignalingData {
568
562
 
569
563
  type Quality = 'lime' | 'red' | 'orange';
570
564
 
565
+ /**
566
+ * Wire contract for every event `StreamStatusTelemetryService2` dispatches
567
+ * through `trackTelemetryData`.
568
+ *
569
+ * This file is the **single source of truth** for the producer side. The
570
+ * consumer side lives in the telemetry viewer
571
+ * (`253.StreamTelemetry/src/app/telemetry/models/telemetry.types.ts`) — any
572
+ * change here needs a paired edit there.
573
+ *
574
+ * Event taxonomy (8 names, 6 payload shapes):
575
+ * | event | payload |
576
+ * |----------------------------|------------------------------------|
577
+ * | `stream.session_started` | {@link SessionStartedData} |
578
+ * | `stream.phase_ended` | {@link PhaseEndedData} |
579
+ * | `stream.session_ended` | {@link SessionEndedData} |
580
+ * | `stream.sample` | {@link SampleData} |
581
+ * | `stream.quality_degraded` | {@link QualityAnomalyData} |
582
+ * | `stream.quality_recovered` | {@link QualityAnomalyData} |
583
+ * | `stream.fps_low` | {@link FpsLowData} |
584
+ * | `stream.signaling_retry` | {@link SignalingRetryData} |
585
+ */
586
+ /**
587
+ * Every stable id the service can put on the wire — phases, milestones,
588
+ * overlays. The viewer's vocabulary maps each member to a human label, so
589
+ * every id added here needs a paired vocabulary row in the viewer
590
+ * (`telemetry-vocabulary.ts`).
591
+ */
592
+ type EventId = 'region-resolving' | 'signaling-connection' | 'webrtc-negotiation' | 'unreal-communication' | 'region-ping-fetch-start' | 'region-ping-fetch-end' | 'region-resolved' | 'polling-started' | 'polling-ended' | 'aws-instance-resolved' | 'signaling-ws-connected' | 'instance-reserved' | 'instance-ready' | 'config-received' | 'ssinfo-received' | 'offer-received' | 'answer-sent' | 'answer-received' | 'first-ice-candidate' | 'last-ice-candidate' | 'datachannel-connected' | 'first-command-started' | 'loopback-sent' | 'loopback-received' | 'viewport-ready' | 'polling-to-instance' | 'signaling-handshake' | 'stabilization-warmup';
593
+ /**
594
+ * High-level cause of `stream.session_ended`.
595
+ * - `disconnected` — Cirrus/WebRTC dropped us mid-stream (granular cause
596
+ * rides in {@link SessionEndedData.disconnectReason}).
597
+ * - `pagehide` — tab closed / evicted to bfcache.
598
+ * - `restart` — a new connection attempt superseded this session.
599
+ * - `destroy` — the scene component was torn down (route change).
600
+ */
601
+ type SessionEndReason = 'disconnected' | 'pagehide' | 'restart' | 'destroy';
602
+ /** Which retry loop in `SignallingService` fired. Mirrors the
603
+ * `signalingRetryAttempted` action's `kind`. */
604
+ type SignalingRetryKind = 'ws-retry' | 'connect' | 'orchestration' | 'region-cycle';
605
+ /**
606
+ * Statistical summary of a time-series metric (bitrate, fps, qp, jitter,
607
+ * rtt) over one aggregation window (5 s, ~20 samples at 250 ms).
608
+ *
609
+ * - `p50` — the typical tick; robust to outliers, primary dashboard signal.
610
+ * - `p95` — the bad tail where HIGH is bad (rtt, jitter, qp).
611
+ * - `p05` — the bad tail where HIGH is good (fps, bitrate). Consumers need a
612
+ * robust low end, and `min` cannot serve: it is a single tick, so one
613
+ * dropped frame defines the window. Sent for every metric so the shape
614
+ * stays uniform; only fps and bitrate have a reason to read it.
615
+ *
616
+ * All three percentiles use linear interpolation between order statistics
617
+ * (type 7), matching the consumer's `percentile()` so the word means one
618
+ * thing across both repos.
619
+ * - `min` — worst single tick (freeze detection).
620
+ * - `max` — best single tick (did we ever reach the target?).
621
+ *
622
+ * Every field is a percentile of the SAME window, so a consumer may compare
623
+ * them to each other — but must never average them across windows to obtain
624
+ * a population percentile.
625
+ */
626
+ interface WindowAggregate {
627
+ readonly p50: number;
628
+ readonly p95: number;
629
+ readonly p05: number;
630
+ readonly min: number;
631
+ readonly max: number;
632
+ }
633
+ /** Milestone pin inside a phase. `id` is stable and kebab-case; the human
634
+ * label lives in the viewer's vocabulary. `time` is anchor-relative ms. */
635
+ interface EmittedMilestone {
636
+ readonly id: EventId;
637
+ readonly time: number;
638
+ }
639
+ /** Display key/value row, rendered verbatim in the viewer's phase tooltip.
640
+ * Always primitives — structured values are pre-formatted by the phase
641
+ * closer before flattening. */
642
+ interface PhaseParam {
643
+ readonly key: string;
644
+ readonly value: string;
645
+ }
646
+ /** Diagonal-striped region inside a phase bar. Endpoints are
647
+ * anchor-relative ms, already resolved by the producer. */
648
+ interface PhaseOverlay {
649
+ readonly fromMs: number;
650
+ readonly toMs: number;
651
+ readonly id: EventId;
652
+ }
653
+ /**
654
+ * One side of the selected ICE pair, as the browser reports it. Every field is
655
+ * optional — a browser that does not expose one leaves it unknown.
656
+ *
657
+ * `address` / `port` are the ALLOCATED relay endpoint and are only kept for a
658
+ * relay candidate (host / srflx addresses are never uploaded). They are not
659
+ * the TURN service endpoint: that one lives in `url`, and the browser→TURN
660
+ * transport in `relayProtocol` — `protocol` is the candidate's own transport,
661
+ * relay→peer. `url` / `relayProtocol` exist on the local side only.
662
+ */
663
+ interface IceCandidateInfo {
664
+ readonly type?: string;
665
+ readonly protocol?: string;
666
+ readonly address?: string;
667
+ readonly port?: number;
668
+ readonly url?: string;
669
+ readonly relayProtocol?: string;
670
+ }
671
+ /** Route description shipped once per {@link RouteSegment.ref} in `stream.sample.routes`. */
672
+ interface IceRoute {
673
+ readonly local: IceCandidateInfo;
674
+ readonly remote: IceCandidateInfo;
675
+ }
676
+ /**
677
+ * Selected WebRTC ICE candidate pair, read off `AggregatedStat` — resolved
678
+ * through `transport.selectedCandidatePairId`. Flattened to `localCandidate` /
679
+ * `remoteCandidate` params by the viewport closer.
680
+ *
681
+ * `ref` is `<pcEpoch>:<candidatePairId>`: a pair id is only unique inside one
682
+ * RTCPeerConnection, so the epoch (bumped per attached connection) keeps a
683
+ * reconnect from reusing the previous connection's ref. The counters are the
684
+ * PAIR's cumulative payload bytes — they start at 0 with the pair, so they
685
+ * never mix across pairs or connections.
686
+ */
687
+ interface SelectedIceCandidatePair extends IceRoute {
688
+ readonly ref: string;
689
+ /** Stats timestamp of the pair report, ms. */
690
+ readonly timestamp?: number;
691
+ readonly bytesReceived?: number;
692
+ readonly bytesSent?: number;
693
+ }
694
+ /**
695
+ * One uninterrupted run of 250 ms stats reads on the same pair inside a
696
+ * `stream.sample` window. Each tuple is `[first, last]` read of that run:
697
+ * stats timestamp, and the pair's cumulative `bytesReceived` / `bytesSent`
698
+ * (`null` when the browser did not report it).
699
+ *
700
+ * Time between two segments — inside a window or across windows — was not
701
+ * observed on any pair and is unattributable; a consumer must not stretch
702
+ * either neighbour over it.
703
+ */
704
+ interface RouteSegment {
705
+ readonly ref: string;
706
+ readonly ts: readonly [number | null, number | null];
707
+ readonly rx: readonly [number | null, number | null];
708
+ readonly tx: readonly [number | null, number | null];
709
+ }
710
+ /** Resource Timing totals for one `initiatorType` (or the grand total).
711
+ * `durationMs` is the SUM across the bucket — with `count` it yields the
712
+ * average per request, and `maxDurationMs` the slowest single one. */
713
+ interface ResourceBucket {
714
+ readonly count: number;
715
+ /** `transferSize === 0 && decodedBodySize > 0` — served from HTTP cache. */
716
+ readonly cachedCount: number;
717
+ readonly transferSize: number;
718
+ readonly encodedBodySize: number;
719
+ readonly decodedBodySize: number;
720
+ readonly durationMs: number;
721
+ readonly maxDurationMs: number;
722
+ }
723
+ interface ResourceTotals extends ResourceBucket {
724
+ readonly byType: Record<string, ResourceBucket>;
725
+ }
726
+ /** One entry of {@link BootstrapInfo.slowestResources}. */
727
+ interface SlowResource {
728
+ /** Path only — origin and query stripped (short, stable, no PII). */
729
+ readonly name: string;
730
+ /** Resource Timing `initiatorType`: 'script' | 'css' | 'img' | 'fetch' | … */
731
+ readonly type: string;
732
+ /** `responseEnd − startTime`, ms. */
733
+ readonly durationMs: number;
734
+ /** Bytes over the wire (0 = served from cache). */
735
+ readonly transferKb: number;
736
+ /** Fetched after `window.load` (lazy route chunk) vs. during page load. */
737
+ readonly lazy: boolean;
738
+ }
739
+ /** Navigation / page-load context explaining the "app bootstrap →
740
+ * session_started" waterfall row. `null` when the Navigation Timing entry
741
+ * is unavailable. */
742
+ interface BootstrapInfo {
743
+ /** `'navigate' | 'reload' | 'back_forward' | 'prerender'`. */
744
+ readonly type: NavigationTimingType;
745
+ /** `nextHopProtocol` — 'h2' / 'h3' / 'http/1.1'. */
746
+ readonly protocol: string | null;
747
+ readonly firstByteMs: number;
748
+ readonly domInteractiveMs: number;
749
+ readonly domContentLoadedMs: number;
750
+ readonly loadEventMs: number;
751
+ readonly navigationTransferSize: number | null;
752
+ readonly navigationEncodedBodySize: number | null;
753
+ readonly navigationDecodedBodySize: number | null;
754
+ /** Resources fetched **before** `loadEventEnd` — page weight. */
755
+ readonly resources: ResourceTotals | null;
756
+ /** Resources fetched **after** `loadEventEnd` — typically lazy chunks for
757
+ * the route the streamer lives on. */
758
+ readonly lazyResources: ResourceTotals | null;
759
+ /** Top-8 slowest individual resources, so the viewer can name the
760
+ * offending file / endpoint. */
761
+ readonly slowestResources: readonly SlowResource[];
762
+ }
763
+ /** Fields present on EVERY event. `userId` is attached centrally by
764
+ * `track()`; the server buckets files under `data/<userId>/<sessionId>`. */
765
+ interface TelemetryEventEnvelope {
766
+ readonly userId: string;
767
+ /**
768
+ * The stream's connection id (`selectCirrusConnectionId`) — the id Cirrus
769
+ * runs this player under, shown as "Connection Id" in the debug overlay. Falls
770
+ * back to a locally generated uuid only when the attempt never got one.
771
+ * Stamped centrally by `track()`, so the value the emitters pass is ignored.
772
+ */
773
+ readonly sessionId: string;
774
+ }
775
+ /** Lifecycle events additionally carry a phase-local `duration` — ms since
776
+ * the previous lifecycle event, NOT anchor-relative. */
777
+ interface TelemetryLifecycleEnvelope extends TelemetryEventEnvelope {
778
+ readonly duration: number;
779
+ }
780
+ /** `stream.session_started` — once per real connection attempt.
781
+ * `duration` = full page-load elapsed on the first session, 0 on resume. */
782
+ interface SessionStartedData extends TelemetryLifecycleEnvelope {
783
+ readonly startTimeUtc: string;
784
+ readonly pixelRatio: number;
785
+ /** `window.innerWidth/innerHeight` at session start — the container that
786
+ * gates rendered video resolution, not the physical screen. */
787
+ readonly browserInnerSize: {
788
+ readonly width: number;
789
+ readonly height: number;
790
+ };
791
+ readonly userAgent: string;
792
+ readonly sampleWindowMs: number;
793
+ /** `location.href` — the server-observed `Referer` is origin-truncated. */
794
+ readonly pageUrl: string;
795
+ readonly bootstrapInfo?: BootstrapInfo;
796
+ }
797
+ /** `stream.phase_ended` — once per phase closer in the service's catalog.
798
+ * No display text on the wire; the viewer's vocabulary resolves every id. */
799
+ interface PhaseEndedData extends TelemetryLifecycleEnvelope {
800
+ /** Stable 1-based catalog index — the viewer orders phases by this. */
801
+ readonly phaseNo: number;
802
+ readonly id: EventId;
803
+ /** CSS hex color for the bar fill. */
804
+ readonly color: string;
805
+ readonly milestones: readonly EmittedMilestone[];
806
+ readonly params: readonly PhaseParam[];
807
+ readonly overlays: readonly PhaseOverlay[];
808
+ /** Set on the connection phases of an ADOPTED prefetched stream: the
809
+ * handshake ran in parallel with page load, so the bar is positioned at
810
+ * {@link spanStartMs} (left-shifted) instead of sequentially. */
811
+ readonly prefetched?: boolean;
812
+ /** Anchor-relative start (ms) of a {@link prefetched} phase's bar. */
813
+ readonly spanStartMs?: number;
814
+ /** Anchor-relative moment Angular adopted the prefetched connection — the
815
+ * sequential timeline resumes here. */
816
+ readonly adoptionAtMs?: number;
817
+ /** The session ended while this phase was running — its closer never fired.
818
+ * Sent right before `session_ended` with the milestones reached so far and
819
+ * no params, so the viewer can show the step the connection died on. */
820
+ readonly incomplete?: true;
821
+ }
822
+ /** `stream.session_ended` — once per session, on disconnect / pagehide /
823
+ * restart / destroy. Requires `api_transport: 'sendBeacon'` to survive a
824
+ * tab close. */
825
+ interface SessionEndedData extends TelemetryLifecycleEnvelope {
826
+ readonly reason: SessionEndReason;
827
+ /** Granular cause read from store state. Omitted when state is clean. */
828
+ readonly disconnectReason?: DisconnectReasonType;
829
+ /** Free-text message paired with {@link disconnectReason}, only when the
830
+ * originating action carried one (e.g. `"Manual Console Drop"`). */
831
+ readonly disconnectMessage?: string;
832
+ readonly timestamp: string;
833
+ }
834
+ /** `stream.sample` — every 5 s, window-aggregated. `seq` is monotonic per
835
+ * session for server-side ordering & dedup. */
836
+ interface SampleData extends TelemetryEventEnvelope {
837
+ readonly seq: number;
838
+ readonly timestamp: string;
839
+ readonly sampleCount: number;
840
+ readonly visibilityState: DocumentVisibilityState;
841
+ readonly bitrate: WindowAggregate;
842
+ readonly fps: WindowAggregate;
843
+ readonly qp: WindowAggregate;
844
+ readonly jitter: WindowAggregate;
845
+ readonly rtt: WindowAggregate;
846
+ readonly packetsLost?: number;
847
+ /**
848
+ * Bytes the video stream delivered DURING this window — how far
849
+ * `inbound-rtp.bytesReceived` moved since the previous window closed, not a
850
+ * running total.
851
+ *
852
+ * What turns a bandwidth figure on the receiving end into a measurement.
853
+ * Volume needs the window's MEAN bitrate; {@link bitrate} carries
854
+ * p50/p95/min/max and no mean, so without this a consumer has to work the
855
+ * volume out from the median — which runs low on a stream that spikes at
856
+ * every keyframe.
857
+ *
858
+ * A delta rather than the cumulative counter on purpose: a cumulative value
859
+ * is only usable if the previous sample survived the trip, so one dropped
860
+ * POST would move bytes silently into the next window.
861
+ *
862
+ * Omitted when the counter is missing or went backwards (a renegotiation
863
+ * restarts it) — see `CounterWindow`. A consumer reads the gap as "estimate
864
+ * this window from the bitrate", which is the honest reading; it must never
865
+ * treat a missing value as zero bytes.
866
+ */
867
+ readonly bytes?: number;
868
+ readonly viewPort: {
869
+ readonly width?: number;
870
+ readonly height?: number;
871
+ };
872
+ /** Selected-pair runs seen in this window, in order. Omitted when no read
873
+ * of the window resolved a selected pair — the whole window is unknown. */
874
+ readonly routeSegments?: readonly RouteSegment[];
875
+ /** Full description of every ref seen for the FIRST time in this session.
876
+ * Later windows carry only the ref. */
877
+ readonly routes?: Readonly<Record<string, IceRoute>>;
878
+ }
879
+ /** `stream.quality_degraded` / `stream.quality_recovered` — QP p50 crossing
880
+ * the red threshold (35) in either direction. */
881
+ interface QualityAnomalyData extends TelemetryEventEnvelope {
882
+ readonly seq: number;
883
+ readonly timestamp: string;
884
+ readonly qpP50: number;
885
+ readonly qpP95: number;
886
+ }
887
+ /** `stream.fps_low` — window FPS p50 dropped below 70% of the target. */
888
+ interface FpsLowData extends TelemetryEventEnvelope {
889
+ readonly seq: number;
890
+ readonly timestamp: string;
891
+ /** Requested `maxFps`; `0` means unlimited. */
892
+ readonly target: number;
893
+ /** Target actually compared against (60 when `target === 0`). */
894
+ readonly referenceTarget: number;
895
+ readonly fpsP50: number;
896
+ readonly fpsP95: number;
897
+ }
898
+ /** `stream.signaling_retry` — one per `retry({ delay })` fire in
899
+ * `SignallingService`. Surfaced in the viewer's Anomalies table. */
900
+ interface SignalingRetryData extends TelemetryEventEnvelope {
901
+ readonly seq: number;
902
+ readonly timestamp: string;
903
+ readonly attempt: number;
904
+ readonly reason: string;
905
+ readonly kind: SignalingRetryKind;
906
+ }
907
+ /** Event name → payload. The authoritative index of the wire taxonomy. */
908
+ interface StreamTelemetryEventMap {
909
+ 'stream.session_started': SessionStartedData;
910
+ 'stream.phase_ended': PhaseEndedData;
911
+ 'stream.session_ended': SessionEndedData;
912
+ 'stream.sample': SampleData;
913
+ 'stream.quality_degraded': QualityAnomalyData;
914
+ 'stream.quality_recovered': QualityAnomalyData;
915
+ 'stream.fps_low': FpsLowData;
916
+ 'stream.signaling_retry': SignalingRetryData;
917
+ }
918
+ type StreamTelemetryEventName = keyof StreamTelemetryEventMap;
919
+ /** Names emitted via `emitLifecycle` — the three `duration`-carrying events. */
920
+ type StreamTelemetryLifecycleEventName = 'stream.session_started' | 'stream.phase_ended' | 'stream.session_ended';
921
+ /** Discriminated union of every `trackTelemetryData` envelope. */
922
+ type StreamTelemetryEvent = {
923
+ [K in StreamTelemetryEventName]: {
924
+ readonly event: K;
925
+ readonly data: StreamTelemetryEventMap[K];
926
+ };
927
+ }[StreamTelemetryEventName];
928
+ /** Payload a caller supplies to `track()` — `userId` is added centrally. */
929
+ type StreamTelemetryTrackData<K extends StreamTelemetryEventName> = Omit<StreamTelemetryEventMap[K], 'userId'>;
930
+ /** Payload a caller supplies to `emitLifecycle()` — `duration` is computed. */
931
+ type StreamTelemetryLifecycleData<K extends StreamTelemetryLifecycleEventName> = Omit<StreamTelemetryEventMap[K], 'userId' | 'duration'>;
932
+
571
933
  interface AggregatedStat {
572
934
  quality: Quality;
573
935
  aggregatedStats: InboundVideoStats;
@@ -582,16 +944,7 @@ interface InboundVideoStats extends RTCInboundRtpStreamStats {
582
944
  videoCodec: string;
583
945
  avgBitrate: number;
584
946
  avgFrameRate: number;
585
- selectedPair: {
586
- local: {
587
- type: string;
588
- url: string;
589
- };
590
- remote: {
591
- type: string;
592
- url: string;
593
- };
594
- } | null;
947
+ selectedPair: SelectedIceCandidatePair | null;
595
948
  currentRoundTripTime: number;
596
949
  codecs: Record<string, string>;
597
950
  receiveToCompositeMs: number;
@@ -670,559 +1023,246 @@ interface ParkedStream {
670
1023
  * Socket flow only — parked so the service can tear it down.
671
1024
  */
672
1025
  controlWs?: WebSocket;
673
- /** `peerConnectionOptions` the machine sent in its `config` message */
674
- config?: RTCConfiguration;
675
- /**
676
- * Reused as-is, none generated: `clientId`/`viewId` from the configurator
677
- * cache (same values the host app dispatches), `correlationId` is the
678
- * configurator id, `streamRequestId` comes from the orchestration.
679
- */
680
- ids: {
681
- clientId: string;
682
- viewId: string;
683
- correlationId: string;
684
- streamRequestId?: string;
685
- };
686
- /** DataChannel messages received before adoption, replayed on adopt */
687
- dcBuffer: ArrayBuffer[];
688
- /** `performance.now()` marks for the prefetch waterfall (telemetry) */
689
- timings: Record<string, number>;
690
- failReason?: string;
691
- failError?: string;
692
- /** Stops the script's watchdog and flips state to `adopted`. */
693
- adopt: () => ParkedStream;
694
- /**
695
- * One-shot callback fired the instant the stream settles; on the next
696
- * microtask if already settled. Required — adoption waits on it.
697
- */
698
- onSettled: (cb: (state: ParkedStream['state']) => void) => void;
699
- }
700
- /** Marker the service writes when it finds the slot free and connects itself. */
701
- interface AppOwnedStream {
702
- owner: 'app';
703
- }
704
- /** True when the slot is the app's own marker rather than a prefetched stream. */
705
- declare function isAppOwned(slot: ParkedStream | AppOwnedStream): slot is AppOwnedStream;
706
- declare global {
707
- interface Window {
708
- /**
709
- * The page's stream slot AND the lock: first writer owns the connection,
710
- * whoever finds it taken stands down. Both sides read-then-write with no
711
- * `await` between, so exactly one wins and a page never builds two
712
- * connections. An older script writes no `owner` — still "taken".
713
- */
714
- __stream?: ParkedStream | AppOwnedStream;
715
- }
716
- }
717
-
718
- interface InputProps {
719
- controlScheme: ControlSchemeValues;
720
- suppressBrowserKeys: boolean;
721
- }
722
-
723
- declare const OrchestrationMessageTypes: {
724
- readonly error: "error";
725
- readonly offer: "offer";
726
- readonly answer: "answer";
727
- readonly ssInfo: "ssInfo";
728
- readonly config: "config";
729
- readonly playerCount: "playerCount";
730
- readonly iceCandidate: "iceCandidate";
731
- readonly streamerList: "streamerList";
732
- readonly requestStream: "requestStream";
733
- readonly listStreamers: "listStreamers";
734
- readonly instanceReady: "instanceReady";
735
- readonly p2pEstablished: "p2pEstablished";
736
- readonly instanceReserved: "instanceReserved";
737
- readonly interruptClientStream: "interruptClientStream";
738
- };
739
- interface InstanceReady extends MessageBase {
740
- type: 'instanceReady';
741
- correlationId: string;
742
- payload: {
743
- instanceId: string;
744
- originInstanceId: string;
745
- ipAddress: string;
746
- streamRequestId: string;
747
- originInstanceUri: string;
748
- };
749
- }
750
- interface InstanceReserved extends InstanceMessageBase {
751
- type: 'instanceReserved';
752
- }
753
- interface OrchestrationErrorMessage {
754
- type: 'error';
755
- payload: {
756
- code: number;
757
- message: string;
758
- };
759
- }
760
- interface InstanceMessageBase extends MessageBase {
761
- correlationId: string;
762
- payload: {
763
- instanceId: string;
764
- streamRequestId: string;
765
- eta: number;
766
- };
767
- }
768
- interface MessageBase {
769
- type: OrchestrationMessageType;
770
- }
771
- interface SSInfo extends MessageBase {
772
- type: 'ssInfo';
773
- message: string;
774
- data: SignalingData;
775
- }
776
- interface PlayerCountMessage extends MessageBase {
777
- type: 'playerCount';
778
- playerCount: number;
779
- }
780
- interface StreamerListMessage extends MessageBase {
781
- type: 'streamerList';
782
- ids: string[];
783
- }
784
- interface ConfigMessage extends MessageBase, UnknownFields {
785
- type: 'config';
786
- peerConnectionOptions: RTCConfiguration;
787
- }
788
- interface CandidateMessage extends MessageBase {
789
- type: 'iceCandidate';
790
- candidate: RTCIceCandidate;
791
- }
792
- type UnknownFields = Record<string, unknown>;
793
- interface InterruptClientStream extends MessageBase {
794
- type: 'interruptClientStream';
795
- correlationId: string;
796
- payload: {
797
- environmentId: string;
798
- };
799
- }
800
- interface ListStreamersMessage extends MessageBase {
801
- type: 'listStreamers';
802
- correlationId: string;
803
- }
804
- interface P2PEstablishedMessage extends MessageBase {
805
- type: 'p2pEstablished';
806
- source: string;
807
- sessionId: string;
808
- }
809
- interface RequestStream extends MessageBase {
810
- type: 'requestStream';
811
- correlationId: string;
812
- payload: {
813
- environmentId: string;
814
- region?: string;
815
- /**
816
- * The context field is used for plugins of the external
817
- * applications for collecting additional statistics, etc.
818
- */
819
- context: StreamRequestContext;
820
- };
821
- }
822
- interface MetaboxBasicConfiguratorContext {
823
- id: 'metaboxBasicConfigurator';
824
- data: {
825
- configuratorId: string;
826
- };
827
- }
828
- interface MetaboxModularConfiguratorContext {
829
- id: 'metaboxModularConfigurator';
830
- data: {
831
- configuratorId: string;
832
- };
833
- }
834
- interface MetaboxProductContext {
835
- id: 'metaboxProduct';
836
- data: {
837
- productId: string;
838
- };
839
- }
840
- interface MetaboxEnvironmentContext {
841
- id: 'metaboxEnvironment';
842
- data: {
843
- environmentId: string;
844
- };
845
- }
846
- interface MetaboxStudioContext {
847
- id: 'metaboxStudio';
848
- data: {
849
- userId: string;
850
- workspaceId: string;
851
- };
852
- }
853
- interface CustomApplicationContext {
854
- id: 'customApplication';
855
- data: {
856
- clientId: string;
857
- applicationId: string;
858
- };
859
- }
860
- interface MetaboxCustomApplicationContext {
861
- id: 'metaboxCustomApplication';
862
- data: {
863
- clientId: string;
864
- };
865
- }
866
- type StreamRequestContext = MetaboxStudioContext | MetaboxProductContext | CustomApplicationContext | MetaboxCustomApplicationContext | MetaboxEnvironmentContext | MetaboxBasicConfiguratorContext | MetaboxModularConfiguratorContext;
867
- interface SignalingMessageMap {
868
- [OrchestrationMessageTypes.offer]: RTCSessionDescriptionInit;
869
- [OrchestrationMessageTypes.error]: OrchestrationErrorMessage;
870
- [OrchestrationMessageTypes.ssInfo]: SSInfo;
871
- [OrchestrationMessageTypes.config]: ConfigMessage;
872
- [OrchestrationMessageTypes.answer]: RTCSessionDescriptionInit;
873
- [OrchestrationMessageTypes.playerCount]: PlayerCountMessage;
874
- [OrchestrationMessageTypes.iceCandidate]: CandidateMessage;
875
- [OrchestrationMessageTypes.streamerList]: StreamerListMessage;
876
- [OrchestrationMessageTypes.instanceReady]: InstanceReady;
877
- [OrchestrationMessageTypes.requestStream]: RequestStream;
878
- [OrchestrationMessageTypes.listStreamers]: ListStreamersMessage;
879
- [OrchestrationMessageTypes.p2pEstablished]: P2PEstablishedMessage;
880
- [OrchestrationMessageTypes.instanceReserved]: InstanceReserved;
881
- [OrchestrationMessageTypes.interruptClientStream]: InterruptClientStream;
882
- }
883
- type OrchestrationMessageType = keyof SignalingMessageMap;
884
- type AnySignalingMessage = SignalingMessageMap[OrchestrationMessageType] | string;
885
- type SignalingMessageHandler<T extends keyof SignalingMessageMap> = (msg: SignalingMessageMap[T]) => void;
886
- interface PollingOrchestrationMessage {
887
- mm_message?: string;
888
- signallingServer?: string;
1026
+ /** `peerConnectionOptions` the machine sent in its `config` message */
1027
+ config?: RTCConfiguration;
889
1028
  /**
890
- * Connection id issued by the orchestration for this stream request. Kept
891
- * internally as `connectionId` and handed to Cirrus on the WS upgrade URL.
892
- * Absent on older backends — Cirrus then generates one itself.
1029
+ * Reused as-is, none generated: `clientId`/`viewId` from the configurator
1030
+ * cache (same values the host app dispatches), `correlationId` is the
1031
+ * configurator id, `streamRequestId` comes from the orchestration.
893
1032
  */
894
- streamRequestId?: string;
895
- error?: string;
896
- info?: {
897
- age: number | null;
898
- left: number | null;
899
- percent: number | null;
900
- total: number | null;
1033
+ ids: {
1034
+ clientId: string;
1035
+ viewId: string;
1036
+ correlationId: string;
1037
+ streamRequestId?: string;
901
1038
  };
1039
+ /** DataChannel messages received before adoption, replayed on adopt */
1040
+ dcBuffer: ArrayBuffer[];
1041
+ /** `performance.now()` marks for the prefetch waterfall (telemetry) */
1042
+ timings: Record<string, number>;
1043
+ failReason?: string;
1044
+ failError?: string;
1045
+ /** Stops the script's watchdog and flips state to `adopted`. */
1046
+ adopt: () => ParkedStream;
1047
+ /**
1048
+ * One-shot callback fired the instant the stream settles; on the next
1049
+ * microtask if already settled. Required — adoption waits on it.
1050
+ */
1051
+ onSettled: (cb: (state: ParkedStream['state']) => void) => void;
902
1052
  }
903
-
904
- interface StreamConfig {
905
- autoStart: boolean;
906
- warnTimeout: number;
1053
+ /** Marker the service writes when it finds the slot free and connects itself. */
1054
+ interface AppOwnedStream {
1055
+ owner: 'app';
907
1056
  }
908
-
909
- interface StreamResolutionProps {
910
- width: number | null;
911
- height: number | null;
1057
+ /** True when the slot is the app's own marker rather than a prefetched stream. */
1058
+ declare function isAppOwned(slot: ParkedStream | AppOwnedStream): slot is AppOwnedStream;
1059
+ declare global {
1060
+ interface Window {
1061
+ /**
1062
+ * The page's stream slot AND the lock: first writer owns the connection,
1063
+ * whoever finds it taken stands down. Both sides read-then-write with no
1064
+ * `await` between, so exactly one wins and a page never builds two
1065
+ * connections. An older script writes no `owner` — still "taken".
1066
+ */
1067
+ __stream?: ParkedStream | AppOwnedStream;
1068
+ }
912
1069
  }
913
1070
 
914
- /**
915
- * Wire contract for every event `StreamStatusTelemetryService2` dispatches
916
- * through `trackTelemetryData`.
917
- *
918
- * This file is the **single source of truth** for the producer side. The
919
- * consumer side lives in the telemetry viewer
920
- * (`253.StreamTelemetry/src/app/telemetry/models/telemetry.types.ts`) — any
921
- * change here needs a paired edit there.
922
- *
923
- * Event taxonomy (8 names, 6 payload shapes):
924
- * | event | payload |
925
- * |----------------------------|------------------------------------|
926
- * | `stream.session_started` | {@link SessionStartedData} |
927
- * | `stream.phase_ended` | {@link PhaseEndedData} |
928
- * | `stream.session_ended` | {@link SessionEndedData} |
929
- * | `stream.sample` | {@link SampleData} |
930
- * | `stream.quality_degraded` | {@link QualityAnomalyData} |
931
- * | `stream.quality_recovered` | {@link QualityAnomalyData} |
932
- * | `stream.fps_low` | {@link FpsLowData} |
933
- * | `stream.signaling_retry` | {@link SignalingRetryData} |
934
- */
935
- /**
936
- * Every stable id the service can put on the wire — phases, milestones,
937
- * overlays. The viewer's vocabulary maps each member to a human label, so
938
- * every id added here needs a paired vocabulary row in the viewer
939
- * (`telemetry-vocabulary.ts`).
940
- */
941
- type EventId = 'region-resolving' | 'signaling-connection' | 'webrtc-negotiation' | 'unreal-communication' | 'region-ping-fetch-start' | 'region-ping-fetch-end' | 'region-resolved' | 'polling-started' | 'polling-ended' | 'aws-instance-resolved' | 'signaling-ws-connected' | 'instance-reserved' | 'instance-ready' | 'config-received' | 'ssinfo-received' | 'offer-received' | 'answer-sent' | 'answer-received' | 'first-ice-candidate' | 'last-ice-candidate' | 'datachannel-connected' | 'first-command-started' | 'loopback-sent' | 'loopback-received' | 'viewport-ready' | 'polling-to-instance' | 'signaling-handshake' | 'stabilization-warmup';
942
- /**
943
- * High-level cause of `stream.session_ended`.
944
- * - `disconnected` — Cirrus/WebRTC dropped us mid-stream (granular cause
945
- * rides in {@link SessionEndedData.disconnectReason}).
946
- * - `pagehide` — tab closed / evicted to bfcache.
947
- * - `restart` — a new connection attempt superseded this session.
948
- * - `destroy` — the scene component was torn down (route change).
949
- */
950
- type SessionEndReason = 'disconnected' | 'pagehide' | 'restart' | 'destroy';
951
- /** Which retry loop in `SignallingService` fired. Mirrors the
952
- * `signalingRetryAttempted` action's `kind`. */
953
- type SignalingRetryKind = 'ws-retry' | 'connect' | 'orchestration' | 'region-cycle';
954
- /**
955
- * Statistical summary of a time-series metric (bitrate, fps, qp, jitter,
956
- * rtt) over one aggregation window (5 s, ~20 samples at 250 ms).
957
- *
958
- * - `p50` — the typical tick; robust to outliers, primary dashboard signal.
959
- * - `p95` — the bad tail where HIGH is bad (rtt, jitter, qp).
960
- * - `p05` — the bad tail where HIGH is good (fps, bitrate). Consumers need a
961
- * robust low end, and `min` cannot serve: it is a single tick, so one
962
- * dropped frame defines the window. Sent for every metric so the shape
963
- * stays uniform; only fps and bitrate have a reason to read it.
964
- *
965
- * All three percentiles use linear interpolation between order statistics
966
- * (type 7), matching the consumer's `percentile()` so the word means one
967
- * thing across both repos.
968
- * - `min` — worst single tick (freeze detection).
969
- * - `max` — best single tick (did we ever reach the target?).
970
- *
971
- * Every field is a percentile of the SAME window, so a consumer may compare
972
- * them to each other — but must never average them across windows to obtain
973
- * a population percentile.
974
- */
975
- interface WindowAggregate {
976
- readonly p50: number;
977
- readonly p95: number;
978
- readonly p05: number;
979
- readonly min: number;
980
- readonly max: number;
981
- }
982
- /** Milestone pin inside a phase. `id` is stable and kebab-case; the human
983
- * label lives in the viewer's vocabulary. `time` is anchor-relative ms. */
984
- interface EmittedMilestone {
985
- readonly id: EventId;
986
- readonly time: number;
1071
+ interface InputProps {
1072
+ controlScheme: ControlSchemeValues;
1073
+ suppressBrowserKeys: boolean;
987
1074
  }
988
- /** Display key/value row, rendered verbatim in the viewer's phase tooltip.
989
- * Always primitives — structured values are pre-formatted by the phase
990
- * closer before flattening. */
991
- interface PhaseParam {
992
- readonly key: string;
993
- readonly value: string;
1075
+
1076
+ declare const OrchestrationMessageTypes: {
1077
+ readonly error: "error";
1078
+ readonly offer: "offer";
1079
+ readonly answer: "answer";
1080
+ readonly ssInfo: "ssInfo";
1081
+ readonly config: "config";
1082
+ readonly playerCount: "playerCount";
1083
+ readonly iceCandidate: "iceCandidate";
1084
+ readonly streamerList: "streamerList";
1085
+ readonly requestStream: "requestStream";
1086
+ readonly listStreamers: "listStreamers";
1087
+ readonly instanceReady: "instanceReady";
1088
+ readonly p2pEstablished: "p2pEstablished";
1089
+ readonly instanceReserved: "instanceReserved";
1090
+ readonly interruptClientStream: "interruptClientStream";
1091
+ };
1092
+ interface InstanceReady extends MessageBase {
1093
+ type: 'instanceReady';
1094
+ correlationId: string;
1095
+ payload: {
1096
+ instanceId: string;
1097
+ originInstanceId: string;
1098
+ ipAddress: string;
1099
+ streamRequestId: string;
1100
+ originInstanceUri: string;
1101
+ };
994
1102
  }
995
- /** Diagonal-striped region inside a phase bar. Endpoints are
996
- * anchor-relative ms, already resolved by the producer. */
997
- interface PhaseOverlay {
998
- readonly fromMs: number;
999
- readonly toMs: number;
1000
- readonly id: EventId;
1103
+ interface InstanceReserved extends InstanceMessageBase {
1104
+ type: 'instanceReserved';
1001
1105
  }
1002
- /** Selected WebRTC ICE candidate pair, read off `AggregatedStat`. Flattened
1003
- * to `localCandidate` / `remoteCandidate` params by the viewport closer. */
1004
- interface SelectedIceCandidatePair {
1005
- readonly local: {
1006
- type: string;
1007
- url: string;
1106
+ interface OrchestrationErrorMessage {
1107
+ type: 'error';
1108
+ payload: {
1109
+ code: number;
1110
+ message: string;
1008
1111
  };
1009
- readonly remote: {
1010
- type: string;
1011
- url: string;
1112
+ }
1113
+ interface InstanceMessageBase extends MessageBase {
1114
+ correlationId: string;
1115
+ payload: {
1116
+ instanceId: string;
1117
+ streamRequestId: string;
1118
+ eta: number;
1012
1119
  };
1013
1120
  }
1014
- /** Resource Timing totals for one `initiatorType` (or the grand total).
1015
- * `durationMs` is the SUM across the bucket — with `count` it yields the
1016
- * average per request, and `maxDurationMs` the slowest single one. */
1017
- interface ResourceBucket {
1018
- readonly count: number;
1019
- /** `transferSize === 0 && decodedBodySize > 0` — served from HTTP cache. */
1020
- readonly cachedCount: number;
1021
- readonly transferSize: number;
1022
- readonly encodedBodySize: number;
1023
- readonly decodedBodySize: number;
1024
- readonly durationMs: number;
1025
- readonly maxDurationMs: number;
1121
+ interface MessageBase {
1122
+ type: OrchestrationMessageType;
1026
1123
  }
1027
- interface ResourceTotals extends ResourceBucket {
1028
- readonly byType: Record<string, ResourceBucket>;
1124
+ interface SSInfo extends MessageBase {
1125
+ type: 'ssInfo';
1126
+ message: string;
1127
+ data: SignalingData;
1029
1128
  }
1030
- /** One entry of {@link BootstrapInfo.slowestResources}. */
1031
- interface SlowResource {
1032
- /** Path only — origin and query stripped (short, stable, no PII). */
1033
- readonly name: string;
1034
- /** Resource Timing `initiatorType`: 'script' | 'css' | 'img' | 'fetch' | … */
1035
- readonly type: string;
1036
- /** `responseEnd − startTime`, ms. */
1037
- readonly durationMs: number;
1038
- /** Bytes over the wire (0 = served from cache). */
1039
- readonly transferKb: number;
1040
- /** Fetched after `window.load` (lazy route chunk) vs. during page load. */
1041
- readonly lazy: boolean;
1129
+ interface PlayerCountMessage extends MessageBase {
1130
+ type: 'playerCount';
1131
+ playerCount: number;
1042
1132
  }
1043
- /** Navigation / page-load context explaining the "app bootstrap →
1044
- * session_started" waterfall row. `null` when the Navigation Timing entry
1045
- * is unavailable. */
1046
- interface BootstrapInfo {
1047
- /** `'navigate' | 'reload' | 'back_forward' | 'prerender'`. */
1048
- readonly type: NavigationTimingType;
1049
- /** `nextHopProtocol` — 'h2' / 'h3' / 'http/1.1'. */
1050
- readonly protocol: string | null;
1051
- readonly firstByteMs: number;
1052
- readonly domInteractiveMs: number;
1053
- readonly domContentLoadedMs: number;
1054
- readonly loadEventMs: number;
1055
- readonly navigationTransferSize: number | null;
1056
- readonly navigationEncodedBodySize: number | null;
1057
- readonly navigationDecodedBodySize: number | null;
1058
- /** Resources fetched **before** `loadEventEnd` — page weight. */
1059
- readonly resources: ResourceTotals | null;
1060
- /** Resources fetched **after** `loadEventEnd` — typically lazy chunks for
1061
- * the route the streamer lives on. */
1062
- readonly lazyResources: ResourceTotals | null;
1063
- /** Top-8 slowest individual resources, so the viewer can name the
1064
- * offending file / endpoint. */
1065
- readonly slowestResources: readonly SlowResource[];
1133
+ interface StreamerListMessage extends MessageBase {
1134
+ type: 'streamerList';
1135
+ ids: string[];
1136
+ }
1137
+ interface ConfigMessage extends MessageBase, UnknownFields {
1138
+ type: 'config';
1139
+ peerConnectionOptions: RTCConfiguration;
1140
+ }
1141
+ interface CandidateMessage extends MessageBase {
1142
+ type: 'iceCandidate';
1143
+ candidate: RTCIceCandidate;
1144
+ }
1145
+ type UnknownFields = Record<string, unknown>;
1146
+ interface InterruptClientStream extends MessageBase {
1147
+ type: 'interruptClientStream';
1148
+ correlationId: string;
1149
+ payload: {
1150
+ environmentId: string;
1151
+ };
1066
1152
  }
1067
- /** Fields present on EVERY event. `userId` is attached centrally by
1068
- * `track()`; the server buckets files under `data/<userId>/<sessionId>`. */
1069
- interface TelemetryEventEnvelope {
1070
- readonly userId: string;
1071
- /**
1072
- * The stream's connection id (`selectCirrusConnectionId`) — the id Cirrus
1073
- * runs this player under, shown as "Connection Id" in the debug overlay. Falls
1074
- * back to a locally generated uuid only when the attempt never got one.
1075
- * Stamped centrally by `track()`, so the value the emitters pass is ignored.
1076
- */
1077
- readonly sessionId: string;
1153
+ interface ListStreamersMessage extends MessageBase {
1154
+ type: 'listStreamers';
1155
+ correlationId: string;
1078
1156
  }
1079
- /** Lifecycle events additionally carry a phase-local `duration` — ms since
1080
- * the previous lifecycle event, NOT anchor-relative. */
1081
- interface TelemetryLifecycleEnvelope extends TelemetryEventEnvelope {
1082
- readonly duration: number;
1157
+ interface P2PEstablishedMessage extends MessageBase {
1158
+ type: 'p2pEstablished';
1159
+ source: string;
1160
+ sessionId: string;
1083
1161
  }
1084
- /** `stream.session_started` — once per real connection attempt.
1085
- * `duration` = full page-load elapsed on the first session, 0 on resume. */
1086
- interface SessionStartedData extends TelemetryLifecycleEnvelope {
1087
- readonly startTimeUtc: string;
1088
- readonly pixelRatio: number;
1089
- /** `window.innerWidth/innerHeight` at session start — the container that
1090
- * gates rendered video resolution, not the physical screen. */
1091
- readonly browserInnerSize: {
1092
- readonly width: number;
1093
- readonly height: number;
1162
+ interface RequestStream extends MessageBase {
1163
+ type: 'requestStream';
1164
+ correlationId: string;
1165
+ payload: {
1166
+ environmentId: string;
1167
+ region?: string;
1168
+ /**
1169
+ * The context field is used for plugins of the external
1170
+ * applications for collecting additional statistics, etc.
1171
+ */
1172
+ context: StreamRequestContext;
1094
1173
  };
1095
- readonly userAgent: string;
1096
- readonly sampleWindowMs: number;
1097
- /** `location.href` — the server-observed `Referer` is origin-truncated. */
1098
- readonly pageUrl: string;
1099
- readonly bootstrapInfo?: BootstrapInfo;
1100
1174
  }
1101
- /** `stream.phase_ended` — once per phase closer in the service's catalog.
1102
- * No display text on the wire; the viewer's vocabulary resolves every id. */
1103
- interface PhaseEndedData extends TelemetryLifecycleEnvelope {
1104
- /** Stable 1-based catalog index — the viewer orders phases by this. */
1105
- readonly phaseNo: number;
1106
- readonly id: EventId;
1107
- /** CSS hex color for the bar fill. */
1108
- readonly color: string;
1109
- readonly milestones: readonly EmittedMilestone[];
1110
- readonly params: readonly PhaseParam[];
1111
- readonly overlays: readonly PhaseOverlay[];
1112
- /** Set on the connection phases of an ADOPTED prefetched stream: the
1113
- * handshake ran in parallel with page load, so the bar is positioned at
1114
- * {@link spanStartMs} (left-shifted) instead of sequentially. */
1115
- readonly prefetched?: boolean;
1116
- /** Anchor-relative start (ms) of a {@link prefetched} phase's bar. */
1117
- readonly spanStartMs?: number;
1118
- /** Anchor-relative moment Angular adopted the prefetched connection — the
1119
- * sequential timeline resumes here. */
1120
- readonly adoptionAtMs?: number;
1175
+ interface MetaboxBasicConfiguratorContext {
1176
+ id: 'metaboxBasicConfigurator';
1177
+ data: {
1178
+ configuratorId: string;
1179
+ };
1121
1180
  }
1122
- /** `stream.session_ended` — once per session, on disconnect / pagehide /
1123
- * restart / destroy. Requires `api_transport: 'sendBeacon'` to survive a
1124
- * tab close. */
1125
- interface SessionEndedData extends TelemetryLifecycleEnvelope {
1126
- readonly reason: SessionEndReason;
1127
- /** Granular cause read from store state. Omitted when state is clean. */
1128
- readonly disconnectReason?: DisconnectReasonType;
1129
- /** Free-text message paired with {@link disconnectReason}, only when the
1130
- * originating action carried one (e.g. `"Manual Console Drop"`). */
1131
- readonly disconnectMessage?: string;
1132
- readonly timestamp: string;
1181
+ interface MetaboxModularConfiguratorContext {
1182
+ id: 'metaboxModularConfigurator';
1183
+ data: {
1184
+ configuratorId: string;
1185
+ };
1133
1186
  }
1134
- /** `stream.sample` — every 5 s, window-aggregated. `seq` is monotonic per
1135
- * session for server-side ordering & dedup. */
1136
- interface SampleData extends TelemetryEventEnvelope {
1137
- readonly seq: number;
1138
- readonly timestamp: string;
1139
- readonly sampleCount: number;
1140
- readonly visibilityState: DocumentVisibilityState;
1141
- readonly bitrate: WindowAggregate;
1142
- readonly fps: WindowAggregate;
1143
- readonly qp: WindowAggregate;
1144
- readonly jitter: WindowAggregate;
1145
- readonly rtt: WindowAggregate;
1146
- readonly packetsLost?: number;
1147
- /**
1148
- * Bytes the video stream delivered DURING this window — how far
1149
- * `inbound-rtp.bytesReceived` moved since the previous window closed, not a
1150
- * running total.
1151
- *
1152
- * What turns a bandwidth figure on the receiving end into a measurement.
1153
- * Volume needs the window's MEAN bitrate; {@link bitrate} carries
1154
- * p50/p95/min/max and no mean, so without this a consumer has to work the
1155
- * volume out from the median — which runs low on a stream that spikes at
1156
- * every keyframe.
1157
- *
1158
- * A delta rather than the cumulative counter on purpose: a cumulative value
1159
- * is only usable if the previous sample survived the trip, so one dropped
1160
- * POST would move bytes silently into the next window.
1161
- *
1162
- * Omitted when the counter is missing or went backwards (a renegotiation
1163
- * restarts it) — see `CounterWindow`. A consumer reads the gap as "estimate
1164
- * this window from the bitrate", which is the honest reading; it must never
1165
- * treat a missing value as zero bytes.
1166
- */
1167
- readonly bytes?: number;
1168
- readonly viewPort: {
1169
- readonly width?: number;
1170
- readonly height?: number;
1187
+ interface MetaboxProductContext {
1188
+ id: 'metaboxProduct';
1189
+ data: {
1190
+ productId: string;
1171
1191
  };
1172
1192
  }
1173
- /** `stream.quality_degraded` / `stream.quality_recovered` — QP p50 crossing
1174
- * the red threshold (35) in either direction. */
1175
- interface QualityAnomalyData extends TelemetryEventEnvelope {
1176
- readonly seq: number;
1177
- readonly timestamp: string;
1178
- readonly qpP50: number;
1179
- readonly qpP95: number;
1193
+ interface MetaboxEnvironmentContext {
1194
+ id: 'metaboxEnvironment';
1195
+ data: {
1196
+ environmentId: string;
1197
+ };
1180
1198
  }
1181
- /** `stream.fps_low` — window FPS p50 dropped below 70% of the target. */
1182
- interface FpsLowData extends TelemetryEventEnvelope {
1183
- readonly seq: number;
1184
- readonly timestamp: string;
1185
- /** Requested `maxFps`; `0` means unlimited. */
1186
- readonly target: number;
1187
- /** Target actually compared against (60 when `target === 0`). */
1188
- readonly referenceTarget: number;
1189
- readonly fpsP50: number;
1190
- readonly fpsP95: number;
1199
+ interface MetaboxStudioContext {
1200
+ id: 'metaboxStudio';
1201
+ data: {
1202
+ userId: string;
1203
+ workspaceId: string;
1204
+ };
1191
1205
  }
1192
- /** `stream.signaling_retry` — one per `retry({ delay })` fire in
1193
- * `SignallingService`. Surfaced in the viewer's Anomalies table. */
1194
- interface SignalingRetryData extends TelemetryEventEnvelope {
1195
- readonly seq: number;
1196
- readonly timestamp: string;
1197
- readonly attempt: number;
1198
- readonly reason: string;
1199
- readonly kind: SignalingRetryKind;
1206
+ interface CustomApplicationContext {
1207
+ id: 'customApplication';
1208
+ data: {
1209
+ clientId: string;
1210
+ applicationId: string;
1211
+ };
1200
1212
  }
1201
- /** Event name → payload. The authoritative index of the wire taxonomy. */
1202
- interface StreamTelemetryEventMap {
1203
- 'stream.session_started': SessionStartedData;
1204
- 'stream.phase_ended': PhaseEndedData;
1205
- 'stream.session_ended': SessionEndedData;
1206
- 'stream.sample': SampleData;
1207
- 'stream.quality_degraded': QualityAnomalyData;
1208
- 'stream.quality_recovered': QualityAnomalyData;
1209
- 'stream.fps_low': FpsLowData;
1210
- 'stream.signaling_retry': SignalingRetryData;
1213
+ interface MetaboxCustomApplicationContext {
1214
+ id: 'metaboxCustomApplication';
1215
+ data: {
1216
+ clientId: string;
1217
+ };
1211
1218
  }
1212
- type StreamTelemetryEventName = keyof StreamTelemetryEventMap;
1213
- /** Names emitted via `emitLifecycle` — the three `duration`-carrying events. */
1214
- type StreamTelemetryLifecycleEventName = 'stream.session_started' | 'stream.phase_ended' | 'stream.session_ended';
1215
- /** Discriminated union of every `trackTelemetryData` envelope. */
1216
- type StreamTelemetryEvent = {
1217
- [K in StreamTelemetryEventName]: {
1218
- readonly event: K;
1219
- readonly data: StreamTelemetryEventMap[K];
1219
+ type StreamRequestContext = MetaboxStudioContext | MetaboxProductContext | CustomApplicationContext | MetaboxCustomApplicationContext | MetaboxEnvironmentContext | MetaboxBasicConfiguratorContext | MetaboxModularConfiguratorContext;
1220
+ interface SignalingMessageMap {
1221
+ [OrchestrationMessageTypes.offer]: RTCSessionDescriptionInit;
1222
+ [OrchestrationMessageTypes.error]: OrchestrationErrorMessage;
1223
+ [OrchestrationMessageTypes.ssInfo]: SSInfo;
1224
+ [OrchestrationMessageTypes.config]: ConfigMessage;
1225
+ [OrchestrationMessageTypes.answer]: RTCSessionDescriptionInit;
1226
+ [OrchestrationMessageTypes.playerCount]: PlayerCountMessage;
1227
+ [OrchestrationMessageTypes.iceCandidate]: CandidateMessage;
1228
+ [OrchestrationMessageTypes.streamerList]: StreamerListMessage;
1229
+ [OrchestrationMessageTypes.instanceReady]: InstanceReady;
1230
+ [OrchestrationMessageTypes.requestStream]: RequestStream;
1231
+ [OrchestrationMessageTypes.listStreamers]: ListStreamersMessage;
1232
+ [OrchestrationMessageTypes.p2pEstablished]: P2PEstablishedMessage;
1233
+ [OrchestrationMessageTypes.instanceReserved]: InstanceReserved;
1234
+ [OrchestrationMessageTypes.interruptClientStream]: InterruptClientStream;
1235
+ }
1236
+ type OrchestrationMessageType = keyof SignalingMessageMap;
1237
+ type AnySignalingMessage = SignalingMessageMap[OrchestrationMessageType] | string;
1238
+ type SignalingMessageHandler<T extends keyof SignalingMessageMap> = (msg: SignalingMessageMap[T]) => void;
1239
+ interface PollingOrchestrationMessage {
1240
+ mm_message?: string;
1241
+ signallingServer?: string;
1242
+ /**
1243
+ * Connection id issued by the orchestration for this stream request. Kept
1244
+ * internally as `connectionId` and handed to Cirrus on the WS upgrade URL.
1245
+ * Absent on older backends — Cirrus then generates one itself.
1246
+ */
1247
+ streamRequestId?: string;
1248
+ error?: string;
1249
+ info?: {
1250
+ age: number | null;
1251
+ left: number | null;
1252
+ percent: number | null;
1253
+ total: number | null;
1220
1254
  };
1221
- }[StreamTelemetryEventName];
1222
- /** Payload a caller supplies to `track()` — `userId` is added centrally. */
1223
- type StreamTelemetryTrackData<K extends StreamTelemetryEventName> = Omit<StreamTelemetryEventMap[K], 'userId'>;
1224
- /** Payload a caller supplies to `emitLifecycle()` — `duration` is computed. */
1225
- type StreamTelemetryLifecycleData<K extends StreamTelemetryLifecycleEventName> = Omit<StreamTelemetryEventMap[K], 'userId' | 'duration'>;
1255
+ }
1256
+
1257
+ interface StreamConfig {
1258
+ autoStart: boolean;
1259
+ warnTimeout: number;
1260
+ }
1261
+
1262
+ interface StreamResolutionProps {
1263
+ width: number | null;
1264
+ height: number | null;
1265
+ }
1226
1266
 
1227
1267
  /**
1228
1268
  * Parts of the module UI a host application can restyle by supplying its own
@@ -1276,6 +1316,10 @@ declare const RECONNECT_CONFIG: {
1276
1316
  readonly maxAttempts: 3;
1277
1317
  readonly delayMs: 1000;
1278
1318
  };
1319
+ declare const DATA_CHANNEL_TIMEOUT_RESTARTS: {
1320
+ readonly hidden: 3;
1321
+ readonly visible: 10;
1322
+ };
1279
1323
  declare const UnrealStatusMessage: {
1280
1324
  readonly CONNECTING_TO_SESSION: "Connecting to session.";
1281
1325
  readonly STARTING_YOUR_SESSION: "Starting your session";
@@ -2047,9 +2091,12 @@ declare class StreamStatusTelemetryService2 {
2047
2091
  * phaseNo (derived from the catalog index), id, color, milestones,
2048
2092
  * params, overlays. No display text on the wire: the viewer's
2049
2093
  * vocabulary maps every id back to a human label, and boundary labels
2050
- * are derived from neighbor phases.
2094
+ * are derived from neighbor phases. `incomplete` marks the phase the
2095
+ * session ended in, sent from `endSession` instead of from its closer.
2051
2096
  */
2052
2097
  private emitPhaseEnded;
2098
+ /** Move the open phase past `bucketIdx` — phases close in catalog order. */
2099
+ private closePhase;
2053
2100
  /**
2054
2101
  * Emit the region / signaling / webrtc phases for an ADOPTED connection.
2055
2102
  *
@@ -2168,6 +2215,9 @@ declare class VideoService extends SubService {
2168
2215
  private container;
2169
2216
  private latencyTestTimings;
2170
2217
  private videoTrack$;
2218
+ /** Bumped per attached peer connection: candidate-pair ids are only unique
2219
+ * inside one connection, so the epoch scopes the telemetry route ref. */
2220
+ private pcEpoch;
2171
2221
  private VideoEncoderQP;
2172
2222
  private aggregatedStats;
2173
2223
  /**
@@ -2218,9 +2268,10 @@ declare class VideoService extends SubService {
2218
2268
  */
2219
2269
  private applyInboundVideoReport;
2220
2270
  /**
2221
- * Resolves the transport's selected candidate pair into the local/remote
2222
- * descriptors shown in the stats overlay. Silently skips when the pair (or
2223
- * either of its candidates) is missing from this report.
2271
+ * Resolves the selected candidate pair into its route description, byte
2272
+ * counters and RTT. Anything missing from this report stays unknown, and a
2273
+ * malformed report never throws into the stats loop — the route is optional,
2274
+ * playback is not.
2224
2275
  */
2225
2276
  private applySelectedPair;
2226
2277
  /** Per-session values that do not come from a single report. */
@@ -2335,6 +2386,7 @@ declare class WebRtcPlayerService extends SubService {
2335
2386
  */
2336
2387
  releaseRemoteConnections(reason: DisconnectReasonType): void;
2337
2388
  canSend(): boolean | null;
2389
+ describeConnectionState(): string;
2338
2390
  send(data: ArrayBuffer): void;
2339
2391
  /**
2340
2392
  * Attempts to reconnect the peer when send fails due to DataChannel not being open.
@@ -3390,7 +3442,16 @@ declare class UnrealEffects {
3390
3442
  forceViewportNotReady$: Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3391
3443
  resetCirrusOnDestroy$: Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3392
3444
  destroyRemoteConnections$: Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3393
- destroyConnectionAndRestart$: Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3445
+ /**
3446
+ * Restarts signalling after a DataChannelTimeout, a limited number of times.
3447
+ *
3448
+ * The counter is the index inside one restart window. A window opens on load,
3449
+ * on a successful data channel, on the user's `startStream` and on a scene
3450
+ * destroy, so only consecutive failures count. Once the limit for the current
3451
+ * tab visibility is reached, `establishingConnection` is cleared and the
3452
+ * resume popup shows.
3453
+ */
3454
+ restartAfterDataChannelTimeout$: Observable<_ngrx_store.Action<string>> & _ngrx_effects.CreateEffectMetadata;
3394
3455
  showUnrealError$: Observable<{
3395
3456
  code: number | null;
3396
3457
  error?: string;
@@ -3789,5 +3850,5 @@ declare class Semaphore {
3789
3850
 
3790
3851
  declare const tapLog: <T>(text: string, ...args: unknown[]) => ((source: Observable<T>) => Observable<T>);
3791
3852
 
3792
- export { AFKService, ALL_KEYBOARD_KEYS, AUTO_HIGH_RESOLUTION_IDLE_MS, AfkTimeoutModalComponent, AggregatorService, AnalyticsService, AnswerHandler, COLOR_CODES, 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, Falsy, FileHandlerService, FileReceiverService, FpsMonitorService, FreezeFrameComponent, FreezeFrameService, HEXtoRGB, HSVtoRGB, IME_PROCESS_KEY, INNER_RETRY_LIMIT, INSTANCE_READY_TIMEOUT, IceCandidateHandler, ImageLoadingSrcComponent, InputOptions, InputService, InstanceReadyHandler, InstanceReservedHandler, IntroSrcComponent, LatencyTimings, LoadingProgressService, Logger, MINIMAL_FPS, MODIFIER_KEY_CODES, 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, RGBtoHEX, RGBtoHSV, RegionsPingService, SAME_SIZE_THRESHOLD, SCREEN_LOCKER_CONTAINER_ID, SIGNALLING_PERCENT_VALUE, SSInfoHandler, STREAMING_AUDIO_ID, STREAMING_VIDEO_ID, STREAM_RESOLUTION_LIMITS, SafePipe, Semaphore, SignallingService, StatGraphComponent, StreamAdoptionService, StreamStatusTelemetryService, StreamStatusTelemetryService2, SubService, ToClientMessage, Truthy, UnrealAfkSlotDirective, UnrealCallbackService, UnrealCommunicatorService, UnrealEffects, UnrealKeyCode, UnrealResumeSlotDirective, UnrealSceneComponent, UnrealStatusMessage, UnrealStatusSlotDirective, 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, clampStreamResolution, clampf, commandCompleted, commandStarted, dataChannelConnected, dataChannelReady, decodeData, destroyRemoteConnections, destroyUnrealScene, disconnectStream, dispatchResize, dropConnection, dropDC, dropPC, fitIntoRectangle, floatToPercents, floatToSmoothPercents, forceResizeViewport, fpIsASameAsB, fromResizeObserver, generateUuid, getActiveUrl, getCanvasCached, getImageFromVideoStream, getResizeStudioValues, getResizeValuesUniversal, getRtcErrorMessage, getSnapshot, iceConnectionFailed, initSignalling, instanceReady, inverseLerp, isAppOwned, isMetaboxMode, keepMaxUntilReset, lerp, makeEven, pollingEnded, pollingStarted, provideUnrealModule, provideUnrealState, qpToQuality, reconnectPeer, reconnectPeerFailed, reconnectPeerSuccess, regionPingFetchEnd, regionPingFetchStart, regionResolved, resetAfk, resetConfig, resetDataChannelForReconnect, resetIntroSrc, resetUserInactivityTimeout, resetWarnTimeout, resolveSkin, 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, startStream, streamAdopted, tapLog, trackMixpanelEvent, trackTelemetryData, uint8ToBase64, unrealCommandCallback, unrealFeature, unrealReducer, updateCirrusInfo, videoAdaptedToContainer, videoStreamInitialized };
3793
- export type { AggregatedStat, AnySignalingMessage, AppOwnedStream, Area, AwsInstance, BootstrapInfo, CandidateMessage, CirrusRequestKind, CloseReason, CommandInProgress, ConfigMessage, ConnectionError, ControlSchemeValues, Coords, DisconnectReasonType, EmittedMilestone, EventId, FpsLowData, FreezeFrameMessage, IKeyCode, IKeyCodeName, IKeyName, ImageOutputValues, InboundVideoStats, InputProps, InstanceReady, InstanceReserved, InterruptClientStream, ListStreamersMessage, MessageBase, MessageTypeValues, OrchestrationErrorMessage, OrchestrationMessageType, P2PEstablishedMessage, ParkedStream, PhaseEndedData, PhaseOverlay, PhaseParam, PlayerCountMessage, PollingOrchestrationMessage, Quality, QualityAnomalyData, ReceivedFile, Rect, RequestStream, ResourceBucket, ResourceTotals, SSInfo, SampleData, SelectedIceCandidatePair, SessionEndReason, SessionEndedData, SessionStartedData, SignalingData, SignalingMessageHandler, SignalingMessageMap, SignalingRetryData, SignalingRetryKind, Size, SlowResource, StreamConfig, StreamRequestContext, StreamResolutionProps, StreamTelemetryEvent, StreamTelemetryEventMap, StreamTelemetryEventName, StreamTelemetryLifecycleData, StreamTelemetryLifecycleEventName, StreamTelemetryTrackData, StreamerListMessage, TelemetryEventEnvelope, TelemetryLifecycleEnvelope, TelemetryType, UnknownFields, UnrealAfkSlotContext, UnrealCallbackDescriptor, UnrealCallbackEventMap, UnrealCallbackJson, UnrealCallbackJsonWrapped, UnrealResumeSlotContext, UnrealSlotTemplateContext, UnrealState, UnrealStatusSlotContext, UnrealUiClasses, UnrealUiPart, WSCloseCodesValues, WindowAggregate };
3853
+ export { AFKService, ALL_KEYBOARD_KEYS, AUTO_HIGH_RESOLUTION_IDLE_MS, AfkTimeoutModalComponent, AggregatorService, AnalyticsService, AnswerHandler, COLOR_CODES, CommandTelemetryService, ConfigHandler, ConsoleExtensionsService, ControlScheme, DATA_CHANNEL_CONNECTION_TIMEOUT, DATA_CHANNEL_TIMEOUT_RESTARTS, DEBOUNCE_TO_MANY_RESIZE_CALLS, DEFAULT_AFK_TIMEOUT, DEFAULT_AFK_TIMEOUT_PERIOD, DESTROY_DISCONNECT_REASONS, DevModeService, DisconnectReason, FULL_HD_HEIGHT, FULL_HD_WIDTH, Falsy, FileHandlerService, FileReceiverService, FpsMonitorService, FreezeFrameComponent, FreezeFrameService, HEXtoRGB, HSVtoRGB, IME_PROCESS_KEY, INNER_RETRY_LIMIT, INSTANCE_READY_TIMEOUT, IceCandidateHandler, ImageLoadingSrcComponent, InputOptions, InputService, InstanceReadyHandler, InstanceReservedHandler, IntroSrcComponent, LatencyTimings, LoadingProgressService, Logger, MINIMAL_FPS, MODIFIER_KEY_CODES, 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, RGBtoHEX, RGBtoHSV, RegionsPingService, SAME_SIZE_THRESHOLD, SCREEN_LOCKER_CONTAINER_ID, SIGNALLING_PERCENT_VALUE, SSInfoHandler, STREAMING_AUDIO_ID, STREAMING_VIDEO_ID, STREAM_RESOLUTION_LIMITS, SafePipe, Semaphore, SignallingService, StatGraphComponent, StreamAdoptionService, StreamStatusTelemetryService, StreamStatusTelemetryService2, SubService, ToClientMessage, Truthy, UnrealAfkSlotDirective, UnrealCallbackService, UnrealCommunicatorService, UnrealEffects, UnrealKeyCode, UnrealResumeSlotDirective, UnrealSceneComponent, UnrealStatusMessage, UnrealStatusSlotDirective, 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, clampStreamResolution, clampf, commandCompleted, commandStarted, dataChannelConnected, dataChannelReady, decodeData, destroyRemoteConnections, destroyUnrealScene, disconnectStream, dispatchResize, dropConnection, dropDC, dropPC, fitIntoRectangle, floatToPercents, floatToSmoothPercents, forceResizeViewport, fpIsASameAsB, fromResizeObserver, generateUuid, getActiveUrl, getCanvasCached, getImageFromVideoStream, getResizeStudioValues, getResizeValuesUniversal, getRtcErrorMessage, getSnapshot, iceConnectionFailed, initSignalling, instanceReady, inverseLerp, isAppOwned, isMetaboxMode, keepMaxUntilReset, lerp, makeEven, pollingEnded, pollingStarted, provideUnrealModule, provideUnrealState, qpToQuality, reconnectPeer, reconnectPeerFailed, reconnectPeerSuccess, regionPingFetchEnd, regionPingFetchStart, regionResolved, resetAfk, resetConfig, resetDataChannelForReconnect, resetIntroSrc, resetUserInactivityTimeout, resetWarnTimeout, resolveSkin, 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, startStream, streamAdopted, tapLog, trackMixpanelEvent, trackTelemetryData, uint8ToBase64, unrealCommandCallback, unrealFeature, unrealReducer, updateCirrusInfo, videoAdaptedToContainer, videoStreamInitialized };
3854
+ export type { AggregatedStat, AnySignalingMessage, AppOwnedStream, Area, AwsInstance, BootstrapInfo, CandidateMessage, CirrusRequestKind, CloseReason, CommandInProgress, ConfigMessage, ConnectionError, ControlSchemeValues, Coords, DisconnectReasonType, EmittedMilestone, EventId, FpsLowData, FreezeFrameMessage, IKeyCode, IKeyCodeName, IKeyName, IceCandidateInfo, IceRoute, ImageOutputValues, InboundVideoStats, InputProps, InstanceReady, InstanceReserved, InterruptClientStream, ListStreamersMessage, MessageBase, MessageTypeValues, OrchestrationErrorMessage, OrchestrationMessageType, P2PEstablishedMessage, ParkedStream, PhaseEndedData, PhaseOverlay, PhaseParam, PlayerCountMessage, PollingOrchestrationMessage, Quality, QualityAnomalyData, ReceivedFile, Rect, RequestStream, ResourceBucket, ResourceTotals, RouteSegment, SSInfo, SampleData, SelectedIceCandidatePair, SessionEndReason, SessionEndedData, SessionStartedData, SignalingData, SignalingMessageHandler, SignalingMessageMap, SignalingRetryData, SignalingRetryKind, Size, SlowResource, StreamConfig, StreamRequestContext, StreamResolutionProps, StreamTelemetryEvent, StreamTelemetryEventMap, StreamTelemetryEventName, StreamTelemetryLifecycleData, StreamTelemetryLifecycleEventName, StreamTelemetryTrackData, StreamerListMessage, TelemetryEventEnvelope, TelemetryLifecycleEnvelope, TelemetryType, UnknownFields, UnrealAfkSlotContext, UnrealCallbackDescriptor, UnrealCallbackEventMap, UnrealCallbackJson, UnrealCallbackJsonWrapped, UnrealResumeSlotContext, UnrealSlotTemplateContext, UnrealState, UnrealStatusSlotContext, UnrealUiClasses, UnrealUiPart, WSCloseCodesValues, WindowAggregate };