@applicaster/zapp-react-native-utils 13.0.0-alpha.3592223128 → 13.0.0-alpha.3755455151

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 (95) hide show
  1. package/actionsExecutor/ActionExecutorContext.tsx +15 -1
  2. package/analyticsUtils/AnalyticPlayerListener.ts +18 -1
  3. package/analyticsUtils/__tests__/__snapshots__/analyticsManagerNoModule.test.js.snap +9 -9
  4. package/analyticsUtils/helpers/hooks.ts +1 -1
  5. package/appUtils/HooksManager/{Hook.js → Hook.ts} +35 -23
  6. package/appUtils/HooksManager/__tests__/__snapshots__/hook.test.js.snap +10 -8
  7. package/appUtils/HooksManager/__tests__/__snapshots__/hooksManager.test.js.snap +693 -0
  8. package/appUtils/HooksManager/__tests__/hook.test.js +196 -184
  9. package/appUtils/HooksManager/__tests__/hooksManager.test.js +96 -99
  10. package/appUtils/HooksManager/{constants.js → constants.ts} +1 -1
  11. package/appUtils/HooksManager/{index.js → index.ts} +121 -112
  12. package/appUtils/HooksManager/types.ts +116 -0
  13. package/appUtils/RiverFocusManager/index.js +17 -12
  14. package/appUtils/accessibilityManager/index.ts +42 -1
  15. package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +6 -6
  16. package/appUtils/focusManager/index.ts +90 -63
  17. package/appUtils/focusManager/treeDataStructure/Tree/index.js +25 -3
  18. package/appUtils/focusManager/treeDataStructure/Utils/index.js +1 -3
  19. package/appUtils/focusManager/utils/enums.ts +4 -0
  20. package/appUtils/{index.js → index.ts} +1 -1
  21. package/appUtils/keyCodes/__tests__/__snapshots__/keyCodes.test.js.snap +2 -2
  22. package/appUtils/keyCodes/__tests__/keyCodes.test.js +4 -4
  23. package/appUtils/keyCodes/{index.js → index.ts} +2 -0
  24. package/appUtils/keyCodes/keys/index.ts +3 -0
  25. package/appUtils/keyCodes/{keys.android.js → keys/keyEventMapper.ts} +0 -19
  26. package/appUtils/keyCodes/keys/keys.android.ts +18 -0
  27. package/appUtils/keyCodes/keys/keys.ios.ts +25 -0
  28. package/appUtils/keyCodes/keys/keys.ts +15 -0
  29. package/appUtils/keyCodes/{keysByPlatform.js → keys/keysByPlatform.ts} +4 -0
  30. package/appUtils/keyCodes/keysByPlatform.ts +8 -0
  31. package/appUtils/keyInputHandler/KeyInputHandler.ts +68 -0
  32. package/appUtils/orientationHelper.ts +1 -1
  33. package/appUtils/platform/platformUtils.ts +0 -14
  34. package/appUtils/playerManager/index.ts +6 -2
  35. package/appUtils/playerManager/player.ts +17 -5
  36. package/appUtils/playerManager/playerNative.ts +3 -2
  37. package/appUtils/playerManager/usePlayerControllerSetup.tsx +3 -3
  38. package/arrayUtils/__tests__/__snapshots__/arrayUtils.test.ts.snap +4 -4
  39. package/domUtils/{cookieManager.js → cookieManager.ts} +1 -2
  40. package/functionUtils/__tests__/__snapshots__/functionUtils.test.js.snap +4 -4
  41. package/functionUtils/index.ts +15 -11
  42. package/manifestUtils/__tests__/createConfig.test.js +18 -16
  43. package/modalState/index.ts +1 -5
  44. package/navigationUtils/__tests__/__snapshots__/navigationUtils.test.js.snap +6 -6
  45. package/navigationUtils/__tests__/itemTypes.test.js +2 -2
  46. package/navigationUtils/__tests__/navigationUtils.test.js +2 -2
  47. package/navigationUtils/index.ts +14 -5
  48. package/package.json +3 -2
  49. package/reactHooks/autoscrolling/__tests__/useTrackCurrentAutoScrollingElement.test.ts +1 -1
  50. package/reactHooks/autoscrolling/__tests__/useTrackedView.test.tsx +1 -1
  51. package/reactHooks/cell-click/__tests__/index.test.js +5 -2
  52. package/reactHooks/feed/__tests__/useBuildPipesUrl.test.tsx +4 -4
  53. package/reactHooks/feed/__tests__/useFeedLoader.test.tsx +20 -13
  54. package/reactHooks/feed/useFeedLoader.tsx +9 -4
  55. package/reactHooks/feed/usePipesCacheReset.ts +5 -5
  56. package/reactHooks/flatList/__tests__/index.test.tsx +30 -21
  57. package/reactHooks/layout/__tests__/index.test.tsx +10 -10
  58. package/reactHooks/layout/useDimensions/helpers/__tests__/getInitialDimensions.native.test.js +14 -28
  59. package/reactHooks/navigation/__tests__/index.test.tsx +0 -4
  60. package/reactHooks/navigation/index.ts +29 -218
  61. package/reactHooks/navigation/useGetBottomTabBarHeight.ts +12 -0
  62. package/reactHooks/navigation/useGetNavBarTopBorderWidth.ts +14 -0
  63. package/reactHooks/navigation/useGetTabBarHeight.ts +12 -0
  64. package/reactHooks/navigation/useIsScreenActive.ts +17 -0
  65. package/reactHooks/navigation/useNavigationPluginData.ts +15 -0
  66. package/reactHooks/navigation/useNavigationType.ts +15 -0
  67. package/reactHooks/navigation/usePathname.ts +4 -0
  68. package/reactHooks/navigation/useRoute.ts +100 -0
  69. package/reactHooks/navigation/useUniqueRouteSuffix.ts +41 -0
  70. package/reactHooks/player/TVSeekControlller/ISeekController.ts +32 -0
  71. package/reactHooks/player/TVSeekControlller/LongPressSeekController.ts +71 -0
  72. package/reactHooks/player/TVSeekControlller/TVSeekController.ts +258 -0
  73. package/reactHooks/player/TVSeekControlller/TapSeekController.ts +53 -0
  74. package/reactHooks/player/__tests__/{useAutoSeek.test.tsx → useAutoSeek._test.tsx} +2 -3
  75. package/reactHooks/player/const.ts +0 -4
  76. package/reactHooks/player/index.ts +0 -6
  77. package/reactHooks/utils/index.ts +1 -1
  78. package/reactUtils/__tests__/reactUtils.test.js +10 -28
  79. package/reactUtils/createContext/__tests__/__snapshots__/helpers.test.js.snap +19 -19
  80. package/reactUtils/createContext/__tests__/__snapshots__/index.test.js.snap +2 -2
  81. package/reactUtils/createContext/__tests__/__snapshots__/provider.test.js.snap +3 -3
  82. package/reactUtils/createContext/__tests__/helpers.test.js +8 -8
  83. package/reactUtils/index.ts +0 -14
  84. package/theme/__mocks__/index.ts +4 -0
  85. package/appUtils/keyCodes/keys.ios.js +0 -46
  86. package/reactHooks/player/useAutoSeek.tsx +0 -87
  87. package/reactHooks/player/useSeek.tsx +0 -66
  88. package/reactHooks/player/useTapSeek.tsx +0 -58
  89. /package/appUtils/HooksManager/{logger.js → logger.ts} +0 -0
  90. /package/appUtils/{directionHelper.js → directionHelper.ts} +0 -0
  91. /package/appUtils/keyCodes/{androidTVKeys.js → androidTVKeys.ts} +0 -0
  92. /package/appUtils/keyCodes/{keys.web.js → keys/keys.web.ts} +0 -0
  93. /package/appUtils/{localizationsHelper.js → localizationsHelper.ts} +0 -0
  94. /package/domUtils/{logger.js → logger.ts} +0 -0
  95. /package/reactHooks/player/__tests__/{useTapSeek.test.ts → useTapSeek._test.ts} +0 -0
