@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 +13 -3
- package/dist/index.d.ts +13 -3
- package/dist/index.js +71 -16
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +64 -9
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
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
|
|
39
|
-
|
|
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
|
-
|
|
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
|
|
39
|
-
|
|
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
|
-
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
};
|
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"],"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.
|
|
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.
|
|
26
|
+
"@tracewayapp/core": "1.0.2",
|
|
27
27
|
"rrweb": "^2.0.0-alpha.18"
|
|
28
28
|
}
|
|
29
29
|
}
|