@multiplayer-app/session-recorder-react-native 1.0.1-beta.4 → 1.0.1-beta.5

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 (165) hide show
  1. package/android/src/main/java/com/multiplayer/sessionrecordernative/SessionRecorderNativeModule.kt +2 -2
  2. package/lib/module/components/SessionRecorderWidget/ErrorBanner.js.map +1 -1
  3. package/lib/module/components/SessionRecorderWidget/ModalHeader.js.map +1 -1
  4. package/lib/module/components/SessionRecorderWidget/SessionRecorderWidget.js.map +1 -1
  5. package/lib/module/components/SessionRecorderWidget/icons.js.map +1 -1
  6. package/lib/module/components/SessionRecorderWidget/styles.js.map +1 -1
  7. package/lib/module/config/constants.js.map +1 -1
  8. package/lib/module/config/defaults.js.map +1 -1
  9. package/lib/module/config/masking.js.map +1 -1
  10. package/lib/module/config/session-recorder.js.map +1 -1
  11. package/lib/module/config/validators.js.map +1 -1
  12. package/lib/module/config/widget.js.map +1 -1
  13. package/lib/module/context/SessionRecorderStore.js.map +1 -1
  14. package/lib/module/context/useSessionRecorderStore.js.map +1 -1
  15. package/lib/module/context/useStoreSelector.js.map +1 -1
  16. package/lib/module/native/SessionRecorderNative.js.map +1 -1
  17. package/lib/module/native/index.js.map +1 -1
  18. package/lib/module/otel/helpers.js +1 -1
  19. package/lib/module/otel/helpers.js.map +1 -1
  20. package/lib/module/otel/index.js.map +1 -1
  21. package/lib/module/otel/instrumentations/index.js.map +1 -1
  22. package/lib/module/patch/xhr.js.map +1 -1
  23. package/lib/module/recorder/eventExporter.js.map +1 -1
  24. package/lib/module/recorder/gestureRecorder.js.map +1 -1
  25. package/lib/module/recorder/index.js.map +1 -1
  26. package/lib/module/recorder/navigationTracker.js.map +1 -1
  27. package/lib/module/recorder/screenRecorder.js.map +1 -1
  28. package/lib/module/services/api.service.js.map +1 -1
  29. package/lib/module/services/network.service.js.map +1 -1
  30. package/lib/module/services/screenMaskingService.js.map +1 -1
  31. package/lib/module/services/storage.service.js.map +1 -1
  32. package/lib/module/session-recorder.js.map +1 -1
  33. package/lib/module/types/index.js.map +1 -1
  34. package/lib/module/types/session-recorder.js.map +1 -1
  35. package/lib/module/utils/app-metadata.js +2 -2
  36. package/lib/module/utils/constants.optional.js.map +1 -1
  37. package/lib/module/utils/createStore.js.map +1 -1
  38. package/lib/module/utils/logger.js +0 -8
  39. package/lib/module/utils/logger.js.map +1 -1
  40. package/lib/module/utils/platform.js +1 -1
  41. package/lib/module/utils/platform.js.map +1 -1
  42. package/lib/module/utils/rrweb-events.js.map +1 -1
  43. package/lib/module/utils/session.js.map +1 -1
  44. package/lib/module/utils/shallowEqual.js.map +1 -1
  45. package/lib/module/utils/time.js.map +1 -1
  46. package/lib/module/version.js +1 -1
  47. package/lib/typescript/src/components/ScreenRecorderView/index.d.ts +1 -1
  48. package/lib/typescript/src/components/SessionRecorderWidget/ErrorBanner.d.ts.map +1 -1
  49. package/lib/typescript/src/components/SessionRecorderWidget/ModalHeader.d.ts.map +1 -1
  50. package/lib/typescript/src/components/SessionRecorderWidget/SessionRecorderWidget.d.ts.map +1 -1
  51. package/lib/typescript/src/components/SessionRecorderWidget/icons.d.ts.map +1 -1
  52. package/lib/typescript/src/components/SessionRecorderWidget/index.d.ts +1 -1
  53. package/lib/typescript/src/components/SessionRecorderWidget/styles.d.ts.map +1 -1
  54. package/lib/typescript/src/components/index.d.ts.map +1 -1
  55. package/lib/typescript/src/config/constants.d.ts.map +1 -1
  56. package/lib/typescript/src/config/defaults.d.ts.map +1 -1
  57. package/lib/typescript/src/config/index.d.ts.map +1 -1
  58. package/lib/typescript/src/config/masking.d.ts.map +1 -1
  59. package/lib/typescript/src/config/session-recorder.d.ts.map +1 -1
  60. package/lib/typescript/src/config/validators.d.ts.map +1 -1
  61. package/lib/typescript/src/config/widget.d.ts +1 -1
  62. package/lib/typescript/src/config/widget.d.ts.map +1 -1
  63. package/lib/typescript/src/context/SessionRecorderStore.d.ts.map +1 -1
  64. package/lib/typescript/src/context/useSessionRecorderStore.d.ts +3 -3
  65. package/lib/typescript/src/context/useSessionRecorderStore.d.ts.map +1 -1
  66. package/lib/typescript/src/context/useStoreSelector.d.ts.map +1 -1
  67. package/lib/typescript/src/index.d.ts.map +1 -1
  68. package/lib/typescript/src/native/SessionRecorderNative.d.ts.map +1 -1
  69. package/lib/typescript/src/native/index.d.ts +1 -1
  70. package/lib/typescript/src/native/index.d.ts.map +1 -1
  71. package/lib/typescript/src/otel/helpers.d.ts.map +1 -1
  72. package/lib/typescript/src/otel/index.d.ts.map +1 -1
  73. package/lib/typescript/src/otel/instrumentations/index.d.ts.map +1 -1
  74. package/lib/typescript/src/patch/index.d.ts.map +1 -1
  75. package/lib/typescript/src/patch/xhr.d.ts.map +1 -1
  76. package/lib/typescript/src/recorder/eventExporter.d.ts.map +1 -1
  77. package/lib/typescript/src/recorder/gestureRecorder.d.ts.map +1 -1
  78. package/lib/typescript/src/recorder/index.d.ts.map +1 -1
  79. package/lib/typescript/src/recorder/navigationTracker.d.ts.map +1 -1
  80. package/lib/typescript/src/recorder/screenRecorder.d.ts.map +1 -1
  81. package/lib/typescript/src/services/api.service.d.ts.map +1 -1
  82. package/lib/typescript/src/services/network.service.d.ts.map +1 -1
  83. package/lib/typescript/src/services/screenMaskingService.d.ts.map +1 -1
  84. package/lib/typescript/src/services/storage.service.d.ts.map +1 -1
  85. package/lib/typescript/src/session-recorder.d.ts.map +1 -1
  86. package/lib/typescript/src/types/configs.d.ts.map +1 -1
  87. package/lib/typescript/src/types/index.d.ts.map +1 -1
  88. package/lib/typescript/src/types/session-recorder.d.ts +4 -4
  89. package/lib/typescript/src/types/session-recorder.d.ts.map +1 -1
  90. package/lib/typescript/src/types/session.d.ts.map +1 -1
  91. package/lib/typescript/src/utils/app-metadata.d.ts.map +1 -1
  92. package/lib/typescript/src/utils/constants.optional.d.ts.map +1 -1
  93. package/lib/typescript/src/utils/constants.optional.expo.d.ts.map +1 -1
  94. package/lib/typescript/src/utils/createStore.d.ts.map +1 -1
  95. package/lib/typescript/src/utils/index.d.ts.map +1 -1
  96. package/lib/typescript/src/utils/logger.d.ts +1 -1
  97. package/lib/typescript/src/utils/logger.d.ts.map +1 -1
  98. package/lib/typescript/src/utils/platform.d.ts.map +1 -1
  99. package/lib/typescript/src/utils/request-utils.d.ts.map +1 -1
  100. package/lib/typescript/src/utils/rrweb-events.d.ts.map +1 -1
  101. package/lib/typescript/src/utils/session.d.ts.map +1 -1
  102. package/lib/typescript/src/utils/shallowEqual.d.ts.map +1 -1
  103. package/lib/typescript/src/utils/time.d.ts.map +1 -1
  104. package/lib/typescript/src/utils/type-utils.d.ts.map +1 -1
  105. package/lib/typescript/src/version.d.ts.map +1 -1
  106. package/package.json +1 -1
  107. package/src/components/ScreenRecorderView/index.ts +1 -1
  108. package/src/components/SessionRecorderWidget/ErrorBanner.tsx +14 -14
  109. package/src/components/SessionRecorderWidget/ModalHeader.tsx +11 -9
  110. package/src/components/SessionRecorderWidget/SessionRecorderWidget.tsx +70 -56
  111. package/src/components/SessionRecorderWidget/icons.tsx +58 -30
  112. package/src/components/SessionRecorderWidget/index.ts +1 -1
  113. package/src/components/SessionRecorderWidget/styles.ts +17 -18
  114. package/src/components/index.ts +2 -2
  115. package/src/config/constants.ts +19 -20
  116. package/src/config/defaults.ts +35 -31
  117. package/src/config/index.ts +5 -5
  118. package/src/config/masking.ts +44 -18
  119. package/src/config/session-recorder.ts +54 -26
  120. package/src/config/validators.ts +43 -20
  121. package/src/config/widget.ts +24 -15
  122. package/src/context/SessionRecorderStore.ts +19 -18
  123. package/src/context/useSessionRecorderStore.ts +17 -10
  124. package/src/context/useStoreSelector.ts +20 -18
  125. package/src/index.ts +7 -7
  126. package/src/native/SessionRecorderNative.ts +83 -67
  127. package/src/native/index.ts +5 -1
  128. package/src/otel/helpers.ts +109 -93
  129. package/src/otel/index.ts +46 -49
  130. package/src/otel/instrumentations/index.ts +44 -41
  131. package/src/patch/index.ts +1 -1
  132. package/src/patch/xhr.ts +77 -78
  133. package/src/recorder/eventExporter.ts +63 -68
  134. package/src/recorder/gestureRecorder.ts +359 -212
  135. package/src/recorder/index.ts +75 -62
  136. package/src/recorder/navigationTracker.ts +120 -97
  137. package/src/recorder/screenRecorder.ts +214 -163
  138. package/src/services/api.service.ts +49 -48
  139. package/src/services/network.service.ts +67 -58
  140. package/src/services/screenMaskingService.ts +81 -50
  141. package/src/services/storage.service.ts +99 -70
  142. package/src/session-recorder.ts +270 -214
  143. package/src/types/configs.ts +53 -31
  144. package/src/types/expo-constants.d.ts +2 -2
  145. package/src/types/index.ts +16 -18
  146. package/src/types/session-recorder.ts +106 -111
  147. package/src/types/session.ts +45 -45
  148. package/src/utils/app-metadata.ts +9 -9
  149. package/src/utils/constants.optional.expo.ts +3 -3
  150. package/src/utils/constants.optional.ts +14 -12
  151. package/src/utils/createStore.ts +23 -20
  152. package/src/utils/index.ts +7 -7
  153. package/src/utils/logger.ts +87 -58
  154. package/src/utils/platform.ts +149 -118
  155. package/src/utils/request-utils.ts +15 -15
  156. package/src/utils/rrweb-events.ts +47 -34
  157. package/src/utils/session.ts +15 -12
  158. package/src/utils/shallowEqual.ts +16 -10
  159. package/src/utils/time.ts +7 -4
  160. package/src/utils/type-utils.ts +36 -36
  161. package/src/version.ts +1 -1
  162. package/android/src/main/java/com/multiplayer/sessionrecordernative/SessionRecorderNativeModuleSpec.kt +0 -51
  163. package/android/src/main/java/com/xxx/XxxModule.kt +0 -23
  164. package/ios/Xxx.h +0 -5
  165. package/ios/Xxx.mm +0 -21
