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

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 (46) hide show
  1. package/README.md +80 -1
  2. package/SessionRecorderNative.podspec +29 -3
  3. package/android/src/main/java/com/sessionrecordernative/SessionRecorderNativeModule.kt +1 -9
  4. package/android/src/main/java/com/sessionrecordernative/SessionRecorderNativePackage.kt +1 -1
  5. package/ios/SessionRecorderNative-Bridging-Header.h +2 -0
  6. package/ios/{SessionRecorderNative.m → SessionRecorderNative.mm} +0 -1
  7. package/ios/SessionRecorderNative.swift +0 -13
  8. package/lib/module/NativeSessionRecorderModule.js +5 -0
  9. package/lib/module/NativeSessionRecorderModule.js.map +1 -0
  10. package/lib/module/NativeSessionRecorderModuleSpec.js +5 -0
  11. package/lib/module/NativeSessionRecorderModuleSpec.js.map +1 -0
  12. package/lib/module/NativeSessionRecorderNative.js +5 -0
  13. package/lib/module/NativeSessionRecorderNative.js.map +1 -0
  14. package/lib/module/index.js +0 -3
  15. package/lib/module/index.js.map +1 -1
  16. package/lib/module/native/SessionRecorderNative.js +9 -12
  17. package/lib/module/native/SessionRecorderNative.js.map +1 -1
  18. package/lib/module/services/screenMaskingService.js +1 -1
  19. package/lib/module/services/screenMaskingService.js.map +1 -1
  20. package/lib/typescript/src/NativeSessionRecorderModule.d.ts +25 -0
  21. package/lib/typescript/src/NativeSessionRecorderModule.d.ts.map +1 -0
  22. package/lib/typescript/src/NativeSessionRecorderModuleSpec.d.ts +25 -0
  23. package/lib/typescript/src/NativeSessionRecorderModuleSpec.d.ts.map +1 -0
  24. package/lib/typescript/src/NativeSessionRecorderNative.d.ts +25 -0
  25. package/lib/typescript/src/NativeSessionRecorderNative.d.ts.map +1 -0
  26. package/lib/typescript/src/index.d.ts +0 -1
  27. package/lib/typescript/src/index.d.ts.map +1 -1
  28. package/lib/typescript/src/native/SessionRecorderNative.d.ts +3 -1
  29. package/lib/typescript/src/native/SessionRecorderNative.d.ts.map +1 -1
  30. package/lib/typescript/src/services/screenMaskingService.d.ts +1 -1
  31. package/lib/typescript/src/services/screenMaskingService.d.ts.map +1 -1
  32. package/package.json +25 -5
  33. package/react-native.config.js +14 -0
  34. package/src/NativeSessionRecorderModule.ts +33 -0
  35. package/src/NativeSessionRecorderModuleSpec.ts +33 -0
  36. package/src/NativeSessionRecorderNative.ts +33 -0
  37. package/src/index.ts +0 -2
  38. package/src/native/SessionRecorderNative.ts +11 -13
  39. package/src/services/screenMaskingService.ts +1 -3
  40. package/android/src/main/java/com/sessionrecordernative/SessionRecorderNativeSpec.kt +0 -79
  41. package/ios/SessionRecorderNative.podspec +0 -22
  42. package/lib/module/SessionRecorderNativeSpec.js +0 -5
  43. package/lib/module/SessionRecorderNativeSpec.js.map +0 -1
  44. package/lib/typescript/src/SessionRecorderNativeSpec.d.ts +0 -41
  45. package/lib/typescript/src/SessionRecorderNativeSpec.d.ts.map +0 -1
  46. package/src/SessionRecorderNativeSpec.ts +0 -52
package/README.md CHANGED
@@ -55,6 +55,65 @@ npx expo install @react-native-async-storage/async-storage @react-native-communi
55
55
 
56
56
  If you use Expo Router or a managed workflow, no extra autolinking steps are required beyond installing the packages.
57
57
 
58
+ ### Expo Autolinking Support
59
+
60
+ This package includes full Expo autolinking support with the following configuration files:
61
+
62
+ - ✅ `expo-module.config.json` - Defines supported platforms and module names
63
+ - ✅ `react-native.config.js` - Configures React Native CLI autolinking
64
+ - ✅ Proper TurboModule registration for both iOS and Android
65
+
66
+ The module will be automatically detected and linked when you install it in your Expo project.
67
+
68
+ #### Expo Go vs Development Builds
69
+
70
+ **Important**: This package uses native modules that require custom native code. While autolinking is configured, you may encounter issues with **Expo Go** due to its limitations with custom native modules.
71
+
72
+ **If autolinking doesn't work with Expo Go**, try using development builds instead:
73
+
74
+ ```bash
75
+ # For iOS
76
+ npx expo run:ios
77
+
78
+ # For Android
79
+ npx expo run:android
80
+ ```
81
+
82
+ Development builds include your custom native modules and provide the full native functionality needed for session recording.
83
+
84
+ #### Troubleshooting Expo Autolinking
85
+
86
+ If you encounter issues with module autolinking in Expo:
87
+
88
+ 1. **Check Expo SDK compatibility**: Ensure you're using a compatible Expo SDK version
89
+ 2. **Clear cache**: Run `npx expo start -c` to clear the Expo cache
90
+ 3. **Use development builds**: Switch from Expo Go to development builds as shown above
91
+ 4. **Verify configuration**: Ensure the autolinking configuration files are present in your `node_modules/@multiplayer-app/session-recorder-react-native/` directory
92
+
93
+ #### Expo Configuration
94
+
95
+ For Expo applications, the package automatically detects the Expo environment:
96
+
97
+ ```javascript
98
+ import SessionRecorder from '@multiplayer-app/session-recorder-react-native';
99
+
100
+ SessionRecorder.init({
101
+ application: 'my-expo-app',
102
+ version: '1.0.0',
103
+ environment: 'production',
104
+ apiKey: 'YOUR_MULTIPLAYER_API_KEY',
105
+ recordGestures: true,
106
+ recordNavigation: true,
107
+ recordScreen: true,
108
+ });
109
+ ```
110
+
111
+ The package will automatically:
112
+
113
+ - Detect Expo environment using `expo-constants`
114
+ - Add Expo-specific attributes to traces
115
+ - Optimize performance for Expo runtime
116
+
58
117
  #### Why direct install is required
59
118
 
60
119
  - Autolinking scans only the app's `package.json`
@@ -809,7 +868,27 @@ SessionRecorder.init(config);
809
868
  - Ensure `expo-constants` is installed: `npx expo install expo-constants`
810
869
  - Check that you're using the correct Expo SDK version
811
870
 
812
- #### 6. Build Issues
871
+ #### 6. TurboModule Not Found (Expo Go)
872
+
873
+ If you see this error in Expo Go:
874
+
875
+ ```
876
+ TurboModuleRegistry.getEnforcing(...): 'SessionRecorderNative' could not be found
877
+ ```
878
+
879
+ **Solution**: Switch to development builds instead of Expo Go:
880
+
881
+ ```bash
882
+ # For iOS
883
+ npx expo run:ios
884
+
885
+ # For Android
886
+ npx expo run:android
887
+ ```
888
+
889
+ Expo Go has limitations with custom native modules. Development builds include your custom native code and will resolve this issue.
890
+
891
+ #### 7. Build Issues
813
892
 
814
893
  - **iOS**: Run `cd ios && pod install` after installing dependencies
815
894
  - **Android**: Run `cd android && ./gradlew clean`
@@ -1,6 +1,8 @@
1
1
  require "json"
2
2
 
3
3
  package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
+ folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
5
+ min_ios_version_supported = '13.0'
4
6
 
5
7
  Pod::Spec.new do |s|
6
8
  s.name = "SessionRecorderNative"
@@ -13,9 +15,33 @@ Pod::Spec.new do |s|
13
15
  s.platforms = { :ios => min_ios_version_supported }
14
16
  s.source = { :git => "https://github.com/multiplayer-app/multiplayer-session-recorder-javascript.git", :tag => "#{s.version}" }
15
17
 
16
- s.source_files = "ios/**/*.{h,m,mm,cpp}"
17
- s.private_header_files = "ios/**/*.h"
18
+ s.source_files = "ios/**/*.{swift,h,hpp,m,mm,c,cpp}"
18
19
 
19
20
 
