@multiplayer-app/session-recorder-browser 1.3.16 → 1.3.19

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 (72) hide show
  1. package/dist/browser/index.js +1423 -288
  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 +8 -0
  14. package/dist/exporters/index.js.map +1 -1
  15. package/dist/index.js +1411 -289
  16. package/dist/index.js.map +1 -1
  17. package/dist/index.umd.js +1411 -288
  18. package/dist/index.umd.js.map +1 -1
  19. package/dist/otel/CrashBufferSpanProcessor.d.ts +18 -0
  20. package/dist/otel/CrashBufferSpanProcessor.d.ts.map +1 -0
  21. package/dist/otel/CrashBufferSpanProcessor.js +42 -0
  22. package/dist/otel/CrashBufferSpanProcessor.js.map +1 -0
  23. package/dist/otel/index.d.ts +9 -1
  24. package/dist/otel/index.d.ts.map +1 -1
  25. package/dist/otel/index.js +45 -32
  26. package/dist/otel/index.js.map +1 -1
  27. package/dist/patch/fetch.js +2 -2
  28. package/dist/patch/fetch.js.map +1 -1
  29. package/dist/rrweb/index.d.ts +50 -17
  30. package/dist/rrweb/index.d.ts.map +1 -1
  31. package/dist/rrweb/index.js +162 -84
  32. package/dist/rrweb/index.js.map +1 -1
  33. package/dist/services/api.service.d.ts +22 -0
  34. package/dist/services/api.service.d.ts.map +1 -1
  35. package/dist/services/api.service.js +22 -5
  36. package/dist/services/api.service.js.map +1 -1
  37. package/dist/services/crashBuffer.service.d.ts +35 -0
  38. package/dist/services/crashBuffer.service.d.ts.map +1 -0
  39. package/dist/services/crashBuffer.service.js +207 -0
  40. package/dist/services/crashBuffer.service.js.map +1 -0
  41. package/dist/services/indexedDb.service.d.ts +72 -0
  42. package/dist/services/indexedDb.service.d.ts.map +1 -0
  43. package/dist/services/indexedDb.service.js +338 -0
  44. package/dist/services/indexedDb.service.js.map +1 -0
  45. package/dist/services/socket.service.d.ts +3 -2
  46. package/dist/services/socket.service.d.ts.map +1 -1
  47. package/dist/services/socket.service.js +8 -1
  48. package/dist/services/socket.service.js.map +1 -1
  49. package/dist/session-recorder.d.ts +13 -2
  50. package/dist/session-recorder.d.ts.map +1 -1
  51. package/dist/session-recorder.js +176 -31
  52. package/dist/session-recorder.js.map +1 -1
  53. package/dist/types/session-recorder.d.ts +19 -6
  54. package/dist/types/session-recorder.d.ts.map +1 -1
  55. package/dist/types/session-recorder.js.map +1 -1
  56. package/dist/utils/index.d.ts +1 -0
  57. package/dist/utils/index.d.ts.map +1 -1
  58. package/dist/utils/index.js +1 -0
  59. package/dist/utils/index.js.map +1 -1
  60. package/dist/utils/storage.d.ts +4 -1
  61. package/dist/utils/storage.d.ts.map +1 -1
  62. package/dist/utils/storage.js +35 -13
  63. package/dist/utils/storage.js.map +1 -1
  64. package/dist/utils/tabId.d.ts +2 -0
  65. package/dist/utils/tabId.d.ts.map +1 -0
  66. package/dist/utils/tabId.js +22 -0
  67. package/dist/utils/tabId.js.map +1 -0
  68. package/package.json +2 -2
  69. package/dist/rrweb/indexedDbService.d.ts +0 -9
  70. package/dist/rrweb/indexedDbService.d.ts.map +0 -1
  71. package/dist/rrweb/indexedDbService.js +0 -54
  72. 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.19" || 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
 
@@ -25721,6 +25735,64 @@ __webpack_require__.r(__webpack_exports__);
25721
25735
 
25722
25736
 
25723
25737
 
25738
+ /***/ }),
25739
+
25740
+ /***/ "./src/otel/CrashBufferSpanProcessor.ts":
25741
+ /*!**********************************************!*\
25742
+ !*** ./src/otel/CrashBufferSpanProcessor.ts ***!
25743
+ \**********************************************/
25744
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
25745
+
25746
+ "use strict";
25747
+ __webpack_require__.r(__webpack_exports__);
25748
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
25749
+ /* harmony export */ CrashBufferSpanProcessor: () => (/* binding */ CrashBufferSpanProcessor)
25750
+ /* harmony export */ });
25751
+ /* harmony import */ var _opentelemetry_api__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @opentelemetry/api */ "../../node_modules/@opentelemetry/api/build/esm/trace/trace_flags.js");
25752
+ /* 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");
25753
+
25754
+
25755
+ /**
25756
+ * Implementation of the {@link SpanProcessor} that batches spans exported by
25757
+ * the SDK then pushes them to the exporter pipeline.
25758
+ */
25759
+ class CrashBufferSpanProcessor {
25760
+ constructor(_exporter, _crashBuffer, _serializeSpan) {
25761
+ this._exporter = _exporter;
25762
+ this._crashBuffer = _crashBuffer;
25763
+ this._serializeSpan = _serializeSpan;
25764
+ }
25765
+ forceFlush() {
25766
+ return this._exporter.forceFlush();
25767
+ }
25768
+ onStart(_span, _parentContext) {
25769
+ return this._exporter.onStart(_span, _parentContext);
25770
+ }
25771
+ onEnd(span) {
25772
+ const traceId = span.spanContext().traceId;
25773
+ if ((span.spanContext().traceFlags & _opentelemetry_api__WEBPACK_IMPORTED_MODULE_1__.TraceFlags.SAMPLED) === 0) {
25774
+ return;
25775
+ }
25776
+ if (traceId.startsWith(_multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_SESSION_CACHE_PREFIX) ||
25777
+ traceId.startsWith(_multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_CONTINUOUS_SESSION_CACHE_PREFIX)) {
25778
+ if (this._crashBuffer) {
25779
+ this._crashBuffer.appendSpans([
25780
+ {
25781
+ ts: span.startTime[0] * 1000 + span.startTime[1] / 1000000,
25782
+ span: this._serializeSpan(span)
25783
+ }
25784
+ ]);
25785
+ }
25786
+ return;
25787
+ }
25788
+ this._exporter.onEnd(span);
25789
+ }
25790
+ shutdown() {
25791
+ return this._exporter.shutdown();
25792
+ }
25793
+ }
25794
+
25795
+
25724
25796
  /***/ }),
25725
25797
 
25726
25798
  /***/ "./src/otel/helpers.ts":
@@ -25965,19 +26037,21 @@ __webpack_require__.r(__webpack_exports__);
25965
26037
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
25966
26038
  /* harmony export */ TracerBrowserSDK: () => (/* binding */ TracerBrowserSDK)
25967
26039
  /* harmony export */ });
25968
- /* harmony import */ var _opentelemetry_resources__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @opentelemetry/resources */ "../../node_modules/@opentelemetry/resources/build/esm/ResourceImpl.js");
25969
- /* harmony import */ var _opentelemetry_core__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @opentelemetry/core */ "../../node_modules/@opentelemetry/core/build/esm/trace/W3CTraceContextPropagator.js");
25970
- /* harmony import */ var _opentelemetry_sdk_trace_web__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @opentelemetry/sdk-trace-web */ "../../node_modules/@opentelemetry/sdk-trace-web/build/esm/WebTracerProvider.js");
25971
- /* harmony import */ var _opentelemetry_sdk_trace_base__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @opentelemetry/sdk-trace-base */ "../../node_modules/@opentelemetry/sdk-trace-base/build/esm/platform/browser/export/BatchSpanProcessor.js");
25972
- /* harmony import */ var _opentelemetry_semantic_conventions__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @opentelemetry/semantic-conventions */ "../../node_modules/@opentelemetry/semantic-conventions/build/esm/resource/SemanticResourceAttributes.js");
25973
- /* harmony import */ var _opentelemetry_instrumentation__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @opentelemetry/instrumentation */ "../../node_modules/@opentelemetry/instrumentation/build/esm/autoLoader.js");
26040
+ /* harmony import */ var _opentelemetry_resources__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @opentelemetry/resources */ "../../node_modules/@opentelemetry/resources/build/esm/ResourceImpl.js");
26041
+ /* harmony import */ var _opentelemetry_core__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @opentelemetry/core */ "../../node_modules/@opentelemetry/core/build/esm/trace/W3CTraceContextPropagator.js");
26042
+ /* harmony import */ var _opentelemetry_sdk_trace_web__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @opentelemetry/sdk-trace-web */ "../../node_modules/@opentelemetry/sdk-trace-web/build/esm/WebTracerProvider.js");
26043
+ /* harmony import */ var _opentelemetry_sdk_trace_base__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @opentelemetry/sdk-trace-base */ "../../node_modules/@opentelemetry/sdk-trace-base/build/esm/platform/browser/export/BatchSpanProcessor.js");
26044
+ /* harmony import */ var _opentelemetry_semantic_conventions__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @opentelemetry/semantic-conventions */ "../../node_modules/@opentelemetry/semantic-conventions/build/esm/resource/SemanticResourceAttributes.js");
26045
+ /* harmony import */ var _opentelemetry_instrumentation__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @opentelemetry/instrumentation */ "../../node_modules/@opentelemetry/instrumentation/build/esm/autoLoader.js");
25974
26046
  /* harmony import */ var _opentelemetry_auto_instrumentations_web__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @opentelemetry/auto-instrumentations-web */ "../../node_modules/@opentelemetry/auto-instrumentations-web/build/esm/index.js");
25975
26047
  /* 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");
25976
- /* harmony import */ var _opentelemetry_api__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @opentelemetry/api */ "../../node_modules/@opentelemetry/api/build/esm/trace-api.js");
25977
- /* harmony import */ var _opentelemetry_api__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @opentelemetry/api */ "../../node_modules/@opentelemetry/api/build/esm/context-api.js");
25978
- /* harmony import */ var _opentelemetry_api__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @opentelemetry/api */ "../../node_modules/@opentelemetry/api/build/esm/trace/status.js");
26048
+ /* harmony import */ var _opentelemetry_api__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @opentelemetry/api */ "../../node_modules/@opentelemetry/api/build/esm/trace-api.js");
26049
+ /* harmony import */ var _opentelemetry_api__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @opentelemetry/api */ "../../node_modules/@opentelemetry/api/build/esm/context-api.js");
26050
+ /* harmony import */ var _opentelemetry_api__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! @opentelemetry/api */ "../../node_modules/@opentelemetry/api/build/esm/trace/status.js");
25979
26051
  /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../config */ "./src/config/index.ts");
25980
26052
  /* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./helpers */ "./src/otel/helpers.ts");
26053
+ /* harmony import */ var _CrashBufferSpanProcessor__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./CrashBufferSpanProcessor */ "./src/otel/CrashBufferSpanProcessor.ts");
26054
+
25981
26055
 
25982
26056
 
25983
26057
 
@@ -25991,49 +26065,52 @@ __webpack_require__.r(__webpack_exports__);
25991
26065
 
25992
26066
  class TracerBrowserSDK {
25993
26067
  constructor() {
26068
+ this.clientId = '';
25994
26069
  this.sessionId = '';
25995
26070
  this.globalErrorListenersRegistered = false;
25996
26071
  }
25997
- setSessionId(sessionId, sessionType = _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionType.PLAIN) {
26072
+ setSessionId(sessionId, sessionType = _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionType.MANUAL) {
25998
26073
  this.sessionId = sessionId;
25999
- this.idGenerator.setSessionId(sessionId, sessionType);
26074
+ if (!this.idGenerator) {
26075
+ throw new Error('Id generator not initialized');
26076
+ }
26077
+ this.idGenerator.setSessionId(sessionId, sessionType, this.clientId);
26000
26078
  }
26001
26079
  init(options) {
26002
26080
  this.config = options;
26081
+ 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
26082
  const { application, version, environment } = this.config;
26004
26083
  this.idGenerator = new _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionRecorderIdGenerator();
26005
26084
  this.exporter = new _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionRecorderBrowserTraceExporter({
26006
26085
  apiKey: options.apiKey,
26007
26086
  url: (0,_helpers__WEBPACK_IMPORTED_MODULE_3__.getExporterEndpoint)(options.exporterEndpoint),
26008
- usePostMessageFallback: options.usePostMessageFallback,
26087
+ usePostMessageFallback: options.usePostMessageFallback
26009
26088
  });
26010
- this.tracerProvider = new _opentelemetry_sdk_trace_web__WEBPACK_IMPORTED_MODULE_4__.WebTracerProvider({
26011
- resource: (0,_opentelemetry_resources__WEBPACK_IMPORTED_MODULE_5__.resourceFromAttributes)({
26012
- [_opentelemetry_semantic_conventions__WEBPACK_IMPORTED_MODULE_6__.SEMRESATTRS_SERVICE_NAME]: application,
26013
- [_opentelemetry_semantic_conventions__WEBPACK_IMPORTED_MODULE_6__.SEMRESATTRS_SERVICE_VERSION]: version,
26014
- [_opentelemetry_semantic_conventions__WEBPACK_IMPORTED_MODULE_6__.SEMRESATTRS_DEPLOYMENT_ENVIRONMENT]: environment,
26089
+ this.batchSpanProcessor = new _opentelemetry_sdk_trace_base__WEBPACK_IMPORTED_MODULE_5__.BatchSpanProcessor(this.exporter);
26090
+ this.tracerProvider = new _opentelemetry_sdk_trace_web__WEBPACK_IMPORTED_MODULE_6__.WebTracerProvider({
26091
+ resource: (0,_opentelemetry_resources__WEBPACK_IMPORTED_MODULE_7__.resourceFromAttributes)({
26092
+ [_opentelemetry_semantic_conventions__WEBPACK_IMPORTED_MODULE_8__.SEMRESATTRS_SERVICE_NAME]: application,
26093
+ [_opentelemetry_semantic_conventions__WEBPACK_IMPORTED_MODULE_8__.SEMRESATTRS_SERVICE_VERSION]: version,
26094
+ [_opentelemetry_semantic_conventions__WEBPACK_IMPORTED_MODULE_8__.SEMRESATTRS_DEPLOYMENT_ENVIRONMENT]: environment
26015
26095
  }),
26016
26096
  idGenerator: this.idGenerator,
26017
26097
  sampler: new _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionRecorderTraceIdRatioBasedSampler(this.config.sampleTraceRatio),
26018
26098
  spanProcessors: [
26019
26099
  this._getSpanSessionIdProcessor(),
26020
- new _opentelemetry_sdk_trace_base__WEBPACK_IMPORTED_MODULE_7__.BatchSpanProcessor(this.exporter),
26021
- ],
26100
+ new _CrashBufferSpanProcessor__WEBPACK_IMPORTED_MODULE_4__.CrashBufferSpanProcessor(this.batchSpanProcessor, this.crashBuffer, this.exporter.serializeSpan.bind(this.exporter))
26101
+ ]
26022
26102
  });
26023
26103
  this.tracerProvider.register({
26024
26104
  // contextManager: new ZoneContextManager(),
26025
- propagator: new _opentelemetry_core__WEBPACK_IMPORTED_MODULE_8__.W3CTraceContextPropagator(),
26105
+ propagator: new _opentelemetry_core__WEBPACK_IMPORTED_MODULE_9__.W3CTraceContextPropagator()
26026
26106
  });
26027
- (0,_opentelemetry_instrumentation__WEBPACK_IMPORTED_MODULE_9__.registerInstrumentations)({
26107
+ (0,_opentelemetry_instrumentation__WEBPACK_IMPORTED_MODULE_10__.registerInstrumentations)({
26028
26108
  tracerProvider: this.tracerProvider,
26029
26109
  instrumentations: [
26030
26110
  (0,_opentelemetry_auto_instrumentations_web__WEBPACK_IMPORTED_MODULE_0__.getWebAutoInstrumentations)({
26031
26111
  '@opentelemetry/instrumentation-xml-http-request': {
26032
26112
  clearTimingResources: true,
26033
- ignoreUrls: [
26034
- ..._config__WEBPACK_IMPORTED_MODULE_2__.OTEL_IGNORE_URLS,
26035
- ...(this.config.ignoreUrls || []),
26036
- ],
26113
+ ignoreUrls: [..._config__WEBPACK_IMPORTED_MODULE_2__.OTEL_IGNORE_URLS, ...(this.config.ignoreUrls || [])],
26037
26114
  propagateTraceHeaderCorsUrls: options.propagateTraceHeaderCorsUrls,
26038
26115
  applyCustomAttributesOnSpan: (span, xhr) => {
26039
26116
  if (!this.config)
@@ -26053,7 +26130,7 @@ class TracerBrowserSDK {
26053
26130
  requestBody,
26054
26131
  responseBody,
26055
26132
  requestHeaders,
26056
- responseHeaders,
26133
+ responseHeaders
26057
26134
  };
26058
26135
  (0,_helpers__WEBPACK_IMPORTED_MODULE_3__.processHttpPayload)(payload, this.config, span);
26059
26136
  }
@@ -26061,14 +26138,11 @@ class TracerBrowserSDK {
26061
26138
  // eslint-disable-next-line
26062
26139
  console.error('[MULTIPLAYER_SESSION_RECORDER] Failed to capture xml-http payload', error);
26063
26140
  }
26064
- },
26141
+ }
26065
26142
  },
26066
26143
  '@opentelemetry/instrumentation-fetch': {
26067
26144
  clearTimingResources: true,
26068
- ignoreUrls: [
26069
- ..._config__WEBPACK_IMPORTED_MODULE_2__.OTEL_IGNORE_URLS,
26070
- ...(this.config.ignoreUrls || []),
26071
- ],
26145
+ ignoreUrls: [..._config__WEBPACK_IMPORTED_MODULE_2__.OTEL_IGNORE_URLS, ...(this.config.ignoreUrls || [])],
26072
26146
  propagateTraceHeaderCorsUrls: options.propagateTraceHeaderCorsUrls,
26073
26147
  applyCustomAttributesOnSpan: async (span, request, response) => {
26074
26148
  if (!this.config)
@@ -26105,7 +26179,7 @@ class TracerBrowserSDK {
26105
26179
  requestBody,
26106
26180
  responseBody,
26107
26181
  requestHeaders,
26108
- responseHeaders,
26182
+ responseHeaders
26109
26183
  };
26110
26184
  (0,_helpers__WEBPACK_IMPORTED_MODULE_3__.processHttpPayload)(payload, this.config, span);
26111
26185
  }
@@ -26113,7 +26187,7 @@ class TracerBrowserSDK {
26113
26187
  // eslint-disable-next-line
26114
26188
  console.error('[MULTIPLAYER_SESSION_RECORDER] Failed to capture fetch payload', error);
26115
26189
  }
26116
- },
26190
+ }
26117
26191
  },
26118
26192
  '@opentelemetry/instrumentation-user-interaction': {
26119
26193
  shouldPreventSpanCreation: (_event, element, span) => {
@@ -26122,17 +26196,20 @@ class TracerBrowserSDK {
26122
26196
  }
26123
26197
  span.setAttribute('target.innerText', (0,_helpers__WEBPACK_IMPORTED_MODULE_3__.getElementInnerText)(element));
26124
26198
  span.setAttribute('target.textContent', (0,_helpers__WEBPACK_IMPORTED_MODULE_3__.getElementTextContent)(element));
26125
- Array.from(element.attributes).forEach(attribute => {
26199
+ Array.from(element.attributes).forEach((attribute) => {
26126
26200
  span.setAttribute(`target.attribute.${attribute.name}`, attribute.value);
26127
26201
  });
26128
26202
  return false;
26129
- },
26130
- },
26131
- }),
26132
- ],
26203
+ }
26204
+ }
26205
+ })
26206
+ ]
26133
26207
  });
26134
26208
  this._registerGlobalErrorListeners();
26135
26209
  }
