react-event-tracking 1.0.6 → 1.0.8

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
@@ -5,6 +5,9 @@ A convenient React context for tracking analytics events.
5
5
 
6
6
  - **Nested Contexts**: Automatically merges parameters from parent providers.
7
7
  - **Zero Re-renders**: No need to wrap props in `useCallback`/`useMemo`.
8
+ - **Multiple Providers**: Send events to different analytics services.
9
+ - **Event Filtering**: Control which events are sent to which provider.
10
+ - **Event Transformation**: Modify event names or parameters before they are sent to provider.
8
11
 
9
12
  ## Table of Contents
10
13
 
@@ -55,7 +58,6 @@ const Dashboard = () => (
55
58
  ```
56
59
 
57
60
  3. Send events conveniently. On button click, parameters will be merged.
58
-
59
61
  ```tsx
60
62
  import { useTracker } from 'react-event-tracking';
61
63
 
@@ -63,10 +65,17 @@ const MyButton = () => {
63
65
  const { sendEvent } = useTracker();
64
66
 
65
67
  return (
68
+ <>
66
69
  // event sent with parameters: { screen: 'dashboard', button_id: '123' }
67
70
  <button onClick={() => sendEvent('click', { button_id: '123' })}>
68
71
  Click me
69
72
  </button>
73
+
74
+ {/* Option B: Object call */}
75
+ <button onClick={() => sendEvent({ eventName: 'click', params: { button_id: '456' } })}>
76
+ Click me too
77
+ </button>
78
+ </>
70
79
  );
71
80
  };
72
81
  ```
@@ -144,7 +153,7 @@ const AmpltitudeUS = TrackRoot.factory(
144
153
  (name, params) => {
145
154
  if (params?.userRegion === 'EU') {
146
155
  // Remove PII (Personally Identifiable Information)
147
- const { userId, email, ...safeParams } = params || {};
156
+ const { userId, email, ...safeParams } = params;
148
157
  return {
149
158
  eventName: name,
150
159
  params: safeParams
package/dist/index.cjs CHANGED
@@ -6,6 +6,19 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
6
6
 
7
7
  const React__default = /*#__PURE__*/_interopDefaultCompat(React);
8
8
 
9
+ function parseEventArgs(eventNameOrObject, eventParams) {
10
+ if (typeof eventNameOrObject === "object") {
11
+ return {
12
+ eventName: eventNameOrObject.eventName,
13
+ params: eventNameOrObject.params
14
+ };
15
+ }
16
+ return {
17
+ eventName: eventNameOrObject,
18
+ params: eventParams
19
+ };
20
+ }
21
+
9
22
  const TrackContext = React__default.createContext(null);
10
23
  const useTracker = () => {
11
24
  const ctx = React.useContext(TrackContext);
@@ -20,44 +33,46 @@ const TrackRootComponent = ({ onEvent, children, filter, transform }) => {
20
33
  const onEventRef = useFreshRef(onEvent);
21
34
  const filterRef = useFreshRef(filter);
22
35
  const transformRef = useFreshRef(transform);
23
- const sendEvent = React.useCallback(
24
- (eventName, params) => {
25
- let localName = eventName;
26
- let localParams = params || EmptyParams;
27
- let shouldProcessLocal = true;
36
+ function sendEvent(eventNameOrObject, eventParams) {
37
+ const { eventName, params: incomingParams } = parseEventArgs(
38
+ eventNameOrObject,
39
+ eventParams
40
+ );
41
+ let localName = eventName;
42
+ let localParams = incomingParams || EmptyParams;
43
+ let shouldProcessLocal = true;
44
+ try {
45
+ if (filterRef.current) {
46
+ shouldProcessLocal = filterRef.current(localName, localParams);
47
+ }
48
+ } catch (error) {
49
+ console.error("TrackRoot filter failed:", error);
50
+ shouldProcessLocal = false;
51
+ }
52
+ if (shouldProcessLocal && transformRef.current) {
28
53
  try {
29
- if (filterRef.current) {
30
- shouldProcessLocal = filterRef.current(localName, localParams);
31
- }
54
+ const paramsCopy = incomingParams ? { ...incomingParams } : EmptyParams;
55
+ const result = transformRef.current(eventName, paramsCopy);
56
+ localName = result.eventName;
57
+ localParams = result.params;
32
58
  } catch (error) {
33
- console.error("TrackRoot filter failed:", error);
59
+ console.error("TrackRoot transform failed:", error);
34
60
  shouldProcessLocal = false;
35
61
  }
36
- if (shouldProcessLocal && transformRef.current) {
37
- try {
38
- const paramsCopy = params ? { ...params } : EmptyParams;
39
- const result = transformRef.current(eventName, paramsCopy);
40
- localName = result.eventName;
41
- localParams = result.params;
42
- } catch (error) {
43
- console.error("TrackRoot transform failed:", error);
44
- shouldProcessLocal = false;
45
- }
46
- }
47
- if (shouldProcessLocal) {
48
- try {
49
- onEventRef.current(localName, localParams);
50
- } catch (error) {
51
- console.error("TrackRoot onEvent failed:", error);
52
- }
53
- }
54
- if (parentCtx) {
55
- parentCtx.sendEvent(eventName, params);
62
+ }
63
+ if (shouldProcessLocal) {
64
+ try {
65
+ onEventRef.current(localName, localParams);
66
+ } catch (error) {
67
+ console.error("TrackRoot onEvent failed:", error);
56
68
  }
57
- },
58
- [parentCtx]
59
- );
60
- const value = React.useMemo(() => ({ sendEvent }), [sendEvent]);
69
+ }
70
+ if (parentCtx) {
71
+ parentCtx.sendEvent(eventName, incomingParams);
72
+ }
73
+ }
74
+ const sendEventCached = React.useCallback(sendEvent, [parentCtx]);
75
+ const value = React.useMemo(() => ({ sendEvent: sendEventCached }), [sendEventCached]);
61
76
  return /* @__PURE__ */ React__default.createElement(TrackContext.Provider, { value }, children);
62
77
  };
63
78
  const factory = (onEvent, filter, transform) => {
@@ -78,17 +93,19 @@ const TrackProvider = ({
78
93
  }) => {
79
94
  const ctx = useTracker();
80
95
  const paramsRef = useFreshRef(params);
81
- const sendEvent = React.useCallback(
82
- (eventName, eventParams) => {
83
- const currentParams = paramsRef.current;
84
- ctx.sendEvent(eventName, {
85
- ...currentParams,
86
- ...eventParams
87
- });
88
- },
89
- [ctx]
90
- );
91
- const value = React.useMemo(() => ({ sendEvent }), [sendEvent]);
96
+ function sendEvent(eventNameOrObject, eventParams) {
97
+ const { eventName, params: incomingParams } = parseEventArgs(
98
+ eventNameOrObject,
99
+ eventParams
100
+ );
101
+ const currentParams = paramsRef.current;
102
+ ctx.sendEvent(eventName, {
103
+ ...currentParams,
104
+ ...incomingParams
105
+ });
106
+ }
107
+ const sendEventCached = React.useCallback(sendEvent, [ctx]);
108
+ const value = React.useMemo(() => ({ sendEvent: sendEventCached }), [sendEventCached]);
92
109
  return /* @__PURE__ */ React__default.createElement(TrackContext.Provider, { value }, children);
93
110
  };
94
111
  function useFreshRef(data) {
@@ -97,9 +114,10 @@ function useFreshRef(data) {
97
114
  return ref;
98
115
  }
99
116
 
100
- function useMountEvent(eventName, params) {
117
+ function useMountEvent(eventNameOrObject, eventParams) {
101
118
  const { sendEvent } = useTracker();
102
119
  const counterRef = React.useRef(0);
120
+ const { eventName, params } = parseEventArgs(eventNameOrObject, eventParams);
103
121
  React.useEffect(() => {
104
122
  if (counterRef.current > 0) {
105
123
  return;
package/dist/index.d.cts CHANGED
@@ -2,8 +2,13 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { PropsWithChildren } from 'react';
3
3
 
4
4
  type EventParams = Record<string, any>;
5
- type TrackContextValue = {
6
- sendEvent: (eventName: string, params?: EventParams) => void;
5
+ interface TrackContextValue {
6
+ sendEvent(eventName: string, params?: EventParams): void;
7
+ sendEvent(event: EventObject): void;
8
+ }
9
+ type EventObject = {
10
+ eventName: string;
11
+ params?: EventParams;
7
12
  };
8
13
  type EventFilter = (eventName: string, params: EventParams) => boolean;
9
14
  type TransformedEvent = {
@@ -26,5 +31,6 @@ declare const TrackProvider: ({ params, children }: PropsWithChildren<{
26
31
  }>) => react_jsx_runtime.JSX.Element;
27
32
 
28
33
  declare function useMountEvent(eventName: string, params?: EventParams): void;
34
+ declare function useMountEvent(event: EventObject): void;
29
35
 
30
36
  export { TrackProvider, TrackRoot, useMountEvent, useTracker };
package/dist/index.d.mts CHANGED
@@ -2,8 +2,13 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { PropsWithChildren } from 'react';
3
3
 
4
4
  type EventParams = Record<string, any>;
5
- type TrackContextValue = {
6
- sendEvent: (eventName: string, params?: EventParams) => void;
5
+ interface TrackContextValue {
6
+ sendEvent(eventName: string, params?: EventParams): void;
7
+ sendEvent(event: EventObject): void;
8
+ }
9
+ type EventObject = {
10
+ eventName: string;
11
+ params?: EventParams;
7
12
  };
8
13
  type EventFilter = (eventName: string, params: EventParams) => boolean;
9
14
  type TransformedEvent = {
@@ -26,5 +31,6 @@ declare const TrackProvider: ({ params, children }: PropsWithChildren<{
26
31
  }>) => react_jsx_runtime.JSX.Element;
27
32
 
28
33
  declare function useMountEvent(eventName: string, params?: EventParams): void;
34
+ declare function useMountEvent(event: EventObject): void;
29
35
 
30
36
  export { TrackProvider, TrackRoot, useMountEvent, useTracker };
package/dist/index.d.ts CHANGED
@@ -2,8 +2,13 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { PropsWithChildren } from 'react';
3
3
 
4
4
  type EventParams = Record<string, any>;
5
- type TrackContextValue = {
6
- sendEvent: (eventName: string, params?: EventParams) => void;
5
+ interface TrackContextValue {
6
+ sendEvent(eventName: string, params?: EventParams): void;
7
+ sendEvent(event: EventObject): void;
8
+ }
9
+ type EventObject = {
10
+ eventName: string;
11
+ params?: EventParams;
7
12
  };
8
13
  type EventFilter = (eventName: string, params: EventParams) => boolean;
9
14
  type TransformedEvent = {
@@ -26,5 +31,6 @@ declare const TrackProvider: ({ params, children }: PropsWithChildren<{
26
31
  }>) => react_jsx_runtime.JSX.Element;
27
32
 
28
33
  declare function useMountEvent(eventName: string, params?: EventParams): void;
34
+ declare function useMountEvent(event: EventObject): void;
29
35
 
30
36
  export { TrackProvider, TrackRoot, useMountEvent, useTracker };
package/dist/index.mjs CHANGED
@@ -1,5 +1,18 @@
1
1
  import React, { useContext, useCallback, useMemo, useRef, useEffect } from 'react';
2
2
 
3
+ function parseEventArgs(eventNameOrObject, eventParams) {
4
+ if (typeof eventNameOrObject === "object") {
5
+ return {
6
+ eventName: eventNameOrObject.eventName,
7
+ params: eventNameOrObject.params
8
+ };
9
+ }
10
+ return {
11
+ eventName: eventNameOrObject,
12
+ params: eventParams
13
+ };
14
+ }
15
+
3
16
  const TrackContext = React.createContext(null);
4
17
  const useTracker = () => {
5
18
  const ctx = useContext(TrackContext);
@@ -14,44 +27,46 @@ const TrackRootComponent = ({ onEvent, children, filter, transform }) => {
14
27
  const onEventRef = useFreshRef(onEvent);
15
28
  const filterRef = useFreshRef(filter);
16
29
  const transformRef = useFreshRef(transform);
17
- const sendEvent = useCallback(
18
- (eventName, params) => {
19
- let localName = eventName;
20
- let localParams = params || EmptyParams;
21
- let shouldProcessLocal = true;
30
+ function sendEvent(eventNameOrObject, eventParams) {
31
+ const { eventName, params: incomingParams } = parseEventArgs(
32
+ eventNameOrObject,
33
+ eventParams
34
+ );
35
+ let localName = eventName;
36
+ let localParams = incomingParams || EmptyParams;
37
+ let shouldProcessLocal = true;
38
+ try {
39
+ if (filterRef.current) {
40
+ shouldProcessLocal = filterRef.current(localName, localParams);
41
+ }
42
+ } catch (error) {
43
+ console.error("TrackRoot filter failed:", error);
44
+ shouldProcessLocal = false;
45
+ }
46
+ if (shouldProcessLocal && transformRef.current) {
22
47
  try {
23
- if (filterRef.current) {
24
- shouldProcessLocal = filterRef.current(localName, localParams);
25
- }
48
+ const paramsCopy = incomingParams ? { ...incomingParams } : EmptyParams;
49
+ const result = transformRef.current(eventName, paramsCopy);
50
+ localName = result.eventName;
51
+ localParams = result.params;
26
52
  } catch (error) {
27
- console.error("TrackRoot filter failed:", error);
53
+ console.error("TrackRoot transform failed:", error);
28
54
  shouldProcessLocal = false;
29
55
  }
30
- if (shouldProcessLocal && transformRef.current) {
31
- try {
32
- const paramsCopy = params ? { ...params } : EmptyParams;
33
- const result = transformRef.current(eventName, paramsCopy);
34
- localName = result.eventName;
35
- localParams = result.params;
36
- } catch (error) {
37
- console.error("TrackRoot transform failed:", error);
38
- shouldProcessLocal = false;
39
- }
40
- }
41
- if (shouldProcessLocal) {
42
- try {
43
- onEventRef.current(localName, localParams);
44
- } catch (error) {
45
- console.error("TrackRoot onEvent failed:", error);
46
- }
47
- }
48
- if (parentCtx) {
49
- parentCtx.sendEvent(eventName, params);
56
+ }
57
+ if (shouldProcessLocal) {
58
+ try {
59
+ onEventRef.current(localName, localParams);
60
+ } catch (error) {
61
+ console.error("TrackRoot onEvent failed:", error);
50
62
  }
51
- },
52
- [parentCtx]
53
- );
54
- const value = useMemo(() => ({ sendEvent }), [sendEvent]);
63
+ }
64
+ if (parentCtx) {
65
+ parentCtx.sendEvent(eventName, incomingParams);
66
+ }
67
+ }
68
+ const sendEventCached = useCallback(sendEvent, [parentCtx]);
69
+ const value = useMemo(() => ({ sendEvent: sendEventCached }), [sendEventCached]);
55
70
  return /* @__PURE__ */ React.createElement(TrackContext.Provider, { value }, children);
56
71
  };
57
72
  const factory = (onEvent, filter, transform) => {
@@ -72,17 +87,19 @@ const TrackProvider = ({
72
87
  }) => {
73
88
  const ctx = useTracker();
74
89
  const paramsRef = useFreshRef(params);
75
- const sendEvent = useCallback(
76
- (eventName, eventParams) => {
77
- const currentParams = paramsRef.current;
78
- ctx.sendEvent(eventName, {
79
- ...currentParams,
80
- ...eventParams
81
- });
82
- },
83
- [ctx]
84
- );
85
- const value = useMemo(() => ({ sendEvent }), [sendEvent]);
90
+ function sendEvent(eventNameOrObject, eventParams) {
91
+ const { eventName, params: incomingParams } = parseEventArgs(
92
+ eventNameOrObject,
93
+ eventParams
94
+ );
95
+ const currentParams = paramsRef.current;
96
+ ctx.sendEvent(eventName, {
97
+ ...currentParams,
98
+ ...incomingParams
99
+ });
100
+ }
101
+ const sendEventCached = useCallback(sendEvent, [ctx]);
102
+ const value = useMemo(() => ({ sendEvent: sendEventCached }), [sendEventCached]);
86
103
  return /* @__PURE__ */ React.createElement(TrackContext.Provider, { value }, children);
87
104
  };
88
105
  function useFreshRef(data) {
@@ -91,9 +108,10 @@ function useFreshRef(data) {
91
108
  return ref;
92
109
  }
93
110
 
94
- function useMountEvent(eventName, params) {
111
+ function useMountEvent(eventNameOrObject, eventParams) {
95
112
  const { sendEvent } = useTracker();
96
113
  const counterRef = useRef(0);
114
+ const { eventName, params } = parseEventArgs(eventNameOrObject, eventParams);
97
115
  useEffect(() => {
98
116
  if (counterRef.current > 0) {
99
117
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-event-tracking",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "files": [
5
5
  "dist"
6
6
  ],