@24i/bigscreen-sdk 0.9.9-alpha.2148 → 0.9.9-alpha.2150

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 (80) hide show
  1. package/__mocks__/@24i/bigscreen-sdk/animations.ts +2 -0
  2. package/package.json +1 -1
  3. package/packages/animations/src/__mocks__/JSAnimations.ts +30 -0
  4. package/packages/conviva/src/__mocks__/ConvivaMock.ts +36 -0
  5. package/packages/developer-tools/src/DeveloperConsole/utils/formatTime.ts +13 -0
  6. package/packages/developer-tools/src/DeveloperConsole/utils/index.ts +3 -0
  7. package/packages/developer-tools/src/DeveloperConsole/utils/stringify.ts +10 -0
  8. package/packages/developer-tools/src/DeveloperConsole/utils/styles.ts +24 -0
  9. package/packages/developer-tools/src/EnvironmentSelection/utils/format.ts +4 -0
  10. package/packages/developer-tools/src/TechnicalInfo/__mocks__/Device.ts +51 -0
  11. package/packages/developer-tools/src/TechnicalInfo/__mocks__/Player.ts +7 -0
  12. package/packages/developer-tools/src/TechnicalInfo/__mocks__/Storage.ts +9 -0
  13. package/packages/developer-tools/src/TechnicalInfo/utils/eme01bSupport.ts +58 -0
  14. package/packages/developer-tools/src/TechnicalInfo/utils/emeSupport.ts +80 -0
  15. package/packages/developer-tools/src/TechnicalInfo/utils/formatTimezone.ts +15 -0
  16. package/packages/developer-tools/src/TechnicalInfo/utils/mseSupport.ts +14 -0
  17. package/packages/developer-tools/src/utils/reload.ts +6 -0
  18. package/packages/driver-base/src/__mocks__/DeviceBase.ts +100 -0
  19. package/packages/driver-base/src/__mocks__/keyMap.ts +41 -0
  20. package/packages/driver-entone/src/__mocks__/entone.ts +177 -0
  21. package/packages/driver-hbbtv/src/__mocks__/hbbtv.ts +17 -0
  22. package/packages/driver-kreatv/src/__mocks__/toi2.ts +76 -0
  23. package/packages/driver-kreatv/src/__mocks__/toi3.ts +43 -0
  24. package/packages/driver-saphi/src/__mocks__/SmartTvA_API.ts +11 -0
  25. package/packages/driver-saphi/src/__mocks__/userAgent.ts +4 -0
  26. package/packages/driver-tizen/src/__mocks__/tizen.ts +35 -0
  27. package/packages/driver-webos/src/__mocks__/webos.ts +172 -0
  28. package/packages/driver-xbox/src/__mocks__/Windows.ts +94 -0
  29. package/packages/gallup/src/__mocks__/SpringStreams.js +18 -0
  30. package/packages/input/__mocks__/MockKeyboard.ts +40 -0
  31. package/packages/keyboard/src/utils/caret.ts +48 -0
  32. package/packages/keyboard/src/utils/generateFocusMatrixFromStringMatrix.ts +12 -0
  33. package/packages/keyboard/src/utils/input.ts +40 -0
  34. package/packages/list/utils/index.ts +1 -0
  35. package/packages/logger/src/__mocks__/LoggerBase.ts +13 -0
  36. package/packages/logger/src/utils/deviceInfo.ts +25 -0
  37. package/packages/logger/src/utils/index.ts +1 -0
  38. package/packages/utils/README.md +336 -0
  39. package/packages/utils/src/addClass.ts +9 -0
  40. package/packages/utils/src/counter.ts +47 -0
  41. package/packages/utils/src/debounce.ts +54 -0
  42. package/packages/utils/src/displayToggler.scss +3 -0
  43. package/packages/utils/src/displayToggler.ts +38 -0
  44. package/packages/utils/src/elementUtils.ts +58 -0
  45. package/packages/utils/src/generateUuid.ts +19 -0
  46. package/packages/utils/src/index.ts +35 -0
  47. package/packages/utils/src/memoryInfo.ts +21 -0
  48. package/packages/utils/src/nTimes.ts +9 -0
  49. package/packages/utils/src/noop.ts +1 -0
  50. package/packages/utils/src/offsetPosition.ts +56 -0
  51. package/packages/utils/src/removeClass.ts +9 -0
  52. package/packages/utils/src/scaledImage.ts +21 -0
  53. package/packages/utils/src/stopEvent.ts +10 -0
  54. package/packages/utils/src/timeConstants.ts +11 -0
  55. package/packages/utils/src/timers/createInterval.ts +19 -0
  56. package/packages/utils/src/timers/createTimeout.ts +22 -0
  57. package/packages/utils/src/timers/index.ts +4 -0
  58. package/packages/utils/src/timers/runAsync.ts +3 -0
  59. package/packages/utils/src/timers/types.ts +9 -0
  60. package/packages/utils/src/wait.ts +1 -0
  61. package/packages/utils/src/xhr/__mocks__/xhr.ts +29 -0
  62. package/packages/utils/src/xhr/index.ts +11 -0
  63. package/packages/utils/src/xhr/xhrSend.ts +139 -0
  64. package/packages/utils/src/xhr/xhrSendRetry.ts +77 -0
  65. package/packages/volume-control/src/__mocks__/VolumeControlUIMock.tsx +18 -0
  66. package/utils/create-export-maps/index.ts +3 -0
  67. package/utils/create-export-maps/src/__tests__/createExportMaps.spec.ts +50 -0
  68. package/utils/create-export-maps/src/createExportMaps.ts +61 -0
  69. package/utils/create-package/README.md +40 -0
  70. package/utils/create-package/src/createPackage.ts +72 -0
  71. package/utils/create-package/src/index.ts +3 -0
  72. package/utils/create-package/src/questionnaire/questions.ts +19 -0
  73. package/utils/create-package/src/settings/Settings.ts +5 -0
  74. package/utils/create-package/src/types.ts +4 -0
  75. package/utils/create-package/templates/typescript/README.md +9 -0
  76. package/utils/create-package/templates/typescript/exports.json +6 -0
  77. package/utils/create-package/templates/typescript/src/index.ts +0 -0
  78. package/utils/run-scripts/index.ts +3 -0
  79. package/utils/run-scripts/src/__tests__/runScripts.spec.ts +45 -0
  80. package/utils/run-scripts/src/runScripts.ts +20 -0