26210
+ setCrashBuffer(crashBuffer) {
26211
+ this.crashBuffer = crashBuffer;
26212
+ }
26136
26213
  start(sessionId, sessionType) {
26137
26214
  if (!this.tracerProvider) {
26138
26215
  throw new Error('Configuration not initialized. Call init() before start().');
@@ -26157,13 +26234,15 @@ class TracerBrowserSDK {
26157
26234
  * Otherwise, a short-lived span will be created to hold the exception event.
26158
26235
  */
26159
26236
  captureException(error, errorInfo) {
26237
+ var _a, _b;
26160
26238
  if (!error)
26161
26239
  return;
26162
26240
  // Prefer attaching to the active span to keep correlation intact
26163
26241
  try {
26164
- const activeSpan = _opentelemetry_api__WEBPACK_IMPORTED_MODULE_10__.trace.getSpan(_opentelemetry_api__WEBPACK_IMPORTED_MODULE_11__.context.active());
26242
+ const activeSpan = _opentelemetry_api__WEBPACK_IMPORTED_MODULE_11__.trace.getSpan(_opentelemetry_api__WEBPACK_IMPORTED_MODULE_12__.context.active());
26165
26243
  if (activeSpan) {
26166
26244
  this._recordException(activeSpan, error, errorInfo);
26245
+ (_a = this.tracerProvider) === null || _a === void 0 ? void 0 : _a.forceFlush();
26167
26246
  return;
26168
26247
  }
26169
26248
  // eslint-disable-next-line
@@ -26171,17 +26250,26 @@ class TracerBrowserSDK {
26171
26250
  catch (_ignored) { }
26172
26251
  // Fallback: create a short-lived span to hold the exception details
26173
26252
  try {
26174
- const tracer = _opentelemetry_api__WEBPACK_IMPORTED_MODULE_10__.trace.getTracer('exception');
26253
+ const tracer = _opentelemetry_api__WEBPACK_IMPORTED_MODULE_11__.trace.getTracer('exception');
26175
26254
  const span = tracer.startSpan(error.name || 'Error');
26176
26255
  this._recordException(span, error, errorInfo);
26177
26256
  span.end();
26257
+ (_b = this.tracerProvider) === null || _b === void 0 ? void 0 : _b.forceFlush();
26178
26258
  // eslint-disable-next-line
26179
26259
  }
26180
26260
  catch (_ignored) { }
26181
26261
  }
26262
+ async exportTraces(spans) {
26263
+ var _a;
26264
+ if ((_a = this === null || this === void 0 ? void 0 : this.batchSpanProcessor) === null || _a === void 0 ? void 0 : _a.onEnd) {
26265
+ spans.map((span) => { var _a; return (_a = this === null || this === void 0 ? void 0 : this.batchSpanProcessor) === null || _a === void 0 ? void 0 : _a.onEnd(span); });
26266
+ // return this.batchSpanProcessor.onEnd()
26267
+ }
26268
+ throw new Error('Buffer span processor not initialized');
26269
+ }
26182
26270
  _recordException(span, error, errorInfo) {
26183
26271
  span.recordException(error);
26184
- span.setStatus({ code: _opentelemetry_api__WEBPACK_IMPORTED_MODULE_12__.SpanStatusCode.ERROR, message: error.message });
26272
+ span.setStatus({ code: _opentelemetry_api__WEBPACK_IMPORTED_MODULE_13__.SpanStatusCode.ERROR, message: error.message });
26185
26273
  span.setAttribute('exception.type', error.name || 'Error');
26186
26274
  span.setAttribute('exception.message', error.message);
26187
26275
  span.setAttribute('exception.stacktrace', error.stack || '');
@@ -26194,14 +26282,14 @@ class TracerBrowserSDK {
26194
26282
  _getSpanSessionIdProcessor() {
26195
26283
  return {
26196
26284
  forceFlush: () => Promise.resolve(),
26197
- onEnd: () => { },
26285
+ onEnd: () => Promise.resolve(),
26198
26286
  shutdown: () => Promise.resolve(),
26199
26287
  onStart: (span) => {
26200
26288
  var _a;
26201
26289
  if ((_a = this.sessionId) === null || _a === void 0 ? void 0 : _a.length) {
26202
26290
  span.setAttribute(_multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.ATTR_MULTIPLAYER_SESSION_ID, this.sessionId);
26203
26291
  }
26204
- },
26292
+ }
26205
26293
  };
26206
26294
  }
26207
26295
  _registerGlobalErrorListeners() {
@@ -26211,14 +26299,12 @@ class TracerBrowserSDK {
26211
26299
  return;
26212
26300
  // eslint-disable-next-line
26213
26301
  const errorHandler = (event) => {
26214
- const err = (event === null || event === void 0 ? void 0 : event.error) instanceof Error
26215
- ? event.error
26216
- : new Error((event === null || event === void 0 ? void 0 : event.message) || 'Script error');
26302
+ const err = (event === null || event === void 0 ? void 0 : event.error) instanceof Error ? event.error : new Error((event === null || event === void 0 ? void 0 : event.message) || 'Script error');
26217
26303
  this.captureException(err);
26218
26304
  };
26219
26305
  // eslint-disable-next-line
26220
26306
  const rejectionHandler = (event) => {
26221
- const reason = (event && 'reason' in event) ? event.reason : undefined;
26307
+ const reason = event && 'reason' in event ? event.reason : undefined;
26222
26308
  const err = reason instanceof Error
26223
26309
  ? reason
26224
26310
  : new Error(typeof reason === 'string' ? reason : 'Unhandled promise rejection');
@@ -26280,7 +26366,7 @@ __webpack_require__.r(__webpack_exports__);
26280
26366
 
26281
26367
 
26282
26368
 
26283
- function _tryReadFetchBody({ body, url }) {
26369
+ function _tryReadFetchBody({ body, url, }) {
26284
26370
  if ((0,_utils_type_utils__WEBPACK_IMPORTED_MODULE_0__.isNullish)(body)) {
26285
26371
  return null;
26286
26372
  }
@@ -26453,7 +26539,7 @@ if (typeof window !== 'undefined' && typeof window.fetch !== 'undefined') {
26453
26539
  if (!(0,_utils_type_utils__WEBPACK_IMPORTED_MODULE_0__.isNullish)(candidateBody)) {
26454
26540
  const requestBody = _tryReadFetchBody({
26455
26541
  body: candidateBody,
26456
- url: urlStr
26542
+ url: urlStr,
26457
26543
  });
26458
26544
  if ((requestBody === null || requestBody === void 0 ? void 0 : requestBody.length) && new Blob([requestBody]).size <= _configs__WEBPACK_IMPORTED_MODULE_2__.configs.maxCapturingHttpPayloadSize) {
26459
26545
  networkRequest.requestBody = requestBody;
@@ -26655,11 +26741,13 @@ __webpack_require__.r(__webpack_exports__);
26655
26741
  /* harmony export */ RecorderBrowserSDK: () => (/* binding */ RecorderBrowserSDK)
26656
26742
  /* harmony export */ });
26657
26743
  /* 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");
26744
+ /* harmony import */ var _rrweb_types__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @rrweb/types */ "../../node_modules/@rrweb/types/dist/types.js");
26745
+ /* harmony import */ var rrweb__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! rrweb */ "../../node_modules/rrweb/dist/rrweb.js");
26746
+ /* 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");
26747
+ /* 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");
26748
+ /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils */ "./src/utils/index.ts");
26749
+ /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../config */ "./src/config/index.ts");
26750
+
26663
26751
 
26664
26752
 
26665
26753
 
@@ -26667,129 +26755,206 @@ __webpack_require__.r(__webpack_exports__);
26667
26755
 
26668
26756
 
26669
26757
  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
26758
  constructor() {
26683
- this.restartInterval = null;
26684
- this._startedAt = '';
26685
- this._stoppedAt = '';
26759
+ this.intervals = {
26760
+ restart: null,
26761
+ bufferSnapshot: null
26762
+ };
26763
+ this.startedAt = '';
26764
+ this.stoppedAt = '';
26686
26765
  }
26687
26766
  /**
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.
26767
+ * Full snapshot.
26768
+ */
26769
+ takeFullSnapshot() {
26770
+ if (!this.stopFn) {
26771
+ return;
26772
+ }
26773
+ rrweb__WEBPACK_IMPORTED_MODULE_6__.record.takeFullSnapshot();
26774
+ }
26775
+ /**
26776
+ * Initializes the recorder SDK.
26777
+ * @param config - Configuration settings.
26778
+ * @param socketService - Optional socket service.
26691
26779
  */
26692
26780
  init(config, socketService) {
26693
26781
  this.config = config;
26694
26782
  this.socketService = socketService;
26695
26783
  }
26696
26784
  /**
26697
- * Starts recording events for a given session ID.
26698
- * @param sessionId - The ID of the session to record events for.
26785
+ * Starts recording.
26786
+ * @param sessionId - Session ID or null for buffer-only mode.
26787
+ * @param sessionType - Session type.
26699
26788
  */
26700
26789
  start(sessionId, sessionType) {
26701
- var _a;
26702
26790
  if (!this.config) {
26703
26791
  throw new Error('Configuration not initialized. Call init() before start().');
26704
26792
  }
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
26793
  this.startedAt = new Date().toISOString();
26707
- // Build masking configuration
26708
- const maskingConfig = this.config.masking || {};
26794
+ this.stopFn = (0,rrweb__WEBPACK_IMPORTED_MODULE_6__.record)({
26795
+ ...this._buildRecordOptions(),
26796
+ emit: async (event) => {
26797
+ const ts = event.timestamp;
26798
+ if (!sessionId) {
26799
+ await this._handleBufferOnlyEvent(event, ts);
26800
+ return;
26801
+ }
26802
+ this._handleLiveSessionEvent(event, ts, sessionId, sessionType);
26803
+ }
26804
+ });
26805
+ this.takeFullSnapshot();
26806
+ this._setupPeriodicSnapshots(sessionId, sessionType);
26807
+ }
26808
+ /**
26809
+ * Restarts recording. Never throws - library mode constraint.
26810
+ */
26811
+ async restart(sessionId, sessionType) {
26812
+ var _a;
26813
+ try {
26814
+ (_a = this.stopFn) === null || _a === void 0 ? void 0 : _a.call(this);
26815
+ this.start(sessionId, sessionType);
26816
+ }
26817
+ catch (_e) {
26818
+ // Silent failure
26819
+ }
26820
+ }
26821
+ /**
26822
+ * Stops recording and cleans up resources.
26823
+ */
26824
+ stop() {
26825
+ var _a, _b, _c;
26826
+ (_a = this.stopFn) === null || _a === void 0 ? void 0 : _a.call(this);
26827
+ this.stopFn = undefined;
26828
+ if (!((_b = this.config) === null || _b === void 0 ? void 0 : _b.useWebsocket)) {
26829
+ (_c = this.socketService) === null || _c === void 0 ? void 0 : _c.close();
26830
+ }
26831
+ this._clearAllIntervals();
26832
+ }
26833
+ _clearAllIntervals() {
26834
+ if (this.intervals.restart) {
26835
+ clearInterval(this.intervals.restart);
26836
+ this.intervals.restart = null;
26837
+ }
26838
+ if (this.intervals.bufferSnapshot) {
26839
+ clearInterval(this.intervals.bufferSnapshot);
26840
+ this.intervals.bufferSnapshot = null;
26841
+ }
26842
+ }
26843
+ /**
26844
+ * Sets the crash buffer.
26845
+ * @param crashBuffer - Crash buffer service.
26846
+ */
26847
+ setCrashBuffer(crashBuffer) {
26848
+ this.crashBuffer = crashBuffer;
26849
+ }
26850
+ /**
26851
+ * Mutates event in-place for performance.
26852
+ */
26853
+ _applyConsoleMasking(event) {
26854
+ var _a, _b;
26855
+ const maskFn = (_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.masking) === null || _b === void 0 ? void 0 : _b.maskConsoleEvent;
26856
+ if (typeof maskFn === 'function' && (0,_utils__WEBPACK_IMPORTED_MODULE_4__.isConsoleEvent)(event)) {
26857
+ const pluginEvt = event;
26858
+ const maskedPayload = maskFn(pluginEvt.data.payload);
26859
+ pluginEvt.data = { ...pluginEvt.data, payload: maskedPayload };
26860
+ }
26861
+ }
26862
+ /**
26863
+ * Handles buffer-only event.
26864
+ * @param event - Event.
26865
+ * @param ts - Timestamp.
26866
+ */
26867
+ async _handleBufferOnlyEvent(event, ts) {
26868
+ if (!this.crashBuffer)
26869
+ return;
26870
+ try {
26871
+ this._applyConsoleMasking(event);
26872
+ const packedEvent = (0,_rrweb_packer__WEBPACK_IMPORTED_MODULE_0__.pack)(event);
26873
+ this.stoppedAt = new Date(ts).toISOString();
26874
+ await this.crashBuffer.appendEvent({
26875
+ ts,
26876
+ isFullSnapshot: event.type === _rrweb_types__WEBPACK_IMPORTED_MODULE_1__.EventType.FullSnapshot,
26877
+ event: {
26878
+ event: packedEvent,
26879
+ eventType: event.type,
26880
+ timestamp: ts
26881
+ }
26882
+ });
26883
+ }
26884
+ catch (error) {
26885
+ // Silent failure - library constraint
26886
+ }
26887
+ }
26888
+ /**
26889
+ * Handles live session event.
26890
+ * @param event - Event.
26891
+ * @param ts - Timestamp.
26892
+ * @param sessionId - Session ID.
26893
+ * @param sessionType - Session type.
26894
+ */
26895
+ _handleLiveSessionEvent(event, ts, sessionId, sessionType) {
26896
+ if (!this.socketService)
26897
+ return;
26898
+ this._applyConsoleMasking(event);
26899
+ const packedEvent = (0,_rrweb_packer__WEBPACK_IMPORTED_MODULE_0__.pack)(event);
26900
+ this.stoppedAt = new Date(ts).toISOString();
26901
+ this.socketService.send({
26902
+ event: packedEvent,
26903
+ eventType: event.type,
26904
+ timestamp: ts,
26905
+ debugSessionId: sessionId,
26906
+ debugSessionType: sessionType
26907
+ });
26908
+ }
26909
+ /**
26910
+ * Builds record options.
26911
+ */
26912
+ _buildRecordOptions() {
26913
+ var _a, _b, _c;
26914
+ const maskingConfig = ((_a = this.config) === null || _a === void 0 ? void 0 : _a.masking) || {};
26709
26915
  const options = {
26710
- maskAllInputs: (_a = maskingConfig.maskAllInputs) !== null && _a !== void 0 ? _a : true,
26916
+ maskAllInputs: (_b = maskingConfig.maskAllInputs) !== null && _b !== void 0 ? _b : true,
26711
26917
  sampling: { canvas: 5 },
26712
- recordCanvas: this.config.recordCanvas,
26918
+ recordCanvas: (_c = this.config) === null || _c === void 0 ? void 0 : _c.recordCanvas,
26713
26919
  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
- ],
26920
+ plugins: [(0,_rrweb_rrweb_plugin_console_record__WEBPACK_IMPORTED_MODULE_3__.getRecordConsolePlugin)({ level: ['log', 'error'] })]
26717
26921
  };
26718
- // Add mask input options if provided
26719
26922
  if (maskingConfig.maskInputOptions) {
26720
26923
  options.maskInputOptions = maskingConfig.maskInputOptions;
26721
26924
  }
26722
- // Add mask text class if provided
26723
26925
  if (maskingConfig.maskTextClass) {
26724
26926
  options.maskTextClass = maskingConfig.maskTextClass;
26725
26927
  }
26726
- // Add mask text selector if provided
26727
26928
  if (maskingConfig.maskTextSelector) {
26728
26929
  options.maskTextSelector = maskingConfig.maskTextSelector;
26729
26930
  }
26730
- // Add custom masking functions if provided
26731
26931
  if (typeof maskingConfig.maskInput === 'function') {
26732
26932
  options.maskInputFn = maskingConfig.maskInput;
26733
26933
  }
26734
26934
  if (typeof maskingConfig.maskText === 'function') {
26735
26935
  options.maskTextFn = maskingConfig.maskText;
26736
26936
  }
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
- }
26765
- }
26766
- /**
26767
- * Restarts the recording of events.
26768
- */
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);
26937
+ return options;
26773
26938
  }
26774
26939
  /**
26775
- * Clears the restart timeout.
26940
+ * Sets up periodic snapshots.
26941
+ * @param sessionId - Session ID.
26942
+ * @param sessionType - Session type.
26776
26943
  */
26777
- clearRestartInterval() {
26778
- if (this.restartInterval) {
26779
- clearInterval(this.restartInterval);
26780
- this.restartInterval = null;
26944
+ _setupPeriodicSnapshots(sessionId, sessionType) {
26945
+ var _a, _b;
26946
+ this._clearAllIntervals();
26947
+ if (sessionType === _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_2__.SessionType.CONTINUOUS) {
26948
+ this.intervals.restart = setInterval(() => {
26949
+ this.takeFullSnapshot();
26950
+ }, _config__WEBPACK_IMPORTED_MODULE_5__.CONTINUOUS_DEBUGGING_TIMEOUT);
26781
26951
  }
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();
26952
+ if (!sessionId && ((_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.buffering) === null || _b === void 0 ? void 0 : _b.enabled)) {
26953
+ const interval = this.config.buffering.snapshotIntervalMs || 30000;
26954
+ this.intervals.bufferSnapshot = setInterval(() => {
26955
+ this.takeFullSnapshot();
26956
+ }, interval);
26791
26957
  }
26792
- this.clearRestartInterval();
26793
26958
  }
26794
26959
  }
26795
26960
 
@@ -26814,7 +26979,7 @@ class ApiService {
26814
26979
  this.config = {
26815
26980
  apiKey: '',
26816
26981
  apiBaseUrl: '',
26817
- exporterEndpoint: '',
26982
+ exporterEndpoint: ''
26818
26983
  };
26819
26984
  }
26820
26985
  /**
@@ -26824,7 +26989,7 @@ class ApiService {
26824
26989
  init(config) {
26825
26990
  this.config = {
26826
26991
  ...this.config,
26827
- ...config,
26992
+ ...config
26828
26993
  };
26829
26994
  }
26830
26995
  /**
@@ -26842,6 +27007,14 @@ class ApiService {
26842
27007
  async startSession(request, signal) {
26843
27008
  return this.makeRequest('/debug-sessions/start', 'POST', request, signal);
26844
27009
  }
27010
+ /**
27011
+ * Create a new error span session
27012
+ * @param request - Session create error span request data
27013
+ * @param signal - Optional AbortSignal for request cancellation
27014
+ */
27015
+ async createErrorSession(request, signal) {
27016
+ return this.makeRequest('/debug-sessions/error-span/start', 'POST', request, signal);
27017
+ }
26845
27018
  /**
26846
27019
  * Stop an active debug session
26847
27020
  * @param sessionId - ID of the session to stop
@@ -26887,6 +27060,15 @@ class ApiService {
26887
27060
  async checkRemoteSession(requestBody, signal) {
26888
27061
  return this.makeRequest('/remote-debug-session/check', 'POST', requestBody, signal);
26889
27062
  }
27063
+ updateSessionAttributes(sessionId, requestBody, signal) {
27064
+ return this.makeRequest(`/debug-sessions/${sessionId}`, 'PATCH', requestBody, signal);
27065
+ }
27066
+ /**
27067
+ * Export events to the session debugger API
27068
+ */
27069
+ async exportEvents(sessionId, requestBody, signal) {
27070
+ return this.makeRequest(`/debug-sessions/${sessionId}/rrweb-events`, 'POST', requestBody, signal);
27071
+ }
26890
27072
  /**
26891
27073
  * Make a request to the session debugger API
26892
27074
  * @param path - API endpoint path (relative to the base URL)
@@ -26901,14 +27083,14 @@ class ApiService {
26901
27083
  body: body ? JSON.stringify(body) : null,
26902
27084
  headers: {
26903
27085
  'Content-Type': 'application/json',
26904
- ...(this.config.apiKey && { 'X-Api-Key': this.config.apiKey }),
26905
- },
27086
+ ...(this.config.apiKey && { 'X-Api-Key': this.config.apiKey })
27087
+ }
26906
27088
  };
26907
27089
  try {
26908
27090
  const response = await fetch(url, {
26909
27091
  ...params,
26910
27092
  credentials: 'include',
26911
- signal,
27093
+ signal
26912
27094
  });
26913
27095
  if (!response.ok) {
26914
27096
  throw new Error('Network response was not ok: ' + response.statusText);
@@ -26925,19 +27107,593 @@ class ApiService {
26925
27107
  return this.handleRequestError(error, { url, params });
26926
27108
  }
26927
27109
  }
26928
- async handleRequestError(error, payload) {
26929
- if (this.config.usePostMessageFallback) {
26930
- try {
26931
- const response = await _messaging_service__WEBPACK_IMPORTED_MODULE_0__["default"].sendMessagePromise('request', payload);
26932
- return response;
26933
- }
26934
- catch (error) {
26935
- throw new Error('Error making request: ' + error.message);
26936
- }
26937
- }
26938
- else {
26939
- throw new Error('Error making request: ' + error.message);
26940
- }
27110
+ async handleRequestError(error, payload) {
27111
+ if (this.config.usePostMessageFallback) {
27112
+ try {
27113
+ const response = await _messaging_service__WEBPACK_IMPORTED_MODULE_0__["default"].sendMessagePromise('request', payload);
27114
+ return response;
27115
+ }
27116
+ catch (error) {
27117
+ throw new Error('Error making request: ' + error.message);
27118
+ }
27119
+ }
27120
+ else {
27121
+ throw new Error('Error making request: ' + error.message);
27122
+ }
27123
+ }
27124
+ }
27125
+
27126
+
27127
+ /***/ }),
27128
+
27129
+ /***/ "./src/services/crashBuffer.service.ts":
27130
+ /*!*********************************************!*\
27131
+ !*** ./src/services/crashBuffer.service.ts ***!
27132
+ \*********************************************/
27133
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
27134
+
27135
+ "use strict";
27136
+ __webpack_require__.r(__webpack_exports__);
27137
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
27138
+ /* harmony export */ CrashBufferService: () => (/* binding */ CrashBufferService)
27139
+ /* harmony export */ });
27140
+ /* harmony import */ var _opentelemetry_api__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @opentelemetry/api */ "../../node_modules/@opentelemetry/api/build/esm/trace/status.js");
27141
+
27142
+ class CrashBufferService {
27143
+ constructor(db, tabId, windowMs) {
27144
+ this.db = db;
27145
+ this.tabId = tabId;
27146
+ this.windowMs = windowMs;
27147
+ this.lastPruneAt = 0;
27148
+ this.pruneInFlight = null;
27149
+ this.isActive = true;
27150
+ this.frozenAtTs = null;
27151
+ this.lastSeenEventTs = 0;
27152
+ this.requiresFullSnapshot = true;
27153
+ this.lastTouchAt = 0;
27154
+ this.listeners = new Map();
27155
+ }
27156
+ async _safe(fn, fallback) {
27157
+ try {
27158
+ return await fn();
27159
+ }
27160
+ catch (_e) {
27161
+ return fallback;
27162
+ }
27163
+ }
27164
+ async setAttrs(attrs) {
27165
+ await this._safe(async () => {
27166
+ await this.db.setAttrs({
27167
+ tabId: this.tabId,
27168
+ ...attrs
27169
+ });
27170
+ }, undefined);
27171
+ }
27172
+ async appendEvent(payload, _windowMs) {
27173
+ this.lastSeenEventTs = Math.max(this.lastSeenEventTs, payload.ts || 0);
27174
+ if (!this.isActive)
27175
+ return;
27176
+ const isFullSnapshot = Boolean(payload.isFullSnapshot);
27177
+ if (this.requiresFullSnapshot && !isFullSnapshot) {
27178
+ // Buffer must always start with a full snapshot; drop incrementals until we see one.
27179
+ return;
27180
+ }
27181
+ await this._safe(async () => {
27182
+ await this.db.appendEvent({
27183
+ tabId: this.tabId,
27184
+ ts: payload.ts,
27185
+ isFullSnapshot: payload.isFullSnapshot,
27186
+ event: payload.event
27187
+ });
27188
+ }, undefined);
27189
+ if (isFullSnapshot && this.requiresFullSnapshot) {
27190
+ // Ensure this snapshot becomes the first replayable event.
27191
+ // We keep the snapshot itself and prune everything older.
27192
+ await this._safe(() => this.db.pruneOlderThan(this.tabId, Math.max(0, payload.ts - 1)), undefined);
27193
+ this.requiresFullSnapshot = false;
27194
+ }
27195
+ else if (isFullSnapshot) {
27196
+ this.requiresFullSnapshot = false;
27197
+ }
27198
+ this.pruneSoon();
27199
+ }
27200
+ async appendSpans(payload, _windowMs) {
27201
+ for (const p of payload) {
27202
+ this.lastSeenEventTs = Math.max(this.lastSeenEventTs, p.ts || 0);
27203
+ }
27204
+ if (!this.isActive)
27205
+ return;
27206
+ let errorEvent = null;
27207
+ await this._safe(async () => {
27208
+ const records = payload.map((p) => {
27209
+ var _a, _b;
27210
+ if (!errorEvent && ((_b = (_a = p === null || p === void 0 ? void 0 : p.span) === null || _a === void 0 ? void 0 : _a.status) === null || _b === void 0 ? void 0 : _b.code) === _opentelemetry_api__WEBPACK_IMPORTED_MODULE_0__.SpanStatusCode.ERROR) {
27211
+ errorEvent = { ts: p.ts, span: p.span };
27212
+ }
27213
+ return {
27214
+ tabId: this.tabId,
27215
+ ts: p.ts,
27216
+ span: p.span
27217
+ };
27218
+ });
27219
+ await this.db.appendSpans(records);
27220
+ }, undefined);
27221
+ this.pruneSoon();
27222
+ if (errorEvent) {
27223
+ this._emit('error-span-appended', errorEvent);
27224
+ }
27225
+ }
27226
+ on(event, listener) {
27227
+ const set = this.listeners.get(event) || new Set();
27228
+ set.add(listener);
27229
+ this.listeners.set(event, set);
27230
+ return () => this.off(event, listener);
27231
+ }
27232
+ off(event, listener) {
27233
+ const set = this.listeners.get(event);
27234
+ if (!set)
27235
+ return;
27236
+ set.delete(listener);
27237
+ if (set.size === 0)
27238
+ this.listeners.delete(event);
27239
+ }
27240
+ _emit(event, payload) {
27241
+ const set = this.listeners.get(event);
27242
+ if (!set || set.size === 0)
27243
+ return;
27244
+ for (const fn of Array.from(set)) {
27245
+ try {
27246
+ ;
27247
+ fn(payload);
27248
+ }
27249
+ catch (_e) {
27250
+ // never throw into app code
27251
+ }
27252
+ }
27253
+ }
27254
+ async snapshot(_windowMs, now = Date.now()) {
27255
+ const toTs = now;
27256
+ const fromTs = Math.max(0, toTs - this.windowMs);
27257
+ // Always include a full snapshot "anchor" if one exists at/before the window start.
27258
+ const rrwebFromTs = await this._safe(async () => {
27259
+ const anchor = await this.db.getLastRrwebFullSnapshotBefore(this.tabId, fromTs);
27260
+ return typeof (anchor === null || anchor === void 0 ? void 0 : anchor.ts) === 'number' ? anchor.ts : fromTs;
27261
+ }, fromTs);
27262
+ const [rrweb, spans, attrs] = await Promise.all([
27263
+ this._safe(() => this.db.getRrwebEventsWindow(this.tabId, rrwebFromTs, toTs), []),
27264
+ this._safe(() => this.db.getOtelSpansWindow(this.tabId, fromTs, toTs), []),
27265
+ this._safe(() => this.db.getAttrs(this.tabId), null)
27266
+ ]);
27267
+ const rrwebSorted = rrweb
27268
+ .sort((a, b) => a.ts - b.ts)
27269
+ .map((r) => ({ ts: r.ts, isFullSnapshot: r.isFullSnapshot, event: r.event }));
27270
+ // Hard guarantee: snapshot payload starts with a FullSnapshot (or is empty).
27271
+ const firstFullSnapshotIdx = rrwebSorted.findIndex((e) => Boolean(e.isFullSnapshot));
27272
+ const rrwebEvents = firstFullSnapshotIdx >= 0 ? rrwebSorted.slice(firstFullSnapshotIdx) : [];
27273
+ // Align spans with the rrweb replay start: spans must start from the FullSnapshot timestamp.
27274
+ const replayStartTs = rrwebEvents.length > 0 ? rrwebEvents[0].ts : fromTs;
27275
+ const otelSpans = spans
27276
+ .filter((s) => typeof (s === null || s === void 0 ? void 0 : s.ts) === 'number' && s.ts >= replayStartTs)
27277
+ .sort((a, b) => a.ts - b.ts)
27278
+ .map((r) => ({ ts: r.ts, span: r.span }));
27279
+ return {
27280
+ rrwebEvents,
27281
+ otelSpans,
27282
+ attrs: attrs
27283
+ ? {
27284
+ sessionAttributes: attrs.sessionAttributes,
27285
+ resourceAttributes: attrs.resourceAttributes,
27286
+ userAttributes: attrs.userAttributes
27287
+ }
27288
+ : null,
27289
+ windowMs: this.windowMs,
27290
+ fromTs: replayStartTs,
27291
+ toTs
27292
+ };
27293
+ }
27294
+ async clear() {
27295
+ await this._safe(() => this.db.clearTab(this.tabId), undefined);
27296
+ this.requiresFullSnapshot = true;
27297
+ }
27298
+ needsFullSnapshot() {
27299
+ return this.requiresFullSnapshot;
27300
+ }
27301
+ /**
27302
+ * Mark the tab as active/inactive.
27303
+ *
27304
+ * - When inactive, we freeze the buffer and keep the last active `windowMs` indefinitely.
27305
+ * - When re-activated, we resume buffering but require a new FullSnapshot to start a replayable segment.
27306
+ */
27307
+ setActive(active) {
27308
+ if (this.isActive === active)
27309
+ return;
27310
+ this.isActive = active;
27311
+ if (!active) {
27312
+ const freezeAt = this.lastSeenEventTs || Date.now();
27313
+ this.frozenAtTs = freezeAt;
27314
+ // Keep the last active window, but preserve rrweb replayability via snapshot anchor.
27315
+ const cutoff = Math.max(0, freezeAt - this.windowMs);
27316
+ void this._safe(() => this.db.pruneOlderThanWithRrwebSnapshotAnchor(this.tabId, cutoff), undefined);
27317
+ return;
27318
+ }
27319
+ const wasFrozen = this.frozenAtTs !== null;
27320
+ this.frozenAtTs = null;
27321
+ // New active segment must start with a full snapshot (don’t stitch segments together).
27322
+ if (wasFrozen)
27323
+ this.requiresFullSnapshot = true;
27324
+ this.pruneSoon();
27325
+ }
27326
+ pruneSoon() {
27327
+ if (!this.isActive)
27328
+ return;
27329
+ const now = Date.now();
27330
+ // Throttle pruning to avoid hammering IDB on high event rates
27331
+ if (now - this.lastPruneAt < 2000)
27332
+ return;
27333
+ if (this.pruneInFlight)
27334
+ return;
27335
+ this.lastPruneAt = now;
27336
+ const cutoff = Math.max(0, now - this.windowMs);
27337
+ // Heartbeat so the stale-tab sweeper never deletes active tabs.
27338
+ if (now - this.lastTouchAt > 30000) {
27339
+ this.lastTouchAt = now;
27340
+ void this._safe(() => this.db.touchTab(this.tabId, now), undefined);
27341
+ }
27342
+ this.pruneInFlight = this._safe(() => this.db.pruneOlderThanWithRrwebSnapshotAnchor(this.tabId, cutoff), undefined).finally(() => {
27343
+ this.pruneInFlight = null;
27344
+ });
27345
+ }
27346
+ }
27347
+
27348
+
27349
+ /***/ }),
27350
+
27351
+ /***/ "./src/services/indexedDb.service.ts":
27352
+ /*!*******************************************!*\
27353
+ !*** ./src/services/indexedDb.service.ts ***!
27354
+ \*******************************************/
27355
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
27356
+
27357
+ "use strict";
27358
+ __webpack_require__.r(__webpack_exports__);
27359
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
27360
+ /* harmony export */ IndexedDBService: () => (/* binding */ IndexedDBService)
27361
+ /* harmony export */ });
27362
+ const dbName = 'mpEventsDB';
27363
+ const dbVersion = 2;
27364
+ const legacyStoreName = 'mpEventsStore';
27365
+ const rrwebEventsStore = 'rrwebEvents';
27366
+ const otelSpansStore = 'otelSpans';
27367
+ const attrsStore = 'crashBufferAttrs';
27368
+ class IndexedDBService {
27369
+ constructor() {
27370
+ this.dbPromise = this.openDB();
27371
+ }
27372
+ openDB() {
27373
+ return new Promise((resolve, reject) => {
27374
+ const request = indexedDB.open(dbName, dbVersion);
27375
+ request.onupgradeneeded = () => {
27376
+ const db = request.result;
27377
+ // Keep the legacy store if it exists to avoid breaking older versions.
27378
+ if (!db.objectStoreNames.contains(legacyStoreName)) {
27379
+ db.createObjectStore(legacyStoreName, { keyPath: 'id', autoIncrement: true });
27380
+ }
27381
+ if (!db.objectStoreNames.contains(rrwebEventsStore)) {
27382
+ const store = db.createObjectStore(rrwebEventsStore, { keyPath: 'id', autoIncrement: true });
27383
+ store.createIndex('tabId_ts', ['tabId', 'ts'], { unique: false });
27384
+ }
27385
+ if (!db.objectStoreNames.contains(otelSpansStore)) {
27386
+ const store = db.createObjectStore(otelSpansStore, { keyPath: 'id', autoIncrement: true });
27387
+ store.createIndex('tabId_ts', ['tabId', 'ts'], { unique: false });
27388
+ }
27389
+ if (!db.objectStoreNames.contains(attrsStore)) {
27390
+ db.createObjectStore(attrsStore, { keyPath: 'tabId' });
27391
+ }
27392
+ };
27393
+ request.onsuccess = () => resolve(request.result);
27394
+ request.onerror = () => reject(request.error);
27395
+ });
27396
+ }
27397
+ /**
27398
+ * @deprecated Prefer `appendEvent(tabId, ...)` and `getRrwebEventsWindow(...)`.
27399
+ * This writes into the legacy store with no pruning semantics.
27400
+ */
27401
+ async saveEvent(event) {
27402
+ const db = await this.dbPromise;
27403
+ return new Promise((resolve, reject) => {
27404
+ const tx = db.transaction(legacyStoreName, 'readwrite');
27405
+ const store = tx.objectStore(legacyStoreName);
27406
+ store.add({ event });
27407
+ tx.oncomplete = () => resolve();
27408
+ tx.onerror = () => reject(tx.error);
27409
+ });
27410
+ }
27411
+ /**
27412
+ * @deprecated Prefer `getRrwebEventsWindow(...)`.
27413
+ */
27414
+ async getAllEvents() {
27415
+ const db = await this.dbPromise;
27416
+ return new Promise((resolve, reject) => {
27417
+ const tx = db.transaction(legacyStoreName, 'readonly');
27418
+ const store = tx.objectStore(legacyStoreName);
27419
+ const request = store.getAll();
27420
+ request.onsuccess = () => {
27421
+ const events = request.result.map((record) => record.event);
27422
+ resolve(events);
27423
+ };
27424
+ request.onerror = () => reject(request.error);
27425
+ });
27426
+ }
27427
+ /**
27428
+ * @deprecated Prefer `clearTab(tabId)`.
27429
+ */
27430
+ async clearEvents() {
27431
+ const db = await this.dbPromise;
27432
+ return new Promise((resolve, reject) => {
27433
+ const tx = db.transaction(legacyStoreName, 'readwrite');
27434
+ const store = tx.objectStore(legacyStoreName);
27435
+ store.clear();
27436
+ tx.oncomplete = () => resolve();
27437
+ tx.onerror = () => reject(tx.error);
27438
+ });
27439
+ }
27440
+ async setAttrs(attrs) {
27441
+ var _a;
27442
+ const db = await this.dbPromise;
27443
+ const payload = {
27444
+ ...attrs,
27445
+ updatedAt: (_a = attrs.updatedAt) !== null && _a !== void 0 ? _a : Date.now()
27446
+ };
27447
+ return new Promise((resolve, reject) => {
27448
+ const tx = db.transaction(attrsStore, 'readwrite');
27449
+ tx.objectStore(attrsStore).put(payload);
27450
+ tx.oncomplete = () => resolve();
27451
+ tx.onerror = () => reject(tx.error);
27452
+ });
27453
+ }
27454
+ async getAttrs(tabId) {
27455
+ const db = await this.dbPromise;
27456
+ return new Promise((resolve, reject) => {
27457
+ const tx = db.transaction(attrsStore, 'readonly');
27458
+ const request = tx.objectStore(attrsStore).get(tabId);
27459
+ request.onsuccess = () => resolve(request.result || null);
27460
+ request.onerror = () => reject(request.error);
27461
+ });
27462
+ }
27463
+ async getAllAttrs() {
27464
+ const db = await this.dbPromise;
27465
+ return new Promise((resolve, reject) => {
27466
+ const tx = db.transaction(attrsStore, 'readonly');
27467
+ const request = tx.objectStore(attrsStore).getAll();
27468
+ request.onsuccess = () => resolve(request.result || []);
27469
+ request.onerror = () => reject(request.error);
27470
+ });
27471
+ }
27472
+ /**
27473
+ * Updates `updatedAt` for the tab without clobbering existing attributes.
27474
+ */
27475
+ async touchTab(tabId, updatedAt = Date.now()) {
27476
+ const db = await this.dbPromise;
27477
+ return new Promise((resolve, reject) => {
27478
+ const tx = db.transaction(attrsStore, 'readwrite');
27479
+ const store = tx.objectStore(attrsStore);
27480
+ const getReq = store.get(tabId);
27481
+ getReq.onsuccess = () => {
27482
+ const existing = (getReq.result || null);
27483
+ const next = existing ? { ...existing, updatedAt } : { tabId, updatedAt };
27484
+ store.put(next);
27485
+ };
27486
+ getReq.onerror = () => reject(getReq.error);
27487
+ tx.oncomplete = () => resolve();
27488
+ tx.onerror = () => reject(tx.error);
27489
+ });
27490
+ }
27491
+ /**
27492
+ * Best-effort garbage collection for orphaned tabs.
27493
+ * Deletes all data for tabs whose `attrs.updatedAt` is older than `maxAgeMs`.
27494
+ */
27495
+ async sweepStaleTabs(maxAgeMs, now = Date.now()) {
27496
+ const attrs = await this.getAllAttrs().catch(() => []);
27497
+ if (!attrs.length)
27498
+ return 0;
27499
+ const stale = attrs
27500
+ .filter((a) => typeof (a === null || a === void 0 ? void 0 : a.updatedAt) === 'number' && now - a.updatedAt > maxAgeMs)
27501
+ .map((a) => a.tabId);
27502
+ let cleared = 0;
27503
+ for (const tabId of stale) {
27504
+ try {
27505
+ await this.clearTab(tabId);
27506
+ cleared += 1;
27507
+ }
27508
+ catch (_e) {
27509
+ // best effort
27510
+ }
27511
+ }
27512
+ return cleared;
27513
+ }
27514
+ async appendEvent(record) {
27515
+ const db = await this.dbPromise;
27516
+ return new Promise((resolve, reject) => {
27517
+ const tx = db.transaction(rrwebEventsStore, 'readwrite');
27518
+ tx.objectStore(rrwebEventsStore).add(record);
27519
+ tx.oncomplete = () => resolve();
27520
+ tx.onerror = () => reject(tx.error);
27521
+ });
27522
+ }
27523
+ async appendSpans(records) {
27524
+ if (!records.length)
27525
+ return;
27526
+ const db = await this.dbPromise;
27527
+ return new Promise((resolve, reject) => {
27528
+ const tx = db.transaction(otelSpansStore, 'readwrite');
27529
+ const store = tx.objectStore(otelSpansStore);
27530
+ for (const record of records) {
27531
+ store.add(record);
27532
+ }
27533
+ tx.oncomplete = () => resolve();
27534
+ tx.onerror = () => reject(tx.error);
27535
+ });
27536
+ }
27537
+ async getRrwebEventsWindow(tabId, fromTs, toTs) {
27538
+ const db = await this.dbPromise;
27539
+ const range = IDBKeyRange.bound([tabId, fromTs], [tabId, toTs]);
27540
+ return new Promise((resolve, reject) => {
27541
+ const tx = db.transaction(rrwebEventsStore, 'readonly');
27542
+ const idx = tx.objectStore(rrwebEventsStore).index('tabId_ts');
27543
+ const req = idx.getAll(range);
27544
+ req.onsuccess = () => resolve(req.result || []);
27545
+ req.onerror = () => reject(req.error);
27546
+ });
27547
+ }
27548
+ /**
27549
+ * Returns the last (highest-ts) FullSnapshot record at/before `cutoffTs`.
27550
+ * Used to keep a replayable anchor when pruning.
27551
+ */
27552
+ async getLastRrwebFullSnapshotBefore(tabId, cutoffTs) {
27553
+ const db = await this.dbPromise;
27554
+ const range = IDBKeyRange.bound([tabId, 0], [tabId, cutoffTs]);
27555
+ return new Promise((resolve, reject) => {
27556
+ const tx = db.transaction(rrwebEventsStore, 'readonly');
27557
+ const idx = tx.objectStore(rrwebEventsStore).index('tabId_ts');
27558
+ const req = idx.openCursor(range, 'prev');
27559
+ req.onsuccess = () => {
27560
+ const cursor = req.result;
27561
+ if (!cursor) {
27562
+ resolve(null);
27563
+ return;
27564
+ }
27565
+ const value = cursor.value;
27566
+ if (value === null || value === void 0 ? void 0 : value.isFullSnapshot) {
27567
+ resolve(value);
27568
+ return;
27569
+ }
27570
+ cursor.continue();
27571
+ };
27572
+ req.onerror = () => reject(req.error);
27573
+ });
27574
+ }
27575
+ async getOtelSpansWindow(tabId, fromTs, toTs) {
27576
+ const db = await this.dbPromise;
27577
+ const range = IDBKeyRange.bound([tabId, fromTs], [tabId, toTs]);
27578
+ return new Promise((resolve, reject) => {
27579
+ const tx = db.transaction(otelSpansStore, 'readonly');
27580
+ const idx = tx.objectStore(otelSpansStore).index('tabId_ts');
27581
+ const req = idx.getAll(range);
27582
+ req.onsuccess = () => resolve(req.result || []);
27583
+ req.onerror = () => reject(req.error);
27584
+ });
27585
+ }
27586
+ async pruneOlderThan(tabId, cutoffTs) {
27587
+ const db = await this.dbPromise;
27588
+ const rrwebRange = IDBKeyRange.bound([tabId, 0], [tabId, cutoffTs]);
27589
+ const spansRange = IDBKeyRange.bound([tabId, 0], [tabId, cutoffTs]);
27590
+ const pruneStore = (store, range) => new Promise((resolve, reject) => {
27591
+ const idx = store.index('tabId_ts');
27592
+ const req = idx.openCursor(range);
27593
+ req.onsuccess = () => {
27594
+ const cursor = req.result;
27595
+ if (!cursor) {
27596
+ resolve();
27597
+ return;
27598
+ }
27599
+ cursor.delete();
27600
+ cursor.continue();
27601
+ };
27602
+ req.onerror = () => reject(req.error);
27603
+ });
27604
+ return new Promise((resolve, reject) => {
27605
+ const tx = db.transaction([rrwebEventsStore, otelSpansStore], 'readwrite');
27606
+ const rrwebStore = tx.objectStore(rrwebEventsStore);
27607
+ const spanStore = tx.objectStore(otelSpansStore);
27608
+ Promise.all([pruneStore(rrwebStore, rrwebRange), pruneStore(spanStore, spansRange)])
27609
+ .then(() => {
27610
+ // noop; completion is signaled by tx.oncomplete
27611
+ })
27612
+ .catch((e) => {
27613
+ reject(e);
27614
+ });
27615
+ tx.oncomplete = () => resolve();
27616
+ tx.onerror = () => reject(tx.error);
27617
+ });
27618
+ }
27619
+ /**
27620
+ * Prune older data while keeping rrweb replayability:
27621
+ * - rrweb: keep the last FullSnapshot at/before cutoff as an "anchor"
27622
+ * - spans: prune strictly by cutoff
27623
+ */
27624
+ async pruneOlderThanWithRrwebSnapshotAnchor(tabId, cutoffTs) {
27625
+ const db = await this.dbPromise;
27626
+ const anchor = await this.getLastRrwebFullSnapshotBefore(tabId, cutoffTs);
27627
+ // rrweb: delete everything strictly older than the anchor snapshot (keep the anchor itself)
27628
+ // spans: delete everything older than cutoffTs
27629
+ const rrwebCutoffTs = typeof (anchor === null || anchor === void 0 ? void 0 : anchor.ts) === 'number' ? Math.max(0, anchor.ts - 1) : cutoffTs;
27630
+ const rrwebRange = IDBKeyRange.bound([tabId, 0], [tabId, rrwebCutoffTs]);
27631
+ const spansRange = IDBKeyRange.bound([tabId, 0], [tabId, cutoffTs]);
27632
+ const pruneStore = (store, range) => new Promise((resolve, reject) => {
27633
+ const idx = store.index('tabId_ts');
27634
+ const req = idx.openCursor(range);
27635
+ req.onsuccess = () => {
27636
+ const cursor = req.result;
27637
+ if (!cursor) {
27638
+ resolve();
27639
+ return;
27640
+ }
27641
+ cursor.delete();
27642
+ cursor.continue();
27643
+ };
27644
+ req.onerror = () => reject(req.error);
27645
+ });
27646
+ return new Promise((resolve, reject) => {
27647
+ const tx = db.transaction([rrwebEventsStore, otelSpansStore], 'readwrite');
27648
+ const rrwebStore = tx.objectStore(rrwebEventsStore);
27649
+ const spanStore = tx.objectStore(otelSpansStore);
27650
+ Promise.all([pruneStore(rrwebStore, rrwebRange), pruneStore(spanStore, spansRange)])
27651
+ .then(() => {
27652
+ // noop
27653
+ })
27654
+ .catch((e) => reject(e));
27655
+ tx.oncomplete = () => resolve();
27656
+ tx.onerror = () => reject(tx.error);
27657
+ });
27658
+ }
27659
+ async clearTab(tabId) {
27660
+ const db = await this.dbPromise;
27661
+ const allRange = IDBKeyRange.bound([tabId, 0], [tabId, Number.MAX_SAFE_INTEGER]);
27662
+ const clearByTab = (store) => new Promise((resolve, reject) => {
27663
+ const idx = store.index('tabId_ts');
27664
+ const req = idx.openCursor(allRange);
27665
+ req.onsuccess = () => {
27666
+ const cursor = req.result;
27667
+ if (!cursor) {
27668
+ resolve();
27669
+ return;
27670
+ }
27671
+ cursor.delete();
27672
+ cursor.continue();
27673
+ };
27674
+ req.onerror = () => reject(req.error);
27675
+ });
27676
+ return new Promise((resolve, reject) => {
27677
+ const tx = db.transaction([rrwebEventsStore, otelSpansStore, attrsStore], 'readwrite');
27678
+ const rrwebStore = tx.objectStore(rrwebEventsStore);
27679
+ const spanStore = tx.objectStore(otelSpansStore);
27680
+ const attr = tx.objectStore(attrsStore);
27681
+ Promise.all([
27682
+ clearByTab(rrwebStore),
27683
+ clearByTab(spanStore),
27684
+ new Promise((res, rej) => {
27685
+ const r = attr.delete(tabId);
27686
+ r.onsuccess = () => res();
27687
+ r.onerror = () => rej(r.error);
27688
+ })
27689
+ ])
27690
+ .then(() => {
27691
+ // noop
27692
+ })
27693
+ .catch((e) => reject(e));
27694
+ tx.oncomplete = () => resolve();
27695
+ tx.onerror = () => reject(tx.error);
27696
+ });
26941
27697
  }
26942
27698
  }
