Add AnalyticsLoader component with idle-callback initialization
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import type { ReactNode } from "react";
|
||||
import type { Analytics, AnalyticsProviders } from "./types.js";
|
||||
import type { Logger } from "@/observability/logger/types";
|
||||
import { createAnalytics } from "./facade.js";
|
||||
import { AnalyticsContext } from "./provider.js";
|
||||
|
||||
export interface AnalyticsLoaderProps {
|
||||
enabled: AnalyticsProviders;
|
||||
consent: { analytics: boolean; telemetry: boolean };
|
||||
logger: Logger;
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mounts in the root layout. Waits for idle callback, then initializes
|
||||
* analytics adapters and provides the Analytics instance to the tree.
|
||||
*/
|
||||
export function AnalyticsLoader({
|
||||
enabled,
|
||||
consent,
|
||||
logger,
|
||||
children,
|
||||
}: AnalyticsLoaderProps): JSX.Element {
|
||||
const [analytics, setAnalytics] = useState<Analytics | null>(null);
|
||||
const initRef = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (initRef.current) return;
|
||||
initRef.current = true;
|
||||
|
||||
const init = () => {
|
||||
const instance = createAnalytics({ enabled, consent, logger });
|
||||
setAnalytics(instance);
|
||||
};
|
||||
|
||||
if (typeof window !== "undefined" && "requestIdleCallback" in window) {
|
||||
(window as unknown as { requestIdleCallback: (cb: () => void) => void }).requestIdleCallback(init);
|
||||
} else {
|
||||
// Fallback for environments without requestIdleCallback
|
||||
setTimeout(init, 1);
|
||||
}
|
||||
}, [enabled, consent, logger]);
|
||||
|
||||
return (
|
||||
<AnalyticsContext.Provider value={analytics}>
|
||||
{children}
|
||||
</AnalyticsContext.Provider>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user