@multiplayer-app/session-recorder-browser 2.0.38 → 2.0.40
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/browser/index.js +37 -14
- package/dist/exporters/index.js +1 -1
- package/dist/index.js +37 -14
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +37 -14
- package/dist/index.umd.js.map +1 -1
- package/dist/rrweb/index.d.ts +1 -0
- package/dist/rrweb/index.d.ts.map +1 -1
- package/dist/rrweb/index.js +10 -2
- package/dist/rrweb/index.js.map +1 -1
- package/dist/session-recorder.d.ts.map +1 -1
- package/dist/session-recorder.js +26 -11
- package/dist/session-recorder.js.map +1 -1
- package/package.json +2 -2
package/dist/index.umd.js
CHANGED
|
@@ -24436,7 +24436,7 @@ const CONTINUOUS_DEBUGGING_TIMEOUT = 60000; // 1 minutes
|
|
|
24436
24436
|
const DEBUG_SESSION_MAX_DURATION_SECONDS = 10 * 60 + 30; // TODO: move to shared config otel core
|
|
24437
24437
|
const REMOTE_SESSION_RECORDING_START = 'remote-session-recording:start';
|
|
24438
24438
|
const REMOTE_SESSION_RECORDING_STOP = 'remote-session-recording:stop';
|
|
24439
|
-
const PACKAGE_VERSION_EXPORT = "2.0.
|
|
24439
|
+
const PACKAGE_VERSION_EXPORT = "2.0.40" || 0;
|
|
24440
24440
|
// Regex patterns for OpenTelemetry ignore URLs
|
|
24441
24441
|
const OTEL_IGNORE_URLS = [
|
|
24442
24442
|
// Traces endpoint
|
|
@@ -26144,6 +26144,7 @@ if (typeof XMLHttpRequest !== 'undefined') {
|
|
|
26144
26144
|
|
|
26145
26145
|
class RecorderBrowserSDK {
|
|
26146
26146
|
constructor() {
|
|
26147
|
+
this.generation = 0;
|
|
26147
26148
|
this.intervals = {
|
|
26148
26149
|
restart: null,
|
|
26149
26150
|
bufferSnapshot: null,
|
|
@@ -26179,12 +26180,15 @@ class RecorderBrowserSDK {
|
|
|
26179
26180
|
throw new Error('Configuration not initialized. Call init() before start().');
|
|
26180
26181
|
}
|
|
26181
26182
|
this.startedAt = new Date().toISOString();
|
|
26183
|
+
const gen = ++this.generation;
|
|
26182
26184
|
this.stopFn = (0,rrweb__WEBPACK_IMPORTED_MODULE_6__.record)({
|
|
26183
26185
|
...this._buildRecordOptions(),
|
|
26184
26186
|
emit: async (event) => {
|
|
26187
|
+
if (gen !== this.generation)
|
|
26188
|
+
return;
|
|
26185
26189
|
const ts = event.timestamp;
|
|
26186
26190
|
if (!sessionId) {
|
|
26187
|
-
await this._handleBufferOnlyEvent(event, ts);
|
|
26191
|
+
await this._handleBufferOnlyEvent(event, ts, gen);
|
|
26188
26192
|
return;
|
|
26189
26193
|
}
|
|
26190
26194
|
this._handleLiveSessionEvent(event, ts, sessionId, sessionType);
|
|
@@ -26200,6 +26204,7 @@ class RecorderBrowserSDK {
|
|
|
26200
26204
|
var _a;
|
|
26201
26205
|
try {
|
|
26202
26206
|
(_a = this.stopFn) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
26207
|
+
this.stopFn = undefined;
|
|
26203
26208
|
this.start(sessionId, sessionType);
|
|
26204
26209
|
}
|
|
26205
26210
|
catch (_e) {
|
|
@@ -26213,6 +26218,7 @@ class RecorderBrowserSDK {
|
|
|
26213
26218
|
var _a, _b, _c;
|
|
26214
26219
|
(_a = this.stopFn) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
26215
26220
|
this.stopFn = undefined;
|
|
26221
|
+
this.generation++;
|
|
26216
26222
|
if (!((_b = this.config) === null || _b === void 0 ? void 0 : _b.useWebsocket)) {
|
|
26217
26223
|
(_c = this.socketService) === null || _c === void 0 ? void 0 : _c.close();
|
|
26218
26224
|
}
|
|
@@ -26252,13 +26258,15 @@ class RecorderBrowserSDK {
|
|
|
26252
26258
|
* @param event - Event.
|
|
26253
26259
|
* @param ts - Timestamp.
|
|
26254
26260
|
*/
|
|
26255
|
-
async _handleBufferOnlyEvent(event, ts) {
|
|
26261
|
+
async _handleBufferOnlyEvent(event, ts, gen) {
|
|
26256
26262
|
if (!this.crashBuffer)
|
|
26257
26263
|
return;
|
|
26258
26264
|
try {
|
|
26259
26265
|
this._applyConsoleMasking(event);
|
|
26260
26266
|
const packedEvent = (0,_rrweb_packer__WEBPACK_IMPORTED_MODULE_0__.pack)(event);
|
|
26261
26267
|
this.stoppedAt = new Date(ts).toISOString();
|
|
26268
|
+
if (gen !== this.generation)
|
|
26269
|
+
return;
|
|
26262
26270
|
await this.crashBuffer.appendEvent({
|
|
26263
26271
|
ts,
|
|
26264
26272
|
isFullSnapshot: event.type === _rrweb_types__WEBPACK_IMPORTED_MODULE_1__.EventType.FullSnapshot,
|
|
@@ -27762,10 +27770,14 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_16__.Obse
|
|
|
27762
27770
|
}
|
|
27763
27771
|
_startBufferOnlyRecording() {
|
|
27764
27772
|
var _a, _b;
|
|
27765
|
-
|
|
27766
|
-
|
|
27767
|
-
|
|
27768
|
-
|
|
27773
|
+
// NOTE: `this.sessionId` is intentionally NOT checked. `_stop()` runs
|
|
27774
|
+
// before `_clearSession()` (the stopSession API call sits between them),
|
|
27775
|
+
// so the clear().then() chain fires while sessionId is still set.
|
|
27776
|
+
// Bailing on sessionId here meant rrweb never restarted after manual
|
|
27777
|
+
// stop, leaving the buffer with no FullSnapshot and silently breaking
|
|
27778
|
+
// exception-triggered flushBuffer. `_recorder.restart(null, ...)` passes
|
|
27779
|
+
// null explicitly, so it's safe regardless of `this.sessionId`.
|
|
27780
|
+
if (!this._crashBuffer || !((_b = (_a = this._configs) === null || _a === void 0 ? void 0 : _a.buffering) === null || _b === void 0 ? void 0 : _b.enabled) || this.sessionState !== _types__WEBPACK_IMPORTED_MODULE_4__.SessionState.stopped) {
|
|
27769
27781
|
return;
|
|
27770
27782
|
}
|
|
27771
27783
|
void this._recorder.restart(null, _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionType.MANUAL);
|
|
@@ -27835,9 +27847,10 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_16__.Obse
|
|
|
27835
27847
|
async stop(comment) {
|
|
27836
27848
|
try {
|
|
27837
27849
|
this._checkOperation('stop');
|
|
27850
|
+
const sid = this.sessionId;
|
|
27838
27851
|
this._stop();
|
|
27839
27852
|
if (this.continuousRecording) {
|
|
27840
|
-
await this._apiService.stopContinuousDebugSession(
|
|
27853
|
+
await this._apiService.stopContinuousDebugSession(sid);
|
|
27841
27854
|
this.sessionType = _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionType.MANUAL;
|
|
27842
27855
|
}
|
|
27843
27856
|
else {
|
|
@@ -27845,10 +27858,9 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_16__.Obse
|
|
|
27845
27858
|
sessionAttributes: { comment },
|
|
27846
27859
|
stoppedAt: this._recorder.stoppedAt,
|
|
27847
27860
|
};
|
|
27848
|
-
const response = await this._apiService.stopSession(
|
|
27861
|
+
const response = await this._apiService.stopSession(sid, request);
|
|
27849
27862
|
_eventBus__WEBPACK_IMPORTED_MODULE_7__.recorderEventBus.emit(_config__WEBPACK_IMPORTED_MODULE_5__.SESSION_RESPONSE, response);
|
|
27850
27863
|
}
|
|
27851
|
-
this._clearSession();
|
|
27852
27864
|
}
|
|
27853
27865
|
catch (error) {
|
|
27854
27866
|
this.error = error.message;
|
|
@@ -27884,15 +27896,15 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_16__.Obse
|
|
|
27884
27896
|
async cancel() {
|
|
27885
27897
|
try {
|
|
27886
27898
|
this._checkOperation('cancel');
|
|
27899
|
+
const sid = this.sessionId;
|
|
27887
27900
|
this._stop();
|
|
27888
27901
|
if (this.continuousRecording) {
|
|
27889
|
-
await this._apiService.stopContinuousDebugSession(
|
|
27902
|
+
await this._apiService.stopContinuousDebugSession(sid);
|
|
27890
27903
|
this.sessionType = _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_0__.SessionType.MANUAL;
|
|
27891
27904
|
}
|
|
27892
27905
|
else {
|
|
27893
|
-
await this._apiService.cancelSession(
|
|
27906
|
+
await this._apiService.cancelSession(sid);
|
|
27894
27907
|
}
|
|
27895
|
-
this._clearSession();
|
|
27896
27908
|
}
|
|
27897
27909
|
catch (error) {
|
|
27898
27910
|
this.error = error.message;
|
|
@@ -28206,7 +28218,18 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_16__.Obse
|
|
|
28206
28218
|
this._tracer.stop();
|
|
28207
28219
|
this._recorder.stop();
|
|
28208
28220
|
this._navigationRecorder.stop();
|
|
28209
|
-
|
|
28221
|
+
// Clear session identity synchronously. The buffer-restart chain and the
|
|
28222
|
+
// error-span-appended listener both gate on `this.sessionId === null`;
|
|
28223
|
+
// deferring this to `_clearSession()` (after the network stopSession
|
|
28224
|
+
// call) left them seeing a stale id and silently no-oping. Callers that
|
|
28225
|
+
// need the id for the stop/cancel API must capture it before _stop().
|
|
28226
|
+
this.session = null;
|
|
28227
|
+
this.sessionId = null;
|
|
28228
|
+
// rrweb assigns new node IDs on each record() call, so the next buffer
|
|
28229
|
+
// segment must not carry events from the previous generation. Await the
|
|
28230
|
+
// clear so its IDB tx can't race past the fresh FullSnapshot.
|
|
28231
|
+
const cleared = this._crashBuffer ? this._crashBuffer.clear() : Promise.resolve();
|
|
28232
|
+
void cleared.catch(() => undefined).then(() => this._startBufferOnlyRecording());
|
|
28210
28233
|
}
|
|
28211
28234
|
/**
|
|
28212
28235
|
* Pause the session tracing and recording
|