26943
27699
 
@@ -27064,15 +27820,17 @@ __webpack_require__.r(__webpack_exports__);
27064
27820
  /* harmony export */ SocketService: () => (/* binding */ SocketService)
27065
27821
  /* harmony export */ });
27066
27822
  /* 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");
27823
+ /* harmony import */ var lib0_observable__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! lib0/observable */ "../../node_modules/lib0/observable.js");
27068
27824
  /* harmony import */ var _services_messaging_service__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../services/messaging.service */ "./src/services/messaging.service.ts");
27069
27825
  /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../config */ "./src/config/index.ts");
27826
+ /* 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");
27827
+
27070
27828
 
27071
27829
 
27072
27830
 
27073
27831
 
27074
27832
  const MAX_RECONNECTION_ATTEMPTS = 2;
27075
- class SocketService extends lib0_observable__WEBPACK_IMPORTED_MODULE_3__.Observable {
27833
+ class SocketService extends lib0_observable__WEBPACK_IMPORTED_MODULE_4__.Observable {
27076
27834
  constructor() {
27077
27835
  super();
27078
27836
  this.socket = null;
@@ -27139,6 +27897,9 @@ class SocketService extends lib0_observable__WEBPACK_IMPORTED_MODULE_3__.Observa
27139
27897
  path: '/v0/radar/ws',
27140
27898
  auth: {
27141
27899
  'x-api-key': this.options.apiKey,
27900
+ ...this.options.clientId
27901
+ ? { [_multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_3__.ATTR_MULTIPLAYER_SESSION_CLIENT_ID]: this.options.clientId }
27902
+ : {},
27142
27903
  },
27143
27904
  reconnectionAttempts: 2,
27144
27905
  transports: ['websocket'],
@@ -27170,6 +27931,9 @@ class SocketService extends lib0_observable__WEBPACK_IMPORTED_MODULE_3__.Observa
27170
27931
  this.socket.on(_config__WEBPACK_IMPORTED_MODULE_2__.REMOTE_SESSION_RECORDING_STOP, (data) => {
27171
27932
  this.emit(_config__WEBPACK_IMPORTED_MODULE_2__.REMOTE_SESSION_RECORDING_STOP, [data]);
27172
27933
  });
27934
+ this.socket.on(_config__WEBPACK_IMPORTED_MODULE_2__.SESSION_SAVE_BUFFER_EVENT, (data) => {
27935
+ this.emit(_config__WEBPACK_IMPORTED_MODULE_2__.SESSION_SAVE_BUFFER_EVENT, [data]);
27936
+ });
27173
27937
  }
27174
27938
  checkReconnectionAttempts() {
27175
27939
  if (this.attempts >= MAX_RECONNECTION_ATTEMPTS) {
@@ -27271,21 +28035,25 @@ __webpack_require__.r(__webpack_exports__);
27271
28035
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
27272
28036
  /* harmony export */ SessionRecorder: () => (/* binding */ SessionRecorder)
