{"version":3,"sources":["../src/index.ts"],"names":["location"],"mappings":";AAAA,YAAY,WAAW;AAGvB,SAAS,aAAa,iBAAiB;AACvC,SAAS,OAAO,OAAO,OAAO,OAAO,QAAQ,aAAa;AAE1D,IAAI,YAAY;AAYhB,SAAS,gBAAgB,QAAgB,SAAsB;AAC7D,MAAI,OAAO,OAAO,QAAQ,QAAQ,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM;AACtE,WAAO,QAAQ,IAAI,QAAQ,OAAO,IAAI,GAAG,GAAG,IAAI;AAAA,EAClD,GAAG,QAAQ,IAAI;AAEf,MAAI,OAAO;AAAA,IACT,KAAK,QAAQ;AAAA;AAAA,IACb,IAAI,OAAO;AAAA;AAAA,IACX;AAAA;AAAA,IACA,MAAM,SAAS;AAAA;AAAA,IACf,YAAY,OAAO;AAAA;AAAA,IACnB,OAAO,OAAO,MAAM,SAAS;AAAA;AAAA,IAC7B,OAAO,mBAAmB;AAAA;AAAA,EAC5B;AAEA,MAAI,QAAQ,OAAO;AACjB,YAAQ,OAAO,MAAM,IAAI;AAAA,EAC3B;AAEA,MAAI,OAAO,IAAI,KAAK,CAAC,IAAI,gBAAgB,IAAI,EAAE,SAAS,CAAC,GAAG;AAAA;AAAA,IAE1D,MAAM;AAAA,EACR,CAAC;AACD,MAAI,UAAU,YAAY;AACxB,cAAU,WAAW,WAAW,IAAI;AAAA,EACtC,OAAO;AACL,UAAM,WAAW;AAAA,MACf,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,aAAa;AAAA,MACb,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACF;AAEA,IAAI,eAAe;AACZ,SAAS,UAAU,SAAkB;AAC1C,MAAIA,YAAW,YAAY;AAC3B,MAAI,SAAS,UAAU;AAEvB,EAAM,gBAAU,MAAM;AACpB,KAAC,MAAM;AACL,UAAI,cAAc;AAChB;AAAA,MACF;AAEA,qBAAe;AAEf,UAAI,cAAc;AAAA,QAChB,GAAG;AAAA,QACH;AAAA,QACA,MAAMA,UAAS;AAAA,MACjB;AAEA,UAAI;AACF,cAAM,CAAC,WAAW,gBAAgB,QAAQ,WAAW,CAAC;AACtD,eAAO,CAAC,WAAW,gBAAgB,QAAQ,WAAW,CAAC;AACvD,cAAM,CAAC,WAAW,gBAAgB,QAAQ,WAAW,CAAC;AACtD,cAAM,CAAC,WAAW,gBAAgB,QAAQ,WAAW,CAAC;AACtD,cAAM,CAAC,WAAW,gBAAgB,QAAQ,WAAW,CAAC;AACtD,cAAM,CAAC,WAAW,gBAAgB,QAAQ,WAAW,CAAC;AAAA,MACxD,SAAS,OAAO;AACd,gBAAQ,KAAK;AAAA,MACf;AAAA,IACF,GAAG;AAAA,EACL,GAAG,CAACA,UAAS,MAAMA,UAAS,UAAUA,UAAS,QAAQ,SAAS,MAAM,CAAC;AAEvE,SAAO;AACT;AAEA,SAAS,qBAA6B;AAEpC,SAAO,gBAAgB,aACrB,UAAU,YAAY;AAAA,EAEtB,mBAAmB,UAAU,YAAY,IACvC,UAAU,YAAY,EAAE,eAAe,IACvC;AACN;AAEA,SAAS,QAAQ,OAAgB;AAC/B,UAAQ,MAAM,8BAA8B,KAAK;AACnD;AAEA,SAAS,QAAQ,UAAkB,MAAa;AAC9C,UAAQ,MAAM,OAAO,GAAG,IAAI;AAC9B","sourcesContent":["import * as React from \"react\";\nimport type { Metric } from \"web-vitals\";\nimport type { Params } from \"@remix-run/react\";\nimport { useLocation, useParams } from \"@remix-run/react\";\nimport { onCLS, onFCP, onFID, onLCP, onTTFB, onINP } from \"web-vitals\";\n\nlet vitalsUrl = \"https://vitals.vercel-analytics.com/v1/vitals\";\n\ntype Options = {\n  analyticsId: string;\n  debug?: boolean;\n};\n\ntype FullOptions = Options & {\n  params: Readonly<Params<string>>;\n  path: string;\n};\n\nfunction sendToAnalytics(metric: Metric, options: FullOptions) {\n  let page = Object.entries(options.params).reduce((acc, [key, value]) => {\n    return value ? acc.replace(value, `[${key}]`) : ``;\n  }, options.path);\n\n  let body = {\n    dsn: options.analyticsId, // qPgJqYH9LQX5o31Ormk8iWhCxZO\n    id: metric.id, // v2-1653884975443-1839479248192\n    page, // /blog/[slug]\n    href: location.href, // https://{my-example-app-name-here}/blog/my-test\n    event_name: metric.name, // TTFB\n    value: metric.value.toString(), // 60.20000000298023\n    speed: getConnectionSpeed(), // 4g\n  };\n\n  if (options.debug) {\n    onDebug(metric.name, body);\n  }\n\n  let blob = new Blob([new URLSearchParams(body).toString()], {\n    // This content type is necessary for `sendBeacon`\n    type: \"application/x-www-form-urlencoded\",\n  });\n  if (navigator.sendBeacon) {\n    navigator.sendBeacon(vitalsUrl, blob);\n  } else {\n    fetch(vitalsUrl, {\n      method: \"POST\",\n      body: blob,\n      credentials: \"omit\",\n      keepalive: true,\n    });\n  }\n}\n\nlet isRegistered = false;\nexport function WebVitals(options: Options) {\n  let location = useLocation();\n  let params = useParams();\n\n  React.useEffect(() => {\n    (() => {\n      if (isRegistered) {\n        return;\n      }\n\n      isRegistered = true;\n\n      let fullOptions = {\n        ...options,\n        params,\n        path: location.pathname,\n      } as const;\n\n      try {\n        onFID((metric) => sendToAnalytics(metric, fullOptions));\n        onTTFB((metric) => sendToAnalytics(metric, fullOptions));\n        onLCP((metric) => sendToAnalytics(metric, fullOptions));\n        onCLS((metric) => sendToAnalytics(metric, fullOptions));\n        onFCP((metric) => sendToAnalytics(metric, fullOptions));\n        onINP((metric) => sendToAnalytics(metric, fullOptions));\n      } catch (error) {\n        onError(error);\n      }\n    })();\n  }, [location.hash, location.pathname, location.search, options, params]);\n\n  return null;\n}\n\nfunction getConnectionSpeed(): string {\n  // @ts-expect-error\n  return \"connection\" in navigator &&\n    navigator[\"connection\"] &&\n    // @ts-expect-error\n    \"effectiveType\" in navigator[\"connection\"]\n    ? navigator[\"connection\"][\"effectiveType\"]\n    : \"\";\n}\n\nfunction onError(error: unknown) {\n  console.error(`[@mcansh/remix-web-vitals]`, error);\n}\n\nfunction onDebug(label: string, ...args: any[]) {\n  console.debug(label, ...args);\n}\n"]}