@multiplayer-app/session-recorder-react-native 0.0.1-alpha.3 → 0.0.1-alpha.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 (40) hide show
  1. package/dist/context/SessionRecorderContext.d.ts +13 -0
  2. package/dist/context/SessionRecorderContext.js +1 -0
  3. package/dist/context/SessionRecorderContext.js.map +1 -0
  4. package/dist/expo.d.ts +5 -9
  5. package/dist/expo.js +1 -1
  6. package/dist/expo.js.map +1 -1
  7. package/dist/index.d.ts +4 -3
  8. package/dist/index.js +1 -1
  9. package/dist/index.js.map +1 -1
  10. package/dist/otel/index.d.ts +0 -23
  11. package/dist/otel/index.js +1 -1
  12. package/dist/otel/index.js.map +1 -1
  13. package/dist/otel/instrumentations/index.d.ts +4 -1
  14. package/dist/otel/instrumentations/index.js +1 -1
  15. package/dist/otel/instrumentations/index.js.map +1 -1
  16. package/dist/otel/instrumentations/reactNativeInstrumentation.js +1 -1
  17. package/dist/otel/instrumentations/reactNativeInstrumentation.js.map +1 -1
  18. package/dist/recorder/gestureRecorder.js +1 -1
  19. package/dist/recorder/gestureRecorder.js.map +1 -1
  20. package/dist/recorder/screenRecorder.js +1 -1
  21. package/dist/recorder/screenRecorder.js.map +1 -1
  22. package/dist/session-recorder.d.ts +3 -9
  23. package/dist/session-recorder.js +1 -1
  24. package/dist/session-recorder.js.map +1 -1
  25. package/dist/utils/platform.js +1 -1
  26. package/dist/utils/platform.js.map +1 -1
  27. package/dist/version.d.ts +1 -1
  28. package/dist/version.js +1 -1
  29. package/package.json +6 -7
  30. package/src/context/SessionRecorderContext.tsx +71 -0
  31. package/src/expo.ts +7 -17
  32. package/src/index.ts +4 -4
  33. package/src/otel/index.ts +1 -237
  34. package/src/otel/instrumentations/index.ts +3 -11
  35. package/src/otel/instrumentations/reactNativeInstrumentation.ts +8 -96
  36. package/src/recorder/gestureRecorder.ts +1 -3
  37. package/src/recorder/screenRecorder.ts +7 -29
  38. package/src/session-recorder.ts +3 -58
  39. package/src/utils/platform.ts +5 -6
  40. package/src/version.ts +1 -1
@@ -1,5 +1,6 @@
1
1
  import { InstrumentationBase } from '@opentelemetry/instrumentation'
2
2
  import { trace, SpanStatusCode } from '@opentelemetry/api'
3
+ import AsyncStorage from '@react-native-async-storage/async-storage'
3
4
 
