riuve-rn 1.0.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 (99) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +848 -0
  3. package/dist/Riuve.d.ts +91 -0
  4. package/dist/Riuve.d.ts.map +1 -0
  5. package/dist/Riuve.js +402 -0
  6. package/dist/Rive.d.ts +91 -0
  7. package/dist/Rive.d.ts.map +1 -0
  8. package/dist/Rive.js +402 -0
  9. package/dist/adapters/deviceInfo/ExpoDeviceInfo.d.ts +13 -0
  10. package/dist/adapters/deviceInfo/ExpoDeviceInfo.d.ts.map +1 -0
  11. package/dist/adapters/deviceInfo/ExpoDeviceInfo.js +91 -0
  12. package/dist/adapters/deviceInfo/FallbackDeviceInfo.d.ts +13 -0
  13. package/dist/adapters/deviceInfo/FallbackDeviceInfo.d.ts.map +1 -0
  14. package/dist/adapters/deviceInfo/FallbackDeviceInfo.js +36 -0
  15. package/dist/adapters/deviceInfo/NativeDeviceInfo.d.ts +17 -0
  16. package/dist/adapters/deviceInfo/NativeDeviceInfo.d.ts.map +1 -0
  17. package/dist/adapters/deviceInfo/NativeDeviceInfo.js +83 -0
  18. package/dist/adapters/deviceInfo/index.d.ts +14 -0
  19. package/dist/adapters/deviceInfo/index.d.ts.map +1 -0
  20. package/dist/adapters/deviceInfo/index.js +38 -0
  21. package/dist/adapters/deviceInfo/types.d.ts +25 -0
  22. package/dist/adapters/deviceInfo/types.d.ts.map +1 -0
  23. package/dist/adapters/deviceInfo/types.js +7 -0
  24. package/dist/adapters/network/ExpoNetworkManager.d.ts +20 -0
  25. package/dist/adapters/network/ExpoNetworkManager.d.ts.map +1 -0
  26. package/dist/adapters/network/ExpoNetworkManager.js +114 -0
  27. package/dist/adapters/network/FallbackNetworkManager.d.ts +15 -0
  28. package/dist/adapters/network/FallbackNetworkManager.d.ts.map +1 -0
  29. package/dist/adapters/network/FallbackNetworkManager.js +27 -0
  30. package/dist/adapters/network/NativeNetworkManager.d.ts +20 -0
  31. package/dist/adapters/network/NativeNetworkManager.d.ts.map +1 -0
  32. package/dist/adapters/network/NativeNetworkManager.js +68 -0
  33. package/dist/adapters/network/index.d.ts +14 -0
  34. package/dist/adapters/network/index.d.ts.map +1 -0
  35. package/dist/adapters/network/index.js +38 -0
  36. package/dist/adapters/network/types.d.ts +28 -0
  37. package/dist/adapters/network/types.d.ts.map +1 -0
  38. package/dist/adapters/network/types.js +7 -0
  39. package/dist/adapters/utils/moduleDetector.d.ts +17 -0
  40. package/dist/adapters/utils/moduleDetector.d.ts.map +1 -0
  41. package/dist/adapters/utils/moduleDetector.js +32 -0
  42. package/dist/constants.d.ts +41 -0
  43. package/dist/constants.d.ts.map +1 -0
  44. package/dist/constants.js +43 -0
  45. package/dist/core/ApiClient.d.ts +49 -0
  46. package/dist/core/ApiClient.d.ts.map +1 -0
  47. package/dist/core/ApiClient.js +184 -0
  48. package/dist/core/DeviceInfo.d.ts +27 -0
  49. package/dist/core/DeviceInfo.d.ts.map +1 -0
  50. package/dist/core/DeviceInfo.js +69 -0
  51. package/dist/core/EventQueue.d.ts +71 -0
  52. package/dist/core/EventQueue.d.ts.map +1 -0
  53. package/dist/core/EventQueue.js +216 -0
  54. package/dist/core/Storage.d.ts +29 -0
  55. package/dist/core/Storage.d.ts.map +1 -0
  56. package/dist/core/Storage.js +88 -0
  57. package/dist/index.d.ts +9 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +17 -0
  60. package/dist/managers/BatchManager.d.ts +50 -0
  61. package/dist/managers/BatchManager.d.ts.map +1 -0
  62. package/dist/managers/BatchManager.js +277 -0
  63. package/dist/managers/IdentityManager.d.ts +47 -0
  64. package/dist/managers/IdentityManager.d.ts.map +1 -0
  65. package/dist/managers/IdentityManager.js +135 -0
  66. package/dist/managers/NetworkManager.d.ts +32 -0
  67. package/dist/managers/NetworkManager.d.ts.map +1 -0
  68. package/dist/managers/NetworkManager.js +67 -0
  69. package/dist/types/api.d.ts +65 -0
  70. package/dist/types/api.d.ts.map +1 -0
  71. package/dist/types/api.js +15 -0
  72. package/dist/types/config.d.ts +32 -0
  73. package/dist/types/config.d.ts.map +1 -0
  74. package/dist/types/config.js +5 -0
  75. package/dist/types/events.d.ts +63 -0
  76. package/dist/types/events.d.ts.map +1 -0
  77. package/dist/types/events.js +5 -0
  78. package/dist/types/index.d.ts +8 -0
  79. package/dist/types/index.d.ts.map +1 -0
  80. package/dist/types/index.js +23 -0
  81. package/dist/types/storage.d.ts +26 -0
  82. package/dist/types/storage.d.ts.map +1 -0
  83. package/dist/types/storage.js +5 -0
  84. package/dist/utils/fetchWithTimeout.d.ts +6 -0
  85. package/dist/utils/fetchWithTimeout.d.ts.map +1 -0
  86. package/dist/utils/fetchWithTimeout.js +28 -0
  87. package/dist/utils/logger.d.ts +21 -0
  88. package/dist/utils/logger.d.ts.map +1 -0
  89. package/dist/utils/logger.js +39 -0
  90. package/dist/utils/retry.d.ts +29 -0
  91. package/dist/utils/retry.d.ts.map +1 -0
  92. package/dist/utils/retry.js +78 -0
  93. package/dist/utils/uuid.d.ts +12 -0
  94. package/dist/utils/uuid.d.ts.map +1 -0
  95. package/dist/utils/uuid.js +27 -0
  96. package/dist/utils/validators.d.ts +32 -0
  97. package/dist/utils/validators.d.ts.map +1 -0
  98. package/dist/utils/validators.js +68 -0
  99. package/package.json +65 -0
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ /**
3
+ * Storage Layer - AsyncStorage Wrapper
4
+ */
5
+ var __importDefault = (this && this.__importDefault) || function (mod) {
6
+ return (mod && mod.__esModule) ? mod : { "default": mod };
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.storage = void 0;
10
+ const async_storage_1 = __importDefault(require("@react-native-async-storage/async-storage"));
11
+ const constants_1 = require("../constants");
12
+ const logger_1 = require("../utils/logger");
13
+ class Storage {
14
+ /**
15
+ * Sets a value in storage
16
+ */
17
+ async set(key, value) {
18
+ try {
19
+ const storageKey = constants_1.STORAGE_KEYS[key];
20
+ const serialized = JSON.stringify(value);
21
+ await async_storage_1.default.setItem(storageKey, serialized);
22
+ // Removed verbose debug logging for production
23
+ }
24
+ catch (error) {
25
+ logger_1.logger.error(`Storage set failed for ${key}:`, error);
26
+ throw new Error(`${constants_1.ERROR_MESSAGES.STORAGE_ERROR}: ${error.message}`);
27
+ }
28
+ }
29
+ /**
30
+ * Gets a value from storage
31
+ */
32
+ async get(key) {
33
+ try {
34
+ const storageKey = constants_1.STORAGE_KEYS[key];
35
+ const serialized = await async_storage_1.default.getItem(storageKey);
36
+ if (serialized === null) {
37
+ return null;
38
+ }
39
+ const value = JSON.parse(serialized);
40
+ return value;
41
+ }
42
+ catch (error) {
43
+ logger_1.logger.error(`Storage get failed for ${key}:`, error);
44
+ throw new Error(`${constants_1.ERROR_MESSAGES.STORAGE_ERROR}: ${error.message}`);
45
+ }
46
+ }
47
+ /**
48
+ * Removes a value from storage
49
+ */
50
+ async remove(key) {
51
+ try {
52
+ const storageKey = constants_1.STORAGE_KEYS[key];
53
+ await async_storage_1.default.removeItem(storageKey);
54
+ // Removed verbose debug logging for production
55
+ }
56
+ catch (error) {
57
+ logger_1.logger.error(`Storage remove failed for ${key}:`, error);
58
+ throw new Error(`${constants_1.ERROR_MESSAGES.STORAGE_ERROR}: ${error.message}`);
59
+ }
60
+ }
61
+ /**
62
+ * Clears all SDK-related storage
63
+ */
64
+ async clear() {
65
+ try {
66
+ const keys = Object.values(constants_1.STORAGE_KEYS);
67
+ await async_storage_1.default.multiRemove(keys);
68
+ // Removed verbose info logging for production
69
+ }
70
+ catch (error) {
71
+ logger_1.logger.error('Storage clear failed:', error);
72
+ throw new Error(`${constants_1.ERROR_MESSAGES.STORAGE_ERROR}: ${error.message}`);
73
+ }
74
+ }
75
+ /**
76
+ * Checks if a key exists in storage
77
+ */
78
+ async has(key) {
79
+ try {
80
+ const value = await this.get(key);
81
+ return value !== null;
82
+ }
83
+ catch (error) {
84
+ return false;
85
+ }
86
+ }
87
+ }
88
+ exports.storage = new Storage();
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Riuve React Native SDK
3
+ * Main export file
4
+ */
5
+ import Riuve from './Riuve';
6
+ export default Riuve;
7
+ export type { RiuveConfig, RiuveConfigInput, Event, DeviceInfo, EventBatch, FailedBatch, InitializeRequest, InitializeResponse, IdentifyRequest, IdentifyResponse, TrackRequest, TrackResponse, SetFcmTokenRequest, SetFcmTokenResponse, ApiError, ErrorType, } from './types';
8
+ export { DEFAULT_CONFIG, ERROR_MESSAGES } from './constants';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,SAAS,CAAC;AAG5B,eAAe,KAAK,CAAC;AAGrB,YAAY,EACV,WAAW,EACX,gBAAgB,EAChB,KAAK,EACL,UAAU,EACV,UAAU,EACV,WAAW,EACX,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACnB,QAAQ,EACR,SAAS,GACV,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ /**
3
+ * Riuve React Native SDK
4
+ * Main export file
5
+ */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.ERROR_MESSAGES = exports.DEFAULT_CONFIG = void 0;
11
+ const Riuve_1 = __importDefault(require("./Riuve"));
12
+ // Export the SDK instance as default
13
+ exports.default = Riuve_1.default;
14
+ // Export constants for advanced users
15
+ var constants_1 = require("./constants");
16
+ Object.defineProperty(exports, "DEFAULT_CONFIG", { enumerable: true, get: function () { return constants_1.DEFAULT_CONFIG; } });
17
+ Object.defineProperty(exports, "ERROR_MESSAGES", { enumerable: true, get: function () { return constants_1.ERROR_MESSAGES; } });
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Batch Manager - Orchestrates batch sending and offline queue
3
+ */
4
+ import { EventQueue } from '../core/EventQueue';
5
+ import { ApiClient } from '../core/ApiClient';
6
+ import { NetworkManager } from './NetworkManager';
7
+ import { IdentityManager } from './IdentityManager';
8
+ import type { Event } from '../types';
9
+ export declare class BatchManager {
10
+ private eventQueue;
11
+ private apiClient;
12
+ private networkManager;
13
+ private identityManager;
14
+ private isFlushing;
15
+ private eventRetentionDays;
16
+ constructor(eventQueue: EventQueue, apiClient: ApiClient, networkManager: NetworkManager, identityManager: IdentityManager, eventRetentionDays: number);
17
+ /**
18
+ * Sends a batch of events to the API
19
+ */
20
+ sendBatch(events: Event[]): Promise<void>;
21
+ /**
22
+ * Saves a failed batch for later retry
23
+ */
24
+ private saveFailedBatch;
25
+ /**
26
+ * Flushes the offline queue (retries failed batches)
27
+ */
28
+ flushOfflineQueue(): Promise<void>;
29
+ /**
30
+ * Validates UUID format (8-4-4-4-12 hex characters)
31
+ */
32
+ private isValidUUID;
33
+ /**
34
+ * Fixes invalid event IDs in a batch
35
+ */
36
+ private fixEventIds;
37
+ /**
38
+ * Processes and retries failed batches
39
+ */
40
+ private processFailedBatches;
41
+ /**
42
+ * Gets the count of failed batches
43
+ */
44
+ getFailedBatchCount(): Promise<number>;
45
+ /**
46
+ * Clears all failed batches
47
+ */
48
+ clearFailedBatches(): Promise<void>;
49
+ }
50
+ //# sourceMappingURL=BatchManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BatchManager.d.ts","sourceRoot":"","sources":["../../src/managers/BatchManager.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,KAAK,EAAE,KAAK,EAAe,MAAM,UAAU,CAAC;AAGnD,qBAAa,YAAY;IACvB,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,kBAAkB,CAAS;gBAGjC,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,SAAS,EACpB,cAAc,EAAE,cAAc,EAC9B,eAAe,EAAE,eAAe,EAChC,kBAAkB,EAAE,MAAM;IAsB5B;;OAEG;IACG,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAsF/C;;OAEG;YACW,eAAe;IAoC7B;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAYxC;;OAEG;IACH,OAAO,CAAC,WAAW;IAKnB;;OAEG;IACH,OAAO,CAAC,WAAW;IAqBnB;;OAEG;YACW,oBAAoB;IAuElC;;OAEG;IACG,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC;IAU5C;;OAEG;IACG,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ1C"}
@@ -0,0 +1,277 @@
1
+ "use strict";
2
+ /**
3
+ * Batch Manager - Orchestrates batch sending and offline queue
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.BatchManager = void 0;
7
+ const uuid_1 = require("../utils/uuid");
8
+ const Storage_1 = require("../core/Storage");
9
+ const logger_1 = require("../utils/logger");
10
+ class BatchManager {
11
+ constructor(eventQueue, apiClient, networkManager, identityManager, eventRetentionDays) {
12
+ this.isFlushing = false;
13
+ this.eventQueue = eventQueue;
14
+ this.apiClient = apiClient;
15
+ this.networkManager = networkManager;
16
+ this.identityManager = identityManager;
17
+ this.eventRetentionDays = eventRetentionDays;
18
+ // Set flush callback on event queue
19
+ this.eventQueue.setFlushCallback((events) => this.sendBatch(events));
20
+ // Listen for network status changes
21
+ this.networkManager.onStatusChange((isOnline) => {
22
+ if (isOnline) {
23
+ logger_1.logger.info('Network came online, processing offline queue...');
24
+ this.flushOfflineQueue().catch((error) => {
25
+ logger_1.logger.error('Failed to flush offline queue:', error);
26
+ });
27
+ }
28
+ });
29
+ }
30
+ /**
31
+ * Sends a batch of events to the API
32
+ */
33
+ async sendBatch(events) {
34
+ if (events.length === 0) {
35
+ return;
36
+ }
37
+ // Check if online
38
+ if (!this.networkManager.isConnected()) {
39
+ logger_1.logger.warn('Offline, events will be stored for later');
40
+ logger_1.logger.warn(` Events not sent: ${events.length} events`);
41
+ events.forEach((event, index) => {
42
+ logger_1.logger.warn(` ${index + 1}. ${event.name} (id: ${event.id}, timestamp: ${new Date(event.timestamp).toISOString()})`);
43
+ });
44
+ await this.saveFailedBatch(events, 'Network offline');
45
+ return;
46
+ }
47
+ // Prevent concurrent flushes
48
+ if (this.isFlushing) {
49
+ logger_1.logger.debug('Already flushing, skipping...');
50
+ return;
51
+ }
52
+ this.isFlushing = true;
53
+ const startTime = Date.now();
54
+ try {
55
+ logger_1.logger.info(`Sending batch: ${events.length} events`);
56
+ if (events.length <= 5) {
57
+ logger_1.logger.info(` Events:`);
58
+ events.forEach((event, index) => {
59
+ logger_1.logger.info(` ${index + 1}. ${event.name} (id: ${event.id.substring(0, 8)}...)`);
60
+ });
61
+ }
62
+ else {
63
+ logger_1.logger.info(` Events: ${events.map(e => e.name).join(', ')}`);
64
+ }
65
+ const anonymousId = this.identityManager.getAnonymousId();
66
+ const externalUserId = this.identityManager.getExternalUserId();
67
+ if (!anonymousId) {
68
+ throw new Error('Anonymous ID not set');
69
+ }
70
+ logger_1.logger.info(` Anonymous ID: ${anonymousId}`);
71
+ if (externalUserId) {
72
+ logger_1.logger.info(` External User ID: ${externalUserId}`);
73
+ }
74
+ // Send to API
75
+ const response = await this.apiClient.track({
76
+ anonymous_id: anonymousId,
77
+ external_user_id: externalUserId || undefined,
78
+ events,
79
+ });
80
+ const responseTime = Date.now() - startTime;
81
+ logger_1.logger.info(`Batch sent successfully`);
82
+ logger_1.logger.info(` Processed: ${response.processed}/${events.length} events`);
83
+ logger_1.logger.info(` Response time: ${responseTime}ms`);
84
+ if (response.processed < events.length) {
85
+ logger_1.logger.warn(` Warning: Only ${response.processed} out of ${events.length} events were processed`);
86
+ }
87
+ }
88
+ catch (error) {
89
+ const responseTime = Date.now() - startTime;
90
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
91
+ logger_1.logger.error(`Failed to send batch (${responseTime}ms): ${errorMessage}`);
92
+ if (events.length <= 5) {
93
+ logger_1.logger.error(` Events not sent:`);
94
+ events.forEach((event, index) => {
95
+ logger_1.logger.error(` ${index + 1}. ${event.name} (id: ${event.id.substring(0, 8)}...)`);
96
+ });
97
+ }
98
+ else {
99
+ logger_1.logger.error(` Events not sent: ${events.length} events (${events.map(e => e.name).join(', ')})`);
100
+ }
101
+ // Save as failed batch for retry
102
+ await this.saveFailedBatch(events, errorMessage);
103
+ throw error;
104
+ }
105
+ finally {
106
+ this.isFlushing = false;
107
+ }
108
+ }
109
+ /**
110
+ * Saves a failed batch for later retry
111
+ */
112
+ async saveFailedBatch(events, errorMessage) {
113
+ try {
114
+ const failedBatch = {
115
+ id: (0, uuid_1.generateUUID)(),
116
+ events,
117
+ failedAt: Date.now(),
118
+ retryCount: 0,
119
+ lastError: errorMessage,
120
+ };
121
+ // Get existing failed batches
122
+ const existingBatches = (await Storage_1.storage.get('FAILED_BATCHES')) || [];
123
+ // Add new failed batch
124
+ existingBatches.push(failedBatch);
125
+ // Save back to storage
126
+ await Storage_1.storage.set('FAILED_BATCHES', existingBatches);
127
+ logger_1.logger.warn(`Saved failed batch: ${failedBatch.id.substring(0, 8)}...`);
128
+ logger_1.logger.warn(` Events: ${events.length} events`);
129
+ logger_1.logger.warn(` Error: ${errorMessage}`);
130
+ if (events.length <= 5) {
131
+ logger_1.logger.warn(` Events in failed batch:`);
132
+ events.forEach((event, index) => {
133
+ logger_1.logger.warn(` ${index + 1}. ${event.name} (id: ${event.id.substring(0, 8)}...)`);
134
+ });
135
+ }
136
+ else {
137
+ logger_1.logger.warn(` Events: ${events.map(e => e.name).join(', ')}`);
138
+ }
139
+ logger_1.logger.warn(` Total failed batches: ${existingBatches.length}`);
140
+ }
141
+ catch (error) {
142
+ logger_1.logger.error('Failed to save failed batch:', error);
143
+ }
144
+ }
145
+ /**
146
+ * Flushes the offline queue (retries failed batches)
147
+ */
148
+ async flushOfflineQueue() {
149
+ // First, process any failed batches
150
+ await this.processFailedBatches();
151
+ // Then, flush any events in the current queue
152
+ try {
153
+ await this.eventQueue.flush();
154
+ }
155
+ catch (error) {
156
+ logger_1.logger.error('Failed to flush event queue:', error);
157
+ }
158
+ }
159
+ /**
160
+ * Validates UUID format (8-4-4-4-12 hex characters)
161
+ */
162
+ isValidUUID(uuid) {
163
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
164
+ return uuidRegex.test(uuid);
165
+ }
166
+ /**
167
+ * Fixes invalid event IDs in a batch
168
+ */
169
+ fixEventIds(events) {
170
+ let fixedCount = 0;
171
+ const fixedEvents = events.map((event) => {
172
+ if (!this.isValidUUID(event.id)) {
173
+ logger_1.logger.warn(`Invalid event ID detected: ${event.id}. Generating new ID.`);
174
+ fixedCount++;
175
+ return {
176
+ ...event,
177
+ id: (0, uuid_1.generateUUID)(),
178
+ };
179
+ }
180
+ return event;
181
+ });
182
+ if (fixedCount > 0) {
183
+ logger_1.logger.info(`Fixed ${fixedCount} invalid event IDs in batch`);
184
+ }
185
+ return fixedEvents;
186
+ }
187
+ /**
188
+ * Processes and retries failed batches
189
+ */
190
+ async processFailedBatches() {
191
+ try {
192
+ const failedBatches = (await Storage_1.storage.get('FAILED_BATCHES')) || [];
193
+ if (failedBatches.length === 0) {
194
+ logger_1.logger.debug('No failed batches to process');
195
+ return;
196
+ }
197
+ logger_1.logger.info(`Processing ${failedBatches.length} failed batches...`);
198
+ const successfulBatches = [];
199
+ const updatedBatches = [];
200
+ let discardedCount = 0;
201
+ for (const batch of failedBatches) {
202
+ // Check if batch is too old (exceeded retention period)
203
+ const age = Date.now() - batch.failedAt;
204
+ const maxAge = this.eventRetentionDays * 24 * 60 * 60 * 1000;
205
+ if (age > maxAge) {
206
+ const ageDays = Math.floor(age / (24 * 60 * 60 * 1000));
207
+ logger_1.logger.warn(`Batch ${batch.id} is too old (${ageDays} days), discarding`);
208
+ logger_1.logger.warn(` Events discarded: ${batch.events.length} events`);
209
+ batch.events.forEach((event, index) => {
210
+ logger_1.logger.warn(` ${index + 1}. ${event.name} (id: ${event.id})`);
211
+ });
212
+ discardedCount++;
213
+ continue;
214
+ }
215
+ logger_1.logger.info(`Retrying failed batch: ${batch.id}`);
216
+ logger_1.logger.info(` Previous error: ${batch.lastError}`);
217
+ logger_1.logger.info(` Retry attempt: ${batch.retryCount + 1}`);
218
+ logger_1.logger.info(` Events: ${batch.events.length} events`);
219
+ // Fix invalid event IDs before retrying
220
+ const fixedEvents = this.fixEventIds(batch.events);
221
+ // Try to send the batch
222
+ try {
223
+ await this.sendBatch(fixedEvents);
224
+ successfulBatches.push(batch.id);
225
+ logger_1.logger.info(`Successfully retried batch ${batch.id}`);
226
+ logger_1.logger.info(` Events sent: ${batch.events.length} events`);
227
+ }
228
+ catch (error) {
229
+ // Update retry count and error, but use fixed events
230
+ batch.retryCount += 1;
231
+ batch.lastError = error instanceof Error ? error.message : 'Unknown error';
232
+ batch.events = fixedEvents; // Update with fixed events
233
+ updatedBatches.push(batch);
234
+ logger_1.logger.warn(`Failed to retry batch ${batch.id} (attempt ${batch.retryCount}):`, error);
235
+ logger_1.logger.warn(` Error: ${batch.lastError}`);
236
+ logger_1.logger.warn(` Events still failed: ${batch.events.length} events`);
237
+ }
238
+ }
239
+ // Update storage with remaining failed batches
240
+ await Storage_1.storage.set('FAILED_BATCHES', updatedBatches);
241
+ logger_1.logger.info(`Processed failed batches:`);
242
+ logger_1.logger.info(` Succeeded: ${successfulBatches.length}`);
243
+ logger_1.logger.info(` Still failed: ${updatedBatches.length}`);
244
+ logger_1.logger.info(` Discarded (too old): ${discardedCount}`);
245
+ logger_1.logger.info(` Total processed: ${failedBatches.length}`);
246
+ }
247
+ catch (error) {
248
+ logger_1.logger.error('Failed to process failed batches:', error);
249
+ }
250
+ }
251
+ /**
252
+ * Gets the count of failed batches
253
+ */
254
+ async getFailedBatchCount() {
255
+ try {
256
+ const failedBatches = (await Storage_1.storage.get('FAILED_BATCHES')) || [];
257
+ return failedBatches.length;
258
+ }
259
+ catch (error) {
260
+ logger_1.logger.error('Failed to get failed batch count:', error);
261
+ return 0;
262
+ }
263
+ }
264
+ /**
265
+ * Clears all failed batches
266
+ */
267
+ async clearFailedBatches() {
268
+ try {
269
+ await Storage_1.storage.set('FAILED_BATCHES', []);
270
+ logger_1.logger.info('Cleared all failed batches');
271
+ }
272
+ catch (error) {
273
+ logger_1.logger.error('Failed to clear failed batches:', error);
274
+ }
275
+ }
276
+ }
277
+ exports.BatchManager = BatchManager;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Identity Manager - Manages user identity
3
+ */
4
+ export declare class IdentityManager {
5
+ private anonymousId;
6
+ private externalUserId;
7
+ private userProperties;
8
+ /**
9
+ * Validates UUID format (8-4-4-4-12 hex characters)
10
+ */
11
+ private isValidUUID;
12
+ /**
13
+ * Initializes the identity manager
14
+ * Generates or loads anonymous ID from storage
15
+ */
16
+ initialize(): Promise<string>;
17
+ /**
18
+ * Identifies a user with an external user ID and optional properties
19
+ */
20
+ identify(externalUserId: string, properties?: Record<string, any>): Promise<void>;
21
+ /**
22
+ * Resets the user identity
23
+ * Generates a new anonymous ID and clears external user ID and properties
24
+ */
25
+ reset(): Promise<void>;
26
+ /**
27
+ * Updates user properties (merges with existing)
28
+ */
29
+ updateUserProperties(properties: Record<string, any>): Promise<void>;
30
+ /**
31
+ * Gets the anonymous ID
32
+ */
33
+ getAnonymousId(): string | null;
34
+ /**
35
+ * Gets the external user ID
36
+ */
37
+ getExternalUserId(): string | null;
38
+ /**
39
+ * Gets user properties
40
+ */
41
+ getUserProperties(): Record<string, any>;
42
+ /**
43
+ * Checks if the user is identified
44
+ */
45
+ isIdentified(): boolean;
46
+ }
47
+ //# sourceMappingURL=IdentityManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IdentityManager.d.ts","sourceRoot":"","sources":["../../src/managers/IdentityManager.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,qBAAa,eAAe;IAC1B,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,cAAc,CAA2B;IAEjD;;OAEG;IACH,OAAO,CAAC,WAAW;IAKnB;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAkCnC;;OAEG;IACG,QAAQ,CACZ,cAAc,EAAE,MAAM,EACtB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC/B,OAAO,CAAC,IAAI,CAAC;IAyBhB;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB5B;;OAEG;IACG,oBAAoB,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAY1E;;OAEG;IACH,cAAc,IAAI,MAAM,GAAG,IAAI;IAI/B;;OAEG;IACH,iBAAiB,IAAI,MAAM,GAAG,IAAI;IAIlC;;OAEG;IACH,iBAAiB,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAIxC;;OAEG;IACH,YAAY,IAAI,OAAO;CAGxB"}
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ /**
3
+ * Identity Manager - Manages user identity
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.IdentityManager = void 0;
7
+ const uuid_1 = require("../utils/uuid");
8
+ const Storage_1 = require("../core/Storage");
9
+ const logger_1 = require("../utils/logger");
10
+ const validators_1 = require("../utils/validators");
11
+ class IdentityManager {
12
+ constructor() {
13
+ this.anonymousId = null;
14
+ this.externalUserId = null;
15
+ this.userProperties = {};
16
+ }
17
+ /**
18
+ * Validates UUID format (8-4-4-4-12 hex characters)
19
+ */
20
+ isValidUUID(uuid) {
21
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
22
+ return uuidRegex.test(uuid);
23
+ }
24
+ /**
25
+ * Initializes the identity manager
26
+ * Generates or loads anonymous ID from storage
27
+ */
28
+ async initialize() {
29
+ // Try to load existing anonymous ID from storage
30
+ const storedAnonymousId = await Storage_1.storage.get('ANONYMOUS_ID');
31
+ if (storedAnonymousId && this.isValidUUID(storedAnonymousId)) {
32
+ logger_1.logger.info(`Loaded existing anonymous ID: ${storedAnonymousId}`);
33
+ this.anonymousId = storedAnonymousId;
34
+ }
35
+ else {
36
+ // Generate new anonymous ID if none exists or if stored one is invalid
37
+ if (storedAnonymousId && !this.isValidUUID(storedAnonymousId)) {
38
+ logger_1.logger.warn(`Invalid UUID format detected: ${storedAnonymousId}. Generating new UUID.`);
39
+ }
40
+ this.anonymousId = (0, uuid_1.generateUUID)();
41
+ await Storage_1.storage.set('ANONYMOUS_ID', this.anonymousId);
42
+ logger_1.logger.info(`Generated new anonymous ID: ${this.anonymousId}`);
43
+ }
44
+ // Load external user ID if it exists
45
+ const storedExternalUserId = await Storage_1.storage.get('EXTERNAL_USER_ID');
46
+ if (storedExternalUserId) {
47
+ this.externalUserId = storedExternalUserId;
48
+ logger_1.logger.info(`Loaded external user ID: ${this.externalUserId}`);
49
+ }
50
+ // Load user properties if they exist
51
+ const storedUserProperties = await Storage_1.storage.get('USER_PROPERTIES');
52
+ if (storedUserProperties) {
53
+ this.userProperties = storedUserProperties;
54
+ logger_1.logger.info('Loaded user properties');
55
+ }
56
+ return this.anonymousId;
57
+ }
58
+ /**
59
+ * Identifies a user with an external user ID and optional properties
60
+ */
61
+ async identify(externalUserId, properties) {
62
+ // Validate inputs
63
+ (0, validators_1.validateUserId)(externalUserId);
64
+ if (properties) {
65
+ (0, validators_1.validateUserProperties)(properties);
66
+ }
67
+ // Store external user ID
68
+ this.externalUserId = externalUserId;
69
+ await Storage_1.storage.set('EXTERNAL_USER_ID', externalUserId);
70
+ logger_1.logger.info(`User identified: ${externalUserId}`);
71
+ // Merge user properties
72
+ if (properties) {
73
+ this.userProperties = {
74
+ ...this.userProperties,
75
+ ...properties,
76
+ };
77
+ await Storage_1.storage.set('USER_PROPERTIES', this.userProperties);
78
+ logger_1.logger.info('User properties updated');
79
+ }
80
+ }
81
+ /**
82
+ * Resets the user identity
83
+ * Generates a new anonymous ID and clears external user ID and properties
84
+ */
85
+ async reset() {
86
+ logger_1.logger.info('Resetting user identity...');
87
+ // Generate new anonymous ID
88
+ this.anonymousId = (0, uuid_1.generateUUID)();
89
+ await Storage_1.storage.set('ANONYMOUS_ID', this.anonymousId);
90
+ // Clear external user ID
91
+ this.externalUserId = null;
92
+ await Storage_1.storage.remove('EXTERNAL_USER_ID');
93
+ // Clear user properties
94
+ this.userProperties = {};
95
+ await Storage_1.storage.remove('USER_PROPERTIES');
96
+ logger_1.logger.info(`Identity reset. New anonymous ID: ${this.anonymousId}`);
97
+ }
98
+ /**
99
+ * Updates user properties (merges with existing)
100
+ */
101
+ async updateUserProperties(properties) {
102
+ (0, validators_1.validateUserProperties)(properties);
103
+ this.userProperties = {
104
+ ...this.userProperties,
105
+ ...properties,
106
+ };
107
+ await Storage_1.storage.set('USER_PROPERTIES', this.userProperties);
108
+ logger_1.logger.info('User properties updated');
109
+ }
110
+ /**
111
+ * Gets the anonymous ID
112
+ */
113
+ getAnonymousId() {
114
+ return this.anonymousId;
115
+ }
116
+ /**
117
+ * Gets the external user ID
118
+ */
119
+ getExternalUserId() {
120
+ return this.externalUserId;
121
+ }
122
+ /**
123
+ * Gets user properties
124
+ */
125
+ getUserProperties() {
126
+ return { ...this.userProperties };
127
+ }
128
+ /**
129
+ * Checks if the user is identified
130
+ */
131
+ isIdentified() {
132
+ return this.externalUserId !== null;
133
+ }
134
+ }
135
+ exports.IdentityManager = IdentityManager;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Network Manager - Monitors network connectivity
3
+ *
4
+ * Uses the adapter pattern to automatically select the best network implementation
5
+ * based on available modules (Native > Expo > Fallback)
6
+ */
7
+ export type NetworkStatusCallback = (isOnline: boolean) => void;
8
+ export declare class NetworkManager {
9
+ private adapter;
10
+ constructor();
11
+ /**
12
+ * Initializes the network manager and starts monitoring
13
+ */
14
+ initialize(): Promise<void>;
15
+ /**
16
+ * Adds a listener for network status changes
17
+ */
18
+ onStatusChange(callback: NetworkStatusCallback): () => void;
19
+ /**
20
+ * Checks if currently online
21
+ */
22
+ isConnected(): boolean;
23
+ /**
24
+ * Manually refreshes network status
25
+ */
26
+ refresh(): Promise<boolean>;
27
+ /**
28
+ * Cleans up the network manager
29
+ */
30
+ cleanup(): void;
31
+ }
32
+ //# sourceMappingURL=NetworkManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NetworkManager.d.ts","sourceRoot":"","sources":["../../src/managers/NetworkManager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,MAAM,qBAAqB,GAAG,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;AAEhE,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAiB;;IAMhC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAKjC;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,qBAAqB,GAAG,MAAM,IAAI;IAoB3D;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAOjC;;OAEG;IACH,OAAO,IAAI,IAAI;CAIhB"}