@tell-rs/browser 0.2.5 → 0.2.6

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.d.ts CHANGED
@@ -44,9 +44,16 @@ interface DeviceContext {
44
44
  url?: string;
45
45
  title?: string;
46
46
  connection_type?: string;
47
+ downlink?: number;
48
+ rtt?: number;
49
+ save_data?: boolean;
47
50
  cpu_cores?: number;
48
51
  device_memory?: number;
49
52
  touch?: boolean;
53
+ bot?: boolean;
54
+ dark_mode?: boolean;
55
+ path?: string;
56
+ screen_orientation?: string;
50
57
  }
51
58
 
52
59
  interface TellInstance {
package/dist/index.js CHANGED
@@ -113,18 +113,13 @@ function generateId() {
113
113
  if (typeof crypto !== "undefined" && crypto.getRandomValues) {
114
114
  const bytes = new Uint8Array(16);
115
115
  crypto.getRandomValues(bytes);
116
- bytes[6] = bytes[6] & 15 | 64;
117
- bytes[8] = bytes[8] & 63 | 128;
118
- const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join(
119
- ""
120
- );
121
- return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
116
+ return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
117
+ }
118
+ let hex = "";
119
+ for (let i = 0; i < 32; i++) {
120
+ hex += (Math.random() * 16 | 0).toString(16);
122
121
  }
123
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
124
- const r = Math.random() * 16 | 0;
125
- const v = c === "x" ? r : r & 3 | 8;
126
- return v.toString(16);
127
- });
122
+ return hex;
128
123
  }
129
124
 
130
125
  // src/bot.ts
@@ -157,13 +152,19 @@ function captureContext() {
157
152
  }
158
153
  ctx.device_type = inferDeviceType(parsed.os, ua, ctx.touch);
159
154
  const conn = navigator.connection;
160
- if (conn?.effectiveType) {
161
- ctx.connection_type = conn.effectiveType;
155
+ if (conn) {
156
+ if (conn.effectiveType) ctx.connection_type = conn.effectiveType;
157
+ if (typeof conn.downlink === "number") ctx.downlink = conn.downlink;
158
+ if (typeof conn.rtt === "number") ctx.rtt = conn.rtt;
159
+ if (conn.saveData) ctx.save_data = true;
162
160
  }
161
+ if (navigator.webdriver) ctx.bot = true;
163
162
  }
164
163
  if (typeof screen !== "undefined") {
165
164
  ctx.screen_width = screen.width;
166
165
  ctx.screen_height = screen.height;
166
+ const orient = screen.orientation;
167
+ if (orient?.type) ctx.screen_orientation = orient.type;
167
168
  }
168
169
  if (typeof window !== "undefined") {
169
170
  ctx.viewport_width = window.innerWidth;
@@ -184,11 +185,18 @@ function captureContext() {
184
185
  }
185
186
  if (typeof location !== "undefined") {
186
187
  ctx.url = location.href;
188
+ if (location.pathname) ctx.path = location.pathname;
187
189
  }
188
190
  try {
189
191
  ctx.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
190
192
  } catch {
191
193
  }
194
+ if (typeof window !== "undefined" && window.matchMedia) {
195
+ try {
196
+ ctx.dark_mode = window.matchMedia("(prefers-color-scheme: dark)").matches;
197
+ } catch {
198
+ }
199
+ }
192
200
  return ctx;
193
201
  }