27273
28037
  /* harmony export */ });
27274
- /* harmony import */ var lib0_observable__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! lib0/observable */ "../../node_modules/lib0/observable.js");
28038
+ /* harmony import */ var lib0_observable__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! lib0/observable */ "../../node_modules/lib0/observable.js");
27275
28039
  /* 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
28040
  /* harmony import */ var _otel__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./otel */ "./src/otel/index.ts");
27277
28041
  /* harmony import */ var _rrweb__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./rrweb */ "./src/rrweb/index.ts");
27278
28042
  /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./utils */ "./src/utils/index.ts");
27279
28043
  /* 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");
28044
+ /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./config */ "./src/config/index.ts");
28045
+ /* harmony import */ var _patch__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./patch */ "./src/patch/index.ts");
28046
+ /* harmony import */ var _eventBus__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./eventBus */ "./src/eventBus.ts");
28047
+ /* harmony import */ var _sessionWidget__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./sessionWidget */ "./src/sessionWidget/index.ts");
28048
+ /* harmony import */ var _services_messaging_service__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./services/messaging.service */ "./src/services/messaging.service.ts");
28049
+ /* harmony import */ var _services_api_service__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./services/api.service */ "./src/services/api.service.ts");
28050
+ /* harmony import */ var _services_socket_service__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./services/socket.service */ "./src/services/socket.service.ts");
28051
+ /* harmony import */ var _services_indexedDb_service__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./services/indexedDb.service */ "./src/services/indexedDb.service.ts");
28052
+ /* harmony import */ var _services_crashBuffer_service__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./services/crashBuffer.service */ "./src/services/crashBuffer.service.ts");
28053
+ /* harmony import */ var _sessionWidget_buttonStateConfigs__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./sessionWidget/buttonStateConfigs */ "./src/sessionWidget/buttonStateConfigs.ts");
28054
+ /* harmony import */ var _navigation__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./navigation */ "./src/navigation/index.ts");
28055
+
28056
+
27289
28057
 
