@multiplayer-app/session-recorder-browser 1.3.16 → 1.3.17-session-buffering.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 (64) hide show
  1. package/dist/browser/index.js +1224 -174
  2. package/dist/config/constants.d.ts +1 -0
  3. package/dist/config/constants.d.ts.map +1 -1
  4. package/dist/config/constants.js +2 -0
  5. package/dist/config/constants.js.map +1 -1
  6. package/dist/config/defaults.d.ts.map +1 -1
  7. package/dist/config/defaults.js +5 -0
  8. package/dist/config/defaults.js.map +1 -1
  9. package/dist/config/session-recorder.d.ts.map +1 -1
  10. package/dist/config/session-recorder.js +6 -1
  11. package/dist/config/session-recorder.js.map +1 -1
  12. package/dist/exporters/index.js +1 -1
  13. package/dist/exporters/index.js.LICENSE.txt +2 -0
  14. package/dist/exporters/index.js.map +1 -1
  15. package/dist/index.js +1216 -175
  16. package/dist/index.js.map +1 -1
  17. package/dist/index.umd.js +1214 -174
  18. package/dist/index.umd.js.map +1 -1
  19. package/dist/otel/index.d.ts +7 -1
  20. package/dist/otel/index.d.ts.map +1 -1
  21. package/dist/otel/index.js +63 -3
  22. package/dist/otel/index.js.map +1 -1
  23. package/dist/patch/fetch.js +2 -2
  24. package/dist/patch/fetch.js.map +1 -1
  25. package/dist/rrweb/index.d.ts +50 -17
  26. package/dist/rrweb/index.d.ts.map +1 -1
  27. package/dist/rrweb/index.js +158 -84
  28. package/dist/rrweb/index.js.map +1 -1
  29. package/dist/services/crashBuffer.service.d.ts +60 -0
  30. package/dist/services/crashBuffer.service.d.ts.map +1 -0
  31. package/dist/services/crashBuffer.service.js +161 -0
  32. package/dist/services/crashBuffer.service.js.map +1 -0
  33. package/dist/services/indexedDb.service.d.ts +72 -0
  34. package/dist/services/indexedDb.service.d.ts.map +1 -0
  35. package/dist/services/indexedDb.service.js +335 -0
  36. package/dist/services/indexedDb.service.js.map +1 -0
  37. package/dist/services/socket.service.d.ts +3 -2
  38. package/dist/services/socket.service.d.ts.map +1 -1
  39. package/dist/services/socket.service.js +8 -1
  40. package/dist/services/socket.service.js.map +1 -1
  41. package/dist/session-recorder.d.ts +12 -1
  42. package/dist/session-recorder.d.ts.map +1 -1
  43. package/dist/session-recorder.js +155 -7
  44. package/dist/session-recorder.js.map +1 -1
  45. package/dist/types/session-recorder.d.ts +20 -0
  46. package/dist/types/session-recorder.d.ts.map +1 -1
  47. package/dist/types/session-recorder.js.map +1 -1
  48. package/dist/utils/index.d.ts +1 -0
  49. package/dist/utils/index.d.ts.map +1 -1
  50. package/dist/utils/index.js +1 -0
  51. package/dist/utils/index.js.map +1 -1
  52. package/dist/utils/storage.d.ts +4 -1
  53. package/dist/utils/storage.d.ts.map +1 -1
  54. package/dist/utils/storage.js +35 -13
  55. package/dist/utils/storage.js.map +1 -1
  56. package/dist/utils/tabId.d.ts +2 -0
  57. package/dist/utils/tabId.d.ts.map +1 -0
  58. package/dist/utils/tabId.js +22 -0
  59. package/dist/utils/tabId.js.map +1 -0
  60. package/package.json +2 -2
  61. package/dist/rrweb/indexedDbService.d.ts +0 -9
  62. package/dist/rrweb/indexedDbService.d.ts.map +0 -1
  63. package/dist/rrweb/indexedDbService.js +0 -54
  64. package/dist/rrweb/indexedDbService.js.map +0 -1
@@ -25023,6 +25023,7 @@ __webpack_require__.r(__webpack_exports__);
25023
25023
  /* harmony export */ SESSION_ID_PROP_NAME: () => (/* binding */ SESSION_ID_PROP_NAME),
25024
25024
  /* harmony export */ SESSION_PROP_NAME: () => (/* binding */ SESSION_PROP_NAME),
25025
25025
  /* harmony export */ SESSION_RESPONSE: () => (/* binding */ SESSION_RESPONSE),
25026
+ /* harmony export */ SESSION_SAVE_BUFFER_EVENT: () => (/* binding */ SESSION_SAVE_BUFFER_EVENT),
25026
25027
  /* harmony export */ SESSION_SHORT_ID_PROP_NAME: () => (/* binding */ SESSION_SHORT_ID_PROP_NAME),
25027
25028
  /* harmony export */ SESSION_STARTED_EVENT: () => (/* binding */ SESSION_STARTED_EVENT),
25028
25029
  /* harmony export */ SESSION_STATE_PROP_NAME: () => (/* binding */ SESSION_STATE_PROP_NAME),
@@ -25044,6 +25045,8 @@ const SESSION_SUBSCRIBE_EVENT = 'debug-session:subscribe';
25044
25045
  const SESSION_UNSUBSCRIBE_EVENT = 'debug-session:unsubscribe';
25045
25046
  const SESSION_AUTO_CREATED = 'debug-session:auto-created';
25046
25047
  const SESSION_ADD_EVENT = 'debug-session:rrweb:add-event';
25048
+ // Backend-triggered flush of client-side crash buffer
25049
+ const SESSION_SAVE_BUFFER_EVENT = 'debug-session:save-buffer';
25047
25050
  const SOCKET_SET_USER_EVENT = 'socket:set-user';
25048
25051
  const DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE = 100000;
25049
25052
  const SESSION_RESPONSE = 'multiplayer-debug-session-response';
@@ -25051,7 +25054,7 @@ const CONTINUOUS_DEBUGGING_TIMEOUT = 60000; // 1 minutes
25051
25054
  const DEBUG_SESSION_MAX_DURATION_SECONDS = 10 * 60 + 30; // TODO: move to shared config otel core
25052
25055
  const REMOTE_SESSION_RECORDING_START = 'remote-session-recording:start';
25053
25056
  const REMOTE_SESSION_RECORDING_STOP = 'remote-session-recording:stop';
25054
- const PACKAGE_VERSION_EXPORT = "1.3.16" || 0;
25057
+ const PACKAGE_VERSION_EXPORT = "1.3.17-session-buffering.0" || 0;
25055
25058
  // Regex patterns for OpenTelemetry ignore URLs
25056
25059
  const OTEL_IGNORE_URLS = [
25057
25060
  // Traces endpoint
@@ -25148,6 +25151,11 @@ const BASE_CONFIG = {
25148
25151
  masking: DEFAULT_MASKING_CONFIG,
25149
25152
  widgetTextOverrides: DEFAULT_WIDGET_TEXT_CONFIG,
25150
25153
  useWebsocket: true,
25154
+ buffering: {
25155
+ enabled: true,
25156
+ windowMinutes: 1,
25157
+ snapshotIntervalMs: 30000,
25158
+ },
25151
25159
  };
25152
25160
 
25153
25161
 
@@ -25178,6 +25186,7 @@ __webpack_require__.r(__webpack_exports__);
25178
25186
  /* harmony export */ SESSION_ID_PROP_NAME: () => (/* reexport safe */ _constants__WEBPACK_IMPORTED_MODULE_0__.SESSION_ID_PROP_NAME),
25179
25187
  /* harmony export */ SESSION_PROP_NAME: () => (/* reexport safe */ _constants__WEBPACK_IMPORTED_MODULE_0__.SESSION_PROP_NAME),
25180
25188
  /* harmony export */ SESSION_RESPONSE: () => (/* reexport safe */ _constants__WEBPACK_IMPORTED_MODULE_0__.SESSION_RESPONSE),
25189
+ /* harmony export */ SESSION_SAVE_BUFFER_EVENT: () => (/* reexport safe */ _constants__WEBPACK_IMPORTED_MODULE_0__.SESSION_SAVE_BUFFER_EVENT),
25181
25190
  /* harmony export */ SESSION_SHORT_ID_PROP_NAME: () => (/* reexport safe */ _constants__WEBPACK_IMPORTED_MODULE_0__.SESSION_SHORT_ID_PROP_NAME),
25182
25191
  /* harmony export */ SESSION_STARTED_EVENT: () => (/* reexport safe */ _constants__WEBPACK_IMPORTED_MODULE_0__.SESSION_STARTED_EVENT),
25183
25192
  /* harmony export */ SESSION_STATE_PROP_NAME: () => (/* reexport safe */ _constants__WEBPACK_IMPORTED_MODULE_0__.SESSION_STATE_PROP_NAME),
@@ -25305,7 +25314,7 @@ const getWidgetTextOverridesConfig = (config, defaultConfig) => {
25305
25314
  };
25306
25315
  };
25307
25316
  const getSessionRecorderConfig = (c) => {
25308
- var _a;
25317
+ var _a, _b, _c, _d, _e, _f, _g;
25309
25318
  if (!c) {
25310
25319
  return _defaults__WEBPACK_IMPORTED_MODULE_1__.BASE_CONFIG;
25311
25320
  }
@@ -25332,6 +25341,11 @@ const getSessionRecorderConfig = (c) => {
25332
25341
  masking: (0,_masking__WEBPACK_IMPORTED_MODULE_2__.getMaskingConfig)(c.masking),
25333
25342
  widgetTextOverrides: getWidgetTextOverridesConfig(c.widgetTextOverrides, _defaults__WEBPACK_IMPORTED_MODULE_1__.BASE_CONFIG.widgetTextOverrides),
25334
25343
  useWebsocket: (0,_validators__WEBPACK_IMPORTED_MODULE_3__.isValidBoolean)(c.useWebsocket, (_a = _defaults__WEBPACK_IMPORTED_MODULE_1__.BASE_CONFIG.useWebsocket) !== null && _a !== void 0 ? _a : false),
25344
+ buffering: {
25345
+ enabled: (_c = (_b = c.buffering) === null || _b === void 0 ? void 0 : _b.enabled) !== null && _c !== void 0 ? _c : _defaults__WEBPACK_IMPORTED_MODULE_1__.BASE_CONFIG.buffering.enabled,
25346
+ windowMinutes: (_e = (_d = c.buffering) === null || _d === void 0 ? void 0 : _d.windowMinutes) !== null && _e !== void 0 ? _e : _defaults__WEBPACK_IMPORTED_MODULE_1__.BASE_CONFIG.buffering.windowMinutes,
25347
+ snapshotIntervalMs: (_g = (_f = c.buffering) === null || _f === void 0 ? void 0 : _f.snapshotIntervalMs) !== null && _g !== void 0 ? _g : _defaults__WEBPACK_IMPORTED_MODULE_1__.BASE_CONFIG.buffering.snapshotIntervalMs,
25348
+ },
25335
25349
  };
25336
25350
  };
25337
25351
 
@@ -25992,14 +26006,19 @@ __webpack_require__.r(__webpack_exports__);
25992
26006
  class TracerBrowserSDK {
25993
26007
  constructor() {
25994
26008
  this.sessionId = '';
26009
+ this.clientId = '';
25995
26010
  this.globalErrorListenersRegistered = false;
25996
26011
  }
25997
- setSessionId(sessionId, sessionType = _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionType.PLAIN) {
26012
+ setSessionId(sessionId, sessionType = _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionType.MANUAL) {
25998
26013
  this.sessionId = sessionId;
25999
- this.idGenerator.setSessionId(sessionId, sessionType);
26014
+ if (!this.idGenerator) {
26015
+ throw new Error('Id generator not initialized');
26016
+ }
26017
+ this.idGenerator.setSessionId(sessionId, sessionType, this.clientId);
26000
26018
  }
26001
26019
  init(options) {
26002
26020
  this.config = options;
26021
+ this.clientId = _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionRecorderSdk.getIdGenerator(_multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.MULTIPLAYER_TRACE_CLIENT_ID_LENGTH)();
26003
26022
  const { application, version, environment } = this.config;
26004
26023
  this.idGenerator = new _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionRecorderIdGenerator();
26005
26024
  this.exporter = new _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionRecorderBrowserTraceExporter({
@@ -26017,6 +26036,7 @@ class TracerBrowserSDK {
26017
26036
  sampler: new _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionRecorderTraceIdRatioBasedSampler(this.config.sampleTraceRatio),
26018
26037
  spanProcessors: [
26019
26038
  this._getSpanSessionIdProcessor(),
26039
+ this._getCrashBufferSpanProcessor(),
26020
26040
  new _opentelemetry_sdk_trace_base__WEBPACK_IMPORTED_MODULE_7__.BatchSpanProcessor(this.exporter),
26021
26041
  ],
26022
26042
  });
@@ -26133,6 +26153,60 @@ class TracerBrowserSDK {
26133
26153
  });
26134
26154
  this._registerGlobalErrorListeners();
26135
26155
  }
26156
+ setCrashBuffer(crashBuffer) {
26157
+ this.crashBuffer = crashBuffer;
26158
+ }
26159
+ _getCrashBufferSpanProcessor() {
26160
+ return {
26161
+ onStart: () => { },
26162
+ onEnd: (span) => {
26163
+ // Only buffer spans when we don't have an active debug session.
26164
+ if (this.sessionId)
26165
+ return;
26166
+ if (!this.crashBuffer)
26167
+ return;
26168
+ try {
26169
+ const now = Date.now();
26170
+ this.crashBuffer.appendOtelSpan({
26171
+ ts: now,
26172
+ span: this._serializeSpan(span),
26173
+ });
26174
+ }
26175
+ catch (_e) {
26176
+ // ignore
26177
+ }
26178
+ },
26179
+ shutdown: () => Promise.resolve(),
26180
+ forceFlush: () => Promise.resolve(),
26181
+ };
26182
+ }
26183
+ _serializeSpan(span) {
26184
+ var _a, _b;
26185
+ const spanContext = ((_a = span === null || span === void 0 ? void 0 : span.spanContext) === null || _a === void 0 ? void 0 : _a.call(span))
26186
+ ? span.spanContext()
26187
+ : span === null || span === void 0 ? void 0 : span._spanContext;
26188
+ return {
26189
+ _spanContext: spanContext,
26190
+ name: span === null || span === void 0 ? void 0 : span.name,
26191
+ kind: span === null || span === void 0 ? void 0 : span.kind,
26192
+ links: span === null || span === void 0 ? void 0 : span.links,
26193
+ ended: span === null || span === void 0 ? void 0 : span.ended,
26194
+ events: span === null || span === void 0 ? void 0 : span.events,
26195
+ status: span === null || span === void 0 ? void 0 : span.status,
26196
+ endTime: span === null || span === void 0 ? void 0 : span.endTime,
26197
+ startTime: span === null || span === void 0 ? void 0 : span.startTime,
26198
+ duration: span === null || span === void 0 ? void 0 : span.duration,
26199
+ attributes: span === null || span === void 0 ? void 0 : span.attributes,
26200
+ parentSpanId: (_b = span === null || span === void 0 ? void 0 : span.parentSpanContext) === null || _b === void 0 ? void 0 : _b.spanId,
26201
+ droppedAttributesCount: span === null || span === void 0 ? void 0 : span.droppedAttributesCount,
26202
+ droppedEventsCount: span === null || span === void 0 ? void 0 : span.droppedEventsCount,
26203
+ droppedLinksCount: span === null || span === void 0 ? void 0 : span.droppedLinksCount,
26204
+ resource: (span === null || span === void 0 ? void 0 : span.resource) ? {
26205
+ attributes: span.resource.attributes,
26206
+ asyncAttributesPending: span.resource.asyncAttributesPending,
26207
+ } : undefined,
26208
+ };
26209
+ }
26136
26210
  start(sessionId, sessionType) {
26137
26211
  if (!this.tracerProvider) {
26138
26212
  throw new Error('Configuration not initialized. Call init() before start().');
@@ -26280,7 +26354,7 @@ __webpack_require__.r(__webpack_exports__);
26280
26354
 
26281
26355
 
26282
26356
 
26283
- function _tryReadFetchBody({ body, url }) {
26357
+ function _tryReadFetchBody({ body, url, }) {
26284
26358
  if ((0,_utils_type_utils__WEBPACK_IMPORTED_MODULE_0__.isNullish)(body)) {
26285
26359
  return null;
26286
26360
  }
@@ -26453,7 +26527,7 @@ if (typeof window !== 'undefined' && typeof window.fetch !== 'undefined') {
26453
26527
  if (!(0,_utils_type_utils__WEBPACK_IMPORTED_MODULE_0__.isNullish)(candidateBody)) {
26454
26528
  const requestBody = _tryReadFetchBody({
26455
26529
  body: candidateBody,
26456
- url: urlStr
26530
+ url: urlStr,
26457
26531
  });
26458
26532
  if ((requestBody === null || requestBody === void 0 ? void 0 : requestBody.length) && new Blob([requestBody]).size <= _configs__WEBPACK_IMPORTED_MODULE_2__.configs.maxCapturingHttpPayloadSize) {
26459
26533
  networkRequest.requestBody = requestBody;
@@ -26655,11 +26729,13 @@ __webpack_require__.r(__webpack_exports__);
26655
26729
  /* harmony export */ RecorderBrowserSDK: () => (/* binding */ RecorderBrowserSDK)
26656
26730
  /* harmony export */ });
26657
26731
  /* harmony import */ var _rrweb_packer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @rrweb/packer */ "../../node_modules/@rrweb/packer/dist/packer.js");
26658
- /* harmony import */ var rrweb__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! rrweb */ "../../node_modules/rrweb/dist/rrweb.js");
26659
- /* harmony import */ var _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @multiplayer-app/session-recorder-common */ "../session-recorder-common/dist/esm/index-browser.js");
26660
- /* harmony import */ var _rrweb_rrweb_plugin_console_record__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @rrweb/rrweb-plugin-console-record */ "../../node_modules/@rrweb/rrweb-plugin-console-record/dist/rrweb-plugin-console-record.js");
26661
- /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils */ "./src/utils/index.ts");
26662
- /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../config */ "./src/config/index.ts");
26732
+ /* harmony import */ var _rrweb_types__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @rrweb/types */ "../../node_modules/@rrweb/types/dist/types.js");
26733
+ /* harmony import */ var rrweb__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! rrweb */ "../../node_modules/rrweb/dist/rrweb.js");
26734
+ /* harmony import */ var _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @multiplayer-app/session-recorder-common */ "../session-recorder-common/dist/esm/index-browser.js");
26735
+ /* harmony import */ var _rrweb_rrweb_plugin_console_record__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @rrweb/rrweb-plugin-console-record */ "../../node_modules/@rrweb/rrweb-plugin-console-record/dist/rrweb-plugin-console-record.js");
26736
+ /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils */ "./src/utils/index.ts");
26737
+ /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../config */ "./src/config/index.ts");
26738
+
26663
26739
 
