@multiplayer-app/session-recorder-react-native 1.3.15 → 1.3.21

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 (56) hide show
  1. package/lib/module/config/constants.js +3 -0
  2. package/lib/module/config/constants.js.map +1 -1
  3. package/lib/module/config/defaults.js +5 -1
  4. package/lib/module/config/defaults.js.map +1 -1
  5. package/lib/module/config/session-recorder.js +5 -1
  6. package/lib/module/config/session-recorder.js.map +1 -1
  7. package/lib/module/otel/CrashBufferSpanProcessor.js +41 -0
  8. package/lib/module/otel/CrashBufferSpanProcessor.js.map +1 -0
  9. package/lib/module/otel/index.js +28 -9
  10. package/lib/module/otel/index.js.map +1 -1
  11. package/lib/module/patch/fetch.js +71 -11
  12. package/lib/module/patch/fetch.js.map +1 -1
  13. package/lib/module/recorder/index.js +15 -1
  14. package/lib/module/recorder/index.js.map +1 -1
  15. package/lib/module/services/api.service.js +24 -2
  16. package/lib/module/services/api.service.js.map +1 -1
  17. package/lib/module/services/crashBuffer.service.js +248 -0
  18. package/lib/module/services/crashBuffer.service.js.map +1 -0
  19. package/lib/module/services/socket.service.js +9 -2
  20. package/lib/module/services/socket.service.js.map +1 -1
  21. package/lib/module/session-recorder.js +152 -6
  22. package/lib/module/session-recorder.js.map +1 -1
  23. package/lib/module/types/session-recorder.js.map +1 -1
  24. package/lib/typescript/src/config/constants.d.ts +1 -0
  25. package/lib/typescript/src/config/constants.d.ts.map +1 -1
  26. package/lib/typescript/src/config/defaults.d.ts.map +1 -1
  27. package/lib/typescript/src/config/session-recorder.d.ts.map +1 -1
  28. package/lib/typescript/src/otel/CrashBufferSpanProcessor.d.ts +18 -0
  29. package/lib/typescript/src/otel/CrashBufferSpanProcessor.d.ts.map +1 -0
  30. package/lib/typescript/src/otel/index.d.ts +8 -0
  31. package/lib/typescript/src/otel/index.d.ts.map +1 -1
  32. package/lib/typescript/src/recorder/index.d.ts +8 -1
  33. package/lib/typescript/src/recorder/index.d.ts.map +1 -1
  34. package/lib/typescript/src/services/api.service.d.ts +27 -2
  35. package/lib/typescript/src/services/api.service.d.ts.map +1 -1
  36. package/lib/typescript/src/services/crashBuffer.service.d.ts +46 -0
  37. package/lib/typescript/src/services/crashBuffer.service.d.ts.map +1 -0
  38. package/lib/typescript/src/services/socket.service.d.ts +4 -3
  39. package/lib/typescript/src/services/socket.service.d.ts.map +1 -1
  40. package/lib/typescript/src/session-recorder.d.ts +8 -0
  41. package/lib/typescript/src/session-recorder.d.ts.map +1 -1
  42. package/lib/typescript/src/types/session-recorder.d.ts +18 -0
  43. package/lib/typescript/src/types/session-recorder.d.ts.map +1 -1
  44. package/package.json +2 -2
  45. package/src/config/constants.ts +3 -0
  46. package/src/config/defaults.ts +5 -0
  47. package/src/config/session-recorder.ts +5 -0
  48. package/src/otel/CrashBufferSpanProcessor.ts +61 -0
  49. package/src/otel/index.ts +90 -34
  50. package/src/patch/fetch.ts +73 -11
  51. package/src/recorder/index.ts +30 -3
  52. package/src/services/api.service.ts +68 -13
  53. package/src/services/crashBuffer.service.ts +327 -0
  54. package/src/services/socket.service.ts +36 -22
  55. package/src/session-recorder.ts +226 -19
  56. package/src/types/session-recorder.ts +18 -0
