@tracewayapp/frontend 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -34,10 +34,20 @@ declare function formatBrowserStackTrace(error: Error): string;
34
34
 
35
35
  declare function installGlobalHandlers(client: TracewayFrontendClient): void;
36
36
 
37
+ declare function getActiveDistributedTraceId(): string | null;
38
+
37
39
  declare function init(connectionString: string, options?: TracewayFrontendOptions): void;
38
- declare function captureException(error: Error): void;
39
- declare function captureExceptionWithAttributes(error: Error, attributes?: Record<string, string>): void;
40
+ declare function captureException(error: Error, options?: {
41
+ distributedTraceId?: string;
42
+ }): void;
43
+ declare function captureExceptionWithAttributes(error: Error, attributes?: Record<string, string>, options?: {
44
+ distributedTraceId?: string;
45
+ }): void;
40
46
  declare function captureMessage(msg: string): void;
41
47
  declare function flush(timeoutMs?: number): Promise<void>;
42
48
 
43
- export { TracewayFrontendClient, type TracewayFrontendOptions, captureException, captureExceptionWithAttributes, captureMessage, flush, formatBrowserStackTrace, init, installGlobalHandlers };
49
+ declare const DISTRIBUTED_TRACE_HEADER = "traceway-trace-id";
50
+
51
+ declare function createAxiosInterceptor(): (config: any) => any;
52
+
53
+ export { DISTRIBUTED_TRACE_HEADER, TracewayFrontendClient, type TracewayFrontendOptions, captureException, captureExceptionWithAttributes, captureMessage, createAxiosInterceptor, flush, formatBrowserStackTrace, getActiveDistributedTraceId, init, installGlobalHandlers };
package/dist/index.d.ts CHANGED
@@ -34,10 +34,20 @@ declare function formatBrowserStackTrace(error: Error): string;
34
34
 
35
35
  declare function installGlobalHandlers(client: TracewayFrontendClient): void;
36
36
 
37
+ declare function getActiveDistributedTraceId(): string | null;
38
+
37
39
  declare function init(connectionString: string, options?: TracewayFrontendOptions): void;
38
- declare function captureException(error: Error): void;
39
- declare function captureExceptionWithAttributes(error: Error, attributes?: Record<string, string>): void;
40
+ declare function captureException(error: Error, options?: {
41
+ distributedTraceId?: string;
42
+ }): void;
43
+ declare function captureExceptionWithAttributes(error: Error, attributes?: Record<string, string>, options?: {
44
+ distributedTraceId?: string;
45
+ }): void;
40
46
  declare function captureMessage(msg: string): void;
41
47
  declare function flush(timeoutMs?: number): Promise<void>;
42
48
 
43
- export { TracewayFrontendClient, type TracewayFrontendOptions, captureException, captureExceptionWithAttributes, captureMessage, flush, formatBrowserStackTrace, init, installGlobalHandlers };
49
+ declare const DISTRIBUTED_TRACE_HEADER = "traceway-trace-id";
50
+
51
+ declare function createAxiosInterceptor(): (config: any) => any;
52
+
53
+ export { DISTRIBUTED_TRACE_HEADER, TracewayFrontendClient, type TracewayFrontendOptions, captureException, captureExceptionWithAttributes, captureMessage, createAxiosInterceptor, flush, formatBrowserStackTrace, getActiveDistributedTraceId, init, installGlobalHandlers };
package/dist/index.js CHANGED
@@ -20,17 +20,20 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ DISTRIBUTED_TRACE_HEADER: () => DISTRIBUTED_TRACE_HEADER,
23
24
  TracewayFrontendClient: () => TracewayFrontendClient,
24
25
  captureException: () => captureException,
25
26
  captureExceptionWithAttributes: () => captureExceptionWithAttributes,
26
27
  captureMessage: () => captureMessage,
28
+ createAxiosInterceptor: () => createAxiosInterceptor,
27
29
  flush: () => flush,
28
30
  formatBrowserStackTrace: () => formatBrowserStackTrace,
31
+ getActiveDistributedTraceId: () => getActiveDistributedTraceId,
29
32
  init: () => init,
30
33
  installGlobalHandlers: () => installGlobalHandlers
31
34
  });
32
35
  module.exports = __toCommonJS(index_exports);
33
- var import_core3 = require("@tracewayapp/core");
36
+ var import_core4 = require("@tracewayapp/core");
34
37
 
35
38
  // src/client.ts
36
39
  var import_core = require("@tracewayapp/core");
@@ -331,7 +334,44 @@ function shortenFilePath(filePath) {
331
334
  }
332
335
 
333
336
  // src/global-handlers.ts
337
+ var import_core3 = require("@tracewayapp/core");
338
+
339
+ // src/fetch-instrumentation.ts
334
340
  var import_core2 = require("@tracewayapp/core");