27290
28058
 
27291
28059
 
@@ -27301,7 +28069,7 @@ __webpack_require__.r(__webpack_exports__);
27301
28069
 
27302
28070
 
27303
28071
 
27304
- class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Observable {
28072
+ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_16__.Observable {
27305
28073
  get navigation() {
27306
28074
  return this._navigationRecorder.api;
27307
28075
  }
@@ -27313,7 +28081,7 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27313
28081
  }
27314
28082
  set sessionId(sessionId) {
27315
28083
  this._sessionId = sessionId;
27316
- (0,_utils__WEBPACK_IMPORTED_MODULE_3__.setStoredItem)(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_ID_PROP_NAME, sessionId);
28084
+ (0,_utils__WEBPACK_IMPORTED_MODULE_3__.setStoredItem)(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_ID_PROP_NAME, sessionId);
27317
28085
  }
27318
28086
  get sessionType() {
27319
28087
  return this._sessionType;
@@ -27322,8 +28090,8 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27322
28090
  this._sessionType = sessionType;
27323
28091
  const continuousRecording = sessionType === _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionType.CONTINUOUS;
27324
28092
  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);
28093
+ _services_messaging_service__WEBPACK_IMPORTED_MODULE_9__["default"].sendMessage('continuous-debugging', continuousRecording);
28094
+ (0,_utils__WEBPACK_IMPORTED_MODULE_3__.setStoredItem)(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_TYPE_PROP_NAME, sessionType);
27327
28095
  }
27328
28096
  get continuousRecording() {
27329
28097
  return this.sessionType === _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionType.CONTINUOUS;
@@ -27334,8 +28102,8 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27334
28102
  set sessionState(state) {
27335
28103
  this._sessionState = state;
27336
28104
  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);
28105
+ _services_messaging_service__WEBPACK_IMPORTED_MODULE_9__["default"].sendMessage('state-change', this._sessionState);
28106
+ (0,_utils__WEBPACK_IMPORTED_MODULE_3__.setStoredItem)(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_STATE_PROP_NAME, state);
27339
28107
  // Emit observable event to support React wrapper
27340
28108
  this.emit('state-change', [this._sessionState || _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.stopped, this.sessionType]);
27341
28109
  }
@@ -27344,7 +28112,7 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27344
28112
  }
27345
28113
  set session(session) {
27346
28114
  this._session = session;
27347
- (0,_utils__WEBPACK_IMPORTED_MODULE_3__.setStoredItem)(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_PROP_NAME, this._session);
28115
+ (0,_utils__WEBPACK_IMPORTED_MODULE_3__.setStoredItem)(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_PROP_NAME, this._session);
27348
28116
  }
27349
28117
  get sessionAttributes() {
27350
28118
  return this._sessionAttributes || {};
@@ -27382,15 +28150,20 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27382
28150
  constructor() {
27383
28151
  var _a;
27384
28152
  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();
28153
+ this._apiService = new _services_api_service__WEBPACK_IMPORTED_MODULE_10__.ApiService();
28154
+ this._socketService = new _services_socket_service__WEBPACK_IMPORTED_MODULE_11__.SocketService();
27387
28155
  this._tracer = new _otel__WEBPACK_IMPORTED_MODULE_1__.TracerBrowserSDK();
27388
28156
  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();
28157
+ this._sessionWidget = new _sessionWidget__WEBPACK_IMPORTED_MODULE_8__.SessionWidget();
28158
+ this._navigationRecorder = new _navigation__WEBPACK_IMPORTED_MODULE_15__.NavigationRecorder();
27391
28159
  this._startRequestController = null;
28160
+ this._tabId = (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getOrCreateTabId)();
28161
+ this._bufferDb = new _services_indexedDb_service__WEBPACK_IMPORTED_MODULE_12__.IndexedDBService();
28162
+ this._crashBuffer = null;
28163
+ this._isFlushingBuffer = false;
28164
+ this._bufferLifecycleHandlersRegistered = false;
27392
28165
  this._isInitialized = false;
27393
- // Session ID and state are stored in localStorage
28166
+ // Session ID and state are stored in sessionStorage (with fallback) to avoid multi-tab conflicts
27394
28167
  this._sessionId = null;
27395
28168
  this._sessionType = _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionType.MANUAL;
27396
28169
  this._sessionState = null;
@@ -27403,10 +28176,10 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27403
28176
  this._error = '';
27404
28177
  // Safety: avoid accessing storage in SSR/non-browser environments
27405
28178
  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;
28179
+ const sessionLocal = isBrowser ? (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getStoredItem)(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_PROP_NAME, true) : null;
28180
+ const sessionIdLocal = isBrowser ? (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getStoredItem)(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_ID_PROP_NAME) : null;
28181
+ const sessionStateLocal = isBrowser ? (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getStoredItem)(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_STATE_PROP_NAME) : null;
28182
+ const sessionTypeLocal = isBrowser ? (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getStoredItem)(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_TYPE_PROP_NAME) : null;
27410
28183
  if ((0,_utils__WEBPACK_IMPORTED_MODULE_3__.isSessionActive)(sessionLocal, sessionTypeLocal)) {
27411
28184
  this.session = sessionLocal;
27412
28185
  this.sessionId = sessionIdLocal;
@@ -27420,8 +28193,8 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27420
28193
  this.sessionType = _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionType.MANUAL;
27421
28194
  }
27422
28195
  this._configs = {
27423
- ..._config__WEBPACK_IMPORTED_MODULE_6__.BASE_CONFIG,
27424
- apiKey: ((_a = this.session) === null || _a === void 0 ? void 0 : _a.tempApiKey) || '',
28196
+ ..._config__WEBPACK_IMPORTED_MODULE_5__.BASE_CONFIG,
28197
+ apiKey: ((_a = this.session) === null || _a === void 0 ? void 0 : _a.tempApiKey) || ''
27425
28198
  };
27426
28199
  }
27427
28200
  /**
@@ -27432,40 +28205,118 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27432
28205
  if (typeof window === 'undefined') {
27433
28206
  return;
27434
28207
  }
27435
- this._configs = (0,_config__WEBPACK_IMPORTED_MODULE_6__.getSessionRecorderConfig)({ ...this._configs, ...configs });
28208
+ this._configs = (0,_config__WEBPACK_IMPORTED_MODULE_5__.getSessionRecorderConfig)({ ...this._configs, ...configs });
27436
28209
  this._isInitialized = true;
27437
28210
  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);
28211
+ // GC: remove orphaned crash buffers from old tabs.
28212
+ // Keep TTL large to avoid any accidental data loss.
28213
+ void this._bufferDb.sweepStaleTabs(24 * 60 * 60 * 1000);
28214
+ (0,_patch__WEBPACK_IMPORTED_MODULE_6__.setMaxCapturingHttpPayloadSize)(this._configs.maxCapturingHttpPayloadSize || _config__WEBPACK_IMPORTED_MODULE_5__.DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE);
28215
+ (0,_patch__WEBPACK_IMPORTED_MODULE_6__.setShouldRecordHttpData)(this._configs.captureBody, this._configs.captureHeaders);
28216
+ this._setupCrashBuffer();
27440
28217
  this._tracer.init(this._configs);
27441
28218
  this._apiService.init(this._configs);
27442
28219
  this._sessionWidget.init(this._configs);
27443
28220
  this._socketService.init({
27444
28221
  apiKey: this._configs.apiKey,
28222
+ clientId: this._tracer.clientId,
27445
28223
  socketUrl: this._configs.apiBaseUrl || '',
27446
28224
  keepAlive: Boolean(this._configs.useWebsocket),
27447
- usePostMessageFallback: Boolean(this._configs.usePostMessageFallback),
28225
+ usePostMessageFallback: Boolean(this._configs.usePostMessageFallback)
27448
28226
  });
27449
28227
  this._navigationRecorder.init({
27450
28228
  version: this._configs.version,
27451
28229
  application: this._configs.application,
27452
28230
  environment: this._configs.environment,
27453
- enabled: this._configs.recordNavigation,
28231
+ enabled: this._configs.recordNavigation
27454
28232
  });
27455
28233
  if (this._configs.apiKey) {
27456
28234
  this._recorder.init(this._configs, this._socketService);
27457
28235
  }
27458
- if (this.sessionId
27459
- && (this.sessionState === _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.started
27460
- || this.sessionState === _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.paused)) {
28236
+ if (this.sessionId && (this.sessionState === _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.started || this.sessionState === _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.paused)) {
27461
28237
  this._start();
27462
28238
  }
28239
+ else {
28240
+ // Buffer-only recording when there is no active debug session.
28241
+ this._startBufferOnlyRecording();
28242
+ }
27463
28243
  this._registerWidgetEvents();
27464
28244
  this._registerSocketServiceListeners();
27465
- _services_messaging_service__WEBPACK_IMPORTED_MODULE_10__["default"].sendMessage('state-change', this.sessionState);
28245
+ _services_messaging_service__WEBPACK_IMPORTED_MODULE_9__["default"].sendMessage('state-change', this.sessionState);
27466
28246
  // Emit init observable event
27467
28247
  this.emit('init', [this]);
27468
28248
  }
28249
+ _setupCrashBuffer() {
28250
+ var _a;
28251
+ if ((_a = this._configs.buffering) === null || _a === void 0 ? void 0 : _a.enabled) {
28252
+ const windowMinutes = this._configs.buffering.windowMinutes || 1;
28253
+ const windowMs = Math.max(10000, windowMinutes * 60 * 1000);
28254
+ this._crashBuffer = new _services_crashBuffer_service__WEBPACK_IMPORTED_MODULE_13__.CrashBufferService(this._bufferDb, this._tabId, windowMs);
28255
+ this._recorder.setCrashBuffer(this._crashBuffer);
28256
+ this._tracer.setCrashBuffer(this._crashBuffer);
28257
+ this._crashBuffer.setAttrs({
28258
+ sessionAttributes: this.sessionAttributes,
28259
+ resourceAttributes: (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getNavigatorInfo)(),
28260
+ userAttributes: this._userAttributes
28261
+ });
28262
+ this._crashBuffer.on('error-span-appended', (payload) => {
28263
+ if (this.sessionState !== _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.stopped || this.sessionId)
28264
+ return;
28265
+ if (!payload.span)
28266
+ return;
28267
+ this._createExceptionSession(payload.span);
28268
+ });
28269
+ this._registerCrashBufferLifecycleHandlers();
28270
+ }
28271
+ }
28272
+ _registerCrashBufferLifecycleHandlers() {
28273
+ if (this._bufferLifecycleHandlersRegistered)
28274
+ return;
28275
+ if (typeof window === 'undefined')
28276
+ return;
28277
+ if (typeof document === 'undefined')
28278
+ return;
28279
+ if (!this._crashBuffer)
28280
+ return;
28281
+ this._bufferLifecycleHandlersRegistered = true;
28282
+ const update = () => this._updateCrashBufferActiveState();
28283
+ window.addEventListener('focus', update, { passive: true });
28284
+ window.addEventListener('blur', update, { passive: true });
28285
+ document.addEventListener('visibilitychange', update, { passive: true });
28286
+ // Set initial state.
28287
+ update();
28288
+ }
28289
+ _updateCrashBufferActiveState() {
28290
+ if (!this._crashBuffer)
28291
+ return;
28292
+ if (typeof document === 'undefined')
28293
+ return;
28294
+ let hasFocus = true;
28295
+ try {
28296
+ hasFocus = typeof document.hasFocus === 'function' ? document.hasFocus() : true;
28297
+ }
28298
+ catch (_e) {
28299
+ hasFocus = true;
28300
+ }
28301
+ const isVisible = document.visibilityState === 'visible' && !document.hidden;
28302
+ const active = isVisible && hasFocus;
28303
+ this._crashBuffer.setActive(active);
28304
+ if (active && this._crashBuffer.needsFullSnapshot()) {
28305
+ // If the buffer was cleared while inactive, the next stored rrweb event must be a FullSnapshot.
28306
+ this._recorder.takeFullSnapshot();
28307
+ }
28308
+ }
28309
+ _startBufferOnlyRecording() {
28310
+ var _a, _b;
28311
+ if (!((_b = (_a = this._configs) === null || _a === void 0 ? void 0 : _a.buffering) === null || _b === void 0 ? void 0 : _b.enabled))
28312
+ return;
28313
+ if (!this._crashBuffer)
28314
+ return;
28315
+ // Don’t start if a session is active.
28316
+ if (this.sessionState !== _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.stopped || this.sessionId)
28317
+ return;
28318
+ void this._recorder.restart(null, _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionType.MANUAL);
28319
+ }
27469
28320
  /**
27470
28321
  * Save the continuous recording session
27471
28322
  */
@@ -27475,31 +28326,32 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27475
28326
  if (!this.continuousRecording || !this._configs.showContinuousRecording) {
27476
28327
  return;
27477
28328
  }
27478
- this._sessionWidget.updateSaveContinuousDebugSessionState(_sessionWidget_buttonStateConfigs__WEBPACK_IMPORTED_MODULE_12__.ContinuousRecordingSaveButtonState.SAVING);
28329
+ this._sessionWidget.updateSaveContinuousDebugSessionState(_sessionWidget_buttonStateConfigs__WEBPACK_IMPORTED_MODULE_14__.ContinuousRecordingSaveButtonState.SAVING);
27479
28330
  const res = await this._apiService.saveContinuousDebugSession(this.sessionId, {
27480
28331
  sessionAttributes: this.sessionAttributes,
27481
28332
  resourceAttributes: (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getNavigatorInfo)(),
27482
28333
  stoppedAt: this._recorder.stoppedAt,
27483
28334
  name: this._getSessionName()
27484
28335
  });
27485
- this._sessionWidget.updateSaveContinuousDebugSessionState(_sessionWidget_buttonStateConfigs__WEBPACK_IMPORTED_MODULE_12__.ContinuousRecordingSaveButtonState.SAVED);
28336
+ this._sessionWidget.updateSaveContinuousDebugSessionState(_sessionWidget_buttonStateConfigs__WEBPACK_IMPORTED_MODULE_14__.ContinuousRecordingSaveButtonState.SAVED);
27486
28337
  const sessionUrl = res === null || res === void 0 ? void 0 : res.url;
27487
28338
  this._sessionWidget.showToast({
27488
28339
  type: 'success',
27489
28340
  message: 'Your session was saved',
27490
28341
  button: {
27491
- text: 'Open session', url: sessionUrl,
27492
- },
28342
+ text: 'Open session',
28343
+ url: sessionUrl
28344
+ }
27493
28345
  }, 5000);
27494
28346
  return res;
27495
28347
  }
27496
28348
  catch (error) {
27497
28349
  this.error = error.message;
27498
- this._sessionWidget.updateSaveContinuousDebugSessionState(_sessionWidget_buttonStateConfigs__WEBPACK_IMPORTED_MODULE_12__.ContinuousRecordingSaveButtonState.ERROR);
28350
+ this._sessionWidget.updateSaveContinuousDebugSessionState(_sessionWidget_buttonStateConfigs__WEBPACK_IMPORTED_MODULE_14__.ContinuousRecordingSaveButtonState.ERROR);
27499
28351
  }
27500
28352
  finally {
27501
28353
  setTimeout(() => {
27502
- this._sessionWidget.updateSaveContinuousDebugSessionState(_sessionWidget_buttonStateConfigs__WEBPACK_IMPORTED_MODULE_12__.ContinuousRecordingSaveButtonState.IDLE);
28354
+ this._sessionWidget.updateSaveContinuousDebugSessionState(_sessionWidget_buttonStateConfigs__WEBPACK_IMPORTED_MODULE_14__.ContinuousRecordingSaveButtonState.IDLE);
27503
28355
  }, 3000);
27504
28356
  }
