@3dsource/angular-unreal-module 0.0.98 → 0.0.100

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/README.md CHANGED
@@ -10,6 +10,10 @@ This package provides:
10
10
  - Communication bridge (commands, UI interactions, input data)
11
11
  - NgRx state and effects for 3D stream lifecycle
12
12
  - Config and utilities for telemetry, errors, and regions ping
13
+ - Auto-reconnection support for WebRTC/DataChannel failures
14
+ - File receiving from Unreal Engine
15
+ - Analytics, FPS monitoring, and stream status telemetry
16
+ - Playwright testing mode with mock services
13
17
 
14
18
  ## Installation
15
19
 
@@ -17,6 +21,8 @@ This package provides:
17
21
 
18
22
  - Angular 18+
19
23
  - NgRx store and effects (v18+)
24
+ - Angular CDK (v18+) — used for dialog overlays
25
+ - `provideHttpClient()` — required by internal services (telemetry, signalling, regions ping, error reporting)
20
26
 
21
27
  ### Peer Dependencies
22
28
 
@@ -48,11 +54,14 @@ The API is fully standalone (no NgModule). Use providers and components as shown
48
54
 
49
55
  ### 1) Provide the module services and store slice
50
56
 
51
- Add providers in your application bootstrap (e.g., app.config.ts):
57
+ Add providers in your application bootstrap (e.g., `app.config.ts`):
58
+
59
+ > **⚠️ Important:** `UNREAL_CONFIG` is **required** — multiple internal services inject it without `{ optional: true }`. Omitting it will cause a `NullInjectorError` at runtime. You can provide it with an empty object `{}` as a minimum.
52
60
 
53
61
  ```ts
54
62
  import { ApplicationConfig } from '@angular/core';
55
63
  import { provideRouter } from '@angular/router';
64
+ import { provideHttpClient } from '@angular/common/http';
56
65
  import { provideStore } from '@ngrx/store';
57
66
  import { provideEffects } from '@ngrx/effects';
58
67
  import { provideAngularUnrealModule, UNREAL_CONFIG } from '@3dsource/angular-unreal-module';
@@ -60,30 +69,49 @@ import { provideAngularUnrealModule, UNREAL_CONFIG } from '@3dsource/angular-unr
60
69
  export const appConfig: ApplicationConfig = {
61
70
  providers: [
62
71
  provideRouter([]),
72
+ provideHttpClient(),
73
+
63
74
  // Root NgRx (if not already added in your app)
64
75
  provideStore(),
65
76
  provideEffects(),
66
77
 
67
- // Unreal providers (adds feature state and effects internally)
68
- // Tip: pass { playwright: true } to switch to testing/dummy services
69
- provideAngularUnrealModule({ playwright: false }),
70
-
71
- // Optional initial config
78
+ // Required: Unreal initial configuration
72
79
  {
73
80
  provide: UNREAL_CONFIG,
74
81
  useValue: {
75
- // customErrorsEndpoint?: string,
76
- // commandTelemetryReceiver?: string,
77
- // regionsPingUrl?: string,
78
- // screenLockerContainerId?: string,
79
- // dataChannelConnectionTimeout?: number,
80
- // playwright?: boolean, // mirrors the provider flag; can be used by services/effects
82
+ customErrorsEndpoint: '', // Endpoint for custom error reporting
83
+ commandTelemetryReceiver: '', // Endpoint for command telemetry
84
+ regionsPingUrl: '', // URL prefix for regions latency ping
85
+ screenLockerContainerId: '', // DOM container id for screen locker overlay
86
+ dataChannelConnectionTimeout: 8000, // Timeout in ms for data channel connection (default: 8000)
87
+ playwright: false, // Mirrors the provider flag for services/effects
88
+ reconnect: {
89
+ // Auto-reconnection configuration
90
+ enabled: true, // Enable auto-reconnection (default: true)
91
+ maxAttempts: 3, // Max reconnection attempts (default: 3)
92
+ delayMs: 1000, // Delay between attempts in ms (default: 1000)
93
+ onIceFailure: true, // Reconnect on ICE connection failure (default: true)
94
+ onDataChannelClose: true, // Reconnect on DataChannel close (default: true)
95
+ },
81
96
  },
82
97
  },
98
+
99
+ // Unreal providers (adds feature state and effects internally)
100
+ // Tip: pass { playwright: true } to switch to testing/dummy services
101
+ provideAngularUnrealModule({ playwright: false }),
83
102
  ],
84
103
  };
85
104
  ```
