@multiplayer-app/session-recorder-react-native 1.3.23 → 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.
- package/README.md +22 -13
- package/lib/module/config/defaults.js +2 -2
- package/lib/module/config/defaults.js.map +1 -1
- package/lib/module/config/session-recorder.js.map +1 -1
- package/lib/module/otel/CrashBufferSpanProcessor.js +14 -13
- package/lib/module/otel/CrashBufferSpanProcessor.js.map +1 -1
- package/lib/module/otel/index.js +85 -59
- package/lib/module/otel/index.js.map +1 -1
- package/lib/module/recorder/index.js +1 -1
- package/lib/module/recorder/index.js.map +1 -1
- package/lib/module/services/api.service.js.map +1 -1
- package/lib/module/services/crashBuffer.service.js +51 -19
- package/lib/module/services/crashBuffer.service.js.map +1 -1
- package/lib/module/services/socket.service.js +2 -2
- package/lib/module/services/socket.service.js.map +1 -1
- package/lib/module/session-recorder.js +29 -78
- package/lib/module/session-recorder.js.map +1 -1
- package/lib/module/types/session-recorder.js.map +1 -1
- package/lib/module/utils/rrweb-events.js +1 -1
- package/lib/module/utils/rrweb-events.js.map +1 -1
- package/lib/typescript/src/config/defaults.d.ts.map +1 -1
- package/lib/typescript/src/config/session-recorder.d.ts.map +1 -1
- package/lib/typescript/src/otel/CrashBufferSpanProcessor.d.ts +3 -4
- package/lib/typescript/src/otel/CrashBufferSpanProcessor.d.ts.map +1 -1
- package/lib/typescript/src/otel/index.d.ts +2 -3
- package/lib/typescript/src/otel/index.d.ts.map +1 -1
- package/lib/typescript/src/services/api.service.d.ts +2 -1
- package/lib/typescript/src/services/api.service.d.ts.map +1 -1
- package/lib/typescript/src/services/crashBuffer.service.d.ts +4 -23
- package/lib/typescript/src/services/crashBuffer.service.d.ts.map +1 -1
- package/lib/typescript/src/services/socket.service.d.ts +4 -1
- package/lib/typescript/src/services/socket.service.d.ts.map +1 -1
- package/lib/typescript/src/session-recorder.d.ts +0 -3
- package/lib/typescript/src/session-recorder.d.ts.map +1 -1
- package/lib/typescript/src/types/session-recorder.d.ts +6 -13
- package/lib/typescript/src/types/session-recorder.d.ts.map +1 -1
- package/lib/typescript/src/utils/rrweb-events.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/config/defaults.ts +29 -29
- package/src/config/session-recorder.ts +8 -2
- package/src/otel/CrashBufferSpanProcessor.ts +17 -24
- package/src/otel/index.ts +110 -61
- package/src/recorder/index.ts +1 -1
- package/src/services/api.service.ts +2 -1
- package/src/services/crashBuffer.service.ts +73 -31
- package/src/services/socket.service.ts +5 -2
- package/src/session-recorder.ts +43 -98
- package/src/types/session-recorder.ts +15 -18
- package/src/utils/rrweb-events.ts +3 -3
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { Platform } from 'react-native';
|
|
2
|
+
import { EventType } from '@rrweb/types';
|
|
2
3
|
import type {
|
|
3
4
|
CrashBufferEventMap,
|
|
4
5
|
CrashBufferEventName,
|
|
5
6
|
CrashBufferErrorSpanAppendedEvent,
|
|
6
7
|
CrashBuffer,
|
|
8
|
+
CrashBufferRrwebEventPayload,
|
|
9
|
+
CrashBufferOtelSpanPayload,
|
|
10
|
+
CrashBufferOtelSpanBatchPayload,
|
|
11
|
+
CrashBufferSnapshot,
|
|
7
12
|
} from '@multiplayer-app/session-recorder-common';
|
|
8
13
|
import { SpanStatusCode } from '@opentelemetry/api';
|
|
9
14
|
|
|
@@ -43,15 +48,6 @@ const RECORD_PREFIX = 'mp_crash_buffer_rec_v1:';
|
|
|
43
48
|
const randomId = (): string =>
|
|
44
49
|
`${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
45
50
|
|
|
46
|
-
export type CrashBufferSnapshot = {
|
|
47
|
-
rrwebEvents: Array<{ ts: number; event: any }>;
|
|
48
|
-
otelSpans: Array<{ ts: number; span: any }>;
|
|
49
|
-
attrs: any | null;
|
|
50
|
-
windowMs: number;
|
|
51
|
-
fromTs: number;
|
|
52
|
-
toTs: number;
|
|
53
|
-
};
|
|
54
|
-
|
|
55
51
|
export class CrashBufferService implements CrashBuffer {
|
|
56
52
|
private static instance: CrashBufferService | null = null;
|
|
57
53
|
|
|
@@ -59,7 +55,9 @@ export class CrashBufferService implements CrashBuffer {
|
|
|
59
55
|
private indexLoaded = false;
|
|
60
56
|
private lastPruneAt = 0;
|
|
61
57
|
private opChain: Promise<any> = Promise.resolve();
|
|
62
|
-
private defaultWindowMs: number =
|
|
58
|
+
private defaultWindowMs: number = 0.5 * 60 * 1000;
|
|
59
|
+
private lastSeenEventTs: number = 0;
|
|
60
|
+
|
|
63
61
|
private listeners = new Map<
|
|
64
62
|
CrashBufferEventName,
|
|
65
63
|
Set<(payload: CrashBufferEventMap[CrashBufferEventName]) => void>
|
|
@@ -111,19 +109,34 @@ export class CrashBufferService implements CrashBuffer {
|
|
|
111
109
|
}
|
|
112
110
|
|
|
113
111
|
async appendEvent(
|
|
114
|
-
payload:
|
|
112
|
+
payload: CrashBufferRrwebEventPayload,
|
|
115
113
|
windowMs?: number
|
|
116
114
|
): Promise<void> {
|
|
115
|
+
const ts = payload?.ts ?? Date.now();
|
|
116
|
+
this.lastSeenEventTs = Math.max(this.lastSeenEventTs, ts);
|
|
117
|
+
|
|
118
|
+
const rawEventType =
|
|
119
|
+
(payload as any)?.event?.eventType ?? (payload as any)?.event?.type;
|
|
120
|
+
const isFullSnapshot =
|
|
121
|
+
Boolean(payload.isFullSnapshot) ||
|
|
122
|
+
rawEventType === EventType.FullSnapshot;
|
|
123
|
+
|
|
124
|
+
const record: CrashBufferRrwebEventPayload = {
|
|
125
|
+
...payload,
|
|
126
|
+
ts,
|
|
127
|
+
isFullSnapshot,
|
|
128
|
+
};
|
|
129
|
+
|
|
117
130
|
return this.appendRecord(
|
|
118
131
|
'rrweb',
|
|
119
|
-
|
|
120
|
-
|
|
132
|
+
record.ts,
|
|
133
|
+
record,
|
|
121
134
|
windowMs ?? this.defaultWindowMs
|
|
122
135
|
);
|
|
123
136
|
}
|
|
124
137
|
|
|
125
138
|
async appendSpans(
|
|
126
|
-
payload:
|
|
139
|
+
payload: CrashBufferOtelSpanBatchPayload,
|
|
127
140
|
windowMs?: number
|
|
128
141
|
): Promise<void> {
|
|
129
142
|
if (!payload.length) return;
|
|
@@ -161,7 +174,7 @@ export class CrashBufferService implements CrashBuffer {
|
|
|
161
174
|
}
|
|
162
175
|
|
|
163
176
|
setDefaultWindowMs(windowMs: number): void {
|
|
164
|
-
this.defaultWindowMs = Math.max(10_000, windowMs ||
|
|
177
|
+
this.defaultWindowMs = Math.max(10_000, windowMs || 0.5 * 60 * 1000);
|
|
165
178
|
}
|
|
166
179
|
|
|
167
180
|
on<E extends CrashBufferEventName>(
|
|
@@ -281,32 +294,60 @@ export class CrashBufferService implements CrashBuffer {
|
|
|
281
294
|
}
|
|
282
295
|
}
|
|
283
296
|
|
|
284
|
-
const
|
|
285
|
-
const
|
|
297
|
+
const allEvents: CrashBufferRrwebEventPayload[] = [];
|
|
298
|
+
const allSpans: CrashBufferOtelSpanPayload[] = [];
|
|
286
299
|
|
|
287
300
|
for (const e of entries.sort((a, b) => a.ts - b.ts)) {
|
|
288
301
|
const key = `${RECORD_PREFIX}${e.id}`;
|
|
289
302
|
const payload = byKey.get(key);
|
|
290
303
|
if (!payload) continue;
|
|
291
|
-
if (e.kind === 'rrweb')
|
|
292
|
-
if (e.kind === 'span')
|
|
304
|
+
if (e.kind === 'rrweb') allEvents.push(payload);
|
|
305
|
+
if (e.kind === 'span') allSpans.push(payload);
|
|
293
306
|
}
|
|
294
307
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
308
|
+
// Mirror browser semantics:
|
|
309
|
+
// - Ensure the rrweb stream starts at Meta -> FullSnapshot (or is empty).
|
|
310
|
+
// - Only include spans from the replayable window onward.
|
|
311
|
+
const eventsSorted = allEvents.slice().sort((a, b) => a.ts - b.ts);
|
|
312
|
+
const firstSnapshotIdx = eventsSorted.findIndex((e) => {
|
|
313
|
+
const t = (e as any)?.event?.eventType ?? (e as any)?.event?.type;
|
|
314
|
+
return t === EventType.FullSnapshot;
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
if (firstSnapshotIdx < 0) {
|
|
318
|
+
return {
|
|
319
|
+
events: [],
|
|
320
|
+
spans: [],
|
|
321
|
+
startedAt: fromTs,
|
|
322
|
+
stoppedAt: toTs,
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
let startIdx = firstSnapshotIdx;
|
|
327
|
+
for (let i = firstSnapshotIdx - 1; i >= 0; i--) {
|
|
328
|
+
const t =
|
|
329
|
+
(eventsSorted[i] as any)?.event?.eventType ??
|
|
330
|
+
(eventsSorted[i] as any)?.event?.type;
|
|
331
|
+
if (t === EventType.Meta) {
|
|
332
|
+
startIdx = i;
|
|
333
|
+
break;
|
|
334
|
+
}
|
|
301
335
|
}
|
|
302
336
|
|
|
337
|
+
const rrwebEvents = eventsSorted.slice(startIdx);
|
|
338
|
+
const firstEvent = rrwebEvents[0];
|
|
339
|
+
const replayStartedAt =
|
|
340
|
+
typeof firstEvent?.ts === 'number' ? firstEvent.ts : fromTs;
|
|
341
|
+
|
|
342
|
+
const otelSpans = allSpans
|
|
343
|
+
.filter((s) => typeof s?.ts === 'number' && s.ts >= replayStartedAt)
|
|
344
|
+
.sort((a, b) => a.ts - b.ts);
|
|
345
|
+
|
|
303
346
|
return {
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
fromTs,
|
|
309
|
-
toTs,
|
|
347
|
+
spans: otelSpans,
|
|
348
|
+
events: rrwebEvents,
|
|
349
|
+
stoppedAt: toTs,
|
|
350
|
+
startedAt: replayStartedAt,
|
|
310
351
|
};
|
|
311
352
|
});
|
|
312
353
|
}
|
|
@@ -317,6 +358,7 @@ export class CrashBufferService implements CrashBuffer {
|
|
|
317
358
|
await this.ensureIndexLoaded();
|
|
318
359
|
const keys = this.index.map((e) => `${RECORD_PREFIX}${e.id}`);
|
|
319
360
|
this.index = [];
|
|
361
|
+
this.lastSeenEventTs = 0;
|
|
320
362
|
try {
|
|
321
363
|
await AsyncStorage.multiRemove([INDEX_KEY, ATTRS_KEY, ...keys]);
|
|
322
364
|
} catch (_e) {
|
|
@@ -216,8 +216,11 @@ export class SocketService extends Observable<SocketServiceEvents> {
|
|
|
216
216
|
}
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
-
public setUser(
|
|
220
|
-
|
|
219
|
+
public setUser(data: {
|
|
220
|
+
userAttributes: IUserAttributes | null;
|
|
221
|
+
clientId?: string;
|
|
222
|
+
}): void {
|
|
223
|
+
this.emitSocketEvent(SOCKET_SET_USER_EVENT, data);
|
|
221
224
|
}
|
|
222
225
|
|
|
223
226
|
public close(): Promise<void> {
|
package/src/session-recorder.ts
CHANGED
|
@@ -180,95 +180,32 @@ class SessionRecorder
|
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
-
public async flushBuffer(payload?: { reason?: string }): Promise<any> {
|
|
184
|
-
if (!this._configs?.buffering?.enabled) return null;
|
|
185
|
-
if (this._isFlushingBuffer) return null;
|
|
186
|
-
if (this.sessionState !== SessionState.stopped || this.sessionId)
|
|
187
|
-
return null;
|
|
188
|
-
|
|
189
|
-
const windowMs = Math.max(
|
|
190
|
-
10_000,
|
|
191
|
-
(this._configs.buffering.windowMinutes || 2) * 60 * 1000
|
|
192
|
-
);
|
|
193
|
-
|
|
194
|
-
this._isFlushingBuffer = true;
|
|
195
|
-
try {
|
|
196
|
-
const reason = payload?.reason || 'manual';
|
|
197
|
-
await this._crashBuffer.setAttrs({
|
|
198
|
-
sessionAttributes: this.sessionAttributes,
|
|
199
|
-
resourceAttributes: getNavigatorInfo(),
|
|
200
|
-
userAttributes: this._userAttributes,
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
const snapshot = await this._crashBuffer.snapshot(windowMs);
|
|
204
|
-
if (
|
|
205
|
-
snapshot.rrwebEvents.length === 0 &&
|
|
206
|
-
snapshot.otelSpans.length === 0
|
|
207
|
-
) {
|
|
208
|
-
return null;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
const request: StartSessionRequest = {
|
|
212
|
-
name: `${this._configs.application} ${getFormattedDate(new Date())}`,
|
|
213
|
-
stoppedAt: new Date().toISOString(),
|
|
214
|
-
sessionAttributes: this.sessionAttributes,
|
|
215
|
-
resourceAttributes: getNavigatorInfo(),
|
|
216
|
-
...(this._userAttributes
|
|
217
|
-
? { userAttributes: this._userAttributes }
|
|
218
|
-
: {}),
|
|
219
|
-
debugSessionData: {
|
|
220
|
-
meta: {
|
|
221
|
-
reason,
|
|
222
|
-
windowMs: snapshot.windowMs,
|
|
223
|
-
fromTs: snapshot.fromTs,
|
|
224
|
-
toTs: snapshot.toTs,
|
|
225
|
-
},
|
|
226
|
-
events: snapshot.rrwebEvents,
|
|
227
|
-
spans: snapshot.otelSpans.map((s) => s.span),
|
|
228
|
-
attrs: snapshot.attrs,
|
|
229
|
-
},
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
try {
|
|
233
|
-
const res = await this._apiService.startSession(request);
|
|
234
|
-
await this._crashBuffer.clear();
|
|
235
|
-
return res;
|
|
236
|
-
} catch (_e) {
|
|
237
|
-
// swallow: flush is best-effort; never throw into app code
|
|
238
|
-
return null;
|
|
239
|
-
}
|
|
240
|
-
} finally {
|
|
241
|
-
this._isFlushingBuffer = false;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
183
|
private async _flushBuffer(sessionId: string): Promise<any> {
|
|
246
|
-
if (
|
|
247
|
-
|
|
248
|
-
|
|
184
|
+
if (
|
|
185
|
+
!sessionId ||
|
|
186
|
+
!this._crashBuffer ||
|
|
187
|
+
this._isFlushingBuffer ||
|
|
188
|
+
!this._configs?.buffering?.enabled ||
|
|
189
|
+
this.sessionState !== SessionState.stopped
|
|
190
|
+
) {
|
|
249
191
|
return null;
|
|
250
|
-
|
|
251
|
-
const windowMs = Math.max(
|
|
252
|
-
10_000,
|
|
253
|
-
(this._configs.buffering.windowMinutes || 2) * 60 * 1000
|
|
254
|
-
);
|
|
192
|
+
}
|
|
255
193
|
|
|
256
194
|
this._isFlushingBuffer = true;
|
|
257
195
|
try {
|
|
258
|
-
const
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
snapshot.otelSpans.length === 0
|
|
262
|
-
) {
|
|
196
|
+
const { events, spans, startedAt, stoppedAt } =
|
|
197
|
+
await this._crashBuffer.snapshot();
|
|
198
|
+
if (events.length === 0 && spans.length === 0) {
|
|
263
199
|
return null;
|
|
264
200
|
}
|
|
265
|
-
const spans = snapshot.otelSpans.map((s) => s.span);
|
|
266
|
-
const events = snapshot.rrwebEvents.map((e) => e.event);
|
|
267
201
|
await Promise.all([
|
|
268
|
-
this._tracer.exportTraces(spans),
|
|
269
|
-
this._apiService.exportEvents(sessionId, {
|
|
202
|
+
this._tracer.exportTraces(spans.map((s) => s.span)),
|
|
203
|
+
this._apiService.exportEvents(sessionId, {
|
|
204
|
+
events: events.map((e) => e.event),
|
|
205
|
+
}),
|
|
270
206
|
this._apiService.updateSessionAttributes(sessionId, {
|
|
271
|
-
|
|
207
|
+
startedAt: new Date(startedAt).toISOString(),
|
|
208
|
+
stoppedAt: new Date(stoppedAt).toISOString(),
|
|
272
209
|
sessionAttributes: this.sessionAttributes,
|
|
273
210
|
resourceAttributes: getNavigatorInfo(),
|
|
274
211
|
userAttributes: this._userAttributes || undefined,
|
|
@@ -285,7 +222,7 @@ class SessionRecorder
|
|
|
285
222
|
private async _createExceptionSession(span: any): Promise<void> {
|
|
286
223
|
try {
|
|
287
224
|
const session = await this._apiService.createErrorSession({ span });
|
|
288
|
-
if (session) {
|
|
225
|
+
if (session?._id) {
|
|
289
226
|
void this._flushBuffer(session._id);
|
|
290
227
|
}
|
|
291
228
|
} catch (_ignored) {
|
|
@@ -341,7 +278,7 @@ class SessionRecorder
|
|
|
341
278
|
const bufferEnabled = Boolean(this._configs.buffering?.enabled);
|
|
342
279
|
const windowMs = Math.max(
|
|
343
280
|
10_000,
|
|
344
|
-
(this._configs.buffering?.windowMinutes ||
|
|
281
|
+
(this._configs.buffering?.windowMinutes || 0.5) * 60 * 1000
|
|
345
282
|
);
|
|
346
283
|
this._tracer.setCrashBuffer(
|
|
347
284
|
bufferEnabled ? this._crashBuffer : undefined,
|
|
@@ -365,8 +302,13 @@ class SessionRecorder
|
|
|
365
302
|
);
|
|
366
303
|
|
|
367
304
|
this._crashBuffer.on('error-span-appended', (payload) => {
|
|
368
|
-
if (
|
|
369
|
-
|
|
305
|
+
if (
|
|
306
|
+
!payload.span ||
|
|
307
|
+
this.sessionId ||
|
|
308
|
+
this.sessionState !== SessionState.stopped
|
|
309
|
+
) {
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
370
312
|
this._createExceptionSession(payload.span);
|
|
371
313
|
});
|
|
372
314
|
|
|
@@ -387,21 +329,20 @@ class SessionRecorder
|
|
|
387
329
|
}
|
|
388
330
|
|
|
389
331
|
private _startBufferOnlyRecording(): void {
|
|
390
|
-
if (
|
|
391
|
-
|
|
332
|
+
if (
|
|
333
|
+
this.sessionId ||
|
|
334
|
+
!this._crashBuffer ||
|
|
335
|
+
!this._configs?.buffering?.enabled ||
|
|
336
|
+
this.sessionState !== SessionState.stopped
|
|
337
|
+
) {
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
392
340
|
|
|
393
341
|
const windowMs = Math.max(
|
|
394
342
|
10_000,
|
|
395
|
-
(this._configs.buffering.windowMinutes ||
|
|
343
|
+
(this._configs.buffering.windowMinutes || 0.5) * 60 * 1000
|
|
396
344
|
);
|
|
397
345
|
|
|
398
|
-
// Best-effort: persist current attrs so flush has context.
|
|
399
|
-
this._crashBuffer.setAttrs({
|
|
400
|
-
sessionAttributes: this.sessionAttributes,
|
|
401
|
-
resourceAttributes: getNavigatorInfo(),
|
|
402
|
-
userAttributes: this._userAttributes,
|
|
403
|
-
});
|
|
404
|
-
|
|
405
346
|
// Wire buffer into tracer + recorder (only used when sessionId is null).
|
|
406
347
|
this._tracer.setCrashBuffer(this._crashBuffer, windowMs);
|
|
407
348
|
this._recorder.init(this._configs, this._socketService, this._crashBuffer, {
|
|
@@ -448,9 +389,7 @@ class SessionRecorder
|
|
|
448
389
|
});
|
|
449
390
|
|
|
450
391
|
this._socketService.on(SESSION_SAVE_BUFFER_EVENT, (payload: any) => {
|
|
451
|
-
|
|
452
|
-
void this._flushBuffer(payload.debugSession._id);
|
|
453
|
-
}
|
|
392
|
+
this._flushBuffer(payload?.debugSession?._id);
|
|
454
393
|
});
|
|
455
394
|
}
|
|
456
395
|
|
|
@@ -628,7 +567,13 @@ class SessionRecorder
|
|
|
628
567
|
return;
|
|
629
568
|
}
|
|
630
569
|
this._userAttributes = userAttributes;
|
|
631
|
-
|
|
570
|
+
|
|
571
|
+
const data = {
|
|
572
|
+
userAttributes: this._userAttributes,
|
|
573
|
+
clientId: this._tracer.clientId,
|
|
574
|
+
};
|
|
575
|
+
|
|
576
|
+
this._socketService.setUser(data);
|
|
632
577
|
}
|
|
633
578
|
|
|
634
579
|
/**
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { type Span } from '@opentelemetry/api';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
type ISession,
|
|
4
|
+
type SessionType,
|
|
5
|
+
type IUserAttributes,
|
|
6
|
+
} from '@multiplayer-app/session-recorder-common';
|
|
3
7
|
import { type PropagateTraceHeaderCorsUrls } from '@opentelemetry/sdk-trace-web';
|
|
4
8
|
|
|
5
|
-
|
|
6
9
|
// WidgetButtonPlacement moved to configs.ts
|
|
7
10
|
|
|
8
11
|
export enum SessionState {
|
|
@@ -157,11 +160,11 @@ export interface SessionRecorderOptions {
|
|
|
157
160
|
};
|
|
158
161
|
|
|
159
162
|
/**
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
useWebsocket?: boolean
|
|
163
|
+
* @description
|
|
164
|
+
* If true, webSocket will be used to manage remote recording sessions.
|
|
165
|
+
* @default true
|
|
166
|
+
*/
|
|
167
|
+
useWebsocket?: boolean;
|
|
165
168
|
|
|
166
169
|
/**
|
|
167
170
|
* (Optional) Client-side crash buffer configuration.
|
|
@@ -169,11 +172,11 @@ export interface SessionRecorderOptions {
|
|
|
169
172
|
* even if the user did not start a manual/continuous recording.
|
|
170
173
|
*/
|
|
171
174
|
buffering?: {
|
|
172
|
-
/** Enable/disable buffering. @default
|
|
173
|
-
enabled?: boolean
|
|
174
|
-
/** Rolling window size (minutes). @default
|
|
175
|
-
windowMinutes?: number
|
|
176
|
-
}
|
|
175
|
+
/** Enable/disable buffering. @default false */
|
|
176
|
+
enabled?: boolean;
|
|
177
|
+
/** Rolling window size (minutes). @default 0.5 */
|
|
178
|
+
windowMinutes?: number;
|
|
179
|
+
};
|
|
177
180
|
}
|
|
178
181
|
|
|
179
182
|
/**
|
|
@@ -361,12 +364,6 @@ export interface ISessionRecorder {
|
|
|
361
364
|
* Capture an exception and send it as an error trace
|
|
362
365
|
*/
|
|
363
366
|
captureException(error: unknown, errorInfo?: Record<string, any>): void;
|
|
364
|
-
|
|
365
|
-
/**
|
|
366
|
-
* Flush the local crash buffer by creating a debug session and uploading buffered data.
|
|
367
|
-
* No-op if a live recording is currently active.
|
|
368
|
-
*/
|
|
369
|
-
flushBuffer(payload?: { reason?: string }): Promise<any>;
|
|
370
367
|
}
|
|
371
368
|
|
|
372
369
|
/**
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Dimensions } from 'react-native';
|
|
2
2
|
import {
|
|
3
|
-
EventType,
|
|
4
|
-
type eventWithTime,
|
|
5
3
|
NodeType,
|
|
6
|
-
|
|
4
|
+
EventType,
|
|
7
5
|
IncrementalSource,
|
|
8
6
|
type mutationData,
|
|
7
|
+
type eventWithTime,
|
|
8
|
+
type serializedNodeWithId,
|
|
9
9
|
} from '@rrweb/types';
|
|
10
10
|
import { getAppMetadata } from './platform';
|
|
11
11
|
|