26664
26740
 
26665
26741
 
@@ -26667,129 +26743,202 @@ __webpack_require__.r(__webpack_exports__);
26667
26743
 
26668
26744
 
26669
26745
  class RecorderBrowserSDK {
26670
- get startedAt() {
26671
- return this._startedAt;
26672
- }
26673
- set startedAt(v) {
26674
- this._startedAt = v;
26675
- }
26676
- get stoppedAt() {
26677
- return this._stoppedAt;
26678
- }
26679
- set stoppedAt(v) {
26680
- this._stoppedAt = v;
26681
- }
26682
26746
  constructor() {
26683
- this.restartInterval = null;
26684
- this._startedAt = '';
26685
- this._stoppedAt = '';
26747
+ this.intervals = {
26748
+ restart: null,
26749
+ bufferSnapshot: null,
26750
+ };
26751
+ this.startedAt = '';
26752
+ this.stoppedAt = '';
26753
+ }
26754
+ /**
26755
+ * Full snapshot.
26756
+ */
26757
+ takeFullSnapshot() {
26758
+ rrweb__WEBPACK_IMPORTED_MODULE_6__.record.takeFullSnapshot();
26686
26759
  }
26687
26760
  /**
26688
- * Initializes the recorder SDK with configuration settings.
26689
- * @param config - Configuration settings for the session debugger.
26690
- * @param socketService - Optional socket service instance for sending events.
26761
+ * Initializes the recorder SDK.
26762
+ * @param config - Configuration settings.
26763
+ * @param socketService - Optional socket service.
26691
26764
  */
26692
26765
  init(config, socketService) {
26693
26766
  this.config = config;
26694
26767
  this.socketService = socketService;
26695
26768
  }
26696
26769
  /**
26697
- * Starts recording events for a given session ID.
26698
- * @param sessionId - The ID of the session to record events for.
26770
+ * Starts recording.
26771
+ * @param sessionId - Session ID or null for buffer-only mode.
26772
+ * @param sessionType - Session type.
26699
26773
  */
26700
26774
  start(sessionId, sessionType) {
26701
- var _a;
26702
26775
  if (!this.config) {
26703
26776
  throw new Error('Configuration not initialized. Call init() before start().');
26704
26777
  }
26705
- const restartInterval = sessionType === _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionType.CONTINUOUS ? _config__WEBPACK_IMPORTED_MODULE_4__.CONTINUOUS_DEBUGGING_TIMEOUT : 0;
26706
26778
  this.startedAt = new Date().toISOString();
26707
- // Build masking configuration
26708
- const maskingConfig = this.config.masking || {};
26779
+ this.stopFn = (0,rrweb__WEBPACK_IMPORTED_MODULE_6__.record)({
26780
+ ...this._buildRecordOptions(),
26781
+ emit: async (event) => {
26782
+ const ts = event.timestamp;
26783
+ if (!sessionId) {
26784
+ await this._handleBufferOnlyEvent(event, ts);
26785
+ return;
26786
+ }
26787
+ this._handleLiveSessionEvent(event, ts, sessionId, sessionType);
26788
+ },
26789
+ });
26790
+ this.takeFullSnapshot();
26791
+ this._setupPeriodicSnapshots(sessionId, sessionType);
26792
+ }
26793
+ /**
26794
+ * Restarts recording. Never throws - library mode constraint.
26795
+ */
26796
+ async restart(sessionId, sessionType) {
26797
+ var _a;
26798
+ try {
26799
+ (_a = this.stopFn) === null || _a === void 0 ? void 0 : _a.call(this);
26800
+ this.start(sessionId, sessionType);
26801
+ }
26802
+ catch (_e) {
26803
+ // Silent failure
26804
+ }
26805
+ }
26806
+ /**
26807
+ * Stops recording and cleans up resources.
26808
+ */
26809
+ stop() {
26810
+ var _a, _b, _c;
26811
+ (_a = this.stopFn) === null || _a === void 0 ? void 0 : _a.call(this);
26812
+ if (!((_b = this.config) === null || _b === void 0 ? void 0 : _b.useWebsocket)) {
26813
+ (_c = this.socketService) === null || _c === void 0 ? void 0 : _c.close();
26814
+ }
26815
+ this._clearAllIntervals();
26816
+ }
26817
+ _clearAllIntervals() {
26818
+ if (this.intervals.restart) {
26819
+ clearInterval(this.intervals.restart);
26820
+ this.intervals.restart = null;
26821
+ }
26822
+ if (this.intervals.bufferSnapshot) {
26823
+ clearInterval(this.intervals.bufferSnapshot);
26824
+ this.intervals.bufferSnapshot = null;
26825
+ }
26826
+ }
26827
+ /**
26828
+ * Sets the crash buffer.
26829
+ * @param crashBuffer - Crash buffer service.
26830
+ */
26831
+ setCrashBuffer(crashBuffer) {
26832
+ this.crashBuffer = crashBuffer;
26833
+ }
26834
+ /**
26835
+ * Mutates event in-place for performance.
26836
+ */
26837
+ _applyConsoleMasking(event) {
26838
+ var _a, _b;
26839
+ const maskFn = (_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.masking) === null || _b === void 0 ? void 0 : _b.maskConsoleEvent;
26840
+ if (typeof maskFn === 'function' && (0,_utils__WEBPACK_IMPORTED_MODULE_4__.isConsoleEvent)(event)) {
26841
+ const pluginEvt = event;
26842
+ const maskedPayload = maskFn(pluginEvt.data.payload);
26843
+ pluginEvt.data = { ...pluginEvt.data, payload: maskedPayload };
26844
+ }
26845
+ }
26846
+ /**
26847
+ * Handles buffer-only event.
26848
+ * @param event - Event.
26849
+ * @param ts - Timestamp.
26850
+ */
26851
+ async _handleBufferOnlyEvent(event, ts) {
26852
+ if (!this.crashBuffer)
26853
+ return;
26854
+ try {
26855
+ this._applyConsoleMasking(event);
26856
+ const packedEvent = (0,_rrweb_packer__WEBPACK_IMPORTED_MODULE_0__.pack)(event);
26857
+ this.stoppedAt = new Date(ts).toISOString();
26858
+ await this.crashBuffer.appendRrwebEvent({
26859
+ ts,
26860
+ isFullSnapshot: event.type === _rrweb_types__WEBPACK_IMPORTED_MODULE_1__.EventType.FullSnapshot,
26861
+ event: {
26862
+ event: packedEvent,
26863
+ eventType: event.type,
26864
+ timestamp: ts,
26865
+ },
26866
+ });
26867
+ }
26868
+ catch (error) {
26869
+ // Silent failure - library constraint
26870
+ }
26871
+ }
26872
+ /**
26873
+ * Handles live session event.
26874
+ * @param event - Event.
26875
+ * @param ts - Timestamp.
26876
+ * @param sessionId - Session ID.
26877
+ * @param sessionType - Session type.
26878
+ */
26879
+ _handleLiveSessionEvent(event, ts, sessionId, sessionType) {
26880
+ if (!this.socketService)
26881
+ return;
26882
+ this._applyConsoleMasking(event);
26883
+ const packedEvent = (0,_rrweb_packer__WEBPACK_IMPORTED_MODULE_0__.pack)(event);
26884
+ this.stoppedAt = new Date(ts).toISOString();
26885
+ this.socketService.send({
26886
+ event: packedEvent,
26887
+ eventType: event.type,
26888
+ timestamp: ts,
26889
+ debugSessionId: sessionId,
26890
+ debugSessionType: sessionType,
26891
+ });
26892
+ }
26893
+ /**
26894
+ * Builds record options.
26895
+ */
26896
+ _buildRecordOptions() {
26897
+ var _a, _b, _c;
26898
+ const maskingConfig = ((_a = this.config) === null || _a === void 0 ? void 0 : _a.masking) || {};
26709
26899
  const options = {
26710
- maskAllInputs: (_a = maskingConfig.maskAllInputs) !== null && _a !== void 0 ? _a : true,
26900
+ maskAllInputs: (_b = maskingConfig.maskAllInputs) !== null && _b !== void 0 ? _b : true,
26711
26901
  sampling: { canvas: 5 },
26712
- recordCanvas: this.config.recordCanvas,
26902
+ recordCanvas: (_c = this.config) === null || _c === void 0 ? void 0 : _c.recordCanvas,
26713
26903
  dataURLOptions: { type: 'image/webp', quality: 0.1 },
26714
- plugins: [
26715
- (0,_rrweb_rrweb_plugin_console_record__WEBPACK_IMPORTED_MODULE_2__.getRecordConsolePlugin)({ level: ['log', 'error'] }),
26716
- ],
26904
+ plugins: [(0,_rrweb_rrweb_plugin_console_record__WEBPACK_IMPORTED_MODULE_3__.getRecordConsolePlugin)({ level: ['log', 'error'] })],
26717
26905
  };
26718
- // Add mask input options if provided
26719
26906
  if (maskingConfig.maskInputOptions) {
26720
26907
  options.maskInputOptions = maskingConfig.maskInputOptions;
26721
26908
  }
26722
- // Add mask text class if provided
26723
26909
  if (maskingConfig.maskTextClass) {
26724
26910
  options.maskTextClass = maskingConfig.maskTextClass;
26725
26911
  }
26726
- // Add mask text selector if provided
26727
26912
  if (maskingConfig.maskTextSelector) {
26728
26913
  options.maskTextSelector = maskingConfig.maskTextSelector;
26729
26914
  }
26730
- // Add custom masking functions if provided
26731
26915
  if (typeof maskingConfig.maskInput === 'function') {
26732
26916
  options.maskInputFn = maskingConfig.maskInput;
26733
26917
  }
26734
26918
  if (typeof maskingConfig.maskText === 'function') {
26735
26919
  options.maskTextFn = maskingConfig.maskText;
26736
26920
  }
26737
- this.stopFn = (0,rrweb__WEBPACK_IMPORTED_MODULE_5__.record)({
26738
- ...options,
26739
- emit: async (event) => {
26740
- if (this.socketService) {
26741
- if (typeof maskingConfig.maskConsoleEvent === 'function' && (0,_utils__WEBPACK_IMPORTED_MODULE_3__.isConsoleEvent)(event)) {
26742
- const { data } = event;
26743
- const maskedPayload = maskingConfig.maskConsoleEvent(data.payload);
26744
- event.data = { ...data, payload: maskedPayload };
26745
- }
26746
- const packedEvent = (0,_rrweb_packer__WEBPACK_IMPORTED_MODULE_0__.pack)(event);
26747
- this.stoppedAt = new Date(event.timestamp).toISOString();
26748
- this.socketService.send({
26749
- event: packedEvent,
26750
- eventType: event.type,
26751
- timestamp: event.timestamp,
26752
- debugSessionId: sessionId,
26753
- debugSessionType: sessionType,
26754
- });
26755
- }
26756
- },
26757
- });
26758
- // It will sent full snapshot again but it will fix missing first snapshot issue
26759
- rrweb__WEBPACK_IMPORTED_MODULE_5__.record.takeFullSnapshot();
26760
- if (restartInterval > 0) {
26761
- this.restartInterval = setInterval(() => {
26762
- rrweb__WEBPACK_IMPORTED_MODULE_5__.record.takeFullSnapshot();
26763
- }, restartInterval);
26764
- }
26921
+ return options;
26765
26922
  }
26766
26923
  /**
26767
- * Restarts the recording of events.
26924
+ * Sets up periodic snapshots.
26925
+ * @param sessionId - Session ID.
26926
+ * @param sessionType - Session type.
26768
26927
  */
26769
- async restart(sessionId, sessionType) {
26770
- var _a;
26771
- (_a = this.stopFn) === null || _a === void 0 ? void 0 : _a.call(this);
26772
- this.start(sessionId, sessionType);
26773
- }
26774
- /**
26775
- * Clears the restart timeout.
26776
- */
26777
- clearRestartInterval() {
26778
- if (this.restartInterval) {
26779
- clearInterval(this.restartInterval);
26780
- this.restartInterval = null;
26928
+ _setupPeriodicSnapshots(sessionId, sessionType) {
26929
+ var _a, _b;
26930
+ this._clearAllIntervals();
26931
+ if (sessionType === _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_2__.SessionType.CONTINUOUS) {
26932
+ this.intervals.restart = setInterval(() => {
26933
+ this.takeFullSnapshot();
26934
+ }, _config__WEBPACK_IMPORTED_MODULE_5__.CONTINUOUS_DEBUGGING_TIMEOUT);
26781
26935
  }
26782
- }
26783
- /**
26784
- * Stops the recording of events.
26785
- */
26786
- stop() {
26787
- var _a, _b, _c;
26788
- (_a = this.stopFn) === null || _a === void 0 ? void 0 : _a.call(this);
26789
- if (!((_b = this.config) === null || _b === void 0 ? void 0 : _b.useWebsocket)) {
26790
- (_c = this.socketService) === null || _c === void 0 ? void 0 : _c.close();
26936
+ if (!sessionId && ((_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.buffering) === null || _b === void 0 ? void 0 : _b.enabled)) {
26937
+ const interval = this.config.buffering.snapshotIntervalMs || 30000;
26938
+ this.intervals.bufferSnapshot = setInterval(() => {
26939
+ this.takeFullSnapshot();
26940
+ }, interval);
26791
26941
  }
26792
- this.clearRestartInterval();
26793
26942
  }
26794
26943
  }
26795
26944
 
@@ -26942,6 +27091,530 @@ class ApiService {
26942
27091
  }
26943
27092
 
26944
27093
 
27094
+ /***/ }),
27095
+
27096
+ /***/ "./src/services/crashBuffer.service.ts":
27097
+ /*!*********************************************!*\
27098
+ !*** ./src/services/crashBuffer.service.ts ***!
27099
+ \*********************************************/
27100
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
27101
+
27102
+ "use strict";
27103
+ __webpack_require__.r(__webpack_exports__);
27104
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
27105
+ /* harmony export */ CrashBufferService: () => (/* binding */ CrashBufferService)
27106
+ /* harmony export */ });
27107
+ class CrashBufferService {
27108
+ constructor(db, tabId, windowMs) {
27109
+ this.db = db;
27110
+ this.tabId = tabId;
27111
+ this.windowMs = windowMs;
27112
+ this.lastPruneAt = 0;
27113
+ this.pruneInFlight = null;
27114
+ this.isActive = true;
27115
+ this.frozenAtTs = null;
27116
+ this.lastSeenEventTs = 0;
27117
+ this.requiresFullSnapshot = true;
27118
+ this.lastTouchAt = 0;
27119
+ }
27120
+ async _safe(fn, fallback) {
27121
+ try {
27122
+ return await fn();
27123
+ }
27124
+ catch (_e) {
27125
+ return fallback;
27126
+ }
27127
+ }
27128
+ async setAttrs(attrs) {
27129
+ await this._safe(async () => {
27130
+ await this.db.setAttrs({
27131
+ tabId: this.tabId,
27132
+ ...attrs,
27133
+ });
27134
+ }, undefined);
27135
+ }
27136
+ async appendRrwebEvent(payload) {
27137
+ this.lastSeenEventTs = Math.max(this.lastSeenEventTs, payload.ts || 0);
27138
+ if (!this.isActive)
27139
+ return;
27140
+ const isFullSnapshot = Boolean(payload.isFullSnapshot);
27141
+ if (this.requiresFullSnapshot && !isFullSnapshot) {
27142
+ // Buffer must always start with a full snapshot; drop incrementals until we see one.
27143
+ return;
27144
+ }
27145
+ await this._safe(async () => {
27146
+ await this.db.appendRrwebEvent({
27147
+ tabId: this.tabId,
27148
+ ts: payload.ts,
27149
+ isFullSnapshot: payload.isFullSnapshot,
27150
+ event: payload.event,
27151
+ });
27152
+ }, undefined);
27153
+ if (isFullSnapshot && this.requiresFullSnapshot) {
27154
+ // Ensure this snapshot becomes the first replayable event.
27155
+ // We keep the snapshot itself and prune everything older.
27156
+ await this._safe(() => this.db.pruneOlderThan(this.tabId, Math.max(0, payload.ts - 1)), undefined);
27157
+ this.requiresFullSnapshot = false;
27158
+ }
27159
+ else if (isFullSnapshot) {
27160
+ this.requiresFullSnapshot = false;
27161
+ }
27162
+ this.pruneSoon();
27163
+ }
27164
+ async appendOtelSpan(payload) {
27165
+ this.lastSeenEventTs = Math.max(this.lastSeenEventTs, payload.ts || 0);
27166
+ if (!this.isActive)
27167
+ return;
27168
+ await this._safe(async () => {
27169
+ await this.db.appendOtelSpan({
27170
+ tabId: this.tabId,
27171
+ ts: payload.ts,
27172
+ span: payload.span,
27173
+ });
27174
+ }, undefined);
27175
+ this.pruneSoon();
27176
+ }
27177
+ async snapshot(now = Date.now()) {
27178
+ const toTs = now;
27179
+ const fromTs = Math.max(0, toTs - this.windowMs);
27180
+ // Always include a full snapshot "anchor" if one exists at/before the window start.
27181
+ const rrwebFromTs = await this._safe(async () => {
27182
+ const anchor = await this.db.getLastRrwebFullSnapshotBefore(this.tabId, fromTs);
27183
+ return typeof (anchor === null || anchor === void 0 ? void 0 : anchor.ts) === 'number' ? anchor.ts : fromTs;
27184
+ }, fromTs);
27185
+ const [rrweb, spans, attrs] = await Promise.all([
27186
+ this._safe(() => this.db.getRrwebEventsWindow(this.tabId, rrwebFromTs, toTs), []),
27187
+ this._safe(() => this.db.getOtelSpansWindow(this.tabId, fromTs, toTs), []),
27188
+ this._safe(() => this.db.getAttrs(this.tabId), null),
27189
+ ]);
27190
+ const rrwebSorted = rrweb
27191
+ .sort((a, b) => a.ts - b.ts)
27192
+ .map((r) => ({ ts: r.ts, isFullSnapshot: r.isFullSnapshot, event: r.event }));
27193
+ // Hard guarantee: snapshot payload starts with a FullSnapshot (or is empty).
27194
+ const firstFullSnapshotIdx = rrwebSorted.findIndex((e) => Boolean(e.isFullSnapshot));
27195
+ const rrwebEvents = firstFullSnapshotIdx >= 0 ? rrwebSorted.slice(firstFullSnapshotIdx) : [];
27196
+ // Align spans with the rrweb replay start: spans must start from the FullSnapshot timestamp.
27197
+ const replayStartTs = rrwebEvents.length > 0 ? rrwebEvents[0].ts : fromTs;
27198
+ const otelSpans = spans
27199
+ .filter((s) => typeof (s === null || s === void 0 ? void 0 : s.ts) === 'number' && s.ts >= replayStartTs)
27200
+ .sort((a, b) => a.ts - b.ts)
27201
+ .map((r) => ({ ts: r.ts, span: r.span }));
27202
+ return {
27203
+ rrwebEvents,
27204
+ otelSpans,
27205
+ attrs: attrs ? {
27206
+ sessionAttributes: attrs.sessionAttributes,
27207
+ resourceAttributes: attrs.resourceAttributes,
27208
+ userAttributes: attrs.userAttributes,
27209
+ } : null,
27210
+ windowMs: this.windowMs,
27211
+ fromTs: replayStartTs,
27212
+ toTs,
27213
+ };
27214
+ }
27215
+ async clear() {
27216
+ await this._safe(() => this.db.clearTab(this.tabId), undefined);
27217
+ this.requiresFullSnapshot = true;
27218
+ }
27219
+ needsFullSnapshot() {
27220
+ return this.requiresFullSnapshot;
27221
+ }
27222
+ /**
27223
+ * Mark the tab as active/inactive.
27224
+ *
27225
+ * - When inactive, we freeze the buffer and keep the last active `windowMs` indefinitely.
27226
+ * - When re-activated, we resume buffering but require a new FullSnapshot to start a replayable segment.
27227
+ */
27228
+ setActive(active) {
27229
+ if (this.isActive === active)
27230
+ return;
27231
+ this.isActive = active;
27232
+ if (!active) {
27233
+ const freezeAt = this.lastSeenEventTs || Date.now();
27234
+ this.frozenAtTs = freezeAt;
27235
+ // Keep the last active window, but preserve rrweb replayability via snapshot anchor.
27236
+ const cutoff = Math.max(0, freezeAt - this.windowMs);
27237
+ void this._safe(() => this.db.pruneOlderThanWithRrwebSnapshotAnchor(this.tabId, cutoff), undefined);
27238
+ return;
27239
+ }
27240
+ const wasFrozen = this.frozenAtTs !== null;
27241
+ this.frozenAtTs = null;
27242
+ // New active segment must start with a full snapshot (don’t stitch segments together).
27243
+ if (wasFrozen)
27244
+ this.requiresFullSnapshot = true;
27245
+ this.pruneSoon();
27246
+ }
27247
+ pruneSoon() {
27248
+ if (!this.isActive)
27249
+ return;
27250
+ const now = Date.now();
27251
+ // Throttle pruning to avoid hammering IDB on high event rates
27252
+ if (now - this.lastPruneAt < 2000)
27253
+ return;
27254
+ if (this.pruneInFlight)
27255
+ return;
27256
+ this.lastPruneAt = now;
27257
+ const cutoff = Math.max(0, now - this.windowMs);
27258
+ // Heartbeat so the stale-tab sweeper never deletes active tabs.
27259
+ if (now - this.lastTouchAt > 30000) {
27260
+ this.lastTouchAt = now;
27261
+ void this._safe(() => this.db.touchTab(this.tabId, now), undefined);
27262
+ }
27263
+ this.pruneInFlight = this._safe(() => this.db.pruneOlderThanWithRrwebSnapshotAnchor(this.tabId, cutoff), undefined)
27264
+ .finally(() => { this.pruneInFlight = null; });
27265
+ }
27266
+ }
27267
+
27268
+
27269
+ /***/ }),
27270
+
27271
+ /***/ "./src/services/indexedDb.service.ts":
27272
+ /*!*******************************************!*\
27273
+ !*** ./src/services/indexedDb.service.ts ***!
27274
+ \*******************************************/
27275
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
27276
+
27277
+ "use strict";
27278
+ __webpack_require__.r(__webpack_exports__);
27279
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
27280
+ /* harmony export */ IndexedDBService: () => (/* binding */ IndexedDBService)
27281
+ /* harmony export */ });
27282
+ const dbName = 'mpEventsDB';
27283
+ const dbVersion = 2;
27284
+ const legacyStoreName = 'mpEventsStore';
27285
+ const rrwebEventsStore = 'rrwebEvents';
27286
+ const otelSpansStore = 'otelSpans';
27287
+ const attrsStore = 'crashBufferAttrs';
27288
+ class IndexedDBService {
27289
+ constructor() {
27290
+ this.dbPromise = this.openDB();
27291
+ }
27292
+ openDB() {
27293
+ return new Promise((resolve, reject) => {
27294
+ const request = indexedDB.open(dbName, dbVersion);
27295
+ request.onupgradeneeded = () => {
27296
+ const db = request.result;
27297
+ // Keep the legacy store if it exists to avoid breaking older versions.
27298
+ if (!db.objectStoreNames.contains(legacyStoreName)) {
27299
+ db.createObjectStore(legacyStoreName, { keyPath: 'id', autoIncrement: true });
27300
+ }
27301
+ if (!db.objectStoreNames.contains(rrwebEventsStore)) {
27302
+ const store = db.createObjectStore(rrwebEventsStore, { keyPath: 'id', autoIncrement: true });
27303
+ store.createIndex('tabId_ts', ['tabId', 'ts'], { unique: false });
27304
+ }
27305
+ if (!db.objectStoreNames.contains(otelSpansStore)) {
27306
+ const store = db.createObjectStore(otelSpansStore, { keyPath: 'id', autoIncrement: true });
27307
+ store.createIndex('tabId_ts', ['tabId', 'ts'], { unique: false });
27308
+ }
27309
+ if (!db.objectStoreNames.contains(attrsStore)) {
27310
+ db.createObjectStore(attrsStore, { keyPath: 'tabId' });
27311
+ }
27312
+ };
27313
+ request.onsuccess = () => resolve(request.result);
27314
+ request.onerror = () => reject(request.error);
27315
+ });
27316
+ }
27317
+ /**
27318
+ * @deprecated Prefer `appendRrwebEvent(tabId, ...)` and `getRrwebEventsWindow(...)`.
27319
+ * This writes into the legacy store with no pruning semantics.
27320
+ */
27321
+ async saveEvent(event) {
27322
+ const db = await this.dbPromise;
27323
+ return new Promise((resolve, reject) => {
27324
+ const tx = db.transaction(legacyStoreName, 'readwrite');
27325
+ const store = tx.objectStore(legacyStoreName);
27326
+ store.add({ event });
27327
+ tx.oncomplete = () => resolve();
27328
+ tx.onerror = () => reject(tx.error);
27329
+ });
27330
+ }
27331
+ /**
27332
+ * @deprecated Prefer `getRrwebEventsWindow(...)`.
27333
+ */
27334
+ async getAllEvents() {
27335
+ const db = await this.dbPromise;
27336
+ return new Promise((resolve, reject) => {
27337
+ const tx = db.transaction(legacyStoreName, 'readonly');
27338
+ const store = tx.objectStore(legacyStoreName);
27339
+ const request = store.getAll();
27340
+ request.onsuccess = () => {
27341
+ const events = request.result.map((record) => record.event);
27342
+ resolve(events);
27343
+ };
27344
+ request.onerror = () => reject(request.error);
27345
+ });
27346
+ }
27347
+ /**
27348
+ * @deprecated Prefer `clearTab(tabId)`.
27349
+ */
27350
+ async clearEvents() {
27351
+ const db = await this.dbPromise;
27352
+ return new Promise((resolve, reject) => {
27353
+ const tx = db.transaction(legacyStoreName, 'readwrite');
27354
+ const store = tx.objectStore(legacyStoreName);
27355
+ store.clear();
27356
+ tx.oncomplete = () => resolve();
27357
+ tx.onerror = () => reject(tx.error);
27358
+ });
27359
+ }
27360
+ async setAttrs(attrs) {
27361
+ var _a;
27362
+ const db = await this.dbPromise;
27363
+ const payload = {
27364
+ ...attrs,
27365
+ updatedAt: (_a = attrs.updatedAt) !== null && _a !== void 0 ? _a : Date.now(),
27366
+ };
27367
+ return new Promise((resolve, reject) => {
27368
+ const tx = db.transaction(attrsStore, 'readwrite');
27369
+ tx.objectStore(attrsStore).put(payload);
27370
+ tx.oncomplete = () => resolve();
27371
+ tx.onerror = () => reject(tx.error);
27372
+ });
27373
+ }
27374
+ async getAttrs(tabId) {
27375
+ const db = await this.dbPromise;
27376
+ return new Promise((resolve, reject) => {
27377
+ const tx = db.transaction(attrsStore, 'readonly');
27378
+ const request = tx.objectStore(attrsStore).get(tabId);
27379
+ request.onsuccess = () => resolve(request.result || null);
27380
+ request.onerror = () => reject(request.error);
27381
+ });
27382
+ }
27383
+ async getAllAttrs() {
27384
+ const db = await this.dbPromise;
27385
+ return new Promise((resolve, reject) => {
27386
+ const tx = db.transaction(attrsStore, 'readonly');
27387
+ const request = tx.objectStore(attrsStore).getAll();
27388
+ request.onsuccess = () => resolve(request.result || []);
27389
+ request.onerror = () => reject(request.error);
27390
+ });
27391
+ }
27392
+ /**
27393
+ * Updates `updatedAt` for the tab without clobbering existing attributes.
27394
+ */
27395
+ async touchTab(tabId, updatedAt = Date.now()) {
27396
+ const db = await this.dbPromise;
27397
+ return new Promise((resolve, reject) => {
27398
+ const tx = db.transaction(attrsStore, 'readwrite');
27399
+ const store = tx.objectStore(attrsStore);
27400
+ const getReq = store.get(tabId);
27401
+ getReq.onsuccess = () => {
27402
+ const existing = (getReq.result || null);
27403
+ const next = existing
27404
+ ? { ...existing, updatedAt }
27405
+ : { tabId, updatedAt };
27406
+ store.put(next);
27407
+ };
27408
+ getReq.onerror = () => reject(getReq.error);
27409
+ tx.oncomplete = () => resolve();
27410
+ tx.onerror = () => reject(tx.error);
27411
+ });
27412
+ }
27413
+ /**
27414
+ * Best-effort garbage collection for orphaned tabs.
27415
+ * Deletes all data for tabs whose `attrs.updatedAt` is older than `maxAgeMs`.
27416
+ */
27417
+ async sweepStaleTabs(maxAgeMs, now = Date.now()) {
27418
+ const attrs = await this.getAllAttrs().catch(() => []);
27419
+ if (!attrs.length)
27420
+ return 0;
27421
+ const stale = attrs
27422
+ .filter((a) => typeof (a === null || a === void 0 ? void 0 : a.updatedAt) === 'number' && now - a.updatedAt > maxAgeMs)
27423
+ .map((a) => a.tabId);
27424
+ let cleared = 0;
27425
+ for (const tabId of stale) {
27426
+ try {
27427
+ await this.clearTab(tabId);
27428
+ cleared += 1;
27429
+ }
27430
+ catch (_e) {
27431
+ // best effort
27432
+ }
27433
+ }
27434
+ return cleared;
27435
+ }
27436
+ async appendRrwebEvent(record) {
27437
+ const db = await this.dbPromise;
27438
+ return new Promise((resolve, reject) => {
27439
+ const tx = db.transaction(rrwebEventsStore, 'readwrite');
27440
+ tx.objectStore(rrwebEventsStore).add(record);
27441
+ tx.oncomplete = () => resolve();
27442
+ tx.onerror = () => reject(tx.error);
27443
+ });
27444
+ }
27445
+ async appendOtelSpan(record) {
27446
+ const db = await this.dbPromise;
27447
+ return new Promise((resolve, reject) => {
27448
+ const tx = db.transaction(otelSpansStore, 'readwrite');
27449
+ tx.objectStore(otelSpansStore).add(record);
27450
+ tx.oncomplete = () => resolve();
27451
+ tx.onerror = () => reject(tx.error);
27452
+ });
27453
+ }
27454
+ async getRrwebEventsWindow(tabId, fromTs, toTs) {
27455
+ const db = await this.dbPromise;
27456
+ const range = IDBKeyRange.bound([tabId, fromTs], [tabId, toTs]);
27457
+ return new Promise((resolve, reject) => {
27458
+ const tx = db.transaction(rrwebEventsStore, 'readonly');
27459
+ const idx = tx.objectStore(rrwebEventsStore).index('tabId_ts');
27460
+ const req = idx.getAll(range);
27461
+ req.onsuccess = () => resolve(req.result || []);
27462
+ req.onerror = () => reject(req.error);
27463
+ });
27464
+ }
27465
+ /**
27466
+ * Returns the last (highest-ts) FullSnapshot record at/before `cutoffTs`.
27467
+ * Used to keep a replayable anchor when pruning.
27468
+ */
27469
+ async getLastRrwebFullSnapshotBefore(tabId, cutoffTs) {
27470
+ const db = await this.dbPromise;
27471
+ const range = IDBKeyRange.bound([tabId, 0], [tabId, cutoffTs]);
27472
+ return new Promise((resolve, reject) => {
27473
+ const tx = db.transaction(rrwebEventsStore, 'readonly');
27474
+ const idx = tx.objectStore(rrwebEventsStore).index('tabId_ts');
27475
+ const req = idx.openCursor(range, 'prev');
27476
+ req.onsuccess = () => {
27477
+ const cursor = req.result;
27478
+ if (!cursor) {
27479
+ resolve(null);
27480
+ return;
27481
+ }
27482
+ const value = cursor.value;
27483
+ if (value === null || value === void 0 ? void 0 : value.isFullSnapshot) {
27484
+ resolve(value);
27485
+ return;
27486
+ }
27487
+ cursor.continue();
27488
+ };
27489
+ req.onerror = () => reject(req.error);
27490
+ });
27491
+ }
27492
+ async getOtelSpansWindow(tabId, fromTs, toTs) {
27493
+ const db = await this.dbPromise;
27494
+ const range = IDBKeyRange.bound([tabId, fromTs], [tabId, toTs]);
27495
+ return new Promise((resolve, reject) => {
27496
+ const tx = db.transaction(otelSpansStore, 'readonly');
27497
+ const idx = tx.objectStore(otelSpansStore).index('tabId_ts');
27498
+ const req = idx.getAll(range);
27499
+ req.onsuccess = () => resolve(req.result || []);
27500
+ req.onerror = () => reject(req.error);
27501
+ });
27502
+ }
27503
+ async pruneOlderThan(tabId, cutoffTs) {
27504
+ const db = await this.dbPromise;
27505
+ const rrwebRange = IDBKeyRange.bound([tabId, 0], [tabId, cutoffTs]);
27506
+ const spansRange = IDBKeyRange.bound([tabId, 0], [tabId, cutoffTs]);
27507
+ const pruneStore = (store, range) => new Promise((resolve, reject) => {
27508
+ const idx = store.index('tabId_ts');
27509
+ const req = idx.openCursor(range);
27510
+ req.onsuccess = () => {
27511
+ const cursor = req.result;
27512
+ if (!cursor) {
27513
+ resolve();
27514
+ return;
27515
+ }
27516
+ cursor.delete();
27517
+ cursor.continue();
27518
+ };
27519
+ req.onerror = () => reject(req.error);
27520
+ });
27521
+ return new Promise((resolve, reject) => {
27522
+ const tx = db.transaction([rrwebEventsStore, otelSpansStore], 'readwrite');
27523
+ const rrwebStore = tx.objectStore(rrwebEventsStore);
27524
+ const spanStore = tx.objectStore(otelSpansStore);
27525
+ Promise.all([
27526
+ pruneStore(rrwebStore, rrwebRange),
27527
+ pruneStore(spanStore, spansRange),
27528
+ ]).then(() => {
27529
+ // noop; completion is signaled by tx.oncomplete
27530
+ }).catch((e) => {
27531
+ reject(e);
27532
+ });
27533
+ tx.oncomplete = () => resolve();
27534
+ tx.onerror = () => reject(tx.error);
27535
+ });
27536
+ }
27537
+ /**
27538
+ * Prune older data while keeping rrweb replayability:
27539
+ * - rrweb: keep the last FullSnapshot at/before cutoff as an "anchor"
27540
+ * - spans: prune strictly by cutoff
27541
+ */
27542
+ async pruneOlderThanWithRrwebSnapshotAnchor(tabId, cutoffTs) {
27543
+ const db = await this.dbPromise;
27544
+ const anchor = await this.getLastRrwebFullSnapshotBefore(tabId, cutoffTs);
27545
+ // rrweb: delete everything strictly older than the anchor snapshot (keep the anchor itself)
27546
+ // spans: delete everything older than cutoffTs
27547
+ const rrwebCutoffTs = typeof (anchor === null || anchor === void 0 ? void 0 : anchor.ts) === 'number' ? Math.max(0, anchor.ts - 1) : cutoffTs;
27548
+ const rrwebRange = IDBKeyRange.bound([tabId, 0], [tabId, rrwebCutoffTs]);
27549
+ const spansRange = IDBKeyRange.bound([tabId, 0], [tabId, cutoffTs]);
27550
+ const pruneStore = (store, range) => new Promise((resolve, reject) => {
27551
+ const idx = store.index('tabId_ts');
27552
+ const req = idx.openCursor(range);
27553
+ req.onsuccess = () => {
27554
+ const cursor = req.result;
27555
+ if (!cursor) {
27556
+ resolve();
27557
+ return;
27558
+ }
27559
+ cursor.delete();
27560
+ cursor.continue();
27561
+ };
27562
+ req.onerror = () => reject(req.error);
27563
+ });
27564
+ return new Promise((resolve, reject) => {
27565
+ const tx = db.transaction([rrwebEventsStore, otelSpansStore], 'readwrite');
27566
+ const rrwebStore = tx.objectStore(rrwebEventsStore);
27567
+ const spanStore = tx.objectStore(otelSpansStore);
27568
+ Promise.all([
27569
+ pruneStore(rrwebStore, rrwebRange),
27570
+ pruneStore(spanStore, spansRange),
27571
+ ]).then(() => {
27572
+ // noop
27573
+ }).catch((e) => reject(e));
27574
+ tx.oncomplete = () => resolve();
27575
+ tx.onerror = () => reject(tx.error);
27576
+ });
27577
+ }
27578
+ async clearTab(tabId) {
27579
+ const db = await this.dbPromise;
27580
+ const allRange = IDBKeyRange.bound([tabId, 0], [tabId, Number.MAX_SAFE_INTEGER]);
27581
+ const clearByTab = (store) => new Promise((resolve, reject) => {
27582
+ const idx = store.index('tabId_ts');
27583
+ const req = idx.openCursor(allRange);
27584
+ req.onsuccess = () => {
27585
+ const cursor = req.result;
27586
+ if (!cursor) {
27587
+ resolve();
27588
+ return;
27589
+ }
27590
+ cursor.delete();
27591
+ cursor.continue();
27592
+ };
27593
+ req.onerror = () => reject(req.error);
27594
+ });
27595
+ return new Promise((resolve, reject) => {
27596
+ const tx = db.transaction([rrwebEventsStore, otelSpansStore, attrsStore], 'readwrite');
27597
+ const rrwebStore = tx.objectStore(rrwebEventsStore);
27598
+ const spanStore = tx.objectStore(otelSpansStore);
27599
+ const attr = tx.objectStore(attrsStore);
27600
+ Promise.all([
27601
+ clearByTab(rrwebStore),
27602
+ clearByTab(spanStore),
27603
+ new Promise((res, rej) => {
27604
+ const r = attr.delete(tabId);
27605
+ r.onsuccess = () => res();
27606
+ r.onerror = () => rej(r.error);
27607
+ }),
27608
+ ]).then(() => {
27609
+ // noop
27610
+ }).catch((e) => reject(e));
27611
+ tx.oncomplete = () => resolve();
27612
+ tx.onerror = () => reject(tx.error);
27613
+ });
27614
+ }
27615
+ }
27616
+
27617
+
26945
27618
  /***/ }),
