@v-tilt/browser 1.1.5 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/array.js +1 -1
  2. package/dist/array.js.map +1 -1
  3. package/dist/array.no-external.js +1 -1
  4. package/dist/array.no-external.js.map +1 -1
  5. package/dist/entrypoints/array.d.ts +1 -0
  6. package/dist/entrypoints/external-scripts-loader.d.ts +24 -0
  7. package/dist/entrypoints/module.es.d.ts +1 -0
  8. package/dist/entrypoints/recorder.d.ts +23 -0
  9. package/dist/extensions/replay/index.d.ts +13 -0
  10. package/dist/extensions/replay/session-recording-utils.d.ts +92 -0
  11. package/dist/extensions/replay/session-recording-wrapper.d.ts +61 -0
  12. package/dist/extensions/replay/session-recording.d.ts +95 -0
  13. package/dist/extensions/replay/types.d.ts +211 -0
  14. package/dist/external-scripts-loader.js +2 -0
  15. package/dist/external-scripts-loader.js.map +1 -0
  16. package/dist/main.js +1 -1
  17. package/dist/main.js.map +1 -1
  18. package/dist/module.d.ts +264 -5
  19. package/dist/module.js +1 -1
  20. package/dist/module.js.map +1 -1
  21. package/dist/module.no-external.d.ts +264 -5
  22. package/dist/module.no-external.js +1 -1
  23. package/dist/module.no-external.js.map +1 -1
  24. package/dist/recorder.js +2 -0
  25. package/dist/recorder.js.map +1 -0
  26. package/dist/types.d.ts +84 -4
  27. package/dist/utils/globals.d.ts +42 -0
  28. package/dist/vtilt.d.ts +36 -0
  29. package/lib/config.js +2 -0
  30. package/lib/entrypoints/array.d.ts +1 -0
  31. package/lib/entrypoints/array.js +1 -0
  32. package/lib/entrypoints/external-scripts-loader.d.ts +24 -0
  33. package/lib/entrypoints/external-scripts-loader.js +107 -0
  34. package/lib/entrypoints/module.es.d.ts +1 -0
  35. package/lib/entrypoints/module.es.js +1 -0
  36. package/lib/entrypoints/recorder.d.ts +23 -0
  37. package/lib/entrypoints/recorder.js +42 -0
  38. package/lib/extensions/replay/index.d.ts +13 -0
  39. package/lib/extensions/replay/index.js +31 -0
  40. package/lib/extensions/replay/session-recording-utils.d.ts +92 -0
  41. package/lib/extensions/replay/session-recording-utils.js +212 -0
  42. package/lib/extensions/replay/session-recording-wrapper.d.ts +61 -0
  43. package/lib/extensions/replay/session-recording-wrapper.js +149 -0
  44. package/lib/extensions/replay/session-recording.d.ts +95 -0
  45. package/lib/extensions/replay/session-recording.js +700 -0
  46. package/lib/extensions/replay/types.d.ts +211 -0
  47. package/lib/extensions/replay/types.js +8 -0
  48. package/lib/types.d.ts +84 -4
  49. package/lib/utils/globals.d.ts +42 -0
  50. package/lib/utils/globals.js +2 -0
  51. package/lib/vtilt.d.ts +36 -0
  52. package/lib/vtilt.js +106 -0
  53. package/package.json +4 -1
