Skip to content

Commit

Permalink
feat: Vendor TraceKit (#729)
Browse files Browse the repository at this point in the history
This PR vendors tracekit to alleviate some issues with ESM
compatibility.
Currently the typescript conversion is minimal. It adds the types which
are largely compatible and leaves most of it reasonably unchanged.

This PR does not port the tests from tracekit to this repository. A
subsequent PR will do this.

BEGIN_COMMIT_OVERRIDE
feat: Vendor TraceKit
feat: Export browser-telemetry initialization method.
END_COMMIT_OVERRIDE

Jira: EMSR-14
Jira: EMSR-15
  • Loading branch information
kinyoklion authored Jan 14, 2025
1 parent 20cccbf commit d1b364e
Show file tree
Hide file tree
Showing 5 changed files with 1,129 additions and 9 deletions.
3 changes: 0 additions & 3 deletions packages/telemetry/browser-telemetry/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@
"bugs": {
"url": "https://github.com/launchdarkly/js-core/issues"
},
"dependencies": {
"tracekit": "^0.4.6"
},
"devDependencies": {
"@jest/globals": "^29.7.0",
"@launchdarkly/js-client-sdk": "0.3.2",
Expand Down
10 changes: 7 additions & 3 deletions packages/telemetry/browser-telemetry/src/BrowserTelemetryImpl.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import * as TraceKit from 'tracekit';

/**
* A limited selection of type information is provided by the browser client SDK.
* This is only a type dependency and these types should be compatible between
Expand All @@ -23,6 +21,7 @@ import makeInspectors from './inspectors';
import { ParsedOptions, ParsedStackOptions } from './options';
import randomUuidV4 from './randomUuidV4';
import parse from './stack/StackParser';
import { getTraceKit } from './vendor/TraceKit';

// TODO: Use a ring buffer for the breadcrumbs/pending events instead of shifting. (SDK-914)

Expand Down Expand Up @@ -54,13 +53,18 @@ function safeValue(u: unknown): string | boolean | number | undefined {
}

function configureTraceKit(options: ParsedStackOptions) {
const TraceKit = getTraceKit();
// Include before + after + source line.
// TraceKit only takes a total context size, so we have to over capture and then reduce the lines.
// So, for instance if before is 3 and after is 4 we need to capture 4 and 4 and then drop a line
// from the before context.
// The typing for this is a bool, but it accepts a number.
const beforeAfterMax = Math.max(options.source.afterLines, options.source.beforeLines);
(TraceKit as any).linesOfContext = beforeAfterMax * 2 + 1;
// The assignment here has bene split to prevent esbuild from complaining about an assigment to
// an import. TraceKit exports a single object and the interface requires modifying an exported
// var.
const anyObj = TraceKit as any;
anyObj.linesOfContext = beforeAfterMax * 2 + 1;
}

export default class BrowserTelemetryImpl implements BrowserTelemetry {
Expand Down
10 changes: 10 additions & 0 deletions packages/telemetry/browser-telemetry/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
import { BrowserTelemetry } from './api/BrowserTelemetry';
import { Options } from './api/Options';
import BrowserTelemetryImpl from './BrowserTelemetryImpl';
import parse from './options';

export * from './api';

export function initializeTelemetry(options?: Options): BrowserTelemetry {
const parsedOptions = parse(options || {});
return new BrowserTelemetryImpl(parsedOptions);
}
5 changes: 2 additions & 3 deletions packages/telemetry/browser-telemetry/src/stack/StackParser.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { computeStackTrace } from 'tracekit';

import { StackFrame } from '../api/stack/StackFrame';
import { StackTrace } from '../api/stack/StackTrace';
import { ParsedStackOptions } from '../options';
import { getTraceKit } from '../vendor/TraceKit';

/**
* In the browser we will not always be able to determine the source file that code originates
Expand Down Expand Up @@ -195,7 +194,7 @@ export function getSrcLines(
* @returns The stack trace for the given error.
*/
export default function parse(error: Error, options: ParsedStackOptions): StackTrace {
const parsed = computeStackTrace(error);
const parsed = getTraceKit().computeStackTrace(error);
const frames: StackFrame[] = parsed.stack.reverse().map((inFrame) => ({
fileName: processUrlToFileName(inFrame.url, window.location.origin),
function: inFrame.func,
Expand Down
Loading

0 comments on commit d1b364e

Please sign in to comment.