@@ -1,11 +1,10 @@
1
+ import { SessionType } from '@multiplayer-app/session-recorder-common';
2
+ import { Observable } from 'lib0/observable';
3
+ import { type eventWithTime } from '@rrweb/types';
1
4
 
2
- import { SessionType } from '@multiplayer-app/session-recorder-common'
3
- import { Observable } from 'lib0/observable'
4
- import { type eventWithTime } from '@rrweb/types'
5
-
6
- import { TracerReactNativeSDK } from './otel'
7
- import { RecorderReactNativeSDK } from './recorder'
8
- import { logger } from './utils'
5
+ import { TracerReactNativeSDK } from './otel';
6
+ import { RecorderReactNativeSDK } from './recorder';
7
+ import { logger } from './utils';
9
8
 
10
9
  import {
11
10
  SessionState,
@@ -13,147 +12,162 @@ import {
13
12
  type ISessionRecorder,
14
13
  type SessionRecorderConfigs,
15
14
  type SessionRecorderOptions,
16
- type EventRecorder
17
- } from './types'
18
- import { getFormattedDate, isSessionActive, getNavigatorInfo } from './utils'
19
- import { setMaxCapturingHttpPayloadSize, setShouldRecordHttpData } from './patch/xhr'
20
- import { BASE_CONFIG, getSessionRecorderConfig } from './config'
21
-
22
- import { StorageService } from './services/storage.service'
23
- import { NetworkService } from './services/network.service'
24
- import { ApiService, type StartSessionRequest, type StopSessionRequest } from './services/api.service'
25
-
26
-
27
- type SessionRecorderEvents = 'state-change'
28
-
29
- class SessionRecorder extends Observable<SessionRecorderEvents> implements ISessionRecorder, EventRecorder {
15
+ type EventRecorder,
16
+ } from './types';
17
+ import { getFormattedDate, isSessionActive, getNavigatorInfo } from './utils';
18
+ import {
19
+ setMaxCapturingHttpPayloadSize,
20
+ setShouldRecordHttpData,
21
+ } from './patch/xhr';
22
+ import { BASE_CONFIG, getSessionRecorderConfig } from './config';
30
23
 
31
- private _configs: SessionRecorderConfigs
32
- private _apiService = new ApiService()
33
- private _tracer = new TracerReactNativeSDK()
34
- private _recorder = new RecorderReactNativeSDK()
35
- private _storageService = StorageService.getInstance()
36
- private _networkService = NetworkService.getInstance()
37
- private _startRequestController: AbortController | null = null
24
+ import { StorageService } from './services/storage.service';
25
+ import { NetworkService } from './services/network.service';
26
+ import {
27
+ ApiService,
28
+ type StartSessionRequest,
29
+ type StopSessionRequest,
30
+ } from './services/api.service';
31
+
32
+ type SessionRecorderEvents = 'state-change';
33
+
34
+ class SessionRecorder
35
+ extends Observable<SessionRecorderEvents>
36
+ implements ISessionRecorder, EventRecorder
37
+ {
38
+ private _configs: SessionRecorderConfigs;
39
+ private _apiService = new ApiService();
40
+ private _tracer = new TracerReactNativeSDK();
41
+ private _recorder = new RecorderReactNativeSDK();
42
+ private _storageService = StorageService.getInstance();
43
+ private _networkService = NetworkService.getInstance();
44
+ private _startRequestController: AbortController | null = null;
38
45
 
39
46
  // Whether the session recorder is initialized
40
- private _isInitialized = false
47
+ private _isInitialized = false;
41
48
  get isInitialized(): boolean {
42
- return this._isInitialized
49
+ return this._isInitialized;
43
50
  }
44
51
  set isInitialized(isInitialized: boolean) {
45
- this._isInitialized = isInitialized
52
+ this._isInitialized = isInitialized;
46
53
  }
47
54
 
48
55
  // Session ID and state are stored in AsyncStorage
49
- private _sessionId: string | null = null
56
+ private _sessionId: string | null = null;
50
57
  get sessionId(): string | null {
51
- return this._sessionId
58
+ return this._sessionId;
52
59
  }
53
60
  set sessionId(sessionId: string | null) {
54
- this._sessionId = sessionId
61
+ this._sessionId = sessionId;
55
62
  if (sessionId) {
56
- this._storageService.saveSessionId(sessionId)
63
+ this._storageService.saveSessionId(sessionId);
57
64
  }
58
65
  }
59
66
 
60
- private _sessionType: SessionType = SessionType.PLAIN
67
+ private _sessionType: SessionType = SessionType.PLAIN;
61
68
  get sessionType(): SessionType {
62
- return this._sessionType
69
+ return this._sessionType;
63
70
  }
64
71
  set sessionType(sessionType: SessionType) {
65
- this._sessionType = sessionType
66
- this._storageService.saveSessionType(sessionType)
72
+ this._sessionType = sessionType;
73
+ this._storageService.saveSessionType(sessionType);
67
74
  }
68
75
 
69
76
  get continuousRecording(): boolean {
70
- return this.sessionType === SessionType.CONTINUOUS
77
+ return this.sessionType === SessionType.CONTINUOUS;
71
78
  }
72
79
 
73
- private _sessionState: SessionState | null = null
80
+ private _sessionState: SessionState | null = null;
74
81
  get sessionState(): SessionState | null {
75
- return this._sessionState || SessionState.stopped
82
+ return this._sessionState || SessionState.stopped;
76
83
  }
77
84
  set sessionState(state: SessionState | null) {
78
- this._sessionState = state
79
- this.emit('state-change', [state || SessionState.stopped, this.sessionType])
85
+ this._sessionState = state;
86
+ this.emit('state-change', [
87
+ state || SessionState.stopped,
88
+ this.sessionType,
89
+ ]);
80
90
  if (state) {
81
- this._storageService.saveSessionState(state)
91
+ this._storageService.saveSessionState(state);
82
92
  }
83
93
  }
84
94
 
85
- private _session: ISession | null = null
95
+ private _session: ISession | null = null;
86
96
  get session(): ISession | null {
87
- return this._session
97
+ return this._session;
88
98
  }
89
99
  set session(session: ISession | null) {
90
- this._session = session
100
+ this._session = session;
91
101
  if (session) {
92
- this._storageService.saveSessionObject(session)
102
+ this._storageService.saveSessionObject(session);
93
103
  }
94
104
  }
95
105
 
96
- private _sessionAttributes: Record<string, any> | null = null
106
+ private _sessionAttributes: Record<string, any> | null = null;
97
107
  get sessionAttributes(): Record<string, any> {
98
- return this._sessionAttributes || {}
108
+ return this._sessionAttributes || {};
99
109
  }
100
110
  set sessionAttributes(attributes: Record<string, any> | null) {
101
- this._sessionAttributes = attributes
111
+ this._sessionAttributes = attributes;
102
112
  }
103
113
 
104
114
  /**
105
115
  * Error message getter and setter
106
116
  */
107
117
  public get error(): string {
108
- return this._error || ''
118
+ return this._error || '';
109
119
  }
110
120
 
111
121
  public set error(v: string) {
112
- this._error = v
122
+ this._error = v;
113
123
  }
114
- private _error: string = ''
124
+ private _error: string = '';
115
125
 
116
126
  /**
117
127
  * React Native doesn't have HTML elements, so we return null
118
128
  */
119
129
  public get sessionWidgetButtonElement(): any {
120
- return null
130
+ return null;
121
131
  }
122
132
 
123
133
  public get config(): SessionRecorderConfigs {
124
- return this._configs
134
+ return this._configs;
125
135
  }
126
136
  /**
127
137
  * Initialize debugger with default or custom configurations
128
138
  */
129
139
  constructor() {
130
- super()
131
- this._configs = BASE_CONFIG
140
+ super();
141
+ this._configs = BASE_CONFIG;
132
142
  // Initialize with stored session data if available
133
- StorageService.initialize()
143
+ StorageService.initialize();
134
144
  }
135
145
 
136
146
  private async _loadStoredSessionData(): Promise<void> {
137
147
  try {
138
- await StorageService.initialize()
139
- const storedData = await this._storageService.getAllSessionData()
148
+ await StorageService.initialize();
149
+ const storedData = await this._storageService.getAllSessionData();
140
150
  if (isSessionActive(storedData.sessionObject, storedData.sessionType)) {
141
- this.session = storedData.sessionObject
142
- this.sessionId = storedData.sessionId
143
- this.sessionType = storedData.sessionType || SessionType.PLAIN
144
- this.sessionState = storedData.sessionState
151
+ this.session = storedData.sessionObject;
152
+ this.sessionId = storedData.sessionId;
153
+ this.sessionType = storedData.sessionType || SessionType.PLAIN;
154
+ this.sessionState = storedData.sessionState;
145
155
  } else {
146
- this.session = null
147
- this.sessionId = null
148
- this.sessionState = null
149
- this.sessionType = SessionType.PLAIN
156
+ this.session = null;
157
+ this.sessionId = null;
158
+ this.sessionState = null;
159
+ this.sessionType = SessionType.PLAIN;
150
160
  }
151
161
  } catch (error) {
152
- logger.error('SessionRecorder', 'Failed to load stored session data', error)
153
- this.session = null
154
- this.sessionId = null
155
- this.sessionState = null
156
- this.sessionType = SessionType.PLAIN
162
+ logger.error(
163
+ 'SessionRecorder',
164
+ 'Failed to load stored session data',
165
+ error
166
+ );
167
+ this.session = null;
168
+ this.sessionId = null;
169
+ this.sessionState = null;
170
+ this.sessionType = SessionType.PLAIN;
157
171
  }
158
172
  }
159
173
 
@@ -162,22 +176,29 @@ class SessionRecorder extends Observable<SessionRecorderEvents> implements ISess
162
176
  * @param configs - custom configurations for session debugger
163
177
  */
164
178
  public async init(configs: SessionRecorderOptions): Promise<void> {
165
- if (this._isInitialized) return
166
- this._isInitialized = true
167
- this._configs = getSessionRecorderConfig({ ...this._configs, ...configs })
168
- logger.configure(this._configs.logger)
169
- await this._loadStoredSessionData()
170
- setMaxCapturingHttpPayloadSize(this._configs.maxCapturingHttpPayloadSize)
171
- setShouldRecordHttpData(!this._configs.captureBody, this._configs.captureHeaders)
172
-
173
- this._tracer.init(this._configs)
174
- this._recorder.init(this._configs)
175
- this._apiService.init(this._configs)
176
- await this._networkService.init()
177
- this._setupNetworkCallbacks()
178
-
179
- if (this.sessionId && (this.sessionState === SessionState.started || this.sessionState === SessionState.paused)) {
180
- this._start()
179
+ if (this._isInitialized) return;
180
+ this._isInitialized = true;
181
+ this._configs = getSessionRecorderConfig({ ...this._configs, ...configs });
182
+ logger.configure(this._configs.logger);
183
+ await this._loadStoredSessionData();
184
+ setMaxCapturingHttpPayloadSize(this._configs.maxCapturingHttpPayloadSize);
185
+ setShouldRecordHttpData(
186
+ !this._configs.captureBody,
187
+ this._configs.captureHeaders
188
+ );
189
+
190
+ this._tracer.init(this._configs);
191
+ this._recorder.init(this._configs);
192
+ this._apiService.init(this._configs);
193
+ await this._networkService.init();
194
+ this._setupNetworkCallbacks();
195
+
196
+ if (
197
+ this.sessionId &&
198
+ (this.sessionState === SessionState.started ||
199
+ this.sessionState === SessionState.paused)
200
+ ) {
201
+ this._start();
181
202
  }
182
203
  }
183
204
 
@@ -187,13 +208,22 @@ class SessionRecorder extends Observable<SessionRecorderEvents> implements ISess
187
208
  private _setupNetworkCallbacks(): void {
188
209
  this._networkService.addCallback((state) => {
189
210
  if (!state.isConnected && this.sessionState === SessionState.started) {
190
- logger.info('SessionRecorder', 'Network went offline - pausing session recording')
191
- this.pause()
192
- } else if (state.isConnected && this.sessionState === SessionState.paused) {
193
- logger.info('SessionRecorder', 'Network came back online - resuming session recording')
194
- this.resume()
211
+ logger.info(
212
+ 'SessionRecorder',
213
+ 'Network went offline - pausing session recording'
214
+ );
215
+ this.pause();
216
+ } else if (
217
+ state.isConnected &&
218
+ this.sessionState === SessionState.paused
219
+ ) {
220
+ logger.info(
221
+ 'SessionRecorder',
222
+ 'Network came back online - resuming session recording'
223
+ );
224
+ this.resume();
195
225
  }
196
- })
226
+ });
197
227
  }
198
228
 
199
229
  /**
@@ -201,26 +231,35 @@ class SessionRecorder extends Observable<SessionRecorderEvents> implements ISess
201
231
  * @param type - the type of session to start
202
232
  * @param session - the session to start
203
233
  */
204
- public async start(type: SessionType = SessionType.PLAIN, session?: ISession): Promise<void> {
205
- this._checkOperation('start')
234
+ public async start(
235
+ type: SessionType = SessionType.PLAIN,
236
+ session?: ISession
237
+ ): Promise<void> {
238
+ this._checkOperation('start');
206
239
 
207
240
  // Check if offline - don't start recording if offline
208
241
  if (!this._networkService.isOnline()) {
209
- logger.warn('SessionRecorder', 'Cannot start session recording - device is offline')
210
- throw new Error('Cannot start session recording while offline')
242
+ logger.warn(
243
+ 'SessionRecorder',
244
+ 'Cannot start session recording - device is offline'
245
+ );
246
+ throw new Error('Cannot start session recording while offline');
211
247
  }
212
248
 
213
249
  // If continuous recording is disabled, force plain mode
214
- if (type === SessionType.CONTINUOUS && !this._configs?.showContinuousRecording) {
215
- type = SessionType.PLAIN
250
+ if (
251
+ type === SessionType.CONTINUOUS &&
252
+ !this._configs?.showContinuousRecording
253
+ ) {
254
+ type = SessionType.PLAIN;
216
255
  }
217
- logger.info('SessionRecorder', 'Starting session with type:', type)
218
- this.sessionType = type
219
- this._startRequestController = new AbortController()
256
+ logger.info('SessionRecorder', 'Starting session with type:', type);
257
+ this.sessionType = type;
258
+ this._startRequestController = new AbortController();
220
259
  if (session) {
221
- this._setupSessionAndStart(session, true)
260
+ this._setupSessionAndStart(session, true);
222
261
  } else {
223
- await this._createSessionAndStart()
262
+ await this._createSessionAndStart();
224
263
  }
225
264
  }
226
265
 
@@ -230,21 +269,21 @@ class SessionRecorder extends Observable<SessionRecorderEvents> implements ISess
230
269
  */
231
270
  public async stop(comment?: string): Promise<void> {
232
271
  try {
233
- this._checkOperation('stop')
234
- this._stop()
272
+ this._checkOperation('stop');
273
+ this._stop();
235
274
  if (this.continuousRecording) {
236
- await this._apiService.stopContinuousDebugSession(this.sessionId!)
237
- this.sessionType = SessionType.PLAIN
275
+ await this._apiService.stopContinuousDebugSession(this.sessionId!);
276
+ this.sessionType = SessionType.PLAIN;
238
277
  } else {
239
278
  const request: StopSessionRequest = {
240
279
  sessionAttributes: { comment },
241
280
  stoppedAt: Date.now(),
242
- }
243
- await this._apiService.stopSession(this.sessionId!, request)
281
+ };
282
+ await this._apiService.stopSession(this.sessionId!, request);
244
283
  }
245
- this._clearSession()
284
+ this._clearSession();
246
285
  } catch (error: any) {
247
- this.error = error.message
286
+ this.error = error.message;
248
287
  }
249
288
  }
250
289
 
@@ -253,10 +292,10 @@ class SessionRecorder extends Observable<SessionRecorderEvents> implements ISess
253
292
  */
254
293
  public async pause(): Promise<void> {
255
294
  try {
256
- this._checkOperation('pause')
257
- this._pause()
295
+ this._checkOperation('pause');
296
+ this._pause();
258
297
  } catch (error: any) {
259
- this.error = error.message
298
+ this.error = error.message;
260
299
  }
261
300
  }
262
301
 
@@ -265,10 +304,10 @@ class SessionRecorder extends Observable<SessionRecorderEvents> implements ISess
265
304
  */
266
305
  public async resume(): Promise<void> {
267
306
  try {
268
- this._checkOperation('resume')
269
- this._resume()
307
+ this._checkOperation('resume');
308
+ this._resume();
270
309
  } catch (error: any) {
271
- this.error = error.message
310
+ this.error = error.message;
272
311
  }
273
312
  }
274
313
 
@@ -277,17 +316,17 @@ class SessionRecorder extends Observable<SessionRecorderEvents> implements ISess
277
316
  */
278
317
  public async cancel(): Promise<void> {
279
318
  try {
280
- this._checkOperation('cancel')
281
- this._stop()
319
+ this._checkOperation('cancel');
320
+ this._stop();
282
321
  if (this.continuousRecording) {
283
- await this._apiService.stopContinuousDebugSession(this.sessionId!)
284
- this.sessionType = SessionType.PLAIN
322
+ await this._apiService.stopContinuousDebugSession(this.sessionId!);
323
+ this.sessionType = SessionType.PLAIN;
285
324
  } else {
286
- await this._apiService.cancelSession(this.sessionId!)
325
+ await this._apiService.cancelSession(this.sessionId!);
287
326
  }
288
- this._clearSession()
327
+ this._clearSession();
289
328
  } catch (error: any) {
290
- this.error = error.message
329
+ this.error = error.message;
291
330
  }
292
331
  }
293
332
 
@@ -296,9 +335,12 @@ class SessionRecorder extends Observable<SessionRecorderEvents> implements ISess
296
335
  */
297
336
  public async save(): Promise<any> {
298
337
  try {
299
- this._checkOperation('save')
300
- if (!this.continuousRecording || !this._configs?.showContinuousRecording) {
301
- return
338
+ this._checkOperation('save');
339
+ if (
340
+ !this.continuousRecording ||
341
+ !this._configs?.showContinuousRecording
342
+ ) {
343
+ return;
302
344
  }
303
345
 
304
346
  const res = await this._apiService.saveContinuousDebugSession(
@@ -309,16 +351,16 @@ class SessionRecorder extends Observable<SessionRecorderEvents> implements ISess
309
351
  stoppedAt: Date.now(),
310
352
  name: this.sessionAttributes.userName
311
353
  ? `${this.sessionAttributes.userName}'s session on ${getFormattedDate(
312
- Date.now(),
313
- { month: 'short', day: 'numeric' },
314
- )}`
354
+ Date.now(),
355
+ { month: 'short', day: 'numeric' }
356
+ )}`
315
357
  : `Session on ${getFormattedDate(Date.now())}`,
316
- },
317
- )
358
+ }
359
+ );
318
360
 
319
- return res
361
+ return res;
320
362
  } catch (error: any) {
321
- this.error = error.message
363
+ this.error = error.message;
322
364
  }
323
365
  }
324
366
 
@@ -327,7 +369,7 @@ class SessionRecorder extends Observable<SessionRecorderEvents> implements ISess
327
369
  * @param attributes - the attributes to set
328
370
  */
329
371
  public setSessionAttributes(attributes: Record<string, any>): void {
330
- this._sessionAttributes = attributes
372
+ this._sessionAttributes = attributes;
331
373
  }
332
374
 
333
375
  /**
@@ -336,11 +378,11 @@ class SessionRecorder extends Observable<SessionRecorderEvents> implements ISess
336
378
  * @returns {Promise<void>}
337
379
  */
338
380
  public async checkRemoteContinuousSession(
339
- sessionPayload?: Omit<ISession, '_id' | 'shortId'>,
381
+ sessionPayload?: Omit<ISession, '_id' | 'shortId'>
340
382
  ): Promise<void> {
341
- this._checkOperation('autoStartRemoteContinuousSession')
383
+ this._checkOperation('autoStartRemoteContinuousSession');
342
384
  if (!this._configs?.showContinuousRecording) {
343
- return
385
+ return;
344
386
  }
345
387
  const payload = {
346
388
  sessionAttributes: {
@@ -351,17 +393,17 @@ class SessionRecorder extends Observable<SessionRecorderEvents> implements ISess
351
393
  ...getNavigatorInfo(),
352
394
  ...(sessionPayload?.resourceAttributes || {}),
353
395
  },
354
- }
396
+ };
355
397
 
356
- const { state } = await this._apiService.checkRemoteSession(payload)
398
+ const { state } = await this._apiService.checkRemoteSession(payload);
357
399
 
358
400
  if (state == 'START') {
359
401
  if (this.sessionState !== SessionState.started) {
360
- await this.start(SessionType.CONTINUOUS)
402
+ await this.start(SessionType.CONTINUOUS);
361
403
  }
362
404
  } else if (state == 'STOP') {
363
405
  if (this.sessionState !== SessionState.stopped) {
364
- await this.stop()
406
+ await this.stop();
365
407
  }
366
408
  }
367
409
  }
@@ -370,7 +412,7 @@ class SessionRecorder extends Observable<SessionRecorderEvents> implements ISess
370
412
  * Create a new session and start it
371
413
  */
372
414
  private async _createSessionAndStart(): Promise<void> {
373
- const signal = this._startRequestController?.signal
415
+ const signal = this._startRequestController?.signal;
374
416
  try {
375
417
  const payload = {
376
418
  sessionAttributes: this.sessionAttributes,
@@ -378,25 +420,26 @@ class SessionRecorder extends Observable<SessionRecorderEvents> implements ISess
378
420
  name: this.sessionAttributes.userName
379
421
  ? `${this.sessionAttributes.userName}'s session on ${getFormattedDate(Date.now(), { month: 'short', day: 'numeric' })}`
380
422
  : `Session on ${getFormattedDate(Date.now())}`,
381
- }
382
- const request: StartSessionRequest = !this.continuousRecording ?
383
- payload : { debugSessionData: payload }
423
+ };
424
+ const request: StartSessionRequest = !this.continuousRecording
425
+ ? payload
426
+ : { debugSessionData: payload };
384
427
 
385
428
  const session = this.continuousRecording
386
429
  ? await this._apiService.startContinuousDebugSession(request, signal)
387
- : await this._apiService.startSession(request, signal)
430
+ : await this._apiService.startSession(request, signal);
388
431
 
389
432
  if (session) {
390
433
  session.sessionType = this.continuousRecording
391
434
  ? SessionType.CONTINUOUS
392
- : SessionType.PLAIN
393
- this._setupSessionAndStart(session, false)
435
+ : SessionType.PLAIN;
436
+ this._setupSessionAndStart(session, false);
394
437
  }
395
438
  } catch (error: any) {
396
- this.error = error.message
397
- logger.error('SessionRecorder', 'Error creating session:', error.message)
439
+ this.error = error.message;
440
+ logger.error('SessionRecorder', 'Error creating session:', error.message);
398
441
  if (this.continuousRecording) {
399
- this.sessionType = SessionType.PLAIN
442
+ this.sessionType = SessionType.PLAIN;
400
443
  }
401
444
  }
402
445
  }
