@tell-rs/browser 0.2.8 → 0.3.2

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.js CHANGED
@@ -31,6 +31,8 @@ var DEFAULTS = {
31
31
  maxQueueSize: 1e3,
32
32
  sessionTimeout: 18e5,
33
33
  // 30 min
34
+ maxSessionLength: 864e5,
35
+ // 24 hours
34
36
  persistence: "localStorage",
35
37
  respectDoNotTrack: false,
36
38
  botDetection: true,
@@ -263,20 +265,41 @@ function captureUtm() {
263
265
  }
264
266
 
265
267
  // src/session.ts
268
+ var SESSION_ID_KEY = "tell_session_id";
269
+ var SESSION_TS_KEY = "tell_session_ts";
270
+ var SESSION_START_KEY = "tell_session_start";
271
+ var PERSIST_INTERVAL = 6e4;
266
272
  var SessionManager = class {
267
273
  _sessionId;
268
274
  lastHiddenAt = 0;
269
275
  lastActivityAt;
276
+ sessionStartedAt;
277
+ lastPersistedAt = 0;
270
278
  timeout;
279
+ maxLength;
280
+ storage;
271
281
  onNewSession;
272
282
  visibilityHandler;
273
- lastContextAt = {};
274
283
  constructor(config) {
275
284
  this.timeout = config.timeout;
285
+ this.maxLength = config.maxLength;
286
+ this.storage = config.storage;
276
287
  this.onNewSession = config.onNewSession;
277
- this._sessionId = generateId();
278
- this.lastActivityAt = Date.now();
279
- this.emitContext("session_start");
288
+ const now = Date.now();
289
+ const storedId = this.storage.get(SESSION_ID_KEY);
290
+ const storedTs = Number(this.storage.get(SESSION_TS_KEY) || 0);
291
+ const storedStart = Number(this.storage.get(SESSION_START_KEY) || 0);
292
+ if (storedId && storedTs > 0 && storedStart > 0 && now - storedTs < this.timeout && now - storedStart < this.maxLength) {
293
+ this._sessionId = storedId;
294
+ this.lastActivityAt = storedTs;
295
+ this.sessionStartedAt = storedStart;
296
+ } else {
297
+ this._sessionId = generateId();
298
+ this.lastActivityAt = now;
299
+ this.sessionStartedAt = now;
300
+ this.persist();
301
+ this.onNewSession("session_start", this._sessionId);
302
+ }
280
303
  this.visibilityHandler = () => this.handleVisibility();
281
304
  if (typeof document !== "undefined") {
282
305
  document.addEventListener("visibilitychange", this.visibilityHandler);
@@ -287,14 +310,21 @@ var SessionManager = class {
287
310
  }
288
311
  set sessionId(id) {
289
312
  this._sessionId = id;
313
+ const now = Date.now();
314
+ this.lastActivityAt = now;
315
+ this.sessionStartedAt = now;
316
+ this.persist();
290
317
  }
291
- /** Update activity timestamp; rotates session if idle longer than timeout. */
318
+ /** Update activity timestamp; rotates session if idle longer than timeout or exceeds max length. */
292
319
  touch() {
293
320
  const now = Date.now();
294
- if (now - this.lastActivityAt > this.timeout) {
321
+ if (now - this.lastActivityAt > this.timeout || now - this.sessionStartedAt > this.maxLength) {
295
322
  this.rotateSession("session_timeout");
296
323
  }
297
324
  this.lastActivityAt = now;
325
+ if (now - this.lastPersistedAt >= PERSIST_INTERVAL) {
326
+ this.persistActivity();
327
+ }
298
328
  }
299
329
  destroy() {
300
330
  if (typeof document !== "undefined") {
@@ -305,26 +335,31 @@ var SessionManager = class {
305
335
  if (document.visibilityState === "hidden") {
306
336
  this.lastHiddenAt = Date.now();
307
337
  } else if (document.visibilityState === "visible") {
308
- if (this.lastHiddenAt > 0 && Date.now() - this.lastHiddenAt > this.timeout) {
338
+ const now = Date.now();
339
+ if (this.lastHiddenAt > 0 && (now - this.lastHiddenAt > this.timeout || now - this.sessionStartedAt > this.maxLength)) {
309
340
  this.rotateSession("session_timeout");
310
- } else if (this.lastHiddenAt > 0) {
311
- this.emitContext("app_foreground");
312
341
  }
313
342
  this.lastHiddenAt = 0;
314
343
  }
315
344
  }
316
345
  rotateSession(reason) {
317
346
  this._sessionId = generateId();
318
- this.lastActivityAt = Date.now();
319
- this.emitContext(reason);
320
- }
321
- emitContext(reason) {
322
347
  const now = Date.now();
323
- const last = this.lastContextAt[reason] ?? 0;
324
- if (now - last < 1e3) return;
325
- this.lastContextAt[reason] = now;
348
+ this.lastActivityAt = now;
349
+ this.sessionStartedAt = now;
350
+ this.persist();
326
351
  this.onNewSession(reason, this._sessionId);
327
352
  }
353
+ persist() {
354
+ this.storage.set(SESSION_ID_KEY, this._sessionId);
355
+ this.storage.set(SESSION_TS_KEY, String(this.lastActivityAt));
356
+ this.storage.set(SESSION_START_KEY, String(this.sessionStartedAt));
357
+ this.lastPersistedAt = Date.now();
358
+ }
359
+ persistActivity() {
360
+ this.storage.set(SESSION_TS_KEY, String(this.lastActivityAt));
361
+ this.lastPersistedAt = Date.now();
362
+ }
328
363
  };
329
364
 
330
365
  // src/transport.ts
@@ -646,6 +681,8 @@ var tell = {
646
681
  });
647
682
  sessionManager = new SessionManager({
648
683
  timeout: resolvedConfig.sessionTimeout,
684
+ maxLength: resolvedConfig.maxSessionLength,
685
+ storage,
649
686
  onNewSession
650
687
  });
651
688
  if (typeof window !== "undefined") {
@@ -665,7 +702,7 @@ var tell = {
665
702
  if (event.lineno) data.lineno = event.lineno;
666
703
  if (event.colno) data.colno = event.colno;
667
704
  if (event.error?.stack) data.stack = event.error.stack;
668
- tell.logError(msg, "browser", data);
705
+ tell.logError(msg, data);
669
706
  };
670
707
  rejectionHandler = (event) => {
671
708
  if (_disabled || _optedOut || closed) return;
@@ -673,7 +710,7 @@ var tell = {
673
710
  const msg = reason instanceof Error ? reason.message : String(reason ?? "Unhandled promise rejection");
674
711
  const data = {};
675
712
  if (reason instanceof Error && reason.stack) data.stack = reason.stack;
676
- tell.logError(msg, "browser", data);
713
+ tell.logError(msg, data);
677
714
  };
678
715
  window.addEventListener("error", errorHandler);
679
716
  window.addEventListener("unhandledrejection", rejectionHandler);
@@ -866,9 +903,9 @@ var tell = {
866
903
  // -----------------------------------------------------------------------
867
904
  // Logging
868
905
  // -----------------------------------------------------------------------
869
- log(level, message, service, data) {
906
+ log(level, message, data) {
870
907
  if (!configured) {
871
- queue.push({ method: "log", args: [level, message, service, data] });
908
+ queue.push({ method: "log", args: [level, message, data] });
872
909
  return;
873
910
  }
874
911
  if (_disabled || _optedOut) return;
@@ -886,7 +923,7 @@ var tell = {
886
923
  level,
887
924
  message,
888
925
  source: resolvedConfig.source,
889
- service: service ?? resolvedService,
926
+ service: resolvedService,
890
927
  session_id: sessionManager.sessionId,
891
928
  timestamp: Date.now(),
892
929
  data
@@ -897,32 +934,32 @@ var tell = {
897
934
  }
898
935
  logBatcher.add(logEntry);
899
936
  },
900
- logEmergency(message, service, data) {
901
- tell.log("emergency", message, service, data);
937
+ logEmergency(message, data) {
938
+ tell.log("emergency", message, data);
902
939
  },
903
- logAlert(message, service, data) {
904
- tell.log("alert", message, service, data);
940
+ logAlert(message, data) {
941
+ tell.log("alert", message, data);
905
942
  },
906
- logCritical(message, service, data) {
907
- tell.log("critical", message, service, data);
943
+ logCritical(message, data) {
944
+ tell.log("critical", message, data);
908
945
  },
909
- logError(message, service, data) {
910
- tell.log("error", message, service, data);
946
+ logError(message, data) {
947
+ tell.log("error", message, data);
911
948
  },
912
- logWarning(message, service, data) {
913
- tell.log("warning", message, service, data);
949
+ logWarning(message, data) {
950
+ tell.log("warning", message, data);
914
951
  },
915
- logNotice(message, service, data) {
916
- tell.log("notice", message, service, data);
952
+ logNotice(message, data) {
953
+ tell.log("notice", message, data);
917
954
  },
918
- logInfo(message, service, data) {
919
- tell.log("info", message, service, data);
955
+ logInfo(message, data) {
956
+ tell.log("info", message, data);
920
957
  },
921
- logDebug(message, service, data) {
922
- tell.log("debug", message, service, data);
958
+ logDebug(message, data) {
959
+ tell.log("debug", message, data);
923
960
  },
924
- logTrace(message, service, data) {
925
- tell.log("trace", message, service, data);
961
+ logTrace(message, data) {
962
+ tell.log("trace", message, data);
926
963
  },
927
964
  // -----------------------------------------------------------------------
928
965
  // Super Properties
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config.ts","../src/persistence.ts","../src/id.ts","../src/bot.ts","../src/context.ts","../src/utm.ts","../src/session.ts","../src/transport.ts","../src/queue.ts","../src/index.ts"],"sourcesContent":["import type { TellError, BeforeSendFn, JsonEvent, JsonLog } from \"@tell-rs/core\";\n\nexport interface TellBrowserConfig {\n /** Service name stamped on every event and log. Defaults to window.location.hostname. */\n service?: string;\n endpoint?: string;\n batchSize?: number;\n flushInterval?: number;\n maxRetries?: number;\n closeTimeout?: number;\n networkTimeout?: number;\n logLevel?: \"error\" | \"warn\" | \"info\" | \"debug\";\n source?: string;\n onError?: (error: TellError) => void;\n disabled?: boolean;\n maxQueueSize?: number;\n sessionTimeout?: number;\n persistence?: \"localStorage\" | \"memory\";\n respectDoNotTrack?: boolean;\n botDetection?: boolean;\n captureErrors?: boolean;\n beforeSend?: BeforeSendFn<JsonEvent> | BeforeSendFn<JsonEvent>[];\n beforeSendLog?: BeforeSendFn<JsonLog> | BeforeSendFn<JsonLog>[];\n}\n\nexport const DEFAULTS = {\n endpoint: \"https://collect.tell.app\",\n batchSize: 20,\n flushInterval: 5_000,\n maxRetries: 5,\n closeTimeout: 5_000,\n networkTimeout: 10_000,\n logLevel: \"error\" as const,\n source: \"browser\",\n disabled: false,\n maxQueueSize: 1000,\n sessionTimeout: 1_800_000, // 30 min\n persistence: \"localStorage\" as const,\n respectDoNotTrack: false,\n botDetection: true,\n captureErrors: false,\n} as const;\n\nexport type ResolvedBrowserConfig = Required<\n Omit<TellBrowserConfig, \"onError\" | \"beforeSend\" | \"beforeSendLog\">\n> &\n Pick<TellBrowserConfig, \"onError\" | \"beforeSend\" | \"beforeSendLog\">;\n\nexport function resolveConfig(\n options: TellBrowserConfig | undefined\n): ResolvedBrowserConfig {\n return { ...DEFAULTS, ...options } as ResolvedBrowserConfig;\n}\n\n/** Development preset: localhost, small batches, fast flush, debug logging. */\nexport function development(\n overrides?: Partial<TellBrowserConfig>\n): TellBrowserConfig {\n return {\n endpoint: \"http://localhost:8080\",\n batchSize: 5,\n flushInterval: 2_000,\n logLevel: \"debug\",\n ...overrides,\n };\n}\n\n/** Production preset: default endpoint, error-only logging. */\nexport function production(\n overrides?: Partial<TellBrowserConfig>\n): TellBrowserConfig {\n return {\n logLevel: \"error\",\n ...overrides,\n };\n}\n","export interface TellStorage {\n get(key: string): string | null;\n set(key: string, value: string): void;\n remove(key: string): void;\n}\n\nexport const STORAGE_KEYS = {\n DEVICE_ID: \"tell_device_id\",\n USER_ID: \"tell_user_id\",\n OPT_OUT: \"tell_opt_out\",\n SUPER_PROPS: \"tell_super_props\",\n} as const;\n\nclass LocalStorageStorage implements TellStorage {\n get(key: string): string | null {\n try {\n return localStorage.getItem(key);\n } catch {\n return null;\n }\n }\n\n set(key: string, value: string): void {\n try {\n localStorage.setItem(key, value);\n } catch {\n // Safari private mode or quota exceeded\n }\n }\n\n remove(key: string): void {\n try {\n localStorage.removeItem(key);\n } catch {\n // ignore\n }\n }\n}\n\nclass MemoryStorage implements TellStorage {\n private data = new Map<string, string>();\n\n get(key: string): string | null {\n return this.data.get(key) ?? null;\n }\n\n set(key: string, value: string): void {\n this.data.set(key, value);\n }\n\n remove(key: string): void {\n this.data.delete(key);\n }\n}\n\n/** Create a storage backend. Falls back to memory if localStorage is unavailable. */\nexport function createStorage(\n persistence: \"localStorage\" | \"memory\"\n): TellStorage {\n if (persistence === \"localStorage\" && typeof localStorage !== \"undefined\") {\n try {\n const testKey = \"tell_test\";\n localStorage.setItem(testKey, \"1\");\n localStorage.removeItem(testKey);\n return new LocalStorageStorage();\n } catch {\n // probe failed — fall through to memory\n }\n }\n return new MemoryStorage();\n}\n","/** Generate a 32-char hex ID (16 random bytes) using crypto.getRandomValues. */\nexport function generateId(): string {\n if (typeof crypto !== \"undefined\" && crypto.getRandomValues) {\n const bytes = new Uint8Array(16);\n crypto.getRandomValues(bytes);\n return Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n }\n\n // Fallback for environments without crypto (extremely rare)\n let hex = \"\";\n for (let i = 0; i < 32; i++) {\n hex += ((Math.random() * 16) | 0).toString(16);\n }\n return hex;\n}\n","/** Returns true if the current environment appears to be an automated bot. */\nexport function isBot(): boolean {\n if (typeof navigator === \"undefined\") return false;\n if ((navigator as any).webdriver === true) return true;\n const ua = navigator.userAgent || \"\";\n return /headless/i.test(ua);\n}\n","export interface DeviceContext {\n browser?: string;\n browser_version?: string;\n os_name?: string;\n os_version?: string;\n device_type?: string;\n screen_width?: number;\n screen_height?: number;\n viewport_width?: number;\n viewport_height?: number;\n device_pixel_ratio?: number;\n locale?: string;\n timezone?: string;\n referrer?: string;\n referrer_domain?: string;\n url?: string;\n title?: string;\n connection_type?: string;\n downlink?: number;\n rtt?: number;\n save_data?: boolean;\n cpu_cores?: number;\n device_memory?: number;\n touch?: boolean;\n bot?: boolean;\n dark_mode?: boolean;\n path?: string;\n screen_orientation?: string;\n}\n\n/** Capture a snapshot of the current device/browser context. */\nexport function captureContext(): DeviceContext {\n const ctx: DeviceContext = {};\n\n if (typeof navigator !== \"undefined\") {\n const ua = navigator.userAgent || \"\";\n const parsed = parseUA(ua);\n ctx.browser = parsed.browser;\n ctx.browser_version = parsed.browserVersion;\n ctx.os_name = parsed.os;\n ctx.os_version = parsed.osVersion;\n ctx.locale = navigator.language;\n\n // Hardware capabilities (touch must come before device_type inference)\n if (\"hardwareConcurrency\" in navigator) {\n ctx.cpu_cores = (navigator as any).hardwareConcurrency;\n }\n if (\"deviceMemory\" in navigator) {\n ctx.device_memory = (navigator as any).deviceMemory;\n }\n if (\"maxTouchPoints\" in navigator) {\n ctx.touch = navigator.maxTouchPoints > 0;\n }\n\n ctx.device_type = inferDeviceType(parsed.os, ua, ctx.touch);\n\n // Network info (Chrome/Edge)\n const conn = (navigator as any).connection;\n if (conn) {\n if (conn.effectiveType) ctx.connection_type = conn.effectiveType;\n if (typeof conn.downlink === \"number\") ctx.downlink = conn.downlink;\n if (typeof conn.rtt === \"number\") ctx.rtt = conn.rtt;\n if (conn.saveData) ctx.save_data = true;\n }\n\n // Bot detection\n if ((navigator as any).webdriver) ctx.bot = true;\n }\n\n if (typeof screen !== \"undefined\") {\n ctx.screen_width = screen.width;\n ctx.screen_height = screen.height;\n const orient = (screen as any).orientation;\n if (orient?.type) ctx.screen_orientation = orient.type;\n }\n\n if (typeof window !== \"undefined\") {\n ctx.viewport_width = window.innerWidth;\n ctx.viewport_height = window.innerHeight;\n if (window.devicePixelRatio) {\n ctx.device_pixel_ratio = window.devicePixelRatio;\n }\n }\n\n if (typeof document !== \"undefined\") {\n ctx.referrer = document.referrer || undefined;\n if (ctx.referrer) {\n try {\n ctx.referrer_domain = new URL(ctx.referrer).hostname;\n } catch {\n // malformed referrer\n }\n }\n ctx.title = document.title || undefined;\n }\n\n if (typeof location !== \"undefined\") {\n ctx.url = location.href;\n if (location.pathname) ctx.path = location.pathname;\n }\n\n try {\n ctx.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n } catch {\n // Intl not available\n }\n\n if (typeof window !== \"undefined\" && window.matchMedia) {\n try {\n ctx.dark_mode = window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n } catch {\n // matchMedia not available\n }\n }\n\n return ctx;\n}\n\nfunction inferDeviceType(os?: string, ua?: string, touch?: boolean): string {\n // iPad (iPadOS 13+) reports as macOS but has touch support\n if (os === \"macOS\" && touch) return \"tablet\";\n // Android tablets have \"Android\" in UA but not \"Mobile\"\n if (os === \"Android\") return ua && !/Mobile/.test(ua) ? \"tablet\" : \"mobile\";\n if (os === \"iOS\") return \"mobile\";\n return \"desktop\";\n}\n\ninterface ParsedUA {\n browser?: string;\n browserVersion?: string;\n os?: string;\n osVersion?: string;\n}\n\nfunction parseUA(ua: string): ParsedUA {\n const result: ParsedUA = {};\n\n // Browser detection (order matters: Edge before Chrome, Chrome before Safari)\n if (/Edg\\/(\\d+[\\d.]*)/.test(ua)) {\n result.browser = \"Edge\";\n result.browserVersion = RegExp.$1;\n } else if (/OPR\\/(\\d+[\\d.]*)/.test(ua)) {\n result.browser = \"Opera\";\n result.browserVersion = RegExp.$1;\n } else if (/Chrome\\/(\\d+[\\d.]*)/.test(ua)) {\n result.browser = \"Chrome\";\n result.browserVersion = RegExp.$1;\n } else if (/Safari\\/[\\d.]+/.test(ua) && /Version\\/(\\d+[\\d.]*)/.test(ua)) {\n result.browser = \"Safari\";\n result.browserVersion = RegExp.$1;\n } else if (/Firefox\\/(\\d+[\\d.]*)/.test(ua)) {\n result.browser = \"Firefox\";\n result.browserVersion = RegExp.$1;\n }\n\n // OS detection\n if (/Windows NT ([\\d.]+)/.test(ua)) {\n result.os = \"Windows\";\n result.osVersion = RegExp.$1;\n } else if (/Mac OS X ([\\d_.]+)/.test(ua)) {\n result.os = \"macOS\";\n result.osVersion = RegExp.$1.replace(/_/g, \".\");\n } else if (/iPhone OS ([\\d_]+)/.test(ua)) {\n result.os = \"iOS\";\n result.osVersion = RegExp.$1.replace(/_/g, \".\");\n } else if (/Android ([\\d.]+)/.test(ua)) {\n result.os = \"Android\";\n result.osVersion = RegExp.$1;\n } else if (/Linux/.test(ua)) {\n result.os = \"Linux\";\n }\n\n return result;\n}\n","import type { Properties } from \"@tell-rs/core\";\n\nconst UTM_KEYS = [\n \"utm_source\",\n \"utm_medium\",\n \"utm_campaign\",\n \"utm_term\",\n \"utm_content\",\n] as const;\n\n/**\n * Extract UTM parameters from the current URL search string.\n * Returns only keys that are present and non-empty.\n */\nexport function captureUtm(): Properties {\n if (typeof window === \"undefined\" || !window.location?.search) return {};\n\n const params = new URLSearchParams(window.location.search);\n const utm: Properties = {};\n\n for (const key of UTM_KEYS) {\n const value = params.get(key);\n if (value) {\n utm[key] = value;\n }\n }\n\n return utm;\n}\n","import { generateId } from \"./id.js\";\n\nexport type SessionReason = \"session_start\" | \"session_timeout\" | \"app_foreground\";\n\nexport interface SessionManagerConfig {\n timeout: number; // ms\n onNewSession: (reason: SessionReason, sessionId: string) => void;\n}\n\nexport class SessionManager {\n private _sessionId: string;\n private lastHiddenAt = 0;\n private lastActivityAt: number;\n private readonly timeout: number;\n private readonly onNewSession: (reason: SessionReason, sessionId: string) => void;\n private readonly visibilityHandler: () => void;\n private lastContextAt: Record<string, number> = {};\n\n constructor(config: SessionManagerConfig) {\n this.timeout = config.timeout;\n this.onNewSession = config.onNewSession;\n this._sessionId = generateId();\n this.lastActivityAt = Date.now();\n\n this.emitContext(\"session_start\");\n\n this.visibilityHandler = () => this.handleVisibility();\n if (typeof document !== \"undefined\") {\n document.addEventListener(\"visibilitychange\", this.visibilityHandler);\n }\n }\n\n get sessionId(): string {\n return this._sessionId;\n }\n\n set sessionId(id: string) {\n this._sessionId = id;\n }\n\n /** Update activity timestamp; rotates session if idle longer than timeout. */\n touch(): void {\n const now = Date.now();\n if (now - this.lastActivityAt > this.timeout) {\n this.rotateSession(\"session_timeout\");\n }\n this.lastActivityAt = now;\n }\n\n destroy(): void {\n if (typeof document !== \"undefined\") {\n document.removeEventListener(\"visibilitychange\", this.visibilityHandler);\n }\n }\n\n private handleVisibility(): void {\n if (document.visibilityState === \"hidden\") {\n this.lastHiddenAt = Date.now();\n } else if (document.visibilityState === \"visible\") {\n if (this.lastHiddenAt > 0 && Date.now() - this.lastHiddenAt > this.timeout) {\n this.rotateSession(\"session_timeout\");\n } else if (this.lastHiddenAt > 0) {\n this.emitContext(\"app_foreground\");\n }\n this.lastHiddenAt = 0;\n }\n }\n\n private rotateSession(reason: SessionReason): void {\n this._sessionId = generateId();\n this.lastActivityAt = Date.now();\n this.emitContext(reason);\n }\n\n private emitContext(reason: SessionReason): void {\n const now = Date.now();\n const last = this.lastContextAt[reason] ?? 0;\n if (now - last < 1000) return; // cooldown\n this.lastContextAt[reason] = now;\n this.onNewSession(reason, this._sessionId);\n }\n}\n","import type { JsonEvent, JsonLog } from \"@tell-rs/core\";\nimport { NetworkError } from \"@tell-rs/core\";\n\nexport interface BrowserTransportConfig {\n endpoint: string;\n apiKey: string;\n maxRetries: number;\n networkTimeout: number;\n onError?: (error: Error) => void;\n onPayloadTooLarge?: () => void;\n}\n\nexport class BrowserTransport {\n private readonly endpoint: string;\n private readonly apiKey: string;\n private readonly maxRetries: number;\n private readonly networkTimeout: number;\n private readonly onError?: (error: Error) => void;\n private readonly onPayloadTooLarge?: () => void;\n\n constructor(config: BrowserTransportConfig) {\n this.endpoint = config.endpoint;\n this.apiKey = config.apiKey;\n this.maxRetries = config.maxRetries;\n this.networkTimeout = config.networkTimeout;\n this.onError = config.onError;\n this.onPayloadTooLarge = config.onPayloadTooLarge;\n }\n\n async sendEvents(events: JsonEvent[]): Promise<void> {\n if (events.length === 0) return;\n const body = events.map((e) => JSON.stringify(e)).join(\"\\n\");\n await this.send(\"/v1/events\", body);\n }\n\n async sendLogs(logs: JsonLog[]): Promise<void> {\n if (logs.length === 0) return;\n const body = logs.map((l) => JSON.stringify(l)).join(\"\\n\");\n await this.send(\"/v1/logs\", body);\n }\n\n /** Best-effort flush via sendBeacon for page unload. */\n beacon(events: JsonEvent[], logs: JsonLog[]): void {\n if (typeof navigator === \"undefined\" || !navigator.sendBeacon) return;\n\n if (events.length > 0) {\n const body = events.map((e) => JSON.stringify(e)).join(\"\\n\");\n const blob = new Blob([body], { type: \"text/plain\" });\n const url = `${this.endpoint}/v1/events?token=${encodeURIComponent(this.apiKey)}`;\n navigator.sendBeacon(url, blob);\n }\n\n if (logs.length > 0) {\n const body = logs.map((l) => JSON.stringify(l)).join(\"\\n\");\n const blob = new Blob([body], { type: \"text/plain\" });\n const url = `${this.endpoint}/v1/logs?token=${encodeURIComponent(this.apiKey)}`;\n navigator.sendBeacon(url, blob);\n }\n }\n\n private resolvePort(): string {\n try {\n const u = new URL(this.endpoint);\n if (u.port) return u.port;\n return u.protocol === \"https:\" ? \"443\" : \"80\";\n } catch {\n return \"unknown\";\n }\n }\n\n private async send(path: string, body: string): Promise<void> {\n // Auth via query param + text/plain content-type keeps this a CORS\n // \"simple request\" — no preflight OPTIONS needed. This matches the\n // pattern used by beacon() and by every major analytics SDK.\n const url = `${this.endpoint}${path}?token=${encodeURIComponent(this.apiKey)}`;\n const port = this.resolvePort();\n const headers: Record<string, string> = {\n \"Content-Type\": \"text/plain\",\n };\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n if (attempt > 0) {\n await this.backoff(attempt);\n }\n\n // Skip attempt if browser reports offline\n if (typeof navigator !== \"undefined\" && !navigator.onLine) {\n lastError = new NetworkError(`Browser is offline (endpoint: ${url}, port: ${port})`);\n continue;\n }\n\n const controller = new AbortController();\n const timer = setTimeout(\n () => controller.abort(),\n this.networkTimeout\n );\n\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body,\n signal: controller.signal,\n keepalive: true,\n });\n\n if (response.status === 202) {\n return;\n }\n\n if (response.status === 207) {\n if (this.onError) {\n this.onError(\n new NetworkError(\n `Partial success: some items rejected`,\n 207\n )\n );\n }\n return;\n }\n\n if (response.status === 413) {\n if (this.onPayloadTooLarge) {\n this.onPayloadTooLarge();\n }\n throw new NetworkError(\"Payload too large\", 413);\n }\n\n if (response.status === 401) {\n throw new NetworkError(\"Invalid API key\", 401);\n }\n\n if (response.status >= 400 && response.status < 500) {\n throw new NetworkError(\n `HTTP ${response.status}: ${response.statusText}`,\n response.status\n );\n }\n\n // 5xx — retryable\n lastError = new NetworkError(\n `HTTP ${response.status} from ${url} (port ${port}): ${response.statusText}`,\n response.status\n );\n } catch (err) {\n if (err instanceof NetworkError && err.statusCode === 413) {\n throw err;\n }\n\n if (\n err instanceof NetworkError &&\n err.statusCode &&\n err.statusCode < 500\n ) {\n if (this.onError) this.onError(err);\n return;\n }\n\n // DNS failures, connection refused, and CORS errors surface as\n // TypeError from fetch. Include the full URL so the developer can\n // verify the endpoint and port. These won't resolve by retrying.\n if (err instanceof TypeError) {\n if (this.onError)\n this.onError(\n new NetworkError(\n `Failed to connect to ${url} (port ${port}): ${err.message}`\n )\n );\n return;\n }\n\n lastError =\n err instanceof Error ? err : new NetworkError(String(err));\n } finally {\n clearTimeout(timer);\n }\n }\n\n if (lastError && this.onError) {\n this.onError(lastError);\n }\n }\n\n private backoff(attempt: number): Promise<void> {\n const base = 1000 * Math.pow(1.5, attempt - 1);\n const jitter = base * 0.2 * Math.random();\n const delay = Math.min(base + jitter, 30_000);\n return new Promise((resolve) => setTimeout(resolve, delay));\n }\n}\n","import type { LogLevel, Properties } from \"@tell-rs/core\";\n\nexport type QueuedCall =\n | { method: \"track\"; args: [string, Properties?] }\n | { method: \"identify\"; args: [string, Properties?] }\n | { method: \"group\"; args: [string, Properties?] }\n | { method: \"revenue\"; args: [number, string, string, Properties?] }\n | { method: \"alias\"; args: [string, string] }\n | { method: \"log\"; args: [LogLevel, string, string?, Properties?] }\n | { method: \"register\"; args: [Properties] }\n | { method: \"unregister\"; args: [string] }\n | { method: \"optOut\"; args: [] }\n | { method: \"optIn\"; args: [] };\n\nexport class PreInitQueue {\n private items: QueuedCall[] = [];\n readonly maxSize: number;\n\n constructor(maxSize = 1000) {\n this.maxSize = maxSize;\n }\n\n push(call: QueuedCall): void {\n if (this.items.length >= this.maxSize) {\n this.items.shift(); // drop oldest\n }\n this.items.push(call);\n }\n\n replay(target: Record<string, (...args: any[]) => any>): void {\n const calls = this.items;\n this.items = [];\n for (const call of calls) {\n try {\n target[call.method](...call.args);\n } catch {\n // continue on per-call error\n }\n }\n }\n\n get length(): number {\n return this.items.length;\n }\n\n clear(): void {\n this.items = [];\n }\n}\n","import type {\n JsonEvent,\n JsonLog,\n LogLevel,\n Properties,\n BeforeSendFn,\n} from \"@tell-rs/core\";\nimport {\n ClosedError,\n ConfigurationError,\n ValidationError,\n validateApiKey,\n validateEventName,\n validateLogMessage,\n validateUserId,\n Batcher,\n runBeforeSend,\n} from \"@tell-rs/core\";\n\nimport type { TellBrowserConfig, ResolvedBrowserConfig } from \"./config.js\";\nimport { resolveConfig } from \"./config.js\";\nimport type { TellStorage } from \"./persistence.js\";\nimport { createStorage, STORAGE_KEYS } from \"./persistence.js\";\nimport { generateId } from \"./id.js\";\nimport { isBot } from \"./bot.js\";\nimport { captureContext } from \"./context.js\";\nimport { captureUtm } from \"./utm.js\";\nimport type { SessionReason } from \"./session.js\";\nimport { SessionManager } from \"./session.js\";\nimport { BrowserTransport } from \"./transport.js\";\nimport { PreInitQueue } from \"./queue.js\";\n\n// Re-export core types and values\nexport { Events, type EventName } from \"@tell-rs/core\";\nexport type { Properties, LogLevel, JsonEvent, JsonLog, BeforeSendFn } from \"@tell-rs/core\";\nexport { redact, redactLog, SENSITIVE_PARAMS, type RedactOptions } from \"@tell-rs/core\";\nexport {\n TellError,\n ConfigurationError,\n ValidationError,\n NetworkError,\n ClosedError,\n SerializationError,\n} from \"@tell-rs/core\";\n\n// Re-export browser-specific config\nexport type { TellBrowserConfig } from \"./config.js\";\nexport { development, production } from \"./config.js\";\nexport type { DeviceContext } from \"./context.js\";\n\n// ---------------------------------------------------------------------------\n// Module-level state\n// ---------------------------------------------------------------------------\n\nlet configured = false;\nlet closed = false;\nlet _disabled = false;\nlet _optedOut = false;\n\nlet storage: TellStorage;\nlet transport: BrowserTransport;\nlet eventBatcher: Batcher<JsonEvent>;\nlet logBatcher: Batcher<JsonLog>;\nlet sessionManager: SessionManager;\nlet resolvedConfig: ResolvedBrowserConfig;\n\nlet _apiKey: string;\nlet resolvedService: string;\nlet deviceId: string;\nlet userId: string | undefined;\nlet superProperties: Properties = {};\nlet beforeSend: BeforeSendFn<JsonEvent> | BeforeSendFn<JsonEvent>[] | undefined;\nlet beforeSendLog:\n | BeforeSendFn<JsonLog>\n | BeforeSendFn<JsonLog>[]\n | undefined;\nlet sdkLogLevel: number;\n\nconst queue = new PreInitQueue(1000);\n\nlet unloadHandler: (() => void) | null = null;\nlet visibilityUnloadHandler: (() => void) | null = null;\nlet errorHandler: ((event: ErrorEvent) => void) | null = null;\nlet rejectionHandler: ((event: PromiseRejectionEvent) => void) | null = null;\n\nconst LOG_LEVELS: Record<string, number> = {\n error: 0,\n warn: 1,\n info: 2,\n debug: 3,\n};\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction reportError(err: unknown): void {\n if (resolvedConfig?.onError && err instanceof Error) {\n resolvedConfig.onError(err);\n }\n}\n\nfunction sdkDebug(msg: string): void {\n if (sdkLogLevel >= LOG_LEVELS.debug) {\n console.debug(`[Tell] ${msg}`);\n }\n}\n\nfunction handleUnload(): void {\n const events = eventBatcher.drain();\n const logs = logBatcher.drain();\n transport.beacon(events, logs);\n}\n\nfunction handleVisibilityUnload(): void {\n if (document.visibilityState === \"hidden\") {\n handleUnload();\n }\n}\n\nfunction onNewSession(reason: SessionReason, sessionId: string): void {\n if (_disabled || _optedOut || closed) return;\n const ctx = captureContext();\n const event: JsonEvent = {\n type: \"context\",\n service: resolvedService,\n device_id: deviceId,\n session_id: sessionId,\n user_id: userId,\n timestamp: Date.now(),\n reason,\n ...ctx,\n };\n eventBatcher.add(event);\n}\n\nfunction persistSuperProps(): void {\n storage.set(STORAGE_KEYS.SUPER_PROPS, JSON.stringify(superProperties));\n}\n\nfunction loadSuperProps(): Properties {\n const raw = storage.get(STORAGE_KEYS.SUPER_PROPS);\n if (!raw) return {};\n try {\n return JSON.parse(raw) as Properties;\n } catch {\n storage.remove(STORAGE_KEYS.SUPER_PROPS);\n return {};\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport interface TellInstance {\n configure(apiKey: string, options?: TellBrowserConfig): void;\n track(eventName: string, properties?: Properties): void;\n identify(userId: string, traits?: Properties): void;\n group(groupId: string, properties?: Properties): void;\n revenue(\n amount: number,\n currency: string,\n orderId: string,\n properties?: Properties\n ): void;\n alias(previousId: string, userId: string): void;\n log(\n level: LogLevel,\n message: string,\n service?: string,\n data?: Properties\n ): void;\n logEmergency(message: string, service?: string, data?: Properties): void;\n logAlert(message: string, service?: string, data?: Properties): void;\n logCritical(message: string, service?: string, data?: Properties): void;\n logError(message: string, service?: string, data?: Properties): void;\n logWarning(message: string, service?: string, data?: Properties): void;\n logNotice(message: string, service?: string, data?: Properties): void;\n logInfo(message: string, service?: string, data?: Properties): void;\n logDebug(message: string, service?: string, data?: Properties): void;\n logTrace(message: string, service?: string, data?: Properties): void;\n register(properties: Properties): void;\n unregister(key: string): void;\n optOut(): void;\n optIn(): void;\n isOptedOut(): boolean;\n flush(): Promise<void>;\n close(): Promise<void>;\n reset(): void;\n enable(): void;\n disable(): void;\n /** @internal Reset all module state. Only for testing. */\n _resetForTesting(): void;\n}\n\nconst tell: TellInstance = {\n // -----------------------------------------------------------------------\n // Lifecycle\n // -----------------------------------------------------------------------\n\n configure(apiKey: string, options?: TellBrowserConfig): void {\n if (configured) {\n reportError(new ConfigurationError(\"Tell is already configured\"));\n return;\n }\n\n validateApiKey(apiKey);\n _apiKey = apiKey;\n resolvedConfig = resolveConfig(options);\n resolvedService =\n options?.service ??\n (typeof window !== \"undefined\" ? window.location?.hostname : undefined) ??\n \"browser\";\n sdkLogLevel = LOG_LEVELS[resolvedConfig.logLevel] ?? 0;\n beforeSend = resolvedConfig.beforeSend;\n beforeSendLog = resolvedConfig.beforeSendLog;\n _disabled = resolvedConfig.disabled;\n\n // Persistence\n storage = createStorage(resolvedConfig.persistence);\n deviceId = storage.get(STORAGE_KEYS.DEVICE_ID) ?? generateId();\n storage.set(STORAGE_KEYS.DEVICE_ID, deviceId);\n userId = storage.get(STORAGE_KEYS.USER_ID) ?? undefined;\n _optedOut = storage.get(STORAGE_KEYS.OPT_OUT) === \"1\";\n superProperties = loadSuperProps();\n\n // UTM parameters — capture from URL and merge into super properties\n const utm = captureUtm();\n if (Object.keys(utm).length > 0) {\n Object.assign(superProperties, utm);\n persistSuperProps();\n }\n\n // Bot detection\n if (resolvedConfig.botDetection && isBot()) {\n _disabled = true;\n sdkDebug(\"bot detected, disabling\");\n }\n\n // Do Not Track\n if (\n resolvedConfig.respectDoNotTrack &&\n typeof navigator !== \"undefined\" &&\n navigator.doNotTrack === \"1\"\n ) {\n _disabled = true;\n sdkDebug(\"Do Not Track enabled, disabling\");\n }\n\n // Transport\n transport = new BrowserTransport({\n endpoint: resolvedConfig.endpoint,\n apiKey: _apiKey,\n maxRetries: resolvedConfig.maxRetries,\n networkTimeout: resolvedConfig.networkTimeout,\n onError: resolvedConfig.onError,\n onPayloadTooLarge: () => {\n eventBatcher.halveBatchSize();\n logBatcher.halveBatchSize();\n sdkDebug(\"413 received, halved batch size\");\n },\n });\n\n // Batchers\n eventBatcher = new Batcher<JsonEvent>({\n size: resolvedConfig.batchSize,\n interval: resolvedConfig.flushInterval,\n maxQueueSize: resolvedConfig.maxQueueSize,\n send: (items) => transport.sendEvents(items),\n onOverflow: () => sdkDebug(\"event queue overflow, dropping oldest\"),\n });\n\n logBatcher = new Batcher<JsonLog>({\n size: resolvedConfig.batchSize,\n interval: resolvedConfig.flushInterval,\n maxQueueSize: resolvedConfig.maxQueueSize,\n send: (items) => transport.sendLogs(items),\n onOverflow: () => sdkDebug(\"log queue overflow, dropping oldest\"),\n });\n\n // Session management\n sessionManager = new SessionManager({\n timeout: resolvedConfig.sessionTimeout,\n onNewSession,\n });\n\n // Unload handlers\n if (typeof window !== \"undefined\") {\n unloadHandler = handleUnload;\n window.addEventListener(\"beforeunload\", unloadHandler);\n }\n if (typeof document !== \"undefined\") {\n visibilityUnloadHandler = handleVisibilityUnload;\n document.addEventListener(\"visibilitychange\", visibilityUnloadHandler);\n }\n\n // Error auto-capture\n if (resolvedConfig.captureErrors && typeof window !== \"undefined\") {\n errorHandler = (event: ErrorEvent) => {\n if (_disabled || _optedOut || closed) return;\n const msg = event.message || \"Unknown error\";\n const data: Properties = {};\n if (event.filename) data.filename = event.filename;\n if (event.lineno) data.lineno = event.lineno;\n if (event.colno) data.colno = event.colno;\n if (event.error?.stack) data.stack = event.error.stack;\n tell.logError(msg, \"browser\", data);\n };\n rejectionHandler = (event: PromiseRejectionEvent) => {\n if (_disabled || _optedOut || closed) return;\n const reason = event.reason;\n const msg =\n reason instanceof Error\n ? reason.message\n : String(reason ?? \"Unhandled promise rejection\");\n const data: Properties = {};\n if (reason instanceof Error && reason.stack) data.stack = reason.stack;\n tell.logError(msg, \"browser\", data);\n };\n window.addEventListener(\"error\", errorHandler);\n window.addEventListener(\"unhandledrejection\", rejectionHandler);\n }\n\n configured = true;\n closed = false;\n\n sdkDebug(\n `configured (endpoint=${resolvedConfig.endpoint}, batch=${resolvedConfig.batchSize})`\n );\n\n // Replay pre-init queue\n queue.replay(tell as unknown as Record<string, (...args: any[]) => any>);\n },\n\n // -----------------------------------------------------------------------\n // Events\n // -----------------------------------------------------------------------\n\n track(eventName: string, properties?: Properties): void {\n if (!configured) {\n queue.push({ method: \"track\", args: [eventName, properties] });\n return;\n }\n if (_disabled || _optedOut) return;\n if (closed) {\n reportError(new ClosedError());\n return;\n }\n try {\n validateEventName(eventName);\n } catch (err) {\n reportError(err);\n return;\n }\n\n sessionManager.touch();\n\n let event: JsonEvent | null = {\n type: \"track\",\n event: eventName,\n service: resolvedService,\n device_id: deviceId,\n session_id: sessionManager.sessionId,\n user_id: userId,\n timestamp: Date.now(),\n ...superProperties,\n ...properties,\n };\n\n if (beforeSend) {\n event = runBeforeSend(event, beforeSend);\n if (event === null) return;\n }\n\n eventBatcher.add(event);\n },\n\n identify(newUserId: string, traits?: Properties): void {\n if (!configured) {\n queue.push({ method: \"identify\", args: [newUserId, traits] });\n return;\n }\n if (_disabled || _optedOut) return;\n if (closed) {\n reportError(new ClosedError());\n return;\n }\n try {\n validateUserId(newUserId);\n } catch (err) {\n reportError(err);\n return;\n }\n\n userId = newUserId;\n storage.set(STORAGE_KEYS.USER_ID, userId);\n\n sessionManager.touch();\n\n let event: JsonEvent | null = {\n type: \"identify\",\n service: resolvedService,\n device_id: deviceId,\n session_id: sessionManager.sessionId,\n user_id: userId,\n timestamp: Date.now(),\n ...traits,\n };\n\n if (beforeSend) {\n event = runBeforeSend(event, beforeSend);\n if (event === null) return;\n }\n\n eventBatcher.add(event);\n },\n\n group(groupId: string, properties?: Properties): void {\n if (!configured) {\n queue.push({ method: \"group\", args: [groupId, properties] });\n return;\n }\n if (_disabled || _optedOut) return;\n if (closed) {\n reportError(new ClosedError());\n return;\n }\n try {\n if (!groupId) throw new ValidationError(\"groupId\", \"is required\");\n } catch (err) {\n reportError(err);\n return;\n }\n\n sessionManager.touch();\n\n let event: JsonEvent | null = {\n type: \"group\",\n service: resolvedService,\n device_id: deviceId,\n session_id: sessionManager.sessionId,\n user_id: userId,\n group_id: groupId,\n timestamp: Date.now(),\n ...superProperties,\n ...properties,\n };\n\n if (beforeSend) {\n event = runBeforeSend(event, beforeSend);\n if (event === null) return;\n }\n\n eventBatcher.add(event);\n },\n\n revenue(\n amount: number,\n currency: string,\n orderId: string,\n properties?: Properties\n ): void {\n if (!configured) {\n queue.push({ method: \"revenue\", args: [amount, currency, orderId, properties] });\n return;\n }\n if (_disabled || _optedOut) return;\n if (closed) {\n reportError(new ClosedError());\n return;\n }\n try {\n if (amount <= 0) throw new ValidationError(\"amount\", \"must be positive\");\n if (!currency) throw new ValidationError(\"currency\", \"is required\");\n if (!orderId) throw new ValidationError(\"orderId\", \"is required\");\n } catch (err) {\n reportError(err);\n return;\n }\n\n sessionManager.touch();\n\n let event: JsonEvent | null = {\n type: \"track\",\n event: \"Order Completed\",\n service: resolvedService,\n device_id: deviceId,\n session_id: sessionManager.sessionId,\n user_id: userId,\n timestamp: Date.now(),\n ...superProperties,\n ...properties,\n order_id: orderId,\n amount,\n currency,\n };\n\n if (beforeSend) {\n event = runBeforeSend(event, beforeSend);\n if (event === null) return;\n }\n\n eventBatcher.add(event);\n },\n\n alias(previousId: string, newUserId: string): void {\n if (!configured) {\n queue.push({ method: \"alias\", args: [previousId, newUserId] });\n return;\n }\n if (_disabled || _optedOut) return;\n if (closed) {\n reportError(new ClosedError());\n return;\n }\n try {\n if (!previousId)\n throw new ValidationError(\"previousId\", \"is required\");\n validateUserId(newUserId);\n } catch (err) {\n reportError(err);\n return;\n }\n\n sessionManager.touch();\n\n let event: JsonEvent | null = {\n type: \"alias\",\n service: resolvedService,\n device_id: deviceId,\n session_id: sessionManager.sessionId,\n user_id: newUserId,\n timestamp: Date.now(),\n previous_id: previousId,\n };\n\n if (beforeSend) {\n event = runBeforeSend(event, beforeSend);\n if (event === null) return;\n }\n\n eventBatcher.add(event);\n },\n\n // -----------------------------------------------------------------------\n // Logging\n // -----------------------------------------------------------------------\n\n log(\n level: LogLevel,\n message: string,\n service?: string,\n data?: Properties\n ): void {\n if (!configured) {\n queue.push({ method: \"log\", args: [level, message, service, data] });\n return;\n }\n if (_disabled || _optedOut) return;\n if (closed) {\n reportError(new ClosedError());\n return;\n }\n try {\n validateLogMessage(message);\n } catch (err) {\n reportError(err);\n return;\n }\n\n let logEntry: JsonLog | null = {\n level,\n message,\n source: resolvedConfig.source,\n service: service ?? resolvedService,\n session_id: sessionManager.sessionId,\n timestamp: Date.now(),\n data,\n };\n\n if (beforeSendLog) {\n logEntry = runBeforeSend(logEntry, beforeSendLog);\n if (logEntry === null) return;\n }\n\n logBatcher.add(logEntry);\n },\n\n logEmergency(message: string, service?: string, data?: Properties): void {\n tell.log(\"emergency\", message, service, data);\n },\n logAlert(message: string, service?: string, data?: Properties): void {\n tell.log(\"alert\", message, service, data);\n },\n logCritical(message: string, service?: string, data?: Properties): void {\n tell.log(\"critical\", message, service, data);\n },\n logError(message: string, service?: string, data?: Properties): void {\n tell.log(\"error\", message, service, data);\n },\n logWarning(message: string, service?: string, data?: Properties): void {\n tell.log(\"warning\", message, service, data);\n },\n logNotice(message: string, service?: string, data?: Properties): void {\n tell.log(\"notice\", message, service, data);\n },\n logInfo(message: string, service?: string, data?: Properties): void {\n tell.log(\"info\", message, service, data);\n },\n logDebug(message: string, service?: string, data?: Properties): void {\n tell.log(\"debug\", message, service, data);\n },\n logTrace(message: string, service?: string, data?: Properties): void {\n tell.log(\"trace\", message, service, data);\n },\n\n // -----------------------------------------------------------------------\n // Super Properties\n // -----------------------------------------------------------------------\n\n register(properties: Properties): void {\n if (!configured) {\n queue.push({ method: \"register\", args: [properties] });\n return;\n }\n Object.assign(superProperties, properties);\n persistSuperProps();\n },\n\n unregister(key: string): void {\n if (!configured) {\n queue.push({ method: \"unregister\", args: [key] });\n return;\n }\n delete superProperties[key];\n persistSuperProps();\n },\n\n // -----------------------------------------------------------------------\n // Privacy\n // -----------------------------------------------------------------------\n\n optOut(): void {\n if (!configured) {\n queue.push({ method: \"optOut\", args: [] });\n return;\n }\n _optedOut = true;\n storage.set(STORAGE_KEYS.OPT_OUT, \"1\");\n },\n\n optIn(): void {\n if (!configured) {\n queue.push({ method: \"optIn\", args: [] });\n return;\n }\n _optedOut = false;\n storage.remove(STORAGE_KEYS.OPT_OUT);\n },\n\n isOptedOut(): boolean {\n return _optedOut;\n },\n\n // -----------------------------------------------------------------------\n // Control\n // -----------------------------------------------------------------------\n\n enable(): void {\n _disabled = false;\n },\n\n disable(): void {\n _disabled = true;\n },\n\n // -----------------------------------------------------------------------\n // Lifecycle\n // -----------------------------------------------------------------------\n\n async flush(): Promise<void> {\n if (!configured) return;\n await Promise.all([eventBatcher.flush(), logBatcher.flush()]);\n },\n\n async close(): Promise<void> {\n if (!configured || closed) return;\n closed = true;\n\n if (sessionManager) sessionManager.destroy();\n\n if (typeof window !== \"undefined\" && unloadHandler) {\n window.removeEventListener(\"beforeunload\", unloadHandler);\n unloadHandler = null;\n }\n if (typeof document !== \"undefined\" && visibilityUnloadHandler) {\n document.removeEventListener(\"visibilitychange\", visibilityUnloadHandler);\n visibilityUnloadHandler = null;\n }\n if (typeof window !== \"undefined\") {\n if (errorHandler) {\n window.removeEventListener(\"error\", errorHandler);\n errorHandler = null;\n }\n if (rejectionHandler) {\n window.removeEventListener(\"unhandledrejection\", rejectionHandler);\n rejectionHandler = null;\n }\n }\n\n const work = Promise.all([eventBatcher.close(), logBatcher.close()]);\n const timeout = new Promise<never>((_, reject) =>\n setTimeout(\n () => reject(new Error(\"close timed out\")),\n resolvedConfig.closeTimeout\n )\n );\n\n try {\n await Promise.race([work, timeout]);\n } catch (err) {\n reportError(err);\n }\n\n configured = false;\n },\n\n reset(): void {\n if (!configured) return;\n userId = undefined;\n deviceId = generateId();\n superProperties = {};\n\n storage.remove(STORAGE_KEYS.USER_ID);\n storage.set(STORAGE_KEYS.DEVICE_ID, deviceId);\n storage.remove(STORAGE_KEYS.SUPER_PROPS);\n\n if (sessionManager) {\n sessionManager.sessionId = generateId();\n }\n },\n\n // -----------------------------------------------------------------------\n // Testing helper\n // -----------------------------------------------------------------------\n\n _resetForTesting(): void {\n if (configured && !closed) {\n // Synchronously tear down timers\n if (sessionManager) sessionManager.destroy();\n if (eventBatcher) {\n eventBatcher.drain();\n eventBatcher.close().catch(() => {});\n }\n if (logBatcher) {\n logBatcher.drain();\n logBatcher.close().catch(() => {});\n }\n if (typeof window !== \"undefined\" && unloadHandler) {\n window.removeEventListener(\"beforeunload\", unloadHandler);\n }\n if (typeof document !== \"undefined\" && visibilityUnloadHandler) {\n document.removeEventListener(\n \"visibilitychange\",\n visibilityUnloadHandler\n );\n }\n if (typeof window !== \"undefined\") {\n if (errorHandler) window.removeEventListener(\"error\", errorHandler);\n if (rejectionHandler)\n window.removeEventListener(\"unhandledrejection\", rejectionHandler);\n }\n }\n\n configured = false;\n closed = false;\n _disabled = false;\n _optedOut = false;\n userId = undefined;\n deviceId = \"\";\n superProperties = {};\n beforeSend = undefined;\n beforeSendLog = undefined;\n sdkLogLevel = 0;\n unloadHandler = null;\n visibilityUnloadHandler = null;\n errorHandler = null;\n rejectionHandler = null;\n queue.clear();\n },\n};\n\nexport default tell;\nexport { tell };\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/config.ts","../src/persistence.ts","../src/id.ts","../src/bot.ts","../src/context.ts","../src/utm.ts","../src/session.ts","../src/transport.ts","../src/queue.ts","../src/index.ts"],"sourcesContent":["import type { TellError, BeforeSendFn, JsonEvent, JsonLog } from \"@tell-rs/core\";\n\nexport interface TellBrowserConfig {\n /** Service name stamped on every event and log. Defaults to window.location.hostname. */\n service?: string;\n endpoint?: string;\n batchSize?: number;\n flushInterval?: number;\n maxRetries?: number;\n closeTimeout?: number;\n networkTimeout?: number;\n logLevel?: \"error\" | \"warn\" | \"info\" | \"debug\";\n source?: string;\n onError?: (error: TellError) => void;\n disabled?: boolean;\n maxQueueSize?: number;\n sessionTimeout?: number;\n maxSessionLength?: number;\n persistence?: \"localStorage\" | \"memory\";\n respectDoNotTrack?: boolean;\n botDetection?: boolean;\n captureErrors?: boolean;\n beforeSend?: BeforeSendFn<JsonEvent> | BeforeSendFn<JsonEvent>[];\n beforeSendLog?: BeforeSendFn<JsonLog> | BeforeSendFn<JsonLog>[];\n}\n\nexport const DEFAULTS = {\n endpoint: \"https://collect.tell.app\",\n batchSize: 20,\n flushInterval: 5_000,\n maxRetries: 5,\n closeTimeout: 5_000,\n networkTimeout: 10_000,\n logLevel: \"error\" as const,\n source: \"browser\",\n disabled: false,\n maxQueueSize: 1000,\n sessionTimeout: 1_800_000, // 30 min\n maxSessionLength: 86_400_000, // 24 hours\n persistence: \"localStorage\" as const,\n respectDoNotTrack: false,\n botDetection: true,\n captureErrors: false,\n} as const;\n\nexport type ResolvedBrowserConfig = Required<\n Omit<TellBrowserConfig, \"onError\" | \"beforeSend\" | \"beforeSendLog\">\n> &\n Pick<TellBrowserConfig, \"onError\" | \"beforeSend\" | \"beforeSendLog\">;\n\nexport function resolveConfig(\n options: TellBrowserConfig | undefined\n): ResolvedBrowserConfig {\n return { ...DEFAULTS, ...options } as ResolvedBrowserConfig;\n}\n\n/** Development preset: localhost, small batches, fast flush, debug logging. */\nexport function development(\n overrides?: Partial<TellBrowserConfig>\n): TellBrowserConfig {\n return {\n endpoint: \"http://localhost:8080\",\n batchSize: 5,\n flushInterval: 2_000,\n logLevel: \"debug\",\n ...overrides,\n };\n}\n\n/** Production preset: default endpoint, error-only logging. */\nexport function production(\n overrides?: Partial<TellBrowserConfig>\n): TellBrowserConfig {\n return {\n logLevel: \"error\",\n ...overrides,\n };\n}\n","export interface TellStorage {\n get(key: string): string | null;\n set(key: string, value: string): void;\n remove(key: string): void;\n}\n\nexport const STORAGE_KEYS = {\n DEVICE_ID: \"tell_device_id\",\n USER_ID: \"tell_user_id\",\n OPT_OUT: \"tell_opt_out\",\n SUPER_PROPS: \"tell_super_props\",\n} as const;\n\nclass LocalStorageStorage implements TellStorage {\n get(key: string): string | null {\n try {\n return localStorage.getItem(key);\n } catch {\n return null;\n }\n }\n\n set(key: string, value: string): void {\n try {\n localStorage.setItem(key, value);\n } catch {\n // Safari private mode or quota exceeded\n }\n }\n\n remove(key: string): void {\n try {\n localStorage.removeItem(key);\n } catch {\n // ignore\n }\n }\n}\n\nclass MemoryStorage implements TellStorage {\n private data = new Map<string, string>();\n\n get(key: string): string | null {\n return this.data.get(key) ?? null;\n }\n\n set(key: string, value: string): void {\n this.data.set(key, value);\n }\n\n remove(key: string): void {\n this.data.delete(key);\n }\n}\n\n/** Create a storage backend. Falls back to memory if localStorage is unavailable. */\nexport function createStorage(\n persistence: \"localStorage\" | \"memory\"\n): TellStorage {\n if (persistence === \"localStorage\" && typeof localStorage !== \"undefined\") {\n try {\n const testKey = \"tell_test\";\n localStorage.setItem(testKey, \"1\");\n localStorage.removeItem(testKey);\n return new LocalStorageStorage();\n } catch {\n // probe failed — fall through to memory\n }\n }\n return new MemoryStorage();\n}\n","/** Generate a 32-char hex ID (16 random bytes) using crypto.getRandomValues. */\nexport function generateId(): string {\n if (typeof crypto !== \"undefined\" && crypto.getRandomValues) {\n const bytes = new Uint8Array(16);\n crypto.getRandomValues(bytes);\n return Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n }\n\n // Fallback for environments without crypto (extremely rare)\n let hex = \"\";\n for (let i = 0; i < 32; i++) {\n hex += ((Math.random() * 16) | 0).toString(16);\n }\n return hex;\n}\n","/** Returns true if the current environment appears to be an automated bot. */\nexport function isBot(): boolean {\n if (typeof navigator === \"undefined\") return false;\n if ((navigator as any).webdriver === true) return true;\n const ua = navigator.userAgent || \"\";\n return /headless/i.test(ua);\n}\n","export interface DeviceContext {\n browser?: string;\n browser_version?: string;\n os_name?: string;\n os_version?: string;\n device_type?: string;\n screen_width?: number;\n screen_height?: number;\n viewport_width?: number;\n viewport_height?: number;\n device_pixel_ratio?: number;\n locale?: string;\n timezone?: string;\n referrer?: string;\n referrer_domain?: string;\n url?: string;\n title?: string;\n connection_type?: string;\n downlink?: number;\n rtt?: number;\n save_data?: boolean;\n cpu_cores?: number;\n device_memory?: number;\n touch?: boolean;\n bot?: boolean;\n dark_mode?: boolean;\n path?: string;\n screen_orientation?: string;\n}\n\n/** Capture a snapshot of the current device/browser context. */\nexport function captureContext(): DeviceContext {\n const ctx: DeviceContext = {};\n\n if (typeof navigator !== \"undefined\") {\n const ua = navigator.userAgent || \"\";\n const parsed = parseUA(ua);\n ctx.browser = parsed.browser;\n ctx.browser_version = parsed.browserVersion;\n ctx.os_name = parsed.os;\n ctx.os_version = parsed.osVersion;\n ctx.locale = navigator.language;\n\n // Hardware capabilities (touch must come before device_type inference)\n if (\"hardwareConcurrency\" in navigator) {\n ctx.cpu_cores = (navigator as any).hardwareConcurrency;\n }\n if (\"deviceMemory\" in navigator) {\n ctx.device_memory = (navigator as any).deviceMemory;\n }\n if (\"maxTouchPoints\" in navigator) {\n ctx.touch = navigator.maxTouchPoints > 0;\n }\n\n ctx.device_type = inferDeviceType(parsed.os, ua, ctx.touch);\n\n // Network info (Chrome/Edge)\n const conn = (navigator as any).connection;\n if (conn) {\n if (conn.effectiveType) ctx.connection_type = conn.effectiveType;\n if (typeof conn.downlink === \"number\") ctx.downlink = conn.downlink;\n if (typeof conn.rtt === \"number\") ctx.rtt = conn.rtt;\n if (conn.saveData) ctx.save_data = true;\n }\n\n // Bot detection\n if ((navigator as any).webdriver) ctx.bot = true;\n }\n\n if (typeof screen !== \"undefined\") {\n ctx.screen_width = screen.width;\n ctx.screen_height = screen.height;\n const orient = (screen as any).orientation;\n if (orient?.type) ctx.screen_orientation = orient.type;\n }\n\n if (typeof window !== \"undefined\") {\n ctx.viewport_width = window.innerWidth;\n ctx.viewport_height = window.innerHeight;\n if (window.devicePixelRatio) {\n ctx.device_pixel_ratio = window.devicePixelRatio;\n }\n }\n\n if (typeof document !== \"undefined\") {\n ctx.referrer = document.referrer || undefined;\n if (ctx.referrer) {\n try {\n ctx.referrer_domain = new URL(ctx.referrer).hostname;\n } catch {\n // malformed referrer\n }\n }\n ctx.title = document.title || undefined;\n }\n\n if (typeof location !== \"undefined\") {\n ctx.url = location.href;\n if (location.pathname) ctx.path = location.pathname;\n }\n\n try {\n ctx.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n } catch {\n // Intl not available\n }\n\n if (typeof window !== \"undefined\" && window.matchMedia) {\n try {\n ctx.dark_mode = window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n } catch {\n // matchMedia not available\n }\n }\n\n return ctx;\n}\n\nfunction inferDeviceType(os?: string, ua?: string, touch?: boolean): string {\n // iPad (iPadOS 13+) reports as macOS but has touch support\n if (os === \"macOS\" && touch) return \"tablet\";\n // Android tablets have \"Android\" in UA but not \"Mobile\"\n if (os === \"Android\") return ua && !/Mobile/.test(ua) ? \"tablet\" : \"mobile\";\n if (os === \"iOS\") return \"mobile\";\n return \"desktop\";\n}\n\ninterface ParsedUA {\n browser?: string;\n browserVersion?: string;\n os?: string;\n osVersion?: string;\n}\n\nfunction parseUA(ua: string): ParsedUA {\n const result: ParsedUA = {};\n\n // Browser detection (order matters: Edge before Chrome, Chrome before Safari)\n if (/Edg\\/(\\d+[\\d.]*)/.test(ua)) {\n result.browser = \"Edge\";\n result.browserVersion = RegExp.$1;\n } else if (/OPR\\/(\\d+[\\d.]*)/.test(ua)) {\n result.browser = \"Opera\";\n result.browserVersion = RegExp.$1;\n } else if (/Chrome\\/(\\d+[\\d.]*)/.test(ua)) {\n result.browser = \"Chrome\";\n result.browserVersion = RegExp.$1;\n } else if (/Safari\\/[\\d.]+/.test(ua) && /Version\\/(\\d+[\\d.]*)/.test(ua)) {\n result.browser = \"Safari\";\n result.browserVersion = RegExp.$1;\n } else if (/Firefox\\/(\\d+[\\d.]*)/.test(ua)) {\n result.browser = \"Firefox\";\n result.browserVersion = RegExp.$1;\n }\n\n // OS detection\n if (/Windows NT ([\\d.]+)/.test(ua)) {\n result.os = \"Windows\";\n result.osVersion = RegExp.$1;\n } else if (/Mac OS X ([\\d_.]+)/.test(ua)) {\n result.os = \"macOS\";\n result.osVersion = RegExp.$1.replace(/_/g, \".\");\n } else if (/iPhone OS ([\\d_]+)/.test(ua)) {\n result.os = \"iOS\";\n result.osVersion = RegExp.$1.replace(/_/g, \".\");\n } else if (/Android ([\\d.]+)/.test(ua)) {\n result.os = \"Android\";\n result.osVersion = RegExp.$1;\n } else if (/Linux/.test(ua)) {\n result.os = \"Linux\";\n }\n\n return result;\n}\n","import type { Properties } from \"@tell-rs/core\";\n\nconst UTM_KEYS = [\n \"utm_source\",\n \"utm_medium\",\n \"utm_campaign\",\n \"utm_term\",\n \"utm_content\",\n] as const;\n\n/**\n * Extract UTM parameters from the current URL search string.\n * Returns only keys that are present and non-empty.\n */\nexport function captureUtm(): Properties {\n if (typeof window === \"undefined\" || !window.location?.search) return {};\n\n const params = new URLSearchParams(window.location.search);\n const utm: Properties = {};\n\n for (const key of UTM_KEYS) {\n const value = params.get(key);\n if (value) {\n utm[key] = value;\n }\n }\n\n return utm;\n}\n","import { generateId } from \"./id.js\";\nimport type { TellStorage } from \"./persistence.js\";\n\nexport type SessionReason = \"session_start\" | \"session_timeout\";\n\nexport interface SessionManagerConfig {\n timeout: number; // idle timeout in ms (default 30 min)\n maxLength: number; // max session length in ms (default 24 hours)\n storage: TellStorage;\n onNewSession: (reason: SessionReason, sessionId: string) => void;\n}\n\nconst SESSION_ID_KEY = \"tell_session_id\";\nconst SESSION_TS_KEY = \"tell_session_ts\";\nconst SESSION_START_KEY = \"tell_session_start\";\nconst PERSIST_INTERVAL = 60_000;\n\nexport class SessionManager {\n private _sessionId: string;\n private lastHiddenAt = 0;\n private lastActivityAt: number;\n private sessionStartedAt: number;\n private lastPersistedAt = 0;\n private readonly timeout: number;\n private readonly maxLength: number;\n private readonly storage: TellStorage;\n private readonly onNewSession: (reason: SessionReason, sessionId: string) => void;\n private readonly visibilityHandler: () => void;\n\n constructor(config: SessionManagerConfig) {\n this.timeout = config.timeout;\n this.maxLength = config.maxLength;\n this.storage = config.storage;\n this.onNewSession = config.onNewSession;\n\n const now = Date.now();\n const storedId = this.storage.get(SESSION_ID_KEY);\n const storedTs = Number(this.storage.get(SESSION_TS_KEY) || 0);\n const storedStart = Number(this.storage.get(SESSION_START_KEY) || 0);\n\n if (\n storedId &&\n storedTs > 0 &&\n storedStart > 0 &&\n now - storedTs < this.timeout &&\n now - storedStart < this.maxLength\n ) {\n this._sessionId = storedId;\n this.lastActivityAt = storedTs;\n this.sessionStartedAt = storedStart;\n } else {\n this._sessionId = generateId();\n this.lastActivityAt = now;\n this.sessionStartedAt = now;\n this.persist();\n this.onNewSession(\"session_start\", this._sessionId);\n }\n\n this.visibilityHandler = () => this.handleVisibility();\n if (typeof document !== \"undefined\") {\n document.addEventListener(\"visibilitychange\", this.visibilityHandler);\n }\n }\n\n get sessionId(): string {\n return this._sessionId;\n }\n\n set sessionId(id: string) {\n this._sessionId = id;\n const now = Date.now();\n this.lastActivityAt = now;\n this.sessionStartedAt = now;\n this.persist();\n }\n\n /** Update activity timestamp; rotates session if idle longer than timeout or exceeds max length. */\n touch(): void {\n const now = Date.now();\n if (\n now - this.lastActivityAt > this.timeout ||\n now - this.sessionStartedAt > this.maxLength\n ) {\n this.rotateSession(\"session_timeout\");\n }\n this.lastActivityAt = now;\n if (now - this.lastPersistedAt >= PERSIST_INTERVAL) {\n this.persistActivity();\n }\n }\n\n destroy(): void {\n if (typeof document !== \"undefined\") {\n document.removeEventListener(\"visibilitychange\", this.visibilityHandler);\n }\n }\n\n private handleVisibility(): void {\n if (document.visibilityState === \"hidden\") {\n this.lastHiddenAt = Date.now();\n } else if (document.visibilityState === \"visible\") {\n const now = Date.now();\n if (\n this.lastHiddenAt > 0 &&\n (now - this.lastHiddenAt > this.timeout ||\n now - this.sessionStartedAt > this.maxLength)\n ) {\n this.rotateSession(\"session_timeout\");\n }\n this.lastHiddenAt = 0;\n }\n }\n\n private rotateSession(reason: SessionReason): void {\n this._sessionId = generateId();\n const now = Date.now();\n this.lastActivityAt = now;\n this.sessionStartedAt = now;\n this.persist();\n this.onNewSession(reason, this._sessionId);\n }\n\n private persist(): void {\n this.storage.set(SESSION_ID_KEY, this._sessionId);\n this.storage.set(SESSION_TS_KEY, String(this.lastActivityAt));\n this.storage.set(SESSION_START_KEY, String(this.sessionStartedAt));\n this.lastPersistedAt = Date.now();\n }\n\n private persistActivity(): void {\n this.storage.set(SESSION_TS_KEY, String(this.lastActivityAt));\n this.lastPersistedAt = Date.now();\n }\n}\n","import type { JsonEvent, JsonLog } from \"@tell-rs/core\";\nimport { NetworkError } from \"@tell-rs/core\";\n\nexport interface BrowserTransportConfig {\n endpoint: string;\n apiKey: string;\n maxRetries: number;\n networkTimeout: number;\n onError?: (error: Error) => void;\n onPayloadTooLarge?: () => void;\n}\n\nexport class BrowserTransport {\n private readonly endpoint: string;\n private readonly apiKey: string;\n private readonly maxRetries: number;\n private readonly networkTimeout: number;\n private readonly onError?: (error: Error) => void;\n private readonly onPayloadTooLarge?: () => void;\n\n constructor(config: BrowserTransportConfig) {\n this.endpoint = config.endpoint;\n this.apiKey = config.apiKey;\n this.maxRetries = config.maxRetries;\n this.networkTimeout = config.networkTimeout;\n this.onError = config.onError;\n this.onPayloadTooLarge = config.onPayloadTooLarge;\n }\n\n async sendEvents(events: JsonEvent[]): Promise<void> {\n if (events.length === 0) return;\n const body = events.map((e) => JSON.stringify(e)).join(\"\\n\");\n await this.send(\"/v1/events\", body);\n }\n\n async sendLogs(logs: JsonLog[]): Promise<void> {\n if (logs.length === 0) return;\n const body = logs.map((l) => JSON.stringify(l)).join(\"\\n\");\n await this.send(\"/v1/logs\", body);\n }\n\n /** Best-effort flush via sendBeacon for page unload. */\n beacon(events: JsonEvent[], logs: JsonLog[]): void {\n if (typeof navigator === \"undefined\" || !navigator.sendBeacon) return;\n\n if (events.length > 0) {\n const body = events.map((e) => JSON.stringify(e)).join(\"\\n\");\n const blob = new Blob([body], { type: \"text/plain\" });\n const url = `${this.endpoint}/v1/events?token=${encodeURIComponent(this.apiKey)}`;\n navigator.sendBeacon(url, blob);\n }\n\n if (logs.length > 0) {\n const body = logs.map((l) => JSON.stringify(l)).join(\"\\n\");\n const blob = new Blob([body], { type: \"text/plain\" });\n const url = `${this.endpoint}/v1/logs?token=${encodeURIComponent(this.apiKey)}`;\n navigator.sendBeacon(url, blob);\n }\n }\n\n private resolvePort(): string {\n try {\n const u = new URL(this.endpoint);\n if (u.port) return u.port;\n return u.protocol === \"https:\" ? \"443\" : \"80\";\n } catch {\n return \"unknown\";\n }\n }\n\n private async send(path: string, body: string): Promise<void> {\n // Auth via query param + text/plain content-type keeps this a CORS\n // \"simple request\" — no preflight OPTIONS needed. This matches the\n // pattern used by beacon() and by every major analytics SDK.\n const url = `${this.endpoint}${path}?token=${encodeURIComponent(this.apiKey)}`;\n const port = this.resolvePort();\n const headers: Record<string, string> = {\n \"Content-Type\": \"text/plain\",\n };\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n if (attempt > 0) {\n await this.backoff(attempt);\n }\n\n // Skip attempt if browser reports offline\n if (typeof navigator !== \"undefined\" && !navigator.onLine) {\n lastError = new NetworkError(`Browser is offline (endpoint: ${url}, port: ${port})`);\n continue;\n }\n\n const controller = new AbortController();\n const timer = setTimeout(\n () => controller.abort(),\n this.networkTimeout\n );\n\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body,\n signal: controller.signal,\n keepalive: true,\n });\n\n if (response.status === 202) {\n return;\n }\n\n if (response.status === 207) {\n if (this.onError) {\n this.onError(\n new NetworkError(\n `Partial success: some items rejected`,\n 207\n )\n );\n }\n return;\n }\n\n if (response.status === 413) {\n if (this.onPayloadTooLarge) {\n this.onPayloadTooLarge();\n }\n throw new NetworkError(\"Payload too large\", 413);\n }\n\n if (response.status === 401) {\n throw new NetworkError(\"Invalid API key\", 401);\n }\n\n if (response.status >= 400 && response.status < 500) {\n throw new NetworkError(\n `HTTP ${response.status}: ${response.statusText}`,\n response.status\n );\n }\n\n // 5xx — retryable\n lastError = new NetworkError(\n `HTTP ${response.status} from ${url} (port ${port}): ${response.statusText}`,\n response.status\n );\n } catch (err) {\n if (err instanceof NetworkError && err.statusCode === 413) {\n throw err;\n }\n\n if (\n err instanceof NetworkError &&\n err.statusCode &&\n err.statusCode < 500\n ) {\n if (this.onError) this.onError(err);\n return;\n }\n\n // DNS failures, connection refused, and CORS errors surface as\n // TypeError from fetch. Include the full URL so the developer can\n // verify the endpoint and port. These won't resolve by retrying.\n if (err instanceof TypeError) {\n if (this.onError)\n this.onError(\n new NetworkError(\n `Failed to connect to ${url} (port ${port}): ${err.message}`\n )\n );\n return;\n }\n\n lastError =\n err instanceof Error ? err : new NetworkError(String(err));\n } finally {\n clearTimeout(timer);\n }\n }\n\n if (lastError && this.onError) {\n this.onError(lastError);\n }\n }\n\n private backoff(attempt: number): Promise<void> {\n const base = 1000 * Math.pow(1.5, attempt - 1);\n const jitter = base * 0.2 * Math.random();\n const delay = Math.min(base + jitter, 30_000);\n return new Promise((resolve) => setTimeout(resolve, delay));\n }\n}\n","import type { LogLevel, Properties } from \"@tell-rs/core\";\n\nexport type QueuedCall =\n | { method: \"track\"; args: [string, Properties?] }\n | { method: \"identify\"; args: [string, Properties?] }\n | { method: \"group\"; args: [string, Properties?] }\n | { method: \"revenue\"; args: [number, string, string, Properties?] }\n | { method: \"alias\"; args: [string, string] }\n | { method: \"log\"; args: [LogLevel, string, Properties?] }\n | { method: \"register\"; args: [Properties] }\n | { method: \"unregister\"; args: [string] }\n | { method: \"optOut\"; args: [] }\n | { method: \"optIn\"; args: [] };\n\nexport class PreInitQueue {\n private items: QueuedCall[] = [];\n readonly maxSize: number;\n\n constructor(maxSize = 1000) {\n this.maxSize = maxSize;\n }\n\n push(call: QueuedCall): void {\n if (this.items.length >= this.maxSize) {\n this.items.shift(); // drop oldest\n }\n this.items.push(call);\n }\n\n replay(target: Record<string, (...args: any[]) => any>): void {\n const calls = this.items;\n this.items = [];\n for (const call of calls) {\n try {\n target[call.method](...call.args);\n } catch {\n // continue on per-call error\n }\n }\n }\n\n get length(): number {\n return this.items.length;\n }\n\n clear(): void {\n this.items = [];\n }\n}\n","import type {\n JsonEvent,\n JsonLog,\n LogLevel,\n Properties,\n BeforeSendFn,\n} from \"@tell-rs/core\";\nimport {\n ClosedError,\n ConfigurationError,\n ValidationError,\n validateApiKey,\n validateEventName,\n validateLogMessage,\n validateUserId,\n Batcher,\n runBeforeSend,\n} from \"@tell-rs/core\";\n\nimport type { TellBrowserConfig, ResolvedBrowserConfig } from \"./config.js\";\nimport { resolveConfig } from \"./config.js\";\nimport type { TellStorage } from \"./persistence.js\";\nimport { createStorage, STORAGE_KEYS } from \"./persistence.js\";\nimport { generateId } from \"./id.js\";\nimport { isBot } from \"./bot.js\";\nimport { captureContext } from \"./context.js\";\nimport { captureUtm } from \"./utm.js\";\nimport type { SessionReason } from \"./session.js\";\nimport { SessionManager } from \"./session.js\";\nimport { BrowserTransport } from \"./transport.js\";\nimport { PreInitQueue } from \"./queue.js\";\n\n// Re-export core types and values\nexport { Events, type EventName } from \"@tell-rs/core\";\nexport type { Properties, LogLevel, JsonEvent, JsonLog, BeforeSendFn } from \"@tell-rs/core\";\nexport { redact, redactLog, SENSITIVE_PARAMS, type RedactOptions } from \"@tell-rs/core\";\nexport {\n TellError,\n ConfigurationError,\n ValidationError,\n NetworkError,\n ClosedError,\n SerializationError,\n} from \"@tell-rs/core\";\n\n// Re-export browser-specific config\nexport type { TellBrowserConfig } from \"./config.js\";\nexport { development, production } from \"./config.js\";\nexport type { DeviceContext } from \"./context.js\";\n\n// ---------------------------------------------------------------------------\n// Module-level state\n// ---------------------------------------------------------------------------\n\nlet configured = false;\nlet closed = false;\nlet _disabled = false;\nlet _optedOut = false;\n\nlet storage: TellStorage;\nlet transport: BrowserTransport;\nlet eventBatcher: Batcher<JsonEvent>;\nlet logBatcher: Batcher<JsonLog>;\nlet sessionManager: SessionManager;\nlet resolvedConfig: ResolvedBrowserConfig;\n\nlet _apiKey: string;\nlet resolvedService: string;\nlet deviceId: string;\nlet userId: string | undefined;\nlet superProperties: Properties = {};\nlet beforeSend: BeforeSendFn<JsonEvent> | BeforeSendFn<JsonEvent>[] | undefined;\nlet beforeSendLog:\n | BeforeSendFn<JsonLog>\n | BeforeSendFn<JsonLog>[]\n | undefined;\nlet sdkLogLevel: number;\n\nconst queue = new PreInitQueue(1000);\n\nlet unloadHandler: (() => void) | null = null;\nlet visibilityUnloadHandler: (() => void) | null = null;\nlet errorHandler: ((event: ErrorEvent) => void) | null = null;\nlet rejectionHandler: ((event: PromiseRejectionEvent) => void) | null = null;\n\nconst LOG_LEVELS: Record<string, number> = {\n error: 0,\n warn: 1,\n info: 2,\n debug: 3,\n};\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction reportError(err: unknown): void {\n if (resolvedConfig?.onError && err instanceof Error) {\n resolvedConfig.onError(err);\n }\n}\n\nfunction sdkDebug(msg: string): void {\n if (sdkLogLevel >= LOG_LEVELS.debug) {\n console.debug(`[Tell] ${msg}`);\n }\n}\n\nfunction handleUnload(): void {\n const events = eventBatcher.drain();\n const logs = logBatcher.drain();\n transport.beacon(events, logs);\n}\n\nfunction handleVisibilityUnload(): void {\n if (document.visibilityState === \"hidden\") {\n handleUnload();\n }\n}\n\nfunction onNewSession(reason: SessionReason, sessionId: string): void {\n if (_disabled || _optedOut || closed) return;\n const ctx = captureContext();\n const event: JsonEvent = {\n type: \"context\",\n service: resolvedService,\n device_id: deviceId,\n session_id: sessionId,\n user_id: userId,\n timestamp: Date.now(),\n reason,\n ...ctx,\n };\n eventBatcher.add(event);\n}\n\nfunction persistSuperProps(): void {\n storage.set(STORAGE_KEYS.SUPER_PROPS, JSON.stringify(superProperties));\n}\n\nfunction loadSuperProps(): Properties {\n const raw = storage.get(STORAGE_KEYS.SUPER_PROPS);\n if (!raw) return {};\n try {\n return JSON.parse(raw) as Properties;\n } catch {\n storage.remove(STORAGE_KEYS.SUPER_PROPS);\n return {};\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport interface TellInstance {\n configure(apiKey: string, options?: TellBrowserConfig): void;\n track(eventName: string, properties?: Properties): void;\n identify(userId: string, traits?: Properties): void;\n group(groupId: string, properties?: Properties): void;\n revenue(\n amount: number,\n currency: string,\n orderId: string,\n properties?: Properties\n ): void;\n alias(previousId: string, userId: string): void;\n log(level: LogLevel, message: string, data?: Properties): void;\n logEmergency(message: string, data?: Properties): void;\n logAlert(message: string, data?: Properties): void;\n logCritical(message: string, data?: Properties): void;\n logError(message: string, data?: Properties): void;\n logWarning(message: string, data?: Properties): void;\n logNotice(message: string, data?: Properties): void;\n logInfo(message: string, data?: Properties): void;\n logDebug(message: string, data?: Properties): void;\n logTrace(message: string, data?: Properties): void;\n register(properties: Properties): void;\n unregister(key: string): void;\n optOut(): void;\n optIn(): void;\n isOptedOut(): boolean;\n flush(): Promise<void>;\n close(): Promise<void>;\n reset(): void;\n enable(): void;\n disable(): void;\n /** @internal Reset all module state. Only for testing. */\n _resetForTesting(): void;\n}\n\nconst tell: TellInstance = {\n // -----------------------------------------------------------------------\n // Lifecycle\n // -----------------------------------------------------------------------\n\n configure(apiKey: string, options?: TellBrowserConfig): void {\n if (configured) {\n reportError(new ConfigurationError(\"Tell is already configured\"));\n return;\n }\n\n validateApiKey(apiKey);\n _apiKey = apiKey;\n resolvedConfig = resolveConfig(options);\n resolvedService =\n options?.service ??\n (typeof window !== \"undefined\" ? window.location?.hostname : undefined) ??\n \"browser\";\n sdkLogLevel = LOG_LEVELS[resolvedConfig.logLevel] ?? 0;\n beforeSend = resolvedConfig.beforeSend;\n beforeSendLog = resolvedConfig.beforeSendLog;\n _disabled = resolvedConfig.disabled;\n\n // Persistence\n storage = createStorage(resolvedConfig.persistence);\n deviceId = storage.get(STORAGE_KEYS.DEVICE_ID) ?? generateId();\n storage.set(STORAGE_KEYS.DEVICE_ID, deviceId);\n userId = storage.get(STORAGE_KEYS.USER_ID) ?? undefined;\n _optedOut = storage.get(STORAGE_KEYS.OPT_OUT) === \"1\";\n superProperties = loadSuperProps();\n\n // UTM parameters — capture from URL and merge into super properties\n const utm = captureUtm();\n if (Object.keys(utm).length > 0) {\n Object.assign(superProperties, utm);\n persistSuperProps();\n }\n\n // Bot detection\n if (resolvedConfig.botDetection && isBot()) {\n _disabled = true;\n sdkDebug(\"bot detected, disabling\");\n }\n\n // Do Not Track\n if (\n resolvedConfig.respectDoNotTrack &&\n typeof navigator !== \"undefined\" &&\n navigator.doNotTrack === \"1\"\n ) {\n _disabled = true;\n sdkDebug(\"Do Not Track enabled, disabling\");\n }\n\n // Transport\n transport = new BrowserTransport({\n endpoint: resolvedConfig.endpoint,\n apiKey: _apiKey,\n maxRetries: resolvedConfig.maxRetries,\n networkTimeout: resolvedConfig.networkTimeout,\n onError: resolvedConfig.onError,\n onPayloadTooLarge: () => {\n eventBatcher.halveBatchSize();\n logBatcher.halveBatchSize();\n sdkDebug(\"413 received, halved batch size\");\n },\n });\n\n // Batchers\n eventBatcher = new Batcher<JsonEvent>({\n size: resolvedConfig.batchSize,\n interval: resolvedConfig.flushInterval,\n maxQueueSize: resolvedConfig.maxQueueSize,\n send: (items) => transport.sendEvents(items),\n onOverflow: () => sdkDebug(\"event queue overflow, dropping oldest\"),\n });\n\n logBatcher = new Batcher<JsonLog>({\n size: resolvedConfig.batchSize,\n interval: resolvedConfig.flushInterval,\n maxQueueSize: resolvedConfig.maxQueueSize,\n send: (items) => transport.sendLogs(items),\n onOverflow: () => sdkDebug(\"log queue overflow, dropping oldest\"),\n });\n\n // Session management\n sessionManager = new SessionManager({\n timeout: resolvedConfig.sessionTimeout,\n maxLength: resolvedConfig.maxSessionLength,\n storage,\n onNewSession,\n });\n\n // Unload handlers\n if (typeof window !== \"undefined\") {\n unloadHandler = handleUnload;\n window.addEventListener(\"beforeunload\", unloadHandler);\n }\n if (typeof document !== \"undefined\") {\n visibilityUnloadHandler = handleVisibilityUnload;\n document.addEventListener(\"visibilitychange\", visibilityUnloadHandler);\n }\n\n // Error auto-capture\n if (resolvedConfig.captureErrors && typeof window !== \"undefined\") {\n errorHandler = (event: ErrorEvent) => {\n if (_disabled || _optedOut || closed) return;\n const msg = event.message || \"Unknown error\";\n const data: Properties = {};\n if (event.filename) data.filename = event.filename;\n if (event.lineno) data.lineno = event.lineno;\n if (event.colno) data.colno = event.colno;\n if (event.error?.stack) data.stack = event.error.stack;\n tell.logError(msg, data);\n };\n rejectionHandler = (event: PromiseRejectionEvent) => {\n if (_disabled || _optedOut || closed) return;\n const reason = event.reason;\n const msg =\n reason instanceof Error\n ? reason.message\n : String(reason ?? \"Unhandled promise rejection\");\n const data: Properties = {};\n if (reason instanceof Error && reason.stack) data.stack = reason.stack;\n tell.logError(msg, data);\n };\n window.addEventListener(\"error\", errorHandler);\n window.addEventListener(\"unhandledrejection\", rejectionHandler);\n }\n\n configured = true;\n closed = false;\n\n sdkDebug(\n `configured (endpoint=${resolvedConfig.endpoint}, batch=${resolvedConfig.batchSize})`\n );\n\n // Replay pre-init queue\n queue.replay(tell as unknown as Record<string, (...args: any[]) => any>);\n },\n\n // -----------------------------------------------------------------------\n // Events\n // -----------------------------------------------------------------------\n\n track(eventName: string, properties?: Properties): void {\n if (!configured) {\n queue.push({ method: \"track\", args: [eventName, properties] });\n return;\n }\n if (_disabled || _optedOut) return;\n if (closed) {\n reportError(new ClosedError());\n return;\n }\n try {\n validateEventName(eventName);\n } catch (err) {\n reportError(err);\n return;\n }\n\n sessionManager.touch();\n\n let event: JsonEvent | null = {\n type: \"track\",\n event: eventName,\n service: resolvedService,\n device_id: deviceId,\n session_id: sessionManager.sessionId,\n user_id: userId,\n timestamp: Date.now(),\n ...superProperties,\n ...properties,\n };\n\n if (beforeSend) {\n event = runBeforeSend(event, beforeSend);\n if (event === null) return;\n }\n\n eventBatcher.add(event);\n },\n\n identify(newUserId: string, traits?: Properties): void {\n if (!configured) {\n queue.push({ method: \"identify\", args: [newUserId, traits] });\n return;\n }\n if (_disabled || _optedOut) return;\n if (closed) {\n reportError(new ClosedError());\n return;\n }\n try {\n validateUserId(newUserId);\n } catch (err) {\n reportError(err);\n return;\n }\n\n userId = newUserId;\n storage.set(STORAGE_KEYS.USER_ID, userId);\n\n sessionManager.touch();\n\n let event: JsonEvent | null = {\n type: \"identify\",\n service: resolvedService,\n device_id: deviceId,\n session_id: sessionManager.sessionId,\n user_id: userId,\n timestamp: Date.now(),\n ...traits,\n };\n\n if (beforeSend) {\n event = runBeforeSend(event, beforeSend);\n if (event === null) return;\n }\n\n eventBatcher.add(event);\n },\n\n group(groupId: string, properties?: Properties): void {\n if (!configured) {\n queue.push({ method: \"group\", args: [groupId, properties] });\n return;\n }\n if (_disabled || _optedOut) return;\n if (closed) {\n reportError(new ClosedError());\n return;\n }\n try {\n if (!groupId) throw new ValidationError(\"groupId\", \"is required\");\n } catch (err) {\n reportError(err);\n return;\n }\n\n sessionManager.touch();\n\n let event: JsonEvent | null = {\n type: \"group\",\n service: resolvedService,\n device_id: deviceId,\n session_id: sessionManager.sessionId,\n user_id: userId,\n group_id: groupId,\n timestamp: Date.now(),\n ...superProperties,\n ...properties,\n };\n\n if (beforeSend) {\n event = runBeforeSend(event, beforeSend);\n if (event === null) return;\n }\n\n eventBatcher.add(event);\n },\n\n revenue(\n amount: number,\n currency: string,\n orderId: string,\n properties?: Properties\n ): void {\n if (!configured) {\n queue.push({ method: \"revenue\", args: [amount, currency, orderId, properties] });\n return;\n }\n if (_disabled || _optedOut) return;\n if (closed) {\n reportError(new ClosedError());\n return;\n }\n try {\n if (amount <= 0) throw new ValidationError(\"amount\", \"must be positive\");\n if (!currency) throw new ValidationError(\"currency\", \"is required\");\n if (!orderId) throw new ValidationError(\"orderId\", \"is required\");\n } catch (err) {\n reportError(err);\n return;\n }\n\n sessionManager.touch();\n\n let event: JsonEvent | null = {\n type: \"track\",\n event: \"Order Completed\",\n service: resolvedService,\n device_id: deviceId,\n session_id: sessionManager.sessionId,\n user_id: userId,\n timestamp: Date.now(),\n ...superProperties,\n ...properties,\n order_id: orderId,\n amount,\n currency,\n };\n\n if (beforeSend) {\n event = runBeforeSend(event, beforeSend);\n if (event === null) return;\n }\n\n eventBatcher.add(event);\n },\n\n alias(previousId: string, newUserId: string): void {\n if (!configured) {\n queue.push({ method: \"alias\", args: [previousId, newUserId] });\n return;\n }\n if (_disabled || _optedOut) return;\n if (closed) {\n reportError(new ClosedError());\n return;\n }\n try {\n if (!previousId)\n throw new ValidationError(\"previousId\", \"is required\");\n validateUserId(newUserId);\n } catch (err) {\n reportError(err);\n return;\n }\n\n sessionManager.touch();\n\n let event: JsonEvent | null = {\n type: \"alias\",\n service: resolvedService,\n device_id: deviceId,\n session_id: sessionManager.sessionId,\n user_id: newUserId,\n timestamp: Date.now(),\n previous_id: previousId,\n };\n\n if (beforeSend) {\n event = runBeforeSend(event, beforeSend);\n if (event === null) return;\n }\n\n eventBatcher.add(event);\n },\n\n // -----------------------------------------------------------------------\n // Logging\n // -----------------------------------------------------------------------\n\n log(level: LogLevel, message: string, data?: Properties): void {\n if (!configured) {\n queue.push({ method: \"log\", args: [level, message, data] });\n return;\n }\n if (_disabled || _optedOut) return;\n if (closed) {\n reportError(new ClosedError());\n return;\n }\n try {\n validateLogMessage(message);\n } catch (err) {\n reportError(err);\n return;\n }\n\n let logEntry: JsonLog | null = {\n level,\n message,\n source: resolvedConfig.source,\n service: resolvedService,\n session_id: sessionManager.sessionId,\n timestamp: Date.now(),\n data,\n };\n\n if (beforeSendLog) {\n logEntry = runBeforeSend(logEntry, beforeSendLog);\n if (logEntry === null) return;\n }\n\n logBatcher.add(logEntry);\n },\n\n logEmergency(message: string, data?: Properties): void {\n tell.log(\"emergency\", message, data);\n },\n logAlert(message: string, data?: Properties): void {\n tell.log(\"alert\", message, data);\n },\n logCritical(message: string, data?: Properties): void {\n tell.log(\"critical\", message, data);\n },\n logError(message: string, data?: Properties): void {\n tell.log(\"error\", message, data);\n },\n logWarning(message: string, data?: Properties): void {\n tell.log(\"warning\", message, data);\n },\n logNotice(message: string, data?: Properties): void {\n tell.log(\"notice\", message, data);\n },\n logInfo(message: string, data?: Properties): void {\n tell.log(\"info\", message, data);\n },\n logDebug(message: string, data?: Properties): void {\n tell.log(\"debug\", message, data);\n },\n logTrace(message: string, data?: Properties): void {\n tell.log(\"trace\", message, data);\n },\n\n // -----------------------------------------------------------------------\n // Super Properties\n // -----------------------------------------------------------------------\n\n register(properties: Properties): void {\n if (!configured) {\n queue.push({ method: \"register\", args: [properties] });\n return;\n }\n Object.assign(superProperties, properties);\n persistSuperProps();\n },\n\n unregister(key: string): void {\n if (!configured) {\n queue.push({ method: \"unregister\", args: [key] });\n return;\n }\n delete superProperties[key];\n persistSuperProps();\n },\n\n // -----------------------------------------------------------------------\n // Privacy\n // -----------------------------------------------------------------------\n\n optOut(): void {\n if (!configured) {\n queue.push({ method: \"optOut\", args: [] });\n return;\n }\n _optedOut = true;\n storage.set(STORAGE_KEYS.OPT_OUT, \"1\");\n },\n\n optIn(): void {\n if (!configured) {\n queue.push({ method: \"optIn\", args: [] });\n return;\n }\n _optedOut = false;\n storage.remove(STORAGE_KEYS.OPT_OUT);\n },\n\n isOptedOut(): boolean {\n return _optedOut;\n },\n\n // -----------------------------------------------------------------------\n // Control\n // -----------------------------------------------------------------------\n\n enable(): void {\n _disabled = false;\n },\n\n disable(): void {\n _disabled = true;\n },\n\n // -----------------------------------------------------------------------\n // Lifecycle\n // -----------------------------------------------------------------------\n\n async flush(): Promise<void> {\n if (!configured) return;\n await Promise.all([eventBatcher.flush(), logBatcher.flush()]);\n },\n\n async close(): Promise<void> {\n if (!configured || closed) return;\n closed = true;\n\n if (sessionManager) sessionManager.destroy();\n\n if (typeof window !== \"undefined\" && unloadHandler) {\n window.removeEventListener(\"beforeunload\", unloadHandler);\n unloadHandler = null;\n }\n if (typeof document !== \"undefined\" && visibilityUnloadHandler) {\n document.removeEventListener(\"visibilitychange\", visibilityUnloadHandler);\n visibilityUnloadHandler = null;\n }\n if (typeof window !== \"undefined\") {\n if (errorHandler) {\n window.removeEventListener(\"error\", errorHandler);\n errorHandler = null;\n }\n if (rejectionHandler) {\n window.removeEventListener(\"unhandledrejection\", rejectionHandler);\n rejectionHandler = null;\n }\n }\n\n const work = Promise.all([eventBatcher.close(), logBatcher.close()]);\n const timeout = new Promise<never>((_, reject) =>\n setTimeout(\n () => reject(new Error(\"close timed out\")),\n resolvedConfig.closeTimeout\n )\n );\n\n try {\n await Promise.race([work, timeout]);\n } catch (err) {\n reportError(err);\n }\n\n configured = false;\n },\n\n reset(): void {\n if (!configured) return;\n userId = undefined;\n deviceId = generateId();\n superProperties = {};\n\n storage.remove(STORAGE_KEYS.USER_ID);\n storage.set(STORAGE_KEYS.DEVICE_ID, deviceId);\n storage.remove(STORAGE_KEYS.SUPER_PROPS);\n\n if (sessionManager) {\n sessionManager.sessionId = generateId();\n }\n },\n\n // -----------------------------------------------------------------------\n // Testing helper\n // -----------------------------------------------------------------------\n\n _resetForTesting(): void {\n if (configured && !closed) {\n // Synchronously tear down timers\n if (sessionManager) sessionManager.destroy();\n if (eventBatcher) {\n eventBatcher.drain();\n eventBatcher.close().catch(() => {});\n }\n if (logBatcher) {\n logBatcher.drain();\n logBatcher.close().catch(() => {});\n }\n if (typeof window !== \"undefined\" && unloadHandler) {\n window.removeEventListener(\"beforeunload\", unloadHandler);\n }\n if (typeof document !== \"undefined\" && visibilityUnloadHandler) {\n document.removeEventListener(\n \"visibilitychange\",\n visibilityUnloadHandler\n );\n }\n if (typeof window !== \"undefined\") {\n if (errorHandler) window.removeEventListener(\"error\", errorHandler);\n if (rejectionHandler)\n window.removeEventListener(\"unhandledrejection\", rejectionHandler);\n }\n }\n\n configured = false;\n closed = false;\n _disabled = false;\n _optedOut = false;\n userId = undefined;\n deviceId = \"\";\n superProperties = {};\n beforeSend = undefined;\n beforeSendLog = undefined;\n sdkLogLevel = 0;\n unloadHandler = null;\n visibilityUnloadHandler = null;\n errorHandler = null;\n rejectionHandler = null;\n queue.clear();\n },\n};\n\nexport default tell;\nexport { tell };\n"],"mappings":"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","names":[]}