senza-sdk 4.2.64-70c0747.0 → 4.2.65-90c49ac.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.
Files changed (26) hide show
  1. package/dist/bundle.js +1 -1
  2. package/package.json +7 -15
  3. package/src/{implementation/alarmManager.js → alarmManager.js} +52 -15
  4. package/src/api.js +350 -183
  5. package/src/{implementation/deviceManager.js → deviceManager.js} +65 -4
  6. package/src/{implementation/lifecycle.js → lifecycle.js} +215 -28
  7. package/src/{implementation/messageManager.js → messageManager.js} +6 -6
  8. package/src/{implementation/platformManager.js → platformManager.js} +4 -5
  9. package/src/{implementation/remotePlayer.js → remotePlayer.js} +22 -18
  10. package/src/{implementation/senzaShakaPlayer.js → senzaShakaPlayer.js} +28 -18
  11. package/src/{implementation/utils.js → utils.js} +6 -15
  12. package/src/implementation/api.js +0 -367
  13. package/src/interface/alarmManager.js +0 -69
  14. package/src/interface/api.js +0 -8
  15. package/src/interface/deviceManager.js +0 -133
  16. package/src/interface/lifecycle.js +0 -278
  17. package/src/interface/messageManager.js +0 -46
  18. package/src/interface/platformManager.js +0 -35
  19. package/src/interface/remotePlayer.js +0 -441
  20. package/src/interface/senzaShakaPlayer.js +0 -171
  21. package/src/interface/utils.js +0 -45
  22. /package/src/{implementation/SessionInfo.js → SessionInfo.js} +0 -0
  23. /package/src/{implementation/devHelper.js → devHelper.js} +0 -0
  24. /package/src/{interface/devSequence.js → devSequence.js} +0 -0
  25. /package/src/{implementation/eventListenersManager.js → eventListenersManager.js} +0 -0
  26. /package/src/{implementation/subtitlesUtils.js → subtitlesUtils.js} +0 -0