20
- install_modules_dependencies(s)
21
+ s.ios.deployment_target = '13.0'
22
+ s.swift_versions = "5.3"
23
+
24
+
25
+
26
+ if respond_to?(:install_modules_dependencies, true)
27
+ install_modules_dependencies(s)
28
+ else
29
+ s.dependency "React-Core"
30
+ s.dependency "React"
31
+
32
+ # Don't install the dependencies when we run `pod install` in the old architecture.
33
+ if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
34
+ s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
35
+ s.pod_target_xcconfig = {
36
+ "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
37
+ "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1",
38
+ "CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
39
+ }
40
+ s.dependency "React-Codegen"
41
+ s.dependency "RCT-Folly"
42
+ s.dependency "RCTRequired"
43
+ s.dependency "RCTTypeSafety"
44
+ s.dependency "ReactCommon/turbomodule/core"
45
+ end
46
+ end
21
47
  end
@@ -25,7 +25,7 @@ import com.facebook.react.module.annotations.ReactModule
25
25
 
26
26
  @ReactModule(name = SessionRecorderNativeModule.NAME)
27
27
  class SessionRecorderNativeModule(reactContext: ReactApplicationContext) :
28
- ReactContextBaseJavaModule(reactContext) {
28
+ ReactContextBaseJavaModule(reactContext) {
29
29
 
30
30
  override fun getName(): String {
31
31
  return NAME
@@ -43,7 +43,6 @@ class SessionRecorderNativeModule(reactContext: ReactApplicationContext) :
43
43
  // Gesture recording state
44
44
  private var isRecording = false
45
45
  private var rootView: ViewGroup? = null
46
- private var gestureCallback: Callback? = null
47
46
  private var originalWindowCallback: android.view.Window.Callback? = null
48
47
  private var initialTouchTime = 0L
49
48
  private var initialTouchX = 0f
@@ -126,11 +125,6 @@ class SessionRecorderNativeModule(reactContext: ReactApplicationContext) :
126
125
  promise.resolve(isRecording)
127
126
  }
128
127
 
129
- @ReactMethod
130
- fun setGestureCallback(callback: Callback) {
131
- this.gestureCallback = callback
132
- }
133
-
134
128
  @ReactMethod
135
129
  fun recordGesture(
136
130
  gestureType: String,
@@ -150,7 +144,6 @@ class SessionRecorderNativeModule(reactContext: ReactApplicationContext) :
150
144
  }
151
145
 
152
146
  sendEvent("onGestureDetected", gestureEvent)
153
- gestureCallback?.invoke(gestureEvent)
154
147
  }
155
148
 
156
149
  private fun setupGestureListener(activity: Activity) {
@@ -333,7 +326,6 @@ class SessionRecorderNativeModule(reactContext: ReactApplicationContext) :
333
326
  }
334
327
 
335
328
  sendEvent("onGestureDetected", gestureEvent)
336
- gestureCallback?.invoke(gestureEvent)
337
329
  }
338
330
 
