@multiplayer-app/session-recorder-node 2.0.17 → 2.0.18

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.
@@ -1,285 +0,0 @@
1
- import {
2
- SessionType,
3
- SessionRecorderSdk,
4
- SessionRecorderIdGenerator,
5
- ATTR_MULTIPLAYER_SESSION_RECORDER_VERSION,
6
- MULTIPLAYER_TRACE_DEBUG_SESSION_SHORT_ID_LENGTH,
7
- } from '@multiplayer-app/session-recorder-common'
8
- import { ApiService } from './services/api.service'
9
- import { ISession } from './types'
10
- import { getFormattedDate } from './helper'
11
- import { SESSION_RECORDER_VERSION } from './config'
12
-
13
- export class SessionRecorder {
14
- private _isInitialized = false
15
-
16
- private _shortSessionId: string | boolean = false
17
-
18
- private _traceIdGenerator: SessionRecorderIdGenerator | undefined
19
- private _sessionType: SessionType = SessionType.MANUAL
20
- private _sessionState: 'STARTED' | 'STOPPED' | 'PAUSED' = 'STOPPED'
21
- private _apiService = new ApiService()
22
- private _sessionShortIdGenerator = SessionRecorderSdk.getIdGenerator(MULTIPLAYER_TRACE_DEBUG_SESSION_SHORT_ID_LENGTH)
23
-
24
- private _resourceAttributes: object = {}
25
-
26
- /**
27
- * Initialize session recorder with default or custom configurations
28
- */
29
- constructor() { }
30
-
31
- /**
32
- * @description Initialize the session recorder
33
- * @param config - Configuration object
34
- * @param config.apiKey - multiplayer otlp key
35
- * @param config.traceIdGenerator - multiplayer compatible trace id generator
36
- * @param config.resourceAttributes - Optional resource attributes
37
- * @param config.generateSessionShortIdLocally - Optional session short ID generator
38
- * @param config.apiBaseUrl - Optional base API URL override
39
- */
40
- public init(config: {
41
- apiKey: string,
42
- traceIdGenerator: SessionRecorderIdGenerator,
43
- resourceAttributes?: object,
44
- generateSessionShortIdLocally?: boolean | (() => string),
45
- apiBaseUrl?: string
46
- }): void {
47
- this._resourceAttributes = config.resourceAttributes || {
48
- [ATTR_MULTIPLAYER_SESSION_RECORDER_VERSION]: SESSION_RECORDER_VERSION,
49
- }
50
- this._isInitialized = true
51
-
52
- if (typeof config.generateSessionShortIdLocally === 'function') {
53
- this._sessionShortIdGenerator = config.generateSessionShortIdLocally
54
- }
55
-
56
- if (!config?.apiKey?.length) {
57
- throw new Error('Api key not provided')
58
- }
59
-
60
- if (!config?.traceIdGenerator?.setSessionId) {
61
- throw new Error('Incompatible trace id generator')
62
- }
63
-
64
- this._traceIdGenerator = config.traceIdGenerator
65
- this._apiService.init({
66
- apiKey: config.apiKey,
67
- apiBaseUrl: config.apiBaseUrl,
68
- })
69
- }
70
-
71
- /**
72
- * @description Start a new session
73
- * @param {SessionType} SessionType - the type of session to start
74
- * @param {ISession} [sessionPayload] - session metadata
75
- * @returns {Promise<void>}
76
- */
77
- public async start(
78
- sessionType: SessionType,
79
- sessionPayload?: Omit<ISession, '_id'>,
80
- ): Promise<void> {
81
- if (!this._isInitialized) {
82
- throw new Error(
83
- 'Configuration not initialized. Call init() before performing any actions.',
84
- )
85
- }
86
-
87
- if (
88
- sessionPayload?.shortId
89
- && sessionPayload?.shortId?.length !== MULTIPLAYER_TRACE_DEBUG_SESSION_SHORT_ID_LENGTH
90
- ) {
91
- throw new Error('Invalid short session id')
92
- }
93
-
94
- sessionPayload = sessionPayload || {}
95
-
96
- if (this._sessionState !== 'STOPPED') {
97
- throw new Error('Session should be ended before starting new one.')
98
- }
99
-
100
- this._sessionType = sessionType
101
-
102
- let session: ISession
103
-
104
- sessionPayload.name = sessionPayload.name
105
- ? sessionPayload.name
106
- : `Session on ${getFormattedDate(Date.now())}`
107
-
108
- sessionPayload.resourceAttributes = {
109
- ...this._resourceAttributes,
110
- ...sessionPayload.resourceAttributes,
111
- }
112
-
113
- if (this._sessionType === SessionType.CONTINUOUS) {
114
- session = await this._apiService.startContinuousSession(sessionPayload)
115
- } else {
116
- session = await this._apiService.startSession(sessionPayload)
117
- }
118
-
119
- if (!session?.shortId) {
120
- throw new Error('Failed to start session')
121
- }
122
-
123
- this._shortSessionId = session.shortId as string
124
-
125
- (this._traceIdGenerator as SessionRecorderIdGenerator).setSessionId(
126
- this._shortSessionId,
127
- this._sessionType,
128
- )
129
-
130
- this._sessionState = 'STARTED'
131
- }
132
-
133
- /**
134
- * @description Save the continuous session
135
- * @param {String} [reason]
136
- * @returns {Promise<void>}
137
- */
138
- static async save(reason?: string) {
139
- SessionRecorderSdk.saveContinuousSession(reason)
140
- }
141
-
142
- /**
143
- * @description Save the continuous session
144
- * @param {ISession} [sessionData]
145
- * @returns {Promise<void>}
146
- */
147
- public async save(
148
- sessionData?: ISession,
149
- ): Promise<void> {
150
- try {
151
- if (!this._isInitialized) {
152
- throw new Error(
153
- 'Configuration not initialized. Call init() before performing any actions.',
154
- )
155
- }
156
-
157
- if (
158
- this._sessionState === 'STOPPED'
159
- || typeof this._shortSessionId !== 'string'
160
- ) {
161
- throw new Error('Session should be active or paused')
162
- }
163
-
164
- if (this._sessionType !== SessionType.CONTINUOUS) {
165
- throw new Error('Invalid session type')
166
- }
167
-
168
- await this._apiService.saveContinuousSession(
169
- this._shortSessionId,
170
- {
171
- ...(sessionData || {}),
172
- name: sessionData?.name
173
- ? sessionData.name
174
- : `Session on ${getFormattedDate(Date.now())}`,
175
- },
176
- )
177
- } catch (e) {
178
- throw e
179
- }
180
- }
181
-
182
- /**
183
- * @description Stop the current session with an optional comment
184
- * @param {ISession} [sessionData] - user-provided comment to include in session metadata
185
- * @returns {Promise<void>}
186
- */
187
- public async stop(
188
- sessionData?: ISession,
189
- ): Promise<void> {
190
- try {
191
- if (!this._isInitialized) {
192
- throw new Error(
193
- 'Configuration not initialized. Call init() before performing any actions.',
194
- )
195
- }
196
-
197
- if (
198
- this._sessionState === 'STOPPED'
199
- || typeof this._shortSessionId !== 'string'
200
- ) {
201
- throw new Error('Session should be active or paused')
202
- }
203
-
204
- if (this._sessionType !== SessionType.MANUAL) {
205
- throw new Error('Invalid session type')
206
- }
207
-
208
- await this._apiService.stopSession(
209
- this._shortSessionId,
210
- sessionData || {},
211
- )
212
- } catch (e) {
213
- throw e
214
- } finally {
215
- (this._traceIdGenerator as SessionRecorderIdGenerator).setSessionId('')
216
-
217
- this._shortSessionId = false
218
- this._sessionState = 'STOPPED'
219
- }
220
- }
221
-
222
- /**
223
- * @description Cancel the current session
224
- * @returns {Promise<void>}
225
- */
226
- public async cancel(): Promise<void> {
227
- try {
228
- if (!this._isInitialized) {
229
- throw new Error(
230
- 'Configuration not initialized. Call init() before performing any actions.',
231
- )
232
- }
233
-
234
- if (
235
- this._sessionState === 'STOPPED'
236
- || typeof this._shortSessionId !== 'string'
237
- ) {
238
- throw new Error('Session should be active or paused')
239
- }
240
-
241
- if (this._sessionType === SessionType.CONTINUOUS) {
242
- await this._apiService.stopContinuousSession(this._shortSessionId)
243
- } else if (this._sessionType === SessionType.MANUAL) {
244
- await this._apiService.cancelSession(this._shortSessionId)
245
- }
246
- } catch (e) {
247
- throw e
248
- } finally {
249
- (this._traceIdGenerator as SessionRecorderIdGenerator).setSessionId('')
250
-
251
- this._shortSessionId = false
252
- this._sessionState = 'STOPPED'
253
- }
254
- }
255
-
256
- /**
257
- * @description Check if continuous session should be started/stopped automatically
258
- * @param {ISession} [sessionPayload]
259
- * @returns {Promise<void>}
260
- */
261
- public async checkRemoteContinuousSession(
262
- sessionPayload?: Omit<ISession, '_id' | 'shortId'>,
263
- ): Promise<void> {
264
- if (!this._isInitialized) {
265
- throw new Error(
266
- 'Configuration not initialized. Call init() before performing any actions.',
267
- )
268
- }
269
-
270
- sessionPayload = sessionPayload || {}
271
-
272
- sessionPayload.resourceAttributes = {
273
- ...(sessionPayload.resourceAttributes || {}),
274
- ...this._resourceAttributes,
275
- }
276
-
277
- const { state } = await this._apiService.checkRemoteSession(sessionPayload)
278
-
279
- if (state == 'START' && this._sessionState !== 'STARTED') {
280
- await this.start(SessionType.CONTINUOUS, sessionPayload)
281
- } else if (state == 'STOP' && this._sessionState !== 'STOPPED') {
282
- await this.stop()
283
- }
284
- }
285
- }
package/src/types.ts DELETED
@@ -1,27 +0,0 @@
1
- export interface ISession {
2
- _id?: string
3
- shortId?: string
4
- name?: string
5
- resourceAttributes?: {
6
- browserInfo?: string,
7
- cookiesEnabled?: string,
8
- deviceInfo?: string,
9
- hardwareConcurrency?: string,
10
- osInfo?: string,
11
- pixelRatio?: string,
12
- screenSize?: string,
13
- } & any
14
- sessionAttributes?: {
15
- userEmail?: string
16
- userId?: string,
17
- userName?: string,
18
- accountId?: string,
19
- accountName?: string,
20
-
21
- comment?: string
22
- } & any
23
- tags?: {
24
- key?: string
25
- value: string
26
- }[]
27
- }
package/tsconfig.json DELETED
@@ -1,38 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "declaration": true,
4
- "declarationMap": true,
5
- "baseUrl": ".",
6
- "noEmit": false,
7
- "module": "commonjs",
8
- "noImplicitAny": false,
9
- "noUnusedParameters": false,
10
- "allowJs": false,
11
- "allowSyntheticDefaultImports": true,
12
- "esModuleInterop": true,
13
- "forceConsistentCasingInFileNames": true,
14
- "isolatedModules": true,
15
- "moduleResolution": "node",
16
- "noImplicitReturns": true,
17
- "noImplicitThis": true,
18
- "noUnusedLocals": false,
19
- "preserveConstEnums": true,
20
- "removeComments": false,
21
- "resolveJsonModule": true,
22
- "skipLibCheck": true,
23
- "sourceMap": true,
24
- "types": [
25
- "node"
26
- ],
27
- "target": "ES2018",
28
- "downlevelIteration": true,
29
- "strict": true,
30
- "composite": true,
31
- "outDir": "./dist/",
32
- "rootDir": "./src/",
33
- "preserveSymlinks": true,
34
- "paths": {}
35
- },
36
- "exclude": ["dist", "examples"],
37
- "references": []
38
- }