@3dsource/angular-unreal-module 0.0.68 → 0.0.71

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, inject, Injectable, signal, ChangeDetectionStrategy, Component, Pipe, ElementRef, input, HostListener, Input, ViewChild, DestroyRef, computed, viewChild, effect, untracked, output } from '@angular/core';
2
+ import { InjectionToken, inject, Injectable, signal, makeEnvironmentProviders, provideEnvironmentInitializer, ChangeDetectionStrategy, Component, Pipe, ElementRef, input, HostListener, Input, ViewChild, DestroyRef, computed, viewChild, effect, untracked, output } from '@angular/core';
3
3
  import { filter, withLatestFrom, distinctUntilChanged, switchMap, catchError, timeout, tap, map as map$1, takeUntil, exhaustMap, debounceTime, takeWhile, delay, skip as skip$1 } from 'rxjs/operators';
4
4
  import { createAction, props, Store, provideState, createReducer, on, createFeature, createSelector } from '@ngrx/store';
5
5
  import { Actions, ofType, provideEffects, createEffect } from '@ngrx/effects';
@@ -246,7 +246,12 @@ const EToClientMessageType = {
246
246
  VideoEncoderAvgQP: 5,
247
247
  LatencyTest: 6,
248
248
  InitialSettings: 7,
249
+ FileExtension: 8,
250
+ FileMimeType: 9,
251
+ FileContents: 10,
252
+ TestEcho: 11,
249
253
  InputControlOwnership: 12,
254
+ GamepadResponse: 13,
250
255
  Protocol: 255,
251
256
  };
252
257
 
@@ -300,9 +305,9 @@ class AFKService extends SubService {
300
305
  this.countdown = 0; // The inactivity warning overlay has a countdown to show time until disconnect.
301
306
  this.selectWarnTimeout = this.store.selectSignal(selectWarnTimeout);
302
307
  this.isViewportReady = this.store.selectSignal(unrealFeature.selectViewportReady);
303
- this.initAfk();
308
+ this.init();
304
309
  }
305
- initAfk() {
310
+ init() {
306
311
  merge(this.store.select(selectWarnTimeout), fromSignal(UnrealInternalSignalEvents.RestAfkTimer))
307
312
  .pipe(withLatestFrom(this.store.select(unrealFeature.selectViewportReady)), filter(([, viewportReady]) => viewportReady))
308
313
  .subscribe(() => this.resetAfkWarningTimer());
@@ -312,9 +317,6 @@ class AFKService extends SubService {
312
317
  .subscribe(() => this.startAfkWarningTimer());
313
318
  this.disconnect$.subscribe(() => this.stop());
314
319
  }
315
- init() {
316
- // do nothing, just to not forget to initialize Service
317
- }
318
320
  hideOverlay() {
319
321
  sendSignal(UnrealInternalSignalEvents.ClickableOverlay);
320
322
  this.store.dispatch(setAfkTimerHide());
@@ -403,10 +405,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.11", ngImpo
403
405
 
404
406
  class FreezeFrameService extends SubService {
405
407
  constructor() {
406
- super(...arguments);
408
+ super();
407
409
  this.receiving = false;
408
410
  this.size = 0;
409
411
  this.freezeFrameOverlay = new Image();
412
+ this.init();
410
413
  }
411
414
  init() {
412
415
  this.store
@@ -472,12 +475,12 @@ class FreezeFrameService extends SubService {
472
475
  progress: 1,
473
476
  }));
474
477
  }
475
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.11", ngImport: i0, type: FreezeFrameService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
478
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.11", ngImport: i0, type: FreezeFrameService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
476
479
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.11", ngImport: i0, type: FreezeFrameService }); }
477
480
  }
478
481
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.11", ngImport: i0, type: FreezeFrameService, decorators: [{
479
482
  type: Injectable
480
- }] });
483
+ }], ctorParameters: () => [] });
481
484
 