26946
27619
 
26947
27620
  /***/ "./src/services/messaging.service.ts":
@@ -27064,15 +27737,17 @@ __webpack_require__.r(__webpack_exports__);
27064
27737
  /* harmony export */ SocketService: () => (/* binding */ SocketService)
27065
27738
  /* harmony export */ });
27066
27739
  /* harmony import */ var socket_io_client__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! socket.io-client */ "../../node_modules/socket.io-client/build/esm/index.js");
27067
- /* harmony import */ var lib0_observable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! lib0/observable */ "../../node_modules/lib0/observable.js");
27740
+ /* harmony import */ var lib0_observable__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! lib0/observable */ "../../node_modules/lib0/observable.js");
27068
27741
  /* harmony import */ var _services_messaging_service__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../services/messaging.service */ "./src/services/messaging.service.ts");
27069
27742
  /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../config */ "./src/config/index.ts");
27743
+ /* harmony import */ var _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @multiplayer-app/session-recorder-common */ "../session-recorder-common/dist/esm/index-browser.js");
27744
+
27070
27745
 
27071
27746
 
27072
27747
 
27073
27748
 
27074
27749
  const MAX_RECONNECTION_ATTEMPTS = 2;
27075
- class SocketService extends lib0_observable__WEBPACK_IMPORTED_MODULE_3__.Observable {
27750
+ class SocketService extends lib0_observable__WEBPACK_IMPORTED_MODULE_4__.Observable {
27076
27751
  constructor() {
27077
27752
  super();
27078
27753
  this.socket = null;
@@ -27139,6 +27814,9 @@ class SocketService extends lib0_observable__WEBPACK_IMPORTED_MODULE_3__.Observa
27139
27814
  path: '/v0/radar/ws',
27140
27815
  auth: {
27141
27816
  'x-api-key': this.options.apiKey,
27817
+ ...this.options.clientId
27818
+ ? { [_multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_3__.ATTR_MULTIPLAYER_SESSION_CLIENT_ID]: this.options.clientId }
27819
+ : {},
27142
27820
  },
27143
27821
  reconnectionAttempts: 2,
27144
27822
  transports: ['websocket'],
@@ -27170,6 +27848,9 @@ class SocketService extends lib0_observable__WEBPACK_IMPORTED_MODULE_3__.Observa
27170
27848
  this.socket.on(_config__WEBPACK_IMPORTED_MODULE_2__.REMOTE_SESSION_RECORDING_STOP, (data) => {
27171
27849
  this.emit(_config__WEBPACK_IMPORTED_MODULE_2__.REMOTE_SESSION_RECORDING_STOP, [data]);
27172
27850
  });
27851
+ this.socket.on(_config__WEBPACK_IMPORTED_MODULE_2__.SESSION_SAVE_BUFFER_EVENT, (data) => {
27852
+ this.emit(_config__WEBPACK_IMPORTED_MODULE_2__.SESSION_SAVE_BUFFER_EVENT, [data]);
27853
+ });
27173
27854
  }
27174
27855
  checkReconnectionAttempts() {
27175
27856
  if (this.attempts >= MAX_RECONNECTION_ATTEMPTS) {
@@ -27271,21 +27952,24 @@ __webpack_require__.r(__webpack_exports__);
27271
27952
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
27272
27953
  /* harmony export */ SessionRecorder: () => (/* binding */ SessionRecorder)
27273
27954
  /* harmony export */ });
27274
- /* harmony import */ var lib0_observable__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! lib0/observable */ "../../node_modules/lib0/observable.js");
27955
+ /* harmony import */ var lib0_observable__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! lib0/observable */ "../../node_modules/lib0/observable.js");
27275
27956
  /* harmony import */ var _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @multiplayer-app/session-recorder-common */ "../session-recorder-common/dist/esm/index-browser.js");