27505
28357
  }
@@ -27538,10 +28390,10 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27538
28390
  else {
27539
28391
  const request = {
27540
28392
  sessionAttributes: { comment },
27541
- stoppedAt: this._recorder.stoppedAt,
28393
+ stoppedAt: this._recorder.stoppedAt
27542
28394
  };
27543
28395
  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);
28396
+ _eventBus__WEBPACK_IMPORTED_MODULE_7__.recorderEventBus.emit(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_RESPONSE, response);
27545
28397
  }
27546
28398
  this._clearSession();
27547
28399
  }
@@ -27596,7 +28448,7 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27596
28448
  /**
27597
28449
  * Set the session attributes
27598
28450
  * @param attributes - the attributes to set
27599
- */
28451
+ */
27600
28452
  setSessionAttributes(attributes) {
27601
28453
  this._sessionAttributes = attributes;
27602
28454
  }
@@ -27634,6 +28486,51 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27634
28486
  this.error = (e === null || e === void 0 ? void 0 : e.message) || 'Failed to capture exception';
27635
28487
  }
27636
28488
  }
28489
+ async _flushBuffer(sessionId) {
28490
+ var _a, _b;
28491
+ if (!((_b = (_a = this._configs) === null || _a === void 0 ? void 0 : _a.buffering) === null || _b === void 0 ? void 0 : _b.enabled))
28492
+ return null;
28493
+ if (!this._crashBuffer)
28494
+ return null;
28495
+ if (this._isFlushingBuffer)
28496
+ return null;
28497
+ // Don’t flush while a live recording is active.
28498
+ if (this.sessionState !== _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.stopped)
28499
+ return null;
28500
+ this._isFlushingBuffer = true;
28501
+ try {
28502
+ // await this._crashBuffer.setAttrs({
28503
+ // sessionAttributes: this.sessionAttributes,
28504
+ // resourceAttributes: getNavigatorInfo(),
28505
+ // userAttributes: this._userAttributes
28506
+ // })
28507
+ const snapshot = await this._crashBuffer.snapshot();
28508
+ if (snapshot.rrwebEvents.length === 0 && snapshot.otelSpans.length === 0) {
28509
+ return null;
28510
+ }
28511
+ if (sessionId) {
28512
+ const spans = snapshot.otelSpans.map((s) => s.span);
28513
+ const events = snapshot.rrwebEvents.map((e) => e.event);
28514
+ await Promise.all([
28515
+ this._tracer.exportTraces(spans),
28516
+ this._apiService.exportEvents(sessionId, { events }),
28517
+ this._apiService.updateSessionAttributes(sessionId, {
28518
+ name: this._getSessionName(),
28519
+ sessionAttributes: this.sessionAttributes,
28520
+ resourceAttributes: (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getNavigatorInfo)(),
28521
+ userAttributes: this._userAttributes || undefined
28522
+ })
28523
+ ]);
28524
+ }
28525
+ }
28526
+ catch (_e) {
28527
+ // swallow: flush is best-effort; never throw into app code
28528
+ }
28529
+ finally {
28530
+ await this._crashBuffer.clear();
28531
+ this._isFlushingBuffer = false;
28532
+ }
28533
+ }
27637
28534
  /**
27638
28535
  * @description Check if session should be started/stopped automatically
27639
28536
  * @param {ISession} [sessionPayload]
@@ -27647,11 +28544,11 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27647
28544
  const payload = {
27648
28545
  sessionAttributes: {
27649
28546
  ...this.sessionAttributes,
27650
- ...((sessionPayload === null || sessionPayload === void 0 ? void 0 : sessionPayload.sessionAttributes) || {}),
28547
+ ...((sessionPayload === null || sessionPayload === void 0 ? void 0 : sessionPayload.sessionAttributes) || {})
27651
28548
  },
27652
28549
  resourceAttributes: {
27653
28550
  ...(0,_utils__WEBPACK_IMPORTED_MODULE_3__.getNavigatorInfo)(),
27654
- ...((sessionPayload === null || sessionPayload === void 0 ? void 0 : sessionPayload.resourceAttributes) || {}),
28551
+ ...((sessionPayload === null || sessionPayload === void 0 ? void 0 : sessionPayload.resourceAttributes) || {})
27655
28552
  },
27656
28553
  userAttributes: this._userAttributes
27657
28554
  };
@@ -27765,12 +28662,12 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27765
28662
  * Register socket service event listeners
27766
28663
  */
27767
28664
  _registerSocketServiceListeners() {
27768
- this._socketService.on(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_STOPPED_EVENT, () => {
28665
+ this._socketService.on(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_STOPPED_EVENT, () => {
27769
28666
  this._stop();
27770
28667
  this._clearSession();
27771
28668
  this._sessionWidget.handleUIReseting();
27772
28669
  });
27773
- this._socketService.on(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_AUTO_CREATED, (payload) => {
28670
+ this._socketService.on(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_AUTO_CREATED, (payload) => {
27774
28671
  var _a;
27775
28672
  if (!(payload === null || payload === void 0 ? void 0 : payload.data))
27776
28673
  return;
@@ -27779,22 +28676,37 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27779
28676
  message: 'Your session was auto-saved due to an error',
27780
28677
  button: {
27781
28678
  text: 'Open session',
27782
- url: (_a = payload === null || payload === void 0 ? void 0 : payload.data) === null || _a === void 0 ? void 0 : _a.url,
27783
- },
28679
+ url: (_a = payload === null || payload === void 0 ? void 0 : payload.data) === null || _a === void 0 ? void 0 : _a.url
28680
+ }
27784
28681
  }, 5000);
27785
28682
  });
27786
- this._socketService.on(_config__WEBPACK_IMPORTED_MODULE_6__.REMOTE_SESSION_RECORDING_START, (payload) => {
28683
+ this._socketService.on(_config__WEBPACK_IMPORTED_MODULE_5__.REMOTE_SESSION_RECORDING_START, (payload) => {
27787
28684
  console.log('REMOTE_SESSION_RECORDING_START', payload);
27788
28685
  if (this.sessionState === _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.stopped) {
27789
28686
  this.start();
27790
28687
  }
27791
28688
  });
27792
- this._socketService.on(_config__WEBPACK_IMPORTED_MODULE_6__.REMOTE_SESSION_RECORDING_STOP, (payload) => {
28689
+ this._socketService.on(_config__WEBPACK_IMPORTED_MODULE_5__.REMOTE_SESSION_RECORDING_STOP, (payload) => {
27793
28690
  console.log('REMOTE_SESSION_RECORDING_STOP', payload);
27794
28691
  if (this.sessionState !== _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.stopped) {
27795
28692
  this.stop();
27796
28693
  }
27797
28694
  });
28695
+ this._socketService.on(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_SAVE_BUFFER_EVENT, (payload) => {
28696
+ var _a;
28697
+ if (!((_a = payload === null || payload === void 0 ? void 0 : payload.debugSession) === null || _a === void 0 ? void 0 : _a._id))
28698
+ return;
28699
+ void this._flushBuffer(payload.debugSession._id);
28700
+ });
28701
+ }
28702
+ async _createExceptionSession(span) {
28703
+ try {
28704
+ const session = await this._apiService.createErrorSession({ span });
28705
+ if (session) {
28706
+ void this._flushBuffer(session._id);
28707
+ }
28708
+ }
28709
+ catch (_ignored) { }
27798
28710
  }
27799
28711
  /**
27800
28712
  * Create a new session and start it
@@ -27807,17 +28719,14 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27807
28719
  sessionAttributes: this.sessionAttributes,
27808
28720
  resourceAttributes: (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getNavigatorInfo)(),
27809
28721
  name: this._getSessionName(),
27810
- ...(this._userAttributes ? { userAttributes: this._userAttributes } : {}),
28722
+ ...(this._userAttributes ? { userAttributes: this._userAttributes } : {})
27811
28723
  };
27812
- const request = !this.continuousRecording ?
27813
- payload : { debugSessionData: payload };
28724
+ const request = !this.continuousRecording ? payload : { debugSessionData: payload };
27814
28725
  const session = this.continuousRecording
27815
28726
  ? await this._apiService.startContinuousDebugSession(request, signal)
27816
28727
  : await this._apiService.startSession(request, signal);
27817
28728
  if (session) {
27818
- session.sessionType = this.continuousRecording
27819
- ? _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionType.CONTINUOUS
27820
- : _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionType.MANUAL;
28729
+ session.sessionType = this.continuousRecording ? _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionType.CONTINUOUS : _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionType.MANUAL;
27821
28730
  this._setupSessionAndStart(session, false);
27822
28731
  }
27823
28732
  }
@@ -27837,10 +28746,11 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27837
28746
  this.sessionState = _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.started;
27838
28747
  this.sessionType = this.sessionType;
27839
28748
  this._tracer.start(this.sessionId, this.sessionType);
27840
- this._recorder.start(this.sessionId, this.sessionType);
27841
- this._navigationRecorder.start({ sessionId: this.sessionId, sessionType: this.sessionType, });
28749
+ // Ensure we switch from buffer-only recording to session recording cleanly.
28750
+ void this._recorder.restart(this.sessionId, this.sessionType);
28751
+ this._navigationRecorder.start({ sessionId: this.sessionId, sessionType: this.sessionType });
27842
28752
  if (this.session) {
27843
- _eventBus__WEBPACK_IMPORTED_MODULE_8__.recorderEventBus.emit(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_STARTED_EVENT, this.session);
28753
+ _eventBus__WEBPACK_IMPORTED_MODULE_7__.recorderEventBus.emit(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_STARTED_EVENT, this.session);
27844
28754
  this._socketService.subscribeToSession(this.session);
27845
28755
  this._sessionWidget.seconds = (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getTimeDifferenceInSeconds)((_a = this.session) === null || _a === void 0 ? void 0 : _a.startedAt);
27846
28756
  }
@@ -27854,6 +28764,7 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27854
28764
  this._tracer.stop();
27855
28765
  this._recorder.stop();
27856
28766
  this._navigationRecorder.stop();
28767
+ this._startBufferOnlyRecording();
27857
28768
  }
27858
28769
  /**
27859
28770
  * Pause the session tracing and recording
@@ -27869,7 +28780,7 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27869
28780
  */
27870
28781
  _resume() {
27871
28782
  this._tracer.start(this.sessionId, this.sessionType);
27872
- this._recorder.start(this.sessionId, this.sessionType);
28783
+ void this._recorder.restart(this.sessionId, this.sessionType);
27873
28784
  this._navigationRecorder.resume();
27874
28785
  this.sessionState = _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.started;
27875
28786
  }
@@ -27885,7 +28796,7 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
27885
28796
  this._start();
27886
28797
  }
27887
28798
  /**
27888
- * Set the session ID in localStorage
28799
+ * Set the session ID in sessionStorage (with fallback)
27889
28800
  * @param sessionId - the session ID to set or clear
27890
28801
  */
27891
28802
  _setSession(session) {
@@ -29580,6 +30491,7 @@ __webpack_require__.r(__webpack_exports__);
29580
30491
  /* harmony export */ formatTimeForSessionTimer: () => (/* reexport safe */ _time__WEBPACK_IMPORTED_MODULE_2__.formatTimeForSessionTimer),
29581
30492
  /* harmony export */ getFormattedDate: () => (/* reexport safe */ _time__WEBPACK_IMPORTED_MODULE_2__.getFormattedDate),
29582
30493
  /* harmony export */ getNavigatorInfo: () => (/* reexport safe */ _navigator__WEBPACK_IMPORTED_MODULE_0__.getNavigatorInfo),
30494
+ /* harmony export */ getOrCreateTabId: () => (/* reexport safe */ _tabId__WEBPACK_IMPORTED_MODULE_8__.getOrCreateTabId),
29583
30495
  /* harmony export */ getStoredItem: () => (/* reexport safe */ _storage__WEBPACK_IMPORTED_MODULE_1__.getStoredItem),
29584
30496
  /* harmony export */ getTimeDifferenceInSeconds: () => (/* reexport safe */ _time__WEBPACK_IMPORTED_MODULE_2__.getTimeDifferenceInSeconds),
29585
30497
  /* harmony export */ hasOwnProperty: () => (/* reexport safe */ _type_utils__WEBPACK_IMPORTED_MODULE_6__.hasOwnProperty),
@@ -29621,6 +30533,7 @@ __webpack_require__.r(__webpack_exports__);
29621
30533
  /* harmony import */ var _array__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./array */ "./src/utils/array.ts");
29622
30534
  /* harmony import */ var _type_utils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./type-utils */ "./src/utils/type-utils.ts");
29623
30535
  /* harmony import */ var _globals__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./globals */ "./src/utils/globals.ts");
30536
+ /* harmony import */ var _tabId__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./tabId */ "./src/utils/tabId.ts");
29624
30537
  // Export all utility functions
29625
30538
 
29626
30539
 
@@ -29632,6 +30545,7 @@ __webpack_require__.r(__webpack_exports__);
29632
30545
 
29633
30546
 
29634
30547
 
30548
+
29635
30549
  /***/ }),
29636
30550
 
29637
30551
  /***/ "./src/utils/navigator.ts":
@@ -29873,32 +30787,90 @@ __webpack_require__.r(__webpack_exports__);
29873
30787
  /* harmony export */ setStoredItem: () => (/* binding */ setStoredItem)
29874
30788
  /* harmony export */ });
29875
30789
  /**
29876
- * LocalStorage utility functions
30790
+ * Storage utility functions.
30791
+ *
30792
+ * Session state must be isolated per-tab to avoid conflicts across multiple tabs.
30793
+ * We therefore prefer `sessionStorage` and fall back to `localStorage` if needed.
29877
30794
  */
29878
- const hasLocalStorage = typeof window !== 'undefined' && !!window.localStorage;
29879
- const getStoredItem = (key, parse) => {
29880
- if (!hasLocalStorage) {
29881
- return parse ? null : null;
30795
+ const hasWindow = typeof window !== 'undefined';
30796
+ const getStorage = () => {
30797
+ if (!hasWindow)
30798
+ return null;
30799
+ try {
30800
+ if (window.sessionStorage)
30801
+ return window.sessionStorage;
30802
+ }
30803
+ catch (_e) {
30804
+ // sessionStorage can throw (e.g. blocked in some environments)
30805
+ }
30806
+ try {
30807
+ if (window.localStorage)
30808
+ return window.localStorage;
29882
30809
  }
29883
- const item = window.localStorage.getItem(key);
30810
+ catch (_e) {
30811
+ // localStorage can throw (e.g. blocked in some environments)
30812
+ }
30813
+ return null;
30814
+ };
30815
+ const getStoredItem = (key, parse) => {
30816
+ const storage = getStorage();
30817
+ if (!storage)
30818
+ return null;
30819
+ const item = storage.getItem(key);
29884
30820
  return parse ? (item ? JSON.parse(item) : null) : item;
29885
30821
  };
29886
30822
  const setStoredItem = (key, value) => {
29887
- if (!hasLocalStorage) {
30823
+ const storage = getStorage();
30824
+ if (!storage)
29888
30825
  return;
29889
- }
29890
30826
  if (value === null || value === undefined) {
29891
- window.localStorage.removeItem(key);
30827
+ storage.removeItem(key);
29892
30828
  }
29893
30829
  else {
29894
- window.localStorage.setItem(key, typeof value === 'string' ? value : JSON.stringify(value));
30830
+ storage.setItem(key, typeof value === 'string' ? value : JSON.stringify(value));
29895
30831
  }
29896
30832
  };
29897
30833
  const removeStoredItem = (key) => {
29898
- if (!hasLocalStorage) {
30834
+ const storage = getStorage();
30835
+ if (!storage)
29899
30836
  return;
30837
+ storage.removeItem(key);
30838
+ };
30839
+
30840
+
30841
+ /***/ }),
30842
+
30843
+ /***/ "./src/utils/tabId.ts":
30844
+ /*!****************************!*\
30845
+ !*** ./src/utils/tabId.ts ***!
30846
+ \****************************/
30847
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
30848
+
30849
+ "use strict";
30850
+ __webpack_require__.r(__webpack_exports__);
30851
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
30852
+ /* harmony export */ getOrCreateTabId: () => (/* binding */ getOrCreateTabId)
30853
+ /* harmony export */ });
30854
+ const TAB_ID_KEY = 'multiplayer-tab-id';
30855
+ const randomId = () => {
30856
+ // Avoid crypto dependency for older browsers; good enough for per-tab isolation
30857
+ return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
30858
+ };
30859
+ const getOrCreateTabId = () => {
30860
+ if (typeof window === 'undefined')
30861
+ return 'ssr';
30862
+ try {
30863
+ const existing = window.sessionStorage.getItem(TAB_ID_KEY);
30864
+ if (existing)
30865
+ return existing;
30866
+ const id = randomId();
30867
+ window.sessionStorage.setItem(TAB_ID_KEY, id);
30868
+ return id;
30869
+ }
30870
+ catch (_e) {
30871
+ // If sessionStorage is blocked, fall back to a runtime-only id.
30872
+ return randomId();
29900
30873
  }
29901
- window.localStorage.removeItem(key);
29902
30874
  };
29903
30875
 
29904
30876
 
@@ -30058,42 +31030,48 @@ __webpack_require__.r(__webpack_exports__);
30058
31030
  /* harmony export */ SessionRecorderIdGenerator: () => (/* binding */ SessionRecorderIdGenerator)
30059
31031
  /* harmony export */ });
