respectlytics-react-native 2.0.1 → 2.2.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 (43) hide show
  1. package/LICENSE +17 -20
  2. package/README.md +77 -29
  3. package/lib/commonjs/EventQueue.js +1 -1
  4. package/lib/commonjs/NetworkClient.js +13 -14
  5. package/lib/commonjs/NetworkClient.js.map +1 -1
  6. package/lib/commonjs/Respectlytics.js +28 -85
  7. package/lib/commonjs/Respectlytics.js.map +1 -1
  8. package/lib/commonjs/SessionManager.js +4 -4
  9. package/lib/commonjs/Storage.js +1 -1
  10. package/lib/commonjs/index.js +3 -3
  11. package/lib/commonjs/index.js.map +1 -1
  12. package/lib/commonjs/types.js +12 -11
  13. package/lib/commonjs/types.js.map +1 -1
  14. package/lib/module/EventQueue.js +1 -1
  15. package/lib/module/NetworkClient.js +13 -14
  16. package/lib/module/NetworkClient.js.map +1 -1
  17. package/lib/module/Respectlytics.js +29 -86
  18. package/lib/module/Respectlytics.js.map +1 -1
  19. package/lib/module/SessionManager.js +4 -4
  20. package/lib/module/Storage.js +1 -1
  21. package/lib/module/index.js +3 -4
  22. package/lib/module/index.js.map +1 -1
  23. package/lib/module/types.js +12 -11
  24. package/lib/module/types.js.map +1 -1
  25. package/lib/typescript/EventQueue.d.ts +1 -1
  26. package/lib/typescript/NetworkClient.d.ts +6 -5
  27. package/lib/typescript/NetworkClient.d.ts.map +1 -1
  28. package/lib/typescript/Respectlytics.d.ts +15 -12
  29. package/lib/typescript/Respectlytics.d.ts.map +1 -1
  30. package/lib/typescript/SessionManager.d.ts +4 -4
  31. package/lib/typescript/Storage.d.ts +1 -1
  32. package/lib/typescript/index.d.ts +2 -2
  33. package/lib/typescript/index.d.ts.map +1 -1
  34. package/lib/typescript/types.d.ts +10 -14
  35. package/lib/typescript/types.d.ts.map +1 -1
  36. package/package.json +5 -2
  37. package/src/EventQueue.ts +4 -4
  38. package/src/NetworkClient.ts +12 -13
  39. package/src/Respectlytics.ts +31 -92
  40. package/src/SessionManager.ts +6 -6
  41. package/src/Storage.ts +1 -1
  42. package/src/index.ts +5 -6
  43. package/src/types.ts +12 -16
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "respectlytics-react-native",
3
- "version": "2.0.1",
3
+ "version": "2.2.0",
4
4
  "description": "Official Respectlytics SDK for React Native. Privacy-first analytics with automatic session management, offline event queuing, and zero device identifier collection.",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
@@ -38,7 +38,7 @@
38
38
  "url": "git+https://github.com/respectlytics/respectlytics-react-native.git"
39
39
  },
40
40
  "author": "Respectlytics <respectlytics@loheden.com>",
41
- "license": "SEE LICENSE IN LICENSE",
41
+ "license": "MIT",
42
42
  "bugs": {
43
43
  "url": "https://github.com/respectlytics/respectlytics-react-native/issues"
44
44
  },
@@ -47,11 +47,14 @@
47
47
  "registry": "https://registry.npmjs.org/"
48
48
  },