@@ -0,0 +1,18 @@
1
+ export const KEYS = {
2
+ Enter: { code: "Enter", keyCode: 13 },
3
+ EnterKeyboard: { code: "EnterKeyboard", keyCode: 66 },
4
+ Back: { code: "Back", keyCode: 8 },
5
+ Space: { code: "Space", keyCode: 32 },
6
+ m: { code: "m", keyCode: 77 },
7
+ ArrowLeft: { code: "ArrowLeft", keyCode: 37 },
8
+ ArrowUp: { code: "ArrowUp", keyCode: 38 },
9
+ ArrowRight: { code: "ArrowRight", keyCode: 39 },
10
+ ArrowDown: { code: "ArrowDown", keyCode: 40 },
11
+ };
12
+
13
+ export const ARROW_KEYS = [
14
+ KEYS.ArrowUp,
15
+ KEYS.ArrowLeft,
16
+ KEYS.ArrowDown,
17
+ KEYS.ArrowRight,
18
+ ];
@@ -0,0 +1,25 @@
1
+ export const KEYS = {
2
+ Enter: { code: "Enter", keyCode: 13 },
3
+ Space: { code: "Space", keyCode: 32 },
4
+ m: { code: "m", keyCode: 77 },
5
+ ArrowLeft: { code: "ArrowLeft", keyCode: 37 },
6
+ ArrowUp: { code: "ArrowUp", keyCode: 38 },
7
+ ArrowRight: { code: "ArrowRight", keyCode: 39 },
8
+ ArrowDown: { code: "ArrowDown", keyCode: 40 },
9
+ Back: { code: "Backspace", keyCode: 8 },
10
+ Play: { code: "PlayPause", keyCode: 179 },
11
+ Pause: { code: "Pause", keyCode: 179 },
12
+ Forward: { code: "Forward", keyCode: 176 },
13
+ Rewind: { code: "Rewind", keyCode: 177 },
14
+ VolumeUp: { code: "VolumeUp", keyCode: 175 },
15
+ VolumeDown: { code: "VolumeDown", keyCode: 174 },
16
+ ToggleMute: { code: "VolumeMute", keyCode: 173 },
17
+ Stop: { code: "Q", keyCode: 81 },
18
+ };
19
+
20
+ export const ARROW_KEYS = [
21
+ KEYS.ArrowUp,
22
+ KEYS.ArrowLeft,
23
+ KEYS.ArrowDown,
24
+ KEYS.ArrowRight,
25
+ ];
@@ -0,0 +1,15 @@
1
+ // dummy file to make sure the folder structure is created
2
+ export const KEYS: Record<string, { code: string; keyCode: number }> = {
3
+ ArrowLeft: { code: "ArrowLeft", keyCode: -1 },
4
+ ArrowUp: { code: "ArrowUp", keyCode: -1 },
5
+ ArrowRight: { code: "ArrowRight", keyCode: -1 },
6
+ ArrowDown: { code: "ArrowDown", keyCode: -1 },
7
+ Back: { code: "Back", keyCode: -1 },
8
+ };
9
+
10
+ export const ARROW_KEYS = [
11
+ KEYS.ArrowUp,
12
+ KEYS.ArrowLeft,
13
+ KEYS.ArrowDown,
14
+ KEYS.ArrowRight,
15
+ ];
@@ -77,6 +77,10 @@ const web = {
77
77
  Exit: { code: "Exit", keyCode: null },
78
78
  Escape: { code: "Escape", keyCode: 27 },
79
79
  EscapeDevice: { code: "Escape", keyCode: 27 },
80
+ // For Debugging
81
+ Z: { code: "KeyZ", keyCode: 90 }, // Hardware Backward Button
82
+ X: { code: "KeyX", keyCode: 88 }, // Hardware Enter Button
83
+ C: { code: "KeyC", keyCode: 67 }, // Hardware Forward Button
80
84
  };
