UNPKG

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
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.