package/dist/types.d.ts CHANGED
@@ -12,6 +12,13 @@ export interface VTiltConfig {
12
12
  api_host?: string;
13
13
  /** UI host for dashboard links */
14
14
  ui_host?: string | null;
15
+ /**
16
+ * Host for loading extension scripts (recorder.js, etc.)
17
+ * Defaults to unpkg CDN: https://unpkg.com/@v-tilt/browser@{version}/dist
18
+ * Can also use jsdelivr: https://cdn.jsdelivr.net/npm/@v-tilt/browser@{version}/dist
19
+ * Or self-hosted: https://your-domain.com/static
20
+ */
21
+ script_host?: string;
15
22
  /** Proxy domain for tracking requests */
16
23
  proxy?: string;
17
24
  /** Full proxy URL for tracking requests */
@@ -64,6 +71,10 @@ export interface VTiltConfig {
64
71
  respect_dnt?: boolean;
65
72
  /** Opt users out by default */
66
73
  opt_out_capturing_by_default?: boolean;
74
+ /** Session recording configuration */
75
+ session_recording?: SessionRecordingOptions;
76
+ /** Disable session recording (convenience flag) */
77
+ disable_session_recording?: boolean;
67
78
  /** Global attributes added to all events */
68
79
  globalAttributes?: Record<string, string>;
69
80
  /** Bootstrap data for initialization */
@@ -176,14 +187,83 @@ export interface RequestOptions {
176
187
  timeout?: number;
177
188
  retry?: boolean;
178
189
  }
190
+ /** Mask options for input elements in session recording */
191
+ export interface SessionRecordingMaskInputOptions {
192
+ color?: boolean;
193
+ date?: boolean;
194
+ "datetime-local"?: boolean;
195
+ email?: boolean;
196
+ month?: boolean;
197
+ number?: boolean;
198
+ range?: boolean;
199
+ search?: boolean;
200
+ tel?: boolean;
201
+ text?: boolean;
202
+ time?: boolean;
203
+ url?: boolean;
204
+ week?: boolean;
205
+ textarea?: boolean;
206
+ select?: boolean;
207
+ password?: boolean;
208
+ }
209
+ /** Session recording configuration */
210
+ export interface SessionRecordingOptions {
211
+ /** Enable session recording */
212
+ enabled?: boolean;
213
+ /** Sample rate (0-1, where 1 = 100%) */
214
+ sampleRate?: number;
215
+ /** Minimum session duration in ms before sending */
216
+ minimumDurationMs?: number;
217
+ /** Session idle threshold in ms (default: 5 minutes) */
218
+ sessionIdleThresholdMs?: number;
219
+ /** Full snapshot interval in ms (default: 5 minutes) */
220
+ fullSnapshotIntervalMs?: number;
221
+ /** Enable console log capture */
222
+ captureConsole?: boolean;
223
+ /** Enable network request capture */
224
+ captureNetwork?: boolean;
225
+ /** Canvas recording settings */
226
+ captureCanvas?: {
227
+ recordCanvas?: boolean;
228
+ canvasFps?: number;
229
+ canvasQuality?: number;
230
+ };
231
+ /** Block class for elements to hide (default: 'vt-no-capture') */
232
+ blockClass?: string;
233
+ /** Block selector for elements to hide */
234
+ blockSelector?: string;
235
+ /** Ignore class for input masking (default: 'vt-ignore-input') */
236
+ ignoreClass?: string;
237
+ /** Mask text class (default: 'vt-mask') */
238
+ maskTextClass?: string;
239
+ /** Mask text selector */
240
+ maskTextSelector?: string;
241
+ /** Mask all inputs (default: true) */
242
+ maskAllInputs?: boolean;
243
+ /** Mask input options */
244
+ maskInputOptions?: SessionRecordingMaskInputOptions;
245
+ /** Masking configuration */
246
+ masking?: {
247
+ maskAllInputs?: boolean;
248
+ maskTextSelector?: string;
249
+ blockSelector?: string;
250
+ };
251
+ /** Record headers in network requests */
252
+ recordHeaders?: boolean;
253
+ /** Record body in network requests */
254
+ recordBody?: boolean;
255
+ /** Compress events before sending (default: true) */
256
+ compressEvents?: boolean;
257
+ /** Internal: Mutation throttler refill rate */
258
+ __mutationThrottlerRefillRate?: number;
259
+ /** Internal: Mutation throttler bucket size */
260
+ __mutationThrottlerBucketSize?: number;
261
+ }
179
262
  export interface RemoteConfig {
180
263
  /** Default to identified_only mode */
181
264
  defaultIdentifiedOnly?: boolean;
182
265
  /** Feature flags */
183
266
  featureFlags?: FeatureFlagsConfig;
184
267
  /** Session recording config */
185
- sessionRecording?: {
186
- enabled?: boolean;
187
- sampleRate?: number;
188
- };
268
+ sessionRecording?: SessionRecordingOptions;
189
269
  }
@@ -1,6 +1,48 @@
1
1
  declare const win: (Window & typeof globalThis) | undefined;
2
+ /**
3
+ * Extension kinds that can be lazy loaded
4
+ */
5
+ export type VTiltExtensionKind = "recorder" | "web-vitals";
6
+ /**
7
+ * Interface for lazy-loaded session recording (set by recorder.ts)
8
+ * Matches LazyLoadedSessionRecordingInterface in session-recording-wrapper.ts
9
+ */
10
+ export interface LazyLoadedSessionRecordingInterface {
11
+ start: (startReason?: string) => void;
12
+ stop: () => void;
13
+ sessionId: string;
14
+ status: string;
15
+ isStarted: boolean;
16
+ onRemoteConfig?: (response: any) => void;
17
+ log: (message: string, level: "log" | "warn" | "error") => void;
18
+ updateConfig: (config: any) => void;
19
+ }
20
+ /**
21
+ * VTilt Extensions interface for dynamically loaded modules
22
+ * This is the contract between lazily loaded extensions and the SDK
23
+ */
24
+ export interface VTiltExtensions {
25
+ /** Load an external dependency script */
26
+ loadExternalDependency?: (instance: any, // VTilt instance - using any to avoid circular imports
27
+ kind: VTiltExtensionKind, callback: (error?: string | Event, event?: Event) => void) => void;
28
+ /** rrweb record function (set by recorder.ts) */
29
+ rrweb?: {
30
+ record: any;
31
+ version?: string;
32
+ };
33
+ /** rrweb plugins (set by recorder.ts) */
34
+ rrwebPlugins?: {
35
+ getRecordConsolePlugin?: () => any;
36
+ getRecordNetworkPlugin?: (options: any) => any;
37
+ };
38
+ /** Factory to create LazyLoadedSessionRecording (set by recorder.ts) */
39
+ initSessionRecording?: (instance: any, config?: any) => LazyLoadedSessionRecordingInterface;
40
+ }
2
41
  export type AssignableWindow = Window & typeof globalThis & {
42
+ /** Main VTilt instance */
3
43
  vt: any;
44
+ /** VTilt Extensions for dynamically loaded modules */
45
+ __VTiltExtensions__?: VTiltExtensions;
4
46
  };
5
47
  export declare const ArrayProto: any[];
6
48
  export declare const nativeForEach: (callbackfn: (value: any, index: number, array: any[]) => void, thisArg?: any) => void;
package/dist/vtilt.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import { VTiltConfig, EventPayload } from "./types";
2
2
  import { HistoryAutocapture } from "./extensions/history-autocapture";
3
+ import { SessionRecordingWrapper } from "./extensions/replay";
3
4
  import { type QueuedRequest } from "./request-queue";
4
5
  export declare class VTilt {
6
+ readonly version = "1.1.5";
5
7
  private configManager;
6
8
  private sessionManager;
7
9
  private userManager;
@@ -10,6 +12,7 @@ export declare class VTilt {
10
12
  private retryQueue;
11
13
  private rateLimiter;
12
14
  historyAutocapture?: HistoryAutocapture;
15
+ sessionRecording?: SessionRecordingWrapper;
13
16
  __loaded: boolean;
14
17
  private _initial_pageview_captured;
15
18
  private _visibility_state_listener;
@@ -236,10 +239,43 @@ export declare class VTilt {
236
239
  * Get current session ID
237
240
  */
238
241
  getSessionId(): string | null;
242
+ /**
243
+ * Get current distinct ID
244
+ */
245
+ getDistinctId(): string;
246
+ /**
247
+ * Get anonymous ID
248
+ */
249
+ getAnonymousId(): string;
239
250
  /**
240
251
  * Update configuration
241
252
  */
242
253
  updateConfig(config: Partial<VTiltConfig>): void;
254
+ /**
255
+ * Initialize session recording
256
+ */
257
+ private _initSessionRecording;
258
+ /**
259
+ * Build session recording config from VTiltConfig
260
+ */
261
+ private _buildSessionRecordingConfig;
262
+ /**
263
+ * Start session recording
264
+ * Call this to manually start recording if it wasn't enabled initially
265
+ */
266
+ startSessionRecording(): void;
267
+ /**
268
+ * Stop session recording
269
+ */
270
+ stopSessionRecording(): void;
271
+ /**
272
+ * Check if session recording is active
273
+ */
274
+ isSessionRecordingActive(): boolean;
275
+ /**
276
+ * Get session recording ID
277
+ */
278
+ getSessionRecordingId(): string | null;
243
279
  /**
244
280
  * _execute_array() deals with processing any vTilt function
245
281
  * calls that were called before the vTilt library was loaded
package/lib/config.js CHANGED
@@ -25,6 +25,8 @@ class ConfigManager {
25
25
  script.getAttribute("data-api-host") ||
26
26
  script.getAttribute("data-host") ||
27
27
  initialConfig.api_host;
28
+ config.script_host =
29
+ script.getAttribute("data-script-host") || initialConfig.script_host;
28
30
  config.proxy = script.getAttribute("data-proxy") || initialConfig.proxy;
29
31
  config.proxyUrl =
30
32
  script.getAttribute("data-proxy-url") || initialConfig.proxyUrl;
@@ -1 +1,2 @@
1
+ import "./external-scripts-loader";
1
2
  import "./array.no-external";
@@ -1,3 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ require("./external-scripts-loader");
3
4
  require("./array.no-external");
@@ -0,0 +1,24 @@
1
+ /**
2
+ * External Scripts Loader
3
+ *
4
+ * Dynamically loads external scripts (like rrweb) from CDN.
5
+ * Based on PostHog's implementation.
6
+ */
7
+ import type { VTilt } from "../vtilt";
8
+ import { VTiltExtensionKind } from "../utils/globals";
9
+ /**
10
+ * Load a script dynamically
11
+ */
12
+ declare const loadScript: (vtilt: VTilt, url: string, callback: (error?: string | Event, event?: Event) => void) => void;
13
+ /**
14
+ * Get the URL for an extension script
15
+ *
16
+ * Priority:
17
+ * 1. script_host config (if set) - loads from {script_host}/dist/{kind}.js
18
+ * 2. Default to unpkg CDN for npm package
19
+ *
20
+ * Note: script_host should be the base URL (e.g., "https://cdn.example.com")
21
+ * The /dist/ path is automatically appended to match the npm package structure
22
+ */
23
+ declare const getExtensionUrl: (vtilt: VTilt, kind: VTiltExtensionKind) => string;
24
+ export { loadScript, getExtensionUrl };
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ /**
3
+ * External Scripts Loader
4
+ *
5
+ * Dynamically loads external scripts (like rrweb) from CDN.
6
+ * Based on PostHog's implementation.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.getExtensionUrl = exports.loadScript = void 0;
10
+ const globals_1 = require("../utils/globals");
11
+ const LOGGER_PREFIX = "[ExternalScriptsLoader]";
12
+ /**
13
+ * Load a script dynamically
14
+ */
15
+ const loadScript = (vtilt, url, callback) => {
16
+ const config = vtilt.getConfig();
17
+ // Check if external script loading is disabled
18
+ if (config.disable_external_dependency_loading) {
19
+ console.warn(`${LOGGER_PREFIX} ${url} was requested but loading of external scripts is disabled.`);
20
+ return callback("Loading of external scripts is disabled");
21
+ }
22
+ // Check if script is already loaded
23
+ const existingScripts = globals_1.document === null || globals_1.document === void 0 ? void 0 : globals_1.document.querySelectorAll("script");
24
+ if (existingScripts) {
25
+ for (let i = 0; i < existingScripts.length; i++) {
26
+ if (existingScripts[i].src === url) {
27
+ const alreadyExistingScriptTag = existingScripts[i];
28
+ if (alreadyExistingScriptTag.__vtilt_loading_callback_fired) {
29
+ // Script already exists and fired its load event
30
+ return callback();
31
+ }
32
+ // Script exists but hasn't loaded yet - attach callback
33
+ alreadyExistingScriptTag.addEventListener("load", (event) => {
34
+ alreadyExistingScriptTag.__vtilt_loading_callback_fired = true;
35
+ callback(undefined, event);
36
+ });
37
+ alreadyExistingScriptTag.onerror = (error) => callback(error);
38
+ return;
39
+ }
40
+ }
41
+ }
42
+ const addScript = () => {
43
+ var _a;
44
+ if (!globals_1.document) {
45
+ return callback("document not found");
46
+ }
47
+ const scriptTag = globals_1.document.createElement("script");
48
+ scriptTag.type = "text/javascript";
49
+ scriptTag.crossOrigin = "anonymous";
50
+ scriptTag.src = url;
51
+ scriptTag.onload = (event) => {
52
+ scriptTag.__vtilt_loading_callback_fired = true;
53
+ callback(undefined, event);
54
+ };
55
+ scriptTag.onerror = (error) => callback(error);
56
+ const scripts = globals_1.document.querySelectorAll("body > script");
57
+ if (scripts.length > 0) {
58
+ (_a = scripts[0].parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(scriptTag, scripts[0]);
59
+ }
60
+ else {
61
+ globals_1.document.body.appendChild(scriptTag);
62
+ }
63
+ };
64
+ if (globals_1.document === null || globals_1.document === void 0 ? void 0 : globals_1.document.body) {
65
+ addScript();
66
+ }
67
+ else {
68
+ globals_1.document === null || globals_1.document === void 0 ? void 0 : globals_1.document.addEventListener("DOMContentLoaded", addScript);
69
+ }
70
+ };
71
+ exports.loadScript = loadScript;
72
+ /**
73
+ * SDK version - used for loading correct script version from CDN
74
+ */
75
+ const SDK_VERSION = "1.1.5";
76
+ /**
77
+ * Get the URL for an extension script
78
+ *
79
+ * Priority:
80
+ * 1. script_host config (if set) - loads from {script_host}/dist/{kind}.js
81
+ * 2. Default to unpkg CDN for npm package
82
+ *
83
+ * Note: script_host should be the base URL (e.g., "https://cdn.example.com")
84
+ * The /dist/ path is automatically appended to match the npm package structure
85
+ */
86
+ const getExtensionUrl = (vtilt, kind) => {
87
+ const config = vtilt.getConfig();
88
+ // Use script_host if configured (matches snippet behavior: script_host+"/dist/array.js")
89
+ if (config.script_host) {
90
+ const cleanHost = config.script_host.replace(/\/+$/gm, "");
91
+ return `${cleanHost}/dist/${kind}.js`;
92
+ }
93
+ // Default: load from unpkg (npm CDN)
94
+ // This serves the file directly from the published @v-tilt/browser package
95
+ return `https://unpkg.com/@v-tilt/browser@${SDK_VERSION}/dist/${kind}.js`;
96
+ };
97
+ exports.getExtensionUrl = getExtensionUrl;
98
+ // Initialize extensions object
99
+ globals_1.assignableWindow.__VTiltExtensions__ =
100
+ globals_1.assignableWindow.__VTiltExtensions__ || {};
101
+ /**
102
+ * Load an external dependency
103
+ */
104
+ globals_1.assignableWindow.__VTiltExtensions__.loadExternalDependency = (vtilt, kind, callback) => {
105
+ const url = getExtensionUrl(vtilt, kind);
106
+ loadScript(vtilt, url, callback);
107
+ };
@@ -1,3 +1,4 @@
1
+ import "./external-scripts-loader";
1
2
  import vt from "./module.no-external.es";
2
3
  export * from "./module.no-external.es";
3
4
  export default vt;
@@ -17,6 +17,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
17
17
  return (mod && mod.__esModule) ? mod : { "default": mod };
18
18
  };
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
+ require("./external-scripts-loader");
20
21
  const module_no_external_es_1 = __importDefault(require("./module.no-external.es"));
21
22
  __exportStar(require("./module.no-external.es"), exports);
22
23
  exports.default = module_no_external_es_1.default;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Recorder Entrypoint
3
+ *
4
+ * This file is built as a separate bundle (recorder.js) that can be
5
+ * lazy-loaded when session recording is enabled.
6
+ *
7
+ * It exports:
8
+ * - rrweb.record: The rrweb record function
9
+ * - rrwebPlugins: Plugins for console recording
10
+ * - initSessionRecording: Factory function to create LazyLoadedSessionRecording
11
+ */
12
+ import { record as rrwebRecord } from "@rrweb/record";
13
+ import { LazyLoadedSessionRecordingInterface } from "../utils/globals";
14
+ import type { SessionRecordingConfig } from "../extensions/replay/types";
15
+ import type { VTilt } from "../vtilt";
16
+ /**
17
+ * Factory function to create a LazyLoadedSessionRecording instance
18
+ *
19
+ * Called by SessionRecordingWrapper after the recorder script is loaded
20
+ */
21
+ declare function initSessionRecording(instance: VTilt, config?: SessionRecordingConfig): LazyLoadedSessionRecordingInterface;
22
+ export { initSessionRecording };
23
+ export default rrwebRecord;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ /**
3
+ * Recorder Entrypoint
4
+ *
5
+ * This file is built as a separate bundle (recorder.js) that can be
6
+ * lazy-loaded when session recording is enabled.
7
+ *
8
+ * It exports:
9
+ * - rrweb.record: The rrweb record function
10
+ * - rrwebPlugins: Plugins for console recording
11
+ * - initSessionRecording: Factory function to create LazyLoadedSessionRecording
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.initSessionRecording = initSessionRecording;
15
+ const record_1 = require("@rrweb/record");
16
+ const rrweb_plugin_console_record_1 = require("@rrweb/rrweb-plugin-console-record");
17
+ const globals_1 = require("../utils/globals");
18
+ const session_recording_1 = require("../extensions/replay/session-recording");
19
+ // Initialize extensions object
20
+ globals_1.assignableWindow.__VTiltExtensions__ =
21
+ globals_1.assignableWindow.__VTiltExtensions__ || {};
22
+ // Register rrweb record function
23
+ globals_1.assignableWindow.__VTiltExtensions__.rrweb = {
24
+ record: record_1.record,
25
+ version: "v2",
26
+ };
27
+ // Register rrweb plugins
28
+ globals_1.assignableWindow.__VTiltExtensions__.rrwebPlugins = {
29
+ getRecordConsolePlugin: rrweb_plugin_console_record_1.getRecordConsolePlugin,
30
+ };
31
+ /**
32
+ * Factory function to create a LazyLoadedSessionRecording instance
33
+ *
34
+ * Called by SessionRecordingWrapper after the recorder script is loaded
35
+ */
36
+ function initSessionRecording(instance, config) {
37
+ return new session_recording_1.LazyLoadedSessionRecording(instance, config);
38
+ }
39
+ // Register the factory function
40
+ globals_1.assignableWindow.__VTiltExtensions__.initSessionRecording =
41
+ initSessionRecording;
42
+ exports.default = record_1.record;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Session Recording Extension
3
+ *
4
+ * Exports for rrweb session recording functionality.
5
+ *
6
+ * Architecture:
7
+ * - SessionRecordingWrapper: Lightweight wrapper in main bundle, handles lazy loading
8
+ * - LazyLoadedSessionRecording: Actual recording logic, loaded on demand via recorder.js
9
+ */
10
+ export { SessionRecordingWrapper, LAZY_LOADING, type SessionRecordingStatus, type LazyLoadedSessionRecordingInterface, } from "./session-recording-wrapper";
11
+ export { LazyLoadedSessionRecording } from "./session-recording";
12
+ export type { SessionRecordingConfig, SessionStartReason, RecordOptions, RRWebRecord, SnapshotBuffer, CanvasRecordingConfig, NetworkPayloadCaptureConfig, MaskingConfig, TriggerType, } from "./types";
13
+ export { compressEvent, estimateSize, truncateLargeConsoleLogs, splitBuffer, isSessionIdleEvent, isRecordingPausedEvent, isInteractiveEvent, RECORDING_MAX_EVENT_SIZE, RECORDING_BUFFER_TIMEOUT, RECORDING_IDLE_THRESHOLD_MS, } from "./session-recording-utils";
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ /**
3
+ * Session Recording Extension
4
+ *
5
+ * Exports for rrweb session recording functionality.
6
+ *
7
+ * Architecture:
8
+ * - SessionRecordingWrapper: Lightweight wrapper in main bundle, handles lazy loading
9
+ * - LazyLoadedSessionRecording: Actual recording logic, loaded on demand via recorder.js
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.RECORDING_IDLE_THRESHOLD_MS = exports.RECORDING_BUFFER_TIMEOUT = exports.RECORDING_MAX_EVENT_SIZE = exports.isInteractiveEvent = exports.isRecordingPausedEvent = exports.isSessionIdleEvent = exports.splitBuffer = exports.truncateLargeConsoleLogs = exports.estimateSize = exports.compressEvent = exports.LazyLoadedSessionRecording = exports.LAZY_LOADING = exports.SessionRecordingWrapper = void 0;
13
+ // Main export - the wrapper that lives in the main bundle
14
+ var session_recording_wrapper_1 = require("./session-recording-wrapper");
15
+ Object.defineProperty(exports, "SessionRecordingWrapper", { enumerable: true, get: function () { return session_recording_wrapper_1.SessionRecordingWrapper; } });
16
+ Object.defineProperty(exports, "LAZY_LOADING", { enumerable: true, get: function () { return session_recording_wrapper_1.LAZY_LOADING; } });
17
+ // Lazy-loaded implementation (only used in recorder.js bundle)
18
+ var session_recording_1 = require("./session-recording");
19
+ Object.defineProperty(exports, "LazyLoadedSessionRecording", { enumerable: true, get: function () { return session_recording_1.LazyLoadedSessionRecording; } });
20
+ // Utilities
21
+ var session_recording_utils_1 = require("./session-recording-utils");
22
+ Object.defineProperty(exports, "compressEvent", { enumerable: true, get: function () { return session_recording_utils_1.compressEvent; } });
23
+ Object.defineProperty(exports, "estimateSize", { enumerable: true, get: function () { return session_recording_utils_1.estimateSize; } });
24
+ Object.defineProperty(exports, "truncateLargeConsoleLogs", { enumerable: true, get: function () { return session_recording_utils_1.truncateLargeConsoleLogs; } });
25
+ Object.defineProperty(exports, "splitBuffer", { enumerable: true, get: function () { return session_recording_utils_1.splitBuffer; } });
26
+ Object.defineProperty(exports, "isSessionIdleEvent", { enumerable: true, get: function () { return session_recording_utils_1.isSessionIdleEvent; } });
27
+ Object.defineProperty(exports, "isRecordingPausedEvent", { enumerable: true, get: function () { return session_recording_utils_1.isRecordingPausedEvent; } });
28
+ Object.defineProperty(exports, "isInteractiveEvent", { enumerable: true, get: function () { return session_recording_utils_1.isInteractiveEvent; } });
29
+ Object.defineProperty(exports, "RECORDING_MAX_EVENT_SIZE", { enumerable: true, get: function () { return session_recording_utils_1.RECORDING_MAX_EVENT_SIZE; } });
30
+ Object.defineProperty(exports, "RECORDING_BUFFER_TIMEOUT", { enumerable: true, get: function () { return session_recording_utils_1.RECORDING_BUFFER_TIMEOUT; } });
31
+ Object.defineProperty(exports, "RECORDING_IDLE_THRESHOLD_MS", { enumerable: true, get: function () { return session_recording_utils_1.RECORDING_IDLE_THRESHOLD_MS; } });
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Session Recording Utilities
3
+ *
4
+ * Utility functions for session recording.
5
+ * Based on PostHog's sessionrecording-utils.ts
6
+ */
7
+ import { EventType, IncrementalSource, eventWithTime } from "@rrweb/types";
8
+ import type { SnapshotBuffer } from "./types";
9
+ export declare const INCREMENTAL_SNAPSHOT_EVENT_TYPE = 3;
10
+ export declare const ONE_KB = 1024;
11
+ export declare const ONE_MB: number;
12
+ export declare const SEVEN_MB: number;
13
+ export declare const PARTIAL_COMPRESSION_THRESHOLD = 1024;
14
+ export declare const RECORDING_MAX_EVENT_SIZE: number;
15
+ export declare const RECORDING_BUFFER_TIMEOUT = 2000;
16
+ export declare const RECORDING_IDLE_THRESHOLD_MS: number;
17
+ /** Active interaction sources */
18
+ export declare const ACTIVE_SOURCES: IncrementalSource[];
19
+ /**
20
+ * Gzip compress data to a base64 string
21
+ */
22
+ export declare function gzipToString(data: unknown): string;
23
+ /**
24
+ * Estimate the size of an object in bytes
25
+ */
26
+ export declare function estimateSize(obj: unknown): number;
27
+ export interface CompressedFullSnapshotEvent {
28
+ type: typeof EventType.FullSnapshot;
29
+ data: string;
30
+ }
31
+ export interface CompressedIncrementalSnapshotEvent {
32
+ type: typeof EventType.IncrementalSnapshot;
33
+ data: {
34
+ source: IncrementalSource;
35
+ texts: string;
36
+ attributes: string;
37
+ removes: string;
38
+ adds: string;
39
+ };
40
+ }
41
+ export interface CompressedIncrementalStyleSnapshotEvent {
42
+ type: typeof EventType.IncrementalSnapshot;
43
+ data: {
44
+ source: typeof IncrementalSource.StyleSheetRule;
45
+ id?: number;
46
+ styleId?: number;
47
+ replace?: string;
48
+ replaceSync?: string;
49
+ adds?: string;
50
+ removes?: string;
51
+ };
52
+ }
53
+ export type CompressedEvent = CompressedFullSnapshotEvent | CompressedIncrementalSnapshotEvent | CompressedIncrementalStyleSnapshotEvent;
54
+ export type CompressedEventWithTime = CompressedEvent & {
55
+ timestamp: number;
56
+ delay?: number;
57
+ cv: "2024-10";
58
+ };
59
+ /**
60
+ * Compress an rrweb event for transmission
61
+ * Only compresses full snapshots and mutation events above threshold
62
+ */
63
+ export declare function compressEvent(event: eventWithTime): eventWithTime | CompressedEventWithTime;
64
+ /**
65
+ * Truncate large console log payloads to prevent excessive data
66
+ */
67
+ export declare function truncateLargeConsoleLogs(event: eventWithTime): eventWithTime;
68
+ /**
69
+ * Split a large buffer into smaller chunks for transmission
70
+ */
71
+ export declare function splitBuffer(buffer: SnapshotBuffer, sizeLimit?: number): SnapshotBuffer[];
72
+ /**
73
+ * Check if an event is a session idle custom event
74
+ */
75
+ export declare function isSessionIdleEvent(event: eventWithTime): event is eventWithTime & {
76
+ data: {
77
+ tag: string;
78
+ payload: unknown;
79
+ };
80
+ };
81
+ /**
82
+ * Check if an event is a recording paused custom event
83
+ */
84
+ export declare function isRecordingPausedEvent(event: eventWithTime): boolean;
85
+ /**
86
+ * Check if an event represents user interaction
87
+ */
88
+ export declare function isInteractiveEvent(event: eventWithTime): boolean;
89
+ /**
90
+ * Clamp a value to a range with logging
91
+ */
92
+ export declare function clampToRange(value: number, min: number, max: number, label: string, defaultValue: number): number;