194
202
  function inferDeviceType(os, ua, touch) {
@@ -262,7 +270,6 @@ var SessionManager = class {
262
270
  timeout;
263
271
  onNewSession;
264
272
  visibilityHandler;
265
- checkTimer;
266
273
  lastContextAt = {};
267
274
  constructor(config) {
268
275
  this.timeout = config.timeout;
@@ -274,10 +281,6 @@ var SessionManager = class {
274
281
  if (typeof document !== "undefined") {
275
282
  document.addEventListener("visibilitychange", this.visibilityHandler);
276
283
  }
277
- this.checkTimer = setInterval(() => this.checkTimeout(), 6e4);
278
- if (typeof this.checkTimer.unref === "function") {
279
- this.checkTimer.unref();
280
- }
281
284
  }
282
285
  get sessionId() {
283
286
  return this._sessionId;
@@ -285,14 +288,18 @@ var SessionManager = class {
285
288
  set sessionId(id) {
286
289
  this._sessionId = id;
287
290
  }
291
+ /** Update activity timestamp; rotates session if idle longer than timeout. */
288
292
  touch() {
289
- this.lastActivityAt = Date.now();
293
+ const now = Date.now();
294
+ if (now - this.lastActivityAt > this.timeout) {
295
+ this.rotateSession("session_timeout");
296
+ }
297
+ this.lastActivityAt = now;
290
298
  }
291
299
  destroy() {
292
300
  if (typeof document !== "undefined") {
293
301
  document.removeEventListener("visibilitychange", this.visibilityHandler);
294
302
  }
295
- clearInterval(this.checkTimer);
296
303
  }
297
304
  handleVisibility() {
298
305
  if (document.visibilityState === "hidden") {
@@ -306,11 +313,6 @@ var SessionManager = class {
306
313
  this.lastHiddenAt = 0;
307
314
  }
308
315
  }
309
- checkTimeout() {
310
- if (Date.now() - this.lastActivityAt > this.timeout) {
311
- this.rotateSession("session_timeout");
312
- }
313
- }
314
316
  rotateSession(reason) {
315
317
  this._sessionId = generateId();
316
318
  this.lastActivityAt = Date.now();
@@ -699,6 +701,7 @@ var tell = {
699
701
  reportError(err);
700
702
  return;
701
703
  }
704
+ sessionManager.touch();
702
705
  let event = {
703
706
  type: "track",
704
707
  event: eventName,
@@ -713,7 +716,6 @@ var tell = {
713
716
  event = runBeforeSend(event, beforeSend);
714
717
  if (event === null) return;
715
718
  }
716
- sessionManager.touch();
717
719
  eventBatcher.add(event);
718
720
  },
719
721
  identify(newUserId, traits) {
@@ -734,6 +736,7 @@ var tell = {
734
736
  }
735
737
  userId = newUserId;
736
738
  storage.set(STORAGE_KEYS.USER_ID, userId);
739
+ sessionManager.touch();
737
740
  let event = {
738
741
  type: "identify",
739
742
  device_id: deviceId,
@@ -746,7 +749,6 @@ var tell = {
746
749
  event = runBeforeSend(event, beforeSend);
747
750
  if (event === null) return;
748
751
  }
749
- sessionManager.touch();
750
752
  eventBatcher.add(event);
751
753
  },
752
754
  group(groupId, properties) {
@@ -765,6 +767,7 @@ var tell = {
765
767
  reportError(err);
766
768
  return;
767
769
  }
770
+ sessionManager.touch();
768
771
  let event = {
769
772
  type: "group",
770
773
  device_id: deviceId,
@@ -779,7 +782,6 @@ var tell = {
779
782
  event = runBeforeSend(event, beforeSend);
780
783
  if (event === null) return;
781
784
  }
782
- sessionManager.touch();
783
785
  eventBatcher.add(event);
784
786
  },
785
787
  revenue(amount, currency, orderId, properties) {
@@ -800,6 +802,7 @@ var tell = {
800
802
  reportError(err);
801
803
  return;
802
804
  }
805
+ sessionManager.touch();
803
806
  let event = {
804
807
  type: "track",
805
808
  event: "Order Completed",
@@ -817,7 +820,6 @@ var tell = {
817
820
  event = runBeforeSend(event, beforeSend);
818
821
  if (event === null) return;
819
822
  }
820
- sessionManager.touch();
821
823
  eventBatcher.add(event);
822
824
  },
823
825
  alias(previousId, newUserId) {
@@ -838,6 +840,7 @@ var tell = {
838
840
  reportError(err);
839
841
  return;
840
842
  }
843
+ sessionManager.touch();
841
844
  let event = {
842
845
  type: "alias",
843
846
  device_id: deviceId,
@@ -850,7 +853,6 @@ var tell = {
850
853
  event = runBeforeSend(event, beforeSend);
851
854
  if (event === null) return;
852
855
  }
853
- sessionManager.touch();
854
856
  eventBatcher.add(event);
855
857
  },
856
858
  // -----------------------------------------------------------------------
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 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 UUID v4 string 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 // Set version (4) and variant (10xx)\n bytes[6] = (bytes[6] & 0x0f) | 0x40;\n bytes[8] = (bytes[8] & 0x3f) | 0x80;\n const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\n \"\"\n );\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n }\n\n // Fallback for environments without crypto (extremely rare)\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === \"x\" ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\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 cpu_cores?: number;\n device_memory?: number;\n touch?: boolean;\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?.effectiveType) {\n ctx.connection_type = conn.effectiveType;\n }\n }\n\n if (typeof screen !== \"undefined\") {\n ctx.screen_width = screen.width;\n ctx.screen_height = screen.height;\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 }\n\n try {\n ctx.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n } catch {\n // Intl not available\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 readonly checkTimer: ReturnType<typeof setInterval>;\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 this.checkTimer = setInterval(() => this.checkTimeout(), 60_000);\n if (typeof (this.checkTimer as any).unref === \"function\") {\n (this.checkTimer as any).unref();\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 touch(): void {\n this.lastActivityAt = Date.now();\n }\n\n destroy(): void {\n if (typeof document !== \"undefined\") {\n document.removeEventListener(\"visibilitychange\", this.visibilityHandler);\n }\n clearInterval(this.checkTimer);\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 checkTimeout(): void {\n if (Date.now() - this.lastActivityAt > this.timeout) {\n this.rotateSession(\"session_timeout\");\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 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 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 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 let event: JsonEvent | null = {\n type: \"track\",\n event: eventName,\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 sessionManager.touch();\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 let event: JsonEvent | null = {\n type: \"identify\",\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 sessionManager.touch();\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 let event: JsonEvent | null = {\n type: \"group\",\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 sessionManager.touch();\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 let event: JsonEvent | null = {\n type: \"track\",\n event: \"Order Completed\",\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 sessionManager.touch();\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 let event: JsonEvent | null = {\n type: \"alias\",\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 sessionManager.touch();\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 ?? \"app\",\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 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 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 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 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 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 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 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 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 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 ?? \"app\",\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":[]}