highlight.run
Version:
Open source, fullstack monitoring. Capture frontend errors, record server side logs, and visualize what broke with session replay.
1,274 lines (1,200 loc) • 83 kB
TypeScript
import { Attributes } from '@opentelemetry/api';
import { Context } from '@opentelemetry/api';
import { Counter } from '@opentelemetry/api';
import { EvaluationSeriesContext } from '@launchdarkly/js-client-sdk';
import { EvaluationSeriesData } from '@launchdarkly/js-client-sdk';
import { eventWithTime } from '@highlight-run/rrweb-types';
import { Gauge } from '@opentelemetry/api';
import { GraphQLClient } from 'graphql-request';
import { GraphQLClientRequestHeaders } from 'graphql-request/build/cjs/types';
import { Histogram } from '@opentelemetry/api';
import { Hook as Hook_2 } from '@launchdarkly/js-client-sdk';
import { LDContext } from '@launchdarkly/js-client-sdk';
import { LDEvaluationReason } from '@launchdarkly/js-client-sdk';
import { LDFlagValue } from '@launchdarkly/js-client-sdk';
import { LDPluginEnvironmentMetadata } from '@launchdarkly/js-client-sdk';
import { LDPluginMetadata } from '@launchdarkly/js-client-sdk';
import { listenerHandler } from '@highlight-run/rrweb-types';
import { ProductAnalyticsEvents } from 'client/types/observe';
import { Span } from '@opentelemetry/api';
import { SpanOptions } from '@opentelemetry/api';
import { StackFrame } from 'stacktrace-js';
import { UpDownCounter } from '@opentelemetry/api';
export declare const __testing: {
reset: () => void;
setHighlightObj: (obj: Partial<Highlight_2>) => void;
};
declare type AddSessionFeedbackMutation = {
__typename?: 'Mutation';
addSessionFeedback: string;
};
declare type AddSessionFeedbackMutationVariables = Exact<{
session_secure_id: Scalars['String']['input'];
user_name?: InputMaybe<Scalars['String']['input']>;
user_email?: InputMaybe<Scalars['String']['input']>;
verbatim: Scalars['String']['input'];
timestamp: Scalars['Timestamp']['input'];
}>;
declare type AddSessionPropertiesMutation = {
__typename?: 'Mutation';
addSessionProperties: string;
};
declare type AddSessionPropertiesMutationVariables = Exact<{
session_secure_id: Scalars['String']['input'];
properties_object?: InputMaybe<Scalars['Any']['input']>;
}>;
declare const ALL_CONSOLE_METHODS: readonly ["assert", "count", "countReset", "debug", "dir", "dirxml", "error", "group", "groupCollapsed", "groupEnd", "info", "log", "table", "time", "timeEnd", "timeLog", "trace", "warn"];
declare interface AmplitudeIntegrationOptions extends DefaultIntegrationOptions {
apiKey?: string;
}
declare type AsyncEventsMessage = {
type: MessageType.AsyncEvents;
id: number;
hasSessionUnloaded: boolean;
highlightLogs: string;
events: eventWithTime[];
messages: ConsoleMessage[];
errors: ErrorMessage[];
resourcesString: string;
webSocketEventsString: string;
};
declare type AsyncEventsResponse = {
type: MessageType.AsyncEvents;
id: number;
eventsSize: number;
compressedSize: number;
};
declare class BufferedClass<T extends object> {
protected _sdk: T;
protected _isLoaded: boolean;
protected _callBuffer: Array<Event_2>;
protected _capacity: number;
protected _droppedEvents: number;
protected _exceededCapacity: boolean;
protected _logger: Logger;
protected _bufferCall(method: string, args: any[]): any;
protected _enqueue(event: Event_2): void;
load(sdk: T): void;
}
declare type CommonOptions = {
/**
* Do not use this.
* @private
*/
debug?: boolean | DebugOptions;
/**
* Specifies the name of the app.
*/
serviceName?: string;
/**
* Specifies the version of your application.
* This is commonly a Git hash or a semantic version.
*/
version?: string;
/**
* Specifies where to send Highlight session data.
* You should not have to set this unless you are running an on-premise instance.
*/
backendUrl?: string;
/**
* Set to `sessionStorage` to bypass all `window.localStorage` usage.
* This can help with compliance for cookie-consent regulation.
* Using `sessionStorage` will cause app close+reopens to start a new highlight session,
* as the session ID will not persist.
*/
storageMode?: 'sessionStorage' | 'localStorage';
/**
* By default, session data is stored in the `sessionStorage` of the browser.
* Set to `true` to store session data in a cookie instead.
* This can help with compliance for cookie-consent regulation.
*/
sessionCookie?: boolean;
/**
* Specifies if Highlight should not automatically initialize when the class is created.
* This should be used with `.start()` and `.stop()` if you want to control when Highlight records.
* @default false
*/
manualStart?: boolean;
/**
* Key to use to determine the sessionSecureID in order to override session generation logic.
* If a sessionKey is provided, the session will be combined with the previous session with the same key.
* Otherwise, the current session logic will be used to generate a sessionSecureID.
*/
sessionKey?: string;
/**
* A function that returns a friendly name for a given context.
* This name will be used to identify the session in the observability UI.
* ```ts
* contextFriendlyName: (context: LDContext) => {
* if(context.kind === 'multi' && context.user?.email) {
* return context.user.email;
* } else if(context.kind === 'user') {
* return context.key;
* }
* // Use the default identifier for contexts which don't contain a user.
* return undefined;
* }
* ```
* @param context The context to get a friendly name for.
* @returns The friendly name for the context, or undefined to use the
* default identifier.
*/
contextFriendlyName?: (context: LDContext) => string | undefined;
};
export declare function configureElectronHighlight(window: any): void;
declare type ConsoleMessage = {
value?: Array<string>;
attributes?: string;
time: number;
type: string;
trace?: StackFrame[];
};
declare type ConsoleMethods = ConsoleMethodsTuple[number];
declare type ConsoleMethodsTuple = typeof ALL_CONSOLE_METHODS;
declare type CustomEventResponse = {
type: MessageType.CustomEvent;
tag: string;
payload: any;
};
declare type DebugOptions = {
clientInteractions?: boolean;
domRecording?: boolean;
};
declare type DefaultIntegrationOptions = {
disabled?: boolean;
};
declare type ErrorMessage = {
event: string;
type: ErrorMessageType;
url: string;
source: string;
lineNumber: number;
columnNumber: number;
stackTrace: StackFrame[];
/** The Unix Time of when the error was thrown. */
timestamp: string;
payload?: string;
error?: Error;
id: string;
};
declare type ErrorMessageType = 'console.error' | 'window.onerror' | 'window.onunhandledrejection' | 'custom' | 'React.ErrorBoundary';
declare type ErrorObjectInput = {
columnNumber: Scalars['Int']['input'];
event: Scalars['String']['input'];
id?: InputMaybe<Scalars['String']['input']>;
lineNumber: Scalars['Int']['input'];
payload?: InputMaybe<Scalars['String']['input']>;
source: Scalars['String']['input'];
stackTrace: Array<InputMaybe<StackFrameInput>>;
timestamp: Scalars['Timestamp']['input'];
type: Scalars['String']['input'];
url: Scalars['String']['input'];
};
declare type Event_2 = {
method: string;
args: any[];
};
declare type Exact<T extends {
[key: string]: unknown;
}> = {
[K in keyof T]: T[K];
};
declare type FeedbackMessage = {
type: MessageType.Feedback;
verbatim: string;
timestamp: string;
userName?: string;
userEmail?: string;
};
declare class FirstLoadListeners {
disableConsoleRecording: boolean;
reportConsoleErrors: boolean;
enablePromisePatch: boolean;
consoleMethodsToRecord: ConsoleMethods[];
listeners: (() => void)[];
errors: ErrorMessage[];
messages: ConsoleMessage[];
options: HighlightClassOptions;
hasNetworkRecording: boolean | undefined;
disableNetworkRecording: boolean;
enableRecordingNetworkContents: boolean;
xhrNetworkContents: RequestResponsePair[];
fetchNetworkContents: RequestResponsePair[];
disableRecordingWebSocketContents: boolean;
webSocketNetworkContents: WebSocketRequest[] | undefined;
webSocketEventContents: WebSocketEvent[];
tracingOrigins: boolean | (string | RegExp)[];
networkHeadersToRedact: string[];
networkBodyKeysToRedact: string[] | undefined;
networkBodyKeysToRecord: string[] | undefined;
networkHeaderKeysToRecord: string[] | undefined;
lastNetworkRequestTimestamp: number;
urlBlocklist: string[];
highlightEndpoints: string[];
requestResponseSanitizer?: (pair: RequestResponsePair) => RequestResponsePair | null;
constructor(options: HighlightClassOptions);
isListening(): boolean;
startListening(): void;
stopListening(): void;
static setupNetworkListener(sThis: FirstLoadListeners, options: HighlightClassOptions): void;
static getRecordedNetworkResources(sThis: FirstLoadListeners, recordingStartTime: number): Array<PerformanceResourceTiming | WebSocketRequest>;
static getRecordedWebSocketEvents(sThis: FirstLoadListeners): Array<WebSocketEvent>;
static clearRecordedNetworkResources(sThis: FirstLoadListeners): void;
}
export declare const GenerateSecureID: (key?: string) => string;
declare type GetSamplingConfigQuery = {
__typename?: 'Query';
sampling: {
__typename?: 'SamplingConfig';
spans?: Array<{
__typename?: 'SpanSamplingConfig';
samplingRatio: number;
name?: {
__typename?: 'MatchConfig';
regexValue?: string | null;
matchValue?: any | null;
} | null;
attributes?: Array<{
__typename?: 'AttributeMatchConfig';
key: {
__typename?: 'MatchConfig';
regexValue?: string | null;
matchValue?: any | null;
};
attribute: {
__typename?: 'MatchConfig';
regexValue?: string | null;
matchValue?: any | null;
};
}> | null;
events?: Array<{
__typename?: 'SpanEventMatchConfig';
name?: {
__typename?: 'MatchConfig';
regexValue?: string | null;
matchValue?: any | null;
} | null;
attributes?: Array<{
__typename?: 'AttributeMatchConfig';
key: {
__typename?: 'MatchConfig';
regexValue?: string | null;
matchValue?: any | null;
};
attribute: {
__typename?: 'MatchConfig';
regexValue?: string | null;
matchValue?: any | null;
};
}> | null;
}> | null;
}> | null;
logs?: Array<{
__typename?: 'LogSamplingConfig';
samplingRatio: number;
message?: {
__typename?: 'MatchConfig';
regexValue?: string | null;
matchValue?: any | null;
} | null;
severityText?: {
__typename?: 'MatchConfig';
regexValue?: string | null;
matchValue?: any | null;
} | null;
attributes?: Array<{
__typename?: 'AttributeMatchConfig';
key: {
__typename?: 'MatchConfig';
regexValue?: string | null;
matchValue?: any | null;
};
attribute: {
__typename?: 'MatchConfig';
regexValue?: string | null;
matchValue?: any | null;
};
}> | null;
}> | null;
};
};
declare type GetSamplingConfigQueryVariables = Exact<{
organization_verbose_id: Scalars['String']['input'];
}>;
declare function getSdk(client: GraphQLClient, withWrapper?: SdkFunctionWrapper): {
PushPayload(variables: PushPayloadMutationVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise<PushPayloadMutation>;
PushSessionEvents(variables: PushSessionEventsMutationVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise<PushSessionEventsMutation>;
identifySession(variables: IdentifySessionMutationVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise<IdentifySessionMutation>;
addSessionProperties(variables: AddSessionPropertiesMutationVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise<AddSessionPropertiesMutation>;
pushMetrics(variables: PushMetricsMutationVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise<PushMetricsMutation>;
addSessionFeedback(variables: AddSessionFeedbackMutationVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise<AddSessionFeedbackMutation>;
initializeSession(variables: InitializeSessionMutationVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise<InitializeSessionMutation>;
Ignore(variables: IgnoreQueryVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise<IgnoreQuery>;
GetSamplingConfig(variables: GetSamplingConfigQueryVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise<GetSamplingConfigQuery>;
};
declare type GetStatusMessage = {
type: MessageType.GetStatus;
};
export declare const H: HighlightPublicInterface;
declare interface Headers_2 {
[key: string]: any;
}
declare class Highlight_2 {
options: HighlightClassOptions;
/** Determines if the client is running on a Highlight property (e.g. frontend). */
isRunningOnHighlight: boolean;
/** Verbose project ID that is exposed to users. Legacy users may still be using ints. */
organizationID: string;
graphqlSDK: Sdk;
events: eventWithTime[];
sessionData: SessionData;
ready: boolean;
manualStopped: boolean;
state: 'NotRecording' | 'Recording';
logger: Logger;
enableSegmentIntegration: boolean;
privacySetting: PrivacySettingOption;
enableCanvasRecording: boolean;
enablePerformanceRecording: boolean;
samplingStrategy: SamplingStrategy;
inlineImages: boolean;
inlineVideos: boolean;
inlineStylesheet: boolean;
debugOptions: DebugOptions;
listeners: listenerHandler[];
firstloadVersion: string;
environment: string;
sessionShortcut: SessionShortcutOptions;
/** The end-user's app version. This isn't Highlight's version. */
appVersion: string | undefined;
serviceName: string;
_worker: HighlightClientRequestWorker;
_optionsInternal: HighlightClassOptionsInternal;
_backendUrl: string;
_recordingStartTime: number;
_isOnLocalHost: boolean;
_onToggleFeedbackFormVisibility: () => void;
_firstLoadListeners: FirstLoadListeners;
_isCrossOriginIframe: boolean;
_eventBytesSinceSnapshot: number;
_lastSnapshotTime: number;
_lastVisibilityChangeTime: number;
pushPayloadTimerId: ReturnType<typeof setTimeout> | undefined;
hasSessionUnloaded: boolean;
hasPushedData: boolean;
reloaded: boolean;
_hasPreviouslyInitialized: boolean;
_recordStop: listenerHandler | undefined;
_gauges: Map<string, Gauge>;
_counters: Map<string, Counter>;
_histograms: Map<string, Histogram>;
_up_down_counters: Map<string, UpDownCounter>;
_integrations: IntegrationClient[];
static create(options: HighlightClassOptions): Highlight_2;
constructor(options: HighlightClassOptions, firstLoadListeners?: FirstLoadListeners);
_reset({ forceNew, sessionKey, }: {
forceNew?: boolean;
sessionKey?: string;
}): Promise<void>;
_initMembers(options: HighlightClassOptions): void;
identify(user_identifier: string, user_object?: {}, source?: Source): void;
log(message: any, level: string, metadata?: Attributes): void;
pushCustomError(message: string, payload?: string): void;
consumeCustomError(error: Error, message?: string, payload?: string): void;
consumeError(error: Error, { message, payload, source, type, }: {
message?: string;
payload?: object;
source?: string;
type?: ErrorMessageType;
}): void;
addProperties(properties_obj?: {}, typeArg?: PropertyType): void;
initialize(options?: StartOptions): Promise<undefined>;
private _productAnalyticsEvents;
_visibilityHandler(hidden: boolean): Promise<void>;
_setupCrossOriginIframe(): Promise<void>;
_setupCrossOriginIframeParent(): void;
_setupWindowListeners(): void;
submitViewportMetrics({ height, width, availHeight, availWidth, }: ViewportResizeListenerArgs): void;
recordGauge(metric: RecordMetric): void;
recordCount(metric: RecordMetric): void;
recordIncr(metric: Omit<RecordMetric, 'value'>): void;
recordHistogram(metric: RecordMetric): void;
recordUpDownCounter(metric: RecordMetric): void;
/**
* Stops Highlight from recording.
* @param manual The end user requested to stop recording.
*/
stopRecording(manual?: boolean): void;
getCurrentSessionTimestamp(): number;
/**
* Returns the current timestamp for the current session.
*/
getCurrentSessionURLWithTimestamp(): string;
getCurrentSessionURL(): string | null;
snapshot(element: HTMLCanvasElement): Promise<void>;
addSessionFeedback({ timestamp, verbatim, user_email, user_name, }: {
verbatim: string;
timestamp: string;
user_name?: string;
user_email?: string;
}): void;
_save(): Promise<void>;
/**
* This proxy should be used instead of rrweb's native addCustomEvent.
* The proxy makes sure recording has started before emitting a custom event.
*/
addCustomEvent<T>(tag: string, payload: T): void;
_sendPayload({ sendFn, }: {
sendFn?: (payload: PushSessionEventsMutationVariables) => Promise<number>;
}): Promise<void>;
private takeFullSnapshot;
registerLD(client: LDClientMin): void;
}
declare type HighlightClassOptions = {
organizationID: number | string;
debug?: boolean | DebugOptions;
backendUrl?: string;
tracingOrigins?: boolean | (string | RegExp)[];
disableNetworkRecording?: boolean;
networkRecording?: boolean | NetworkRecordingOptions;
disableBackgroundRecording?: boolean;
disableConsoleRecording?: boolean;
disableSessionRecording?: boolean;
reportConsoleErrors?: boolean;
consoleMethodsToRecord?: ConsoleMethods[];
privacySetting?: PrivacySettingOption;
maskAllInputs?: boolean;
maskInputOptions?: MaskInputOptions;
maskTextClass?: string | RegExp;
maskTextSelector?: string;
blockClass?: string | RegExp;
blockSelector?: string;
ignoreClass?: string;
ignoreSelector?: string;
enableSegmentIntegration?: boolean;
enableCanvasRecording?: boolean;
enablePerformanceRecording?: boolean;
enablePromisePatch?: boolean;
samplingStrategy?: SamplingStrategy;
inlineImages?: boolean;
inlineVideos?: boolean;
inlineStylesheet?: boolean;
recordCrossOriginIframe?: boolean;
firstloadVersion?: string;
environment?: 'development' | 'production' | 'staging' | string;
appVersion?: string;
serviceName?: string;
sessionKey?: string;
sessionShortcut?: SessionShortcutOptions;
sessionSecureID: string;
storageMode?: 'sessionStorage' | 'localStorage';
sessionCookie?: boolean;
sendMode?: 'webworker' | 'local';
otlpEndpoint?: HighlightOptions['otlpEndpoint'];
otel?: HighlightOptions['otel'];
productAnalytics?: boolean | ProductAnalyticsEvents;
contextFriendlyName?: (context: LDContext) => string | undefined;
};
/**
* Subset of HighlightClassOptions that is stored with the session. These fields are stored for debugging purposes.
*/
declare type HighlightClassOptionsInternal = Omit<HighlightClassOptions, 'firstloadVersion'>;
declare interface HighlightClientRequestWorker {
postMessage: (message: HighlightClientWorkerParams) => void;
onmessage: (message: MessageEvent<HighlightClientWorkerResponse>) => void;
}
declare type HighlightClientWorkerParams = {
message: InitializeMessage | ResetMessage | GetStatusMessage | AsyncEventsMessage | IdentifyMessage | PropertiesMessage | MetricsMessage | FeedbackMessage;
};
declare type HighlightClientWorkerResponse = {
response?: AsyncEventsResponse | CustomEventResponse | StopEventResponse | StatusResponse;
};
export declare type HighlightOptions = CommonOptions & {
/**
* Specifies where the backend of the app lives. If specified, Highlight will attach the
* X-Highlight-Request header to outgoing requests whose destination URLs match a substring
* or regexp from this list, so that backend errors can be linked back to the session.
* If 'true' is specified, all requests to the current domain will be matched.
* @example tracingOrigins: ['localhost', /^\//, 'backend.myapp.com']
*/
tracingOrigins?: boolean | (string | RegExp)[];
/**
* This disables recording network requests.
* The data includes the URLs, the size of the request, and how long the request took.
* @default false
* @deprecated Use `networkRecording` instead.
*/
disableNetworkRecording?: boolean;
/**
* Specifies how and what Highlight records from network requests and responses.
*/
networkRecording?: boolean | NetworkRecordingOptions;
/**
* If set, Highlight will not record when your app is not visible (in the background).
* By default, Highlight will record in the background.
* @default false
*/
disableBackgroundRecording?: boolean;
/**
* Specifies whether Highlight will record console messages.
* @default false
*/
disableConsoleRecording?: boolean;
/**
* Specifies whether Highlight will record user session replays.
* Unless you are using Highlight only for error monitoring, you do not want to set this to true.
* @default false
*/
disableSessionRecording?: boolean;
/**
* Specifies whether Highlight will report `console.error` invocations as Highlight Errors.
* @default false
*/
reportConsoleErrors?: boolean;
/**
* Specifies which console methods to record.
* The value here will be ignored if `disabledConsoleRecording` is `true`.
* @default All console methods.
* @example consoleMethodsToRecord: ['log', 'info', 'error']
*/
consoleMethodsToRecord?: ConsoleMethods[];
enableSegmentIntegration?: boolean;
/**
* Specifies the environment your application is running in.
* This is useful to distinguish whether your session was recorded on localhost or in production.
* @default 'production'
*/
environment?: 'development' | 'staging' | 'production' | string;
/**
* Specifies how much data Highlight should redact during recording.
* strict - Highlight will redact all text data on the page.
* default - Highlight will redact text data on the page that is associated with personal identifiable data.
* none - Highlight will not redact any text data on the page.
* // Redacted text will be randomized. Instead of seeing "Hello World" in a recording, you will see "1fds1 j59a0".
* @see {@link https://docs.highlight.run/docs/privacy} for more information.
*/
privacySetting?: PrivacySettingOption;
/**
* Specifies whether to record canvas elements or not.
* @default false
*/
enableCanvasRecording?: boolean;
/**
* Specifies whether to record performance metrics (e.g. FPS, device memory).
* @default true
*/
enablePerformanceRecording?: boolean;
/**
* Specifies whether window.Promise should be patched
* to record the stack trace of promise rejections.
* @default true
*/
enablePromisePatch?: boolean;
/**
* Configure the recording sampling options, eg. how frequently we record canvas updates.
*/
samplingStrategy?: SamplingStrategy;
/**
* Specifies whether to inline images into the recording.
* This means that images that are local to the client (eg. client-generated blob: urls)
* will be serialized into the recording and will be valid on replay.
* This will also use canvas snapshotting to inline <video> elements
* that use `src="blob:..."` data or webcam feeds (blank src) as <canvas> elements
* Only enable this if you are running into issues with client-local images.
* Will negatively affect performance.
* @default false
*/
inlineImages?: boolean;
/**
* Specifies whether to inline <video> elements into the recording.
* This means that video that are not accessible at a later time
* (eg., a signed URL that is short lived)
* will be serialized into the recording and will be valid on replay.
* Only enable this if you are running into issues with the normal serialization.
* Will negatively affect performance.
* @default false
*/
inlineVideos?: boolean;
/**
* Specifies whether to inline stylesheets into the recording.
* This means that stylesheets that are local to the client (eg. client-generated blob: urls)
* will be serialized into the recording and will be valid on replay.
* Only enable this if you are running into issues with client-local stylesheets.
* May negatively affect performance.
* @default true
*/
inlineStylesheet?: boolean;
/**
* Enables recording of cross-origin iframes. Should be set in both the parent window and
* in the cross-origin iframe.
* @default false
*/
recordCrossOriginIframe?: boolean;
/**
* Deprecated: this setting is now inferred automatically. Passing this option does nothing.
* @deprecated
*/
isCrossOriginIframe?: boolean;
integrations?: IntegrationOptions;
/**
* Specifies the keyboard shortcut to open the current session in Highlight.
* @see {@link https://docs.highlight.run/session-shortcut} for more information.
*/
sessionShortcut?: SessionShortcutOptions;
/**
* By default, data is serialized and send by the Web Worker. Set to `local` to force
* sending from the main js thread. Only use `local` for custom environments where Web Workers
* are not available (ie. Figma plugins).
*/
sendMode?: 'webworker' | 'local';
/**
* OTLP endpoint for OpenTelemetry tracing.
*/
otlpEndpoint?: string;
/**
* OTLP options for OpenTelemetry tracing. Instrumentations are enabled by default.
*/
otel?: OtelOptions;
};
declare interface HighlightPublicInterface {
init: (projectID?: string | number, debug?: HighlightOptions) => {
sessionSecureID: string;
} | undefined;
/**
* Calling this will assign an identifier to the session.
* @example identify('teresa@acme.com', { accountAge: 3, cohort: 8 })
* @param identifier Is commonly set as an email or UUID.
* @param metadata Additional details you want to associate to the user.
*/
identify: (identifier: string, metadata?: Metadata_2, source?: Source) => void;
/**
* Call this to record when you want to track a specific event happening in your application.
* @example track('startedCheckoutProcess', { cartSize: 10, value: 85 })
* @param event The name of the event.
* @param metadata Additional details you want to associate to the event.
*/
track: (event: string, metadata?: Metadata_2) => void;
log: (message: any, level: string, metadata?: Attributes) => void;
/**
* @deprecated with replacement by `consumeError` for an in-app stacktrace.
*/
error: (message: string, payload?: {
[key: string]: string;
}) => void;
/**
* Calling this method will report metrics to Highlight. You can graph metrics or configure
* alerts on metrics that exceed a threshold.
* @see {@link https://docs.highlight.run/frontend-observability} for more information.
*/
metrics: (metrics: Metric[]) => void;
/**
* Record arbitrary metric values via as a Gauge.
* A Gauge records any point-in-time measurement, such as the current CPU utilization %.
* Values with the same metric name and attributes are aggregated via the OTel SDK.
* See https://opentelemetry.io/docs/specs/otel/metrics/data-model/ for more details.
*/
recordMetric: (metric: Metric) => void;
/**
* Record arbitrary metric values via as a Counter.
* A Counter efficiently records an increment in a metric, such as number of cache hits.
* Values with the same metric name and attributes are aggregated via the OTel SDK.
* See https://opentelemetry.io/docs/specs/otel/metrics/data-model/ for more details.
*/
recordCount: (metric: Metric) => void;
/**
* Record arbitrary metric values via as a Counter.
* A Counter efficiently records an increment in a metric, such as number of cache hits.
* Values with the same metric name and attributes are aggregated via the OTel SDK.
* See https://opentelemetry.io/docs/specs/otel/metrics/data-model/ for more details.
*/
recordIncr: (metric: Omit<Metric, 'value'>) => void;
/**
* Record arbitrary metric values via as a Histogram.
* A Histogram efficiently records near-by point-in-time measurement into a bucketed aggregate.
* Values with the same metric name and attributes are aggregated via the OTel SDK.
* See https://opentelemetry.io/docs/specs/otel/metrics/data-model/ for more details.
*/
recordHistogram: (metric: Metric) => void;
/**
* Record arbitrary metric values via as a UpDownCounter.
* A UpDownCounter efficiently records an increment or decrement in a metric, such as number of paying customers.
* Values with the same metric name and attributes are aggregated via the OTel SDK.
* See https://opentelemetry.io/docs/specs/otel/metrics/data-model/ for more details.
*/
recordUpDownCounter: (metric: Metric) => void;
/**
* Starts a new span for tracing in Highlight. The span will be ended when the
* callback function returns.
*
* @example
* ```typescript
* H.startSpan('span-name', callbackFn)
* ```
* @example
* ```typescript
* H.startSpan('span-name', options, callbackFn)
* ```
* @example
* ```typescript
* H.startSpan('span-name', options, context, callbackFn)
* ```
* @example
* ```typescript
* H.startSpan('span-name', async (span) => {
* span.setAttribute('key', 'value')
* await someAsyncFunction()
* })
* ```
*
* @param name The name of the span.
* @param options Options for the span.
* @param context The context for the span.
* @param callbackFn The function to run in the span.
*/
startSpan: {
<F extends (span?: Span) => ReturnType<F>>(name: string, fn: F): ReturnType<F>;
<F extends (span?: Span) => ReturnType<F>>(name: string, options: SpanOptions, fn: F): ReturnType<F>;
<F extends (span?: Span) => ReturnType<F>>(name: string, options: SpanOptions, context: Context, fn: F): ReturnType<F>;
};
/**
* Starts a new span for tracing in Highlight. The span will be ended when the
* `end()` is called on the span. It returns whatever is returned from the
* callback function.
*
* @example
* ```typescript
* H.startManualSpan('span-name', options, (span) => {
* span.addEvent('event-name', { key: 'value' })
* span.setAttribute('key', 'value')
* await someAsyncFunction()
* span.end()
* })
* ```
*
* @example
* ```typescript
* const span = H.startManualSpan('span-name', (s) => s)
* span.addEvent('event-name', { key: 'value' })
* await someAsyncFunction()
* span.end()
* ```
*
* @param name The name of the span.
* @param options Options for the span.
* @param context The context for the span.
* @param fn The function to run in the span.
*/
startManualSpan: {
<F extends (span: Span) => ReturnType<F>>(name: string, fn: F): ReturnType<F>;
<F extends (span: Span) => ReturnType<F>>(name: string, options: SpanOptions, fn: F): ReturnType<F>;
<F extends (span: Span) => ReturnType<F>>(name: string, options: SpanOptions, context: Context, fn: F): ReturnType<F>;
};
/**
* Calling this method will report an error in Highlight and map it to the current session being recorded.
* A common use case for `H.error` is calling it right outside of an error boundary.
* @see {@link https://docs.highlight.run/grouping-errors} for more information.
*/
consumeError: (error: Error, message?: string, payload?: {
[key: string]: string;
}) => void;
/**
* Calling this method will report an error in Highlight
* while allowing additional attributes to be sent over as metadata.
* @see {consumeError} for more information.
*/
consume: (error: Error, opts: {
message?: string;
payload?: object;
source?: string;
type?: ErrorMessageType;
}) => void;
getSessionURL: () => Promise<string>;
getSessionDetails: () => Promise<SessionDetails>;
start: (options?: StartOptions) => void;
/** Stops the session and error recording. */
stop: (options?: StartOptions) => void;
onHighlightReady: (func: () => void | Promise<void>, options?: OnHighlightReadyOptions) => void;
getRecordingState: () => 'NotRecording' | 'Recording';
options: HighlightOptions | undefined;
/**
* Calling this will add a feedback comment to the session.
*/
addSessionFeedback: (feedbackOptions: SessionFeedbackOptions) => void;
snapshot: (element: HTMLCanvasElement) => Promise<void>;
registerLD: (client: LDClientMin, metadata?: LDPluginEnvironmentMetadata) => void;
}
export declare const HighlightSegmentMiddleware: ({ next, payload, }: SegmentContext) => void;
/**
* Interface for extending SDK functionality via hooks.
*/
declare type Hook = Omit<Hook_2, 'afterEvaluation'> & {
/**
* This method is called during the execution of the variation method
* after the flag value has been determined. The method is executed synchronously.
*
* @param hookContext Contains read-only information about the evaluation
* being performed.
* @param data A record associated with each stage of hook invocations. Each
* stage is called with the data of the previous stage for a series.
* @param detail The result of the evaluation. This value should not be
* modified.
* @returns Data to use when executing the next state of the hook in the evaluation series. It is
* recommended to expand the previous input into the return. This helps ensure your stage remains
* compatible moving forward as more stages are added.
* ```js
* return {...data, "my-new-field": /*my data/*}
* ```
*/
afterEvaluation?(hookContext: EvaluationSeriesContext, data: EvaluationSeriesData, detail: {
/**
* The result of the flag evaluation. This will be either one of the flag's variations or
* the default value that was passed to `LDClient.variationDetail`.
*/
value: LDFlagValue;
/**
* The index of the returned value within the flag's list of variations, e.g. 0 for the
* first variation-- or `null` if the default value was returned.
*/
variationIndex?: number | null;
/**
* An object describing the main factor that influenced the flag evaluation value.
*/
reason?: LDEvaluationReason | null;
}): EvaluationSeriesData;
};
declare type IdentifyMessage = {
type: MessageType.Identify;
userIdentifier: string;
userObject: any;
source?: Source;
};
declare type IdentifySessionMutation = {
__typename?: 'Mutation';
identifySession: string;
};
declare type IdentifySessionMutationVariables = Exact<{
session_secure_id: Scalars['String']['input'];
user_identifier: Scalars['String']['input'];
user_object?: InputMaybe<Scalars['Any']['input']>;
}>;
declare type IgnoreQuery = {
__typename?: 'Query';
ignore?: any | null;
};
declare type IgnoreQueryVariables = Exact<{
id: Scalars['ID']['input'];
}>;
declare type InitializeMessage = {
type: MessageType.Initialize;
backend: string;
sessionSecureID: string;
debug: boolean;
recordingStartTime: number;
};
declare type InitializeSessionMutation = {
__typename?: 'Mutation';
initializeSession: {
__typename?: 'InitializeSessionResponse';
secure_id: string;
project_id: string;
sampling?: {
__typename?: 'SamplingConfig';
spans?: Array<{
__typename?: 'SpanSamplingConfig';
samplingRatio: number;
name?: {
__typename?: 'MatchConfig';
regexValue?: string | null;
matchValue?: any | null;
} | null;
attributes?: Array<{
__typename?: 'AttributeMatchConfig';
key: {
__typename?: 'MatchConfig';
regexValue?: string | null;
matchValue?: any | null;
};
attribute: {
__typename?: 'MatchConfig';
regexValue?: string | null;
matchValue?: any | null;
};
}> | null;
events?: Array<{
__typename?: 'SpanEventMatchConfig';
name?: {
__typename?: 'MatchConfig';
regexValue?: string | null;
matchValue?: any | null;
} | null;
attributes?: Array<{
__typename?: 'AttributeMatchConfig';
key: {
__typename?: 'MatchConfig';
regexValue?: string | null;
matchValue?: any | null;
};
attribute: {
__typename?: 'MatchConfig';
regexValue?: string | null;
matchValue?: any | null;
};
}> | null;
}> | null;
}> | null;
logs?: Array<{
__typename?: 'LogSamplingConfig';
samplingRatio: number;
message?: {
__typename?: 'MatchConfig';
regexValue?: string | null;
matchValue?: any | null;
} | null;
severityText?: {
__typename?: 'MatchConfig';
regexValue?: string | null;
matchValue?: any | null;
} | null;
attributes?: Array<{
__typename?: 'AttributeMatchConfig';
key: {
__typename?: 'MatchConfig';
regexValue?: string | null;
matchValue?: any | null;
};
attribute: {
__typename?: 'MatchConfig';
regexValue?: string | null;
matchValue?: any | null;
};
}> | null;
}> | null;
} | null;
};
};
declare type InitializeSessionMutationVariables = Exact<{
session_secure_id: Scalars['String']['input'];
session_key?: InputMaybe<Scalars['String']['input']>;
organization_verbose_id: Scalars['String']['input'];
enable_strict_privacy: Scalars['Boolean']['input'];
privacy_setting: Scalars['String']['input'];
enable_recording_network_contents: Scalars['Boolean']['input'];
clientVersion: Scalars['String']['input'];
firstloadVersion: Scalars['String']['input'];
clientConfig: Scalars['String']['input'];
environment: Scalars['String']['input'];
id: Scalars['String']['input'];
appVersion?: InputMaybe<Scalars['String']['input']>;
serviceName: Scalars['String']['input'];
client_id: Scalars['String']['input'];
network_recording_domains?: InputMaybe<Array<Scalars['String']['input']> | Scalars['String']['input']>;
disable_session_recording?: InputMaybe<Scalars['Boolean']['input']>;
}>;
declare type InputMaybe<T> = Maybe<T>;
declare interface IntegrationClient {
init(sessionSecureID: string): void;
identify(sessionSecureID: string, user_identifier: string, user_object: object, source?: Source): void;
error(sessionSecureID: string, error: ErrorMessage): void;
track(sessionSecureID: string, metadata: object): void;
recordGauge(sessionSecureID: string, metric: RecordMetric): void;
getHooks?(metadata: LDPluginEnvironmentMetadata): Hook[];
}
declare type IntegrationOptions = {
amplitude?: AmplitudeIntegrationOptions;
intercom?: IntercomIntegrationOptions;
mixpanel?: MixpanelIntegrationOptions;
};
declare interface IntercomIntegrationOptions extends DefaultIntegrationOptions {
}
declare interface LDClientMin {
track(key: string, data?: any, metricValue?: number): void;
identify(ctx: any): void;
addHook(hook: Hook): void;
}
export declare let LDObserve: _LDObserve;
declare class _LDObserve extends BufferedClass<Observe_2> implements Observe_2 {
start(): Promise<void>;
stop(): Promise<void>;
recordGauge(metric: OTelMetric): any;
recordCount(metric: OTelMetric): any;
recordIncr(metric: Omit<OTelMetric, 'value'>): any;
recordHistogram(metric: OTelMetric): any;
recordUpDownCounter(metric: OTelMetric): any;
startSpan(name: string, options: SpanOptions | ((span?: Span) => any), context?: Context | ((span?: Span) => any), fn?: (span?: Span) => any): any;
startManualSpan(name: string, options: SpanOptions | ((span: Span) => any), context?: Context | ((span: Span) => any), fn?: (span: Span) => any): any;
register(client: LDClientMin, environmentMetadata: LDPluginEnvironmentMetadata): any;
recordLog(message: any, level: ConsoleMethods, metadata?: Attributes): any;
recordError(error: Error, message?: string, payload?: {
[key: string]: string;
}, source?: string, type?: ErrorMessageType): any;
setLDContextKeyAttributes(contextKeys: Attributes): any;
getLDContextKeyAttributes(): Attributes | undefined;
}
declare interface LDPlugin {
getMetadata(): LDPluginMetadata;
register(client: LDClientMin, environmentMetadata: LDPluginEnvironmentMetadata): void;
getHooks?(metadata: LDPluginEnvironmentMetadata): Hook[];
}
export declare let LDRecord: _LDRecord;
declare class _LDRecord extends BufferedClass<Record_3> implements Record_3 {
getSession(): SessionDetails | null;
start(options?: StartOptions): Promise<void>;
stop(): void;
addSessionProperties(properties: {
[key: string]: any;
}): any;
getRecordingState(): any;
snapshot(element: HTMLCanvasElement): any;
register(client: LDClientMin, environmentMetadata: LDPluginEnvironmentMetadata): any;
}
declare class Logger {
debug: boolean | undefined;
name: string | undefined;
constructor(debug?: boolean, name?: string);
log(...data: any[]): void;
warn(...data: any[]): void;
}
declare type MaskInputOptions = Partial<{
color: boolean;
date: boolean;
'datetime-local': boolean;
email: boolean;
month: boolean;
number: boolean;
range: boolean;
search: boolean;
tel: boolean;
text: boolean;
time: boolean;
url: boolean;
week: boolean;
textarea: boolean;
select: boolean;
password: boolean;
}>;
declare type Maybe<T> = T | null;
declare enum MessageType {
Initialize = 0,
Reset = 1,
AsyncEvents = 2,
Identify = 3,
Properties = 4,
Metrics = 5,
Feedback = 6,
CustomEvent = 7,
Stop = 8,
GetStatus = 9
}
declare interface Metadata_2 {
[key: string]: any;
}
export { Metadata_2 as Metadata }
declare interface Metric {
name: string;
value: number;
tags?: {
name: string;
value: string;
}[];
}
export declare enum MetricCategory {
Device = "Device",
WebVital = "WebVital",
Frontend = "Frontend",
Backend = "Backend"
}
declare enum MetricCategory_2 {
Device = "Device",
WebVital = "WebVital",
Performance = "Performance",
Frontend = "Frontend",
Backend = "Backend"
}
declare type MetricInput = {
category?: InputMaybe<Scalars['String']['input']>;
group?: InputMaybe<Scalars['String']['input']>;
name: Scalars['String']['input'];
parent_span_id?: InputMaybe<Scalars['String']['input']>;
session_secure_id: Scalars['String']['input'];
span_id?: InputMaybe<Scalars['String']['input']>;
tags?: InputMaybe<Array<MetricTag>>;
timestamp: Scalars['Timestamp']['input'];
trace_id?: InputMaybe<Scalars['String']['input']>;
value: Scalars['Float']['input'];
};
declare type MetricsMessage = {
type: MessageType.Metrics;
metrics: {
name: string;
value: number;
category: MetricCategory_2;
group: string;
timestamp: Date;
tags: {
name: string;
value: string;
}[];
}[];
};
declare type MetricTag = {
name: Scalars['String']['input'];
value: Scalars['String']['input'];
};
declare interface MixpanelIntegrationOptions extends DefaultIntegrationOptions {
projectToken?: string;
}
declare type NetworkRecordingOptions = {
/**
* Enables recording of network requests.
* The data includes the URLs, the size of the request, and how long the request took.
* @default true
*/
enabled?: boolean;
/**
* This enables recording XMLHttpRequest and Fetch headers and bodies.
* @default false
*/
recordHeadersAndBody?: boolean;
/**
* This disables recording WebSocket events.
* WebSocket events are recorded by default if recordHeadersAndBody is set.
* @default false
*/
disableWebSocketEventRecordings?: boolean;
/**
* Request and response headers where the value is not recorded.
* The header value is replaced with '[REDACTED]'.
* These headers are case-insensitive.
* `recordHeadersAndBody` needs to be enabled.
* This option will be ignored if `headerKeysToRecord` is set.
* @example
* networkHeadersToRedact: ['Secret-Header', 'Plain-Text-Password']
*/
networkHeadersToRedact?: string[];
/**
* Specifies the keys for request/response JSON body that should not be recorded.
* The body value is replaced with '[REDACTED]'.
* These keys are case-insensitive.
* `enabled` and `recordHeadersAndBody` need to be `true`. Otherwise this option will be ignored.
* @example bodyKeysToRedact: ['secret-token', 'plain-text-password']
* // Only `body.id` and `body.pageNumber` will be recorded.
* body = {
* 'id': '123',
* 'pageNumber': '1',
* 'secret-token': 'super-sensitive-value',
* 'plain-text-password': 'password123',
* }
*/
networkBodyKeysToRedact?: string[];
/**
* URLs to not record headers and bodies for, and to not propagate trace
* headers (e.g. `traceparent`) to. Each entry is matched as a
* case-insensitive substring of the full request URL; a match suppresses
* both recording and trace-header propagation for that request.
* To disable recording headers and bodies for all URLs, set `recordHeadersAndBody` to `false`.
* @default ['https://www.googleapis.com/identitytoolkit', 'https://securetoken.googleapis.com']
*/
urlBlocklist?: string[];
/**
* Specifies the keys for request/response headers to record.
* This option will override `networkHeadersToRedact` if specified.