@3dsource/angular-unreal-module 0.0.199 → 0.0.200-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
CHANGED
|
File without changes
|
|
@@ -3,7 +3,7 @@ import { ChangeDetectionStrategy, Component, DestroyRef, Directive, ElementRef,
|
|
|
3
3
|
import { JsonPipe, NgOptimizedImage, NgTemplateOutlet } from "@angular/common";
|
|
4
4
|
import { Store, createAction, createFeature, createReducer, createSelector, on, props, provideState } from "@ngrx/store";
|
|
5
5
|
import { Actions, createEffect, ofType, provideEffects } from "@ngrx/effects";
|
|
6
|
-
import { BehaviorSubject, EMPTY, NEVER, Observable, Subject, Subscription, animationFrameScheduler, asyncScheduler, bufferTime, combineLatestWith, concat, concatMap, debounceTime, defer, delay, filter, firstValueFrom, from, fromEvent, ignoreElements, interval, map, merge, mergeMap, of, pairwise, repeat, retry, scan, share, shareReplay, skip, startWith, switchMap, take, takeUntil, takeWhile, tap, throttleTime, throwError, timeout, timer, timestamp, withLatestFrom } from "rxjs";
|
|
6
|
+
import { BehaviorSubject, EMPTY, NEVER, Observable, Subject, Subscription, TimeoutError, animationFrameScheduler, asyncScheduler, bufferTime, combineLatestWith, concat, concatMap, debounceTime, defer, delay, filter, firstValueFrom, from, fromEvent, ignoreElements, interval, map, merge, mergeMap, of, pairwise, repeat, retry, scan, share, shareReplay, skip, startWith, switchMap, take, takeUntil, takeWhile, tap, throttleTime, throwError, timeout, timer, timestamp, withLatestFrom } from "rxjs";
|
|
7
7
|
import { UNREAL_CONFIG } from "@3dsource/angular-unreal-module/config";
|
|
8
8
|
import { catchError, debounceTime as debounceTime$1, distinctUntilChanged, exhaustMap, filter as filter$1, finalize, first, map as map$1, startWith as startWith$1, switchMap as switchMap$1, take as take$1, takeUntil as takeUntil$1, takeWhile as takeWhile$1, tap as tap$1, timeout as timeout$1, withLatestFrom as withLatestFrom$1 } from "rxjs/operators";
|
|
9
9
|
import { v4 } from "uuid";
|
|
@@ -1804,6 +1804,7 @@ const ORCHESTRATION_ERROR_CODES = {
|
|
|
1804
1804
|
};
|
|
1805
1805
|
const RETRY_CODES = /* @__PURE__ */ new Set([ORCHESTRATION_ERROR_CODES.NO_AVAILABLE_INSTANCES.code, ORCHESTRATION_ERROR_CODES.LIMIT_REACHED.code]);
|
|
1806
1806
|
function OrchestrationErrorHandler(msg) {
|
|
1807
|
+
this.onOrchestrationError$.next(msg.payload);
|
|
1807
1808
|
if (RETRY_CODES.has(msg.payload.code)) {
|
|
1808
1809
|
const errorInfo = Object.values(ORCHESTRATION_ERROR_CODES).find(({ code }) => code === msg.payload.code);
|
|
1809
1810
|
this.store.dispatch(setOrchestrationMessage({ message: errorInfo?.description }));
|
|
@@ -1831,6 +1832,10 @@ var SignallingService = class SignallingService extends SubService {
|
|
|
1831
1832
|
this.onWebRtcIce$ = new Subject();
|
|
1832
1833
|
this.onWebRtcAnswer$ = new Subject();
|
|
1833
1834
|
this.onInstanceReady$ = new Subject();
|
|
1835
|
+
this.onRequestStreamSent$ = new Subject();
|
|
1836
|
+
this.onOrchestrationError$ = new Subject();
|
|
1837
|
+
this.onCirrusClose$ = new Subject();
|
|
1838
|
+
this.onPollResponse$ = new Subject();
|
|
1834
1839
|
this.abort$ = this.actions$.pipe(ofType(abortEstablishingConnection));
|
|
1835
1840
|
this.ws = null;
|
|
1836
1841
|
this.controlWs = null;
|
|
@@ -1978,8 +1983,13 @@ var SignallingService = class SignallingService extends SubService {
|
|
|
1978
1983
|
}));
|
|
1979
1984
|
}
|
|
1980
1985
|
pollLoop(url) {
|
|
1981
|
-
|
|
1986
|
+
let sentAt = 0;
|
|
1987
|
+
return defer(() => {
|
|
1988
|
+
sentAt = performance.now();
|
|
1989
|
+
return this.httpClient.get(url);
|
|
1990
|
+
}).pipe(timeout(POLLING_TIME), tap$1((data) => this.onPollResponse$.next(pollResponse(200, data, sentAt))), catchError((err) => {
|
|
1982
1991
|
const status = err?.status;
|
|
1992
|
+
this.onPollResponse$.next(pollResponse(typeof status === "number" && status > 0 ? status : err instanceof TimeoutError ? "timeout" : "network", null, sentAt));
|
|
1983
1993
|
if (typeof status === "number" && status >= 400 && status < 500 && status !== 429) {
|
|
1984
1994
|
Logger.warn(`Polling HARD error on ${url} (HTTP ${status}); rotating URL`);
|
|
1985
1995
|
return throwError(() => err);
|
|
@@ -2122,6 +2132,7 @@ var SignallingService = class SignallingService extends SubService {
|
|
|
2122
2132
|
context
|
|
2123
2133
|
}
|
|
2124
2134
|
});
|
|
2135
|
+
this.onRequestStreamSent$.next(this.correlationId);
|
|
2125
2136
|
}
|
|
2126
2137
|
isConnected() {
|
|
2127
2138
|
return !!(this.ws && this.ws.readyState === 1);
|
|
@@ -2161,6 +2172,15 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
2161
2172
|
}],
|
|
2162
2173
|
ctorParameters: () => []
|
|
2163
2174
|
});
|
|
2175
|
+
function pollResponse(status, data, sentAt) {
|
|
2176
|
+
return {
|
|
2177
|
+
status,
|
|
2178
|
+
ms: Math.round(performance.now() - sentAt),
|
|
2179
|
+
ready: !!data?.signallingServer,
|
|
2180
|
+
percent: data?.info?.percent ?? null,
|
|
2181
|
+
message: data?.mm_message || data?.error || null
|
|
2182
|
+
};
|
|
2183
|
+
}
|
|
2164
2184
|
function finite(value) {
|
|
2165
2185
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
2166
2186
|
}
|
|
@@ -2908,6 +2928,13 @@ var StreamAdoptionService = class StreamAdoptionService {
|
|
|
2908
2928
|
this.store = inject(Store);
|
|
2909
2929
|
this.signalling = inject(SignallingService);
|
|
2910
2930
|
this.webRtc = inject(WebRtcPlayerService);
|
|
2931
|
+
this.report$ = new Subject();
|
|
2932
|
+
this.waitStarted$ = new Subject();
|
|
2933
|
+
this.waiting = null;
|
|
2934
|
+
}
|
|
2935
|
+
waitingReport() {
|
|
2936
|
+
const w = this.waiting;
|
|
2937
|
+
return w ? reportOf(w.parked, "waiting", w.sincePerf) : null;
|
|
2911
2938
|
}
|
|
2912
2939
|
awaitAndAdopt$() {
|
|
2913
2940
|
return defer(() => {
|
|
@@ -2917,32 +2944,47 @@ var StreamAdoptionService = class StreamAdoptionService {
|
|
|
2917
2944
|
return of(false);
|
|
2918
2945
|
}
|
|
2919
2946
|
if (isAppOwned(slot)) return of(false);
|
|
2920
|
-
if (slot.state !== "connecting") return of(this.
|
|
2947
|
+
if (slot.state !== "connecting") return of(this.settle(slot, null));
|
|
2921
2948
|
Logger.info("[Adoption] Prefetch in progress — waiting before connecting");
|
|
2949
|
+
this.waitStarted$.next();
|
|
2922
2950
|
return this.awaitSettled$(slot);
|
|
2923
2951
|
});
|
|
2924
2952
|
}
|
|
2925
2953
|
awaitSettled$(parked) {
|
|
2926
2954
|
return new Observable((subscriber) => {
|
|
2927
2955
|
let done = false;
|
|
2956
|
+
const sincePerf = performance.now();
|
|
2957
|
+
this.waiting = {
|
|
2958
|
+
parked,
|
|
2959
|
+
sincePerf
|
|
2960
|
+
};
|
|
2928
2961
|
parked.onSettled(() => {
|
|
2929
2962
|
if (done) return;
|
|
2930
2963
|
done = true;
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
adopted = this.tryAdoptOrTakeSlot();
|
|
2934
|
-
} catch (e) {
|
|
2935
|
-
Logger.error("[Adoption] Adoption threw — falling back", e);
|
|
2936
|
-
this.takeSlot();
|
|
2937
|
-
}
|
|
2938
|
-
subscriber.next(adopted);
|
|
2964
|
+
this.waiting = null;
|
|
2965
|
+
subscriber.next(this.settle(parked, sincePerf));
|
|
2939
2966
|
subscriber.complete();
|
|
2940
2967
|
});
|
|
2941
2968
|
return () => {
|
|
2969
|
+
if (done) return;
|
|
2942
2970
|
done = true;
|
|
2971
|
+
this.waiting = null;
|
|
2972
|
+
this.report$.next(reportOf(parked, "abandoned", sincePerf));
|
|
2943
2973
|
};
|
|
2944
2974
|
});
|
|
2945
2975
|
}
|
|
2976
|
+
settle(parked, sincePerf) {
|
|
2977
|
+
let adopted = false;
|
|
2978
|
+
try {
|
|
2979
|
+
adopted = this.tryAdoptOrTakeSlot();
|
|
2980
|
+
} catch (e) {
|
|
2981
|
+
Logger.error("[Adoption] Adoption threw — falling back", e);
|
|
2982
|
+
this.takeSlot();
|
|
2983
|
+
}
|
|
2984
|
+
const outcome = adopted ? "adopted" : parked.state === "failed" ? "failed" : parked.state === "ready" ? "dead" : null;
|
|
2985
|
+
if (outcome) this.report$.next(reportOf(parked, outcome, sincePerf));
|
|
2986
|
+
return adopted;
|
|
2987
|
+
}
|
|
2946
2988
|
tryAdoptOrTakeSlot() {
|
|
2947
2989
|
const adopted = this.tryAdopt();
|
|
2948
2990
|
if (!adopted) this.takeSlot();
|
|
@@ -2969,7 +3011,7 @@ var StreamAdoptionService = class StreamAdoptionService {
|
|
|
2969
3011
|
if (!slot || isAppOwned(slot)) return false;
|
|
2970
3012
|
const parked = slot;
|
|
2971
3013
|
if (parked.state !== "ready") return false;
|
|
2972
|
-
if (!parked.ws || parked.ws.readyState !== 1 || !parked.pc || !parked.dc || !parked.stream) {
|
|
3014
|
+
if (parked.deadReason || !parked.ws || parked.ws.readyState !== 1 || !parked.pc || DEAD_PC_STATES.has(parked.pc.connectionState) || !parked.dc || DEAD_DC_STATES.has(parked.dc.readyState) || !parked.stream) {
|
|
2973
3015
|
Logger.warn("[Adoption] Parked stream is ready but transport is not live");
|
|
2974
3016
|
return false;
|
|
2975
3017
|
}
|
|
@@ -2980,6 +3022,7 @@ var StreamAdoptionService = class StreamAdoptionService {
|
|
|
2980
3022
|
pollingUrl: parked.pollingUrl ?? null,
|
|
2981
3023
|
ssData: parked.ssData ?? null,
|
|
2982
3024
|
streamRequestId: parked.ids?.streamRequestId || null,
|
|
3025
|
+
correlationId: parked.ids?.correlationId || null,
|
|
2983
3026
|
kind: parked.kind ?? null,
|
|
2984
3027
|
instanceName: parked.instanceName ?? null,
|
|
2985
3028
|
eta: parked.eta ?? null,
|
|
@@ -3020,6 +3063,20 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
3020
3063
|
args: [{ providedIn: "root" }]
|
|
3021
3064
|
}]
|
|
3022
3065
|
});
|
|
3066
|
+
const DEAD_PC_STATES = /* @__PURE__ */ new Set(["failed", "closed"]);
|
|
3067
|
+
const DEAD_DC_STATES = /* @__PURE__ */ new Set(["closing", "closed"]);
|
|
3068
|
+
function reportOf(parked, outcome, sincePerf) {
|
|
3069
|
+
return {
|
|
3070
|
+
outcome,
|
|
3071
|
+
failReason: outcome === "dead" ? parked.deadReason ?? "transport-not-live" : parked.failReason ?? null,
|
|
3072
|
+
failError: parked.failError ?? null,
|
|
3073
|
+
waitMs: sincePerf === null ? null : Math.round(performance.now() - sincePerf),
|
|
3074
|
+
kind: parked.kind ?? null,
|
|
3075
|
+
instanceName: parked.instanceName ?? null,
|
|
3076
|
+
streamRequestId: parked.ids?.streamRequestId || null,
|
|
3077
|
+
trail: [...parked.trail ?? []]
|
|
3078
|
+
};
|
|
3079
|
+
}
|
|
3023
3080
|
var UnrealCallbackService = class UnrealCallbackService {
|
|
3024
3081
|
constructor() {
|
|
3025
3082
|
this.actions$ = inject(Actions);
|
|
@@ -3542,6 +3599,10 @@ const dropCodes = [
|
|
|
3542
3599
|
function OnCloseHandler(e) {
|
|
3543
3600
|
const message = `WebSocket closed: ${JSON.stringify(e.code)} - ${e.reason}`;
|
|
3544
3601
|
Logger.warn(message);
|
|
3602
|
+
this.onCirrusClose$.next({
|
|
3603
|
+
code: e.code,
|
|
3604
|
+
reason: e.reason
|
|
3605
|
+
});
|
|
3545
3606
|
this.store.dispatch(setCirrusDisconnected());
|
|
3546
3607
|
if (dropCodes.includes(e.code)) this.store.dispatch(dropConnection());
|
|
3547
3608
|
}
|
|
@@ -5155,6 +5216,7 @@ var StreamStatusTelemetryService2 = class StreamStatusTelemetryService2 {
|
|
|
5155
5216
|
this.videoService = inject(VideoService);
|
|
5156
5217
|
this.signallingService = inject(SignallingService);
|
|
5157
5218
|
this.webRtcPlayer = inject(WebRtcPlayerService);
|
|
5219
|
+
this.adoption = inject(StreamAdoptionService);
|
|
5158
5220
|
this.unrealConfig = inject(UNREAL_CONFIG, { optional: true });
|
|
5159
5221
|
this.destroyRef = inject(DestroyRef);
|
|
5160
5222
|
this.destroy$ = new Subject();
|
|
@@ -5203,6 +5265,10 @@ var StreamStatusTelemetryService2 = class StreamStatusTelemetryService2 {
|
|
|
5203
5265
|
id: "region-resolving",
|
|
5204
5266
|
color: "#61afef",
|
|
5205
5267
|
milestones: [
|
|
5268
|
+
{
|
|
5269
|
+
id: "prefetch-wait-start",
|
|
5270
|
+
event: this.adoption.waitStarted$
|
|
5271
|
+
},
|
|
5206
5272
|
{
|
|
5207
5273
|
id: "region-ping-fetch-start",
|
|
5208
5274
|
event: this.actions$.pipe(ofType(regionPingFetchStart))
|
|
@@ -5235,6 +5301,10 @@ var StreamStatusTelemetryService2 = class StreamStatusTelemetryService2 {
|
|
|
5235
5301
|
id: "polling-ended",
|
|
5236
5302
|
event: this.actions$.pipe(ofType(pollingEnded))
|
|
5237
5303
|
},
|
|
5304
|
+
{
|
|
5305
|
+
id: "request-stream-sent",
|
|
5306
|
+
event: this.signallingService.onRequestStreamSent$
|
|
5307
|
+
},
|
|
5238
5308
|
this.awsInstanceResolvedEntry,
|
|
5239
5309
|
this.signalingServerConnectedEntry,
|
|
5240
5310
|
{
|
|
@@ -5248,12 +5318,7 @@ var StreamStatusTelemetryService2 = class StreamStatusTelemetryService2 {
|
|
|
5248
5318
|
this.configReceivedEntry,
|
|
5249
5319
|
{
|
|
5250
5320
|
id: "ssinfo-received",
|
|
5251
|
-
event: this.store.select(unrealFeature.selectSsData).pipe(filter(Boolean), take(1),
|
|
5252
|
-
client: aws.wsUrl,
|
|
5253
|
-
instanceName: aws.instanceName,
|
|
5254
|
-
...ssData,
|
|
5255
|
-
connectionId
|
|
5256
|
-
})))
|
|
5321
|
+
event: this.store.select(unrealFeature.selectSsData).pipe(filter(Boolean), take(1), map(() => this.signalingParams()))
|
|
5257
5322
|
}
|
|
5258
5323
|
]
|
|
5259
5324
|
},
|
|
@@ -5396,12 +5461,48 @@ var StreamStatusTelemetryService2 = class StreamStatusTelemetryService2 {
|
|
|
5396
5461
|
handshakeFlow: null,
|
|
5397
5462
|
commandCount: 0,
|
|
5398
5463
|
times,
|
|
5399
|
-
openPhaseIdx: 0
|
|
5464
|
+
openPhaseIdx: 0,
|
|
5465
|
+
connectCorrelationId: null,
|
|
5466
|
+
orchestrationError: null,
|
|
5467
|
+
iceServers: null,
|
|
5468
|
+
cirrusClose: null,
|
|
5469
|
+
aws: null,
|
|
5470
|
+
prefetchReported: false,
|
|
5471
|
+
polls: {
|
|
5472
|
+
count: 0,
|
|
5473
|
+
errors: 0,
|
|
5474
|
+
last: null
|
|
5475
|
+
}
|
|
5400
5476
|
};
|
|
5401
5477
|
sub.add(this.store.select(selectCirrusConnectionId).pipe(filter(Boolean), take(1)).subscribe((connectionId) => this.resolveWireId(connectionId)));
|
|
5402
5478
|
sub.add(this.signallingService.onWebRtcIce$.pipe(filter(Boolean)).subscribe(() => {
|
|
5403
5479
|
if (this.session) this.session.iceCandidateCount++;
|
|
5404
5480
|
}));
|
|
5481
|
+
sub.add(this.signallingService.onRequestStreamSent$.subscribe((id) => {
|
|
5482
|
+
if (!this.session) return;
|
|
5483
|
+
this.session.connectCorrelationId = id;
|
|
5484
|
+
this.session.aws = null;
|
|
5485
|
+
}));
|
|
5486
|
+
sub.add(this.signallingService.onOrchestrationError$.subscribe((e) => {
|
|
5487
|
+
if (this.session) this.session.orchestrationError = `${e?.code}: ${e?.message ?? ""}`;
|
|
5488
|
+
}));
|
|
5489
|
+
sub.add(this.signallingService.onConfig$.pipe(take(1)).subscribe((msg) => {
|
|
5490
|
+
if (this.session) this.session.iceServers = iceServerHosts(msg?.peerConnectionOptions?.iceServers);
|
|
5491
|
+
}));
|
|
5492
|
+
sub.add(this.actions$.pipe(ofType(setAwsInstance)).subscribe(() => {
|
|
5493
|
+
if (this.session) this.session.aws = this.awsInstance$();
|
|
5494
|
+
}));
|
|
5495
|
+
sub.add(this.signallingService.onCirrusClose$.subscribe((close) => {
|
|
5496
|
+
if (this.session) this.session.cirrusClose = close;
|
|
5497
|
+
}));
|
|
5498
|
+
sub.add(this.signallingService.onPollResponse$.subscribe((poll) => {
|
|
5499
|
+
const polls = this.session?.polls;
|
|
5500
|
+
if (!polls) return;
|
|
5501
|
+
polls.count++;
|
|
5502
|
+
if (poll.status !== 200) polls.errors++;
|
|
5503
|
+
polls.last = poll;
|
|
5504
|
+
}));
|
|
5505
|
+
sub.add(this.adoption.report$.subscribe((report) => this.trackPrefetch(report)));
|
|
5405
5506
|
sub.add(this.actions$.pipe(ofType(answerSent), take(1)).subscribe(() => {
|
|
5406
5507
|
if (this.session) this.session.handshakeFlow = "server-offer";
|
|
5407
5508
|
}));
|
|
@@ -5447,7 +5548,10 @@ var StreamStatusTelemetryService2 = class StreamStatusTelemetryService2 {
|
|
|
5447
5548
|
}));
|
|
5448
5549
|
});
|
|
5449
5550
|
});
|
|
5450
|
-
sub.add(this.actions$.pipe(ofType(streamAdopted)).subscribe(({ timings, region }) =>
|
|
5551
|
+
sub.add(this.actions$.pipe(ofType(streamAdopted)).subscribe(({ timings, region, correlationId }) => {
|
|
5552
|
+
if (this.session && correlationId) this.session.connectCorrelationId = correlationId;
|
|
5553
|
+
this.emitAdoptedConnection(timings, region);
|
|
5554
|
+
}));
|
|
5451
5555
|
const bootstrapInfo = this.collectBootstrapInfo();
|
|
5452
5556
|
const embedderUrl = this.collectEmbedderUrl();
|
|
5453
5557
|
this.emitLifecycle("stream.session_started", {
|
|
@@ -5475,14 +5579,19 @@ var StreamStatusTelemetryService2 = class StreamStatusTelemetryService2 {
|
|
|
5475
5579
|
const errorMessage = this.errorMessage$();
|
|
5476
5580
|
const granularMessage = errorMessage?.reason === granularReason ? errorMessage.message : void 0;
|
|
5477
5581
|
const includeGranular = granularReason && granularReason !== DisconnectReason.None;
|
|
5582
|
+
const waiting = this.adoption.waitingReport();
|
|
5583
|
+
if (waiting) this.trackPrefetch(waiting);
|
|
5478
5584
|
const openPhase = this.phaseCatalog[session.openPhaseIdx];
|
|
5479
|
-
if (openPhase) this.emitPhaseEnded(openPhase, session.openPhaseIdx, null, true);
|
|
5585
|
+
if (openPhase) this.emitPhaseEnded(openPhase, session.openPhaseIdx, openPhase.id === "signaling-connection" ? this.signalingParams() : null, true);
|
|
5480
5586
|
this.flushPaks(true);
|
|
5587
|
+
const close = session.cirrusClose;
|
|
5481
5588
|
this.emitLifecycle("stream.session_ended", {
|
|
5482
5589
|
sessionId: id,
|
|
5483
5590
|
reason,
|
|
5484
5591
|
...includeGranular ? { disconnectReason: granularReason } : {},
|
|
5485
5592
|
...includeGranular && granularMessage ? { disconnectMessage: granularMessage } : {},
|
|
5593
|
+
...close && { closeCode: close.code },
|
|
5594
|
+
...close?.reason && { closeReason: close.reason },
|
|
5486
5595
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
5487
5596
|
});
|
|
5488
5597
|
this.flushOutbox(session, id);
|
|
@@ -5561,7 +5670,7 @@ var StreamStatusTelemetryService2 = class StreamStatusTelemetryService2 {
|
|
|
5561
5670
|
const region = parkedRegion ?? NO_REGION;
|
|
5562
5671
|
this.emitAdoptedPhase(0, startMs, 0, adoptionAtMs, regionParams(region));
|
|
5563
5672
|
this.emitAdoptedPhase(1, startMs, sigDur, adoptionAtMs, {
|
|
5564
|
-
...this.
|
|
5673
|
+
...this.signalingParams(),
|
|
5565
5674
|
...savings,
|
|
5566
5675
|
prefetchSignalingMs: sigDur
|
|
5567
5676
|
}, [{
|
|
@@ -5596,13 +5705,22 @@ var StreamStatusTelemetryService2 = class StreamStatusTelemetryService2 {
|
|
|
5596
5705
|
});
|
|
5597
5706
|
this.closePhase(bucketIdx);
|
|
5598
5707
|
}
|
|
5599
|
-
|
|
5600
|
-
const
|
|
5601
|
-
const
|
|
5708
|
+
signalingParams() {
|
|
5709
|
+
const s = this.session;
|
|
5710
|
+
const aws = s?.aws ?? this.awsInstance$();
|
|
5602
5711
|
return {
|
|
5603
5712
|
client: aws?.wsUrl ?? null,
|
|
5604
5713
|
instanceName: aws?.instanceName ?? null,
|
|
5605
|
-
|
|
5714
|
+
transport: aws ? aws.kind ?? "direct" : null,
|
|
5715
|
+
orchestrationUrl: aws?.kind === "socket" ? aws.pollingUrl : null,
|
|
5716
|
+
streamRequestId: aws?.streamRequestId ?? null,
|
|
5717
|
+
connectCorrelationId: s?.connectCorrelationId ?? null,
|
|
5718
|
+
orchestrationError: s?.orchestrationError ?? null,
|
|
5719
|
+
iceServers: s?.iceServers ?? null,
|
|
5720
|
+
orchPolls: s?.polls.count || null,
|
|
5721
|
+
orchPollErrors: s?.polls.errors || null,
|
|
5722
|
+
orchLastPoll: s?.polls.last ? pollText(s.polls.last) : null,
|
|
5723
|
+
...this.ssData$() ?? {},
|
|
5606
5724
|
connectionId: this.connectionId$()
|
|
5607
5725
|
};
|
|
5608
5726
|
}
|
|
@@ -5845,6 +5963,26 @@ var StreamStatusTelemetryService2 = class StreamStatusTelemetryService2 {
|
|
|
5845
5963
|
...session?.wireId ? { sessionId: session.wireId } : {}
|
|
5846
5964
|
});
|
|
5847
5965
|
}
|
|
5966
|
+
trackPrefetch(report) {
|
|
5967
|
+
const session = this.session;
|
|
5968
|
+
if (!session || session.prefetchReported) return;
|
|
5969
|
+
session.prefetchReported = true;
|
|
5970
|
+
this.track("stream.prefetch", {
|
|
5971
|
+
sessionId: session.id,
|
|
5972
|
+
outcome: report.outcome,
|
|
5973
|
+
...report.failReason && { failReason: report.failReason },
|
|
5974
|
+
...report.failError && { failError: report.failError },
|
|
5975
|
+
...report.waitMs !== null && { waitMs: report.waitMs },
|
|
5976
|
+
...report.kind && { kind: report.kind },
|
|
5977
|
+
...report.instanceName && { instanceName: report.instanceName },
|
|
5978
|
+
...report.streamRequestId && { streamRequestId: report.streamRequestId },
|
|
5979
|
+
trail: report.trail.map((entry) => ({
|
|
5980
|
+
...entry,
|
|
5981
|
+
t: Math.round(entry.t - session.anchorPerf)
|
|
5982
|
+
})),
|
|
5983
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
5984
|
+
});
|
|
5985
|
+
}
|
|
5848
5986
|
emit(event, data) {
|
|
5849
5987
|
this.store.dispatch(trackTelemetryData({
|
|
5850
5988
|
event,
|
|
@@ -5915,6 +6053,26 @@ function iceParams(ice) {
|
|
|
5915
6053
|
function fmtCounts(counts) {
|
|
5916
6054
|
return Object.entries(counts).map(([k, n]) => `${k} ${n}`).join(" · ") || null;
|
|
5917
6055
|
}
|
|
6056
|
+
function pollText(poll) {
|
|
6057
|
+
return [
|
|
6058
|
+
poll.status,
|
|
6059
|
+
poll.status === 200 ? poll.ready ? "ready" : "waiting" : null,
|
|
6060
|
+
poll.percent !== null ? `${poll.percent}%` : null,
|
|
6061
|
+
poll.message,
|
|
6062
|
+
`${poll.ms}ms`
|
|
6063
|
+
].filter((part) => part !== null && part !== "").join(" ");
|
|
6064
|
+
}
|
|
6065
|
+
function iceServerHosts(servers) {
|
|
6066
|
+
const hosts = /* @__PURE__ */ new Set();
|
|
6067
|
+
for (const server of servers ?? []) {
|
|
6068
|
+
const urls = Array.isArray(server.urls) ? server.urls : [server.urls];
|
|
6069
|
+
for (const url of urls) {
|
|
6070
|
+
const m = /^(stuns?|turns?):([^:?/]+)/i.exec(url ?? "");
|
|
6071
|
+
if (m) hosts.add(`${m[1].toLowerCase()}:${m[2].toLowerCase()}`);
|
|
6072
|
+
}
|
|
6073
|
+
}
|
|
6074
|
+
return hosts.size ? [...hosts].join(", ") : null;
|
|
6075
|
+
}
|
|
5918
6076
|
function toPhaseParams(value) {
|
|
5919
6077
|
if (!value || typeof value !== "object") return [];
|
|
5920
6078
|
const out = [];
|