27276
27957
  /* harmony import */ var _otel__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./otel */ "./src/otel/index.ts");
27277
27958
  /* harmony import */ var _rrweb__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./rrweb */ "./src/rrweb/index.ts");
27278
27959
  /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./utils */ "./src/utils/index.ts");
27279
27960
  /* harmony import */ var _types__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./types */ "./src/types/index.ts");
27280
- /* harmony import */ var _services_socket_service__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./services/socket.service */ "./src/services/socket.service.ts");
27281
- /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./config */ "./src/config/index.ts");
27282
- /* harmony import */ var _patch__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./patch */ "./src/patch/index.ts");
27283
- /* harmony import */ var _eventBus__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./eventBus */ "./src/eventBus.ts");
27284
- /* harmony import */ var _sessionWidget__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./sessionWidget */ "./src/sessionWidget/index.ts");
27285
- /* harmony import */ var _services_messaging_service__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./services/messaging.service */ "./src/services/messaging.service.ts");
27286
- /* harmony import */ var _services_api_service__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./services/api.service */ "./src/services/api.service.ts");
27287
- /* harmony import */ var _sessionWidget_buttonStateConfigs__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./sessionWidget/buttonStateConfigs */ "./src/sessionWidget/buttonStateConfigs.ts");
27288
- /* harmony import */ var _navigation__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./navigation */ "./src/navigation/index.ts");
27961
+ /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./config */ "./src/config/index.ts");
27962
+ /* harmony import */ var _patch__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./patch */ "./src/patch/index.ts");
27963
+ /* harmony import */ var _eventBus__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./eventBus */ "./src/eventBus.ts");
27964
+ /* harmony import */ var _sessionWidget__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./sessionWidget */ "./src/sessionWidget/index.ts");
27965
+ /* harmony import */ var _services_messaging_service__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./services/messaging.service */ "./src/services/messaging.service.ts");
27966
+ /* harmony import */ var _services_api_service__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./services/api.service */ "./src/services/api.service.ts");
27967
+ /* harmony import */ var _services_socket_service__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./services/socket.service */ "./src/services/socket.service.ts");
27968
+ /* harmony import */ var _services_indexedDb_service__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./services/indexedDb.service */ "./src/services/indexedDb.service.ts");
27969
+ /* harmony import */ var _services_crashBuffer_service__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./services/crashBuffer.service */ "./src/services/crashBuffer.service.ts");
27970
+ /* harmony import */ var _sessionWidget_buttonStateConfigs__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./sessionWidget/buttonStateConfigs */ "./src/sessionWidget/buttonStateConfigs.ts");
27971
+ /* harmony import */ var _navigation__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./navigation */ "./src/navigation/index.ts");
27972
+
27289
27973
 
