@applicaster/zapp-react-native-utils 15.0.0-rc.99 → 15.1.0-alpha.2915689988

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 (160) hide show
  1. package/actionsExecutor/ActionExecutorContext.tsx +51 -5
  2. package/actionsExecutor/feedDecorator.ts +6 -6
  3. package/adsUtils/index.ts +2 -2
  4. package/analyticsUtils/AnalyticsEvents/sendMenuClickEvent.ts +2 -2
  5. package/analyticsUtils/PlayerAnalyticsManager.ts +11 -1
  6. package/analyticsUtils/README.md +1 -1
  7. package/analyticsUtils/__tests__/analyticsMapper.test.ts +35 -0
  8. package/analyticsUtils/__tests__/fixtures/analytics_mapper_testACP_events.json +1 -1
  9. package/analyticsUtils/__tests__/fixtures/analytics_mapper_testBlockUnlistedParams_rules.json +1 -1
  10. package/analyticsUtils/__tests__/fixtures/analytics_mapper_testEmptyRenameKeepsName_events.json +4 -0
  11. package/analyticsUtils/__tests__/fixtures/analytics_mapper_testEmptyRenameKeepsName_rules.json +6 -0
  12. package/analyticsUtils/__tests__/fixtures/analytics_mapper_testEventRegex_events.json +3 -9
  13. package/analyticsUtils/__tests__/fixtures/analytics_mapper_testIgnoreOrdering_events.json +18 -0
  14. package/analyticsUtils/__tests__/fixtures/analytics_mapper_testIgnoreOrdering_rules.json +16 -0
  15. package/analyticsUtils/__tests__/fixtures/analytics_mapper_testRegexEventNoFallback_events.json +4 -0
  16. package/analyticsUtils/__tests__/fixtures/analytics_mapper_testRegexEventNoFallback_rules.json +6 -0
  17. package/analyticsUtils/__tests__/fixtures/analytics_mapper_testRegexMultiGroupRename_events.json +4 -0
  18. package/analyticsUtils/__tests__/fixtures/analytics_mapper_testRegexMultiGroupRename_rules.json +6 -0
  19. package/analyticsUtils/__tests__/fixtures/analytics_mapper_testRegexNonNamedFullMatch_events.json +4 -0
  20. package/analyticsUtils/__tests__/fixtures/analytics_mapper_testRegexNonNamedFullMatch_rules.json +6 -0
  21. package/analyticsUtils/__tests__/fixtures/index.js +20 -0
  22. package/analyticsUtils/analyticsMapper.ts +4 -1
  23. package/analyticsUtils/playerAnalyticsTracker.ts +26 -3
  24. package/appUtils/HooksManager/__tests__/__snapshots__/hooksManager.test.js.snap +188 -0
  25. package/appUtils/HooksManager/__tests__/hooksManager.test.js +2 -16
  26. package/appUtils/HooksManager/index.ts +47 -17
  27. package/appUtils/RiverFocusManager/{index.ts → index.js} +18 -25
  28. package/appUtils/accessibilityManager/const.ts +0 -4
  29. package/appUtils/accessibilityManager/utils.ts +1 -0
  30. package/appUtils/contextKeysManager/__tests__/getKeys/failure.test.ts +2 -7
  31. package/appUtils/contextKeysManager/__tests__/getKeys/success.test.ts +0 -48
  32. package/appUtils/contextKeysManager/contextResolver.ts +22 -51
  33. package/appUtils/contextKeysManager/index.ts +10 -65
  34. package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +0 -3
  35. package/appUtils/focusManager/index.ios.ts +4 -43
  36. package/appUtils/focusManagerAux/utils/index.ts +3 -5
  37. package/appUtils/focusManagerAux/utils/utils.ios.ts +3 -199
  38. package/appUtils/keyCodes/keys/keys.web.ts +4 -1
  39. package/appUtils/localizationsHelper.ts +4 -0
  40. package/appUtils/orientationHelper.ts +4 -2
  41. package/appUtils/platform/platformUtils.ts +1 -1
  42. package/appUtils/playerManager/__tests__/playerFactory.test.ts +150 -0
  43. package/appUtils/playerManager/index.ts +9 -0
  44. package/appUtils/playerManager/player.ts +1 -5
  45. package/appUtils/playerManager/playerFactory.ts +17 -34
  46. package/appUtils/playerManager/playerNative.ts +22 -30
  47. package/appUtils/playerManager/usePlayer.tsx +5 -3
  48. package/appUtils/playerManager/usePlayerState.tsx +2 -14
  49. package/cellUtils/__tests__/cellUtils.test.ts +39 -0
  50. package/cellUtils/index.ts +11 -1
  51. package/cloudEventsUtils/index.ts +1 -65
  52. package/configurationUtils/__tests__/manifestKeyParser.test.ts +26 -26
  53. package/dateUtils/__tests__/dayjs.test.ts +0 -3
  54. package/dateUtils/index.ts +2 -0
  55. package/focusManager/aux/index.ts +1 -1
  56. package/headersUtils/__tests__/headersUtils.test.js +1 -11
  57. package/headersUtils/index.ts +1 -2
  58. package/manifestUtils/defaultManifestConfigurations/player.js +7 -75
  59. package/manifestUtils/tvAction/container/index.js +1 -1
  60. package/numberUtils/__tests__/toNumber.test.ts +0 -12
  61. package/numberUtils/index.ts +1 -19
  62. package/package.json +4 -4
  63. package/playerUtils/index.ts +24 -2
  64. package/pluginUtils/index.ts +4 -9
  65. package/reactHooks/advertising/index.ts +2 -2
  66. package/reactHooks/app/__tests__/useAppState.test.ts +1 -1
  67. package/reactHooks/autoscrolling/__tests__/useTrackCurrentAutoScrollingElement.test.ts +1 -1
  68. package/reactHooks/autoscrolling/__tests__/useTrackedView.test.tsx +2 -1
  69. package/reactHooks/casting/index.ts +1 -0
  70. package/reactHooks/casting/useIsCasting.tsx +57 -0
  71. package/reactHooks/cell-click/__tests__/index.test.js +3 -1
  72. package/reactHooks/componentsMap/index.ts +55 -0
  73. package/reactHooks/configuration/__tests__/index.test.tsx +1 -1
  74. package/reactHooks/connection/__tests__/index.test.js +1 -1
  75. package/reactHooks/debugging/__tests__/index.test.js +4 -4
  76. package/reactHooks/device/useIsTablet.tsx +19 -14
  77. package/reactHooks/device/useMemoizedIsTablet.ts +3 -3
  78. package/reactHooks/feed/__tests__/useBatchLoading.test.tsx +23 -32
  79. package/reactHooks/feed/__tests__/useBuildPipesUrl.test.tsx +19 -19
  80. package/reactHooks/feed/__tests__/useEntryScreenId.test.tsx +1 -4
  81. package/reactHooks/feed/__tests__/useFeedLoader.test.tsx +30 -42
  82. package/reactHooks/feed/__tests__/useFeedRefresh.test.tsx +1 -1
  83. package/reactHooks/feed/__tests__/useInflatedUrl.test.tsx +1 -1
  84. package/reactHooks/feed/useBatchLoading.ts +1 -7
  85. package/reactHooks/feed/useEntryScreenId.ts +2 -2
  86. package/reactHooks/feed/useInflatedUrl.ts +1 -1
  87. package/reactHooks/feed/usePipesCacheReset.ts +1 -3
  88. package/reactHooks/flatList/useLoadNextPageIfNeeded.ts +16 -13
  89. package/reactHooks/layout/__tests__/index.test.tsx +1 -1
  90. package/reactHooks/layout/__tests__/useLayoutVersion.test.tsx +1 -1
  91. package/reactHooks/layout/useDimensions/__tests__/{useDimensions.test.tsx → useDimensions.test.ts} +25 -105
  92. package/reactHooks/layout/useDimensions/useDimensions.ts +2 -2
  93. package/reactHooks/navigation/__tests__/index.test.tsx +4 -2
  94. package/reactHooks/navigation/index.ts +6 -7
  95. package/reactHooks/navigation/useRoute.ts +6 -8
  96. package/reactHooks/player/TVSeekControlller/TVSeekController.ts +10 -27
  97. package/reactHooks/player/__tests__/useAutoSeek._test.tsx +1 -1
  98. package/reactHooks/player/__tests__/useTapSeek._test.ts +1 -1
  99. package/reactHooks/resolvers/__tests__/useCellResolver.test.tsx +1 -1
  100. package/reactHooks/resolvers/__tests__/useComponentResolver.test.tsx +1 -1
  101. package/reactHooks/resolvers/useCellResolver.ts +2 -6
  102. package/reactHooks/resolvers/useComponentResolver.ts +13 -9
  103. package/reactHooks/screen/__tests__/useCurrentScreenData.test.tsx +2 -2
  104. package/reactHooks/screen/__tests__/useCurrentScreenIsHook.test.ts +103 -0
  105. package/reactHooks/screen/__tests__/useCurrentScreenIsStartupHook.test.ts +94 -0
  106. package/reactHooks/screen/__tests__/useScreenBackgroundColor.test.tsx +1 -1
  107. package/reactHooks/screen/__tests__/useScreenData.test.tsx +1 -1
  108. package/reactHooks/screen/__tests__/useTargetScreenData.test.tsx +4 -12
  109. package/reactHooks/screen/index.ts +6 -0
  110. package/reactHooks/screen/useCurrentScreenIsHook.ts +9 -0
  111. package/reactHooks/screen/useCurrentScreenIsStartupHook.ts +8 -0
  112. package/reactHooks/screen/useIsStandaloneFullscreen.ts +12 -0
  113. package/reactHooks/screen/useTargetScreenData.ts +2 -4
  114. package/reactHooks/state/__tests__/useComponentScreenState.test.ts +246 -0
  115. package/reactHooks/state/index.ts +2 -0
  116. package/reactHooks/state/useComponentScreenState.ts +45 -0
  117. package/reactHooks/state/useRivers.ts +1 -1
  118. package/reactHooks/usePluginConfiguration.ts +2 -2
  119. package/reactHooks/utils/__tests__/index.test.js +1 -1
  120. package/reactHooks/videoModal/hooks/useVideoModalScreenData.tsx +22 -4
  121. package/rectUtils/index.ts +2 -2
  122. package/screenPickerUtils/index.ts +5 -0
  123. package/screenState/__tests__/index.test.ts +1 -1
  124. package/stringUtils/index.ts +1 -1
  125. package/testUtils/index.tsx +21 -30
  126. package/typeGuards/index.ts +0 -4
  127. package/utils/__tests__/clone.test.ts +158 -0
  128. package/utils/clone.ts +7 -0
  129. package/utils/index.ts +1 -13
  130. package/utils/path.ts +3 -6
  131. package/utils/pathOr.ts +1 -5
  132. package/zappFrameworkUtils/HookCallback/callbackNavigationAction.ts +2 -2
  133. package/zappFrameworkUtils/HookCallback/hookCallbackManifestExtensions.config.js +1 -1
  134. package/zappFrameworkUtils/loginPluginUtils.ts +1 -1
  135. package/adsUtils/__tests__/createVMAP.test.ts +0 -419
  136. package/appDataUtils/__tests__/urlScheme.test.ts +0 -678
  137. package/appUtils/focusManagerAux/utils/index.ios.ts +0 -122
  138. package/cloudEventsUtils/__tests__/index.test.ts +0 -529
  139. package/enumUtils/__tests__/getEnumKeyByEnumValue.test.ts +0 -207
  140. package/errorUtils/__tests__/GeneralError.test.ts +0 -97
  141. package/errorUtils/__tests__/HttpStatusCode.test.ts +0 -344
  142. package/errorUtils/__tests__/MissingPluginError.test.ts +0 -113
  143. package/errorUtils/__tests__/NetworkError.test.ts +0 -202
  144. package/errorUtils/__tests__/getParsedResponse.test.ts +0 -188
  145. package/errorUtils/__tests__/invariant.test.ts +0 -112
  146. package/numberUtils/__tests__/toPositiveNumber.test.ts +0 -165
  147. package/reactHooks/analytics/__tests__/useSendAnalyticsOnPress.test.ts +0 -537
  148. package/reactHooks/dev/__tests__/useReRenderLog.test.ts +0 -188
  149. package/reactHooks/ui/__tests__/useFadeOutWhenBlurred.test.ts +0 -580
  150. package/rectUtils/__tests__/index.test.ts +0 -549
  151. package/screenPickerUtils/__tests__/index.test.ts +0 -333
  152. package/searchUtils/const.ts +0 -7
  153. package/searchUtils/index.ts +0 -3
  154. package/time/__tests__/BackgroundTimer.test.ts +0 -156
  155. package/time/__tests__/Timer.test.ts +0 -236
  156. package/typeGuards/__tests__/isString.test.ts +0 -21
  157. package/utils/__tests__/mergeRight.test.ts +0 -48
  158. package/utils/__tests__/selectors.test.ts +0 -124
  159. package/utils/mergeRight.ts +0 -5
  160. package/utils/selectors.ts +0 -46