86
105
 
106
+ #### Minimal configuration
107
+
108
+ If you don't need custom endpoints, provide `UNREAL_CONFIG` with an empty object:
109
+
110
+ ```ts
111
+ { provide: UNREAL_CONFIG, useValue: {} },
112
+ provideAngularUnrealModule(),
113
+ ```
114
+
87
115
  ### 2) Use the Unreal scene component
88
116
 
89
117
  Import the component into a standalone component and use it in the template.
@@ -96,7 +124,7 @@ import { UnrealSceneComponent } from '@3dsource/angular-unreal-module';
96
124
  selector: 'app-root',
97
125
  standalone: true,
98
126
  imports: [UnrealSceneComponent],
99
- template: ` <app-unreal-scene [isStudio]="false" [useContainerAsSizeProvider]="true" [studioResolutionSize]="{ width: 1920, height: 1080 }" (changeMouseOverScene)="onHover($event)"></app-unreal-scene> `,
127
+ template: ` <app-unreal-scene [isStudio]="false" [useContainerAsSizeProvider]="true" [studioResolutionSize]="{ width: 1920, height: 1080 }" (changeMouseOverScene)="onHover($event)"> </app-unreal-scene> `,
100
128
  })
101
129
  export class AppComponent {
102
130
  onHover(isOver: boolean) {
@@ -105,25 +133,38 @@ export class AppComponent {
105
133
  }
106
134
  ```
107
135
 
108
- Component selector: <app-unreal-scene>
136
+ Component selector: `<app-unreal-scene>`
109
137
 
110
138
  Inputs:
111
139
 
112
- - isStudio: boolean = false
113
- - useContainerAsSizeProvider: boolean = true
114
- - studioResolutionSize: { width: number; height: number } = { width: 1920, height: 1080 }
140
+ | Input | Type | Default |
141
+ | ---------------------------- | ----------------------------------- | ------------------------------- |
142
+ | `isStudio` | `boolean` | `false` |
143
+ | `useContainerAsSizeProvider` | `boolean` | `true` |
144
+ | `studioResolutionSize` | `{ width: number; height: number }` | `{ width: 1920, height: 1080 }` |
115
145
 
116
146
  Outputs:
117
147
 
118
- - changeMouseOverScene: EventEmitter<boolean>
148
+ | Output | Type |
149
+ | ---------------------- | --------------------------- |
150
+ | `changeMouseOverScene` | `OutputEmitterRef<boolean>` |
119
151
 
120
152
  ### 3) Send commands / interactions to Unreal
121
153
 
122
154
  Inject `UnrealCommunicatorService` to send commands or UI interactions. Types for command packets are provided by `@3dsource/types-unreal`.
123
155
 
156
+ There are three sending methods — choose based on your needs:
157
+
158
+ | Method | Description |
159
+ | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
160
+ | `sendCommandToUnreal` | Full pipeline: adds `correlationId`, records telemetry, dispatches NgRx `commandStarted` action. **Recommended for application commands.** |
161
+ | `emitUIInteraction` | Sends the packet as a raw `UIInteraction` message. No telemetry or store dispatch. |
162
+ | `emitCommand` | Sends the packet as a raw `Command` message (for console commands, resolution changes, etc.). |
163
+
124
164
  ```ts
125
165
  import { Component, inject } from '@angular/core';
126
166
  import { UnrealCommunicatorService } from '@3dsource/angular-unreal-module';
167
+ import { MetaBoxCommand } from '@3dsource/types-unreal';
127
168
  import type { MetaBoxCommandPacket } from '@3dsource/types-unreal';
128
169
 
129
170
  @Component({ standalone: true, template: '' })
@@ -131,29 +172,126 @@ export class MyComponent {
131
172
  private unreal = inject(UnrealCommunicatorService);
132
173
 
133
174
  sendSomeCommand() {
134
- const packet: MetaBoxCommandPacket = {
135
- command: 'SomeCommand',
136
- parameters: {
137
- /* command parameters */
138
- },
139
- } as MetaBoxCommandPacket;
175
+ // Recommended: use sendCommandToUnreal for full telemetry + store tracking
176
+ this.unreal.sendCommandToUnreal({
177
+ command: MetaBoxCommand.FChangeResolutionCommand,
178
+ payload: { resolution: { x: 1920, y: 1080 } },
179
+ });
180
+ }
140
181
 
141
- // Records telemetry and dispatches store events
142
- this.unreal.sendCommandToUnreal(packet);
143
- // Or use:
144
- // this.unreal.emitCommand(packet); // to send as Command message
145
- // this.unreal.emitUIInteraction(packet); // to send as UIInteraction
182
+ sendRawUIInteraction() {
183
+ // Low-level: sends UIInteraction message without telemetry tracking
184
+ const packet = {
185
+ command: 'CustomCommand',
186
+ payload: { key: 'value' },
187
+ } as MetaBoxCommandPacket;
188
+ this.unreal.emitUIInteraction(packet);
146
189
  }
147
190
  }
148
191
  ```
149
192
 
193
+ ### 4) Store integration (actions & selectors)
194
+
195
+ The module registers an NgRx feature state `unrealFeature`. You can dispatch actions and select state in your components:
196
+
197
+ ```ts
198
+ import { inject } from '@angular/core';
199
+ import { Store } from '@ngrx/store';
200
+ import { startStream, setConfig, setOrchestrationContext, disconnectStream, selectTotalProgress, selectShowLoader, unrealFeature } from '@3dsource/angular-unreal-module';
201
+
202
+ // Dispatch actions
203
+ const store = inject(Store);
204
+ store.dispatch(startStream({ config: { autoStart: true, warnTimeout: 120 } }));
205
+
206
+ // Select state
207
+ const progress = store.selectSignal(selectTotalProgress);
208
+ const isVideoPlaying = store.selectSignal(unrealFeature.selectIsVideoPlaying);
209
+ const dataChannelConnected = store.selectSignal(unrealFeature.selectDataChannelConnected);
210
+ ```
211
+
212
+ **Key selectors:**
213
+
214
+ - `selectTotalProgress` — Scene load progress (0–1 float)
215
+ - `selectShowLoader` — Whether loader screen should be visible
216
+ - `selectShowReconnectPopup` — Whether reconnect popup should be shown
217
+ - `selectIsVideoPlayingAndDataChannelConnected` — Combined readiness check
218
+ - `selectStreamConfig` — Current stream configuration
219
+ - `unrealFeature.selectCirrusConnected` — Signalling server connection status
220
+ - `unrealFeature.selectDataChannelConnected` — Data channel status
221
+ - `unrealFeature.selectViewportReady` — Viewport readiness
222
+
223
+ **Key actions:**
224
+
225
+ - `startStream` — Start streaming with config
226
+ - `setConfig` — Update stream configuration
227
+ - `setOrchestrationContext` — Set orchestration URLs and environment
228
+ - `disconnectStream` — Disconnect with reason
229
+ - `destroyUnrealScene` — Full teardown
230
+ - `reconnectPeer` — Trigger peer reconnection
231
+
232
+ ## Exported API
233
+
234
+ ### Components
235
+
236
+ | Component | Selector | Description |
237
+ | -------------------------------- | ------------------ | -------------------------------------- |
238
+ | `UnrealSceneComponent` | `app-unreal-scene` | Main scene container with video stream |
239
+ | `AfkTimeoutModalComponent` | — | AFK timeout warning modal |
240
+ | `FreezeFrameComponent` | — | Freeze frame overlay |
241
+ | `LowBandwidthModalComponent` | — | Low bandwidth warning modal |
242
+ | `LowBandwidthIndicatorComponent` | — | Low bandwidth indicator |
243
+ | `ImageLoadingSrcComponent` | — | Loading image overlay |
244
+ | `IntroSrcComponent` | — | Intro image/video overlay |
245
+ | `VideoStatsComponent` | — | Video statistics display |
246
+ | `StatGraphComponent` | — | Statistics graph |
247
+ | `WebrtcErrorModalComponent` | — | WebRTC error modal |
248
+
249
+ ### Services
250
+
251
+ | Service | Description |
252
+ | ------------------------------ | ---------------------------------------------- |
253
+ | `UnrealCommunicatorService` | Send commands and UI interactions to Unreal |
254
+ | `AggregatorService` | Aggregates data channel messages from Unreal |
255
+ | `SignallingService` | Manages WebSocket signalling connection |
256
+ | `VideoService` | Manages video element and stats |
257
+ | `WebRtcPlayerService` | Manages WebRTC peer connection |
258
+ | `FreezeFrameService` | Handles freeze frame images |
259
+ | `AFKService` | AFK (away from keyboard) detection and timeout |
260
+ | `DevModeService` | Toggle dev mode for debugging |
261
+ | `FileReceiverService` | Receives files from Unreal via data channel |
262
+ | `FileHandlerService` | Processes received files |
263
+ | `RegionsPingService` | Pings regions to determine latency |
264
+ | `CommandTelemetryService` | Records command telemetry |
265
+ | `StreamStatusTelemetryService` | Reports stream status telemetry |
266
+ | `AnalyticsService` | Analytics event tracking |
267
+ | `FpsMonitorService` | FPS monitoring |
268
+
269
+ ### Pipes
270
+
271
+ | Pipe | Description |
272
+ | -------------- | ------------------------------- |
273
+ | `SafeHtmlPipe` | Bypasses Angular HTML sanitizer |
274
+
275
+ ### Interfaces
276
+
277
+ | Interface | Description |
278
+ | ----------------------- | --------------------------------------------- |
279
+ | `UnrealInitialConfig` | Shape for `UNREAL_CONFIG` injection token |
280
+ | `ReconnectConfig` | Auto-reconnection behavior configuration |
281
+ | `StreamConfig` | Stream configuration (autoStart, warnTimeout) |
282
+ | `StreamResolutionProps` | Stream resolution width/height |
283
+
150
284
  ## Features
151
285
 
152
286
  - Standalone Unreal Scene Component
153
- - Command and UI Interaction API via UnrealCommunicatorService
154
- - Event-driven status UI (freeze frame, video stats, play overlay)
287
+ - Command and UI Interaction API via `UnrealCommunicatorService`
288
+ - Event-driven status UI (freeze frame, video stats, play overlay, AFK, low bandwidth)
155
289
  - NgRx-powered state management and effects
156
- - Optional initial configuration via UNREAL_CONFIG token
290
+ - **Required** initial configuration via `UNREAL_CONFIG` injection token
291
+ - Auto-reconnection on WebRTC/DataChannel failures (configurable)
292
+ - File receiving from Unreal Engine via data channel
293
+ - Analytics and FPS monitoring
294
+ - Playwright testing mode with mock service substitution
157
295
 
158
296
  ## Examples
159
297
 
@@ -163,6 +301,8 @@ Check the demo application for complete usage examples:
163
301
  npm run demo:start
164
302
  ```
165
303
 
304
+ See also: `projects/demo/src/app/demo-layout/info-pages/unreal-scene-demo/constants/unreal.routes.ts` for a real-world provider configuration example.
305
+
166
306
  ## Engine requirements
167
307
 
168
308
  - Node.js: >=20