react-native-netmera 2.1.0-beta01 → 2.1.0-beta03

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 CHANGED
@@ -555,13 +555,20 @@ Netmera Autotracking automatically captures screen transitions via **React Navig
555
555
 
556
556
  ### NetmeraAnalyticProvider
557
557
 
558
- Wrap your `NavigationContainer` (or your root component) with `NetmeraAnalyticProvider`. The provider handles both screen tracking and tap tracking based on the configuration received from the Netmera dashboard.
558
+ Wrap your app with `NetmeraAnalyticProvider` and pass a `navigationRef` so the provider can subscribe to screen changes. The provider handles both screen tracking and tap tracking based on the configuration received from the Netmera dashboard.
559
+
560
+ **Dynamic API** (React Navigation v6 / v7):
559
561
 
560
562
  ```tsx
563
+ import { useNavigationContainerRef, NavigationContainer } from '@react-navigation/native';
564
+ import { NetmeraAnalyticProvider } from 'react-native-netmera';
565
+
561
566
  export default function App() {
567
+ const navigationRef = useNavigationContainerRef();
568
+
562
569
  return (
563
- <NetmeraAnalyticProvider>
564
- <NavigationContainer>
570
+ <NetmeraAnalyticProvider navigationRef={navigationRef}>
571
+ <NavigationContainer ref={navigationRef}>
565
572
  {/* your navigators */}
566
573
  </NavigationContainer>
567
574
  </NetmeraAnalyticProvider>
@@ -569,29 +576,27 @@ export default function App() {
569
576
  }
570
577
  ```
571
578
 
572
- ### React Navigation v6 and below
573
-
574
- On **React Navigation v7+** the provider locates the navigation container automatically via the React fiber tree (no extra configuration needed).
575
-
576
- On **React Navigation v6 and below** the fiber-based detection is not available. Pass an explicit `navigationRef` prop so the provider can subscribe to screen changes:
579
+ **Static API** (React Navigation v7):
577
580
 
578
581
  ```tsx
579
- import { useNavigationContainerRef, NavigationContainer } from '@react-navigation/native';
582
+ import { useNavigationContainerRef, createStaticNavigation } from '@react-navigation/native';
580
583
  import { NetmeraAnalyticProvider } from 'react-native-netmera';
581
584
 
585
+ const Navigation = createStaticNavigation(RootStack);
586
+
582
587
  export default function App() {
583
588
  const navigationRef = useNavigationContainerRef();
584
589
 
585
590
  return (
586
591
  <NetmeraAnalyticProvider navigationRef={navigationRef}>
587
- <NavigationContainer ref={navigationRef}>
588
- {/* your navigators */}
589
- </NavigationContainer>
592
+ <Navigation ref={navigationRef} />
590
593
  </NetmeraAnalyticProvider>
591
594
  );
592
595
  }
593
596
  ```
594
597
 
598
+ > **Note:** Use a single `NetmeraAnalyticProvider` per application. The current screen name is stored in a module-level singleton — mounting multiple providers simultaneously will cause them to overwrite each other's screen state.
599
+
595
600
  ### Manual action tracking with `Netmera.trackAction`
596
601
 
597
602
  For components that do not fire standard `onPress` or `onValueChange` events (e.g. third-party dropdowns, custom pickers, gesture-only views), call `Netmera.trackAction` to record the interaction manually.
@@ -614,7 +619,7 @@ When a tap is detected, Netmera resolves an identifier for the tapped component
614
619
  1. **`accessibilityLabel`** — the preferred identifier; human-readable and stable.
615
620
  2. **`testID`** — used when `accessibilityLabel` is absent.
616
621
  3. **`placeholder`** — for `TextInput` components with no label or testID.
617
- 4. **Child text content** — the text of the first `<Text>` descendant, trimmed to 50 characters.
622
+ 4. **Child text content** — the text of the first `<Text>` descendant.
618
623
 
619
624
  If none of the above resolves to a non-empty string the tap is not recorded.
620
625
 
@@ -63,7 +63,7 @@ class RNNetmeraModule(reactContext: ReactApplicationContext) :
63
63
 
64
64
  @ReactMethod(isBlockingSynchronousMethod = true)