@@ -1,5 +1,193 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
+ exports[`HooksManager when target route is playable executes the player hook 1`] = `
4
+ [
5
+ {
6
+ "callback": [Function],
7
+ "hookPlugin": Hook {
8
+ "configuration": {
9
+ "config_field": "bar",
10
+ },
11
+ "identifier": "headless_player_hook",
12
+ "lastHook": true,
13
+ "manager": {
14
+ "executeHook": [Function],
15
+ "handleHooks": [Function],
16
+ "presentScreenHook": [Function],
17
+ "runInBackground": [Function],
18
+ "subscriber": {
19
+ "handlers": {
20
+ "complete": [
21
+ [MockFunction] {
22
+ "calls": [
23
+ [
24
+ {
25
+ "callback": [Function],
26
+ "hookPlugin": [Circular],
27
+ "payload": {
28
+ "foo": "bar",
29
+ },
30
+ },
31
+ [Function],
32
+ ],
33
+ ],
34
+ "results": [
35
+ {
36
+ "type": "return",
37
+ "value": undefined,
38
+ },
39
+ ],
40
+ },
41
+ ],
42
+ "presentScreenHook": [
43
+ [MockFunction],
44
+ ],
45
+ "success": [
46
+ [MockFunction] {
47
+ "calls": [
48
+ [Circular],
49
+ ],
50
+ "results": [
51
+ {
52
+ "type": "return",
53
+ "value": undefined,
54
+ },
55
+ ],
56
+ },
57
+ ],
58
+ },
59
+ "invokeHandler": [Function],
60
+ "on": [Function],
61
+ "removeHandler": [Function],
62
+ },
63
+ },
64
+ "module": {
65
+ "hasPlayerHook": true,
66
+ "run": [MockFunction] {
67
+ "calls": [
68
+ [
69
+ {
70
+ "foo": "bar",
71
+ },
72
+ [Function],
73
+ {
74
+ "config_field": "bar",
75
+ },
76
+ ],
77
+ ],
78
+ "results": [
79
+ {
80
+ "type": "return",
81
+ "value": undefined,
82
+ },
83
+ ],
84
+ },
85
+ },
86
+ "state": 7,
87
+ "weight": 1,
88
+ },
89
+ "payload": {
90
+ "foo": "bar",
91
+ },
92
+ },
93
+ [Function],
94
+ ]
95
+ `;
96
+
97
+ exports[`HooksManager when target route is playable executes the player hook 2`] = `
98
+ [
99
+ {
100
+ "callback": [Function],
101
+ "hookPlugin": Hook {
102
+ "configuration": {
103
+ "config_field": "bar",
104
+ },
105
+ "identifier": "headless_player_hook",
106
+ "lastHook": true,
107
+ "manager": {
108
+ "executeHook": [Function],
109
+ "handleHooks": [Function],
110
+ "presentScreenHook": [Function],
111
+ "runInBackground": [Function],
112
+ "subscriber": {
113
+ "handlers": {
114
+ "complete": [
115
+ [MockFunction] {
116
+ "calls": [
117
+ [Circular],
118
+ ],
119
+ "results": [
120
+ {
121
+ "type": "return",
122
+ "value": undefined,
123
+ },
124
+ ],
125
+ },
126
+ ],
127
+ "presentScreenHook": [
128
+ [MockFunction],
129
+ ],
130
+ "success": [
131
+ [MockFunction] {
132
+ "calls": [
133
+ [
134
+ {
135
+ "callback": [Function],
136
+ "hookPlugin": [Circular],
137
+ "payload": {
138
+ "foo": "bar",
139
+ },
140
+ },
141
+ [Function],
142
+ ],
143
+ ],
144
+ "results": [
145
+ {
146
+ "type": "return",
147
+ "value": undefined,
148
+ },
149
+ ],
150
+ },
151
+ ],
152
+ },
153
+ "invokeHandler": [Function],
154
+ "on": [Function],
155
+ "removeHandler": [Function],
156
+ },
157
+ },
158
+ "module": {
159
+ "hasPlayerHook": true,
160
+ "run": [MockFunction] {
161
+ "calls": [
162
+ [
163
+ {
164
+ "foo": "bar",
165
+ },
166
+ [Function],
167
+ {
168
+ "config_field": "bar",
169
+ },
170
+ ],
171
+ ],
172
+ "results": [
173
+ {
174
+ "type": "return",
175
+ "value": undefined,
176
+ },
177
+ ],
178
+ },
179
+ },
180
+ "state": 7,
181
+ "weight": 1,
182
+ },
183
+ "payload": {
184
+ "foo": "bar",
185
+ },
186
+ },
187
+ [Function],
188
+ ]
189
+ `;
190
+
3
191
  exports[`HooksManager when there are preload hooks hook with screen: executes 1`] = `
4
192
  [
5
193
  {
@@ -116,23 +116,9 @@ describe("HooksManager", () => {
116
116
  headlessPlayerHook.configuration
117
117
  );
118
118
 
119
- expect(successHandler).toHaveBeenCalledTimes(1);
120
- expect(successHandler.mock.calls[0][0].payload).toEqual(payload);
121
-
122
- expect(successHandler.mock.calls[0][0].hookPlugin.identifier).toBe(
123
- "headless_player_hook"
124
- );
125
-
126
- expect(typeof successHandler.mock.calls[0][1]).toBe("function");
127
-
128
- expect(completeHandler).toHaveBeenCalledTimes(1);
129
- expect(completeHandler.mock.calls[0][0].payload).toEqual(payload);
130
-
131
- expect(completeHandler.mock.calls[0][0].hookPlugin.identifier).toBe(
132
- "headless_player_hook"
133
- );
119
+ expect(successHandler.mock.calls[0]).toMatchSnapshot();
134
120
 
135
- expect(typeof completeHandler.mock.calls[0][1]).toBe("function");
121
+ expect(completeHandler.mock.calls[0]).toMatchSnapshot();
136
122
  });
137
123
  });
138
124
 
@@ -11,6 +11,10 @@ import { HOOKS_EVENTS, HOOKS_TYPE } from "./constants";
11
11
 
12
12
  import { hooksManagerLogger } from "./logger";
13
13
  import { HookManager, HookManagerArgs } from "./types";
14
+ import {
15
+ actionExecutor,
16
+ ActionResult,
17
+ } from "../../actionsExecutor/ActionExecutor";
14
18
 
15
19
  /**
16
20
  * orders the hooks according to their weight
@@ -86,7 +90,7 @@ export function HooksManager({
86
90
  }: HookManagerArgs): HookManager {
87
91
  hooksManagerLogger.addContext({ targetScreenId: targetScreen.id });
88
92
 
89
- function logHookEvent(func, message, data) {
93
+ function logHookEvent(func, message, data = {}) {
90
94
  func({
91
95
  message,
92
96
  data: __DEV__ ? data : null,
@@ -230,7 +234,7 @@ export function HooksManager({
230
234
  function completeHook(hookPlugin, payload, callback) {
231
235
  logHookEvent(
232
236
  hooksManagerLogger.info,
233
- `completeHook: hook sequence completed successfully: ${hookPlugin.identifier}`,
237
+ `completeHook: hook sequence completed successfully: ${hookPlugin["identifier"]}`,
234
238
  {
235
239
  payload,
236
240
  hook: hookPlugin,
@@ -276,10 +280,12 @@ export function HooksManager({
276
280
  if (hookPlugin.isCancelled()) {
277
281
  logHookEvent(
278
282
  hooksManagerLogger.info,
279
- `hookCallback: hook was cancelled: ${hookPlugin.identifier}`,
283
+ `hookCallback: hook was cancelled: ${hookPlugin["identifier"]}`,
280
284
  {}
281
285
  );
282
286
 
287
+ actionExecutor.unregisterAction("finishHook");
288
+
283
289
  return;
284
290
  }
285
291
 
@@ -294,6 +300,8 @@ export function HooksManager({
294
300
  }
295
301
  );
296
302
 
303
+ actionExecutor.unregisterAction("finishHook");
304
+
297
305
  return hookPlugin.setStateAndNotify(HOOKS_EVENTS.ERROR, {
298
306
  error,
299
307
  hookPlugin,
@@ -305,7 +313,7 @@ export function HooksManager({
305
313
  if (!success) {
306
314
  logHookEvent(
307
315
  hooksManagerLogger.info,
308
- `hookCallback: hook was cancelled: ${hookPlugin.identifier}`,
316
+ `hookCallback: hook was cancelled: ${hookPlugin["identifier"]}`,
309
317
  {
310
318
  payload,
311
319
  hook: hookPlugin,
@@ -316,6 +324,8 @@ export function HooksManager({
316
324
  // TODO: Temporary hack to pass getLoginProtocol to other plugins to refresh in case token expired, need be deleted later
317
325
  delete payload.getLoginProtocol;
318
326
 
327
+ actionExecutor.unregisterAction("finishHook");
328
+
319
329
  hookPlugin.setStateAndNotify(HOOKS_EVENTS.CANCEL, {
320
330
  hookPlugin,
321
331
  payload,
@@ -334,10 +344,9 @@ export function HooksManager({
334
344
  if (isHookInHomescreen && isHookFlowBlocker && cancelled) {
335
345
  logHookEvent(
336
346
  hooksManagerLogger.info,
337
- `hookCallback: send app to background, cancelled flow blocker hook ${hookPlugin.identifier} on home screen`,
347
+ `hookCallback: send app to background, cancelled flow blocker hook ${hookPlugin["identifier"]} on home screen`,
338
348
  {
339
349
  payload,
340
- hook: hookPlugin,
341
350
  }
342
351
  );
343
352
 
@@ -349,20 +358,16 @@ export function HooksManager({
349
358
  } else {
350
359
  logHookEvent(
351
360
  hooksManagerLogger.info,
352
- `hookCallback: hook successfully finished: ${hookPlugin.identifier}`,
361
+ `hookCallback: hook successfully finished: ${hookPlugin["identifier"]}`,
353
362
  {
354
363
  payload,
355
- hook: hookPlugin,
356
364
  }
357
365
  );
358
366
 
359
367
  if (!callback) {
360
368
  logHookEvent(
361
- hooksManagerLogger.warn,
362
- `hookCallback: ${hookPlugin.identifier} is missing \`callback\`, using hookCallback(default one)`,
363
- {
364
- hookPlugin,
365
- }
369
+ hooksManagerLogger.debug,
370
+ `hookCallback: ${hookPlugin.identifier} is missing \`callback\`, using hookCallback(default one)`
366
371
  );