30060
31032
  /* 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");
31033
+ /* harmony import */ var _sdk__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./sdk */ "../session-recorder-common/dist/esm/sdk/index.js");
31034
+ /* 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
31035
 
30064
31036
 
30065
31037
 
30066
31038
  var SessionRecorderIdGenerator = /** @class */ (function () {
30067
31039
  function SessionRecorderIdGenerator() {
30068
- this.generateLongId = (0,_sdk__WEBPACK_IMPORTED_MODULE_2__.getIdGenerator)(16);
30069
- this.generateShortId = (0,_sdk__WEBPACK_IMPORTED_MODULE_2__.getIdGenerator)(8);
31040
+ this.generateLongId = (0,_sdk__WEBPACK_IMPORTED_MODULE_1__.getIdGenerator)(16);
31041
+ this.generateShortId = (0,_sdk__WEBPACK_IMPORTED_MODULE_1__.getIdGenerator)(8);
30070
31042
  this.sessionShortId = '';
31043
+ this.clientId = '';
30071
31044
  this.sessionType = _type__WEBPACK_IMPORTED_MODULE_0__.SessionType.MANUAL;
30072
31045
  }
30073
31046
  SessionRecorderIdGenerator.prototype.generateTraceId = function () {
30074
31047
  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;
31048
+ if (!this.sessionShortId && !this.sessionType) {
31049
+ return traceId;
30087
31050
  }
30088
- return traceId;
31051
+ var sessionTypePrefix = _constants_constants_base__WEBPACK_IMPORTED_MODULE_2__.MULTIPLAYER_TRACE_PREFIX_MAP[this.sessionType];
31052
+ 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);
31053
+ var sessionTraceId = "".concat(prefix).concat(traceId.substring(prefix.length, traceId.length));
31054
+ return sessionTraceId;
30089
31055
  };
30090
31056
  SessionRecorderIdGenerator.prototype.generateSpanId = function () {
30091
31057
  return this.generateShortId();
30092
31058
  };
30093
- SessionRecorderIdGenerator.prototype.setSessionId = function (sessionShortId, sessionType) {
31059
+ SessionRecorderIdGenerator.prototype.setSessionId = function (sessionShortId, sessionType, clientId) {
30094
31060
  if (sessionType === void 0) { sessionType = _type__WEBPACK_IMPORTED_MODULE_0__.SessionType.MANUAL; }
31061
+ if (clientId === void 0) { clientId = ''; }
31062
+ if (!clientId &&
31063
+ [
31064
+ _type__WEBPACK_IMPORTED_MODULE_0__.SessionType.SESSION_CACHE,
31065
+ _type__WEBPACK_IMPORTED_MODULE_0__.SessionType.CONTINUOUS_SESSION_CACHE,
31066
+ ].includes(sessionType)) {
31067
+ throw new Error("Client ID is required for ".concat([
31068
+ _type__WEBPACK_IMPORTED_MODULE_0__.SessionType.SESSION_CACHE,
31069
+ _type__WEBPACK_IMPORTED_MODULE_0__.SessionType.CONTINUOUS_SESSION_CACHE,
31070
+ ].join(', '), " session types"));
31071
+ }
30095
31072
  this.sessionShortId = sessionShortId;
30096
31073
  this.sessionType = sessionType;
31074
+ this.clientId = clientId;
30097
31075
  };
30098
31076
  return SessionRecorderIdGenerator;
30099
31077
  }());
@@ -30128,7 +31106,10 @@ var SessionRecorderTraceIdRatioBasedSampler = /** @class */ (function () {
30128
31106
  }
30129
31107
  SessionRecorderTraceIdRatioBasedSampler.prototype.shouldSample = function (context, traceId) {
30130
31108
  if (traceId.startsWith(_constants_constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_DEBUG_PREFIX)
30131
- || traceId.startsWith(_constants_constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX)) {
31109
+ || traceId.startsWith(_constants_constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX)
31110
+ // || traceId.startsWith(MULTIPLAYER_TRACE_SESSION_CACHE_PREFIX)
31111
+ // || traceId.startsWith(MULTIPLAYER_TRACE_CONTINUOUS_SESSION_CACHE_PREFIX)
31112
+ ) {
30132
31113
  return {
30133
31114
  decision: _opentelemetry_sdk_trace_base__WEBPACK_IMPORTED_MODULE_1__.SamplingDecision.RECORD_AND_SAMPLED,
30134
31115
  };
@@ -30198,6 +31179,7 @@ __webpack_require__.r(__webpack_exports__);
30198
31179
  /* harmony export */ ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE: () => (/* binding */ ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE),
30199
31180
  /* harmony export */ ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE_ENCODING: () => (/* binding */ ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE_ENCODING),
30200
31181
  /* harmony export */ ATTR_MULTIPLAYER_RPC_RESPONSE_MESSAGE: () => (/* binding */ ATTR_MULTIPLAYER_RPC_RESPONSE_MESSAGE),
31182
+ /* harmony export */ ATTR_MULTIPLAYER_SESSION_CLIENT_ID: () => (/* binding */ ATTR_MULTIPLAYER_SESSION_CLIENT_ID),
30201
31183
  /* harmony export */ ATTR_MULTIPLAYER_SESSION_ID: () => (/* binding */ ATTR_MULTIPLAYER_SESSION_ID),
30202
31184
  /* harmony export */ ATTR_MULTIPLAYER_SESSION_RECORDER_VERSION: () => (/* binding */ ATTR_MULTIPLAYER_SESSION_RECORDER_VERSION),
30203
31185
  /* harmony export */ ATTR_MULTIPLAYER_USER_HASH: () => (/* binding */ ATTR_MULTIPLAYER_USER_HASH),
@@ -30211,18 +31193,34 @@ __webpack_require__.r(__webpack_exports__);
30211
31193
  /* harmony export */ MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_GRPC_URL: () => (/* binding */ MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_GRPC_URL),
30212
31194
  /* harmony export */ MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_HTTP_URL: () => (/* binding */ MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_HTTP_URL),
30213
31195
  /* harmony export */ MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_URL: () => (/* binding */ MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_URL),
31196
+ /* harmony export */ MULTIPLAYER_TRACE_CLIENT_ID_LENGTH: () => (/* binding */ MULTIPLAYER_TRACE_CLIENT_ID_LENGTH),
30214
31197
  /* harmony export */ MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX: () => (/* binding */ MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX),
31198
+ /* harmony export */ MULTIPLAYER_TRACE_CONTINUOUS_SESSION_CACHE_PREFIX: () => (/* binding */ MULTIPLAYER_TRACE_CONTINUOUS_SESSION_CACHE_PREFIX),
30215
31199
  /* harmony export */ MULTIPLAYER_TRACE_DEBUG_PREFIX: () => (/* binding */ MULTIPLAYER_TRACE_DEBUG_PREFIX),
30216
31200
  /* 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)
31201
+ /* harmony export */ MULTIPLAYER_TRACE_DOC_PREFIX: () => (/* binding */ MULTIPLAYER_TRACE_DOC_PREFIX),
31202
+ /* harmony export */ MULTIPLAYER_TRACE_PREFIX_MAP: () => (/* binding */ MULTIPLAYER_TRACE_PREFIX_MAP),
31203
+ /* harmony export */ MULTIPLAYER_TRACE_SESSION_CACHE_PREFIX: () => (/* binding */ MULTIPLAYER_TRACE_SESSION_CACHE_PREFIX)
30218
31204
  /* harmony export */ });
31205
+ /* harmony import */ var _type__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../type */ "../session-recorder-common/dist/esm/type/index.js");
31206
+ var _a;
31207
+
30219
31208
  /**
30220
31209
  * @deprecated
30221
31210
  */
30222
31211
  var MULTIPLAYER_TRACE_DOC_PREFIX = 'd0cd0c';
30223
31212
  var MULTIPLAYER_TRACE_DEBUG_PREFIX = 'debdeb';
30224
31213
  var MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX = 'cdbcdb';
30225
- var MULTIPLAYER_TRACE_DEBUG_SESSION_SHORT_ID_LENGTH = 16;
31214
+ var MULTIPLAYER_TRACE_SESSION_CACHE_PREFIX = 'cdbcac';
31215
+ var MULTIPLAYER_TRACE_CONTINUOUS_SESSION_CACHE_PREFIX = 'debcdb';
31216
+ var MULTIPLAYER_TRACE_PREFIX_MAP = (_a = {},
31217
+ _a[_type__WEBPACK_IMPORTED_MODULE_0__.SessionType.CONTINUOUS] = MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX,
31218
+ _a[_type__WEBPACK_IMPORTED_MODULE_0__.SessionType.SESSION_CACHE] = MULTIPLAYER_TRACE_SESSION_CACHE_PREFIX,
31219
+ _a[_type__WEBPACK_IMPORTED_MODULE_0__.SessionType.CONTINUOUS_SESSION_CACHE] = MULTIPLAYER_TRACE_CONTINUOUS_SESSION_CACHE_PREFIX,
31220
+ _a[_type__WEBPACK_IMPORTED_MODULE_0__.SessionType.MANUAL] = MULTIPLAYER_TRACE_DEBUG_PREFIX,
31221
+ _a);
31222
+ var MULTIPLAYER_TRACE_DEBUG_SESSION_SHORT_ID_LENGTH = 8;
31223
+ var MULTIPLAYER_TRACE_CLIENT_ID_LENGTH = 8;
30226
31224
  /**
30227
31225
  * @deprecated Use MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_HTTP_URL instead
30228
31226
  */
@@ -30246,6 +31244,7 @@ var ATTR_MULTIPLAYER_PLATFORM_NAME = 'multiplayer.platform.name';
30246
31244
  var ATTR_MULTIPLAYER_CLIENT_ID = 'multiplayer.client.id';
30247
31245
  var ATTR_MULTIPLAYER_INTEGRATION_ID = 'multiplayer.integration.id';
30248
31246
  var ATTR_MULTIPLAYER_SESSION_ID = 'multiplayer.session.id';
31247
+ var ATTR_MULTIPLAYER_SESSION_CLIENT_ID = 'multiplayer.session.client.id';
30249
31248
  var ATTR_MULTIPLAYER_HTTP_PROXY = 'multiplayer.http.proxy';
30250
31249
  var ATTR_MULTIPLAYER_HTTP_PROXY_TYPE = 'multiplayer.http.proxy.type';
30251
31250
  var ATTR_MULTIPLAYER_HTTP_REQUEST_BODY = 'multiplayer.http.request.body';
@@ -30305,6 +31304,7 @@ __webpack_require__.r(__webpack_exports__);
30305
31304
  /* harmony export */ ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE),
30306
31305
  /* harmony export */ ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE_ENCODING: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE_ENCODING),
30307
31306
  /* harmony export */ ATTR_MULTIPLAYER_RPC_RESPONSE_MESSAGE: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_RPC_RESPONSE_MESSAGE),
31307
+ /* harmony export */ ATTR_MULTIPLAYER_SESSION_CLIENT_ID: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_SESSION_CLIENT_ID),
30308
31308
  /* harmony export */ ATTR_MULTIPLAYER_SESSION_ID: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_SESSION_ID),
30309
31309
  /* harmony export */ ATTR_MULTIPLAYER_SESSION_RECORDER_VERSION: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_SESSION_RECORDER_VERSION),
30310
31310
  /* harmony export */ ATTR_MULTIPLAYER_USER_HASH: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_USER_HASH),
@@ -30318,10 +31318,14 @@ __webpack_require__.r(__webpack_exports__);
30318
31318
  /* 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
31319
  /* 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
31320
  /* harmony export */ MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_URL: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_URL),
31321
+ /* harmony export */ MULTIPLAYER_TRACE_CLIENT_ID_LENGTH: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_CLIENT_ID_LENGTH),
30321
31322
  /* harmony export */ MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX),
31323
+ /* harmony export */ MULTIPLAYER_TRACE_CONTINUOUS_SESSION_CACHE_PREFIX: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_CONTINUOUS_SESSION_CACHE_PREFIX),
30322
31324
  /* harmony export */ MULTIPLAYER_TRACE_DEBUG_PREFIX: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_DEBUG_PREFIX),
30323
31325
  /* 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)
31326
+ /* harmony export */ MULTIPLAYER_TRACE_DOC_PREFIX: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_DOC_PREFIX),
31327
+ /* harmony export */ MULTIPLAYER_TRACE_PREFIX_MAP: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_PREFIX_MAP),
31328
+ /* harmony export */ MULTIPLAYER_TRACE_SESSION_CACHE_PREFIX: () => (/* reexport safe */ _constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_SESSION_CACHE_PREFIX)
30325
31329
  /* harmony export */ });
30326
31330
  /* harmony import */ var _constants_base__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./constants.base */ "../session-recorder-common/dist/esm/constants/constants.base.js");
30327
31331
 
@@ -30365,7 +31369,7 @@ var SessionRecorderBrowserTraceExporter = /** @class */ (function () {
30365
31369
  if (config === void 0) { config = {}; }
30366
31370
  this.usePostMessage = false;
30367
31371
  var _a = config.url, url = _a === void 0 ? _constants_constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_HTTP_URL : _a, apiKey = config.apiKey, _b = config.headers, headers = _b === void 0 ? {} : _b, _c = config.timeoutMillis, timeoutMillis = _c === void 0 ? 30000 : _c, _d = config.keepAlive, keepAlive = _d === void 0 ? true : _d, _e = config.concurrencyLimit, concurrencyLimit = _e === void 0 ? 20 : _e, _f = config.postMessageType, postMessageType = _f === void 0 ? 'MULTIPLAYER_SESSION_DEBUGGER_LIB' : _f, _g = config.postMessageTargetOrigin, postMessageTargetOrigin = _g === void 0 ? '*' : _g;
30368
- this.config = __assign(__assign({}, config), { url: url, apiKey: apiKey, headers: headers, timeoutMillis: timeoutMillis, keepAlive: keepAlive, concurrencyLimit: concurrencyLimit });
31372
+ this.config = __assign(__assign({}, config), { url: url, apiKey: apiKey, headers: headers, keepAlive: keepAlive, timeoutMillis: timeoutMillis, concurrencyLimit: concurrencyLimit });
30369
31373
  this.postMessageType = postMessageType;
30370
31374
  this.postMessageTargetOrigin = postMessageTargetOrigin;
30371
31375
  this.exporter = this._createExporter();
@@ -30375,8 +31379,8 @@ var SessionRecorderBrowserTraceExporter = /** @class */ (function () {
30375
31379
  // Filter spans to only include those with Multiplayer trace prefixes
30376
31380
  var filteredSpans = spans.filter(function (span) {
30377
31381
  var traceId = span.spanContext().traceId;
30378
- return traceId.startsWith(_constants_constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_DEBUG_PREFIX) ||
30379
- traceId.startsWith(_constants_constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX);
31382
+ return (traceId.startsWith(_constants_constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_DEBUG_PREFIX) ||
31383
+ traceId.startsWith(_constants_constants_base__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX));
30380
31384
  });
30381
31385
  // Only proceed if there are filtered spans
30382
31386
  if (filteredSpans.length === 0) {
@@ -30403,6 +31407,14 @@ var SessionRecorderBrowserTraceExporter = /** @class */ (function () {
30403
31407
  SessionRecorderBrowserTraceExporter.prototype.shutdown = function () {
30404
31408
  return this.exporter.shutdown();
30405
31409
  };
31410
+ SessionRecorderBrowserTraceExporter.prototype.exportBuffer = function (spans) {
31411
+ var _this = this;
31412
+ return new Promise(function (resolve) {
31413
+ _this.exporter.export(spans, function (result) {
31414
+ resolve(result);
31415
+ });
31416
+ });
31417
+ };
30406
31418
  SessionRecorderBrowserTraceExporter.prototype.exportViaPostMessage = function (spans, resultCallback) {
30407
31419
  var _this = this;
30408
31420
  if (typeof window === 'undefined') {
@@ -30413,7 +31425,7 @@ var SessionRecorderBrowserTraceExporter = /** @class */ (function () {
30413
31425
  window.postMessage({
30414
31426
  action: 'traces',
30415
31427
  type: this.postMessageType,
30416
- payload: spans.map(function (span) { return _this._serializeSpan(span); }),
31428
+ payload: spans.map(function (span) { return _this.serializeSpan(span); })
30417
31429
  }, this.postMessageTargetOrigin);
30418
31430
  resultCallback({ code: 0 });
30419
31431
  }
@@ -30421,38 +31433,17 @@ var SessionRecorderBrowserTraceExporter = /** @class */ (function () {
30421
31433
  resultCallback({ code: 1 });
30422
31434
  }
30423
31435
  };
30424
- SessionRecorderBrowserTraceExporter.prototype._serializeSpan = function (span) {
30425
- var _a;
31436
+ SessionRecorderBrowserTraceExporter.prototype.serializeSpan = function (span) {
30426
31437
  var spanContext = span.spanContext();
30427
- return {
30428
- _spanContext: spanContext,
30429
- name: span.name,
30430
- kind: span.kind,
30431
- links: span.links,
30432
- ended: span.ended,
30433
- events: span.events,
30434
- status: span.status,
30435
- endTime: span.endTime,
30436
- startTime: span.startTime,
30437
- duration: span.duration,
30438
- attributes: span.attributes,
30439
- parentSpanId: (_a = span.parentSpanContext) === null || _a === void 0 ? void 0 : _a.spanId,
30440
- droppedAttributesCount: span.droppedAttributesCount,
30441
- droppedEventsCount: span.droppedEventsCount,
30442
- droppedLinksCount: span.droppedLinksCount,
30443
- resource: {
30444
- attributes: span.resource.attributes,
30445
- asyncAttributesPending: span.resource.asyncAttributesPending,
30446
- },
30447
- };
31438
+ return __assign(__assign({}, span), { _spanContext: spanContext });
30448
31439
  };
30449
31440
  SessionRecorderBrowserTraceExporter.prototype._createExporter = function () {
30450
31441
  return new _opentelemetry_exporter_trace_otlp_http__WEBPACK_IMPORTED_MODULE_1__.OTLPTraceExporter({
30451
31442
  url: this.config.url,
30452
- headers: __assign(__assign({ 'Content-Type': 'application/json' }, (this.config.apiKey ? { 'Authorization': this.config.apiKey } : {})), (this.config.headers || {})),
31443
+ headers: __assign(__assign({ 'Content-Type': 'application/json' }, (this.config.apiKey ? { Authorization: this.config.apiKey } : {})), (this.config.headers || {})),
30453
31444
  timeoutMillis: this.config.timeoutMillis,
30454
31445
  keepAlive: this.config.keepAlive,
30455
- concurrencyLimit: this.config.concurrencyLimit,
31446
+ concurrencyLimit: this.config.concurrencyLimit
30456
31447
  });
30457
31448
  };
30458
31449
  SessionRecorderBrowserTraceExporter.prototype.setApiKey = function (apiKey) {
@@ -30517,6 +31508,7 @@ __webpack_require__.r(__webpack_exports__);
30517
31508
  /* harmony export */ ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE),
30518
31509
  /* harmony export */ ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE_ENCODING: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE_ENCODING),
30519
31510
  /* harmony export */ ATTR_MULTIPLAYER_RPC_RESPONSE_MESSAGE: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_RPC_RESPONSE_MESSAGE),
31511
+ /* harmony export */ ATTR_MULTIPLAYER_SESSION_CLIENT_ID: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_SESSION_CLIENT_ID),
30520
31512
  /* harmony export */ ATTR_MULTIPLAYER_SESSION_ID: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_SESSION_ID),
30521
31513
  /* harmony export */ ATTR_MULTIPLAYER_SESSION_RECORDER_VERSION: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_SESSION_RECORDER_VERSION),
30522
31514
  /* harmony export */ ATTR_MULTIPLAYER_USER_HASH: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_USER_HASH),
@@ -30531,10 +31523,14 @@ __webpack_require__.r(__webpack_exports__);
30531
31523
  /* 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
31524
  /* 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
31525
  /* harmony export */ MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_URL: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_URL),
31526
+ /* harmony export */ MULTIPLAYER_TRACE_CLIENT_ID_LENGTH: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_CLIENT_ID_LENGTH),
30534
31527
  /* harmony export */ MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX),
31528
+ /* harmony export */ MULTIPLAYER_TRACE_CONTINUOUS_SESSION_CACHE_PREFIX: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_CONTINUOUS_SESSION_CACHE_PREFIX),
30535
31529
  /* harmony export */ MULTIPLAYER_TRACE_DEBUG_PREFIX: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_DEBUG_PREFIX),
