@scaleway/use-analytics
Version:
A small hook to handle events analytics
125 lines (124 loc) • 4.05 kB
JavaScript
;
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
const jsxRuntime = require("react/jsx-runtime");
const analyticsJs = require("@rudderstack/analytics-js");
const react = require("react");
const useDeepCompareEffect = require("use-deep-compare-effect");
const constants = require("../constants.cjs");
const constants$1 = require("./constants.cjs");
const userMigrationsTraits = require("./segments/userMigrationsTraits.cjs");
const AnalyticsContext = react.createContext(
void 0
);
function useAnalytics() {
const context = react.useContext(
// @ts-expect-error Here we force cast the generic onto the useContext because the context is a
// global variable and cannot be generic
AnalyticsContext
);
if (context === void 0) {
throw new Error("useAnalytics must be used within a AnalyticsProvider");
}
return context;
}
function AnalyticsProvider({
children,
settings,
loadOptions,
shouldRenderOnlyWhenReady = false,
needConsent = true,
onError,
onEventError,
allowedConsents,
deniedConsents,
events,
onLoaded,
timeout
}) {
const [isAnalyticsReady, setIsAnalyticsReady] = react.useState(false);
const [internalAnalytics, setAnalytics] = react.useState(
void 0
);
react.useEffect(() => {
let timer;
if (!isAnalyticsReady && !internalAnalytics && timeout) {
if (shouldRenderOnlyWhenReady) {
timer = setTimeout(() => setIsAnalyticsReady(true), timeout);
onError?.(new Error("Analytics Setup Timeout"));
}
}
return () => {
clearTimeout(timer);
};
}, [
isAnalyticsReady,
internalAnalytics,
setIsAnalyticsReady,
shouldRenderOnlyWhenReady,
timeout,
onError
]);
const shouldLoad = react.useMemo(() => {
if (needConsent) {
return false;
}
return !!settings?.writeKey;
}, [settings?.writeKey, needConsent]);
useDeepCompareEffect.useDeepCompareEffectNoCheck(() => {
if (shouldLoad && settings) {
const analytics = new analyticsJs.RudderAnalytics();
analytics.load(settings.writeKey, settings.cdnURL, {
...constants$1.defaultLoadOptions,
configUrl: settings.cdnURL,
destSDKBaseURL: constants.destSDKBaseURL(settings.cdnURL),
pluginsSDKBaseURL: constants.pluginsSDKBaseURL(settings.cdnURL),
onLoaded: (rudderAnalytics) => {
userMigrationsTraits.userMigrationsTraits(rudderAnalytics);
rudderAnalytics.consent({
...constants$1.defaultConsentOptions,
consentManagement: {
enabled: true,
allowedConsentIds: allowedConsents,
deniedConsentIds: deniedConsents
}
});
onLoaded(rudderAnalytics);
setIsAnalyticsReady(true);
},
...loadOptions
});
analytics.ready(() => {
setAnalytics(analytics);
setIsAnalyticsReady(true);
});
}
}, [settings, loadOptions, shouldLoad]);
const value = react.useMemo(() => {
const curiedEvents = Object.entries(events).reduce(
(acc, [eventName, eventFn]) => ({
...acc,
[eventName]: eventFn(internalAnalytics, onEventError)
}),
{}
);
return {
analytics: internalAnalytics,
events: curiedEvents,
isAnalyticsReady
};
}, [events, internalAnalytics, isAnalyticsReady, onEventError]);
const shouldRender = !shouldRenderOnlyWhenReady || isAnalyticsReady && !needConsent;
useDeepCompareEffect.useDeepCompareEffectNoCheck(() => {
internalAnalytics?.consent({
consentManagement: {
enabled: true,
allowedConsentIds: allowedConsents,
deniedConsentIds: deniedConsents
}
});
}, [allowedConsents, deniedConsents]);
return /* @__PURE__ */ jsxRuntime.jsx(AnalyticsContext.Provider, { value, children: shouldRender ? children : null });
}
exports.AnalyticsProvider = AnalyticsProvider;
exports.default = AnalyticsProvider;
exports.useAnalytics = useAnalytics;