@@ -405,12 +448,12 @@ class SessionRecorder extends Observable<SessionRecorderEvents> implements ISess
405
448
  * Start tracing and recording for the session
406
449
  */
407
450
  private _start(): void {
408
- this.sessionState = SessionState.started
409
- this.sessionType = this.sessionType
451
+ this.sessionState = SessionState.started;
452
+ this.sessionType = this.sessionType;
410
453
 
411
454
  if (this.sessionId) {
412
- this._tracer.start(this.sessionId, this.sessionType)
413
- this._recorder.start(this.sessionId, this.sessionType)
455
+ this._tracer.start(this.sessionId, this.sessionType);
456
+ this._recorder.start(this.sessionId, this.sessionType);
414
457
  }
415
458
  }
416
459
 
@@ -418,18 +461,18 @@ class SessionRecorder extends Observable<SessionRecorderEvents> implements ISess
418
461
  * Stop tracing and recording for the session
419
462
  */
420
463
  private _stop(): void {
421
- this.sessionState = SessionState.stopped
422
- this._tracer.shutdown()
423
- this._recorder.stop()
464
+ this.sessionState = SessionState.stopped;
465
+ this._tracer.shutdown();
466
+ this._recorder.stop();
424
467
  }
425
468
 
426
469
  /**
427
470
  * Pause the session tracing and recording
428
471
  */