27290
27974
 
27291
27975
 
@@ -27301,7 +27985,8 @@ __webpack_require__.r(__webpack_exports__);
27301
27985
 
27302
27986
 
27303
27987
 
27304
- class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Observable {
27988
+
27989
+ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_16__.Observable {
27305
27990
  get navigation() {
27306
27991
  return this._navigationRecorder.api;
27307
27992
  }
@@ -27313,7 +27998,7 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27313
27998
  }
27314
27999
  set sessionId(sessionId) {
27315
28000
  this._sessionId = sessionId;
27316
- (0,_utils__WEBPACK_IMPORTED_MODULE_3__.setStoredItem)(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_ID_PROP_NAME, sessionId);
28001
+ (0,_utils__WEBPACK_IMPORTED_MODULE_3__.setStoredItem)(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_ID_PROP_NAME, sessionId);
27317
28002
  }
27318
28003
  get sessionType() {
27319
28004
  return this._sessionType;
@@ -27322,8 +28007,8 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27322
28007
  this._sessionType = sessionType;
27323
28008
  const continuousRecording = sessionType === _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionType.CONTINUOUS;
27324
28009
  this._sessionWidget.updateContinuousRecordingState(continuousRecording);
27325
- _services_messaging_service__WEBPACK_IMPORTED_MODULE_10__["default"].sendMessage('continuous-debugging', continuousRecording);
27326
- (0,_utils__WEBPACK_IMPORTED_MODULE_3__.setStoredItem)(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_TYPE_PROP_NAME, sessionType);
28010
+ _services_messaging_service__WEBPACK_IMPORTED_MODULE_9__["default"].sendMessage('continuous-debugging', continuousRecording);
28011
+ (0,_utils__WEBPACK_IMPORTED_MODULE_3__.setStoredItem)(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_TYPE_PROP_NAME, sessionType);
27327
28012
  }
27328
28013
  get continuousRecording() {
27329
28014
  return this.sessionType === _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionType.CONTINUOUS;
@@ -27334,8 +28019,8 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27334
28019
  set sessionState(state) {
27335
28020
  this._sessionState = state;
27336
28021
  this._sessionWidget.updateState(this._sessionState, this.continuousRecording);
27337
- _services_messaging_service__WEBPACK_IMPORTED_MODULE_10__["default"].sendMessage('state-change', this._sessionState);
27338
- (0,_utils__WEBPACK_IMPORTED_MODULE_3__.setStoredItem)(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_STATE_PROP_NAME, state);
28022
+ _services_messaging_service__WEBPACK_IMPORTED_MODULE_9__["default"].sendMessage('state-change', this._sessionState);
28023
+ (0,_utils__WEBPACK_IMPORTED_MODULE_3__.setStoredItem)(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_STATE_PROP_NAME, state);
27339
28024
  // Emit observable event to support React wrapper
27340
28025
  this.emit('state-change', [this._sessionState || _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.stopped, this.sessionType]);
27341
28026
  }
@@ -27344,19 +28029,23 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27344
28029
  }
27345
28030
  set session(session) {
27346
28031
  this._session = session;
27347
- (0,_utils__WEBPACK_IMPORTED_MODULE_3__.setStoredItem)(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_PROP_NAME, this._session);
28032
+ (0,_utils__WEBPACK_IMPORTED_MODULE_3__.setStoredItem)(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_PROP_NAME, this._session);
27348
28033
  }
27349
28034
  get sessionAttributes() {
27350
28035
  return this._sessionAttributes || {};
27351
28036
  }
27352
28037
  set sessionAttributes(attributes) {
28038
+ var _a;
27353
28039
  this._sessionAttributes = attributes;
28040
+ (_a = this._crashBuffer) === null || _a === void 0 ? void 0 : _a.setAttrs({ sessionAttributes: this.sessionAttributes });
27354
28041
  }
27355
28042
  get userAttributes() {
27356
28043
  return this._userAttributes;
27357
28044
  }
27358
28045
  set userAttributes(userAttributes) {
28046
+ var _a;
27359
28047
  this._userAttributes = userAttributes;
28048
+ (_a = this._crashBuffer) === null || _a === void 0 ? void 0 : _a.setAttrs({ userAttributes: this._userAttributes });
27360
28049
  }
27361
28050
  get error() {
27362
28051
  return this._error;
@@ -27382,15 +28071,20 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27382
28071
  constructor() {
27383
28072
  var _a;
27384
28073
  super();
27385
- this._apiService = new _services_api_service__WEBPACK_IMPORTED_MODULE_11__.ApiService();
27386
- this._socketService = new _services_socket_service__WEBPACK_IMPORTED_MODULE_5__.SocketService();
28074
+ this._apiService = new _services_api_service__WEBPACK_IMPORTED_MODULE_10__.ApiService();
28075
+ this._socketService = new _services_socket_service__WEBPACK_IMPORTED_MODULE_11__.SocketService();
27387
28076
  this._tracer = new _otel__WEBPACK_IMPORTED_MODULE_1__.TracerBrowserSDK();
27388
28077
  this._recorder = new _rrweb__WEBPACK_IMPORTED_MODULE_2__.RecorderBrowserSDK();
27389
- this._sessionWidget = new _sessionWidget__WEBPACK_IMPORTED_MODULE_9__.SessionWidget();
27390
- this._navigationRecorder = new _navigation__WEBPACK_IMPORTED_MODULE_13__.NavigationRecorder();
28078
+ this._sessionWidget = new _sessionWidget__WEBPACK_IMPORTED_MODULE_8__.SessionWidget();
28079
+ this._navigationRecorder = new _navigation__WEBPACK_IMPORTED_MODULE_15__.NavigationRecorder();
27391
28080
  this._startRequestController = null;
28081
+ this._tabId = (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getOrCreateTabId)();
28082
+ this._bufferDb = new _services_indexedDb_service__WEBPACK_IMPORTED_MODULE_12__.IndexedDBService();
28083
+ this._crashBuffer = null;
28084
+ this._isFlushingBuffer = false;
28085
+ this._bufferLifecycleHandlersRegistered = false;
27392
28086
  this._isInitialized = false;
27393
- // Session ID and state are stored in localStorage
28087
+ // Session ID and state are stored in sessionStorage (with fallback) to avoid multi-tab conflicts
27394
28088
  this._sessionId = null;
27395
28089
  this._sessionType = _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionType.MANUAL;
27396
28090
  this._sessionState = null;
@@ -27403,10 +28097,10 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27403
28097
  this._error = '';
27404
28098
  // Safety: avoid accessing storage in SSR/non-browser environments
27405
28099
  const isBrowser = typeof window !== 'undefined';
27406
- const sessionLocal = isBrowser ? (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getStoredItem)(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_PROP_NAME, true) : null;
27407
- const sessionIdLocal = isBrowser ? (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getStoredItem)(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_ID_PROP_NAME) : null;
27408
- const sessionStateLocal = isBrowser ? (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getStoredItem)(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_STATE_PROP_NAME) : null;
27409
- const sessionTypeLocal = isBrowser ? (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getStoredItem)(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_TYPE_PROP_NAME) : null;
28100
+ const sessionLocal = isBrowser ? (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getStoredItem)(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_PROP_NAME, true) : null;
28101
+ const sessionIdLocal = isBrowser ? (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getStoredItem)(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_ID_PROP_NAME) : null;
28102
+ const sessionStateLocal = isBrowser ? (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getStoredItem)(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_STATE_PROP_NAME) : null;
28103
+ const sessionTypeLocal = isBrowser ? (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getStoredItem)(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_TYPE_PROP_NAME) : null;
27410
28104
  if ((0,_utils__WEBPACK_IMPORTED_MODULE_3__.isSessionActive)(sessionLocal, sessionTypeLocal)) {
27411
28105
  this.session = sessionLocal;
27412
28106
  this.sessionId = sessionIdLocal;
@@ -27420,7 +28114,7 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27420
28114
  this.sessionType = _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionType.MANUAL;
27421
28115
  }
27422
28116
  this._configs = {
27423
- ..._config__WEBPACK_IMPORTED_MODULE_6__.BASE_CONFIG,
28117
+ ..._config__WEBPACK_IMPORTED_MODULE_5__.BASE_CONFIG,
27424
28118
  apiKey: ((_a = this.session) === null || _a === void 0 ? void 0 : _a.tempApiKey) || '',
27425
28119
  };
27426
28120
  }
@@ -27429,18 +28123,23 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27429
28123
  * @param configs - custom configurations for session debugger
27430
28124
  */
27431
28125
  init(configs) {
28126
+ var _a;
27432
28127
  if (typeof window === 'undefined') {
27433
28128
  return;
27434
28129
  }
27435
- this._configs = (0,_config__WEBPACK_IMPORTED_MODULE_6__.getSessionRecorderConfig)({ ...this._configs, ...configs });
28130
+ this._configs = (0,_config__WEBPACK_IMPORTED_MODULE_5__.getSessionRecorderConfig)({ ...this._configs, ...configs });
27436
28131
  this._isInitialized = true;
27437
28132
  this._checkOperation('init');
27438
- (0,_patch__WEBPACK_IMPORTED_MODULE_7__.setMaxCapturingHttpPayloadSize)(this._configs.maxCapturingHttpPayloadSize || _config__WEBPACK_IMPORTED_MODULE_6__.DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE);
27439
- (0,_patch__WEBPACK_IMPORTED_MODULE_7__.setShouldRecordHttpData)(this._configs.captureBody, this._configs.captureHeaders);
28133
+ // GC: remove orphaned crash buffers from old tabs.
28134
+ // Keep TTL large to avoid any accidental data loss.
28135
+ void this._bufferDb.sweepStaleTabs(24 * 60 * 60 * 1000);
28136
+ (0,_patch__WEBPACK_IMPORTED_MODULE_6__.setMaxCapturingHttpPayloadSize)(this._configs.maxCapturingHttpPayloadSize || _config__WEBPACK_IMPORTED_MODULE_5__.DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE);
28137
+ (0,_patch__WEBPACK_IMPORTED_MODULE_6__.setShouldRecordHttpData)(this._configs.captureBody, this._configs.captureHeaders);
27440
28138
  this._tracer.init(this._configs);
27441
28139
  this._apiService.init(this._configs);
27442
28140
  this._sessionWidget.init(this._configs);
27443
28141
  this._socketService.init({
28142
+ clientId: this._tracer.clientId,
27444
28143
  apiKey: this._configs.apiKey,
27445
28144
  socketUrl: this._configs.apiBaseUrl || '',
27446
28145
  keepAlive: Boolean(this._configs.useWebsocket),
@@ -27455,17 +28154,83 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27455
28154
  if (this._configs.apiKey) {
27456
28155
  this._recorder.init(this._configs, this._socketService);
27457
28156
  }
28157
+ // Crash buffer (browser): keep a short rolling window when not actively recording.
28158
+ if ((_a = this._configs.buffering) === null || _a === void 0 ? void 0 : _a.enabled) {
28159
+ const windowMinutes = this._configs.buffering.windowMinutes || 1;
28160
+ const windowMs = Math.max(10000, windowMinutes * 60 * 1000);
28161
+ this._crashBuffer = new _services_crashBuffer_service__WEBPACK_IMPORTED_MODULE_13__.CrashBufferService(this._bufferDb, this._tabId, windowMs);
28162
+ this._recorder.setCrashBuffer(this._crashBuffer);
28163
+ this._tracer.setCrashBuffer(this._crashBuffer);
28164
+ this._crashBuffer.setAttrs({
28165
+ sessionAttributes: this.sessionAttributes,
28166
+ resourceAttributes: (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getNavigatorInfo)(),
28167
+ userAttributes: this._userAttributes,
28168
+ });
28169
+ this._registerCrashBufferLifecycleHandlers();
28170
+ }
27458
28171
  if (this.sessionId
27459
28172
  && (this.sessionState === _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.started
27460
28173
  || this.sessionState === _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.paused)) {
27461
28174
  this._start();
27462
28175
  }
28176
+ else {
28177
+ // Buffer-only recording when there is no active debug session.
28178
+ this._startBufferOnlyRecording();
28179
+ }
27463
28180
  this._registerWidgetEvents();
27464
28181
  this._registerSocketServiceListeners();
27465
- _services_messaging_service__WEBPACK_IMPORTED_MODULE_10__["default"].sendMessage('state-change', this.sessionState);
28182
+ _services_messaging_service__WEBPACK_IMPORTED_MODULE_9__["default"].sendMessage('state-change', this.sessionState);
27466
28183
  // Emit init observable event
27467
28184
  this.emit('init', [this]);
27468
28185
  }
28186
+ _registerCrashBufferLifecycleHandlers() {
28187
+ if (this._bufferLifecycleHandlersRegistered)
28188
+ return;
28189
+ if (typeof window === 'undefined')
28190
+ return;
28191
+ if (typeof document === 'undefined')
28192
+ return;
28193
+ if (!this._crashBuffer)
28194
+ return;
28195
+ this._bufferLifecycleHandlersRegistered = true;
28196
+ const update = () => this._updateCrashBufferActiveState();
28197
+ window.addEventListener('focus', update, { passive: true });
28198
+ window.addEventListener('blur', update, { passive: true });
28199
+ document.addEventListener('visibilitychange', update, { passive: true });
28200
+ // Set initial state.
28201
+ update();
28202
+ }
28203
+ _updateCrashBufferActiveState() {
28204
+ if (!this._crashBuffer)
28205
+ return;
28206
+ if (typeof document === 'undefined')
28207
+ return;
28208
+ let hasFocus = true;
28209
+ try {
28210
+ hasFocus = typeof document.hasFocus === 'function' ? document.hasFocus() : true;
28211
+ }
28212
+ catch (_e) {
28213
+ hasFocus = true;
28214
+ }
28215
+ const isVisible = document.visibilityState === 'visible' && !document.hidden;
28216
+ const active = isVisible && hasFocus;
28217
+ this._crashBuffer.setActive(active);
28218
+ if (active && this._crashBuffer.needsFullSnapshot()) {
28219
+ // If the buffer was cleared while inactive, the next stored rrweb event must be a FullSnapshot.
28220
+ this._recorder.takeFullSnapshot();
28221
+ }
28222
+ }
28223
+ _startBufferOnlyRecording() {
28224
+ var _a, _b;
28225
+ if (!((_b = (_a = this._configs) === null || _a === void 0 ? void 0 : _a.buffering) === null || _b === void 0 ? void 0 : _b.enabled))
28226
+ return;
28227
+ if (!this._crashBuffer)
28228
+ return;
28229
+ // Don’t start if a session is active.
28230
+ if (this.sessionState !== _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.stopped || this.sessionId)
28231
+ return;
28232
+ void this._recorder.restart(null, _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionType.MANUAL);
28233
+ }
27469
28234
  /**
27470
28235
  * Save the continuous recording session
27471
28236
  */
@@ -27475,14 +28240,14 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27475
28240
  if (!this.continuousRecording || !this._configs.showContinuousRecording) {
27476
28241
  return;
27477
28242
  }
27478
- this._sessionWidget.updateSaveContinuousDebugSessionState(_sessionWidget_buttonStateConfigs__WEBPACK_IMPORTED_MODULE_12__.ContinuousRecordingSaveButtonState.SAVING);
28243
+ this._sessionWidget.updateSaveContinuousDebugSessionState(_sessionWidget_buttonStateConfigs__WEBPACK_IMPORTED_MODULE_14__.ContinuousRecordingSaveButtonState.SAVING);
27479
28244
  const res = await this._apiService.saveContinuousDebugSession(this.sessionId, {
27480
28245
  sessionAttributes: this.sessionAttributes,
27481
28246
  resourceAttributes: (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getNavigatorInfo)(),
27482
28247
  stoppedAt: this._recorder.stoppedAt,
27483
28248
  name: this._getSessionName()
27484
28249
  });
27485
- this._sessionWidget.updateSaveContinuousDebugSessionState(_sessionWidget_buttonStateConfigs__WEBPACK_IMPORTED_MODULE_12__.ContinuousRecordingSaveButtonState.SAVED);
28250
+ this._sessionWidget.updateSaveContinuousDebugSessionState(_sessionWidget_buttonStateConfigs__WEBPACK_IMPORTED_MODULE_14__.ContinuousRecordingSaveButtonState.SAVED);
27486
28251
  const sessionUrl = res === null || res === void 0 ? void 0 : res.url;
27487
28252
  this._sessionWidget.showToast({
27488
28253
  type: 'success',
@@ -27495,11 +28260,11 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27495
28260
  }
27496
28261
  catch (error) {
27497
28262
  this.error = error.message;
27498
- this._sessionWidget.updateSaveContinuousDebugSessionState(_sessionWidget_buttonStateConfigs__WEBPACK_IMPORTED_MODULE_12__.ContinuousRecordingSaveButtonState.ERROR);
28263
+ this._sessionWidget.updateSaveContinuousDebugSessionState(_sessionWidget_buttonStateConfigs__WEBPACK_IMPORTED_MODULE_14__.ContinuousRecordingSaveButtonState.ERROR);
27499
28264
  }
27500
28265
  finally {
27501
28266
  setTimeout(() => {
27502
- this._sessionWidget.updateSaveContinuousDebugSessionState(_sessionWidget_buttonStateConfigs__WEBPACK_IMPORTED_MODULE_12__.ContinuousRecordingSaveButtonState.IDLE);
28267
+ this._sessionWidget.updateSaveContinuousDebugSessionState(_sessionWidget_buttonStateConfigs__WEBPACK_IMPORTED_MODULE_14__.ContinuousRecordingSaveButtonState.IDLE);
27503
28268
  }, 3000);
27504
28269
  }
27505
28270
  }
@@ -27541,7 +28306,7 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27541
28306
  stoppedAt: this._recorder.stoppedAt,
27542
28307
  };
27543
28308
  const response = await this._apiService.stopSession(this.sessionId, request);
27544
- _eventBus__WEBPACK_IMPORTED_MODULE_8__.recorderEventBus.emit(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_RESPONSE, response);
28309
+ _eventBus__WEBPACK_IMPORTED_MODULE_7__.recorderEventBus.emit(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_RESPONSE, response);
27545
28310
  }
27546
28311
  this._clearSession();
27547
28312
  }
@@ -27629,11 +28394,70 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27629
28394
  const normalizedError = this._normalizeError(error);
27630
28395
  const normalizedErrorInfo = this._normalizeErrorInfo(errorInfo);
27631
28396
  this._tracer.captureException(normalizedError, normalizedErrorInfo);
28397
+ // If user isn't actively recording, auto-flush the crash buffer.
28398
+ if (this.sessionState === _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.stopped && !this.sessionId) {
28399
+ void this.flushBuffer({ reason: 'exception' });
28400
+ }
27632
28401
  }
