@applicaster/zapp-react-native-utils 13.0.0-rc.10 → 13.0.0-rc.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 +0 -10
- package/actionsExecutor/ActionExecutor.ts +16 -9
- package/actionsExecutor/ActionExecutorContext.tsx +174 -11
- package/alertUtils/alert.ts +148 -0
- package/alertUtils/index.ts +1 -148
- package/analyticsUtils/AnalyticPlayerListener.ts +18 -1
- package/analyticsUtils/__tests__/__snapshots__/analyticsManagerNoModule.test.js.snap +9 -9
- package/analyticsUtils/currentScreenProperities.ts +6 -4
- package/analyticsUtils/helpers/hooks.ts +1 -1
- package/appUtils/HooksManager/{Hook.js → Hook.ts} +39 -23
- package/appUtils/HooksManager/__tests__/__snapshots__/hook.test.js.snap +10 -8
- package/appUtils/HooksManager/__tests__/__snapshots__/hooksManager.test.js.snap +693 -0
- package/appUtils/HooksManager/__tests__/hook.test.js +196 -184
- package/appUtils/HooksManager/__tests__/hooksManager.test.js +96 -99
- package/appUtils/HooksManager/{constants.js → constants.ts} +1 -1
- package/appUtils/HooksManager/{index.js → index.ts} +124 -113
- package/appUtils/HooksManager/types.ts +119 -0
- package/appUtils/RiverFocusManager/index.js +17 -12
- package/appUtils/accessibilityManager/index.ts +42 -1
- package/appUtils/contextKeysManager/contextResolver.ts +66 -0
- package/appUtils/contextKeysManager/index.ts +2 -2
- package/appUtils/contextKeysManager/utils/index.ts +2 -1
- package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +8 -6
- package/appUtils/focusManager/index.ts +108 -69
- package/appUtils/focusManager/treeDataStructure/Tree/index.js +25 -3
- package/appUtils/focusManager/treeDataStructure/Utils/index.js +1 -3
- package/appUtils/focusManager/utils/enums.ts +4 -0
- package/appUtils/focusManagerAux/utils/index.ts +4 -3
- package/appUtils/{index.js → index.ts} +1 -1
- package/appUtils/keyCodes/__tests__/__snapshots__/keyCodes.test.js.snap +2 -2
- package/appUtils/keyCodes/__tests__/keyCodes.test.js +4 -4
- package/appUtils/keyCodes/{index.js → index.ts} +13 -7
- package/appUtils/keyCodes/keys/index.ts +3 -0
- package/appUtils/keyCodes/{keys.android.js → keys/keyEventMapper.ts} +0 -19
- package/appUtils/keyCodes/keys/keys.android.ts +18 -0
- package/appUtils/keyCodes/keys/keys.ios.ts +25 -0
- package/appUtils/keyCodes/keys/keys.ts +15 -0
- package/appUtils/keyCodes/{keysByPlatform.js → keys/keysByPlatform.ts} +4 -0
- package/appUtils/keyCodes/keysByPlatform.ts +8 -0
- package/appUtils/keyInputHandler/KeyInputHandler.ts +68 -0
- package/appUtils/{localizationsHelper.js → localizationsHelper.ts} +23 -0
- package/appUtils/orientationHelper.ts +11 -13
- package/appUtils/platform/const.ts +14 -0
- package/appUtils/platform/platformUtils.ts +47 -18
- package/appUtils/playerManager/index.ts +1 -1
- package/appUtils/playerManager/player.ts +42 -18
- package/appUtils/playerManager/playerNative.ts +18 -2
- package/appUtils/playerManager/usePlayerControllerSetup.tsx +3 -3
- package/appUtils/playerManager/usePlayerTitleSummaryOverlay.tsx +7 -1
- package/arrayUtils/__tests__/__snapshots__/arrayUtils.test.ts.snap +4 -4
- package/componentsUtils/__tests__/isFirstComponentGallery.test.ts +33 -0
- package/componentsUtils/__tests__/isFirstComponentScreenPicker.test.ts +33 -0
- package/componentsUtils/__tests__/isGallery.test.ts +33 -0
- package/componentsUtils/__tests__/isScreenPicker.test.ts +33 -0
- package/componentsUtils/index.ts +32 -0
- package/dateUtils/index.ts +19 -0
- package/domUtils/{cookieManager.js → cookieManager.ts} +1 -2
- package/equalUtils/__tests__/isEqual/combination.test.ts +263 -0
- package/equalUtils/index.ts +49 -30
- package/focusManager/FocusManager.ts +14 -2
- package/focusManager/index.ts +23 -4
- package/functionUtils/__tests__/__snapshots__/functionUtils.test.js.snap +4 -4
- package/functionUtils/index.ts +61 -19
- package/idleUtils/__tests__/withTimeout$.test.ts +37 -0
- package/idleUtils/index.ts +1 -1
- package/idleUtils/withTimeout.ts +15 -2
- package/index.d.ts +0 -12
- package/localizationUtils/index.ts +5 -10
- package/logger/const.ts +9 -67
- package/manifestUtils/__tests__/createConfig.test.js +16 -16
- package/manifestUtils/defaultManifestConfigurations/player.js +14 -0
- package/manifestUtils/fonts/index.js +5 -6
- package/manifestUtils/sharedConfiguration/screenPicker/__tests__/utils.test.js +304 -0
- package/manifestUtils/sharedConfiguration/screenPicker/stylesFields.js +875 -0
- package/manifestUtils/sharedConfiguration/screenPicker/utils.js +130 -0
- package/modalState/__tests__/index.test.ts +51 -0
- package/modalState/index.ts +33 -7
- package/navigationUtils/__tests__/__snapshots__/navigationUtils.test.js.snap +7 -6
- package/navigationUtils/__tests__/itemTypes.test.js +2 -2
- package/navigationUtils/__tests__/navigationUtils.test.js +2 -2
- package/navigationUtils/index.ts +20 -9
- package/numberUtils/__tests__/toPositiveNumberWithDefault.test.ts +23 -3
- package/numberUtils/index.ts +11 -5
- package/package.json +5 -10
- package/playerUtils/configurationGenerator.ts +14 -0
- package/reactHooks/advertising/index.ts +5 -5
- package/reactHooks/autoscrolling/__tests__/useTrackCurrentAutoScrollingElement.test.ts +1 -1
- package/reactHooks/autoscrolling/__tests__/useTrackedView.test.tsx +6 -8
- package/reactHooks/autoscrolling/useTrackedView.ts +12 -1
- package/reactHooks/cell-click/__tests__/index.test.js +10 -2
- package/reactHooks/cell-click/index.ts +7 -1
- package/reactHooks/feed/__tests__/useBuildPipesUrl.test.tsx +4 -4
- package/reactHooks/feed/__tests__/useFeedLoader.test.tsx +10 -11
- package/reactHooks/feed/useFeedLoader.tsx +18 -9
- package/reactHooks/feed/usePipesCacheReset.ts +5 -5
- package/reactHooks/flatList/__tests__/index.test.tsx +30 -21
- package/reactHooks/hookModal/hooks/useHookModalScreenData.ts +39 -0
- package/reactHooks/layout/__tests__/index.test.tsx +10 -10
- package/reactHooks/layout/useDimensions/helpers/__tests__/getInitialDimensions.native.test.js +14 -28
- package/reactHooks/layout/useDimensions/helpers/__tests__/getInitialDimensions.test.js +1 -1
- package/reactHooks/layout/useDimensions/useDimensions.ts +8 -0
- package/reactHooks/navigation/__mocks__/useNavigation.ts +3 -0
- package/reactHooks/navigation/__tests__/index.test.tsx +6 -21
- package/reactHooks/navigation/index.ts +41 -240
- package/reactHooks/navigation/useGetBottomTabBarHeight.ts +12 -0
- package/reactHooks/navigation/useGetNavBarTopBorderWidth.ts +14 -0
- package/reactHooks/navigation/useGetTabBarHeight.ts +10 -0
- package/reactHooks/navigation/useIsScreenActive.ts +17 -0
- package/reactHooks/navigation/useNavigationPluginData.ts +15 -0
- package/reactHooks/navigation/useNavigationType.ts +15 -0
- package/reactHooks/navigation/usePathname.ts +4 -0
- package/reactHooks/navigation/useProfilerLogging.ts +15 -0
- package/reactHooks/navigation/useRoute.ts +98 -0
- package/reactHooks/navigation/useUniqueRouteSuffix.ts +41 -0
- package/reactHooks/player/TVSeekControlller/ISeekController.ts +32 -0
- package/reactHooks/player/TVSeekControlller/LongPressSeekController.ts +71 -0
- package/reactHooks/player/TVSeekControlller/TVSeekController.ts +258 -0
- package/reactHooks/player/TVSeekControlller/TapSeekController.ts +53 -0
- package/reactHooks/player/__tests__/{useAutoSeek.test.tsx → useAutoSeek._test.tsx} +2 -3
- package/reactHooks/player/const.ts +0 -4
- package/reactHooks/player/index.ts +0 -6
- package/reactHooks/state/useRefWithInitialValue.ts +14 -0
- package/reactHooks/state/useStateFromSubscribe.ts +23 -0
- package/reactHooks/usePluginConfiguration.ts +1 -1
- package/reactHooks/useSubscriberFor.ts +4 -3
- package/reactUtils/__tests__/__snapshots__/reactUtilsHelpers.test.js.snap +16 -4
- package/reactUtils/__tests__/reactUtils.test.js +1 -37
- package/reactUtils/__tests__/reactUtilsHelpers.test.js +72 -71
- package/reactUtils/createContext/__tests__/__snapshots__/helpers.test.js.snap +13 -79
- package/reactUtils/createContext/__tests__/__snapshots__/{index.test.js.snap → index.test.ts.snap} +2 -2
- package/reactUtils/createContext/__tests__/__snapshots__/provider.test.js.snap +3 -28
- package/reactUtils/createContext/__tests__/__snapshots__/withConsumer.test.js.snap +3 -4
- package/reactUtils/createContext/__tests__/__snapshots__/withProvider.test.js.snap +7 -3
- package/reactUtils/createContext/__tests__/helpers.test.js +107 -121
- package/reactUtils/createContext/__tests__/{index.test.js → index.test.ts} +2 -2
- package/reactUtils/createContext/__tests__/provider.test.js +4 -6
- package/reactUtils/createContext/__tests__/withConsumer.test.js +12 -12
- package/reactUtils/createContext/__tests__/withProvider.test.js +4 -4
- package/reactUtils/createContext/helpers.ts +6 -1
- package/reactUtils/createContext/index.ts +11 -25
- package/reactUtils/index.ts +0 -25
- package/screenState/index.ts +24 -10
- package/services/js2native.ts +673 -0
- package/testUtils/index.tsx +0 -10
- package/theme/__mocks__/index.ts +4 -0
- package/theme/index.ts +1 -1
- package/time/BackgroundTimer.ts +55 -0
- package/time/Timer.ts +9 -6
- package/types.ts +1 -0
- package/utils/README.md +30 -0
- package/utils/chunk.ts +5 -0
- package/utils/index.ts +5 -0
- package/utils/times.ts +5 -0
- package/zappFrameworkUtils/localStorageHelper.ts +6 -0
- package/zappFrameworkUtils/loginPluginUtils.ts +6 -2
- package/zappFrameworkUtils/presentPluginOneTime.ts +2 -3
- package/zappFrameworkUtils/types.ts +11 -0
- package/appUtils/keyCodes/keys.ios.js +0 -46
- package/reactHooks/player/useAutoSeek.tsx +0 -87
- package/reactHooks/player/useSeek.tsx +0 -66
- package/reactHooks/player/useTapSeek.tsx +0 -58
- package/reactUtils/createContext/__tests__/index-no-react.test.js +0 -27
- /package/appUtils/HooksManager/{logger.js → logger.ts} +0 -0
- /package/appUtils/{directionHelper.js → directionHelper.ts} +0 -0
- /package/appUtils/keyCodes/{androidTVKeys.js → androidTVKeys.ts} +0 -0
- /package/appUtils/keyCodes/{keys.web.js → keys/keys.web.ts} +0 -0
- /package/domUtils/{logger.js → logger.ts} +0 -0
- /package/reactHooks/player/__tests__/{useTapSeek.test.ts → useTapSeek._test.ts} +0 -0
|
@@ -62,9 +62,9 @@ describe("HooksManager", () => {
|
|
|
62
62
|
const successHandler = jest.fn();
|
|
63
63
|
|
|
64
64
|
it("invokes the success handler directly", () => {
|
|
65
|
-
hooksManager
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
hooksManager.subscriber.on(HOOKS_EVENTS.COMPLETE, successHandler);
|
|
66
|
+
|
|
67
|
+
hooksManager.handleHooks(payload);
|
|
68
68
|
|
|
69
69
|
expect(successHandler).toHaveBeenCalledTimes(1);
|
|
70
70
|
|
|
@@ -103,11 +103,12 @@ describe("HooksManager", () => {
|
|
|
103
103
|
const presentScreenHandler = jest.fn();
|
|
104
104
|
|
|
105
105
|
it("executes the player hook", () => {
|
|
106
|
-
hooksManager
|
|
106
|
+
hooksManager.subscriber
|
|
107
107
|
.on(HOOKS_EVENTS.PRESENT_SCREEN_HOOK, presentScreenHandler)
|
|
108
108
|
.on(HOOKS_EVENTS.SUCCESS, successHandler)
|
|
109
|
-
.on(HOOKS_EVENTS.COMPLETE, completeHandler)
|
|
110
|
-
|
|
109
|
+
.on(HOOKS_EVENTS.COMPLETE, completeHandler);
|
|
110
|
+
|
|
111
|
+
hooksManager.handleHooks(payload);
|
|
111
112
|
|
|
112
113
|
expect(headlessPlayerHook.module.run).toHaveBeenCalledWith(
|
|
113
114
|
payload,
|
|
@@ -115,20 +116,14 @@ describe("HooksManager", () => {
|
|
|
115
116
|
headlessPlayerHook.configuration
|
|
116
117
|
);
|
|
117
118
|
|
|
118
|
-
expect(successHandler).
|
|
119
|
-
{ hookPlugin: expect.objectContaining(headlessPlayerHook), payload },
|
|
120
|
-
expect.any(Function)
|
|
121
|
-
);
|
|
119
|
+
expect(successHandler.mock.calls[0]).toMatchSnapshot();
|
|
122
120
|
|
|
123
|
-
expect(completeHandler).
|
|
124
|
-
{ hookPlugin: expect.objectContaining(headlessPlayerHook), payload },
|
|
125
|
-
expect.any(Function)
|
|
126
|
-
);
|
|
121
|
+
expect(completeHandler.mock.calls[0]).toMatchSnapshot();
|
|
127
122
|
});
|
|
128
123
|
});
|
|
129
124
|
|
|
130
125
|
describe("when there are preload hooks", () => {
|
|
131
|
-
|
|
126
|
+
it("hook with screen: executes", () => {
|
|
132
127
|
const hookScreenId = "6e15fcbf-9414-4ea8-b7db-a287593ab6bd";
|
|
133
128
|
const pluginScreenId = "1bb8ad39-a42e-4096-a134-56aadbd35c83";
|
|
134
129
|
|
|
@@ -157,36 +152,29 @@ describe("HooksManager", () => {
|
|
|
157
152
|
}
|
|
158
153
|
);
|
|
159
154
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
.on(HOOKS_EVENTS.COMPLETE, completeHandler)
|
|
165
|
-
.handleHooks(payload);
|
|
155
|
+
hooksManager.subscriber
|
|
156
|
+
.on(HOOKS_EVENTS.PRESENT_SCREEN_HOOK, presentScreenHandler)
|
|
157
|
+
.on(HOOKS_EVENTS.SUCCESS, successHandler)
|
|
158
|
+
.on(HOOKS_EVENTS.COMPLETE, completeHandler);
|
|
166
159
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
160
|
+
hooksManager.handleHooks(payload);
|
|
161
|
+
|
|
162
|
+
expect(presentScreenHandler).toHaveBeenCalledWith(
|
|
163
|
+
{
|
|
164
|
+
route: `/hooks/${pluginScreenId}`,
|
|
165
|
+
hookPlugin: expect.objectContaining(hookScreen),
|
|
166
|
+
payload: {
|
|
167
|
+
payload,
|
|
170
168
|
hookPlugin: expect.objectContaining(hookScreen),
|
|
171
|
-
|
|
172
|
-
payload,
|
|
173
|
-
hookPlugin: expect.objectContaining(hookScreen),
|
|
174
|
-
callback: expect.any(Function),
|
|
175
|
-
},
|
|
169
|
+
callback: expect.any(Function),
|
|
176
170
|
},
|
|
177
|
-
|
|
178
|
-
)
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
expect(completeHandler).toHaveBeenCalledWith(
|
|
186
|
-
{ payload, hookPlugin: expect.objectContaining(hookScreen) },
|
|
187
|
-
expect.any(Function)
|
|
188
|
-
);
|
|
189
|
-
});
|
|
171
|
+
},
|
|
172
|
+
expect.any(Function)
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
expect(successHandler.mock.calls[0]).toMatchSnapshot();
|
|
176
|
+
|
|
177
|
+
expect(completeHandler.mock.calls[0]).toMatchSnapshot();
|
|
190
178
|
});
|
|
191
179
|
});
|
|
192
180
|
|
|
@@ -226,11 +214,12 @@ describe("HooksManager", () => {
|
|
|
226
214
|
});
|
|
227
215
|
|
|
228
216
|
it("executes the hook", () => {
|
|
229
|
-
hooksManager
|
|
217
|
+
hooksManager.subscriber
|
|
230
218
|
.on(HOOKS_EVENTS.PRESENT_SCREEN_HOOK, presentScreenHandler)
|
|
231
219
|
.on(HOOKS_EVENTS.SUCCESS, successHandler)
|
|
232
|
-
.on(HOOKS_EVENTS.COMPLETE, completeHandler)
|
|
233
|
-
|
|
220
|
+
.on(HOOKS_EVENTS.COMPLETE, completeHandler);
|
|
221
|
+
|
|
222
|
+
hooksManager.handleHooks(payload);
|
|
234
223
|
|
|
235
224
|
expect(presentScreenHandler).toHaveBeenCalledTimes(2);
|
|
236
225
|
|
|
@@ -341,12 +330,13 @@ describe("HooksManager", () => {
|
|
|
341
330
|
);
|
|
342
331
|
|
|
343
332
|
it("stops the flow", () => {
|
|
344
|
-
hooksManager
|
|
333
|
+
hooksManager.subscriber
|
|
345
334
|
.on(HOOKS_EVENTS.PRESENT_SCREEN_HOOK, presentScreenHandler)
|
|
346
335
|
.on(HOOKS_EVENTS.CANCEL, cancelHandler)
|
|
347
336
|
.on(HOOKS_EVENTS.SUCCESS, successHandler)
|
|
348
|
-
.on(HOOKS_EVENTS.COMPLETE, completeHandler)
|
|
349
|
-
|
|
337
|
+
.on(HOOKS_EVENTS.COMPLETE, completeHandler);
|
|
338
|
+
|
|
339
|
+
hooksManager.handleHooks(payload);
|
|
350
340
|
|
|
351
341
|
expect(cancelHandler).toHaveBeenCalledWith(
|
|
352
342
|
{ hookPlugin: expect.any(Object), payload },
|
|
@@ -370,25 +360,28 @@ describe("HooksManager", () => {
|
|
|
370
360
|
const payload = { foo: "bar" };
|
|
371
361
|
|
|
372
362
|
it("executes the hook", () => {
|
|
373
|
-
hooksManager
|
|
363
|
+
hooksManager.subscriber
|
|
374
364
|
.on(HOOKS_EVENTS.SUCCESS, successHandler)
|
|
375
|
-
.on(HOOKS_EVENTS.COMPLETE, completeHandler)
|
|
376
|
-
.handleHooks(payload);
|
|
365
|
+
.on(HOOKS_EVENTS.COMPLETE, completeHandler);
|
|
377
366
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
367
|
+
hooksManager.handleHooks(payload);
|
|
368
|
+
|
|
369
|
+
expect(successHandler.mock.calls[0][0].payload).toMatchObject({
|
|
370
|
+
...payload,
|
|
371
|
+
identifier: "hook_plugin",
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
expect(successHandler.mock.calls[0][0].hookPlugin).toMatchObject(
|
|
375
|
+
hookPlugin
|
|
384
376
|
);
|
|
385
377
|
|
|
386
|
-
expect(completeHandler).
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
378
|
+
expect(completeHandler.mock.calls[0][0].payload).toMatchObject({
|
|
379
|
+
...payload,
|
|
380
|
+
identifier: "hook_plugin",
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
expect(completeHandler.mock.calls[0][0].hookPlugin).toMatchObject(
|
|
384
|
+
hookPlugin
|
|
392
385
|
);
|
|
393
386
|
});
|
|
394
387
|
});
|
|
@@ -410,11 +403,12 @@ describe("HooksManager", () => {
|
|
|
410
403
|
const hooksManager = HooksManager({ rivers, targetScreen, plugins });
|
|
411
404
|
|
|
412
405
|
it("invokes the error handler but not the success handler", () => {
|
|
413
|
-
hooksManager
|
|
406
|
+
hooksManager.subscriber
|
|
414
407
|
.on(HOOKS_EVENTS.SUCCESS, successHandler)
|
|
415
408
|
.on(HOOKS_EVENTS.COMPLETE, completeHandler)
|
|
416
|
-
.on(HOOKS_EVENTS.ERROR, errorHandler)
|
|
417
|
-
|
|
409
|
+
.on(HOOKS_EVENTS.ERROR, errorHandler);
|
|
410
|
+
|
|
411
|
+
hooksManager.handleHooks(payload);
|
|
418
412
|
|
|
419
413
|
expect(successHandler).not.toHaveBeenCalled();
|
|
420
414
|
|
|
@@ -447,12 +441,13 @@ describe("HooksManager", () => {
|
|
|
447
441
|
const hooksManager = HooksManager({ rivers, targetScreen, plugins });
|
|
448
442
|
|
|
449
443
|
it("invokes the error handler, and stops the flow", () => {
|
|
450
|
-
hooksManager
|
|
444
|
+
hooksManager.subscriber
|
|
451
445
|
.on(HOOKS_EVENTS.SUCCESS, successHandler)
|
|
452
446
|
.on(HOOKS_EVENTS.COMPLETE, completeHandler)
|
|
453
447
|
.on(HOOKS_EVENTS.ERROR, errorHandler)
|
|
454
|
-
.on(HOOKS_EVENTS.CANCEL, cancelHandler)
|
|
455
|
-
|
|
448
|
+
.on(HOOKS_EVENTS.CANCEL, cancelHandler);
|
|
449
|
+
|
|
450
|
+
hooksManager.handleHooks(payload);
|
|
456
451
|
|
|
457
452
|
expect(errorHandler).toHaveBeenCalledWith(
|
|
458
453
|
{
|
|
@@ -507,48 +502,50 @@ describe("HooksManager", () => {
|
|
|
507
502
|
const hooksManager = HooksManager({ rivers, targetScreen, plugins });
|
|
508
503
|
|
|
509
504
|
it("executes the hook", () => {
|
|
510
|
-
hooksManager
|
|
505
|
+
hooksManager.subscriber
|
|
511
506
|
.on(HOOKS_EVENTS.COMPLETE, completeHandler)
|
|
512
|
-
.on(HOOKS_EVENTS.SUCCESS, successHandler)
|
|
513
|
-
|
|
507
|
+
.on(HOOKS_EVENTS.SUCCESS, successHandler);
|
|
508
|
+
|
|
509
|
+
hooksManager.handleHooks(payload);
|
|
514
510
|
|
|
515
511
|
expect(successHandler).toHaveBeenCalledTimes(3);
|
|
516
512
|
|
|
517
|
-
expect(successHandler).
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
513
|
+
expect(successHandler.mock.calls[0][0].payload).toMatchObject({
|
|
514
|
+
...payload,
|
|
515
|
+
identifier: "hook_plugin",
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
expect(successHandler.mock.calls[0][0].hookPlugin).toMatchObject(
|
|
519
|
+
hookPlugin
|
|
524
520
|
);
|
|
525
521
|
|
|
526
|
-
expect(successHandler).
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
522
|
+
expect(successHandler.mock.calls[1][0].payload).toMatchObject({
|
|
523
|
+
...payload,
|
|
524
|
+
identifier: "hook_plugin_2",
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
expect(successHandler.mock.calls[1][0].hookPlugin).toMatchObject(
|
|
528
|
+
hookPlugin2
|
|
533
529
|
);
|
|
534
530
|
|
|
535
|
-
expect(successHandler).
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
531
|
+
expect(successHandler.mock.calls[2][0].payload).toMatchObject({
|
|
532
|
+
...payload,
|
|
533
|
+
identifier: "hook_plugin_3",
|
|
534
|
+
});
|
|
535
|
+
|
|
536
|
+
expect(successHandler.mock.calls[2][0].hookPlugin).toMatchObject(
|
|
537
|
+
hookPlugin3
|
|
542
538
|
);
|
|
543
539
|
|
|
544
540
|
expect(completeHandler).toHaveBeenCalledTimes(1);
|
|
545
541
|
|
|
546
|
-
expect(completeHandler).
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
542
|
+
expect(completeHandler.mock.calls[0][0].payload).toMatchObject({
|
|
543
|
+
...payload,
|
|
544
|
+
identifier: "hook_plugin_3",
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
expect(completeHandler.mock.calls[0][0].hookPlugin).toMatchObject(
|
|
548
|
+
hookPlugin3
|
|
552
549
|
);
|
|
553
550
|
|
|
554
551
|
expect(hookPlugin.module.run).toHaveBeenCalledWith(
|
|
@@ -10,14 +10,72 @@ import { Hook } from "./Hook";
|
|
|
10
10
|
import { HOOKS_EVENTS, HOOKS_TYPE } from "./constants";
|
|
11
11
|
|
|
12
12
|
import { hooksManagerLogger } from "./logger";
|
|
13
|
+
import { HookManager, HookManagerArgs } from "./types";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* orders the hooks according to their weight
|
|
17
|
+
* @param {Array<object>} hooks to sort out
|
|
18
|
+
* @returns {Array<object>} sorted hooks
|
|
19
|
+
*/
|
|
20
|
+
function orderHooksByWeight(hooks: Hook[]) {
|
|
21
|
+
return R.sortBy(R.compose(Number, R.prop("weight")), hooks);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function executeOnNextHook(
|
|
25
|
+
hooks: Hook[],
|
|
26
|
+
payload: object,
|
|
27
|
+
callback: (hookPlugin: Hook, restOfHooks: Hook[], payload: object) => void
|
|
28
|
+
) {
|
|
29
|
+
const [nextHook, ...restOfHooks] = orderHooksByWeight(hooks);
|
|
30
|
+
|
|
31
|
+
if (nextHook) {
|
|
32
|
+
nextHook.execute(payload, callback(nextHook, restOfHooks, payload));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* tells wether the current river is related to a player plugin, or the default player
|
|
38
|
+
* @param {Object} river
|
|
39
|
+
* @returns {boolean}
|
|
40
|
+
*/
|
|
41
|
+
function riverIsPlayer(river, plugins) {
|
|
42
|
+
const { screenType, plugin_type } = river;
|
|
43
|
+
|
|
44
|
+
if (screenType || plugin_type) {
|
|
45
|
+
return screenType === "playable" || plugin_type === "player";
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const { type } = river;
|
|
49
|
+
|
|
50
|
+
return R.compose(
|
|
51
|
+
R.propEq("type", "player"),
|
|
52
|
+
R.defaultTo({}),
|
|
53
|
+
R.find(R.propEq("identifier", type))
|
|
54
|
+
)(plugins);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Injects the hooks for the player
|
|
59
|
+
* @param _hookType type of hook
|
|
60
|
+
* @param plugins plugins
|
|
61
|
+
* @returns {Array<Object>}
|
|
62
|
+
*/
|
|
63
|
+
function injectPlayerHooks(_hookType: string, plugins): Hook[] {
|
|
64
|
+
const playerhooks: Hook[] = R.compose(
|
|
65
|
+
R.sortBy(R.prop("weight")),
|
|
66
|
+
R.map((plugin) => ({
|
|
67
|
+
identifier: plugin.identifier,
|
|
68
|
+
weight: R.path(["module", "weight"], plugin) || 1,
|
|
69
|
+
})),
|
|
70
|
+
R.filter(R.pathEq(["module", "hasPlayerHook"], true))
|
|
71
|
+
)(plugins);
|
|
72
|
+
|
|
73
|
+
return playerhooks;
|
|
74
|
+
}
|
|
13
75
|
|
|
14
76
|
/**
|
|
15
77
|
* creates a hooksManager object to handle the hooks process.
|
|
16
78
|
* it is based on the `subscriber` object
|
|
17
|
-
* @param {object} options
|
|
18
|
-
* @param {object} rivers map of rivers in the app
|
|
19
|
-
* @param {object} targetScreen rivers which we are navigating to
|
|
20
|
-
* @param {Array<object>} plugins array of plugins in the app
|
|
21
79
|
* @returns {object} hooksManager object - see Navigator for usage
|
|
22
80
|
*/
|
|
23
81
|
export function HooksManager({
|
|
@@ -25,8 +83,8 @@ export function HooksManager({
|
|
|
25
83
|
targetScreen,
|
|
26
84
|
plugins,
|
|
27
85
|
startUpHooksData = {},
|
|
28
|
-
}) {
|
|
29
|
-
hooksManagerLogger.addContext({ targetScreen });
|
|
86
|
+
}: HookManagerArgs): HookManager {
|
|
87
|
+
hooksManagerLogger.addContext({ targetScreenId: targetScreen.id });
|
|
30
88
|
|
|
31
89
|
function logHookEvent(func, message, data) {
|
|
32
90
|
func({
|
|
@@ -35,7 +93,8 @@ export function HooksManager({
|
|
|
35
93
|
});
|
|
36
94
|
}
|
|
37
95
|
|
|
38
|
-
const hooksManager =
|
|
96
|
+
const hooksManager: Partial<HookManager> = {};
|
|
97
|
+
hooksManager.subscriber = subscriber();
|
|
39
98
|
|
|
40
99
|
/**
|
|
41
100
|
* attaches the screen data to the hook object if the hook
|
|
@@ -100,15 +159,6 @@ export function HooksManager({
|
|
|
100
159
|
};
|
|
101
160
|
}
|
|
102
161
|
|
|
103
|
-
/**
|
|
104
|
-
* orders the hooks according to their weight
|
|
105
|
-
* @param {Array<object>} hooks to sort out
|
|
106
|
-
* @returns {Array<object>} sorted hooks
|
|
107
|
-
*/
|
|
108
|
-
function orderHooksByWeight(hooks) {
|
|
109
|
-
return R.sortBy(R.compose(Number, R.prop("weight")), hooks);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
162
|
/**
|
|
113
163
|
* extracts the hooks form the target river. returns null if there are none
|
|
114
164
|
* if there are hooks, gathers all required data and constructs a Hook object
|
|
@@ -117,10 +167,10 @@ export function HooksManager({
|
|
|
117
167
|
* @returns {Array<Hooks>} list of hooks to go through
|
|
118
168
|
*/
|
|
119
169
|
function getHooks(hookType, river) {
|
|
120
|
-
const playerhooks = [];
|
|
170
|
+
const playerhooks: Hook[] = [];
|
|
121
171
|
|
|
122
|
-
if (riverIsPlayer(river)) {
|
|
123
|
-
playerhooks.push(...injectPlayerHooks(hookType));
|
|
172
|
+
if (riverIsPlayer(river, plugins)) {
|
|
173
|
+
playerhooks.push(...injectPlayerHooks(hookType, plugins));
|
|
124
174
|
}
|
|
125
175
|
|
|
126
176
|
let hooks = R.concat(playerhooks, R.pathOr([], ["hooks", hookType], river));
|
|
@@ -130,8 +180,10 @@ export function HooksManager({
|
|
|
130
180
|
const { startUpHooks, setStartUpHooks } = startUpHooksData;
|
|
131
181
|
|
|
132
182
|
if (startUpHooks && startUpHooks !== "in_process") {
|
|
133
|
-
|
|
134
|
-
|
|
183
|
+
if (Array.isArray(startUpHooks)) {
|
|
184
|
+
hooks.unshift(...startUpHooks);
|
|
185
|
+
setStartUpHooks("in_process");
|
|
186
|
+
}
|
|
135
187
|
}
|
|
136
188
|
|
|
137
189
|
if (!R.length(hooks)) {
|
|
@@ -158,45 +210,6 @@ export function HooksManager({
|
|
|
158
210
|
)(hooks);
|
|
159
211
|
}
|
|
160
212
|
|
|
161
|
-
/**
|
|
162
|
-
* tells wether the current river is related to a player plugin, or the default player
|
|
163
|
-
* @param {Object} river
|
|
164
|
-
* @returns {boolean}
|
|
165
|
-
*/
|
|
166
|
-
function riverIsPlayer(river) {
|
|
167
|
-
const { screenType, plugin_type } = river;
|
|
168
|
-
|
|
169
|
-
if (screenType || plugin_type) {
|
|
170
|
-
return screenType === "playable" || plugin_type === "player";
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const { type } = river;
|
|
174
|
-
|
|
175
|
-
return R.compose(
|
|
176
|
-
R.propEq("type", "player"),
|
|
177
|
-
R.defaultTo({}),
|
|
178
|
-
R.find(R.propEq("identifier", type))
|
|
179
|
-
)(plugins);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Injects the hooks for the player
|
|
184
|
-
* @param {String} hookType type of hook
|
|
185
|
-
* @returns {Array<Object>}
|
|
186
|
-
*/
|
|
187
|
-
function injectPlayerHooks(_hookType) {
|
|
188
|
-
const playerhooks = R.compose(
|
|
189
|
-
R.sortBy(R.prop("weight")),
|
|
190
|
-
R.map((plugin) => ({
|
|
191
|
-
identifier: plugin.identifier,
|
|
192
|
-
weight: R.path(["module", "weight"], plugin) || 1,
|
|
193
|
-
})),
|
|
194
|
-
R.filter(R.pathEq(["module", "hasPlayerHook"], true))
|
|
195
|
-
)(plugins);
|
|
196
|
-
|
|
197
|
-
return playerhooks;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
213
|
/**
|
|
201
214
|
* tells wether the given hook is the last one or not
|
|
202
215
|
* @param {Hook} hookPlugin
|
|
@@ -209,6 +222,32 @@ export function HooksManager({
|
|
|
209
222
|
return hookPlugin.lastHook;
|
|
210
223
|
}
|
|
211
224
|
|
|
225
|
+
/**
|
|
226
|
+
* flags a hook as succeeded, and pass hook data along
|
|
227
|
+
* @param {Hook} hookPlugin
|
|
228
|
+
* @param {object} payload returned by the hook plugin
|
|
229
|
+
*/
|
|
230
|
+
function completeHook(hookPlugin, payload, callback) {
|
|
231
|
+
logHookEvent(
|
|
232
|
+
hooksManagerLogger.info,
|
|
233
|
+
`completeHook: hook sequence completed successfully: ${hookPlugin["identifier"]}`,
|
|
234
|
+
{
|
|
235
|
+
payload,
|
|
236
|
+
hook: hookPlugin,
|
|
237
|
+
}
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
// eslint-disable-next-line
|
|
241
|
+
// TODO: Temporary hack to pass getLoginProtocol to other plugins to refresh in case token expired, need be deleted later
|
|
242
|
+
delete payload.getLoginProtocol;
|
|
243
|
+
|
|
244
|
+
hookPlugin.setStateAndNotify(HOOKS_EVENTS.COMPLETE, {
|
|
245
|
+
hookPlugin,
|
|
246
|
+
payload,
|
|
247
|
+
callback,
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
|
|
212
251
|
/**
|
|
213
252
|
* creates the callback to invoke in order to proceed to the next hook
|
|
214
253
|
* covers the scenarios of failure & flow blocking
|
|
@@ -228,9 +267,12 @@ export function HooksManager({
|
|
|
228
267
|
success,
|
|
229
268
|
error,
|
|
230
269
|
payload = initialPayload,
|
|
231
|
-
callback,
|
|
270
|
+
callback: callbackArg,
|
|
232
271
|
cancelled,
|
|
272
|
+
abort,
|
|
233
273
|
}) {
|
|
274
|
+
let callback = callbackArg;
|
|
275
|
+
|
|
234
276
|
if (error) {
|
|
235
277
|
logHookEvent(
|
|
236
278
|
hooksManagerLogger.error,
|
|
@@ -267,12 +309,15 @@ export function HooksManager({
|
|
|
267
309
|
hookPlugin.setStateAndNotify(HOOKS_EVENTS.CANCEL, {
|
|
268
310
|
hookPlugin,
|
|
269
311
|
payload,
|
|
312
|
+
abort,
|
|
270
313
|
});
|
|
271
314
|
|
|
272
315
|
const isHookInHomescreen = payload?.home;
|
|
273
316
|
|
|
274
317
|
const isHookFlowBlocker =
|
|
275
|
-
hookPlugin?.module?.isFlowBlocker
|
|
318
|
+
typeof hookPlugin?.module?.isFlowBlocker === "function"
|
|
319
|
+
? hookPlugin?.module?.isFlowBlocker()
|
|
320
|
+
: hookPlugin?.module?.isFlowBlocker;
|
|
276
321
|
|
|
277
322
|
// TODO: We technically need to also support the case where there is more than one hook in the stack,
|
|
278
323
|
// if needed we could add differentiation explicit user cancellation (when we should go to background) and other types of cancellation
|
|
@@ -301,6 +346,18 @@ export function HooksManager({
|
|
|
301
346
|
}
|
|
302
347
|
);
|
|
303
348
|
|
|
349
|
+
if (!callback) {
|
|
350
|
+
logHookEvent(
|
|
351
|
+
hooksManagerLogger.warn,
|
|
352
|
+
`hookCallback: ${hookPlugin["identifier"]} is missing \`callback\`, using hookCallback(default one)`,
|
|
353
|
+
{
|
|
354
|
+
hookPlugin,
|
|
355
|
+
}
|
|
356
|
+
);
|
|
357
|
+
|
|
358
|
+
callback = hookCallback;
|
|
359
|
+
}
|
|
360
|
+
|
|
304
361
|
hookPlugin.setStateAndNotify(HOOKS_EVENTS.SUCCESS, {
|
|
305
362
|
hookPlugin,
|
|
306
363
|
payload,
|
|
@@ -309,37 +366,11 @@ export function HooksManager({
|
|
|
309
366
|
|
|
310
367
|
isLastHook(hookPlugin, restOfHooks)
|
|
311
368
|
? completeHook(hookPlugin, payload, callback)
|
|
312
|
-
:
|
|
369
|
+
: executeOnNextHook(restOfHooks, payload, callback);
|
|
313
370
|
}
|
|
314
371
|
};
|
|
315
372
|
}
|
|
316
373
|
|
|
317
|
-
/**
|
|
318
|
-
* flags a hook as succeeded, and pass hook data along
|
|
319
|
-
* @param {Hook} hookPlugin
|
|
320
|
-
* @param {object} payload returned by the hook plugin
|
|
321
|
-
*/
|
|
322
|
-
function completeHook(hookPlugin, payload, callback) {
|
|
323
|
-
logHookEvent(
|
|
324
|
-
hooksManagerLogger.info,
|
|
325
|
-
`completeHook: hook sequence completed successfully: ${hookPlugin["identifier"]}`,
|
|
326
|
-
{
|
|
327
|
-
payload,
|
|
328
|
-
hook: hookPlugin,
|
|
329
|
-
}
|
|
330
|
-
);
|
|
331
|
-
|
|
332
|
-
// eslint-disable-next-line
|
|
333
|
-
// TODO: Temporary hack to pass getLoginProtocol to other plugins to refresh in case token expired, need be deleted later
|
|
334
|
-
delete payload.getLoginProtocol;
|
|
335
|
-
|
|
336
|
-
hookPlugin.setStateAndNotify(HOOKS_EVENTS.COMPLETE, {
|
|
337
|
-
hookPlugin,
|
|
338
|
-
payload,
|
|
339
|
-
callback,
|
|
340
|
-
});
|
|
341
|
-
}
|
|
342
|
-
|
|
343
374
|
/**
|
|
344
375
|
* presents a screen hook by triggering an event invoking the handler with
|
|
345
376
|
* the appropriate route & payload
|
|
@@ -376,9 +407,6 @@ export function HooksManager({
|
|
|
376
407
|
|
|
377
408
|
/**
|
|
378
409
|
* executes a headless hook
|
|
379
|
-
* @param {Hook} hookPlugin to present
|
|
380
|
-
* @param {object} payload to pass to the hook module
|
|
381
|
-
* @param {function} callback to invoke when the hook is successful
|
|
382
410
|
*/
|
|
383
411
|
hooksManager.executeHook = function (hookPlugin, payload, callback) {
|
|
384
412
|
logHookEvent(
|
|
@@ -444,30 +472,13 @@ export function HooksManager({
|
|
|
444
472
|
}
|
|
445
473
|
};
|
|
446
474
|
|
|
447
|
-
/**
|
|
448
|
-
* handles the next hook in the list of provided hooks, passing the payload along
|
|
449
|
-
* @param {Array<Hook>} hooks to process
|
|
450
|
-
* @param {object} payload to pass to the hook
|
|
451
|
-
*/
|
|
452
|
-
function handleNextHook(hooks, payload) {
|
|
453
|
-
const [hookPlugin, ...restOfHooks] = orderHooksByWeight(hooks);
|
|
454
|
-
|
|
455
|
-
/**
|
|
456
|
-
* Commenting out part of the code which is trying to run the next hook
|
|
457
|
-
* in parallel - it's not in use, and it's creating unexpected side
|
|
458
|
-
* effects
|
|
459
|
-
* */
|
|
460
|
-
|
|
461
|
-
hookPlugin.execute(payload, hookCallback(hookPlugin, restOfHooks, payload));
|
|
462
|
-
}
|
|
463
|
-
|
|
464
475
|
/**
|
|
465
476
|
* function exposes on the hooks manager to trigger the handling of the hooks for
|
|
466
477
|
* the given targetScreen
|
|
467
478
|
* @param {object} payload to send to the hooks
|
|
468
479
|
* @returns {object} returns the hooks manager so methods can be chained
|
|
469
480
|
*/
|
|
470
|
-
hooksManager.handleHooks = function (payload) {
|
|
481
|
+
hooksManager.handleHooks = function (payload: object) {
|
|
471
482
|
const preloadHooks = getHooks(HOOKS_TYPE.PRELOAD, targetScreen);
|
|
472
483
|
|
|
473
484
|
if (preloadHooks?.length) {
|
|
@@ -482,9 +493,9 @@ export function HooksManager({
|
|
|
482
493
|
}
|
|
483
494
|
);
|
|
484
495
|
|
|
485
|
-
|
|
496
|
+
executeOnNextHook(preloadHooks, payload, hookCallback);
|
|
486
497
|
} else {
|
|
487
|
-
hooksManager.invokeHandler(HOOKS_EVENTS.COMPLETE, {
|
|
498
|
+
hooksManager.subscriber.invokeHandler(HOOKS_EVENTS.COMPLETE, {
|
|
488
499
|
hookPlugin: { lastHook: true },
|
|
489
500
|
payload,
|
|
490
501
|
});
|
|
@@ -493,5 +504,5 @@ export function HooksManager({
|
|
|
493
504
|
return hooksManager;
|
|
494
505
|
};
|
|
495
506
|
|
|
496
|
-
return hooksManager;
|
|
507
|
+
return hooksManager as HookManager;
|
|
497
508
|
}
|