4
5
  export class ReactNativeInstrumentation extends InstrumentationBase {
5
6
  constructor() {
@@ -13,9 +14,8 @@ export class ReactNativeInstrumentation extends InstrumentationBase {
13
14
  enable(): void {
14
15
  // Try to wrap AsyncStorage if it's available
15
16
  try {
16
- const asyncStorage = require('@react-native-async-storage/async-storage')
17
- if (asyncStorage) {
18
- this._wrap(asyncStorage, 'AsyncStorage', this._wrapAsyncStorage)
17
+ if (AsyncStorage) {
18
+ this._wrap(AsyncStorage, 'setItem', this._wrapAsyncStorage)
19
19
  }
20
20
  } catch (error) {
21
21
  console.warn('@react-native-async-storage/async-storage is not available. AsyncStorage instrumentation will be disabled.')
@@ -25,24 +25,19 @@ export class ReactNativeInstrumentation extends InstrumentationBase {
25
25
  disable(): void {
26
26
  // Try to unwrap AsyncStorage if it was wrapped
27
27
  try {
28
- const asyncStorage = require('@react-native-async-storage/async-storage')
29
- if (asyncStorage) {
30
- this._unwrap(asyncStorage, 'AsyncStorage')
28
+ if (AsyncStorage) {
29
+ this._unwrap(AsyncStorage, 'setItem')
31
30
  }
32
31
  } catch (error) {
33
32
  // AsyncStorage was not available, nothing to unwrap
34
33
  }
35
34
  }
36
35
 
37
- private _wrapAsyncStorage(originalModule: any) {
38
- const self = this
39
-
40
- // Wrap setItem
41
- const originalSetItem = originalModule.setItem
42
- originalModule.setItem = async function (key: string, value: string) {
36
+ private _wrapAsyncStorage(originalMethod: any) {
37
+ return async function (this: any, key: string, value: string) {
43
38
  const startTime = Date.now()
44
39
  try {
45
- const result = await originalSetItem.call(this, key, value)
40
+ const result = await originalMethod.call(this, key, value)
46
41
 
47
42
  const span = trace.getTracer('react-native').startSpan('AsyncStorage.setItem', {
48
43
  attributes: {
@@ -77,88 +72,5 @@ export class ReactNativeInstrumentation extends InstrumentationBase {
77
72
  throw error
78
73
  }
79
74
  }
80
-
81
- // Wrap getItem
82
- const originalGetItem = originalModule.getItem
83
- originalModule.getItem = async function (key: string) {
84
- const startTime = Date.now()
85
- try {
86
- const result = await originalGetItem.call(this, key)
87
-
88
- const span = trace.getTracer('react-native').startSpan('AsyncStorage.getItem', {
89
- attributes: {
90
- 'storage.operation': 'getItem',
91
- 'storage.key': key,
92
- 'storage.value_length': result ? result.length : 0,
93
- 'storage.duration': Date.now() - startTime,
94
- },
95
- })
96
-
97
- span.setStatus({ code: SpanStatusCode.OK })
98
- span.end()
99
-
100
- return result
101
- } catch (error) {
102
- const span = trace.getTracer('react-native').startSpan('AsyncStorage.getItem', {
103
- attributes: {
104
- 'storage.operation': 'getItem',
105
- 'storage.key': key,
106
- 'storage.error': true,
107
- 'storage.duration': Date.now() - startTime,
108
- },
109
- })
110
-
111
- const errorMessage = error instanceof Error ? error.message : String(error)
112
- span.setStatus({ code: SpanStatusCode.ERROR, message: errorMessage })
113
- if (error instanceof Error) {
114
- span.recordException(error)
115
- }
116
- span.end()
117
-
118
- throw error
119
- }
120
- }
121
-
122
- // Wrap removeItem
123
- const originalRemoveItem = originalModule.removeItem
124
- originalModule.removeItem = async function (key: string) {
125
- const startTime = Date.now()
126
- try {
127
- const result = await originalRemoveItem.call(this, key)
128
-
129
- const span = trace.getTracer('react-native').startSpan('AsyncStorage.removeItem', {
130
- attributes: {
131
- 'storage.operation': 'removeItem',
132
- 'storage.key': key,
133
- 'storage.duration': Date.now() - startTime,
134
- },
135
- })
136
-
137
- span.setStatus({ code: SpanStatusCode.OK })
138
- span.end()
139
-
140
- return result
141
- } catch (error) {
142
- const span = trace.getTracer('react-native').startSpan('AsyncStorage.removeItem', {
143
- attributes: {
144
- 'storage.operation': 'removeItem',
145
- 'storage.key': key,
146
- 'storage.error': true,
147
- 'storage.duration': Date.now() - startTime,
148
- },
149
- })
150
-
151
- const errorMessage = error instanceof Error ? error.message : String(error)
152
- span.setStatus({ code: SpanStatusCode.ERROR, message: errorMessage })
153
- if (error instanceof Error) {
154
- span.recordException(error)
155
- }
156
- span.end()
157
-
158
- throw error
159
- }
160
- }
161
-
162
- return originalModule
163
75
  }
164
76
  }
@@ -1,5 +1,6 @@
1
1
  import { GestureEvent, RecorderConfig } from '../types'
2
2
  import { trace, SpanStatusCode } from '@opentelemetry/api'
3
+ import { Dimensions } from 'react-native'
3
4
 
4
5
  export class GestureRecorder {
5
6
  private config?: RecorderConfig
@@ -39,7 +40,6 @@ export class GestureRecorder {
39
40
 
40
41
  private _getScreenDimensions(): void {
41
42
  try {
42
- const { Dimensions } = require('react-native')
43
43
  this.screenDimensions = Dimensions.get('window')
44
44
  } catch (error) {
45
45
  // Failed to get screen dimensions - silently continue
@@ -70,8 +70,6 @@ export class GestureRecorder {
70
70
  private _setupGlobalGestureListener(): void {
71
71
  try {
72
72
  // Listen for touch events at the app level
73
- const { TouchableWithoutFeedback } = require('react-native')
74
-
75
73
  // This is a simplified implementation - in production you'd use react-native-gesture-handler
76
74
  // Global gesture listener setup complete
77
75
  } catch (error) {
@@ -1,5 +1,7 @@
1
1
  import { ScreenEvent, RecorderConfig } from '../types'
2
2
  import { trace, SpanStatusCode } from '@opentelemetry/api'
3
+ import { Dimensions, AppRegistry } from 'react-native'
4
+ import { captureRef, captureScreen } from 'react-native-view-shot'
3
5
 
4
6
  export class ScreenRecorder {
5
7
  private config?: RecorderConfig
@@ -44,7 +46,6 @@ export class ScreenRecorder {
44
46
 
45
47
  private _getScreenDimensions(): void {
46
48
  try {
47
- const { Dimensions } = require('react-native')
48
49
  this.screenDimensions = Dimensions.get('window')
49
50
  } catch (error) {
50
51
  // Failed to get screen dimensions - silently continue
@@ -109,11 +110,8 @@ export class ScreenRecorder {
109
110
 
110
111
  private async _performScreenCapture(): Promise<string | null> {
111
112
  try {
112
- // Try react-native-view-shot first
113
- const ViewShot = require('react-native-view-shot')
114
- if (ViewShot && ViewShot.captureRef) {
115
- return await this._captureWithViewShot()
116
- }
113
+ // Try react-native-view-shot screen capture first
114
+ return await this._captureWithViewShot()
117
115
  } catch (error) {
118
116
  // react-native-view-shot not available - silently continue
119
117
  }
@@ -134,21 +132,9 @@ export class ScreenRecorder {
134
132
 
135
133
  private async _captureWithViewShot(): Promise<string | null> {
136
134
  try {
137
- const ViewShot = require('react-native-view-shot')
138
-
139
- // Get the root view reference
140
- const { findNodeHandle } = require('react-native')
141
- const rootViewRef = this._getRootViewRef()
142
-
143
- if (rootViewRef) {
144
- const options = {
145
- format: this.captureFormat,
146
- quality: this.captureQuality,
147
- result: 'data-uri',
148
- }
135
+ // Use captureScreen for full screen capture
149
136
 
150
- return await ViewShot.captureRef(rootViewRef, options)
151
- }
137
+ return await captureScreen()
152
138
  } catch (error) {
153
139
  // Failed to capture with ViewShot - silently continue
154
140
  }
@@ -158,7 +144,6 @@ export class ScreenRecorder {
158
144
  private async _captureWithScreenshot(): Promise<string | null> {
159
145
  try {
160
146
  const Screenshot = require('react-native-screenshot')
161
-
162
147
  const options = {
163
148
  format: this.captureFormat,
164
149
  quality: this.captureQuality,
@@ -174,7 +159,6 @@ export class ScreenRecorder {
174
159
  private _getRootViewRef(): any {
175
160
  try {
176
161
  // Try to get the root view reference
177
- const { AppRegistry } = require('react-native')
178
162
  const appName = AppRegistry.getAppKeys()[0]
179
163
  return appName ? { current: null } : null
180
164
  } catch (error) {
@@ -269,15 +253,9 @@ export class ScreenRecorder {
269
253
  quality?: number
270
254
  }): Promise<string | null> {
271
255
  try {
272
- const ViewShot = require('react-native-view-shot')
273
256
 
274
- const captureOptions = {
275
- format: options?.format || this.captureFormat,
276
- quality: options?.quality || this.captureQuality,
277
- result: 'data-uri',
278
- }
279
257
 
280
- return await ViewShot.captureRef(elementRef, captureOptions)
258
+ return await captureRef(elementRef)
281
259
  } catch (error) {
282
260
  // Failed to capture specific element - silently continue
283
261
  return null
@@ -21,7 +21,7 @@ import { ApiService, StartSessionRequest, StopSessionRequest } from './services/
21
21
  // Utility functions for React Native
22
22
 
23
23
 
24
- export class SessionRecorder implements ISessionRecorder {
24
+ class SessionRecorder implements ISessionRecorder {
25
25
  private _isInitialized = false
26
26
  private _configs: SessionRecorderConfigs | null = null
27
27
  private _apiService = new ApiService()
@@ -500,53 +500,6 @@ export class SessionRecorder implements ISessionRecorder {
500
500
  break
501
501
  }
502
502
  }
503
-
504
- // Navigation methods
505
- setNavigationRef(ref: any): void {
506
- if (this._isInitialized) {
507
- this._tracer.setNavigationRef(ref)
508
- this._recorder.setNavigationRef(ref)
509
- }
510
- }
511
-
512
- // Gesture methods
513
- enableGestureTracking(): void {
514
- if (this._isInitialized) {
515
- this._tracer.enableGestureTracking()
516
- }
517
- }
518
-
519
- disableGestureTracking(): void {
520
- if (this._isInitialized) {
521
- this._tracer.disableGestureTracking()
522
- }
523
- }
524
-
525
- // Manual recording methods
526
- recordTap(x: number, y: number, target?: string): void {
527
- if (this._isInitialized) {
528
- this._tracer.recordTap(x, y, target)
529
- }
530
- }
531
-
532
- recordSwipe(direction: string, target?: string): void {
533
- if (this._isInitialized) {
534
- this._tracer.recordSwipe(direction, target)
535
- }
536
- }
537
-
538
- recordNavigate(routeName: string, params?: Record<string, any>): void {
539
- if (this._isInitialized) {
540
- this._tracer.recordNavigate(routeName, params)
541
- }
542
- }
543
-
544
- recordGoBack(): void {
545
- if (this._isInitialized) {
546
- this._tracer.recordGoBack()
547
- }
548
- }
549
-
550
503
  // Session attributes
551
504
  setSessionAttribute(key: string, value: any): void {
552
505
  if (this._session) {
@@ -557,14 +510,6 @@ export class SessionRecorder implements ISessionRecorder {
557
510
  this._session.updatedAt = new Date().toISOString()
558
511
  }
559
512
  }
560
-
561
-
562
-
563
-
564
- captureException(error: Error, context?: Record<string, any>): void {
565
- if (this._isInitialized) {
566
- this._tracer.captureException(error, context)
567
- }
568
- }
569
-
570
513
  }
514
+
515
+ export default new SessionRecorder()
@@ -1,4 +1,6 @@
1
1
  import { IResourceAttributes } from '../types'
2
+ import Constants from 'expo-constants'
3
+ import { Platform } from 'react-native'
2
4
 
3
5
  export interface PlatformInfo {
4
6
  isExpo: boolean
@@ -12,12 +14,11 @@ export interface PlatformInfo {
12
14
  export function detectPlatform(): PlatformInfo {
13
15
  try {
14
16
  // Check if we're in an Expo environment
15
- const expoConstants = require('expo-constants')
16
- const isExpo = !!expoConstants.default?.expoVersion || !!expoConstants.expoVersion
17
+ const isExpo = !!Constants.default?.expoVersion || !!Constants.expoVersion
17
18
 
18
19
  if (isExpo) {
19
- const expoVersion = expoConstants.default?.expoVersion || expoConstants.expoVersion
20
- const platform = expoConstants.default?.platform || expoConstants.platform
20
+ const expoVersion = Constants.default?.expoVersion || Constants.expoVersion
21
+ const platform = Constants.default?.platform || Constants.platform
21
22
 
22
23
  return {
23
24
  isExpo: true,
@@ -29,8 +30,6 @@ export function detectPlatform(): PlatformInfo {
29
30
  }
30
31
 
31
32
  // Fallback to React Native detection
32
- const { Platform } = require('react-native')
33
-
34
33
  return {
35
34
  isExpo: false,
36
35
  isReactNative: true,
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = "0.0.1-alpha.3"
1
+ export const version = "0.0.1-alpha.5"