27633
28402
  catch (e) {
27634
28403
  this.error = (e === null || e === void 0 ? void 0 : e.message) || 'Failed to capture exception';
27635
28404
  }
27636
28405
  }
28406
+ async flushBuffer(payload) {
28407
+ var _a, _b;
28408
+ if (!((_b = (_a = this._configs) === null || _a === void 0 ? void 0 : _a.buffering) === null || _b === void 0 ? void 0 : _b.enabled))
28409
+ return null;
28410
+ if (!this._crashBuffer)
28411
+ return null;
28412
+ if (this._isFlushingBuffer)
28413
+ return null;
28414
+ // Don’t flush while a live recording is active.
28415
+ if (this.sessionState !== _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.stopped || this.sessionId)
28416
+ return null;
28417
+ this._isFlushingBuffer = true;
28418
+ try {
28419
+ const reason = (payload === null || payload === void 0 ? void 0 : payload.reason) || 'manual';
28420
+ await this._crashBuffer.setAttrs({
28421
+ sessionAttributes: this.sessionAttributes,
28422
+ resourceAttributes: (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getNavigatorInfo)(),
28423
+ userAttributes: this._userAttributes,
28424
+ });
28425
+ const snapshot = await this._crashBuffer.snapshot();
28426
+ if (snapshot.rrwebEvents.length === 0 && snapshot.otelSpans.length === 0) {
28427
+ return null;
28428
+ }
28429
+ const request = {
28430
+ name: this._getSessionName(),
28431
+ stoppedAt: new Date().toISOString(),
28432
+ sessionAttributes: this.sessionAttributes,
28433
+ resourceAttributes: (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getNavigatorInfo)(),
28434
+ ...(this._userAttributes ? { userAttributes: this._userAttributes } : {}),
28435
+ debugSessionData: {
28436
+ meta: {
28437
+ reason,
28438
+ windowMs: snapshot.windowMs,
28439
+ fromTs: snapshot.fromTs,
28440
+ toTs: snapshot.toTs,
28441
+ },
28442
+ events: snapshot.rrwebEvents.map((e) => e.event),
28443
+ spans: snapshot.otelSpans.map((s) => s.span),
28444
+ attrs: snapshot.attrs,
28445
+ },
28446
+ };
28447
+ try {
28448
+ const res = await this._apiService.startSession(request);
28449
+ await this._crashBuffer.clear();
28450
+ return res;
28451
+ }
28452
+ catch (_e) {
28453
+ // swallow: flush is best-effort; never throw into app code
28454
+ return null;
28455
+ }
28456
+ }
28457
+ finally {
28458
+ this._isFlushingBuffer = false;
28459
+ }
28460
+ }
27637
28461
  /**
27638
28462
  * @description Check if session should be started/stopped automatically
27639
28463
  * @param {ISession} [sessionPayload]
@@ -27765,12 +28589,12 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27765
28589
  * Register socket service event listeners
27766
28590
  */
27767
28591
  _registerSocketServiceListeners() {
27768
- this._socketService.on(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_STOPPED_EVENT, () => {
28592
+ this._socketService.on(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_STOPPED_EVENT, () => {
27769
28593
  this._stop();
27770
28594
  this._clearSession();
27771
28595
  this._sessionWidget.handleUIReseting();
27772
28596
  });
27773
- this._socketService.on(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_AUTO_CREATED, (payload) => {
28597
+ this._socketService.on(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_AUTO_CREATED, (payload) => {
27774
28598
  var _a;
27775
28599
  if (!(payload === null || payload === void 0 ? void 0 : payload.data))
27776
28600
  return;
@@ -27783,18 +28607,23 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27783
28607
  },
27784
28608
  }, 5000);
27785
28609
  });
27786
- this._socketService.on(_config__WEBPACK_IMPORTED_MODULE_6__.REMOTE_SESSION_RECORDING_START, (payload) => {
28610
+ this._socketService.on(_config__WEBPACK_IMPORTED_MODULE_5__.REMOTE_SESSION_RECORDING_START, (payload) => {
27787
28611
  console.log('REMOTE_SESSION_RECORDING_START', payload);
27788
28612
  if (this.sessionState === _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.stopped) {
27789
28613
  this.start();
27790
28614
  }
27791
28615
  });
27792
- this._socketService.on(_config__WEBPACK_IMPORTED_MODULE_6__.REMOTE_SESSION_RECORDING_STOP, (payload) => {
28616
+ this._socketService.on(_config__WEBPACK_IMPORTED_MODULE_5__.REMOTE_SESSION_RECORDING_STOP, (payload) => {
27793
28617
  console.log('REMOTE_SESSION_RECORDING_STOP', payload);
27794
28618
  if (this.sessionState !== _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.stopped) {
27795
28619
  this.stop();
27796
28620
  }
27797
28621
  });
28622
+ this._socketService.on(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_SAVE_BUFFER_EVENT, (payload) => {
28623
+ // Backend asks the client to flush its crash buffer as a debug session.
28624
+ const reason = (payload === null || payload === void 0 ? void 0 : payload.reason) || 'remote';
28625
+ void this.flushBuffer({ reason });
28626
+ });
27798
28627
  }
27799
28628
  /**
27800
28629
  * Create a new session and start it
@@ -27837,10 +28666,11 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27837
28666
  this.sessionState = _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.started;
27838
28667
  this.sessionType = this.sessionType;
27839
28668
  this._tracer.start(this.sessionId, this.sessionType);
27840
- this._recorder.start(this.sessionId, this.sessionType);
28669
+ // Ensure we switch from buffer-only recording to session recording cleanly.
28670
+ void this._recorder.restart(this.sessionId, this.sessionType);
27841
28671
  this._navigationRecorder.start({ sessionId: this.sessionId, sessionType: this.sessionType, });
27842
28672
  if (this.session) {
27843
- _eventBus__WEBPACK_IMPORTED_MODULE_8__.recorderEventBus.emit(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_STARTED_EVENT, this.session);
28673
+ _eventBus__WEBPACK_IMPORTED_MODULE_7__.recorderEventBus.emit(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_STARTED_EVENT, this.session);
27844
28674
  this._socketService.subscribeToSession(this.session);
27845
28675
  this._sessionWidget.seconds = (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getTimeDifferenceInSeconds)((_a = this.session) === null || _a === void 0 ? void 0 : _a.startedAt);
27846
28676
  }
@@ -27854,6 +28684,7 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27854
28684
  this._tracer.stop();
27855
28685
  this._recorder.stop();
27856
28686
  this._navigationRecorder.stop();
28687
+ this._startBufferOnlyRecording();
27857
28688
  }
27858
28689
  /**
27859
28690
  * Pause the session tracing and recording
@@ -27869,7 +28700,7 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27869
28700
  */
27870
28701
  _resume() {
27871
28702
  this._tracer.start(this.sessionId, this.sessionType);
27872
- this._recorder.start(this.sessionId, this.sessionType);
28703
+ void this._recorder.restart(this.sessionId, this.sessionType);
27873
28704
  this._navigationRecorder.resume();
27874
28705
  this.sessionState = _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.started;
27875
28706
  }
@@ -27885,7 +28716,7 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27885
28716
  this._start();
27886
28717
  }
27887
28718
  /**
27888
- * Set the session ID in localStorage
28719
+ * Set the session ID in sessionStorage (with fallback)
27889
28720
  * @param sessionId - the session ID to set or clear
27890
28721
  */
27891
28722
  _setSession(session) {
@@ -29580,6 +30411,7 @@ __webpack_require__.r(__webpack_exports__);
29580
30411
  /* harmony export */ formatTimeForSessionTimer: () => (/* reexport safe */ _time__WEBPACK_IMPORTED_MODULE_2__.formatTimeForSessionTimer),
29581
30412
  /* harmony export */ getFormattedDate: () => (/* reexport safe */ _time__WEBPACK_IMPORTED_MODULE_2__.getFormattedDate),
29582
30413
  /* harmony export */ getNavigatorInfo: () => (/* reexport safe */ _navigator__WEBPACK_IMPORTED_MODULE_0__.getNavigatorInfo),
30414
+ /* harmony export */ getOrCreateTabId: () => (/* reexport safe */ _tabId__WEBPACK_IMPORTED_MODULE_8__.getOrCreateTabId),
29583
30415
  /* harmony export */ getStoredItem: () => (/* reexport safe */ _storage__WEBPACK_IMPORTED_MODULE_1__.getStoredItem),
29584
30416
  /* harmony export */ getTimeDifferenceInSeconds: () => (/* reexport safe */ _time__WEBPACK_IMPORTED_MODULE_2__.getTimeDifferenceInSeconds),
29585
30417
  /* harmony export */ hasOwnProperty: () => (/* reexport safe */ _type_utils__WEBPACK_IMPORTED_MODULE_6__.hasOwnProperty),
@@ -29621,6 +30453,7 @@ __webpack_require__.r(__webpack_exports__);
29621
30453
  /* harmony import */ var _array__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./array */ "./src/utils/array.ts");
29622
30454
  /* harmony import */ var _type_utils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./type-utils */ "./src/utils/type-utils.ts");
29623
30455
  /* harmony import */ var _globals__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./globals */ "./src/utils/globals.ts");
30456
+ /* harmony import */ var _tabId__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./tabId */ "./src/utils/tabId.ts");
29624
30457
  // Export all utility functions
29625
30458
 
29626
30459
 
@@ -29632,6 +30465,7 @@ __webpack_require__.r(__webpack_exports__);
29632
30465
 
29633
30466
 
29634
30467
 
30468
+
29635
30469
  /***/ }),
29636
30470
 
29637
30471
  /***/ "./src/utils/navigator.ts":
@@ -29873,32 +30707,90 @@ __webpack_require__.r(__webpack_exports__);
29873
30707
  /* harmony export */ setStoredItem: () => (/* binding */ setStoredItem)
29874
30708
  /* harmony export */ });
29875
30709
  /**
29876
- * LocalStorage utility functions
30710
+ * Storage utility functions.
30711
+ *
30712
+ * Session state must be isolated per-tab to avoid conflicts across multiple tabs.
30713
+ * We therefore prefer `sessionStorage` and fall back to `localStorage` if needed.
29877
30714
  */
29878
- const hasLocalStorage = typeof window !== 'undefined' && !!window.localStorage;
29879
- const getStoredItem = (key, parse) => {
29880
- if (!hasLocalStorage) {
29881
- return parse ? null : null;
30715
+ const hasWindow = typeof window !== 'undefined';
30716
+ const getStorage = () => {
30717
+ if (!hasWindow)
30718
+ return null;
30719
+ try {
30720
+ if (window.sessionStorage)
30721
+ return window.sessionStorage;
30722
+ }
30723
+ catch (_e) {
30724
+ // sessionStorage can throw (e.g. blocked in some environments)
30725
+ }
30726
+ try {
30727
+ if (window.localStorage)
30728
+ return window.localStorage;
29882
30729
  }
29883
- const item = window.localStorage.getItem(key);
30730
+ catch (_e) {
30731
+ // localStorage can throw (e.g. blocked in some environments)
30732
+ }
30733
+ return null;
30734
+ };
30735
+ const getStoredItem = (key, parse) => {
30736
+ const storage = getStorage();
30737
+ if (!storage)
30738
+ return null;
30739
+ const item = storage.getItem(key);
29884
30740
  return parse ? (item ? JSON.parse(item) : null) : item;
29885
30741
  };
29886
30742
  const setStoredItem = (key, value) => {
29887
- if (!hasLocalStorage) {
30743
+ const storage = getStorage();
30744
+ if (!storage)
29888
30745
  return;
29889
- }
29890
30746
  if (value === null || value === undefined) {
29891
- window.localStorage.removeItem(key);
30747
+ storage.removeItem(key);
29892
30748
  }
29893
30749
  else {
29894
- window.localStorage.setItem(key, typeof value === 'string' ? value : JSON.stringify(value));
30750
+ storage.setItem(key, typeof value === 'string' ? value : JSON.stringify(value));
29895
30751
  }
29896
30752
  };
29897
30753
  const removeStoredItem = (key) => {
29898
- if (!hasLocalStorage) {
30754
+ const storage = getStorage();
30755
+ if (!storage)
29899
30756
  return;
30757
+ storage.removeItem(key);
30758
+ };
30759
+
30760
+
30761
+ /***/ }),
30762
+
30763
+ /***/ "./src/utils/tabId.ts":
30764
+ /*!****************************!*\
30765
+ !*** ./src/utils/tabId.ts ***!
30766
+ \****************************/
30767
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
30768
+
30769
+ "use strict";
30770
+ __webpack_require__.r(__webpack_exports__);
30771
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
30772
+ /* harmony export */ getOrCreateTabId: () => (/* binding */ getOrCreateTabId)
30773
+ /* harmony export */ });
30774
+ const TAB_ID_KEY = 'multiplayer-tab-id';
30775
+ const randomId = () => {
30776
+ // Avoid crypto dependency for older browsers; good enough for per-tab isolation
30777
+ return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
30778
+ };
30779
+ const getOrCreateTabId = () => {
30780
+ if (typeof window === 'undefined')
30781
+ return 'ssr';
30782
+ try {
30783
+ const existing = window.sessionStorage.getItem(TAB_ID_KEY);
30784
+ if (existing)
30785
+ return existing;
30786
+ const id = randomId();
30787
+ window.sessionStorage.setItem(TAB_ID_KEY, id);
30788
+ return id;
30789
+ }
30790
+ catch (_e) {
30791
+ // If sessionStorage is blocked, fall back to a runtime-only id.
30792
+ return randomId();
29900
30793
  }
29901
- window.localStorage.removeItem(key);
29902
30794
  };
