@shopana/ga
Version:
Type-safe Google Analytics 4 (GA4) tracking library for React and Next.js with ecommerce support, event batching, and SSR compatibility
89 lines • 3.63 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import { useEffect, useMemo, useRef } from 'react';
import { AnalyticsClient } from '../core/AnalyticsClient';
import {} from '../types/core';
import {} from '../types/common';
import { createPlatformAdapter } from '../platform/createAdapter';
import {} from '../types/platform';
import { GATracker } from '../trackers/GATracker';
import { DebugChannel } from '../utils/debugChannel';
import { GAContext } from './context';
export const GAProvider = ({ config, children, adapterFactory, hooks, }) => {
const adapter = useMemo(() => (adapterFactory ? adapterFactory() : createPlatformAdapter()), [adapterFactory]);
const debugChannel = useMemo(() => new DebugChannel(), []);
const clientRef = useRef(null);
const configRef = useRef(config);
const hooksRef = useRef(hooks);
const adapterRef = useRef(adapter);
const client = useMemo(() => {
const featuresEqual = (a, b) => {
if (a === b) {
return true;
}
if (!a || !b) {
return false;
}
const aBatching = a.batching;
const bBatching = b.batching;
if (aBatching?.enabled !== bBatching?.enabled) {
return false;
}
if (aBatching?.size !== bBatching?.size) {
return false;
}
if (aBatching?.timeoutMs !== bBatching?.timeoutMs) {
return false;
}
const aRetries = a.retries;
const bRetries = b.retries;
if (aRetries?.enabled !== bRetries?.enabled) {
return false;
}
if (aRetries?.maxAttempts !== bRetries?.maxAttempts) {
return false;
}
if (aRetries?.delayMs !== bRetries?.delayMs) {
return false;
}
if (aRetries?.jitterRatio !== bRetries?.jitterRatio) {
return false;
}
return true;
};
const configChanged = configRef.current.measurementId !== config.measurementId ||
configRef.current.disabled !== config.disabled ||
!featuresEqual(configRef.current.features, config.features);
const hooksChanged = hooksRef.current?.onReady !== hooks?.onReady ||
hooksRef.current?.onEvent !== hooks?.onEvent ||
hooksRef.current?.onError !== hooks?.onError ||
hooksRef.current?.onFlush !== hooks?.onFlush;
const adapterChanged = adapterRef.current !== adapter;
if (!clientRef.current || configChanged || hooksChanged || adapterChanged) {
const options = {
hooks,
debugChannel,
};
clientRef.current = new AnalyticsClient(adapter, config, options);
configRef.current = config;
hooksRef.current = hooks;
adapterRef.current = adapter;
}
else if (config !== configRef.current) {
clientRef.current.updateConfig(config);
configRef.current = config;
}
return clientRef.current;
}, [adapter, config, hooks, debugChannel]);
useEffect(() => {
void client.init();
return () => client.destroy();
}, [client]);
const tracker = useMemo(() => new GATracker(client), [client]);
const value = useMemo(() => ({
client,
tracker,
debugChannel,
}), [client, tracker, debugChannel]);
return _jsx(GAContext.Provider, { value: value, children: children });
};
//# sourceMappingURL=GAProvider.js.map