429
472
  private _pause(): void {
430
- this._tracer.shutdown()
431
- this._recorder.stop()
432
- this.sessionState = SessionState.paused
473
+ this._tracer.shutdown();
474
+ this._recorder.stop();
475
+ this.sessionState = SessionState.paused;
433
476
  }
434
477
 
435
478
  /**
@@ -437,40 +480,44 @@ class SessionRecorder extends Observable<SessionRecorderEvents> implements ISess
437
480
  */
438
481
  private _resume(): void {
439
482
  if (this.sessionId) {
440
- this._tracer.setSessionId(this.sessionId, this.sessionType)
441
- this._recorder.start(this.sessionId, this.sessionType)
483
+ this._tracer.setSessionId(this.sessionId, this.sessionType);
484
+ this._recorder.start(this.sessionId, this.sessionType);
442
485
  }
443
- this.sessionState = SessionState.started
486
+ this.sessionState = SessionState.started;
444
487
  }
445
488
 
446
- private _setupSessionAndStart(session: ISession, configureExporters: boolean = true): void {
489
+ private _setupSessionAndStart(
490
+ session: ISession,
491
+ configureExporters: boolean = true
492
+ ): void {
447
493
  if (configureExporters && session.tempApiKey) {
448
- this._configs.apiKey = session.tempApiKey
449
- this._tracer.setApiKey(session.tempApiKey)
450
- this._recorder.setApiKey(session.tempApiKey)
451
- this._apiService.setApiKey(session.tempApiKey)
494
+ this._configs.apiKey = session.tempApiKey;
495
+ this._tracer.setApiKey(session.tempApiKey);
496
+ this._recorder.setApiKey(session.tempApiKey);
497
+ this._apiService.setApiKey(session.tempApiKey);
452
498
  }
453
499
 
454
- this._setSession(session)
455
- this._start()
500
+ this._setSession(session);
501
+ this._start();
456
502
  }
457
503
 
458
504
  /**
459
505
  * Set the session ID in storage
460
506
  * @param sessionId - the session ID to set or clear
461
507
  */
462
- private _setSession(
463
- session: ISession,
464
- ): void {
465
- this.session = { ...session, createdAt: session.createdAt || new Date().toISOString() }
466
- this.sessionId = session?.shortId || session?._id
508
+ private _setSession(session: ISession): void {
509
+ this.session = {
510
+ ...session,
511
+ createdAt: session.createdAt || new Date().toISOString(),
512
+ };
513
+ this.sessionId = session?.shortId || session?._id;
467
514
  }
468
515
 
469
516
  private _clearSession(): void {
470
- this.session = null
471
- this.sessionId = null
472
- this.sessionState = SessionState.stopped
473
- this._storageService.clearSessionData()
517
+ this.session = null;
518
+ this.sessionId = null;
519
+ this.sessionState = SessionState.stopped;
520
+ this._storageService.clearSessionData();
474
521
  }
475
522
 
476
523
  /**
@@ -487,62 +534,71 @@ class SessionRecorder extends Observable<SessionRecorderEvents> implements ISess
487
534
  | 'resume'
488
535
  | 'save'
489
536
  | 'autoStartRemoteContinuousSession',
490
- _payload?: any,
537
+ _payload?: any
491
538
  ): void {
492
539
  if (!this._isInitialized) {
493
540
  throw new Error(
494
- 'Configuration not initialized. Call init() before performing any actions.',
495
- )
541
+ 'Configuration not initialized. Call init() before performing any actions.'
542
+ );
496
543
  }
497
544
  switch (action) {
498
545
  case 'start':
499
546
  if (this.sessionState === SessionState.started) {
500
- throw new Error('Session is already started.')
547
+ throw new Error('Session is already started.');
501
548
  }
502
- break
549
+ break;
503
550
  case 'stop':
504
- if (this.sessionState !== SessionState.paused && this.sessionState !== SessionState.started) {
505
- throw new Error('Cannot stop. Session is not currently started.')
551
+ if (
552
+ this.sessionState !== SessionState.paused &&
553
+ this.sessionState !== SessionState.started
554
+ ) {
555
+ throw new Error('Cannot stop. Session is not currently started.');
506
556
  }
507
- break
557
+ break;
508
558
  case 'cancel':
509
559
  if (this.sessionState === SessionState.stopped) {
510
- throw new Error('Cannot cancel. Session has already been stopped.')
560
+ throw new Error('Cannot cancel. Session has already been stopped.');
511
561
  }
512
- break
562
+ break;
513
563
  case 'pause':
514
564
  if (this.sessionState !== SessionState.started) {
515
- throw new Error('Cannot pause. Session is not running.')
565
+ throw new Error('Cannot pause. Session is not running.');
516
566
  }
517
- break
567
+ break;
518
568
  case 'resume':
519
569
  if (this.sessionState !== SessionState.paused) {
520
- throw new Error('Cannot resume. Session is not paused.')
570
+ throw new Error('Cannot resume. Session is not paused.');
521
571
  }
522
- break
572
+ break;
523
573
  case 'save':
524
574
  if (!this.continuousRecording) {
525
- throw new Error('Cannot save continuous recording session. Continuous recording is not enabled.')
575
+ throw new Error(
576
+ 'Cannot save continuous recording session. Continuous recording is not enabled.'
577
+ );
526
578
  }
527
579
  if (this.sessionState !== SessionState.started) {
528
- throw new Error('Cannot save continuous recording session. Session is not started.')
580
+ throw new Error(
581
+ 'Cannot save continuous recording session. Session is not started.'
582
+ );
529
583
  }
530
- break
584
+ break;
531
585
  case 'autoStartRemoteContinuousSession':
532
586
  if (this.sessionState !== SessionState.stopped) {
533
- throw new Error('Cannot start remote continuous session. Session is not stopped.')
587
+ throw new Error(
588
+ 'Cannot start remote continuous session. Session is not stopped.'
589
+ );
534
590
  }
535
- break
591
+ break;
536
592
  }
537
593
  }
538
594
  // Session attributes
539
595
  setSessionAttribute(key: string, value: any): void {
540
596
  if (this._session) {
541
597
  if (!this._session.sessionAttributes) {
542
- this._session.sessionAttributes = {}
598
+ this._session.sessionAttributes = {};
543
599
  }
544
- this._session.sessionAttributes[key] = value
545
- this._session.updatedAt = new Date().toISOString()
600
+ this._session.sessionAttributes[key] = value;
601
+ this._session.updatedAt = new Date().toISOString();
546
602
  }
547
603
  }
548
604
 
@@ -553,11 +609,11 @@ class SessionRecorder extends Observable<SessionRecorderEvents> implements ISess
553
609
  */
554
610
  recordEvent(event: eventWithTime): void {
555
611
  if (!this._isInitialized || this.sessionState !== SessionState.started) {
556
- return
612
+ return;
557
613
  }
558
614
 
559
615
  // Forward the event to the recorder SDK
560
- this._recorder.recordEvent(event)
616
+ this._recorder.recordEvent(event);
561
617
  }
562
618
 
563
619
  /**
@@ -566,7 +622,7 @@ class SessionRecorder extends Observable<SessionRecorderEvents> implements ISess
566
622
  */
567
623
  setViewShotRef(ref: any): void {
568
624
  if (this._recorder) {
569
- this._recorder.setViewShotRef(ref)
625
+ this._recorder.setViewShotRef(ref);
570
626
  }
571
627
  }
572
628
 
@@ -576,7 +632,7 @@ class SessionRecorder extends Observable<SessionRecorderEvents> implements ISess
576
632
  */
577
633
  setNavigationRef(ref: any): void {
578
634
  if (this._recorder) {
579
- this._recorder.setNavigationRef(ref)
635
+ this._recorder.setNavigationRef(ref);
580
636
  }
581
637
  }
582
638
 
@@ -584,8 +640,8 @@ class SessionRecorder extends Observable<SessionRecorderEvents> implements ISess
584
640
  * Cleanup resources and unsubscribe from network monitoring
585
641
  */
586
642
  cleanup(): void {
587
- this._networkService.cleanup()
643
+ this._networkService.cleanup();
588
644
  }
589
645
  }
590
646
 
591
- export default new SessionRecorder()
647
+ export default new SessionRecorder();