482
485
  class DataFlowMonitor {
483
486
  /**
@@ -601,6 +604,9 @@ class VideoService extends SubService {
601
604
  ? // IMPORTANT! DO NOT CHANGE THOSE NUMBERS, LBM Stats are based on those values
602
605
  interval(250).pipe(map(() => track.pcClient), switchMap((pcClient) => from(this.getStats(pcClient))), filter(Truthy))
603
606
  : of(null)), filter(Truthy), share());
607
+ this.init();
608
+ }
609
+ init() {
604
610
  Signal.on('setKalmanParams').subscribe((data) => {
605
611
  this.kalmanFilter1D.config(data);
606
612
  BITRATE_MONITOR.config(data);
@@ -861,6 +867,9 @@ class CommandTelemetryService {
861
867
  this.unrealInitialConfig = inject(UNREAL_CONFIG, {
862
868
  optional: true,
863
869
  });
870
+ this.init();
871
+ }
872
+ init() {
864
873
  if (!this.unrealInitialConfig?.commandTelemetryReceiver) {
865
874
  return;
866
875
  }
@@ -1183,6 +1192,9 @@ class SignallingService extends SubService {
1183
1192
  this.onWebRtcAnswer$ = new Subject();
1184
1193
  this.abort$ = this.action$.pipe(ofType(abortEstablishingConnection));
1185
1194
  this.wsMsgHandlers = {};
1195
+ this.init();
1196
+ }
1197
+ init() {
1186
1198
  this.setHandlersFromStream();
1187
1199
  this.store
1188
1200
  .select(unrealFeature.selectDataChannelConnected)
@@ -1491,9 +1503,9 @@ class WebRtcPlayerService extends SubService {
1491
1503
  this.useMic = false;
1492
1504
  this.forceTURN = false;
1493
1505
  this.forceMonoAudio = false;
1494
- this.listenSignaling();
1506
+ this.init();
1495
1507
  }
1496
- listenSignaling() {
1508
+ init() {
1497
1509
  const iceCandidateBuffer = [];
1498
1510
  const processBuffer = () => {
1499
1511
  iceCandidateBuffer.forEach((cnd) => {
@@ -1863,6 +1875,115 @@ const deepEqual = (a, b) => {
1863
1875
  return false;
1864
1876
  };
1865
1877
 
1878
+ class FileReceiverService extends SubService {
1879
+ constructor() {
1880
+ super();
1881
+ this.fileComplete$ = new Subject();
1882
+ this.valid = false;
1883
+ this.chunks = 0;
1884
+ this.mimetype = '';
1885
+ this.receiving = false;
1886
+ this.extension = '';
1887
+ this.timestampStart = 0;
1888
+ this.data = [];
1889
+ this.init();
1890
+ }
1891
+ init() {
1892
+ this.store
1893
+ .select(unrealFeature.selectViewportReady)
1894
+ .pipe(filter(Truthy))
1895
+ .subscribe(() => this.reset());
1896
+ }
1897
+ reset() {
1898
+ this.mimetype = '';
1899
+ this.extension = '';
1900
+ this.receiving = false;
1901
+ this.valid = false;
1902
+ this.chunks = 0;
1903
+ this.data = [];
1904
+ this.timestampStart = new Date().getTime();
1905
+ //Logger.info('Received file state');
1906
+ }
1907
+ resetOnStart() {
1908
+ this.reset();
1909
+ this.receiving = true;
1910
+ }
1911
+ /**
1912
+ * Processes a files extension when received over data channel
1913
+ * @param view - the file extension data
1914
+ */
1915
+ setExtensionFromBytes(view) {
1916
+ // Reset this if we got a file message and we are not "receiving" it yet
1917
+ if (!this.receiving) {
1918
+ this.resetOnStart();
1919
+ }
1920
+ const extensionAsString = new TextDecoder('utf-16').decode(view.slice(1));
1921
+ //Logger.info(extensionAsString);
1922
+ this.extension = extensionAsString;
1923
+ }
1924
+ /**
1925
+ * Processes a files mime type when received over data channel
1926
+ * @param view - the file mime type data
1927
+ */
1928
+ setMimeTypeFromBytes(view) {
1929
+ // Reset this if we got a file message and we are not "receiving" it yet
1930
+ if (!this.receiving) {
1931
+ this.resetOnStart();
1932
+ }
1933
+ const mimeAsString = new TextDecoder('utf-16').decode(view.slice(1));
1934
+ //Logger.info(mimeAsString);
1935
+ this.mimetype = mimeAsString;
1936
+ }
1937
+ /*-------------------------------------------------------------------------------------------*/
1938
+ setContentsFromBytes(view) {
1939
+ // If we haven't received the initial setup instructions, return
1940
+ if (!this.receiving)
1941
+ return;
1942
+ const typeSize = 1;
1943
+ const intSize = 4;
1944
+ const maxMessageSize = 16 * 1024;
1945
+ const headerSize = typeSize + intSize;
1946
+ const maxPayloadSize = maxMessageSize - headerSize;
1947
+ // Calculate total number of chunks from the total this size
1948
+ this.chunks = Math.ceil(new DataView(view.slice(typeSize, headerSize).buffer).getInt32(0, true) /
1949
+ maxPayloadSize);
1950
+ // Get the file part of the payload
1951
+ const thisBytes = view.slice(headerSize);
1952
+ // Append to existing data that holds the this
1953
+ this.data.push(thisBytes);
1954
+ // Uncomment for debug
1955
+ // Logger.info(`Received this chunk: ${this.data.length}/${this.chunks}`);
1956
+ if (this.data.length === this.chunks) {
1957
+ this.receiving = false;
1958
+ this.valid = true;
1959
+ /*Logger.info('Received complete file');
1960
+ const transferDuration = new Date().getTime() - this.timestampStart;
1961
+ const transferBitrate = Math.round(
1962
+ (this.chunks * maxMessageSize) / transferDuration,
1963
+ );
1964
+ Logger.info(
1965
+ `Average transfer bitrate: ${transferBitrate}kb/s over ${transferDuration / 1000} seconds`,
1966
+ );*/
1967
+ /**
1968
+ * Reconstruct the file
1969
+ * This code reconstructs the received data into the original this based on the mime type and extension provided
1970
+ */
1971
+ const blob = new Blob([...this.data], { type: this.mimetype });
1972
+ this.fileComplete$.next({
1973
+ blob,
1974
+ mimetype: this.mimetype,
1975
+ extension: this.extension,
1976
+ valid: this.valid,
1977
+ });
1978
+ this.reset();
1979
+ }
1980
+ else if (this.data.length > this.chunks) {
1981
+ Logger.error(`Received bigger this than advertised: ${this.data.length}/${this.chunks}`);
1982
+ this.reset();
1983
+ }
1984
+ }
1985
+ }
1986
+
1866
1987
  const filteredLogs = [
1867
1988
  {
1868
1989
  command: 'onChangeSequence',
@@ -1875,17 +1996,23 @@ class AggregatorService extends SubService {
1875
1996
  this.videoService = inject(VideoService);
1876
1997
  this.webrtcPlayer = inject(WebRtcPlayerService);
1877
1998
  this.freezeFrame = inject(FreezeFrameService);
1999
+ this.fileReceiver = inject(FileReceiverService);
1878
2000
  this.unrealInitialConfig = inject(UNREAL_CONFIG);
1879
2001
  this.responseEventListeners = new Map();
1880
2002
  /**
1881
2003
  * Never called for now
1882
2004
  */
1883
2005
  this.destroy$ = new Subject();
2006
+ this.init();
2007
+ }
2008
+ init() {
1884
2009
  this.listenWebRTC();
1885
2010
  this.initialize();
1886
2011
  }
1887
- init() {
1888
- // do nothing, just to not forget to initialize Service
2012
+ listenWebRTC() {
2013
+ this.webrtcPlayer.onDataChannelMessage$
2014
+ .pipe(takeUntil(this.destroy$))
2015
+ .subscribe((data) => this.dataChannelMessageHandler(data));
1889
2016
  }
1890
2017
  initialize() {
1891
2018
  this.store
@@ -1973,11 +2100,6 @@ class AggregatorService extends SubService {
1973
2100
  resetResponseList() {
1974
2101
  this.responseEventListeners.clear();
1975
2102
  }
1976
- listenWebRTC() {
1977
- this.webrtcPlayer.onDataChannelMessage$
1978
- .pipe(takeUntil(this.destroy$))
1979
- .subscribe((data) => this.dataChannelMessageHandler(data));
1980
- }
1981
2103
  dataChannelMessageHandler(data) {
1982
2104
  const view = new Uint8Array(data);
1983
2105
  const anyData = data.slice(1);
@@ -2008,6 +2130,18 @@ class AggregatorService extends SubService {
2008
2130
  }
2009
2131
  break;
2010
2132
  }
2133
+ case EToClientMessageType.FileExtension:
2134
+ Logger.colored(...COLOR_CODES.FROM_UNREAL, 'FileExtension');
2135
+ this.fileReceiver.setExtensionFromBytes(view);
2136
+ break;
2137
+ case EToClientMessageType.FileMimeType:
2138
+ Logger.colored(...COLOR_CODES.FROM_UNREAL, 'FileMimeType');
2139
+ this.fileReceiver.setMimeTypeFromBytes(view);
2140
+ break;
2141
+ case EToClientMessageType.FileContents:
2142
+ Logger.colored(...COLOR_CODES.FROM_UNREAL, 'FileContents');
2143
+ this.fileReceiver.setContentsFromBytes(view);
2144
+ break;
2011
2145
  case EToClientMessageType.FreezeFrame:
2012
2146
  Logger.colored(...COLOR_CODES.FROM_UNREAL, 'Freeze frame');
2013
2147
  this.freezeFrame.start(view);
@@ -2047,13 +2181,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.11", ngImpo
2047
2181
  }], ctorParameters: () => [] });
2048
2182
 
2049
2183
  class ConsoleExtensionsService extends SubService {
2184
+ #httpClient = inject(HttpClient);
2185
+ #isDevMode = inject(DevModeService).isDevMode;
2050
2186
  constructor() {
2051
- super(...arguments);
2052
- this.httpClient = inject(HttpClient);
2053
- this.isDevMode = inject(DevModeService).isDevMode;
2187
+ super();
2188
+ this.init();
2054
2189
  }
2055
2190
  init() {
2056
- if (!this.isDevMode) {
2191
+ if (!this.#isDevMode) {
2057
2192
  return;
2058
2193
  }
2059
2194
  window.dropConnection = () => {
@@ -2077,7 +2212,7 @@ class ConsoleExtensionsService extends SubService {
2077
2212
  window.restartApp = () => {
2078
2213
  this.store
2079
2214
  .select(unrealFeature.selectAwsInstance)
2080
- .pipe(take(1), filter((data) => !!data.instanceName), tapLog('Instance', `Restart initiated`), switchMap$1((data) => this.httpClient.get(`//${data.instanceName}/restartapp`)), catchError(() => of(null)))
2215
+ .pipe(take(1), filter((data) => !!data.instanceName), tapLog('Instance', `Restart initiated`), switchMap$1((data) => this.#httpClient.get(`//${data.instanceName}/restartapp`)), catchError(() => of(null)))
2081
2216
  .subscribe();
2082
2217
  };
2083
2218
  window.unrealHelp = () => this.unrealHelp();
@@ -2094,12 +2229,12 @@ class ConsoleExtensionsService extends SubService {
2094
2229
  Logger.info('setWarnTime() => set time to appear the AFK window.');
2095
2230
  Logger.info('emitCommand(command) => send command to Unreal Engine.');
2096
2231
  }
2097
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.11", ngImport: i0, type: ConsoleExtensionsService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
2232
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.11", ngImport: i0, type: ConsoleExtensionsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2098
2233
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.11", ngImport: i0, type: ConsoleExtensionsService }); }
2099
2234
  }
2100
2235
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.11", ngImport: i0, type: ConsoleExtensionsService, decorators: [{
2101
2236
  type: Injectable
2102
- }] });
2237
+ }], ctorParameters: () => [] });
2103
2238
 
