UNPKG

posthog-js

Version:

Posthog-js allows you to automatically capture usage and send events to PostHog.

254 lines (253 loc) • 9.84 kB
export { RECORDING_REMOTE_CONFIG_TTL_MS } from '../../../constants'; import { EventType, eventWithTime, IncrementalSource } from '../types/rrweb-types'; import { SessionRecordingStatus, TriggerType } from './triggerMatching'; export { SEVEN_MEGABYTES, splitBuffer } from './sessionrecording-utils'; import { LazyLoadedSessionRecordingInterface } from '../../../utils/globals'; import { PostHog } from '../../../posthog-core'; import { Properties, SessionRecordingPersistedConfig, SessionStartReason } from '../../../types'; export declare const RECORDING_IDLE_THRESHOLD_MS: number; export declare const RECORDING_MAX_EVENT_SIZE: number; export declare const RECORDING_BUFFER_TIMEOUT = 2000; export declare const SESSION_RECORDING_BATCH_KEY = "recordings"; export declare const PENDING_BUFFER_STORAGE_SUFFIX = "_replay_pending_buffer"; export interface SnapshotBuffer { size: number; data: any[]; sizes: number[]; sessionId: string; windowId: string; } export type compressedFullSnapshotEvent = { type: typeof EventType.FullSnapshot; data: string; }; export type compressedIncrementalSnapshotEvent = { type: typeof EventType.IncrementalSnapshot; data: { source: IncrementalSource; texts: string; attributes: string; removes: string; adds: string; }; }; export type compressedIncrementalStyleSnapshotEvent = { type: typeof EventType.IncrementalSnapshot; data: { source: typeof IncrementalSource.StyleSheetRule; id?: number; styleId?: number; replace?: string; replaceSync?: string; adds?: string; removes?: string; }; }; export type compressedEvent = compressedIncrementalStyleSnapshotEvent | compressedFullSnapshotEvent | compressedIncrementalSnapshotEvent; export type compressedEventWithTime = compressedEvent & { timestamp: number; delay?: number; cv: '2024-10'; }; export declare class LazyLoadedSessionRecording implements LazyLoadedSessionRecordingInterface { private readonly _instance; private _endpoint; private _mutationThrottler?; /** * Util to help developers working on this feature manually override */ private _forceAllowLocalhostNetworkCapture; private _stopRrweb; private _jsonLdCapture; private _jsonLdCaptureReady; private _lastActivityTimestamp; private _sessionStartTimestamp; private _isActivatingTrigger; /** * if pageview capture is disabled, * then we can manually track href changes */ private _lastHref?; /** * and a queue - that contains rrweb events that we want to send to rrweb, but rrweb wasn't able to accept them yet */ private _queuedRRWebEvents; private _isIdle; private _eventsDroppedWhileIdle; private _throttledMutationsDropped; private _oversizedMutationsDropped; private _oversizedMutationBytesDropped; private _unstringifiableEventsDropped; private _holdFlushUntilInteraction; private _flushHoldReason; private _lastLoggedFlushHold; private _heldEpochShipsOnUnload; private _documentWasEverVisible; private _heldBufferOverflowed; private _suppressNextFreshStartHold; private _rrwebError; private _rrwebStartAttempted; private _lastSeenSnapshotCost; private _snapshotCostErrorLogged; private _hasWarnedClientMaskingOverride; private _hasWarnedExclusiveAttributeMasking; private _maskRegionsFnFailed; private _hasLoggedRecorderCallbackError; private _linkedFlagMatching; private _urlTriggerMatching; private _eventTriggerMatching; private _strategy; private _fullSnapshotTimer?; private _lastFullSnapshotSessionId; private _fullSnapshotHealAttemptedFor; private _windowId; private _sessionId; get sessionId(): string; private _flushBufferTimer?; private _buffer; private readonly _pendingBufferStorageKey; private _pendingBufferRestored; private _lastParkedBufferSize; private _compressionQueue?; private _pendingCompressionEvents; private _queuedCompressionEvents; private _compressionQueueGeneration; private _isStoppingAfterCompression; private _removePageViewCaptureHook; private _removeEventTriggerCaptureHook; private _flushedSizeTracker; private get _sessionManager(); private get _sessionIdleThresholdMilliseconds(); private get _isSampled(); private get _sampleRate(); private get _minimumDuration(); private _onSessionIdListener; private _onSessionIdleResetForcedListener; private _forceIdleSessionIdListener; constructor(_instance: PostHog, documentWasEverVisible?: boolean); setDocumentWasEverVisible(documentWasEverVisible: boolean): void; private get _masking(); /** * Client-side masking config in `posthog.init` intentionally wins over the "Privacy and masking" * project setting (the remote config). That precedence is by-design, but silent: a developer who * sets e.g. `maskTextSelector: '*'` locally can be surprised that their dashboard setting has no * effect. Warn (once per recorder) when the two diverge so the override is self-explaining. */ private _warnIfClientMaskingShadowsServer; private get _canvasResolutionScale(); private get _canvasRecording(); private get _isConsoleLogCaptureEnabled(); private get _networkPayloadCapture(); private _gatherRRWebPlugins; private _stripUrlHash; private _maskReplayUrl; private _maskUrl; private _tryRRWebMethod; private _tryAddCustomEvent; private _canCaptureJsonLd; private _tryAddJsonLdEvent; private _scheduleJsonLdScan; private _pageViewFallBack; private _processQueuedEvents; private _tryTakeFullSnapshot; private get _fullSnapshotIntervalMillis(); private _scheduleFullSnapshot; private _onTriggerActivated; private _pauseRecording; private _resumeRecording; private _activateTrigger; get isStarted(): boolean; get _remoteConfig(): SessionRecordingPersistedConfig | undefined; private _checkOverride; start(startReason?: SessionStartReason): void; private _onSessionIdCallback; private _teardown; private _invalidateCompressionQueue; private _stopRecordingProducers; private _stopAfterCompressionQueueDrains; stop(): void; private _releaseHoldAfterStop; flushBeforeIdentityReset(): void; private _isRestartingForSessionIdChange; private _restartForSessionIdChange; private _setFlushHold; private _releaseHoldAndFlush; discard({ discardProducerEvents }?: { discardProducerEvents?: boolean; }): void; private _captureProcessedEvent; private _safeTrackFullSnapshotCost; private _trackFullSnapshotCost; private _ensureFullSnapshotForSession; private _finishQueuedCompressionEvent; private _captureQueuedCompressionEvent; private _processQueuedCompressionEventSync; private _drainCompressionQueueSync; private _enqueueCompression; onRRwebEmit(rawEvent: eventWithTime): void; get status(): SessionRecordingStatus; log(message: string, level?: 'log' | 'warn' | 'error'): void; overrideLinkedFlag(): void; /** * this ignores the sampling config and (if other conditions are met) causes capture to start * * It is not usual to call this directly, * instead call `posthog.startSessionRecording({sampling: true})` * */ overrideSampling(): void; /** * this ignores the URL/Event trigger config and (if other conditions are met) causes capture to start * * It is not usual to call this directly, * instead call `posthog.startSessionRecording({trigger: 'url' | 'event'})` * */ overrideTrigger(triggerType: TriggerType): void; private _currentMaskedHostname; private _clearFlushBufferTimer; private _scheduleFlushBuffer; private _wouldOpenRecordingWithMarkersOnly; /** * Names the trigger conditions that are keeping the session in BUFFERING, so diagnostics can * identify which leg failed instead of only reporting an unexplained "buffering". A URL trigger * that never matches under the default AND matching otherwise looks like a session that is about * to record. */ private _describePendingTriggerConditions; private _lastLoggedBufferingReason; private _maybeLogBufferingReason; private _canParkPendingBuffer; /** * Parks the buffer for the next page in this tab. A timing gate holds the buffer for a retry * that an unloading page never runs, so without this the snapshots die with the page and the * recording opens partway through the session. */ private _parkBufferForNextPage; private _restorePendingBuffer; private _flushBuffer; private _hasPassedMinimumDuration; private _getBufferDuration; private _isBelowMinimumDuration; private _captureSnapshotBuffered; private _captureSnapshot; private get _sessionDuration(); private _clearBufferBeforeMostRecentMeta; private _clearBuffer; private _onBeforeUnload; private _onPageHide; private _onOffline; private _onOnline; private _onVisibilityChange; private _reportStarted; private _isInteractiveEvent; private _updateWindowAndSessionIds; private _clearConditionalRecordingPersistence; get sdkDebugProperties(): Properties; /** * whether rrweb is observing the page, not merely constructed. rrweb returns its * stop handler synchronously even when it defers init() to a document event, so a * recorder that never observed anything would otherwise report itself as attached. */ private get _rrwebAttached(); private _startRecorder; tryAddCustomEvent(tag: string, payload: any): boolean; }