@tracewayapp/frontend 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +50 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +47 -2
- package/dist/index.mjs.map +1 -1
- package/dist/traceway.iife.global.js +75 -0
- package/dist/traceway.iife.global.js.map +1 -0
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -33,7 +33,7 @@ __export(index_exports, {
|
|
|
33
33
|
installGlobalHandlers: () => installGlobalHandlers
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(index_exports);
|
|
36
|
-
var
|
|
36
|
+
var import_core5 = require("@tracewayapp/core");
|
|
37
37
|
|
|
38
38
|
// src/client.ts
|
|
39
39
|
var import_core = require("@tracewayapp/core");
|
|
@@ -342,6 +342,14 @@ var activeDistributedTraceId = null;
|
|
|
342
342
|
function getActiveDistributedTraceId() {
|
|
343
343
|
return activeDistributedTraceId;
|
|
344
344
|
}
|
|
345
|
+
function setActiveDistributedTraceId(id) {
|
|
346
|
+
activeDistributedTraceId = id;
|
|
347
|
+
}
|
|
348
|
+
function clearActiveDistributedTraceId(traceId) {
|
|
349
|
+
if (activeDistributedTraceId === traceId) {
|
|
350
|
+
activeDistributedTraceId = null;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
345
353
|
function isSameOrigin(input) {
|
|
346
354
|
try {
|
|
347
355
|
const url = new URL(
|
|
@@ -423,6 +431,42 @@ function installGlobalHandlers(client2) {
|
|
|
423
431
|
};
|
|
424
432
|
}
|
|
425
433
|
|
|
434
|
+
// src/xhr-instrumentation.ts
|
|
435
|
+
var import_core4 = require("@tracewayapp/core");
|
|
436
|
+
function isSameOriginUrl(url) {
|
|
437
|
+
try {
|
|
438
|
+
const resolved = new URL(url, window.location.origin);
|
|
439
|
+
return resolved.origin === window.location.origin;
|
|
440
|
+
} catch {
|
|
441
|
+
return true;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
function installXhrInstrumentation() {
|
|
445
|
+
const originalOpen = XMLHttpRequest.prototype.open;
|
|
446
|
+
const originalSend = XMLHttpRequest.prototype.send;
|
|
447
|
+
XMLHttpRequest.prototype.open = function(method, url, ...rest) {
|
|
448
|
+
this._tracewaySameOrigin = isSameOriginUrl(String(url));
|
|
449
|
+
return originalOpen.apply(this, [method, url, ...rest]);
|
|
450
|
+
};
|
|
451
|
+
XMLHttpRequest.prototype.send = function(body) {
|
|
452
|
+
if (this._tracewaySameOrigin) {
|
|
453
|
+
const traceId = (0, import_core4.generateUUID)();
|
|
454
|
+
setActiveDistributedTraceId(traceId);
|
|
455
|
+
this.setRequestHeader("traceway-trace-id", traceId);
|
|
456
|
+
const onComplete = () => {
|
|
457
|
+
clearActiveDistributedTraceId(traceId);
|
|
458
|
+
this.removeEventListener("load", onComplete);
|
|
459
|
+
this.removeEventListener("error", onComplete);
|
|
460
|
+
this.removeEventListener("abort", onComplete);
|
|
461
|
+
};
|
|
462
|
+
this.addEventListener("load", onComplete);
|
|
463
|
+
this.addEventListener("error", onComplete);
|
|
464
|
+
this.addEventListener("abort", onComplete);
|
|
465
|
+
}
|
|
466
|
+
return originalSend.call(this, body);
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
|
|
426
470
|
// src/index.ts
|
|
427
471
|
var client = null;
|
|
428
472
|
function init(connectionString, options = {}) {
|
|
@@ -430,6 +474,7 @@ function init(connectionString, options = {}) {
|
|
|
430
474
|
if (typeof window !== "undefined") {
|
|
431
475
|
installGlobalHandlers(client);
|
|
432
476
|
installFetchInstrumentation();
|
|
477
|
+
installXhrInstrumentation();
|
|
433
478
|
}
|
|
434
479
|
}
|
|
435
480
|
function captureException(error, options) {
|
|
@@ -437,7 +482,7 @@ function captureException(error, options) {
|
|
|
437
482
|
client.addException({
|
|
438
483
|
traceId: null,
|
|
439
484
|
stackTrace: formatBrowserStackTrace(error),
|
|
440
|
-
recordedAt: (0,
|
|
485
|
+
recordedAt: (0, import_core5.nowISO)(),
|
|
441
486
|
isMessage: false,
|
|
442
487
|
distributedTraceId: options?.distributedTraceId ?? getActiveDistributedTraceId()
|
|
443
488
|
});
|
|
@@ -447,7 +492,7 @@ function captureExceptionWithAttributes(error, attributes, options) {
|
|
|
447
492
|
client.addException({
|
|
448
493
|
traceId: null,
|
|
449
494
|
stackTrace: formatBrowserStackTrace(error),
|
|
450
|
-
recordedAt: (0,
|
|
495
|
+
recordedAt: (0, import_core5.nowISO)(),
|
|
451
496
|
attributes,
|
|
452
497
|
isMessage: false,
|
|
453
498
|
distributedTraceId: options?.distributedTraceId ?? getActiveDistributedTraceId()
|
|
@@ -458,7 +503,7 @@ function captureMessage(msg) {
|
|
|
458
503
|
client.addException({
|
|
459
504
|
traceId: null,
|
|
460
505
|
stackTrace: msg,
|
|
461
|
-
recordedAt: (0,
|
|
506
|
+
recordedAt: (0, import_core5.nowISO)(),
|
|
462
507
|
isMessage: true
|
|
463
508
|
});
|
|
464
509
|
}
|
|
@@ -470,7 +515,7 @@ var DISTRIBUTED_TRACE_HEADER = "traceway-trace-id";
|
|
|
470
515
|
function createAxiosInterceptor() {
|
|
471
516
|
return (config) => {
|
|
472
517
|
config.headers = config.headers || {};
|
|
473
|
-
config.headers["traceway-trace-id"] = (0,
|
|
518
|
+
config.headers["traceway-trace-id"] = (0, import_core5.generateUUID)();
|
|
474
519
|
return config;
|
|
475
520
|
};
|
|
476
521
|
}
|
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","../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"]}
|
|
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","../src/xhr-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\";\nimport { installXhrInstrumentation } from \"./xhr-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 installXhrInstrumentation();\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\nexport function setActiveDistributedTraceId(id: string | null): void {\n activeDistributedTraceId = id;\n}\n\nexport function clearActiveDistributedTraceId(traceId: string): void {\n if (activeDistributedTraceId === traceId) {\n activeDistributedTraceId = null;\n }\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","import { generateUUID } from \"@tracewayapp/core\";\nimport {\n setActiveDistributedTraceId,\n clearActiveDistributedTraceId,\n} from \"./fetch-instrumentation.js\";\n\nfunction isSameOriginUrl(url: string): boolean {\n try {\n const resolved = new URL(url, window.location.origin);\n return resolved.origin === window.location.origin;\n } catch {\n return true;\n }\n}\n\ninterface TracewayXHR extends XMLHttpRequest {\n _tracewaySameOrigin?: boolean;\n}\n\nexport function installXhrInstrumentation(): void {\n const originalOpen = XMLHttpRequest.prototype.open;\n const originalSend = XMLHttpRequest.prototype.send;\n\n XMLHttpRequest.prototype.open = function (\n this: TracewayXHR,\n method: string,\n url: string | URL,\n ...rest: any[]\n ) {\n this._tracewaySameOrigin = isSameOriginUrl(String(url));\n return originalOpen.apply(this, [method, url, ...rest] as any);\n };\n\n XMLHttpRequest.prototype.send = function (\n this: TracewayXHR,\n body?: Document | XMLHttpRequestBodyInit | null,\n ) {\n if (this._tracewaySameOrigin) {\n const traceId = generateUUID();\n setActiveDistributedTraceId(traceId);\n this.setRequestHeader(\"traceway-trace-id\", traceId);\n\n const onComplete = () => {\n clearActiveDistributedTraceId(traceId);\n this.removeEventListener(\"load\", onComplete);\n this.removeEventListener(\"error\", onComplete);\n this.removeEventListener(\"abort\", onComplete);\n };\n this.addEventListener(\"load\", onComplete);\n this.addEventListener(\"error\", onComplete);\n this.addEventListener(\"abort\", onComplete);\n }\n return originalSend.call(this, body);\n };\n}\n"],"mappings":"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","names":["import_core","import_core","import_core","init","client","import_core"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
import { nowISO as nowISO2, generateUUID as
|
|
2
|
+
import { nowISO as nowISO2, generateUUID as generateUUID4 } from "@tracewayapp/core";
|
|
3
3
|
|
|
4
4
|
// src/client.ts
|
|
5
5
|
import { parseConnectionString, generateUUID } from "@tracewayapp/core";
|
|
@@ -308,6 +308,14 @@ var activeDistributedTraceId = null;
|
|
|
308
308
|
function getActiveDistributedTraceId() {
|
|
309
309
|
return activeDistributedTraceId;
|
|
310
310
|
}
|
|
311
|
+
function setActiveDistributedTraceId(id) {
|
|
312
|
+
activeDistributedTraceId = id;
|
|
313
|
+
}
|
|
314
|
+
function clearActiveDistributedTraceId(traceId) {
|
|
315
|
+
if (activeDistributedTraceId === traceId) {
|
|
316
|
+
activeDistributedTraceId = null;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
311
319
|
function isSameOrigin(input) {
|
|
312
320
|
try {
|
|
313
321
|
const url = new URL(
|
|
@@ -389,6 +397,42 @@ function installGlobalHandlers(client2) {
|
|
|
389
397
|
};
|
|
390
398
|
}
|
|
391
399
|
|
|
400
|
+
// src/xhr-instrumentation.ts
|
|
401
|
+
import { generateUUID as generateUUID3 } from "@tracewayapp/core";
|
|
402
|
+
function isSameOriginUrl(url) {
|
|
403
|
+
try {
|
|
404
|
+
const resolved = new URL(url, window.location.origin);
|
|
405
|
+
return resolved.origin === window.location.origin;
|
|
406
|
+
} catch {
|
|
407
|
+
return true;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
function installXhrInstrumentation() {
|
|
411
|
+
const originalOpen = XMLHttpRequest.prototype.open;
|
|
412
|
+
const originalSend = XMLHttpRequest.prototype.send;
|
|
413
|
+
XMLHttpRequest.prototype.open = function(method, url, ...rest) {
|
|
414
|
+
this._tracewaySameOrigin = isSameOriginUrl(String(url));
|
|
415
|
+
return originalOpen.apply(this, [method, url, ...rest]);
|
|
416
|
+
};
|
|
417
|
+
XMLHttpRequest.prototype.send = function(body) {
|
|
418
|
+
if (this._tracewaySameOrigin) {
|
|
419
|
+
const traceId = generateUUID3();
|
|
420
|
+
setActiveDistributedTraceId(traceId);
|
|
421
|
+
this.setRequestHeader("traceway-trace-id", traceId);
|
|
422
|
+
const onComplete = () => {
|
|
423
|
+
clearActiveDistributedTraceId(traceId);
|
|
424
|
+
this.removeEventListener("load", onComplete);
|
|
425
|
+
this.removeEventListener("error", onComplete);
|
|
426
|
+
this.removeEventListener("abort", onComplete);
|
|
427
|
+
};
|
|
428
|
+
this.addEventListener("load", onComplete);
|
|
429
|
+
this.addEventListener("error", onComplete);
|
|
430
|
+
this.addEventListener("abort", onComplete);
|
|
431
|
+
}
|
|
432
|
+
return originalSend.call(this, body);
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
|
|
392
436
|
// src/index.ts
|
|
393
437
|
var client = null;
|
|
394
438
|
function init(connectionString, options = {}) {
|
|
@@ -396,6 +440,7 @@ function init(connectionString, options = {}) {
|
|
|
396
440
|
if (typeof window !== "undefined") {
|
|
397
441
|
installGlobalHandlers(client);
|
|
398
442
|
installFetchInstrumentation();
|
|
443
|
+
installXhrInstrumentation();
|
|
399
444
|
}
|
|
400
445
|
}
|
|
401
446
|
function captureException(error, options) {
|
|
@@ -436,7 +481,7 @@ var DISTRIBUTED_TRACE_HEADER = "traceway-trace-id";
|
|
|
436
481
|
function createAxiosInterceptor() {
|
|
437
482
|
return (config) => {
|
|
438
483
|
config.headers = config.headers || {};
|
|
439
|
-
config.headers["traceway-trace-id"] =
|
|
484
|
+
config.headers["traceway-trace-id"] = generateUUID4();
|
|
440
485
|
return config;
|
|
441
486
|
};
|
|
442
487
|
}
|
package/dist/index.mjs.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","../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"]}
|
|
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","../src/xhr-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\";\nimport { installXhrInstrumentation } from \"./xhr-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 installXhrInstrumentation();\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\nexport function setActiveDistributedTraceId(id: string | null): void {\n activeDistributedTraceId = id;\n}\n\nexport function clearActiveDistributedTraceId(traceId: string): void {\n if (activeDistributedTraceId === traceId) {\n activeDistributedTraceId = null;\n }\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","import { generateUUID } from \"@tracewayapp/core\";\nimport {\n setActiveDistributedTraceId,\n clearActiveDistributedTraceId,\n} from \"./fetch-instrumentation.js\";\n\nfunction isSameOriginUrl(url: string): boolean {\n try {\n const resolved = new URL(url, window.location.origin);\n return resolved.origin === window.location.origin;\n } catch {\n return true;\n }\n}\n\ninterface TracewayXHR extends XMLHttpRequest {\n _tracewaySameOrigin?: boolean;\n}\n\nexport function installXhrInstrumentation(): void {\n const originalOpen = XMLHttpRequest.prototype.open;\n const originalSend = XMLHttpRequest.prototype.send;\n\n XMLHttpRequest.prototype.open = function (\n this: TracewayXHR,\n method: string,\n url: string | URL,\n ...rest: any[]\n ) {\n this._tracewaySameOrigin = isSameOriginUrl(String(url));\n return originalOpen.apply(this, [method, url, ...rest] as any);\n };\n\n XMLHttpRequest.prototype.send = function (\n this: TracewayXHR,\n body?: Document | XMLHttpRequestBodyInit | null,\n ) {\n if (this._tracewaySameOrigin) {\n const traceId = generateUUID();\n setActiveDistributedTraceId(traceId);\n this.setRequestHeader(\"traceway-trace-id\", traceId);\n\n const onComplete = () => {\n clearActiveDistributedTraceId(traceId);\n this.removeEventListener(\"load\", onComplete);\n this.removeEventListener(\"error\", onComplete);\n this.removeEventListener(\"abort\", onComplete);\n };\n this.addEventListener(\"load\", onComplete);\n this.addEventListener(\"error\", onComplete);\n this.addEventListener(\"abort\", onComplete);\n }\n return originalSend.call(this, body);\n };\n}\n"],"mappings":"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","names":["nowISO","generateUUID","generateUUID","init","client","generateUUID","generateUUID","nowISO","generateUUID"]}
|