2104
2239
  class DevModeService {
2105
2240
  get isDevMode() {
@@ -2279,19 +2414,17 @@ class TouchEmulator {
2279
2414
 
2280
2415
  class UnrealCommunicatorService {
2281
2416
  constructor() {
2417
+ this.store = inject(Store);
2282
2418
  this.telemetry = inject(CommandTelemetryService);
2283
- this.afkService = inject(AFKService);
2284
2419
  this.freezeFrame = inject(FreezeFrameService);
2285
2420
  this.webrtcPlayer = inject(WebRtcPlayerService);
2286
2421
  this.videoService = inject(VideoService);
2287
- this.consoleExtensions = inject(ConsoleExtensionsService);
2288
- this.store = inject(Store);
2289
2422
  this.destroy$ = new Subject();
2290
2423
  this.cirrusConnected = toSignal(this.store.select(unrealFeature.selectCirrusConnected));
2424
+ this.init();
2425
+ }
2426
+ init() {
2291
2427
  this.emitUIInteraction = this.telemetry.decorate(this.emitUIInteraction.bind(this));
2292
- this.consoleExtensions.init();
2293
- this.afkService.init();
2294
- this.freezeFrame.init();
2295
2428
  this.listenVideo();
2296
2429
  this.store
2297
2430
  .select(unrealFeature.selectDataChannelConnected)
@@ -2980,7 +3113,12 @@ class StreamStatusTelemetryService {
2980
3113
  constructor() {
2981
3114
  this.store = inject(Store);
2982
3115
  this.videoService = inject(VideoService);
2983
- this.initTelemetry();
3116
+ this.init();
3117
+ }
3118
+ init() {
3119
+ this.videoService.videoStats$
3120
+ .pipe(withLatestFrom(this.store.select(unrealFeature.selectAwsInstance), this.store.select(unrealFeature.selectLowBandwidth), this.store.select(unrealFeature.selectLowBandwidthStats), this.store.select(unrealFeature.selectCirrusConnected)), auditTime(5000), filter(([, , , , cirrusConnected]) => cirrusConnected), map$1(([data, signalingServer, isLowBandwidth, lbmStats]) => this.mapEventData(data, signalingServer, isLowBandwidth, lbmStats)))
3121
+ .subscribe((data) => this.trackEventToMixPanel(data));
2984
3122
  }
2985
3123
  mapEventData(data, signalingServer, isLowBandwidth, lbmStats) {
2986
3124
  const { bitrate, VideoEncoderQP, framesPerSecond, frameWidth, frameHeight, jitter, packetsLost, currentRoundTripTime, } = data.aggregatedStats;
@@ -3001,17 +3139,9 @@ class StreamStatusTelemetryService {
3001
3139
  VideoEncoderQP,
3002
3140
  };
3003
3141
  }
3004
- initTelemetry() {
3005
- this.videoService.videoStats$
3006
- .pipe(withLatestFrom(this.store.select(unrealFeature.selectAwsInstance), this.store.select(unrealFeature.selectLowBandwidth), this.store.select(unrealFeature.selectLowBandwidthStats), this.store.select(unrealFeature.selectCirrusConnected)), auditTime(5000), filter(([, , , , cirrusConnected]) => cirrusConnected), map$1(([data, signalingServer, isLowBandwidth, lbmStats]) => this.mapEventData(data, signalingServer, isLowBandwidth, lbmStats)))
3007
- .subscribe((data) => this.trackEventToMixPanel(data));
3008
- }
3009
3142
  trackEventToMixPanel(data) {
3010
3143
  this.store.dispatch(trackMixpanelEvent({ event: 'streamStatus', data }));
3011
3144
  }
3012
- init() {
3013
- // do nothing, just to not forget to initialize Service
3014
- }
3015
3145
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.11", ngImport: i0, type: StreamStatusTelemetryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3016
3146
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.11", ngImport: i0, type: StreamStatusTelemetryService }); }
3017
3147
  }
@@ -3020,7 +3150,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.11", ngImpo
3020
3150
  }], ctorParameters: () => [] });
3021
3151
 
3022
3152
  class AfkPlaywrightService extends AFKService {
3023
- initAfk() {
3153
+ init() {
3024
3154
  return;
3025
3155
  }
3026
3156
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.11", ngImport: i0, type: AfkPlaywrightService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
@@ -3049,6 +3179,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.11", ngImpo
3049
3179
  }], ctorParameters: () => [] });
