@multiplayer-app/session-recorder-react-native 1.0.1-beta.4 → 1.0.1-beta.6
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/android/build.gradle +1 -1
- package/android/src/main/AndroidManifest.xml +2 -2
- package/android/src/main/java/com/{multiplayer/sessionrecordernative → sessionrecordernative}/SessionRecorderNativeConfig.kt +1 -1
- package/android/src/main/java/com/{multiplayer/sessionrecordernative → sessionrecordernative}/SessionRecorderNativeModule.kt +9 -9
- package/android/src/main/java/com/{multiplayer/sessionrecordernative → sessionrecordernative}/SessionRecorderNativePackage.kt +2 -2
- package/android/src/main/java/com/{multiplayer/sessionrecordernative → sessionrecordernative}/model/TargetInfo.kt +1 -1
- package/android/src/main/java/com/{multiplayer/sessionrecordernative → sessionrecordernative}/util/ViewUtils.kt +2 -2
- package/lib/module/SessionRecorderNativeSpec.js +5 -0
- package/lib/module/SessionRecorderNativeSpec.js.map +1 -0
- package/lib/module/components/SessionRecorderWidget/ErrorBanner.js.map +1 -1
- package/lib/module/components/SessionRecorderWidget/ModalHeader.js.map +1 -1
- package/lib/module/components/SessionRecorderWidget/SessionRecorderWidget.js.map +1 -1
- package/lib/module/components/SessionRecorderWidget/icons.js.map +1 -1
- package/lib/module/components/SessionRecorderWidget/styles.js.map +1 -1
- package/lib/module/config/constants.js.map +1 -1
- package/lib/module/config/defaults.js.map +1 -1
- package/lib/module/config/masking.js.map +1 -1
- package/lib/module/config/session-recorder.js.map +1 -1
- package/lib/module/config/validators.js.map +1 -1
- package/lib/module/config/widget.js.map +1 -1
- package/lib/module/context/SessionRecorderStore.js.map +1 -1
- package/lib/module/context/useSessionRecorderStore.js.map +1 -1
- package/lib/module/context/useStoreSelector.js.map +1 -1
- package/lib/module/native/SessionRecorderNative.js +16 -11
- package/lib/module/native/SessionRecorderNative.js.map +1 -1
- package/lib/module/native/index.js.map +1 -1
- package/lib/module/otel/helpers.js +1 -1
- package/lib/module/otel/helpers.js.map +1 -1
- package/lib/module/otel/index.js.map +1 -1
- package/lib/module/otel/instrumentations/index.js.map +1 -1
- package/lib/module/patch/xhr.js.map +1 -1
- package/lib/module/recorder/eventExporter.js.map +1 -1
- package/lib/module/recorder/gestureRecorder.js.map +1 -1
- package/lib/module/recorder/index.js.map +1 -1
- package/lib/module/recorder/navigationTracker.js.map +1 -1
- package/lib/module/recorder/screenRecorder.js.map +1 -1
- package/lib/module/services/api.service.js.map +1 -1
- package/lib/module/services/network.service.js.map +1 -1
- package/lib/module/services/screenMaskingService.js +1 -1
- package/lib/module/services/screenMaskingService.js.map +1 -1
- package/lib/module/services/storage.service.js.map +1 -1
- package/lib/module/session-recorder.js.map +1 -1
- package/lib/module/types/index.js.map +1 -1
- package/lib/module/types/session-recorder.js.map +1 -1
- package/lib/module/utils/app-metadata.js +2 -2
- package/lib/module/utils/constants.optional.js.map +1 -1
- package/lib/module/utils/createStore.js.map +1 -1
- package/lib/module/utils/logger.js +0 -8
- package/lib/module/utils/logger.js.map +1 -1
- package/lib/module/utils/platform.js +1 -1
- package/lib/module/utils/platform.js.map +1 -1
- package/lib/module/utils/rrweb-events.js.map +1 -1
- package/lib/module/utils/session.js.map +1 -1
- package/lib/module/utils/shallowEqual.js.map +1 -1
- package/lib/module/utils/time.js.map +1 -1
- package/lib/module/version.js +1 -1
- package/lib/typescript/src/SessionRecorderNativeSpec.d.ts +42 -0
- package/lib/typescript/src/SessionRecorderNativeSpec.d.ts.map +1 -0
- package/lib/typescript/src/components/ScreenRecorderView/index.d.ts +1 -1
- package/lib/typescript/src/components/SessionRecorderWidget/ErrorBanner.d.ts.map +1 -1
- package/lib/typescript/src/components/SessionRecorderWidget/ModalHeader.d.ts.map +1 -1
- package/lib/typescript/src/components/SessionRecorderWidget/SessionRecorderWidget.d.ts.map +1 -1
- package/lib/typescript/src/components/SessionRecorderWidget/icons.d.ts.map +1 -1
- package/lib/typescript/src/components/SessionRecorderWidget/index.d.ts +1 -1
- package/lib/typescript/src/components/SessionRecorderWidget/styles.d.ts.map +1 -1
- package/lib/typescript/src/components/index.d.ts.map +1 -1
- package/lib/typescript/src/config/constants.d.ts.map +1 -1
- package/lib/typescript/src/config/defaults.d.ts.map +1 -1
- package/lib/typescript/src/config/index.d.ts.map +1 -1
- package/lib/typescript/src/config/masking.d.ts.map +1 -1
- package/lib/typescript/src/config/session-recorder.d.ts.map +1 -1
- package/lib/typescript/src/config/validators.d.ts.map +1 -1
- package/lib/typescript/src/config/widget.d.ts +1 -1
- package/lib/typescript/src/config/widget.d.ts.map +1 -1
- package/lib/typescript/src/context/SessionRecorderStore.d.ts.map +1 -1
- package/lib/typescript/src/context/useSessionRecorderStore.d.ts +3 -3
- package/lib/typescript/src/context/useSessionRecorderStore.d.ts.map +1 -1
- package/lib/typescript/src/context/useStoreSelector.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/native/SessionRecorderNative.d.ts +3 -54
- package/lib/typescript/src/native/SessionRecorderNative.d.ts.map +1 -1
- package/lib/typescript/src/native/index.d.ts +1 -1
- package/lib/typescript/src/native/index.d.ts.map +1 -1
- package/lib/typescript/src/otel/helpers.d.ts.map +1 -1
- package/lib/typescript/src/otel/index.d.ts.map +1 -1
- package/lib/typescript/src/otel/instrumentations/index.d.ts.map +1 -1
- package/lib/typescript/src/patch/index.d.ts.map +1 -1
- package/lib/typescript/src/patch/xhr.d.ts.map +1 -1
- package/lib/typescript/src/recorder/eventExporter.d.ts.map +1 -1
- package/lib/typescript/src/recorder/gestureRecorder.d.ts.map +1 -1
- package/lib/typescript/src/recorder/index.d.ts.map +1 -1
- package/lib/typescript/src/recorder/navigationTracker.d.ts.map +1 -1
- package/lib/typescript/src/recorder/screenRecorder.d.ts.map +1 -1
- package/lib/typescript/src/services/api.service.d.ts.map +1 -1
- package/lib/typescript/src/services/network.service.d.ts.map +1 -1
- package/lib/typescript/src/services/screenMaskingService.d.ts +1 -1
- package/lib/typescript/src/services/screenMaskingService.d.ts.map +1 -1
- package/lib/typescript/src/services/storage.service.d.ts.map +1 -1
- package/lib/typescript/src/session-recorder.d.ts.map +1 -1
- package/lib/typescript/src/types/configs.d.ts.map +1 -1
- package/lib/typescript/src/types/index.d.ts.map +1 -1
- package/lib/typescript/src/types/session-recorder.d.ts +4 -4
- package/lib/typescript/src/types/session-recorder.d.ts.map +1 -1
- package/lib/typescript/src/types/session.d.ts.map +1 -1
- package/lib/typescript/src/utils/app-metadata.d.ts.map +1 -1
- package/lib/typescript/src/utils/constants.optional.d.ts.map +1 -1
- package/lib/typescript/src/utils/constants.optional.expo.d.ts.map +1 -1
- package/lib/typescript/src/utils/createStore.d.ts.map +1 -1
- package/lib/typescript/src/utils/index.d.ts.map +1 -1
- package/lib/typescript/src/utils/logger.d.ts +1 -1
- package/lib/typescript/src/utils/logger.d.ts.map +1 -1
- package/lib/typescript/src/utils/platform.d.ts.map +1 -1
- package/lib/typescript/src/utils/request-utils.d.ts.map +1 -1
- package/lib/typescript/src/utils/rrweb-events.d.ts.map +1 -1
- package/lib/typescript/src/utils/session.d.ts.map +1 -1
- package/lib/typescript/src/utils/shallowEqual.d.ts.map +1 -1
- package/lib/typescript/src/utils/time.d.ts.map +1 -1
- package/lib/typescript/src/utils/type-utils.d.ts.map +1 -1
- package/lib/typescript/src/version.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/SessionRecorderNativeSpec.ts +53 -0
- package/src/components/ScreenRecorderView/index.ts +1 -1
- package/src/components/SessionRecorderWidget/ErrorBanner.tsx +14 -14
- package/src/components/SessionRecorderWidget/ModalHeader.tsx +11 -9
- package/src/components/SessionRecorderWidget/SessionRecorderWidget.tsx +70 -56
- package/src/components/SessionRecorderWidget/icons.tsx +58 -30
- package/src/components/SessionRecorderWidget/index.ts +1 -1
- package/src/components/SessionRecorderWidget/styles.ts +17 -18
- package/src/components/index.ts +2 -2
- package/src/config/constants.ts +19 -20
- package/src/config/defaults.ts +35 -31
- package/src/config/index.ts +5 -5
- package/src/config/masking.ts +44 -18
- package/src/config/session-recorder.ts +54 -26
- package/src/config/validators.ts +43 -20
- package/src/config/widget.ts +24 -15
- package/src/context/SessionRecorderStore.ts +19 -18
- package/src/context/useSessionRecorderStore.ts +17 -10
- package/src/context/useStoreSelector.ts +20 -18
- package/src/index.ts +7 -7
- package/src/native/SessionRecorderNative.ts +68 -112
- package/src/native/index.ts +5 -1
- package/src/otel/helpers.ts +109 -93
- package/src/otel/index.ts +46 -49
- package/src/otel/instrumentations/index.ts +44 -41
- package/src/patch/index.ts +1 -1
- package/src/patch/xhr.ts +77 -78
- package/src/recorder/eventExporter.ts +63 -68
- package/src/recorder/gestureRecorder.ts +359 -212
- package/src/recorder/index.ts +75 -62
- package/src/recorder/navigationTracker.ts +120 -97
- package/src/recorder/screenRecorder.ts +214 -163
- package/src/services/api.service.ts +49 -48
- package/src/services/network.service.ts +67 -58
- package/src/services/screenMaskingService.ts +81 -50
- package/src/services/storage.service.ts +99 -70
- package/src/session-recorder.ts +270 -214
- package/src/types/configs.ts +53 -31
- package/src/types/expo-constants.d.ts +2 -2
- package/src/types/index.ts +16 -18
- package/src/types/session-recorder.ts +106 -111
- package/src/types/session.ts +45 -45
- package/src/utils/app-metadata.ts +9 -9
- package/src/utils/constants.optional.expo.ts +3 -3
- package/src/utils/constants.optional.ts +14 -12
- package/src/utils/createStore.ts +23 -20
- package/src/utils/index.ts +7 -7
- package/src/utils/logger.ts +87 -58
- package/src/utils/platform.ts +149 -118
- package/src/utils/request-utils.ts +15 -15
- package/src/utils/rrweb-events.ts +47 -34
- package/src/utils/session.ts +15 -12
- package/src/utils/shallowEqual.ts +16 -10
- package/src/utils/time.ts +7 -4
- package/src/utils/type-utils.ts +36 -36
- package/src/version.ts +1 -1
- package/android/src/main/java/com/multiplayer/sessionrecordernative/SessionRecorderNativeModuleSpec.kt +0 -51
- package/android/src/main/java/com/xxx/XxxModule.kt +0 -23
- package/ios/Xxx.h +0 -5
- package/ios/Xxx.mm +0 -21
package/src/session-recorder.ts
CHANGED
|
@@ -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 {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
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 {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
import {
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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', [
|
|
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(
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
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(
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
this.
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
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(
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
this.
|
|
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(
|
|
205
|
-
|
|
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(
|
|
210
|
-
|
|
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 (
|
|
215
|
-
type
|
|
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 (
|
|
301
|
-
|
|
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
|
-
|
|
313
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
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 (
|
|
505
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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();
|