{"version":3,"sources":["../src/constants/index.ts","../src/utils/getDataAttributes.ts","../src/utils/getMeaningfulTag.ts","../src/hooks/use-tracking.ts","../src/components/provider.tsx"],"sourcesContent":["export const IGNORE_PATTERNS = [\n  // aria\n  'aria-',\n  // class and associated\n  'class',\n  'height',\n  'width',\n  'style',\n  // shadcn\n  'data-state',\n  'data-sidebar',\n]\n\nexport const MEANINGFUL_TAGS = ['A', 'BUTTON']\n","interface GetDataAttributesOptions {\n  ignore?: string[]\n  prefix?: string\n}\n\nexport function getDataAttributes(\n  target: HTMLElement,\n  { ignore = [], prefix }: GetDataAttributesOptions = {},\n): Record<string, string> {\n  if (!target) return {}\n\n  return Array.from(target.attributes).reduce(\n    (acc, attr) => {\n      if (ignore.some((i) => attr.name.startsWith(i))) return acc\n      if (prefix && !attr.name.startsWith(prefix)) return acc\n      return { ...acc, [attr.name]: attr.value }\n    },\n    {} as Record<string, string>,\n  )\n}\n","interface GetMeaningfulTagOptions {\n  meaningfulTags?: string[]\n  target: HTMLElement | null\n}\n\nexport function getMeaningfulTag({\n  meaningfulTags = [],\n  target,\n}: GetMeaningfulTagOptions): {\n  name: string\n  target: HTMLElement\n} | null {\n  if (!target) return null\n\n  const renameTag = (tag: string) => (tag === 'A' ? 'link' : tag.toLowerCase())\n\n  const isMeaningfulTag = (el: HTMLElement) => {\n    return !meaningfulTags.length\n      ? el\n      : meaningfulTags.includes(el.tagName)\n        ? el\n        : (el.closest(meaningfulTags.join(',')) as HTMLElement | null)\n  }\n\n  const meaningfulTag = isMeaningfulTag(target)\n\n  return meaningfulTag\n    ? {\n        name: renameTag(meaningfulTag.tagName),\n        target: meaningfulTag,\n      }\n    : null\n}\n","import { IGNORE_PATTERNS, MEANINGFUL_TAGS } from '@/src/constants'\nimport { getDataAttributes, getMeaningfulTag } from '@/src/utils'\nimport { usePathname } from 'next/navigation'\nimport { useCallback, useEffect, useRef } from 'react'\n\nexport interface UseTrackingOptions {\n  prefix?: string\n  ignore?: string[]\n  meaningfulTags?: string[]\n  action?: (data: Record<string, string>) => void\n}\n\nexport function useTracking({\n  prefix = '',\n  ignore = IGNORE_PATTERNS,\n  meaningfulTags = MEANINGFUL_TAGS,\n  action,\n}: UseTrackingOptions = {}) {\n  // if no action is provided, log to console in development\n  if (!action && process.env.NODE_ENV === 'development') {\n    action = (data) => console.log(data)\n  }\n\n  const url = usePathname()\n\n  const sessionId = useRef(\n    Array.from(crypto.getRandomValues(new Uint8Array(16)))\n      .map((n) => n.toString(16))\n      .join(''),\n  )\n\n  const trackPageView = useCallback(() => {\n    action?.({\n      sessionId: sessionId.current,\n      url,\n      event: 'pageview',\n      timestamp: new Date().toISOString(),\n    })\n  }, [action, url])\n\n  const trackClickEvent = useCallback(\n    (e: MouseEvent) => {\n      const target = e.target as HTMLElement\n\n      const meaningfulTag = getMeaningfulTag({\n        target,\n        meaningfulTags,\n      })\n\n      if (!meaningfulTag) return\n\n      const attributes = getDataAttributes(meaningfulTag.target, {\n        ignore,\n        prefix,\n      })\n\n      const eventData: Record<string, string> = {\n        sessionId: sessionId.current,\n        url,\n        event: `${meaningfulTag.name}click`,\n        timestamp: new Date().toISOString(),\n        attributes: JSON.stringify(attributes),\n      }\n\n      return action?.(eventData)\n    },\n    [action, url, ignore, prefix],\n  )\n\n  useEffect(() => {\n    trackPageView()\n  }, [trackPageView])\n\n  useEffect(() => {\n    document.addEventListener('click', trackClickEvent)\n    return () => {\n      document.removeEventListener('click', trackClickEvent)\n    }\n  }, [trackClickEvent])\n\n  return null\n}\n","import { useTracking, type UseTrackingOptions } from '@/src/hooks/use-tracking'\nimport React from 'react'\n\nexport function TrackingClientProvider({\n  config,\n  children,\n}: {\n  config: UseTrackingOptions\n  children?: React.ReactNode\n}) {\n  useTracking(config)\n\n  return <React.Fragment>{children}</React.Fragment>\n}\n"],"mappings":"AAAO,IAAMA,EAAkB,CAE7B,QAEA,QACA,SACA,QACA,QAEA,aACA,cACF,EAEaC,EAAkB,CAAC,IAAK,QAAQ,ECRtC,SAASC,EACdC,EACA,CAAE,OAAAC,EAAS,CAAC,EAAG,OAAAC,CAAO,EAA8B,CAAC,EAC7B,CACxB,OAAKF,EAEE,MAAM,KAAKA,EAAO,UAAU,EAAE,OACnC,CAACG,EAAKC,IACAH,EAAO,KAAMI,GAAMD,EAAK,KAAK,WAAWC,CAAC,CAAC,GAC1CH,GAAU,CAACE,EAAK,KAAK,WAAWF,CAAM,EAAUC,EAC7C,CAAE,GAAGA,EAAK,CAACC,EAAK,IAAI,EAAGA,EAAK,KAAM,EAE3C,CAAC,CACH,EAToB,CAAC,CAUvB,CCdO,SAASE,EAAiB,CAC/B,eAAAC,EAAiB,CAAC,EAClB,OAAAC,CACF,EAGS,CACP,GAAI,CAACA,EAAQ,OAAO,KAEpB,IAAMC,EAAaC,GAAiBA,IAAQ,IAAM,OAASA,EAAI,YAAY,EAUrEC,GARmBC,GACfL,EAAe,OAEnBA,EAAe,SAASK,EAAG,OAAO,EAChCA,EACCA,EAAG,QAAQL,EAAe,KAAK,GAAG,CAAC,EAHtCK,GAMgCJ,CAAM,EAE5C,OAAOG,EACH,CACE,KAAMF,EAAUE,EAAc,OAAO,EACrC,OAAQA,CACV,EACA,IACN,CC9BA,OAAS,eAAAE,MAAmB,kBAC5B,OAAS,eAAAC,EAAa,aAAAC,EAAW,UAAAC,MAAc,QASxC,SAASC,EAAY,CAC1B,OAAAC,EAAS,GACT,OAAAC,EAASC,EACT,eAAAC,EAAiBC,EACjB,OAAAC,CACF,EAAwB,CAAC,EAAG,CAEtB,CAACA,GAAU,QAAQ,IAAI,WAAa,gBACtCA,EAAUC,GAAS,QAAQ,IAAIA,CAAI,GAGrC,IAAMC,EAAMZ,EAAY,EAElBa,EAAYV,EAChB,MAAM,KAAK,OAAO,gBAAgB,IAAI,WAAW,EAAE,CAAC,CAAC,EAClD,IAAKW,GAAMA,EAAE,SAAS,EAAE,CAAC,EACzB,KAAK,EAAE,CACZ,EAEMC,EAAgBd,EAAY,IAAM,CACtCS,IAAS,CACP,UAAWG,EAAU,QACrB,IAAAD,EACA,MAAO,WACP,UAAW,IAAI,KAAK,EAAE,YAAY,CACpC,CAAC,CACH,EAAG,CAACF,EAAQE,CAAG,CAAC,EAEVI,EAAkBf,EACrBgB,GAAkB,CACjB,IAAMC,EAASD,EAAE,OAEXE,EAAgBC,EAAiB,CACrC,OAAAF,EACA,eAAAV,CACF,CAAC,EAED,GAAI,CAACW,EAAe,OAEpB,IAAME,EAAaC,EAAkBH,EAAc,OAAQ,CACzD,OAAAb,EACA,OAAAD,CACF,CAAC,EAEKkB,EAAoC,CACxC,UAAWV,EAAU,QACrB,IAAAD,EACA,MAAO,GAAGO,EAAc,IAAI,QAC5B,UAAW,IAAI,KAAK,EAAE,YAAY,EAClC,WAAY,KAAK,UAAUE,CAAU,CACvC,EAEA,OAAOX,IAASa,CAAS,CAC3B,EACA,CAACb,EAAQE,EAAKN,EAAQD,CAAM,CAC9B,EAEA,OAAAH,EAAU,IAAM,CACda,EAAc,CAChB,EAAG,CAACA,CAAa,CAAC,EAElBb,EAAU,KACR,SAAS,iBAAiB,QAASc,CAAe,EAC3C,IAAM,CACX,SAAS,oBAAoB,QAASA,CAAe,CACvD,GACC,CAACA,CAAe,CAAC,EAEb,IACT,CChFA,OAAOQ,MAAW,QAEX,SAASC,EAAuB,CACrC,OAAAC,EACA,SAAAC,CACF,EAGG,CACD,OAAAC,EAAYF,CAAM,EAEXF,EAAA,cAACA,EAAM,SAAN,KAAgBG,CAAS,CACnC","names":["IGNORE_PATTERNS","MEANINGFUL_TAGS","getDataAttributes","target","ignore","prefix","acc","attr","i","getMeaningfulTag","meaningfulTags","target","renameTag","tag","meaningfulTag","el","usePathname","useCallback","useEffect","useRef","useTracking","prefix","ignore","IGNORE_PATTERNS","meaningfulTags","MEANINGFUL_TAGS","action","data","url","sessionId","n","trackPageView","trackClickEvent","e","target","meaningfulTag","getMeaningfulTag","attributes","getDataAttributes","eventData","React","TrackingClientProvider","config","children","useTracking"]}