341
+ var activeDistributedTraceId = null;
342
+ function getActiveDistributedTraceId() {
343
+ return activeDistributedTraceId;
344
+ }
345
+ function isSameOrigin(input) {
346
+ try {
347
+ const url = new URL(
348
+ typeof input === "string" ? input : input instanceof Request ? input.url : input.href,
349
+ window.location.origin
350
+ );
351
+ return url.origin === window.location.origin;
352
+ } catch {
353
+ return true;
354
+ }
355
+ }
356
+ function installFetchInstrumentation() {
357
+ const originalFetch = window.fetch;
358
+ window.fetch = function(input, init2) {
359
+ if (!isSameOrigin(input)) {
360
+ return originalFetch.call(this, input, init2);
361
+ }
362
+ const traceId = (0, import_core2.generateUUID)();
363
+ activeDistributedTraceId = traceId;
364
+ const headers = new Headers(init2?.headers);
365
+ headers.set("traceway-trace-id", traceId);
366
+ return originalFetch.call(this, input, { ...init2, headers }).finally(() => {
367
+ if (activeDistributedTraceId === traceId) {
368
+ activeDistributedTraceId = null;
369
+ }
370
+ });
371
+ };
372
+ }
373
+
374
+ // src/global-handlers.ts
335
375
  function installGlobalHandlers(client2) {
336
376
  const prevOnError = window.onerror;
337
377
  window.onerror = (message, source, lineno, colno, error) => {
@@ -339,15 +379,17 @@ function installGlobalHandlers(client2) {
339
379
  client2.addException({
340
380
  traceId: null,
341
381
  stackTrace: formatBrowserStackTrace(error),
342
- recordedAt: (0, import_core2.nowISO)(),
343
- isMessage: false
382
+ recordedAt: (0, import_core3.nowISO)(),
383
+ isMessage: false,
384
+ distributedTraceId: getActiveDistributedTraceId()
344
385
  });
345
386
  } else {
346
387
  client2.addException({
347
388
  traceId: null,
348
389
  stackTrace: String(message),
349
- recordedAt: (0, import_core2.nowISO)(),
350
- isMessage: false
390
+ recordedAt: (0, import_core3.nowISO)(),
391
+ isMessage: false,
392
+ distributedTraceId: getActiveDistributedTraceId()
351
393
  });
352
394
  }
353
395
  if (typeof prevOnError === "function") {
@@ -362,15 +404,17 @@ function installGlobalHandlers(client2) {
362
404
  client2.addException({
363
405
  traceId: null,
364
406
  stackTrace: formatBrowserStackTrace(reason),
365
- recordedAt: (0, import_core2.nowISO)(),
366
- isMessage: false
407
+ recordedAt: (0, import_core3.nowISO)(),
408
+ isMessage: false,
409
+ distributedTraceId: getActiveDistributedTraceId()
367
410
  });
368
411
  } else {
369
412
  client2.addException({
370
413
  traceId: null,
371
414
  stackTrace: String(reason),
372
- recordedAt: (0, import_core2.nowISO)(),
373
- isMessage: false
415
+ recordedAt: (0, import_core3.nowISO)(),
416
+ isMessage: false,
417
+ distributedTraceId: getActiveDistributedTraceId()
374
418
  });
375
419
  }
376
420
  if (typeof prevOnUnhandledRejection === "function") {
@@ -385,25 +429,28 @@ function init(connectionString, options = {}) {
385
429
  client = new TracewayFrontendClient(connectionString, options);
386
430
  if (typeof window !== "undefined") {
387
431
  installGlobalHandlers(client);
432
+ installFetchInstrumentation();
388
433
  }
389
434
  }
390
- function captureException(error) {
435
+ function captureException(error, options) {
391
436
  if (!client) return;
392
437
  client.addException({
393
438
  traceId: null,
394
439
  stackTrace: formatBrowserStackTrace(error),
395
- recordedAt: (0, import_core3.nowISO)(),
396
- isMessage: false
440
+ recordedAt: (0, import_core4.nowISO)(),
441
+ isMessage: false,
442
+ distributedTraceId: options?.distributedTraceId ?? getActiveDistributedTraceId()
397
443
  });
398
444
  }
399
- function captureExceptionWithAttributes(error, attributes) {
445
+ function captureExceptionWithAttributes(error, attributes, options) {
400
446
  if (!client) return;
401
447
  client.addException({
402
448
  traceId: null,
403
449
  stackTrace: formatBrowserStackTrace(error),
404
- recordedAt: (0, import_core3.nowISO)(),
450
+ recordedAt: (0, import_core4.nowISO)(),
405
451
  attributes,
406
- isMessage: false
452
+ isMessage: false,
453
+ distributedTraceId: options?.distributedTraceId ?? getActiveDistributedTraceId()
407
454
  });
408
455
  }
409
456
  function captureMessage(msg) {
@@ -411,7 +458,7 @@ function captureMessage(msg) {
411
458
  client.addException({
412
459
  traceId: null,
413
460
  stackTrace: msg,
414
- recordedAt: (0, import_core3.nowISO)(),
461
+ recordedAt: (0, import_core4.nowISO)(),
415
462
  isMessage: true
416
463
  });
417
464
  }
@@ -419,4 +466,12 @@ async function flush(timeoutMs) {
419
466
  if (!client) return;
420
467
  await client.flush(timeoutMs);
421
468
  }
469
+ var DISTRIBUTED_TRACE_HEADER = "traceway-trace-id";
470
+ function createAxiosInterceptor() {
471
+ return (config) => {
472
+ config.headers = config.headers || {};
473
+ config.headers["traceway-trace-id"] = (0, import_core4.generateUUID)();
474
+ return config;
475
+ };
476
+ }
422
477
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/transport.ts","../src/session-recorder.ts","../src/stack-trace.ts","../src/global-handlers.ts"],"sourcesContent":["import { nowISO } from \"@tracewayapp/core\";\nimport type { ExceptionStackTrace } from \"@tracewayapp/core\";\nimport {\n TracewayFrontendClient,\n type TracewayFrontendOptions,\n} from \"./client.js\";\nimport { formatBrowserStackTrace } from \"./stack-trace.js\";\nimport { installGlobalHandlers } from \"./global-handlers.js\";\n\nlet client: TracewayFrontendClient | null = null;\n\nexport function init(\n connectionString: string,\n options: TracewayFrontendOptions = {},\n): void {\n client = new TracewayFrontendClient(connectionString, options);\n if (typeof window !== \"undefined\") {\n installGlobalHandlers(client);\n }\n}\n\nexport function captureException(error: Error): void {\n if (!client) return;\n client.addException({\n traceId: null,\n stackTrace: formatBrowserStackTrace(error),\n recordedAt: nowISO(),\n isMessage: false,\n });\n}\n\nexport function captureExceptionWithAttributes(\n error: Error,\n attributes?: Record<string, string>,\n): void {\n if (!client) return;\n client.addException({\n traceId: null,\n stackTrace: formatBrowserStackTrace(error),\n recordedAt: nowISO(),\n attributes,\n isMessage: false,\n });\n}\n\nexport function captureMessage(msg: string): void {\n if (!client) return;\n client.addException({\n traceId: null,\n stackTrace: msg,\n recordedAt: nowISO(),\n isMessage: true,\n });\n}\n\nexport async function flush(timeoutMs?: number): Promise<void> {\n if (!client) return;\n await client.flush(timeoutMs);\n}\n\nexport { TracewayFrontendClient } from \"./client.js\";\nexport type { TracewayFrontendOptions } from \"./client.js\";\nexport { formatBrowserStackTrace } from \"./stack-trace.js\";\nexport { installGlobalHandlers } from \"./global-handlers.js\";\n\nexport type {\n ExceptionStackTrace,\n CollectionFrame,\n ReportRequest,\n} from \"@tracewayapp/core\";\n","import type {\n ExceptionStackTrace,\n ReportRequest,\n CollectionFrame,\n SessionRecordingPayload,\n} from \"@tracewayapp/core\";\nimport { parseConnectionString, generateUUID } from \"@tracewayapp/core\";\nimport { sendReport } from \"./transport.js\";\nimport { SessionRecorder } from \"./session-recorder.js\";\n\nexport interface TracewayFrontendOptions {\n debug?: boolean;\n debounceMs?: number;\n retryDelayMs?: number;\n version?: string;\n sessionRecording?: boolean;\n sessionRecordingSegmentDuration?: number;\n}\n\nexport class TracewayFrontendClient {\n private apiUrl: string;\n private token: string;\n private debug: boolean;\n private debounceMs: number;\n private retryDelayMs: number;\n private version: string;\n\n private pendingExceptions: ExceptionStackTrace[] = [];\n private pendingRecordings: SessionRecordingPayload[] = [];\n private isSyncing = false;\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n private retryTimer: ReturnType<typeof setTimeout> | null = null;\n\n private recorder: SessionRecorder | null = null;\n\n constructor(connectionString: string, options: TracewayFrontendOptions = {}) {\n const { token, apiUrl } = parseConnectionString(connectionString);\n this.apiUrl = apiUrl;\n this.token = token;\n this.debug = options.debug ?? false;\n this.debounceMs = options.debounceMs ?? 1500;\n this.retryDelayMs = options.retryDelayMs ?? 10000;\n this.version = options.version ?? \"\";\n\n if (options.sessionRecording !== false && typeof window !== \"undefined\") {\n this.recorder = new SessionRecorder({\n segmentDuration: options.sessionRecordingSegmentDuration,\n });\n this.recorder.start();\n }\n }\n\n addException(exception: ExceptionStackTrace): void {\n if (this.recorder && this.recorder.hasSegments()) {\n const segments = this.recorder.getSegments();\n const allEvents = segments.flatMap((s) => s.events);\n const exceptionId = generateUUID();\n exception.sessionRecordingId = exceptionId;\n this.pendingRecordings.push({ exceptionId, events: allEvents });\n }\n\n this.pendingExceptions.push(exception);\n this.scheduleSync();\n }\n\n private scheduleSync(): void {\n if (this.debounceTimer !== null) {\n clearTimeout(this.debounceTimer);\n }\n this.debounceTimer = setTimeout(() => {\n this.debounceTimer = null;\n this.doSync();\n }, this.debounceMs);\n }\n\n private async doSync(): Promise<void> {\n if (this.isSyncing) return;\n if (this.pendingExceptions.length === 0) return;\n\n this.isSyncing = true;\n const batch = this.pendingExceptions.splice(0);\n const recordings = this.pendingRecordings.splice(0);\n\n const frame: CollectionFrame = {\n stackTraces: batch,\n metrics: [],\n traces: [],\n sessionRecordings: recordings.length > 0 ? recordings : undefined,\n };\n\n const payload: ReportRequest = {\n collectionFrames: [frame],\n appVersion: this.version,\n serverName: \"\",\n };\n\n let failed = false;\n try {\n const success = await sendReport(\n this.apiUrl,\n this.token,\n JSON.stringify(payload),\n );\n if (!success) {\n failed = true;\n this.pendingExceptions.unshift(...batch);\n this.pendingRecordings.unshift(...recordings);\n if (this.debug) {\n console.error(\"Traceway: sync failed, re-queued exceptions\");\n }\n }\n } catch (err) {\n failed = true;\n this.pendingExceptions.unshift(...batch);\n this.pendingRecordings.unshift(...recordings);\n if (this.debug) {\n console.error(\"Traceway: sync error:\", err);\n }\n } finally {\n this.isSyncing = false;\n if (this.pendingExceptions.length > 0) {\n if (failed) {\n this.scheduleRetry();\n } else {\n this.doSync();\n }\n }\n }\n }\n\n private scheduleRetry(): void {\n if (this.retryTimer !== null) return;\n this.retryTimer = setTimeout(() => {\n this.retryTimer = null;\n this.doSync();\n }, this.retryDelayMs);\n }\n\n async flush(timeoutMs?: number): Promise<void> {\n if (this.debounceTimer !== null) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n if (this.retryTimer !== null) {\n clearTimeout(this.retryTimer);\n this.retryTimer = null;\n }\n if (this.recorder) {\n this.recorder.stop();\n }\n\n const syncPromise = this.doSync();\n\n if (timeoutMs !== undefined) {\n await Promise.race([\n syncPromise,\n new Promise<void>((resolve) => setTimeout(resolve, timeoutMs)),\n ]);\n } else {\n await syncPromise;\n }\n }\n}\n","export async function compressGzip(data: string): Promise<Uint8Array> {\n const encoder = new TextEncoder();\n const inputBytes = encoder.encode(data);\n\n const cs = new CompressionStream(\"gzip\");\n const writer = cs.writable.getWriter();\n writer.write(inputBytes);\n writer.close();\n\n const reader = cs.readable.getReader();\n const chunks: Uint8Array[] = [];\n let totalLength = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n totalLength += value.length;\n }\n\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n\n return result;\n}\n\nexport async function sendReport(\n apiUrl: string,\n token: string,\n body: string,\n): Promise<boolean> {\n const compressed = await compressGzip(body);\n\n const resp = await fetch(apiUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Content-Encoding\": \"gzip\",\n Authorization: `Bearer ${token}`,\n },\n body: compressed,\n });\n\n return resp.status === 200;\n}\n","import type { eventWithTime } from \"rrweb\";\nimport { record } from \"rrweb\";\n\nexport interface SessionRecorderOptions {\n segmentDuration?: number;\n}\n\ninterface Segment {\n events: eventWithTime[];\n startedAt: string;\n}\n\nexport class SessionRecorder {\n private segmentDuration: number;\n private current: Segment;\n private previous: Segment | null = null;\n private stopFn: (() => void) | null = null;\n private rotateInterval: ReturnType<typeof setInterval> | null = null;\n\n constructor(options: SessionRecorderOptions = {}) {\n this.segmentDuration = options.segmentDuration ?? 10_000;\n this.current = { events: [], startedAt: new Date().toISOString() };\n }\n\n start(): void {\n this.stopFn = record({\n emit: (event) => {\n this.onEvent(event);\n },\n });\n\n this.rotateInterval = setInterval(() => {\n this.rotateSegment();\n }, this.segmentDuration);\n }\n\n stop(): void {\n if (this.stopFn) {\n this.stopFn();\n this.stopFn = null;\n }\n if (this.rotateInterval) {\n clearInterval(this.rotateInterval);\n this.rotateInterval = null;\n }\n }\n\n private onEvent(event: eventWithTime): void {\n this.current.events.push(event);\n }\n\n private rotateSegment(): void {\n this.previous = this.current;\n this.current = { events: [], startedAt: new Date().toISOString() };\n record.takeFullSnapshot();\n }\n\n getSegments(): { events: eventWithTime[]; timestamp: string }[] {\n const segments: { events: eventWithTime[]; timestamp: string }[] = [];\n if (this.previous && this.previous.events.length > 0) {\n segments.push({\n events: this.previous.events,\n timestamp: this.previous.startedAt,\n });\n }\n if (this.current.events.length > 0) {\n segments.push({\n events: this.current.events,\n timestamp: this.current.startedAt,\n });\n }\n return segments;\n }\n\n hasSegments(): boolean {\n return (\n this.current.events.length > 0 ||\n (this.previous !== null && this.previous.events.length > 0)\n );\n }\n\n flush(): void {\n this.previous = null;\n this.current = { events: [], startedAt: new Date().toISOString() };\n if (this.stopFn) {\n record.takeFullSnapshot();\n }\n }\n}\n","export function formatBrowserStackTrace(error: Error): string {\n const lines: string[] = [];\n const typeName = error.constructor?.name || \"Error\";\n lines.push(`${typeName}: ${error.message}`);\n\n if (error.stack) {\n const stackLines = error.stack.split(\"\\n\");\n for (const line of stackLines) {\n // V8 format: \" at funcName (file:line:col)\"\n const v8Match = line.match(/^\\s+at\\s+(.+?)\\s+\\((.+):(\\d+):(\\d+)\\)$/);\n if (v8Match) {\n const funcName = shortenFunctionName(v8Match[1]);\n const file = shortenFilePath(v8Match[2]);\n lines.push(`${funcName}()`);\n lines.push(` ${file}:${v8Match[3]}:${v8Match[4]}`);\n continue;\n }\n\n // V8 anonymous: \" at file:line:col\"\n const v8AnonMatch = line.match(/^\\s+at\\s+(.+):(\\d+):(\\d+)$/);\n if (v8AnonMatch) {\n const file = shortenFilePath(v8AnonMatch[1]);\n lines.push(`<anonymous>()`);\n lines.push(` ${file}:${v8AnonMatch[2]}:${v8AnonMatch[3]}`);\n continue;\n }\n\n // Firefox format: \"funcName@file:line:col\"\n const ffMatch = line.match(/^(.+)@(.+):(\\d+):(\\d+)$/);\n if (ffMatch) {\n const funcName = shortenFunctionName(ffMatch[1]) || \"<anonymous>\";\n const file = shortenFilePath(ffMatch[2]);\n lines.push(`${funcName}()`);\n lines.push(` ${file}:${ffMatch[3]}:${ffMatch[4]}`);\n continue;\n }\n\n // Firefox anonymous: \"@file:line:col\"\n const ffAnonMatch = line.match(/^@(.+):(\\d+):(\\d+)$/);\n if (ffAnonMatch) {\n const file = shortenFilePath(ffAnonMatch[1]);\n lines.push(`<anonymous>()`);\n lines.push(` ${file}:${ffAnonMatch[2]}:${ffAnonMatch[3]}`);\n continue;\n }\n }\n }\n\n return lines.join(\"\\n\") + \"\\n\";\n}\n\nfunction shortenFunctionName(fn: string): string {\n const slashIdx = fn.lastIndexOf(\"/\");\n if (slashIdx >= 0) {\n fn = fn.slice(slashIdx + 1);\n }\n const dotIdx = fn.indexOf(\".\");\n if (dotIdx >= 0) {\n fn = fn.slice(dotIdx + 1);\n }\n return fn;\n}\n\nfunction shortenFilePath(filePath: string): string {\n const parts = filePath.split(\"/\");\n return parts[parts.length - 1];\n}\n","import type { TracewayFrontendClient } from \"./client.js\";\nimport { formatBrowserStackTrace } from \"./stack-trace.js\";\nimport { nowISO } from \"@tracewayapp/core\";\n\nexport function installGlobalHandlers(client: TracewayFrontendClient): void {\n const prevOnError = window.onerror;\n window.onerror = (message, source, lineno, colno, error) => {\n if (error) {\n client.addException({\n traceId: null,\n stackTrace: formatBrowserStackTrace(error),\n recordedAt: nowISO(),\n isMessage: false,\n });\n } else {\n client.addException({\n traceId: null,\n stackTrace: String(message),\n recordedAt: nowISO(),\n isMessage: false,\n });\n }\n if (typeof prevOnError === \"function\") {\n return prevOnError(message, source, lineno, colno, error);\n }\n return false;\n };\n\n const prevOnUnhandledRejection = window.onunhandledrejection;\n window.onunhandledrejection = (event: PromiseRejectionEvent) => {\n const reason = event.reason;\n if (reason instanceof Error) {\n client.addException({\n traceId: null,\n stackTrace: formatBrowserStackTrace(reason),\n recordedAt: nowISO(),\n isMessage: false,\n });\n } else {\n client.addException({\n traceId: null,\n stackTrace: String(reason),\n recordedAt: nowISO(),\n isMessage: false,\n });\n }\n if (typeof prevOnUnhandledRejection === \"function\") {\n prevOnUnhandledRejection.call(window, event);\n }\n };\n}\n"],"mappings":"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","names":["import_core","import_core","client"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/transport.ts","../src/session-recorder.ts","../src/stack-trace.ts","../src/global-handlers.ts","../src/fetch-instrumentation.ts"],"sourcesContent":["import { nowISO, generateUUID } from \"@tracewayapp/core\";\nimport type { ExceptionStackTrace } from \"@tracewayapp/core\";\nimport {\n TracewayFrontendClient,\n type TracewayFrontendOptions,\n} from \"./client.js\";\nimport { formatBrowserStackTrace } from \"./stack-trace.js\";\nimport { installGlobalHandlers } from \"./global-handlers.js\";\nimport {\n installFetchInstrumentation,\n getActiveDistributedTraceId,\n} from \"./fetch-instrumentation.js\";\n\nlet client: TracewayFrontendClient | null = null;\n\nexport function init(\n connectionString: string,\n options: TracewayFrontendOptions = {},\n): void {\n client = new TracewayFrontendClient(connectionString, options);\n if (typeof window !== \"undefined\") {\n installGlobalHandlers(client);\n installFetchInstrumentation();\n }\n}\n\nexport function captureException(\n error: Error,\n options?: { distributedTraceId?: string },\n): void {\n if (!client) return;\n client.addException({\n traceId: null,\n stackTrace: formatBrowserStackTrace(error),\n recordedAt: nowISO(),\n isMessage: false,\n distributedTraceId:\n options?.distributedTraceId ?? getActiveDistributedTraceId(),\n });\n}\n\nexport function captureExceptionWithAttributes(\n error: Error,\n attributes?: Record<string, string>,\n options?: { distributedTraceId?: string },\n): void {\n if (!client) return;\n client.addException({\n traceId: null,\n stackTrace: formatBrowserStackTrace(error),\n recordedAt: nowISO(),\n attributes,\n isMessage: false,\n distributedTraceId:\n options?.distributedTraceId ?? getActiveDistributedTraceId(),\n });\n}\n\nexport function captureMessage(msg: string): void {\n if (!client) return;\n client.addException({\n traceId: null,\n stackTrace: msg,\n recordedAt: nowISO(),\n isMessage: true,\n });\n}\n\nexport async function flush(timeoutMs?: number): Promise<void> {\n if (!client) return;\n await client.flush(timeoutMs);\n}\n\nexport { TracewayFrontendClient } from \"./client.js\";\nexport type { TracewayFrontendOptions } from \"./client.js\";\nexport { formatBrowserStackTrace } from \"./stack-trace.js\";\nexport { installGlobalHandlers } from \"./global-handlers.js\";\n\nexport type {\n ExceptionStackTrace,\n CollectionFrame,\n ReportRequest,\n} from \"@tracewayapp/core\";\n\nexport const DISTRIBUTED_TRACE_HEADER = \"traceway-trace-id\";\n\nexport { getActiveDistributedTraceId } from \"./fetch-instrumentation.js\";\n\nexport function createAxiosInterceptor() {\n return (config: any) => {\n config.headers = config.headers || {};\n config.headers[\"traceway-trace-id\"] = generateUUID();\n return config;\n };\n}\n","import type {\n ExceptionStackTrace,\n ReportRequest,\n CollectionFrame,\n SessionRecordingPayload,\n} from \"@tracewayapp/core\";\nimport { parseConnectionString, generateUUID } from \"@tracewayapp/core\";\nimport { sendReport } from \"./transport.js\";\nimport { SessionRecorder } from \"./session-recorder.js\";\n\nexport interface TracewayFrontendOptions {\n debug?: boolean;\n debounceMs?: number;\n retryDelayMs?: number;\n version?: string;\n sessionRecording?: boolean;\n sessionRecordingSegmentDuration?: number;\n}\n\nexport class TracewayFrontendClient {\n private apiUrl: string;\n private token: string;\n private debug: boolean;\n private debounceMs: number;\n private retryDelayMs: number;\n private version: string;\n\n private pendingExceptions: ExceptionStackTrace[] = [];\n private pendingRecordings: SessionRecordingPayload[] = [];\n private isSyncing = false;\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n private retryTimer: ReturnType<typeof setTimeout> | null = null;\n\n private recorder: SessionRecorder | null = null;\n\n constructor(connectionString: string, options: TracewayFrontendOptions = {}) {\n const { token, apiUrl } = parseConnectionString(connectionString);\n this.apiUrl = apiUrl;\n this.token = token;\n this.debug = options.debug ?? false;\n this.debounceMs = options.debounceMs ?? 1500;\n this.retryDelayMs = options.retryDelayMs ?? 10000;\n this.version = options.version ?? \"\";\n\n if (options.sessionRecording !== false && typeof window !== \"undefined\") {\n this.recorder = new SessionRecorder({\n segmentDuration: options.sessionRecordingSegmentDuration,\n });\n this.recorder.start();\n }\n }\n\n addException(exception: ExceptionStackTrace): void {\n if (this.recorder && this.recorder.hasSegments()) {\n const segments = this.recorder.getSegments();\n const allEvents = segments.flatMap((s) => s.events);\n const exceptionId = generateUUID();\n exception.sessionRecordingId = exceptionId;\n this.pendingRecordings.push({ exceptionId, events: allEvents });\n }\n\n this.pendingExceptions.push(exception);\n this.scheduleSync();\n }\n\n private scheduleSync(): void {\n if (this.debounceTimer !== null) {\n clearTimeout(this.debounceTimer);\n }\n this.debounceTimer = setTimeout(() => {\n this.debounceTimer = null;\n this.doSync();\n }, this.debounceMs);\n }\n\n private async doSync(): Promise<void> {\n if (this.isSyncing) return;\n if (this.pendingExceptions.length === 0) return;\n\n this.isSyncing = true;\n const batch = this.pendingExceptions.splice(0);\n const recordings = this.pendingRecordings.splice(0);\n\n const frame: CollectionFrame = {\n stackTraces: batch,\n metrics: [],\n traces: [],\n sessionRecordings: recordings.length > 0 ? recordings : undefined,\n };\n\n const payload: ReportRequest = {\n collectionFrames: [frame],\n appVersion: this.version,\n serverName: \"\",\n };\n\n let failed = false;\n try {\n const success = await sendReport(\n this.apiUrl,\n this.token,\n JSON.stringify(payload),\n );\n if (!success) {\n failed = true;\n this.pendingExceptions.unshift(...batch);\n this.pendingRecordings.unshift(...recordings);\n if (this.debug) {\n console.error(\"Traceway: sync failed, re-queued exceptions\");\n }\n }\n } catch (err) {\n failed = true;\n this.pendingExceptions.unshift(...batch);\n this.pendingRecordings.unshift(...recordings);\n if (this.debug) {\n console.error(\"Traceway: sync error:\", err);\n }\n } finally {\n this.isSyncing = false;\n if (this.pendingExceptions.length > 0) {\n if (failed) {\n this.scheduleRetry();\n } else {\n this.doSync();\n }\n }\n }\n }\n\n private scheduleRetry(): void {\n if (this.retryTimer !== null) return;\n this.retryTimer = setTimeout(() => {\n this.retryTimer = null;\n this.doSync();\n }, this.retryDelayMs);\n }\n\n async flush(timeoutMs?: number): Promise<void> {\n if (this.debounceTimer !== null) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n if (this.retryTimer !== null) {\n clearTimeout(this.retryTimer);\n this.retryTimer = null;\n }\n if (this.recorder) {\n this.recorder.stop();\n }\n\n const syncPromise = this.doSync();\n\n if (timeoutMs !== undefined) {\n await Promise.race([\n syncPromise,\n new Promise<void>((resolve) => setTimeout(resolve, timeoutMs)),\n ]);\n } else {\n await syncPromise;\n }\n }\n}\n","export async function compressGzip(data: string): Promise<Uint8Array> {\n const encoder = new TextEncoder();\n const inputBytes = encoder.encode(data);\n\n const cs = new CompressionStream(\"gzip\");\n const writer = cs.writable.getWriter();\n writer.write(inputBytes);\n writer.close();\n\n const reader = cs.readable.getReader();\n const chunks: Uint8Array[] = [];\n let totalLength = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n totalLength += value.length;\n }\n\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n\n return result;\n}\n\nexport async function sendReport(\n apiUrl: string,\n token: string,\n body: string,\n): Promise<boolean> {\n const compressed = await compressGzip(body);\n\n const resp = await fetch(apiUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Content-Encoding\": \"gzip\",\n Authorization: `Bearer ${token}`,\n },\n body: compressed,\n });\n\n return resp.status === 200;\n}\n","import type { eventWithTime } from \"rrweb\";\nimport { record } from \"rrweb\";\n\nexport interface SessionRecorderOptions {\n segmentDuration?: number;\n}\n\ninterface Segment {\n events: eventWithTime[];\n startedAt: string;\n}\n\nexport class SessionRecorder {\n private segmentDuration: number;\n private current: Segment;\n private previous: Segment | null = null;\n private stopFn: (() => void) | null = null;\n private rotateInterval: ReturnType<typeof setInterval> | null = null;\n\n constructor(options: SessionRecorderOptions = {}) {\n this.segmentDuration = options.segmentDuration ?? 10_000;\n this.current = { events: [], startedAt: new Date().toISOString() };\n }\n\n start(): void {\n this.stopFn = record({\n emit: (event) => {\n this.onEvent(event);\n },\n });\n\n this.rotateInterval = setInterval(() => {\n this.rotateSegment();\n }, this.segmentDuration);\n }\n\n stop(): void {\n if (this.stopFn) {\n this.stopFn();\n this.stopFn = null;\n }\n if (this.rotateInterval) {\n clearInterval(this.rotateInterval);\n this.rotateInterval = null;\n }\n }\n\n private onEvent(event: eventWithTime): void {\n this.current.events.push(event);\n }\n\n private rotateSegment(): void {\n this.previous = this.current;\n this.current = { events: [], startedAt: new Date().toISOString() };\n record.takeFullSnapshot();\n }\n\n getSegments(): { events: eventWithTime[]; timestamp: string }[] {\n const segments: { events: eventWithTime[]; timestamp: string }[] = [];\n if (this.previous && this.previous.events.length > 0) {\n segments.push({\n events: this.previous.events,\n timestamp: this.previous.startedAt,\n });\n }\n if (this.current.events.length > 0) {\n segments.push({\n events: this.current.events,\n timestamp: this.current.startedAt,\n });\n }\n return segments;\n }\n\n hasSegments(): boolean {\n return (\n this.current.events.length > 0 ||\n (this.previous !== null && this.previous.events.length > 0)\n );\n }\n\n flush(): void {\n this.previous = null;\n this.current = { events: [], startedAt: new Date().toISOString() };\n if (this.stopFn) {\n record.takeFullSnapshot();\n }\n }\n}\n","export function formatBrowserStackTrace(error: Error): string {\n const lines: string[] = [];\n const typeName = error.constructor?.name || \"Error\";\n lines.push(`${typeName}: ${error.message}`);\n\n if (error.stack) {\n const stackLines = error.stack.split(\"\\n\");\n for (const line of stackLines) {\n // V8 format: \" at funcName (file:line:col)\"\n const v8Match = line.match(/^\\s+at\\s+(.+?)\\s+\\((.+):(\\d+):(\\d+)\\)$/);\n if (v8Match) {\n const funcName = shortenFunctionName(v8Match[1]);\n const file = shortenFilePath(v8Match[2]);\n lines.push(`${funcName}()`);\n lines.push(` ${file}:${v8Match[3]}:${v8Match[4]}`);\n continue;\n }\n\n // V8 anonymous: \" at file:line:col\"\n const v8AnonMatch = line.match(/^\\s+at\\s+(.+):(\\d+):(\\d+)$/);\n if (v8AnonMatch) {\n const file = shortenFilePath(v8AnonMatch[1]);\n lines.push(`<anonymous>()`);\n lines.push(` ${file}:${v8AnonMatch[2]}:${v8AnonMatch[3]}`);\n continue;\n }\n\n // Firefox format: \"funcName@file:line:col\"\n const ffMatch = line.match(/^(.+)@(.+):(\\d+):(\\d+)$/);\n if (ffMatch) {\n const funcName = shortenFunctionName(ffMatch[1]) || \"<anonymous>\";\n const file = shortenFilePath(ffMatch[2]);\n lines.push(`${funcName}()`);\n lines.push(` ${file}:${ffMatch[3]}:${ffMatch[4]}`);\n continue;\n }\n\n // Firefox anonymous: \"@file:line:col\"\n const ffAnonMatch = line.match(/^@(.+):(\\d+):(\\d+)$/);\n if (ffAnonMatch) {\n const file = shortenFilePath(ffAnonMatch[1]);\n lines.push(`<anonymous>()`);\n lines.push(` ${file}:${ffAnonMatch[2]}:${ffAnonMatch[3]}`);\n continue;\n }\n }\n }\n\n return lines.join(\"\\n\") + \"\\n\";\n}\n\nfunction shortenFunctionName(fn: string): string {\n const slashIdx = fn.lastIndexOf(\"/\");\n if (slashIdx >= 0) {\n fn = fn.slice(slashIdx + 1);\n }\n const dotIdx = fn.indexOf(\".\");\n if (dotIdx >= 0) {\n fn = fn.slice(dotIdx + 1);\n }\n return fn;\n}\n\nfunction shortenFilePath(filePath: string): string {\n const parts = filePath.split(\"/\");\n return parts[parts.length - 1];\n}\n","import type { TracewayFrontendClient } from \"./client.js\";\nimport { formatBrowserStackTrace } from \"./stack-trace.js\";\nimport { nowISO } from \"@tracewayapp/core\";\nimport { getActiveDistributedTraceId } from \"./fetch-instrumentation.js\";\n\nexport function installGlobalHandlers(client: TracewayFrontendClient): void {\n const prevOnError = window.onerror;\n window.onerror = (message, source, lineno, colno, error) => {\n if (error) {\n client.addException({\n traceId: null,\n stackTrace: formatBrowserStackTrace(error),\n recordedAt: nowISO(),\n isMessage: false,\n distributedTraceId: getActiveDistributedTraceId(),\n });\n } else {\n client.addException({\n traceId: null,\n stackTrace: String(message),\n recordedAt: nowISO(),\n isMessage: false,\n distributedTraceId: getActiveDistributedTraceId(),\n });\n }\n if (typeof prevOnError === \"function\") {\n return prevOnError(message, source, lineno, colno, error);\n }\n return false;\n };\n\n const prevOnUnhandledRejection = window.onunhandledrejection;\n window.onunhandledrejection = (event: PromiseRejectionEvent) => {\n const reason = event.reason;\n if (reason instanceof Error) {\n client.addException({\n traceId: null,\n stackTrace: formatBrowserStackTrace(reason),\n recordedAt: nowISO(),\n isMessage: false,\n distributedTraceId: getActiveDistributedTraceId(),\n });\n } else {\n client.addException({\n traceId: null,\n stackTrace: String(reason),\n recordedAt: nowISO(),\n isMessage: false,\n distributedTraceId: getActiveDistributedTraceId(),\n });\n }\n if (typeof prevOnUnhandledRejection === \"function\") {\n prevOnUnhandledRejection.call(window, event);\n }\n };\n}\n","import { generateUUID } from \"@tracewayapp/core\";\n\nlet activeDistributedTraceId: string | null = null;\n\nexport function getActiveDistributedTraceId(): string | null {\n return activeDistributedTraceId;\n}\n\nfunction isSameOrigin(input: RequestInfo | URL): boolean {\n try {\n const url = new URL(\n typeof input === \"string\"\n ? input\n : input instanceof Request\n ? input.url\n : input.href,\n window.location.origin,\n );\n return url.origin === window.location.origin;\n } catch {\n return true;\n }\n}\n\nexport function installFetchInstrumentation(): void {\n const originalFetch = window.fetch;\n\n window.fetch = function (\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> {\n if (!isSameOrigin(input)) {\n return originalFetch.call(this, input, init);\n }\n\n const traceId = generateUUID();\n activeDistributedTraceId = traceId;\n\n const headers = new Headers(init?.headers);\n headers.set(\"traceway-trace-id\", traceId);\n\n return originalFetch\n .call(this, input, { ...init, headers })\n .finally(() => {\n if (activeDistributedTraceId === traceId) {\n activeDistributedTraceId = null;\n }\n });\n };\n}\n"],"mappings":"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","names":["import_core","import_core","import_core","init","client"]}
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/index.ts
2
- import { nowISO as nowISO2 } from "@tracewayapp/core";
2
+ import { nowISO as nowISO2, generateUUID as generateUUID3 } from "@tracewayapp/core";
3
3
 
4
4
  // src/client.ts
5
5
  import { parseConnectionString, generateUUID } from "@tracewayapp/core";
@@ -301,6 +301,43 @@ function shortenFilePath(filePath) {
301
301
 
302
302
  // src/global-handlers.ts
303
303
  import { nowISO } from "@tracewayapp/core";
304
+
305
+ // src/fetch-instrumentation.ts
306
+ import { generateUUID as generateUUID2 } from "@tracewayapp/core";
307
+ var activeDistributedTraceId = null;
308
+ function getActiveDistributedTraceId() {
309
+ return activeDistributedTraceId;
310
+ }
311
+ function isSameOrigin(input) {
312
+ try {
313
+ const url = new URL(
314
+ typeof input === "string" ? input : input instanceof Request ? input.url : input.href,
315
+ window.location.origin
316
+ );
317
+ return url.origin === window.location.origin;
318
+ } catch {
319
+ return true;
320
+ }
321
+ }
322
+ function installFetchInstrumentation() {
323
+ const originalFetch = window.fetch;
324
+ window.fetch = function(input, init2) {
325
+ if (!isSameOrigin(input)) {
326
+ return originalFetch.call(this, input, init2);
327
+ }
328
+ const traceId = generateUUID2();
329
+ activeDistributedTraceId = traceId;
330
+ const headers = new Headers(init2?.headers);
331
+ headers.set("traceway-trace-id", traceId);
332
+ return originalFetch.call(this, input, { ...init2, headers }).finally(() => {
333
+ if (activeDistributedTraceId === traceId) {
334
+ activeDistributedTraceId = null;
335
+ }
336
+ });
337
+ };
338
+ }
339
+
340
+ // src/global-handlers.ts
304
341
  function installGlobalHandlers(client2) {
305
342
  const prevOnError = window.onerror;
306
343
  window.onerror = (message, source, lineno, colno, error) => {
@@ -309,14 +346,16 @@ function installGlobalHandlers(client2) {
309
346
  traceId: null,
310
347
  stackTrace: formatBrowserStackTrace(error),
311
348
  recordedAt: nowISO(),
312
- isMessage: false
349
+ isMessage: false,
350
+ distributedTraceId: getActiveDistributedTraceId()
313
351
  });
314
352
  } else {
315
353
  client2.addException({
316
354
  traceId: null,
317
355
  stackTrace: String(message),
318
356
  recordedAt: nowISO(),
319
- isMessage: false
357
+ isMessage: false,
358
+ distributedTraceId: getActiveDistributedTraceId()
320
359
  });
321
360
  }
322
361
  if (typeof prevOnError === "function") {
@@ -332,14 +371,16 @@ function installGlobalHandlers(client2) {
332
371
  traceId: null,
333
372
  stackTrace: formatBrowserStackTrace(reason),
334
373
  recordedAt: nowISO(),
335
- isMessage: false
374
+ isMessage: false,
375
+ distributedTraceId: getActiveDistributedTraceId()
336
376
  });
337
377
  } else {
338
378
  client2.addException({
339
379
  traceId: null,
340
380
  stackTrace: String(reason),
341
381
  recordedAt: nowISO(),
342
- isMessage: false
382
+ isMessage: false,
383
+ distributedTraceId: getActiveDistributedTraceId()
343
384
  });
344
385
  }
345
386
  if (typeof prevOnUnhandledRejection === "function") {
@@ -354,25 +395,28 @@ function init(connectionString, options = {}) {
354
395
  client = new TracewayFrontendClient(connectionString, options);
355
396
  if (typeof window !== "undefined") {
356
397
  installGlobalHandlers(client);
398
+ installFetchInstrumentation();
357
399
  }
358
400
  }
359
- function captureException(error) {
401
+ function captureException(error, options) {
360
402
  if (!client) return;
361
403
  client.addException({
362
404
  traceId: null,
363
405
  stackTrace: formatBrowserStackTrace(error),
364
406
  recordedAt: nowISO2(),
365
- isMessage: false
407
+ isMessage: false,
408
+ distributedTraceId: options?.distributedTraceId ?? getActiveDistributedTraceId()
366
409
  });
367
410
  }
368
- function captureExceptionWithAttributes(error, attributes) {
411
+ function captureExceptionWithAttributes(error, attributes, options) {
369
412
  if (!client) return;
370
413
  client.addException({
371
414
  traceId: null,
372
415
  stackTrace: formatBrowserStackTrace(error),
373
416
  recordedAt: nowISO2(),
374
417
  attributes,
375
- isMessage: false
418
+ isMessage: false,
419
+ distributedTraceId: options?.distributedTraceId ?? getActiveDistributedTraceId()
376
420
  });
377
421
  }
378
422
  function captureMessage(msg) {
@@ -388,13 +432,24 @@ async function flush(timeoutMs) {
388
432
  if (!client) return;
389
433
  await client.flush(timeoutMs);
390
434
  }
435
+ var DISTRIBUTED_TRACE_HEADER = "traceway-trace-id";
436
+ function createAxiosInterceptor() {
437
+ return (config) => {
438
+ config.headers = config.headers || {};
439
+ config.headers["traceway-trace-id"] = generateUUID3();
440
+ return config;
441
+ };
442
+ }
391
443
  export {
444
+ DISTRIBUTED_TRACE_HEADER,
392
445
  TracewayFrontendClient,
393
446
  captureException,
394
447
  captureExceptionWithAttributes,
395
448
  captureMessage,
449
+ createAxiosInterceptor,
396
450
  flush,
397
451
  formatBrowserStackTrace,
452
+ getActiveDistributedTraceId,
398
453
  init,
399
454
  installGlobalHandlers
400
455
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/transport.ts","../src/session-recorder.ts","../src/stack-trace.ts","../src/global-handlers.ts"],"sourcesContent":["import { nowISO } from \"@tracewayapp/core\";\nimport type { ExceptionStackTrace } from \"@tracewayapp/core\";\nimport {\n TracewayFrontendClient,\n type TracewayFrontendOptions,\n} from \"./client.js\";\nimport { formatBrowserStackTrace } from \"./stack-trace.js\";\nimport { installGlobalHandlers } from \"./global-handlers.js\";\n\nlet client: TracewayFrontendClient | null = null;\n\nexport function init(\n connectionString: string,\n options: TracewayFrontendOptions = {},\n): void {\n client = new TracewayFrontendClient(connectionString, options);\n if (typeof window !== \"undefined\") {\n installGlobalHandlers(client);\n }\n}\n\nexport function captureException(error: Error): void {\n if (!client) return;\n client.addException({\n traceId: null,\n stackTrace: formatBrowserStackTrace(error),\n recordedAt: nowISO(),\n isMessage: false,\n });\n}\n\nexport function captureExceptionWithAttributes(\n error: Error,\n attributes?: Record<string, string>,\n): void {\n if (!client) return;\n client.addException({\n traceId: null,\n stackTrace: formatBrowserStackTrace(error),\n recordedAt: nowISO(),\n attributes,\n isMessage: false,\n });\n}\n\nexport function captureMessage(msg: string): void {\n if (!client) return;\n client.addException({\n traceId: null,\n stackTrace: msg,\n recordedAt: nowISO(),\n isMessage: true,\n });\n}\n\nexport async function flush(timeoutMs?: number): Promise<void> {\n if (!client) return;\n await client.flush(timeoutMs);\n}\n\nexport { TracewayFrontendClient } from \"./client.js\";\nexport type { TracewayFrontendOptions } from \"./client.js\";\nexport { formatBrowserStackTrace } from \"./stack-trace.js\";\nexport { installGlobalHandlers } from \"./global-handlers.js\";\n\nexport type {\n ExceptionStackTrace,\n CollectionFrame,\n ReportRequest,\n} from \"@tracewayapp/core\";\n","import type {\n ExceptionStackTrace,\n ReportRequest,\n CollectionFrame,\n SessionRecordingPayload,\n} from \"@tracewayapp/core\";\nimport { parseConnectionString, generateUUID } from \"@tracewayapp/core\";\nimport { sendReport } from \"./transport.js\";\nimport { SessionRecorder } from \"./session-recorder.js\";\n\nexport interface TracewayFrontendOptions {\n debug?: boolean;\n debounceMs?: number;\n retryDelayMs?: number;\n version?: string;\n sessionRecording?: boolean;\n sessionRecordingSegmentDuration?: number;\n}\n\nexport class TracewayFrontendClient {\n private apiUrl: string;\n private token: string;\n private debug: boolean;\n private debounceMs: number;\n private retryDelayMs: number;\n private version: string;\n\n private pendingExceptions: ExceptionStackTrace[] = [];\n private pendingRecordings: SessionRecordingPayload[] = [];\n private isSyncing = false;\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n private retryTimer: ReturnType<typeof setTimeout> | null = null;\n\n private recorder: SessionRecorder | null = null;\n\n constructor(connectionString: string, options: TracewayFrontendOptions = {}) {\n const { token, apiUrl } = parseConnectionString(connectionString);\n this.apiUrl = apiUrl;\n this.token = token;\n this.debug = options.debug ?? false;\n this.debounceMs = options.debounceMs ?? 1500;\n this.retryDelayMs = options.retryDelayMs ?? 10000;\n this.version = options.version ?? \"\";\n\n if (options.sessionRecording !== false && typeof window !== \"undefined\") {\n this.recorder = new SessionRecorder({\n segmentDuration: options.sessionRecordingSegmentDuration,\n });\n this.recorder.start();\n }\n }\n\n addException(exception: ExceptionStackTrace): void {\n if (this.recorder && this.recorder.hasSegments()) {\n const segments = this.recorder.getSegments();\n const allEvents = segments.flatMap((s) => s.events);\n const exceptionId = generateUUID();\n exception.sessionRecordingId = exceptionId;\n this.pendingRecordings.push({ exceptionId, events: allEvents });\n }\n\n this.pendingExceptions.push(exception);\n this.scheduleSync();\n }\n\n private scheduleSync(): void {\n if (this.debounceTimer !== null) {\n clearTimeout(this.debounceTimer);\n }\n this.debounceTimer = setTimeout(() => {\n this.debounceTimer = null;\n this.doSync();\n }, this.debounceMs);\n }\n\n private async doSync(): Promise<void> {\n if (this.isSyncing) return;\n if (this.pendingExceptions.length === 0) return;\n\n this.isSyncing = true;\n const batch = this.pendingExceptions.splice(0);\n const recordings = this.pendingRecordings.splice(0);\n\n const frame: CollectionFrame = {\n stackTraces: batch,\n metrics: [],\n traces: [],\n sessionRecordings: recordings.length > 0 ? recordings : undefined,\n };\n\n const payload: ReportRequest = {\n collectionFrames: [frame],\n appVersion: this.version,\n serverName: \"\",\n };\n\n let failed = false;\n try {\n const success = await sendReport(\n this.apiUrl,\n this.token,\n JSON.stringify(payload),\n );\n if (!success) {\n failed = true;\n this.pendingExceptions.unshift(...batch);\n this.pendingRecordings.unshift(...recordings);\n if (this.debug) {\n console.error(\"Traceway: sync failed, re-queued exceptions\");\n }\n }\n } catch (err) {\n failed = true;\n this.pendingExceptions.unshift(...batch);\n this.pendingRecordings.unshift(...recordings);\n if (this.debug) {\n console.error(\"Traceway: sync error:\", err);\n }\n } finally {\n this.isSyncing = false;\n if (this.pendingExceptions.length > 0) {\n if (failed) {\n this.scheduleRetry();\n } else {\n this.doSync();\n }\n }\n }\n }\n\n private scheduleRetry(): void {\n if (this.retryTimer !== null) return;\n this.retryTimer = setTimeout(() => {\n this.retryTimer = null;\n this.doSync();\n }, this.retryDelayMs);\n }\n\n async flush(timeoutMs?: number): Promise<void> {\n if (this.debounceTimer !== null) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n if (this.retryTimer !== null) {\n clearTimeout(this.retryTimer);\n this.retryTimer = null;\n }\n if (this.recorder) {\n this.recorder.stop();\n }\n\n const syncPromise = this.doSync();\n\n if (timeoutMs !== undefined) {\n await Promise.race([\n syncPromise,\n new Promise<void>((resolve) => setTimeout(resolve, timeoutMs)),\n ]);\n } else {\n await syncPromise;\n }\n }\n}\n","export async function compressGzip(data: string): Promise<Uint8Array> {\n const encoder = new TextEncoder();\n const inputBytes = encoder.encode(data);\n\n const cs = new CompressionStream(\"gzip\");\n const writer = cs.writable.getWriter();\n writer.write(inputBytes);\n writer.close();\n\n const reader = cs.readable.getReader();\n const chunks: Uint8Array[] = [];\n let totalLength = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n totalLength += value.length;\n }\n\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n\n return result;\n}\n\nexport async function sendReport(\n apiUrl: string,\n token: string,\n body: string,\n): Promise<boolean> {\n const compressed = await compressGzip(body);\n\n const resp = await fetch(apiUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Content-Encoding\": \"gzip\",\n Authorization: `Bearer ${token}`,\n },\n body: compressed,\n });\n\n return resp.status === 200;\n}\n","import type { eventWithTime } from \"rrweb\";\nimport { record } from \"rrweb\";\n\nexport interface SessionRecorderOptions {\n segmentDuration?: number;\n}\n\ninterface Segment {\n events: eventWithTime[];\n startedAt: string;\n}\n\nexport class SessionRecorder {\n private segmentDuration: number;\n private current: Segment;\n private previous: Segment | null = null;\n private stopFn: (() => void) | null = null;\n private rotateInterval: ReturnType<typeof setInterval> | null = null;\n\n constructor(options: SessionRecorderOptions = {}) {\n this.segmentDuration = options.segmentDuration ?? 10_000;\n this.current = { events: [], startedAt: new Date().toISOString() };\n }\n\n start(): void {\n this.stopFn = record({\n emit: (event) => {\n this.onEvent(event);\n },\n });\n\n this.rotateInterval = setInterval(() => {\n this.rotateSegment();\n }, this.segmentDuration);\n }\n\n stop(): void {\n if (this.stopFn) {\n this.stopFn();\n this.stopFn = null;\n }\n if (this.rotateInterval) {\n clearInterval(this.rotateInterval);\n this.rotateInterval = null;\n }\n }\n\n private onEvent(event: eventWithTime): void {\n this.current.events.push(event);\n }\n\n private rotateSegment(): void {\n this.previous = this.current;\n this.current = { events: [], startedAt: new Date().toISOString() };\n record.takeFullSnapshot();\n }\n\n getSegments(): { events: eventWithTime[]; timestamp: string }[] {\n const segments: { events: eventWithTime[]; timestamp: string }[] = [];\n if (this.previous && this.previous.events.length > 0) {\n segments.push({\n events: this.previous.events,\n timestamp: this.previous.startedAt,\n });\n }\n if (this.current.events.length > 0) {\n segments.push({\n events: this.current.events,\n timestamp: this.current.startedAt,\n });\n }\n return segments;\n }\n\n hasSegments(): boolean {\n return (\n this.current.events.length > 0 ||\n (this.previous !== null && this.previous.events.length > 0)\n );\n }\n\n flush(): void {\n this.previous = null;\n this.current = { events: [], startedAt: new Date().toISOString() };\n if (this.stopFn) {\n record.takeFullSnapshot();\n }\n }\n}\n","export function formatBrowserStackTrace(error: Error): string {\n const lines: string[] = [];\n const typeName = error.constructor?.name || \"Error\";\n lines.push(`${typeName}: ${error.message}`);\n\n if (error.stack) {\n const stackLines = error.stack.split(\"\\n\");\n for (const line of stackLines) {\n // V8 format: \" at funcName (file:line:col)\"\n const v8Match = line.match(/^\\s+at\\s+(.+?)\\s+\\((.+):(\\d+):(\\d+)\\)$/);\n if (v8Match) {\n const funcName = shortenFunctionName(v8Match[1]);\n const file = shortenFilePath(v8Match[2]);\n lines.push(`${funcName}()`);\n lines.push(` ${file}:${v8Match[3]}:${v8Match[4]}`);\n continue;\n }\n\n // V8 anonymous: \" at file:line:col\"\n const v8AnonMatch = line.match(/^\\s+at\\s+(.+):(\\d+):(\\d+)$/);\n if (v8AnonMatch) {\n const file = shortenFilePath(v8AnonMatch[1]);\n lines.push(`<anonymous>()`);\n lines.push(` ${file}:${v8AnonMatch[2]}:${v8AnonMatch[3]}`);\n continue;\n }\n\n // Firefox format: \"funcName@file:line:col\"\n const ffMatch = line.match(/^(.+)@(.+):(\\d+):(\\d+)$/);\n if (ffMatch) {\n const funcName = shortenFunctionName(ffMatch[1]) || \"<anonymous>\";\n const file = shortenFilePath(ffMatch[2]);\n lines.push(`${funcName}()`);\n lines.push(` ${file}:${ffMatch[3]}:${ffMatch[4]}`);\n continue;\n }\n\n // Firefox anonymous: \"@file:line:col\"\n const ffAnonMatch = line.match(/^@(.+):(\\d+):(\\d+)$/);\n if (ffAnonMatch) {\n const file = shortenFilePath(ffAnonMatch[1]);\n lines.push(`<anonymous>()`);\n lines.push(` ${file}:${ffAnonMatch[2]}:${ffAnonMatch[3]}`);\n continue;\n }\n }\n }\n\n return lines.join(\"\\n\") + \"\\n\";\n}\n\nfunction shortenFunctionName(fn: string): string {\n const slashIdx = fn.lastIndexOf(\"/\");\n if (slashIdx >= 0) {\n fn = fn.slice(slashIdx + 1);\n }\n const dotIdx = fn.indexOf(\".\");\n if (dotIdx >= 0) {\n fn = fn.slice(dotIdx + 1);\n }\n return fn;\n}\n\nfunction shortenFilePath(filePath: string): string {\n const parts = filePath.split(\"/\");\n return parts[parts.length - 1];\n}\n","import type { TracewayFrontendClient } from \"./client.js\";\nimport { formatBrowserStackTrace } from \"./stack-trace.js\";\nimport { nowISO } from \"@tracewayapp/core\";\n\nexport function installGlobalHandlers(client: TracewayFrontendClient): void {\n const prevOnError = window.onerror;\n window.onerror = (message, source, lineno, colno, error) => {\n if (error) {\n client.addException({\n traceId: null,\n stackTrace: formatBrowserStackTrace(error),\n recordedAt: nowISO(),\n isMessage: false,\n });\n } else {\n client.addException({\n traceId: null,\n stackTrace: String(message),\n recordedAt: nowISO(),\n isMessage: false,\n });\n }\n if (typeof prevOnError === \"function\") {\n return prevOnError(message, source, lineno, colno, error);\n }\n return false;\n };\n\n const prevOnUnhandledRejection = window.onunhandledrejection;\n window.onunhandledrejection = (event: PromiseRejectionEvent) => {\n const reason = event.reason;\n if (reason instanceof Error) {\n client.addException({\n traceId: null,\n stackTrace: formatBrowserStackTrace(reason),\n recordedAt: nowISO(),\n isMessage: false,\n });\n } else {\n client.addException({\n traceId: null,\n stackTrace: String(reason),\n recordedAt: nowISO(),\n isMessage: false,\n });\n }\n if (typeof prevOnUnhandledRejection === \"function\") {\n prevOnUnhandledRejection.call(window, event);\n }\n };\n}\n"],"mappings":"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","names":["nowISO","client","nowISO"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/transport.ts","../src/session-recorder.ts","../src/stack-trace.ts","../src/global-handlers.ts","../src/fetch-instrumentation.ts"],"sourcesContent":["import { nowISO, generateUUID } from \"@tracewayapp/core\";\nimport type { ExceptionStackTrace } from \"@tracewayapp/core\";\nimport {\n TracewayFrontendClient,\n type TracewayFrontendOptions,\n} from \"./client.js\";\nimport { formatBrowserStackTrace } from \"./stack-trace.js\";\nimport { installGlobalHandlers } from \"./global-handlers.js\";\nimport {\n installFetchInstrumentation,\n getActiveDistributedTraceId,\n} from \"./fetch-instrumentation.js\";\n\nlet client: TracewayFrontendClient | null = null;\n\nexport function init(\n connectionString: string,\n options: TracewayFrontendOptions = {},\n): void {\n client = new TracewayFrontendClient(connectionString, options);\n if (typeof window !== \"undefined\") {\n installGlobalHandlers(client);\n installFetchInstrumentation();\n }\n}\n\nexport function captureException(\n error: Error,\n options?: { distributedTraceId?: string },\n): void {\n if (!client) return;\n client.addException({\n traceId: null,\n stackTrace: formatBrowserStackTrace(error),\n recordedAt: nowISO(),\n isMessage: false,\n distributedTraceId:\n options?.distributedTraceId ?? getActiveDistributedTraceId(),\n });\n}\n\nexport function captureExceptionWithAttributes(\n error: Error,\n attributes?: Record<string, string>,\n options?: { distributedTraceId?: string },\n): void {\n if (!client) return;\n client.addException({\n traceId: null,\n stackTrace: formatBrowserStackTrace(error),\n recordedAt: nowISO(),\n attributes,\n isMessage: false,\n distributedTraceId:\n options?.distributedTraceId ?? getActiveDistributedTraceId(),\n });\n}\n\nexport function captureMessage(msg: string): void {\n if (!client) return;\n client.addException({\n traceId: null,\n stackTrace: msg,\n recordedAt: nowISO(),\n isMessage: true,\n });\n}\n\nexport async function flush(timeoutMs?: number): Promise<void> {\n if (!client) return;\n await client.flush(timeoutMs);\n}\n\nexport { TracewayFrontendClient } from \"./client.js\";\nexport type { TracewayFrontendOptions } from \"./client.js\";\nexport { formatBrowserStackTrace } from \"./stack-trace.js\";\nexport { installGlobalHandlers } from \"./global-handlers.js\";\n\nexport type {\n ExceptionStackTrace,\n CollectionFrame,\n ReportRequest,\n} from \"@tracewayapp/core\";\n\nexport const DISTRIBUTED_TRACE_HEADER = \"traceway-trace-id\";\n\nexport { getActiveDistributedTraceId } from \"./fetch-instrumentation.js\";\n\nexport function createAxiosInterceptor() {\n return (config: any) => {\n config.headers = config.headers || {};\n config.headers[\"traceway-trace-id\"] = generateUUID();\n return config;\n };\n}\n","import type {\n ExceptionStackTrace,\n ReportRequest,\n CollectionFrame,\n SessionRecordingPayload,\n} from \"@tracewayapp/core\";\nimport { parseConnectionString, generateUUID } from \"@tracewayapp/core\";\nimport { sendReport } from \"./transport.js\";\nimport { SessionRecorder } from \"./session-recorder.js\";\n\nexport interface TracewayFrontendOptions {\n debug?: boolean;\n debounceMs?: number;\n retryDelayMs?: number;\n version?: string;\n sessionRecording?: boolean;\n sessionRecordingSegmentDuration?: number;\n}\n\nexport class TracewayFrontendClient {\n private apiUrl: string;\n private token: string;\n private debug: boolean;\n private debounceMs: number;\n private retryDelayMs: number;\n private version: string;\n\n private pendingExceptions: ExceptionStackTrace[] = [];\n private pendingRecordings: SessionRecordingPayload[] = [];\n private isSyncing = false;\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n private retryTimer: ReturnType<typeof setTimeout> | null = null;\n\n private recorder: SessionRecorder | null = null;\n\n constructor(connectionString: string, options: TracewayFrontendOptions = {}) {\n const { token, apiUrl } = parseConnectionString(connectionString);\n this.apiUrl = apiUrl;\n this.token = token;\n this.debug = options.debug ?? false;\n this.debounceMs = options.debounceMs ?? 1500;\n this.retryDelayMs = options.retryDelayMs ?? 10000;\n this.version = options.version ?? \"\";\n\n if (options.sessionRecording !== false && typeof window !== \"undefined\") {\n this.recorder = new SessionRecorder({\n segmentDuration: options.sessionRecordingSegmentDuration,\n });\n this.recorder.start();\n }\n }\n\n addException(exception: ExceptionStackTrace): void {\n if (this.recorder && this.recorder.hasSegments()) {\n const segments = this.recorder.getSegments();\n const allEvents = segments.flatMap((s) => s.events);\n const exceptionId = generateUUID();\n exception.sessionRecordingId = exceptionId;\n this.pendingRecordings.push({ exceptionId, events: allEvents });\n }\n\n this.pendingExceptions.push(exception);\n this.scheduleSync();\n }\n\n private scheduleSync(): void {\n if (this.debounceTimer !== null) {\n clearTimeout(this.debounceTimer);\n }\n this.debounceTimer = setTimeout(() => {\n this.debounceTimer = null;\n this.doSync();\n }, this.debounceMs);\n }\n\n private async doSync(): Promise<void> {\n if (this.isSyncing) return;\n if (this.pendingExceptions.length === 0) return;\n\n this.isSyncing = true;\n const batch = this.pendingExceptions.splice(0);\n const recordings = this.pendingRecordings.splice(0);\n\n const frame: CollectionFrame = {\n stackTraces: batch,\n metrics: [],\n traces: [],\n sessionRecordings: recordings.length > 0 ? recordings : undefined,\n };\n\n const payload: ReportRequest = {\n collectionFrames: [frame],\n appVersion: this.version,\n serverName: \"\",\n };\n\n let failed = false;\n try {\n const success = await sendReport(\n this.apiUrl,\n this.token,\n JSON.stringify(payload),\n );\n if (!success) {\n failed = true;\n this.pendingExceptions.unshift(...batch);\n this.pendingRecordings.unshift(...recordings);\n if (this.debug) {\n console.error(\"Traceway: sync failed, re-queued exceptions\");\n }\n }\n } catch (err) {\n failed = true;\n this.pendingExceptions.unshift(...batch);\n this.pendingRecordings.unshift(...recordings);\n if (this.debug) {\n console.error(\"Traceway: sync error:\", err);\n }\n } finally {\n this.isSyncing = false;\n if (this.pendingExceptions.length > 0) {\n if (failed) {\n this.scheduleRetry();\n } else {\n this.doSync();\n }\n }\n }\n }\n\n private scheduleRetry(): void {\n if (this.retryTimer !== null) return;\n this.retryTimer = setTimeout(() => {\n this.retryTimer = null;\n this.doSync();\n }, this.retryDelayMs);\n }\n\n async flush(timeoutMs?: number): Promise<void> {\n if (this.debounceTimer !== null) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n if (this.retryTimer !== null) {\n clearTimeout(this.retryTimer);\n this.retryTimer = null;\n }\n if (this.recorder) {\n this.recorder.stop();\n }\n\n const syncPromise = this.doSync();\n\n if (timeoutMs !== undefined) {\n await Promise.race([\n syncPromise,\n new Promise<void>((resolve) => setTimeout(resolve, timeoutMs)),\n ]);\n } else {\n await syncPromise;\n }\n }\n}\n","export async function compressGzip(data: string): Promise<Uint8Array> {\n const encoder = new TextEncoder();\n const inputBytes = encoder.encode(data);\n\n const cs = new CompressionStream(\"gzip\");\n const writer = cs.writable.getWriter();\n writer.write(inputBytes);\n writer.close();\n\n const reader = cs.readable.getReader();\n const chunks: Uint8Array[] = [];\n let totalLength = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n totalLength += value.length;\n }\n\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n\n return result;\n}\n\nexport async function sendReport(\n apiUrl: string,\n token: string,\n body: string,\n): Promise<boolean> {\n const compressed = await compressGzip(body);\n\n const resp = await fetch(apiUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Content-Encoding\": \"gzip\",\n Authorization: `Bearer ${token}`,\n },\n body: compressed,\n });\n\n return resp.status === 200;\n}\n","import type { eventWithTime } from \"rrweb\";\nimport { record } from \"rrweb\";\n\nexport interface SessionRecorderOptions {\n segmentDuration?: number;\n}\n\ninterface Segment {\n events: eventWithTime[];\n startedAt: string;\n}\n\nexport class SessionRecorder {\n private segmentDuration: number;\n private current: Segment;\n private previous: Segment | null = null;\n private stopFn: (() => void) | null = null;\n private rotateInterval: ReturnType<typeof setInterval> | null = null;\n\n constructor(options: SessionRecorderOptions = {}) {\n this.segmentDuration = options.segmentDuration ?? 10_000;\n this.current = { events: [], startedAt: new Date().toISOString() };\n }\n\n start(): void {\n this.stopFn = record({\n emit: (event) => {\n this.onEvent(event);\n },\n });\n\n this.rotateInterval = setInterval(() => {\n this.rotateSegment();\n }, this.segmentDuration);\n }\n\n stop(): void {\n if (this.stopFn) {\n this.stopFn();\n this.stopFn = null;\n }\n if (this.rotateInterval) {\n clearInterval(this.rotateInterval);\n this.rotateInterval = null;\n }\n }\n\n private onEvent(event: eventWithTime): void {\n this.current.events.push(event);\n }\n\n private rotateSegment(): void {\n this.previous = this.current;\n this.current = { events: [], startedAt: new Date().toISOString() };\n record.takeFullSnapshot();\n }\n\n getSegments(): { events: eventWithTime[]; timestamp: string }[] {\n const segments: { events: eventWithTime[]; timestamp: string }[] = [];\n if (this.previous && this.previous.events.length > 0) {\n segments.push({\n events: this.previous.events,\n timestamp: this.previous.startedAt,\n });\n }\n if (this.current.events.length > 0) {\n segments.push({\n events: this.current.events,\n timestamp: this.current.startedAt,\n });\n }\n return segments;\n }\n\n hasSegments(): boolean {\n return (\n this.current.events.length > 0 ||\n (this.previous !== null && this.previous.events.length > 0)\n );\n }\n\n flush(): void {\n this.previous = null;\n this.current = { events: [], startedAt: new Date().toISOString() };\n if (this.stopFn) {\n record.takeFullSnapshot();\n }\n }\n}\n","export function formatBrowserStackTrace(error: Error): string {\n const lines: string[] = [];\n const typeName = error.constructor?.name || \"Error\";\n lines.push(`${typeName}: ${error.message}`);\n\n if (error.stack) {\n const stackLines = error.stack.split(\"\\n\");\n for (const line of stackLines) {\n // V8 format: \" at funcName (file:line:col)\"\n const v8Match = line.match(/^\\s+at\\s+(.+?)\\s+\\((.+):(\\d+):(\\d+)\\)$/);\n if (v8Match) {\n const funcName = shortenFunctionName(v8Match[1]);\n const file = shortenFilePath(v8Match[2]);\n lines.push(`${funcName}()`);\n lines.push(` ${file}:${v8Match[3]}:${v8Match[4]}`);\n continue;\n }\n\n // V8 anonymous: \" at file:line:col\"\n const v8AnonMatch = line.match(/^\\s+at\\s+(.+):(\\d+):(\\d+)$/);\n if (v8AnonMatch) {\n const file = shortenFilePath(v8AnonMatch[1]);\n lines.push(`<anonymous>()`);\n lines.push(` ${file}:${v8AnonMatch[2]}:${v8AnonMatch[3]}`);\n continue;\n }\n\n // Firefox format: \"funcName@file:line:col\"\n const ffMatch = line.match(/^(.+)@(.+):(\\d+):(\\d+)$/);\n if (ffMatch) {\n const funcName = shortenFunctionName(ffMatch[1]) || \"<anonymous>\";\n const file = shortenFilePath(ffMatch[2]);\n lines.push(`${funcName}()`);\n lines.push(` ${file}:${ffMatch[3]}:${ffMatch[4]}`);\n continue;\n }\n\n // Firefox anonymous: \"@file:line:col\"\n const ffAnonMatch = line.match(/^@(.+):(\\d+):(\\d+)$/);\n if (ffAnonMatch) {\n const file = shortenFilePath(ffAnonMatch[1]);\n lines.push(`<anonymous>()`);\n lines.push(` ${file}:${ffAnonMatch[2]}:${ffAnonMatch[3]}`);\n continue;\n }\n }\n }\n\n return lines.join(\"\\n\") + \"\\n\";\n}\n\nfunction shortenFunctionName(fn: string): string {\n const slashIdx = fn.lastIndexOf(\"/\");\n if (slashIdx >= 0) {\n fn = fn.slice(slashIdx + 1);\n }\n const dotIdx = fn.indexOf(\".\");\n if (dotIdx >= 0) {\n fn = fn.slice(dotIdx + 1);\n }\n return fn;\n}\n\nfunction shortenFilePath(filePath: string): string {\n const parts = filePath.split(\"/\");\n return parts[parts.length - 1];\n}\n","import type { TracewayFrontendClient } from \"./client.js\";\nimport { formatBrowserStackTrace } from \"./stack-trace.js\";\nimport { nowISO } from \"@tracewayapp/core\";\nimport { getActiveDistributedTraceId } from \"./fetch-instrumentation.js\";\n\nexport function installGlobalHandlers(client: TracewayFrontendClient): void {\n const prevOnError = window.onerror;\n window.onerror = (message, source, lineno, colno, error) => {\n if (error) {\n client.addException({\n traceId: null,\n stackTrace: formatBrowserStackTrace(error),\n recordedAt: nowISO(),\n isMessage: false,\n distributedTraceId: getActiveDistributedTraceId(),\n });\n } else {\n client.addException({\n traceId: null,\n stackTrace: String(message),\n recordedAt: nowISO(),\n isMessage: false,\n distributedTraceId: getActiveDistributedTraceId(),\n });\n }\n if (typeof prevOnError === \"function\") {\n return prevOnError(message, source, lineno, colno, error);\n }\n return false;\n };\n\n const prevOnUnhandledRejection = window.onunhandledrejection;\n window.onunhandledrejection = (event: PromiseRejectionEvent) => {\n const reason = event.reason;\n if (reason instanceof Error) {\n client.addException({\n traceId: null,\n stackTrace: formatBrowserStackTrace(reason),\n recordedAt: nowISO(),\n isMessage: false,\n distributedTraceId: getActiveDistributedTraceId(),\n });\n } else {\n client.addException({\n traceId: null,\n stackTrace: String(reason),\n recordedAt: nowISO(),\n isMessage: false,\n distributedTraceId: getActiveDistributedTraceId(),\n });\n }\n if (typeof prevOnUnhandledRejection === \"function\") {\n prevOnUnhandledRejection.call(window, event);\n }\n };\n}\n","import { generateUUID } from \"@tracewayapp/core\";\n\nlet activeDistributedTraceId: string | null = null;\n\nexport function getActiveDistributedTraceId(): string | null {\n return activeDistributedTraceId;\n}\n\nfunction isSameOrigin(input: RequestInfo | URL): boolean {\n try {\n const url = new URL(\n typeof input === \"string\"\n ? input\n : input instanceof Request\n ? input.url\n : input.href,\n window.location.origin,\n );\n return url.origin === window.location.origin;\n } catch {\n return true;\n }\n}\n\nexport function installFetchInstrumentation(): void {\n const originalFetch = window.fetch;\n\n window.fetch = function (\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> {\n if (!isSameOrigin(input)) {\n return originalFetch.call(this, input, init);\n }\n\n const traceId = generateUUID();\n activeDistributedTraceId = traceId;\n\n const headers = new Headers(init?.headers);\n headers.set(\"traceway-trace-id\", traceId);\n\n return originalFetch\n .call(this, input, { ...init, headers })\n .finally(() => {\n if (activeDistributedTraceId === traceId) {\n activeDistributedTraceId = null;\n }\n });\n };\n}\n"],"mappings":"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","names":["nowISO","generateUUID","generateUUID","init","client","nowISO","generateUUID"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tracewayapp/frontend",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Traceway SDK for browser environments",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -23,7 +23,7 @@
23
23
  "dev": "tsup --watch"
24
24
  },
25
25
  "dependencies": {
26
- "@tracewayapp/core": "1.0.1",
26
+ "@tracewayapp/core": "1.0.2",
27
27
  "rrweb": "^2.0.0-alpha.18"
28
28
  }
29
29
  }