3050
3180
 
3051
3181
  class UnrealCommunicatorPlaywrightService extends UnrealCommunicatorService {
3182
+ init() {
3183
+ return;
3184
+ }
3052
3185
  sendCommandToUnreal() {
3053
3186
  return;
3054
3187
  }
@@ -3066,10 +3199,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.11", ngImpo
3066
3199
  }] });
3067
3200
 
3068
3201
  class AggregatorPlaywrightService extends AggregatorService {
3069
- listenWebRTC() {
3070
- return;
3071
- }
3072
- initialize() {
3202
+ init() {
3073
3203
  return;
3074
3204
  }
3075
3205
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.11", ngImport: i0, type: AggregatorPlaywrightService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
@@ -3083,9 +3213,6 @@ class FreezeFramePlaywrightService extends FreezeFrameService {
3083
3213
  init() {
3084
3214
  return;
3085
3215
  }
3086
- invalidate() {
3087
- return;
3088
- }
3089
3216
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.11", ngImport: i0, type: FreezeFramePlaywrightService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
3090
3217
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.11", ngImport: i0, type: FreezeFramePlaywrightService }); }
3091
3218
  }
@@ -3094,10 +3221,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.11", ngImpo
3094
3221
  }] });
3095
3222
 
3096
3223
  class CommandTelemetryPlaywrightService extends CommandTelemetryService {
3097
- start() {
3098
- return;
3099
- }
3100
- listenCallbacks() {
3224
+ init() {
3101
3225
  return;
3102
3226
  }
3103
3227
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.11", ngImport: i0, type: CommandTelemetryPlaywrightService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
@@ -3108,7 +3232,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.11", ngImpo
3108
3232
  }] });
