UNPKG

@multiplayer-app/session-recorder-browser

Version:
133 lines 5.03 kB
import { pack } from '@rrweb/packer'; import { record } from 'rrweb'; import { SessionType } from '@multiplayer-app/session-recorder-common'; import { getRecordConsolePlugin } from '@rrweb/rrweb-plugin-console-record'; import { isConsoleEvent } from '../utils'; import { CONTINUOUS_DEBUGGING_TIMEOUT } from '../config'; export class RecorderBrowserSDK { get startedAt() { return this._startedAt; } set startedAt(v) { this._startedAt = v; } get stoppedAt() { return this._stoppedAt; } set stoppedAt(v) { this._stoppedAt = v; } constructor() { this.restartInterval = null; this._startedAt = ''; this._stoppedAt = ''; } /** * Initializes the recorder SDK with configuration settings. * @param config - Configuration settings for the session debugger. * @param socketService - Optional socket service instance for sending events. */ init(config, socketService) { this.config = config; this.socketService = socketService; } /** * Starts recording events for a given session ID. * @param sessionId - The ID of the session to record events for. */ start(sessionId, sessionType) { var _a; if (!this.config) { throw new Error('Configuration not initialized. Call init() before start().'); } const restartInterval = sessionType === SessionType.CONTINUOUS ? CONTINUOUS_DEBUGGING_TIMEOUT : 0; this.startedAt = new Date().toISOString(); // Build masking configuration const maskingConfig = this.config.masking || {}; const options = { maskAllInputs: (_a = maskingConfig.maskAllInputs) !== null && _a !== void 0 ? _a : true, sampling: { canvas: 5 }, recordCanvas: this.config.recordCanvas, dataURLOptions: { type: 'image/webp', quality: 0.1 }, plugins: [ getRecordConsolePlugin({ level: ['log', 'error'] }), ], }; // Add mask input options if provided if (maskingConfig.maskInputOptions) { options.maskInputOptions = maskingConfig.maskInputOptions; } // Add mask text class if provided if (maskingConfig.maskTextClass) { options.maskTextClass = maskingConfig.maskTextClass; } // Add mask text selector if provided if (maskingConfig.maskTextSelector) { options.maskTextSelector = maskingConfig.maskTextSelector; } // Add custom masking functions if provided if (typeof maskingConfig.maskInput === 'function') { options.maskInputFn = maskingConfig.maskInput; } if (typeof maskingConfig.maskText === 'function') { options.maskTextFn = maskingConfig.maskText; } this.stopFn = record({ ...options, emit: async (event) => { if (this.socketService) { if (typeof maskingConfig.maskConsoleEvent === 'function' && isConsoleEvent(event)) { const { data } = event; const maskedPayload = maskingConfig.maskConsoleEvent(data.payload); event.data = { ...data, payload: maskedPayload }; } const packedEvent = pack(event); this.stoppedAt = new Date(event.timestamp).toISOString(); this.socketService.send({ event: packedEvent, eventType: event.type, timestamp: event.timestamp, debugSessionId: sessionId, debugSessionType: sessionType, }); } }, }); // It will sent full snapshot again but it will fix missing first snapshot issue record.takeFullSnapshot(); if (restartInterval > 0) { this.restartInterval = setInterval(() => { record.takeFullSnapshot(); }, restartInterval); } } /** * Restarts the recording of events. */ async restart(sessionId, sessionType) { var _a; (_a = this.stopFn) === null || _a === void 0 ? void 0 : _a.call(this); this.start(sessionId, sessionType); } /** * Clears the restart timeout. */ clearRestartInterval() { if (this.restartInterval) { clearInterval(this.restartInterval); this.restartInterval = null; } } /** * Stops the recording of events. */ stop() { var _a, _b, _c; (_a = this.stopFn) === null || _a === void 0 ? void 0 : _a.call(this); if (!((_b = this.config) === null || _b === void 0 ? void 0 : _b.useWebsocket)) { (_c = this.socketService) === null || _c === void 0 ? void 0 : _c.close(); } this.clearRestartInterval(); } } //# sourceMappingURL=index.js.map