30536
31530
  /* 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
31531
  /* harmony export */ MULTIPLAYER_TRACE_DOC_PREFIX: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_DOC_PREFIX),
31532
+ /* harmony export */ MULTIPLAYER_TRACE_PREFIX_MAP: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_PREFIX_MAP),
31533
+ /* harmony export */ MULTIPLAYER_TRACE_SESSION_CACHE_PREFIX: () => (/* reexport safe */ _constants_constants_browser__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_SESSION_CACHE_PREFIX),
30538
31534
  /* harmony export */ SessionRecorderBrowserTraceExporter: () => (/* reexport safe */ _exporters_index_browser__WEBPACK_IMPORTED_MODULE_5__.SessionRecorderBrowserTraceExporter),
30539
31535
  /* harmony export */ SessionRecorderIdGenerator: () => (/* reexport safe */ _SessionRecorderIdGenerator__WEBPACK_IMPORTED_MODULE_1__.SessionRecorderIdGenerator),
30540
31536
  /* harmony export */ SessionRecorderSdk: () => (/* reexport module object */ _sdk__WEBPACK_IMPORTED_MODULE_3__),
@@ -31146,6 +32142,19 @@ var setGrpcResponseMessage = function (body, options) {
31146
32142
 
31147
32143
  /***/ }),
31148
32144
 
32145
+ /***/ "../session-recorder-common/dist/esm/type/crash-buffer.js":
32146
+ /*!****************************************************************!*\
32147
+ !*** ../session-recorder-common/dist/esm/type/crash-buffer.js ***!
32148
+ \****************************************************************/
32149
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
32150
+
32151
+ "use strict";
32152
+ __webpack_require__.r(__webpack_exports__);
32153
+
32154
+ //# sourceMappingURL=crash-buffer.js.map
32155
+
32156
+ /***/ }),
32157
+
31149
32158
  /***/ "../session-recorder-common/dist/esm/type/index.js":
31150
32159
  /*!*********************************************************!*\
31151
32160
  !*** ../session-recorder-common/dist/esm/type/index.js ***!
@@ -31162,6 +32171,8 @@ __webpack_require__.r(__webpack_exports__);
31162
32171
  /* harmony import */ var _session_type_enum__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./session-type.enum */ "../session-recorder-common/dist/esm/type/session-type.enum.js");
31163
32172
  /* harmony import */ var _user_type_enum__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./user-type.enum */ "../session-recorder-common/dist/esm/type/user-type.enum.js");
31164
32173
  /* harmony import */ var _session__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./session */ "../session-recorder-common/dist/esm/type/session.js");
32174
+ /* harmony import */ var _crash_buffer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./crash-buffer */ "../session-recorder-common/dist/esm/type/crash-buffer.js");
32175
+
31165
32176
 
31166
32177
 
31167
32178
 
@@ -31188,6 +32199,8 @@ var SessionType;
31188
32199
  */
31189
32200
  SessionType["PLAIN"] = "MANUAL";
31190
32201
  SessionType["MANUAL"] = "MANUAL";
32202
+ SessionType["CONTINUOUS_SESSION_CACHE"] = "CONTINUOUS_SESSION_CACHE";
32203
+ SessionType["SESSION_CACHE"] = "SESSION_CACHE";
31191
32204
  })(SessionType || (SessionType = {}));
31192
32205
  //# sourceMappingURL=session-type.enum.js.map
31193
32206
 
@@ -33057,6 +34070,123 @@ const getRecordConsolePlugin = (options) => ({
33057
34070
  //# sourceMappingURL=rrweb-plugin-console-record.js.map
33058
34071
 
33059
34072
 
34073
+ /***/ }),
34074
+
34075
+ /***/ "../../node_modules/@rrweb/types/dist/types.js":
34076
+ /*!*****************************************************!*\
34077
+ !*** ../../node_modules/@rrweb/types/dist/types.js ***!
34078
+ \*****************************************************/
34079
+ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
34080
+
34081
+ "use strict";
34082
+ __webpack_require__.r(__webpack_exports__);
34083
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
34084
+ /* harmony export */ CanvasContext: () => (/* binding */ CanvasContext),
34085
+ /* harmony export */ EventType: () => (/* binding */ EventType),
34086
+ /* harmony export */ IncrementalSource: () => (/* binding */ IncrementalSource),
34087
+ /* harmony export */ MediaInteractions: () => (/* binding */ MediaInteractions),
34088
+ /* harmony export */ MouseInteractions: () => (/* binding */ MouseInteractions),
34089
+ /* harmony export */ NodeType: () => (/* binding */ NodeType),
34090
+ /* harmony export */ PointerTypes: () => (/* binding */ PointerTypes),
34091
+ /* harmony export */ ReplayerEvents: () => (/* binding */ ReplayerEvents)
34092
+ /* harmony export */ });
34093
+ var EventType = /* @__PURE__ */ ((EventType2) => {
34094
+ EventType2[EventType2["DomContentLoaded"] = 0] = "DomContentLoaded";
34095
+ EventType2[EventType2["Load"] = 1] = "Load";
34096
+ EventType2[EventType2["FullSnapshot"] = 2] = "FullSnapshot";
34097
+ EventType2[EventType2["IncrementalSnapshot"] = 3] = "IncrementalSnapshot";
34098
+ EventType2[EventType2["Meta"] = 4] = "Meta";
34099
+ EventType2[EventType2["Custom"] = 5] = "Custom";
34100
+ EventType2[EventType2["Plugin"] = 6] = "Plugin";
34101
+ return EventType2;
34102
+ })(EventType || {});
34103
+ var IncrementalSource = /* @__PURE__ */ ((IncrementalSource2) => {
34104
+ IncrementalSource2[IncrementalSource2["Mutation"] = 0] = "Mutation";
34105
+ IncrementalSource2[IncrementalSource2["MouseMove"] = 1] = "MouseMove";
34106
+ IncrementalSource2[IncrementalSource2["MouseInteraction"] = 2] = "MouseInteraction";
34107
+ IncrementalSource2[IncrementalSource2["Scroll"] = 3] = "Scroll";
34108
+ IncrementalSource2[IncrementalSource2["ViewportResize"] = 4] = "ViewportResize";
34109
+ IncrementalSource2[IncrementalSource2["Input"] = 5] = "Input";
34110
+ IncrementalSource2[IncrementalSource2["TouchMove"] = 6] = "TouchMove";
34111
+ IncrementalSource2[IncrementalSource2["MediaInteraction"] = 7] = "MediaInteraction";
34112
+ IncrementalSource2[IncrementalSource2["StyleSheetRule"] = 8] = "StyleSheetRule";
34113
+ IncrementalSource2[IncrementalSource2["CanvasMutation"] = 9] = "CanvasMutation";
34114
+ IncrementalSource2[IncrementalSource2["Font"] = 10] = "Font";
34115
+ IncrementalSource2[IncrementalSource2["Log"] = 11] = "Log";
34116
+ IncrementalSource2[IncrementalSource2["Drag"] = 12] = "Drag";
34117
+ IncrementalSource2[IncrementalSource2["StyleDeclaration"] = 13] = "StyleDeclaration";
34118
+ IncrementalSource2[IncrementalSource2["Selection"] = 14] = "Selection";
34119
+ IncrementalSource2[IncrementalSource2["AdoptedStyleSheet"] = 15] = "AdoptedStyleSheet";
34120
+ IncrementalSource2[IncrementalSource2["CustomElement"] = 16] = "CustomElement";
34121
+ return IncrementalSource2;
34122
+ })(IncrementalSource || {});
34123
+ var MouseInteractions = /* @__PURE__ */ ((MouseInteractions2) => {
34124
+ MouseInteractions2[MouseInteractions2["MouseUp"] = 0] = "MouseUp";
34125
+ MouseInteractions2[MouseInteractions2["MouseDown"] = 1] = "MouseDown";
34126
+ MouseInteractions2[MouseInteractions2["Click"] = 2] = "Click";
34127
+ MouseInteractions2[MouseInteractions2["ContextMenu"] = 3] = "ContextMenu";
34128
+ MouseInteractions2[MouseInteractions2["DblClick"] = 4] = "DblClick";
34129
+ MouseInteractions2[MouseInteractions2["Focus"] = 5] = "Focus";
34130
+ MouseInteractions2[MouseInteractions2["Blur"] = 6] = "Blur";
34131
+ MouseInteractions2[MouseInteractions2["TouchStart"] = 7] = "TouchStart";
34132
+ MouseInteractions2[MouseInteractions2["TouchMove_Departed"] = 8] = "TouchMove_Departed";
34133
+ MouseInteractions2[MouseInteractions2["TouchEnd"] = 9] = "TouchEnd";
34134
+ MouseInteractions2[MouseInteractions2["TouchCancel"] = 10] = "TouchCancel";
34135
+ return MouseInteractions2;
34136
+ })(MouseInteractions || {});
34137
+ var PointerTypes = /* @__PURE__ */ ((PointerTypes2) => {
34138
+ PointerTypes2[PointerTypes2["Mouse"] = 0] = "Mouse";
34139
+ PointerTypes2[PointerTypes2["Pen"] = 1] = "Pen";
34140
+ PointerTypes2[PointerTypes2["Touch"] = 2] = "Touch";
34141
+ return PointerTypes2;
34142
+ })(PointerTypes || {});
34143
+ var CanvasContext = /* @__PURE__ */ ((CanvasContext2) => {
34144
+ CanvasContext2[CanvasContext2["2D"] = 0] = "2D";
34145
+ CanvasContext2[CanvasContext2["WebGL"] = 1] = "WebGL";
34146
+ CanvasContext2[CanvasContext2["WebGL2"] = 2] = "WebGL2";
34147
+ return CanvasContext2;
34148
+ })(CanvasContext || {});
34149
+ var MediaInteractions = /* @__PURE__ */ ((MediaInteractions2) => {
34150
+ MediaInteractions2[MediaInteractions2["Play"] = 0] = "Play";
34151
+ MediaInteractions2[MediaInteractions2["Pause"] = 1] = "Pause";
34152
+ MediaInteractions2[MediaInteractions2["Seeked"] = 2] = "Seeked";
34153
+ MediaInteractions2[MediaInteractions2["VolumeChange"] = 3] = "VolumeChange";
34154
+ MediaInteractions2[MediaInteractions2["RateChange"] = 4] = "RateChange";
34155
+ return MediaInteractions2;
34156
+ })(MediaInteractions || {});
34157
+ var ReplayerEvents = /* @__PURE__ */ ((ReplayerEvents2) => {
34158
+ ReplayerEvents2["Start"] = "start";
34159
+ ReplayerEvents2["Pause"] = "pause";
34160
+ ReplayerEvents2["Resume"] = "resume";
34161
+ ReplayerEvents2["Resize"] = "resize";
34162
+ ReplayerEvents2["Finish"] = "finish";
34163
+ ReplayerEvents2["FullsnapshotRebuilded"] = "fullsnapshot-rebuilded";
34164
+ ReplayerEvents2["LoadStylesheetStart"] = "load-stylesheet-start";
34165
+ ReplayerEvents2["LoadStylesheetEnd"] = "load-stylesheet-end";
34166
+ ReplayerEvents2["SkipStart"] = "skip-start";
34167
+ ReplayerEvents2["SkipEnd"] = "skip-end";
34168
+ ReplayerEvents2["MouseInteraction"] = "mouse-interaction";
34169
+ ReplayerEvents2["EventCast"] = "event-cast";
34170
+ ReplayerEvents2["CustomEvent"] = "custom-event";
34171
+ ReplayerEvents2["Flush"] = "flush";
34172
+ ReplayerEvents2["StateChange"] = "state-change";
34173
+ ReplayerEvents2["PlayBack"] = "play-back";
34174
+ ReplayerEvents2["Destroy"] = "destroy";
34175
+ return ReplayerEvents2;
34176
+ })(ReplayerEvents || {});
34177
+ var NodeType = /* @__PURE__ */ ((NodeType2) => {
34178
+ NodeType2[NodeType2["Document"] = 0] = "Document";
34179
+ NodeType2[NodeType2["DocumentType"] = 1] = "DocumentType";
34180
+ NodeType2[NodeType2["Element"] = 2] = "Element";
34181
+ NodeType2[NodeType2["Text"] = 3] = "Text";
34182
+ NodeType2[NodeType2["CDATA"] = 4] = "CDATA";
34183
+ NodeType2[NodeType2["Comment"] = 5] = "Comment";
34184
+ return NodeType2;
34185
+ })(NodeType || {});
34186
+
34187
+ //# sourceMappingURL=types.js.map
34188
+
34189
+
33060
34190
  /***/ }),
33061
34191
 
33062
34192
  /***/ "../../node_modules/@socket.io/component-emitter/lib/esm/index.js":
@@ -49578,6 +50708,7 @@ __webpack_require__.r(__webpack_exports__);
49578
50708
  /* harmony export */ ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE),
49579
50709
  /* 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
50710
  /* harmony export */ ATTR_MULTIPLAYER_RPC_RESPONSE_MESSAGE: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.ATTR_MULTIPLAYER_RPC_RESPONSE_MESSAGE),
50711
+ /* harmony export */ ATTR_MULTIPLAYER_SESSION_CLIENT_ID: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.ATTR_MULTIPLAYER_SESSION_CLIENT_ID),
49581
50712
  /* harmony export */ ATTR_MULTIPLAYER_SESSION_ID: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.ATTR_MULTIPLAYER_SESSION_ID),
49582
50713
  /* harmony export */ ATTR_MULTIPLAYER_SESSION_RECORDER_VERSION: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.ATTR_MULTIPLAYER_SESSION_RECORDER_VERSION),
49583
50714
  /* harmony export */ ATTR_MULTIPLAYER_USER_HASH: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.ATTR_MULTIPLAYER_USER_HASH),
@@ -49592,10 +50723,14 @@ __webpack_require__.r(__webpack_exports__);
49592
50723
  /* 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
50724
  /* 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
50725
  /* 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),
50726
+ /* harmony export */ MULTIPLAYER_TRACE_CLIENT_ID_LENGTH: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.MULTIPLAYER_TRACE_CLIENT_ID_LENGTH),
49595
50727
  /* harmony export */ MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX),
50728
+ /* harmony export */ MULTIPLAYER_TRACE_CONTINUOUS_SESSION_CACHE_PREFIX: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.MULTIPLAYER_TRACE_CONTINUOUS_SESSION_CACHE_PREFIX),
49596
50729
  /* harmony export */ MULTIPLAYER_TRACE_DEBUG_PREFIX: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.MULTIPLAYER_TRACE_DEBUG_PREFIX),
49597
50730
  /* 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
50731
  /* harmony export */ MULTIPLAYER_TRACE_DOC_PREFIX: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.MULTIPLAYER_TRACE_DOC_PREFIX),
50732
+ /* harmony export */ MULTIPLAYER_TRACE_PREFIX_MAP: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.MULTIPLAYER_TRACE_PREFIX_MAP),
50733
+ /* harmony export */ MULTIPLAYER_TRACE_SESSION_CACHE_PREFIX: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.MULTIPLAYER_TRACE_SESSION_CACHE_PREFIX),
49599
50734
  /* harmony export */ NavigationRecorder: () => (/* reexport safe */ _navigation__WEBPACK_IMPORTED_MODULE_6__.NavigationRecorder),
49600
50735
  /* harmony export */ SessionRecorderBrowserTraceExporter: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.SessionRecorderBrowserTraceExporter),
49601
50736
  /* harmony export */ SessionRecorderIdGenerator: () => (/* reexport safe */ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_7__.SessionRecorderIdGenerator),