@@ -7,20 +7,16 @@ import React, {
77 useEffect ,
88 useState ,
99} from "react"
10- import { Analytics , AnalyticsBrowser } from "@segment/analytics-next"
11- import posthog from "posthog-js"
12-
13- // @ts -expect-error Doesn't have a types package
14- import { loadReoScript } from "reodotdev"
10+ import { useSegmentAnalytics } from "./providers/segment"
11+ import { usePostHogAnalytics } from "./providers/posthog"
12+ import { useReoDevAnalytics } from "./providers/reo-dev"
1513
1614export type ExtraData = {
1715 section ?: string
18- [ key : string ] : any
16+ [ key : string ] : unknown
1917}
2018
2119export type AnalyticsContextType = {
22- loaded : boolean
23- analytics : Analytics | null
2420 track : ( {
2521 event,
2622 instant,
@@ -34,7 +30,7 @@ type Trackers = "segment" | "posthog"
3430
3531export type TrackedEvent = {
3632 event : string
37- options ?: Record < string , any >
33+ options ?: Record < string , unknown >
3834 callback ?: ( ) => void
3935 tracker ?: Trackers | Trackers [ ]
4036}
@@ -47,73 +43,18 @@ export type AnalyticsProviderProps = {
4743 children ?: React . ReactNode
4844}
4945
50- const LOCAL_STORAGE_KEY = "ajs_anonymous_id"
51-
5246export const AnalyticsProvider = ( {
53- segmentWriteKey = "temp" ,
47+ segmentWriteKey,
5448 reoDevKey,
5549 children,
5650} : AnalyticsProviderProps ) => {
57- // loaded is used to ensure that a connection has been made to segment
58- // even if it failed. This is to ensure that the connection isn't
59- // continuously retried
60- const [ loaded , setLoaded ] = useState < boolean > ( false )
61- const [ analytics , setAnalytics ] = useState < Analytics | null > ( null )
62- const analyticsBrowser = new AnalyticsBrowser ( )
63- const [ queue , setQueue ] = useState < TrackedEvent [ ] > ( [ ] )
64-
65- const initSegment = useCallback ( ( ) => {
66- if ( ! loaded ) {
67- analyticsBrowser
68- . load (
69- { writeKey : segmentWriteKey } ,
70- {
71- initialPageview : true ,
72- user : {
73- localStorage : {
74- key : LOCAL_STORAGE_KEY ,
75- } ,
76- } ,
77- }
78- )
79- . then ( ( instance ) => {
80- setAnalytics ( instance [ 0 ] )
81- } )
82- . catch ( ( e ) =>
83- console . error ( `Could not connect to Segment. Error: ${ e } ` )
84- )
85- . finally ( ( ) => setLoaded ( true ) )
86- }
87- } , [ loaded , segmentWriteKey ] )
88-
89- const trackWithSegment = useCallback (
90- async ( { event, options } : TrackedEvent ) => {
91- if ( analytics ) {
92- void analytics . track ( event , {
93- ...options ,
94- uuid : analytics . user ( ) . anonymousId ( ) ,
95- } )
96- } else {
97- // push the event into the queue
98- setQueue ( ( prevQueue ) => [
99- ...prevQueue ,
100- {
101- event,
102- options,
103- tracker : "segment" ,
104- } ,
105- ] )
106- console . warn (
107- "Segment is either not installed or not configured. Simulating success..."
108- )
109- }
110- } ,
111- [ analytics , loaded ]
112- )
113-
114- const trackWithPostHog = async ( { event, options } : TrackedEvent ) => {
115- posthog . capture ( event , options )
116- }
51+ const [ eventsQueue , setEventsQueue ] = useState < TrackedEvent [ ] > ( [ ] )
52+ const { track : trackWithSegment } = useSegmentAnalytics ( {
53+ segmentWriteKey,
54+ setEventsQueue,
55+ } )
56+ const { track : trackWithPostHog } = usePostHogAnalytics ( )
57+ useReoDevAnalytics ( { reoDevKey } )
11758
11859 const processEvent = useCallback (
11960 async ( event : TrackedEvent ) => {
@@ -137,22 +78,18 @@ export const AnalyticsProvider = ({
13778
13879 const track = ( { event } : { event : TrackedEvent } ) => {
13980 // Always queue events - this makes tracking non-blocking
140- setQueue ( ( prevQueue ) => [ ...prevQueue , event ] )
81+ setEventsQueue ( ( prevQueue ) => [ ...prevQueue , event ] )
14182
14283 // Process event callback immediately
14384 // This ensures that the callback is called even if the event is queued
14485 event . callback ?.( )
14586 }
14687
14788 useEffect ( ( ) => {
148- initSegment ( )
149- } , [ initSegment ] )
150-
151- useEffect ( ( ) => {
152- if ( analytics && queue . length ) {
89+ if ( eventsQueue . length ) {
15390 // Process queue in background without blocking
154- const currentQueue = [ ...queue ]
155- setQueue ( [ ] )
91+ const currentQueue = [ ...eventsQueue ]
92+ setEventsQueue ( [ ] )
15693
15794 // Process events asynchronously in batches to avoid overwhelming the system
15895 const batchSize = 5
@@ -163,32 +100,12 @@ export const AnalyticsProvider = ({
163100 } , i * 10 ) // Small delay between batches
164101 }
165102 }
166- } , [ analytics , queue , trackWithSegment , trackWithPostHog , processEvent ] )
167-
168- useEffect ( ( ) => {
169- if ( ! reoDevKey ) {
170- return
171- }
172-
173- loadReoScript ( {
174- clientID : reoDevKey ,
175- } )
176- . then ( ( Reo : unknown ) => {
177- ; ( Reo as { init : ( config : { clientID : string } ) => void } ) . init ( {
178- clientID : reoDevKey ,
179- } )
180- } )
181- . catch ( ( e : Error ) => {
182- console . error ( `Could not connect to Reodotdev. Error: ${ e } ` )
183- } )
184- } , [ reoDevKey ] )
103+ } , [ eventsQueue , processEvent ] )
185104
186105 return (
187106 < AnalyticsContext . Provider
188107 value = { {
189- analytics,
190108 track,
191- loaded,
192109 } }
193110 >
194111 { children }
0 commit comments