import type { Poool } from 'poool-access'; import { type ComponentPropsWithoutRef, useCallback, useEffect, useReducer, } from 'react'; import { mockState } from '@junipero/core'; import type { AuditEvents, EventCallback, EventCallbackFunction, EventCallbackObject, } from '../types'; import { type AuditContextValue, AuditContext as Ctx } from '../contexts'; import { loadScript } from '../utils'; export interface AuditContextProps extends AuditContextValue, ComponentPropsWithoutRef { /** * Maximum time for the Audit script to load * @default 2000 */ scriptLoadTimeout?: number; } export interface AuditContextState { lib?: Poool.Audit; } const AuditContext = ({ appId, config, events, scriptUrl = 'https://assets.poool.fr/audit.min.js', scriptLoadTimeout = 2000, ...rest }: AuditContextProps) => { const [state, dispatch] = useReducer(mockState, { lib: null, }); useEffect(() => { init(); return () => { deinit(); }; // eslint-disable-next-line react-hooks/exhaustive-deps,@eslint-react/exhaustive-deps }, [config?.cookies_enabled]); const init = async () => { if ( (!globalThis.Audit?.isPoool) && (!globalThis.PooolAudit?.isPoool) ) { await loadScript(scriptUrl, 'poool-react-audit-lib', { timeout: scriptLoadTimeout, }); } const auditRef = globalThis.PooolAudit || globalThis.Audit; const lib = auditRef.noConflict().init(appId).config(config); Object .entries(events || {}) .forEach(([ event, callback, ]: [ Poool.EventsList, EventCallback, ]) => { if ((callback as EventCallbackObject).once) { lib.once(event, (callback as EventCallbackObject).callback); } else { lib.on(event, callback as EventCallbackFunction); } }); lib.once('identityAvailable', onIdentityAvailable); dispatch({ lib }); }; const deinit = () => { Object .entries(events || {}) .forEach(([ event, callback, ]: [ Poool.EventsList, EventCallback, ]) => { state.lib?.off( event, (callback as EventCallbackObject).callback || (callback as EventCallbackFunction) ); }); state.lib?.off('identityAvailable', onIdentityAvailable); }; const onIdentityAvailable = ( e: Parameters< Extract> >[0] ) => { try { globalThis.document.dispatchEvent(new CustomEvent('$_poool.onMessage', { detail: { type: '$_poool.setUser', data: e, }, })); } catch {} }; const getContext = useCallback(() => ({ appId, config, events, scriptUrl, lib: state.lib, // eslint-disable-next-line react-hooks/exhaustive-deps,@eslint-react/exhaustive-deps }), [state.lib, config?.cookies_enabled]); return ( ); }; AuditContext.displayName = 'AuditContext'; export default AuditContext;