3109
3233
 
3110
3234
  class StreamStatusTelemetryPlaywrightService extends StreamStatusTelemetryService {
3111
- initTelemetry() {
3235
+ init() {
3112
3236
  return;
3113
3237
  }
3114
3238
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.11", ngImport: i0, type: StreamStatusTelemetryPlaywrightService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
@@ -3118,15 +3242,69 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.11", ngImpo
3118
3242
  type: Injectable
3119
3243
  }] });
3120
3244
 
3121
- function provideAngularUnrealModule(config) {
3245
+ class ConsoleExtensionsPlaywrightService extends ConsoleExtensionsService {
3246
+ init() {
3247
+ return;
3248
+ }
3249
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.11", ngImport: i0, type: ConsoleExtensionsPlaywrightService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
3250
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.11", ngImport: i0, type: ConsoleExtensionsPlaywrightService }); }
3251
+ }
3252
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.11", ngImport: i0, type: ConsoleExtensionsPlaywrightService, decorators: [{
3253
+ type: Injectable
3254
+ }] });
3255
+
3256
+ class FileReceiverPlaywrightService extends FileReceiverService {
3257
+ init() {
3258
+ return;
3259
+ }
3260
+ }
3261
+
3262
+ /*
3263
+ * Copyright (c) 2025.
3264
+ * 3DSource.com. Sergii Karanda steve@3dsource.com. All Rights Reserved.
3265
+ */
3266
+ const ReceivedMimeTypes = {
3267
+ ApplicationJson: 'application/json',
3268
+ };
3269
+
3270
+ class FileHandlerService {
3271
+ constructor() {
3272
+ this.fileService = inject(FileReceiverService);
3273
+ this.fileHandlers = {
3274
+ [ReceivedMimeTypes.ApplicationJson]: this.handleJsonFile.bind(this),
3275
+ };
3276
+ }
3277
+ handleJsonFile(data, correlationId) {
3278
+ const { blob } = data;
3279
+ return from(blob.text()).pipe(map$1((text) => JSON.parse(text)), filter(({ commandCallback }) => {
3280
+ return commandCallback.correlationId === correlationId;
3281
+ }));
3282
+ }
3283
+ observeFileResponse(mimetype, data, sender, timeOut = 60000) {
3284
+ const correlationId = generateUuid();
3285
+ const out = { ...data, correlationId };
3286
+ const observable = this.fileService.fileComplete$.pipe(switchMap$1((data) => {
3287
+ const { valid } = data;
3288
+ if (valid && this.fileHandlers[mimetype]) {
3289
+ return this.fileHandlers[mimetype](data, correlationId).pipe(filter(Truthy));
3290
+ }
3291
+ return of(null);
3292
+ }), timeout$1(timeOut), catchError((e) => {
3293
+ Logger.error(e);
3294
+ return of(null);
3295
+ }), take(1));
3296
+ setTimeout(() => sender(out), 0);
3297
+ return observable;
3298
+ }
3299
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.11", ngImport: i0, type: FileHandlerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3300
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.11", ngImport: i0, type: FileHandlerService }); }
3301
+ }
3302
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.11", ngImport: i0, type: FileHandlerService, decorators: [{
3303
+ type: Injectable
3304
+ }] });
3305
+
3306
+ function providePlaywrightProviders(config) {
3122
3307
  return [
3123
- provideState(unrealFeature),
3124
- provideEffects([UnrealEffects]),
3125
- ConsoleExtensionsService,
3126
- InputService,
3127
- VideoService,
3128
- WebRtcPlayerService,
3129
- RegionsPingService,
3130
3308
  {
3131
3309
  provide: StreamStatusTelemetryService,
3132
3310
  useClass: config?.playwright
@@ -3167,9 +3345,43 @@ function provideAngularUnrealModule(config) {
3167
3345
  ? SignallingPlaywrightService
3168
3346
  : SignallingService,
3169
3347
  },
3348
+ {
3349
+ provide: ConsoleExtensionsService,
3350
+ useClass: config?.playwright
3351
+ ? ConsoleExtensionsPlaywrightService
3352
+ : ConsoleExtensionsService,
3353
+ },
3354
+ {
3355
+ provide: FileReceiverService,
3356
+ useClass: config?.playwright
3357
+ ? FileReceiverPlaywrightService
3358
+ : FileReceiverService,
3359
+ },
3170
3360
  ];
3171
3361
  }
3172
3362
 
3363
+ function provideAngularUnrealModule(config) {
3364
+ return makeEnvironmentProviders([
3365
+ provideState(unrealFeature),
3366
+ provideEffects([UnrealEffects]),
3367
+ ConsoleExtensionsService,
3368
+ InputService,
3369
+ VideoService,
3370
+ WebRtcPlayerService,
3371
+ RegionsPingService,
3372
+ FileReceiverService,
3373
+ FileHandlerService,
3374
+ providePlaywrightProviders(config),
3375
+ provideEnvironmentInitializer(() => {
3376
+ inject(AggregatorService);
3377
+ inject(StreamStatusTelemetryService);
3378
+ inject(ConsoleExtensionsService);
3379
+ inject(AFKService);
3380
+ inject(FreezeFrameService);
3381
+ }),
3382
+ ]);
3383
+ }
3384
+
3173
3385
  const initialState = {
3174
3386
  streamRequestContext: null,
3175
3387
  environmentId: null,
@@ -4634,19 +4846,15 @@ class UnrealSceneComponent {
4634
4846
  this.lightMode = this.store.selectSignal(unrealFeature.selectLowBandwidth);
4635
4847
  this.isFreezeFrameLoading = this.store.selectSignal(selectIsFreezeFrameLoading);
4636
4848
  this.isExistMatchUrls = this.store.selectSignal(selectIsExistMatchUrls);
4637
- this.aggregatorService = inject(AggregatorService);
4638
4849
  this.commandsSender = inject(UnrealCommunicatorService);
4639
4850
  this.inputService = inject(InputService);
4640
4851
  this.videoService = inject(VideoService);
4641
- this.streamTelemetryService = inject(StreamStatusTelemetryService);
4642
4852
  this.element = inject(ElementRef);
4643
4853
  this.destroyRef = inject(DestroyRef);
4644
4854
  this.destroyRef.onDestroy(() => {
4645
4855
  this.commandsSender.destroy();
4646
4856
  this.store.dispatch(destroyUnrealScene());
4647
4857
  });
4648
- this.streamTelemetryService.init();
4649
- this.aggregatorService.init();
4650
4858
  this.inputService.useKeyboardKeys(this.inputService.defaultKeys);
4651
4859
  if (this.isExistMatchUrls()) {
4652
4860
  this.store.dispatch(initSignalling());
@@ -4998,5 +5206,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.11", ngImpo
4998
5206
  * Generated bundle index. Do not edit.
4999
5207
  */
5000
5208
 
5001
- export { AFKService, AfkPlaywrightService, AggregatorPlaywrightService, AggregatorService, AnswerHandler, CONSOLE_COMMAND_DISABLE_MESSAGES, CONSOLE_COMMAND_ENABLE_MESSAGES, CONSOLE_COMMAND_PIXEL_QUALITY, ClickableOverlayComponent, CommandTelemetryPlaywrightService, CommandTelemetryService, ConfigHandler, ConsoleExtensionsService, DATA_CHANNEL_CONNECTION_TIMEOUT, DEBOUNCE_TO_MANY_RESIZE_CALLS, DEFAULT_AFK_TIMEOUT, DEFAULT_AFK_TIMEOUT_PERIOD, DataFlowMonitor, DevModeService, DisconnectReason, EControlSchemeType, EMessageType, EToClientMessageType, FULL_HD_HEIGHT, FULL_HD_WIDTH, FilterSettingsComponent, FreezeFrameComponent, FreezeFramePlaywrightService, FreezeFrameService, IceCandidateHandler, ImageLoadingSrcComponent, InputOptions, InputService, InstanceReadyHandler, InstanceReservedHandler, IntroSrcComponent, KalmanFilter1D, LatencyTimings, LowBandwidthDetectorComponent, LowBandwidthModalComponent, MINIMAL_FPS, MouseButton, MouseButtonsMask, OnCloseHandler, OnErrorHandler, OnMessageHandler, OnOpenHandler, OrchestrationMessageTypes, POLLING_TIME, PingHandler, PlayerCountHandler, RegionsPingService, ResetTelemetry, SAME_SIZE_THRESHOLD, SCREEN_LOCKER_CONTAINER_ID, SIGNALLING_PERCENT_VALUE, SSInfoHandler, STREAMING_VIDEO_ID, SafePipe, SignallingPlaywrightService, SignallingService, SpecialKeyCodes, StatGraphComponent, StreamStatusTelemetryPlaywrightService, StreamStatusTelemetryService, SubService, TelemetryStart, TelemetryStop, UNREAL_CONFIG, UnrealCommunicatorPlaywrightService, UnrealCommunicatorService, UnrealEffects, UnrealInternalSignalEvents, UnrealSceneComponent, UnrealStatusMessage, VideoRecorder, 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_TIMEOUT, WebRtcPlayerService, WebrtcErrorModalComponent, abortEstablishingConnection, changeLowBandwidth, changeStatusMainVideoOnScene, changeStreamResolutionAction, changeStreamResolutionSuccessAction, commandCompleted, commandStarted, decodeData, destroyRemoteConnections, destroyUnrealScene, disconnectStream, dispatchResize, dropConnection, floatToSmoothPercents, forceResizeUnrealVideo, fromResizeObserver, fromSignal, fromUnrealCallBackSignal, getActiveUrl, getImageFromVideoStream, getRtcErrorMessage, initSignalling, initialState, isLoaderScreenVisible, keepMaxUntilReset, mapQpToQuality, observeCommandResponse, provideAngularUnrealModule, removeExileCommands, resetAfk, resetAfkAction, resetConfig, resetIntroSrc, resetWarnTimeout, selectClientAndViewIds, selectCommandProgress, selectCommandsInProgress, selectFreezeFrameCombinedDataUrl, selectFreezeFrameDataUrl, selectFreezeFrameDataUrlFromVideo, selectFreezeFrameProgressMessageFromVideo, selectIsAutostart, selectIsExistMatchUrls, selectIsFreezeFrameLoading, selectIsVideoPlayingAndDataChannelConnected, selectLastCommandInProgress, selectLoaderCommands, selectShowLoader, selectShowReconnectPopup, selectSignalingParameters, selectStreamConfig, selectTotalProgress, selectWarnTimeout, sendSignal, setAfkTimerHide, setAfkTimerVisible, setAwsInstance, setCirrusConnected, setCirrusDisconnected, setConfig, setDataChannelConnected, setEstablishingConnection, setFreezeFrame, setFreezeFrameFromVideo, setIntroImageSrc, setIntroVideoSrc, setLoadingImageSrc, setLoopBackCommandIsCompleted, setMaxFps, setOrchestrationContext, setOrchestrationMessage, setOrchestrationParameters, setOrchestrationProgress, setSignalingName, setStatusMessage, setStatusPercentSignallingServer, setStreamClientCompanyId, setStreamViewId, setUnrealPlaywrightConfig, setViewportNotReady, setViewportReady, showPopupWithoutAutoStart, showUnrealErrorMessage, smoothTransition, startStream, trackMixpanelEvent, unrealFeature, unrealReducer, updateCirrusInfo };
5209
+ export { AFKService, AfkPlaywrightService, AggregatorPlaywrightService, AggregatorService, AnswerHandler, CONSOLE_COMMAND_DISABLE_MESSAGES, CONSOLE_COMMAND_ENABLE_MESSAGES, CONSOLE_COMMAND_PIXEL_QUALITY, ClickableOverlayComponent, CommandTelemetryPlaywrightService, CommandTelemetryService, ConfigHandler, ConsoleExtensionsPlaywrightService, ConsoleExtensionsService, DATA_CHANNEL_CONNECTION_TIMEOUT, DEBOUNCE_TO_MANY_RESIZE_CALLS, DEFAULT_AFK_TIMEOUT, DEFAULT_AFK_TIMEOUT_PERIOD, DataFlowMonitor, DevModeService, DisconnectReason, EControlSchemeType, EMessageType, EToClientMessageType, FULL_HD_HEIGHT, FULL_HD_WIDTH, FileHandlerService, FileReceiverPlaywrightService, FileReceiverService, FilterSettingsComponent, FreezeFrameComponent, FreezeFramePlaywrightService, FreezeFrameService, IceCandidateHandler, ImageLoadingSrcComponent, InputOptions, InputService, InstanceReadyHandler, InstanceReservedHandler, IntroSrcComponent, KalmanFilter1D, LatencyTimings, LowBandwidthDetectorComponent, LowBandwidthModalComponent, MINIMAL_FPS, MouseButton, MouseButtonsMask, OnCloseHandler, OnErrorHandler, OnMessageHandler, OnOpenHandler, OrchestrationMessageTypes, POLLING_TIME, PingHandler, PlayerCountHandler, RegionsPingService, ResetTelemetry, SAME_SIZE_THRESHOLD, SCREEN_LOCKER_CONTAINER_ID, SIGNALLING_PERCENT_VALUE, SSInfoHandler, STREAMING_VIDEO_ID, SafePipe, SignallingPlaywrightService, SignallingService, SpecialKeyCodes, StatGraphComponent, StreamStatusTelemetryPlaywrightService, StreamStatusTelemetryService, SubService, TelemetryStart, TelemetryStop, UNREAL_CONFIG, UnrealCommunicatorPlaywrightService, UnrealCommunicatorService, UnrealEffects, UnrealInternalSignalEvents, UnrealSceneComponent, UnrealStatusMessage, VideoRecorder, 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_TIMEOUT, WebRtcPlayerService, WebrtcErrorModalComponent, abortEstablishingConnection, changeLowBandwidth, changeStatusMainVideoOnScene, changeStreamResolutionAction, changeStreamResolutionSuccessAction, commandCompleted, commandStarted, decodeData, destroyRemoteConnections, destroyUnrealScene, disconnectStream, dispatchResize, dropConnection, floatToSmoothPercents, forceResizeUnrealVideo, fromResizeObserver, fromSignal, fromUnrealCallBackSignal, getActiveUrl, getImageFromVideoStream, getRtcErrorMessage, initSignalling, initialState, isLoaderScreenVisible, keepMaxUntilReset, mapQpToQuality, observeCommandResponse, provideAngularUnrealModule, removeExileCommands, resetAfk, resetAfkAction, resetConfig, resetIntroSrc, resetWarnTimeout, selectClientAndViewIds, selectCommandProgress, selectCommandsInProgress, selectFreezeFrameCombinedDataUrl, selectFreezeFrameDataUrl, selectFreezeFrameDataUrlFromVideo, selectFreezeFrameProgressMessageFromVideo, selectIsAutostart, selectIsExistMatchUrls, selectIsFreezeFrameLoading, selectIsVideoPlayingAndDataChannelConnected, selectLastCommandInProgress, selectLoaderCommands, selectShowLoader, selectShowReconnectPopup, selectSignalingParameters, selectStreamConfig, selectTotalProgress, selectWarnTimeout, sendSignal, setAfkTimerHide, setAfkTimerVisible, setAwsInstance, setCirrusConnected, setCirrusDisconnected, setConfig, setDataChannelConnected, setEstablishingConnection, setFreezeFrame, setFreezeFrameFromVideo, setIntroImageSrc, setIntroVideoSrc, setLoadingImageSrc, setLoopBackCommandIsCompleted, setMaxFps, setOrchestrationContext, setOrchestrationMessage, setOrchestrationParameters, setOrchestrationProgress, setSignalingName, setStatusMessage, setStatusPercentSignallingServer, setStreamClientCompanyId, setStreamViewId, setUnrealPlaywrightConfig, setViewportNotReady, setViewportReady, showPopupWithoutAutoStart, showUnrealErrorMessage, smoothTransition, startStream, trackMixpanelEvent, unrealFeature, unrealReducer, updateCirrusInfo };
5002
5210
  //# sourceMappingURL=3dsource-angular-unreal-module.mjs.map