65
65
  fun checkNotificationPermission(): String {
66
- val activity: Activity? = reactContext.currentActivity
66
+ val activity: Activity? = reactContext?.currentActivity
67
67
  return if (activity != null) {
68
68
  Netmera.checkNotificationPermission(activity).toString()
69
69
  } else {
@@ -74,7 +74,7 @@ class RNNetmeraModule(reactContext: ReactApplicationContext) :
74
74
 
75
75
  @ReactMethod
76
76
  fun requestPushNotificationAuthorization(promise: Promise) {
77
- val activity: Activity? = reactContext.currentActivity
77
+ val activity: Activity? = reactContext?.currentActivity
78
78
  if (activity == null) {
79
79
  promise.reject(
80
80
  ERROR_CODE_INVALID_ACTIVITY,
@@ -702,18 +702,18 @@ class RNNetmeraModule(reactContext: ReactApplicationContext) :
702
702
  const val ERROR_MESSAGE_NOTIFICATION_PERMISSION =
703
703
  "Error occurred while requesting notification permission. "
704
704
 
705
- private lateinit var reactContext: ReactApplicationContext
705
+ var reactContext: ReactApplicationContext? = null
706
706
 
707
707
  fun emitEvent(eventName: String, eventData: String) {
708
708
  reactContext
709
- .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
710
- .emit(eventName, eventData)
709
+ ?.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
710
+ ?.emit(eventName, eventData)
711
711
  }
712
712
 
713
713
  fun emitEvent(eventName: String, eventData: WritableMap) {
714
714
  reactContext
715
- .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
716
- .emit(eventName, eventData)
715
+ ?.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
716
+ ?.emit(eventName, eventData)
717
717
  }
718
718
 
719
719
  private fun hasKey(map: MutableMap<*, *>, key: String?): Boolean {
@@ -154,6 +154,8 @@ public class RNNetmeraRCTEventEmitter: RCTEventEmitter {
154
154
 
155
155
  static func onAutoTrackConfigUpdate(_ body: [String: Bool]) {
156
156
  guard let emitter = emitterInstance else { return }
157
- emitter.sendEvent(withName: EventName.onAutoTrackConfigUpdate, body: body)
157
+ DispatchQueue.main.async {
158
+ emitter.sendEvent(withName: EventName.onAutoTrackConfigUpdate, body: body)
159
+ }
158
160
  }
159
161
  }
@@ -5,58 +5,63 @@
5
5
  */
6
6
 
7
7
  import React, { useEffect, useRef, useState } from 'react';
8
- import { NativeEventEmitter, NativeModules, StyleSheet, View } from 'react-native';
8
+ import { NativeModules, StyleSheet, View } from 'react-native';
9
+ import { netmeraRCTEventEmitter } from "./utils/RNNetmera.js";
9
10
  import { useNavigationTracking } from "./autotracking/useNavigationTracking.js";
10
11
  import { useTapTracking } from "./autotracking/useTapTracking.js";
11
12
  import { jsx as _jsx } from "react/jsx-runtime";
12
13
  /**
13
14
  * Wraps your app to enable automatic screen tracking and tap tracking.
14
- *
15
- * <NetmeraAnalyticProvider>
16
- * <NavigationContainer>…</NavigationContainer>
17
- * </NetmeraAnalyticProvider>
15
+ * Place it outside your NavigationContainer (or Static Navigation component).
18
16
  */
19
17
  export function NetmeraAnalyticProvider({
20
18
  children,
21
19
  navigationRef
22
20
  }) {
23
- const viewRef = useRef(null);
24
21
  const [config, setConfig] = useState(null);
25
22
  const appliedConfigRef = useRef(null);
26
- const applyConfig = cfg => {
27
- const prev = appliedConfigRef.current;
28
- if (prev?.isScreenFlowEnabled === cfg.isScreenFlowEnabled && prev?.isInputActionEnabled === cfg.isInputActionEnabled && prev?.shouldCollectValues === cfg.shouldCollectValues) return;
29
- appliedConfigRef.current = cfg;
30
- setConfig(cfg);
31
- console.log('[NMAutotrack] screen tracking ', cfg.isScreenFlowEnabled ? 'enabled' : 'disabled');
32
- console.log('[NMAutotrack] input action tracking ', cfg.isInputActionEnabled ? 'enabled' : 'disabled');
23
+ const applyConfig = incomingConfig => {
24
+ const currentConfig = appliedConfigRef.current;
25
+ if (currentConfig?.isScreenFlowEnabled === incomingConfig.isScreenFlowEnabled && currentConfig?.isInputActionEnabled === incomingConfig.isInputActionEnabled && currentConfig?.shouldCollectValues === incomingConfig.shouldCollectValues) {
26
+ return;
27
+ }
28
+ appliedConfigRef.current = incomingConfig;
29
+ setConfig(incomingConfig);
30
+ if (__DEV__) {
31
+ console.log('[NMAutotrack] screen tracking', incomingConfig.isScreenFlowEnabled ? 'enabled' : 'disabled');
32
+ console.log('[NMAutotrack] input action tracking', incomingConfig.isInputActionEnabled ? `enabled ${incomingConfig.shouldCollectValues ? 'with' : 'without'} collection values` : 'disabled');
33
+ }
33
34
  };
34
35
  useEffect(() => {
35
- NativeModules.RNNetmera?.getAutoTrackConfig?.()?.then(cfg => {
36
- if (cfg) applyConfig(cfg);
36
+ NativeModules.RNNetmera?.getAutoTrackConfig?.()?.then(fetchedConfig => {
37
+ if (fetchedConfig) {
38
+ applyConfig(fetchedConfig);
39
+ }
37
40
  })?.catch(_err => {});
38
41
  }, []);
39
42
  useEffect(() => {
40
- const emitter = new NativeEventEmitter(NativeModules.RNNetmeraRCTEventEmitter);
41
- const subscription = emitter.addListener('onAutoTrackConfigUpdate', cfg => {
42
- if (cfg) applyConfig(cfg);
43
+ const subscription = netmeraRCTEventEmitter.addListener('onAutoTrackConfigUpdate', updatedConfig => {
44
+ if (updatedConfig) {
45
+ applyConfig(updatedConfig);
46
+ }
43
47
  });
44
48
  return () => subscription.remove();
45
49
  }, []);
46
50
  const screenFlowEnabled = config?.isScreenFlowEnabled ?? false;
47
51
  const inputActionEnabled = config?.isInputActionEnabled ?? false;
48
52
  const shouldCollectValues = config?.shouldCollectValues ?? false;
49
- const navigationEnabled = screenFlowEnabled || inputActionEnabled;
50
- useNavigationTracking(viewRef, navigationRef, navigationEnabled, screenFlowEnabled);
53
+
54
+ // Navigation tracking is needed whenever either flag is on: screen events
55
+ // need it for trackView, action events need it for the screen-name prefix.
56
+ useNavigationTracking(navigationRef, screenFlowEnabled || inputActionEnabled, screenFlowEnabled);
51
57
  const {
52
58
  onTouchStart,
53
59
  onTouchEnd
54
60
  } = useTapTracking(inputActionEnabled, shouldCollectValues);
55
61
  return /*#__PURE__*/_jsx(View, {
56
- ref: navigationEnabled ? viewRef : undefined,
57
62
  style: styles.container,
58
- onTouchStart: onTouchStart,
59
- onTouchEnd: onTouchEnd,
63
+ onTouchStart: inputActionEnabled ? onTouchStart : undefined,
64
+ onTouchEnd: inputActionEnabled ? onTouchEnd : undefined,
60
65
  children: children
61
66
  });
62
67
  }
@@ -1 +1 @@
1
- {"version":3,"names":["React","useEffect","useRef","useState","NativeEventEmitter","NativeModules","StyleSheet","View","useNavigationTracking","useTapTracking","jsx","_jsx","NetmeraAnalyticProvider","children","navigationRef","viewRef","config","setConfig","appliedConfigRef","applyConfig","cfg","prev","current","isScreenFlowEnabled","isInputActionEnabled","shouldCollectValues","console","log","RNNetmera","getAutoTrackConfig","then","catch","_err","emitter","RNNetmeraRCTEventEmitter","subscription","addListener","remove","screenFlowEnabled","inputActionEnabled","navigationEnabled","onTouchStart","onTouchEnd","ref","undefined","style","styles","container","create","flex"],"sourceRoot":"../../src","sources":["NetmeraAnalyticProvider.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["React","useEffect","useRef","useState","NativeModules","StyleSheet","View","netmeraRCTEventEmitter","useNavigationTracking","useTapTracking","jsx","_jsx","NetmeraAnalyticProvider","children","navigationRef","config","setConfig","appliedConfigRef","applyConfig","incomingConfig","currentConfig","current","isScreenFlowEnabled","isInputActionEnabled","shouldCollectValues","__DEV__","console","log","RNNetmera","getAutoTrackConfig","then","fetchedConfig","catch","_err","subscription","addListener","updatedConfig","remove","screenFlowEnabled","inputActionEnabled","onTouchStart","onTouchEnd","style","styles","container","undefined","create","flex"],"sourceRoot":"../../src","sources":["NetmeraAnalyticProvider.tsx"],"mappings":"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","ignoreList":[]}
@@ -4,75 +4,42 @@
4
4
  * Copyright (c) 2026 Netmera Research.
5
5
  */
6
6
 
7
- import React, { useEffect, useRef } from 'react';
7
+ import { useEffect, useRef } from 'react';
8
8
  import { setCurrentScreen } from "./NetmeraNavigationState.js";
9
9
  import { RNNetmera } from "../utils/RNNetmera.js";
10
10
 
11
- // ContextProvider fiber tag stable React internal constant since React 16.
12
- const CONTEXT_PROVIDER_TAG = 10;
13
- const NAV_SEARCH_DEPTH = 25;
14
-
15
- // Duck-type check: React Navigation v5/v6/v7 all expose this surface on the container ref.
11
+ // Duck-type check: React Navigation v5/v6/v7 all expose this surface.
16
12
  function isNavContainerRef(value) {
17
13
  return value != null && typeof value.addListener === 'function' && typeof value.getCurrentRoute === 'function' && typeof value.isReady === 'function';
18
14
  }
19
15
 
20
- // DFS through child fibers to find NavigationContainerRefContext.Provider.
21
- // Siblings walk at the same depth — they sit at the same level in the tree.
22
- function findNavContainerRef(fiber, depth = 0) {
23
- if (!fiber || depth > NAV_SEARCH_DEPTH) return null;
24
- if (fiber.tag === CONTEXT_PROVIDER_TAG && isNavContainerRef(fiber.memoizedProps?.value)) {
25
- return fiber.memoizedProps.value;
26
- }
27
- return findNavContainerRef(fiber.child, depth + 1) ?? findNavContainerRef(fiber.sibling, depth);
28
- }
29
-
30
16
  /**
31
17
  * Subscribes to React Navigation screen changes and keeps NetmeraNavigationState
32
- * up to date. Resolves the navigation container ref via two paths:
18
+ * up to date.
33
19
  *
34
- * - New Arch (Fabric): auto-detected through the fiber tree via viewRef.
35
- * - Old Arch (Paper): caller passes navigationRef prop explicitly.
20
+ * Requires a valid navigation container ref — pass the same ref to both
21
+ * NetmeraAnalyticProvider and NavigationContainer (or the component created
22
+ * by createStaticNavigation).
36
23
  *
37
- * Silently no-ops if neither path yields a valid ref.
38
- * Respects the isScreenFlowEnabled flag — screen changes are ignored when disabled.
24
+ * Silently no-ops when navigationRef is absent or not yet populated.
25
+ * Respects the enabled flag — screen changes are ignored when disabled.
39
26
  */
40
- export function useNavigationTracking(viewRef, navigationRef, enabled, screenLogEnabled) {
41
- // React 18: capture own fiber during render via ReactCurrentOwner.
42
- // React 19 removed ReactCurrentOwner — this silently yields null, which is fine
43
- // because the Fabric path (viewRef.__internalInstanceHandle) covers React 19.
27
+ export function useNavigationTracking(navigationRef, enabled, screenLogEnabled) {
44
28
  const screenLogEnabledRef = useRef(screenLogEnabled);
29
+ const lastEmittedRouteRef = useRef(null);
45
30
  useEffect(() => {
46
31
  screenLogEnabledRef.current = screenLogEnabled;
47
32
  }, [screenLogEnabled]);
48
- const selfFiberRef = useRef(null);
49
- if (selfFiberRef.current === null) {
50
- try {
51
- const R = React;
52
- selfFiberRef.current = R.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED?.ReactCurrentOwner?.current ?? null;
53
- } catch (_) {}
54
- }
55
33
  useEffect(() => {
56
- if (!enabled) return;
57
- let navRef = null;
58
-
59
- // Path 1 — New Arch: ReactNativeElement exposes its fiber via __internalInstanceHandle.
60
- // Guard with 'child' in candidate to confirm it's a fiber, not another host object.
61
- const candidate = viewRef.current?.__internalInstanceHandle;
62
- const viewFiber = candidate != null && 'child' in candidate ? candidate : selfFiberRef.current?.child ?? null;
63
- if (viewFiber) {
64
- navRef = findNavContainerRef(viewFiber);
65
- }
66
-
67
- // Path 2 — Old Arch: use the ref passed explicitly via prop.
68
- if (!navRef && isNavContainerRef(navigationRef?.current)) {
69
- navRef = navigationRef.current;
34
+ if (!enabled || !isNavContainerRef(navigationRef?.current)) {
35
+ return;
70
36
  }
71
- if (!navRef) return;
37
+ const navRef = navigationRef.current;
72
38
  const handleChange = () => {
73
39
  try {
74
40
  const route = navRef.getCurrentRoute();
75
- if (route?.name) {
41
+ if (route?.name && route.name !== lastEmittedRouteRef.current) {
42
+ lastEmittedRouteRef.current = route.name;
76
43
  setCurrentScreen(route.name);
77
44
  if (screenLogEnabledRef.current) {
78
45
  RNNetmera.trackView(route.name);
@@ -82,9 +49,8 @@ export function useNavigationTracking(viewRef, navigationRef, enabled, screenLog
82
49
  };
83
50
  const unsubState = navRef.addListener('state', handleChange);
84
51
 
85
- // NavigationContainer's effects run before ours (child-first), so 'ready' has
86
- // already fired. isReady() captures the initial screen synchronously; the 'ready'
87
- // listener is a safety net for async startup (deferred auth, deep links, etc.).
52
+ // NavigationContainer's effects (child) run before ours (parent), so the ref
53
+ // is already populated and isReady() reflects the real mount state.
88
54
  let unsubReady;
89
55
  if (navRef.isReady()) {
90
56
  handleChange();
@@ -99,6 +65,6 @@ export function useNavigationTracking(viewRef, navigationRef, enabled, screenLog
99
65
  unsubState?.();
100
66
  unsubReady?.();
101
67
  };
102
- }, [enabled]); // eslint-disable-line react-hooks/exhaustive-deps
68
+ }, [enabled, navigationRef]);
103
69
  }
104
70
  //# sourceMappingURL=useNavigationTracking.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["React","useEffect","useRef","setCurrentScreen","RNNetmera","CONTEXT_PROVIDER_TAG","NAV_SEARCH_DEPTH","isNavContainerRef","value","addListener","getCurrentRoute","isReady","findNavContainerRef","fiber","depth","tag","memoizedProps","child","sibling","useNavigationTracking","viewRef","navigationRef","enabled","screenLogEnabled","screenLogEnabledRef","current","selfFiberRef","R","__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED","ReactCurrentOwner","_","navRef","candidate","__internalInstanceHandle","viewFiber","handleChange","route","name","trackView","unsubState","unsubReady","undefined"],"sourceRoot":"../../../src","sources":["autotracking/useNavigationTracking.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["useEffect","useRef","setCurrentScreen","RNNetmera","isNavContainerRef","value","addListener","getCurrentRoute","isReady","useNavigationTracking","navigationRef","enabled","screenLogEnabled","screenLogEnabledRef","lastEmittedRouteRef","current","navRef","handleChange","route","name","trackView","_","unsubState","unsubReady","undefined"],"sourceRoot":"../../../src","sources":["autotracking/useNavigationTracking.ts"],"mappings":";;AAAA;AACA;AACA;;AAEA,SAASA,SAAS,EAAEC,MAAM,QAAQ,OAAO;AAEzC,SAASC,gBAAgB,QAAQ,6BAA0B;AAC3D,SAASC,SAAS,QAAQ,uBAAoB;;AAE9C;AACA,SAASC,iBAAiBA,CAACC,KAAU,EAAW;EAC9C,OACEA,KAAK,IAAI,IAAI,IACb,OAAOA,KAAK,CAACC,WAAW,KAAK,UAAU,IACvC,OAAOD,KAAK,CAACE,eAAe,KAAK,UAAU,IAC3C,OAAOF,KAAK,CAACG,OAAO,KAAK,UAAU;AAEvC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,qBAAqBA,CACnCC,aAA+C,EAC/CC,OAAgB,EAChBC,gBAAyB,EACnB;EACN,MAAMC,mBAAmB,GAAGZ,MAAM,CAACW,gBAAgB,CAAC;EACpD,MAAME,mBAAmB,GAAGb,MAAM,CAAgB,IAAI,CAAC;EAEvDD,SAAS,CAAC,MAAM;IACda,mBAAmB,CAACE,OAAO,GAAGH,gBAAgB;EAChD,CAAC,EAAE,CAACA,gBAAgB,CAAC,CAAC;EAEtBZ,SAAS,CAAC,MAAM;IACd,IAAI,CAACW,OAAO,IAAI,CAACP,iBAAiB,CAACM,aAAa,EAAEK,OAAO,CAAC,EAAE;MAC1D;IACF;IAEA,MAAMC,MAAM,GAAGN,aAAa,CAAEK,OAAO;IAErC,MAAME,YAAY,GAAGA,CAAA,KAAM;MACzB,IAAI;QACF,MAAMC,KAAK,GAAGF,MAAM,CAACT,eAAe,CAAC,CAAC;QACtC,IAAIW,KAAK,EAAEC,IAAI,IAAID,KAAK,CAACC,IAAI,KAAKL,mBAAmB,CAACC,OAAO,EAAE;UAC7DD,mBAAmB,CAACC,OAAO,GAAGG,KAAK,CAACC,IAAI;UACxCjB,gBAAgB,CAACgB,KAAK,CAACC,IAAI,CAAC;UAC5B,IAAIN,mBAAmB,CAACE,OAAO,EAAE;YAC/BZ,SAAS,CAACiB,SAAS,CAACF,KAAK,CAACC,IAAI,CAAC;UACjC;QACF;MACF,CAAC,CAAC,OAAOE,CAAC,EAAE,CAAC;IACf,CAAC;IAED,MAAMC,UAAU,GAAGN,MAAM,CAACV,WAAW,CAAC,OAAO,EAAEW,YAAY,CAAC;;IAE5D;IACA;IACA,IAAIM,UAAoC;IACxC,IAAIP,MAAM,CAACR,OAAO,CAAC,CAAC,EAAE;MACpBS,YAAY,CAAC,CAAC;IAChB,CAAC,MAAM;MACLM,UAAU,GAAGP,MAAM,CAACV,WAAW,CAAC,OAAO,EAAE,MAAM;QAC7CW,YAAY,CAAC,CAAC;QACdM,UAAU,GAAG,CAAC;QACdA,UAAU,GAAGC,SAAS;MACxB,CAAC,CAAC;IACJ;IAEA,OAAO,MAAM;MACXF,UAAU,GAAG,CAAC;MACdC,UAAU,GAAG,CAAC;IAChB,CAAC;EACH,CAAC,EAAE,CAACZ,OAAO,EAAED,aAAa,CAAC,CAAC;AAC9B","ignoreList":[]}
@@ -27,8 +27,10 @@ function isSwitch(props) {
27
27
  // Tapping them only opens the picker UI — the real select event fires separately.
28
28
  function isInsideSelectionControl(fiber) {
29
29
  let node = fiber?.return;
30
- for (let d = 0; d < 5 && node; d++, node = node.return) {
31
- if (node?.memoizedProps?.onSelect != null) return true;
30
+ for (let d = 0; d < 3 && node; d++, node = node.return) {
31
+ if (node?.memoizedProps?.onSelect != null) {
32
+ return true;
33
+ }
32
34
  }
33
35
  return false;
34
36
  }
@@ -36,16 +38,22 @@ function isInsideSelectionControl(fiber) {
36
38
  // ── Identifier resolution ─────────────────────────────────────────────────────
37
39
 
38
40
  function textFromChildren(children, depth = 0) {
39
- if (depth > MAX_TEXT_DEPTH) return undefined;
41
+ if (depth > MAX_TEXT_DEPTH) {
42
+ return undefined;
43
+ }
40
44
  if (typeof children === 'string') {
41
45
  const t = children.trim();
42
46
  return t.length > 0 ? t : undefined;
43
47
  }
44
- if (typeof children === 'number') return String(children);
48
+ if (typeof children === 'number') {
49
+ return String(children);
50
+ }
45
51
  if (Array.isArray(children)) {
46
52
  for (const child of children) {
47
53
  const t = textFromChildren(child, depth + 1);
48
- if (t) return t;
54
+ if (t) {
55
+ return t;
56
+ }
49
57
  }
50
58
  return undefined;
51
59
  }
@@ -57,7 +65,9 @@ function textFromChildren(children, depth = 0) {
57
65
 
58
66
  // Priority: accessibilityLabel → testID → placeholder (TextInput) → first child text.
59
67
  function resolveIdentifier(props) {
60
- if (!props) return undefined;
68
+ if (!props) {
69
+ return undefined;
70
+ }
61
71
  if (typeof props.accessibilityLabel === 'string' && props.accessibilityLabel.trim()) {
62
72
  return props.accessibilityLabel.trim();
63
73
  }
@@ -96,7 +106,9 @@ function resolveListIndex(startFiber) {
96
106
  }
97
107
  }
98
108
  if (sections) {
99
- if (cellKey.endsWith(':header') || cellKey.endsWith(':footer')) return undefined;
109
+ if (cellKey.endsWith(':header') || cellKey.endsWith(':footer')) {
110
+ return undefined;
111
+ }
100
112
 
101
113
  // Mirrors VirtualizedSectionList._getItem offset arithmetic:
102
114
  // flatIndex 0 → section 0 header
@@ -106,12 +118,16 @@ function resolveListIndex(startFiber) {
106
118
  let idx = flatIndex - 1;
107
119
  for (let si = 0; si < sections.length; si++) {
108
120
  const count = sections[si].data?.length ?? 0;
109
- if (idx === -1 || idx === count) return undefined;
110
- if (idx < count) return {
111
- type: 'sectionlist',
112
- sectionIndex: si,
113
- itemIndex: idx
114
- };
121
+ if (idx === -1 || idx === count) {
122
+ return undefined;
123
+ }
124
+ if (idx < count) {
125
+ return {
126
+ type: 'sectionlist',
127
+ sectionIndex: si,
128
+ itemIndex: idx
129
+ };
130
+ }
115
131
  idx -= count + 2;
116
132
  }
117
133
  return undefined;
@@ -126,9 +142,10 @@ function resolveListIndex(startFiber) {
126
142
 
127
143
  // ── Log path ──────────────────────────────────────────────────────────────────
128
144
 
129
- function buildPath(screen, listType, identifier, indexSuffix, value) {
130
- const base = listType ? `${screen}|${listType}|${identifier}` : `${screen}|${identifier}`;
131
- return value !== undefined ? `${base}|${value}${indexSuffix}` : `${base}${indexSuffix}`;
145
+ function buildPath(screen, listType, identifier, indexSuffix, switchValue) {
146
+ const screenName = screen ?? 'unknown';
147
+ const base = listType ? `${screenName}|${listType}|${identifier}` : `${screenName}|${identifier}`;
148
+ return switchValue !== undefined ? `${base}|${switchValue}${indexSuffix}` : `${base}${indexSuffix}`;
132
149
  }
133
150
 
134
151
  // ── Hook ──────────────────────────────────────────────────────────────────────
@@ -156,7 +173,9 @@ export function useTapTracking(enabled, shouldCollectValues) {
156
173
  shouldCollectValuesRef.current = shouldCollectValues;
157
174
  }, [shouldCollectValues]);
158
175
  const onTouchStart = useCallback(e => {
159
- if (!enabledRef.current) return;
176
+ if (!enabledRef.current) {
177
+ return;
178
+ }
160
179
  let switchValue;
161
180
  try {
162
181
  let fiber = e._targetInst;
@@ -171,20 +190,29 @@ export function useTapTracking(enabled, shouldCollectValues) {
171
190
  touchStartRef.current = {
172
191
  x: e.nativeEvent.pageX,
173
192
  y: e.nativeEvent.pageY,
174
- switchValue
193
+ switchValue,
194
+ isSwitch: switchValue !== undefined
175
195
  };
176
196
  }, []);
177
197
  const onTouchEnd = useCallback(e => {
178
- if (!enabledRef.current) return;
198
+ if (!enabledRef.current) {
199
+ return;
200
+ }
179
201
  const start = touchStartRef.current;
180
- if (start) {
181
- const dx = Math.abs(e.nativeEvent.pageX - start.x);
182
- const dy = Math.abs(e.nativeEvent.pageY - start.y);
183
- if (dx > TAP_THRESHOLD || dy > TAP_THRESHOLD) return;
202
+ if (!start) {
203
+ return;
204
+ }
205
+ const dx = Math.abs(e.nativeEvent.pageX - start.x);
206
+ const dy = Math.abs(e.nativeEvent.pageY - start.y);
207
+ const isScrollGesture = dx > TAP_THRESHOLD || dy > TAP_THRESHOLD;
208
+ if (isScrollGesture && !start.isSwitch) {
209
+ return;
184
210
  }
185
211
  try {
186
212
  let node = e._targetInst;
187
- if (!node) return;
213
+ if (!node) {
214
+ return;
215
+ }
188
216
 
189
217
  // Pass 1: walk up to find the first interactive ancestor.
190
218
  // e.g. tapping a <Text> inside a <Pressable> yields the Pressable.
@@ -198,7 +226,9 @@ export function useTapTracking(enabled, shouldCollectValues) {
198
226
  node = node.return;
199
227
  depth++;
200
228
  }
201
- if (!interactiveNode) return;
229
+ if (!interactiveNode) {
230
+ return;
231
+ }
202
232
 
203
233
  // Pass 2: resolve identifier from the interactive fiber and up to 2 ancestors.
204
234
  // The look-ahead handles TouchableOpacity, where the inner Animated.View fiber
@@ -207,12 +237,18 @@ export function useTapTracking(enabled, shouldCollectValues) {
207
237
  let identifier;
208
238
  for (let i = 0; i < 3 && identifierNode; i++) {
209
239
  identifier = resolveIdentifier(identifierNode.memoizedProps);
210
- if (identifier) break;
240
+ if (identifier) {
241
+ break;
242
+ }
211
243
  identifierNode = identifierNode.return;
212
244
  }
213
- if (!identifier) return;
245
+ if (!identifier) {
246
+ return;
247
+ }
214
248
  const isSwitchNode = isSwitch(interactiveNode.memoizedProps);
215
- if (!isSwitchNode && isInsideSelectionControl(interactiveNode)) return;
249
+ if (!isSwitchNode && isInsideSelectionControl(interactiveNode)) {
250
+ return;
251
+ }
216
252
  const screen = getCurrentScreen();
217
253
  if (screen !== lastScreenRef.current) {
218
254
  switchLastLoggedRef.current.clear();
@@ -231,7 +267,7 @@ export function useTapTracking(enabled, shouldCollectValues) {
231
267
  newValue = preTapValue !== undefined ? !preTapValue : !interactiveNode.memoizedProps.value;
232
268
  }
233
269
  switchLastLoggedRef.current.set(identifier, newValue);
234
- const switchPath = buildPath(screen, listType, identifier, indexSuffix, newValue);
270
+ const switchPath = buildPath(screen, listType, identifier, indexSuffix, shouldCollectValuesRef.current ? newValue : undefined);
235
271
  RNNetmera.trackAction(switchPath);
236
272
  } else {
237
273
  const tapPath = buildPath(screen, listType, identifier, indexSuffix);
@@ -1 +1 @@
1
- {"version":3,"names":["useCallback","useEffect","useRef","getCurrentScreen","RNNetmera","MAX_FIBER_DEPTH","MAX_TEXT_DEPTH","TAP_THRESHOLD","isInteractive","props","onPress","onClick","onValueChange","isSwitch","value","isInsideSelectionControl","fiber","node","return","d","memoizedProps","onSelect","textFromChildren","children","depth","undefined","t","trim","length","String","Array","isArray","child","resolveIdentifier","accessibilityLabel","testID","placeholder","resolveListIndex","startFiber","p","index","cellKey","onUnmount","flatIndex","stateNode","sections","up","i","upProps","endsWith","idx","si","count","data","type","sectionIndex","itemIndex","buildPath","screen","listType","identifier","indexSuffix","base","useTapTracking","enabled","shouldCollectValues","enabledRef","shouldCollectValuesRef","touchStartRef","lastScreenRef","switchLastLoggedRef","Map","current","clear","onTouchStart","e","switchValue","_targetInst","_","x","nativeEvent","pageX","y","pageY","onTouchEnd","start","dx","Math","abs","dy","interactiveNode","identifierNode","isSwitchNode","listIndex","lastLogged","get","newValue","preTapValue","set","switchPath","trackAction","tapPath"],"sourceRoot":"../../../src","sources":["autotracking/useTapTracking.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["useCallback","useEffect","useRef","getCurrentScreen","RNNetmera","MAX_FIBER_DEPTH","MAX_TEXT_DEPTH","TAP_THRESHOLD","isInteractive","props","onPress","onClick","onValueChange","isSwitch","value","isInsideSelectionControl","fiber","node","return","d","memoizedProps","onSelect","textFromChildren","children","depth","undefined","t","trim","length","String","Array","isArray","child","resolveIdentifier","accessibilityLabel","testID","placeholder","resolveListIndex","startFiber","p","index","cellKey","onUnmount","flatIndex","stateNode","sections","up","i","upProps","endsWith","idx","si","count","data","type","sectionIndex","itemIndex","buildPath","screen","listType","identifier","indexSuffix","switchValue","screenName","base","useTapTracking","enabled","shouldCollectValues","enabledRef","shouldCollectValuesRef","touchStartRef","lastScreenRef","switchLastLoggedRef","Map","current","clear","onTouchStart","e","_targetInst","_","x","nativeEvent","pageX","y","pageY","onTouchEnd","start","dx","Math","abs","dy","isScrollGesture","interactiveNode","identifierNode","isSwitchNode","listIndex","lastLogged","get","newValue","preTapValue","set","switchPath","trackAction","tapPath"],"sourceRoot":"../../../src","sources":["autotracking/useTapTracking.ts"],"mappings":"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","ignoreList":[]}
@@ -2,25 +2,30 @@ import React from 'react';
2
2
  export interface NetmeraAnalyticProviderProps {
3
3
  children: React.ReactNode;
4
4
  /**
5
- * Required on Old Architecture (newArchEnabled=false). Pass your NavigationContainer
6
- * ref so the provider can subscribe to screen changes.
5
+ * Pass the navigation container ref so the provider can subscribe to screen
6
+ * changes. Required for screen tracking and for correct action event prefixes.
7
7
  *
8
- * On New Architecture the provider detects the navigation context automatically
9
- * through the fiber tree — this prop is not needed.
8
+ * Use the same ref for both this prop and your NavigationContainer (or the
9
+ * component returned by createStaticNavigation).
10
10
  *
11
- * const navRef = useRef(null);
11
+ * React Navigation v7 Dynamic API:
12
+ * const navRef = useNavigationContainerRef();
12
13
  * <NetmeraAnalyticProvider navigationRef={navRef}>
13
14
  * <NavigationContainer ref={navRef}>…</NavigationContainer>
14
15
  * </NetmeraAnalyticProvider>
16
+ *
17
+ * React Navigation v7 Static API:
18
+ * const navRef = useNavigationContainerRef();
19
+ * const Navigation = createStaticNavigation(RootStack);
20
+ * <NetmeraAnalyticProvider navigationRef={navRef}>
21
+ * <Navigation ref={navRef} />
22
+ * </NetmeraAnalyticProvider>
15
23
  */
16
24
  navigationRef?: React.RefObject<any>;
17
25
  }
18
26
  /**
19
27
  * Wraps your app to enable automatic screen tracking and tap tracking.
20
- *
21
- * <NetmeraAnalyticProvider>
22
- * <NavigationContainer>…</NavigationContainer>
23
- * </NetmeraAnalyticProvider>
28
+ * Place it outside your NavigationContainer (or Static Navigation component).
24
29
  */
25
30
  export declare function NetmeraAnalyticProvider({ children, navigationRef, }: NetmeraAnalyticProviderProps): import("react/jsx-runtime").JSX.Element;
26
31
  //# sourceMappingURL=NetmeraAnalyticProvider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"NetmeraAnalyticProvider.d.ts","sourceRoot":"","sources":["../../../src/NetmeraAnalyticProvider.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAU3D,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B;;;;;;;;;;;OAWG;IACH,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;CACtC;AAQD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,QAAQ,EACR,aAAa,GACd,EAAE,4BAA4B,2CAwE9B"}
1
+ {"version":3,"file":"NetmeraAnalyticProvider.d.ts","sourceRoot":"","sources":["../../../src/NetmeraAnalyticProvider.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAM3D,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B;;;;;;;;;;;;;;;;;;;OAmBG;IACH,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;CACtC;AAQD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,QAAQ,EACR,aAAa,GACd,EAAE,4BAA4B,2CA8E9B"}
@@ -1,13 +1,14 @@
1
- import React from 'react';
1
+ import type React from 'react';
2
2
  /**
3
3
  * Subscribes to React Navigation screen changes and keeps NetmeraNavigationState
4
- * up to date. Resolves the navigation container ref via two paths:
4
+ * up to date.
5
5
  *
6
- * - New Arch (Fabric): auto-detected through the fiber tree via viewRef.
7
- * - Old Arch (Paper): caller passes navigationRef prop explicitly.
6
+ * Requires a valid navigation container ref — pass the same ref to both
7
+ * NetmeraAnalyticProvider and NavigationContainer (or the component created
8
+ * by createStaticNavigation).
8
9
  *
9
- * Silently no-ops if neither path yields a valid ref.
10
- * Respects the isScreenFlowEnabled flag — screen changes are ignored when disabled.
10
+ * Silently no-ops when navigationRef is absent or not yet populated.
11
+ * Respects the enabled flag — screen changes are ignored when disabled.
11
12
  */
12
- export declare function useNavigationTracking(viewRef: React.RefObject<any>, navigationRef: React.RefObject<any> | undefined, enabled: boolean, screenLogEnabled: boolean): void;
13
+ export declare function useNavigationTracking(navigationRef: React.RefObject<any> | undefined, enabled: boolean, screenLogEnabled: boolean): void;
13
14
  //# sourceMappingURL=useNavigationTracking.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useNavigationTracking.d.ts","sourceRoot":"","sources":["../../../../src/autotracking/useNavigationTracking.ts"],"names":[],"mappings":"AAIA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAkCjD;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,EAC7B,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,SAAS,EAC/C,OAAO,EAAE,OAAO,EAChB,gBAAgB,EAAE,OAAO,GACxB,IAAI,CA4EN"}
1
+ {"version":3,"file":"useNavigationTracking.d.ts","sourceRoot":"","sources":["../../../../src/autotracking/useNavigationTracking.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAc/B;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,SAAS,EAC/C,OAAO,EAAE,OAAO,EAChB,gBAAgB,EAAE,OAAO,GACxB,IAAI,CAgDN"}
@@ -1 +1 @@
1
- {"version":3,"file":"useTapTracking.d.ts","sourceRoot":"","sources":["../../../../src/autotracking/useTapTracking.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AA6J1D,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,OAAO;sBA6BtC,qBAAqB;oBAoBvB,qBAAqB;EA8FzD"}
1
+ {"version":3,"file":"useTapTracking.d.ts","sourceRoot":"","sources":["../../../../src/autotracking/useTapTracking.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AA4K1D,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,OAAO;sBA8BtC,qBAAqB;oBAuBvB,qBAAqB;EA8GzD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-netmera",
3
- "version": "2.1.0-beta01",
3
+ "version": "2.1.0-beta03",
4
4
  "description": "Netmera React Native SDK",
5
5
  "source": "./src/index.ts",
6
6
  "main": "./lib/module/index.js",
@@ -3,28 +3,32 @@
3
3
  */
4
4
 
5
5
  import React, { useEffect, useRef, useState } from 'react';
6
- import {
7
- NativeEventEmitter,
8
- NativeModules,
9
- StyleSheet,
10
- View,
11
- } from 'react-native';
6
+ import { NativeModules, StyleSheet, View } from 'react-native';
7
+ import { netmeraRCTEventEmitter } from './utils/RNNetmera';
12
8
  import { useNavigationTracking } from './autotracking/useNavigationTracking';
13
9
  import { useTapTracking } from './autotracking/useTapTracking';
14
10
 
15
11
  export interface NetmeraAnalyticProviderProps {
16
12
  children: React.ReactNode;
17
13
  /**
18
- * Required on Old Architecture (newArchEnabled=false). Pass your NavigationContainer
19
- * ref so the provider can subscribe to screen changes.
14
+ * Pass the navigation container ref so the provider can subscribe to screen
15
+ * changes. Required for screen tracking and for correct action event prefixes.
20
16
  *
21
- * On New Architecture the provider detects the navigation context automatically
22
- * through the fiber tree — this prop is not needed.
17
+ * Use the same ref for both this prop and your NavigationContainer (or the
18
+ * component returned by createStaticNavigation).
23
19
  *
24
- * const navRef = useRef(null);
20
+ * React Navigation v7 Dynamic API:
21
+ * const navRef = useNavigationContainerRef();
25
22
  * <NetmeraAnalyticProvider navigationRef={navRef}>
26
23
  * <NavigationContainer ref={navRef}>…</NavigationContainer>
27
24
  * </NetmeraAnalyticProvider>
25
+ *
26
+ * React Navigation v7 Static API:
27
+ * const navRef = useNavigationContainerRef();
28
+ * const Navigation = createStaticNavigation(RootStack);
29
+ * <NetmeraAnalyticProvider navigationRef={navRef}>
30
+ * <Navigation ref={navRef} />
31
+ * </NetmeraAnalyticProvider>
28
32
  */
29
33
  navigationRef?: React.RefObject<any>;
30
34
  }
@@ -37,55 +41,59 @@ type AutoTrackConfig = {
37
41
 
38
42
  /**
39
43
  * Wraps your app to enable automatic screen tracking and tap tracking.
40
- *
41
- * <NetmeraAnalyticProvider>
42
- * <NavigationContainer>…</NavigationContainer>
43
- * </NetmeraAnalyticProvider>
44
+ * Place it outside your NavigationContainer (or Static Navigation component).
44
45
  */
45
46
  export function NetmeraAnalyticProvider({
46
47
  children,
47
48
  navigationRef,
48
49
  }: NetmeraAnalyticProviderProps) {
49
- const viewRef = useRef<any>(null);
50
50
  const [config, setConfig] = useState<AutoTrackConfig | null>(null);
51
51
  const appliedConfigRef = useRef<AutoTrackConfig | null>(null);
52
52
 
53
- const applyConfig = (cfg: AutoTrackConfig) => {
54
- const prev = appliedConfigRef.current;
53
+ const applyConfig = (incomingConfig: AutoTrackConfig) => {
54
+ const currentConfig = appliedConfigRef.current;
55
55
  if (
56
- prev?.isScreenFlowEnabled === cfg.isScreenFlowEnabled &&
57
- prev?.isInputActionEnabled === cfg.isInputActionEnabled &&
58
- prev?.shouldCollectValues === cfg.shouldCollectValues
59
- )
56
+ currentConfig?.isScreenFlowEnabled ===
57
+ incomingConfig.isScreenFlowEnabled &&
58
+ currentConfig?.isInputActionEnabled ===
59
+ incomingConfig.isInputActionEnabled &&
60
+ currentConfig?.shouldCollectValues === incomingConfig.shouldCollectValues
61
+ ) {
60
62
  return;
61
- appliedConfigRef.current = cfg;
62
- setConfig(cfg);
63
- console.log(
64
- '[NMAutotrack] screen tracking ',
65
- cfg.isScreenFlowEnabled ? 'enabled' : 'disabled'
66
- );
67
- console.log(
68
- '[NMAutotrack] input action tracking ',
69
- cfg.isInputActionEnabled ? 'enabled' : 'disabled'
70
- );
63
+ }
64
+ appliedConfigRef.current = incomingConfig;
65
+ setConfig(incomingConfig);
66
+ if (__DEV__) {
67
+ console.log(
68
+ '[NMAutotrack] screen tracking',
69
+ incomingConfig.isScreenFlowEnabled ? 'enabled' : 'disabled'
70
+ );
71
+ console.log(
72
+ '[NMAutotrack] input action tracking',
73
+ incomingConfig.isInputActionEnabled
74
+ ? `enabled ${incomingConfig.shouldCollectValues ? 'with' : 'without'} collection values`
75
+ : 'disabled'
76
+ );
77
+ }
71
78
  };
72
79
 
73
80
  useEffect(() => {
74
81
  NativeModules.RNNetmera?.getAutoTrackConfig?.()
75
- ?.then((cfg: AutoTrackConfig | null) => {
76
- if (cfg) applyConfig(cfg);
82
+ ?.then((fetchedConfig: AutoTrackConfig | null) => {
83
+ if (fetchedConfig) {
84
+ applyConfig(fetchedConfig);
85
+ }
77
86
  })
78
87
  ?.catch((_err: unknown) => {});
79
88
  }, []);
80
89
 
81
90
  useEffect(() => {
82
- const emitter = new NativeEventEmitter(
83
- NativeModules.RNNetmeraRCTEventEmitter
84
- );
85
- const subscription = emitter.addListener(
91
+ const subscription = netmeraRCTEventEmitter.addListener(
86
92
  'onAutoTrackConfigUpdate',
87
- (cfg: AutoTrackConfig) => {
88
- if (cfg) applyConfig(cfg);
93
+ (updatedConfig: AutoTrackConfig) => {
94
+ if (updatedConfig) {
95
+ applyConfig(updatedConfig);
96
+ }
89
97
  }
90
98
  );
91
99
  return () => subscription.remove();
@@ -95,11 +103,11 @@ export function NetmeraAnalyticProvider({
95
103
  const inputActionEnabled = config?.isInputActionEnabled ?? false;
96
104
  const shouldCollectValues = config?.shouldCollectValues ?? false;
97
105
 
98
- const navigationEnabled = screenFlowEnabled || inputActionEnabled;
106
+ // Navigation tracking is needed whenever either flag is on: screen events
107
+ // need it for trackView, action events need it for the screen-name prefix.
99
108
  useNavigationTracking(
100
- viewRef,
101
109
  navigationRef,
102
- navigationEnabled,
110
+ screenFlowEnabled || inputActionEnabled,
103
111
  screenFlowEnabled
104
112
  );
105
113
  const { onTouchStart, onTouchEnd } = useTapTracking(
@@ -109,10 +117,9 @@ export function NetmeraAnalyticProvider({
109
117
 
110
118
  return (
111
119
  <View
112
- ref={navigationEnabled ? viewRef : undefined}
113
120
  style={styles.container}
114
- onTouchStart={onTouchStart}
115
- onTouchEnd={onTouchEnd}
121
+ onTouchStart={inputActionEnabled ? onTouchStart : undefined}
122
+ onTouchEnd={inputActionEnabled ? onTouchEnd : undefined}
116
123
  >
117
124
  {children}
118
125
  </View>
@@ -2,15 +2,12 @@
2
2
  * Copyright (c) 2026 Netmera Research.
3
3
  */
4
4
 
5
- import React, { useEffect, useRef } from 'react';
5
+ import { useEffect, useRef } from 'react';
6
+ import type React from 'react';
6
7
  import { setCurrentScreen } from './NetmeraNavigationState';
7
8
  import { RNNetmera } from '../utils/RNNetmera';
8
9
 
9
- // ContextProvider fiber tag stable React internal constant since React 16.
10
- const CONTEXT_PROVIDER_TAG = 10;
11
- const NAV_SEARCH_DEPTH = 25;
12
-
13
- // Duck-type check: React Navigation v5/v6/v7 all expose this surface on the container ref.
10
+ // Duck-type check: React Navigation v5/v6/v7 all expose this surface.
14
11
  function isNavContainerRef(value: any): boolean {
15
12
  return (
16
13
  value != null &&
@@ -20,84 +17,41 @@ function isNavContainerRef(value: any): boolean {
20
17
  );
21
18
  }
22
19
 
23
- // DFS through child fibers to find NavigationContainerRefContext.Provider.
24
- // Siblings walk at the same depth — they sit at the same level in the tree.
25
- function findNavContainerRef(fiber: any, depth = 0): any {
26
- if (!fiber || depth > NAV_SEARCH_DEPTH) return null;
27
- if (
28
- fiber.tag === CONTEXT_PROVIDER_TAG &&
29
- isNavContainerRef(fiber.memoizedProps?.value)
30
- ) {
31
- return fiber.memoizedProps.value;
32
- }
33
- return (
34
- findNavContainerRef(fiber.child, depth + 1) ??
35
- findNavContainerRef(fiber.sibling, depth)
36
- );
37
- }
38
-
39
20
  /**
40
21
  * Subscribes to React Navigation screen changes and keeps NetmeraNavigationState
41
- * up to date. Resolves the navigation container ref via two paths:
22
+ * up to date.
42
23
  *
43
- * - New Arch (Fabric): auto-detected through the fiber tree via viewRef.
44
- * - Old Arch (Paper): caller passes navigationRef prop explicitly.
24
+ * Requires a valid navigation container ref — pass the same ref to both
25
+ * NetmeraAnalyticProvider and NavigationContainer (or the component created
26
+ * by createStaticNavigation).
45
27
  *
46
- * Silently no-ops if neither path yields a valid ref.
47
- * Respects the isScreenFlowEnabled flag — screen changes are ignored when disabled.
28
+ * Silently no-ops when navigationRef is absent or not yet populated.
29
+ * Respects the enabled flag — screen changes are ignored when disabled.
48
30
  */
49
31
  export function useNavigationTracking(
50
- viewRef: React.RefObject<any>,
51
32
  navigationRef: React.RefObject<any> | undefined,
52
33
  enabled: boolean,
53
34
  screenLogEnabled: boolean
54
35
  ): void {
55
- // React 18: capture own fiber during render via ReactCurrentOwner.
56
- // React 19 removed ReactCurrentOwner — this silently yields null, which is fine
57
- // because the Fabric path (viewRef.__internalInstanceHandle) covers React 19.
58
36
  const screenLogEnabledRef = useRef(screenLogEnabled);
37
+ const lastEmittedRouteRef = useRef<string | null>(null);
59
38
 
60
39
  useEffect(() => {
61
40
  screenLogEnabledRef.current = screenLogEnabled;
62
41
  }, [screenLogEnabled]);
63
42
 
64
- const selfFiberRef = useRef<any>(null);
65
- if (selfFiberRef.current === null) {
66
- try {
67
- const R = React as any;
68
- selfFiberRef.current =
69
- R.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED?.ReactCurrentOwner
70
- ?.current ?? null;
71
- } catch (_) {}
72
- }
73
-
74
43
  useEffect(() => {
75
- if (!enabled) return;
76
- let navRef: any = null;
77
-
78
- // Path 1 — New Arch: ReactNativeElement exposes its fiber via __internalInstanceHandle.
79
- // Guard with 'child' in candidate to confirm it's a fiber, not another host object.
80
- const candidate = viewRef.current?.__internalInstanceHandle;
81
- const viewFiber: any =
82
- candidate != null && 'child' in candidate
83
- ? candidate
84
- : (selfFiberRef.current?.child ?? null);
85
-
86
- if (viewFiber) {
87
- navRef = findNavContainerRef(viewFiber);
88
- }
89
-
90
- // Path 2 — Old Arch: use the ref passed explicitly via prop.
91
- if (!navRef && isNavContainerRef(navigationRef?.current)) {
92
- navRef = navigationRef!.current;
44
+ if (!enabled || !isNavContainerRef(navigationRef?.current)) {
45
+ return;
93
46
  }
94
47
 
95
- if (!navRef) return;
48
+ const navRef = navigationRef!.current;
96
49
 
97
50
  const handleChange = () => {
98
51
  try {
99
52
  const route = navRef.getCurrentRoute();
100
- if (route?.name) {
53
+ if (route?.name && route.name !== lastEmittedRouteRef.current) {
54
+ lastEmittedRouteRef.current = route.name;
101
55
  setCurrentScreen(route.name);
102
56
  if (screenLogEnabledRef.current) {
103
57
  RNNetmera.trackView(route.name);
@@ -108,9 +62,8 @@ export function useNavigationTracking(
108
62
 
109
63
  const unsubState = navRef.addListener('state', handleChange);
110
64
 
111
- // NavigationContainer's effects run before ours (child-first), so 'ready' has
112
- // already fired. isReady() captures the initial screen synchronously; the 'ready'
113
- // listener is a safety net for async startup (deferred auth, deep links, etc.).
65
+ // NavigationContainer's effects (child) run before ours (parent), so the ref
66
+ // is already populated and isReady() reflects the real mount state.
114
67
  let unsubReady: (() => void) | undefined;
115
68
  if (navRef.isReady()) {
116
69
  handleChange();
@@ -126,5 +79,5 @@ export function useNavigationTracking(
126
79
  unsubState?.();
127
80
  unsubReady?.();
128
81
  };
129
- }, [enabled]); // eslint-disable-line react-hooks/exhaustive-deps
82
+ }, [enabled, navigationRef]);
130
83
  }
@@ -31,8 +31,10 @@ function isSwitch(props: any): boolean {
31
31
  // Tapping them only opens the picker UI — the real select event fires separately.
32
32
  function isInsideSelectionControl(fiber: any): boolean {
33
33
  let node: any = fiber?.return;
34
- for (let d = 0; d < 5 && node; d++, node = node.return) {
35
- if (node?.memoizedProps?.onSelect != null) return true;
34
+ for (let d = 0; d < 3 && node; d++, node = node.return) {
35
+ if (node?.memoizedProps?.onSelect != null) {
36
+ return true;
37
+ }
36
38
  }
37
39
  return false;
38
40
  }
@@ -40,16 +42,22 @@ function isInsideSelectionControl(fiber: any): boolean {
40
42
  // ── Identifier resolution ─────────────────────────────────────────────────────
41
43
 
42
44
  function textFromChildren(children: any, depth = 0): string | undefined {
43
- if (depth > MAX_TEXT_DEPTH) return undefined;
45
+ if (depth > MAX_TEXT_DEPTH) {
46
+ return undefined;
47
+ }
44
48
  if (typeof children === 'string') {
45
49
  const t = children.trim();
46
50
  return t.length > 0 ? t : undefined;
47
51
  }
48
- if (typeof children === 'number') return String(children);
52
+ if (typeof children === 'number') {
53
+ return String(children);
54
+ }
49
55
  if (Array.isArray(children)) {
50
56
  for (const child of children) {
51
57
  const t = textFromChildren(child, depth + 1);
52
- if (t) return t;
58
+ if (t) {
59
+ return t;
60
+ }
53
61
  }
54
62
  return undefined;
55
63
  }
@@ -61,7 +69,9 @@ function textFromChildren(children: any, depth = 0): string | undefined {
61
69
 
62
70
  // Priority: accessibilityLabel → testID → placeholder (TextInput) → first child text.
63
71
  function resolveIdentifier(props: any): string | undefined {
64
- if (!props) return undefined;
72
+ if (!props) {
73
+ return undefined;
74
+ }
65
75
  if (
66
76
  typeof props.accessibilityLabel === 'string' &&
67
77
  props.accessibilityLabel.trim()
@@ -117,8 +127,9 @@ function resolveListIndex(startFiber: any): ListIndex | undefined {
117
127
  }
118
128
 
119
129
  if (sections) {
120
- if (cellKey.endsWith(':header') || cellKey.endsWith(':footer'))
130
+ if (cellKey.endsWith(':header') || cellKey.endsWith(':footer')) {
121
131
  return undefined;
132
+ }
122
133
 
123
134
  // Mirrors VirtualizedSectionList._getItem offset arithmetic:
124
135
  // flatIndex 0 → section 0 header
@@ -128,9 +139,12 @@ function resolveListIndex(startFiber: any): ListIndex | undefined {
128
139
  let idx = flatIndex - 1;
129
140
  for (let si = 0; si < sections.length; si++) {
130
141
  const count = sections[si].data?.length ?? 0;
131
- if (idx === -1 || idx === count) return undefined;
132
- if (idx < count)
142
+ if (idx === -1 || idx === count) {
143
+ return undefined;
144
+ }
145
+ if (idx < count) {
133
146
  return { type: 'sectionlist', sectionIndex: si, itemIndex: idx };
147
+ }
134
148
  idx -= count + 2;
135
149
  }
136
150
  return undefined;
@@ -148,13 +162,14 @@ function buildPath(
148
162
  listType: string | null,
149
163
  identifier: string,
150
164
  indexSuffix: string,
151
- value?: boolean
165
+ switchValue?: boolean
152
166
  ): string {
167
+ const screenName = screen ?? 'unknown';
153
168
  const base = listType
154
- ? `${screen}|${listType}|${identifier}`
155
- : `${screen}|${identifier}`;
156
- return value !== undefined
157
- ? `${base}|${value}${indexSuffix}`
169
+ ? `${screenName}|${listType}|${identifier}`
170
+ : `${screenName}|${identifier}`;
171
+ return switchValue !== undefined
172
+ ? `${base}|${switchValue}${indexSuffix}`
158
173
  : `${base}${indexSuffix}`;
159
174
  }
160
175
 
@@ -167,6 +182,7 @@ export function useTapTracking(enabled: boolean, shouldCollectValues: boolean) {
167
182
  x: number;
168
183
  y: number;
169
184
  switchValue?: boolean;
185
+ isSwitch?: boolean;
170
186
  } | null>(null);
171
187
  const lastScreenRef = useRef<string | null | undefined>(undefined);
172
188
 
@@ -190,7 +206,9 @@ export function useTapTracking(enabled: boolean, shouldCollectValues: boolean) {
190
206
  }, [shouldCollectValues]);
191
207
 
192
208
  const onTouchStart = useCallback((e: GestureResponderEvent) => {
193
- if (!enabledRef.current) return;
209
+ if (!enabledRef.current) {
210
+ return;
211
+ }
194
212
  let switchValue: boolean | undefined;
195
213
  try {
196
214
  let fiber: any = (e as any)._targetInst;
@@ -206,21 +224,30 @@ export function useTapTracking(enabled: boolean, shouldCollectValues: boolean) {
206
224
  x: e.nativeEvent.pageX,
207
225
  y: e.nativeEvent.pageY,
208
226
  switchValue,
227
+ isSwitch: switchValue !== undefined,
209
228
  };
210
229
  }, []);
211
230
 
212
231
  const onTouchEnd = useCallback((e: GestureResponderEvent) => {
213
- if (!enabledRef.current) return;
232
+ if (!enabledRef.current) {
233
+ return;
234
+ }
214
235
  const start = touchStartRef.current;
215
- if (start) {
216
- const dx = Math.abs(e.nativeEvent.pageX - start.x);
217
- const dy = Math.abs(e.nativeEvent.pageY - start.y);
218
- if (dx > TAP_THRESHOLD || dy > TAP_THRESHOLD) return;
236
+ if (!start) {
237
+ return;
238
+ }
239
+ const dx = Math.abs(e.nativeEvent.pageX - start.x);
240
+ const dy = Math.abs(e.nativeEvent.pageY - start.y);
241
+ const isScrollGesture = dx > TAP_THRESHOLD || dy > TAP_THRESHOLD;
242
+ if (isScrollGesture && !start.isSwitch) {
243
+ return;
219
244
  }
220
245
 
221
246
  try {
222
247
  let node: any = (e as any)._targetInst;
223
- if (!node) return;
248
+ if (!node) {
249
+ return;
250
+ }
224
251
 
225
252
  // Pass 1: walk up to find the first interactive ancestor.
226
253
  // e.g. tapping a <Text> inside a <Pressable> yields the Pressable.
@@ -234,7 +261,9 @@ export function useTapTracking(enabled: boolean, shouldCollectValues: boolean) {
234
261
  node = node.return;
235
262
  depth++;
236
263
  }
237
- if (!interactiveNode) return;
264
+ if (!interactiveNode) {
265
+ return;
266
+ }
238
267
 
239
268
  // Pass 2: resolve identifier from the interactive fiber and up to 2 ancestors.
240
269
  // The look-ahead handles TouchableOpacity, where the inner Animated.View fiber
@@ -243,14 +272,20 @@ export function useTapTracking(enabled: boolean, shouldCollectValues: boolean) {
243
272
  let identifier: string | undefined;
244
273
  for (let i = 0; i < 3 && identifierNode; i++) {
245
274
  identifier = resolveIdentifier(identifierNode.memoizedProps);
246
- if (identifier) break;
275
+ if (identifier) {
276
+ break;
277
+ }
247
278
  identifierNode = identifierNode.return;
248
279
  }
249
280
 
250
- if (!identifier) return;
281
+ if (!identifier) {
282
+ return;
283
+ }
251
284
 
252
285
  const isSwitchNode = isSwitch(interactiveNode.memoizedProps);
253
- if (!isSwitchNode && isInsideSelectionControl(interactiveNode)) return;
286
+ if (!isSwitchNode && isInsideSelectionControl(interactiveNode)) {
287
+ return;
288
+ }
254
289
 
255
290
  const screen = getCurrentScreen();
256
291
  if (screen !== lastScreenRef.current) {
@@ -290,7 +325,7 @@ export function useTapTracking(enabled: boolean, shouldCollectValues: boolean) {
290
325
  listType,
291
326
  identifier,
292
327
  indexSuffix,
293
- newValue
328
+ shouldCollectValuesRef.current ? newValue : undefined
294
329
  );
295
330
  RNNetmera.trackAction(switchPath);
296
331
  } else {