367
372
 
368
373
  callback = hookCallback;
@@ -381,6 +386,27 @@ export function HooksManager({
381
386
  };
382
387
  }
383
388
 
389
+ function registerFinishHookAction(payload, callback) {
390
+ // Ensure no stale finishHook remains (e.g. presentUI re-entry from runInBackground)
391
+ actionExecutor.unregisterAction("finishHook");
392
+
393
+ actionExecutor.registerAction("finishHook", async (action: ActionType) => {
394
+ const { success, errorMessage, abort } = action.options;
395
+
396
+ actionExecutor.unregisterAction("finishHook");
397
+
398
+ if (errorMessage) {
399
+ callback({ success, error: new Error(errorMessage), payload, abort });
400
+ } else {
401
+ callback({ success, error: null, payload, abort });
402
+ }
403
+
404
+ hooksManagerLogger.info("finishHook action executed, finishing flow");
405
+
406
+ return ActionResult.Success;
407
+ });
408
+ }
409
+
384
410
  /**
385
411
  * presents a screen hook by triggering an event invoking the handler with
386
412
  * the appropriate route & payload
@@ -401,13 +427,15 @@ export function HooksManager({
401
427
 
402
428
  logHookEvent(
403
429
  hooksManagerLogger.info,
404
- `presentScreenHook: Presenting screen hook: ${hookPlugin.identifier}`,
430
+ `presentScreenHook: Presenting screen hook: ${hookPlugin["identifier"]}`,
405
431
  {
406
432
  hook: hookPlugin,
407
433
  payload,
408
434
  }
409
435
  );
410
436
 
437
+ registerFinishHookAction(payload, callback);
438
+
411
439
  hookPlugin.setStateAndNotify(HOOKS_EVENTS.PRESENT_SCREEN_HOOK, {
412
440
  hookPlugin,
413
441
  route: targetScreenRoute,
@@ -421,7 +449,7 @@ export function HooksManager({
421
449
  hooksManager.executeHook = function (hookPlugin, payload, callback) {
422
450
  logHookEvent(
423
451
  hooksManagerLogger.info,
424
- `executeHook: ${hookPlugin.identifier}`,
452
+ `executeHook: ${hookPlugin["identifier"]}`,
425
453
  {
426
454
  hook: hookPlugin,
427
455
  payload,
@@ -433,7 +461,7 @@ export function HooksManager({
433
461
  } catch (error) {
434
462
  logHookEvent(
435
463
  hooksManagerLogger.error,
436
- `executeHook: error executing hook: ${hookPlugin.identifier} error: ${error.message}`,
464
+ `executeHook: error executing hook: ${hookPlugin["identifier"]} error: ${error.message}`,
437
465
  {
438
466
  hook: hookPlugin,
439
467
  payload,
@@ -460,13 +488,15 @@ export function HooksManager({
460
488
  try {
461
489
  logHookEvent(
462
490
  hooksManagerLogger.info,
463
- `runInBackground: Executing hook: ${hookPlugin.identifier}`,
491
+ `runInBackground: Executing hook: ${hookPlugin["identifier"]}`,
464
492
  {
465
493
  hook: hookPlugin,
466
494
  payload,
467
495
  }
468
496
  );
469
497
 
498
+ registerFinishHookAction(payload, callback);
499
+
470
500
  hookPlugin.module.runInBackground(
471
501
  payload,
472
502
  callback,
@@ -1,31 +1,11 @@
1
- import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager/index.ios";
2
- import { QUICK_BRICK_CONTENT } from "@applicaster/quick-brick-core/const";
3
- import { isNil, isEmpty } from "@applicaster/zapp-react-native-utils/utils";
4
- import { isNotNil } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
1
+ import * as R from "ramda";
2
+
3
+ import { focusManager } from "../focusManager";
5
4
 
6
5
  let riverFocusData = {};
7
6
  let initialyPresentedScreenFocused = false;
8
7
 
9
8
  export const riverFocusManager = (function () {
10
- /**
11
- * Create unique key that will be used for save focused group data inside specific screen
12
- * @param {{ screenId: string, isInsideContainer: boolean }}
13
- * screenId Unique Id of the screen from layout.json
14
- * isInsideContainer If this screen a screen picker child
15
- *
16
- */
17
- function screenFocusableGroupId({
18
- screenId,
19
- isInsideContainer,
20
- }: {
21
- screenId: string;
22
- isInsideContainer: Option<boolean>;
23
- }) {
24
- return `${QUICK_BRICK_CONTENT}-${screenId}${
25
- isNil(isInsideContainer) ? "" : "-isInsideContainer"
26
- }`;
27
- }
28
-
29
9
  function setScreenFocusableData({
30
10
  screenFocusableGroupId,
31
11
  groupId,
@@ -98,8 +78,8 @@ export const riverFocusManager = (function () {
98
78
  }) {
99
79
  // Check if screen should be focused
100
80
  const shouldFocus =
101
- (initialyPresentedScreenFocused === false && isEmpty(riverFocusData)) ||
102
- isNotNil(riverFocusData[screenFocusableGroupId]) ||
81
+ (initialyPresentedScreenFocused === false && R.isEmpty(riverFocusData)) ||
82
+ R.compose(R.not, R.isNil)(riverFocusData[screenFocusableGroupId]) ||
103
83
  isDeepLink;
104
84
 
105
85
  // TODO: Uncommit it to start fixing bug where selection wrong item
@@ -138,6 +118,19 @@ export const riverFocusManager = (function () {
138
118
  }
139
119
  }
140
120
 
121
+ /**
122
+ * Create unique key that will be used for save focused group data inside specific screen
123
+ * @param {{ screenId: string, isInsideContainer: boolean }}
124
+ * screenId Unique Id of the screen from layout.json
125
+ * isInsideContainer If this screen a screen picker child
126
+ *
127
+ */
128
+ function screenFocusableGroupId({ screenId, isInsideContainer }) {
129
+ return `RiverFocusableGroup-${screenId}${
130
+ R.isNil(isInsideContainer) ? "" : "-isInsideContainer"
131
+ }`;
132
+ }
133
+
141
134
  return {
142
135
  setScreenFocusableData,
143
136
  clearAllScreensData,
@@ -31,10 +31,6 @@ export const BUTTON_ACCESSIBILITY_KEYS = {
31
31
  hint: "accessibility_close_mini_hint",
32
32
  },
33
33
  },
34
- back_to_live: {
35
- label: "back_to_live_label",
36
- hint: "",
37
- },
38
34
  maximize: {
39
35
  label: "accessibility_maximize_label",
40
36
  hint: "accessibility_maximize_hint",
@@ -35,6 +35,7 @@ export function calculateReadingTime(
35
35
  return 0;
36
36
  }
37
37
 
38
+ // Count words (split on whitespace and punctuation, keep alnum boundaries)
38
39
  const words = trimmed
39
40
  .split(/(?<=\d)(?=[a-zA-Z])|(?<=[a-zA-Z])(?=\d)|[^\w\s]+|\s+/)
40
41
  .filter(Boolean).length;
@@ -1,12 +1,7 @@
1
- import { NativeModules } from "react-native";
2
1
  import { ContextKeysManager } from "../..";
3
2
 
4
3
  describe("Context Keys Manager - getKeys", () => {
5
- beforeEach(() => {
6
- delete NativeModules.ContextResolverBridge;
7
- });
8
-
9
- it("returns null if all keys are invalid 1", async () => {
4
+ it("returns null if all keys are invalid", async () => {
10
5
  // setup
11
6
  const keys = [null];
12
7
 
@@ -29,7 +24,7 @@ describe("Context Keys Manager - getKeys", () => {
29
24
  expect(getKey.mock.calls).toEqual([[null]]);
30
25
  });
31
26
 
32
- it("returns null if all keys are invalid 2", async () => {
27
+ it("returns null if all keys are invalid", async () => {
33
28
  // setup
34
29
  const keys = [null, undefined];
35
30
 
@@ -1,11 +1,6 @@
1
- import { NativeModules } from "react-native";
2
1
  import { ContextKeysManager } from "../..";
3
2
 
4
3
  describe("Context Keys Manager - getKeys", () => {
5
- beforeEach(() => {
6
- delete NativeModules.ContextResolverBridge;
7
- });
8
-
9
4
  it("returns value if found by getKey", async () => {
10
5
  // setup
11
6
  const keys = ["namespace.key"];
@@ -170,47 +165,4 @@ describe("Context Keys Manager - getKeys", () => {
170
165
  expect(getKey).toHaveBeenCalledTimes(2);
171
166
  expect(getKey.mock.calls).toEqual([[keys[0]], [keys[1]]]);
172
167
  });
173
-
174
- it("returns values from native bridge when available", async () => {
175
- // setup
176
- const keys = ["namespace.key1", "namespace.key2"];
177
-
178
- const contextObj = [
179
- { key: keys[0], required: true },
180
- { key: keys[1], required: false },
181
- ];
182
-
183
- const resolved = {
184
- [keys[0]]: "value1",
185
- [keys[1]]: "value2",
186
- };
187
-
188
- const reactNative = require("react-native");
189
-
190
- const bridgeMock = {
191
- resolveContextKeys: jest.fn().mockResolvedValue(resolved),
192
- };
193
-
194
- reactNative.__setContextResolverBridgeMock(bridgeMock);
195
-
196
- const contextManager = new ContextKeysManager({});
197
- const getKey = jest.spyOn(contextManager, "getKey");
198
-
199
- // run
200
- const result = await contextManager.getKeys(keys, contextObj);
201
-
202
- // verify
203
- const map = new Map();
204
- map.set(keys[0], "value1");
205
- map.set(keys[1], "value2");
206
-
207
- expect(result).toEqual(map);
208
-
209
- expect(bridgeMock.resolveContextKeys).toHaveBeenCalledWith({
210
- [keys[0]]: true,
211
- [keys[1]]: false,
212
- });
213
-
214
- expect(getKey).not.toHaveBeenCalled();
215
- });
216
168
  });
@@ -1,10 +1,8 @@
1
1
  import { ContextKeysManager } from "./index";
2
- import { get, values } from "@applicaster/zapp-react-native-utils/utils";
2
+ import * as R from "ramda";
3
+ import * as _ from "lodash";
3
4
  import { useScreenStateStore } from "../../reactHooks/navigation/useScreenStateStore";
4
5
 
5
- const contextKeyPattern = /@{([^/]+)\/([^}]*)}/;
6
- const contextVariablePattern = /@\{([^}]*)\}/g;
7
-
8
6
  export interface IResolver {
9
7
  resolve: (string) => Promise<string | number | object>;
10
8
  }
@@ -22,7 +20,7 @@ export class EntryResolver implements IResolver {
22
20
  return this.entry;
23
21
  }
24
22
 
25
- return get(this.entry, key.split("."));
23
+ return R.view(R.lensPath(key.split(".")), this.entry);
26
24
  }
27
25
  }
28
26
 
@@ -41,7 +39,7 @@ export class ScreenStateResolver implements IResolver {
41
39
  }
42
40
 
43
41
  if (key.includes(".")) {
44
- return get(screenState, key.split("."));
42
+ return R.view(R.lensPath(key.split(".")), screenState);
45
43
  }
46
44
 
47
45
  return screenState?.[key];
@@ -63,16 +61,21 @@ export const resolveObjectValues = async (
63
61
 
64
62
  const resolvedEntries = await Promise.all(
65
63
  entries.map(async ([key, value]) => {
66
- if (typeof value !== "string" || !value.startsWith("@")) {
64
+ if (typeof value !== "string") {
67
65
  return [key, value];
68
66
  }
69
67
 
70
- const regex = contextKeyPattern;
68
+ if (!value.startsWith("@")) {
69
+ return [key, value];
70
+ }
71
+
72
+ const regex = /@{([^/]+)\/([^}]*)}/;
71
73
 
72
74
  const match = (value as string).match(regex);
73
75
 
74
76
  if (match) {
75
- const [_, contextResolverName, compositeKey] = match;
77
+ const contextResolverName = match[1];
78
+ const compositeKey = match[2];
76
79
 
77
80
  const resolver = exResolvers[contextResolverName] || exResolvers.ctx;
78
81
  const resolvedValue = await resolver.resolve(compositeKey);
@@ -87,50 +90,18 @@ export const resolveObjectValues = async (
87
90
  return Object.fromEntries(resolvedEntries);
88
91
  };
89
92
 
90
- // Simple memoization cache
91
- const extractAtValuesCache = new Map<any, string[]>();
92
-
93
- const flatMapDeep = <T, U>(arr: T[], fn: (value: T) => U | U[]): U[] => {
94
- const result: U[] = [];
93
+ export const extractAtValues = _.memoize((input: any): string[] => {
94
+ return _.flatMapDeep(input, (value: any) => {
95
+ if (_.isString(value)) {
96
+ const matches = value.match(/@\{([^}]*)\}/g);
95
97
 
96
- const flatten = (items: any) => {
97
- for (const item of items) {
98
- if (Array.isArray(item)) {
99
- flatten(item);
100
- } else {
101
- result.push(item);
102
- }
98
+ return matches ? matches.map((match) => match.slice(2, -1)) : [];
103
99
  }
104
- };
105
-
106
- flatten(arr.map(fn));
107
100
 
108
- return result;
109
- };
110
-
111
- export const extractAtValues = (input: any): string[] => {
112
- if (extractAtValuesCache.has(input)) {
113
- return extractAtValuesCache.get(input)!;
114
- }
115
-
116
- const result = flatMapDeep(
117
- Array.isArray(input) ? input : [input],
118
- (value: any) => {
119
- if (typeof value === "string") {
120
- const matches = value.match(contextVariablePattern);
121
-
122
- return matches ? matches.map((match) => match.slice(2, -1)) : [];
123
- }
124
-
125
- if (typeof value === "object" && value !== null) {
126
- return extractAtValues(values(value));
127
- }
128
-
129
- return [];
101
+ if (_.isObject(value)) {
102
+ return extractAtValues(_.values(value));
130
103
  }
131
- );
132
104
 
133
- extractAtValuesCache.set(input, result);
134
-
135
- return result;
136
- };
105
+ return [];
106
+ });
107
+ });