@@ -0,0 +1,58 @@
1
+ import { Reference, unwrapReference } from '@24i/bigscreen-sdk/jsx';
2
+
3
+ export const isElementVisible = (
4
+ elementOrReference: HTMLElement | Reference<HTMLElement>,
5
+ ) => {
6
+ const element = unwrapReference(elementOrReference);
7
+ if (!element) return false;
8
+ const style = window.getComputedStyle(element);
9
+ return style.display !== 'none' && style.visibility !== 'hidden';
10
+ };
11
+
12
+ export const isElementFullyVisible = (
13
+ elementOrReference: HTMLElement | Reference<HTMLElement>,
14
+ ) => {
15
+ const element = unwrapReference(elementOrReference);
16
+ if (isElementVisible(element)) {
17
+ let parent = element.parentElement;
18
+ while (parent) {
19
+ if (parent === document.body) {
20
+ return true;
21
+ }
22
+ if (!isElementVisible(parent)) {
23
+ return false;
24
+ }
25
+ parent = parent.parentElement;
26
+ }
27
+ return false;
28
+ }
29
+ return false;
30
+ };
31
+
32
+ export const isElementWrappedBy = (
33
+ elementOrReference: HTMLElement | Reference<HTMLElement>,
34
+ wrapperElementOrReferenceOrCondition:
35
+ HTMLElement | Reference<HTMLElement> | ((currentWrapper: HTMLElement) => boolean),
36
+ includesElementItself = false,
37
+ ) => {
38
+ const element = unwrapReference(elementOrReference);
39
+ let currentParent = includesElementItself ? element : element.parentElement;
40
+ let wrapperElement: HTMLElement | null = null;
41
+ let condition: ((currentWrapper: HTMLElement) => boolean) | null = null;
42
+ if (typeof wrapperElementOrReferenceOrCondition === 'function') {
43
+ condition = wrapperElementOrReferenceOrCondition;
44
+ } else {
45
+ wrapperElement = unwrapReference(wrapperElementOrReferenceOrCondition);
46
+ if (!wrapperElement) return false;
47
+ }
48
+ while (currentParent) {
49
+ if (condition && condition(currentParent)) {
50
+ return true;
51
+ }
52
+ if (currentParent === wrapperElement) {
53
+ return true;
54
+ }
55
+ currentParent = currentParent.parentElement;
56
+ }
57
+ return false;
58
+ };
@@ -0,0 +1,19 @@
1
+ /* eslint-disable no-magic-numbers */
2
+ /* eslint-disable no-nested-ternary */
3
+ /* eslint-disable no-bitwise */
4
+
5
+ /**
6
+ * Generates Universally Unique ID (UUIDv4 - RFC 4122)
7
+ * @returns universally unique identifier. Ex. "123e4567-e89b-12d3-a456-426614174000"
8
+ */
9
+ export const generateUuid = (): string => {
10
+ let id = '';
11
+ for (let i = 0; i < 32; i++) {
12
+ const random = Math.random() * 16 | 0;
13
+ if (i === 8 || i === 12 || i === 16 || i === 20) {
14
+ id += '-';
15
+ }
16
+ id += (i === 12 ? 4 : (i === 16 ? ((random & 3) | 8) : random)).toString(16);
17
+ }
18
+ return id;
19
+ };
@@ -0,0 +1,35 @@
1
+ export { generateUuid } from './generateUuid';
2
+ export { stopEvent } from './stopEvent';
3
+ export { noop } from './noop';
4
+ export { offsetPosition } from './offsetPosition';
5
+ export { addClass } from './addClass';
6
+ export { removeClass } from './removeClass';
7
+ export { debounce } from './debounce';
8
+ export { wait } from './wait';
9
+ export { scaledImage } from './scaledImage';
10
+ export { nTimes } from './nTimes';
11
+ export { getDisplayToggler, DISPLAY_NONE } from './displayToggler';
12
+ export type { IDisplayToggler } from './displayToggler';
13
+ export { getUsedJSHeapSize, getTotalJSHeapSize } from './memoryInfo';
14
+ export {
15
+ isElementVisible,
16
+ isElementFullyVisible,
17
+ isElementWrappedBy,
18
+ } from './elementUtils';
19
+ export { createInterval, createTimeout, runAsync } from './timers';
20
+ export type { TimedFunction } from './timers';
21
+ export { createCounter } from './counter';
22
+ export type { ICounter } from './counter';
23
+ export {
24
+ DAY_IN_MS,
25
+ HOURS_PER_DAY,
26
+ HALF_HOUR_IN_MS,
27
+ HOUR_IN_MS,
28
+ MINUTES_PER_HALF_HOUR,
29
+ MINUTES_PER_HOUR,
30
+ MINUTE_IN_MS,
31
+ SECONDS_PER_MINUTE,
32
+ SECOND_IN_MS,
33
+ } from './timeConstants';
34
+ export { xhrSend, xhrSendRetry, defaultRetryConfig, mockXhr } from './xhr';
35
+ export type { XhrOptions, XhrResponse, RetryConfig, RSOptions, ShouldRetryParam } from './xhr';
@@ -0,0 +1,21 @@
1
+ /**
2
+ * The currently active segment size of JS heap, in bytes.
3
+ * @return {Number} size value. If size is unknown, returns 0.
4
+ */
5
+
6
+ function getUsedJSHeapSize() {
7
+ return (window.performance as any)?.memory?.usedJSHeapSize as number || 0;
8
+ }
9
+
10
+ /**
11
+ * The total allocated heap size, in bytes.
12
+ * @return size value. If size is unknown, returns 0.
13
+ */
14
+ function getTotalJSHeapSize() {
15
+ return (window.performance as any)?.memory?.totalJSHeapSize as number || 0;
16
+ }
17
+
18
+ export {
19
+ getUsedJSHeapSize,
20
+ getTotalJSHeapSize,
21
+ };
@@ -0,0 +1,9 @@
1
+ import { map } from '@24i/bigscreen-sdk/perf-utils/array';
2
+
3
+ export const nTimes = <T>(
4
+ n: number,
5
+ mappingFunction: (_: undefined, index: number) => T,
6
+ ): T[] => {
7
+ const array = new Array(n);
8
+ return map(array, mappingFunction);
9
+ };
@@ -0,0 +1 @@
1
+ export const noop = () => {};
@@ -0,0 +1,56 @@
1
+ import { Reference } from '@24i/bigscreen-sdk/jsx';
2
+ import { isRtl } from '@24i/bigscreen-sdk/i18n';
3
+
4
+ type WritableCSSKeys = Exclude<(keyof CSSStyleDeclaration), 'length' | 'parentRule'>;
5
+
6
+ const isCssSupported = <T extends WritableCSSKeys>(
7
+ property: T, value: CSSStyleDeclaration[T],
8
+ ) => {
9
+ const el = document.createElement('div');
10
+ if (el.style[property] === undefined) {
11
+ return false;
12
+ }
13
+ el.style[property] = value;
14
+ return !!el.style[property];
15
+ };
16
+
17
+ let useTransform = false;
18
+ let transformKey = '';
19
+ if (isCssSupported('transform', 'translate3d(0px, 0px, 0px)')) {
20
+ useTransform = true;
21
+ transformKey = 'transform';
22
+ } else if (isCssSupported('webkitTransform', 'translate3d(0px, 0px, 0px)')) {
23
+ useTransform = true;
24
+ transformKey = 'webkitTransform';
25
+ }
26
+
27
+ function offsetPosition(
28
+ reference: Reference,
29
+ { x, y }: { x?: number | string, y?: number | string },
30
+ rtl: boolean = isRtl(),
31
+ ): void {
32
+ if (!reference.current) return;
33
+
34
+ const tx = typeof x === 'number' ? `${rtl ? -x : x}px` : (x || 0);
35
+ const ty = typeof y === 'number' ? `${y}px` : (y || 0);
36
+ if (useTransform) {
37
+ reference.current.style[transformKey] = `translate3d(${tx}, ${ty}, 0)`;
38
+ } else {
39
+ reference.current.style.top = ty;
40
+ reference.current.style.left = tx;
41
+ }
42
+ }
43
+
44
+ // eslint-disable-next-line no-redeclare
45
+ namespace offsetPosition {
46
+ export const getTransformKey = () => transformKey;
47
+ export const usesTransform = () => useTransform;
48
+ export const forceTransform = () => {
49
+ useTransform = true;
50
+ };
51
+ export const forceTopLeft = () => {
52
+ useTransform = false;
53
+ };
54
+ }
55
+
56
+ export { offsetPosition };
@@ -0,0 +1,9 @@
1
+ import { Reference } from '@24i/bigscreen-sdk/jsx';
2
+
3
+ export const removeClass = (
4
+ reference: Reference,
5
+ className: string,
6
+ ): void => {
7
+ if (!reference.current) return;
8
+ reference.current.classList.remove(className);
9
+ };
@@ -0,0 +1,21 @@
1
+ export const DEFAULT_SCALING_ENDPOINT = 'http://imageresize.24i.com';
2
+
3
+ type Dimensions = {
4
+ height: number,
5
+ width: number,
6
+ fit?: 'cover' | 'contain' | 'inside',
7
+ };
8
+
9
+ const attention = (fit: Dimensions['fit']) => (
10
+ fit === 'cover' ? '&a=attention' : ''
11
+ );
12
+
13
+ const scaledImage = (
14
+ url: string,
15
+ { height, width, fit = 'cover' }: Dimensions,
16
+ scalingEndpoint: string = DEFAULT_SCALING_ENDPOINT,
17
+ ) => (
18
+ `${scalingEndpoint}?url=${url}&h=${height}&w=${width}&fit=${fit}${attention(fit)}`
19
+ );
20
+
21
+ export { scaledImage, Dimensions };
@@ -0,0 +1,10 @@
1
+ export const stopEvent = (event: Event) => {
2
+ event.preventDefault();
3
+ event.stopPropagation();
4
+ };
5
+
6
+ export const stopEventImmediately = (event: Event) => {
7
+ event.preventDefault();
8
+ event.stopPropagation();
9
+ event.stopImmediatePropagation?.();
10
+ };
@@ -0,0 +1,11 @@
1
+ export const SECONDS_PER_MINUTE = 60;
2
+ export const MINUTES_PER_HALF_HOUR = 30;
3
+ export const MINUTES_PER_HOUR = 60;
4
+ export const HOURS_PER_DAY = 24;
5
+ export const DAYS_PER_WEEK = 7;
6
+
7
+ export const SECOND_IN_MS = 1000;
8
+ export const MINUTE_IN_MS = SECOND_IN_MS * SECONDS_PER_MINUTE;
9
+ export const HALF_HOUR_IN_MS = MINUTE_IN_MS * MINUTES_PER_HALF_HOUR;
10
+ export const HOUR_IN_MS = MINUTE_IN_MS * MINUTES_PER_HOUR;
11
+ export const DAY_IN_MS = HOUR_IN_MS * HOURS_PER_DAY;
@@ -0,0 +1,19 @@
1
+ import { TimedObject, TimedFunction } from './types';
2
+
3
+ export const createInterval = () => {
4
+ const intervalObject: TimedObject = {
5
+ id: null,
6
+ set: (callbackFn: () => void, timeMs: number) => {
7
+ intervalObject.clear();
8
+ intervalObject.id = window.setInterval(callbackFn, timeMs);
9
+ },
10
+ clear: () => {
11
+ if (intervalObject.id !== null) {
12
+ window.clearInterval(intervalObject.id);
13
+ intervalObject.id = null;
14
+ }
15
+ },
16
+ isActive: () => intervalObject.id !== null,
17
+ };
18
+ return intervalObject as TimedFunction;
19
+ };
@@ -0,0 +1,22 @@
1
+ import { TimedObject, TimedFunction } from './types';
2
+
3
+ export const createTimeout = () => {
4
+ const timeoutObject: TimedObject = {
5
+ id: null,
6
+ set: (callbackFn: () => void, timeMs: number) => {
7
+ timeoutObject.clear();
8
+ timeoutObject.id = window.setTimeout(() => {
9
+ timeoutObject.id = null;
10
+ callbackFn();
11
+ }, timeMs);
12
+ },
13
+ clear: () => {
14
+ if (timeoutObject.id !== null) {
15
+ window.clearTimeout(timeoutObject.id);
16
+ timeoutObject.id = null;
17
+ }
18
+ },
19
+ isActive: () => timeoutObject.id !== null,
20
+ };
21
+ return timeoutObject as TimedFunction;
22
+ };
@@ -0,0 +1,4 @@
1
+ export { createInterval } from './createInterval';
2
+ export { createTimeout } from './createTimeout';
3
+ export { runAsync } from './runAsync';
4
+ export type { TimedFunction } from './types';
@@ -0,0 +1,3 @@
1
+ export const runAsync = (callbackFn: () => void) => {
2
+ window.setTimeout(callbackFn, 0);
3
+ };
@@ -0,0 +1,9 @@
1
+ export interface TimedFunction {
2
+ set: (callbackFn: () => void, timeMs: number) => void,
3
+ clear: () => void,
4
+ isActive: () => boolean,
5
+ }
6
+
7
+ export type TimedObject = {
8
+ id: number | null,
9
+ } & TimedFunction;
@@ -0,0 +1 @@
1
+ export const wait = (waitMs: number) => new Promise((r) => setTimeout(r, waitMs));
@@ -0,0 +1,29 @@
1
+ function mockXhr(status?: number, responseData?: string) {
2
+ const mockXhrObj = {
3
+ open: jest.fn(),
4
+ send: jest.fn(),
5
+ ontimeout: jest.fn(),
6
+ onerror: jest.fn(),
7
+ onabort: jest.fn(),
8
+ onload: jest.fn(),
9
+ setRequestHeader: jest.fn(),
10
+ readyState: 4,
11
+ status,
12
+ response: responseData,
13
+ timeout: undefined as undefined | number,
14
+ };
15
+
16
+ const mockXhrClass = () => mockXhrObj;
17
+
18
+ // @ts-ignore - Needed for mocking purposes
19
+ window.XMLHttpRequest = jest.fn().mockImplementation(mockXhrClass);
20
+
21
+ setTimeout(() => {
22
+ // @ts-ignore - Needed for mocking purposes
23
+ mockXhrObj.onload();
24
+ }, 0);
25
+
26
+ return mockXhrObj;
27
+ }
28
+
29
+ export { mockXhr };
@@ -0,0 +1,11 @@
1
+ export {
2
+ xhrSend,
3
+ type XhrOptions, type XhrResponse,
4
+ } from './xhrSend';
5
+
6
+ export {
7
+ xhrSendRetry, defaultRetryConfig,
8
+ type RetryConfig, type RSOptions, type ShouldRetryParam,
9
+ } from './xhrSendRetry';
10
+
11
+ export { mockXhr } from './__mocks__/xhr';
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Simple wrap "xhrSend" function over XMLHttpRequest.
3
+ */
4
+
5
+ const HttpStatusCode = {
6
+ OK: 200,
7
+ MULTIPLE_CHOICES: 300,
8
+ UNAUTHORIZED: 401,
9
+ FORBIDDEN: 403,
10
+ };
11
+
12
+ type HttpMethods = 'GET' | 'POST' | 'PUT' | 'DELETE';
13
+
14
+ export type XhrOptions = {
15
+ /**
16
+ * HTTP request method, e.g. POST.
17
+ */
18
+ method: HttpMethods,
19
+ /**
20
+ * The object with HTTP request headers.
21
+ */
22
+ headers: { [key: string]: string },
23
+ /**
24
+ * The number of milliseconds a request can take before automatically being terminated.
25
+ * Value 0 means there is no timeout.
26
+ */
27
+ timeoutInMs: number,
28
+ /**
29
+ * The body of data to be sent in the XHR request, a string (e.g. JSON-encoded).
30
+ */
31
+ body?: string,
32
+ };
33
+
34
+ export type XhrResponse = {
35
+ /**
36
+ * The body content of response.
37
+ */
38
+ dataText: string,
39
+ /**
40
+ * The object corresponding to the given JSON body text.
41
+ */
42
+ dataJson: Object | undefined,
43
+ /**
44
+ * The status code of the response (e.g., 200 for a success).
45
+ */
46
+ status: number,
47
+ /**
48
+ * The status message corresponding to the status code (e.g., "OK" for 200).
49
+ */
50
+ statusText: string
51
+ /**
52
+ * The state whether the response was successful (status in the range 200-299) or not.
53
+ */
54
+ ok: boolean,
55
+ };
56
+
57
+ const defaultOptions: XhrOptions = {
58
+ method: 'GET',
59
+ headers: {},
60
+ timeoutInMs: 0,
61
+ };
62
+
63
+ /**
64
+ * Sends HTTP request
65
+ *
66
+ * @param url The URL to access.
67
+ * @param options The optional options object.
68
+ * @param options.method [options.method='GET'] HTTP request method.
69
+ * @param options.timeoutInMs [options.timeoutInMs=0] The number of milliseconds
70
+ * a request can take before automatically being terminated.
71
+ * @param options.headers [options.headers={}] The object with HTTP request headers.
72
+ * @param options.body [options.body] The body of data to be sent in the XHR request,
73
+ * a string (e.g. JSON-encoded).
74
+ * @returns Promise rejects with TypeError. Resolves with XhrResponse object.
75
+ */
76
+ function xhrSend(url: string, options: Partial<XhrOptions> = {}): Promise<XhrResponse | TypeError> {
77
+ return new Promise((resolve, reject) => {
78
+ const method = options.method || defaultOptions.method;
79
+ const headers = options.headers || defaultOptions.headers;
80
+ const timeoutInMs = options.timeoutInMs !== undefined
81
+ ? options.timeoutInMs : defaultOptions.timeoutInMs;
82
+ const { body } = options;
83
+
84
+ const xhr = new XMLHttpRequest();
85
+
86
+ function onLoad() {
87
+ const dataText = 'response' in xhr ? xhr.response : xhr.responseText;
88
+ const dataJson = parseJson(dataText);
89
+ const status = xhr.status === undefined ? HttpStatusCode.OK : xhr.status;
90
+ const statusText = xhr.statusText === undefined ? 'OK' : xhr.statusText;
91
+ const ok = status >= HttpStatusCode.OK && status < HttpStatusCode.MULTIPLE_CHOICES;
92
+ resolve({ dataText, dataJson, status, statusText, ok });
93
+ }
94
+
95
+ function onError() {
96
+ const error = new TypeError('Network request failed');
97
+ reject(error);
98
+ }
99
+
100
+ function onTimeout() {
101
+ const error = new TypeError('Network request failed - timeout');
102
+ error.name = 'TimeoutError';
103
+ reject(error);
104
+ }
105
+
106
+ function onAbort() {
107
+ const error = new TypeError('Aborted');
108
+ error.name = 'AbortedError';
109
+ reject(error);
110
+ }
111
+
112
+ xhr.onload = onLoad;
113
+ xhr.onerror = onError;
114
+ xhr.ontimeout = onTimeout;
115
+ xhr.onabort = onAbort;
116
+ xhr.open(method, url, true);
117
+
118
+ xhr.timeout = timeoutInMs;
119
+
120
+ const keys = Object.keys(headers);
121
+ for (let i = 0; i < keys.length; i++) {
122
+ const name = keys[i];
123
+ const value = headers[name];
124
+ xhr.setRequestHeader(name, value);
125
+ }
126
+
127
+ xhr.send(typeof body === 'undefined' ? null : body);
128
+ });
129
+ }
130
+
131
+ function parseJson(text: string): string | undefined {
132
+ try {
133
+ return JSON.parse(text);
134
+ } catch (e) {
135
+ return undefined;
136
+ }
137
+ }
138
+
139
+ export { xhrSend };
@@ -0,0 +1,77 @@
1
+ import { xhrSend, XhrResponse, XhrOptions } from './xhrSend';
2
+
3
+ export type RetryConfig = {
4
+ /**
5
+ * The number of times to retry the request. Defaults to 0.
6
+ */
7
+ retry?: number,
8
+ /**
9
+ * The amount of time in milliseconds to initially delay the retry. Defaults to 1000.
10
+ */
11
+ retryDelay?: number,
12
+ /**
13
+ * The number of retries already attempted.
14
+ */
15
+ currentRetryAttempt?: number,
16
+ /**
17
+ * Function to invoke which determines if you should retry
18
+ */
19
+ shouldRetry?: (data: ShouldRetryParam) => boolean,
20
+ };
21
+
22
+ export type RSOptions = {
23
+ retryConfig: RetryConfig;
24
+ } & XhrOptions;
25
+
26
+ export type ShouldRetryParam = {
27
+ options: Partial<RSOptions>,
28
+ response?: XhrResponse,
29
+ error?: any,
30
+ };
31
+
32
+ function shouldRetryRequest(data: ShouldRetryParam) {
33
+ const { error, response } = data;
34
+ if (error) return true;
35
+ if (!response || !response.ok) return true;
36
+ return false;
37
+ }
38
+
39
+ export const defaultRetryConfig = {
40
+ retry: 0,
41
+ retryDelay: 1000,
42
+ currentRetryAttempt: 0,
43
+ shouldRetry: shouldRetryRequest,
44
+ } as const;
45
+
46
+ export async function xhrSendRetry(url: string, options: Partial<RSOptions> = {}):
47
+ Promise<XhrResponse | TypeError> {
48
+ const config = options.retryConfig || {} as RetryConfig;
49
+ config.retry = config.retry ?? defaultRetryConfig.retry;
50
+ config.retryDelay = config.retryDelay ?? defaultRetryConfig.retryDelay;
51
+ config.currentRetryAttempt = config.currentRetryAttempt
52
+ ?? defaultRetryConfig.currentRetryAttempt;
53
+
54
+ options.retryConfig = config;
55
+ let response;
56
+ let error;
57
+ try {
58
+ response = await xhrSend(url, options) as XhrResponse;
59
+ } catch (e) {
60
+ error = e;
61
+ }
62
+
63
+ if (config.currentRetryAttempt === config.retry) {
64
+ if (response) return response;
65
+ throw error;
66
+ }
67
+
68
+ const shouldRetryFn = config.shouldRetry || defaultRetryConfig.shouldRetry;
69
+ const shouldRetry = shouldRetryFn({ options, response, error });
70
+ if (shouldRetry) {
71
+ await new Promise((res) => window.setTimeout(res, config.retryDelay));
72
+ config.currentRetryAttempt += 1;
73
+ return xhrSendRetry(url, options);
74
+ }
75
+ if (response) return response;
76
+ throw error;
77
+ }
@@ -0,0 +1,18 @@
1
+ import { Component } from '@24i/bigscreen-sdk/jsx';
2
+ import { IVolumeControlUI } from '../IVolumeControlUI';
3
+
4
+ export class VolumeControlUIMock extends Component<{}> implements IVolumeControlUI {
5
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
6
+ onUpdateVolume(volumeLevel: number) {}
7
+
8
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
9
+ onUpdateMute(isMuted: boolean) {}
10
+
11
+ show = () => {};
12
+
13
+ hide = () => {};
14
+
15
+ isVisible() { return true; }
16
+
17
+ render() { return <div className="volume-control-ui" />; }
18
+ }
@@ -0,0 +1,3 @@
1
+ import { createExportMaps } from './src/createExportMaps';
2
+
3
+ createExportMaps();
@@ -0,0 +1,50 @@
1
+ import { writeFileSync } from 'fs';
2
+ import { createExportMaps } from '../createExportMaps';
3
+
4
+ jest.mock('fs', () => ({
5
+ readdirSync: jest.fn(() => [
6
+ 'adobe-heartbeat',
7
+ 'animations',
8
+ '.DS-STORE',
9
+ ]),
10
+ lstatSync: jest.fn((name: string) => ({
11
+ isDirectory: () => name.indexOf('.DS-STORE') === -1
12
+ })),
13
+ existsSync: jest.fn(() => true),
14
+ writeFileSync: jest.fn(),
15
+ }));
16
+
17
+ jest.mock('../../../../packages/adobe-heartbeat/exports.json', () => ({
18
+ name: 'adobe-heartbeat',
19
+ entryPoints: {
20
+ '/': 'src/index.ts'
21
+ },
22
+ }));
23
+ jest.mock('../../../../packages/animations/exports.json', () => ({
24
+ name: 'animations',
25
+ entryPoints: {
26
+ '/': 'src/index.ts',
27
+ 'mock': 'src/__mocks__/JSAnimations.ts'
28
+ },
29
+ }));
30
+
31
+ jest.mock('../../../../package.json', () => ({
32
+ name: 'mock-root-package',
33
+ }));
34
+
35
+ describe('createExportMaps', () => {
36
+ it('should add all exports to the package.json', () => {
37
+ createExportMaps();
38
+ expect(writeFileSync).toHaveBeenCalledWith(
39
+ expect.stringContaining('package.json'),
40
+ JSON.stringify({
41
+ name: 'mock-root-package',
42
+ exports: {
43
+ './adobe-heartbeat': './packages/adobe-heartbeat/src/index.ts',
44
+ './animations/mock': './packages/animations/src/__mocks__/JSAnimations.ts',
45
+ './animations': './packages/animations/src/index.ts',
46
+ }
47
+ }, null, 4),
48
+ );
49
+ });
50
+ });