@multiplayer-app/session-recorder-browser 1.3.31 → 1.3.32

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 (42) hide show
  1. package/README.md +3 -3
  2. package/dist/browser/index.js +300 -347
  3. package/dist/config/defaults.d.ts.map +1 -1
  4. package/dist/config/defaults.js +8 -8
  5. package/dist/config/defaults.js.map +1 -1
  6. package/dist/exporters/index.js +1 -1
  7. package/dist/exporters/index.js.map +1 -1
  8. package/dist/index.js +298 -347
  9. package/dist/index.js.map +1 -1
  10. package/dist/index.umd.js +299 -347
  11. package/dist/index.umd.js.map +1 -1
  12. package/dist/otel/CrashBufferSpanProcessor.js +2 -2
  13. package/dist/otel/index.d.ts +2 -3
  14. package/dist/otel/index.d.ts.map +1 -1
  15. package/dist/otel/index.js +63 -163
  16. package/dist/otel/index.js.map +1 -1
  17. package/dist/otel/instrumentations/index.d.ts +3 -0
  18. package/dist/otel/instrumentations/index.d.ts.map +1 -0
  19. package/dist/otel/instrumentations/index.js +104 -0
  20. package/dist/otel/instrumentations/index.js.map +1 -0
  21. package/dist/rrweb/index.d.ts.map +1 -1
  22. package/dist/rrweb/index.js +7 -7
  23. package/dist/rrweb/index.js.map +1 -1
  24. package/dist/services/api.service.d.ts +2 -0
  25. package/dist/services/api.service.d.ts.map +1 -1
  26. package/dist/services/api.service.js +5 -5
  27. package/dist/services/api.service.js.map +1 -1
  28. package/dist/services/crashBuffer.service.d.ts +1 -2
  29. package/dist/services/crashBuffer.service.d.ts.map +1 -1
  30. package/dist/services/crashBuffer.service.js +33 -73
  31. package/dist/services/crashBuffer.service.js.map +1 -1
  32. package/dist/services/indexedDb.service.js +2 -2
  33. package/dist/services/indexedDb.service.js.map +1 -1
  34. package/dist/services/socket.service.d.ts.map +1 -1
  35. package/dist/services/socket.service.js +10 -17
  36. package/dist/services/socket.service.js.map +1 -1
  37. package/dist/session-recorder.d.ts.map +1 -1
  38. package/dist/session-recorder.js +29 -49
  39. package/dist/session-recorder.js.map +1 -1
  40. package/dist/types/session-recorder.d.ts +3 -3
  41. package/dist/types/session-recorder.d.ts.map +1 -1
  42. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -24152,7 +24152,7 @@ const CONTINUOUS_DEBUGGING_TIMEOUT = 60000; // 1 minutes
24152
24152
  const DEBUG_SESSION_MAX_DURATION_SECONDS = 10 * 60 + 30; // TODO: move to shared config otel core
24153
24153
  const REMOTE_SESSION_RECORDING_START = 'remote-session-recording:start';
24154
24154
  const REMOTE_SESSION_RECORDING_STOP = 'remote-session-recording:stop';
24155
- const PACKAGE_VERSION_EXPORT = "1.3.31" || 0;
24155
+ const PACKAGE_VERSION_EXPORT = "1.3.32" || 0;
24156
24156
  // Regex patterns for OpenTelemetry ignore URLs
24157
24157
  const OTEL_IGNORE_URLS = [
24158
24158
  // Traces endpoint
@@ -24200,7 +24200,7 @@ const DEFAULT_MASKING_CONFIG = {
24200
24200
  maskBodyFieldsList: sensitiveFields,
24201
24201
  maskHeadersList: sensitiveHeaders,
24202
24202
  headersToInclude: [],
24203
- headersToExclude: [],
24203
+ headersToExclude: []
24204
24204
  };
24205
24205
  const DEFAULT_WIDGET_TEXT_CONFIG = {
24206
24206
  initialTitleWithContinuous: 'Encountered an issue?',
@@ -24222,7 +24222,7 @@ const DEFAULT_WIDGET_TEXT_CONFIG = {
24222
24222
  submitDialogCommentLabel: 'You can also add context, comments, or notes.',
24223
24223
  submitDialogCommentPlaceholder: 'Add a message...',
24224
24224
  submitDialogSubmitText: 'Save',
24225
- submitDialogCancelText: 'Cancel',
24225
+ submitDialogCancelText: 'Cancel'
24226
24226
  };
24227
24227
  const BASE_CONFIG = {
24228
24228
  apiKey: '',
@@ -24249,9 +24249,9 @@ const BASE_CONFIG = {
24249
24249
  useWebsocket: true,
24250
24250
  buffering: {
24251
24251
  enabled: true,
24252
- windowMinutes: 1,
24253
- snapshotIntervalMs: 30000,
24254
- },
24252
+ windowMinutes: 0.5,
24253
+ snapshotIntervalMs: 20000
24254
+ }
24255
24255
  };
24256
24256
 
24257
24257
 
@@ -24838,8 +24838,8 @@ class CrashBufferSpanProcessor {
24838
24838
  this._crashBuffer.appendSpans([
24839
24839
  {
24840
24840
  ts: span.startTime[0] * 1000 + span.startTime[1] / 1000000,
24841
- span: this._serializeSpan(span),
24842
- },
24841
+ span: this._serializeSpan(span)
24842
+ }
24843
24843
  ]);
24844
24844
  }
24845
24845
  return;
@@ -25089,18 +25089,16 @@ const getElementTextContent = (element) => {
25089
25089
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
25090
25090
  /* harmony export */ TracerBrowserSDK: () => (/* binding */ TracerBrowserSDK)
25091
25091
  /* harmony export */ });
25092
- /* harmony import */ var _opentelemetry_resources__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @opentelemetry/resources */ "../../node_modules/@opentelemetry/resources/build/esm/ResourceImpl.js");
25093
- /* harmony import */ var _opentelemetry_core__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @opentelemetry/core */ "../../node_modules/@opentelemetry/core/build/esm/trace/W3CTraceContextPropagator.js");
25094
- /* harmony import */ var _opentelemetry_sdk_trace_web__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @opentelemetry/sdk-trace-web */ "../../node_modules/@opentelemetry/sdk-trace-web/build/esm/WebTracerProvider.js");
25095
- /* harmony import */ var _opentelemetry_sdk_trace_base__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @opentelemetry/sdk-trace-base */ "../../node_modules/@opentelemetry/sdk-trace-base/build/esm/platform/browser/export/BatchSpanProcessor.js");
25096
- /* 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");
25097
- /* harmony import */ var _opentelemetry_instrumentation__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @opentelemetry/instrumentation */ "../../node_modules/@opentelemetry/instrumentation/build/esm/autoLoader.js");
25098
- /* 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");
25099
- /* 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");
25100
- /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../config */ "./src/config/index.ts");
25101
- /* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./helpers */ "./src/otel/helpers.ts");
25102
- /* harmony import */ var _CrashBufferSpanProcessor__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./CrashBufferSpanProcessor */ "./src/otel/CrashBufferSpanProcessor.ts");
25103
-
25092
+ /* harmony import */ var _opentelemetry_resources__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @opentelemetry/resources */ "../../node_modules/@opentelemetry/resources/build/esm/ResourceImpl.js");
25093
+ /* harmony import */ var _opentelemetry_core__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @opentelemetry/core */ "../../node_modules/@opentelemetry/core/build/esm/trace/W3CTraceContextPropagator.js");
25094
+ /* 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");
25095
+ /* 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");
25096
+ /* harmony import */ var _opentelemetry_semantic_conventions__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @opentelemetry/semantic-conventions */ "../../node_modules/@opentelemetry/semantic-conventions/build/esm/resource/SemanticResourceAttributes.js");
25097
+ /* harmony import */ var _opentelemetry_instrumentation__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @opentelemetry/instrumentation */ "../../node_modules/@opentelemetry/instrumentation/build/esm/autoLoader.js");
25098
+ /* 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");
25099
+ /* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./helpers */ "./src/otel/helpers.ts");
25100
+ /* harmony import */ var _instrumentations__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./instrumentations */ "./src/otel/instrumentations/index.ts");
25101
+ /* harmony import */ var _CrashBufferSpanProcessor__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./CrashBufferSpanProcessor */ "./src/otel/CrashBufferSpanProcessor.ts");
25104
25102
 