29903
30795
 
29904
30796
 
@@ -30058,42 +30950,48 @@ __webpack_require__.r(__webpack_exports__);
30058
30950
  /* harmony export */ SessionRecorderIdGenerator: () => (/* binding */ SessionRecorderIdGenerator)
30059
30951
  /* harmony export */ });
30060
30952
  /* harmony import */ var _type__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./type */ "../session-recorder-common/dist/esm/type/index.js");
30061
- /* harmony import */ var _constants_constants_base__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./constants/constants.base */ "../session-recorder-common/dist/esm/constants/constants.base.js");
30062
- /* harmony import */ var _sdk__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./sdk */ "../session-recorder-common/dist/esm/sdk/index.js");
30953
+ /* harmony import */ var _sdk__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./sdk */ "../session-recorder-common/dist/esm/sdk/index.js");
30954
+ /* harmony import */ var _constants_constants_base__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./constants/constants.base */ "../session-recorder-common/dist/esm/constants/constants.base.js");
30063
30955
 
30064
30956
 
30065
30957
 
30066
30958
  var SessionRecorderIdGenerator = /** @class */ (function () {
30067
30959
  function SessionRecorderIdGenerator() {
30068
- this.generateLongId = (0,_sdk__WEBPACK_IMPORTED_MODULE_2__.getIdGenerator)(16);
30069
- this.generateShortId = (0,_sdk__WEBPACK_IMPORTED_MODULE_2__.getIdGenerator)(8);
30960
+ this.generateLongId = (0,_sdk__WEBPACK_IMPORTED_MODULE_1__.getIdGenerator)(16);
30961
+ this.generateShortId = (0,_sdk__WEBPACK_IMPORTED_MODULE_1__.getIdGenerator)(8);
30070
30962
  this.sessionShortId = '';
30963
+ this.clientId = '';
30071
30964
  this.sessionType = _type__WEBPACK_IMPORTED_MODULE_0__.SessionType.MANUAL;
30072
30965
  }
30073
30966
  SessionRecorderIdGenerator.prototype.generateTraceId = function () {
30074
30967
  var traceId = this.generateLongId();
30075
- if (this.sessionShortId) {
30076
- var sessionTypePrefix = '';
30077
- switch (this.sessionType) {
30078
- case _type__WEBPACK_IMPORTED_MODULE_0__.SessionType.CONTINUOUS:
30079
- sessionTypePrefix = _constants_constants_base__WEBPACK_IMPORTED_MODULE_1__.MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX;
30080
- break;
30081
- default:
30082
- sessionTypePrefix = _constants_constants_base__WEBPACK_IMPORTED_MODULE_1__.MULTIPLAYER_TRACE_DEBUG_PREFIX;
30083
- }
30084
- var prefix = "".concat(sessionTypePrefix).concat(this.sessionShortId);
30085
- var sessionTraceId = "".concat(prefix).concat(traceId.substring(prefix.length, traceId.length));
30086
- return sessionTraceId;
30968
+ if (!this.sessionShortId && !this.sessionType) {
30969
+ return traceId;
30087
30970
  }
30088
- return traceId;
30971
+ var sessionTypePrefix = _constants_constants_base__WEBPACK_IMPORTED_MODULE_2__.MULTIPLAYER_TRACE_PREFIX_MAP[this.sessionType];
30972
+ var prefix = "".concat(sessionTypePrefix).concat([_type__WEBPACK_IMPORTED_MODULE_0__.SessionType.CONTINUOUS_SESSION_CACHE, _type__WEBPACK_IMPORTED_MODULE_0__.SessionType.SESSION_CACHE].includes(this.sessionType) ? this.clientId : '').concat(this.sessionShortId);
30973
+ var sessionTraceId = "".concat(prefix).concat(traceId.substring(prefix.length, traceId.length));
30974
+ return sessionTraceId;
30089
30975
  };
30090
30976
  SessionRecorderIdGenerator.prototype.generateSpanId = function () {
30091
30977
  return this.generateShortId();
30092
30978
  };
30093
- SessionRecorderIdGenerator.prototype.setSessionId = function (sessionShortId, sessionType) {
30979
+ SessionRecorderIdGenerator.prototype.setSessionId = function (sessionShortId, sessionType, clientId) {
30094
30980
  if (sessionType === void 0) { sessionType = _type__WEBPACK_IMPORTED_MODULE_0__.SessionType.MANUAL; }
30981
+ if (clientId === void 0) { clientId = ''; }
30982
+ if (!clientId &&
30983
+ [
30984
+ _type__WEBPACK_IMPORTED_MODULE_0__.SessionType.SESSION_CACHE,
30985
+ _type__WEBPACK_IMPORTED_MODULE_0__.SessionType.CONTINUOUS_SESSION_CACHE,
30986
+ ].includes(sessionType)) {
30987
+ throw new Error("Client ID is required for ".concat([
30988
+ _type__WEBPACK_IMPORTED_MODULE_0__.SessionType.SESSION_CACHE,
30989
+ _type__WEBPACK_IMPORTED_MODULE_0__.SessionType.CONTINUOUS_SESSION_CACHE,
30990
+ ].join(', '), " session types"));
30991
+ }
30095
30992
  this.sessionShortId = sessionShortId;
30096
30993
  this.sessionType = sessionType;
30994
+ this.clientId = clientId;
30097
30995
  };
30098
30996
  return SessionRecorderIdGenerator;
30099
30997
  }());
@@ -30198,6 +31096,7 @@ __webpack_require__.r(__webpack_exports__);
30198
31096
  /* harmony export */ ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE: () => (/* binding */ ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE),
30199
31097
  /* harmony export */ ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE_ENCODING: () => (/* binding */ ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE_ENCODING),
30200
31098
  /* harmony export */ ATTR_MULTIPLAYER_RPC_RESPONSE_MESSAGE: () => (/* binding */ ATTR_MULTIPLAYER_RPC_RESPONSE_MESSAGE),
31099
+ /* harmony export */ ATTR_MULTIPLAYER_SESSION_CLIENT_ID: () => (/* binding */ ATTR_MULTIPLAYER_SESSION_CLIENT_ID),
30201
31100
  /* harmony export */ ATTR_MULTIPLAYER_SESSION_ID: () => (/* binding */ ATTR_MULTIPLAYER_SESSION_ID),
30202
31101
  /* harmony export */ ATTR_MULTIPLAYER_SESSION_RECORDER_VERSION: () => (/* binding */ ATTR_MULTIPLAYER_SESSION_RECORDER_VERSION),
30203
31102
  /* harmony export */ ATTR_MULTIPLAYER_USER_HASH: () => (/* binding */ ATTR_MULTIPLAYER_USER_HASH),
@@ -30211,18 +31110,34 @@ __webpack_require__.r(__webpack_exports__);
30211
31110
  /* harmony export */ MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_GRPC_URL: () => (/* binding */ MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_GRPC_URL),
30212
31111
  /* harmony export */ MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_HTTP_URL: () => (/* binding */ MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_HTTP_URL),
30213
31112
  /* harmony export */ MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_URL: () => (/* binding */ MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_URL),
31113
+ /* harmony export */ MULTIPLAYER_TRACE_CLIENT_ID_LENGTH: () => (/* binding */ MULTIPLAYER_TRACE_CLIENT_ID_LENGTH),
30214
31114
  /* harmony export */ MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX: () => (/* binding */ MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX),
31115
+ /* harmony export */ MULTIPLAYER_TRACE_CONTINUOUS_SESSION_DEBUG_PREFIX: () => (/* binding */ MULTIPLAYER_TRACE_CONTINUOUS_SESSION_DEBUG_PREFIX),
30215
31116
  /* harmony export */ MULTIPLAYER_TRACE_DEBUG_PREFIX: () => (/* binding */ MULTIPLAYER_TRACE_DEBUG_PREFIX),
30216
31117
  /* harmony export */ MULTIPLAYER_TRACE_DEBUG_SESSION_SHORT_ID_LENGTH: () => (/* binding */ MULTIPLAYER_TRACE_DEBUG_SESSION_SHORT_ID_LENGTH),
30217
- /* harmony export */ MULTIPLAYER_TRACE_DOC_PREFIX: () => (/* binding */ MULTIPLAYER_TRACE_DOC_PREFIX)
31118
+ /* harmony export */ MULTIPLAYER_TRACE_DOC_PREFIX: () => (/* binding */ MULTIPLAYER_TRACE_DOC_PREFIX),
31119
+ /* harmony export */ MULTIPLAYER_TRACE_PREFIX_MAP: () => (/* binding */ MULTIPLAYER_TRACE_PREFIX_MAP),
31120
+ /* harmony export */ MULTIPLAYER_TRACE_SESSION_CACHE_PREFIX: () => (/* binding */ MULTIPLAYER_TRACE_SESSION_CACHE_PREFIX)
30218
31121
  /* harmony export */ });
31122
+ /* harmony import */ var _type__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../type */ "../session-recorder-common/dist/esm/type/index.js");
31123
+ var _a;
31124
+
30219
31125
  /**
30220
31126
  * @deprecated
30221
31127
  */
30222
31128
  var MULTIPLAYER_TRACE_DOC_PREFIX = 'd0cd0c';
30223
31129
  var MULTIPLAYER_TRACE_DEBUG_PREFIX = 'debdeb';
30224
31130
  var MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX = 'cdbcdb';
30225
- var MULTIPLAYER_TRACE_DEBUG_SESSION_SHORT_ID_LENGTH = 16;
31131
+ var MULTIPLAYER_TRACE_SESSION_CACHE_PREFIX = 'cdbcac';
31132
+ var MULTIPLAYER_TRACE_CONTINUOUS_SESSION_DEBUG_PREFIX = 'debcdb';
31133
+ var MULTIPLAYER_TRACE_PREFIX_MAP = (_a = {},
31134
+ _a[_type__WEBPACK_IMPORTED_MODULE_0__.SessionType.CONTINUOUS] = MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX,
31135
+ _a[_type__WEBPACK_IMPORTED_MODULE_0__.SessionType.SESSION_CACHE] = MULTIPLAYER_TRACE_SESSION_CACHE_PREFIX,
31136
+ _a[_type__WEBPACK_IMPORTED_MODULE_0__.SessionType.CONTINUOUS_SESSION_CACHE] = MULTIPLAYER_TRACE_CONTINUOUS_SESSION_DEBUG_PREFIX,
31137
+ _a[_type__WEBPACK_IMPORTED_MODULE_0__.SessionType.MANUAL] = MULTIPLAYER_TRACE_DEBUG_PREFIX,
31138
+ _a);
31139
+ var MULTIPLAYER_TRACE_DEBUG_SESSION_SHORT_ID_LENGTH = 8;
31140
+ var MULTIPLAYER_TRACE_CLIENT_ID_LENGTH = 8;
30226
31141
  /**
30227
31142
  * @deprecated Use MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_HTTP_URL instead
30228
31143
  */
@@ -30246,6 +31161,7 @@ var ATTR_MULTIPLAYER_PLATFORM_NAME = 'multiplayer.platform.name';
30246
31161
  var ATTR_MULTIPLAYER_CLIENT_ID = 'multiplayer.client.id';
30247
31162
  var ATTR_MULTIPLAYER_INTEGRATION_ID = 'multiplayer.integration.id';
30248
31163
  var ATTR_MULTIPLAYER_SESSION_ID = 'multiplayer.session.id';
31164
+ var ATTR_MULTIPLAYER_SESSION_CLIENT_ID = 'multiplayer.session.client.id';
30249
31165
  var ATTR_MULTIPLAYER_HTTP_PROXY = 'multiplayer.http.proxy';
30250
31166
  var ATTR_MULTIPLAYER_HTTP_PROXY_TYPE = 'multiplayer.http.proxy.type';
30251
31167
  var ATTR_MULTIPLAYER_HTTP_REQUEST_BODY = 'multiplayer.http.request.body';
@@ -30305,6 +31221,7 @@ __webpack_require__.r(__webpack_exports__);
30305
31221
  /* harmony export */ ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE),
30306
31222
  /* harmony export */ ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE_ENCODING: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE_ENCODING),
30307
31223
  /* harmony export */ ATTR_MULTIPLAYER_RPC_RESPONSE_MESSAGE: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_RPC_RESPONSE_MESSAGE),
31224
+ /* harmony export */ ATTR_MULTIPLAYER_SESSION_CLIENT_ID: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_SESSION_CLIENT_ID),
30308
31225
  /* harmony export */ ATTR_MULTIPLAYER_SESSION_ID: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_SESSION_ID),
30309
31226
  /* harmony export */ ATTR_MULTIPLAYER_SESSION_RECORDER_VERSION: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_SESSION_RECORDER_VERSION),
30310
31227
  /* harmony export */ ATTR_MULTIPLAYER_USER_HASH: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_USER_HASH),
@@ -30318,10 +31235,14 @@ __webpack_require__.r(__webpack_exports__);
30318
31235
  /* harmony export */ MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_GRPC_URL: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_GRPC_URL),
30319
31236
  /* harmony export */ MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_HTTP_URL: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_HTTP_URL),
30320
31237
  /* harmony export */ MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_URL: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_URL),
31238
+ /* harmony export */ MULTIPLAYER_TRACE_CLIENT_ID_LENGTH: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_CLIENT_ID_LENGTH),
30321
31239
  /* harmony export */ MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX),
31240
+ /* harmony export */ MULTIPLAYER_TRACE_CONTINUOUS_SESSION_DEBUG_PREFIX: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_CONTINUOUS_SESSION_DEBUG_PREFIX),
30322
31241
  /* harmony export */ MULTIPLAYER_TRACE_DEBUG_PREFIX: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_DEBUG_PREFIX),
30323
31242
  /* harmony export */ MULTIPLAYER_TRACE_DEBUG_SESSION_SHORT_ID_LENGTH: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_DEBUG_SESSION_SHORT_ID_LENGTH),
30324
- /* harmony export */ MULTIPLAYER_TRACE_DOC_PREFIX: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_DOC_PREFIX)
31243
+ /* harmony export */ MULTIPLAYER_TRACE_DOC_PREFIX: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_DOC_PREFIX),
31244
+ /* harmony export */ MULTIPLAYER_TRACE_PREFIX_MAP: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_PREFIX_MAP),
31245
+ /* harmony export */ MULTIPLAYER_TRACE_SESSION_CACHE_PREFIX: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_SESSION_CACHE_PREFIX)
30325
31246
  /* harmony export */ });
30326
31247
  /* harmony import */ var _constants_base__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./constants.base */ "../session-recorder-common/dist/esm/constants/constants.base.js");
30327
31248
 
@@ -30517,6 +31438,7 @@ __webpack_require__.r(__webpack_exports__);
30517
31438
  /* harmony export */ ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE),
30518
31439
  /* harmony export */ ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE_ENCODING: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE_ENCODING),
30519
31440
  /* harmony export */ ATTR_MULTIPLAYER_RPC_RESPONSE_MESSAGE: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_RPC_RESPONSE_MESSAGE),