@@ -1,4 +1,3 @@
1
- import { RemotePlayer as RemotePlayerInterface } from "../interface/remotePlayer";
2
1
  import {
3
2
  getFCID,
4
3
  isAudioSyncConfigured,
@@ -83,7 +82,7 @@ function setPlaybackInfo(playbackInfo) {
83
82
  * @fires seeked (Not implemented yet)
84
83
  * @fires loadedmetadata (Not implemented yet)
85
84
  */
86
- class RemotePlayer extends RemotePlayerInterface {
85
+ class RemotePlayer extends EventTarget {
87
86
  constructor() {
88
87
  super();
89
88
  /**
@@ -1134,8 +1133,13 @@ class RemotePlayer extends RemotePlayerInterface {
1134
1133
 
1135
1134
  // If seeking in progress, wait for seek to complete before playing
1136
1135
  if (this._isSeekingByApplication) {
1137
- sdkLogger.info("application requesting play during seek");
1138
- this._targetSeekPlayingState = TargetPlayingState.PLAYING_UI;
1136
+ if (lifecycle.state === lifecycle.UiState.FOREGROUND) {
1137
+ sdkLogger.info("application requesting play during seek. setting targetSeekPlayingState to PLAYING_UI");
1138
+ this._targetSeekPlayingState = TargetPlayingState.PLAYING_UI;
1139
+ } else {
1140
+ sdkLogger.info("application requesting play during seek. setting targetSeekPlayingState to PLAYING_ABR");
1141
+ this._targetSeekPlayingState = TargetPlayingState.PLAYING_ABR;
1142
+ }
1139
1143
  return Promise.resolve(true);
1140
1144
  }
1141
1145
  /*
@@ -1657,9 +1661,7 @@ class RemotePlayer extends RemotePlayerInterface {
1657
1661
  }
1658
1662
  }
1659
1663
 
1660
- // Only allow seeking in foreground. Still ignore the initialized local player seeking event above
1661
- if (this._remotePlayerApiVersion >= 2 && !this._isSeekingByPlatform && !this._isSeekingByApplication &&
1662
- (lifecycle.state === lifecycle.UiState.FOREGROUND || lifecycle.state === lifecycle.UiState.IN_TRANSITION_TO_FOREGROUND)) {
1664
+ if (this._remotePlayerApiVersion >= 2 && !this._isSeekingByPlatform && !this._isSeekingByApplication) {
1663
1665
  this._atomicSeek();
1664
1666
  } else {
1665
1667
  sdkLogger.info(`Seeking: skipping seeking event to currentTime: ${playbackPosition}, internalSeek: ${this._isSeekingByPlatform}, localPlayerSeek: ${this._isSeekingByApplication}, state: ${lifecycle.state}`);
@@ -1678,16 +1680,16 @@ class RemotePlayer extends RemotePlayerInterface {
1678
1680
  * */
1679
1681
  async _atomicSeek() {
1680
1682
  sdkLogger.info("Seeking: local video element seeking start while isPlaying: ", this._isPlaying);
1681
-
1682
- // Initialize the target playing state unless changed during the seek process
1683
- // In the future, we should allow for seeking in background. Currently, there's no
1684
- // way to know when the web application will call moveToForeground (i.e Before/After seek)
1685
- // Therefore, for now, we will assume the target is either paused or playing in ui unless
1686
- // specifically receiving a moveToBackground during the process.
1687
- // if (this._isPlaying && (lifecycle.state === lifecycle.UiState.BACKGROUND || lifecycle.state === lifecycle.UiState.IN_TRANSITION_TO_BACKGROUND)) {
1688
- // this._targetSeekPlayingState = TargetPlayingState.PLAYING_ABR;
1689
- // }
1690
- this._targetSeekPlayingState = this._isPlaying ? TargetPlayingState.PLAYING_UI : TargetPlayingState.PAUSED;
1683
+ if (this._isPlaying) {
1684
+ if (!lifecycle._inTransitionToForeground && (lifecycle._inTransitionToBackground || lifecycle.state === lifecycle.UiState.BACKGROUND || lifecycle.state === lifecycle.UiState.IN_TRANSITION_TO_BACKGROUND)) {
1685
+ sdkLogger.info("seek in background", this._isPlaying);
1686
+ this._targetSeekPlayingState = TargetPlayingState.PLAYING_ABR;
1687
+ } else {
1688
+ this._targetSeekPlayingState = TargetPlayingState.PLAYING_UI;
1689
+ }
1690
+ } else {
1691
+ this._targetSeekPlayingState = TargetPlayingState.PAUSED;
1692
+ }
1691
1693
 
1692
1694
  // The platform could be currently syncing audio/video using playback rate. Reset when performing seek.
1693
1695
  if (this._videoElement) {
@@ -1754,7 +1756,7 @@ class RemotePlayer extends RemotePlayerInterface {
1754
1756
 
1755
1757
  // If in TargetPlayingState.PAUSE, no need to resume.
1756
1758
  // Resume without awaiting to avoid blocking the seek process anymore
1757
- // In case where we aborted, we don't want to resume playback.
1759
+ // In case where we aborted (new load or unload called), we don't want to resume playback.
1758
1760
  if (!this._abortSeeking) {
1759
1761
  if (this._targetSeekPlayingState === TargetPlayingState.PLAYING_UI) {
1760
1762
  if (!this._isAudioSyncEnabled()) {
@@ -1763,6 +1765,8 @@ class RemotePlayer extends RemotePlayerInterface {
1763
1765
  // resume audio play only if _isAudioSyncEnabled
1764
1766
  this._play(StreamType.AUDIO);
1765
1767
  } else if (this._targetSeekPlayingState === TargetPlayingState.PLAYING_ABR) {
1768
+ // When moving back to background, we need to put the remote player back into play mode
1769
+ this._changePlayMode(true);
1766
1770
  lifecycle._moveToBackground();
1767
1771
  }
1768
1772
  }
@@ -1,5 +1,4 @@
1
- import { shaka } from "../interface/senzaShakaPlayer";
2
-
1
+ import * as shaka from "shaka-player";
3
2
  import { remotePlayer, lifecycle, getPlatformInfo } from "./api";
4
3
  import { sdkLogger, iso6393to1 } from "./utils";
5
4
 
@@ -31,6 +30,11 @@ class SenzaError extends shaka.util.Error {
31
30
  }
32
31
 
33
32
 
33
+ // Copy the shaka module and replace the Player class with SenzaShakaPlayer
34
+ // if we don't Copy the shaka module, the Player class will be replaced for all the other modules that import shaka
35
+ const senzaShaka = { ...shaka };
36
+
37
+
34
38
  /**
35
39
  * SenzaShakaPlayer subclass of Shaka that handles both local and remote playback.
36
40
  *
@@ -74,7 +78,7 @@ export class SenzaShakaPlayer extends shaka.Player {
74
78
  * @description Timeout in milliseconds to wait for playing event
75
79
  * @default 3000
76
80
  */
77
- _playingTimeout = 3000;
81
+ _playingTimeout = 4000;
78
82
 
79
83
  /**
80
84
  * @private
@@ -89,7 +93,7 @@ export class SenzaShakaPlayer extends shaka.Player {
89
93
  * @description Whether to stop remote player on error
90
94
  * @default false
91
95
  */
92
- _shouldStopRemotePlayerOnError = false;
96
+ _shouldStopOnRemotePlayerError = false;
93
97
 
94
98
  /**
95
99
  * @private
@@ -181,7 +185,7 @@ export class SenzaShakaPlayer extends shaka.Player {
181
185
  originatesFromRemotePlayer: true
182
186
  };
183
187
 
184
- const response = await this.getNetworkingEngine().request(shaka.net.NetworkingEngine.RequestType.LICENSE, request).promise;
188
+ const response = await this.getNetworkingEngine().request(senzaShaka.net.NetworkingEngine.RequestType.LICENSE, request).promise;
185
189
 
186
190
  let responseBody = response.data;
187
191
  if (response.status < 200 || response.status >= 300) {
@@ -280,13 +284,15 @@ export class SenzaShakaPlayer extends shaka.Player {
280
284
 
281
285
 
282
286
  /**
283
- * Handles errors for play promises and remote player events.
287
+ * Handles errors received by remote player while waiting for the playing event.
288
+ * The promise returned to the call for video element play will be rejected.
284
289
  * @private
285
290
  * @param {Error} error - The error object.
286
291
  */
287
292
  _handlePlayPromiseError(error) {
288
293
 
289
294
  sdkLogger.error("Error while waiting for playing event:", error);
295
+
290
296
  if (this._playPromiseReject) {
291
297
  this._playPromiseReject(error);
292
298
  this._playPromiseResolve = null;
@@ -296,6 +302,7 @@ export class SenzaShakaPlayer extends shaka.Player {
296
302
  clearTimeout(this._playTimeoutId);
297
303
  this._playTimeoutId = null;
298
304
  }
305
+
299
306
  }
300
307
 
301
308
  /**
@@ -556,11 +563,12 @@ export class SenzaShakaPlayer extends shaka.Player {
556
563
  const isCritical = this._isErrorCritical(remotePlayerErrorCode);
557
564
  const error = this._createSenzaError(remotePlayerErrorCode, message, isCritical);
558
565
  const errorMap = new Map();
566
+ const shouldStopPlayback = this._shouldStopOnRemotePlayerError && this.videoElement && isCritical;
559
567
  errorMap.set("detail", error);
560
568
 
561
569
  // Check if we should stop playback - only for critical errors when configured
562
- if (this._shouldStopRemotePlayerOnError &&
563
- this.videoElement && isCritical) {
570
+
571
+ if (shouldStopPlayback) {
564
572
  try {
565
573
  sdkLogger.warn("Stopping local player playback due to critical error");
566
574
  // Stop only local playback
@@ -568,9 +576,11 @@ export class SenzaShakaPlayer extends shaka.Player {
568
576
  } catch (stopError) {
569
577
  sdkLogger.error("Error while trying to stop video element playback:", stopError);
570
578
  }
579
+ // Handle error while waiting for play event. If the error is not critical or the system is configured not to stop remote player on error,
580
+ // the playback timeout will start the local playback
581
+ this._handlePlayPromiseError(error);
571
582
  }
572
- // Handle error while waiting for play event
573
- this._handlePlayPromiseError(error);
583
+
574
584
  this.dispatchEvent(new shaka.util.FakeEvent("error", errorMap));
575
585
  }
576
586
 
@@ -680,14 +690,14 @@ export class SenzaShakaPlayer extends shaka.Player {
680
690
  /**
681
691
  * Override the configure method to add custom configuration handling
682
692
  * Supports the following additional configuration options:
683
- * - shouldStopRemotePlayerOnError: boolean - If true, remote player will be stopped on error
693
+ * - shouldStopOnRemotePlayerError: boolean - If true, local player will be stopped on remote player error
684
694
  *
685
695
  * @override
686
696
  * @param {Object} config - Configuration object to be merged with existing config
687
- * @param {boolean} [config.shouldStopRemotePlayerOnError=true] - Whether to stop remote player on error
697
+ * @param {boolean} [config.shouldStopOnRemotePlayerError=true] - Whether to stop local player on remote player error
688
698
  * @example
689
699
  * player.configure({
690
- * shouldStopRemotePlayerOnError: false, // Don't stop remote player on error
700
+ * shouldStopOnRemotePlayerError: false, // Don't stop local playback on remote player error
691
701
  * // ... other shaka configurations
692
702
  * });
693
703
  */
@@ -695,12 +705,12 @@ export class SenzaShakaPlayer extends shaka.Player {
695
705
  sdkLogger.log("configure player with: ", JSON.stringify(config));
696
706
 
697
707
  // Handle custom configuration
698
- if (config.shouldStopRemotePlayerOnError !== undefined) {
699
- this._shouldStopRemotePlayerOnError = !!config.shouldStopRemotePlayerOnError;
708
+ if (config.shouldStopOnRemotePlayerError !== undefined) {
709
+ this._shouldStopOnRemotePlayerError = !!config.shouldStopOnRemotePlayerError;
700
710
  // Remove our custom config so it doesn't get passed to parent
701
711
  // Use rest operator without creating a named variable for the removed property
702
712
  // eslint-disable-next-line no-unused-vars
703
- const { shouldStopRemotePlayerOnError, ...shakaConfig } = config;
713
+ const { shouldStopOnRemotePlayerError, ...shakaConfig } = config;
704
714
  config = shakaConfig;
705
715
  }
706
716
 
@@ -800,5 +810,5 @@ export class SenzaShakaPlayer extends shaka.Player {
800
810
 
801
811
  }
802
812
 
803
- shaka.Player = SenzaShakaPlayer;
804
- export { shaka };
813
+ senzaShaka.Player = SenzaShakaPlayer;
814
+ export { senzaShaka as shaka };
@@ -1,15 +1,10 @@
1
1
  import { getPlatformInfo } from "./api";
2
+ import pack from "../package.json";
2
3
  import { sessionInfo } from "./SessionInfo";
4
+ const { version } = pack;
3
5
 
4
6
  const REST_RESPONSE_TIMEOUT_SECONDS = 5;
5
7
 
6
- export function getVersion() {
7
- return typeof IMPLEMENTATION_VERSION !== "undefined"
8
- // eslint-disable-next-line no-undef
9
- ? IMPLEMENTATION_VERSION
10
- : "unknown";
11
- };
12
-
13
8
  export function getFCID() {
14
9
  return Math.round(Math.random() * 100000) + "-" + getPlatformInfo().sessionInfo?.connectionId;
15
10
  }
@@ -47,7 +42,7 @@ class SdkLogger {
47
42
  console.info(`[hs-sdk] [metrics] ${JSON.stringify(metricObj)}`);
48
43
  }
49
44
  withFields(logFields) {
50
- return new SdkLogger({ ...this.logFields, ...logFields });
45
+ return new SdkLogger({...this.logFields, ...logFields});
51
46
  }
52
47
  formatLogString(data) {
53
48
  let logString = "[hs-sdk] " + data.join(" ");
@@ -56,13 +51,9 @@ class SdkLogger {
56
51
  }
57
52
  return logString;
58
53
  }
59
- addfields(fields) {
60
- this.logFields = { ...this.logFields, ...fields };
61
- return this;
62
- }
63
54
  }
64
55
 
65
- export const sdkLogger = new SdkLogger({ sdkVersion: getVersion(), url: window?.location?.href ?? "" });
56
+ export const sdkLogger = new SdkLogger({sdkVersion: version, url: window?.location?.href ?? ""});
66
57
 
67
58
  export async function getRestResponse(messageName) {
68
59
 
@@ -73,14 +64,14 @@ export async function getRestResponse(messageName) {
73
64
 
74
65
  return new Promise((resolve, reject) => {
75
66
  const FCID = getFCID();
76
- const logger = sdkLogger.withFields({ FCID });
67
+ const logger = sdkLogger.withFields({FCID});
77
68
  const message = {
78
69
  type: "restRequest",
79
70
  name: messageName,
80
71
  method: "GET",
81
72
  fcid: FCID
82
73
  };
83
- const request = { target: "TC", waitForResponse: true, message: JSON.stringify(message) };
74
+ const request = {target: "TC", waitForResponse: true, message: JSON.stringify(message)};
84
75
  let timeoutHandler = 0;
85
76
  const queryId = window.cefQuery({
86
77
  request: JSON.stringify(request),
@@ -1,367 +0,0 @@
1
- import { getFCID, sdkLogger, getVersion } from "./utils.js";
2
- import { sessionInfo } from "./SessionInfo.js";
3
- import { lifecycle } from "./lifecycle.js";
4
- import { alarmManager } from "./alarmManager.js";
5
-
6
- let authToken;
7
-
8
- const API_VERSION = "1.0";
9
- let interfaceVersion;
10
-
11
- typeof document !== "undefined" && document.addEventListener("keydown", (event) => {
12
- sdkLogger.log(`Got ${event.key} key`);
13
- });
14
-
15
- /** @namespace auth
16
- *@example
17
- * import { auth } from "senza-sdk";
18
- **/
19
- export const auth = {
20
-
21
- /** Should be called upon startup and be embedded in future requests */
22
- getToken,
23
-
24
- /** Should be called upon '401' event (unauthorized) */
25
- forceTokenUpdate,
26
-
27
- getClientAssertion
28
-
29
- };
30
-
31
- import { remotePlayer } from "./remotePlayer.js";
32
- export { remotePlayer };
33
-
34
- /** Should be called once to init the library
35
- *@example
36
- * import { init } from "senza-sdk";
37
- * await init();
38
- **/
39
- export async function init(interfaceApiVersion, showSequenceFunc, initSequenceFunc) {
40
- interfaceVersion = interfaceApiVersion;
41
- sdkLogger.addfields({ interfaceVersion });
42
- sdkLogger.log(`init. Interface version: ${interfaceVersion}. Implementation version: ${getVersion()}`);
43
-
44
- if (!window.diagnostics) {
45
- // ------------------------------------------------------------------------------------------------
46
- // -- Do NOT change this log, as ui-streamer is checking this string to detect abnormal behavior --
47
- // ------------------------------------------------------------------------------------------------
48
- sdkLogger.error("[ init ] window.diagnostics is undefined");
49
- }
50
-
51
- if (window.cefQuery) {
52
-
53
- // First, check compatability with ui-streamer api version
54
- await new Promise((resolve, reject) => {
55
- window.cefQuery({
56
- request: "apiVersion " + API_VERSION,
57
- persistent: false,
58
- onSuccess: () => {
59
- sdkLogger.log("api version compatability check succeeded");
60
- resolve();
61
- },
62
- onFailure: (code, msg) => {
63
- sdkLogger.error("api version compatability check failed: " + msg);
64
- reject(msg);
65
- }
66
- });
67
- });
68
-
69
- const sessionInfoStr = await new Promise((resolve) => {
70
- window.cefQuery({
71
- request: "sessionInfo",
72
- persistent: false,
73
- onSuccess: (response) => {
74
- sdkLogger.log("sessionInfo request successfully returned " + response);
75
- resolve(response);
76
- },
77
- onFailure: (code, msg) => {
78
- sdkLogger.error(`sessionInfo request failed: ${code} ${msg}`);
79
- }
80
- });
81
- });
82
-
83
- sessionInfo.setSessionInfoStr(sessionInfoStr);
84
- const sessionInfoObj = JSON.parse(sessionInfoStr);
85
- authToken = sessionInfoObj?.settings?.webUI?.backendHeaders?.Authorization;
86
- sdkLogger.log(`authToken: token = ${authToken}`);
87
- // Listen to updateSession event to set the new token
88
- document.addEventListener("updateSession", (e) => {
89
- authToken = e.detail?.updateObj;
90
- sdkLogger.log(`onUpdateSessionEvent: token = ${authToken}`);
91
- });
92
-
93
- // Set default alarm timeout using UI-Streamer settings
94
- const alarmTimeout = sessionInfoObj?.settings?.["ui-streamer"]?.alarmTimeout;
95
- if (alarmTimeout) {
96
- alarmManager._setDefaultTimeout(alarmTimeout);
97
- }
98
-
99
- // Get trigger event
100
- const triggerEventStr = await new Promise((resolve) => {
101
- const FCID = getFCID();
102
- const logger = sdkLogger.withFields({ FCID });
103
- const message = { type: "triggerEvent", fcid: FCID };
104
- const request = { target: "UI-Streamer", waitForResponse: false, message: JSON.stringify(message) };
105
- window.cefQuery({
106
- request: JSON.stringify(request),
107
- persistent: false,
108
- onSuccess: (response) => {
109
- logger.log(`triggerEvent request successfully returned '${response}'`);
110
- resolve(response);
111
- },
112
- onFailure: (code, msg) => {
113
- logger.error(`triggerEvent request failed: ${code} ${msg}`);
114
- resolve("");
115
- }
116
- });
117
- });
118
- let triggerEvent = {};
119
- if (triggerEventStr) {
120
- try {
121
- triggerEvent = JSON.parse(triggerEventStr);
122
- } catch (e) {
123
- sdkLogger.error(`failed to parse trigger event string ${triggerEventStr}: ${e.message}`);
124
- }
125
- }
126
-
127
- // Initialize lifecycle first to make sure the state is updated.
128
- await lifecycle._init(sessionInfoObj?.settings?.["ui-streamer"], triggerEvent);
129
- await remotePlayer._init(sessionInfoObj?.settings?.["ui-streamer"], triggerEvent);
130
-
131
- const devSequence = sessionInfoObj?.settings?.["ui-streamer"]?.devSequence;
132
- if (devSequence) {
133
- initSequenceFunc({ lifecycle, remotePlayer });
134
- showSequenceFunc(true);
135
- }
136
-
137
- } else {
138
- authToken = getPlatformInfo().sessionInfo?.settings?.webUI?.backendHeaders?.Authorization;
139
- sdkLogger.log(`authToken dummy: token = ${authToken}`);
140
- }
141
-
142
- // override window.close() since it's not allowed to close the application this way
143
- window.close = () => {
144
- sdkLogger.warn("window.close is disabled on Senza platform. Use lifecycle.exitApplication() instead.");
145
- };
146
-
147
-
148
- }
149
-
150
- // Returns the platform information, including version, pod, pod ip and session info.
151
- export function getPlatformInfo() {
152
- if (typeof window !== "undefined" && window.diagnostics) {
153
- try {
154
- const platformInfo = window.diagnostics() || {};
155
- platformInfo.sessionInfo = sessionInfo.sessionInfoObj;
156
- return platformInfo;
157
- } catch (e) {
158
- sdkLogger.error("Could not get platform info", e.stack);
159
- }
160
-
161
- } else {
162
- if (typeof window !== "undefined" && !window.diagnostics) {
163
- sdkLogger.error("[ getPlatformInfo ] window.diagnostics is undefined");
164
- }
165
- return {
166
- version: "X.X.XX-X",
167
- pod: "ui-streamer-X.X.XX-X-QWERT-ASDFG-XXX-XXXXXX-XXXXX",
168
- podIP: "0.0.0.0",
169
- sessionInfo: {
170
- userAgent: "SynamediaSenza/XX.YY.ZZ",
171
- connectionId: "dummy",
172
- deviceId: "123456789",
173
- community: "LocalDev",
174
- tenant: "XXXXXX",
175
- tenantId: "XXXXXX",
176
- manifest: {
177
- transcontainer: "X.X.XX-X"
178
- },
179
- settings: {
180
- webUI: {
181
- backendHeaders: {
182
- Authorization: "Bearer dummytoken"
183
- }
184
- }
185
- },
186
- homeSessionInfo: {
187
- tenantId: "XXXXXX",
188
- community: "LocalDev"
189
- }
190
- }
191
- };
192
- }
193
- }
194
-
195
- async function getToken() {
196
- if (!authToken) {
197
- sdkLogger.log("getToken wait for promise updateSession event");
198
- return new Promise((resolve) => {
199
- // Listen to updateSession event to set the new token
200
- document.addEventListener("updateSession", (e) => {
201
- authToken = e.detail?.updateObj;
202
- sdkLogger.log(`onUpdateSessionEvent: token= ${authToken}`);
203
- resolve(authToken);
204
- }, { once: true });
205
- });
206
- }
207
- return Promise.resolve(authToken);
208
- }
209
-
210
- function forceTokenUpdate() {
211
- authToken = null;
212
-
213
- if (window.cefQuery) {
214
- const FCID = getFCID();
215
- const logger = sdkLogger.withFields({ FCID });
216
- logger.log("forceTokenUpdate: sending updateSessionRequest");
217
- const message = {
218
- type: "updateSessionRequest",
219
- updateKey: "authorization",
220
- parentPath: "settings.webUI.backendHeaders.Authorization",
221
- fcid: FCID
222
- };
223
- const request = { target: "TC", waitForResponse: false, message: JSON.stringify(message) };
224
- window.cefQuery({
225
- request: JSON.stringify(request),
226
- persistent: false,
227
- onSuccess: () => {
228
- logger.log("updateSessionRequest successfully sent");
229
- },
230
- onFailure: (code, msg) => {
231
- logger.error(`updateSessionRequest failed: ${code} ${msg}`);
232
- }
233
- });
234
- } else {
235
- sdkLogger.error("forceTokenUpdate: window.cefQuery is undefined");
236
- }
237
- }
238
-
239
- /** Returns a boolean that indicates whether we are running in an e2e environment, or on local browser */
240
- export function isRunningE2E() {
241
- return !!(typeof window !== "undefined" && window.cefQuery);
242
- }
243
-
244
- /** Call this API once after application startup, when the ui is ready to accept keys/events */
245
- export function uiReady() {
246
- if (window.cefQuery) {
247
- window.cefQuery({
248
- request: "uiReady",
249
- persistent: false,
250
- onSuccess: () => {
251
- sdkLogger.log("uiReady request successfully sent");
252
- },
253
- onFailure: (code, msg) => {
254
- sdkLogger.error(`uiReady request failed: ${code} ${msg}`);
255
- }
256
- });
257
- } else {
258
- sdkLogger.error("uiReady: window.cefQuery is undefined");
259
- }
260
- }
261
-
262
- export { lifecycle } from "./lifecycle.js";
263
- export { deviceManager } from "./deviceManager.js";
264
- export { platformManager } from "./platformManager.js";
265
- export { alarmManager };
266
- export { messageManager } from "./messageManager.js";
267
- export { SenzaShakaPlayer as ShakaPlayer, shaka } from "./senzaShakaPlayer.js";
268
-
269
- import "./devHelper.js";
270
-
271
- /**
272
- * The function receives a license response and passes it to platform.
273
- * @param {number} statusCode status code that was received from the license server
274
- * @param {ArrayBuffer|string} licenseResponse a license response that was received from the license server to be passed to platform.
275
- * @param {string} fcid a fcid received with the license request
276
- * @param {string} sessionId a sessionId received with the license request
277
- * In case of success licenceResponse is of type @type {ArrayBuffer}
278
- * In case of error licenseResponse is of type @type {string}
279
- */
280
- export function writeLicenseResponse(statusCode, licenseResponse, fcid, sessionId) {
281
-
282
- if (statusCode >= 200 && statusCode < 300) {
283
- licenseResponse = window.btoa(String.fromCharCode.apply(null, new Uint8Array(licenseResponse))); // to base64
284
- }
285
-
286
- if (window.cefQuery) {
287
- const message = {
288
- type: "updateLicense",
289
- sessionId,
290
- fcid
291
- };
292
- message[statusCode >= 200 && statusCode < 300 ? "response" : "error"] = licenseResponse;
293
- const request = { target: "TC", waitForResponse: false, message: JSON.stringify(message) };
294
- window.cefQuery({
295
- request: JSON.stringify(request),
296
- persistent: false,
297
- onSuccess: () => {
298
- sdkLogger.log("updateLicense request successfully sent");
299
- },
300
- onFailure: (code, msg) => {
301
- sdkLogger.error(`updateLicense request failed: ${code} ${msg}`);
302
- }
303
- });
304
- }
305
-
306
- }
307
-
308
- export class ClientAssertionError extends Error {
309
- constructor(code, message) {
310
- super(message);
311
- this.code = code;
312
- }
313
- }
314
-
315
- /**
316
- * @typedef Token
317
- * @property {string} hostplatform_assertion The client assertion token.
318
- */
319
-
320
- /**
321
- * Async function that returns the client assertion
322
- * @return {Promise<Token>} Promise which is resolved to a client assertion object when getClientAssertion has been successfully performed. * client assertion object contains hostplatform_assertion property which holds the client assertion token.
323
- * Failure to getClientAssertion for any reason, result in the promise being rejected.
324
- * Error status codes:
325
- * Status code 400 - Tenant configuration is missing
326
- * Status code 0 - General error
327
- * @example
328
- * try {
329
- * const client_assertion = await auth.getClientAssertion();
330
- * console.log("Client assertion token is", client_assertion.hostplatform_assertion);
331
- * } catch (e) {
332
- * console.error("getClientAssertion failed", e);
333
- * }
334
- */
335
- export function getClientAssertion() {
336
- if (window.cefQuery) {
337
- sdkLogger.log("getClientAssertion is called");
338
-
339
- return new Promise((resolve, reject) => {
340
- window.cefQuery({
341
- request: "client_assertion",
342
- persistent: false,
343
- onSuccess: (response) => {
344
- try {
345
- const json_response = JSON.parse(response);
346
- sdkLogger.log(`client_assertion request successfully returned ${response}`);
347
- resolve(json_response);
348
- } catch (e) {
349
- sdkLogger.error(`Failed to parse client assertion ${response}: ${e.message}`);
350
- reject(new ClientAssertionError(0, "Failed to parse client assertion"));
351
- }
352
-
353
- },
354
- onFailure: (code, msg) => {
355
- sdkLogger.log(`client_assertion request failed: ${code} ${msg}`);
356
- reject(new ClientAssertionError(code, msg));
357
- }
358
- });
359
- });
360
- }
361
- sdkLogger.warn("getClientAssertion is not supported if NOT running e2e");
362
- }
363
-
364
- import * as senzaSDK from "./api.js";
365
- if (typeof window !== "undefined") {
366
- window.senzaSDKImplementation = window.senzaSDKImplementation || senzaSDK; // this is only for testing purposes which allows us to use and test senza APIs in pipeline tests
367
- }