@repliqo/sdk-react-native 0.1.0

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 (58) hide show
  1. package/INTEGRATION_GUIDE.md +1312 -0
  2. package/android/build.gradle +24 -0
  3. package/android/src/main/AndroidManifest.xml +4 -0
  4. package/android/src/main/java/com/repliqo/screencapture/MultiWindowCapture.java +230 -0
  5. package/android/src/main/java/com/repliqo/screencapture/ScreenCaptureModule.java +94 -0
  6. package/android/src/main/java/com/repliqo/screencapture/ScreenCapturePackage.java +38 -0
  7. package/dist/components/ScreenCapturePermission.d.ts +55 -0
  8. package/dist/components/ScreenCapturePermission.js +112 -0
  9. package/dist/core/client.d.ts +41 -0
  10. package/dist/core/client.js +309 -0
  11. package/dist/core/config.d.ts +4 -0
  12. package/dist/core/config.js +26 -0
  13. package/dist/core/logger.d.ts +8 -0
  14. package/dist/core/logger.js +25 -0
  15. package/dist/index.d.ts +15 -0
  16. package/dist/index.js +28 -0
  17. package/dist/snapshot/NativeScreenCapture.d.ts +17 -0
  18. package/dist/snapshot/NativeScreenCapture.js +38 -0
  19. package/dist/snapshot/capture.d.ts +36 -0
  20. package/dist/snapshot/capture.js +109 -0
  21. package/dist/snapshot/captureScreenshot.d.ts +26 -0
  22. package/dist/snapshot/captureScreenshot.js +89 -0
  23. package/dist/trackers/error.tracker.d.ts +22 -0
  24. package/dist/trackers/error.tracker.js +123 -0
  25. package/dist/trackers/navigation.tracker.d.ts +6 -0
  26. package/dist/trackers/navigation.tracker.js +78 -0
  27. package/dist/trackers/screen.tracker.d.ts +2 -0
  28. package/dist/trackers/screen.tracker.js +23 -0
  29. package/dist/trackers/touch.tracker.d.ts +8 -0
  30. package/dist/trackers/touch.tracker.js +30 -0
  31. package/dist/transport/api.client.d.ts +29 -0
  32. package/dist/transport/api.client.js +156 -0
  33. package/dist/transport/batch-queue.d.ts +18 -0
  34. package/dist/transport/batch-queue.js +80 -0
  35. package/dist/types/crash.d.ts +10 -0
  36. package/dist/types/crash.js +2 -0
  37. package/dist/types/events.d.ts +53 -0
  38. package/dist/types/events.js +2 -0
  39. package/dist/types/snapshot.d.ts +21 -0
  40. package/dist/types/snapshot.js +9 -0
  41. package/package.json +64 -0
  42. package/src/components/ScreenCapturePermission.tsx +160 -0
  43. package/src/core/client.ts +425 -0
  44. package/src/core/config.ts +27 -0
  45. package/src/core/logger.ts +27 -0
  46. package/src/index.ts +47 -0
  47. package/src/snapshot/NativeScreenCapture.ts +54 -0
  48. package/src/snapshot/capture.ts +142 -0
  49. package/src/snapshot/captureScreenshot.ts +109 -0
  50. package/src/trackers/error.tracker.ts +136 -0
  51. package/src/trackers/navigation.tracker.ts +98 -0
  52. package/src/trackers/screen.tracker.ts +19 -0
  53. package/src/trackers/touch.tracker.tsx +44 -0
  54. package/src/transport/api.client.ts +225 -0
  55. package/src/transport/batch-queue.ts +95 -0
  56. package/src/types/crash.ts +10 -0
  57. package/src/types/events.ts +59 -0
  58. package/src/types/snapshot.ts +23 -0
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,53 @@
1
+ export type EventType = 'touch' | 'scroll' | 'gesture' | 'navigation' | 'custom';
2
+ export interface AnalyticsEvent {
3
+ type: EventType;
4
+ screenName?: string;
5
+ data: Record<string, any>;
6
+ timestamp: string;
7
+ }
8
+ export interface TouchEventData {
9
+ x: number;
10
+ y: number;
11
+ elementTag?: string;
12
+ elementText?: string;
13
+ }
14
+ export interface NavigationEventData {
15
+ fromScreen: string;
16
+ toScreen: string;
17
+ }
18
+ export interface ScreenVisit {
19
+ sessionId: string;
20
+ screenName: string;
21
+ enteredAt: string;
22
+ exitedAt?: string;
23
+ duration?: number;
24
+ }
25
+ export interface DeviceInfo {
26
+ os: string;
27
+ osVersion: string;
28
+ model: string;
29
+ brand: string;
30
+ screenWidth: number;
31
+ screenHeight: number;
32
+ appVersion?: string;
33
+ }
34
+ export interface SDKConfig {
35
+ apiKey: string;
36
+ appId: string;
37
+ baseUrl: string;
38
+ batchSize?: number;
39
+ flushInterval?: number;
40
+ enableTouchTracking?: boolean;
41
+ enableNavigationTracking?: boolean;
42
+ enableSnapshots?: boolean;
43
+ snapshotInterval?: number;
44
+ maxSnapshotsPerSession?: number;
45
+ /** Max snapshots per network batch. Defaults to 8. */
46
+ snapshotBatchSize?: number;
47
+ /** Auto-flush interval for the snapshot queue (ms). Defaults to 15000. */
48
+ snapshotFlushInterval?: number;
49
+ /** Max snapshots kept in memory if the backend is unreachable. Defaults to 32. */
50
+ snapshotMaxBufferSize?: number;
51
+ enableCrashTracking?: boolean;
52
+ debug?: boolean;
53
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Repliqo snapshot types.
3
+ *
4
+ * The SDK captures JPEG screenshots of the view hierarchy via
5
+ * react-native-view-shot. Each snapshot is stored as a base64 JPEG
6
+ * together with its rendered dimensions.
7
+ */
8
+ export interface ScreenshotData {
9
+ image: string;
10
+ width: number;
11
+ height: number;
12
+ format: 'jpeg';
13
+ }
14
+ export interface SnapshotPayload {
15
+ sessionId: string;
16
+ screenName: string;
17
+ timestamp: string;
18
+ sequence: number;
19
+ isDiff: boolean;
20
+ data: ScreenshotData;
21
+ }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ /**
3
+ * Repliqo snapshot types.
4
+ *
5
+ * The SDK captures JPEG screenshots of the view hierarchy via
6
+ * react-native-view-shot. Each snapshot is stored as a base64 JPEG
7
+ * together with its rendered dimensions.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@repliqo/sdk-react-native",
3
+ "version": "0.1.0",
4
+ "description": "Session replay & analytics SDK for React Native. Captures screenshots (including modals/alerts), navigation, screen visits, and custom events.",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/SbtnAvls/app-analytics-api",
10
+ "directory": "packages/sdk-react-native"
11
+ },
12
+ "homepage": "https://repliqo.odmservice.site",
13
+ "license": "MIT",
14
+ "keywords": [
15
+ "react-native",
16
+ "analytics",
17
+ "session-replay",
18
+ "screen-capture",
19
+ "heatmaps",
20
+ "uxcam",
21
+ "repliqo"
22
+ ],
23
+ "files": [
24
+ "dist/",
25
+ "android/src/",
26
+ "android/build.gradle",
27
+ "src/",
28
+ "INTEGRATION_GUIDE.md"
29
+ ],
30
+ "scripts": {
31
+ "build": "tsc",
32
+ "test": "jest",
33
+ "prepublishOnly": "npm run build"
34
+ },
35
+ "publishConfig": {
36
+ "access": "public"
37
+ },
38
+ "peerDependencies": {
39
+ "@react-navigation/native": ">=6.0.0",
40
+ "react": ">=17.0.0",
41
+ "react-native": ">=0.68.0",
42
+ "react-native-view-shot": ">=3.0.0"
43
+ },
44
+ "peerDependenciesMeta": {
45
+ "react-native-view-shot": {
46
+ "optional": true
47
+ },
48
+ "@react-navigation/native": {
49
+ "optional": true
50
+ }
51
+ },
52
+ "devDependencies": {
53
+ "@react-navigation/native": "^6.1.0",
54
+ "@types/jest": "^29.5.0",
55
+ "@types/react": "^18.2.0",
56
+ "@types/react-native": "^0.72.0",
57
+ "jest": "^29.7.0",
58
+ "react": "^18.2.0",
59
+ "react-native": "^0.73.0",
60
+ "react-native-view-shot": "^4.0.3",
61
+ "ts-jest": "^29.1.0",
62
+ "typescript": "^5.3.0"
63
+ }
64
+ }
@@ -0,0 +1,160 @@
1
+ import React from 'react';
2
+ import {
3
+ View,
4
+ Text,
5
+ TouchableOpacity,
6
+ StyleSheet,
7
+ Platform,
8
+ ViewStyle,
9
+ TextStyle,
10
+ } from 'react-native';
11
+
12
+ interface ScreenCapturePermissionProps {
13
+ /**
14
+ * Called when the user taps "Allow" — the host app should then call
15
+ * `AppAnalytics.getInstance().startSession(...)` which triggers the
16
+ * actual system permission dialog.
17
+ */
18
+ onAccept: () => void;
19
+ /**
20
+ * Called when the user taps "Not now" — the host app can proceed
21
+ * without screen capture (view-shot fallback will be used).
22
+ */
23
+ onDecline: () => void;
24
+ /** Optional custom title. */
25
+ title?: string;
26
+ /** Optional custom description. */
27
+ description?: string;
28
+ /** Override container (overlay) style. */
29
+ containerStyle?: ViewStyle;
30
+ /** Override card style. */
31
+ cardStyle?: ViewStyle;
32
+ /** Override title text style. */
33
+ titleStyle?: TextStyle;
34
+ /** Override description text style. */
35
+ descriptionStyle?: TextStyle;
36
+ /** Override accept button style. */
37
+ acceptButtonStyle?: ViewStyle;
38
+ /** Override decline button style. */
39
+ declineButtonStyle?: ViewStyle;
40
+ }
41
+
42
+ /**
43
+ * Pre-permission explanation screen for session replay.
44
+ *
45
+ * Android requires a system-level permission dialog for screen capture
46
+ * (MediaProjection), which can be confusing without context. Show this
47
+ * component BEFORE the system dialog to explain why the permission is
48
+ * needed.
49
+ *
50
+ * Usage in the host app:
51
+ *
52
+ * ```tsx
53
+ * import { ScreenCapturePermission } from '@repliqo/sdk-react-native';
54
+ *
55
+ * <ScreenCapturePermission
56
+ * onAccept={() => initRepliqo()}
57
+ * onDecline={() => initRepliqoWithoutCapture()}
58
+ * />
59
+ * ```
60
+ *
61
+ * This component is OPTIONAL. If not shown, the SDK still works — the
62
+ * system dialog appears directly, and denial falls back to view-shot.
63
+ */
64
+ export function ScreenCapturePermission({
65
+ onAccept,
66
+ onDecline,
67
+ title,
68
+ description,
69
+ containerStyle,
70
+ cardStyle,
71
+ titleStyle,
72
+ descriptionStyle,
73
+ acceptButtonStyle,
74
+ declineButtonStyle,
75
+ }: ScreenCapturePermissionProps) {
76
+ if (Platform.OS !== 'android') {
77
+ return null;
78
+ }
79
+
80
+ return (
81
+ <View style={[styles.container, containerStyle]}>
82
+ <View style={[styles.card, cardStyle]}>
83
+ <Text style={styles.icon}>📹</Text>
84
+ <Text style={[styles.title, titleStyle]}>
85
+ {title || 'Session Recording'}
86
+ </Text>
87
+ <Text style={[styles.description, descriptionStyle]}>
88
+ {description ||
89
+ 'To capture your full session including dialogs and menus, ' +
90
+ 'we need screen recording permission. This helps us improve ' +
91
+ 'your experience by understanding how you use the app.\n\n' +
92
+ 'You can stop recording at any time from the notification bar.'}
93
+ </Text>
94
+ <TouchableOpacity style={[styles.acceptButton, acceptButtonStyle]} onPress={onAccept}>
95
+ <Text style={styles.acceptText}>Allow Recording</Text>
96
+ </TouchableOpacity>
97
+ <TouchableOpacity style={[styles.declineButton, declineButtonStyle]} onPress={onDecline}>
98
+ <Text style={styles.declineText}>Not Now</Text>
99
+ </TouchableOpacity>
100
+ </View>
101
+ </View>
102
+ );
103
+ }
104
+
105
+ const styles = StyleSheet.create({
106
+ container: {
107
+ flex: 1,
108
+ justifyContent: 'center',
109
+ alignItems: 'center',
110
+ backgroundColor: 'rgba(0,0,0,0.5)',
111
+ padding: 24,
112
+ },
113
+ card: {
114
+ backgroundColor: '#1a1a2e',
115
+ borderRadius: 16,
116
+ padding: 24,
117
+ width: '100%',
118
+ maxWidth: 340,
119
+ alignItems: 'center',
120
+ },
121
+ icon: {
122
+ fontSize: 48,
123
+ marginBottom: 16,
124
+ },
125
+ title: {
126
+ fontSize: 20,
127
+ fontWeight: '700',
128
+ color: '#ffffff',
129
+ marginBottom: 12,
130
+ textAlign: 'center',
131
+ },
132
+ description: {
133
+ fontSize: 14,
134
+ color: '#a0a0b8',
135
+ lineHeight: 22,
136
+ textAlign: 'center',
137
+ marginBottom: 24,
138
+ },
139
+ acceptButton: {
140
+ backgroundColor: '#6366f1',
141
+ borderRadius: 12,
142
+ paddingVertical: 14,
143
+ paddingHorizontal: 32,
144
+ width: '100%',
145
+ alignItems: 'center',
146
+ marginBottom: 12,
147
+ },
148
+ acceptText: {
149
+ color: '#ffffff',
150
+ fontSize: 16,
151
+ fontWeight: '600',
152
+ },
153
+ declineButton: {
154
+ paddingVertical: 10,
155
+ },
156
+ declineText: {
157
+ color: '#6b7280',
158
+ fontSize: 14,
159
+ },
160
+ });