31441
+ /* harmony export */ ATTR_MULTIPLAYER_SESSION_CLIENT_ID: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_SESSION_CLIENT_ID),
30520
31442
  /* harmony export */ ATTR_MULTIPLAYER_SESSION_ID: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_SESSION_ID),
30521
31443
  /* harmony export */ ATTR_MULTIPLAYER_SESSION_RECORDER_VERSION: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_SESSION_RECORDER_VERSION),
30522
31444
  /* harmony export */ ATTR_MULTIPLAYER_USER_HASH: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_USER_HASH),
@@ -30531,10 +31453,14 @@ __webpack_require__.r(__webpack_exports__);
30531
31453
  /* harmony export */ MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_GRPC_URL: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_GRPC_URL),
30532
31454
  /* harmony export */ MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_HTTP_URL: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_HTTP_URL),
30533
31455
  /* harmony export */ MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_URL: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_URL),
31456
+ /* harmony export */ MULTIPLAYER_TRACE_CLIENT_ID_LENGTH: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_CLIENT_ID_LENGTH),
30534
31457
  /* harmony export */ MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX),
31458
+ /* harmony export */ MULTIPLAYER_TRACE_CONTINUOUS_SESSION_DEBUG_PREFIX: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_CONTINUOUS_SESSION_DEBUG_PREFIX),
30535
31459
  /* harmony export */ MULTIPLAYER_TRACE_DEBUG_PREFIX: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_DEBUG_PREFIX),
30536
31460
  /* harmony export */ MULTIPLAYER_TRACE_DEBUG_SESSION_SHORT_ID_LENGTH: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_DEBUG_SESSION_SHORT_ID_LENGTH),
30537
31461
  /* harmony export */ MULTIPLAYER_TRACE_DOC_PREFIX: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_DOC_PREFIX),
31462
+ /* harmony export */ MULTIPLAYER_TRACE_PREFIX_MAP: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_PREFIX_MAP),
31463
+ /* harmony export */ MULTIPLAYER_TRACE_SESSION_CACHE_PREFIX: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_SESSION_CACHE_PREFIX),
30538
31464
  /* harmony export */ SessionRecorderBrowserTraceExporter: () => (/* reexport safe */ _exporters_index_browser__WEBPACK_IMPORTED_MODULE_5__.SessionRecorderBrowserTraceExporter),
30539
31465
  /* harmony export */ SessionRecorderIdGenerator: () => (/* reexport safe */ _SessionRecorderIdGenerator__WEBPACK_IMPORTED_MODULE_1__.SessionRecorderIdGenerator),
30540
31466
  /* harmony export */ SessionRecorderSdk: () => (/* reexport module object */ _sdk__WEBPACK_IMPORTED_MODULE_3__),
@@ -31188,6 +32114,8 @@ var SessionType;
31188
32114
  */
31189
32115
  SessionType["PLAIN"] = "MANUAL";
31190
32116
  SessionType["MANUAL"] = "MANUAL";
32117
+ SessionType["CONTINUOUS_SESSION_CACHE"] = "CONTINUOUS_SESSION_CACHE";
32118
+ SessionType["SESSION_CACHE"] = "SESSION_CACHE";
31191
32119
  })(SessionType || (SessionType = {}));
31192
32120
  //# sourceMappingURL=session-type.enum.js.map
31193
32121
 
@@ -33057,6 +33985,123 @@ const getRecordConsolePlugin = (options) => ({
33057
33985
  //# sourceMappingURL=rrweb-plugin-console-record.js.map
33058
33986
 
33059
33987
 
33988
+ /***/ }),
33989
+
33990
+ /***/ "../../node_modules/@rrweb/types/dist/types.js":
33991
+ /*!*****************************************************!*\
33992
+ !*** ../../node_modules/@rrweb/types/dist/types.js ***!
33993
+ \*****************************************************/
33994
+ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
33995
+
33996
+ "use strict";
33997
+ __webpack_require__.r(__webpack_exports__);
33998
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
33999
+ /* harmony export */ CanvasContext: () => (/* binding */ CanvasContext),
34000
+ /* harmony export */ EventType: () => (/* binding */ EventType),
34001
+ /* harmony export */ IncrementalSource: () => (/* binding */ IncrementalSource),
34002
+ /* harmony export */ MediaInteractions: () => (/* binding */ MediaInteractions),
34003
+ /* harmony export */ MouseInteractions: () => (/* binding */ MouseInteractions),
34004
+ /* harmony export */ NodeType: () => (/* binding */ NodeType),
34005
+ /* harmony export */ PointerTypes: () => (/* binding */ PointerTypes),
34006
+ /* harmony export */ ReplayerEvents: () => (/* binding */ ReplayerEvents)
34007
+ /* harmony export */ });
34008
+ var EventType = /* @__PURE__ */ ((EventType2) => {
34009
+ EventType2[EventType2["DomContentLoaded"] = 0] = "DomContentLoaded";
34010
+ EventType2[EventType2["Load"] = 1] = "Load";
34011
+ EventType2[EventType2["FullSnapshot"] = 2] = "FullSnapshot";
34012
+ EventType2[EventType2["IncrementalSnapshot"] = 3] = "IncrementalSnapshot";
34013
+ EventType2[EventType2["Meta"] = 4] = "Meta";
34014
+ EventType2[EventType2["Custom"] = 5] = "Custom";
34015
+ EventType2[EventType2["Plugin"] = 6] = "Plugin";
34016
+ return EventType2;
34017
+ })(EventType || {});
34018
+ var IncrementalSource = /* @__PURE__ */ ((IncrementalSource2) => {
34019
+ IncrementalSource2[IncrementalSource2["Mutation"] = 0] = "Mutation";
34020
+ IncrementalSource2[IncrementalSource2["MouseMove"] = 1] = "MouseMove";
34021
+ IncrementalSource2[IncrementalSource2["MouseInteraction"] = 2] = "MouseInteraction";
34022
+ IncrementalSource2[IncrementalSource2["Scroll"] = 3] = "Scroll";
34023
+ IncrementalSource2[IncrementalSource2["ViewportResize"] = 4] = "ViewportResize";
34024
+ IncrementalSource2[IncrementalSource2["Input"] = 5] = "Input";
34025
+ IncrementalSource2[IncrementalSource2["TouchMove"] = 6] = "TouchMove";
34026
+ IncrementalSource2[IncrementalSource2["MediaInteraction"] = 7] = "MediaInteraction";
34027
+ IncrementalSource2[IncrementalSource2["StyleSheetRule"] = 8] = "StyleSheetRule";
34028
+ IncrementalSource2[IncrementalSource2["CanvasMutation"] = 9] = "CanvasMutation";
34029
+ IncrementalSource2[IncrementalSource2["Font"] = 10] = "Font";
34030
+ IncrementalSource2[IncrementalSource2["Log"] = 11] = "Log";
34031
+ IncrementalSource2[IncrementalSource2["Drag"] = 12] = "Drag";
34032
+ IncrementalSource2[IncrementalSource2["StyleDeclaration"] = 13] = "StyleDeclaration";
34033
+ IncrementalSource2[IncrementalSource2["Selection"] = 14] = "Selection";
34034
+ IncrementalSource2[IncrementalSource2["AdoptedStyleSheet"] = 15] = "AdoptedStyleSheet";
34035
+ IncrementalSource2[IncrementalSource2["CustomElement"] = 16] = "CustomElement";
34036
+ return IncrementalSource2;
34037
+ })(IncrementalSource || {});
34038
+ var MouseInteractions = /* @__PURE__ */ ((MouseInteractions2) => {
34039
+ MouseInteractions2[MouseInteractions2["MouseUp"] = 0] = "MouseUp";
34040
+ MouseInteractions2[MouseInteractions2["MouseDown"] = 1] = "MouseDown";
34041
+ MouseInteractions2[MouseInteractions2["Click"] = 2] = "Click";
34042
+ MouseInteractions2[MouseInteractions2["ContextMenu"] = 3] = "ContextMenu";
34043
+ MouseInteractions2[MouseInteractions2["DblClick"] = 4] = "DblClick";
34044
+ MouseInteractions2[MouseInteractions2["Focus"] = 5] = "Focus";
34045
+ MouseInteractions2[MouseInteractions2["Blur"] = 6] = "Blur";
34046
+ MouseInteractions2[MouseInteractions2["TouchStart"] = 7] = "TouchStart";
34047
+ MouseInteractions2[MouseInteractions2["TouchMove_Departed"] = 8] = "TouchMove_Departed";
34048
+ MouseInteractions2[MouseInteractions2["TouchEnd"] = 9] = "TouchEnd";
34049
+ MouseInteractions2[MouseInteractions2["TouchCancel"] = 10] = "TouchCancel";
34050
+ return MouseInteractions2;
34051
+ })(MouseInteractions || {});
34052
+ var PointerTypes = /* @__PURE__ */ ((PointerTypes2) => {
34053
+ PointerTypes2[PointerTypes2["Mouse"] = 0] = "Mouse";
34054
+ PointerTypes2[PointerTypes2["Pen"] = 1] = "Pen";
34055
+ PointerTypes2[PointerTypes2["Touch"] = 2] = "Touch";
34056
+ return PointerTypes2;
34057
+ })(PointerTypes || {});
34058
+ var CanvasContext = /* @__PURE__ */ ((CanvasContext2) => {
34059
+ CanvasContext2[CanvasContext2["2D"] = 0] = "2D";
34060
+ CanvasContext2[CanvasContext2["WebGL"] = 1] = "WebGL";
34061
+ CanvasContext2[CanvasContext2["WebGL2"] = 2] = "WebGL2";
34062
+ return CanvasContext2;
34063
+ })(CanvasContext || {});
34064
+ var MediaInteractions = /* @__PURE__ */ ((MediaInteractions2) => {
34065
+ MediaInteractions2[MediaInteractions2["Play"] = 0] = "Play";
34066
+ MediaInteractions2[MediaInteractions2["Pause"] = 1] = "Pause";
34067
+ MediaInteractions2[MediaInteractions2["Seeked"] = 2] = "Seeked";
34068
+ MediaInteractions2[MediaInteractions2["VolumeChange"] = 3] = "VolumeChange";
34069
+ MediaInteractions2[MediaInteractions2["RateChange"] = 4] = "RateChange";
34070
+ return MediaInteractions2;
34071
+ })(MediaInteractions || {});
34072
+ var ReplayerEvents = /* @__PURE__ */ ((ReplayerEvents2) => {
34073
+ ReplayerEvents2["Start"] = "start";
34074
+ ReplayerEvents2["Pause"] = "pause";
34075
+ ReplayerEvents2["Resume"] = "resume";
34076
+ ReplayerEvents2["Resize"] = "resize";
34077
+ ReplayerEvents2["Finish"] = "finish";
34078
+ ReplayerEvents2["FullsnapshotRebuilded"] = "fullsnapshot-rebuilded";
34079
+ ReplayerEvents2["LoadStylesheetStart"] = "load-stylesheet-start";
34080
+ ReplayerEvents2["LoadStylesheetEnd"] = "load-stylesheet-end";
34081
+ ReplayerEvents2["SkipStart"] = "skip-start";
34082
+ ReplayerEvents2["SkipEnd"] = "skip-end";
34083
+ ReplayerEvents2["MouseInteraction"] = "mouse-interaction";
34084
+ ReplayerEvents2["EventCast"] = "event-cast";
34085
+ ReplayerEvents2["CustomEvent"] = "custom-event";
34086
+ ReplayerEvents2["Flush"] = "flush";
34087
+ ReplayerEvents2["StateChange"] = "state-change";
34088
+ ReplayerEvents2["PlayBack"] = "play-back";
34089
+ ReplayerEvents2["Destroy"] = "destroy";
34090
+ return ReplayerEvents2;
34091
+ })(ReplayerEvents || {});
34092
+ var NodeType = /* @__PURE__ */ ((NodeType2) => {
34093
+ NodeType2[NodeType2["Document"] = 0] = "Document";
34094
+ NodeType2[NodeType2["DocumentType"] = 1] = "DocumentType";
34095
+ NodeType2[NodeType2["Element"] = 2] = "Element";
34096
+ NodeType2[NodeType2["Text"] = 3] = "Text";
34097
+ NodeType2[NodeType2["CDATA"] = 4] = "CDATA";
34098
+ NodeType2[NodeType2["Comment"] = 5] = "Comment";
34099
+ return NodeType2;
34100
+ })(NodeType || {});
34101
+
34102
+ //# sourceMappingURL=types.js.map
34103
+
34104
+
33060
34105
  /***/ }),
33061
34106
 
33062
34107
  /***/ "../../node_modules/@socket.io/component-emitter/lib/esm/index.js":
@@ -49578,6 +50623,7 @@ __webpack_require__.r(__webpack_exports__);
49578
50623
  /* harmony export */ ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE),
49579
50624
  /* harmony export */ ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE_ENCODING: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE_ENCODING),
49580
50625
  /* harmony export */ ATTR_MULTIPLAYER_RPC_RESPONSE_MESSAGE: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.ATTR_MULTIPLAYER_RPC_RESPONSE_MESSAGE),
50626
+ /* harmony export */ ATTR_MULTIPLAYER_SESSION_CLIENT_ID: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.ATTR_MULTIPLAYER_SESSION_CLIENT_ID),
49581
50627
  /* harmony export */ ATTR_MULTIPLAYER_SESSION_ID: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.ATTR_MULTIPLAYER_SESSION_ID),
49582
50628
  /* harmony export */ ATTR_MULTIPLAYER_SESSION_RECORDER_VERSION: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.ATTR_MULTIPLAYER_SESSION_RECORDER_VERSION),
49583
50629
  /* harmony export */ ATTR_MULTIPLAYER_USER_HASH: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.ATTR_MULTIPLAYER_USER_HASH),
@@ -49592,10 +50638,14 @@ __webpack_require__.r(__webpack_exports__);
49592
50638
  /* harmony export */ MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_GRPC_URL: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_GRPC_URL),
49593
50639
  /* harmony export */ MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_HTTP_URL: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_HTTP_URL),
49594
50640
  /* harmony export */ MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_URL: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_URL),
50641
+ /* harmony export */ MULTIPLAYER_TRACE_CLIENT_ID_LENGTH: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.MULTIPLAYER_TRACE_CLIENT_ID_LENGTH),
49595
50642
  /* harmony export */ MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX),
50643
+ /* harmony export */ MULTIPLAYER_TRACE_CONTINUOUS_SESSION_DEBUG_PREFIX: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.MULTIPLAYER_TRACE_CONTINUOUS_SESSION_DEBUG_PREFIX),
49596
50644
  /* harmony export */ MULTIPLAYER_TRACE_DEBUG_PREFIX: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.MULTIPLAYER_TRACE_DEBUG_PREFIX),
49597
50645
  /* harmony export */ MULTIPLAYER_TRACE_DEBUG_SESSION_SHORT_ID_LENGTH: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.MULTIPLAYER_TRACE_DEBUG_SESSION_SHORT_ID_LENGTH),
49598
50646
  /* harmony export */ MULTIPLAYER_TRACE_DOC_PREFIX: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.MULTIPLAYER_TRACE_DOC_PREFIX),
50647
+ /* harmony export */ MULTIPLAYER_TRACE_PREFIX_MAP: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.MULTIPLAYER_TRACE_PREFIX_MAP),
50648
+ /* harmony export */ MULTIPLAYER_TRACE_SESSION_CACHE_PREFIX: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.MULTIPLAYER_TRACE_SESSION_CACHE_PREFIX),
49599
50649
  /* harmony export */ NavigationRecorder: () => (/* reexport safe */ _navigation__WEBPACK_IMPORTED_MODULE_6__.NavigationRecorder),
49600
50650
  /* harmony export */ SessionRecorderBrowserTraceExporter: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.SessionRecorderBrowserTraceExporter),
49601
50651
  /* harmony export */ SessionRecorderIdGenerator: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.SessionRecorderIdGenerator),