339
331
  private fun createTapMetadata(): WritableMap {
@@ -10,7 +10,7 @@ import java.util.HashMap
10
10
  class SessionRecorderNativePackage : BaseReactPackage() {
11
11
  override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
12
12
  return if (name == SessionRecorderNativeModule.NAME) {
13
- SessionRecorderNativeModule(reactContext) as NativeModule
13
+ SessionRecorderNativeModule(reactContext)
14
14
  } else {
15
15
  null
16
16
  }
@@ -0,0 +1,2 @@
1
+ #import <React/RCTBridgeModule.h>
2
+ #import <React/RCTViewManager.h>
@@ -17,7 +17,6 @@ RCT_EXTERN_METHOD(stopGestureRecording:(RCTPromiseResolveBlock)resolve
17
17
  reject:(RCTPromiseRejectBlock)reject)
18
18
  RCT_EXTERN_METHOD(isGestureRecordingActive:(RCTPromiseResolveBlock)resolve
19
19
  reject:(RCTPromiseRejectBlock)reject)
20
- RCT_EXTERN_METHOD(setGestureCallback:(RCTResponseSenderBlock)callback)
21
20
  RCT_EXTERN_METHOD(recordGesture:(NSString *)gestureType
22
21
  x:(nonnull NSNumber *)x
23
22
  y:(nonnull NSNumber *)y
@@ -120,7 +120,6 @@ class SessionRecorderNative: RCTEventEmitter, UIGestureRecognizerDelegate {
120
120
 
121
121
  // MARK: - Gesture recording state
122
122
  private var isRecording = false
123
- private var gestureCallback: RCTResponseSenderBlock?
124
123
  private var rootViewController: UIViewController?
125
124
 
126
125
  private var tapGestureRecognizer: UITapGestureRecognizer?
@@ -168,10 +167,6 @@ class SessionRecorderNative: RCTEventEmitter, UIGestureRecognizerDelegate {
168
167
  resolve(self.isRecording)
169
168
  }
170
169
 
171
- @objc func setGestureCallback(_ callback: @escaping RCTResponseSenderBlock) {
172
- self.gestureCallback = callback
173
- }
174
-
175
170
  @objc func recordGesture(_ gestureType: String, x: NSNumber, y: NSNumber, target: String?, metadata: NSDictionary?) {
176
171
  let gestureEvent: [String: Any] = [
177
172
  "type": gestureType,
@@ -183,7 +178,6 @@ class SessionRecorderNative: RCTEventEmitter, UIGestureRecognizerDelegate {
183
178
  ]
184
179
 
185
180
  self.sendEvent(withName: "onGestureDetected", body: gestureEvent)
186
- if let cb = gestureCallback { cb([gestureEvent]) }
187
181
  }
188
182
 
189
183
  private func updateConfiguration(from options: NSDictionary) {
@@ -653,7 +647,6 @@ class SessionRecorderNative: RCTEventEmitter, UIGestureRecognizerDelegate {
653
647
  ]
654
648
 
655
649
  self.sendEvent(withName: "onGestureDetected", body: gestureEvent)
656
- if let cb = gestureCallback { cb([gestureEvent]) }
657
650
  }
658
651
 
659
652
  @objc private func handlePan(_ gesture: UIPanGestureRecognizer) {
@@ -693,7 +686,6 @@ class SessionRecorderNative: RCTEventEmitter, UIGestureRecognizerDelegate {
693
686
  ]
694
687
 
695
688
  self.sendEvent(withName: "onGestureDetected", body: gestureEvent)
696
- if let cb = gestureCallback { cb([gestureEvent]) }
697
689
  }
698
690
 
699
691
  @objc private func handleLongPress(_ gesture: UILongPressGestureRecognizer) {
@@ -722,7 +714,6 @@ class SessionRecorderNative: RCTEventEmitter, UIGestureRecognizerDelegate {
722
714
  ]
723
715
 
724
716
  self.sendEvent(withName: "onGestureDetected", body: gestureEvent)
725
- if let cb = gestureCallback { cb([gestureEvent]) }
726
717
  }
727
718
 
728
719
  @objc private func handlePinch(_ gesture: UIPinchGestureRecognizer) {
@@ -753,7 +744,6 @@ class SessionRecorderNative: RCTEventEmitter, UIGestureRecognizerDelegate {
753
744
  ]
754
745
 
755
746
  self.sendEvent(withName: "onGestureDetected", body: gestureEvent)
756
- if let cb = gestureCallback { cb([gestureEvent]) }
757
747
  }
758
748
 
759
749
  // MARK: - UIGestureRecognizerDelegate
@@ -812,9 +802,6 @@ extension UIView {
812
802
  }
813
803
 
814
804
  func isNoCapture() -> Bool {
815
- // Check for common patterns that indicate sensitive content
816
-
817
-
818
805
  // Check accessibility label for sensitive keywords
819
806
  if let accessibilityLabel = accessibilityLabel?.lowercased() {
820
807
  let sensitiveKeywords = ["password", "secret", "private", "sensitive", "confidential"]
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ import { TurboModuleRegistry } from 'react-native';
4
+ export default TurboModuleRegistry.getEnforcing('SessionRecorderNative');
5
+ //# sourceMappingURL=NativeSessionRecorderModule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeSessionRecorderModule.ts"],"mappings":";;AACA,SAASA,mBAAmB,QAAQ,cAAc;AA+BlD,eAAeA,mBAAmB,CAACC,YAAY,CAAO,uBAAuB,CAAC","ignoreList":[]}
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ import { TurboModuleRegistry } from 'react-native';
4
+ export default TurboModuleRegistry.getEnforcing('SessionRecorderNative');
5
+ //# sourceMappingURL=NativeSessionRecorderModuleSpec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeSessionRecorderModuleSpec.ts"],"mappings":";;AACA,SAASA,mBAAmB,QAAQ,cAAc;AA+BlD,eAAeA,mBAAmB,CAACC,YAAY,CAAO,uBAAuB,CAAC","ignoreList":[]}
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ import { TurboModuleRegistry } from 'react-native';
4
+ export default TurboModuleRegistry.getEnforcing('SessionRecorderNative');
5
+ //# sourceMappingURL=NativeSessionRecorderNative.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeSessionRecorderNative.ts"],"mappings":";;AACA,SAASA,mBAAmB,QAAQ,cAAc;AA+BlD,eAAeA,mBAAmB,CAACC,YAAY,CAAO,uBAAuB,CAAC","ignoreList":[]}
@@ -6,9 +6,6 @@ export * from '@multiplayer-app/session-recorder-common';
6
6
  export * from "./context/SessionRecorderContext.js";
7
7
  export * from "./context/useSessionRecorderStore.js";
8
8
 
9
- // Export TurboModule spec for codegen
10
- export * from "./SessionRecorderNativeSpec.js";
11
-
12
9
  // Export the class for type checking
13
10
  export { SessionRecorder };
14
11
  // Export the instance as default
@@ -1 +1 @@
1
- {"version":3,"names":["SessionRecorder"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA,OAAO,kBAAS;AAChB,OAAOA,eAAe,MAAM,uBAAoB;AAChD,cAAc,0CAA0C;AACxD,cAAc,qCAAkC;AAChD,cAAc,sCAAmC;;AAEjD;AACA,cAAc,gCAA6B;;AAE3C;AACA,SAASA,eAAe;AACxB;AACA,eAAeA,eAAe","ignoreList":[]}
1
+ {"version":3,"names":["SessionRecorder"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA,OAAO,kBAAS;AAChB,OAAOA,eAAe,MAAM,uBAAoB;AAChD,cAAc,0CAA0C;AACxD,cAAc,qCAAkC;AAChD,cAAc,sCAAmC;;AAGjD;AACA,SAASA,eAAe;AACxB;AACA,eAAeA,eAAe","ignoreList":[]}
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  import { Platform, NativeEventEmitter } from 'react-native';
4
- import SessionRecorderNative from "../SessionRecorderNativeSpec.js";
4
+ import SessionRecorderNative from "../NativeSessionRecorderModule.js";
5
5
 
6
6
  // Check if we're on web platform
7
7
  const isWeb = Platform.OS === 'web';
@@ -48,17 +48,6 @@ const SafeSessionRecorderNative = {
48
48
  }
49
49
  return SessionRecorderNative.isGestureRecordingActive();
50
50
  },
51
- setGestureCallback(callback) {
52
- if (isWeb || !SessionRecorderNative) {
53
- throw new Error('SessionRecorderNative is not available on web platform');
54
- }
55
- // Native side will also invoke callback if provided; also subscribe to events here
56
- try {
57
- SessionRecorderNative.setGestureCallback(callback);
58
- } catch {}
59
- eventEmitter?.removeAllListeners('onGestureDetected');
60
- eventEmitter?.addListener('onGestureDetected', callback);
61
- },
62
51
  recordGesture(gestureType, x, y, target, metadata) {
63
52
  if (isWeb || !SessionRecorderNative) {
64
53
  throw new Error('SessionRecorderNative is not available on web platform');
@@ -72,6 +61,14 @@ const SafeSessionRecorderNative = {
72
61
  // Required for RN event emitter contracts
73
62
  }
74
63
  };
64
+ // Helper function to set gesture callback using event emitter pattern
65
+ export function setGestureCallback(callback) {
66
+ if (isWeb || !SessionRecorderNative) {
67
+ throw new Error('SessionRecorderNative is not available on web platform');
68
+ }
69
+ eventEmitter?.removeAllListeners('onGestureDetected');
70
+ eventEmitter?.addListener('onGestureDetected', callback);
71
+ }
75
72
  export default SafeSessionRecorderNative;
76
73
 
77
74
  // Export event emitter for gesture events to maintain previous API
@@ -1 +1 @@
1
- {"version":3,"names":["Platform","NativeEventEmitter","SessionRecorderNative","isWeb","OS","eventEmitter","console","warn","info","SafeSessionRecorderNative","captureAndMask","Error","captureAndMaskWithOptions","options","startGestureRecording","stopGestureRecording","isGestureRecordingActive","setGestureCallback","callback","removeAllListeners","addListener","recordGesture","gestureType","x","y","target","metadata","_eventName","removeListeners","_count","gestureEventEmitter"],"sourceRoot":"../../../src","sources":["native/SessionRecorderNative.ts"],"mappings":";;AAAA,SAASA,QAAQ,EAAEC,kBAAkB,QAAQ,cAAc;AAC3D,OAAOC,qBAAqB,MAA0C,iCAA8B;;AAGpG;AACA,MAAMC,KAAK,GAAGH,QAAQ,CAACI,EAAE,KAAK,KAAK;;AAEnC;AACA,IAAIC,YAAY,GAAG,IAAIJ,kBAAkB,CAACC,qBAA4B,CAAC;;AAGvE;AACA,IAAI,CAACA,qBAAqB,IAAI,CAACC,KAAK,EAAE;EACpCG,OAAO,CAACC,IAAI,CACV,+FACF,CAAC;AACH,CAAC,MAAM,IAAIJ,KAAK,EAAE;EAChBG,OAAO,CAACE,IAAI,CACV,wEACF,CAAC;AACH;;AAEA;AACA,MAAMC,yBAA+B,GAAG;EACtC,MAAMC,cAAcA,CAAA,EAAoB;IACtC,IAAIP,KAAK,IAAI,CAACD,qBAAqB,EAAE;MACnC,MAAM,IAAIS,KAAK,CAAC,wDAAwD,CAAC;IAC3E;IACA,OAAOT,qBAAqB,CAACQ,cAAc,CAAC,CAAC;EAC/C,CAAC;EAED,MAAME,yBAAyBA,CAACC,OAAuB,EAAmB;IACxE,IAAIV,KAAK,IAAI,CAACD,qBAAqB,EAAE;MACnC,MAAM,IAAIS,KAAK,CAAC,wDAAwD,CAAC;IAC3E;IACA,OAAOT,qBAAqB,CAACU,yBAAyB,CAACC,OAAO,CAAC;EACjE,CAAC;EAED,MAAMC,qBAAqBA,CAAA,EAAkB;IAC3C,IAAIX,KAAK,IAAI,CAACD,qBAAqB,EAAE;MACnC,MAAM,IAAIS,KAAK,CAAC,wDAAwD,CAAC;IAC3E;IACA,OAAOT,qBAAqB,CAACY,qBAAqB,CAAC,CAAC;EACtD,CAAC;EAED,MAAMC,oBAAoBA,CAAA,EAAkB;IAC1C,IAAIZ,KAAK,IAAI,CAACD,qBAAqB,EAAE;MACnC,MAAM,IAAIS,KAAK,CAAC,wDAAwD,CAAC;IAC3E;IACA,OAAOT,qBAAqB,CAACa,oBAAoB,CAAC,CAAC;EACrD,CAAC;EAED,MAAMC,wBAAwBA,CAAA,EAAqB;IACjD,IAAIb,KAAK,IAAI,CAACD,qBAAqB,EAAE;MACnC,MAAM,IAAIS,KAAK,CAAC,wDAAwD,CAAC;IAC3E;IACA,OAAOT,qBAAqB,CAACc,wBAAwB,CAAC,CAAC;EACzD,CAAC;EAEDC,kBAAkBA,CAACC,QAA8B,EAAQ;IACvD,IAAIf,KAAK,IAAI,CAACD,qBAAqB,EAAE;MACnC,MAAM,IAAIS,KAAK,CAAC,wDAAwD,CAAC;IAC3E;IACA;IACA,IAAI;MACFT,qBAAqB,CAACe,kBAAkB,CAACC,QAAe,CAAC;IAC3D,CAAC,CAAC,MAAM,CAAE;IACVb,YAAY,EAAEc,kBAAkB,CAAC,mBAAmB,CAAC;IACrDd,YAAY,EAAEe,WAAW,CAAC,mBAAmB,EAAEF,QAAQ,CAAC;EAC1D,CAAC;EAEDG,aAAaA,CAACC,WAAmB,EAAEC,CAAS,EAAEC,CAAS,EAAEC,MAAe,EAAEC,QAAc,EAAQ;IAC9F,IAAIvB,KAAK,IAAI,CAACD,qBAAqB,EAAE;MACnC,MAAM,IAAIS,KAAK,CAAC,wDAAwD,CAAC;IAC3E;IACAT,qBAAqB,CAACmB,aAAa,CAACC,WAAW,EAAEC,CAAC,EAAEC,CAAC,EAAEC,MAAM,EAAEC,QAAQ,CAAC;EAC1E,CAAC;EAEDN,WAAWA,CAACO,UAAkB,EAAQ;IACpC;EAAA,CACD;EAEDC,eAAeA,CAACC,MAAc,EAAQ;IACpC;EAAA;AAEJ,CAAC;AA+BD,eAAepB,yBAAyB;;AAExC;AACA,OAAO,MAAMqB,mBAAmB,GAAGzB,YAAY","ignoreList":[]}
1
+ {"version":3,"names":["Platform","NativeEventEmitter","SessionRecorderNative","isWeb","OS","eventEmitter","console","warn","info","SafeSessionRecorderNative","captureAndMask","Error","captureAndMaskWithOptions","options","startGestureRecording","stopGestureRecording","isGestureRecordingActive","recordGesture","gestureType","x","y","target","metadata","addListener","_eventName","removeListeners","_count","setGestureCallback","callback","removeAllListeners","gestureEventEmitter"],"sourceRoot":"../../../src","sources":["native/SessionRecorderNative.ts"],"mappings":";;AAAA,SAASA,QAAQ,EAAEC,kBAAkB,QAAQ,cAAc;AAC3D,OAAOC,qBAAqB,MAA0C,mCAAgC;;AAGtG;AACA,MAAMC,KAAK,GAAGH,QAAQ,CAACI,EAAE,KAAK,KAAK;;AAEnC;AACA,IAAIC,YAAY,GAAG,IAAIJ,kBAAkB,CAACC,qBAA4B,CAAC;;AAGvE;AACA,IAAI,CAACA,qBAAqB,IAAI,CAACC,KAAK,EAAE;EACpCG,OAAO,CAACC,IAAI,CACV,+FACF,CAAC;AACH,CAAC,MAAM,IAAIJ,KAAK,EAAE;EAChBG,OAAO,CAACE,IAAI,CACV,wEACF,CAAC;AACH;;AAEA;AACA,MAAMC,yBAA+B,GAAG;EACtC,MAAMC,cAAcA,CAAA,EAAoB;IACtC,IAAIP,KAAK,IAAI,CAACD,qBAAqB,EAAE;MACnC,MAAM,IAAIS,KAAK,CAAC,wDAAwD,CAAC;IAC3E;IACA,OAAOT,qBAAqB,CAACQ,cAAc,CAAC,CAAC;EAC/C,CAAC;EAED,MAAME,yBAAyBA,CAACC,OAAuB,EAAmB;IACxE,IAAIV,KAAK,IAAI,CAACD,qBAAqB,EAAE;MACnC,MAAM,IAAIS,KAAK,CAAC,wDAAwD,CAAC;IAC3E;IACA,OAAOT,qBAAqB,CAACU,yBAAyB,CAACC,OAAO,CAAC;EACjE,CAAC;EAED,MAAMC,qBAAqBA,CAAA,EAAkB;IAC3C,IAAIX,KAAK,IAAI,CAACD,qBAAqB,EAAE;MACnC,MAAM,IAAIS,KAAK,CAAC,wDAAwD,CAAC;IAC3E;IACA,OAAOT,qBAAqB,CAACY,qBAAqB,CAAC,CAAC;EACtD,CAAC;EAED,MAAMC,oBAAoBA,CAAA,EAAkB;IAC1C,IAAIZ,KAAK,IAAI,CAACD,qBAAqB,EAAE;MACnC,MAAM,IAAIS,KAAK,CAAC,wDAAwD,CAAC;IAC3E;IACA,OAAOT,qBAAqB,CAACa,oBAAoB,CAAC,CAAC;EACrD,CAAC;EAED,MAAMC,wBAAwBA,CAAA,EAAqB;IACjD,IAAIb,KAAK,IAAI,CAACD,qBAAqB,EAAE;MACnC,MAAM,IAAIS,KAAK,CAAC,wDAAwD,CAAC;IAC3E;IACA,OAAOT,qBAAqB,CAACc,wBAAwB,CAAC,CAAC;EACzD,CAAC;EAEDC,aAAaA,CAACC,WAAmB,EAAEC,CAAS,EAAEC,CAAS,EAAEC,MAAe,EAAEC,QAAc,EAAQ;IAC9F,IAAInB,KAAK,IAAI,CAACD,qBAAqB,EAAE;MACnC,MAAM,IAAIS,KAAK,CAAC,wDAAwD,CAAC;IAC3E;IACAT,qBAAqB,CAACe,aAAa,CAACC,WAAW,EAAEC,CAAC,EAAEC,CAAC,EAAEC,MAAM,EAAEC,QAAQ,CAAC;EAC1E,CAAC;EAEDC,WAAWA,CAACC,UAAkB,EAAQ;IACpC;EAAA,CACD;EAEDC,eAAeA,CAACC,MAAc,EAAQ;IACpC;EAAA;AAEJ,CAAC;AA+BD;AACA,OAAO,SAASC,kBAAkBA,CAACC,QAA6C,EAAQ;EACtF,IAAIzB,KAAK,IAAI,CAACD,qBAAqB,EAAE;IACnC,MAAM,IAAIS,KAAK,CAAC,wDAAwD,CAAC;EAC3E;EACAN,YAAY,EAAEwB,kBAAkB,CAAC,mBAAmB,CAAC;EACrDxB,YAAY,EAAEkB,WAAW,CAAC,mBAAmB,EAAEK,QAAe,CAAC;AACjE;AAEA,eAAenB,yBAAyB;;AAExC;AACA,OAAO,MAAMqB,mBAAmB,GAAGzB,YAAY","ignoreList":[]}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- import SessionRecorderNative from "../SessionRecorderNativeSpec.js";
3
+ import SessionRecorderNative from "../native/SessionRecorderNative.js";
4
4
  import { logger } from "../utils/index.js";
5
5
  export class ScreenMaskingService {
6
6
  isAvailable = false;
@@ -1 +1 @@
1
- {"version":3,"names":["SessionRecorderNative","logger","ScreenMaskingService","isAvailable","constructor","config","enabled","maskTextInputs","maskImages","maskButtons","maskLabels","maskWebViews","maskSandboxedViews","checkAvailability","captureAndMask","info","warn","error","captureMaskedScreen","options","maskingOptions","maskedImageBase64","captureAndMaskWithOptions","captureMaskedScreenBasic","updateConfig","isScreenMaskingAvailable","getConfig","screenMaskingService"],"sourceRoot":"../../../src","sources":["services/screenMaskingService.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["SessionRecorderNative","logger","ScreenMaskingService","isAvailable","constructor","config","enabled","maskTextInputs","maskImages","maskButtons","maskLabels","maskWebViews","maskSandboxedViews","checkAvailability","captureAndMask","info","warn","error","captureMaskedScreen","options","maskingOptions","maskedImageBase64","captureAndMaskWithOptions","captureMaskedScreenBasic","updateConfig","isScreenMaskingAvailable","getConfig","screenMaskingService"],"sourceRoot":"../../../src","sources":["services/screenMaskingService.ts"],"mappings":";;AAAA,OAAOA,qBAAqB,MAA+B,oCAAiC;AAC5F,SAASC,MAAM,QAAQ,mBAAU;AAmBjC,OAAO,MAAMC,oBAAoB,CAAC;EAExBC,WAAW,GAAY,KAAK;EAEpCC,WAAWA,CACTC,MAA2B,GAAG;IAC5BC,OAAO,EAAE,IAAI;IACbC,cAAc,EAAE,IAAI;IACpBC,UAAU,EAAE,KAAK;IACjBC,WAAW,EAAE,KAAK;IAClBC,UAAU,EAAE,KAAK;IACjBC,YAAY,EAAE,KAAK;IACnBC,kBAAkB,EAAE;EACtB,CAAC,EACD;IACA,IAAI,CAACP,MAAM,GAAGA,MAAM;IACpB,IAAI,CAACQ,iBAAiB,CAAC,CAAC;EAC1B;;EAEA;AACF;AACA;EACUA,iBAAiBA,CAAA,EAAS;IAChC,IAAI;MACF;MACA,IACEb,qBAAqB,IACrB,OAAOA,qBAAqB,CAACc,cAAc,KAAK,UAAU,EAC1D;QACA,IAAI,CAACX,WAAW,GAAG,IAAI;QACvBF,MAAM,CAACc,IAAI,CACT,sBAAsB,EACtB,2CACF,CAAC;MACH,CAAC,MAAM;QACL,IAAI,CAACZ,WAAW,GAAG,KAAK;QACxBF,MAAM,CAACe,IAAI,CACT,sBAAsB,EACtB,uFACF,CAAC;MACH;IACF,CAAC,CAAC,OAAOC,KAAK,EAAE;MACd,IAAI,CAACd,WAAW,GAAG,KAAK;MACxBF,MAAM,CAACgB,KAAK,CACV,sBAAsB,EACtB,6CAA6C,EAC7CA,KACF,CAAC;IACH;EACF;;EAEA;AACF;AACA;EACE,MAAMC,mBAAmBA,CAACC,OAAuB,EAA0B;IACzE,IAAI,CAAC,IAAI,CAAChB,WAAW,IAAI,CAAC,IAAI,CAACE,MAAM,CAACC,OAAO,EAAE;MAC7CL,MAAM,CAACe,IAAI,CACT,sBAAsB,EACtB,6CACF,CAAC;MACD,OAAO,IAAI;IACb;IAEA,IAAI;MACF,MAAMI,cAA8B,GAAG;QACrC,GAAG,IAAI,CAACf,MAAM;QACd,GAAGc;MACL,CAAC;MACD,MAAME,iBAAiB,GACrB,MAAMrB,qBAAqB,CAACsB,yBAAyB,CAACF,cAAc,CAAC;MACvE,OAAOC,iBAAiB;IAC1B,CAAC,CAAC,OAAOJ,KAAK,EAAE;MACdhB,MAAM,CAACgB,KAAK,CACV,sBAAsB,EACtB,kCAAkC,EAClCA,KACF,CAAC;MACD,OAAO,IAAI;IACb;EACF;;EAEA;AACF;AACA;EACE,MAAMM,wBAAwBA,CAAA,EAA2B;IACvD,IAAI,CAAC,IAAI,CAACpB,WAAW,IAAI,CAAC,IAAI,CAACE,MAAM,CAACC,OAAO,EAAE;MAC7CL,MAAM,CAACe,IAAI,CACT,sBAAsB,EACtB,6CACF,CAAC;MACD,OAAO,IAAI;IACb;IAEA,IAAI;MACF,MAAMK,iBAAiB,GAAG,MAAMrB,qBAAqB,CAACc,cAAc,CAAC,CAAC;MACtE,OAAOO,iBAAiB;IAC1B,CAAC,CAAC,OAAOJ,KAAK,EAAE;MACdhB,MAAM,CAACgB,KAAK,CACV,sBAAsB,EACtB,0CAA0C,EAC1CA,KACF,CAAC;MACD,OAAO,IAAI;IACb;EACF;;EAEA;AACF;AACA;EACEO,YAAYA,CAACnB,MAAoC,EAAQ;IACvD,IAAI,CAACA,MAAM,GAAG;MAAE,GAAG,IAAI,CAACA,MAAM;MAAE,GAAGA;IAAO,CAAC;IAC3CJ,MAAM,CAACc,IAAI,CAAC,sBAAsB,EAAE,sCAAsC,CAAC;EAC7E;;EAEA;AACF;AACA;EACEU,wBAAwBA,CAAA,EAAY;IAClC,OAAO,IAAI,CAACtB,WAAW,IAAI,IAAI,CAACE,MAAM,CAACC,OAAO;EAChD;;EAEA;AACF;AACA;EACEoB,SAASA,CAAA,EAAwB;IAC/B,OAAO;MAAE,GAAG,IAAI,CAACrB;IAAO,CAAC;EAC3B;AACF;;AAEA;AACA,OAAO,MAAMsB,oBAAoB,GAAG,IAAIzB,oBAAoB,CAAC,CAAC","ignoreList":[]}
@@ -0,0 +1,25 @@
1
+ import type { TurboModule } from 'react-native';
2
+ export type MaskingOptions = Readonly<{
3
+ maskTextInputs?: boolean;
4
+ maskImages?: boolean;
5
+ maskButtons?: boolean;
6
+ maskLabels?: boolean;
7
+ maskWebViews?: boolean;
8
+ maskSandboxedViews?: boolean;
9
+ quality?: number;
10
+ scale?: number;
11
+ noCaptureLabel?: string;
12
+ }>;
13
+ export interface Spec extends TurboModule {
14
+ captureAndMask(): Promise<string>;
15
+ captureAndMaskWithOptions(options: MaskingOptions): Promise<string>;
16
+ startGestureRecording(): Promise<void>;
17
+ stopGestureRecording(): Promise<void>;
18
+ isGestureRecordingActive(): Promise<boolean>;
19
+ recordGesture(gestureType: string, x: number, y: number, target?: string, metadata?: Object): void;
20
+ addListener(eventName: string): void;
21
+ removeListeners(count: number): void;
22
+ }
23
+ declare const _default: Spec;
24
+ export default _default;
25
+ //# sourceMappingURL=NativeSessionRecorderModule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NativeSessionRecorderModule.d.ts","sourceRoot":"","sources":["../../../src/NativeSessionRecorderModule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC,CAAC;AAEH,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC,yBAAyB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpE,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,wBAAwB,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,aAAa,CACX,WAAW,EAAE,MAAM,EACnB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,MAAM,CAAC,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,GAChB,IAAI,CAAC;IACR,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;wBAEiF,IAAI;AAAtF,wBAAuF"}
@@ -0,0 +1,25 @@
1
+ import type { TurboModule } from 'react-native';
2
+ export type MaskingOptions = Readonly<{
3
+ maskTextInputs?: boolean;
4
+ maskImages?: boolean;
5
+ maskButtons?: boolean;
6
+ maskLabels?: boolean;
7
+ maskWebViews?: boolean;
8
+ maskSandboxedViews?: boolean;
9
+ quality?: number;
10
+ scale?: number;
11
+ noCaptureLabel?: string;
12
+ }>;
13
+ export interface Spec extends TurboModule {
14
+ captureAndMask(): Promise<string>;
15
+ captureAndMaskWithOptions(options: MaskingOptions): Promise<string>;
16
+ startGestureRecording(): Promise<void>;
17
+ stopGestureRecording(): Promise<void>;
18
+ isGestureRecordingActive(): Promise<boolean>;
19
+ recordGesture(gestureType: string, x: number, y: number, target?: string, metadata?: Object): void;
20
+ addListener(eventName: string): void;
21
+ removeListeners(count: number): void;
22
+ }
23
+ declare const _default: Spec;
24
+ export default _default;
25
+ //# sourceMappingURL=NativeSessionRecorderModuleSpec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NativeSessionRecorderModuleSpec.d.ts","sourceRoot":"","sources":["../../../src/NativeSessionRecorderModuleSpec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC,CAAC;AAEH,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC,yBAAyB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpE,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,wBAAwB,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,aAAa,CACX,WAAW,EAAE,MAAM,EACnB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,MAAM,CAAC,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,GAChB,IAAI,CAAC;IACR,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;wBAEiF,IAAI;AAAtF,wBAAuF"}
@@ -0,0 +1,25 @@
1
+ import type { TurboModule } from 'react-native';
2
+ export type MaskingOptions = Readonly<{
3
+ maskTextInputs?: boolean;
4
+ maskImages?: boolean;
5
+ maskButtons?: boolean;
6
+ maskLabels?: boolean;
7
+ maskWebViews?: boolean;
8
+ maskSandboxedViews?: boolean;
9
+ quality?: number;
10
+ scale?: number;
11
+ noCaptureLabel?: string;
12
+ }>;
13
+ export interface Spec extends TurboModule {
14
+ captureAndMask(): Promise<string>;
15
+ captureAndMaskWithOptions(options: MaskingOptions): Promise<string>;
16
+ startGestureRecording(): Promise<void>;
17
+ stopGestureRecording(): Promise<void>;
18
+ isGestureRecordingActive(): Promise<boolean>;
19
+ recordGesture(gestureType: string, x: number, y: number, target?: string, metadata?: Object): void;
20
+ addListener(eventName: string): void;
21
+ removeListeners(count: number): void;
22
+ }
23
+ declare const _default: Spec;
24
+ export default _default;
25
+ //# sourceMappingURL=NativeSessionRecorderNative.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NativeSessionRecorderNative.d.ts","sourceRoot":"","sources":["../../../src/NativeSessionRecorderNative.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC,CAAC;AAEH,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC,yBAAyB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpE,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,wBAAwB,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,aAAa,CACX,WAAW,EAAE,MAAM,EACnB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,MAAM,CAAC,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,GAChB,IAAI,CAAC;IACR,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;;AAED,wBAA+E"}
@@ -3,7 +3,6 @@ import SessionRecorder from './session-recorder';
3
3
  export * from '@multiplayer-app/session-recorder-common';
4
4
  export * from './context/SessionRecorderContext';
5
5
  export * from './context/useSessionRecorderStore';
6
- export * from './SessionRecorderNativeSpec';
7
6
  export { SessionRecorder };
8
7
  export default SessionRecorder;
9
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,CAAC;AACjB,OAAO,eAAe,MAAM,oBAAoB,CAAC;AACjD,cAAc,0CAA0C,CAAC;AACzD,cAAc,kCAAkC,CAAC;AACjD,cAAc,mCAAmC,CAAC;AAGlD,cAAc,6BAA6B,CAAC;AAG5C,OAAO,EAAE,eAAe,EAAE,CAAC;AAE3B,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,CAAC;AACjB,OAAO,eAAe,MAAM,oBAAoB,CAAC;AACjD,cAAc,0CAA0C,CAAC;AACzD,cAAc,kCAAkC,CAAC;AACjD,cAAc,mCAAmC,CAAC;AAIlD,OAAO,EAAE,eAAe,EAAE,CAAC;AAE3B,eAAe,eAAe,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { NativeEventEmitter } from 'react-native';
2
- import { type Spec } from '../SessionRecorderNativeSpec';
2
+ import { type MaskingOptions, type Spec } from '../NativeSessionRecorderModule';
3
3
  declare const SafeSessionRecorderNative: Spec;
4
4
  export interface NativeGestureEvent {
5
5
  type: 'tap' | 'pan_start' | 'pan_move' | 'pan_end' | 'long_press' | 'pinch' | 'swipe';
@@ -22,6 +22,8 @@ export interface NativeGestureEvent {
22
22
  distance?: number;
23
23
  };
24
24
  }
25
+ export declare function setGestureCallback(callback: (event: NativeGestureEvent) => void): void;
25
26
  export default SafeSessionRecorderNative;
26
27
  export declare const gestureEventEmitter: NativeEventEmitter<Readonly<Record<string, readonly Object[]>>>;
28
+ export type { MaskingOptions };
27
29
  //# sourceMappingURL=SessionRecorderNative.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SessionRecorderNative.d.ts","sourceRoot":"","sources":["../../../../src/native/SessionRecorderNative.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAC5D,OAA8B,EAAuB,KAAK,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAsBrG,QAAA,MAAM,yBAAyB,EAAE,IA8DhC,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,IAAI,EACF,KAAK,GACL,WAAW,GACX,UAAU,GACV,SAAS,GACT,YAAY,GACZ,OAAO,GACP,OAAO,CAAC;IACV,SAAS,EAAE,MAAM,CAAC;IAClB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE;QACX,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,eAAe,yBAAyB,CAAC;AAGzC,eAAO,MAAM,mBAAmB,iEAAe,CAAC"}
1
+ {"version":3,"file":"SessionRecorderNative.d.ts","sourceRoot":"","sources":["../../../../src/native/SessionRecorderNative.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAC5D,OAA8B,EAAE,KAAK,cAAc,EAAE,KAAK,IAAI,EAAE,MAAM,gCAAgC,CAAC;AAsBvG,QAAA,MAAM,yBAAyB,EAAE,IAkDhC,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,IAAI,EACF,KAAK,GACL,WAAW,GACX,UAAU,GACV,SAAS,GACT,YAAY,GACZ,OAAO,GACP,OAAO,CAAC;IACV,SAAS,EAAE,MAAM,CAAC;IAClB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE;QACX,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAGD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,GAAG,IAAI,CAMtF;AAED,eAAe,yBAAyB,CAAC;AAGzC,eAAO,MAAM,mBAAmB,iEAAe,CAAC;AAChD,YAAY,EAAE,cAAc,EAAE,CAAC"}
@@ -1,4 +1,4 @@
1
- import { type MaskingOptions } from '../SessionRecorderNativeSpec';
1
+ import { type MaskingOptions } from '../native/SessionRecorderNative';
2
2
  export interface ScreenMaskingConfig {
3
3
  /** Whether screen masking is enabled */
4
4
  enabled: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"screenMaskingService.d.ts","sourceRoot":"","sources":["../../../../src/services/screenMaskingService.ts"],"names":[],"mappings":"AAAA,OAA8B,EAC5B,KAAK,cAAc,EACpB,MAAM,8BAA8B,CAAC;AAGtC,MAAM,WAAW,mBAAmB;IAClC,wCAAwC;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,0FAA0F;IAC1F,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yCAAyC;IACzC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uCAAuC;IACvC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,4CAA4C;IAC5C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,0FAA0F;IAC1F,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,WAAW,CAAkB;gBAGnC,MAAM,GAAE,mBAQP;IAMH;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA6BzB;;OAEG;IACG,mBAAmB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IA2B1E;;OAEG;IACG,wBAAwB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAsBxD;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,mBAAmB,CAAC,GAAG,IAAI;IAKxD;;OAEG;IACH,wBAAwB,IAAI,OAAO;IAInC;;OAEG;IACH,SAAS,IAAI,mBAAmB;CAGjC;AAGD,eAAO,MAAM,oBAAoB,sBAA6B,CAAC"}
1
+ {"version":3,"file":"screenMaskingService.d.ts","sourceRoot":"","sources":["../../../../src/services/screenMaskingService.ts"],"names":[],"mappings":"AAAA,OAA8B,EAAE,KAAK,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAG7F,MAAM,WAAW,mBAAmB;IAClC,wCAAwC;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,0FAA0F;IAC1F,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yCAAyC;IACzC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uCAAuC;IACvC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,4CAA4C;IAC5C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,0FAA0F;IAC1F,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,WAAW,CAAkB;gBAGnC,MAAM,GAAE,mBAQP;IAMH;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA6BzB;;OAEG;IACG,mBAAmB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IA2B1E;;OAEG;IACG,wBAAwB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAsBxD;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,mBAAmB,CAAC,GAAG,IAAI;IAKxD;;OAEG;IACH,wBAAwB,IAAI,OAAO;IAInC;;OAEG;IACH,SAAS,IAAI,mBAAmB;CAGjC;AAGD,eAAO,MAAM,oBAAoB,sBAA6B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@multiplayer-app/session-recorder-react-native",
3
- "version": "1.0.1-beta.9",
3
+ "version": "1.0.1",
4
4
  "description": "Multiplayer Fullstack Session Recorder for React Native",
5
5
  "author": {
6
6
  "name": "Multiplayer Software, Inc.",
@@ -17,6 +17,15 @@
17
17
  },
18
18
  "main": "./lib/module/index.js",
19
19
  "types": "./lib/typescript/src/index.d.ts",
20
+ "react-native": "./lib/module/index.js",
21
+ "android": {
22
+ "package": "com.sessionrecordernative",
23
+ "sourceDir": "./android",
24
+ "packageImportPath": "import com.sessionrecordernative.SessionRecorderNativePackage;"
25
+ },
26
+ "ios": {
27
+ "podspecPath": "./SessionRecorderNative.podspec"
28
+ },
20
29
  "exports": {
21
30
  ".": {
22
31
  "source": "./src/index.ts",
@@ -48,9 +57,9 @@
48
57
  "test": "jest",
49
58
  "typecheck": "tsc",
50
59
  "lint": "eslint \"**/*.{js,ts,tsx}\"",
51
- "clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
52
60
  "prepare": "bob build",
53
- "release": "release-it --only-version"
61
+ "release": "release-it --only-version",
62
+ "copy": "./copy.sh"
54
63
  },
55
64
  "keywords": [
56
65
  "multiplayer",
@@ -126,6 +135,9 @@
126
135
  "react-native-safe-area-context": "*",
127
136
  "react-native-svg": "*"
128
137
  },
138
+ "workspaces": [
139
+ "example"
140
+ ],
129
141
  "packageManager": "yarn@3.6.1",
130
142
  "jest": {
131
143
  "preset": "react-native",
@@ -184,7 +196,7 @@
184
196
  ]
185
197
  },
186
198
  "codegenConfig": {
187
- "name": "SessionRecorderNativeSpec",
199
+ "name": "NativeSessionRecorderModule",
188
200
  "type": "modules",
189
201
  "jsSrcsDir": "src",
190
202
  "android": {
@@ -192,8 +204,16 @@
192
204
  }
193
205
  },
194
206
  "create-react-native-library": {
195
- "languages": "kotlin-objc",
207
+ "languages": "kotlin-swift",
196
208
  "type": "turbo-module",
197
209
  "version": "0.54.5"
210
+ },
211
+ "expo": {
212
+ "name": "@multiplayer-app/session-recorder-react-native",
213
+ "slug": "session-recorder-react-native",
214
+ "platforms": [
215
+ "ios",
216
+ "android"
217
+ ]
198
218
  }
199
219
  }
@@ -0,0 +1,14 @@
1
+ module.exports = {
2
+ dependency: {
3
+ platforms: {
4
+ android: {
5
+ sourceDir: './android',
6
+ packageImportPath:
7
+ 'import com.sessionrecordernative.SessionRecorderNativePackage;',
8
+ },
9
+ ios: {
10
+ podspecPath: './SessionRecorderNative.podspec',
11
+ },
12
+ },
13
+ },
14
+ };
@@ -0,0 +1,33 @@
1
+ import type { TurboModule } from 'react-native';
2
+ import { TurboModuleRegistry } from 'react-native';
3
+
4
+ export type MaskingOptions = Readonly<{
5
+ maskTextInputs?: boolean;
6
+ maskImages?: boolean;
7
+ maskButtons?: boolean;
8
+ maskLabels?: boolean;
9
+ maskWebViews?: boolean;
10
+ maskSandboxedViews?: boolean;
11
+ quality?: number;
12
+ scale?: number;
13
+ noCaptureLabel?: string;
14
+ }>;
15
+
16
+ export interface Spec extends TurboModule {
17
+ captureAndMask(): Promise<string>;
18
+ captureAndMaskWithOptions(options: MaskingOptions): Promise<string>;
19
+ startGestureRecording(): Promise<void>;
20
+ stopGestureRecording(): Promise<void>;
21
+ isGestureRecordingActive(): Promise<boolean>;
22
+ recordGesture(
23
+ gestureType: string,
24
+ x: number,
25
+ y: number,
26
+ target?: string,
27
+ metadata?: Object,
28
+ ): void;
29
+ addListener(eventName: string): void;
30
+ removeListeners(count: number): void;
31
+ }
32
+
33
+ export default TurboModuleRegistry.getEnforcing<Spec>('SessionRecorderNative') as Spec;
@@ -0,0 +1,33 @@
1
+ import type { TurboModule } from 'react-native';
2
+ import { TurboModuleRegistry } from 'react-native';
3
+
4
+ export type MaskingOptions = Readonly<{
5
+ maskTextInputs?: boolean;
6
+ maskImages?: boolean;
7
+ maskButtons?: boolean;
8
+ maskLabels?: boolean;
9
+ maskWebViews?: boolean;
10
+ maskSandboxedViews?: boolean;
11
+ quality?: number;
12
+ scale?: number;
13
+ noCaptureLabel?: string;
14
+ }>;
15
+
16
+ export interface Spec extends TurboModule {
17
+ captureAndMask(): Promise<string>;
18
+ captureAndMaskWithOptions(options: MaskingOptions): Promise<string>;
19
+ startGestureRecording(): Promise<void>;
20
+ stopGestureRecording(): Promise<void>;
21
+ isGestureRecordingActive(): Promise<boolean>;
22
+ recordGesture(
23
+ gestureType: string,
24
+ x: number,
25
+ y: number,
26
+ target?: string,
27
+ metadata?: Object,
28
+ ): void;
29
+ addListener(eventName: string): void;
30
+ removeListeners(count: number): void;
31
+ }
32
+
33
+ export default TurboModuleRegistry.getEnforcing<Spec>('SessionRecorderNative') as Spec;
@@ -0,0 +1,33 @@
1
+ import type { TurboModule } from 'react-native';
2
+ import { TurboModuleRegistry } from 'react-native';
3
+
4
+ export type MaskingOptions = Readonly<{
5
+ maskTextInputs?: boolean;
6
+ maskImages?: boolean;
7
+ maskButtons?: boolean;
8
+ maskLabels?: boolean;
9
+ maskWebViews?: boolean;
10
+ maskSandboxedViews?: boolean;
11
+ quality?: number;
12
+ scale?: number;
13
+ noCaptureLabel?: string;
14
+ }>;
15
+
16
+ export interface Spec extends TurboModule {
17
+ captureAndMask(): Promise<string>;
18
+ captureAndMaskWithOptions(options: MaskingOptions): Promise<string>;
19
+ startGestureRecording(): Promise<void>;
20
+ stopGestureRecording(): Promise<void>;
21
+ isGestureRecordingActive(): Promise<boolean>;
22
+ recordGesture(
23
+ gestureType: string,
24
+ x: number,
25
+ y: number,
26
+ target?: string,
27
+ metadata?: Object,
28
+ ): void;
29
+ addListener(eventName: string): void;
30
+ removeListeners(count: number): void;
31
+ }
32
+
33
+ export default TurboModuleRegistry.getEnforcing<Spec>('SessionRecorderNative');
package/src/index.ts CHANGED
@@ -4,8 +4,6 @@ export * from '@multiplayer-app/session-recorder-common';
4
4
  export * from './context/SessionRecorderContext';
5
5
  export * from './context/useSessionRecorderStore';
6
6
 
7
- // Export TurboModule spec for codegen
8
- export * from './SessionRecorderNativeSpec';
9
7
 
10
8
  // Export the class for type checking
11
9
  export { SessionRecorder };
@@ -1,5 +1,5 @@
1
1
  import { Platform, NativeEventEmitter } from 'react-native';
2
- import SessionRecorderNative, { type MaskingOptions, type Spec } from '../SessionRecorderNativeSpec';
2
+ import SessionRecorderNative, { type MaskingOptions, type Spec } from '../NativeSessionRecorderModule';
3
3
 
4
4
 
5
5
  // Check if we're on web platform
@@ -57,18 +57,6 @@ const SafeSessionRecorderNative: Spec = {
57
57
  return SessionRecorderNative.isGestureRecordingActive();
58
58
  },
59
59
 
60
- setGestureCallback(callback: (event: any) => void): void {
61
- if (isWeb || !SessionRecorderNative) {
62
- throw new Error('SessionRecorderNative is not available on web platform');
63
- }
64
- // Native side will also invoke callback if provided; also subscribe to events here
65
- try {
66
- SessionRecorderNative.setGestureCallback(callback as any);
67
- } catch { }
68
- eventEmitter?.removeAllListeners('onGestureDetected');
69
- eventEmitter?.addListener('onGestureDetected', callback);
70
- },
71
-
72
60
  recordGesture(gestureType: string, x: number, y: number, target?: string, metadata?: any): void {
73
61
  if (isWeb || !SessionRecorderNative) {
74
62
  throw new Error('SessionRecorderNative is not available on web platform');
@@ -114,7 +102,17 @@ export interface NativeGestureEvent {
114
102
  };
115
103
  }
116
104
 
105
+ // Helper function to set gesture callback using event emitter pattern
106
+ export function setGestureCallback(callback: (event: NativeGestureEvent) => void): void {
107
+ if (isWeb || !SessionRecorderNative) {
108
+ throw new Error('SessionRecorderNative is not available on web platform');
109
+ }
110
+ eventEmitter?.removeAllListeners('onGestureDetected');
111
+ eventEmitter?.addListener('onGestureDetected', callback as any);
112
+ }
113
+
117
114
  export default SafeSessionRecorderNative;
118
115
 
119
116
  // Export event emitter for gesture events to maintain previous API
120
117
  export const gestureEventEmitter = eventEmitter;
118
+ export type { MaskingOptions };
@@ -1,6 +1,4 @@
1
- import SessionRecorderNative, {
2
- type MaskingOptions,
3
- } from '../SessionRecorderNativeSpec';
1
+ import SessionRecorderNative, { type MaskingOptions } from '../native/SessionRecorderNative';
4
2
  import { logger } from '../utils';
5
3
 
6
4
  export interface ScreenMaskingConfig {
@@ -1,79 +0,0 @@
1
- package com.multiplayer.sessionrecordernative
2
-
3
- import com.facebook.react.bridge.ReactApplicationContext
4
- import com.facebook.react.bridge.ReactContextBaseJavaModule
5
- import com.facebook.react.bridge.ReactMethod
6
- import com.facebook.react.bridge.Promise
7
- import com.facebook.react.bridge.Callback
8
- import com.facebook.react.bridge.ReadableMap
9
- import com.facebook.react.bridge.Arguments
10
- import com.facebook.react.bridge.WritableMap
11
-
12
- /**
13
- * Spec class for SessionRecorderNative TurboModule
14
- * This class defines the interface that React Native expects for TurboModules
15
- */
16
- class SessionRecorderNativeSpec(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
17
-
18
- override fun getName(): String {
19
- return NAME
20
- }
21
-
22
- companion object {
23
- const val NAME = "SessionRecorderNative"
24
- }
25
-
26
- // Delegate to the actual implementation
27
- private val implementation = SessionRecorderNativeModule(reactContext)
28
-
29
- @ReactMethod
30
- fun captureAndMask(promise: Promise) {
31
- implementation.captureAndMask(promise)
32
- }
33
-
34
- @ReactMethod
35
- fun captureAndMaskWithOptions(options: ReadableMap, promise: Promise) {
36
- implementation.captureAndMaskWithOptions(options, promise)
37
- }
38
-
39
- @ReactMethod
40
- fun startGestureRecording(promise: Promise) {
41
- implementation.startGestureRecording(promise)
42
- }
43
-
44
- @ReactMethod
45
- fun stopGestureRecording(promise: Promise) {
46
- implementation.stopGestureRecording(promise)
47
- }
48
-
49
- @ReactMethod
50
- fun isGestureRecordingActive(promise: Promise) {
51
- implementation.isGestureRecordingActive(promise)
52
- }
53
-
54
- @ReactMethod
55
- fun setGestureCallback(callback: Callback) {
56
- implementation.setGestureCallback(callback)
57
- }
58
-
59
- @ReactMethod
60
- fun recordGesture(
61
- gestureType: String,
62
- x: Double,
63
- y: Double,
64
- target: String?,
65
- metadata: ReadableMap?
66
- ) {
67
- implementation.recordGesture(gestureType, x, y, target, metadata)
68
- }
69
-
70
- @ReactMethod
71
- fun addListener(eventName: String) {
72
- implementation.addListener(eventName)
73
- }
74
-
75
- @ReactMethod
76
- fun removeListeners(count: Int) {
77
- implementation.removeListeners(count)
78
- }
79
- }
@@ -1,22 +0,0 @@
1
- require "json"
2
-
3
- package = JSON.parse(File.read(File.join(__dir__, "..", "package.json")))
4
-
5
- Pod::Spec.new do |s|
6
- s.name = "SessionRecorderNative"
7
- s.version = package["version"]
8
- s.summary = "Native session recorder module for React Native"
9
- s.description = "A native module that provides session recording with automatic masking of sensitive UI elements"
10
- s.homepage = "https://github.com/multiplayer-app/multiplayer-session-recorder-javascript"
11
- s.license = "MIT"
12
- s.authors = { "Multiplayer Software, Inc." => "https://www.multiplayer.app" }
13
- s.platforms = { :ios => "12.0" }
14
- s.source = { :git => "https://github.com/multiplayer-app/multiplayer-session-recorder-javascript.git", :tag => "#{s.version}" }
15
-
16
- s.source_files = "ios/**/*.{h,m,mm,swift}"
17
- s.swift_version = "5.0"
18
- s.requires_arc = true
19
-
20
- s.dependency "React-Core"
21
- s.dependency "React"
22
- end
@@ -1,5 +0,0 @@
1
- "use strict";
2
-
3
- import { NativeModules } from 'react-native';
4
- export default NativeModules.SessionRecorderNative;
5
- //# sourceMappingURL=SessionRecorderNativeSpec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["NativeModules","SessionRecorderNative"],"sourceRoot":"../../src","sources":["SessionRecorderNativeSpec.ts"],"mappings":";;AAAA,SAASA,aAAa,QAAQ,cAAc;AAmD5C,eAAeA,aAAa,CAACC,qBAAqB","ignoreList":[]}
@@ -1,41 +0,0 @@
1
- export interface Spec {
2
- /**
3
- * Capture the current screen and apply masking to sensitive elements
4
- * @returns Promise that resolves to base64 encoded image
5
- */
6
- captureAndMask(): Promise<string>;
7
- /**
8
- * Capture the current screen and apply masking with custom options
9
- * @param options Custom masking options
10
- * @returns Promise that resolves to base64 encoded image
11
- */
12
- captureAndMaskWithOptions(options: MaskingOptions): Promise<string>;
13
- startGestureRecording(): Promise<void>;
14
- stopGestureRecording(): Promise<void>;
15
- isGestureRecordingActive(): Promise<boolean>;
16
- setGestureCallback(callback: (event: any) => void): void;
17
- recordGesture(gestureType: string, x: number, y: number, target?: string, metadata?: any): void;
18
- addListener(eventName: string): void;
19
- removeListeners(count: number): void;
20
- }
21
- export interface MaskingOptions {
22
- /** Quality of the captured image (0.1 to 1.0, default: 0.3 for smaller file size) */
23
- quality?: number;
24
- /** Scale of the captured image (0.1 to 1.0, default: 1.0) */
25
- scale?: number;
26
- /** Whether to mask text inputs (UITextField, UITextView, React Native text components) */
27
- maskTextInputs?: boolean;
28
- /** Whether to mask images (UIImageView, React Native Image components) */
29
- maskImages?: boolean;
30
- /** Whether to mask buttons (UIButton) */
31
- maskButtons?: boolean;
32
- /** Whether to mask labels (UILabel) */
33
- maskLabels?: boolean;
34
- /** Whether to mask web views (WKWebView) */
35
- maskWebViews?: boolean;
36
- /** Whether to mask sandboxed views (system views that don't belong to current process) */
37
- maskSandboxedViews?: boolean;
38
- }
39
- declare const _default: Spec;
40
- export default _default;
41
- //# sourceMappingURL=SessionRecorderNativeSpec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SessionRecorderNativeSpec.d.ts","sourceRoot":"","sources":["../../../src/SessionRecorderNativeSpec.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,IAAI;IACnB;;;OAGG;IACH,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAElC;;;;OAIG;IACH,yBAAyB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAGpE,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,wBAAwB,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,kBAAkB,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;IACzD,aAAa,CACX,WAAW,EAAE,MAAM,EACnB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,MAAM,CAAC,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,GAAG,GACb,IAAI,CAAC;IACR,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,cAAc;IAC7B,qFAAqF;IACrF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0FAA0F;IAC1F,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yCAAyC;IACzC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uCAAuC;IACvC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,4CAA4C;IAC5C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,0FAA0F;IAC1F,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;wBAEqD,IAAI;AAA1D,wBAA2D"}
@@ -1,52 +0,0 @@
1
- import { NativeModules } from 'react-native';
2
-
3
- export interface Spec {
4
- /**
5
- * Capture the current screen and apply masking to sensitive elements
6
- * @returns Promise that resolves to base64 encoded image
7
- */
8
- captureAndMask(): Promise<string>;
9
-
10
- /**
11
- * Capture the current screen and apply masking with custom options
12
- * @param options Custom masking options
13
- * @returns Promise that resolves to base64 encoded image
14
- */
15
- captureAndMaskWithOptions(options: MaskingOptions): Promise<string>;
16
-
17
- // Gesture recording APIs
18
- startGestureRecording(): Promise<void>;
19
- stopGestureRecording(): Promise<void>;
20
- isGestureRecordingActive(): Promise<boolean>;
21
- setGestureCallback(callback: (event: any) => void): void;
22
- recordGesture(
23
- gestureType: string,
24
- x: number,
25
- y: number,
26
- target?: string,
27
- metadata?: any
28
- ): void;
29
- addListener(eventName: string): void;
30
- removeListeners(count: number): void;
31
- }
32
-
33
- export interface MaskingOptions {
34
- /** Quality of the captured image (0.1 to 1.0, default: 0.3 for smaller file size) */
35
- quality?: number;
36
- /** Scale of the captured image (0.1 to 1.0, default: 1.0) */
37
- scale?: number;
38
- /** Whether to mask text inputs (UITextField, UITextView, React Native text components) */
39
- maskTextInputs?: boolean;
40
- /** Whether to mask images (UIImageView, React Native Image components) */
41
- maskImages?: boolean;
42
- /** Whether to mask buttons (UIButton) */
43
- maskButtons?: boolean;
44
- /** Whether to mask labels (UILabel) */
45
- maskLabels?: boolean;
46
- /** Whether to mask web views (WKWebView) */
47
- maskWebViews?: boolean;
48
- /** Whether to mask sandboxed views (system views that don't belong to current process) */
49
- maskSandboxedViews?: boolean;
50
- }
51
-
52
- export default NativeModules.SessionRecorderNative as Spec;