@diegotsi/flint-core 1.9.0 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +141 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -3
- package/dist/index.d.ts +31 -3
- package/dist/index.js +141 -21
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api.ts","../src/sanitize.ts","../src/collectors/console.ts","../src/collectors/environment.ts","../src/collectors/errorCapture.ts","../src/collectors/formErrors.ts","../src/collectors/frustration.ts","../src/collectors/network.ts","../src/store.ts","../src/singleton.ts","../src/theme.ts"],"sourcesContent":["import { gzipSync } from \"fflate\";\nimport type { ReportPayload, ReportResult } from \"./types.js\";\n\nasync function fetchWithRetry(url: string, init: RequestInit, retries = 3, baseDelay = 1000): Promise<Response> {\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n const res = await fetch(url, init);\n if (res.ok || attempt === retries) return res;\n // Don't retry client errors (4xx) except 429\n if (res.status >= 400 && res.status < 500 && res.status !== 429) return res;\n } catch (err) {\n if (attempt === retries) throw err;\n }\n await new Promise((r) => setTimeout(r, baseDelay * 2 ** attempt));\n }\n throw new Error(\"Max retries exceeded\");\n}\n\nexport async function submitReport(\n serverUrl: string,\n projectKey: string,\n payload: ReportPayload,\n screenshot?: File,\n): Promise<ReportResult> {\n const url = `${serverUrl.replace(/\\/$/, \"\")}/api/v1/bug-reports`;\n\n let body: BodyInit;\n const headers: Record<string, string> = {\n \"x-project-key\": projectKey,\n };\n\n if (screenshot) {\n const form = new FormData();\n form.append(\"reporterId\", payload.reporterId);\n form.append(\"reporterName\", payload.reporterName);\n if (payload.reporterEmail) form.append(\"reporterEmail\", payload.reporterEmail);\n if (payload.reporterExtraAttributes)\n form.append(\"reporterExtraAttributes\", JSON.stringify(payload.reporterExtraAttributes));\n form.append(\"description\", payload.description);\n if (payload.expectedBehavior) form.append(\"expectedBehavior\", payload.expectedBehavior);\n if (payload.stepsToReproduce) form.append(\"stepsToReproduce\", JSON.stringify(payload.stepsToReproduce));\n if (payload.externalReplayUrl) form.append(\"externalReplayUrl\", payload.externalReplayUrl);\n if (payload.additionalContext) form.append(\"additionalContext\", payload.additionalContext);\n form.append(\"severity\", payload.severity);\n if (payload.url) form.append(\"url\", payload.url);\n if (payload.meta) form.append(\"meta\", JSON.stringify(payload.meta));\n if (payload.appVersion) form.append(\"appVersion\", payload.appVersion);\n if (payload.release) form.append(\"release\", payload.release);\n form.append(\"screenshot\", screenshot);\n body = form;\n } else {\n body = JSON.stringify(payload);\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n const res = await fetchWithRetry(url, { method: \"POST\", headers, body });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({ error: \"Unknown error\" }));\n throw new Error((err as { error?: string }).error ?? `HTTP ${res.status}`);\n }\n\n return res.json() as Promise<ReportResult>;\n}\n\nexport async function submitReplay(\n serverUrl: string,\n projectKey: string,\n reportId: string,\n events: unknown[],\n): Promise<void> {\n const json = JSON.stringify(events);\n const encoded = new TextEncoder().encode(json);\n const compressed = gzipSync(encoded);\n\n const url = `${serverUrl.replace(/\\/$/, \"\")}/api/v1/bug-reports/${reportId}/replay`;\n await fetch(url, {\n method: \"POST\",\n headers: {\n \"x-project-key\": projectKey,\n \"Content-Type\": \"application/octet-stream\",\n },\n body: compressed.buffer as ArrayBuffer,\n });\n}\n","// Redact values that look like tokens, passwords, secrets, or API keys\nconst SENSITIVE_PATTERNS = [\n /(?:password|passwd|pwd|secret|token|api[_-]?key|access[_-]?key|authorization|bearer)\\s*[:=]\\s*[\"']?[^\\s\"',]{4,}/gi,\n /\\b(sk-[a-zA-Z0-9_-]{20,})\\b/g, // API keys (e.g. sk-ant-...)\n /\\b(ghp_[a-zA-Z0-9]{36,})\\b/g, // GitHub tokens\n /\\b(xoxb-[a-zA-Z0-9-]+)\\b/g, // Slack tokens\n /\\b(eyJ[a-zA-Z0-9_-]{10,}\\.[a-zA-Z0-9_-]{10,})\\b/g, // JWTs\n];\n\nexport function sanitize(str: string): string {\n let result = str;\n for (const pattern of SENSITIVE_PATTERNS) {\n result = result.replace(pattern, \"[REDACTED]\");\n }\n return result;\n}\n","import { sanitize } from \"../sanitize.js\";\nimport type { ConsoleEntry } from \"../types.js\";\n\nconst MAX_ENTRIES = 50;\n\nexport interface ConsoleCollector {\n start(): void;\n stop(): void;\n getEntries(): ConsoleEntry[];\n}\n\nexport function createConsoleCollector(): ConsoleCollector {\n const entries: ConsoleEntry[] = [];\n let active = false;\n\n const originals = {\n log: console.log.bind(console),\n warn: console.warn.bind(console),\n error: console.error.bind(console),\n };\n\n let origOnerror: typeof window.onerror = null;\n let origUnhandled: typeof window.onunhandledrejection = null;\n\n function push(level: ConsoleEntry[\"level\"], args: unknown[]) {\n let str: string;\n try {\n str = args.map((a) => (typeof a === \"string\" ? a : JSON.stringify(a))).join(\" \");\n } catch {\n str = String(args[0]);\n }\n if (str.length > 500) str = str.slice(0, 500) + \"\\u2026\";\n str = sanitize(str);\n entries.push({ level, args: str, timestamp: Date.now() });\n if (entries.length > MAX_ENTRIES) entries.shift();\n }\n\n return {\n start() {\n if (active) return;\n active = true;\n\n console.log = (...args: unknown[]) => {\n push(\"log\", args);\n originals.log(...args);\n };\n console.warn = (...args: unknown[]) => {\n push(\"warn\", args);\n originals.warn(...args);\n };\n console.error = (...args: unknown[]) => {\n push(\"error\", args);\n originals.error(...args);\n };\n\n origOnerror = window.onerror;\n window.onerror = (msg, src, line, col, err) => {\n push(\"error\", [err?.message ?? String(msg), `${src}:${line}:${col}`]);\n if (typeof origOnerror === \"function\") return origOnerror(msg, src, line, col, err);\n return false;\n };\n\n origUnhandled = window.onunhandledrejection;\n window.onunhandledrejection = (event) => {\n const reason = event.reason instanceof Error ? event.reason.message : JSON.stringify(event.reason);\n push(\"error\", [\"UnhandledRejection:\", reason]);\n if (typeof origUnhandled === \"function\") origUnhandled.call(window, event);\n };\n },\n\n stop() {\n if (!active) return;\n active = false;\n console.log = originals.log;\n console.warn = originals.warn;\n console.error = originals.error;\n window.onerror = origOnerror;\n window.onunhandledrejection = origUnhandled;\n },\n\n getEntries() {\n return [...entries];\n },\n };\n}\n","import type { EnvironmentInfo } from \"../types.js\";\n\nexport function collectEnvironment(): EnvironmentInfo {\n const ua = navigator.userAgent;\n\n // -- Browser --\n let browser = \"Unknown\";\n const chromeM = ua.match(/Chrome\\/(\\d+)/);\n const firefoxM = ua.match(/Firefox\\/(\\d+)/);\n const edgeM = ua.match(/Edg\\/(\\d+)/);\n const safariM = ua.match(/Version\\/(\\d+)/);\n const operaM = ua.match(/OPR\\/(\\d+)/);\n\n if (operaM) {\n browser = `Opera ${operaM[1]}`;\n } else if (edgeM) {\n browser = `Edge ${edgeM[1]}`;\n } else if (chromeM && !/Edg|OPR/.test(ua)) {\n browser = `Chrome ${chromeM[1]}`;\n } else if (firefoxM) {\n browser = `Firefox ${firefoxM[1]}`;\n } else if (safariM && /Safari\\//.test(ua)) {\n browser = `Safari ${safariM[1]}`;\n }\n\n // -- OS --\n let os = \"Unknown\";\n const macM = ua.match(/Mac OS X (\\d+[._]\\d+)/);\n const winM = ua.match(/Windows NT (\\d+\\.\\d+)/);\n const androidM = ua.match(/Android (\\d+)/);\n const iosM = ua.match(/iPhone OS (\\d+[._]\\d+)/);\n\n if (macM) {\n os = `macOS ${macM[1].replace(\"_\", \".\")}`;\n } else if (winM) {\n const winMap: Record<string, string> = {\n \"10.0\": \"10/11\",\n \"6.3\": \"8.1\",\n \"6.2\": \"8\",\n \"6.1\": \"7\",\n };\n os = `Windows ${winMap[winM[1]] ?? winM[1]}`;\n } else if (androidM) {\n os = `Android ${androidM[1]}`;\n } else if (iosM) {\n os = `iOS ${iosM[1].replace(/_/g, \".\")}`;\n } else if (/Linux/.test(ua)) {\n os = \"Linux\";\n }\n\n return {\n browser,\n os,\n viewport: `${window.innerWidth}x${window.innerHeight}`,\n screen: `${screen.width}x${screen.height}`,\n language: navigator.language,\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n online: navigator.onLine,\n };\n}\n","// Automatic error monitoring — captures uncaught errors and unhandled\n// rejections, batches them, and ships them to POST /api/v1/error-events.\n//\n// Grouping is server-authoritative: the local key computed here is used only\n// for client-side throttling and in-batch dedup, never as the grouping\n// fingerprint (so the grouping algorithm can evolve without an SDK redeploy).\nimport { sanitize } from \"../sanitize.js\";\nimport type { ConsoleEntry, EnvironmentInfo, ErrorEventPayload, FlintUser, NetworkEntry } from \"../types.js\";\n\nconst MAX_MESSAGE = 1000;\nconst MAX_STACK = 8000;\nconst MAX_BATCH = 20;\n// sendBeacon payloads are dropped silently above ~64KB — stay well under it\nconst MAX_PAYLOAD_BYTES = 60_000;\nconst PER_KEY_PER_MINUTE = 10;\nconst GLOBAL_PAGE_CAP = 100;\nconst FLUSH_INTERVAL_MS = 5_000;\nconst THROTTLE_WINDOW_MS = 60_000;\nconst BREADCRUMB_CONSOLE = 10;\nconst BREADCRUMB_NETWORK = 10;\n\n// Noise that is never actionable: benign browser warnings, cross-origin\n// \"Script error.\" (no stack, no message), and browser-extension code.\nconst DEFAULT_IGNORE = [/ResizeObserver loop/i, /^Script error\\.?$/];\nconst EXTENSION_URL = /(chrome|moz|safari|safari-web)-extension:\\/\\//;\n\nexport interface ErrorCaptureCollector {\n start(): void;\n stop(): void;\n /** Flush pending events immediately (also called on pagehide/interval). */\n flush(): void;\n}\n\nexport interface ErrorCaptureOptions {\n serverUrl: string;\n projectKey: string;\n release?: string;\n appVersion?: string;\n /** Fraction of captured errors to report, 0..1. Default 1.0 */\n sampleRate?: number;\n /** Errors whose message matches any entry are dropped (string = substring match) */\n ignoreErrors?: (string | RegExp)[];\n /** Mutate or drop (return null) an event before it is queued for sending */\n beforeSend?: (event: ErrorEventPayload) => ErrorEventPayload | null;\n getUser?: () => FlintUser | undefined;\n getBreadcrumbs?: () => { consoleLogs: ConsoleEntry[]; networkErrors: NetworkEntry[] };\n getEnvironment?: () => EnvironmentInfo;\n debug?: boolean;\n}\n\nfunction normalizeForKey(message: string): string {\n return message.toLowerCase().replace(/\\d+/g, \"#\").replace(/\\s+/g, \" \").trim().slice(0, 200);\n}\n\nfunction topFrame(stack: string | undefined): string {\n if (!stack) return \"\";\n const lines = stack.split(\"\\n\").map((l) => l.trim());\n return lines.find((l) => l.startsWith(\"at \") || /@/.test(l)) ?? \"\";\n}\n\nexport function createErrorCaptureCollector(options: ErrorCaptureOptions): ErrorCaptureCollector {\n const sampleRate = options.sampleRate ?? 1.0;\n const ignoreList = [...DEFAULT_IGNORE, ...(options.ignoreErrors ?? [])];\n const sessionId = `s_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 10)}`;\n\n let active = false;\n let queue: ErrorEventPayload[] = [];\n let interval: ReturnType<typeof setInterval> | null = null;\n let sentCount = 0;\n let environment: EnvironmentInfo | undefined;\n const keyTimestamps = new Map<string, number[]>();\n\n function debugLog(...args: unknown[]) {\n if (options.debug) console.log(\"[Flint]\", ...args);\n }\n\n function isIgnored(message: string, stack: string | undefined, frameUrl: string | undefined): boolean {\n for (const entry of ignoreList) {\n if (typeof entry === \"string\") {\n if (message.includes(entry)) return true;\n } else if (entry.test(message)) {\n return true;\n }\n }\n if (EXTENSION_URL.test(frameUrl ?? \"\") || EXTENSION_URL.test(stack ?? \"\")) return true;\n return false;\n }\n\n function isThrottled(localKey: string): boolean {\n const now = Date.now();\n const stamps = (keyTimestamps.get(localKey) ?? []).filter((t) => now - t < THROTTLE_WINDOW_MS);\n if (stamps.length >= PER_KEY_PER_MINUTE) {\n keyTimestamps.set(localKey, stamps);\n return true;\n }\n stamps.push(now);\n keyTimestamps.set(localKey, stamps);\n return false;\n }\n\n function capture(input: {\n type: \"error\" | \"unhandledrejection\";\n message: string;\n errorClass: string;\n stack?: string;\n frameUrl?: string;\n }) {\n try {\n if (sentCount + queue.length >= GLOBAL_PAGE_CAP) return;\n\n let message = input.message.slice(0, MAX_MESSAGE);\n if (isIgnored(message, input.stack, input.frameUrl)) return;\n if (sampleRate < 1 && Math.random() >= sampleRate) return;\n\n const localKey = `${input.type}|${normalizeForKey(message)}|${topFrame(input.stack)}`;\n if (isThrottled(localKey)) return;\n\n // In-batch dedup: identical errors before a flush become one event with a count\n const pending = queue.find((e) => e._localKey === localKey);\n if (pending) {\n pending.count += 1;\n return;\n }\n\n message = sanitize(message);\n const stack = input.stack ? sanitize(input.stack.slice(0, MAX_STACK)) : undefined;\n if (!environment && options.getEnvironment) {\n try {\n environment = options.getEnvironment();\n } catch {\n /* environment is best-effort */\n }\n }\n const user = options.getUser?.();\n\n let event: ErrorEventPayload = {\n type: input.type,\n message,\n errorClass: input.errorClass,\n stack,\n url: typeof location !== \"undefined\" ? location.href : \"\",\n timestamp: Date.now(),\n release: options.release,\n appVersion: options.appVersion,\n userId: user?.id,\n sessionId,\n browser: environment?.browser,\n os: environment?.os,\n count: 1,\n breadcrumbs: options.getBreadcrumbs\n ? {\n consoleLogs: options.getBreadcrumbs().consoleLogs.slice(-BREADCRUMB_CONSOLE),\n networkErrors: options.getBreadcrumbs().networkErrors.slice(-BREADCRUMB_NETWORK),\n }\n : undefined,\n _localKey: localKey,\n };\n\n if (options.beforeSend) {\n try {\n const result = options.beforeSend(event);\n if (!result) return;\n event = { ...result, _localKey: localKey };\n } catch {\n // beforeSend threw — keep the original event rather than losing it\n }\n }\n\n queue.push(event);\n debugLog(\"Error captured\", input.errorClass, message);\n if (queue.length >= MAX_BATCH) flush(false);\n } catch {\n // Never let the error monitor itself throw\n }\n }\n\n function serialize(events: ErrorEventPayload[]): string {\n const wire = events.map(({ _localKey, ...e }) => e);\n let body = JSON.stringify(wire);\n if (body.length > MAX_PAYLOAD_BYTES) {\n // Shed weight: breadcrumbs first, then stacks\n body = JSON.stringify(wire.map((e) => ({ ...e, breadcrumbs: undefined })));\n if (body.length > MAX_PAYLOAD_BYTES) {\n body = JSON.stringify(wire.map((e) => ({ ...e, breadcrumbs: undefined, stack: e.stack?.slice(0, 2000) })));\n }\n }\n return body;\n }\n\n function flush(unloading: boolean) {\n if (queue.length === 0) return;\n const events = queue;\n queue = [];\n sentCount += events.length;\n\n const base = options.serverUrl.replace(/\\/$/, \"\");\n // Query auth + text/plain body: sendBeacon can't set headers, and a JSON\n // content-type triggers a CORS preflight that drops beacons on unload.\n const url = `${base}/api/v1/error-events?project_key=${encodeURIComponent(options.projectKey)}`;\n const body = serialize(events);\n\n if (unloading && typeof navigator !== \"undefined\" && typeof navigator.sendBeacon === \"function\") {\n const ok = navigator.sendBeacon(url, body);\n debugLog(\"Flushed via beacon\", events.length, ok);\n if (ok) return;\n // Beacon refused (e.g. payload too large) — fall through to fetch\n }\n\n fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"text/plain;charset=UTF-8\" },\n body,\n keepalive: unloading,\n }).catch(() => {\n /* fire-and-forget */\n });\n debugLog(\"Flushed via fetch\", events.length);\n }\n\n function onError(event: Event) {\n // Resource load failures also dispatch \"error\" in the capture phase but\n // are not ErrorEvents — out of MVP scope (frustration.ts covers loops).\n const e = event as ErrorEvent;\n if (typeof e.message !== \"string\" && !(e.error instanceof Error)) return;\n const err = e.error instanceof Error ? e.error : undefined;\n capture({\n type: \"error\",\n message: err?.message ?? (e.message || \"Unknown error\"),\n errorClass: err?.name ?? \"Error\",\n stack: err?.stack,\n frameUrl: e.filename,\n });\n }\n\n function onRejection(event: Event) {\n const reason = (event as PromiseRejectionEvent).reason;\n const err = reason instanceof Error ? reason : undefined;\n let message: string;\n if (err) {\n message = err.message;\n } else {\n try {\n message = typeof reason === \"string\" ? reason : JSON.stringify(reason);\n } catch {\n message = String(reason);\n }\n }\n capture({\n type: \"unhandledrejection\",\n message: message || \"Unhandled promise rejection\",\n errorClass: err?.name ?? \"UnhandledRejection\",\n stack: err?.stack,\n });\n }\n\n function onPageHide() {\n flush(true);\n }\n\n function onVisibilityChange() {\n if (document.visibilityState === \"hidden\") flush(true);\n }\n\n return {\n start() {\n if (active) return;\n active = true;\n // capture-phase listeners coexist with console.ts, which *assigns*\n // window.onerror / onunhandledrejection\n window.addEventListener(\"error\", onError, { capture: true });\n window.addEventListener(\"unhandledrejection\", onRejection, { capture: true });\n window.addEventListener(\"pagehide\", onPageHide);\n document.addEventListener(\"visibilitychange\", onVisibilityChange);\n interval = setInterval(() => flush(false), FLUSH_INTERVAL_MS);\n },\n\n stop() {\n if (!active) return;\n active = false;\n window.removeEventListener(\"error\", onError, { capture: true });\n window.removeEventListener(\"unhandledrejection\", onRejection, { capture: true });\n window.removeEventListener(\"pagehide\", onPageHide);\n document.removeEventListener(\"visibilitychange\", onVisibilityChange);\n if (interval) clearInterval(interval);\n interval = null;\n flush(false);\n },\n\n flush() {\n flush(false);\n },\n };\n}\n","import type { FormErrorEntry, FormErrorField } from \"../types.js\";\n\nconst MAX_ENTRIES = 30;\n\n/**\n * Time to wait after a submit event before checking the DOM for error\n * indicators. RHF/zod validate asynchronously — 300ms covers most cases\n * while keeping the detection snappy.\n */\nconst POST_SUBMIT_CHECK_MS = 300;\n\n/**\n * After a submit button click, if no submit event fires within this window\n * it means the form library swallowed the submit entirely (e.g. RHF's\n * handleSubmit called preventDefault before the native event propagated,\n * or the button isn't even inside a <form>). We treat this as a potential\n * silent failure and scan the page for error indicators.\n */\nconst SILENT_SUBMIT_WINDOW_MS = 400;\n\nexport interface FormErrorCollector {\n start(): void;\n stop(): void;\n getEntries(): FormErrorEntry[];\n /**\n * Manually report a form validation failure. Call this from your form\n * library's error handler to capture exact field-level errors.\n *\n * @example\n * // React Hook Form + Zod\n * <form onSubmit={handleSubmit(onValid, (errors) => {\n * flint.reportFormError('checkout-form', errors);\n * })}>\n */\n report(formId: string, errors: Record<string, { message?: string } | undefined>): void;\n}\n\n// ── DOM helpers ────────────────────────────────────────────────────────────────\n\nfunction getFormId(form: HTMLFormElement): string {\n if (form.id) return `#${form.id}`;\n if (form.getAttribute(\"name\")) return `form[name=\"${form.getAttribute(\"name\")}\"]`;\n if (form.action && form.action !== location.href) return form.action;\n return `form:${Array.from(document.forms).indexOf(form)}`;\n}\n\nfunction getFieldLabel(field: HTMLElement, root: HTMLElement): string {\n const ariaLabel = field.getAttribute(\"aria-label\");\n if (ariaLabel) return ariaLabel;\n\n const id = field.id;\n if (id) {\n const label = root.querySelector<HTMLLabelElement>(`label[for=\"${id}\"]`);\n if (label?.textContent) return label.textContent.trim();\n }\n\n const parentLabel = field.closest(\"label\");\n if (parentLabel?.textContent) {\n const text = parentLabel.textContent.trim();\n if (text.length < 60) return text;\n }\n\n return (field as HTMLInputElement).name || (field as HTMLInputElement).placeholder || field.tagName.toLowerCase();\n}\n\nfunction getErrorMessage(field: HTMLElement): string | undefined {\n // aria-errormessage\n const errId = field.getAttribute(\"aria-errormessage\");\n if (errId) {\n const el = document.getElementById(errId);\n if (el?.textContent) return el.textContent.trim();\n }\n\n // aria-describedby (RHF wires error messages here)\n const descId = field.getAttribute(\"aria-describedby\");\n if (descId) {\n for (const id of descId.split(/\\s+/)) {\n const el = document.getElementById(id);\n if (el?.textContent?.trim()) return el.textContent.trim();\n }\n }\n\n // native validationMessage\n if (field instanceof HTMLInputElement || field instanceof HTMLTextAreaElement || field instanceof HTMLSelectElement) {\n if (field.validationMessage) return field.validationMessage;\n }\n\n // adjacent role=\"alert\"\n const next = field.nextElementSibling;\n if (next?.getAttribute(\"role\") === \"alert\" && next.textContent) {\n return next.textContent.trim();\n }\n\n return undefined;\n}\n\n/**\n * Collect fields with `aria-invalid=\"true\"` or native `:invalid` inside a\n * root element (a <form> or the whole document).\n */\nfunction collectInvalidFields(root: HTMLElement): FormErrorField[] {\n const fields: FormErrorField[] = [];\n const invalidEls = root.querySelectorAll<HTMLElement>('[aria-invalid=\"true\"], :invalid');\n\n for (const el of invalidEls) {\n if (el instanceof HTMLFormElement) continue;\n if (el.tagName === \"FIELDSET\") continue;\n\n fields.push({\n name: getFieldLabel(el, root),\n message: getErrorMessage(el),\n });\n }\n\n return fields;\n}\n\n/**\n * Scan the page for visible error indicators that appeared after a submit\n * attempt. This catches errors even when:\n * - The errored field is in another tab/step of a multi-step form\n * - The form doesn't use aria-invalid at all\n * - Errors are rendered as standalone alert divs\n */\nfunction collectVisibleErrors(root: HTMLElement): FormErrorField[] {\n const fields: FormErrorField[] = [];\n const seen = new Set<string>();\n\n // 1. role=\"alert\" elements that appeared (error toasts, inline messages)\n const alerts = root.querySelectorAll<HTMLElement>('[role=\"alert\"]');\n for (const el of alerts) {\n const text = el.textContent?.trim();\n if (!text || text.length > 200) continue;\n if (seen.has(text)) continue;\n seen.add(text);\n fields.push({ name: \"alert\", message: text });\n }\n\n // 2. Common error class patterns (data-error, .error, .field-error, etc.)\n const errorEls = root.querySelectorAll<HTMLElement>(\n \"[data-error], [data-field-error], .error-message, .field-error, .form-error\",\n );\n for (const el of errorEls) {\n const text = el.textContent?.trim();\n if (!text || text.length > 200) continue;\n if (seen.has(text)) continue;\n seen.add(text);\n fields.push({ name: \"error\", message: text });\n }\n\n return fields;\n}\n\nfunction isSubmitButton(el: HTMLElement): el is HTMLButtonElement {\n if (el.tagName === \"BUTTON\") {\n const type = el.getAttribute(\"type\");\n // Buttons default to type=\"submit\" inside forms when no type is set\n return type === \"submit\" || type === null || type === \"\";\n }\n if (el.tagName === \"INPUT\") {\n return (el as HTMLInputElement).type === \"submit\";\n }\n return false;\n}\n\nfunction findClosestForm(el: HTMLElement): HTMLFormElement | null {\n // Direct form association\n if (\"form\" in el && (el as HTMLButtonElement).form) {\n return (el as HTMLButtonElement).form;\n }\n return el.closest(\"form\");\n}\n\n// ── Collector ──────────────────────────────────────────────────────────────────\n\nexport function createFormErrorCollector(): FormErrorCollector {\n const entries: FormErrorEntry[] = [];\n const attemptCounts = new Map<string, number>();\n let active = false;\n\n // Handlers we need to clean up\n let submitHandler: ((e: Event) => void) | null = null;\n let invalidHandler: ((e: Event) => void) | null = null;\n let clickHandler: ((e: MouseEvent) => void) | null = null;\n\n // Track whether a real submit event followed a button click\n let lastSubmitTime = 0;\n\n // Dedup: avoid recording the same form twice within a short window\n const recentRecords = new Map<string, number>();\n const DEDUP_MS = 500;\n\n function push(entry: FormErrorEntry) {\n // Dedup check\n const _key = `${entry.formId}:${entry.timestamp}`;\n const last = recentRecords.get(entry.formId);\n if (last && entry.timestamp - last < DEDUP_MS) return;\n recentRecords.set(entry.formId, entry.timestamp);\n\n entries.push(entry);\n if (entries.length > MAX_ENTRIES) entries.shift();\n }\n\n function recordFormErrors(form: HTMLFormElement, type: FormErrorEntry[\"type\"]) {\n const formId = getFormId(form);\n\n // Strategy 1: aria-invalid / :invalid fields\n let fields = collectInvalidFields(form);\n\n // Strategy 2: if no aria-invalid fields found, look for visible error messages\n if (fields.length === 0) {\n fields = collectVisibleErrors(form);\n }\n\n if (fields.length === 0) return;\n\n const count = (attemptCounts.get(formId) ?? 0) + 1;\n attemptCounts.set(formId, count);\n\n push({\n type,\n formId,\n fields,\n attemptNumber: count,\n url: location.href,\n timestamp: Date.now(),\n });\n }\n\n /**\n * Handle clicks on submit buttons. If no submit event follows within\n * SILENT_SUBMIT_WINDOW_MS, it means the form library blocked the submit\n * entirely — scan for errors.\n */\n function handleSubmitButtonClick(button: HTMLElement) {\n const form = findClosestForm(button);\n\n setTimeout(() => {\n if (!active) return;\n // A real submit event fired — the submitHandler already took care of it\n if (Date.now() - lastSubmitTime < SILENT_SUBMIT_WINDOW_MS) return;\n\n // No submit event → silent failure\n const root = form ?? (document.body as HTMLElement);\n const formId = form ? getFormId(form) : `page:${location.pathname}`;\n\n let fields = form ? collectInvalidFields(form) : [];\n if (fields.length === 0) {\n fields = collectVisibleErrors(root);\n }\n\n // Also scan full page — the error might be in a toast or outside the form\n if (fields.length === 0 && form) {\n fields = collectVisibleErrors(document.body);\n }\n\n if (fields.length === 0) return;\n\n const count = (attemptCounts.get(formId) ?? 0) + 1;\n attemptCounts.set(formId, count);\n\n push({\n type: \"silent_submit\",\n formId,\n fields,\n attemptNumber: count,\n url: location.href,\n timestamp: Date.now(),\n });\n }, SILENT_SUBMIT_WINDOW_MS);\n }\n\n return {\n start() {\n if (active) return;\n active = true;\n\n // 1. Capture submit events (fires even with e.preventDefault())\n submitHandler = (e: Event) => {\n lastSubmitTime = Date.now();\n const form = e.target as HTMLFormElement;\n if (!(form instanceof HTMLFormElement)) return;\n\n setTimeout(() => {\n if (!active) return;\n recordFormErrors(form, \"validation_failed\");\n }, POST_SUBMIT_CHECK_MS);\n };\n document.addEventListener(\"submit\", submitHandler, true);\n\n // 2. Capture native invalid events (HTML5 constraint validation)\n invalidHandler = (e: Event) => {\n lastSubmitTime = Date.now();\n const field = e.target as HTMLElement;\n const form = field.closest(\"form\");\n if (!form) return;\n\n setTimeout(() => {\n if (!active) return;\n recordFormErrors(form, \"validation_failed\");\n }, POST_SUBMIT_CHECK_MS);\n };\n document.addEventListener(\"invalid\", invalidHandler, true);\n\n // 3. Capture clicks on submit buttons — catches silent failures\n // where the form lib eats the submit and shows nothing\n clickHandler = (e: MouseEvent) => {\n const target = e.target as HTMLElement;\n if (!target) return;\n\n // Walk up to find the actual button (click might be on an icon/span inside)\n const button = target.closest(\"button, input[type=submit]\") as HTMLElement | null;\n if (!button) return;\n if (!isSubmitButton(button)) return;\n\n handleSubmitButtonClick(button);\n };\n document.addEventListener(\"click\", clickHandler, true);\n },\n\n stop() {\n if (!active) return;\n active = false;\n if (submitHandler) document.removeEventListener(\"submit\", submitHandler, true);\n if (invalidHandler) document.removeEventListener(\"invalid\", invalidHandler, true);\n if (clickHandler) document.removeEventListener(\"click\", clickHandler, true);\n attemptCounts.clear();\n recentRecords.clear();\n },\n\n getEntries() {\n return [...entries];\n },\n\n report(formId: string, errors: Record<string, { message?: string } | undefined>) {\n const fields: FormErrorField[] = [];\n for (const [name, err] of Object.entries(errors)) {\n if (!err) continue;\n fields.push({ name, message: err.message });\n }\n if (fields.length === 0) return;\n\n const count = (attemptCounts.get(formId) ?? 0) + 1;\n attemptCounts.set(formId, count);\n\n push({\n type: \"validation_failed\",\n formId,\n fields,\n attemptNumber: count,\n url: location.href,\n timestamp: Date.now(),\n });\n },\n };\n}\n","export interface FrustrationEvent {\n type: \"rage_click\" | \"dead_click\" | \"error_loop\";\n timestamp: number;\n target: string;\n details: string;\n url: string;\n}\n\nexport interface FrustrationCollector {\n start(): void;\n stop(): void;\n getEvents(): FrustrationEvent[];\n onFrustration(callback: (event: FrustrationEvent) => void): () => void;\n}\n\nexport function createFrustrationCollector(opts?: {\n rageClickThreshold?: number;\n rageClickWindow?: number;\n errorLoopThreshold?: number;\n errorLoopWindow?: number;\n enableDeadClicks?: boolean;\n}): FrustrationCollector {\n const threshold = opts?.rageClickThreshold ?? 3;\n const window = opts?.rageClickWindow ?? 500;\n const errorThreshold = opts?.errorLoopThreshold ?? 3;\n const errorWindow = opts?.errorLoopWindow ?? 30_000;\n const deadClicksEnabled = opts?.enableDeadClicks ?? true;\n\n const events: FrustrationEvent[] = [];\n const listeners = new Set<(event: FrustrationEvent) => void>();\n const clickHistory: { target: EventTarget | null; time: number }[] = [];\n const errorCounts = new Map<string, { count: number; firstSeen: number }>();\n let clickHandler: ((e: MouseEvent) => void) | null = null;\n let origConsoleError: typeof console.error | null = null;\n\n function emit(event: FrustrationEvent) {\n events.push(event);\n if (events.length > 50) events.shift();\n for (const cb of listeners) cb(event);\n }\n\n function getCSSSelector(el: Element): string {\n if (el.id) return `#${el.id}`;\n const tag = el.tagName.toLowerCase();\n const cls = [...el.classList].slice(0, 3).join(\".\");\n if (cls) return `${tag}.${cls}`;\n return tag;\n }\n\n function isInteractive(el: HTMLElement): boolean {\n const tag = el.tagName.toLowerCase();\n if ([\"a\", \"button\", \"input\", \"select\", \"textarea\", \"label\", \"summary\"].includes(tag)) return true;\n if (el.getAttribute(\"role\") === \"button\" || el.getAttribute(\"tabindex\")) return true;\n if (el.onclick || el.getAttribute(\"onclick\")) return true;\n if (el.closest(\"a, button, [role=button], [onclick]\")) return true;\n try {\n if (getComputedStyle(el).cursor === \"pointer\") return true;\n } catch {\n /* getComputedStyle may throw */\n }\n return false;\n }\n\n function handleClick(e: MouseEvent) {\n const target = e.target as HTMLElement;\n if (!target) return;\n const now = Date.now();\n\n // --- Rage click detection ---\n clickHistory.push({ target, time: now });\n // Remove old clicks\n while (clickHistory.length > 0 && now - clickHistory[0].time > 1000) {\n clickHistory.shift();\n }\n const recentOnSame = clickHistory.filter((c) => c.target === target && now - c.time < window);\n if (recentOnSame.length >= threshold) {\n emit({\n type: \"rage_click\",\n timestamp: now,\n target: getCSSSelector(target),\n details: `${recentOnSame.length} clicks in ${now - recentOnSame[0].time}ms`,\n url: globalThis.location?.href ?? \"\",\n });\n clickHistory.length = 0;\n }\n\n // --- Dead click detection ---\n if (deadClicksEnabled && !isInteractive(target)) {\n emit({\n type: \"dead_click\",\n timestamp: now,\n target: getCSSSelector(target),\n details: `Click on non-interactive <${target.tagName.toLowerCase()}>`,\n url: globalThis.location?.href ?? \"\",\n });\n }\n }\n\n function patchConsoleError() {\n origConsoleError = console.error;\n console.error = (...args: unknown[]) => {\n origConsoleError?.apply(console, args);\n // Check for error loop\n const key = String(args[0]).slice(0, 100);\n const now = Date.now();\n const existing = errorCounts.get(key);\n if (existing && now - existing.firstSeen < errorWindow) {\n existing.count++;\n if (existing.count >= errorThreshold) {\n emit({\n type: \"error_loop\",\n timestamp: now,\n target: \"console\",\n details: `Same error ${existing.count}x in ${Math.round((now - existing.firstSeen) / 1000)}s: ${key}`,\n url: globalThis.location?.href ?? \"\",\n });\n errorCounts.delete(key);\n }\n } else {\n errorCounts.set(key, { count: 1, firstSeen: now });\n }\n };\n }\n\n return {\n start() {\n clickHandler = handleClick;\n document.addEventListener(\"click\", clickHandler, true);\n patchConsoleError();\n },\n stop() {\n if (clickHandler) document.removeEventListener(\"click\", clickHandler, true);\n if (origConsoleError) console.error = origConsoleError;\n clickHistory.length = 0;\n errorCounts.clear();\n },\n getEvents() {\n return [...events];\n },\n onFrustration(callback) {\n listeners.add(callback);\n return () => listeners.delete(callback);\n },\n };\n}\n","import type { NetworkEntry } from \"../types.js\";\n\nconst MAX_ENTRIES = 50;\nconst MAX_FULL_URL = 2000;\nconst MAX_REQUEST_BODY = 2048;\nconst MAX_RESPONSE_BODY = 4096;\nconst MAX_HEADERS = 30;\nconst REDACTED_HEADERS = new Set([\"authorization\", \"cookie\", \"set-cookie\", \"x-api-key\"]);\n\n// Well-known third-party domains to always ignore\nconst DEFAULT_BLOCKED_HOSTS = [\n \"browser-intake-datadoghq.com\",\n \"datadoghq.com\",\n \"datadoghq.eu\",\n \"google.com\",\n \"googleapis.com\",\n \"google-analytics.com\",\n \"googletagmanager.com\",\n \"gstatic.com\",\n \"doubleclick.net\",\n \"facebook.com\",\n \"facebook.net\",\n \"hotjar.com\",\n \"hotjar.io\",\n \"intercom.io\",\n \"intercomcdn.com\",\n \"segment.io\",\n \"segment.com\",\n \"mixpanel.com\",\n \"amplitude.com\",\n \"sentry.io\",\n \"fullstory.com\",\n \"clarity.ms\",\n \"newrelic.com\",\n \"nr-data.net\",\n \"cloudflareinsights.com\",\n \"heapanalytics.com\",\n \"posthog.com\",\n \"logrocket.io\",\n \"lr-in-prod.com\",\n \"crowdin.net\",\n \"crowdin.com\",\n];\n\n// Static asset extensions to ignore\nconst ASSET_EXTENSIONS = new Set([\n \".woff\",\n \".woff2\",\n \".ttf\",\n \".otf\",\n \".eot\", // fonts\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".gif\",\n \".svg\",\n \".webp\",\n \".ico\",\n \".avif\", // images\n \".css\",\n \".map\", // styles & source maps\n \".js\",\n \".mjs\", // scripts (usually loaded by browser, not app logic)\n \".mp3\",\n \".mp4\",\n \".webm\",\n \".ogg\", // media\n]);\n\nfunction isAssetUrl(url: string): boolean {\n try {\n const pathname = new URL(url, location.href).pathname;\n const ext = pathname.slice(pathname.lastIndexOf(\".\")).toLowerCase();\n return ASSET_EXTENSIONS.has(ext);\n } catch {\n return false;\n }\n}\n\nfunction isBlockedUrl(url: string, blocked: Set<string>): boolean {\n try {\n const host = new URL(url, location.href).hostname;\n return [...blocked].some((b) => host === b || host.endsWith(\".\" + b));\n } catch {\n return false;\n }\n}\n\nfunction shouldIgnore(url: string, blocked: Set<string>): boolean {\n return isBlockedUrl(url, blocked) || isAssetUrl(url);\n}\n\nexport interface NetworkCollector {\n start(): void;\n stop(): void;\n getEntries(): NetworkEntry[];\n}\n\nfunction truncateUrl(url: string): string {\n try {\n const u = new URL(url, location.href);\n const base = `${u.origin}${u.pathname}`;\n return base.length > 200 ? base.slice(0, 200) + \"\\u2026\" : base;\n } catch {\n return url.length > 200 ? url.slice(0, 200) + \"\\u2026\" : url;\n }\n}\n\nfunction captureFullUrl(url: string): string {\n return url.length > MAX_FULL_URL ? url.slice(0, MAX_FULL_URL) + \"\\u2026\" : url;\n}\n\nfunction safeBodyPreview(body: unknown, max: number): string | undefined {\n try {\n if (body == null) return undefined;\n if (typeof body === \"string\") return body.length > max ? body.slice(0, max) + \"\\u2026\" : body;\n if (typeof URLSearchParams !== \"undefined\" && body instanceof URLSearchParams) {\n const s = body.toString();\n return s.length > max ? s.slice(0, max) + \"\\u2026\" : s;\n }\n if (typeof FormData !== \"undefined\" && body instanceof FormData) {\n const keys: string[] = [];\n body.forEach((_, k) => keys.push(k));\n return `FormData { ${keys.join(\", \")} }`;\n }\n if (typeof Blob !== \"undefined\" && body instanceof Blob)\n return `[Blob ${body.type || \"unknown\"}, ${body.size} bytes]`;\n if (typeof ArrayBuffer !== \"undefined\" && body instanceof ArrayBuffer)\n return `[ArrayBuffer ${body.byteLength} bytes]`;\n } catch {\n /* ignore */\n }\n return undefined;\n}\n\nfunction captureHeaders(\n raw: HeadersInit | Headers | string | undefined | null,\n max: number,\n): Record<string, string> | undefined {\n if (!raw) return undefined;\n try {\n const result: Record<string, string> = {};\n let count = 0;\n let total = 0;\n\n if (typeof raw === \"string\") {\n // XHR getAllResponseHeaders() format: \"key: value\\r\\n\"\n for (const line of raw.split(/\\r?\\n/)) {\n if (!line) continue;\n total++;\n if (count >= max) continue;\n const idx = line.indexOf(\":\");\n if (idx === -1) continue;\n const key = line.slice(0, idx).trim().toLowerCase();\n const val = REDACTED_HEADERS.has(key) ? \"[REDACTED]\" : line.slice(idx + 1).trim();\n result[key] = val;\n count++;\n }\n } else {\n const entries: Iterable<[string, string]> =\n typeof Headers !== \"undefined\" && raw instanceof Headers\n ? raw.entries()\n : Array.isArray(raw)\n ? raw\n : Object.entries(raw as Record<string, string>);\n for (const [k, v] of entries) {\n total++;\n if (count >= max) continue;\n const key = k.toLowerCase();\n result[key] = REDACTED_HEADERS.has(key) ? \"[REDACTED]\" : v;\n count++;\n }\n }\n\n if (total > max) result[\"...truncated\"] = `${total - max} more`;\n return count > 0 ? result : undefined;\n } catch {\n /* ignore */\n }\n return undefined;\n}\n\nfunction extractContentType(headers: HeadersInit | undefined | null): string | undefined {\n if (!headers) return undefined;\n try {\n if (typeof Headers !== \"undefined\" && headers instanceof Headers) return headers.get(\"content-type\") ?? undefined;\n if (Array.isArray(headers)) {\n const found = headers.find(([k]) => k.toLowerCase() === \"content-type\");\n return found?.[1];\n }\n const rec = headers as Record<string, string>;\n for (const k of Object.keys(rec)) {\n if (k.toLowerCase() === \"content-type\") return rec[k];\n }\n } catch {\n /* ignore */\n }\n return undefined;\n}\n\nexport function createNetworkCollector(extraBlockedHosts: string[] = []): NetworkCollector {\n const entries: NetworkEntry[] = [];\n const blocked = new Set([...DEFAULT_BLOCKED_HOSTS, ...extraBlockedHosts]);\n let origFetch: typeof window.fetch | null = null;\n let origXHROpen: typeof XMLHttpRequest.prototype.open | null = null;\n let origXHRSend: typeof XMLHttpRequest.prototype.send | null = null;\n let origXHRSetHeader: typeof XMLHttpRequest.prototype.setRequestHeader | null = null;\n let active = false;\n\n function push(entry: NetworkEntry) {\n entries.push(entry);\n if (entries.length > MAX_ENTRIES) entries.shift();\n }\n\n return {\n start() {\n if (active) return;\n active = true;\n\n // -- Patch fetch --\n origFetch = window.fetch;\n window.fetch = async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n const method = ((init?.method ?? \"GET\") as string).toUpperCase();\n const url = typeof input === \"string\" ? input : input instanceof URL ? input.href : (input as Request).url;\n const startTime = Date.now();\n const reqBody = safeBodyPreview(init?.body, MAX_REQUEST_BODY);\n const reqHeaders = captureHeaders(init?.headers, MAX_HEADERS);\n const reqContentType = extractContentType(init?.headers);\n\n const res = await origFetch!.call(window, input, init);\n if (!shouldIgnore(url, blocked)) {\n const entry: NetworkEntry = {\n method,\n url: truncateUrl(url),\n fullUrl: captureFullUrl(url),\n status: res.status,\n duration: Date.now() - startTime,\n timestamp: startTime,\n requestHeaders: reqHeaders,\n requestBody: reqBody,\n requestContentType: reqContentType,\n responseContentType: res.headers.get(\"content-type\") ?? undefined,\n responseSize: parseInt(res.headers.get(\"content-length\") || \"0\", 10) || undefined,\n responseHeaders: captureHeaders(res.headers, MAX_HEADERS),\n };\n // Non-blocking: read response body from clone\n try {\n const clone = res.clone();\n clone\n .text()\n .then((text) => {\n entry.responseBody =\n text.length > MAX_RESPONSE_BODY ? text.slice(0, MAX_RESPONSE_BODY) + \"\\u2026\" : text;\n if (!entry.responseSize && text.length) entry.responseSize = text.length;\n })\n .catch(() => {});\n } catch {\n /* ignore */\n }\n push(entry);\n }\n return res;\n };\n\n // -- Patch XHR --\n const xhrMeta = new WeakMap<\n XMLHttpRequest,\n { reqBody?: string; reqHeaders: Record<string, string>; reqContentType?: string }\n >();\n\n origXHROpen = XMLHttpRequest.prototype.open;\n origXHRSend = XMLHttpRequest.prototype.send;\n origXHRSetHeader = XMLHttpRequest.prototype.setRequestHeader;\n\n XMLHttpRequest.prototype.setRequestHeader = function (name: string, value: string) {\n let meta = xhrMeta.get(this);\n if (!meta) {\n meta = { reqHeaders: {} };\n xhrMeta.set(this, meta);\n }\n const key = name.toLowerCase();\n meta.reqHeaders[key] = REDACTED_HEADERS.has(key) ? \"[REDACTED]\" : value;\n if (key === \"content-type\") meta.reqContentType = value;\n return origXHRSetHeader!.call(this, name, value);\n };\n\n XMLHttpRequest.prototype.send = function (body?: Document | XMLHttpRequestBodyInit | null) {\n let meta = xhrMeta.get(this);\n if (!meta) {\n meta = { reqHeaders: {} };\n xhrMeta.set(this, meta);\n }\n meta.reqBody = safeBodyPreview(body, MAX_REQUEST_BODY);\n return origXHRSend!.call(this, body);\n };\n\n XMLHttpRequest.prototype.open = function (\n method: string,\n url: string | URL,\n async?: boolean,\n username?: string | null,\n password?: string | null,\n ) {\n const startTime = Date.now();\n const urlStr = typeof url === \"string\" ? url : (url as URL).href;\n\n this.addEventListener(\"load\", () => {\n if (!shouldIgnore(urlStr, blocked)) {\n const meta = xhrMeta.get(this);\n let resBody: string | undefined;\n try {\n const text = this.responseText;\n resBody =\n text && text.length > MAX_RESPONSE_BODY\n ? text.slice(0, MAX_RESPONSE_BODY) + \"\\u2026\"\n : text || undefined;\n } catch {\n /* ignore */\n }\n push({\n method: method.toUpperCase(),\n url: truncateUrl(urlStr),\n fullUrl: captureFullUrl(urlStr),\n status: this.status,\n duration: Date.now() - startTime,\n timestamp: startTime,\n requestHeaders: meta?.reqHeaders && Object.keys(meta.reqHeaders).length > 0 ? meta.reqHeaders : undefined,\n requestBody: meta?.reqBody,\n requestContentType: meta?.reqContentType,\n responseHeaders: captureHeaders(this.getAllResponseHeaders(), MAX_HEADERS),\n responseBody: resBody,\n responseContentType: this.getResponseHeader(\"content-type\") ?? undefined,\n responseSize: resBody ? resBody.length : undefined,\n });\n }\n });\n\n return origXHROpen!.apply(this, [method, url, async ?? true, username, password] as Parameters<\n typeof XMLHttpRequest.prototype.open\n >);\n };\n },\n\n stop() {\n if (!active) return;\n active = false;\n if (origFetch) window.fetch = origFetch;\n if (origXHROpen) XMLHttpRequest.prototype.open = origXHROpen;\n if (origXHRSend) XMLHttpRequest.prototype.send = origXHRSend;\n if (origXHRSetHeader) XMLHttpRequest.prototype.setRequestHeader = origXHRSetHeader;\n },\n\n getEntries() {\n return [...entries];\n },\n };\n}\n","import type { FormErrorCollector } from \"./collectors/formErrors.js\";\nimport type { FlintUser } from \"./types.js\";\n\nexport interface FlintState {\n user: FlintUser | undefined;\n sessionReplay: string | (() => string) | undefined;\n}\n\n// Holds a reference to the active form error collector so flint.reportFormError\n// can forward calls without the consumer needing to manage the collector.\nlet formErrorCollectorRef: FormErrorCollector | null = null;\n\nexport function _setFormErrorCollector(collector: FormErrorCollector | null) {\n formErrorCollectorRef = collector;\n}\n\nlet state: FlintState = { user: undefined, sessionReplay: undefined };\nconst listeners = new Set<() => void>();\n\nfunction emit() {\n for (const l of listeners) l();\n}\n\nexport function subscribe(listener: () => void) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n}\n\nexport function getSnapshot(): FlintState {\n return state;\n}\n\n/** @internal Use Flint.setUser() / Flint.setSessionReplay() / Flint.reportFormError() instead */\nexport const flint = {\n setUser(user: FlintUser | null) {\n state = { ...state, user: user ?? undefined };\n emit();\n },\n setSessionReplay(url: string | (() => string) | null) {\n state = { ...state, sessionReplay: url ?? undefined };\n emit();\n },\n\n /**\n * Report a form validation failure with exact field-level errors.\n * Call this from your form library's error callback.\n *\n * @example\n * // React Hook Form + Zod\n * const onSubmit = handleSubmit(onValid, (errors) => {\n * flint.reportFormError('checkout-form', errors);\n * });\n */\n reportFormError(formId: string, errors: Record<string, { message?: string } | undefined>) {\n formErrorCollectorRef?.report(formId, errors);\n },\n};\n","// Flint singleton — manages global collector lifecycle\nimport { submitReport } from \"./api.js\";\nimport type { ConsoleCollector } from \"./collectors/console.js\";\nimport { createConsoleCollector } from \"./collectors/console.js\";\nimport { collectEnvironment } from \"./collectors/environment.js\";\nimport type { ErrorCaptureCollector } from \"./collectors/errorCapture.js\";\nimport { createErrorCaptureCollector } from \"./collectors/errorCapture.js\";\nimport type { FormErrorCollector } from \"./collectors/formErrors.js\";\nimport { createFormErrorCollector } from \"./collectors/formErrors.js\";\nimport type { FrustrationCollector } from \"./collectors/frustration.js\";\nimport { createFrustrationCollector } from \"./collectors/frustration.js\";\nimport type { NetworkCollector } from \"./collectors/network.js\";\nimport { createNetworkCollector } from \"./collectors/network.js\";\nimport { _setFormErrorCollector, flint, getSnapshot } from \"./store.js\";\nimport type { CollectedMeta, FlintConfig } from \"./types.js\";\n\nconst DEFAULT_REPLAY_BUFFER_MS = 60_000;\n\ninterface FlintInstance {\n config: FlintConfig;\n console: ConsoleCollector | null;\n network: NetworkCollector | null;\n formErrors: FormErrorCollector | null;\n frustration: FrustrationCollector | null;\n errorCapture: ErrorCaptureCollector | null;\n replayEvents: unknown[];\n stopReplay: (() => void) | null;\n}\n\nlet instance: FlintInstance | null = null;\n\nfunction debugLog(config: FlintConfig, ...args: unknown[]) {\n if (config.debug) console.log(\"[Flint]\", ...args);\n}\n\nfunction init(config: FlintConfig): void {\n if (instance) {\n console.warn(\"[Flint] Already initialized. Call Flint.shutdown() first to re-initialize.\");\n return;\n }\n\n const {\n enableConsole = true,\n enableNetwork = true,\n enableFormErrors = true,\n enableFrustration = false,\n autoReportFrustration = false,\n enableErrorMonitoring = true,\n errorMonitoring: errorMonitoringOpts,\n enableReplay = false,\n replayBufferMs = DEFAULT_REPLAY_BUFFER_MS,\n blockedHosts = [],\n frustration: frustrationOpts,\n onFrustration,\n _replayRecorder,\n _collectors,\n } = config;\n\n debugLog(config, \"Initializing\", {\n serverUrl: config.serverUrl,\n enableConsole,\n enableNetwork,\n enableFormErrors,\n enableFrustration,\n enableReplay,\n });\n\n // Determine Flint server host to block from network capture\n const flintHost = (() => {\n try {\n return new URL(config.serverUrl).hostname;\n } catch {\n return \"\";\n }\n })();\n\n const allBlockedHosts = [...blockedHosts, ...(flintHost ? [flintHost] : [])];\n\n // Create and start collectors (use injected factories if provided, e.g. React Native)\n const consoleCol = enableConsole ? (_collectors?.console?.() ?? createConsoleCollector()) : null;\n consoleCol?.start();\n\n const networkCol = enableNetwork\n ? (_collectors?.network?.(allBlockedHosts) ?? createNetworkCollector(allBlockedHosts))\n : null;\n networkCol?.start();\n\n const formErrorsCol = enableFormErrors ? createFormErrorCollector() : null;\n if (formErrorsCol) {\n formErrorsCol.start();\n _setFormErrorCollector(formErrorsCol);\n }\n\n const frustrationCol = enableFrustration ? createFrustrationCollector(frustrationOpts) : null;\n frustrationCol?.start();\n\n const errorCaptureCol = enableErrorMonitoring\n ? createErrorCaptureCollector({\n serverUrl: config.serverUrl,\n projectKey: config.projectKey,\n release: config.release,\n appVersion: config.appVersion,\n debug: config.debug,\n sampleRate: errorMonitoringOpts?.sampleRate,\n ignoreErrors: errorMonitoringOpts?.ignoreErrors,\n beforeSend: errorMonitoringOpts?.beforeSend,\n getUser: () => getSnapshot().user ?? config.user,\n getBreadcrumbs: () => ({\n consoleLogs: consoleCol?.getEntries() ?? [],\n networkErrors: networkCol?.getEntries() ?? [],\n }),\n getEnvironment: _collectors?.environment ?? collectEnvironment,\n })\n : null;\n errorCaptureCol?.start();\n\n // Set user if provided\n if (config.user) {\n flint.setUser(config.user);\n }\n\n const replayEvents: unknown[] = [];\n let stopReplay: (() => void) | null = null;\n\n debugLog(config, \"Collectors started\", {\n console: !!consoleCol,\n network: !!networkCol,\n formErrors: !!formErrorsCol,\n frustration: !!frustrationCol,\n errorCapture: !!errorCaptureCol,\n });\n\n instance = {\n config,\n console: consoleCol,\n network: networkCol,\n formErrors: formErrorsCol,\n frustration: frustrationCol,\n errorCapture: errorCaptureCol,\n replayEvents,\n stopReplay: null,\n };\n\n // Start replay recording (async, via injected recorder)\n if (enableReplay && _replayRecorder) {\n _replayRecorder((event: unknown) => {\n replayEvents.push(event);\n const cutoff = Date.now() - replayBufferMs;\n while (replayEvents.length > 0 && (replayEvents[0] as { timestamp: number }).timestamp < cutoff) {\n replayEvents.shift();\n }\n }).then((stop) => {\n stopReplay = stop ?? null;\n if (instance) instance.stopReplay = stopReplay;\n });\n }\n\n // Wire frustration auto-report\n const getEnvironment = _collectors?.environment ?? collectEnvironment;\n if (frustrationCol && autoReportFrustration) {\n frustrationCol.onFrustration(async (event) => {\n debugLog(config, \"Frustration detected, auto-reporting:\", event.type, event.details);\n onFrustration?.(event);\n const user = getSnapshot().user ?? config.user;\n await submitReport(config.serverUrl, config.projectKey, {\n reporterId: user?.id ?? \"anonymous\",\n reporterName: user?.name ?? \"Anonymous\",\n reporterEmail: user?.email,\n description: `[Auto-detected] ${event.type.replace(/_/g, \" \")}: ${event.details}`,\n severity: event.type === \"error_loop\" ? \"P1\" : event.type === \"rage_click\" ? \"P2\" : \"P3\",\n url: event.url,\n source: \"auto_capture\",\n appVersion: config.appVersion,\n release: config.release,\n meta: {\n ...config.meta,\n environment: getEnvironment(),\n consoleLogs: consoleCol?.getEntries() ?? [],\n networkErrors: networkCol?.getEntries() ?? [],\n formErrors: formErrorsCol?.getEntries() ?? [],\n frustrationEvent: event,\n },\n }).catch(() => {});\n });\n } else if (frustrationCol && onFrustration) {\n frustrationCol.onFrustration(onFrustration);\n }\n\n // Auto-fetch remote integrations config if no externalReplayProvider was set\n if (!config.externalReplayProvider) {\n fetchProjectConfig(config.serverUrl, config.projectKey)\n .then((remote) => {\n if (!instance || !remote?.integrations) return;\n const dd = remote.integrations.datadog;\n if (dd?.enabled && dd.site) {\n // Lazy-import to avoid bundling datadog helper when not needed\n import(\"./integrations/datadog.js\").then(({ createDatadogReplayProvider }) => {\n if (!instance) return;\n instance.config = {\n ...instance.config,\n externalReplayProvider: createDatadogReplayProvider(dd.site as string),\n };\n debugLog(config, \"Remote Datadog integration loaded:\", dd.site);\n });\n }\n })\n .catch(() => {\n // Fail silently — remote config is optional\n });\n }\n}\n\n/** Fetch project integrations config from the server. */\nasync function fetchProjectConfig(\n serverUrl: string,\n projectKey: string,\n): Promise<{ integrations: Record<string, { enabled: boolean; [k: string]: unknown }> } | null> {\n try {\n const url = `${serverUrl.replace(/\\/$/, \"\")}/api/v1/project-config`;\n const res = await fetch(url, { headers: { \"x-project-key\": projectKey } });\n if (!res.ok) return null;\n return res.json();\n } catch {\n return null;\n }\n}\n\nfunction shutdown(): void {\n if (!instance) return;\n\n instance.console?.stop();\n instance.network?.stop();\n instance.formErrors?.stop();\n _setFormErrorCollector(null);\n instance.frustration?.stop();\n instance.errorCapture?.stop();\n instance.stopReplay?.();\n instance = null;\n}\n\nfunction isInitialized(): boolean {\n return instance !== null;\n}\n\nfunction getInstance(): FlintInstance | null {\n return instance;\n}\n\nfunction getMeta(extraMeta?: Record<string, unknown>): CollectedMeta {\n const getEnvironment = instance?.config._collectors?.environment ?? collectEnvironment;\n return {\n ...extraMeta,\n environment: getEnvironment(),\n consoleLogs: instance?.console?.getEntries() ?? [],\n networkErrors: instance?.network?.getEntries() ?? [],\n formErrors: instance?.formErrors?.getEntries() ?? [],\n };\n}\n\nfunction getReplayEvents(): unknown[] {\n return instance ? [...instance.replayEvents] : [];\n}\n\nfunction getConfig(): FlintConfig | null {\n return instance?.config ?? null;\n}\n\nfunction getExternalReplayUrl(): string | undefined {\n // 1. Store value (set via Flint.setSessionReplay)\n const storeReplay = getSnapshot().sessionReplay;\n const fromStore = typeof storeReplay === \"function\" ? storeReplay() : storeReplay;\n if (fromStore) return fromStore;\n // 2. Config provider (e.g. createDatadogReplayProvider)\n return instance?.config.externalReplayProvider?.();\n}\n\nexport const Flint = {\n init,\n shutdown,\n isInitialized,\n getInstance,\n getMeta,\n getReplayEvents,\n getConfig,\n getExternalReplayUrl,\n setUser: flint.setUser,\n setSessionReplay: flint.setSessionReplay,\n reportFormError: flint.reportFormError,\n};\n","import type { Theme, ThemeOverride } from \"./types.js\";\n\nexport interface ResolvedTheme {\n background: string;\n backgroundSecondary: string;\n accent: string;\n accentHover: string;\n text: string;\n textMuted: string;\n border: string;\n shadow: string;\n buttonText: string;\n backdropFilter: string;\n}\n\nconst light: ResolvedTheme = {\n background: \"rgba(255,255,255,0.90)\",\n backgroundSecondary: \"rgba(249,250,251,0.75)\",\n accent: \"#2563eb\",\n accentHover: \"#1d4ed8\",\n text: \"#111827\",\n textMuted: \"#6b7280\",\n border: \"rgba(255,255,255,0.9)\",\n shadow: \"0 32px 80px rgba(0,0,0,0.18), 0 8px 32px rgba(0,0,0,0.1), 0 0 0 1px rgba(0,0,0,0.04)\",\n buttonText: \"#ffffff\",\n backdropFilter: \"blur(32px) saturate(1.8)\",\n};\n\nconst dark: ResolvedTheme = {\n background: \"rgba(15,20,35,0.88)\",\n backgroundSecondary: \"rgba(5,8,18,0.65)\",\n accent: \"#4d8aff\",\n accentHover: \"#3b6fdb\",\n text: \"#dde3ef\",\n textMuted: \"#6b7a93\",\n border: \"rgba(255,255,255,0.08)\",\n shadow: \"0 24px 60px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.04)\",\n buttonText: \"#ffffff\",\n backdropFilter: \"blur(32px) saturate(1.6)\",\n};\n\nexport function resolveTheme(theme: Theme): ResolvedTheme {\n if (theme === \"dark\") return dark;\n if (theme === \"light\") return light;\n // ThemeOverride — merge over light base\n const override = theme as ThemeOverride;\n return {\n ...light,\n background: override.background ?? light.background,\n accent: override.accent ?? light.accent,\n accentHover: override.accent ?? light.accentHover,\n text: override.text ?? light.text,\n border: override.border ?? light.border,\n };\n}\n"],"mappings":"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","names":["init","debugLog","MAX_ENTRIES","window","listeners","emit","MAX_ENTRIES","init","createDatadogReplayProvider"]}
|
|
1
|
+
{"version":3,"sources":["../src/api.ts","../src/sanitize.ts","../src/collectors/console.ts","../src/collectors/environment.ts","../src/collectors/errorCapture.ts","../src/collectors/formErrors.ts","../src/collectors/frustration.ts","../src/collectors/network.ts","../src/replayBuffer.ts","../src/store.ts","../src/singleton.ts","../src/theme.ts"],"sourcesContent":["import { gzipSync } from \"fflate\";\nimport type { ReportPayload, ReportResult } from \"./types.js\";\n\nasync function fetchWithRetry(url: string, init: RequestInit, retries = 3, baseDelay = 1000): Promise<Response> {\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n const res = await fetch(url, init);\n if (res.ok || attempt === retries) return res;\n // Don't retry client errors (4xx) except 429\n if (res.status >= 400 && res.status < 500 && res.status !== 429) return res;\n } catch (err) {\n if (attempt === retries) throw err;\n }\n await new Promise((r) => setTimeout(r, baseDelay * 2 ** attempt));\n }\n throw new Error(\"Max retries exceeded\");\n}\n\nexport async function submitReport(\n serverUrl: string,\n projectKey: string,\n payload: ReportPayload,\n screenshot?: File,\n): Promise<ReportResult> {\n const url = `${serverUrl.replace(/\\/$/, \"\")}/api/v1/bug-reports`;\n\n let body: BodyInit;\n const headers: Record<string, string> = {\n \"x-project-key\": projectKey,\n };\n\n if (screenshot) {\n const form = new FormData();\n form.append(\"reporterId\", payload.reporterId);\n form.append(\"reporterName\", payload.reporterName);\n if (payload.reporterEmail) form.append(\"reporterEmail\", payload.reporterEmail);\n if (payload.reporterExtraAttributes)\n form.append(\"reporterExtraAttributes\", JSON.stringify(payload.reporterExtraAttributes));\n form.append(\"description\", payload.description);\n if (payload.expectedBehavior) form.append(\"expectedBehavior\", payload.expectedBehavior);\n if (payload.stepsToReproduce) form.append(\"stepsToReproduce\", JSON.stringify(payload.stepsToReproduce));\n if (payload.externalReplayUrl) form.append(\"externalReplayUrl\", payload.externalReplayUrl);\n if (payload.additionalContext) form.append(\"additionalContext\", payload.additionalContext);\n form.append(\"severity\", payload.severity);\n if (payload.url) form.append(\"url\", payload.url);\n if (payload.meta) form.append(\"meta\", JSON.stringify(payload.meta));\n if (payload.appVersion) form.append(\"appVersion\", payload.appVersion);\n if (payload.release) form.append(\"release\", payload.release);\n form.append(\"screenshot\", screenshot);\n body = form;\n } else {\n body = JSON.stringify(payload);\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n const res = await fetchWithRetry(url, { method: \"POST\", headers, body });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({ error: \"Unknown error\" }));\n throw new Error((err as { error?: string }).error ?? `HTTP ${res.status}`);\n }\n\n return res.json() as Promise<ReportResult>;\n}\n\nexport async function submitReplay(\n serverUrl: string,\n projectKey: string,\n reportId: string,\n events: unknown[],\n): Promise<void> {\n const json = JSON.stringify(events);\n const encoded = new TextEncoder().encode(json);\n const compressed = gzipSync(encoded);\n\n const url = `${serverUrl.replace(/\\/$/, \"\")}/api/v1/bug-reports/${reportId}/replay`;\n await fetch(url, {\n method: \"POST\",\n headers: {\n \"x-project-key\": projectKey,\n \"Content-Type\": \"application/octet-stream\",\n },\n body: compressed.buffer as ArrayBuffer,\n });\n}\n","// Redact values that look like tokens, passwords, secrets, or API keys\nconst SENSITIVE_PATTERNS = [\n /(?:password|passwd|pwd|secret|token|api[_-]?key|access[_-]?key|authorization|bearer)\\s*[:=]\\s*[\"']?[^\\s\"',]{4,}/gi,\n /\\b(sk-[a-zA-Z0-9_-]{20,})\\b/g, // API keys (e.g. sk-ant-...)\n /\\b(ghp_[a-zA-Z0-9]{36,})\\b/g, // GitHub tokens\n /\\b(xoxb-[a-zA-Z0-9-]+)\\b/g, // Slack tokens\n /\\b(eyJ[a-zA-Z0-9_-]{10,}\\.[a-zA-Z0-9_-]{10,})\\b/g, // JWTs\n];\n\nexport function sanitize(str: string): string {\n let result = str;\n for (const pattern of SENSITIVE_PATTERNS) {\n result = result.replace(pattern, \"[REDACTED]\");\n }\n return result;\n}\n","import { sanitize } from \"../sanitize.js\";\nimport type { ConsoleEntry } from \"../types.js\";\n\nconst MAX_ENTRIES = 50;\n\nexport interface ConsoleCollector {\n start(): void;\n stop(): void;\n getEntries(): ConsoleEntry[];\n}\n\nexport function createConsoleCollector(): ConsoleCollector {\n const entries: ConsoleEntry[] = [];\n let active = false;\n\n const originals = {\n log: console.log.bind(console),\n warn: console.warn.bind(console),\n error: console.error.bind(console),\n };\n\n let origOnerror: typeof window.onerror = null;\n let origUnhandled: typeof window.onunhandledrejection = null;\n\n function push(level: ConsoleEntry[\"level\"], args: unknown[]) {\n let str: string;\n try {\n str = args.map((a) => (typeof a === \"string\" ? a : JSON.stringify(a))).join(\" \");\n } catch {\n str = String(args[0]);\n }\n if (str.length > 500) str = str.slice(0, 500) + \"\\u2026\";\n str = sanitize(str);\n entries.push({ level, args: str, timestamp: Date.now() });\n if (entries.length > MAX_ENTRIES) entries.shift();\n }\n\n return {\n start() {\n if (active) return;\n active = true;\n\n console.log = (...args: unknown[]) => {\n push(\"log\", args);\n originals.log(...args);\n };\n console.warn = (...args: unknown[]) => {\n push(\"warn\", args);\n originals.warn(...args);\n };\n console.error = (...args: unknown[]) => {\n push(\"error\", args);\n originals.error(...args);\n };\n\n origOnerror = window.onerror;\n window.onerror = (msg, src, line, col, err) => {\n push(\"error\", [err?.message ?? String(msg), `${src}:${line}:${col}`]);\n if (typeof origOnerror === \"function\") return origOnerror(msg, src, line, col, err);\n return false;\n };\n\n origUnhandled = window.onunhandledrejection;\n window.onunhandledrejection = (event) => {\n const reason = event.reason instanceof Error ? event.reason.message : JSON.stringify(event.reason);\n push(\"error\", [\"UnhandledRejection:\", reason]);\n if (typeof origUnhandled === \"function\") origUnhandled.call(window, event);\n };\n },\n\n stop() {\n if (!active) return;\n active = false;\n console.log = originals.log;\n console.warn = originals.warn;\n console.error = originals.error;\n window.onerror = origOnerror;\n window.onunhandledrejection = origUnhandled;\n },\n\n getEntries() {\n return [...entries];\n },\n };\n}\n","import type { EnvironmentInfo } from \"../types.js\";\n\nexport function collectEnvironment(): EnvironmentInfo {\n const ua = navigator.userAgent;\n\n // -- Browser --\n let browser = \"Unknown\";\n const chromeM = ua.match(/Chrome\\/(\\d+)/);\n const firefoxM = ua.match(/Firefox\\/(\\d+)/);\n const edgeM = ua.match(/Edg\\/(\\d+)/);\n const safariM = ua.match(/Version\\/(\\d+)/);\n const operaM = ua.match(/OPR\\/(\\d+)/);\n\n if (operaM) {\n browser = `Opera ${operaM[1]}`;\n } else if (edgeM) {\n browser = `Edge ${edgeM[1]}`;\n } else if (chromeM && !/Edg|OPR/.test(ua)) {\n browser = `Chrome ${chromeM[1]}`;\n } else if (firefoxM) {\n browser = `Firefox ${firefoxM[1]}`;\n } else if (safariM && /Safari\\//.test(ua)) {\n browser = `Safari ${safariM[1]}`;\n }\n\n // -- OS --\n let os = \"Unknown\";\n const macM = ua.match(/Mac OS X (\\d+[._]\\d+)/);\n const winM = ua.match(/Windows NT (\\d+\\.\\d+)/);\n const androidM = ua.match(/Android (\\d+)/);\n const iosM = ua.match(/iPhone OS (\\d+[._]\\d+)/);\n\n if (macM) {\n os = `macOS ${macM[1].replace(\"_\", \".\")}`;\n } else if (winM) {\n const winMap: Record<string, string> = {\n \"10.0\": \"10/11\",\n \"6.3\": \"8.1\",\n \"6.2\": \"8\",\n \"6.1\": \"7\",\n };\n os = `Windows ${winMap[winM[1]] ?? winM[1]}`;\n } else if (androidM) {\n os = `Android ${androidM[1]}`;\n } else if (iosM) {\n os = `iOS ${iosM[1].replace(/_/g, \".\")}`;\n } else if (/Linux/.test(ua)) {\n os = \"Linux\";\n }\n\n return {\n browser,\n os,\n viewport: `${window.innerWidth}x${window.innerHeight}`,\n screen: `${screen.width}x${screen.height}`,\n language: navigator.language,\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n online: navigator.onLine,\n };\n}\n","// Automatic error monitoring — captures uncaught errors and unhandled\n// rejections, batches them, and ships them to POST /api/v1/error-events.\n//\n// Grouping is server-authoritative: the local key computed here is used only\n// for client-side throttling and in-batch dedup, never as the grouping\n// fingerprint (so the grouping algorithm can evolve without an SDK redeploy).\nimport { sanitize } from \"../sanitize.js\";\nimport type { ConsoleEntry, EnvironmentInfo, ErrorEventPayload, FlintUser, NetworkEntry } from \"../types.js\";\n\nconst MAX_MESSAGE = 1000;\nconst MAX_STACK = 8000;\nconst MAX_BATCH = 20;\n// sendBeacon payloads are dropped silently above ~64KB — stay well under it\nconst MAX_PAYLOAD_BYTES = 60_000;\nconst PER_KEY_PER_MINUTE = 10;\nconst GLOBAL_PAGE_CAP = 100;\nconst FLUSH_INTERVAL_MS = 5_000;\nconst THROTTLE_WINDOW_MS = 60_000;\nconst BREADCRUMB_CONSOLE = 10;\nconst BREADCRUMB_NETWORK = 10;\n\n// Noise that is never actionable: benign browser warnings, cross-origin\n// \"Script error.\" (no stack, no message), and browser-extension code.\nconst DEFAULT_IGNORE = [/ResizeObserver loop/i, /^Script error\\.?$/];\nconst EXTENSION_URL = /(chrome|moz|safari|safari-web)-extension:\\/\\//;\n\nexport interface ErrorCaptureCollector {\n start(): void;\n stop(): void;\n /** Flush pending events immediately (also called on pagehide/interval). */\n flush(): void;\n}\n\nexport interface ErrorCaptureOptions {\n serverUrl: string;\n projectKey: string;\n release?: string;\n appVersion?: string;\n /** Fraction of captured errors to report, 0..1. Default 1.0 */\n sampleRate?: number;\n /** Errors whose message matches any entry are dropped (string = substring match) */\n ignoreErrors?: (string | RegExp)[];\n /** Mutate or drop (return null) an event before it is queued for sending */\n beforeSend?: (event: ErrorEventPayload) => ErrorEventPayload | null;\n getUser?: () => FlintUser | undefined;\n getBreadcrumbs?: () => { consoleLogs: ConsoleEntry[]; networkErrors: NetworkEntry[] };\n getEnvironment?: () => EnvironmentInfo;\n debug?: boolean;\n}\n\nfunction normalizeForKey(message: string): string {\n return message.toLowerCase().replace(/\\d+/g, \"#\").replace(/\\s+/g, \" \").trim().slice(0, 200);\n}\n\nfunction topFrame(stack: string | undefined): string {\n if (!stack) return \"\";\n const lines = stack.split(\"\\n\").map((l) => l.trim());\n return lines.find((l) => l.startsWith(\"at \") || /@/.test(l)) ?? \"\";\n}\n\nexport function createErrorCaptureCollector(options: ErrorCaptureOptions): ErrorCaptureCollector {\n const sampleRate = options.sampleRate ?? 1.0;\n const ignoreList = [...DEFAULT_IGNORE, ...(options.ignoreErrors ?? [])];\n const sessionId = `s_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 10)}`;\n\n let active = false;\n let queue: ErrorEventPayload[] = [];\n let interval: ReturnType<typeof setInterval> | null = null;\n let sentCount = 0;\n let environment: EnvironmentInfo | undefined;\n const keyTimestamps = new Map<string, number[]>();\n\n function debugLog(...args: unknown[]) {\n if (options.debug) console.log(\"[Flint]\", ...args);\n }\n\n function isIgnored(message: string, stack: string | undefined, frameUrl: string | undefined): boolean {\n for (const entry of ignoreList) {\n if (typeof entry === \"string\") {\n if (message.includes(entry)) return true;\n } else if (entry.test(message)) {\n return true;\n }\n }\n if (EXTENSION_URL.test(frameUrl ?? \"\") || EXTENSION_URL.test(stack ?? \"\")) return true;\n return false;\n }\n\n function isThrottled(localKey: string): boolean {\n const now = Date.now();\n const stamps = (keyTimestamps.get(localKey) ?? []).filter((t) => now - t < THROTTLE_WINDOW_MS);\n if (stamps.length >= PER_KEY_PER_MINUTE) {\n keyTimestamps.set(localKey, stamps);\n return true;\n }\n stamps.push(now);\n keyTimestamps.set(localKey, stamps);\n return false;\n }\n\n function capture(input: {\n type: \"error\" | \"unhandledrejection\";\n message: string;\n errorClass: string;\n stack?: string;\n frameUrl?: string;\n }) {\n try {\n if (sentCount + queue.length >= GLOBAL_PAGE_CAP) return;\n\n let message = input.message.slice(0, MAX_MESSAGE);\n if (isIgnored(message, input.stack, input.frameUrl)) return;\n if (sampleRate < 1 && Math.random() >= sampleRate) return;\n\n const localKey = `${input.type}|${normalizeForKey(message)}|${topFrame(input.stack)}`;\n if (isThrottled(localKey)) return;\n\n // In-batch dedup: identical errors before a flush become one event with a count\n const pending = queue.find((e) => e._localKey === localKey);\n if (pending) {\n pending.count += 1;\n return;\n }\n\n message = sanitize(message);\n const stack = input.stack ? sanitize(input.stack.slice(0, MAX_STACK)) : undefined;\n if (!environment && options.getEnvironment) {\n try {\n environment = options.getEnvironment();\n } catch {\n /* environment is best-effort */\n }\n }\n const user = options.getUser?.();\n\n let event: ErrorEventPayload = {\n type: input.type,\n message,\n errorClass: input.errorClass,\n stack,\n url: typeof location !== \"undefined\" ? location.href : \"\",\n timestamp: Date.now(),\n release: options.release,\n appVersion: options.appVersion,\n userId: user?.id,\n sessionId,\n browser: environment?.browser,\n os: environment?.os,\n count: 1,\n breadcrumbs: options.getBreadcrumbs\n ? {\n consoleLogs: options.getBreadcrumbs().consoleLogs.slice(-BREADCRUMB_CONSOLE),\n networkErrors: options.getBreadcrumbs().networkErrors.slice(-BREADCRUMB_NETWORK),\n }\n : undefined,\n _localKey: localKey,\n };\n\n if (options.beforeSend) {\n try {\n const result = options.beforeSend(event);\n if (!result) return;\n event = { ...result, _localKey: localKey };\n } catch {\n // beforeSend threw — keep the original event rather than losing it\n }\n }\n\n queue.push(event);\n debugLog(\"Error captured\", input.errorClass, message);\n if (queue.length >= MAX_BATCH) flush(false);\n } catch {\n // Never let the error monitor itself throw\n }\n }\n\n function serialize(events: ErrorEventPayload[]): string {\n const wire = events.map(({ _localKey, ...e }) => e);\n let body = JSON.stringify(wire);\n if (body.length > MAX_PAYLOAD_BYTES) {\n // Shed weight: breadcrumbs first, then stacks\n body = JSON.stringify(wire.map((e) => ({ ...e, breadcrumbs: undefined })));\n if (body.length > MAX_PAYLOAD_BYTES) {\n body = JSON.stringify(wire.map((e) => ({ ...e, breadcrumbs: undefined, stack: e.stack?.slice(0, 2000) })));\n }\n }\n return body;\n }\n\n function flush(unloading: boolean) {\n if (queue.length === 0) return;\n const events = queue;\n queue = [];\n sentCount += events.length;\n\n const base = options.serverUrl.replace(/\\/$/, \"\");\n // Query auth + text/plain body: sendBeacon can't set headers, and a JSON\n // content-type triggers a CORS preflight that drops beacons on unload.\n const url = `${base}/api/v1/error-events?project_key=${encodeURIComponent(options.projectKey)}`;\n const body = serialize(events);\n\n if (unloading && typeof navigator !== \"undefined\" && typeof navigator.sendBeacon === \"function\") {\n const ok = navigator.sendBeacon(url, body);\n debugLog(\"Flushed via beacon\", events.length, ok);\n if (ok) return;\n // Beacon refused (e.g. payload too large) — fall through to fetch\n }\n\n fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"text/plain;charset=UTF-8\" },\n body,\n keepalive: unloading,\n }).catch(() => {\n /* fire-and-forget */\n });\n debugLog(\"Flushed via fetch\", events.length);\n }\n\n function onError(event: Event) {\n // Resource load failures also dispatch \"error\" in the capture phase but\n // are not ErrorEvents — out of MVP scope (frustration.ts covers loops).\n const e = event as ErrorEvent;\n if (typeof e.message !== \"string\" && !(e.error instanceof Error)) return;\n const err = e.error instanceof Error ? e.error : undefined;\n capture({\n type: \"error\",\n message: err?.message ?? (e.message || \"Unknown error\"),\n errorClass: err?.name ?? \"Error\",\n stack: err?.stack,\n frameUrl: e.filename,\n });\n }\n\n function onRejection(event: Event) {\n const reason = (event as PromiseRejectionEvent).reason;\n const err = reason instanceof Error ? reason : undefined;\n let message: string;\n if (err) {\n message = err.message;\n } else {\n try {\n message = typeof reason === \"string\" ? reason : JSON.stringify(reason);\n } catch {\n message = String(reason);\n }\n }\n capture({\n type: \"unhandledrejection\",\n message: message || \"Unhandled promise rejection\",\n errorClass: err?.name ?? \"UnhandledRejection\",\n stack: err?.stack,\n });\n }\n\n function onPageHide() {\n flush(true);\n }\n\n function onVisibilityChange() {\n if (document.visibilityState === \"hidden\") flush(true);\n }\n\n return {\n start() {\n if (active) return;\n active = true;\n // capture-phase listeners coexist with console.ts, which *assigns*\n // window.onerror / onunhandledrejection\n window.addEventListener(\"error\", onError, { capture: true });\n window.addEventListener(\"unhandledrejection\", onRejection, { capture: true });\n window.addEventListener(\"pagehide\", onPageHide);\n document.addEventListener(\"visibilitychange\", onVisibilityChange);\n interval = setInterval(() => flush(false), FLUSH_INTERVAL_MS);\n },\n\n stop() {\n if (!active) return;\n active = false;\n window.removeEventListener(\"error\", onError, { capture: true });\n window.removeEventListener(\"unhandledrejection\", onRejection, { capture: true });\n window.removeEventListener(\"pagehide\", onPageHide);\n document.removeEventListener(\"visibilitychange\", onVisibilityChange);\n if (interval) clearInterval(interval);\n interval = null;\n flush(false);\n },\n\n flush() {\n flush(false);\n },\n };\n}\n","import type { FormErrorEntry, FormErrorField } from \"../types.js\";\n\nconst MAX_ENTRIES = 30;\n\n/**\n * Time to wait after a submit event before checking the DOM for error\n * indicators. RHF/zod validate asynchronously — 300ms covers most cases\n * while keeping the detection snappy.\n */\nconst POST_SUBMIT_CHECK_MS = 300;\n\n/**\n * After a submit button click, if no submit event fires within this window\n * it means the form library swallowed the submit entirely (e.g. RHF's\n * handleSubmit called preventDefault before the native event propagated,\n * or the button isn't even inside a <form>). We treat this as a potential\n * silent failure and scan the page for error indicators.\n */\nconst SILENT_SUBMIT_WINDOW_MS = 400;\n\nexport interface FormErrorCollector {\n start(): void;\n stop(): void;\n getEntries(): FormErrorEntry[];\n /**\n * Manually report a form validation failure. Call this from your form\n * library's error handler to capture exact field-level errors.\n *\n * @example\n * // React Hook Form + Zod\n * <form onSubmit={handleSubmit(onValid, (errors) => {\n * flint.reportFormError('checkout-form', errors);\n * })}>\n */\n report(formId: string, errors: Record<string, { message?: string } | undefined>): void;\n}\n\n// ── DOM helpers ────────────────────────────────────────────────────────────────\n\nfunction getFormId(form: HTMLFormElement): string {\n if (form.id) return `#${form.id}`;\n if (form.getAttribute(\"name\")) return `form[name=\"${form.getAttribute(\"name\")}\"]`;\n if (form.action && form.action !== location.href) return form.action;\n return `form:${Array.from(document.forms).indexOf(form)}`;\n}\n\nfunction getFieldLabel(field: HTMLElement, root: HTMLElement): string {\n const ariaLabel = field.getAttribute(\"aria-label\");\n if (ariaLabel) return ariaLabel;\n\n const id = field.id;\n if (id) {\n const label = root.querySelector<HTMLLabelElement>(`label[for=\"${id}\"]`);\n if (label?.textContent) return label.textContent.trim();\n }\n\n const parentLabel = field.closest(\"label\");\n if (parentLabel?.textContent) {\n const text = parentLabel.textContent.trim();\n if (text.length < 60) return text;\n }\n\n return (field as HTMLInputElement).name || (field as HTMLInputElement).placeholder || field.tagName.toLowerCase();\n}\n\nfunction getErrorMessage(field: HTMLElement): string | undefined {\n // aria-errormessage\n const errId = field.getAttribute(\"aria-errormessage\");\n if (errId) {\n const el = document.getElementById(errId);\n if (el?.textContent) return el.textContent.trim();\n }\n\n // aria-describedby (RHF wires error messages here)\n const descId = field.getAttribute(\"aria-describedby\");\n if (descId) {\n for (const id of descId.split(/\\s+/)) {\n const el = document.getElementById(id);\n if (el?.textContent?.trim()) return el.textContent.trim();\n }\n }\n\n // native validationMessage\n if (field instanceof HTMLInputElement || field instanceof HTMLTextAreaElement || field instanceof HTMLSelectElement) {\n if (field.validationMessage) return field.validationMessage;\n }\n\n // adjacent role=\"alert\"\n const next = field.nextElementSibling;\n if (next?.getAttribute(\"role\") === \"alert\" && next.textContent) {\n return next.textContent.trim();\n }\n\n return undefined;\n}\n\n/**\n * Collect fields with `aria-invalid=\"true\"` or native `:invalid` inside a\n * root element (a <form> or the whole document).\n */\nfunction collectInvalidFields(root: HTMLElement): FormErrorField[] {\n const fields: FormErrorField[] = [];\n const invalidEls = root.querySelectorAll<HTMLElement>('[aria-invalid=\"true\"], :invalid');\n\n for (const el of invalidEls) {\n if (el instanceof HTMLFormElement) continue;\n if (el.tagName === \"FIELDSET\") continue;\n\n fields.push({\n name: getFieldLabel(el, root),\n message: getErrorMessage(el),\n });\n }\n\n return fields;\n}\n\n/**\n * Scan the page for visible error indicators that appeared after a submit\n * attempt. This catches errors even when:\n * - The errored field is in another tab/step of a multi-step form\n * - The form doesn't use aria-invalid at all\n * - Errors are rendered as standalone alert divs\n */\nfunction collectVisibleErrors(root: HTMLElement): FormErrorField[] {\n const fields: FormErrorField[] = [];\n const seen = new Set<string>();\n\n // 1. role=\"alert\" elements that appeared (error toasts, inline messages)\n const alerts = root.querySelectorAll<HTMLElement>('[role=\"alert\"]');\n for (const el of alerts) {\n const text = el.textContent?.trim();\n if (!text || text.length > 200) continue;\n if (seen.has(text)) continue;\n seen.add(text);\n fields.push({ name: \"alert\", message: text });\n }\n\n // 2. Common error class patterns (data-error, .error, .field-error, etc.)\n const errorEls = root.querySelectorAll<HTMLElement>(\n \"[data-error], [data-field-error], .error-message, .field-error, .form-error\",\n );\n for (const el of errorEls) {\n const text = el.textContent?.trim();\n if (!text || text.length > 200) continue;\n if (seen.has(text)) continue;\n seen.add(text);\n fields.push({ name: \"error\", message: text });\n }\n\n return fields;\n}\n\nfunction isSubmitButton(el: HTMLElement): el is HTMLButtonElement {\n if (el.tagName === \"BUTTON\") {\n const type = el.getAttribute(\"type\");\n // Buttons default to type=\"submit\" inside forms when no type is set\n return type === \"submit\" || type === null || type === \"\";\n }\n if (el.tagName === \"INPUT\") {\n return (el as HTMLInputElement).type === \"submit\";\n }\n return false;\n}\n\nfunction findClosestForm(el: HTMLElement): HTMLFormElement | null {\n // Direct form association\n if (\"form\" in el && (el as HTMLButtonElement).form) {\n return (el as HTMLButtonElement).form;\n }\n return el.closest(\"form\");\n}\n\n// ── Collector ──────────────────────────────────────────────────────────────────\n\nexport function createFormErrorCollector(): FormErrorCollector {\n const entries: FormErrorEntry[] = [];\n const attemptCounts = new Map<string, number>();\n let active = false;\n\n // Handlers we need to clean up\n let submitHandler: ((e: Event) => void) | null = null;\n let invalidHandler: ((e: Event) => void) | null = null;\n let clickHandler: ((e: MouseEvent) => void) | null = null;\n\n // Track whether a real submit event followed a button click\n let lastSubmitTime = 0;\n\n // Dedup: avoid recording the same form twice within a short window\n const recentRecords = new Map<string, number>();\n const DEDUP_MS = 500;\n\n function push(entry: FormErrorEntry) {\n // Dedup check\n const _key = `${entry.formId}:${entry.timestamp}`;\n const last = recentRecords.get(entry.formId);\n if (last && entry.timestamp - last < DEDUP_MS) return;\n recentRecords.set(entry.formId, entry.timestamp);\n\n entries.push(entry);\n if (entries.length > MAX_ENTRIES) entries.shift();\n }\n\n function recordFormErrors(form: HTMLFormElement, type: FormErrorEntry[\"type\"]) {\n const formId = getFormId(form);\n\n // Strategy 1: aria-invalid / :invalid fields\n let fields = collectInvalidFields(form);\n\n // Strategy 2: if no aria-invalid fields found, look for visible error messages\n if (fields.length === 0) {\n fields = collectVisibleErrors(form);\n }\n\n if (fields.length === 0) return;\n\n const count = (attemptCounts.get(formId) ?? 0) + 1;\n attemptCounts.set(formId, count);\n\n push({\n type,\n formId,\n fields,\n attemptNumber: count,\n url: location.href,\n timestamp: Date.now(),\n });\n }\n\n /**\n * Handle clicks on submit buttons. If no submit event follows within\n * SILENT_SUBMIT_WINDOW_MS, it means the form library blocked the submit\n * entirely — scan for errors.\n */\n function handleSubmitButtonClick(button: HTMLElement) {\n const form = findClosestForm(button);\n\n setTimeout(() => {\n if (!active) return;\n // A real submit event fired — the submitHandler already took care of it\n if (Date.now() - lastSubmitTime < SILENT_SUBMIT_WINDOW_MS) return;\n\n // No submit event → silent failure\n const root = form ?? (document.body as HTMLElement);\n const formId = form ? getFormId(form) : `page:${location.pathname}`;\n\n let fields = form ? collectInvalidFields(form) : [];\n if (fields.length === 0) {\n fields = collectVisibleErrors(root);\n }\n\n // Also scan full page — the error might be in a toast or outside the form\n if (fields.length === 0 && form) {\n fields = collectVisibleErrors(document.body);\n }\n\n if (fields.length === 0) return;\n\n const count = (attemptCounts.get(formId) ?? 0) + 1;\n attemptCounts.set(formId, count);\n\n push({\n type: \"silent_submit\",\n formId,\n fields,\n attemptNumber: count,\n url: location.href,\n timestamp: Date.now(),\n });\n }, SILENT_SUBMIT_WINDOW_MS);\n }\n\n return {\n start() {\n if (active) return;\n active = true;\n\n // 1. Capture submit events (fires even with e.preventDefault())\n submitHandler = (e: Event) => {\n lastSubmitTime = Date.now();\n const form = e.target as HTMLFormElement;\n if (!(form instanceof HTMLFormElement)) return;\n\n setTimeout(() => {\n if (!active) return;\n recordFormErrors(form, \"validation_failed\");\n }, POST_SUBMIT_CHECK_MS);\n };\n document.addEventListener(\"submit\", submitHandler, true);\n\n // 2. Capture native invalid events (HTML5 constraint validation)\n invalidHandler = (e: Event) => {\n lastSubmitTime = Date.now();\n const field = e.target as HTMLElement;\n const form = field.closest(\"form\");\n if (!form) return;\n\n setTimeout(() => {\n if (!active) return;\n recordFormErrors(form, \"validation_failed\");\n }, POST_SUBMIT_CHECK_MS);\n };\n document.addEventListener(\"invalid\", invalidHandler, true);\n\n // 3. Capture clicks on submit buttons — catches silent failures\n // where the form lib eats the submit and shows nothing\n clickHandler = (e: MouseEvent) => {\n const target = e.target as HTMLElement;\n if (!target) return;\n\n // Walk up to find the actual button (click might be on an icon/span inside)\n const button = target.closest(\"button, input[type=submit]\") as HTMLElement | null;\n if (!button) return;\n if (!isSubmitButton(button)) return;\n\n handleSubmitButtonClick(button);\n };\n document.addEventListener(\"click\", clickHandler, true);\n },\n\n stop() {\n if (!active) return;\n active = false;\n if (submitHandler) document.removeEventListener(\"submit\", submitHandler, true);\n if (invalidHandler) document.removeEventListener(\"invalid\", invalidHandler, true);\n if (clickHandler) document.removeEventListener(\"click\", clickHandler, true);\n attemptCounts.clear();\n recentRecords.clear();\n },\n\n getEntries() {\n return [...entries];\n },\n\n report(formId: string, errors: Record<string, { message?: string } | undefined>) {\n const fields: FormErrorField[] = [];\n for (const [name, err] of Object.entries(errors)) {\n if (!err) continue;\n fields.push({ name, message: err.message });\n }\n if (fields.length === 0) return;\n\n const count = (attemptCounts.get(formId) ?? 0) + 1;\n attemptCounts.set(formId, count);\n\n push({\n type: \"validation_failed\",\n formId,\n fields,\n attemptNumber: count,\n url: location.href,\n timestamp: Date.now(),\n });\n },\n };\n}\n","export interface FrustrationEvent {\n type: \"rage_click\" | \"dead_click\" | \"error_loop\";\n timestamp: number;\n target: string;\n details: string;\n url: string;\n}\n\nexport interface FrustrationCollector {\n start(): void;\n stop(): void;\n getEvents(): FrustrationEvent[];\n onFrustration(callback: (event: FrustrationEvent) => void): () => void;\n}\n\nexport function createFrustrationCollector(opts?: {\n rageClickThreshold?: number;\n rageClickWindow?: number;\n errorLoopThreshold?: number;\n errorLoopWindow?: number;\n enableDeadClicks?: boolean;\n}): FrustrationCollector {\n const threshold = opts?.rageClickThreshold ?? 3;\n const window = opts?.rageClickWindow ?? 500;\n const errorThreshold = opts?.errorLoopThreshold ?? 3;\n const errorWindow = opts?.errorLoopWindow ?? 30_000;\n const deadClicksEnabled = opts?.enableDeadClicks ?? true;\n\n const events: FrustrationEvent[] = [];\n const listeners = new Set<(event: FrustrationEvent) => void>();\n const clickHistory: { target: EventTarget | null; time: number }[] = [];\n const errorCounts = new Map<string, { count: number; firstSeen: number }>();\n let clickHandler: ((e: MouseEvent) => void) | null = null;\n let origConsoleError: typeof console.error | null = null;\n\n function emit(event: FrustrationEvent) {\n events.push(event);\n if (events.length > 50) events.shift();\n for (const cb of listeners) cb(event);\n }\n\n function getCSSSelector(el: Element): string {\n if (el.id) return `#${el.id}`;\n const tag = el.tagName.toLowerCase();\n const cls = [...el.classList].slice(0, 3).join(\".\");\n if (cls) return `${tag}.${cls}`;\n return tag;\n }\n\n function isInteractive(el: HTMLElement): boolean {\n const tag = el.tagName.toLowerCase();\n if ([\"a\", \"button\", \"input\", \"select\", \"textarea\", \"label\", \"summary\"].includes(tag)) return true;\n if (el.getAttribute(\"role\") === \"button\" || el.getAttribute(\"tabindex\")) return true;\n if (el.onclick || el.getAttribute(\"onclick\")) return true;\n if (el.closest(\"a, button, [role=button], [onclick]\")) return true;\n try {\n if (getComputedStyle(el).cursor === \"pointer\") return true;\n } catch {\n /* getComputedStyle may throw */\n }\n return false;\n }\n\n function handleClick(e: MouseEvent) {\n const target = e.target as HTMLElement;\n if (!target) return;\n const now = Date.now();\n\n // --- Rage click detection ---\n clickHistory.push({ target, time: now });\n // Remove old clicks\n while (clickHistory.length > 0 && now - clickHistory[0].time > 1000) {\n clickHistory.shift();\n }\n const recentOnSame = clickHistory.filter((c) => c.target === target && now - c.time < window);\n if (recentOnSame.length >= threshold) {\n emit({\n type: \"rage_click\",\n timestamp: now,\n target: getCSSSelector(target),\n details: `${recentOnSame.length} clicks in ${now - recentOnSame[0].time}ms`,\n url: globalThis.location?.href ?? \"\",\n });\n clickHistory.length = 0;\n }\n\n // --- Dead click detection ---\n if (deadClicksEnabled && !isInteractive(target)) {\n emit({\n type: \"dead_click\",\n timestamp: now,\n target: getCSSSelector(target),\n details: `Click on non-interactive <${target.tagName.toLowerCase()}>`,\n url: globalThis.location?.href ?? \"\",\n });\n }\n }\n\n function patchConsoleError() {\n origConsoleError = console.error;\n console.error = (...args: unknown[]) => {\n origConsoleError?.apply(console, args);\n // Check for error loop\n const key = String(args[0]).slice(0, 100);\n const now = Date.now();\n const existing = errorCounts.get(key);\n if (existing && now - existing.firstSeen < errorWindow) {\n existing.count++;\n if (existing.count >= errorThreshold) {\n emit({\n type: \"error_loop\",\n timestamp: now,\n target: \"console\",\n details: `Same error ${existing.count}x in ${Math.round((now - existing.firstSeen) / 1000)}s: ${key}`,\n url: globalThis.location?.href ?? \"\",\n });\n errorCounts.delete(key);\n }\n } else {\n errorCounts.set(key, { count: 1, firstSeen: now });\n }\n };\n }\n\n return {\n start() {\n clickHandler = handleClick;\n document.addEventListener(\"click\", clickHandler, true);\n patchConsoleError();\n },\n stop() {\n if (clickHandler) document.removeEventListener(\"click\", clickHandler, true);\n if (origConsoleError) console.error = origConsoleError;\n clickHistory.length = 0;\n errorCounts.clear();\n },\n getEvents() {\n return [...events];\n },\n onFrustration(callback) {\n listeners.add(callback);\n return () => listeners.delete(callback);\n },\n };\n}\n","import type { NetworkEntry } from \"../types.js\";\n\nconst MAX_ENTRIES = 50;\nconst MAX_FULL_URL = 2000;\nconst MAX_REQUEST_BODY = 2048;\nconst MAX_RESPONSE_BODY = 4096;\nconst MAX_HEADERS = 30;\nconst REDACTED_HEADERS = new Set([\"authorization\", \"cookie\", \"set-cookie\", \"x-api-key\"]);\n\n// Well-known third-party domains to always ignore\nconst DEFAULT_BLOCKED_HOSTS = [\n \"browser-intake-datadoghq.com\",\n \"datadoghq.com\",\n \"datadoghq.eu\",\n \"google.com\",\n \"googleapis.com\",\n \"google-analytics.com\",\n \"googletagmanager.com\",\n \"gstatic.com\",\n \"doubleclick.net\",\n \"facebook.com\",\n \"facebook.net\",\n \"hotjar.com\",\n \"hotjar.io\",\n \"intercom.io\",\n \"intercomcdn.com\",\n \"segment.io\",\n \"segment.com\",\n \"mixpanel.com\",\n \"amplitude.com\",\n \"sentry.io\",\n \"fullstory.com\",\n \"clarity.ms\",\n \"newrelic.com\",\n \"nr-data.net\",\n \"cloudflareinsights.com\",\n \"heapanalytics.com\",\n \"posthog.com\",\n \"logrocket.io\",\n \"lr-in-prod.com\",\n \"crowdin.net\",\n \"crowdin.com\",\n];\n\n// Static asset extensions to ignore\nconst ASSET_EXTENSIONS = new Set([\n \".woff\",\n \".woff2\",\n \".ttf\",\n \".otf\",\n \".eot\", // fonts\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".gif\",\n \".svg\",\n \".webp\",\n \".ico\",\n \".avif\", // images\n \".css\",\n \".map\", // styles & source maps\n \".js\",\n \".mjs\", // scripts (usually loaded by browser, not app logic)\n \".mp3\",\n \".mp4\",\n \".webm\",\n \".ogg\", // media\n]);\n\nfunction isAssetUrl(url: string): boolean {\n try {\n const pathname = new URL(url, location.href).pathname;\n const ext = pathname.slice(pathname.lastIndexOf(\".\")).toLowerCase();\n return ASSET_EXTENSIONS.has(ext);\n } catch {\n return false;\n }\n}\n\nfunction isBlockedUrl(url: string, blocked: Set<string>): boolean {\n try {\n const host = new URL(url, location.href).hostname;\n return [...blocked].some((b) => host === b || host.endsWith(\".\" + b));\n } catch {\n return false;\n }\n}\n\nfunction shouldIgnore(url: string, blocked: Set<string>): boolean {\n return isBlockedUrl(url, blocked) || isAssetUrl(url);\n}\n\nexport interface NetworkCollector {\n start(): void;\n stop(): void;\n getEntries(): NetworkEntry[];\n}\n\nfunction truncateUrl(url: string): string {\n try {\n const u = new URL(url, location.href);\n const base = `${u.origin}${u.pathname}`;\n return base.length > 200 ? base.slice(0, 200) + \"\\u2026\" : base;\n } catch {\n return url.length > 200 ? url.slice(0, 200) + \"\\u2026\" : url;\n }\n}\n\nfunction captureFullUrl(url: string): string {\n return url.length > MAX_FULL_URL ? url.slice(0, MAX_FULL_URL) + \"\\u2026\" : url;\n}\n\nfunction safeBodyPreview(body: unknown, max: number): string | undefined {\n try {\n if (body == null) return undefined;\n if (typeof body === \"string\") return body.length > max ? body.slice(0, max) + \"\\u2026\" : body;\n if (typeof URLSearchParams !== \"undefined\" && body instanceof URLSearchParams) {\n const s = body.toString();\n return s.length > max ? s.slice(0, max) + \"\\u2026\" : s;\n }\n if (typeof FormData !== \"undefined\" && body instanceof FormData) {\n const keys: string[] = [];\n body.forEach((_, k) => keys.push(k));\n return `FormData { ${keys.join(\", \")} }`;\n }\n if (typeof Blob !== \"undefined\" && body instanceof Blob)\n return `[Blob ${body.type || \"unknown\"}, ${body.size} bytes]`;\n if (typeof ArrayBuffer !== \"undefined\" && body instanceof ArrayBuffer)\n return `[ArrayBuffer ${body.byteLength} bytes]`;\n } catch {\n /* ignore */\n }\n return undefined;\n}\n\nfunction captureHeaders(\n raw: HeadersInit | Headers | string | undefined | null,\n max: number,\n): Record<string, string> | undefined {\n if (!raw) return undefined;\n try {\n const result: Record<string, string> = {};\n let count = 0;\n let total = 0;\n\n if (typeof raw === \"string\") {\n // XHR getAllResponseHeaders() format: \"key: value\\r\\n\"\n for (const line of raw.split(/\\r?\\n/)) {\n if (!line) continue;\n total++;\n if (count >= max) continue;\n const idx = line.indexOf(\":\");\n if (idx === -1) continue;\n const key = line.slice(0, idx).trim().toLowerCase();\n const val = REDACTED_HEADERS.has(key) ? \"[REDACTED]\" : line.slice(idx + 1).trim();\n result[key] = val;\n count++;\n }\n } else {\n // Duck-type Headers (instanceof breaks across realms, e.g. undici vs jsdom).\n const headersLike = raw as Headers;\n const entries: Iterable<[string, string]> =\n typeof headersLike.entries === \"function\" && typeof headersLike.forEach === \"function\"\n ? headersLike.entries()\n : Array.isArray(raw)\n ? raw\n : Object.entries(raw as Record<string, string>);\n for (const [k, v] of entries) {\n total++;\n if (count >= max) continue;\n const key = k.toLowerCase();\n result[key] = REDACTED_HEADERS.has(key) ? \"[REDACTED]\" : v;\n count++;\n }\n }\n\n if (total > max) result[\"...truncated\"] = `${total - max} more`;\n return count > 0 ? result : undefined;\n } catch {\n /* ignore */\n }\n return undefined;\n}\n\nfunction extractContentType(headers: HeadersInit | undefined | null): string | undefined {\n if (!headers) return undefined;\n try {\n // Duck-type Headers (instanceof breaks across realms, e.g. undici vs jsdom).\n if (typeof (headers as Headers).get === \"function\") return (headers as Headers).get(\"content-type\") ?? undefined;\n if (Array.isArray(headers)) {\n const found = headers.find(([k]) => k.toLowerCase() === \"content-type\");\n return found?.[1];\n }\n const rec = headers as Record<string, string>;\n for (const k of Object.keys(rec)) {\n if (k.toLowerCase() === \"content-type\") return rec[k];\n }\n } catch {\n /* ignore */\n }\n return undefined;\n}\n\nexport interface NetworkCollectorOptions {\n maxEntries?: number;\n maxResponseBody?: number;\n}\n\nexport function createNetworkCollector(\n extraBlockedHosts: string[] = [],\n options?: NetworkCollectorOptions,\n): NetworkCollector {\n const maxEntries = options?.maxEntries ?? MAX_ENTRIES;\n const maxResponseBody = options?.maxResponseBody ?? MAX_RESPONSE_BODY;\n const entries: NetworkEntry[] = [];\n const blocked = new Set([...DEFAULT_BLOCKED_HOSTS, ...extraBlockedHosts]);\n let origFetch: typeof window.fetch | null = null;\n let origXHROpen: typeof XMLHttpRequest.prototype.open | null = null;\n let origXHRSend: typeof XMLHttpRequest.prototype.send | null = null;\n let origXHRSetHeader: typeof XMLHttpRequest.prototype.setRequestHeader | null = null;\n let perfObserver: PerformanceObserver | null = null;\n let active = false;\n\n // Keys of requests already captured by the fetch/XHR patches, so the\n // PerformanceObserver fallback can skip duplicates of the same request.\n const seenUrls = new Set<string>();\n\n function push(entry: NetworkEntry) {\n seenUrls.add(entry.fullUrl ?? entry.url);\n entries.push(entry);\n if (entries.length > maxEntries) entries.shift();\n }\n\n return {\n start() {\n if (active) return;\n active = true;\n\n // -- Patch fetch --\n origFetch = window.fetch;\n window.fetch = async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n // Clients like openapi-fetch call fetch(new Request(...)) — method, url,\n // headers and body live on the Request, with init undefined. Read from\n // the Request when present so POST/PUT/etc. aren't mislabelled as GET.\n const reqObj = typeof Request !== \"undefined\" && input instanceof Request ? input : null;\n const method = ((init?.method ?? reqObj?.method ?? \"GET\") as string).toUpperCase();\n const url = reqObj ? reqObj.url : typeof input === \"string\" ? input : (input as URL).href;\n const startTime = Date.now();\n const reqHeaders = captureHeaders(init?.headers ?? reqObj?.headers, MAX_HEADERS);\n const reqContentType = extractContentType(init?.headers ?? reqObj?.headers);\n let reqBody = safeBodyPreview(init?.body, MAX_REQUEST_BODY);\n if (reqBody === undefined && reqObj && !shouldIgnore(url, blocked)) {\n // Body lives on the Request — read it from a clone (non-destructive).\n try {\n const t = await reqObj.clone().text();\n if (t) reqBody = t.length > MAX_REQUEST_BODY ? t.slice(0, MAX_REQUEST_BODY) + \"…\" : t;\n } catch {\n /* ignore */\n }\n }\n\n let res: Response;\n try {\n res = await origFetch!.call(window, input, init);\n } catch (err) {\n // Network-level failure (offline, CORS, DNS, timeout) \\u2014 not a 4xx/5xx.\n if (!shouldIgnore(url, blocked)) {\n push({\n method,\n url: truncateUrl(url),\n fullUrl: captureFullUrl(url),\n status: 0,\n duration: Date.now() - startTime,\n timestamp: startTime,\n source: \"fetch\",\n failed: true,\n errorMessage: err instanceof Error ? err.message : String(err),\n requestHeaders: reqHeaders,\n requestBody: reqBody,\n requestContentType: reqContentType,\n });\n }\n throw err; // do not swallow \\u2014 preserve app behaviour\n }\n\n if (!shouldIgnore(url, blocked)) {\n const entry: NetworkEntry = {\n method,\n url: truncateUrl(url),\n fullUrl: captureFullUrl(url),\n status: res.status,\n statusText: res.statusText || undefined,\n source: \"fetch\",\n duration: Date.now() - startTime,\n timestamp: startTime,\n requestHeaders: reqHeaders,\n requestBody: reqBody,\n requestContentType: reqContentType,\n responseContentType: res.headers.get(\"content-type\") ?? undefined,\n responseSize: parseInt(res.headers.get(\"content-length\") || \"0\", 10) || undefined,\n responseHeaders: captureHeaders(res.headers, MAX_HEADERS),\n };\n // Non-blocking: read response body from clone\n try {\n const clone = res.clone();\n clone\n .text()\n .then((text) => {\n entry.responseBody = text.length > maxResponseBody ? text.slice(0, maxResponseBody) + \"\\u2026\" : text;\n if (!entry.responseSize && text.length) entry.responseSize = text.length;\n })\n .catch(() => {});\n } catch {\n /* ignore */\n }\n push(entry);\n }\n return res;\n };\n\n // -- Patch XHR --\n const xhrMeta = new WeakMap<\n XMLHttpRequest,\n { reqBody?: string; reqHeaders: Record<string, string>; reqContentType?: string }\n >();\n\n origXHROpen = XMLHttpRequest.prototype.open;\n origXHRSend = XMLHttpRequest.prototype.send;\n origXHRSetHeader = XMLHttpRequest.prototype.setRequestHeader;\n\n XMLHttpRequest.prototype.setRequestHeader = function (name: string, value: string) {\n let meta = xhrMeta.get(this);\n if (!meta) {\n meta = { reqHeaders: {} };\n xhrMeta.set(this, meta);\n }\n const key = name.toLowerCase();\n meta.reqHeaders[key] = REDACTED_HEADERS.has(key) ? \"[REDACTED]\" : value;\n if (key === \"content-type\") meta.reqContentType = value;\n return origXHRSetHeader!.call(this, name, value);\n };\n\n XMLHttpRequest.prototype.send = function (body?: Document | XMLHttpRequestBodyInit | null) {\n let meta = xhrMeta.get(this);\n if (!meta) {\n meta = { reqHeaders: {} };\n xhrMeta.set(this, meta);\n }\n meta.reqBody = safeBodyPreview(body, MAX_REQUEST_BODY);\n return origXHRSend!.call(this, body);\n };\n\n XMLHttpRequest.prototype.open = function (\n method: string,\n url: string | URL,\n async?: boolean,\n username?: string | null,\n password?: string | null,\n ) {\n const startTime = Date.now();\n const urlStr = typeof url === \"string\" ? url : (url as URL).href;\n // Ensure only one entry per request across load/error/timeout/abort.\n let captured = false;\n\n this.addEventListener(\"load\", () => {\n if (captured) return;\n captured = true;\n if (!shouldIgnore(urlStr, blocked)) {\n const meta = xhrMeta.get(this);\n let resBody: string | undefined;\n try {\n const text = this.responseText;\n resBody =\n text && text.length > maxResponseBody ? text.slice(0, maxResponseBody) + \"\\u2026\" : text || undefined;\n } catch {\n /* ignore */\n }\n push({\n method: method.toUpperCase(),\n url: truncateUrl(urlStr),\n fullUrl: captureFullUrl(urlStr),\n status: this.status,\n statusText: this.statusText || undefined,\n source: \"xhr\",\n duration: Date.now() - startTime,\n timestamp: startTime,\n requestHeaders: meta?.reqHeaders && Object.keys(meta.reqHeaders).length > 0 ? meta.reqHeaders : undefined,\n requestBody: meta?.reqBody,\n requestContentType: meta?.reqContentType,\n responseHeaders: captureHeaders(this.getAllResponseHeaders(), MAX_HEADERS),\n responseBody: resBody,\n responseContentType: this.getResponseHeader(\"content-type\") ?? undefined,\n responseSize: resBody ? resBody.length : undefined,\n });\n }\n });\n\n const pushFailure = (errorMessage: string) => {\n if (captured) return;\n captured = true;\n if (shouldIgnore(urlStr, blocked)) return;\n const meta = xhrMeta.get(this);\n push({\n method: method.toUpperCase(),\n url: truncateUrl(urlStr),\n fullUrl: captureFullUrl(urlStr),\n status: 0,\n source: \"xhr\",\n failed: true,\n errorMessage,\n duration: Date.now() - startTime,\n timestamp: startTime,\n requestHeaders: meta?.reqHeaders && Object.keys(meta.reqHeaders).length > 0 ? meta.reqHeaders : undefined,\n requestBody: meta?.reqBody,\n requestContentType: meta?.reqContentType,\n });\n };\n\n this.addEventListener(\"error\", () => pushFailure(\"Network error\"));\n this.addEventListener(\"timeout\", () => pushFailure(\"Timeout\"));\n this.addEventListener(\"abort\", () => pushFailure(\"Aborted\"));\n\n return origXHROpen!.apply(this, [method, url, async ?? true, username, password] as Parameters<\n typeof XMLHttpRequest.prototype.open\n >);\n };\n\n // -- PerformanceObserver fallback --\n // Catches requests that bypass the fetch/XHR patch (e.g. apps that captured\n // fetch before init). Resource timing has no body/headers, so perf entries\n // are best-effort and de-duplicated against fetch/XHR captures by URL.\n if (typeof PerformanceObserver !== \"undefined\") {\n try {\n perfObserver = new PerformanceObserver((list) => {\n for (const entry of list.getEntries()) {\n const res = entry as PerformanceResourceTiming;\n if (res.initiatorType !== \"fetch\" && res.initiatorType !== \"xmlhttprequest\") continue;\n const url = res.name;\n if (shouldIgnore(url, blocked)) continue;\n if (seenUrls.has(captureFullUrl(url)) || seenUrls.has(truncateUrl(url))) continue;\n push({\n // Resource timing does not expose the HTTP method; default to GET.\n method: \"GET\",\n url: truncateUrl(url),\n fullUrl: captureFullUrl(url),\n status: (res as { responseStatus?: number }).responseStatus ?? 0,\n source: \"perf\",\n duration: Math.round(res.duration),\n timestamp: Math.round(performance.timeOrigin + res.startTime),\n responseSize: res.transferSize || res.encodedBodySize || undefined,\n });\n }\n });\n perfObserver.observe({ type: \"resource\", buffered: true });\n } catch {\n perfObserver = null;\n }\n }\n },\n\n stop() {\n if (!active) return;\n active = false;\n if (origFetch) window.fetch = origFetch;\n if (origXHROpen) XMLHttpRequest.prototype.open = origXHROpen;\n if (origXHRSend) XMLHttpRequest.prototype.send = origXHRSend;\n if (origXHRSetHeader) XMLHttpRequest.prototype.setRequestHeader = origXHRSetHeader;\n if (perfObserver) {\n perfObserver.disconnect();\n perfObserver = null;\n }\n },\n\n getEntries() {\n return [...entries];\n },\n };\n}\n","/**\n * Rolling buffer for rrweb replay events.\n *\n * rrweb playback requires the event stream to begin with a Meta + FullSnapshot\n * (\"checkout\"). A naive time-window trim can strip that opening snapshot and\n * leave the player with orphaned incremental mutations it can't render.\n *\n * When the recorder signals checkouts (via `isCheckout`), this buffer trims by\n * *segment* instead of by time: it always retains the current checkout segment\n * plus the previous one, so the buffer never starts mid-stream. Recorders that\n * never signal a checkout fall back to the legacy time-window trim.\n */\nexport interface ReplayBuffer {\n push(event: unknown, isCheckout?: boolean): void;\n getEvents(): unknown[];\n}\n\nexport function createReplayBuffer(replayBufferMs: number, now: () => number = Date.now): ReplayBuffer {\n const events: unknown[] = [];\n let checkoutSeen = false;\n // Index where the most recent checkout segment begins.\n let recentCheckoutIdx = 0;\n\n return {\n push(event: unknown, isCheckout?: boolean) {\n if (isCheckout) {\n checkoutSeen = true;\n if (events.length > 0) {\n // Drop the oldest retained segment, keeping previous + current.\n events.splice(0, recentCheckoutIdx);\n recentCheckoutIdx = events.length;\n }\n }\n events.push(event);\n\n if (!checkoutSeen) {\n // Legacy recorders (no checkout signalling): trim by time window.\n const cutoff = now() - replayBufferMs;\n while (events.length > 0 && (events[0] as { timestamp: number }).timestamp < cutoff) {\n events.shift();\n }\n }\n },\n getEvents() {\n return [...events];\n },\n };\n}\n","import type { FormErrorCollector } from \"./collectors/formErrors.js\";\nimport type { FlintUser } from \"./types.js\";\n\nexport interface FlintState {\n user: FlintUser | undefined;\n sessionReplay: string | (() => string) | undefined;\n}\n\n// Holds a reference to the active form error collector so flint.reportFormError\n// can forward calls without the consumer needing to manage the collector.\nlet formErrorCollectorRef: FormErrorCollector | null = null;\n\nexport function _setFormErrorCollector(collector: FormErrorCollector | null) {\n formErrorCollectorRef = collector;\n}\n\nlet state: FlintState = { user: undefined, sessionReplay: undefined };\nconst listeners = new Set<() => void>();\n\nfunction emit() {\n for (const l of listeners) l();\n}\n\nexport function subscribe(listener: () => void) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n}\n\nexport function getSnapshot(): FlintState {\n return state;\n}\n\n/** @internal Use Flint.setUser() / Flint.setSessionReplay() / Flint.reportFormError() instead */\nexport const flint = {\n setUser(user: FlintUser | null) {\n state = { ...state, user: user ?? undefined };\n emit();\n },\n setSessionReplay(url: string | (() => string) | null) {\n state = { ...state, sessionReplay: url ?? undefined };\n emit();\n },\n\n /**\n * Report a form validation failure with exact field-level errors.\n * Call this from your form library's error callback.\n *\n * @example\n * // React Hook Form + Zod\n * const onSubmit = handleSubmit(onValid, (errors) => {\n * flint.reportFormError('checkout-form', errors);\n * });\n */\n reportFormError(formId: string, errors: Record<string, { message?: string } | undefined>) {\n formErrorCollectorRef?.report(formId, errors);\n },\n};\n","// Flint singleton — manages global collector lifecycle\nimport { submitReport } from \"./api.js\";\nimport type { ConsoleCollector } from \"./collectors/console.js\";\nimport { createConsoleCollector } from \"./collectors/console.js\";\nimport { collectEnvironment } from \"./collectors/environment.js\";\nimport type { ErrorCaptureCollector } from \"./collectors/errorCapture.js\";\nimport { createErrorCaptureCollector } from \"./collectors/errorCapture.js\";\nimport type { FormErrorCollector } from \"./collectors/formErrors.js\";\nimport { createFormErrorCollector } from \"./collectors/formErrors.js\";\nimport type { FrustrationCollector } from \"./collectors/frustration.js\";\nimport { createFrustrationCollector } from \"./collectors/frustration.js\";\nimport type { NetworkCollector } from \"./collectors/network.js\";\nimport { createNetworkCollector } from \"./collectors/network.js\";\nimport { createReplayBuffer, type ReplayBuffer } from \"./replayBuffer.js\";\nimport { _setFormErrorCollector, flint, getSnapshot } from \"./store.js\";\nimport type { CollectedMeta, FlintConfig } from \"./types.js\";\n\nconst DEFAULT_REPLAY_BUFFER_MS = 60_000;\n\ninterface FlintInstance {\n config: FlintConfig;\n console: ConsoleCollector | null;\n network: NetworkCollector | null;\n formErrors: FormErrorCollector | null;\n frustration: FrustrationCollector | null;\n errorCapture: ErrorCaptureCollector | null;\n replayBuffer: ReplayBuffer;\n stopReplay: (() => void) | null;\n}\n\nlet instance: FlintInstance | null = null;\n\nfunction debugLog(config: FlintConfig, ...args: unknown[]) {\n if (config.debug) console.log(\"[Flint]\", ...args);\n}\n\nfunction init(config: FlintConfig): void {\n if (instance) {\n console.warn(\"[Flint] Already initialized. Call Flint.shutdown() first to re-initialize.\");\n return;\n }\n\n const {\n enableConsole = true,\n enableNetwork = true,\n enableFormErrors = true,\n enableFrustration = false,\n autoReportFrustration = false,\n enableErrorMonitoring = true,\n errorMonitoring: errorMonitoringOpts,\n enableReplay = false,\n replayBufferMs = DEFAULT_REPLAY_BUFFER_MS,\n blockedHosts = [],\n frustration: frustrationOpts,\n onFrustration,\n _replayRecorder,\n _collectors,\n } = config;\n\n debugLog(config, \"Initializing\", {\n serverUrl: config.serverUrl,\n enableConsole,\n enableNetwork,\n enableFormErrors,\n enableFrustration,\n enableReplay,\n });\n\n // Determine Flint server host to block from network capture\n const flintHost = (() => {\n try {\n return new URL(config.serverUrl).hostname;\n } catch {\n return \"\";\n }\n })();\n\n const allBlockedHosts = [...blockedHosts, ...(flintHost ? [flintHost] : [])];\n\n // Create and start collectors (use injected factories if provided, e.g. React Native)\n const consoleCol = enableConsole ? (_collectors?.console?.() ?? createConsoleCollector()) : null;\n consoleCol?.start();\n\n const networkCol = enableNetwork\n ? (_collectors?.network?.(allBlockedHosts) ?? createNetworkCollector(allBlockedHosts))\n : null;\n networkCol?.start();\n\n const formErrorsCol = enableFormErrors ? createFormErrorCollector() : null;\n if (formErrorsCol) {\n formErrorsCol.start();\n _setFormErrorCollector(formErrorsCol);\n }\n\n const frustrationCol = enableFrustration ? createFrustrationCollector(frustrationOpts) : null;\n frustrationCol?.start();\n\n const errorCaptureCol = enableErrorMonitoring\n ? createErrorCaptureCollector({\n serverUrl: config.serverUrl,\n projectKey: config.projectKey,\n release: config.release,\n appVersion: config.appVersion,\n debug: config.debug,\n sampleRate: errorMonitoringOpts?.sampleRate,\n ignoreErrors: errorMonitoringOpts?.ignoreErrors,\n beforeSend: errorMonitoringOpts?.beforeSend,\n getUser: () => getSnapshot().user ?? config.user,\n getBreadcrumbs: () => ({\n consoleLogs: consoleCol?.getEntries() ?? [],\n networkErrors: networkCol?.getEntries() ?? [],\n }),\n getEnvironment: _collectors?.environment ?? collectEnvironment,\n })\n : null;\n errorCaptureCol?.start();\n\n // Set user if provided\n if (config.user) {\n flint.setUser(config.user);\n }\n\n const replayBuffer = createReplayBuffer(replayBufferMs);\n let stopReplay: (() => void) | null = null;\n\n debugLog(config, \"Collectors started\", {\n console: !!consoleCol,\n network: !!networkCol,\n formErrors: !!formErrorsCol,\n frustration: !!frustrationCol,\n errorCapture: !!errorCaptureCol,\n });\n\n instance = {\n config,\n console: consoleCol,\n network: networkCol,\n formErrors: formErrorsCol,\n frustration: frustrationCol,\n errorCapture: errorCaptureCol,\n replayBuffer,\n stopReplay: null,\n };\n\n // Start replay recording (async, via injected recorder). The buffer keeps the\n // stream playable (always starting at a checkout) — see createReplayBuffer.\n if (enableReplay && _replayRecorder) {\n _replayRecorder((event: unknown, isCheckout?: boolean) => {\n replayBuffer.push(event, isCheckout);\n }).then((stop) => {\n stopReplay = stop ?? null;\n if (instance) instance.stopReplay = stopReplay;\n });\n }\n\n // Wire frustration auto-report\n const getEnvironment = _collectors?.environment ?? collectEnvironment;\n if (frustrationCol && autoReportFrustration) {\n frustrationCol.onFrustration(async (event) => {\n debugLog(config, \"Frustration detected, auto-reporting:\", event.type, event.details);\n onFrustration?.(event);\n const user = getSnapshot().user ?? config.user;\n await submitReport(config.serverUrl, config.projectKey, {\n reporterId: user?.id ?? \"anonymous\",\n reporterName: user?.name ?? \"Anonymous\",\n reporterEmail: user?.email,\n description: `[Auto-detected] ${event.type.replace(/_/g, \" \")}: ${event.details}`,\n severity: event.type === \"error_loop\" ? \"P1\" : event.type === \"rage_click\" ? \"P2\" : \"P3\",\n url: event.url,\n source: \"auto_capture\",\n appVersion: config.appVersion,\n release: config.release,\n meta: {\n ...config.meta,\n environment: getEnvironment(),\n consoleLogs: consoleCol?.getEntries() ?? [],\n networkErrors: networkCol?.getEntries() ?? [],\n formErrors: formErrorsCol?.getEntries() ?? [],\n frustrationEvent: event,\n },\n }).catch(() => {});\n });\n } else if (frustrationCol && onFrustration) {\n frustrationCol.onFrustration(onFrustration);\n }\n\n // Auto-fetch remote integrations config if no externalReplayProvider was set\n if (!config.externalReplayProvider) {\n fetchProjectConfig(config.serverUrl, config.projectKey)\n .then((remote) => {\n if (!instance || !remote?.integrations) return;\n const dd = remote.integrations.datadog;\n if (dd?.enabled && dd.site) {\n // Lazy-import to avoid bundling datadog helper when not needed\n import(\"./integrations/datadog.js\").then(({ createDatadogReplayProvider }) => {\n if (!instance) return;\n instance.config = {\n ...instance.config,\n externalReplayProvider: createDatadogReplayProvider(dd.site as string),\n };\n debugLog(config, \"Remote Datadog integration loaded:\", dd.site);\n });\n }\n })\n .catch(() => {\n // Fail silently — remote config is optional\n });\n }\n}\n\n/** Fetch project integrations config from the server. */\nasync function fetchProjectConfig(\n serverUrl: string,\n projectKey: string,\n): Promise<{ integrations: Record<string, { enabled: boolean; [k: string]: unknown }> } | null> {\n try {\n const url = `${serverUrl.replace(/\\/$/, \"\")}/api/v1/project-config`;\n const res = await fetch(url, { headers: { \"x-project-key\": projectKey } });\n if (!res.ok) return null;\n return res.json();\n } catch {\n return null;\n }\n}\n\nfunction shutdown(): void {\n if (!instance) return;\n\n instance.console?.stop();\n instance.network?.stop();\n instance.formErrors?.stop();\n _setFormErrorCollector(null);\n instance.frustration?.stop();\n instance.errorCapture?.stop();\n instance.stopReplay?.();\n instance = null;\n}\n\nfunction isInitialized(): boolean {\n return instance !== null;\n}\n\nfunction getInstance(): FlintInstance | null {\n return instance;\n}\n\nfunction getMeta(extraMeta?: Record<string, unknown>): CollectedMeta {\n const getEnvironment = instance?.config._collectors?.environment ?? collectEnvironment;\n return {\n ...extraMeta,\n environment: getEnvironment(),\n consoleLogs: instance?.console?.getEntries() ?? [],\n networkErrors: instance?.network?.getEntries() ?? [],\n formErrors: instance?.formErrors?.getEntries() ?? [],\n };\n}\n\nfunction getReplayEvents(): unknown[] {\n return instance ? instance.replayBuffer.getEvents() : [];\n}\n\nfunction getConfig(): FlintConfig | null {\n return instance?.config ?? null;\n}\n\nfunction getExternalReplayUrl(): string | undefined {\n // 1. Store value (set via Flint.setSessionReplay)\n const storeReplay = getSnapshot().sessionReplay;\n const fromStore = typeof storeReplay === \"function\" ? storeReplay() : storeReplay;\n if (fromStore) return fromStore;\n // 2. Config provider (e.g. createDatadogReplayProvider)\n return instance?.config.externalReplayProvider?.();\n}\n\nexport const Flint = {\n init,\n shutdown,\n isInitialized,\n getInstance,\n getMeta,\n getReplayEvents,\n getConfig,\n getExternalReplayUrl,\n setUser: flint.setUser,\n setSessionReplay: flint.setSessionReplay,\n reportFormError: flint.reportFormError,\n};\n","import type { Theme, ThemeOverride } from \"./types.js\";\n\nexport interface ResolvedTheme {\n background: string;\n backgroundSecondary: string;\n accent: string;\n accentHover: string;\n text: string;\n textMuted: string;\n border: string;\n shadow: string;\n buttonText: string;\n backdropFilter: string;\n}\n\nconst light: ResolvedTheme = {\n background: \"rgba(255,255,255,0.90)\",\n backgroundSecondary: \"rgba(249,250,251,0.75)\",\n accent: \"#2563eb\",\n accentHover: \"#1d4ed8\",\n text: \"#111827\",\n textMuted: \"#6b7280\",\n border: \"rgba(255,255,255,0.9)\",\n shadow: \"0 32px 80px rgba(0,0,0,0.18), 0 8px 32px rgba(0,0,0,0.1), 0 0 0 1px rgba(0,0,0,0.04)\",\n buttonText: \"#ffffff\",\n backdropFilter: \"blur(32px) saturate(1.8)\",\n};\n\nconst dark: ResolvedTheme = {\n background: \"rgba(15,20,35,0.88)\",\n backgroundSecondary: \"rgba(5,8,18,0.65)\",\n accent: \"#4d8aff\",\n accentHover: \"#3b6fdb\",\n text: \"#dde3ef\",\n textMuted: \"#6b7a93\",\n border: \"rgba(255,255,255,0.08)\",\n shadow: \"0 24px 60px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.04)\",\n buttonText: \"#ffffff\",\n backdropFilter: \"blur(32px) saturate(1.6)\",\n};\n\nexport function resolveTheme(theme: Theme): ResolvedTheme {\n if (theme === \"dark\") return dark;\n if (theme === \"light\") return light;\n // ThemeOverride — merge over light base\n const override = theme as ThemeOverride;\n return {\n ...light,\n background: override.background ?? light.background,\n accent: override.accent ?? light.accent,\n accentHover: override.accent ?? light.accentHover,\n text: override.text ?? light.text,\n border: override.border ?? light.border,\n };\n}\n"],"mappings":"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","names":["init","debugLog","MAX_ENTRIES","window","listeners","emit","MAX_ENTRIES","init","createDatadogReplayProvider"]}
|