@multiplayer-app/session-recorder-browser 2.0.87 → 2.0.88
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.
- package/dist/config/constants.d.ts +2 -1
- package/dist/config/constants.js +3 -1
- package/dist/index.js +84 -35
- package/dist/index.umd.js +84 -35
- package/dist/session-recorder.js +83 -38
- package/package.json +2 -2
|
@@ -11,9 +11,10 @@ export declare const SESSION_UNSUBSCRIBE_EVENT = "debug-session:unsubscribe";
|
|
|
11
11
|
export declare const SESSION_AUTO_CREATED = "debug-session:auto-created";
|
|
12
12
|
export declare const SESSION_ADD_EVENT = "debug-session:rrweb:add-event";
|
|
13
13
|
export declare const SESSION_SAVE_BUFFER_EVENT = "debug-session:save-buffer";
|
|
14
|
+
export declare const SESSION_READY_EVENT = "debug-session:ready";
|
|
15
|
+
export declare const SESSION_READY_EVENT_LEGACY = "debug-session-ready";
|
|
14
16
|
export declare const SOCKET_SET_USER_EVENT = "socket:set-user";
|
|
15
17
|
export declare const DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE = 100000;
|
|
16
|
-
export declare const SESSION_READY_EVENT = "debug-session-ready";
|
|
17
18
|
export declare const CONTINUOUS_DEBUGGING_TIMEOUT = 60000;
|
|
18
19
|
export declare const DEBUG_SESSION_MAX_DURATION_SECONDS: number;
|
|
19
20
|
export declare const REMOTE_SESSION_RECORDING_START = "remote-session-recording:start";
|
package/dist/config/constants.js
CHANGED
|
@@ -12,9 +12,11 @@ export const SESSION_AUTO_CREATED = 'debug-session:auto-created';
|
|
|
12
12
|
export const SESSION_ADD_EVENT = 'debug-session:rrweb:add-event';
|
|
13
13
|
// Backend-triggered flush of client-side crash buffer
|
|
14
14
|
export const SESSION_SAVE_BUFFER_EVENT = 'debug-session:save-buffer';
|
|
15
|
+
export const SESSION_READY_EVENT = 'debug-session:ready';
|
|
16
|
+
// Deprecated event name for backwards compatibility
|
|
17
|
+
export const SESSION_READY_EVENT_LEGACY = 'debug-session-ready';
|
|
15
18
|
export const SOCKET_SET_USER_EVENT = 'socket:set-user';
|
|
16
19
|
export const DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE = 100000;
|
|
17
|
-
export const SESSION_READY_EVENT = 'debug-session-ready';
|
|
18
20
|
export const CONTINUOUS_DEBUGGING_TIMEOUT = 60000; // 1 minutes
|
|
19
21
|
export const DEBUG_SESSION_MAX_DURATION_SECONDS = 10 * 60 + 30; // TODO: move to shared config otel core
|
|
20
22
|
export const REMOTE_SESSION_RECORDING_START = 'remote-session-recording:start';
|
package/dist/index.js
CHANGED
|
@@ -7030,6 +7030,7 @@ module.exports = {
|
|
|
7030
7030
|
/* harmony export */ SESSION_ID_PROP_NAME: () => (/* binding */ SESSION_ID_PROP_NAME),
|
|
7031
7031
|
/* harmony export */ SESSION_PROP_NAME: () => (/* binding */ SESSION_PROP_NAME),
|
|
7032
7032
|
/* harmony export */ SESSION_READY_EVENT: () => (/* binding */ SESSION_READY_EVENT),
|
|
7033
|
+
/* harmony export */ SESSION_READY_EVENT_LEGACY: () => (/* binding */ SESSION_READY_EVENT_LEGACY),
|
|
7033
7034
|
/* harmony export */ SESSION_SAVE_BUFFER_EVENT: () => (/* binding */ SESSION_SAVE_BUFFER_EVENT),
|
|
7034
7035
|
/* harmony export */ SESSION_STARTED_EVENT: () => (/* binding */ SESSION_STARTED_EVENT),
|
|
7035
7036
|
/* harmony export */ SESSION_STATE_PROP_NAME: () => (/* binding */ SESSION_STATE_PROP_NAME),
|
|
@@ -7054,14 +7055,16 @@ const SESSION_AUTO_CREATED = 'debug-session:auto-created';
|
|
|
7054
7055
|
const SESSION_ADD_EVENT = 'debug-session:rrweb:add-event';
|
|
7055
7056
|
// Backend-triggered flush of client-side crash buffer
|
|
7056
7057
|
const SESSION_SAVE_BUFFER_EVENT = 'debug-session:save-buffer';
|
|
7058
|
+
const SESSION_READY_EVENT = 'debug-session:ready';
|
|
7059
|
+
// Deprecated event name for backwards compatibility
|
|
7060
|
+
const SESSION_READY_EVENT_LEGACY = 'debug-session-ready';
|
|
7057
7061
|
const SOCKET_SET_USER_EVENT = 'socket:set-user';
|
|
7058
7062
|
const DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE = 100000;
|
|
7059
|
-
const SESSION_READY_EVENT = 'debug-session-ready';
|
|
7060
7063
|
const CONTINUOUS_DEBUGGING_TIMEOUT = 60000; // 1 minutes
|
|
7061
7064
|
const DEBUG_SESSION_MAX_DURATION_SECONDS = 10 * 60 + 30; // TODO: move to shared config otel core
|
|
7062
7065
|
const REMOTE_SESSION_RECORDING_START = 'remote-session-recording:start';
|
|
7063
7066
|
const REMOTE_SESSION_RECORDING_STOP = 'remote-session-recording:stop';
|
|
7064
|
-
const PACKAGE_VERSION_EXPORT = "2.0.
|
|
7067
|
+
const PACKAGE_VERSION_EXPORT = "2.0.88" || 0;
|
|
7065
7068
|
// Regex patterns for OpenTelemetry ignore URLs
|
|
7066
7069
|
const OTEL_IGNORE_URLS = [
|
|
7067
7070
|
// Traces endpoint
|
|
@@ -7199,6 +7202,7 @@ const BASE_CONFIG = {
|
|
|
7199
7202
|
/* harmony export */ SESSION_ID_PROP_NAME: () => (/* reexport safe */ _constants__WEBPACK_IMPORTED_MODULE_0__.SESSION_ID_PROP_NAME),
|
|
7200
7203
|
/* harmony export */ SESSION_PROP_NAME: () => (/* reexport safe */ _constants__WEBPACK_IMPORTED_MODULE_0__.SESSION_PROP_NAME),
|
|
7201
7204
|
/* harmony export */ SESSION_READY_EVENT: () => (/* reexport safe */ _constants__WEBPACK_IMPORTED_MODULE_0__.SESSION_READY_EVENT),
|
|
7205
|
+
/* harmony export */ SESSION_READY_EVENT_LEGACY: () => (/* reexport safe */ _constants__WEBPACK_IMPORTED_MODULE_0__.SESSION_READY_EVENT_LEGACY),
|
|
7202
7206
|
/* harmony export */ SESSION_SAVE_BUFFER_EVENT: () => (/* reexport safe */ _constants__WEBPACK_IMPORTED_MODULE_0__.SESSION_SAVE_BUFFER_EVENT),
|
|
7203
7207
|
/* harmony export */ SESSION_STARTED_EVENT: () => (/* reexport safe */ _constants__WEBPACK_IMPORTED_MODULE_0__.SESSION_STARTED_EVENT),
|
|
7204
7208
|
/* harmony export */ SESSION_STATE_PROP_NAME: () => (/* reexport safe */ _constants__WEBPACK_IMPORTED_MODULE_0__.SESSION_STATE_PROP_NAME),
|
|
@@ -10278,7 +10282,10 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
10278
10282
|
_services_messaging_service__WEBPACK_IMPORTED_MODULE_10__["default"].sendMessage('state-change', this._sessionState);
|
|
10279
10283
|
(0,_utils__WEBPACK_IMPORTED_MODULE_4__.setStoredItem)(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_STATE_PROP_NAME, state);
|
|
10280
10284
|
// Emit observable event to support React wrapper
|
|
10281
|
-
this.emit('state-change', [
|
|
10285
|
+
this.emit('state-change', [
|
|
10286
|
+
this._sessionState || _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.stopped,
|
|
10287
|
+
this.sessionType,
|
|
10288
|
+
]);
|
|
10282
10289
|
}
|
|
10283
10290
|
get session() {
|
|
10284
10291
|
return this._session;
|
|
@@ -10349,10 +10356,18 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
10349
10356
|
this._error = '';
|
|
10350
10357
|
// Safety: avoid accessing storage in SSR/non-browser environments
|
|
10351
10358
|
const isBrowser = typeof window !== 'undefined';
|
|
10352
|
-
const sessionLocal = isBrowser
|
|
10353
|
-
|
|
10354
|
-
|
|
10355
|
-
const
|
|
10359
|
+
const sessionLocal = isBrowser
|
|
10360
|
+
? (0,_utils__WEBPACK_IMPORTED_MODULE_4__.getStoredItem)(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_PROP_NAME, true)
|
|
10361
|
+
: null;
|
|
10362
|
+
const sessionIdLocal = isBrowser
|
|
10363
|
+
? (0,_utils__WEBPACK_IMPORTED_MODULE_4__.getStoredItem)(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_ID_PROP_NAME)
|
|
10364
|
+
: null;
|
|
10365
|
+
const sessionStateLocal = isBrowser
|
|
10366
|
+
? (0,_utils__WEBPACK_IMPORTED_MODULE_4__.getStoredItem)(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_STATE_PROP_NAME)
|
|
10367
|
+
: null;
|
|
10368
|
+
const sessionTypeLocal = isBrowser
|
|
10369
|
+
? (0,_utils__WEBPACK_IMPORTED_MODULE_4__.getStoredItem)(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_TYPE_PROP_NAME)
|
|
10370
|
+
: null;
|
|
10356
10371
|
if ((0,_utils__WEBPACK_IMPORTED_MODULE_4__.isSessionActive)(sessionLocal, sessionTypeLocal)) {
|
|
10357
10372
|
this.session = sessionLocal;
|
|
10358
10373
|
this.sessionId = sessionIdLocal;
|
|
@@ -10384,7 +10399,8 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
10384
10399
|
// GC: remove orphaned crash buffers from old tabs.
|
|
10385
10400
|
// Keep TTL large to avoid any accidental data loss.
|
|
10386
10401
|
void this._bufferDb.sweepStaleTabs(10 * 60 * 60 * 1000);
|
|
10387
|
-
(0,_patch__WEBPACK_IMPORTED_MODULE_7__.setMaxCapturingHttpPayloadSize)(this._configs.maxCapturingHttpPayloadSize ||
|
|
10402
|
+
(0,_patch__WEBPACK_IMPORTED_MODULE_7__.setMaxCapturingHttpPayloadSize)(this._configs.maxCapturingHttpPayloadSize ||
|
|
10403
|
+
_config__WEBPACK_IMPORTED_MODULE_6__.DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE);
|
|
10388
10404
|
(0,_patch__WEBPACK_IMPORTED_MODULE_7__.setShouldRecordHttpData)(this._configs.captureBody, this._configs.captureHeaders);
|
|
10389
10405
|
this._setupCrashBuffer();
|
|
10390
10406
|
this._tracer.init(this._configs);
|
|
@@ -10406,7 +10422,9 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
10406
10422
|
if (this._configs.apiKey) {
|
|
10407
10423
|
this._recorder.init(this._configs, this._socketService);
|
|
10408
10424
|
}
|
|
10409
|
-
if (this.sessionId &&
|
|
10425
|
+
if (this.sessionId &&
|
|
10426
|
+
(this.sessionState === _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.started ||
|
|
10427
|
+
this.sessionState === _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.paused)) {
|
|
10410
10428
|
this._start();
|
|
10411
10429
|
}
|
|
10412
10430
|
else {
|
|
@@ -10460,7 +10478,8 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
10460
10478
|
return;
|
|
10461
10479
|
let hasFocus = true;
|
|
10462
10480
|
try {
|
|
10463
|
-
hasFocus =
|
|
10481
|
+
hasFocus =
|
|
10482
|
+
typeof document.hasFocus === 'function' ? document.hasFocus() : true;
|
|
10464
10483
|
}
|
|
10465
10484
|
catch (_e) {
|
|
10466
10485
|
hasFocus = true;
|
|
@@ -10482,7 +10501,9 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
10482
10501
|
// stop, leaving the buffer with no FullSnapshot and silently breaking
|
|
10483
10502
|
// exception-triggered flushBuffer. `_recorder.restart(null, ...)` passes
|
|
10484
10503
|
// null explicitly, so it's safe regardless of `this.sessionId`.
|
|
10485
|
-
if (!this._crashBuffer ||
|
|
10504
|
+
if (!this._crashBuffer ||
|
|
10505
|
+
!((_b = (_a = this._configs) === null || _a === void 0 ? void 0 : _a.buffering) === null || _b === void 0 ? void 0 : _b.enabled) ||
|
|
10506
|
+
this.sessionState !== _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.stopped) {
|
|
10486
10507
|
return;
|
|
10487
10508
|
}
|
|
10488
10509
|
void this._recorder.restart(null, _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionType.MANUAL);
|
|
@@ -10533,7 +10554,8 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
10533
10554
|
start(type = _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionType.MANUAL, session) {
|
|
10534
10555
|
this._checkOperation('start');
|
|
10535
10556
|
// If continuous recording is disabled, force plain mode
|
|
10536
|
-
if (type === _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionType.CONTINUOUS &&
|
|
10557
|
+
if (type === _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionType.CONTINUOUS &&
|
|
10558
|
+
!this._configs.showContinuousRecording) {
|
|
10537
10559
|
type = _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionType.MANUAL;
|
|
10538
10560
|
}
|
|
10539
10561
|
this.sessionType = type;
|
|
@@ -10564,7 +10586,8 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
10564
10586
|
stoppedAt: this._recorder.stoppedAt,
|
|
10565
10587
|
};
|
|
10566
10588
|
const response = await this._apiService.stopSession(sid, request);
|
|
10567
|
-
_eventBus__WEBPACK_IMPORTED_MODULE_8__.recorderEventBus.emit(_config__WEBPACK_IMPORTED_MODULE_6__.
|
|
10589
|
+
_eventBus__WEBPACK_IMPORTED_MODULE_8__.recorderEventBus.emit(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_READY_EVENT_LEGACY, response._id);
|
|
10590
|
+
_eventBus__WEBPACK_IMPORTED_MODULE_8__.recorderEventBus.emit(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_READY_EVENT, response);
|
|
10568
10591
|
}
|
|
10569
10592
|
}
|
|
10570
10593
|
catch (error) {
|
|
@@ -10660,8 +10683,8 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
10660
10683
|
this.error = (e === null || e === void 0 ? void 0 : e.message) || 'Failed to capture exception';
|
|
10661
10684
|
}
|
|
10662
10685
|
}
|
|
10663
|
-
async _flushBuffer(
|
|
10664
|
-
if (!
|
|
10686
|
+
async _flushBuffer(session, force = false) {
|
|
10687
|
+
if (!session || !this._crashBuffer || this._isFlushingBuffer) {
|
|
10665
10688
|
return null;
|
|
10666
10689
|
}
|
|
10667
10690
|
this._isFlushingBuffer = true;
|
|
@@ -10672,8 +10695,10 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
10672
10695
|
}
|
|
10673
10696
|
await Promise.all([
|
|
10674
10697
|
this._tracer.exportTraces(spans.map((s) => s.span)),
|
|
10675
|
-
this._apiService.exportEvents(
|
|
10676
|
-
|
|
10698
|
+
this._apiService.exportEvents(session._id, {
|
|
10699
|
+
events: events.map((e) => e.event),
|
|
10700
|
+
}),
|
|
10701
|
+
this._apiService.updateSessionAttributes(session._id, {
|
|
10677
10702
|
startedAt: this._toCrashBufferSessionIso(startedAt),
|
|
10678
10703
|
stoppedAt: this._toCrashBufferSessionIso(stoppedAt),
|
|
10679
10704
|
sessionAttributes: this.sessionAttributes,
|
|
@@ -10688,7 +10713,8 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
10688
10713
|
finally {
|
|
10689
10714
|
await this._crashBuffer.clear();
|
|
10690
10715
|
this._isFlushingBuffer = false;
|
|
10691
|
-
_eventBus__WEBPACK_IMPORTED_MODULE_8__.recorderEventBus.emit(_config__WEBPACK_IMPORTED_MODULE_6__.
|
|
10716
|
+
_eventBus__WEBPACK_IMPORTED_MODULE_8__.recorderEventBus.emit(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_READY_EVENT_LEGACY, session._id);
|
|
10717
|
+
_eventBus__WEBPACK_IMPORTED_MODULE_8__.recorderEventBus.emit(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_READY_EVENT, session);
|
|
10692
10718
|
}
|
|
10693
10719
|
}
|
|
10694
10720
|
_toCrashBufferSessionIso(ts) {
|
|
@@ -10777,7 +10803,8 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
10777
10803
|
* Handle the safe stop event
|
|
10778
10804
|
*/
|
|
10779
10805
|
_handleStop(comment) {
|
|
10780
|
-
if (this.sessionState === _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.started ||
|
|
10806
|
+
if (this.sessionState === _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.started ||
|
|
10807
|
+
this.sessionState === _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.paused) {
|
|
10781
10808
|
this.stop(comment);
|
|
10782
10809
|
}
|
|
10783
10810
|
}
|
|
@@ -10801,7 +10828,8 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
10801
10828
|
* Handle the safe cancel event
|
|
10802
10829
|
*/
|
|
10803
10830
|
_handleCancel() {
|
|
10804
|
-
if (this.sessionState === _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.started ||
|
|
10831
|
+
if (this.sessionState === _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.started ||
|
|
10832
|
+
this.sessionState === _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.paused) {
|
|
10805
10833
|
this.cancel();
|
|
10806
10834
|
}
|
|
10807
10835
|
}
|
|
@@ -10809,7 +10837,8 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
10809
10837
|
* Handle the safe save event
|
|
10810
10838
|
*/
|
|
10811
10839
|
_handleSave() {
|
|
10812
|
-
if (this.sessionState === _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.started &&
|
|
10840
|
+
if (this.sessionState === _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.started &&
|
|
10841
|
+
this.continuousRecording) {
|
|
10813
10842
|
this.save();
|
|
10814
10843
|
}
|
|
10815
10844
|
}
|
|
@@ -10854,12 +10883,12 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
10854
10883
|
}
|
|
10855
10884
|
});
|
|
10856
10885
|
this._socketService.on(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_SAVE_BUFFER_EVENT, (payload) => {
|
|
10857
|
-
var _a, _b
|
|
10886
|
+
var _a, _b;
|
|
10858
10887
|
if (this.sessionState !== _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.stopped)
|
|
10859
10888
|
return;
|
|
10860
|
-
this._flushBuffer(
|
|
10861
|
-
if ((
|
|
10862
|
-
_eventBus__WEBPACK_IMPORTED_MODULE_8__.recorderEventBus.emit(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_AUTO_CREATED, (
|
|
10889
|
+
this._flushBuffer(payload === null || payload === void 0 ? void 0 : payload.debugSession, true);
|
|
10890
|
+
if ((_a = payload === null || payload === void 0 ? void 0 : payload.debugSession) === null || _a === void 0 ? void 0 : _a.url) {
|
|
10891
|
+
_eventBus__WEBPACK_IMPORTED_MODULE_8__.recorderEventBus.emit(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_AUTO_CREATED, (_b = payload === null || payload === void 0 ? void 0 : payload.debugSession) === null || _b === void 0 ? void 0 : _b.url);
|
|
10863
10892
|
}
|
|
10864
10893
|
});
|
|
10865
10894
|
}
|
|
@@ -10867,7 +10896,7 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
10867
10896
|
try {
|
|
10868
10897
|
const session = await this._apiService.createErrorSession({ span });
|
|
10869
10898
|
if (session === null || session === void 0 ? void 0 : session._id) {
|
|
10870
|
-
this._flushBuffer(session
|
|
10899
|
+
this._flushBuffer(session);
|
|
10871
10900
|
}
|
|
10872
10901
|
if (session === null || session === void 0 ? void 0 : session.url) {
|
|
10873
10902
|
_eventBus__WEBPACK_IMPORTED_MODULE_8__.recorderEventBus.emit(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_AUTO_CREATED, session.url);
|
|
@@ -10887,14 +10916,20 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
10887
10916
|
sessionAttributes: this.sessionAttributes,
|
|
10888
10917
|
resourceAttributes: (0,_utils__WEBPACK_IMPORTED_MODULE_4__.getNavigatorInfo)(),
|
|
10889
10918
|
name: this._getSessionName(),
|
|
10890
|
-
...(this._userAttributes
|
|
10919
|
+
...(this._userAttributes
|
|
10920
|
+
? { userAttributes: this._userAttributes }
|
|
10921
|
+
: {}),
|
|
10891
10922
|
};
|
|
10892
|
-
const request = !this.continuousRecording
|
|
10923
|
+
const request = !this.continuousRecording
|
|
10924
|
+
? payload
|
|
10925
|
+
: { debugSessionData: payload };
|
|
10893
10926
|
const session = this.continuousRecording
|
|
10894
10927
|
? await this._apiService.startContinuousDebugSession(request, signal)
|
|
10895
10928
|
: await this._apiService.startSession(request, signal);
|
|
10896
10929
|
if (session) {
|
|
10897
|
-
session.sessionType = this.continuousRecording
|
|
10930
|
+
session.sessionType = this.continuousRecording
|
|
10931
|
+
? _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionType.CONTINUOUS
|
|
10932
|
+
: _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionType.MANUAL;
|
|
10898
10933
|
this._setupSessionAndStart(session, false);
|
|
10899
10934
|
}
|
|
10900
10935
|
}
|
|
@@ -10917,7 +10952,10 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
10917
10952
|
this._tracer.start(this.sessionId, this.sessionType);
|
|
10918
10953
|
// Ensure we switch from buffer-only recording to session recording cleanly.
|
|
10919
10954
|
void this._recorder.restart(this.sessionId, this.sessionType);
|
|
10920
|
-
this._navigationRecorder.start({
|
|
10955
|
+
this._navigationRecorder.start({
|
|
10956
|
+
sessionId: this.sessionId,
|
|
10957
|
+
sessionType: this.sessionType,
|
|
10958
|
+
});
|
|
10921
10959
|
if (this.session) {
|
|
10922
10960
|
this._socketService.subscribeToSession(this.session);
|
|
10923
10961
|
this._sessionWidget.seconds = (0,_utils__WEBPACK_IMPORTED_MODULE_4__.getTimeDifferenceInSeconds)((_a = this.session) === null || _a === void 0 ? void 0 : _a.startedAt);
|
|
@@ -10945,8 +10983,12 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
10945
10983
|
// rrweb assigns new node IDs on each record() call, so the next buffer
|
|
10946
10984
|
// segment must not carry events from the previous generation. Await the
|
|
10947
10985
|
// clear so its IDB tx can't race past the fresh FullSnapshot.
|
|
10948
|
-
const cleared = this._crashBuffer
|
|
10949
|
-
|
|
10986
|
+
const cleared = this._crashBuffer
|
|
10987
|
+
? this._crashBuffer.clear()
|
|
10988
|
+
: Promise.resolve();
|
|
10989
|
+
void cleared
|
|
10990
|
+
.catch(() => undefined)
|
|
10991
|
+
.then(() => this._startBufferOnlyRecording());
|
|
10950
10992
|
}
|
|
10951
10993
|
/**
|
|
10952
10994
|
* Pause the session tracing and recording
|
|
@@ -10982,7 +11024,10 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
10982
11024
|
* @param sessionId - the session ID to set or clear
|
|
10983
11025
|
*/
|
|
10984
11026
|
_setSession(session) {
|
|
10985
|
-
this.session = {
|
|
11027
|
+
this.session = {
|
|
11028
|
+
...session,
|
|
11029
|
+
startedAt: session.startedAt || new Date().toISOString(),
|
|
11030
|
+
};
|
|
10986
11031
|
this.sessionId = (session === null || session === void 0 ? void 0 : session.shortId) || (session === null || session === void 0 ? void 0 : session._id);
|
|
10987
11032
|
}
|
|
10988
11033
|
_clearSession() {
|
|
@@ -11005,7 +11050,8 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
11005
11050
|
}
|
|
11006
11051
|
break;
|
|
11007
11052
|
case 'stop':
|
|
11008
|
-
if (this.sessionState !== _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.paused &&
|
|
11053
|
+
if (this.sessionState !== _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.paused &&
|
|
11054
|
+
this.sessionState !== _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.started) {
|
|
11009
11055
|
throw new Error('Cannot stop. Session is not currently started.');
|
|
11010
11056
|
}
|
|
11011
11057
|
break;
|
|
@@ -11083,7 +11129,10 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
11083
11129
|
*/
|
|
11084
11130
|
_getSessionName(date = new Date()) {
|
|
11085
11131
|
var _a, _b, _c;
|
|
11086
|
-
const userName = ((_a = this.sessionAttributes) === null || _a === void 0 ? void 0 : _a.userName) ||
|
|
11132
|
+
const userName = ((_a = this.sessionAttributes) === null || _a === void 0 ? void 0 : _a.userName) ||
|
|
11133
|
+
((_b = this._userAttributes) === null || _b === void 0 ? void 0 : _b.userName) ||
|
|
11134
|
+
((_c = this._userAttributes) === null || _c === void 0 ? void 0 : _c.name) ||
|
|
11135
|
+
'';
|
|
11087
11136
|
return userName
|
|
11088
11137
|
? `${userName}'s session on ${(0,_utils__WEBPACK_IMPORTED_MODULE_4__.getFormattedDate)(date, { month: 'short', day: 'numeric' })}`
|
|
11089
11138
|
: `Session on ${(0,_utils__WEBPACK_IMPORTED_MODULE_4__.getFormattedDate)(date)}`;
|
package/dist/index.umd.js
CHANGED
|
@@ -21463,6 +21463,7 @@ module.exports = {
|
|
|
21463
21463
|
/* harmony export */ SESSION_ID_PROP_NAME: () => (/* binding */ SESSION_ID_PROP_NAME),
|
|
21464
21464
|
/* harmony export */ SESSION_PROP_NAME: () => (/* binding */ SESSION_PROP_NAME),
|
|
21465
21465
|
/* harmony export */ SESSION_READY_EVENT: () => (/* binding */ SESSION_READY_EVENT),
|
|
21466
|
+
/* harmony export */ SESSION_READY_EVENT_LEGACY: () => (/* binding */ SESSION_READY_EVENT_LEGACY),
|
|
21466
21467
|
/* harmony export */ SESSION_SAVE_BUFFER_EVENT: () => (/* binding */ SESSION_SAVE_BUFFER_EVENT),
|
|
21467
21468
|
/* harmony export */ SESSION_STARTED_EVENT: () => (/* binding */ SESSION_STARTED_EVENT),
|
|
21468
21469
|
/* harmony export */ SESSION_STATE_PROP_NAME: () => (/* binding */ SESSION_STATE_PROP_NAME),
|
|
@@ -21487,14 +21488,16 @@ const SESSION_AUTO_CREATED = 'debug-session:auto-created';
|
|
|
21487
21488
|
const SESSION_ADD_EVENT = 'debug-session:rrweb:add-event';
|
|
21488
21489
|
// Backend-triggered flush of client-side crash buffer
|
|
21489
21490
|
const SESSION_SAVE_BUFFER_EVENT = 'debug-session:save-buffer';
|
|
21491
|
+
const SESSION_READY_EVENT = 'debug-session:ready';
|
|
21492
|
+
// Deprecated event name for backwards compatibility
|
|
21493
|
+
const SESSION_READY_EVENT_LEGACY = 'debug-session-ready';
|
|
21490
21494
|
const SOCKET_SET_USER_EVENT = 'socket:set-user';
|
|
21491
21495
|
const DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE = 100000;
|
|
21492
|
-
const SESSION_READY_EVENT = 'debug-session-ready';
|
|
21493
21496
|
const CONTINUOUS_DEBUGGING_TIMEOUT = 60000; // 1 minutes
|
|
21494
21497
|
const DEBUG_SESSION_MAX_DURATION_SECONDS = 10 * 60 + 30; // TODO: move to shared config otel core
|
|
21495
21498
|
const REMOTE_SESSION_RECORDING_START = 'remote-session-recording:start';
|
|
21496
21499
|
const REMOTE_SESSION_RECORDING_STOP = 'remote-session-recording:stop';
|
|
21497
|
-
const PACKAGE_VERSION_EXPORT = "2.0.
|
|
21500
|
+
const PACKAGE_VERSION_EXPORT = "2.0.88" || 0;
|
|
21498
21501
|
// Regex patterns for OpenTelemetry ignore URLs
|
|
21499
21502
|
const OTEL_IGNORE_URLS = [
|
|
21500
21503
|
// Traces endpoint
|
|
@@ -21634,6 +21637,7 @@ const BASE_CONFIG = {
|
|
|
21634
21637
|
/* harmony export */ SESSION_ID_PROP_NAME: () => (/* reexport safe */ _constants__WEBPACK_IMPORTED_MODULE_0__.SESSION_ID_PROP_NAME),
|
|
21635
21638
|
/* harmony export */ SESSION_PROP_NAME: () => (/* reexport safe */ _constants__WEBPACK_IMPORTED_MODULE_0__.SESSION_PROP_NAME),
|
|
21636
21639
|
/* harmony export */ SESSION_READY_EVENT: () => (/* reexport safe */ _constants__WEBPACK_IMPORTED_MODULE_0__.SESSION_READY_EVENT),
|
|
21640
|
+
/* harmony export */ SESSION_READY_EVENT_LEGACY: () => (/* reexport safe */ _constants__WEBPACK_IMPORTED_MODULE_0__.SESSION_READY_EVENT_LEGACY),
|
|
21637
21641
|
/* harmony export */ SESSION_SAVE_BUFFER_EVENT: () => (/* reexport safe */ _constants__WEBPACK_IMPORTED_MODULE_0__.SESSION_SAVE_BUFFER_EVENT),
|
|
21638
21642
|
/* harmony export */ SESSION_STARTED_EVENT: () => (/* reexport safe */ _constants__WEBPACK_IMPORTED_MODULE_0__.SESSION_STARTED_EVENT),
|
|
21639
21643
|
/* harmony export */ SESSION_STATE_PROP_NAME: () => (/* reexport safe */ _constants__WEBPACK_IMPORTED_MODULE_0__.SESSION_STATE_PROP_NAME),
|
|
@@ -24739,7 +24743,10 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
24739
24743
|
_services_messaging_service__WEBPACK_IMPORTED_MODULE_10__["default"].sendMessage('state-change', this._sessionState);
|
|
24740
24744
|
(0,_utils__WEBPACK_IMPORTED_MODULE_4__.setStoredItem)(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_STATE_PROP_NAME, state);
|
|
24741
24745
|
// Emit observable event to support React wrapper
|
|
24742
|
-
this.emit('state-change', [
|
|
24746
|
+
this.emit('state-change', [
|
|
24747
|
+
this._sessionState || _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.stopped,
|
|
24748
|
+
this.sessionType,
|
|
24749
|
+
]);
|
|
24743
24750
|
}
|
|
24744
24751
|
get session() {
|
|
24745
24752
|
return this._session;
|
|
@@ -24810,10 +24817,18 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
24810
24817
|
this._error = '';
|
|
24811
24818
|
// Safety: avoid accessing storage in SSR/non-browser environments
|
|
24812
24819
|
const isBrowser = typeof window !== 'undefined';
|
|
24813
|
-
const sessionLocal = isBrowser
|
|
24814
|
-
|
|
24815
|
-
|
|
24816
|
-
const
|
|
24820
|
+
const sessionLocal = isBrowser
|
|
24821
|
+
? (0,_utils__WEBPACK_IMPORTED_MODULE_4__.getStoredItem)(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_PROP_NAME, true)
|
|
24822
|
+
: null;
|
|
24823
|
+
const sessionIdLocal = isBrowser
|
|
24824
|
+
? (0,_utils__WEBPACK_IMPORTED_MODULE_4__.getStoredItem)(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_ID_PROP_NAME)
|
|
24825
|
+
: null;
|
|
24826
|
+
const sessionStateLocal = isBrowser
|
|
24827
|
+
? (0,_utils__WEBPACK_IMPORTED_MODULE_4__.getStoredItem)(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_STATE_PROP_NAME)
|
|
24828
|
+
: null;
|
|
24829
|
+
const sessionTypeLocal = isBrowser
|
|
24830
|
+
? (0,_utils__WEBPACK_IMPORTED_MODULE_4__.getStoredItem)(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_TYPE_PROP_NAME)
|
|
24831
|
+
: null;
|
|
24817
24832
|
if ((0,_utils__WEBPACK_IMPORTED_MODULE_4__.isSessionActive)(sessionLocal, sessionTypeLocal)) {
|
|
24818
24833
|
this.session = sessionLocal;
|
|
24819
24834
|
this.sessionId = sessionIdLocal;
|
|
@@ -24845,7 +24860,8 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
24845
24860
|
// GC: remove orphaned crash buffers from old tabs.
|
|
24846
24861
|
// Keep TTL large to avoid any accidental data loss.
|
|
24847
24862
|
void this._bufferDb.sweepStaleTabs(10 * 60 * 60 * 1000);
|
|
24848
|
-
(0,_patch__WEBPACK_IMPORTED_MODULE_7__.setMaxCapturingHttpPayloadSize)(this._configs.maxCapturingHttpPayloadSize ||
|
|
24863
|
+
(0,_patch__WEBPACK_IMPORTED_MODULE_7__.setMaxCapturingHttpPayloadSize)(this._configs.maxCapturingHttpPayloadSize ||
|
|
24864
|
+
_config__WEBPACK_IMPORTED_MODULE_6__.DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE);
|
|
24849
24865
|
(0,_patch__WEBPACK_IMPORTED_MODULE_7__.setShouldRecordHttpData)(this._configs.captureBody, this._configs.captureHeaders);
|
|
24850
24866
|
this._setupCrashBuffer();
|
|
24851
24867
|
this._tracer.init(this._configs);
|
|
@@ -24867,7 +24883,9 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
24867
24883
|
if (this._configs.apiKey) {
|
|
24868
24884
|
this._recorder.init(this._configs, this._socketService);
|
|
24869
24885
|
}
|
|
24870
|
-
if (this.sessionId &&
|
|
24886
|
+
if (this.sessionId &&
|
|
24887
|
+
(this.sessionState === _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.started ||
|
|
24888
|
+
this.sessionState === _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.paused)) {
|
|
24871
24889
|
this._start();
|
|
24872
24890
|
}
|
|
24873
24891
|
else {
|
|
@@ -24921,7 +24939,8 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
24921
24939
|
return;
|
|
24922
24940
|
let hasFocus = true;
|
|
24923
24941
|
try {
|
|
24924
|
-
hasFocus =
|
|
24942
|
+
hasFocus =
|
|
24943
|
+
typeof document.hasFocus === 'function' ? document.hasFocus() : true;
|
|
24925
24944
|
}
|
|
24926
24945
|
catch (_e) {
|
|
24927
24946
|
hasFocus = true;
|
|
@@ -24943,7 +24962,9 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
24943
24962
|
// stop, leaving the buffer with no FullSnapshot and silently breaking
|
|
24944
24963
|
// exception-triggered flushBuffer. `_recorder.restart(null, ...)` passes
|
|
24945
24964
|
// null explicitly, so it's safe regardless of `this.sessionId`.
|
|
24946
|
-
if (!this._crashBuffer ||
|
|
24965
|
+
if (!this._crashBuffer ||
|
|
24966
|
+
!((_b = (_a = this._configs) === null || _a === void 0 ? void 0 : _a.buffering) === null || _b === void 0 ? void 0 : _b.enabled) ||
|
|
24967
|
+
this.sessionState !== _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.stopped) {
|
|
24947
24968
|
return;
|
|
24948
24969
|
}
|
|
24949
24970
|
void this._recorder.restart(null, _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionType.MANUAL);
|
|
@@ -24994,7 +25015,8 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
24994
25015
|
start(type = _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionType.MANUAL, session) {
|
|
24995
25016
|
this._checkOperation('start');
|
|
24996
25017
|
// If continuous recording is disabled, force plain mode
|
|
24997
|
-
if (type === _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionType.CONTINUOUS &&
|
|
25018
|
+
if (type === _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionType.CONTINUOUS &&
|
|
25019
|
+
!this._configs.showContinuousRecording) {
|
|
24998
25020
|
type = _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionType.MANUAL;
|
|
24999
25021
|
}
|
|
25000
25022
|
this.sessionType = type;
|
|
@@ -25025,7 +25047,8 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
25025
25047
|
stoppedAt: this._recorder.stoppedAt,
|
|
25026
25048
|
};
|
|
25027
25049
|
const response = await this._apiService.stopSession(sid, request);
|
|
25028
|
-
_eventBus__WEBPACK_IMPORTED_MODULE_8__.recorderEventBus.emit(_config__WEBPACK_IMPORTED_MODULE_6__.
|
|
25050
|
+
_eventBus__WEBPACK_IMPORTED_MODULE_8__.recorderEventBus.emit(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_READY_EVENT_LEGACY, response._id);
|
|
25051
|
+
_eventBus__WEBPACK_IMPORTED_MODULE_8__.recorderEventBus.emit(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_READY_EVENT, response);
|
|
25029
25052
|
}
|
|
25030
25053
|
}
|
|
25031
25054
|
catch (error) {
|
|
@@ -25121,8 +25144,8 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
25121
25144
|
this.error = (e === null || e === void 0 ? void 0 : e.message) || 'Failed to capture exception';
|
|
25122
25145
|
}
|
|
25123
25146
|
}
|
|
25124
|
-
async _flushBuffer(
|
|
25125
|
-
if (!
|
|
25147
|
+
async _flushBuffer(session, force = false) {
|
|
25148
|
+
if (!session || !this._crashBuffer || this._isFlushingBuffer) {
|
|
25126
25149
|
return null;
|
|
25127
25150
|
}
|
|
25128
25151
|
this._isFlushingBuffer = true;
|
|
@@ -25133,8 +25156,10 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
25133
25156
|
}
|
|
25134
25157
|
await Promise.all([
|
|
25135
25158
|
this._tracer.exportTraces(spans.map((s) => s.span)),
|
|
25136
|
-
this._apiService.exportEvents(
|
|
25137
|
-
|
|
25159
|
+
this._apiService.exportEvents(session._id, {
|
|
25160
|
+
events: events.map((e) => e.event),
|
|
25161
|
+
}),
|
|
25162
|
+
this._apiService.updateSessionAttributes(session._id, {
|
|
25138
25163
|
startedAt: this._toCrashBufferSessionIso(startedAt),
|
|
25139
25164
|
stoppedAt: this._toCrashBufferSessionIso(stoppedAt),
|
|
25140
25165
|
sessionAttributes: this.sessionAttributes,
|
|
@@ -25149,7 +25174,8 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
25149
25174
|
finally {
|
|
25150
25175
|
await this._crashBuffer.clear();
|
|
25151
25176
|
this._isFlushingBuffer = false;
|
|
25152
|
-
_eventBus__WEBPACK_IMPORTED_MODULE_8__.recorderEventBus.emit(_config__WEBPACK_IMPORTED_MODULE_6__.
|
|
25177
|
+
_eventBus__WEBPACK_IMPORTED_MODULE_8__.recorderEventBus.emit(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_READY_EVENT_LEGACY, session._id);
|
|
25178
|
+
_eventBus__WEBPACK_IMPORTED_MODULE_8__.recorderEventBus.emit(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_READY_EVENT, session);
|
|
25153
25179
|
}
|
|
25154
25180
|
}
|
|
25155
25181
|
_toCrashBufferSessionIso(ts) {
|
|
@@ -25238,7 +25264,8 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
25238
25264
|
* Handle the safe stop event
|
|
25239
25265
|
*/
|
|
25240
25266
|
_handleStop(comment) {
|
|
25241
|
-
if (this.sessionState === _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.started ||
|
|
25267
|
+
if (this.sessionState === _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.started ||
|
|
25268
|
+
this.sessionState === _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.paused) {
|
|
25242
25269
|
this.stop(comment);
|
|
25243
25270
|
}
|
|
25244
25271
|
}
|
|
@@ -25262,7 +25289,8 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
25262
25289
|
* Handle the safe cancel event
|
|
25263
25290
|
*/
|
|
25264
25291
|
_handleCancel() {
|
|
25265
|
-
if (this.sessionState === _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.started ||
|
|
25292
|
+
if (this.sessionState === _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.started ||
|
|
25293
|
+
this.sessionState === _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.paused) {
|
|
25266
25294
|
this.cancel();
|
|
25267
25295
|
}
|
|
25268
25296
|
}
|
|
@@ -25270,7 +25298,8 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
25270
25298
|
* Handle the safe save event
|
|
25271
25299
|
*/
|
|
25272
25300
|
_handleSave() {
|
|
25273
|
-
if (this.sessionState === _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.started &&
|
|
25301
|
+
if (this.sessionState === _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.started &&
|
|
25302
|
+
this.continuousRecording) {
|
|
25274
25303
|
this.save();
|
|
25275
25304
|
}
|
|
25276
25305
|
}
|
|
@@ -25315,12 +25344,12 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
25315
25344
|
}
|
|
25316
25345
|
});
|
|
25317
25346
|
this._socketService.on(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_SAVE_BUFFER_EVENT, (payload) => {
|
|
25318
|
-
var _a, _b
|
|
25347
|
+
var _a, _b;
|
|
25319
25348
|
if (this.sessionState !== _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.stopped)
|
|
25320
25349
|
return;
|
|
25321
|
-
this._flushBuffer(
|
|
25322
|
-
if ((
|
|
25323
|
-
_eventBus__WEBPACK_IMPORTED_MODULE_8__.recorderEventBus.emit(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_AUTO_CREATED, (
|
|
25350
|
+
this._flushBuffer(payload === null || payload === void 0 ? void 0 : payload.debugSession, true);
|
|
25351
|
+
if ((_a = payload === null || payload === void 0 ? void 0 : payload.debugSession) === null || _a === void 0 ? void 0 : _a.url) {
|
|
25352
|
+
_eventBus__WEBPACK_IMPORTED_MODULE_8__.recorderEventBus.emit(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_AUTO_CREATED, (_b = payload === null || payload === void 0 ? void 0 : payload.debugSession) === null || _b === void 0 ? void 0 : _b.url);
|
|
25324
25353
|
}
|
|
25325
25354
|
});
|
|
25326
25355
|
}
|
|
@@ -25328,7 +25357,7 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
25328
25357
|
try {
|
|
25329
25358
|
const session = await this._apiService.createErrorSession({ span });
|
|
25330
25359
|
if (session === null || session === void 0 ? void 0 : session._id) {
|
|
25331
|
-
this._flushBuffer(session
|
|
25360
|
+
this._flushBuffer(session);
|
|
25332
25361
|
}
|
|
25333
25362
|
if (session === null || session === void 0 ? void 0 : session.url) {
|
|
25334
25363
|
_eventBus__WEBPACK_IMPORTED_MODULE_8__.recorderEventBus.emit(_config__WEBPACK_IMPORTED_MODULE_6__.SESSION_AUTO_CREATED, session.url);
|
|
@@ -25348,14 +25377,20 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
25348
25377
|
sessionAttributes: this.sessionAttributes,
|
|
25349
25378
|
resourceAttributes: (0,_utils__WEBPACK_IMPORTED_MODULE_4__.getNavigatorInfo)(),
|
|
25350
25379
|
name: this._getSessionName(),
|
|
25351
|
-
...(this._userAttributes
|
|
25380
|
+
...(this._userAttributes
|
|
25381
|
+
? { userAttributes: this._userAttributes }
|
|
25382
|
+
: {}),
|
|
25352
25383
|
};
|
|
25353
|
-
const request = !this.continuousRecording
|
|
25384
|
+
const request = !this.continuousRecording
|
|
25385
|
+
? payload
|
|
25386
|
+
: { debugSessionData: payload };
|
|
25354
25387
|
const session = this.continuousRecording
|
|
25355
25388
|
? await this._apiService.startContinuousDebugSession(request, signal)
|
|
25356
25389
|
: await this._apiService.startSession(request, signal);
|
|
25357
25390
|
if (session) {
|
|
25358
|
-
session.sessionType = this.continuousRecording
|
|
25391
|
+
session.sessionType = this.continuousRecording
|
|
25392
|
+
? _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionType.CONTINUOUS
|
|
25393
|
+
: _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionType.MANUAL;
|
|
25359
25394
|
this._setupSessionAndStart(session, false);
|
|
25360
25395
|
}
|
|
25361
25396
|
}
|
|
@@ -25378,7 +25413,10 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
25378
25413
|
this._tracer.start(this.sessionId, this.sessionType);
|
|
25379
25414
|
// Ensure we switch from buffer-only recording to session recording cleanly.
|
|
25380
25415
|
void this._recorder.restart(this.sessionId, this.sessionType);
|
|
25381
|
-
this._navigationRecorder.start({
|
|
25416
|
+
this._navigationRecorder.start({
|
|
25417
|
+
sessionId: this.sessionId,
|
|
25418
|
+
sessionType: this.sessionType,
|
|
25419
|
+
});
|
|
25382
25420
|
if (this.session) {
|
|
25383
25421
|
this._socketService.subscribeToSession(this.session);
|
|
25384
25422
|
this._sessionWidget.seconds = (0,_utils__WEBPACK_IMPORTED_MODULE_4__.getTimeDifferenceInSeconds)((_a = this.session) === null || _a === void 0 ? void 0 : _a.startedAt);
|
|
@@ -25406,8 +25444,12 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
25406
25444
|
// rrweb assigns new node IDs on each record() call, so the next buffer
|
|
25407
25445
|
// segment must not carry events from the previous generation. Await the
|
|
25408
25446
|
// clear so its IDB tx can't race past the fresh FullSnapshot.
|
|
25409
|
-
const cleared = this._crashBuffer
|
|
25410
|
-
|
|
25447
|
+
const cleared = this._crashBuffer
|
|
25448
|
+
? this._crashBuffer.clear()
|
|
25449
|
+
: Promise.resolve();
|
|
25450
|
+
void cleared
|
|
25451
|
+
.catch(() => undefined)
|
|
25452
|
+
.then(() => this._startBufferOnlyRecording());
|
|
25411
25453
|
}
|
|
25412
25454
|
/**
|
|
25413
25455
|
* Pause the session tracing and recording
|
|
@@ -25443,7 +25485,10 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
25443
25485
|
* @param sessionId - the session ID to set or clear
|
|
25444
25486
|
*/
|
|
25445
25487
|
_setSession(session) {
|
|
25446
|
-
this.session = {
|
|
25488
|
+
this.session = {
|
|
25489
|
+
...session,
|
|
25490
|
+
startedAt: session.startedAt || new Date().toISOString(),
|
|
25491
|
+
};
|
|
25447
25492
|
this.sessionId = (session === null || session === void 0 ? void 0 : session.shortId) || (session === null || session === void 0 ? void 0 : session._id);
|
|
25448
25493
|
}
|
|
25449
25494
|
_clearSession() {
|
|
@@ -25466,7 +25511,8 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
25466
25511
|
}
|
|
25467
25512
|
break;
|
|
25468
25513
|
case 'stop':
|
|
25469
|
-
if (this.sessionState !== _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.paused &&
|
|
25514
|
+
if (this.sessionState !== _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.paused &&
|
|
25515
|
+
this.sessionState !== _types__WEBPACK_IMPORTED_MODULE_5__.SessionState.started) {
|
|
25470
25516
|
throw new Error('Cannot stop. Session is not currently started.');
|
|
25471
25517
|
}
|
|
25472
25518
|
break;
|
|
@@ -25544,7 +25590,10 @@ class SessionRecorder extends _observable__WEBPACK_IMPORTED_MODULE_0__.Observabl
|
|
|
25544
25590
|
*/
|
|
25545
25591
|
_getSessionName(date = new Date()) {
|
|
25546
25592
|
var _a, _b, _c;
|
|
25547
|
-
const userName = ((_a = this.sessionAttributes) === null || _a === void 0 ? void 0 : _a.userName) ||
|
|
25593
|
+
const userName = ((_a = this.sessionAttributes) === null || _a === void 0 ? void 0 : _a.userName) ||
|
|
25594
|
+
((_b = this._userAttributes) === null || _b === void 0 ? void 0 : _b.userName) ||
|
|
25595
|
+
((_c = this._userAttributes) === null || _c === void 0 ? void 0 : _c.name) ||
|
|
25596
|
+
'';
|
|
25548
25597
|
return userName
|
|
25549
25598
|
? `${userName}'s session on ${(0,_utils__WEBPACK_IMPORTED_MODULE_4__.getFormattedDate)(date, { month: 'short', day: 'numeric' })}`
|
|
25550
25599
|
: `Session on ${(0,_utils__WEBPACK_IMPORTED_MODULE_4__.getFormattedDate)(date)}`;
|
package/dist/session-recorder.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { Observable } from './observable';
|
|
2
|
-
import { SessionType } from '@multiplayer-app/session-recorder-common';
|
|
2
|
+
import { SessionType, } from '@multiplayer-app/session-recorder-common';
|
|
3
3
|
import { TracerBrowserSDK } from './otel';
|
|
4
4
|
import { RecorderBrowserSDK } from './rrweb';
|
|
5
5
|
import { getStoredItem, setStoredItem, getNavigatorInfo, getFormattedDate, getTimeDifferenceInSeconds, isSessionActive, getOrCreateTabId, } from './utils';
|
|
6
|
-
import { SessionState } from './types';
|
|
7
|
-
import { BASE_CONFIG, SESSION_PROP_NAME, SESSION_ID_PROP_NAME, SESSION_TYPE_PROP_NAME, SESSION_STATE_PROP_NAME, DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE, getSessionRecorderConfig, SESSION_AUTO_CREATED, SESSION_STOPPED_EVENT, REMOTE_SESSION_RECORDING_START, REMOTE_SESSION_RECORDING_STOP, SESSION_SAVE_BUFFER_EVENT, SESSION_READY_EVENT, } from './config';
|
|
8
|
-
import { setShouldRecordHttpData, setMaxCapturingHttpPayloadSize } from './patch';
|
|
6
|
+
import { SessionState, } from './types';
|
|
7
|
+
import { BASE_CONFIG, SESSION_PROP_NAME, SESSION_ID_PROP_NAME, SESSION_TYPE_PROP_NAME, SESSION_STATE_PROP_NAME, DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE, getSessionRecorderConfig, SESSION_AUTO_CREATED, SESSION_STOPPED_EVENT, REMOTE_SESSION_RECORDING_START, REMOTE_SESSION_RECORDING_STOP, SESSION_SAVE_BUFFER_EVENT, SESSION_READY_EVENT_LEGACY, SESSION_READY_EVENT, } from './config';
|
|
8
|
+
import { setShouldRecordHttpData, setMaxCapturingHttpPayloadSize, } from './patch';
|
|
9
9
|
import { recorderEventBus } from './eventBus';
|
|
10
10
|
import { SessionWidget } from './sessionWidget';
|
|
11
11
|
import messagingService from './services/messaging.service';
|
|
12
|
-
import { ApiService } from './services/api.service';
|
|
12
|
+
import { ApiService, } from './services/api.service';
|
|
13
13
|
import { SocketService } from './services/socket.service';
|
|
14
14
|
import { IndexedDBService } from './services/indexedDb.service';
|
|
15
15
|
import { CrashBufferService } from './services/crashBuffer.service';
|
|
@@ -51,7 +51,10 @@ export class SessionRecorder extends Observable {
|
|
|
51
51
|
messagingService.sendMessage('state-change', this._sessionState);
|
|
52
52
|
setStoredItem(SESSION_STATE_PROP_NAME, state);
|
|
53
53
|
// Emit observable event to support React wrapper
|
|
54
|
-
this.emit('state-change', [
|
|
54
|
+
this.emit('state-change', [
|
|
55
|
+
this._sessionState || SessionState.stopped,
|
|
56
|
+
this.sessionType,
|
|
57
|
+
]);
|
|
55
58
|
}
|
|
56
59
|
get session() {
|
|
57
60
|
return this._session;
|
|
@@ -122,10 +125,18 @@ export class SessionRecorder extends Observable {
|
|
|
122
125
|
this._error = '';
|
|
123
126
|
// Safety: avoid accessing storage in SSR/non-browser environments
|
|
124
127
|
const isBrowser = typeof window !== 'undefined';
|
|
125
|
-
const sessionLocal = isBrowser
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const
|
|
128
|
+
const sessionLocal = isBrowser
|
|
129
|
+
? getStoredItem(SESSION_PROP_NAME, true)
|
|
130
|
+
: null;
|
|
131
|
+
const sessionIdLocal = isBrowser
|
|
132
|
+
? getStoredItem(SESSION_ID_PROP_NAME)
|
|
133
|
+
: null;
|
|
134
|
+
const sessionStateLocal = isBrowser
|
|
135
|
+
? getStoredItem(SESSION_STATE_PROP_NAME)
|
|
136
|
+
: null;
|
|
137
|
+
const sessionTypeLocal = isBrowser
|
|
138
|
+
? getStoredItem(SESSION_TYPE_PROP_NAME)
|
|
139
|
+
: null;
|
|
129
140
|
if (isSessionActive(sessionLocal, sessionTypeLocal)) {
|
|
130
141
|
this.session = sessionLocal;
|
|
131
142
|
this.sessionId = sessionIdLocal;
|
|
@@ -157,7 +168,8 @@ export class SessionRecorder extends Observable {
|
|
|
157
168
|
// GC: remove orphaned crash buffers from old tabs.
|
|
158
169
|
// Keep TTL large to avoid any accidental data loss.
|
|
159
170
|
void this._bufferDb.sweepStaleTabs(10 * 60 * 60 * 1000);
|
|
160
|
-
setMaxCapturingHttpPayloadSize(this._configs.maxCapturingHttpPayloadSize ||
|
|
171
|
+
setMaxCapturingHttpPayloadSize(this._configs.maxCapturingHttpPayloadSize ||
|
|
172
|
+
DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE);
|
|
161
173
|
setShouldRecordHttpData(this._configs.captureBody, this._configs.captureHeaders);
|
|
162
174
|
this._setupCrashBuffer();
|
|
163
175
|
this._tracer.init(this._configs);
|
|
@@ -179,7 +191,9 @@ export class SessionRecorder extends Observable {
|
|
|
179
191
|
if (this._configs.apiKey) {
|
|
180
192
|
this._recorder.init(this._configs, this._socketService);
|
|
181
193
|
}
|
|
182
|
-
if (this.sessionId &&
|
|
194
|
+
if (this.sessionId &&
|
|
195
|
+
(this.sessionState === SessionState.started ||
|
|
196
|
+
this.sessionState === SessionState.paused)) {
|
|
183
197
|
this._start();
|
|
184
198
|
}
|
|
185
199
|
else {
|
|
@@ -233,7 +247,8 @@ export class SessionRecorder extends Observable {
|
|
|
233
247
|
return;
|
|
234
248
|
let hasFocus = true;
|
|
235
249
|
try {
|
|
236
|
-
hasFocus =
|
|
250
|
+
hasFocus =
|
|
251
|
+
typeof document.hasFocus === 'function' ? document.hasFocus() : true;
|
|
237
252
|
}
|
|
238
253
|
catch (_e) {
|
|
239
254
|
hasFocus = true;
|
|
@@ -255,7 +270,9 @@ export class SessionRecorder extends Observable {
|
|
|
255
270
|
// stop, leaving the buffer with no FullSnapshot and silently breaking
|
|
256
271
|
// exception-triggered flushBuffer. `_recorder.restart(null, ...)` passes
|
|
257
272
|
// null explicitly, so it's safe regardless of `this.sessionId`.
|
|
258
|
-
if (!this._crashBuffer ||
|
|
273
|
+
if (!this._crashBuffer ||
|
|
274
|
+
!((_b = (_a = this._configs) === null || _a === void 0 ? void 0 : _a.buffering) === null || _b === void 0 ? void 0 : _b.enabled) ||
|
|
275
|
+
this.sessionState !== SessionState.stopped) {
|
|
259
276
|
return;
|
|
260
277
|
}
|
|
261
278
|
void this._recorder.restart(null, SessionType.MANUAL);
|
|
@@ -306,7 +323,8 @@ export class SessionRecorder extends Observable {
|
|
|
306
323
|
start(type = SessionType.MANUAL, session) {
|
|
307
324
|
this._checkOperation('start');
|
|
308
325
|
// If continuous recording is disabled, force plain mode
|
|
309
|
-
if (type === SessionType.CONTINUOUS &&
|
|
326
|
+
if (type === SessionType.CONTINUOUS &&
|
|
327
|
+
!this._configs.showContinuousRecording) {
|
|
310
328
|
type = SessionType.MANUAL;
|
|
311
329
|
}
|
|
312
330
|
this.sessionType = type;
|
|
@@ -337,7 +355,8 @@ export class SessionRecorder extends Observable {
|
|
|
337
355
|
stoppedAt: this._recorder.stoppedAt,
|
|
338
356
|
};
|
|
339
357
|
const response = await this._apiService.stopSession(sid, request);
|
|
340
|
-
recorderEventBus.emit(
|
|
358
|
+
recorderEventBus.emit(SESSION_READY_EVENT_LEGACY, response._id);
|
|
359
|
+
recorderEventBus.emit(SESSION_READY_EVENT, response);
|
|
341
360
|
}
|
|
342
361
|
}
|
|
343
362
|
catch (error) {
|
|
@@ -433,8 +452,8 @@ export class SessionRecorder extends Observable {
|
|
|
433
452
|
this.error = (e === null || e === void 0 ? void 0 : e.message) || 'Failed to capture exception';
|
|
434
453
|
}
|
|
435
454
|
}
|
|
436
|
-
async _flushBuffer(
|
|
437
|
-
if (!
|
|
455
|
+
async _flushBuffer(session, force = false) {
|
|
456
|
+
if (!session || !this._crashBuffer || this._isFlushingBuffer) {
|
|
438
457
|
return null;
|
|
439
458
|
}
|
|
440
459
|
this._isFlushingBuffer = true;
|
|
@@ -445,8 +464,10 @@ export class SessionRecorder extends Observable {
|
|
|
445
464
|
}
|
|
446
465
|
await Promise.all([
|
|
447
466
|
this._tracer.exportTraces(spans.map((s) => s.span)),
|
|
448
|
-
this._apiService.exportEvents(
|
|
449
|
-
|
|
467
|
+
this._apiService.exportEvents(session._id, {
|
|
468
|
+
events: events.map((e) => e.event),
|
|
469
|
+
}),
|
|
470
|
+
this._apiService.updateSessionAttributes(session._id, {
|
|
450
471
|
startedAt: this._toCrashBufferSessionIso(startedAt),
|
|
451
472
|
stoppedAt: this._toCrashBufferSessionIso(stoppedAt),
|
|
452
473
|
sessionAttributes: this.sessionAttributes,
|
|
@@ -461,7 +482,8 @@ export class SessionRecorder extends Observable {
|
|
|
461
482
|
finally {
|
|
462
483
|
await this._crashBuffer.clear();
|
|
463
484
|
this._isFlushingBuffer = false;
|
|
464
|
-
recorderEventBus.emit(
|
|
485
|
+
recorderEventBus.emit(SESSION_READY_EVENT_LEGACY, session._id);
|
|
486
|
+
recorderEventBus.emit(SESSION_READY_EVENT, session);
|
|
465
487
|
}
|
|
466
488
|
}
|
|
467
489
|
_toCrashBufferSessionIso(ts) {
|
|
@@ -550,7 +572,8 @@ export class SessionRecorder extends Observable {
|
|
|
550
572
|
* Handle the safe stop event
|
|
551
573
|
*/
|
|
552
574
|
_handleStop(comment) {
|
|
553
|
-
if (this.sessionState === SessionState.started ||
|
|
575
|
+
if (this.sessionState === SessionState.started ||
|
|
576
|
+
this.sessionState === SessionState.paused) {
|
|
554
577
|
this.stop(comment);
|
|
555
578
|
}
|
|
556
579
|
}
|
|
@@ -574,7 +597,8 @@ export class SessionRecorder extends Observable {
|
|
|
574
597
|
* Handle the safe cancel event
|
|
575
598
|
*/
|
|
576
599
|
_handleCancel() {
|
|
577
|
-
if (this.sessionState === SessionState.started ||
|
|
600
|
+
if (this.sessionState === SessionState.started ||
|
|
601
|
+
this.sessionState === SessionState.paused) {
|
|
578
602
|
this.cancel();
|
|
579
603
|
}
|
|
580
604
|
}
|
|
@@ -582,7 +606,8 @@ export class SessionRecorder extends Observable {
|
|
|
582
606
|
* Handle the safe save event
|
|
583
607
|
*/
|
|
584
608
|
_handleSave() {
|
|
585
|
-
if (this.sessionState === SessionState.started &&
|
|
609
|
+
if (this.sessionState === SessionState.started &&
|
|
610
|
+
this.continuousRecording) {
|
|
586
611
|
this.save();
|
|
587
612
|
}
|
|
588
613
|
}
|
|
@@ -627,12 +652,12 @@ export class SessionRecorder extends Observable {
|
|
|
627
652
|
}
|
|
628
653
|
});
|
|
629
654
|
this._socketService.on(SESSION_SAVE_BUFFER_EVENT, (payload) => {
|
|
630
|
-
var _a, _b
|
|
655
|
+
var _a, _b;
|
|
631
656
|
if (this.sessionState !== SessionState.stopped)
|
|
632
657
|
return;
|
|
633
|
-
this._flushBuffer(
|
|
634
|
-
if ((
|
|
635
|
-
recorderEventBus.emit(SESSION_AUTO_CREATED, (
|
|
658
|
+
this._flushBuffer(payload === null || payload === void 0 ? void 0 : payload.debugSession, true);
|
|
659
|
+
if ((_a = payload === null || payload === void 0 ? void 0 : payload.debugSession) === null || _a === void 0 ? void 0 : _a.url) {
|
|
660
|
+
recorderEventBus.emit(SESSION_AUTO_CREATED, (_b = payload === null || payload === void 0 ? void 0 : payload.debugSession) === null || _b === void 0 ? void 0 : _b.url);
|
|
636
661
|
}
|
|
637
662
|
});
|
|
638
663
|
}
|
|
@@ -640,7 +665,7 @@ export class SessionRecorder extends Observable {
|
|
|
640
665
|
try {
|
|
641
666
|
const session = await this._apiService.createErrorSession({ span });
|
|
642
667
|
if (session === null || session === void 0 ? void 0 : session._id) {
|
|
643
|
-
this._flushBuffer(session
|
|
668
|
+
this._flushBuffer(session);
|
|
644
669
|
}
|
|
645
670
|
if (session === null || session === void 0 ? void 0 : session.url) {
|
|
646
671
|
recorderEventBus.emit(SESSION_AUTO_CREATED, session.url);
|
|
@@ -660,14 +685,20 @@ export class SessionRecorder extends Observable {
|
|
|
660
685
|
sessionAttributes: this.sessionAttributes,
|
|
661
686
|
resourceAttributes: getNavigatorInfo(),
|
|
662
687
|
name: this._getSessionName(),
|
|
663
|
-
...(this._userAttributes
|
|
688
|
+
...(this._userAttributes
|
|
689
|
+
? { userAttributes: this._userAttributes }
|
|
690
|
+
: {}),
|
|
664
691
|
};
|
|
665
|
-
const request = !this.continuousRecording
|
|
692
|
+
const request = !this.continuousRecording
|
|
693
|
+
? payload
|
|
694
|
+
: { debugSessionData: payload };
|
|
666
695
|
const session = this.continuousRecording
|
|
667
696
|
? await this._apiService.startContinuousDebugSession(request, signal)
|
|
668
697
|
: await this._apiService.startSession(request, signal);
|
|
669
698
|
if (session) {
|
|
670
|
-
session.sessionType = this.continuousRecording
|
|
699
|
+
session.sessionType = this.continuousRecording
|
|
700
|
+
? SessionType.CONTINUOUS
|
|
701
|
+
: SessionType.MANUAL;
|
|
671
702
|
this._setupSessionAndStart(session, false);
|
|
672
703
|
}
|
|
673
704
|
}
|
|
@@ -690,7 +721,10 @@ export class SessionRecorder extends Observable {
|
|
|
690
721
|
this._tracer.start(this.sessionId, this.sessionType);
|
|
691
722
|
// Ensure we switch from buffer-only recording to session recording cleanly.
|
|
692
723
|
void this._recorder.restart(this.sessionId, this.sessionType);
|
|
693
|
-
this._navigationRecorder.start({
|
|
724
|
+
this._navigationRecorder.start({
|
|
725
|
+
sessionId: this.sessionId,
|
|
726
|
+
sessionType: this.sessionType,
|
|
727
|
+
});
|
|
694
728
|
if (this.session) {
|
|
695
729
|
this._socketService.subscribeToSession(this.session);
|
|
696
730
|
this._sessionWidget.seconds = getTimeDifferenceInSeconds((_a = this.session) === null || _a === void 0 ? void 0 : _a.startedAt);
|
|
@@ -718,8 +752,12 @@ export class SessionRecorder extends Observable {
|
|
|
718
752
|
// rrweb assigns new node IDs on each record() call, so the next buffer
|
|
719
753
|
// segment must not carry events from the previous generation. Await the
|
|
720
754
|
// clear so its IDB tx can't race past the fresh FullSnapshot.
|
|
721
|
-
const cleared = this._crashBuffer
|
|
722
|
-
|
|
755
|
+
const cleared = this._crashBuffer
|
|
756
|
+
? this._crashBuffer.clear()
|
|
757
|
+
: Promise.resolve();
|
|
758
|
+
void cleared
|
|
759
|
+
.catch(() => undefined)
|
|
760
|
+
.then(() => this._startBufferOnlyRecording());
|
|
723
761
|
}
|
|
724
762
|
/**
|
|
725
763
|
* Pause the session tracing and recording
|
|
@@ -755,7 +793,10 @@ export class SessionRecorder extends Observable {
|
|
|
755
793
|
* @param sessionId - the session ID to set or clear
|
|
756
794
|
*/
|
|
757
795
|
_setSession(session) {
|
|
758
|
-
this.session = {
|
|
796
|
+
this.session = {
|
|
797
|
+
...session,
|
|
798
|
+
startedAt: session.startedAt || new Date().toISOString(),
|
|
799
|
+
};
|
|
759
800
|
this.sessionId = (session === null || session === void 0 ? void 0 : session.shortId) || (session === null || session === void 0 ? void 0 : session._id);
|
|
760
801
|
}
|
|
761
802
|
_clearSession() {
|
|
@@ -778,7 +819,8 @@ export class SessionRecorder extends Observable {
|
|
|
778
819
|
}
|
|
779
820
|
break;
|
|
780
821
|
case 'stop':
|
|
781
|
-
if (this.sessionState !== SessionState.paused &&
|
|
822
|
+
if (this.sessionState !== SessionState.paused &&
|
|
823
|
+
this.sessionState !== SessionState.started) {
|
|
782
824
|
throw new Error('Cannot stop. Session is not currently started.');
|
|
783
825
|
}
|
|
784
826
|
break;
|
|
@@ -856,7 +898,10 @@ export class SessionRecorder extends Observable {
|
|
|
856
898
|
*/
|
|
857
899
|
_getSessionName(date = new Date()) {
|
|
858
900
|
var _a, _b, _c;
|
|
859
|
-
const userName = ((_a = this.sessionAttributes) === null || _a === void 0 ? void 0 : _a.userName) ||
|
|
901
|
+
const userName = ((_a = this.sessionAttributes) === null || _a === void 0 ? void 0 : _a.userName) ||
|
|
902
|
+
((_b = this._userAttributes) === null || _b === void 0 ? void 0 : _b.userName) ||
|
|
903
|
+
((_c = this._userAttributes) === null || _c === void 0 ? void 0 : _c.name) ||
|
|
904
|
+
'';
|
|
860
905
|
return userName
|
|
861
906
|
? `${userName}'s session on ${getFormattedDate(date, { month: 'short', day: 'numeric' })}`
|
|
862
907
|
: `Session on ${getFormattedDate(date)}`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@multiplayer-app/session-recorder-browser",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.88",
|
|
4
4
|
"description": "Multiplayer Fullstack Session Recorder for Browser",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Multiplayer Software, Inc.",
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"webpack-cli": "5.1.4"
|
|
76
76
|
},
|
|
77
77
|
"dependencies": {
|
|
78
|
-
"@multiplayer-app/session-recorder-common": "2.0.
|
|
78
|
+
"@multiplayer-app/session-recorder-common": "2.0.88",
|
|
79
79
|
"@opentelemetry/core": "2.0.1",
|
|
80
80
|
"@opentelemetry/exporter-trace-otlp-http": "0.203.0",
|
|
81
81
|
"@opentelemetry/instrumentation": "0.203.0",
|