@glassanalytics/browser 0.1.2 → 0.1.4

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
@@ -21,11 +21,29 @@ interface GlassConfig {
21
21
  errors?: boolean;
22
22
  /** Opt-in: capture `console.error`/`console.warn` as breadcrumbs/errors (§5). Default off. */
23
23
  captureConsole?: boolean;
24
+ /**
25
+ * Record console output INTO the session replay (surfaced in the player's
26
+ * Console inspector). Independent of `captureConsole` (which turns errors into
27
+ * Glass events). Default on when replay is on.
28
+ */
29
+ recordConsole?: boolean;
30
+ /**
31
+ * Record network requests (fetch/XHR) into the session replay (player's Network
32
+ * inspector). Captures ONLY method, URL, status and timing — never headers or
33
+ * bodies — and never the Glass ingest host itself. Default on when replay is on.
34
+ */
35
+ recordNetwork?: boolean;
24
36
  /** Fraction of sessions recorded (client-side). */
25
37
  sampleRate?: number;
26
38
  consent?: 'implied' | 'opt-in' | 'opt-out';
27
39
  maskAllInputs?: boolean;
28
40
  maskTextSelector?: string;
41
+ /**
42
+ * Extra CSS selector for subtrees to exclude from replay (shown as a
43
+ * placeholder). Glass ALWAYS also blocks `.glass-block` / `[data-glass-block]`
44
+ * (and rrweb's `rr-block`) — mark decorative/animated elements with those to
45
+ * keep them out of recordings without flooding the stream.
46
+ */
29
47
  blockSelector?: string;
30
48
  respectDoNotTrack?: boolean;
31
49
  flushIntervalMs?: number;
@@ -36,7 +54,7 @@ interface GlassConfig {
36
54
  bootstrapFlags?: Record<string, FlagValue>;
37
55
  /**
38
56
  * Optional flag DEFINITIONS for local (offline / property-aware) bucketing via
39
- * `@glassanalytics/core` evaluateFlag. The hosted server intentionally does NOT leak the
57
+ * `@glass/core` evaluateFlag. The hosted server intentionally does NOT leak the
40
58
  * rule set, so this is for self-host / advanced setups that ship definitions.
41
59
  */
42
60
  flagDefinitions?: FlagDefinition[];
@@ -147,7 +165,7 @@ declare class Glass {
147
165
  * resolved value → fallback.
148
166
  */
149
167
  private resolve;
150
- /** Local bucketing via @glassanalytics/core when definitions were provided to init(). */
168
+ /** Local bucketing via @glass/core when definitions were provided to init(). */
151
169
  private evaluateLocal;
152
170
  isFeatureEnabledSync(key: string, opts?: FlagOptions): boolean;
153
171
  isFeatureEnabled(key: string, opts?: FlagOptions): Promise<boolean>;
package/dist/index.js CHANGED
@@ -119,9 +119,108 @@ var ReplayEncoder = class {
119
119
  }
120
120
  };
121
121
 
122
+ // src/network-plugin.ts
123
+ var NETWORK_PLUGIN_NAME = "rrweb/network@1";
124
+ function getGlassNetworkPlugin(options = {}) {
125
+ return {
126
+ name: NETWORK_PLUGIN_NAME,
127
+ options,
128
+ observer(cb, _win, opts) {
129
+ if (typeof window === "undefined") return () => {
130
+ };
131
+ const ignore = opts.ignoreUrlPrefix;
132
+ const teardowns = [];
133
+ const shouldIgnore = (url) => !url || (ignore ? url.startsWith(ignore) : false);
134
+ const record = (r) => {
135
+ try {
136
+ cb({ requests: [r] });
137
+ } catch {
138
+ }
139
+ };
140
+ if (typeof window.fetch === "function") {
141
+ const orig = window.fetch;
142
+ const patched = (input, init) => {
143
+ const url = typeof input === "string" ? input : input instanceof URL ? input.href : input?.url ?? "";
144
+ const method = (init?.method ?? (typeof input === "object" && input && "method" in input ? input.method : "GET")).toUpperCase();
145
+ const startTime = Date.now();
146
+ const p = orig(input, init);
147
+ if (!shouldIgnore(url)) {
148
+ p.then(
149
+ (res) => record({ type: "fetch", method, name: url, status: res.status, startTime, endTime: Date.now() }),
150
+ () => record({ type: "fetch", method, name: url, status: 0, startTime, endTime: Date.now() })
151
+ );
152
+ }
153
+ return p;
154
+ };
155
+ window.fetch = patched;
156
+ teardowns.push(() => {
157
+ window.fetch = orig;
158
+ });
159
+ }
160
+ if (typeof XMLHttpRequest !== "undefined") {
161
+ const proto = XMLHttpRequest.prototype;
162
+ const origOpen = proto.open;
163
+ const origSend = proto.send;
164
+ const meta = /* @__PURE__ */ new WeakMap();
165
+ proto.open = function open(method, url, ...rest) {
166
+ meta.set(this, {
167
+ method: String(method ?? "GET").toUpperCase(),
168
+ url: typeof url === "string" ? url : url.href
169
+ });
170
+ return origOpen.call(
171
+ this,
172
+ method,
173
+ url,
174
+ ...rest
175
+ );
176
+ };
177
+ proto.send = function send(...args) {
178
+ const m = meta.get(this);
179
+ if (m && !shouldIgnore(m.url)) {
180
+ const startTime = Date.now();
181
+ this.addEventListener(
182
+ "loadend",
183
+ () => record({
184
+ type: "xhr",
185
+ method: m.method,
186
+ name: m.url,
187
+ status: this.status,
188
+ startTime,
189
+ endTime: Date.now()
190
+ }),
191
+ { once: true }
192
+ );
193
+ }
194
+ return origSend.apply(this, args);
195
+ };
196
+ teardowns.push(() => {
197
+ proto.open = origOpen;
198
+ proto.send = origSend;
199
+ });
200
+ }
201
+ return () => {
202
+ for (const t of teardowns) {
203
+ try {
204
+ t();
205
+ } catch {
206
+ }
207
+ }
208
+ };
209
+ }
210
+ };
211
+ }
212
+
122
213
  // src/replay.ts
123
214
  var SENSITIVE_INPUT_TYPES = /* @__PURE__ */ new Set(["password", "email", "tel", "hidden"]);
124
215
  var SENSITIVE_NAME_RE = /pass|secret|token|ssn|card|cvv|cvc|account|email|phone|tax/i;
216
+ var GLASS_BLOCK_SELECTOR = ".glass-block,[data-glass-block]";
217
+ var SAMPLING = {
218
+ mousemove: 50,
219
+ mouseInteraction: true,
220
+ scroll: 150,
221
+ media: 800,
222
+ input: "last"
223
+ };
125
224
  var ReplayRecorder = class {
126
225
  constructor(cfg, getSessionId) {
127
226
  this.cfg = cfg;
@@ -137,21 +236,36 @@ var ReplayRecorder = class {
137
236
  encoder = new ReplayEncoder();
138
237
  /** rrweb's addCustomEvent, captured on start — lets us weave Glass events into the stream. */
139
238
  addCustom = null;
239
+ boundVisibility = null;
140
240
  async start() {
141
241
  if (this.stop) return;
142
242
  if (typeof window === "undefined") return;
143
243
  const { record } = await import('rrweb');
144
244
  const rec = record;
145
245
  this.addCustom = typeof rec.addCustomEvent === "function" ? rec.addCustomEvent.bind(record) : null;
246
+ const plugins = [];
247
+ if (this.cfg.recordConsole) {
248
+ try {
249
+ const { getRecordConsolePlugin } = await import('@rrweb/rrweb-plugin-console-record');
250
+ plugins.push(getRecordConsolePlugin());
251
+ } catch {
252
+ }
253
+ }
254
+ if (this.cfg.recordNetwork) {
255
+ plugins.push(getGlassNetworkPlugin({ ignoreUrlPrefix: this.cfg.ingestHost }));
256
+ }
146
257
  this.stop = record({
147
258
  emit: (event) => {
148
259
  this.events.push(event);
149
260
  if (this.events.length >= 50) void this.flushSegment();
150
261
  },
262
+ plugins: plugins.length ? plugins : void 0,
151
263
  // Privacy defaults: never leak user input.
152
264
  maskAllInputs: this.cfg.maskAllInputs,
153
265
  maskTextSelector: this.cfg.maskTextSelector,
154
- blockSelector: this.cfg.blockSelector,
266
+ // Merge the caller's blockSelector with Glass's always-on block convention.
267
+ blockSelector: this.cfg.blockSelector ? `${this.cfg.blockSelector},${GLASS_BLOCK_SELECTOR}` : GLASS_BLOCK_SELECTOR,
268
+ sampling: SAMPLING,
155
269
  // ALWAYS mask sensitive fields regardless of maskAllInputs (defense in depth).
156
270
  maskInputFn: (text, element) => {
157
271
  if (this.cfg.maskAllInputs) return "*".repeat(text.length);
@@ -166,6 +280,15 @@ var ReplayRecorder = class {
166
280
  this.interval = setInterval(() => void this.flushSegment(), 5e3);
167
281
  this.boundFinal = () => this.flushFinalBeacon();
168
282
  window.addEventListener("pagehide", this.boundFinal);
283
+ if (typeof document !== "undefined") {
284
+ this.boundVisibility = () => {
285
+ const hidden = document.visibilityState === "hidden";
286
+ this.addEvent(hidden ? "$window_hidden" : "$window_visible", {
287
+ event: hidden ? "Window became hidden" : "Window became visible"
288
+ });
289
+ };
290
+ document.addEventListener("visibilitychange", this.boundVisibility);
291
+ }
169
292
  }
170
293
  /**
171
294
  * Weave a Glass event into the rrweb stream as a Custom (type 5) event, so the
@@ -225,6 +348,10 @@ var ReplayRecorder = class {
225
348
  window.removeEventListener("pagehide", this.boundFinal);
226
349
  this.boundFinal = null;
227
350
  }
351
+ if (this.boundVisibility && typeof document !== "undefined") {
352
+ document.removeEventListener("visibilitychange", this.boundVisibility);
353
+ this.boundVisibility = null;
354
+ }
228
355
  this.encoder.dispose();
229
356
  }
230
357
  get recording() {
@@ -577,6 +704,8 @@ var Glass = class {
577
704
  autocapture: config.autocapture ?? true,
578
705
  errors: config.errors ?? true,
579
706
  captureConsole: config.captureConsole ?? false,
707
+ recordConsole: config.recordConsole ?? true,
708
+ recordNetwork: config.recordNetwork ?? true,
580
709
  sampleRate: config.sampleRate ?? 1,
581
710
  consent: config.consent ?? "implied",
582
711
  maskAllInputs: config.maskAllInputs ?? true,
@@ -764,7 +893,13 @@ var Glass = class {
764
893
  });
765
894
  if (this.cfg.replay) {
766
895
  const name = event ?? type;
767
- this.replay.addEvent(name, { event: name, ...type === "error" ? { level: "error" } : {} });
896
+ this.replay.addEvent(name, {
897
+ event: name,
898
+ ...type === "error" ? { level: "error" } : {},
899
+ // Stamp the URL on pageviews so the player's address bar follows SPA route
900
+ // changes — rrweb only emits a meta snapshot on full (hard) page loads.
901
+ ...name === "$pageview" && typeof location !== "undefined" ? { href: location.href } : {}
902
+ });
768
903
  }
769
904
  }
770
905
  /** Device/screen context attached to EVERY event (`SDK.md` §4). */
@@ -973,7 +1108,7 @@ var Glass = class {
973
1108
  if (value !== void 0 && opts?.trackExposure !== false) this.exposure(key, value);
974
1109
  return value;
975
1110
  }
976
- /** Local bucketing via @glassanalytics/core when definitions were provided to init(). */
1111
+ /** Local bucketing via @glass/core when definitions were provided to init(). */
977
1112
  evaluateLocal(key) {
978
1113
  const def = this.cfg.flagDefinitions.find((d) => d.key === key);
979
1114
  if (!def) return void 0;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/replay-encoder.ts","../src/replay.ts","../src/offline-store.ts","../src/transport.ts","../src/index.ts"],"names":["ls"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Off-main-thread replay-segment encoder (`SDK.md` §6). rrweb segments are large\n * and highly repetitive, so we (a) JSON-serialize and (b) gzip them in a Web\n * Worker — keeping both the (potentially multi-MB) stringify and the compression\n * off the page's main thread. Everything degrades gracefully: no Worker → encode\n * on the main thread; no `CompressionStream` → send uncompressed JSON. The result\n * is the same bytes the ingest endpoint already accepts, just optionally gzipped\n * (signalled to callers via `gzip`, which they translate to `Content-Encoding`).\n */\n\nexport interface EncodedSegment {\n body: Uint8Array | string;\n gzip: boolean;\n}\n\n/**\n * Worker body, kept dependency-free so it can be inlined via a Blob URL (no\n * separate build step / bundler entry). It receives `{ id, json }`, gzips when\n * possible, and posts back `{ id, buf, gzip }` transferring the buffer.\n */\nconst WORKER_SRC = `\nself.onmessage = async function (e) {\n var id = e.data.id, json = e.data.json;\n try {\n var bytes = new TextEncoder().encode(json);\n if (typeof CompressionStream !== 'undefined') {\n var cs = new CompressionStream('gzip');\n var w = cs.writable.getWriter();\n w.write(bytes); w.close();\n var buf = await new Response(cs.readable).arrayBuffer();\n self.postMessage({ id: id, buf: buf, gzip: true }, [buf]);\n } else {\n self.postMessage({ id: id, buf: bytes.buffer, gzip: false }, [bytes.buffer]);\n }\n } catch (err) {\n self.postMessage({ id: id, error: String(err) });\n }\n};\n`;\n\ninterface WorkerReply {\n id: number;\n buf?: ArrayBuffer;\n gzip?: boolean;\n error?: string;\n}\n\nexport class ReplayEncoder {\n private worker: Worker | null = null;\n private workerUrl: string | null = null;\n private workerBroken = false;\n private nextId = 1;\n private pending = new Map<number, (r: WorkerReply) => void>();\n\n /** Lazily spin up the encode worker; null if Workers/Blob URLs aren't available. */\n private ensureWorker(): Worker | null {\n if (this.worker || this.workerBroken) return this.worker;\n try {\n if (typeof Worker === 'undefined' || typeof Blob === 'undefined' || typeof URL === 'undefined') {\n this.workerBroken = true;\n return null;\n }\n this.workerUrl = URL.createObjectURL(new Blob([WORKER_SRC], { type: 'text/javascript' }));\n this.worker = new Worker(this.workerUrl);\n this.worker.onmessage = (ev: MessageEvent<WorkerReply>) => {\n const resolve = this.pending.get(ev.data.id);\n if (resolve) {\n this.pending.delete(ev.data.id);\n resolve(ev.data);\n }\n };\n this.worker.onerror = () => {\n // A broken worker disables itself; future encodes run on the main thread.\n this.workerBroken = true;\n for (const [, resolve] of this.pending) resolve({ id: -1, error: 'worker_error' });\n this.pending.clear();\n };\n return this.worker;\n } catch {\n this.workerBroken = true;\n return null;\n }\n }\n\n async encode(segment: unknown): Promise<EncodedSegment> {\n let json: string;\n try {\n json = JSON.stringify(segment);\n } catch {\n json = '[]';\n }\n\n const worker = this.ensureWorker();\n if (worker) {\n try {\n const reply = await this.postToWorker(worker, json);\n if (!reply.error && reply.buf) {\n return { body: new Uint8Array(reply.buf), gzip: reply.gzip === true };\n }\n } catch {\n /* fall through to main-thread encoding */\n }\n }\n return this.encodeMainThread(json);\n }\n\n private postToWorker(worker: Worker, json: string): Promise<WorkerReply> {\n const id = this.nextId++;\n return new Promise<WorkerReply>((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.pending.delete(id);\n reject(new Error('encode_timeout'));\n }, 2000);\n this.pending.set(id, (r) => {\n clearTimeout(timeout);\n resolve(r);\n });\n worker.postMessage({ id, json });\n });\n }\n\n /** Main-thread fallback: gzip via CompressionStream when present, else raw JSON. */\n private async encodeMainThread(json: string): Promise<EncodedSegment> {\n const CS = (globalThis as { CompressionStream?: typeof CompressionStream }).CompressionStream;\n if (typeof CS !== 'undefined') {\n try {\n const cs = new CS('gzip');\n const writer = cs.writable.getWriter();\n void writer.write(new TextEncoder().encode(json));\n void writer.close();\n const buf = await new Response(cs.readable).arrayBuffer();\n return { body: new Uint8Array(buf), gzip: true };\n } catch {\n /* fall through to uncompressed */\n }\n }\n return { body: json, gzip: false };\n }\n\n dispose(): void {\n this.worker?.terminate();\n this.worker = null;\n if (this.workerUrl) {\n try {\n URL.revokeObjectURL(this.workerUrl);\n } catch {\n /* ignore */\n }\n this.workerUrl = null;\n }\n this.pending.clear();\n }\n}\n","import { replaySegmentPath } from '@glassanalytics/core';\nimport type { ResolvedConfig } from './types.js';\nimport { ReplayEncoder } from './replay-encoder.js';\n\n/**\n * Session replay (`SDK.md` §6). rrweb is loaded LAZILY (dynamic import) so apps\n * that don't record pay nothing. Recording is MASKED BY DEFAULT — all inputs\n * masked, configurable text/blocked selectors — and segments are streamed to the\n * ingest `/v1/replay/:session/:seq` endpoint, not buffered in memory.\n */\n/** Input types/name patterns ALWAYS masked, even when maskAllInputs is false. */\nconst SENSITIVE_INPUT_TYPES = new Set(['password', 'email', 'tel', 'hidden']);\nconst SENSITIVE_NAME_RE = /pass|secret|token|ssn|card|cvv|cvc|account|email|phone|tax/i;\n\nexport class ReplayRecorder {\n private stop: (() => void) | null = null;\n private seq = 0;\n private events: unknown[] = [];\n private interval: ReturnType<typeof setInterval> | null = null;\n private boundFinal: (() => void) | null = null;\n private encoder = new ReplayEncoder();\n /** rrweb's addCustomEvent, captured on start — lets us weave Glass events into the stream. */\n private addCustom: ((tag: string, payload: unknown) => void) | null = null;\n\n constructor(\n private cfg: ResolvedConfig,\n private getSessionId: () => string,\n ) {}\n\n async start(): Promise<void> {\n if (this.stop) return;\n if (typeof window === 'undefined') return;\n const { record } = await import('rrweb');\n const rec = record as unknown as { addCustomEvent?: (tag: string, payload: unknown) => void };\n this.addCustom = typeof rec.addCustomEvent === 'function' ? rec.addCustomEvent.bind(record) : null;\n this.stop =\n record({\n emit: (event: unknown) => {\n this.events.push(event);\n if (this.events.length >= 50) void this.flushSegment();\n },\n // Privacy defaults: never leak user input.\n maskAllInputs: this.cfg.maskAllInputs,\n maskTextSelector: this.cfg.maskTextSelector,\n blockSelector: this.cfg.blockSelector,\n // ALWAYS mask sensitive fields regardless of maskAllInputs (defense in depth).\n maskInputFn: (text: string, element: HTMLElement) => {\n if (this.cfg.maskAllInputs) return '*'.repeat(text.length);\n const type = (element.getAttribute('type') ?? '').toLowerCase();\n const name = `${element.getAttribute('name') ?? ''} ${element.getAttribute('autocomplete') ?? ''} ${element.id}`;\n if (SENSITIVE_INPUT_TYPES.has(type) || SENSITIVE_NAME_RE.test(name)) return '*'.repeat(text.length);\n return text;\n },\n recordCanvas: false,\n collectFonts: false,\n }) ?? null;\n\n this.interval = setInterval(() => void this.flushSegment(), 5000);\n // Final segment on unload via beacon (fetch is unreliable during teardown).\n this.boundFinal = () => this.flushFinalBeacon();\n window.addEventListener('pagehide', this.boundFinal);\n }\n\n /**\n * Weave a Glass event into the rrweb stream as a Custom (type 5) event, so the\n * player can render it as a timeline marker (`UI.md` §4.1). No-op unless we're\n * actively recording. Payload is kept tiny (name + optional level) to avoid\n * bloating replay segments.\n */\n addEvent(name: string, payload: { event: string; level?: string }): void {\n if (!this.stop || !this.addCustom) return;\n try {\n this.addCustom(name, payload);\n } catch {\n /* a dropped marker is non-fatal */\n }\n }\n\n private async flushSegment(): Promise<void> {\n if (this.events.length === 0) return;\n const segment = this.events.splice(0, this.events.length);\n const seq = this.seq++;\n const url = `${this.cfg.ingestHost}${replaySegmentPath(this.getSessionId(), seq)}`;\n\n // Serialize + gzip OFF the main thread (Web Worker) so a big segment never\n // janks the page; on any failure we fall back to plain JSON. Compression is\n // a large COGS/bandwidth win (rrweb segments are very repetitive).\n const encoded = await this.encoder.encode(segment);\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Glass-Key ${this.cfg.projectKey}`,\n };\n if (encoded.gzip) headers['Content-Encoding'] = 'gzip';\n\n try {\n await fetch(url, {\n method: 'POST',\n keepalive: true,\n headers,\n body: encoded.body as BodyInit,\n });\n } catch {\n // a dropped replay segment is non-fatal; the player tolerates gaps.\n }\n }\n\n /** Flush the trailing segment with sendBeacon so it survives page teardown. */\n private flushFinalBeacon(): void {\n if (this.events.length === 0) return;\n const segment = this.events.splice(0, this.events.length);\n const seq = this.seq++;\n const url = `${this.cfg.ingestHost}${replaySegmentPath(this.getSessionId(), seq)}?k=${encodeURIComponent(this.cfg.projectKey)}`;\n const payload = JSON.stringify(segment);\n if (typeof navigator !== 'undefined' && navigator.sendBeacon) {\n navigator.sendBeacon(url, payload);\n }\n }\n\n async stopRecording(): Promise<void> {\n await this.flushSegment();\n this.stop?.();\n this.stop = null;\n this.addCustom = null;\n if (this.interval) {\n clearInterval(this.interval);\n this.interval = null;\n }\n if (this.boundFinal && typeof window !== 'undefined') {\n window.removeEventListener('pagehide', this.boundFinal);\n this.boundFinal = null;\n }\n this.encoder.dispose();\n }\n\n get recording(): boolean {\n return this.stop !== null;\n }\n}\n","import type { QueuedBatch } from './transport.js';\n\n/**\n * Durable offline queue for event batches (`SDK.md` §10). Prefers IndexedDB\n * (larger quota, survives reloads) and transparently falls back to localStorage\n * when IDB is unavailable (private mode / old browsers) and to an in-memory\n * array when neither is present (SSR/tests). Only already-masked payloads are\n * stored, entries are TTL'd, and the queue is size-capped.\n */\n\nconst DB_NAME = 'glass';\nconst STORE = 'offline_q';\nconst LS_KEY = 'glass_offline_q';\n\nexport class OfflineStore {\n private mem: QueuedBatch[] = [];\n private dbPromise: Promise<IDBDatabase> | null = null;\n\n constructor(\n private max: number,\n private ttlMs: number,\n ) {}\n\n private idb(): Promise<IDBDatabase> | null {\n if (typeof indexedDB === 'undefined') return null;\n if (!this.dbPromise) {\n this.dbPromise = new Promise<IDBDatabase>((resolve, reject) => {\n const req = indexedDB.open(DB_NAME, 1);\n req.onupgradeneeded = () => {\n const db = req.result;\n if (!db.objectStoreNames.contains(STORE)) db.createObjectStore(STORE, { autoIncrement: true });\n };\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => reject(req.error);\n }).catch((err) => {\n // Disable IDB for the rest of the session on failure.\n this.dbPromise = null;\n throw err;\n });\n }\n return this.dbPromise;\n }\n\n private fresh(items: QueuedBatch[]): QueuedBatch[] {\n const cutoff = Date.now() - this.ttlMs;\n const kept = items.filter((b) => b.at >= cutoff);\n return kept.length > this.max ? kept.slice(kept.length - this.max) : kept;\n }\n\n async append(batch: QueuedBatch): Promise<void> {\n try {\n const db = await this.idb();\n if (db) {\n await this.idbWrite(db, batch);\n return;\n }\n } catch {\n /* fall through to localStorage */\n }\n if (this.tryLS((q) => this.fresh([...q, batch]))) return;\n this.mem = this.fresh([...this.mem, batch]);\n }\n\n async drain(): Promise<QueuedBatch[]> {\n try {\n const db = await this.idb();\n if (db) return this.fresh(await this.idbDrain(db));\n } catch {\n /* fall through */\n }\n const ls = this.readLS();\n if (ls !== null) {\n this.writeLS([]);\n return this.fresh(ls);\n }\n const m = this.mem;\n this.mem = [];\n return this.fresh(m);\n }\n\n async clear(): Promise<void> {\n this.mem = [];\n try {\n const db = await this.idb();\n if (db) {\n await new Promise<void>((resolve) => {\n const tx = db.transaction(STORE, 'readwrite');\n tx.objectStore(STORE).clear();\n tx.oncomplete = () => resolve();\n tx.onerror = () => resolve();\n });\n }\n } catch {\n /* ignore */\n }\n this.writeLS([]);\n }\n\n // --- IndexedDB helpers ------------------------------------------------------\n\n private idbWrite(db: IDBDatabase, batch: QueuedBatch): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE, 'readwrite');\n tx.objectStore(STORE).add(batch);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n private idbDrain(db: IDBDatabase): Promise<QueuedBatch[]> {\n return new Promise<QueuedBatch[]>((resolve, reject) => {\n const tx = db.transaction(STORE, 'readwrite');\n const store = tx.objectStore(STORE);\n const getAll = store.getAll();\n getAll.onsuccess = () => {\n store.clear();\n resolve((getAll.result as QueuedBatch[]) ?? []);\n };\n getAll.onerror = () => reject(getAll.error);\n });\n }\n\n // --- localStorage fallback --------------------------------------------------\n\n private readLS(): QueuedBatch[] | null {\n if (typeof localStorage === 'undefined') return null;\n try {\n const raw = localStorage.getItem(LS_KEY);\n return raw ? (JSON.parse(raw) as QueuedBatch[]) : [];\n } catch {\n return null;\n }\n }\n\n private writeLS(q: QueuedBatch[]): void {\n if (typeof localStorage === 'undefined') return;\n try {\n localStorage.setItem(LS_KEY, JSON.stringify(q));\n } catch {\n /* storage full/disabled — drop silently */\n }\n }\n\n private tryLS(update: (q: QueuedBatch[]) => QueuedBatch[]): boolean {\n const cur = this.readLS();\n if (cur === null) return false;\n this.writeLS(update(cur));\n return true;\n }\n}\n","import { INGEST_AUTH_SCHEME, type IngestBatch } from '@glassanalytics/core';\nimport { OfflineStore } from './offline-store.js';\nimport type { GlassEvent, ResolvedConfig } from './types.js';\n\n/**\n * Reliable, cheap transport (`SDK.md` §10): batch on a timer/size, use\n * `sendBeacon` on unload, queue offline, and BACK OFF (exponential + jitter) on\n * failures. Under memory pressure we drop the LOWEST-value events first so\n * high-signal events (errors, identify, exposure) survive. The goal is to never\n * block the app's main work and never lose more than the lowest-value tail.\n */\n\nconst QUEUE_TTL_MS = 24 * 3_600_000;\nconst QUEUE_MAX = 500;\n/** In-memory ceiling before value-based shedding kicks in. */\nconst BUFFER_MAX = 1000;\nconst BACKOFF_BASE_MS = 1000;\nconst BACKOFF_CAP_MS = 5 * 60_000;\n\ninterface QueuedBatch {\n at: number;\n body: IngestBatch;\n}\n\n/** Priority for value-based backpressure — higher survives shedding. */\nfunction eventValue(e: GlassEvent): number {\n switch (e.type) {\n case 'error':\n return 100;\n case 'identify':\n case 'group':\n return 90;\n case 'exposure':\n return 80;\n case 'track':\n // Autocapture / passive pageviews are the most sheddable.\n return e.event === '$autocapture' || e.event === '$pageview' ? 10 : 50;\n default:\n return 40;\n }\n}\n\nexport class Transport {\n private buffer: GlassEvent[] = [];\n private timer: ReturnType<typeof setTimeout> | null = null;\n private retryTimer: ReturnType<typeof setTimeout> | null = null;\n private backoffUntil = 0;\n private failures = 0;\n private store = new OfflineStore(QUEUE_MAX, QUEUE_TTL_MS);\n\n private onPageHide = () => void this.flush(true);\n private onOnline = () => void this.drainOffline();\n\n constructor(\n private cfg: ResolvedConfig,\n private getIdentity: () => Pick<IngestBatch, 'device_id' | 'session_id' | 'user_id' | 'traits' | 'group'>,\n ) {\n if (typeof window !== 'undefined') {\n window.addEventListener('pagehide', this.onPageHide);\n window.addEventListener('online', this.onOnline);\n }\n }\n\n /** Remove window listeners and pending timers (called from Glass.shutdown()). */\n destroy(): void {\n if (typeof window !== 'undefined') {\n window.removeEventListener('pagehide', this.onPageHide);\n window.removeEventListener('online', this.onOnline);\n }\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n if (this.retryTimer) {\n clearTimeout(this.retryTimer);\n this.retryTimer = null;\n }\n }\n\n enqueue(event: GlassEvent): void {\n const finalEvent = this.cfg.beforeSend(event);\n if (!finalEvent) return; // dropped by beforeSend\n this.buffer.push(finalEvent);\n this.applyBackpressure();\n if (this.buffer.length >= this.cfg.flushAt) {\n void this.flush();\n } else if (!this.timer) {\n this.timer = setTimeout(() => void this.flush(), this.cfg.flushIntervalMs);\n }\n }\n\n /**\n * Cap the in-memory buffer by shedding the lowest-value events when it grows\n * past BUFFER_MAX (e.g. a long offline burst of autocapture). Errors and\n * identity events are kept preferentially.\n */\n private applyBackpressure(): void {\n if (this.buffer.length <= BUFFER_MAX) return;\n // Stable sort by value descending, keep the top BUFFER_MAX, preserve order.\n const indexed = this.buffer.map((e, i) => ({ e, i }));\n indexed.sort((a, b) => eventValue(b.e) - eventValue(a.e) || a.i - b.i);\n const kept = indexed.slice(0, BUFFER_MAX).sort((a, b) => a.i - b.i);\n this.buffer = kept.map((x) => x.e);\n }\n\n async flush(useBeacon = false): Promise<void> {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n if (this.buffer.length === 0) return;\n const events = this.buffer.splice(0, this.buffer.length);\n const body: IngestBatch = {\n sent_at: new Date().toISOString(),\n ...this.getIdentity(),\n events,\n };\n\n // Respect server backpressure: persist for a scheduled retry rather than hammer.\n if (Date.now() < this.backoffUntil) {\n await this.store.append({ at: Date.now(), body });\n this.scheduleRetry();\n return;\n }\n await this.send(body, useBeacon);\n }\n\n private async send(body: IngestBatch, useBeacon: boolean): Promise<void> {\n const url = `${this.cfg.ingestHost}/v1/batch`;\n const payload = JSON.stringify(body);\n\n if (useBeacon && typeof navigator !== 'undefined' && navigator.sendBeacon) {\n // Beacon can't set Authorization; the key rides as a query param fallback.\n navigator.sendBeacon(`${url}?k=${encodeURIComponent(this.cfg.projectKey)}`, payload);\n return;\n }\n\n try {\n const res = await fetch(url, {\n method: 'POST',\n keepalive: true,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `${INGEST_AUTH_SCHEME} ${this.cfg.projectKey}`,\n },\n body: payload,\n });\n if (res.status === 429) {\n const retry = Number(res.headers.get('retry-after') ?? '0');\n this.failures++;\n this.backoffUntil = Date.now() + (retry > 0 ? retry * 1000 : this.backoffMs());\n await this.store.append({ at: Date.now(), body });\n this.scheduleRetry();\n } else if (res.status >= 500) {\n // Server-side failure: back off (exp + jitter) and retry the batch later.\n this.failures++;\n this.backoffUntil = Date.now() + this.backoffMs();\n await this.store.append({ at: Date.now(), body });\n this.scheduleRetry();\n } else {\n // 2xx (and non-retryable 4xx) — the batch is done; clear the failure streak.\n this.failures = 0;\n }\n } catch {\n // Offline / network error → persist for the next online drain + retry.\n this.failures++;\n this.backoffUntil = Date.now() + this.backoffMs();\n await this.store.append({ at: Date.now(), body });\n this.scheduleRetry();\n }\n }\n\n /** Exponential backoff with full jitter, capped. */\n private backoffMs(): number {\n const exp = Math.min(BACKOFF_CAP_MS, BACKOFF_BASE_MS * 2 ** Math.min(this.failures, 12));\n return Math.floor(Math.random() * exp);\n }\n\n private scheduleRetry(): void {\n if (this.retryTimer) return;\n const delay = Math.max(0, this.backoffUntil - Date.now()) + 250;\n this.retryTimer = setTimeout(() => {\n this.retryTimer = null;\n void this.drainOffline();\n }, delay);\n }\n\n // --- durable offline queue (masked data only; TTL'd; size-capped) ----------\n\n async drainOffline(): Promise<void> {\n if (Date.now() < this.backoffUntil) {\n this.scheduleRetry();\n return;\n }\n const q = await this.store.drain();\n for (const item of q) {\n if (Date.now() < this.backoffUntil) {\n // Backoff re-armed mid-drain: re-persist the remainder and reschedule.\n await this.store.append(item);\n this.scheduleRetry();\n return;\n }\n await this.send(item.body, false);\n }\n }\n\n /** optOut/reset clears any queued (but already-masked) payloads. */\n clearOffline(): void {\n void this.store.clear();\n }\n\n /** Drop the in-memory buffer so no buffered PII survives optOut()/reset(). */\n clearBuffer(): void {\n this.buffer = [];\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n }\n}\n\nexport type { QueuedBatch };\n","import { type FlagDefinition, type ScalarValue, type Value, evaluateFlag, prefixedId, randomToken } from '@glassanalytics/core';\nimport { ReplayRecorder } from './replay.js';\nimport { Transport } from './transport.js';\nimport type { FlagOptions, FlagValue, GlassConfig, GlassEvent, ResolvedConfig } from './types.js';\n\nexport type { GlassConfig, GlassEvent, FlagValue, FlagOptions } from './types.js';\n\nconst SESSION_IDLE_MS = 30 * 60_000;\nconst DEVICE_KEY = 'glass_device_id';\nconst SESSION_KEY = 'glass_session';\n\nfunction ls(): Storage | null {\n try {\n return typeof localStorage !== 'undefined' ? localStorage : null;\n } catch {\n return null;\n }\n}\n\n/**\n * The Glass browser client (`SDK.md` §3). One small object: identity, events,\n * errors, replay and flags. Non-blocking by construction; nothing here should\n * ever be on the app's critical path.\n */\nexport class Glass {\n private cfg!: ResolvedConfig;\n private transport!: Transport;\n private replay!: ReplayRecorder;\n private deviceId = '';\n private sessionId = '';\n private userId: string | null = null;\n private traits: Record<string, Value> = {};\n private groupCtx: { type: string; key: string } | null = null;\n private superProps: Record<string, Value> = {};\n private seq = 0;\n private lastActivity = 0;\n private flags: Record<string, FlagValue> = {};\n private flagsLoaded = false;\n private flagListeners: Array<(flags: Record<string, FlagValue>) => void> = [];\n private optedOut = false;\n private started = false;\n /** Calls made before init() are queued and replayed once started (`SDK.md` §2). */\n private preInitQueue: Array<() => void> = [];\n /** Removers for every listener/patch we install, so shutdown() leaves no trace. */\n private teardowns: Array<() => void> = [];\n\n init(config: GlassConfig): void {\n if (this.started) return;\n this.cfg = {\n projectKey: config.projectKey,\n ingestHost: config.ingestHost ?? 'https://in.glass.dev',\n apiHost: config.apiHost ?? 'https://api.glass.dev',\n replay: config.replay ?? true,\n autocapture: config.autocapture ?? true,\n errors: config.errors ?? true,\n captureConsole: config.captureConsole ?? false,\n sampleRate: config.sampleRate ?? 1,\n consent: config.consent ?? 'implied',\n maskAllInputs: config.maskAllInputs ?? true,\n maskTextSelector: config.maskTextSelector,\n blockSelector: config.blockSelector,\n respectDoNotTrack: config.respectDoNotTrack ?? true,\n flushIntervalMs: config.flushIntervalMs ?? 5000,\n flushAt: config.flushAt ?? 25,\n beforeSend: config.beforeSend ?? ((e) => e),\n bootstrapFlags: config.bootstrapFlags ?? {},\n flagDefinitions: config.flagDefinitions ?? [],\n };\n this.flags = { ...this.cfg.bootstrapFlags };\n\n if (this.cfg.respectDoNotTrack && typeof navigator !== 'undefined' && navigator.doNotTrack === '1') {\n this.optedOut = true;\n }\n\n this.deviceId = this.loadDeviceId();\n this.sessionId = this.loadSession();\n this.transport = new Transport(this.cfg, () => ({\n device_id: this.deviceId,\n session_id: this.sessionId,\n ...(this.userId ? { user_id: this.userId } : {}),\n traits: this.traits,\n ...(this.groupCtx ? { group: this.groupCtx } : {}),\n }));\n this.replay = new ReplayRecorder(this.cfg, () => this.sessionId);\n this.started = true;\n\n if (this.optedOut || (this.cfg.consent === 'opt-in')) {\n // No collection until optIn() is called.\n } else {\n this.afterConsent();\n }\n void this.reloadFeatureFlags();\n\n // Replay any calls made before init() resolved, in order.\n const queued = this.preInitQueue.splice(0, this.preInitQueue.length);\n for (const fn of queued) fn();\n }\n\n private afterConsent(): void {\n if (this.cfg.errors) this.installErrorHandlers();\n if (this.cfg.autocapture) this.installAutocapture();\n if (this.cfg.captureConsole) this.installConsoleCapture();\n this.installVisibilityFlush();\n if (this.cfg.replay && Math.random() < this.cfg.sampleRate) void this.replay.start();\n void this.transport.drainOffline();\n this.track('$pageview', this.pageProps());\n // Deliver the first pageview immediately (batched with anything queued during\n // init) so a fast bounce — open then close within the flush window — still\n // records the view, instead of relying only on the lossy pagehide beacon.\n this.flushSoon();\n }\n\n /**\n * Flush once on the next microtask. Runs after init()'s synchronous work\n * (pre-init queue drain + any `track()` right after `init()`), so the initial\n * pageview and those events go out in ONE batch, within a tick of load.\n */\n private initialFlushScheduled = false;\n private flushSoon(): void {\n if (this.initialFlushScheduled) return;\n this.initialFlushScheduled = true;\n const run = () => {\n this.initialFlushScheduled = false;\n void this.transport.flush();\n };\n if (typeof queueMicrotask === 'function') queueMicrotask(run);\n else void Promise.resolve().then(run);\n }\n\n /** Register a DOM listener and remember how to remove it on shutdown(). */\n private addListener(\n target: EventTarget,\n type: string,\n handler: EventListenerOrEventListenerObject,\n opts?: AddEventListenerOptions | boolean,\n ): void {\n target.addEventListener(type, handler, opts);\n this.teardowns.push(() => target.removeEventListener(type, handler, opts));\n }\n\n /**\n * Flush on tab hide (`SDK.md` §10). `visibilitychange`→hidden is the most\n * reliable \"user is leaving\" signal on mobile (where `pagehide`/`unload` are\n * unreliable), so we drain the buffer with a beacon while we still can.\n */\n private installVisibilityFlush(): void {\n if (typeof document === 'undefined') return;\n this.addListener(document, 'visibilitychange', () => {\n if (document.visibilityState === 'hidden') void this.transport.flush(true);\n });\n }\n\n // --- identity --------------------------------------------------------------\n\n private loadDeviceId(): string {\n const store = ls();\n let id = store?.getItem(DEVICE_KEY) ?? null;\n if (!id) {\n id = `dev_${randomToken(16)}`;\n store?.setItem(DEVICE_KEY, id);\n }\n return id;\n }\n\n private loadSession(): string {\n const store = ls();\n try {\n const raw = store?.getItem(SESSION_KEY);\n if (raw) {\n const parsed = JSON.parse(raw) as { id: string; last: number };\n if (Date.now() - parsed.last < SESSION_IDLE_MS) {\n this.lastActivity = parsed.last;\n return parsed.id;\n }\n }\n } catch {\n /* ignore */\n }\n const id = prefixedId('sess');\n this.persistSession(id);\n return id;\n }\n\n private persistSession(id: string): void {\n this.lastActivity = Date.now();\n ls()?.setItem(SESSION_KEY, JSON.stringify({ id, last: this.lastActivity }));\n }\n\n private touchSession(): void {\n if (Date.now() - this.lastActivity > SESSION_IDLE_MS) {\n this.sessionId = prefixedId('sess');\n this.seq = 0;\n }\n this.persistSession(this.sessionId);\n }\n\n /** Queue a call made before init() so nothing is lost; returns true if deferred. */\n private deferred(fn: () => void): boolean {\n if (this.started) return false;\n this.preInitQueue.push(fn);\n return true;\n }\n\n identify(userId: string, traits: Record<string, Value> = {}): void {\n if (this.deferred(() => this.identify(userId, traits))) return;\n this.userId = userId;\n this.traits = { ...this.traits, ...traits };\n this.emit('identify', undefined, traits);\n void this.reloadFeatureFlags();\n }\n\n reset(): void {\n // Flush what we have under the OLD identity, then drop everything so no\n // buffered/queued data leaks across the user-switch boundary.\n void this.transport.flush();\n this.transport.clearBuffer();\n this.transport.clearOffline();\n this.exposedKeys.clear();\n this.flags = { ...this.cfg.bootstrapFlags };\n this.userId = null;\n this.traits = {};\n this.groupCtx = null;\n this.superProps = {};\n const store = ls();\n store?.removeItem(SESSION_KEY);\n this.deviceId = `dev_${randomToken(16)}`;\n store?.setItem(DEVICE_KEY, this.deviceId);\n this.sessionId = prefixedId('sess');\n this.seq = 0;\n }\n\n getDeviceId(): string {\n return this.deviceId;\n }\n getSessionId(): string {\n return this.sessionId;\n }\n getSessionReplayUrl(): string {\n return `${this.cfg.apiHost}/replays/${this.sessionId}`;\n }\n\n groupIdentify(type: string, key: string, traits: Record<string, Value> = {}): void {\n if (this.deferred(() => this.groupIdentify(type, key, traits))) return;\n this.groupCtx = { type, key };\n this.emit('group', undefined, { group_type: type, group_key: key, ...traits });\n }\n\n /** Alias for `groupIdentify` (`SDK.md` API parity). */\n group(type: string, key: string, traits: Record<string, Value> = {}): void {\n this.groupIdentify(type, key, traits);\n }\n\n // --- events ----------------------------------------------------------------\n\n register(props: Record<string, Value>): void {\n if (this.deferred(() => this.register(props))) return;\n this.superProps = { ...this.superProps, ...props };\n }\n unregister(key: string): void {\n if (this.deferred(() => this.unregister(key))) return;\n delete this.superProps[key];\n }\n\n track(event: string, props: Record<string, Value> = {}): void {\n if (this.deferred(() => this.track(event, props))) return;\n this.emit('track', event, props);\n }\n\n private emit(type: GlassEvent['type'], event: string | undefined, props: Record<string, Value>): void {\n if (this.optedOut || !this.started) return;\n this.touchSession();\n this.transport.enqueue({\n type,\n ...(event ? { event } : {}),\n seq: this.seq++,\n t_client: new Date().toISOString(),\n props: { ...this.contextProps(), ...this.superProps, ...props },\n });\n // Mirror the event onto the replay timeline as a lightweight marker (errors\n // flagged so the player's \"jump to error\" works). No-op unless recording.\n if (this.cfg.replay) {\n const name = event ?? type;\n this.replay.addEvent(name, { event: name, ...(type === 'error' ? { level: 'error' } : {}) });\n }\n }\n\n /** Device/screen context attached to EVERY event (`SDK.md` §4). */\n private contextProps(): Record<string, Value> {\n const ctx: Record<string, Value> = {};\n if (typeof screen !== 'undefined') {\n ctx.$screen_width = screen.width;\n ctx.$screen_height = screen.height;\n }\n if (typeof window !== 'undefined') {\n ctx.$viewport_width = window.innerWidth;\n ctx.$viewport_height = window.innerHeight;\n }\n if (typeof navigator !== 'undefined') {\n ctx.$locale = navigator.language ?? null;\n }\n return ctx;\n }\n\n private pageProps(): Record<string, Value> {\n if (typeof document === 'undefined' || typeof location === 'undefined') return {};\n return { url: location.href, $pathname: location.pathname, referrer: document.referrer };\n }\n\n // --- errors ----------------------------------------------------------------\n\n captureException(error: unknown, context: Record<string, Value> = {}): void {\n if (this.deferred(() => this.captureException(error, context))) return;\n const err = error instanceof Error ? error : new Error(String(error));\n this.emit('error', err.name, {\n message: err.message,\n stack: err.stack ?? '',\n ...context,\n });\n }\n\n /** Breadcrumb with optional category (`SDK.md` API parity). */\n addBreadcrumb(\n arg: string | { category?: string; message: string; data?: Record<string, Value> },\n data: Record<string, Value> = {},\n ): void {\n if (this.deferred(() => this.addBreadcrumb(arg, data))) return;\n if (typeof arg === 'string') {\n this.emit('track', '$breadcrumb', { message: arg, ...data });\n } else {\n this.emit('track', '$breadcrumb', {\n message: arg.message,\n ...(arg.category ? { category: arg.category } : {}),\n ...(arg.data ?? {}),\n });\n }\n }\n\n private installErrorHandlers(): void {\n if (typeof window === 'undefined') return;\n this.addListener(window, 'error', (e) =>\n this.captureException((e as ErrorEvent).error ?? (e as ErrorEvent).message),\n );\n this.addListener(window, 'unhandledrejection', (e) =>\n this.captureException((e as PromiseRejectionEvent).reason),\n );\n }\n\n /**\n * Opt-in console capture (`SDK.md` §5): mirror `console.error`/`console.warn`\n * into Glass (errors as exceptions, warnings as breadcrumbs) while ALWAYS\n * calling through to the original console, so we never swallow the developer's\n * own logs. Restored verbatim on shutdown().\n */\n private installConsoleCapture(): void {\n if (typeof console === 'undefined') return;\n const wrap = (level: 'error' | 'warn') => {\n const original = console[level];\n if (typeof original !== 'function') return;\n console[level] = (...args: unknown[]) => {\n try {\n const first = args[0];\n const message = args\n .map((a) => (typeof a === 'string' ? a : a instanceof Error ? a.message : safeString(a)))\n .join(' ')\n .slice(0, 500);\n if (level === 'error') {\n this.captureException(first instanceof Error ? first : new Error(message), { $console: true });\n } else {\n this.addBreadcrumb({ category: 'console.warn', message });\n }\n } catch {\n /* never let capture break the app's logging */\n }\n return (original as (...a: unknown[]) => void).apply(console, args);\n };\n this.teardowns.push(() => {\n console[level] = original;\n });\n };\n wrap('error');\n wrap('warn');\n }\n\n private rageWindow: number[] = [];\n\n private installAutocapture(): void {\n if (typeof document === 'undefined') return;\n\n this.addListener(\n document,\n 'click',\n (e) => {\n const target = (e as MouseEvent).target as HTMLElement | null;\n if (!target) return;\n this.detectRageClick();\n const el = target.closest('a,button,input[type=submit],[role=button],[data-glass]') as HTMLElement | null;\n if (!el) return;\n this.track('$click', this.elementProps(el));\n },\n { capture: true },\n );\n\n this.addListener(\n document,\n 'submit',\n (e) => {\n const form = (e as SubmitEvent).target as HTMLFormElement | null;\n if (!form || form.tagName !== 'FORM') return;\n // Never capture field VALUES — only structural metadata.\n this.track('$form_submit', {\n form_id: form.id || null,\n form_name: form.getAttribute('name'),\n action: form.getAttribute('action'),\n field_count: form.elements.length,\n });\n },\n { capture: true },\n );\n\n this.installSpaPageviews();\n }\n\n /** Stable, value-free descriptor of a clicked element. */\n private elementProps(el: HTMLElement): Record<string, Value> {\n return {\n tag: el.tagName.toLowerCase(),\n text: (el.textContent ?? '').trim().slice(0, 80),\n href: el instanceof HTMLAnchorElement ? el.href : null,\n el_id: el.id || null,\n el_class: el.getAttribute('class'),\n data_glass: el.getAttribute('data-glass'),\n };\n }\n\n /** Three+ clicks within 1s at roughly one spot = a rage click (frustration signal). */\n private detectRageClick(): void {\n const now = Date.now();\n this.rageWindow = this.rageWindow.filter((t) => now - t < 1000);\n this.rageWindow.push(now);\n if (this.rageWindow.length >= 3) {\n this.rageWindow = [];\n this.track('$rageclick', { url: typeof location !== 'undefined' ? location.href : null });\n }\n }\n\n /** SPA route changes: patch History + listen to popstate, de-duping same-URL. */\n private lastPath = '';\n private installSpaPageviews(): void {\n if (typeof history === 'undefined' || typeof location === 'undefined') return;\n this.lastPath = location.href;\n const fire = () => {\n if (location.href === this.lastPath) return;\n this.lastPath = location.href;\n this.track('$pageview', this.pageProps());\n };\n const wrap = (key: 'pushState' | 'replaceState') => {\n const orig = history[key];\n history[key] = function patched(this: History, ...args: Parameters<History['pushState']>) {\n const ret = orig.apply(this, args);\n // Defer so location has updated before we read it.\n setTimeout(fire, 0);\n return ret;\n } as History[typeof key];\n // Restore the native method on shutdown() so we don't leak a patch.\n this.teardowns.push(() => {\n history[key] = orig;\n });\n };\n wrap('pushState');\n wrap('replaceState');\n this.addListener(window, 'popstate', fire);\n }\n\n // --- session replay control ------------------------------------------------\n\n startSessionRecording(): void {\n void this.replay.start();\n }\n stopSessionRecording(): void {\n void this.replay.stopRecording();\n }\n\n // --- feature flags (deterministic, edge-evaluated) -------------------------\n\n async reloadFeatureFlags(): Promise<void> {\n try {\n const unit = this.userId ?? this.deviceId;\n const res = await fetch(`${this.cfg.apiHost}/v1/sdk/flags?user_id=${encodeURIComponent(unit)}`, {\n headers: { Authorization: `Glass-Key ${this.cfg.projectKey}` },\n });\n if (res.ok) {\n const json = (await res.json()) as { flags?: Record<string, FlagValue> };\n this.flags = { ...this.flags, ...(json.flags ?? {}) };\n }\n } catch {\n /* keep bootstrap/cached flags */\n } finally {\n this.flagsLoaded = true;\n for (const fn of this.flagListeners) fn(this.flags);\n }\n }\n\n onFlagsLoaded(fn: (flags: Record<string, FlagValue>) => void): void {\n this.flagListeners.push(fn);\n if (this.flagsLoaded) fn(this.flags);\n }\n\n /**\n * Resolve a flag value with precedence: locally-evaluated definition (if the\n * app shipped one, so targeting reflects CURRENT properties) → server/bootstrap\n * resolved value → fallback.\n */\n private resolve(key: string, opts?: FlagOptions): FlagValue {\n const local = this.evaluateLocal(key);\n const v = local !== undefined ? local : this.flags[key];\n const value = v !== undefined ? v : opts?.fallback;\n if (value !== undefined && opts?.trackExposure !== false) this.exposure(key, value);\n return value;\n }\n\n /** Local bucketing via @glassanalytics/core when definitions were provided to init(). */\n private evaluateLocal(key: string): FlagValue {\n const def = this.cfg.flagDefinitions.find((d: FlagDefinition) => d.key === key);\n if (!def) return undefined;\n const properties: Record<string, ScalarValue> = {};\n for (const [k, val] of Object.entries(this.traits)) {\n if (val === null || typeof val === 'string' || typeof val === 'number' || typeof val === 'boolean') {\n properties[k] = val as ScalarValue;\n }\n }\n return evaluateFlag(def, { unitId: this.userId ?? this.deviceId, properties });\n }\n\n isFeatureEnabledSync(key: string, opts?: FlagOptions): boolean {\n const v = this.resolve(key, opts);\n return v === true || (typeof v === 'string' && v !== '');\n }\n async isFeatureEnabled(key: string, opts?: FlagOptions): Promise<boolean> {\n if (!this.flagsLoaded) await this.reloadFeatureFlags();\n return this.isFeatureEnabledSync(key, opts);\n }\n getFeatureFlagSync(key: string, opts?: FlagOptions): FlagValue {\n return this.resolve(key, opts);\n }\n async getFeatureFlag(key: string, opts?: FlagOptions): Promise<FlagValue> {\n if (!this.flagsLoaded) await this.reloadFeatureFlags();\n return this.getFeatureFlagSync(key, opts);\n }\n getVariantSync(key: string, opts?: FlagOptions): FlagValue {\n return this.resolve(key, opts);\n }\n async getVariant(key: string, opts?: FlagOptions): Promise<FlagValue> {\n if (!this.flagsLoaded) await this.reloadFeatureFlags();\n return this.getVariantSync(key, opts);\n }\n\n /** Fire a `$exposure` once per (flag, value) so experiment analysis is honest (§8). */\n private exposedKeys = new Set<string>();\n private exposure(key: string, value: FlagValue): void {\n const k = `${key}=${String(value)}`;\n if (this.exposedKeys.has(k)) return;\n this.exposedKeys.add(k);\n this.emit('exposure', key, { $feature_flag: key, $feature_flag_value: String(value) });\n }\n\n // --- consent ---------------------------------------------------------------\n\n optIn(): void {\n this.optedOut = false;\n this.afterConsent();\n }\n optOut(): void {\n this.optedOut = true;\n // Discard anything buffered/queued the moment consent is withdrawn.\n this.transport.clearBuffer();\n this.transport.clearOffline();\n void this.replay.stopRecording();\n }\n hasConsent(): boolean {\n return !this.optedOut;\n }\n\n // --- lifecycle -------------------------------------------------------------\n\n flush(): Promise<void> {\n return this.transport.flush();\n }\n shutdown(): void {\n void this.transport.flush(true);\n void this.replay.stopRecording();\n // Remove every listener/patch we installed (in reverse) so re-init or a SPA\n // teardown leaves the page exactly as we found it.\n for (const off of this.teardowns.splice(0, this.teardowns.length).reverse()) {\n try {\n off();\n } catch {\n /* best-effort cleanup */\n }\n }\n this.transport.destroy();\n this.started = false;\n }\n}\n\n/** JSON-stringify that never throws (cyclic refs, BigInt, etc.) for console capture. */\nfunction safeString(value: unknown): string {\n try {\n return JSON.stringify(value) ?? String(value);\n } catch {\n return String(value);\n }\n}\n\n/** Default singleton, mirroring the ergonomic `glass.init(...)` usage in `SDK.md`. */\nexport const glass = new Glass();\nexport default glass;\n"]}
1
+ {"version":3,"sources":["../src/replay-encoder.ts","../src/network-plugin.ts","../src/replay.ts","../src/offline-store.ts","../src/transport.ts","../src/index.ts"],"names":["ls"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Off-main-thread replay-segment encoder (`SDK.md` §6). rrweb segments are large\n * and highly repetitive, so we (a) JSON-serialize and (b) gzip them in a Web\n * Worker — keeping both the (potentially multi-MB) stringify and the compression\n * off the page's main thread. Everything degrades gracefully: no Worker → encode\n * on the main thread; no `CompressionStream` → send uncompressed JSON. The result\n * is the same bytes the ingest endpoint already accepts, just optionally gzipped\n * (signalled to callers via `gzip`, which they translate to `Content-Encoding`).\n */\n\nexport interface EncodedSegment {\n body: Uint8Array | string;\n gzip: boolean;\n}\n\n/**\n * Worker body, kept dependency-free so it can be inlined via a Blob URL (no\n * separate build step / bundler entry). It receives `{ id, json }`, gzips when\n * possible, and posts back `{ id, buf, gzip }` transferring the buffer.\n */\nconst WORKER_SRC = `\nself.onmessage = async function (e) {\n var id = e.data.id, json = e.data.json;\n try {\n var bytes = new TextEncoder().encode(json);\n if (typeof CompressionStream !== 'undefined') {\n var cs = new CompressionStream('gzip');\n var w = cs.writable.getWriter();\n w.write(bytes); w.close();\n var buf = await new Response(cs.readable).arrayBuffer();\n self.postMessage({ id: id, buf: buf, gzip: true }, [buf]);\n } else {\n self.postMessage({ id: id, buf: bytes.buffer, gzip: false }, [bytes.buffer]);\n }\n } catch (err) {\n self.postMessage({ id: id, error: String(err) });\n }\n};\n`;\n\ninterface WorkerReply {\n id: number;\n buf?: ArrayBuffer;\n gzip?: boolean;\n error?: string;\n}\n\nexport class ReplayEncoder {\n private worker: Worker | null = null;\n private workerUrl: string | null = null;\n private workerBroken = false;\n private nextId = 1;\n private pending = new Map<number, (r: WorkerReply) => void>();\n\n /** Lazily spin up the encode worker; null if Workers/Blob URLs aren't available. */\n private ensureWorker(): Worker | null {\n if (this.worker || this.workerBroken) return this.worker;\n try {\n if (typeof Worker === 'undefined' || typeof Blob === 'undefined' || typeof URL === 'undefined') {\n this.workerBroken = true;\n return null;\n }\n this.workerUrl = URL.createObjectURL(new Blob([WORKER_SRC], { type: 'text/javascript' }));\n this.worker = new Worker(this.workerUrl);\n this.worker.onmessage = (ev: MessageEvent<WorkerReply>) => {\n const resolve = this.pending.get(ev.data.id);\n if (resolve) {\n this.pending.delete(ev.data.id);\n resolve(ev.data);\n }\n };\n this.worker.onerror = () => {\n // A broken worker disables itself; future encodes run on the main thread.\n this.workerBroken = true;\n for (const [, resolve] of this.pending) resolve({ id: -1, error: 'worker_error' });\n this.pending.clear();\n };\n return this.worker;\n } catch {\n this.workerBroken = true;\n return null;\n }\n }\n\n async encode(segment: unknown): Promise<EncodedSegment> {\n let json: string;\n try {\n json = JSON.stringify(segment);\n } catch {\n json = '[]';\n }\n\n const worker = this.ensureWorker();\n if (worker) {\n try {\n const reply = await this.postToWorker(worker, json);\n if (!reply.error && reply.buf) {\n return { body: new Uint8Array(reply.buf), gzip: reply.gzip === true };\n }\n } catch {\n /* fall through to main-thread encoding */\n }\n }\n return this.encodeMainThread(json);\n }\n\n private postToWorker(worker: Worker, json: string): Promise<WorkerReply> {\n const id = this.nextId++;\n return new Promise<WorkerReply>((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.pending.delete(id);\n reject(new Error('encode_timeout'));\n }, 2000);\n this.pending.set(id, (r) => {\n clearTimeout(timeout);\n resolve(r);\n });\n worker.postMessage({ id, json });\n });\n }\n\n /** Main-thread fallback: gzip via CompressionStream when present, else raw JSON. */\n private async encodeMainThread(json: string): Promise<EncodedSegment> {\n const CS = (globalThis as { CompressionStream?: typeof CompressionStream }).CompressionStream;\n if (typeof CS !== 'undefined') {\n try {\n const cs = new CS('gzip');\n const writer = cs.writable.getWriter();\n void writer.write(new TextEncoder().encode(json));\n void writer.close();\n const buf = await new Response(cs.readable).arrayBuffer();\n return { body: new Uint8Array(buf), gzip: true };\n } catch {\n /* fall through to uncompressed */\n }\n }\n return { body: json, gzip: false };\n }\n\n dispose(): void {\n this.worker?.terminate();\n this.worker = null;\n if (this.workerUrl) {\n try {\n URL.revokeObjectURL(this.workerUrl);\n } catch {\n /* ignore */\n }\n this.workerUrl = null;\n }\n this.pending.clear();\n }\n}\n","/**\n * Minimal, privacy-safe network recorder for session replay.\n *\n * The official rrweb network plugin (`@rrweb/rrweb-plugin-network-record`) is\n * documented but NOT published to npm, so we vendor a compact equivalent. It\n * returns an rrweb `RecordPlugin`; rrweb calls `observer(cb, win, options)` and\n * wraps each `cb(payload)` into a type-6 Plugin event\n * `{ plugin: 'rrweb/network@1', payload }` — the exact shape the player already\n * parses for its Network inspector.\n *\n * SAFE BY DEFAULT: only method, URL, status and timing are captured — NEVER\n * request/response headers or bodies. Requests to the Glass ingest host are\n * ignored so replay/segment/event uploads never record themselves (feedback\n * loop). The patched `fetch`/`XMLHttpRequest` are restored on teardown.\n */\n\ninterface NetworkRequest {\n type: 'fetch' | 'xhr';\n method: string;\n /** Request URL (the player shows this; kept as `name` to match rrweb's shape). */\n name: string;\n status?: number;\n startTime: number;\n endTime: number;\n}\n\ntype Teardown = () => void;\n\nexport interface GlassNetworkPluginOptions {\n /** Absolute URL prefix (the ingest host) whose requests are never recorded. */\n ignoreUrlPrefix?: string;\n}\n\n/** Structural subset of rrweb's `RecordPlugin` — enough for `record({ plugins })`. */\nexport interface GlassRecordPlugin {\n name: string;\n observer: (\n cb: (payload: { requests: NetworkRequest[] }) => void,\n win: unknown,\n options: GlassNetworkPluginOptions,\n ) => Teardown;\n options: GlassNetworkPluginOptions;\n}\n\nconst NETWORK_PLUGIN_NAME = 'rrweb/network@1';\n\nexport function getGlassNetworkPlugin(\n options: GlassNetworkPluginOptions = {},\n): GlassRecordPlugin {\n return {\n name: NETWORK_PLUGIN_NAME,\n options,\n observer(cb, _win, opts) {\n if (typeof window === 'undefined') return () => {};\n const ignore = opts.ignoreUrlPrefix;\n const teardowns: Teardown[] = [];\n\n const shouldIgnore = (url: string): boolean =>\n !url || (ignore ? url.startsWith(ignore) : false);\n\n const record = (r: NetworkRequest) => {\n try {\n cb({ requests: [r] });\n } catch {\n /* a dropped network entry is non-fatal */\n }\n };\n\n // --- fetch --------------------------------------------------------------\n if (typeof window.fetch === 'function') {\n const orig = window.fetch;\n const patched: typeof fetch = (input, init) => {\n const url =\n typeof input === 'string'\n ? input\n : input instanceof URL\n ? input.href\n : ((input as Request | undefined)?.url ?? '');\n const method = (\n init?.method ??\n (typeof input === 'object' && input && 'method' in input\n ? (input as Request).method\n : 'GET')\n ).toUpperCase();\n const startTime = Date.now();\n const p = orig(input, init);\n if (!shouldIgnore(url)) {\n p.then(\n (res) =>\n record({ type: 'fetch', method, name: url, status: res.status, startTime, endTime: Date.now() }),\n () => record({ type: 'fetch', method, name: url, status: 0, startTime, endTime: Date.now() }),\n );\n }\n return p;\n };\n window.fetch = patched;\n teardowns.push(() => {\n window.fetch = orig;\n });\n }\n\n // --- XMLHttpRequest -----------------------------------------------------\n if (typeof XMLHttpRequest !== 'undefined') {\n const proto = XMLHttpRequest.prototype;\n const origOpen = proto.open;\n const origSend = proto.send;\n const meta = new WeakMap<XMLHttpRequest, { method: string; url: string }>();\n\n proto.open = function open(\n this: XMLHttpRequest,\n method: string,\n url: string | URL,\n ...rest: unknown[]\n ) {\n meta.set(this, {\n method: String(method ?? 'GET').toUpperCase(),\n url: typeof url === 'string' ? url : url.href,\n });\n return (origOpen as unknown as (...a: unknown[]) => void).call(\n this,\n method,\n url,\n ...rest,\n );\n } as typeof proto.open;\n\n proto.send = function send(this: XMLHttpRequest, ...args: unknown[]) {\n const m = meta.get(this);\n if (m && !shouldIgnore(m.url)) {\n const startTime = Date.now();\n this.addEventListener(\n 'loadend',\n () =>\n record({\n type: 'xhr',\n method: m.method,\n name: m.url,\n status: this.status,\n startTime,\n endTime: Date.now(),\n }),\n { once: true },\n );\n }\n return (origSend as unknown as (...a: unknown[]) => void).apply(this, args);\n } as typeof proto.send;\n\n teardowns.push(() => {\n proto.open = origOpen;\n proto.send = origSend;\n });\n }\n\n return () => {\n for (const t of teardowns) {\n try {\n t();\n } catch {\n /* ignore */\n }\n }\n };\n },\n };\n}\n","import { replaySegmentPath } from '@glass/core';\nimport type { ResolvedConfig } from './types.js';\nimport { ReplayEncoder } from './replay-encoder.js';\nimport { getGlassNetworkPlugin } from './network-plugin.js';\n\n/**\n * Session replay (`SDK.md` §6). rrweb is loaded LAZILY (dynamic import) so apps\n * that don't record pay nothing. Recording is MASKED BY DEFAULT — all inputs\n * masked, configurable text/blocked selectors — and segments are streamed to the\n * ingest `/v1/replay/:session/:seq` endpoint, not buffered in memory.\n */\n/** Input types/name patterns ALWAYS masked, even when maskAllInputs is false. */\nconst SENSITIVE_INPUT_TYPES = new Set(['password', 'email', 'tel', 'hidden']);\nconst SENSITIVE_NAME_RE = /pass|secret|token|ssn|card|cvv|cvc|account|email|phone|tax/i;\n\n/**\n * Elements a consumer marks as \"never record\" — rendered as a same-size\n * placeholder in the player. Use this for perpetually-animating / decorative\n * subtrees (marquees, parallax, canvases) that would otherwise flood the replay\n * with per-frame DOM mutations. rrweb's own `rr-block` class also still applies.\n */\nconst GLASS_BLOCK_SELECTOR = '.glass-block,[data-glass-block]';\n\n/**\n * Throttle the high-frequency signals rrweb captures so a busy page doesn't\n * bloat segments (a COGS/bandwidth lever). These cap event RATE, not fidelity of\n * the DOM itself; NOTE they do NOT throttle DOM mutations — a JS animation that\n * mutates the DOM every frame must be excluded via the block convention above.\n */\nconst SAMPLING = {\n mousemove: 50,\n mouseInteraction: true,\n scroll: 150,\n media: 800,\n input: 'last',\n} as const;\n\nexport class ReplayRecorder {\n private stop: (() => void) | null = null;\n private seq = 0;\n private events: unknown[] = [];\n private interval: ReturnType<typeof setInterval> | null = null;\n private boundFinal: (() => void) | null = null;\n private encoder = new ReplayEncoder();\n /** rrweb's addCustomEvent, captured on start — lets us weave Glass events into the stream. */\n private addCustom: ((tag: string, payload: unknown) => void) | null = null;\n private boundVisibility: (() => void) | null = null;\n\n constructor(\n private cfg: ResolvedConfig,\n private getSessionId: () => string,\n ) {}\n\n async start(): Promise<void> {\n if (this.stop) return;\n if (typeof window === 'undefined') return;\n const { record } = await import('rrweb');\n const rec = record as unknown as { addCustomEvent?: (tag: string, payload: unknown) => void };\n this.addCustom = typeof rec.addCustomEvent === 'function' ? rec.addCustomEvent.bind(record) : null;\n\n // Optional record plugins (console + network) so the player's inspector tabs\n // populate. The console plugin is loaded lazily so apps that disable it pay\n // nothing; the network plugin is vendored (see network-plugin.ts) and never\n // records headers/bodies or the Glass ingest host itself.\n const plugins: unknown[] = [];\n if (this.cfg.recordConsole) {\n try {\n const { getRecordConsolePlugin } = await import('@rrweb/rrweb-plugin-console-record');\n plugins.push(getRecordConsolePlugin());\n } catch {\n /* console plugin unavailable — replay still records DOM */\n }\n }\n if (this.cfg.recordNetwork) {\n plugins.push(getGlassNetworkPlugin({ ignoreUrlPrefix: this.cfg.ingestHost }));\n }\n\n this.stop =\n record({\n emit: (event: unknown) => {\n this.events.push(event);\n if (this.events.length >= 50) void this.flushSegment();\n },\n plugins: plugins.length ? (plugins as never) : undefined,\n // Privacy defaults: never leak user input.\n maskAllInputs: this.cfg.maskAllInputs,\n maskTextSelector: this.cfg.maskTextSelector,\n // Merge the caller's blockSelector with Glass's always-on block convention.\n blockSelector: this.cfg.blockSelector\n ? `${this.cfg.blockSelector},${GLASS_BLOCK_SELECTOR}`\n : GLASS_BLOCK_SELECTOR,\n sampling: SAMPLING,\n // ALWAYS mask sensitive fields regardless of maskAllInputs (defense in depth).\n maskInputFn: (text: string, element: HTMLElement) => {\n if (this.cfg.maskAllInputs) return '*'.repeat(text.length);\n const type = (element.getAttribute('type') ?? '').toLowerCase();\n const name = `${element.getAttribute('name') ?? ''} ${element.getAttribute('autocomplete') ?? ''} ${element.id}`;\n if (SENSITIVE_INPUT_TYPES.has(type) || SENSITIVE_NAME_RE.test(name)) return '*'.repeat(text.length);\n return text;\n },\n recordCanvas: false,\n collectFonts: false,\n }) ?? null;\n\n this.interval = setInterval(() => void this.flushSegment(), 5000);\n // Final segment on unload via beacon (fetch is unreliable during teardown).\n this.boundFinal = () => this.flushFinalBeacon();\n window.addEventListener('pagehide', this.boundFinal);\n\n // Weave tab visibility transitions into the stream as markers, so the player\n // shows when the user backgrounded/returned to the tab.\n if (typeof document !== 'undefined') {\n this.boundVisibility = () => {\n const hidden = document.visibilityState === 'hidden';\n this.addEvent(hidden ? '$window_hidden' : '$window_visible', {\n event: hidden ? 'Window became hidden' : 'Window became visible',\n });\n };\n document.addEventListener('visibilitychange', this.boundVisibility);\n }\n }\n\n /**\n * Weave a Glass event into the rrweb stream as a Custom (type 5) event, so the\n * player can render it as a timeline marker (`UI.md` §4.1). No-op unless we're\n * actively recording. Payload is kept tiny (name + optional level) to avoid\n * bloating replay segments.\n */\n addEvent(name: string, payload: { event: string; level?: string; href?: string }): void {\n if (!this.stop || !this.addCustom) return;\n try {\n this.addCustom(name, payload);\n } catch {\n /* a dropped marker is non-fatal */\n }\n }\n\n private async flushSegment(): Promise<void> {\n if (this.events.length === 0) return;\n const segment = this.events.splice(0, this.events.length);\n const seq = this.seq++;\n const url = `${this.cfg.ingestHost}${replaySegmentPath(this.getSessionId(), seq)}`;\n\n // Serialize + gzip OFF the main thread (Web Worker) so a big segment never\n // janks the page; on any failure we fall back to plain JSON. Compression is\n // a large COGS/bandwidth win (rrweb segments are very repetitive).\n const encoded = await this.encoder.encode(segment);\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Glass-Key ${this.cfg.projectKey}`,\n };\n if (encoded.gzip) headers['Content-Encoding'] = 'gzip';\n\n try {\n await fetch(url, {\n method: 'POST',\n keepalive: true,\n headers,\n body: encoded.body as BodyInit,\n });\n } catch {\n // a dropped replay segment is non-fatal; the player tolerates gaps.\n }\n }\n\n /** Flush the trailing segment with sendBeacon so it survives page teardown. */\n private flushFinalBeacon(): void {\n if (this.events.length === 0) return;\n const segment = this.events.splice(0, this.events.length);\n const seq = this.seq++;\n const url = `${this.cfg.ingestHost}${replaySegmentPath(this.getSessionId(), seq)}?k=${encodeURIComponent(this.cfg.projectKey)}`;\n const payload = JSON.stringify(segment);\n if (typeof navigator !== 'undefined' && navigator.sendBeacon) {\n navigator.sendBeacon(url, payload);\n }\n }\n\n async stopRecording(): Promise<void> {\n await this.flushSegment();\n this.stop?.();\n this.stop = null;\n this.addCustom = null;\n if (this.interval) {\n clearInterval(this.interval);\n this.interval = null;\n }\n if (this.boundFinal && typeof window !== 'undefined') {\n window.removeEventListener('pagehide', this.boundFinal);\n this.boundFinal = null;\n }\n if (this.boundVisibility && typeof document !== 'undefined') {\n document.removeEventListener('visibilitychange', this.boundVisibility);\n this.boundVisibility = null;\n }\n this.encoder.dispose();\n }\n\n get recording(): boolean {\n return this.stop !== null;\n }\n}\n","import type { QueuedBatch } from './transport.js';\n\n/**\n * Durable offline queue for event batches (`SDK.md` §10). Prefers IndexedDB\n * (larger quota, survives reloads) and transparently falls back to localStorage\n * when IDB is unavailable (private mode / old browsers) and to an in-memory\n * array when neither is present (SSR/tests). Only already-masked payloads are\n * stored, entries are TTL'd, and the queue is size-capped.\n */\n\nconst DB_NAME = 'glass';\nconst STORE = 'offline_q';\nconst LS_KEY = 'glass_offline_q';\n\nexport class OfflineStore {\n private mem: QueuedBatch[] = [];\n private dbPromise: Promise<IDBDatabase> | null = null;\n\n constructor(\n private max: number,\n private ttlMs: number,\n ) {}\n\n private idb(): Promise<IDBDatabase> | null {\n if (typeof indexedDB === 'undefined') return null;\n if (!this.dbPromise) {\n this.dbPromise = new Promise<IDBDatabase>((resolve, reject) => {\n const req = indexedDB.open(DB_NAME, 1);\n req.onupgradeneeded = () => {\n const db = req.result;\n if (!db.objectStoreNames.contains(STORE)) db.createObjectStore(STORE, { autoIncrement: true });\n };\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => reject(req.error);\n }).catch((err) => {\n // Disable IDB for the rest of the session on failure.\n this.dbPromise = null;\n throw err;\n });\n }\n return this.dbPromise;\n }\n\n private fresh(items: QueuedBatch[]): QueuedBatch[] {\n const cutoff = Date.now() - this.ttlMs;\n const kept = items.filter((b) => b.at >= cutoff);\n return kept.length > this.max ? kept.slice(kept.length - this.max) : kept;\n }\n\n async append(batch: QueuedBatch): Promise<void> {\n try {\n const db = await this.idb();\n if (db) {\n await this.idbWrite(db, batch);\n return;\n }\n } catch {\n /* fall through to localStorage */\n }\n if (this.tryLS((q) => this.fresh([...q, batch]))) return;\n this.mem = this.fresh([...this.mem, batch]);\n }\n\n async drain(): Promise<QueuedBatch[]> {\n try {\n const db = await this.idb();\n if (db) return this.fresh(await this.idbDrain(db));\n } catch {\n /* fall through */\n }\n const ls = this.readLS();\n if (ls !== null) {\n this.writeLS([]);\n return this.fresh(ls);\n }\n const m = this.mem;\n this.mem = [];\n return this.fresh(m);\n }\n\n async clear(): Promise<void> {\n this.mem = [];\n try {\n const db = await this.idb();\n if (db) {\n await new Promise<void>((resolve) => {\n const tx = db.transaction(STORE, 'readwrite');\n tx.objectStore(STORE).clear();\n tx.oncomplete = () => resolve();\n tx.onerror = () => resolve();\n });\n }\n } catch {\n /* ignore */\n }\n this.writeLS([]);\n }\n\n // --- IndexedDB helpers ------------------------------------------------------\n\n private idbWrite(db: IDBDatabase, batch: QueuedBatch): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE, 'readwrite');\n tx.objectStore(STORE).add(batch);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n private idbDrain(db: IDBDatabase): Promise<QueuedBatch[]> {\n return new Promise<QueuedBatch[]>((resolve, reject) => {\n const tx = db.transaction(STORE, 'readwrite');\n const store = tx.objectStore(STORE);\n const getAll = store.getAll();\n getAll.onsuccess = () => {\n store.clear();\n resolve((getAll.result as QueuedBatch[]) ?? []);\n };\n getAll.onerror = () => reject(getAll.error);\n });\n }\n\n // --- localStorage fallback --------------------------------------------------\n\n private readLS(): QueuedBatch[] | null {\n if (typeof localStorage === 'undefined') return null;\n try {\n const raw = localStorage.getItem(LS_KEY);\n return raw ? (JSON.parse(raw) as QueuedBatch[]) : [];\n } catch {\n return null;\n }\n }\n\n private writeLS(q: QueuedBatch[]): void {\n if (typeof localStorage === 'undefined') return;\n try {\n localStorage.setItem(LS_KEY, JSON.stringify(q));\n } catch {\n /* storage full/disabled — drop silently */\n }\n }\n\n private tryLS(update: (q: QueuedBatch[]) => QueuedBatch[]): boolean {\n const cur = this.readLS();\n if (cur === null) return false;\n this.writeLS(update(cur));\n return true;\n }\n}\n","import { INGEST_AUTH_SCHEME, type IngestBatch } from '@glass/core';\nimport { OfflineStore } from './offline-store.js';\nimport type { GlassEvent, ResolvedConfig } from './types.js';\n\n/**\n * Reliable, cheap transport (`SDK.md` §10): batch on a timer/size, use\n * `sendBeacon` on unload, queue offline, and BACK OFF (exponential + jitter) on\n * failures. Under memory pressure we drop the LOWEST-value events first so\n * high-signal events (errors, identify, exposure) survive. The goal is to never\n * block the app's main work and never lose more than the lowest-value tail.\n */\n\nconst QUEUE_TTL_MS = 24 * 3_600_000;\nconst QUEUE_MAX = 500;\n/** In-memory ceiling before value-based shedding kicks in. */\nconst BUFFER_MAX = 1000;\nconst BACKOFF_BASE_MS = 1000;\nconst BACKOFF_CAP_MS = 5 * 60_000;\n\ninterface QueuedBatch {\n at: number;\n body: IngestBatch;\n}\n\n/** Priority for value-based backpressure — higher survives shedding. */\nfunction eventValue(e: GlassEvent): number {\n switch (e.type) {\n case 'error':\n return 100;\n case 'identify':\n case 'group':\n return 90;\n case 'exposure':\n return 80;\n case 'track':\n // Autocapture / passive pageviews are the most sheddable.\n return e.event === '$autocapture' || e.event === '$pageview' ? 10 : 50;\n default:\n return 40;\n }\n}\n\nexport class Transport {\n private buffer: GlassEvent[] = [];\n private timer: ReturnType<typeof setTimeout> | null = null;\n private retryTimer: ReturnType<typeof setTimeout> | null = null;\n private backoffUntil = 0;\n private failures = 0;\n private store = new OfflineStore(QUEUE_MAX, QUEUE_TTL_MS);\n\n private onPageHide = () => void this.flush(true);\n private onOnline = () => void this.drainOffline();\n\n constructor(\n private cfg: ResolvedConfig,\n private getIdentity: () => Pick<IngestBatch, 'device_id' | 'session_id' | 'user_id' | 'traits' | 'group'>,\n ) {\n if (typeof window !== 'undefined') {\n window.addEventListener('pagehide', this.onPageHide);\n window.addEventListener('online', this.onOnline);\n }\n }\n\n /** Remove window listeners and pending timers (called from Glass.shutdown()). */\n destroy(): void {\n if (typeof window !== 'undefined') {\n window.removeEventListener('pagehide', this.onPageHide);\n window.removeEventListener('online', this.onOnline);\n }\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n if (this.retryTimer) {\n clearTimeout(this.retryTimer);\n this.retryTimer = null;\n }\n }\n\n enqueue(event: GlassEvent): void {\n const finalEvent = this.cfg.beforeSend(event);\n if (!finalEvent) return; // dropped by beforeSend\n this.buffer.push(finalEvent);\n this.applyBackpressure();\n if (this.buffer.length >= this.cfg.flushAt) {\n void this.flush();\n } else if (!this.timer) {\n this.timer = setTimeout(() => void this.flush(), this.cfg.flushIntervalMs);\n }\n }\n\n /**\n * Cap the in-memory buffer by shedding the lowest-value events when it grows\n * past BUFFER_MAX (e.g. a long offline burst of autocapture). Errors and\n * identity events are kept preferentially.\n */\n private applyBackpressure(): void {\n if (this.buffer.length <= BUFFER_MAX) return;\n // Stable sort by value descending, keep the top BUFFER_MAX, preserve order.\n const indexed = this.buffer.map((e, i) => ({ e, i }));\n indexed.sort((a, b) => eventValue(b.e) - eventValue(a.e) || a.i - b.i);\n const kept = indexed.slice(0, BUFFER_MAX).sort((a, b) => a.i - b.i);\n this.buffer = kept.map((x) => x.e);\n }\n\n async flush(useBeacon = false): Promise<void> {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n if (this.buffer.length === 0) return;\n const events = this.buffer.splice(0, this.buffer.length);\n const body: IngestBatch = {\n sent_at: new Date().toISOString(),\n ...this.getIdentity(),\n events,\n };\n\n // Respect server backpressure: persist for a scheduled retry rather than hammer.\n if (Date.now() < this.backoffUntil) {\n await this.store.append({ at: Date.now(), body });\n this.scheduleRetry();\n return;\n }\n await this.send(body, useBeacon);\n }\n\n private async send(body: IngestBatch, useBeacon: boolean): Promise<void> {\n const url = `${this.cfg.ingestHost}/v1/batch`;\n const payload = JSON.stringify(body);\n\n if (useBeacon && typeof navigator !== 'undefined' && navigator.sendBeacon) {\n // Beacon can't set Authorization; the key rides as a query param fallback.\n navigator.sendBeacon(`${url}?k=${encodeURIComponent(this.cfg.projectKey)}`, payload);\n return;\n }\n\n try {\n const res = await fetch(url, {\n method: 'POST',\n keepalive: true,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `${INGEST_AUTH_SCHEME} ${this.cfg.projectKey}`,\n },\n body: payload,\n });\n if (res.status === 429) {\n const retry = Number(res.headers.get('retry-after') ?? '0');\n this.failures++;\n this.backoffUntil = Date.now() + (retry > 0 ? retry * 1000 : this.backoffMs());\n await this.store.append({ at: Date.now(), body });\n this.scheduleRetry();\n } else if (res.status >= 500) {\n // Server-side failure: back off (exp + jitter) and retry the batch later.\n this.failures++;\n this.backoffUntil = Date.now() + this.backoffMs();\n await this.store.append({ at: Date.now(), body });\n this.scheduleRetry();\n } else {\n // 2xx (and non-retryable 4xx) — the batch is done; clear the failure streak.\n this.failures = 0;\n }\n } catch {\n // Offline / network error → persist for the next online drain + retry.\n this.failures++;\n this.backoffUntil = Date.now() + this.backoffMs();\n await this.store.append({ at: Date.now(), body });\n this.scheduleRetry();\n }\n }\n\n /** Exponential backoff with full jitter, capped. */\n private backoffMs(): number {\n const exp = Math.min(BACKOFF_CAP_MS, BACKOFF_BASE_MS * 2 ** Math.min(this.failures, 12));\n return Math.floor(Math.random() * exp);\n }\n\n private scheduleRetry(): void {\n if (this.retryTimer) return;\n const delay = Math.max(0, this.backoffUntil - Date.now()) + 250;\n this.retryTimer = setTimeout(() => {\n this.retryTimer = null;\n void this.drainOffline();\n }, delay);\n }\n\n // --- durable offline queue (masked data only; TTL'd; size-capped) ----------\n\n async drainOffline(): Promise<void> {\n if (Date.now() < this.backoffUntil) {\n this.scheduleRetry();\n return;\n }\n const q = await this.store.drain();\n for (const item of q) {\n if (Date.now() < this.backoffUntil) {\n // Backoff re-armed mid-drain: re-persist the remainder and reschedule.\n await this.store.append(item);\n this.scheduleRetry();\n return;\n }\n await this.send(item.body, false);\n }\n }\n\n /** optOut/reset clears any queued (but already-masked) payloads. */\n clearOffline(): void {\n void this.store.clear();\n }\n\n /** Drop the in-memory buffer so no buffered PII survives optOut()/reset(). */\n clearBuffer(): void {\n this.buffer = [];\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n }\n}\n\nexport type { QueuedBatch };\n","import { type FlagDefinition, type ScalarValue, type Value, evaluateFlag, prefixedId, randomToken } from '@glass/core';\nimport { ReplayRecorder } from './replay.js';\nimport { Transport } from './transport.js';\nimport type { FlagOptions, FlagValue, GlassConfig, GlassEvent, ResolvedConfig } from './types.js';\n\nexport type { GlassConfig, GlassEvent, FlagValue, FlagOptions } from './types.js';\n\nconst SESSION_IDLE_MS = 30 * 60_000;\nconst DEVICE_KEY = 'glass_device_id';\nconst SESSION_KEY = 'glass_session';\n\nfunction ls(): Storage | null {\n try {\n return typeof localStorage !== 'undefined' ? localStorage : null;\n } catch {\n return null;\n }\n}\n\n/**\n * The Glass browser client (`SDK.md` §3). One small object: identity, events,\n * errors, replay and flags. Non-blocking by construction; nothing here should\n * ever be on the app's critical path.\n */\nexport class Glass {\n private cfg!: ResolvedConfig;\n private transport!: Transport;\n private replay!: ReplayRecorder;\n private deviceId = '';\n private sessionId = '';\n private userId: string | null = null;\n private traits: Record<string, Value> = {};\n private groupCtx: { type: string; key: string } | null = null;\n private superProps: Record<string, Value> = {};\n private seq = 0;\n private lastActivity = 0;\n private flags: Record<string, FlagValue> = {};\n private flagsLoaded = false;\n private flagListeners: Array<(flags: Record<string, FlagValue>) => void> = [];\n private optedOut = false;\n private started = false;\n /** Calls made before init() are queued and replayed once started (`SDK.md` §2). */\n private preInitQueue: Array<() => void> = [];\n /** Removers for every listener/patch we install, so shutdown() leaves no trace. */\n private teardowns: Array<() => void> = [];\n\n init(config: GlassConfig): void {\n if (this.started) return;\n this.cfg = {\n projectKey: config.projectKey,\n ingestHost: config.ingestHost ?? 'https://in.glass.dev',\n apiHost: config.apiHost ?? 'https://api.glass.dev',\n replay: config.replay ?? true,\n autocapture: config.autocapture ?? true,\n errors: config.errors ?? true,\n captureConsole: config.captureConsole ?? false,\n recordConsole: config.recordConsole ?? true,\n recordNetwork: config.recordNetwork ?? true,\n sampleRate: config.sampleRate ?? 1,\n consent: config.consent ?? 'implied',\n maskAllInputs: config.maskAllInputs ?? true,\n maskTextSelector: config.maskTextSelector,\n blockSelector: config.blockSelector,\n respectDoNotTrack: config.respectDoNotTrack ?? true,\n flushIntervalMs: config.flushIntervalMs ?? 5000,\n flushAt: config.flushAt ?? 25,\n beforeSend: config.beforeSend ?? ((e) => e),\n bootstrapFlags: config.bootstrapFlags ?? {},\n flagDefinitions: config.flagDefinitions ?? [],\n };\n this.flags = { ...this.cfg.bootstrapFlags };\n\n if (this.cfg.respectDoNotTrack && typeof navigator !== 'undefined' && navigator.doNotTrack === '1') {\n this.optedOut = true;\n }\n\n this.deviceId = this.loadDeviceId();\n this.sessionId = this.loadSession();\n this.transport = new Transport(this.cfg, () => ({\n device_id: this.deviceId,\n session_id: this.sessionId,\n ...(this.userId ? { user_id: this.userId } : {}),\n traits: this.traits,\n ...(this.groupCtx ? { group: this.groupCtx } : {}),\n }));\n this.replay = new ReplayRecorder(this.cfg, () => this.sessionId);\n this.started = true;\n\n if (this.optedOut || (this.cfg.consent === 'opt-in')) {\n // No collection until optIn() is called.\n } else {\n this.afterConsent();\n }\n void this.reloadFeatureFlags();\n\n // Replay any calls made before init() resolved, in order.\n const queued = this.preInitQueue.splice(0, this.preInitQueue.length);\n for (const fn of queued) fn();\n }\n\n private afterConsent(): void {\n if (this.cfg.errors) this.installErrorHandlers();\n if (this.cfg.autocapture) this.installAutocapture();\n if (this.cfg.captureConsole) this.installConsoleCapture();\n this.installVisibilityFlush();\n if (this.cfg.replay && Math.random() < this.cfg.sampleRate) void this.replay.start();\n void this.transport.drainOffline();\n this.track('$pageview', this.pageProps());\n // Deliver the first pageview immediately (batched with anything queued during\n // init) so a fast bounce — open then close within the flush window — still\n // records the view, instead of relying only on the lossy pagehide beacon.\n this.flushSoon();\n }\n\n /**\n * Flush once on the next microtask. Runs after init()'s synchronous work\n * (pre-init queue drain + any `track()` right after `init()`), so the initial\n * pageview and those events go out in ONE batch, within a tick of load.\n */\n private initialFlushScheduled = false;\n private flushSoon(): void {\n if (this.initialFlushScheduled) return;\n this.initialFlushScheduled = true;\n const run = () => {\n this.initialFlushScheduled = false;\n void this.transport.flush();\n };\n if (typeof queueMicrotask === 'function') queueMicrotask(run);\n else void Promise.resolve().then(run);\n }\n\n /** Register a DOM listener and remember how to remove it on shutdown(). */\n private addListener(\n target: EventTarget,\n type: string,\n handler: EventListenerOrEventListenerObject,\n opts?: AddEventListenerOptions | boolean,\n ): void {\n target.addEventListener(type, handler, opts);\n this.teardowns.push(() => target.removeEventListener(type, handler, opts));\n }\n\n /**\n * Flush on tab hide (`SDK.md` §10). `visibilitychange`→hidden is the most\n * reliable \"user is leaving\" signal on mobile (where `pagehide`/`unload` are\n * unreliable), so we drain the buffer with a beacon while we still can.\n */\n private installVisibilityFlush(): void {\n if (typeof document === 'undefined') return;\n this.addListener(document, 'visibilitychange', () => {\n if (document.visibilityState === 'hidden') void this.transport.flush(true);\n });\n }\n\n // --- identity --------------------------------------------------------------\n\n private loadDeviceId(): string {\n const store = ls();\n let id = store?.getItem(DEVICE_KEY) ?? null;\n if (!id) {\n id = `dev_${randomToken(16)}`;\n store?.setItem(DEVICE_KEY, id);\n }\n return id;\n }\n\n private loadSession(): string {\n const store = ls();\n try {\n const raw = store?.getItem(SESSION_KEY);\n if (raw) {\n const parsed = JSON.parse(raw) as { id: string; last: number };\n if (Date.now() - parsed.last < SESSION_IDLE_MS) {\n this.lastActivity = parsed.last;\n return parsed.id;\n }\n }\n } catch {\n /* ignore */\n }\n const id = prefixedId('sess');\n this.persistSession(id);\n return id;\n }\n\n private persistSession(id: string): void {\n this.lastActivity = Date.now();\n ls()?.setItem(SESSION_KEY, JSON.stringify({ id, last: this.lastActivity }));\n }\n\n private touchSession(): void {\n if (Date.now() - this.lastActivity > SESSION_IDLE_MS) {\n this.sessionId = prefixedId('sess');\n this.seq = 0;\n }\n this.persistSession(this.sessionId);\n }\n\n /** Queue a call made before init() so nothing is lost; returns true if deferred. */\n private deferred(fn: () => void): boolean {\n if (this.started) return false;\n this.preInitQueue.push(fn);\n return true;\n }\n\n identify(userId: string, traits: Record<string, Value> = {}): void {\n if (this.deferred(() => this.identify(userId, traits))) return;\n this.userId = userId;\n this.traits = { ...this.traits, ...traits };\n this.emit('identify', undefined, traits);\n void this.reloadFeatureFlags();\n }\n\n reset(): void {\n // Flush what we have under the OLD identity, then drop everything so no\n // buffered/queued data leaks across the user-switch boundary.\n void this.transport.flush();\n this.transport.clearBuffer();\n this.transport.clearOffline();\n this.exposedKeys.clear();\n this.flags = { ...this.cfg.bootstrapFlags };\n this.userId = null;\n this.traits = {};\n this.groupCtx = null;\n this.superProps = {};\n const store = ls();\n store?.removeItem(SESSION_KEY);\n this.deviceId = `dev_${randomToken(16)}`;\n store?.setItem(DEVICE_KEY, this.deviceId);\n this.sessionId = prefixedId('sess');\n this.seq = 0;\n }\n\n getDeviceId(): string {\n return this.deviceId;\n }\n getSessionId(): string {\n return this.sessionId;\n }\n getSessionReplayUrl(): string {\n return `${this.cfg.apiHost}/replays/${this.sessionId}`;\n }\n\n groupIdentify(type: string, key: string, traits: Record<string, Value> = {}): void {\n if (this.deferred(() => this.groupIdentify(type, key, traits))) return;\n this.groupCtx = { type, key };\n this.emit('group', undefined, { group_type: type, group_key: key, ...traits });\n }\n\n /** Alias for `groupIdentify` (`SDK.md` API parity). */\n group(type: string, key: string, traits: Record<string, Value> = {}): void {\n this.groupIdentify(type, key, traits);\n }\n\n // --- events ----------------------------------------------------------------\n\n register(props: Record<string, Value>): void {\n if (this.deferred(() => this.register(props))) return;\n this.superProps = { ...this.superProps, ...props };\n }\n unregister(key: string): void {\n if (this.deferred(() => this.unregister(key))) return;\n delete this.superProps[key];\n }\n\n track(event: string, props: Record<string, Value> = {}): void {\n if (this.deferred(() => this.track(event, props))) return;\n this.emit('track', event, props);\n }\n\n private emit(type: GlassEvent['type'], event: string | undefined, props: Record<string, Value>): void {\n if (this.optedOut || !this.started) return;\n this.touchSession();\n this.transport.enqueue({\n type,\n ...(event ? { event } : {}),\n seq: this.seq++,\n t_client: new Date().toISOString(),\n props: { ...this.contextProps(), ...this.superProps, ...props },\n });\n // Mirror the event onto the replay timeline as a lightweight marker (errors\n // flagged so the player's \"jump to error\" works). No-op unless recording.\n if (this.cfg.replay) {\n const name = event ?? type;\n this.replay.addEvent(name, {\n event: name,\n ...(type === 'error' ? { level: 'error' } : {}),\n // Stamp the URL on pageviews so the player's address bar follows SPA route\n // changes — rrweb only emits a meta snapshot on full (hard) page loads.\n ...(name === '$pageview' && typeof location !== 'undefined' ? { href: location.href } : {}),\n });\n }\n }\n\n /** Device/screen context attached to EVERY event (`SDK.md` §4). */\n private contextProps(): Record<string, Value> {\n const ctx: Record<string, Value> = {};\n if (typeof screen !== 'undefined') {\n ctx.$screen_width = screen.width;\n ctx.$screen_height = screen.height;\n }\n if (typeof window !== 'undefined') {\n ctx.$viewport_width = window.innerWidth;\n ctx.$viewport_height = window.innerHeight;\n }\n if (typeof navigator !== 'undefined') {\n ctx.$locale = navigator.language ?? null;\n }\n return ctx;\n }\n\n private pageProps(): Record<string, Value> {\n if (typeof document === 'undefined' || typeof location === 'undefined') return {};\n return { url: location.href, $pathname: location.pathname, referrer: document.referrer };\n }\n\n // --- errors ----------------------------------------------------------------\n\n captureException(error: unknown, context: Record<string, Value> = {}): void {\n if (this.deferred(() => this.captureException(error, context))) return;\n const err = error instanceof Error ? error : new Error(String(error));\n this.emit('error', err.name, {\n message: err.message,\n stack: err.stack ?? '',\n ...context,\n });\n }\n\n /** Breadcrumb with optional category (`SDK.md` API parity). */\n addBreadcrumb(\n arg: string | { category?: string; message: string; data?: Record<string, Value> },\n data: Record<string, Value> = {},\n ): void {\n if (this.deferred(() => this.addBreadcrumb(arg, data))) return;\n if (typeof arg === 'string') {\n this.emit('track', '$breadcrumb', { message: arg, ...data });\n } else {\n this.emit('track', '$breadcrumb', {\n message: arg.message,\n ...(arg.category ? { category: arg.category } : {}),\n ...(arg.data ?? {}),\n });\n }\n }\n\n private installErrorHandlers(): void {\n if (typeof window === 'undefined') return;\n this.addListener(window, 'error', (e) =>\n this.captureException((e as ErrorEvent).error ?? (e as ErrorEvent).message),\n );\n this.addListener(window, 'unhandledrejection', (e) =>\n this.captureException((e as PromiseRejectionEvent).reason),\n );\n }\n\n /**\n * Opt-in console capture (`SDK.md` §5): mirror `console.error`/`console.warn`\n * into Glass (errors as exceptions, warnings as breadcrumbs) while ALWAYS\n * calling through to the original console, so we never swallow the developer's\n * own logs. Restored verbatim on shutdown().\n */\n private installConsoleCapture(): void {\n if (typeof console === 'undefined') return;\n const wrap = (level: 'error' | 'warn') => {\n const original = console[level];\n if (typeof original !== 'function') return;\n console[level] = (...args: unknown[]) => {\n try {\n const first = args[0];\n const message = args\n .map((a) => (typeof a === 'string' ? a : a instanceof Error ? a.message : safeString(a)))\n .join(' ')\n .slice(0, 500);\n if (level === 'error') {\n this.captureException(first instanceof Error ? first : new Error(message), { $console: true });\n } else {\n this.addBreadcrumb({ category: 'console.warn', message });\n }\n } catch {\n /* never let capture break the app's logging */\n }\n return (original as (...a: unknown[]) => void).apply(console, args);\n };\n this.teardowns.push(() => {\n console[level] = original;\n });\n };\n wrap('error');\n wrap('warn');\n }\n\n private rageWindow: number[] = [];\n\n private installAutocapture(): void {\n if (typeof document === 'undefined') return;\n\n this.addListener(\n document,\n 'click',\n (e) => {\n const target = (e as MouseEvent).target as HTMLElement | null;\n if (!target) return;\n this.detectRageClick();\n const el = target.closest('a,button,input[type=submit],[role=button],[data-glass]') as HTMLElement | null;\n if (!el) return;\n this.track('$click', this.elementProps(el));\n },\n { capture: true },\n );\n\n this.addListener(\n document,\n 'submit',\n (e) => {\n const form = (e as SubmitEvent).target as HTMLFormElement | null;\n if (!form || form.tagName !== 'FORM') return;\n // Never capture field VALUES — only structural metadata.\n this.track('$form_submit', {\n form_id: form.id || null,\n form_name: form.getAttribute('name'),\n action: form.getAttribute('action'),\n field_count: form.elements.length,\n });\n },\n { capture: true },\n );\n\n this.installSpaPageviews();\n }\n\n /** Stable, value-free descriptor of a clicked element. */\n private elementProps(el: HTMLElement): Record<string, Value> {\n return {\n tag: el.tagName.toLowerCase(),\n text: (el.textContent ?? '').trim().slice(0, 80),\n href: el instanceof HTMLAnchorElement ? el.href : null,\n el_id: el.id || null,\n el_class: el.getAttribute('class'),\n data_glass: el.getAttribute('data-glass'),\n };\n }\n\n /** Three+ clicks within 1s at roughly one spot = a rage click (frustration signal). */\n private detectRageClick(): void {\n const now = Date.now();\n this.rageWindow = this.rageWindow.filter((t) => now - t < 1000);\n this.rageWindow.push(now);\n if (this.rageWindow.length >= 3) {\n this.rageWindow = [];\n this.track('$rageclick', { url: typeof location !== 'undefined' ? location.href : null });\n }\n }\n\n /** SPA route changes: patch History + listen to popstate, de-duping same-URL. */\n private lastPath = '';\n private installSpaPageviews(): void {\n if (typeof history === 'undefined' || typeof location === 'undefined') return;\n this.lastPath = location.href;\n const fire = () => {\n if (location.href === this.lastPath) return;\n this.lastPath = location.href;\n this.track('$pageview', this.pageProps());\n };\n const wrap = (key: 'pushState' | 'replaceState') => {\n const orig = history[key];\n history[key] = function patched(this: History, ...args: Parameters<History['pushState']>) {\n const ret = orig.apply(this, args);\n // Defer so location has updated before we read it.\n setTimeout(fire, 0);\n return ret;\n } as History[typeof key];\n // Restore the native method on shutdown() so we don't leak a patch.\n this.teardowns.push(() => {\n history[key] = orig;\n });\n };\n wrap('pushState');\n wrap('replaceState');\n this.addListener(window, 'popstate', fire);\n }\n\n // --- session replay control ------------------------------------------------\n\n startSessionRecording(): void {\n void this.replay.start();\n }\n stopSessionRecording(): void {\n void this.replay.stopRecording();\n }\n\n // --- feature flags (deterministic, edge-evaluated) -------------------------\n\n async reloadFeatureFlags(): Promise<void> {\n try {\n const unit = this.userId ?? this.deviceId;\n const res = await fetch(`${this.cfg.apiHost}/v1/sdk/flags?user_id=${encodeURIComponent(unit)}`, {\n headers: { Authorization: `Glass-Key ${this.cfg.projectKey}` },\n });\n if (res.ok) {\n const json = (await res.json()) as { flags?: Record<string, FlagValue> };\n this.flags = { ...this.flags, ...(json.flags ?? {}) };\n }\n } catch {\n /* keep bootstrap/cached flags */\n } finally {\n this.flagsLoaded = true;\n for (const fn of this.flagListeners) fn(this.flags);\n }\n }\n\n onFlagsLoaded(fn: (flags: Record<string, FlagValue>) => void): void {\n this.flagListeners.push(fn);\n if (this.flagsLoaded) fn(this.flags);\n }\n\n /**\n * Resolve a flag value with precedence: locally-evaluated definition (if the\n * app shipped one, so targeting reflects CURRENT properties) → server/bootstrap\n * resolved value → fallback.\n */\n private resolve(key: string, opts?: FlagOptions): FlagValue {\n const local = this.evaluateLocal(key);\n const v = local !== undefined ? local : this.flags[key];\n const value = v !== undefined ? v : opts?.fallback;\n if (value !== undefined && opts?.trackExposure !== false) this.exposure(key, value);\n return value;\n }\n\n /** Local bucketing via @glass/core when definitions were provided to init(). */\n private evaluateLocal(key: string): FlagValue {\n const def = this.cfg.flagDefinitions.find((d: FlagDefinition) => d.key === key);\n if (!def) return undefined;\n const properties: Record<string, ScalarValue> = {};\n for (const [k, val] of Object.entries(this.traits)) {\n if (val === null || typeof val === 'string' || typeof val === 'number' || typeof val === 'boolean') {\n properties[k] = val as ScalarValue;\n }\n }\n return evaluateFlag(def, { unitId: this.userId ?? this.deviceId, properties });\n }\n\n isFeatureEnabledSync(key: string, opts?: FlagOptions): boolean {\n const v = this.resolve(key, opts);\n return v === true || (typeof v === 'string' && v !== '');\n }\n async isFeatureEnabled(key: string, opts?: FlagOptions): Promise<boolean> {\n if (!this.flagsLoaded) await this.reloadFeatureFlags();\n return this.isFeatureEnabledSync(key, opts);\n }\n getFeatureFlagSync(key: string, opts?: FlagOptions): FlagValue {\n return this.resolve(key, opts);\n }\n async getFeatureFlag(key: string, opts?: FlagOptions): Promise<FlagValue> {\n if (!this.flagsLoaded) await this.reloadFeatureFlags();\n return this.getFeatureFlagSync(key, opts);\n }\n getVariantSync(key: string, opts?: FlagOptions): FlagValue {\n return this.resolve(key, opts);\n }\n async getVariant(key: string, opts?: FlagOptions): Promise<FlagValue> {\n if (!this.flagsLoaded) await this.reloadFeatureFlags();\n return this.getVariantSync(key, opts);\n }\n\n /** Fire a `$exposure` once per (flag, value) so experiment analysis is honest (§8). */\n private exposedKeys = new Set<string>();\n private exposure(key: string, value: FlagValue): void {\n const k = `${key}=${String(value)}`;\n if (this.exposedKeys.has(k)) return;\n this.exposedKeys.add(k);\n this.emit('exposure', key, { $feature_flag: key, $feature_flag_value: String(value) });\n }\n\n // --- consent ---------------------------------------------------------------\n\n optIn(): void {\n this.optedOut = false;\n this.afterConsent();\n }\n optOut(): void {\n this.optedOut = true;\n // Discard anything buffered/queued the moment consent is withdrawn.\n this.transport.clearBuffer();\n this.transport.clearOffline();\n void this.replay.stopRecording();\n }\n hasConsent(): boolean {\n return !this.optedOut;\n }\n\n // --- lifecycle -------------------------------------------------------------\n\n flush(): Promise<void> {\n return this.transport.flush();\n }\n shutdown(): void {\n void this.transport.flush(true);\n void this.replay.stopRecording();\n // Remove every listener/patch we installed (in reverse) so re-init or a SPA\n // teardown leaves the page exactly as we found it.\n for (const off of this.teardowns.splice(0, this.teardowns.length).reverse()) {\n try {\n off();\n } catch {\n /* best-effort cleanup */\n }\n }\n this.transport.destroy();\n this.started = false;\n }\n}\n\n/** JSON-stringify that never throws (cyclic refs, BigInt, etc.) for console capture. */\nfunction safeString(value: unknown): string {\n try {\n return JSON.stringify(value) ?? String(value);\n } catch {\n return String(value);\n }\n}\n\n/** Default singleton, mirroring the ergonomic `glass.init(...)` usage in `SDK.md`. */\nexport const glass = new Glass();\nexport default glass;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glassanalytics/browser",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Glass browser SDK — session replay (rrweb), autocapture, identity, errors and edge-evaluated feature flags. Small, lazy, safe-by-default.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -15,20 +15,9 @@
15
15
  },
16
16
  "files": ["dist"],
17
17
  "sideEffects": false,
18
- "scripts": {
19
- "build": "tsup",
20
- "dev": "tsup --watch",
21
- "typecheck": "tsc --noEmit",
22
- "test": "vitest run --passWithNoTests",
23
- "clean": "rm -rf dist .turbo"
24
- },
25
18
  "dependencies": {
26
19
  "@glassanalytics/core": "0.1.0",
20
+ "@rrweb/rrweb-plugin-console-record": "2.0.1",
27
21
  "rrweb": "^2.0.0-alpha.18"
28
- },
29
- "devDependencies": {
30
- "tsup": "^8.3.5",
31
- "typescript": "^5.7.2",
32
- "vitest": "^2.1.8"
33
22
  }
34
23
  }