@@ -0,0 +1,248 @@
1
+ "use strict";
2
+
3
+ import { Platform } from 'react-native';
4
+ import { SpanStatusCode } from '@opentelemetry/api';
5
+
6
+ // Safe import for AsyncStorage with web fallback
7
+ let AsyncStorage = null;
8
+ const isWeb = Platform.OS === 'web';
9
+ if (!isWeb) {
10
+ try {
11
+ AsyncStorage = require('@react-native-async-storage/async-storage').default;
12
+ } catch (_error) {
13
+ AsyncStorage = null;
14
+ }
15
+ } else {
16
+ AsyncStorage = {
17
+ getItem: _key => Promise.resolve(null),
18
+ setItem: (_key, _value) => Promise.resolve(undefined),
19
+ removeItem: _key => Promise.resolve(undefined),
20
+ multiRemove: _keys => Promise.resolve(undefined),
21
+ multiGet: _keys => Promise.resolve([]),
22
+ multiSet: _pairs => Promise.resolve(undefined)
23
+ };
24
+ }
25
+ const INDEX_KEY = 'mp_crash_buffer_index_v1';
26
+ const ATTRS_KEY = 'mp_crash_buffer_attrs_v1';
27
+ const RECORD_PREFIX = 'mp_crash_buffer_rec_v1:';
28
+ const randomId = () => `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
29
+ export class CrashBufferService {
30
+ static instance = null;
31
+ index = [];
32
+ indexLoaded = false;
33
+ lastPruneAt = 0;
34
+ opChain = Promise.resolve();
35
+ defaultWindowMs = 1 * 60 * 1000;
36
+ listeners = new Map();
37
+ static getInstance() {
38
+ if (!CrashBufferService.instance) {
39
+ CrashBufferService.instance = new CrashBufferService();
40
+ }
41
+ return CrashBufferService.instance;
42
+ }
43
+ enqueue(fn) {
44
+ const next = this.opChain.then(fn, fn);
45
+ // Preserve chain, but don't leak rejections.
46
+ this.opChain = next.then(() => undefined, () => undefined);
47
+ return next;
48
+ }
49
+ async ensureIndexLoaded() {
50
+ if (this.indexLoaded) return;
51
+ if (!AsyncStorage) {
52
+ this.indexLoaded = true;
53
+ this.index = [];
54
+ return;
55
+ }
56
+ try {
57
+ const raw = await AsyncStorage.getItem(INDEX_KEY);
58
+ this.index = raw ? JSON.parse(raw) : [];
59
+ } catch (_e) {
60
+ this.index = [];
61
+ } finally {
62
+ this.indexLoaded = true;
63
+ }
64
+ }
65
+ async setAttrs(attrs) {
66
+ return this.enqueue(async () => {
67
+ if (!AsyncStorage) return;
68
+ try {
69
+ await AsyncStorage.setItem(ATTRS_KEY, JSON.stringify(attrs || null));
70
+ } catch (_e) {
71
+ // best-effort
72
+ }
73
+ });
74
+ }
75
+ async appendEvent(payload, windowMs) {
76
+ return this.appendRecord('rrweb', payload.ts, payload, windowMs ?? this.defaultWindowMs);
77
+ }
78
+ async appendSpans(payload, windowMs) {
79
+ if (!payload.length) return;
80
+ const effectiveWindowMs = windowMs ?? this.defaultWindowMs;
81
+ return this.enqueue(async () => {
82
+ if (!AsyncStorage) return;
83
+ await this.ensureIndexLoaded();
84
+ const pairs = [];
85
+ let errorEvent = null;
86
+ for (const p of payload) {
87
+ const id = randomId();
88
+ const key = `${RECORD_PREFIX}${id}`;
89
+ const entry = {
90
+ id,
91
+ ts: p.ts,
92
+ kind: 'span'
93
+ };
94
+ this.index.push(entry);
95
+ pairs.push([key, JSON.stringify(p)]);
96
+ if (!errorEvent && p?.span?.status?.code === SpanStatusCode.ERROR) {
97
+ errorEvent = {
98
+ ts: p.ts,
99
+ span: p.span
100
+ };
101
+ }
102
+ }
103
+ try {
104
+ await AsyncStorage.multiSet(pairs);
105
+ await AsyncStorage.setItem(INDEX_KEY, JSON.stringify(this.index));
106
+ } catch (_e) {
107
+ // best-effort
108
+ }
109
+ this.pruneSoon(effectiveWindowMs);
110
+ if (errorEvent) {
111
+ this._emit('error-span-appended', errorEvent);
112
+ }
113
+ });
114
+ }
115
+ setDefaultWindowMs(windowMs) {
116
+ this.defaultWindowMs = Math.max(10_000, windowMs || 1 * 60 * 1000);
117
+ }
118
+ on(event, listener) {
119
+ const set = this.listeners.get(event) || new Set();
120
+ set.add(listener);
121
+ this.listeners.set(event, set);
122
+ return () => this.off(event, listener);
123
+ }
124
+ off(event, listener) {
125
+ const set = this.listeners.get(event);
126
+ if (!set) return;
127
+ set.delete(listener);
128
+ if (set.size === 0) this.listeners.delete(event);
129
+ }
130
+ _emit(event, payload) {
131
+ const set = this.listeners.get(event);
132
+ if (!set || set.size === 0) return;
133
+ for (const fn of Array.from(set)) {
134
+ try {
135
+ fn(payload);
136
+ } catch (_e) {
137
+ // never throw into app code
138
+ }
139
+ }
140
+ }
141
+ async appendRecord(kind, ts, payload, windowMs) {
142
+ return this.enqueue(async () => {
143
+ if (!AsyncStorage) return;
144
+ await this.ensureIndexLoaded();
145
+ const id = randomId();
146
+ const key = `${RECORD_PREFIX}${id}`;
147
+ const entry = {
148
+ id,
149
+ ts,
150
+ kind
151
+ };
152
+ this.index.push(entry);
153
+ try {
154
+ await AsyncStorage.setItem(key, JSON.stringify(payload));
155
+ await AsyncStorage.setItem(INDEX_KEY, JSON.stringify(this.index));
156
+ } catch (_e) {
157
+ // best-effort
158
+ }
159
+ this.pruneSoon(windowMs);
160
+ });
161
+ }
162
+ pruneSoon(windowMs) {
163
+ const now = Date.now();
164
+ if (now - this.lastPruneAt < 2000) return;
165
+ this.lastPruneAt = now;
166
+ const cutoff = Math.max(0, now - windowMs);
167
+ void this.pruneOlderThan(cutoff);
168
+ }
169
+ async pruneOlderThan(cutoffTs) {
170
+ return this.enqueue(async () => {
171
+ if (!AsyncStorage) return;
172
+ await this.ensureIndexLoaded();
173
+ const toRemove = this.index.filter(e => e.ts < cutoffTs);
174
+ if (toRemove.length === 0) return;
175
+ const removeKeys = toRemove.map(e => `${RECORD_PREFIX}${e.id}`);
176
+ this.index = this.index.filter(e => e.ts >= cutoffTs);
177
+ try {
178
+ await AsyncStorage.multiRemove(removeKeys);
179
+ await AsyncStorage.setItem(INDEX_KEY, JSON.stringify(this.index));
180
+ } catch (_e) {
181
+ // best-effort
182
+ }
183
+ });
184
+ }
185
+ async snapshot(windowMs, now = Date.now()) {
186
+ return this.enqueue(async () => {
187
+ await this.ensureIndexLoaded();
188
+ const effectiveWindowMs = windowMs ?? this.defaultWindowMs;
189
+ const toTs = now;
190
+ const fromTs = Math.max(0, toTs - effectiveWindowMs);
191
+ const entries = this.index.filter(e => e.ts >= fromTs && e.ts <= toTs);
192
+ const keys = entries.map(e => `${RECORD_PREFIX}${e.id}`);
193
+ let pairs = [];
194
+ try {
195
+ pairs = AsyncStorage ? await AsyncStorage.multiGet(keys) : [];
196
+ } catch (_e) {
197
+ pairs = [];
198
+ }
199
+ const byKey = new Map();
200
+ for (const [k, v] of pairs) {
201
+ if (!v) continue;
202
+ try {
203
+ byKey.set(k, JSON.parse(v));
204
+ } catch (_e) {
205
+ // ignore
206
+ }
207
+ }
208
+ const rrwebEvents = [];
209
+ const otelSpans = [];
210
+ for (const e of entries.sort((a, b) => a.ts - b.ts)) {
211
+ const key = `${RECORD_PREFIX}${e.id}`;
212
+ const payload = byKey.get(key);
213
+ if (!payload) continue;
214
+ if (e.kind === 'rrweb') rrwebEvents.push(payload);
215
+ if (e.kind === 'span') otelSpans.push(payload);
216
+ }
217
+ let attrs = null;
218
+ try {
219
+ const raw = AsyncStorage ? await AsyncStorage.getItem(ATTRS_KEY) : null;
220
+ attrs = raw ? JSON.parse(raw) : null;
221
+ } catch (_e) {
222
+ attrs = null;
223
+ }
224
+ return {
225
+ rrwebEvents,
226
+ otelSpans,
227
+ attrs,
228
+ windowMs: effectiveWindowMs,
229
+ fromTs,
230
+ toTs
231
+ };
232
+ });
233
+ }
234
+ async clear() {
235
+ return this.enqueue(async () => {
236
+ if (!AsyncStorage) return;
237
+ await this.ensureIndexLoaded();
238
+ const keys = this.index.map(e => `${RECORD_PREFIX}${e.id}`);
239
+ this.index = [];
240
+ try {
241
+ await AsyncStorage.multiRemove([INDEX_KEY, ATTRS_KEY, ...keys]);
242
+ } catch (_e) {
243
+ // best-effort
244
+ }
245
+ });
246
+ }
247
+ }
248
+ //# sourceMappingURL=crashBuffer.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Platform","SpanStatusCode","AsyncStorage","isWeb","OS","require","default","_error","getItem","_key","Promise","resolve","setItem","_value","undefined","removeItem","multiRemove","_keys","multiGet","multiSet","_pairs","INDEX_KEY","ATTRS_KEY","RECORD_PREFIX","randomId","Date","now","toString","Math","random","slice","CrashBufferService","instance","index","indexLoaded","lastPruneAt","opChain","defaultWindowMs","listeners","Map","getInstance","enqueue","fn","next","then","ensureIndexLoaded","raw","JSON","parse","_e","setAttrs","attrs","stringify","appendEvent","payload","windowMs","appendRecord","ts","appendSpans","length","effectiveWindowMs","pairs","errorEvent","p","id","key","entry","kind","push","span","status","code","ERROR","pruneSoon","_emit","setDefaultWindowMs","max","on","event","listener","set","get","Set","add","off","delete","size","Array","from","cutoff","pruneOlderThan","cutoffTs","toRemove","filter","e","removeKeys","map","snapshot","toTs","fromTs","entries","keys","byKey","k","v","rrwebEvents","otelSpans","sort","a","b","clear"],"sourceRoot":"../../../src","sources":["services/crashBuffer.service.ts"],"mappings":"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","ignoreList":[]}
@@ -3,7 +3,8 @@
3
3
  import io from 'socket.io-client';
4
4
  import { Observable } from 'lib0/observable';
5
5
  import { logger } from "../utils/index.js";
6
- import { SESSION_ADD_EVENT, SESSION_AUTO_CREATED, SESSION_STOPPED_EVENT, SESSION_SUBSCRIBE_EVENT, SESSION_UNSUBSCRIBE_EVENT, SOCKET_SET_USER_EVENT, REMOTE_SESSION_RECORDING_START, REMOTE_SESSION_RECORDING_STOP, SESSION_STARTED_EVENT } from "../config/index.js";
6
+ import { SESSION_ADD_EVENT, SESSION_AUTO_CREATED, SESSION_STOPPED_EVENT, SESSION_SUBSCRIBE_EVENT, SESSION_UNSUBSCRIBE_EVENT, SOCKET_SET_USER_EVENT, REMOTE_SESSION_RECORDING_START, REMOTE_SESSION_RECORDING_STOP, SESSION_STARTED_EVENT, SESSION_SAVE_BUFFER_EVENT } from "../config/index.js";
7
+ import { ATTR_MULTIPLAYER_SESSION_CLIENT_ID } from '@multiplayer-app/session-recorder-common';
7
8
  const MAX_RECONNECTION_ATTEMPTS = 2;
8
9
  export class SocketService extends Observable {
9
10
  socket = null;
@@ -66,7 +67,10 @@ export class SocketService extends Observable {
66
67
  this.socket = io(this.options.socketUrl, {
67
68
  path: '/v0/radar/ws',
68
69
  auth: {
69
- 'x-api-key': this.options.apiKey
70
+ 'x-api-key': this.options.apiKey,
71
+ ...(this.options.clientId ? {
72
+ [ATTR_MULTIPLAYER_SESSION_CLIENT_ID]: this.options.clientId
73
+ } : {})
70
74
  },
71
75
  reconnectionAttempts: 2,
72
76
  transports: ['websocket']
@@ -100,6 +104,9 @@ export class SocketService extends Observable {
100
104
  this.socket.on(REMOTE_SESSION_RECORDING_STOP, data => {
101
105
  this.emit(REMOTE_SESSION_RECORDING_STOP, [data]);
102
106
  });
107
+ this.socket.on(SESSION_SAVE_BUFFER_EVENT, data => {
108
+ this.emit(SESSION_SAVE_BUFFER_EVENT, [data]);
109
+ });
103
110
  }
104
111
  checkReconnectionAttempts() {
105
112
  if (this.attempts >= MAX_RECONNECTION_ATTEMPTS) {
@@ -1 +1 @@
1
- {"version":3,"names":["io","Observable","logger","SESSION_ADD_EVENT","SESSION_AUTO_CREATED","SESSION_STOPPED_EVENT","SESSION_SUBSCRIBE_EVENT","SESSION_UNSUBSCRIBE_EVENT","SOCKET_SET_USER_EVENT","REMOTE_SESSION_RECORDING_START","REMOTE_SESSION_RECORDING_STOP","SESSION_STARTED_EVENT","MAX_RECONNECTION_ATTEMPTS","SocketService","socket","queue","isConnecting","isConnected","attempts","sessionId","constructor","options","apiKey","socketUrl","keepAlive","init","config","_initConnection","updateConfigs","hasChanges","Object","keys","some","key","typedKey","undefined","connected","close","then","path","auth","reconnectionAttempts","transports","on","info","flushQueue","_err","err","checkReconnectionAttempts","error","data","emit","emitSocketEvent","name","push","length","event","shift","send","subscribeToSession","session","shortId","_id","payload","projectId","project","workspaceId","workspace","debugSessionId","sessionType","creationType","unsubscribeFromSession","stopSession","setUser","userAttributes","Promise","resolve","setTimeout","disconnect"],"sourceRoot":"../../../src","sources":["services/socket.service.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["io","Observable","logger","SESSION_ADD_EVENT","SESSION_AUTO_CREATED","SESSION_STOPPED_EVENT","SESSION_SUBSCRIBE_EVENT","SESSION_UNSUBSCRIBE_EVENT","SOCKET_SET_USER_EVENT","REMOTE_SESSION_RECORDING_START","REMOTE_SESSION_RECORDING_STOP","SESSION_STARTED_EVENT","SESSION_SAVE_BUFFER_EVENT","ATTR_MULTIPLAYER_SESSION_CLIENT_ID","MAX_RECONNECTION_ATTEMPTS","SocketService","socket","queue","isConnecting","isConnected","attempts","sessionId","constructor","options","apiKey","socketUrl","keepAlive","init","config","_initConnection","updateConfigs","hasChanges","Object","keys","some","key","typedKey","undefined","connected","close","then","path","auth","clientId","reconnectionAttempts","transports","on","info","flushQueue","_err","err","checkReconnectionAttempts","error","data","emit","emitSocketEvent","name","push","length","event","shift","send","subscribeToSession","session","shortId","_id","payload","projectId","project","workspaceId","workspace","debugSessionId","sessionType","creationType","unsubscribeFromSession","stopSession","setUser","userAttributes","Promise","resolve","setTimeout","disconnect"],"sourceRoot":"../../../src","sources":["services/socket.service.ts"],"mappings":"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","ignoreList":[]}
@@ -6,12 +6,13 @@ import { TracerReactNativeSDK } from "./otel/index.js";
6
6
  import { RecorderReactNativeSDK } from "./recorder/index.js";
7
7
  import { logger } from "./utils/index.js";
8
8
  import { SessionState } from "./types/index.js";
9
- import { SESSION_STOPPED_EVENT, REMOTE_SESSION_RECORDING_START, REMOTE_SESSION_RECORDING_STOP } from "./config/index.js";
9
+ import { SESSION_STOPPED_EVENT, REMOTE_SESSION_RECORDING_START, REMOTE_SESSION_RECORDING_STOP, SESSION_SAVE_BUFFER_EVENT } from "./config/index.js";
10
10
  import { getFormattedDate, isSessionActive, getNavigatorInfo } from "./utils/index.js";
11
11
  import { setShouldRecordHttpData, setMaxCapturingHttpPayloadSize } from "./patch/index.js";
12
12
  import { BASE_CONFIG, getSessionRecorderConfig } from "./config/index.js";
13
13
  import { StorageService } from "./services/storage.service.js";
14
14
  import { NetworkService } from "./services/network.service.js";
15
+ import { CrashBufferService } from "./services/crashBuffer.service.js";
15
16
  import { ApiService } from "./services/api.service.js";
16
17
  import { SocketService } from "./services/socket.service.js";
17
18
  class SessionRecorder extends Observable {
@@ -21,6 +22,8 @@ class SessionRecorder extends Observable {
21
22
  _recorder = new RecorderReactNativeSDK();
22
23
  _storageService = StorageService.getInstance();
23
24
  _networkService = NetworkService.getInstance();
25
+ _crashBuffer = CrashBufferService.getInstance();
26
+ _isFlushingBuffer = false;
24
27
  _startRequestController = null;
25
28
 
26
29
  // Whether the session recorder is initialized
@@ -131,6 +134,95 @@ class SessionRecorder extends Observable {
131
134
  this.error = e?.message || 'Failed to capture exception';
132
135
  }
133
136
  }
137
+ async flushBuffer(payload) {
138
+ if (!this._configs?.buffering?.enabled) return null;
139
+ if (this._isFlushingBuffer) return null;
140
+ if (this.sessionState !== SessionState.stopped || this.sessionId) return null;
141
+ const windowMs = Math.max(10_000, (this._configs.buffering.windowMinutes || 2) * 60 * 1000);
142
+ this._isFlushingBuffer = true;
143
+ try {
144
+ const reason = payload?.reason || 'manual';
145
+ await this._crashBuffer.setAttrs({
146
+ sessionAttributes: this.sessionAttributes,
147
+ resourceAttributes: getNavigatorInfo(),
148
+ userAttributes: this._userAttributes
149
+ });
150
+ const snapshot = await this._crashBuffer.snapshot(windowMs);
151
+ if (snapshot.rrwebEvents.length === 0 && snapshot.otelSpans.length === 0) {
152
+ return null;
153
+ }
154
+ const request = {
155
+ name: `${this._configs.application} ${getFormattedDate(new Date())}`,
156
+ stoppedAt: new Date().toISOString(),
157
+ sessionAttributes: this.sessionAttributes,
158
+ resourceAttributes: getNavigatorInfo(),
159
+ ...(this._userAttributes ? {
160
+ userAttributes: this._userAttributes
161
+ } : {}),
162
+ debugSessionData: {
163
+ meta: {
164
+ reason,
165
+ windowMs: snapshot.windowMs,
166
+ fromTs: snapshot.fromTs,
167
+ toTs: snapshot.toTs
168
+ },
169
+ events: snapshot.rrwebEvents,
170
+ spans: snapshot.otelSpans.map(s => s.span),
171
+ attrs: snapshot.attrs
172
+ }
173
+ };
174
+ try {
175
+ const res = await this._apiService.startSession(request);
176
+ await this._crashBuffer.clear();
177
+ return res;
178
+ } catch (_e) {
179
+ // swallow: flush is best-effort; never throw into app code
180
+ return null;
181
+ }
182
+ } finally {
183
+ this._isFlushingBuffer = false;
184
+ }
185
+ }
186
+ async _flushBuffer(sessionId) {
187
+ if (!this._configs?.buffering?.enabled) return null;
188
+ if (this._isFlushingBuffer) return null;
189
+ if (this.sessionState !== SessionState.stopped || this.sessionId) return null;
190
+ const windowMs = Math.max(10_000, (this._configs.buffering.windowMinutes || 2) * 60 * 1000);
191
+ this._isFlushingBuffer = true;
192
+ try {
193
+ const snapshot = await this._crashBuffer.snapshot(windowMs);
194
+ if (snapshot.rrwebEvents.length === 0 && snapshot.otelSpans.length === 0) {
195
+ return null;
196
+ }
197
+ const spans = snapshot.otelSpans.map(s => s.span);
198
+ const events = snapshot.rrwebEvents.map(e => e.event);
199
+ await Promise.all([this._tracer.exportTraces(spans), this._apiService.exportEvents(sessionId, {
200
+ events
201
+ }), this._apiService.updateSessionAttributes(sessionId, {
202
+ name: this._getSessionName(),
203
+ sessionAttributes: this.sessionAttributes,
204
+ resourceAttributes: getNavigatorInfo(),
205
+ userAttributes: this._userAttributes || undefined
206
+ })]);
207
+ } catch (_e) {
208
+ // swallow: flush is best-effort; never throw into app code
209
+ } finally {
210
+ await this._crashBuffer.clear();
211
+ this._isFlushingBuffer = false;
212
+ }
213
+ }
214
+ async _createExceptionSession(span) {
215
+ try {
216
+ const session = await this._apiService.createErrorSession({
217
+ span
218
+ });
219
+ if (session) {
220
+ void this._flushBuffer(session._id);
221
+ }
222
+ } catch (_ignored) {
223
+ // best-effort
224
+ }
225
+ }
134
226
  async _loadStoredSessionData() {
135
227
  try {
136
228
  await StorageService.initialize();
@@ -170,22 +262,63 @@ class SessionRecorder extends Observable {
170
262
  await this._loadStoredSessionData();
171
263
  setMaxCapturingHttpPayloadSize(this._configs.maxCapturingHttpPayloadSize);
172
264
  setShouldRecordHttpData(this._configs.captureBody, this._configs.captureHeaders);
265
+
266
+ // Crash buffer wiring (RN): set BEFORE tracer init so early spans don't get exported.
267
+ const bufferEnabled = Boolean(this._configs.buffering?.enabled);
268
+ const windowMs = Math.max(10_000, (this._configs.buffering?.windowMinutes || 2) * 60 * 1000);
269
+ this._tracer.setCrashBuffer(bufferEnabled ? this._crashBuffer : undefined, windowMs);
173
270
  this._tracer.init(this._configs);
174
271
  this._apiService.init(this._configs);
175
272
  this._socketService.init({
176
273
  apiKey: this._configs.apiKey,
177
274
  socketUrl: this._configs.apiBaseUrl,
178
- keepAlive: this._configs.useWebsocket
275
+ keepAlive: this._configs.useWebsocket,
276
+ clientId: this._tracer.clientId
277
+ });
278
+ this._recorder.init(this._configs, this._socketService, bufferEnabled ? this._crashBuffer : undefined, {
279
+ enabled: bufferEnabled,
280
+ windowMs
281
+ });
282
+ this._crashBuffer.on('error-span-appended', payload => {
283
+ if (this.sessionState !== SessionState.stopped || this.sessionId) return;
284
+ if (!payload.span) return;
285
+ this._createExceptionSession(payload.span);
179
286
  });
180
- this._recorder.init(this._configs, this._socketService);
181
287
  await this._networkService.init();
182
288
  this._setupNetworkCallbacks();
183
289
  this._registerSocketServiceListeners();
184
290
  if (this.sessionId && (this.sessionState === SessionState.started || this.sessionState === SessionState.paused)) {
185
291
  this._start();
292
+ } else {
293
+ this._startBufferOnlyRecording();
186
294
  }
187
295
  this.emit('init', []);
188
296
  }
297
+ _startBufferOnlyRecording() {
298
+ if (!this._configs?.buffering?.enabled) return;
299
+ if (this.sessionState !== SessionState.stopped || this.sessionId) return;
300
+ const windowMs = Math.max(10_000, (this._configs.buffering.windowMinutes || 2) * 60 * 1000);
301
+
302
+ // Best-effort: persist current attrs so flush has context.
303
+ this._crashBuffer.setAttrs({
304
+ sessionAttributes: this.sessionAttributes,
305
+ resourceAttributes: getNavigatorInfo(),
306
+ userAttributes: this._userAttributes
307
+ });
308
+
309
+ // Wire buffer into tracer + recorder (only used when sessionId is null).
310
+ this._tracer.setCrashBuffer(this._crashBuffer, windowMs);
311
+ this._recorder.init(this._configs, this._socketService, this._crashBuffer, {
312
+ enabled: true,
313
+ windowMs
314
+ });
315
+
316
+ // Start capturing events without an active debug session id.
317
+ try {
318
+ this._recorder.stop();
319
+ } catch (_e) {}
320
+ this._recorder.start(null, SessionType.MANUAL);
321
+ }
189
322
 
190
323
  /**
191
324
  * Register socket service event listeners
@@ -207,6 +340,11 @@ class SessionRecorder extends Observable {
207
340
  this.stop();
208
341
  }
209
342
  });
343
+ this._socketService.on(SESSION_SAVE_BUFFER_EVENT, payload => {
344
+ if (payload?.debugSession?._id) {
345
+ void this._flushBuffer(payload.debugSession._id);
346
+ }
347
+ });
210
348
  }
211
349
 
212
350
  /**
@@ -437,6 +575,10 @@ class SessionRecorder extends Observable {
437
575
  this.sessionState = SessionState.started;
438
576
  this.sessionType = this.sessionType;
439
577
  if (this.sessionId) {
578
+ // Switch from buffer-only recording to session recording cleanly.
579
+ try {
580
+ this._recorder.stop();
581
+ } catch (_e) {}
440
582
  this._tracer.start(this.sessionId, this.sessionType);
441
583
  this._recorder.start(this.sessionId, this.sessionType);
442
584
  if (this.session) {
@@ -451,15 +593,16 @@ class SessionRecorder extends Observable {
451
593
  _stop() {
452
594
  this.sessionState = SessionState.stopped;
453
595
  this._socketService.unsubscribeFromSession(true);
454
- this._tracer.shutdown();
596
+ this._tracer.stop();
455
597
  this._recorder.stop();
598
+ this._startBufferOnlyRecording();
456
599
  }
457
600
 
458
601
  /**
459
602
  * Pause the session tracing and recording
460
603
  */
461
604
  _pause() {
462
- this._tracer.shutdown();
605
+ this._tracer.stop();
463
606
  this._recorder.stop();
464
607
  this.sessionState = SessionState.paused;
465
608
  }
@@ -469,7 +612,10 @@ class SessionRecorder extends Observable {
469
612
  */
470
613
  _resume() {
471
614
  if (this.sessionId) {
472
- this._tracer.setSessionId(this.sessionId, this.sessionType);
615
+ this._tracer.start(this.sessionId, this.sessionType);
616
+ try {
617
+ this._recorder.stop();
618
+ } catch (_e) {}
473
619
  this._recorder.start(this.sessionId, this.sessionType);
474
620
  }
475
621
  this.sessionState = SessionState.started;