25105
25103
 
25106
25104
 
@@ -25111,14 +25109,14 @@ const getElementTextContent = (element) => {
25111
25109
 
25112
25110
 
25113
25111
 
25114
- const clientIdGenerator = _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);
25112
+ const clientIdGenerator = _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionRecorderSdk.getIdGenerator(_multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.MULTIPLAYER_TRACE_CLIENT_ID_LENGTH);
25115
25113
  class TracerBrowserSDK {
25116
25114
  constructor() {
25117
25115
  this.clientId = '';
25118
25116
  this.sessionId = '';
25119
25117
  this.globalErrorListenersRegistered = false;
25120
25118
  }
25121
- _setSessionId(sessionId, sessionType = _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionType.MANUAL) {
25119
+ _setSessionId(sessionId, sessionType = _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionType.MANUAL) {
25122
25120
  this.sessionId = sessionId;
25123
25121
  if (!this.idGenerator) {
25124
25122
  throw new Error('Id generator not initialized');
@@ -25129,133 +25127,35 @@ class TracerBrowserSDK {
25129
25127
  this.config = options;
25130
25128
  this.clientId = clientIdGenerator();
25131
25129
  const { application, version, environment } = this.config;
25132
- this.idGenerator = new _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionRecorderIdGenerator();
25133
- this._setSessionId('', _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionType.SESSION_CACHE);
25134
- this.exporter = new _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionRecorderBrowserTraceExporter({
25130
+ this.idGenerator = new _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionRecorderIdGenerator();
25131
+ this._setSessionId('', _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionType.SESSION_CACHE);
25132
+ this.exporter = new _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionRecorderBrowserTraceExporter({
25135
25133
  apiKey: options.apiKey,
25136
- url: (0,_helpers__WEBPACK_IMPORTED_MODULE_3__.getExporterEndpoint)(options.exporterEndpoint),
25137
- usePostMessageFallback: options.usePostMessageFallback,
25134
+ url: (0,_helpers__WEBPACK_IMPORTED_MODULE_1__.getExporterEndpoint)(options.exporterEndpoint),
25135
+ usePostMessageFallback: options.usePostMessageFallback
25138
25136
  });
25139
- const resourceAttributes = (0,_opentelemetry_resources__WEBPACK_IMPORTED_MODULE_5__.resourceFromAttributes)({
25140
- [_opentelemetry_semantic_conventions__WEBPACK_IMPORTED_MODULE_6__.SEMRESATTRS_SERVICE_NAME]: application,
25141
- [_opentelemetry_semantic_conventions__WEBPACK_IMPORTED_MODULE_6__.SEMRESATTRS_SERVICE_VERSION]: version,
25142
- [_opentelemetry_semantic_conventions__WEBPACK_IMPORTED_MODULE_6__.SEMRESATTRS_DEPLOYMENT_ENVIRONMENT]: environment,
25137
+ const resourceAttributes = (0,_opentelemetry_resources__WEBPACK_IMPORTED_MODULE_4__.resourceFromAttributes)({
25138
+ [_opentelemetry_semantic_conventions__WEBPACK_IMPORTED_MODULE_5__.SEMRESATTRS_SERVICE_NAME]: application,
25139
+ [_opentelemetry_semantic_conventions__WEBPACK_IMPORTED_MODULE_5__.SEMRESATTRS_SERVICE_VERSION]: version,
25140
+ [_opentelemetry_semantic_conventions__WEBPACK_IMPORTED_MODULE_5__.SEMRESATTRS_DEPLOYMENT_ENVIRONMENT]: environment
25143
25141
  });
25144
- _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionRecorderSdk.setResourceAttributes(resourceAttributes.attributes);
25145
- this.tracerProvider = new _opentelemetry_sdk_trace_web__WEBPACK_IMPORTED_MODULE_7__.WebTracerProvider({
25142
+ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionRecorderSdk.setResourceAttributes(resourceAttributes.attributes);
25143
+ this.tracerProvider = new _opentelemetry_sdk_trace_web__WEBPACK_IMPORTED_MODULE_6__.WebTracerProvider({
25146
25144
  resource: resourceAttributes,
25147
25145
  idGenerator: this.idGenerator,
25148
- sampler: new _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionRecorderTraceIdRatioBasedSampler(this.config.sampleTraceRatio),
25146
+ sampler: new _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionRecorderTraceIdRatioBasedSampler(this.config.sampleTraceRatio),
25149
25147
  spanProcessors: [
25150
25148
  this._getSpanSessionIdProcessor(),
25151
- new _opentelemetry_sdk_trace_base__WEBPACK_IMPORTED_MODULE_8__.BatchSpanProcessor(this.exporter),
25152
- new _CrashBufferSpanProcessor__WEBPACK_IMPORTED_MODULE_4__.CrashBufferSpanProcessor(this.crashBuffer, this.exporter.serializeSpan),
25153
- ],
25149
+ new _opentelemetry_sdk_trace_base__WEBPACK_IMPORTED_MODULE_7__.BatchSpanProcessor(this.exporter),
25150
+ new _CrashBufferSpanProcessor__WEBPACK_IMPORTED_MODULE_3__.CrashBufferSpanProcessor(this.crashBuffer, this.exporter.serializeSpan)
25151
+ ]
25154
25152
  });
25155
25153
  this.tracerProvider.register({
25156
- // contextManager: new ZoneContextManager(),
25157
- propagator: new _opentelemetry_core__WEBPACK_IMPORTED_MODULE_9__.W3CTraceContextPropagator(),
25154
+ propagator: new _opentelemetry_core__WEBPACK_IMPORTED_MODULE_8__.W3CTraceContextPropagator()
25158
25155
  });
25159
- (0,_opentelemetry_instrumentation__WEBPACK_IMPORTED_MODULE_10__.registerInstrumentations)({
25156
+ (0,_opentelemetry_instrumentation__WEBPACK_IMPORTED_MODULE_9__.registerInstrumentations)({
25160
25157
  tracerProvider: this.tracerProvider,
25161
- instrumentations: [
25162
- (0,_opentelemetry_auto_instrumentations_web__WEBPACK_IMPORTED_MODULE_0__.getWebAutoInstrumentations)({
25163
- '@opentelemetry/instrumentation-xml-http-request': {
25164
- clearTimingResources: true,
25165
- ignoreUrls: [..._config__WEBPACK_IMPORTED_MODULE_2__.OTEL_IGNORE_URLS, ...(this.config.ignoreUrls || [])],
25166
- propagateTraceHeaderCorsUrls: options.propagateTraceHeaderCorsUrls,
25167
- applyCustomAttributesOnSpan: (span, xhr) => {
25168
- if (!this.config)
25169
- return;
25170
- const { captureBody, captureHeaders } = this.config;
25171
- try {
25172
- if (!captureBody && !captureHeaders) {
25173
- return;
25174
- }
25175
- // @ts-ignore
25176
- const networkRequest = xhr.networkRequest;
25177
- const requestBody = networkRequest.requestBody;
25178
- const responseBody = networkRequest.responseBody;
25179
- const requestHeaders = networkRequest.requestHeaders || {};
25180
- const responseHeaders = networkRequest.responseHeaders || {};
25181
- const payload = {
25182
- requestBody,
25183
- responseBody,
25184
- requestHeaders,
25185
- responseHeaders,
25186
- };
25187
- (0,_helpers__WEBPACK_IMPORTED_MODULE_3__.processHttpPayload)(payload, this.config, span);
25188
- }
25189
- catch (error) {
25190
- // eslint-disable-next-line
25191
- console.error('[MULTIPLAYER_SESSION_RECORDER] Failed to capture xml-http payload', error);
25192
- }
25193
- },
25194
- },
25195
- '@opentelemetry/instrumentation-fetch': {
25196
- clearTimingResources: true,
25197
- ignoreUrls: [..._config__WEBPACK_IMPORTED_MODULE_2__.OTEL_IGNORE_URLS, ...(this.config.ignoreUrls || [])],
25198
- propagateTraceHeaderCorsUrls: options.propagateTraceHeaderCorsUrls,
25199
- applyCustomAttributesOnSpan: async (span, request, response) => {
25200
- if (!this.config)
25201
- return;
25202
- const { captureBody, captureHeaders } = this.config;
25203
- try {
25204
- if (!captureBody && !captureHeaders) {
25205
- return;
25206
- }
25207
- // Try to get data from our fetch wrapper first
25208
- // @ts-ignore
25209
- const networkRequest = response === null || response === void 0 ? void 0 : response.networkRequest;
25210
- let requestBody = null;
25211
- let responseBody = null;
25212
- let requestHeaders = {};
25213
- let responseHeaders = {};
25214
- if (networkRequest) {
25215
- // Use data captured by our fetch wrapper
25216
- requestBody = networkRequest.requestBody;
25217
- responseBody = networkRequest.responseBody;
25218
- requestHeaders = networkRequest.requestHeaders || {};
25219
- responseHeaders = networkRequest.responseHeaders || {};
25220
- }
25221
- else {
25222
- // Fallback to original OpenTelemetry approach
25223
- requestBody = request.body;
25224
- requestHeaders = (0,_helpers__WEBPACK_IMPORTED_MODULE_3__.headersToObject)(request.headers);
25225
- responseHeaders = (0,_helpers__WEBPACK_IMPORTED_MODULE_3__.headersToObject)(response instanceof Response ? response.headers : undefined);
25226
- if (response instanceof Response && response.body) {
25227
- responseBody = await (0,_helpers__WEBPACK_IMPORTED_MODULE_3__.extractResponseBody)(response);
25228
- }
25229
- }
25230
- const payload = {
25231
- requestBody,
25232
- responseBody,
25233
- requestHeaders,
25234
- responseHeaders,
25235
- };
25236
- (0,_helpers__WEBPACK_IMPORTED_MODULE_3__.processHttpPayload)(payload, this.config, span);
25237
- }
25238
- catch (error) {
25239
- // eslint-disable-next-line
25240
- console.error('[MULTIPLAYER_SESSION_RECORDER] Failed to capture fetch payload', error);
25241
- }
25242
- },
25243
- },
25244
- '@opentelemetry/instrumentation-user-interaction': {
25245
- shouldPreventSpanCreation: (_event, element, span) => {
25246
- if (span['parentSpanContext']) {
25247
- return true;
25248
- }
25249
- span.setAttribute('target.innerText', (0,_helpers__WEBPACK_IMPORTED_MODULE_3__.getElementInnerText)(element));
25250
- span.setAttribute('target.textContent', (0,_helpers__WEBPACK_IMPORTED_MODULE_3__.getElementTextContent)(element));
25251
- Array.from(element.attributes).forEach((attribute) => {
25252
- span.setAttribute(`target.attribute.${attribute.name}`, attribute.value);
25253
- });
25254
- return false;
25255
- },
25256
- },
25257
- }),
25258
- ],
25158
+ instrumentations: (0,_instrumentations__WEBPACK_IMPORTED_MODULE_2__.getInstrumentations)(this.config)
25259
25159
  });
25260
25160
  this._registerGlobalErrorListeners();
25261
25161
  }
@@ -25272,7 +25172,7 @@ class TracerBrowserSDK {
25272
25172
  if (!this.tracerProvider) {
25273
25173
  throw new Error('Configuration not initialized. Call init() before start().');
25274
25174
  }
25275
- this._setSessionId('', _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionType.SESSION_CACHE);
25175
+ this._setSessionId('', _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionType.SESSION_CACHE);
25276
25176
  }
25277
25177
  setApiKey(apiKey) {
25278
25178
  if (!this.exporter) {
@@ -25280,56 +25180,6 @@ class TracerBrowserSDK {
25280
25180
  }
25281
25181
  this.exporter.setApiKey(apiKey);
25282
25182
  }
25283
- static _toReadableSpanLike(span) {
25284
- var _a;
25285
- if (span && typeof span.spanContext === 'function' && span.instrumentationScope) {
25286
- return span;
25287
- }
25288
- const spanContext = typeof (span === null || span === void 0 ? void 0 : span.spanContext) === 'function' ? span.spanContext() : span === null || span === void 0 ? void 0 : span._spanContext;
25289
- const normalizedCtx = spanContext ||
25290
- {
25291
- traceId: span === null || span === void 0 ? void 0 : span.traceId,
25292
- spanId: span === null || span === void 0 ? void 0 : span.spanId,
25293
- traceFlags: span === null || span === void 0 ? void 0 : span.traceFlags,
25294
- traceState: span === null || span === void 0 ? void 0 : span.traceState,
25295
- };
25296
- const instrumentationScope = (span === null || span === void 0 ? void 0 : span.instrumentationScope) ||
25297
- (span === null || span === void 0 ? void 0 : span.instrumentationLibrary) ||
25298
- { name: 'multiplayer-buffer', version: undefined, schemaUrl: undefined };
25299
- const normalizedScope = {
25300
- name: (instrumentationScope === null || instrumentationScope === void 0 ? void 0 : instrumentationScope.name) || 'multiplayer-buffer',
25301
- version: instrumentationScope === null || instrumentationScope === void 0 ? void 0 : instrumentationScope.version,
25302
- schemaUrl: instrumentationScope === null || instrumentationScope === void 0 ? void 0 : instrumentationScope.schemaUrl,
25303
- };
25304
- const resource = (span === null || span === void 0 ? void 0 : span.resource) || { attributes: {}, asyncAttributesPending: false };
25305
- const parentSpanId = span === null || span === void 0 ? void 0 : span.parentSpanId;
25306
- return {
25307
- name: (span === null || span === void 0 ? void 0 : span.name) || '',
25308
- kind: span === null || span === void 0 ? void 0 : span.kind,
25309
- spanContext: () => normalizedCtx,
25310
- parentSpanContext: parentSpanId
25311
- ? {
25312
- traceId: normalizedCtx === null || normalizedCtx === void 0 ? void 0 : normalizedCtx.traceId,
25313
- spanId: parentSpanId,
25314
- traceFlags: normalizedCtx === null || normalizedCtx === void 0 ? void 0 : normalizedCtx.traceFlags,
25315
- traceState: normalizedCtx === null || normalizedCtx === void 0 ? void 0 : normalizedCtx.traceState,
25316
- }
25317
- : undefined,
25318
- startTime: span === null || span === void 0 ? void 0 : span.startTime,
25319
- endTime: (_a = span === null || span === void 0 ? void 0 : span.endTime) !== null && _a !== void 0 ? _a : span === null || span === void 0 ? void 0 : span.startTime,
25320
- duration: span === null || span === void 0 ? void 0 : span.duration,
25321
- status: span === null || span === void 0 ? void 0 : span.status,
25322
- attributes: (span === null || span === void 0 ? void 0 : span.attributes) || {},
25323
- links: (span === null || span === void 0 ? void 0 : span.links) || [],
25324
- events: (span === null || span === void 0 ? void 0 : span.events) || [],
25325
- ended: typeof (span === null || span === void 0 ? void 0 : span.ended) === 'boolean' ? span.ended : true,
25326
- droppedAttributesCount: (span === null || span === void 0 ? void 0 : span.droppedAttributesCount) || 0,
25327
- droppedEventsCount: (span === null || span === void 0 ? void 0 : span.droppedEventsCount) || 0,
25328
- droppedLinksCount: (span === null || span === void 0 ? void 0 : span.droppedLinksCount) || 0,
25329
- resource,
25330
- instrumentationScope: normalizedScope,
25331
- };
25332
- }
25333
25183
  async exportTraces(spans) {
25334
25184
  if (!this.exporter) {
25335
25185
  throw new Error('Trace exporter not initialized');
@@ -25351,19 +25201,18 @@ class TracerBrowserSDK {
25351
25201
  * Otherwise, a short-lived span will be created to hold the exception event.
25352
25202
  */
25353
25203
  captureException(error, errorInfo) {
25354
- _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionRecorderSdk.captureException(error, errorInfo);
25204
+ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionRecorderSdk.captureException(error, errorInfo);
25355
25205
  }
25356
25206
  _getSpanSessionIdProcessor() {
25357
25207
  return {
25358
- forceFlush: () => Promise.resolve(),
25359
- onEnd: () => Promise.resolve(),
25360
- shutdown: () => Promise.resolve(),
25361
25208
  onStart: (span) => {
25362
- var _a;
25363
- if ((_a = this.sessionId) === null || _a === void 0 ? void 0 : _a.length) {
25364
- span.setAttribute(_multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.ATTR_MULTIPLAYER_SESSION_ID, this.sessionId);
25209
+ if (this.sessionId) {
25210
+ span.setAttribute(_multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.ATTR_MULTIPLAYER_SESSION_ID, this.sessionId);
25365
25211
  }
25366
25212
  },
25213
+ onEnd: () => { },
25214
+ shutdown: () => Promise.resolve(),
25215
+ forceFlush: () => Promise.resolve()
25367
25216
  };
25368
25217
  }
25369
25218
  _registerGlobalErrorListeners() {
@@ -25388,9 +25237,178 @@ class TracerBrowserSDK {
25388
25237
  window.addEventListener('unhandledrejection', rejectionHandler);
25389
25238
  this.globalErrorListenersRegistered = true;
25390
25239
  }
25240
+ static _toReadableSpanLike(span) {
25241
+ var _a;
25242
+ if (span && typeof span.spanContext === 'function' && span.instrumentationScope) {
25243
+ return span;
25244
+ }
25245
+ const spanContext = typeof (span === null || span === void 0 ? void 0 : span.spanContext) === 'function' ? span.spanContext() : span === null || span === void 0 ? void 0 : span._spanContext;
25246
+ const normalizedCtx = spanContext ||
25247
+ {
25248
+ traceId: span === null || span === void 0 ? void 0 : span.traceId,
25249
+ spanId: span === null || span === void 0 ? void 0 : span.spanId,
25250
+ traceFlags: span === null || span === void 0 ? void 0 : span.traceFlags,
25251
+ traceState: span === null || span === void 0 ? void 0 : span.traceState
25252
+ };
25253
+ const instrumentationScope = (span === null || span === void 0 ? void 0 : span.instrumentationScope) ||
25254
+ (span === null || span === void 0 ? void 0 : span.instrumentationLibrary) ||
25255
+ { name: 'multiplayer-buffer', version: undefined, schemaUrl: undefined };
25256
+ const normalizedScope = {
25257
+ name: (instrumentationScope === null || instrumentationScope === void 0 ? void 0 : instrumentationScope.name) || 'multiplayer-buffer',
25258
+ version: instrumentationScope === null || instrumentationScope === void 0 ? void 0 : instrumentationScope.version,
25259
+ schemaUrl: instrumentationScope === null || instrumentationScope === void 0 ? void 0 : instrumentationScope.schemaUrl
25260
+ };
25261
+ const resource = (span === null || span === void 0 ? void 0 : span.resource) || { attributes: {}, asyncAttributesPending: false };
25262
+ const parentSpanId = span === null || span === void 0 ? void 0 : span.parentSpanId;
25263
+ return {
25264
+ name: (span === null || span === void 0 ? void 0 : span.name) || '',
25265
+ kind: span === null || span === void 0 ? void 0 : span.kind,
25266
+ spanContext: () => normalizedCtx,
25267
+ parentSpanContext: parentSpanId
25268
+ ? {
25269
+ traceId: normalizedCtx === null || normalizedCtx === void 0 ? void 0 : normalizedCtx.traceId,
25270
+ spanId: parentSpanId,
25271
+ traceFlags: normalizedCtx === null || normalizedCtx === void 0 ? void 0 : normalizedCtx.traceFlags,
25272
+ traceState: normalizedCtx === null || normalizedCtx === void 0 ? void 0 : normalizedCtx.traceState
25273
+ }
25274
+ : undefined,
25275
+ startTime: span === null || span === void 0 ? void 0 : span.startTime,
25276
+ endTime: (_a = span === null || span === void 0 ? void 0 : span.endTime) !== null && _a !== void 0 ? _a : span === null || span === void 0 ? void 0 : span.startTime,
25277
+ duration: span === null || span === void 0 ? void 0 : span.duration,
25278
+ status: span === null || span === void 0 ? void 0 : span.status,
25279
+ attributes: (span === null || span === void 0 ? void 0 : span.attributes) || {},
25280
+ links: (span === null || span === void 0 ? void 0 : span.links) || [],
25281
+ events: (span === null || span === void 0 ? void 0 : span.events) || [],
25282
+ ended: typeof (span === null || span === void 0 ? void 0 : span.ended) === 'boolean' ? span.ended : true,
25283
+ droppedAttributesCount: (span === null || span === void 0 ? void 0 : span.droppedAttributesCount) || 0,
25284
+ droppedEventsCount: (span === null || span === void 0 ? void 0 : span.droppedEventsCount) || 0,
25285
+ droppedLinksCount: (span === null || span === void 0 ? void 0 : span.droppedLinksCount) || 0,
25286
+ resource,
25287
+ instrumentationScope: normalizedScope
25288
+ };
25289
+ }
25391
25290
  }
25392
25291
 
25393
25292
 
25293
+ /***/ }),
25294
+
25295
+ /***/ "./src/otel/instrumentations/index.ts":
25296
+ /*!********************************************!*\
25297
+ !*** ./src/otel/instrumentations/index.ts ***!
25298
+ \********************************************/
25299
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
25300
+
25301
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
25302
+ /* harmony export */ getInstrumentations: () => (/* binding */ getInstrumentations)
25303
+ /* harmony export */ });
25304
+ /* 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");
25305
+ /* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../helpers */ "./src/otel/helpers.ts");
25306
+ /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../config */ "./src/config/index.ts");
25307
+
25308
+
25309
+
25310
+ const getInstrumentations = (config) => {
25311
+ return [
25312
+ (0,_opentelemetry_auto_instrumentations_web__WEBPACK_IMPORTED_MODULE_0__.getWebAutoInstrumentations)({
25313
+ '@opentelemetry/instrumentation-xml-http-request': {
25314
+ clearTimingResources: true,
25315
+ ignoreUrls: [..._config__WEBPACK_IMPORTED_MODULE_2__.OTEL_IGNORE_URLS, ...(config.ignoreUrls || [])],
25316
+ propagateTraceHeaderCorsUrls: config.propagateTraceHeaderCorsUrls,
25317
+ applyCustomAttributesOnSpan: (span, xhr) => {
25318
+ if (!config)
25319
+ return;
25320
+ const { captureBody, captureHeaders } = config;
25321
+ try {
25322
+ if (!captureBody && !captureHeaders) {
25323
+ return;
25324
+ }
25325
+ // @ts-ignore
25326
+ const networkRequest = xhr.networkRequest;
25327
+ const requestBody = networkRequest.requestBody;
25328
+ const responseBody = networkRequest.responseBody;
25329
+ const requestHeaders = networkRequest.requestHeaders || {};
25330
+ const responseHeaders = networkRequest.responseHeaders || {};
25331
+ const payload = {
25332
+ requestBody,
25333
+ responseBody,
25334
+ requestHeaders,
25335
+ responseHeaders
25336
+ };
25337
+ (0,_helpers__WEBPACK_IMPORTED_MODULE_1__.processHttpPayload)(payload, config, span);
25338
+ }
25339
+ catch (error) {
25340
+ // eslint-disable-next-line
25341
+ console.error('[MULTIPLAYER_SESSION_RECORDER] Failed to capture xml-http payload', error);
25342
+ }
25343
+ }
25344
+ },
25345
+ '@opentelemetry/instrumentation-fetch': {
25346
+ clearTimingResources: true,
25347
+ ignoreUrls: [..._config__WEBPACK_IMPORTED_MODULE_2__.OTEL_IGNORE_URLS, ...(config.ignoreUrls || [])],
25348
+ propagateTraceHeaderCorsUrls: config.propagateTraceHeaderCorsUrls,
25349
+ applyCustomAttributesOnSpan: async (span, request, response) => {
25350
+ if (!config)
25351
+ return;
25352
+ const { captureBody, captureHeaders } = config;
25353
+ try {
25354
+ if (!captureBody && !captureHeaders) {
25355
+ return;
25356
+ }
25357
+ // Try to get data from our fetch wrapper first
25358
+ // @ts-ignore
25359
+ const networkRequest = response === null || response === void 0 ? void 0 : response.networkRequest;
25360
+ let requestBody = null;
25361
+ let responseBody = null;
25362
+ let requestHeaders = {};
25363
+ let responseHeaders = {};
25364
+ if (networkRequest) {
25365
+ // Use data captured by our fetch wrapper
25366
+ requestBody = networkRequest.requestBody;
25367
+ responseBody = networkRequest.responseBody;
25368
+ requestHeaders = networkRequest.requestHeaders || {};
25369
+ responseHeaders = networkRequest.responseHeaders || {};
25370
+ }
25371
+ else {
25372
+ // Fallback to original OpenTelemetry approach
25373
+ requestBody = request.body;
25374
+ requestHeaders = (0,_helpers__WEBPACK_IMPORTED_MODULE_1__.headersToObject)(request.headers);
25375
+ responseHeaders = (0,_helpers__WEBPACK_IMPORTED_MODULE_1__.headersToObject)(response instanceof Response ? response.headers : undefined);
25376
+ if (response instanceof Response && response.body) {
25377
+ responseBody = await (0,_helpers__WEBPACK_IMPORTED_MODULE_1__.extractResponseBody)(response);
25378
+ }
25379
+ }
25380
+ const payload = {
25381
+ requestBody,
25382
+ responseBody,
25383
+ requestHeaders,
25384
+ responseHeaders
25385
+ };
25386
+ (0,_helpers__WEBPACK_IMPORTED_MODULE_1__.processHttpPayload)(payload, config, span);
25387
+ }
25388
+ catch (error) {
25389
+ // eslint-disable-next-line
25390
+ console.error('[MULTIPLAYER_SESSION_RECORDER] Failed to capture fetch payload', error);
25391
+ }
25392
+ }
25393
+ },
25394
+ '@opentelemetry/instrumentation-user-interaction': {
25395
+ shouldPreventSpanCreation: (_event, element, span) => {
25396
+ if (span['parentSpanContext']) {
25397
+ return true;
25398
+ }
25399
+ span.setAttribute('target.innerText', (0,_helpers__WEBPACK_IMPORTED_MODULE_1__.getElementInnerText)(element));
25400
+ span.setAttribute('target.textContent', (0,_helpers__WEBPACK_IMPORTED_MODULE_1__.getElementTextContent)(element));
25401
+ Array.from(element.attributes).forEach((attribute) => {
25402
+ span.setAttribute(`target.attribute.${attribute.name}`, attribute.value);
25403
+ });
25404
+ return false;
25405
+ }
25406
+ }
25407
+ })
25408
+ ];
25409
+ };
25410
+
25411
+
25394
25412
  /***/ }),
25395
25413
 
25396
25414
  /***/ "./src/patch/configs.ts":
@@ -25821,7 +25839,7 @@ class RecorderBrowserSDK {
25821
25839
  constructor() {
25822
25840
  this.intervals = {
25823
25841
  restart: null,
25824
- bufferSnapshot: null,
25842
+ bufferSnapshot: null
25825
25843
  };
25826
25844
  this.startedAt = '';
25827
25845
  this.stoppedAt = '';
@@ -25863,7 +25881,7 @@ class RecorderBrowserSDK {
25863
25881
  return;
25864
25882
  }
25865
25883
  this._handleLiveSessionEvent(event, ts, sessionId, sessionType);
25866
- },
25884
+ }
25867
25885
  });
25868
25886
  this.takeFullSnapshot();
25869
25887
  this._setupPeriodicSnapshots(sessionId, sessionType);
@@ -25940,8 +25958,8 @@ class RecorderBrowserSDK {
25940
25958
  event: {
25941
25959
  event: packedEvent,
25942
25960
  eventType: event.type,
25943
- timestamp: ts,
25944
- },
25961
+ timestamp: ts
25962
+ }
25945
25963
  });
25946
25964
  }
25947
25965
  catch (error) {
@@ -25966,7 +25984,7 @@ class RecorderBrowserSDK {
25966
25984
  eventType: event.type,
25967
25985
  timestamp: ts,
25968
25986
  debugSessionId: sessionId,
25969
- debugSessionType: sessionType,
25987
+ debugSessionType: sessionType
25970
25988
  });
25971
25989
  }
25972
25990
  /**
@@ -25980,7 +25998,7 @@ class RecorderBrowserSDK {
25980
25998
  sampling: { canvas: 5 },
25981
25999
  recordCanvas: (_c = this.config) === null || _c === void 0 ? void 0 : _c.recordCanvas,
25982
26000
  dataURLOptions: { type: 'image/webp', quality: 0.1 },
25983
- plugins: [(0,_rrweb_rrweb_plugin_console_record__WEBPACK_IMPORTED_MODULE_3__.getRecordConsolePlugin)({ level: ['log', 'error'] })],
26001
+ plugins: [(0,_rrweb_rrweb_plugin_console_record__WEBPACK_IMPORTED_MODULE_3__.getRecordConsolePlugin)({ level: ['log', 'error'] })]
25984
26002
  };
25985
26003
  if (maskingConfig.maskInputOptions) {
25986
26004
  options.maskInputOptions = maskingConfig.maskInputOptions;
@@ -26013,7 +26031,7 @@ class RecorderBrowserSDK {
26013
26031
  }, _config__WEBPACK_IMPORTED_MODULE_5__.CONTINUOUS_DEBUGGING_TIMEOUT);
26014
26032
  }
26015
26033
  if (!sessionId && ((_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.buffering) === null || _b === void 0 ? void 0 : _b.enabled)) {
26016
- const interval = this.config.buffering.snapshotIntervalMs || 30000;
26034
+ const interval = this.config.buffering.snapshotIntervalMs || 20000;
26017
26035
  this.intervals.bufferSnapshot = setInterval(() => {
26018
26036
  this.takeFullSnapshot();
26019
26037
  }, interval);
@@ -26040,7 +26058,7 @@ class ApiService {
26040
26058
  this.config = {
26041
26059
  apiKey: '',
26042
26060
  apiBaseUrl: '',
26043
- exporterEndpoint: '',
26061
+ exporterEndpoint: ''
26044
26062
  };
26045
26063
  }
26046
26064
  /**
@@ -26050,7 +26068,7 @@ class ApiService {
26050
26068
  init(config) {
26051
26069
  this.config = {
26052
26070
  ...this.config,
26053
- ...config,
26071
+ ...config
26054
26072
  };
26055
26073
  }
26056
26074
  /**
@@ -26144,14 +26162,14 @@ class ApiService {
26144
26162
  body: body ? JSON.stringify(body) : null,
26145
26163
  headers: {
26146
26164
  'Content-Type': 'application/json',
26147
- ...(this.config.apiKey && { 'X-Api-Key': this.config.apiKey }),
26148
- },
26165
+ ...(this.config.apiKey && { 'X-Api-Key': this.config.apiKey })
26166
+ }
26149
26167
  };
26150
26168
  try {
26151
26169
  const response = await fetch(url, {
26152
26170
  ...params,
26153
26171
  credentials: 'include',
26154
- signal,
26172
+ signal
26155
26173
  });
26156
26174
  if (!response.ok) {
26157
26175
  throw new Error('Network response was not ok: ' + response.statusText);
@@ -26222,14 +26240,6 @@ class CrashBufferService {
26222
26240
  return fallback;
26223
26241
  }
26224
26242
  }
26225
- async setAttrs(attrs) {
26226
- await this._safe(async () => {
26227
- await this.db.setAttrs({
26228
- tabId: this.tabId,
26229
- ...attrs,
26230
- });
26231
- }, undefined);
26232
- }
26233
26243
  async appendEvent(payload, _windowMs) {
26234
26244
  var _a;
26235
26245
  this.lastSeenEventTs = Math.max(this.lastSeenEventTs, payload.ts || 0);
@@ -26238,26 +26248,15 @@ class CrashBufferService {
26238
26248
  const isFullSnapshot = Boolean(payload.isFullSnapshot);
26239
26249
  const eventType = (_a = payload === null || payload === void 0 ? void 0 : payload.event) === null || _a === void 0 ? void 0 : _a.eventType;
26240
26250
  const isMeta = eventType === _rrweb_types__WEBPACK_IMPORTED_MODULE_0__.EventType.Meta;
26241
- if (this.requiresFullSnapshot && !isFullSnapshot && !isMeta) {
26242
- // rrweb replayable prefix is Meta -> FullSnapshot.
26243
- // While waiting for the first FullSnapshot, we still keep the Meta event (but drop incrementals).
26244
- return;
26245
- }
26246
26251
  await this._safe(async () => {
26247
26252
  await this.db.appendEvent({
26248
26253
  tabId: this.tabId,
26249
26254
  ts: payload.ts,
26250
26255
  isFullSnapshot: payload.isFullSnapshot,
26251
- event: payload.event,
26256
+ event: payload.event
26252
26257
  });
26253
26258
  }, undefined);
26254
- if (isFullSnapshot && this.requiresFullSnapshot) {
26255
- // Ensure this snapshot becomes the first replayable event.
26256
- // Keep Meta + FullSnapshot (if present) and prune everything older.
26257
- await this._safe(() => this.db.pruneOlderThanWithRrwebSnapshotAnchor(this.tabId, payload.ts), undefined);
26258
- this.requiresFullSnapshot = false;
26259
- }
26260
- else if (isFullSnapshot) {
26259
+ if (isFullSnapshot) {
26261
26260
  this.requiresFullSnapshot = false;
26262
26261
  }
26263
26262
  this.pruneSoon();
@@ -26278,7 +26277,7 @@ class CrashBufferService {
26278
26277
  return {
26279
26278
  tabId: this.tabId,
26280
26279
  ts: p.ts,
26281
- span: p.span,
26280
+ span: p.span
26282
26281
  };
26283
26282
  });
26284
26283
  await this.db.appendSpans(records);
@@ -26318,71 +26317,50 @@ class CrashBufferService {
26318
26317
  }
26319
26318
  async snapshot(_windowMs, now = Date.now()) {
26320
26319
  var _a, _b;
26321
- const toTs = now;
26322
- const fromTs = Math.max(0, toTs - this.windowMs);
26320
+ const stoppedAt = now;
26321
+ let startedAt = Math.max(0, stoppedAt - this.windowMs);
26323
26322
  // Always include a full snapshot "anchor" if one exists at/before the window start.
26324
- const rrwebFromTs = await this._safe(async () => {
26325
- const anchor = await this.db.getLastRrwebFullSnapshotBefore(this.tabId, fromTs);
26326
- return typeof (anchor === null || anchor === void 0 ? void 0 : anchor.ts) === 'number' ? anchor.ts : fromTs;
26327
- }, fromTs);
26328
- const [rrweb, spans, attrs] = await Promise.all([
26329
- this._safe(() => this.db.getRrwebEventsWindow(this.tabId, rrwebFromTs, toTs), []),
26330
- this._safe(() => this.db.getOtelSpansWindow(this.tabId, fromTs, toTs), []),
26331
- this._safe(() => this.db.getAttrs(this.tabId), null),
26323
+ const firstSnapshotAt = await this._safe(async () => {
26324
+ const anchor = await this.db.getLastRrwebFullSnapshotBefore(this.tabId, startedAt);
26325
+ return typeof (anchor === null || anchor === void 0 ? void 0 : anchor.ts) === 'number' ? anchor.ts : startedAt;
26326
+ }, startedAt);
26327
+ const [allEvents, allSpans] = await Promise.all([
26328
+ this._safe(() => this.db.getRrwebEventsWindow(this.tabId, firstSnapshotAt, stoppedAt), []),
26329
+ this._safe(() => this.db.getOtelSpansWindow(this.tabId, startedAt, stoppedAt), [])
26332
26330
  ]);
26333
- const rrwebSorted = rrweb
26331
+ const eventsSorted = allEvents
26334
26332
  .sort((a, b) => a.ts - b.ts)
26335
26333
  .map((r) => ({ ts: r.ts, isFullSnapshot: r.isFullSnapshot, event: r.event }));
26334
+ const payload = {
26335
+ startedAt,
26336
+ stoppedAt,
26337
+ spans: [],
26338
+ events: []
26339
+ };
26336
26340
  // Hard guarantee: snapshot payload starts with Meta -> FullSnapshot (or is empty).
26337
- const firstFullSnapshotIdx = rrwebSorted.findIndex((e) => Boolean(e.isFullSnapshot));
26338
- if (firstFullSnapshotIdx < 0) {
26339
- return {
26340
- rrwebEvents: [],
26341
- otelSpans: [],
26342
- attrs: attrs
26343
- ? {
26344
- sessionAttributes: attrs.sessionAttributes,
26345
- resourceAttributes: attrs.resourceAttributes,
26346
- userAttributes: attrs.userAttributes,
26347
- }
26348
- : null,
26349
- windowMs: this.windowMs,
26350
- fromTs,
26351
- toTs,
26352
- };
26341
+ const firstSnapshotIdx = eventsSorted.findIndex((e) => Boolean(e.isFullSnapshot));
26342
+ if (firstSnapshotIdx < 0) {
26343
+ return payload;
26353
26344
  }
26354
26345
  // Prefer including the Meta event immediately preceding the first FullSnapshot.
26355
- let startIdx = firstFullSnapshotIdx;
26356
- for (let i = firstFullSnapshotIdx - 1; i >= 0; i--) {
26357
- const t = (_b = (_a = rrwebSorted[i]) === null || _a === void 0 ? void 0 : _a.event) === null || _b === void 0 ? void 0 : _b.eventType;
26346
+ let startIdx = firstSnapshotIdx;
26347
+ for (let i = firstSnapshotIdx - 1; i >= 0; i--) {
26348
+ const t = (_b = (_a = eventsSorted[i]) === null || _a === void 0 ? void 0 : _a.event) === null || _b === void 0 ? void 0 : _b.eventType;
26358
26349
  if (t === _rrweb_types__WEBPACK_IMPORTED_MODULE_0__.EventType.Meta) {
26359
26350
  startIdx = i;
26360
26351
  break;
26361
26352
  }
26362
26353
  }
26363
- const rrwebEvents = rrwebSorted.slice(startIdx);
26364
- // Align spans with the rrweb replay start (Meta if present, otherwise FullSnapshot).
26365
- // Important: we return `fromTs` to consumers and many UIs compute relative offsets from it,
26366
- // so `fromTs` must match the first rrweb event timestamp we return.
26367
- const replayStartTs = rrwebEvents.length > 0 ? rrwebEvents[0].ts : fromTs;
26368
- const otelSpans = spans
26369
- .filter((s) => typeof (s === null || s === void 0 ? void 0 : s.ts) === 'number' && s.ts >= replayStartTs)
26354
+ const events = eventsSorted.slice(startIdx);
26355
+ const replayStartedAt = events.length > 0 ? events[0].ts : startedAt;
26356
+ const spans = allSpans
26357
+ .filter((s) => typeof (s === null || s === void 0 ? void 0 : s.ts) === 'number' && s.ts >= replayStartedAt)
26370
26358
  .sort((a, b) => a.ts - b.ts)
26371
26359
  .map((r) => ({ ts: r.ts, span: r.span }));
26372
- return {
26373
- rrwebEvents,
26374
- otelSpans,
26375
- attrs: attrs
26376
- ? {
26377
- sessionAttributes: attrs.sessionAttributes,
26378
- resourceAttributes: attrs.resourceAttributes,
26379
- userAttributes: attrs.userAttributes,
26380
- }
26381
- : null,
26382
- windowMs: this.windowMs,
26383
- fromTs: replayStartTs,
26384
- toTs,
26385
- };
26360
+ payload.events = events;
26361
+ payload.spans = spans;
26362
+ payload.startedAt = replayStartedAt;
26363
+ return payload;
26386
26364
  }
26387
26365
  async clear() {
26388
26366
  await this._safe(() => this.db.clearTab(this.tabId), undefined);
@@ -26535,7 +26513,7 @@ class IndexedDBService {
26535
26513
  const db = await this.dbPromise;
26536
26514
  const payload = {
26537
26515
  ...attrs,
26538
- updatedAt: (_a = attrs.updatedAt) !== null && _a !== void 0 ? _a : Date.now(),
26516
+ updatedAt: (_a = attrs.updatedAt) !== null && _a !== void 0 ? _a : Date.now()
26539
26517
  };
26540
26518
  return new Promise((resolve, reject) => {
26541
26519
  const tx = db.transaction(attrsStore, 'readwrite');
@@ -26821,7 +26799,7 @@ class IndexedDBService {
26821
26799
  const r = attr.delete(tabId);
26822
26800
  r.onsuccess = () => res();
26823
26801
  r.onerror = () => rej(r.error);
26824
- }),
26802
+ })
26825
26803
  ])
26826
26804
  .then(() => {
26827
26805
  // noop
@@ -26976,7 +26954,7 @@ class SocketService extends lib0_observable__WEBPACK_IMPORTED_MODULE_4__.Observa
26976
26954
  apiKey: '',
26977
26955
  socketUrl: '',
26978
26956
  keepAlive: false,
26979
- usePostMessageFallback: false,
26957
+ usePostMessageFallback: false
26980
26958
  };
26981
26959
  }
26982
26960
  /**
@@ -26986,11 +26964,9 @@ class SocketService extends lib0_observable__WEBPACK_IMPORTED_MODULE_4__.Observa
26986
26964
  init(config) {
26987
26965
  this.options = {
26988
26966
  ...this.options,
26989
- ...config,
26967
+ ...config
26990
26968
  };
26991
- if (this.options.keepAlive &&
26992
- this.options.socketUrl &&
26993
- this.options.apiKey) {
26969
+ if (this.options.keepAlive && this.options.socketUrl && this.options.apiKey) {
26994
26970
  this._initConnection();
26995
26971
  }
26996
26972
  }
@@ -27003,16 +26979,13 @@ class SocketService extends lib0_observable__WEBPACK_IMPORTED_MODULE_4__.Observa
27003
26979
  // If any config changed, reconnect if connected
27004
26980
  const hasChanges = Object.keys(config).some((key) => {
27005
26981
  const typedKey = key;
27006
- return (config[typedKey] !== undefined &&
27007
- config[typedKey] !== this.options[typedKey]);
26982
+ return config[typedKey] !== undefined && config[typedKey] !== this.options[typedKey];
27008
26983
  });
27009
26984
  if (hasChanges) {
27010
26985
  this.options = { ...this.options, ...config };
27011
26986
  if ((_a = this.socket) === null || _a === void 0 ? void 0 : _a.connected) {
27012
26987
  this.close().then(() => {
27013
- if (this.options.keepAlive &&
27014
- this.options.socketUrl &&
27015
- this.options.apiKey) {
26988
+ if (this.options.keepAlive && this.options.socketUrl && this.options.apiKey) {
27016
26989
  this._initConnection();
27017
26990
  }
27018
26991
  });
@@ -27029,12 +27002,10 @@ class SocketService extends lib0_observable__WEBPACK_IMPORTED_MODULE_4__.Observa
27029
27002
  path: '/v0/radar/ws',
27030
27003
  auth: {
27031
27004
  'x-api-key': this.options.apiKey,
27032
- ...this.options.clientId
27033
- ? { [_multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_3__.ATTR_MULTIPLAYER_SESSION_CLIENT_ID]: this.options.clientId }
27034
- : {},
27005
+ ...(this.options.clientId ? { [_multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_3__.ATTR_MULTIPLAYER_SESSION_CLIENT_ID]: this.options.clientId } : {})
27035
27006
  },
27036
27007
  reconnectionAttempts: 2,
27037
- transports: ['websocket'],
27008
+ transports: ['websocket']
27038
27009
  });
27039
27010
  this.socket.on('ready', () => {
27040
27011
  this.isConnecting = false;
@@ -27111,7 +27082,7 @@ class SocketService extends lib0_observable__WEBPACK_IMPORTED_MODULE_4__.Observa
27111
27082
  projectId: session.project,
27112
27083
  workspaceId: session.workspace,
27113
27084
  debugSessionId: this.sessionId,
27114
- sessionType: session.creationType,
27085
+ sessionType: session.creationType
27115
27086
  };
27116
27087
  this.emitSocketEvent(_config__WEBPACK_IMPORTED_MODULE_2__.SESSION_SUBSCRIBE_EVENT, payload);
27117
27088
  // use long id instead of short id
@@ -27340,7 +27311,7 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_16__.Obse
27340
27311
  this._checkOperation('init');
27341
27312
  // GC: remove orphaned crash buffers from old tabs.
27342
27313
  // Keep TTL large to avoid any accidental data loss.
27343
- void this._bufferDb.sweepStaleTabs(24 * 60 * 60 * 1000);
27314
+ void this._bufferDb.sweepStaleTabs(10 * 60 * 60 * 1000);
27344
27315
  (0,_patch__WEBPACK_IMPORTED_MODULE_6__.setMaxCapturingHttpPayloadSize)(this._configs.maxCapturingHttpPayloadSize || _config__WEBPACK_IMPORTED_MODULE_5__.DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE);
27345
27316
  (0,_patch__WEBPACK_IMPORTED_MODULE_6__.setShouldRecordHttpData)(this._configs.captureBody, this._configs.captureHeaders);
27346
27317
  this._setupCrashBuffer();
@@ -27379,22 +27350,16 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_16__.Obse
27379
27350
  _setupCrashBuffer() {
27380
27351
  var _a;
27381
27352
  if ((_a = this._configs.buffering) === null || _a === void 0 ? void 0 : _a.enabled) {
27382
- const windowMinutes = this._configs.buffering.windowMinutes || 1;
27353
+ const windowMinutes = this._configs.buffering.windowMinutes || 0.5;
27383
27354
  const windowMs = Math.max(10000, windowMinutes * 60 * 1000);
27384
27355
  this._crashBuffer = new _services_crashBuffer_service__WEBPACK_IMPORTED_MODULE_13__.CrashBufferService(this._bufferDb, this._tabId, windowMs);
27385
27356
  this._recorder.setCrashBuffer(this._crashBuffer);
27386
27357
  this._tracer.setCrashBuffer(this._crashBuffer);
27387
- this._crashBuffer.setAttrs({
27388
- sessionAttributes: this.sessionAttributes,
27389
- resourceAttributes: (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getNavigatorInfo)(),
27390
- userAttributes: this._userAttributes
27391
- });
27392
27358
  this._crashBuffer.on('error-span-appended', (payload) => {
27393
27359
  if (this.sessionState !== _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.stopped || this.sessionId)
27394
27360
  return;
27395
27361
  if (!payload.span)
27396
27362
  return;
27397
- console.log('error-span-appended', payload);
27398
27363
  this._createExceptionSession(payload.span);
27399
27364
  });
27400
27365
  this._registerCrashBufferLifecycleHandlers();
@@ -27439,13 +27404,12 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_16__.Obse
27439
27404
  }
27440
27405
  _startBufferOnlyRecording() {
27441
27406
  var _a, _b;
27442
- if (!((_b = (_a = this._configs) === null || _a === void 0 ? void 0 : _a.buffering) === null || _b === void 0 ? void 0 : _b.enabled))
27443
- return;
27444
- if (!this._crashBuffer)
27445
- return;
27446
- // Don’t start if a session is active.
27447
- if (this.sessionState !== _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.stopped || this.sessionId)
27407
+ if (this.sessionId ||
27408
+ !this._crashBuffer ||
27409
+ !((_b = (_a = this._configs) === null || _a === void 0 ? void 0 : _a.buffering) === null || _b === void 0 ? void 0 : _b.enabled) ||
27410
+ this.sessionState !== _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.stopped) {
27448
27411
  return;
27412
+ }
27449
27413
  void this._recorder.restart(null, _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionType.MANUAL);
27450
27414
  }
27451
27415
  /**
@@ -27592,7 +27556,6 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_16__.Obse
27592
27556
  return;
27593
27557
  }
27594
27558
  this._userAttributes = userAttributes;
27595
- this._tracer.clientId;
27596
27559
  const data = {
27597
27560
  userAttributes: this._userAttributes,
27598
27561
  clientId: this._tracer.clientId
@@ -27624,37 +27587,30 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_16__.Obse
27624
27587
  }
27625
27588
  async _flushBuffer(sessionId) {
27626
27589
  var _a, _b;
27627
- if (!((_b = (_a = this._configs) === null || _a === void 0 ? void 0 : _a.buffering) === null || _b === void 0 ? void 0 : _b.enabled))
27628
- return null;
27629
- if (!this._crashBuffer)
27630
- return null;
27631
- if (this._isFlushingBuffer)
27632
- return null;
27633
- // Don’t flush while a live recording is active.
27634
- if (this.sessionState !== _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.stopped)
27590
+ if (!sessionId ||
27591
+ !this._crashBuffer ||
27592
+ this._isFlushingBuffer ||
27593
+ !((_b = (_a = this._configs) === null || _a === void 0 ? void 0 : _a.buffering) === null || _b === void 0 ? void 0 : _b.enabled) ||
27594
+ this.sessionState !== _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.stopped) {
27635
27595
  return null;
27596
+ }
27636
27597
  this._isFlushingBuffer = true;
27637
27598
  try {
27638
- const snapshot = await this._crashBuffer.snapshot();
27639
- if (snapshot.rrwebEvents.length === 0 && snapshot.otelSpans.length === 0) {
27599
+ const { events, spans, startedAt, stoppedAt } = await this._crashBuffer.snapshot();
27600
+ if (events.length === 0 && spans.length === 0) {
27640
27601
  return null;
27641
27602
  }
27642
- if (sessionId) {
27643
- const spans = snapshot.otelSpans.map((s) => s.span);
27644
- const events = snapshot.rrwebEvents.map((e) => e.event);
27645
- await Promise.all([
27646
- this._tracer.exportTraces(spans),
27647
- this._apiService.exportEvents(sessionId, { events }),
27648
- this._apiService.updateSessionAttributes(sessionId, {
27649
- name: this._getSessionName(),
27650
- // startedAt: new Date(snapshot.rrwebEvents[0].ts).toISOString(),
27651
- // stoppedAt: new Date().toISOString(),
27652
- sessionAttributes: this.sessionAttributes,
27653
- resourceAttributes: (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getNavigatorInfo)(),
27654
- userAttributes: this._userAttributes || undefined
27655
- })
27656
- ]);
27657
- }
27603
+ await Promise.all([
27604
+ this._tracer.exportTraces(spans.map((s) => s.span)),
27605
+ this._apiService.exportEvents(sessionId, { events: events.map((e) => e.event) }),
27606
+ this._apiService.updateSessionAttributes(sessionId, {
27607
+ startedAt: new Date(startedAt).toISOString(),
27608
+ stoppedAt: new Date(stoppedAt).toISOString(),
27609
+ sessionAttributes: this.sessionAttributes,
27610
+ resourceAttributes: (0,_utils__WEBPACK_IMPORTED_MODULE_3__.getNavigatorInfo)(),
27611
+ userAttributes: this._userAttributes || undefined
27612
+ })
27613
+ ]);
27658
27614
  }
27659
27615
  catch (_e) {
27660
27616
  // swallow: flush is best-effort; never throw into app code
@@ -27825,19 +27781,14 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_16__.Obse
27825
27781
  });
27826
27782
  this._socketService.on(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_SAVE_BUFFER_EVENT, (payload) => {
27827
27783
  var _a;
27828
- if (!((_a = payload === null || payload === void 0 ? void 0 : payload.debugSession) === null || _a === void 0 ? void 0 : _a._id))
27829
- return;
27830
- void this._flushBuffer(payload.debugSession._id);
27784
+ this._flushBuffer((_a = payload === null || payload === void 0 ? void 0 : payload.debugSession) === null || _a === void 0 ? void 0 : _a._id);
27831
27785
  });
27832
27786
  }
27833
27787
  async _createExceptionSession(span) {
27834
27788
  try {
27835
27789
  const session = await this._apiService.createErrorSession({ span });
27836
- console.log('====================================');
27837
- console.log(span);
27838
- console.log('====================================');
27839
- if (session) {
27840
- void this._flushBuffer(session._id);
27790
+ if (session === null || session === void 0 ? void 0 : session._id) {
27791
+ this._flushBuffer(session._id);
27841
27792
  }
27842
27793
  }
27843
27794
  catch (_ignored) { }