@glassanalytics/browser 0.1.1 → 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;
@@ -135,19 +234,38 @@ var ReplayRecorder = class {
135
234
  interval = null;
136
235
  boundFinal = null;
137
236
  encoder = new ReplayEncoder();
237
+ /** rrweb's addCustomEvent, captured on start — lets us weave Glass events into the stream. */
238
+ addCustom = null;
239
+ boundVisibility = null;
138
240
  async start() {
139
241
  if (this.stop) return;
140
242
  if (typeof window === "undefined") return;
141
243
  const { record } = await import('rrweb');
244
+ const rec = record;
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
+ }
142
257
  this.stop = record({
143
258
  emit: (event) => {
144
259
  this.events.push(event);
145
260
  if (this.events.length >= 50) void this.flushSegment();
146
261
  },
262
+ plugins: plugins.length ? plugins : void 0,
147
263
  // Privacy defaults: never leak user input.
148
264
  maskAllInputs: this.cfg.maskAllInputs,
149
265
  maskTextSelector: this.cfg.maskTextSelector,
150
- 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,
151
269
  // ALWAYS mask sensitive fields regardless of maskAllInputs (defense in depth).
152
270
  maskInputFn: (text, element) => {
153
271
  if (this.cfg.maskAllInputs) return "*".repeat(text.length);
@@ -162,6 +280,28 @@ var ReplayRecorder = class {
162
280
  this.interval = setInterval(() => void this.flushSegment(), 5e3);
163
281
  this.boundFinal = () => this.flushFinalBeacon();
164
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
+ }
292
+ }
293
+ /**
294
+ * Weave a Glass event into the rrweb stream as a Custom (type 5) event, so the
295
+ * player can render it as a timeline marker (`UI.md` §4.1). No-op unless we're
296
+ * actively recording. Payload is kept tiny (name + optional level) to avoid
297
+ * bloating replay segments.
298
+ */
299
+ addEvent(name, payload) {
300
+ if (!this.stop || !this.addCustom) return;
301
+ try {
302
+ this.addCustom(name, payload);
303
+ } catch {
304
+ }
165
305
  }
166
306
  async flushSegment() {
167
307
  if (this.events.length === 0) return;
@@ -199,6 +339,7 @@ var ReplayRecorder = class {
199
339
  await this.flushSegment();
200
340
  this.stop?.();
201
341
  this.stop = null;
342
+ this.addCustom = null;
202
343
  if (this.interval) {
203
344
  clearInterval(this.interval);
204
345
  this.interval = null;
@@ -207,6 +348,10 @@ var ReplayRecorder = class {
207
348
  window.removeEventListener("pagehide", this.boundFinal);
208
349
  this.boundFinal = null;
209
350
  }
351
+ if (this.boundVisibility && typeof document !== "undefined") {
352
+ document.removeEventListener("visibilitychange", this.boundVisibility);
353
+ this.boundVisibility = null;
354
+ }
210
355
  this.encoder.dispose();
211
356
  }
212
357
  get recording() {
@@ -559,6 +704,8 @@ var Glass = class {
559
704
  autocapture: config.autocapture ?? true,
560
705
  errors: config.errors ?? true,
561
706
  captureConsole: config.captureConsole ?? false,
707
+ recordConsole: config.recordConsole ?? true,
708
+ recordNetwork: config.recordNetwork ?? true,
562
709
  sampleRate: config.sampleRate ?? 1,
563
710
  consent: config.consent ?? "implied",
564
711
  maskAllInputs: config.maskAllInputs ?? true,
@@ -744,6 +891,16 @@ var Glass = class {
744
891
  t_client: (/* @__PURE__ */ new Date()).toISOString(),
745
892
  props: { ...this.contextProps(), ...this.superProps, ...props }
746
893
  });
894
+ if (this.cfg.replay) {
895
+ const name = event ?? type;
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
+ });
903
+ }
747
904
  }
748
905
  /** Device/screen context attached to EVERY event (`SDK.md` §4). */
749
906
  contextProps() {
@@ -951,7 +1108,7 @@ var Glass = class {
951
1108
  if (value !== void 0 && opts?.trackExposure !== false) this.exposure(key, value);
952
1109
  return value;
953
1110
  }
954
- /** Local bucketing via @glassanalytics/core when definitions were provided to init(). */
1111
+ /** Local bucketing via @glass/core when definitions were provided to init(). */
955
1112
  evaluateLocal(key) {
956
1113
  const def = this.cfg.flagDefinitions.find((d) => d.key === key);
957
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\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 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 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 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 }\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.1",
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
  }