81
85
 
82
86
  const android_tv = {
@@ -0,0 +1,8 @@
1
+ export {
2
+ lg_tv,
3
+ samsung_tv,
4
+ web,
5
+ tvos,
6
+ android_tv,
7
+ vizio,
8
+ } from "./keys/keysByPlatform";
@@ -0,0 +1,68 @@
1
+ export type SeekKeyHandlerListener = {
2
+ onRewindPress: () => boolean;
3
+ onForwardPress: () => boolean;
4
+ onRewindPressOut: () => void;
5
+ onForwardPressOut: () => void;
6
+ };
7
+
8
+ export class KeyInputHandler {
9
+ private static instance: KeyInputHandler;
10
+
11
+ public static getInstance() {
12
+ if (!KeyInputHandler.instance) {
13
+ KeyInputHandler.instance = new KeyInputHandler();
14
+ }
15
+
16
+ return KeyInputHandler.instance;
17
+ }
18
+
19
+ constructor() {
20
+ this.listeners = [];
21
+ }
22
+
23
+ private listeners: SeekKeyHandlerListener[] = [];
24
+
25
+ addListener = (listener: SeekKeyHandlerListener) => {
26
+ this.listeners.splice(0, 0, listener);
27
+
28
+ return () => this.removeListener(listener);
29
+ };
30
+
31
+ removeListener = (listener: SeekKeyHandlerListener) => {
32
+ this.listeners = this.listeners.filter((l) => l !== listener);
33
+ };
34
+
35
+ onRewindPress = () => {
36
+ for (const element of this.listeners) {
37
+ if (element.onRewindPress()) {
38
+ break;
39
+ }
40
+ }
41
+ };
42
+
43
+ onForwardPress = () => {
44
+ for (const element of this.listeners) {
45
+ if (element.onForwardPress()) {
46
+ break;
47
+ }
48
+ }
49
+ };
50
+
51
+ // TODO: Event should be send to listeners who handled down event
52
+ onRewindPressOut = () => {
53
+ this.listeners.forEach((listener) => listener.onRewindPressOut());
54
+ };
55
+
56
+ onForwardPressOut = () => {
57
+ this.listeners.forEach((listener) => listener.onForwardPressOut());
58
+ };
59
+
60
+ getSeekMethods = () => {
61
+ return {
62
+ onForwardPress: this.onForwardPress,
63
+ onRewindPress: this.onRewindPress,
64
+ onForwardPressOut: this.onForwardPressOut,
65
+ onRewindPressOut: this.onRewindPressOut,
66
+ };
67
+ };
68
+ }
@@ -2,7 +2,7 @@
2
2
  import * as ReactNative from "react-native";
3
3
  import { isTV, platformSelect } from "../reactUtils";
4
4
  import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
5
- import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
5
+ import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks/device/useIsTablet";
6
6
 
7
7
  import {
8
8
  QUICK_BRICK_EVENTS,
@@ -9,20 +9,6 @@ import {
9
9
  import { PLATFORM_KEYS, PLATFORMS } from "./const";
10
10
  import { createLogger, utilsLogger } from "../../logger";
11
11
 
12
- declare global {
13
- interface Window {
14
- VIZIO?: {
15
- exitApplication: () => void;
16
- Chromevox: {
17
- play: (text: string) => void;
18
- };
19
- setClosedCaptionHandler: (
20
- callback: (isCCEnabled: boolean) => void
21
- ) => void;
22
- };
23
- }
24
- }
25
-
26
12
  const { log_debug } = createLogger({
27
13
  category: "General",
28
14
  subsystem: "PlatformUtils",
@@ -169,8 +169,12 @@ export class PlayerManager {
169
169
  this.addPlayer(id, playerController);
170
170
 
171
171
  if (playerController.playerRole === PlayerRole.Primary) {
172
- if (playerController.playerPluginId !== "QuickBrickPlayerPlugin") {
173
- RNPlayerManager?.["QuickBrickPlayerPlugin"]?.stopBackgroundPlayback?.();
172
+ if (RNPlayerManager) {
173
+ Object.keys(RNPlayerManager).forEach((pluginId) => {
174
+ if (pluginId !== playerController.playerPluginId) {
175
+ RNPlayerManager[pluginId]?.stopBackgroundPlayback?.();
176
+ }
177
+ });
174
178
  }
175
179
 
176
180
  playerController.addListener({
@@ -5,6 +5,7 @@ import { createLogger, utilsLogger } from "../../logger";
5
5
  import { getBoolFromConfigValue } from "../../configurationUtils";
6
6
  import { PlayerRole, SharedPlayerCallBacksKeys } from "./conts";
7
7
  import { OverlaysObserver } from "./OverlayObserver/OverlaysObserver";
8
+ import { TVSeekController } from "../../reactHooks/player/TVSeekControlller/TVSeekController";
8
9
 
9
10
  const logger = createLogger({
10
11
  category: "PlayerController",
@@ -49,6 +50,8 @@ export class Player {
49
50
  [key: string]: QuickBrickPlayer.SharedPlayerCallBacks;
50
51
  } = {};
51
52
 
53
+ public seekController?: TVSeekController | null;
54
+
52
55
  get entry(): ZappEntry | null {
53
56
  return this._entry;
54
57
  }
@@ -59,6 +62,8 @@ export class Player {
59
62
  }
60
63
 
61
64
  constructor(props) {
65
+ this.seekController = null;
66
+
62
67
  this.playerState = {
63
68
  // We want isLive null by default to be able not to show controls if we do not know type
64
69
  isLive: null,
@@ -91,6 +96,8 @@ export class Player {
91
96
  this.onVideoProgress = this.onVideoProgress.bind(this);
92
97
  this.onVideoLoad = this.onVideoLoad.bind(this);
93
98
  this.isFullScreenSupported = this.isFullScreenSupported.bind(this);
99
+ this.onPlayerSeekComplete = this.onPlayerSeekComplete.bind(this);
100
+
94
101
  this.entryObservable = null;
95
102
  }
96
103
 
@@ -321,7 +328,7 @@ export class Player {
321
328
  * You should use dispatchPlayerEvent at PlayerContainer or call playerManager.invokeHandler directly
322
329
  * This allows you to use one method for everything.
323
330
  */
324
- onSeekStart = (event: QuickBrickPlayer.OnSeekStartEvent) => {
331
+ onPlayerSeekStart = (event: QuickBrickPlayer.OnSeekStartEvent) => {
325
332
  const { isLive, seekableDuration, currentTime, duration, seekTime } = event;
326
333
 
327
334
  this.setPlaybackState({ currentTime, duration, seekableDuration, isLive });
@@ -336,10 +343,11 @@ export class Player {
336
343
  });
337
344
  };
338
345
 
339
- onSeekComplete = (event: QuickBrickPlayer.OnSeekCompleteEvent) => {
346
+ onPlayerSeekComplete = (event: QuickBrickPlayer.OnSeekCompleteEvent) => {
340
347
  const { isLive, seekableDuration, currentTime, duration } = event;
341
348
 
342
349
  this.setPlaybackState({ currentTime, duration, seekableDuration, isLive });
350
+
343
351
  this.playerState.seekPosition = null;
344
352
 
345
353
  if (!isLive) {
@@ -620,14 +628,18 @@ export class Player {
620
628
  selectTrack = (_track) => {};
621
629
 
622
630
  protected notifyPlayHeadPositionUpdate = () => {
631
+ const currentTime = this.getPosition();
632
+
623
633
  const event = {
624
- currentTime: this.getPosition(),
634
+ currentTime,
625
635
  duration: this.getDuration(),
626
636
  item: this.getEntry(),
627
637
  seekableDuration: this.playerState.seekableDuration,
628
638
  isLive: this.isLive(),
629
639
  };
630
640
 
641
+ this.seekController?.onVideoProgress(currentTime);
642
+
631
643
  this.invokeListenersUpdate({
632
644
  callbackName: SharedPlayerCallBacksKeys.OnVideoProgress,
633
645
  event,
@@ -653,8 +665,8 @@ export class Player {
653
665
  };
654
666
 
655
667
  public getListener = (): QuickBrickPlayer.SharedPlayerCallBacks => ({
656
- onPlayerSeekStart: this.onSeekStart,
657
- onPlayerSeekComplete: this.onSeekComplete,
668
+ onPlayerSeekStart: this.onPlayerSeekStart,
669
+ onPlayerSeekComplete: this.onPlayerSeekComplete,
658
670
  onVideoEnd: this.onVideoEnd,
659
671
  onError: this.onError,
660
672
  onVideoError: this.onVideoError,
@@ -58,7 +58,7 @@ export class PlayerNative extends Player {
58
58
  return this.playerState.contentPosition;
59
59
  };
60
60
 
61
- currentPlayerComponent = (): ReactComponent<PlayerProps> =>
61
+ currentPlayerComponent = (): ReactComponent<PlayerRefProps> =>
62
62
  this.playerComponent?.current;
63
63
 
64
64
  getState = () => this.playerState;
@@ -222,9 +222,10 @@ export class PlayerNative extends Player {
222
222
 
223
223
  onVideoLoad = (event) => {
224
224
  if (this.startPosition) {
225
- super.onVideoLoad({ ...event, ignoreContinueWatching: true });
226
225
  this.seekTo(this.startPosition);
227
226
  this.startPosition = null;
227
+
228
+ super.onVideoLoad({ ...event, ignoreContinueWatching: true });
228
229
  } else {
229
230
  super.onVideoLoad(event);
230
231
  }
@@ -39,7 +39,7 @@ export const usePlayerControllerSetup = ({
39
39
  ? { supports_native_controls: true, ...config }
40
40
  : config;
41
41
 
42
- const newPlayerController = new ControllerType({
42
+ const combinedProps = {
43
43
  player: ref,
44
44
  listener: props as any,
45
45
  config: newConfig,
@@ -47,9 +47,9 @@ export const usePlayerControllerSetup = ({
47
47
  entry,
48
48
  playerPluginId: pluginId,
49
49
  playerRole: PlayerRole.Primary,
50
- });
50
+ };
51
51
 
52
- setPlayerController(newPlayerController);
52
+ setPlayerController(new ControllerType(combinedProps));
53
53
  }, [playerId, entry?.id]);
54
54
 
55
55
  React.useEffect(() => {
@@ -1,7 +1,7 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`shiftArray shifts the n first items from the head to the tail of the array with a positive offset 1`] = `
4
- Array [
4
+ [
5
5
  "bar",
6
6
  "baz",
7
7
  42,
@@ -10,7 +10,7 @@ Array [
10
10
  `;
11
11
 
12
12
  exports[`shiftArray shifts the n first items from the head to the tail of the array with a positive offset 2`] = `
13
- Array [
13
+ [
14
14
  "baz",
15
15
  42,
16
16
  "foo",
@@ -19,7 +19,7 @@ Array [
19
19
  `;
20
20
 
21
21
  exports[`shiftArray shifts the n last items from the tail to the head of the array with a negative offset 1`] = `
22
- Array [
22
+ [
23
23
  42,
24
24
  "foo",
25
25
  "bar",
@@ -28,7 +28,7 @@ Array [
28
28
  `;
29
29
 
30
30
  exports[`shiftArray shifts the n last items from the tail to the head of the array with a negative offset 2`] = `
31
- Array [
31
+ [
32
32
  "baz",
33
33
  42,
34
34
  "foo",
@@ -2,7 +2,6 @@ import { domUtilsLogger } from "./logger";
2
2
 
3
3
  /**
4
4
  * Gets an object of cookies and sets them on the DOM.
5
- * @param {Object} cookies selected data key for label.
6
5
  */
7
6
  export function setCookies(cookies): void {
8
7
  const cookieKeys = Object.keys(cookies);
@@ -25,7 +24,7 @@ export function setCookies(cookies): void {
25
24
  /**
26
25
  * Gets cookies set on DOM
27
26
  */
28
- export function getCookies(): Object {
27
+ export function getCookies(): typeof document.cookie {
29
28
  try {
30
29
  if (document) {
31
30
  return document.cookie;
@@ -1,8 +1,8 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`functionUtils subscriber can be invoked without args 1`] = `
4
- Object {
5
- "handlers": Object {},
4
+ {
5
+ "handlers": {},
6
6
  "invokeHandler": [Function],
7
7
  "on": [Function],
8
8
  "removeHandler": [Function],
@@ -10,9 +10,9 @@ Object {
10
10
  `;
11
11
 
12
12
  exports[`functionUtils subscriber returns the original object with additional methods 1`] = `
13
- Object {
13
+ {
14
14
  "foo": "bar",
15
- "handlers": Object {},
15
+ "handlers": {},
16
16
  "invokeHandler": [Function],
17
17
  "method": [Function],
18
18
  "on": [Function],
@@ -111,12 +111,12 @@ type SubscriberFn<T> = (
111
111
 
112
112
  export type EventHandlerFn<T> = (event: string, ...args: unknown[]) => T;
113
113
 
114
- type SubscriberObj = Partial<{
115
- on?: SubscriberFn<SubscriberObj>;
116
- invokeHandler: EventHandlerFn<SubscriberObj>;
117
- removeHandler: EventHandlerFn<SubscriberObj>;
118
- handlers: Record<string, SubscriberFn<SubscriberObj>[] | []>;
119
- }>;
114
+ export type SubscriberObj<T extends {} = {}> = {
115
+ on: SubscriberFn<SubscriberObj<T>>;
116
+ invokeHandler: EventHandlerFn<SubscriberObj<T>>;
117
+ removeHandler: EventHandlerFn<SubscriberObj<T>>;
118
+ handlers: Record<string, SubscriberFn<SubscriberObj<T>>[] | []>;
119
+ } & T;
120
120
 
121
121
  export const clearObject = (object: { [key: string]: unknown }) =>
122
122
  Object.keys(object).forEach((key) => delete object[key]);
@@ -126,7 +126,11 @@ export const clearObject = (object: { [key: string]: unknown }) =>
126
126
  * @param {Object} obj to add the subscription feature on
127
127
  * @returns {Object} subscriber object
128
128
  */
129
- export function subscriber(obj: SubscriberObj = {}): SubscriberObj {
129
+ export function subscriber<T extends Partial<SubscriberObj> = {}>(
130
+ _obj: T = {} as T
131
+ ): SubscriberObj {
132
+ const obj: T = _obj;
133
+
130
134
  if (!obj.handlers) {
131
135
  obj.handlers = {};
132
136
  }
@@ -172,7 +176,7 @@ export function subscriber(obj: SubscriberObj = {}): SubscriberObj {
172
176
  | SubscriberFn<SubscriberObj>[]
173
177
  | [];
174
178
 
175
- return obj;
179
+ return obj as SubscriberObj;
176
180
  };
177
181
 
178
182
  /**
@@ -188,16 +192,16 @@ export function subscriber(obj: SubscriberObj = {}): SubscriberObj {
188
192
 
189
193
  R.compose(R.forEach(callHandlerWithDispose), R.propOr([], event))(handlers);
190
194
 
191
- return obj;
195
+ return obj as SubscriberObj;
192
196
  };
193
197
 
194
198
  obj.removeHandler = function (event, handler) {
195
199
  handlers[event] = R.reject(R.equals(handler), handlers[event]);
196
200
 
197
- return obj;
201
+ return obj as SubscriberObj;
198
202
  };
199
203
 
200
- return obj;
204
+ return obj as SubscriberObj;
201
205
  }
202
206
 
203
207
  /**
@@ -1,11 +1,9 @@
1
- import { createConfig } from "../createConfig";
2
-
3
- const styles = {
1
+ const mockStyles = {
4
2
  fields: [{ key: "field_1", initial_value: 1 }],
5
3
  label: "styles",
6
4
  };
7
5
 
8
- const stylesWithGroup = {
6
+ const mockStylesWithGroup = {
9
7
  fields: [
10
8
  {
11
9
  group: true,
@@ -15,26 +13,28 @@ const stylesWithGroup = {
15
13
  ],
16
14
  };
17
15
 
18
- const generators = {
19
- styles: jest.fn(() => ({ styles })),
16
+ const mockGenerators = {
17
+ styles: jest.fn(() => ({ styles: mockStyles })),
20
18
  stylesGroup: jest.fn(() => ({
21
- styles: stylesWithGroup,
19
+ styles: mockStylesWithGroup,
22
20
  })),
23
- customConfiguration: jest.fn(() => ({ custom_configuration: [styles] })),
21
+ customConfiguration: jest.fn(() => ({ custom_configuration: [mockStyles] })),
24
22
  customConfigurationGroup: jest.fn(() => ({
25
- custom_configuration: [stylesWithGroup],
23
+ custom_configuration: [mockStylesWithGroup],
26
24
  })),
27
25
  };
28
26
 
29
- jest.mock("../defaultManifestConfigurations", () => ({
27
+ jest.doMock("../defaultManifestConfigurations", () => ({
30
28
  defaultConfigurations: {
31
- styles: generators.styles,
32
- stylesGroup: generators.stylesGroup,
33
- customConfiguration: generators.customConfiguration,
34
- customConfigurationGroup: generators.customConfigurationGroup,
29
+ styles: mockGenerators.styles,
30
+ stylesGroup: mockGenerators.stylesGroup,
31
+ customConfiguration: mockGenerators.customConfiguration,
32
+ customConfigurationGroup: mockGenerators.customConfigurationGroup,
35
33
  },
36
34
  }));
37
35
 
36
+ const { createConfig } = require("../createConfig");
37
+
38
38
  describe("createConfig", () => {
39
39
  it("should return a function", () => {
40
40
  const currentResult = createConfig(jest.fn());
@@ -78,7 +78,9 @@ describe("createConfig", () => {
78
78
  extend: "styles",
79
79
  })(props);
80
80
 
81
- expect(generators.styles).toBeCalledWith(props);
81
+ console.log(mockGenerators.styles.mock.calls);
82
+
83
+ expect(mockGenerators.styles).toBeCalledWith(props);
82
84
  });
83
85
 
84
86
  it("should return base configuration if manifest is not provided", () => {
@@ -88,7 +90,7 @@ describe("createConfig", () => {
88
90
  extend: "styles",
89
91
  })({});
90
92
 
91
- expect(currentResult).toEqual({ styles });
93
+ expect(currentResult).toEqual({ styles: mockStyles });
92
94
  });
93
95
 
94
96
  describe("Data merging", () => {
@@ -31,11 +31,7 @@ export const useModalStore = create<ModalStore>((set) => ({
31
31
  set((state) => ({
32
32
  modalState: { ...state.modalState, ...newState },
33
33
  })),
34
- openModal: ({
35
- item,
36
- options = {},
37
- props = { screenData: {} },
38
- }: OpenModalArg) =>
34
+ openModal: ({ item, options = {}, props }: OpenModalArg) =>
39
35
  set({
40
36
  modalState: {
41
37
  visible: true,
@@ -1,19 +1,19 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`getNavigationProps returns the props otherwise 1`] = `
4
- Object {
5
- "assets": Object {
4
+ {
5
+ "assets": {
6
6
  "appLogo": "appLogo.png",
7
7
  },
8
8
  "home": false,
9
- "nav_items": Array [
10
- Object {
9
+ "nav_items": [
10
+ {
11
11
  "type": "label",
12
12
  },
13
13
  ],
14
- "rules": Object {},
14
+ "rules": {},
15
15
  "selected": "A1234",
16
- "styles": Object {
16
+ "styles": {
17
17
  "style": "foo",
18
18
  },
19
19
  "title": "testTitle",
@@ -61,8 +61,8 @@ describe("getTypeMatcher", () => {
61
61
 
62
62
  describe("isItemOfType", () => {
63
63
  it("is a curried function", () => {
64
- expect(itemIsOfType(river, SCREEN_TYPES.RIVER)).toBeBoolean();
65
- expect(itemIsOfType(river)).toBeFunction();
64
+ expect(itemIsOfType(river, SCREEN_TYPES.RIVER)).toBeTruthy();
65
+ expect(itemIsOfType(river)).toBeInstanceOf(Function);
66
66
  });
67
67
 
68
68
  it("returns true if the item is of the given type", () => {
@@ -243,7 +243,7 @@ describe("getTargetRoute", () => {
243
243
  it("returns a valid path when initial pathname is /", () => {
244
244
  const targetRoute = getTargetRoute(river, "/", { layoutVersion });
245
245
  expect(targetRoute).toEqual(`/river/${river.id}`);
246
- expect(targetRoute).not.toInclude("//");
246
+ expect(targetRoute).not.toContainEntry("//");
247
247
  });
248
248
  });
249
249
 
@@ -273,7 +273,7 @@ describe("getTargetRoute", () => {
273
273
  it("returns a valid path when initial pathname is /", () => {
274
274
  const targetRoute = getTargetRoute(river, "/", { layoutVersion });
275
275
  expect(targetRoute).toEqual(`/river/${river.id}`);
276
- expect(targetRoute).not.toInclude("//");
276
+ expect(targetRoute).not.toContainEntry("//");
277
277
  });
278
278
  });
279
279
  });
@@ -324,7 +324,13 @@ export function getPathAttributes({
324
324
  * @param {object} rivers
325
325
  * @returns {object}
326
326
  */
327
- export function getRiverFromRoute({ route, rivers }) {
327
+ export function getRiverFromRoute({
328
+ route,
329
+ rivers,
330
+ }: {
331
+ route: string;
332
+ rivers: Record<string, ZappRiver>;
333
+ }) {
328
334
  if (!route) {
329
335
  return null;
330
336
  }
@@ -437,7 +443,7 @@ export const runZappHooksForEntry = async (
437
443
 
438
444
  let success;
439
445
  let payload;
440
- const rivers = appStore.get("rivers");
446
+ const rivers: Record<string, ZappRiver> = appStore.get("rivers");
441
447
  const plugins = appStore.get("plugins");
442
448
  const appData = appStore.get("appData");
443
449
 
@@ -492,13 +498,16 @@ export const runZappHooksForEntry = async (
492
498
  payload = _payload;
493
499
  };
494
500
 
495
- HooksManager(hooksOptions)
501
+ const hooksManager = HooksManager(hooksOptions);
502
+
503
+ hooksManager.subscriber
496
504
  .on(HOOKS_EVENTS.PRESENT_SCREEN_HOOK, handleHookPresent)
497
505
  .on(HOOKS_EVENTS.START_BACKGROUND_HOOK, handleBackgroundHook)
498
506
  .on(HOOKS_EVENTS.ERROR, onFinished(false))
499
507
  .on(HOOKS_EVENTS.CANCEL, onFinished(false))
500
- .on(HOOKS_EVENTS.COMPLETE, onFinished(true))
501
- .handleHooks(entry);
508
+ .on(HOOKS_EVENTS.COMPLETE, onFinished(true));
509
+
510
+ hooksManager.handleHooks(entry);
502
511
 
503
512
  // eslint-disable-next-line no-unmodified-loop-condition
504
513
  while (success === undefined) {