@multiplayer-app/session-recorder-react-native 0.0.1-beta.6 → 0.0.1-beta.8

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