import { DebugLogger } from '@affine/debug'; import type { CallableEventsChain, EventsUnion } from './types'; const logger = new DebugLogger('mixpanel'); interface TrackFn { (event: string, props: Record): void; } const levels = ['page', 'segment', 'module', 'event'] as const; export function makeTracker(trackFn: TrackFn): CallableEventsChain { function makeTrackerInner(level: number, info: Record) { const proxy = new Proxy({} as Record, { get(target, prop) { if ( typeof prop !== 'string' || prop === '$$typeof' /* webpack hot-reload reads this prop */ ) { return undefined; } if (levels[level] === 'event') { return (arg: string | Record) => { trackFn(prop, { ...info, ...(typeof arg === 'string' ? { arg } : arg), }); }; } else { let levelProxy = target[prop]; if (levelProxy) { return levelProxy; } levelProxy = makeTrackerInner( level + 1, prop === '$' ? { ...info } : { ...info, [levels[level]]: prop } ); target[prop] = levelProxy; return levelProxy; } }, }); return proxy; } return makeTrackerInner(0, {}) as CallableEventsChain; } /** * listen on clicking on all subtree elements and auto track events if defined * * @example * * ```html *