49
49
  "devDependencies": {
50
+ "@babel/preset-env": "^7.28.5",
51
+ "@babel/preset-typescript": "^7.28.5",
50
52
  "@react-native-async-storage/async-storage": "^2.0.0",
51
53
  "@react-native-community/netinfo": "^11.3.0",
52
54
  "@types/jest": "^29.5.12",
53
55
  "@types/react": "^18.2.0",
54
56
  "@types/react-native": "^0.72.0",
57
+ "babel-jest": "^30.2.0",
55
58
  "eslint": "^8.56.0",
56
59
  "jest": "^29.7.0",
57
60
  "react": "^18.2.0",
package/src/EventQueue.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * EventQueue.ts
3
3
  * Respectlytics React Native SDK
4
- *
4
+ *
5
5
  * Manages event batching, persistence, and automatic flushing.
6
6
  * Events are NEVER lost - they are persisted immediately and retried on failure.
7
- * Copyright (c) 2025 Respectlytics. All rights reserved.
7
+ * Copyright (c) 2025 Respectlytics. Licensed under MIT.
8
8
  */
9
9
 
10
10
  import { AppState, AppStateStatus } from 'react-native';
@@ -65,10 +65,10 @@ export class EventQueue {
65
65
  */
66
66
  async add(event: Event): Promise<void> {
67
67
  this.events.push(event);
68
-
68
+
69
69
  // IMMEDIATELY persist before any async operations
70
70
  await this.persistQueue();
71
-
71
+
72
72
  // Check if we should flush
73
73
  if (this.events.length >= MAX_QUEUE_SIZE) {
74
74
  this.flush();
@@ -1,14 +1,14 @@
1
1
  /**
2
2
  * NetworkClient.ts
3
3
  * Respectlytics React Native SDK
4
- *
4
+ *
5
5
  * Handles HTTP communication with the Respectlytics API.
6
- * Copyright (c) 2025 Respectlytics. All rights reserved.
6
+ * Copyright (c) 2025 Respectlytics. Licensed under MIT.
7
7
  */
8
8
 
9
9
  import { Event } from './types';
10
10
 
11
- const API_ENDPOINT = 'https://respectlytics.com/api/v1/events/';
11
+ const DEFAULT_API_ENDPOINT = 'https://respectlytics.com/api/v1/events/';
12
12
  const MAX_RETRIES = 3;
13
13
  const TIMEOUT_MS = 30000;
14
14
 
@@ -25,12 +25,16 @@ export enum NetworkError {
25
25
 
26
26
  export class NetworkClient {
27
27
  private apiKey: string | null = null;
28
+ private apiEndpoint: string = DEFAULT_API_ENDPOINT;
28
29
 
29
30
  /**
30
- * Configure the network client with an API key
31
+ * Configure the network client with an API key and optional custom endpoint
31
32
  */
32
- configure(apiKey: string): void {
33
+ configure(apiKey: string, apiEndpoint?: string): void {
33
34
  this.apiKey = apiKey;
35
+ if (apiEndpoint) {
36
+ this.apiEndpoint = apiEndpoint;
37
+ }
34
38
  }
35
39
 
36
40
  /**
@@ -65,7 +69,7 @@ export class NetworkClient {
65
69
  const timeoutId = setTimeout(() => controller.abort(), TIMEOUT_MS);
66
70
 
67
71
  try {
68
- const response = await fetch(API_ENDPOINT, {
72
+ const response = await fetch(this.apiEndpoint, {
69
73
  method: 'POST',
70
74
  headers: {
71
75
  'Content-Type': 'application/json',
@@ -137,20 +141,15 @@ export class NetworkClient {
137
141
  }
138
142
 
139
143
  /**
140
- * Convert Event object to API payload format
141
- * Note: As of v2.0.0, no user_id field is sent (session-based analytics only)
144
+ * Convert Event object to API payload format.
145
+ * The SDK sends 4 fields; the API stores 5 (adding country derived from IP).
142
146
  */
143
147
  private eventToPayload(event: Event): Record<string, unknown> {
144
148
  return {
145
149
  event_name: event.eventName,
146
150
  timestamp: event.timestamp,
147
151
  session_id: event.sessionId,
148
- screen: event.screen || undefined,
149
152
  platform: event.platform,
150
- os_version: event.osVersion,
151
- app_version: event.appVersion,
152
- locale: event.locale,
153
- device_type: event.deviceType,
154
153
  };
155
154
  }
156
155
 
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * Respectlytics.ts
3
3
  * Respectlytics React Native SDK
4
- *
4
+ *
5
5
  * Main entry point for the SDK.
6
- * Copyright (c) 2025 Respectlytics. All rights reserved.
6
+ * Copyright (c) 2025 Respectlytics. Licensed under MIT.
7
7
  */
8
8
 
9
- import { Platform, Dimensions, NativeModules } from 'react-native';
9
+ import { Platform } from 'react-native';
10
10
  import { Event } from './types';
11
11
  import { SessionManager } from './SessionManager';
12
12
  import { NetworkClient } from './NetworkClient';
@@ -14,21 +14,23 @@ import { EventQueue } from './EventQueue';
14
14
 
15
15
  /**
16
16
  * Main entry point for the Respectlytics SDK.
17
- *
18
- * v2.0.0 uses session-based analytics only:
17
+ *
18
+ * v2.1.0 uses session-based analytics only:
19
19
  * - Session IDs are generated automatically in RAM
20
20
  * - Sessions rotate every 2 hours
21
21
  * - New session on every app restart
22
- * - No persistent user tracking (GDPR/ePrivacy compliant)
23
- *
22
+ * - Only 4 fields sent by SDK; 5 stored (country derived server-side)
23
+ *
24
24
  * Usage:
25
25
  * ```typescript
26
26
  * // 1. Configure at app launch
27
27
  * Respectlytics.configure('your-api-key');
28
- *
28
+ *
29
+ * // For self-hosted instances:
30
+ * Respectlytics.configure('your-api-key', { apiEndpoint: 'https://your-server.com/api/v1/events/' });
31
+ *
29
32
  * // 2. Track events
30
33
  * Respectlytics.track('purchase');
31
- * Respectlytics.track('view_product', 'ProductScreen');
32
34
  * ```
33
35
  */
34
36
  class RespectlyticsSDK {
@@ -36,42 +38,44 @@ class RespectlyticsSDK {
36
38
  private networkClient: NetworkClient;
37
39
  private eventQueue: EventQueue;
38
40
  private sessionManager: SessionManager;
41
+ private platform: string;
39
42
 
40
43
  constructor() {
41
44
  this.networkClient = new NetworkClient();
42
45
  this.eventQueue = new EventQueue(this.networkClient);
43
46
  this.sessionManager = new SessionManager();
47
+ this.platform = Platform.OS === 'ios' ? 'iOS' : 'Android';
44
48
  }
45
49
 
46
50
  /**
47
51
  * Initialize the SDK with your API key.
48
52
  * Call once at app startup.
49
- *
53
+ *
50
54
  * @param apiKey Your Respectlytics API key from the dashboard
55
+ * @param options Optional configuration (e.g., apiEndpoint for self-hosted instances)
51
56
  */
52
- configure(apiKey: string): void {
57
+ configure(apiKey: string, options?: { apiEndpoint?: string }): void {
53
58
  if (!apiKey || apiKey.trim() === '') {
54
59
  console.log('[Respectlytics] ⚠️ API key cannot be empty');
55
60
  return;
56
61
  }
57
62
 
58
- this.networkClient.configure(apiKey);
63
+ this.networkClient.configure(apiKey, options?.apiEndpoint);
59
64
  this.eventQueue.start();
60
65
  this.isConfigured = true;
61
66
 
62
- console.log('[Respectlytics] ✓ SDK configured');
67
+ console.log('[Respectlytics] ✓ SDK configured (v2.2.0)');
63
68
  }
64
69
 
65
70
  /**
66
- * Track an event with an optional screen name.
67
- *
68
- * The SDK automatically collects privacy-safe metadata:
69
- * - timestamp, session_id, platform, os_version, app_version, locale
70
- *
71
+ * Track an event.
72
+ *
73
+ * Custom properties are NOT supported - this is by design for privacy.
74
+ * The API stores 5 fields (these 4 plus country derived server-side).
75
+ *
71
76
  * @param eventName Name of the event (e.g., "purchase", "button_clicked")
72
- * @param screen Optional screen name where the event occurred
73
77
  */
74
- track(eventName: string, screen?: string): void {
78
+ track(eventName: string): void {
75
79
  if (!this.isConfigured) {
76
80
  console.log('[Respectlytics] ⚠️ SDK not configured. Call configure(apiKey) first.');
77
81
  return;
@@ -87,7 +91,13 @@ class RespectlyticsSDK {
87
91
  return;
88
92
  }
89
93
 
90
- const event = this.createEvent(eventName, screen);
94
+ const event: Event = {
95
+ eventName,
96
+ timestamp: new Date().toISOString(),
97
+ sessionId: this.sessionManager.getSessionId(),
98
+ platform: this.platform,
99
+ };
100
+
91
101
  this.eventQueue.add(event);
92
102
  }
93
103
 
@@ -98,77 +108,6 @@ class RespectlyticsSDK {
98
108
  async flush(): Promise<void> {
99
109
  await this.eventQueue.flush();
100
110
  }
101
-
102
- // MARK: - Private Helpers
103
-
104
- private createEvent(eventName: string, screen?: string): Event {
105
- const metadata = this.collectMetadata();
106
-
107
- return {
108
- eventName,
109
- timestamp: new Date().toISOString(),
110
- sessionId: this.sessionManager.getSessionId(),
111
- screen: screen || null,
112
- ...metadata,
113
- };
114
- }
115
-
116
- private collectMetadata(): {
117
- platform: string;
118
- osVersion: string;
119
- appVersion: string;
120
- locale: string;
121
- deviceType: string;
122
- } {
123
- // Determine platform
124
- const platform = Platform.OS === 'ios' ? 'iOS' : 'Android';
125
-
126
- // Get OS version
127
- const osVersion = String(Platform.Version);
128
-
129
- // Get app version - try to get from native modules
130
- let appVersion = 'unknown';
131
- try {
132
- // React Native provides app info through different native modules
133
- const { PlatformConstants } = NativeModules;
134
- if (PlatformConstants?.reactNativeVersion) {
135
- // This is React Native version, not app version
136
- // App version should come from the host app
137
- }
138
- // For now, use 'unknown' as we can't reliably get app version without additional dependencies
139
- // In a real app, the developer would configure this
140
- } catch {
141
- appVersion = 'unknown';
142
- }
143
-
144
- // Get locale
145
- let locale = 'en_US';
146
- try {
147
- // React Native doesn't expose locale directly, but we can get it from platform
148
- if (Platform.OS === 'ios') {
149
- locale = NativeModules.SettingsManager?.settings?.AppleLocale ||
150
- NativeModules.SettingsManager?.settings?.AppleLanguages?.[0] ||
151
- 'en_US';
152
- } else {
153
- locale = NativeModules.I18nManager?.localeIdentifier || 'en_US';
154
- }
155
- } catch {
156
- locale = 'en_US';
157
- }
158
-
159
- // Determine device type based on screen size
160
- const { width, height } = Dimensions.get('window');
161
- const minDimension = Math.min(width, height);
162
- const deviceType = minDimension >= 600 ? 'tablet' : 'phone';
163
-
164
- return {
165
- platform,
166
- osVersion,
167
- appVersion,
168
- locale,
169
- deviceType,
170
- };
171
- }
172
111
  }
173
112
 
174
113
  // Export singleton instance
@@ -3,10 +3,10 @@
3
3
  * Respectlytics React Native SDK
4
4
  *
5
5
  * Manages session ID generation and rotation.
6
- * Sessions are stored in RAM only (never persisted) for GDPR/ePrivacy compliance.
6
+ * Sessions are stored in RAM only (never persisted to disk).
7
7
  * Sessions automatically rotate every 2 hours.
8
8
  *
9
- * Copyright (c) 2025 Respectlytics. All rights reserved.
9
+ * Copyright (c) 2025 Respectlytics. Licensed under MIT.
10
10
  */
11
11
 
12
12
  /**
@@ -22,15 +22,15 @@ function generateUUID(): string {
22
22
 
23
23
  /**
24
24
  * Manages session ID generation and rotation.
25
- *
25
+ *
26
26
  * Session IDs are:
27
27
  * - Generated immediately when the SDK initializes
28
28
  * - Stored in RAM only (never persisted to AsyncStorage)
29
29
  * - Rotated automatically every 2 hours
30
30
  * - Regenerated on every app restart (new instance = new session)
31
- *
32
- * This RAM-only approach ensures GDPR/ePrivacy compliance:
33
- * - No device storage = No consent required under ePrivacy Directive Article 5(3)
31
+ *
32
+ * This RAM-only approach means session data never touches device storage:
33
+ * - Sessions exist only in memory and are lost on app restart
34
34
  * - Each app launch creates a fresh, unlinked session
35
35
  */
36
36
  export class SessionManager {
package/src/Storage.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * Wrapper around AsyncStorage for persisting SDK data.
6
6
  *
7
- * Copyright (c) 2025 Respectlytics. All rights reserved.
7
+ * Copyright (c) 2025 Respectlytics. Licensed under MIT.
8
8
  */
9
9
 
10
10
  import AsyncStorage from '@react-native-async-storage/async-storage';
package/src/index.ts CHANGED
@@ -1,17 +1,16 @@
1
1
  /**
2
2
  * Respectlytics React Native SDK
3
- *
3
+ *
4
4
  * Official SDK for privacy-first, session-based analytics.
5
- *
5
+ *
6
6
  * v2.0.0 Features:
7
7
  * - Session-based analytics (no persistent user tracking)
8
- * - RAM-only session storage (GDPR/ePrivacy compliant)
8
+ * - RAM-only session storage (never persisted to disk)
9
9
  * - Automatic 2-hour session rotation
10
10
  * - New session on every app restart
11
- *
12
- * Copyright (c) 2025 Respectlytics. All rights reserved.
11
+ *
12
+ * Copyright (c) 2025 Respectlytics. Licensed under MIT.
13
13
  */
14
-
15
14
  import Respectlytics from './Respectlytics';
16
15
 
17
16
  // Default export - the main SDK instance
package/src/types.ts CHANGED
@@ -2,37 +2,33 @@
2
2
  * types.ts
3
3
  * Respectlytics React Native SDK
4
4
  *
5
- * Copyright (c) 2025 Respectlytics. All rights reserved.
6
- * This SDK is provided under a proprietary license.
7
- * See LICENSE file for details.
5
+ * Copyright (c) 2025 Respectlytics. Licensed under MIT.
8
6
  */
9
7
 
10
8
  /**
11
9
  * Represents an analytics event - flat structure matching API payload
12
10
  *
13
- * This interface only contains fields accepted by the Respectlytics API.
14
- * The API uses a strict allowlist for privacy protection.
15
- * Custom properties are NOT supported - this is by design for privacy.
16
- *
17
- * Note: As of v2.0.0, there is no userId field. Session-based analytics only.
11
+ * The SDK sends these 4 fields. The API stores 5 total
12
+ * (adding country, derived server-side from IP which is immediately discarded):
13
+ * - event_name (required)
14
+ * - timestamp
15
+ * - session_id
16
+ * - platform
17
+ *
18
+ * Country is derived server-side from IP (which is immediately discarded).
18
19
  */
19
20
  export interface Event {
20
21
  eventName: string;
21
22
  timestamp: string;
22
23
  sessionId: string;
23
- screen: string | null;
24
24
  platform: string;
25
- osVersion: string;
26
- appVersion: string;
27
- locale: string;
28
- deviceType: string;
29
25
  }
30
26
 
31
27
  /**
32
28
  * Storage keys used by the SDK
33
- *
34
- * Note: As of v2.0.0, we only persist the event queue.
35
- * Session IDs are RAM-only for GDPR/ePrivacy compliance.
29
+ *
30
+ * Note: Only the event queue is persisted.
31
+ * Session IDs are RAM-only for privacy.
36
32
  */
37
33
  export const STORAGE_KEYS = {
38
34
  EVENT_QUEUE: 'com.respectlytics.eventQueue',