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,184 @@
1
+ "use strict";
2
+ /**
3
+ * API Client - Handles HTTP requests with retry logic
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ApiClient = void 0;
7
+ const constants_1 = require("../constants");
8
+ const logger_1 = require("../utils/logger");
9
+ const retry_1 = require("../utils/retry");
10
+ const fetchWithTimeout_1 = require("../utils/fetchWithTimeout");
11
+ class ApiClient {
12
+ constructor(baseUrl, apiKey, maxRetries, retryDelay, timeout = 10000) {
13
+ this.baseUrl = baseUrl.replace(/\/$/, ''); // Remove trailing slash
14
+ this.apiKey = apiKey;
15
+ this.maxRetries = maxRetries;
16
+ this.retryDelay = retryDelay;
17
+ this.timeout = timeout;
18
+ }
19
+ /**
20
+ * Updates the API client configuration
21
+ */
22
+ updateConfig(baseUrl, apiKey, maxRetries, retryDelay, timeout = 10000) {
23
+ this.baseUrl = baseUrl.replace(/\/$/, '');
24
+ this.apiKey = apiKey;
25
+ this.maxRetries = maxRetries;
26
+ this.retryDelay = retryDelay;
27
+ this.timeout = timeout;
28
+ }
29
+ /**
30
+ * Initialize endpoint
31
+ */
32
+ async initialize(request) {
33
+ return this.post(constants_1.API_ENDPOINTS.INITIALIZE, {
34
+ ...request,
35
+ api_key: this.apiKey,
36
+ });
37
+ }
38
+ /**
39
+ * Identify endpoint
40
+ */
41
+ async identify(request) {
42
+ return this.post(constants_1.API_ENDPOINTS.IDENTIFY, {
43
+ ...request,
44
+ api_key: this.apiKey,
45
+ });
46
+ }
47
+ /**
48
+ * Track endpoint
49
+ */
50
+ async track(request) {
51
+ return this.post(constants_1.API_ENDPOINTS.TRACK, {
52
+ ...request,
53
+ api_key: this.apiKey,
54
+ });
55
+ }
56
+ /**
57
+ * Set FCM token endpoint
58
+ */
59
+ async setFcmToken(request) {
60
+ return this.post(constants_1.API_ENDPOINTS.FCM_TOKEN, {
61
+ ...request,
62
+ api_key: this.apiKey,
63
+ });
64
+ }
65
+ /**
66
+ * Generic POST request with retry logic
67
+ */
68
+ async post(endpoint, data) {
69
+ const url = `${this.baseUrl}${endpoint}`;
70
+ return (0, retry_1.retryWithBackoff)(async () => this.makeRequest(url, data), this.maxRetries, this.retryDelay, (error) => {
71
+ const errorType = this.classifyError(error);
72
+ return (0, retry_1.shouldRetry)(errorType);
73
+ });
74
+ }
75
+ /**
76
+ * Makes the actual HTTP request
77
+ */
78
+ async makeRequest(url, data) {
79
+ const startTime = Date.now();
80
+ const endpoint = url.replace(this.baseUrl, '');
81
+ // Extract event count if this is a track request
82
+ const eventCount = data.events ? data.events.length : undefined;
83
+ try {
84
+ logger_1.logger.info(`Making HTTP request: POST ${endpoint}`);
85
+ if (eventCount !== undefined) {
86
+ logger_1.logger.info(` Event count: ${eventCount}`);
87
+ }
88
+ logger_1.logger.info(` URL: ${url}`);
89
+ const response = await (0, fetchWithTimeout_1.fetchWithTimeout)(url, {
90
+ method: 'POST',
91
+ headers: {
92
+ 'Content-Type': 'application/json',
93
+ },
94
+ body: JSON.stringify(data),
95
+ }, this.timeout);
96
+ const responseTime = Date.now() - startTime;
97
+ // Handle non-OK responses
98
+ if (!response.ok) {
99
+ const errorData = await this.parseErrorResponse(response);
100
+ const error = new Error(errorData.message || `HTTP ${response.status}`);
101
+ error.status = response.status;
102
+ error.errorData = errorData;
103
+ logger_1.logger.error(`HTTP request failed: POST ${endpoint}`);
104
+ logger_1.logger.error(` Status: ${response.status} ${response.statusText}`);
105
+ logger_1.logger.error(` Response time: ${responseTime}ms`);
106
+ logger_1.logger.error(` Error: ${errorData.message || errorData.error || 'Unknown error'}`);
107
+ if (errorData.details) {
108
+ logger_1.logger.error(` Details: ${JSON.stringify(errorData.details, null, 2)}`);
109
+ }
110
+ if (eventCount !== undefined) {
111
+ logger_1.logger.error(` Events not processed: ${eventCount} events`);
112
+ }
113
+ throw error;
114
+ }
115
+ // Parse successful response
116
+ const responseData = await response.json();
117
+ logger_1.logger.info(`HTTP request successful: POST ${endpoint}`);
118
+ logger_1.logger.info(` Status: ${response.status} ${response.statusText}`);
119
+ logger_1.logger.info(` Response time: ${responseTime}ms`);
120
+ if (eventCount !== undefined && responseData.processed !== undefined) {
121
+ logger_1.logger.info(` Events processed: ${responseData.processed}/${eventCount}`);
122
+ }
123
+ return responseData;
124
+ }
125
+ catch (error) {
126
+ const responseTime = Date.now() - startTime;
127
+ // Only log if it's not already logged above (non-HTTP errors)
128
+ if (!error.status) {
129
+ const errorMsg = error instanceof Error ? error.message : String(error);
130
+ logger_1.logger.error(`HTTP request failed: POST ${endpoint} (${responseTime}ms)`);
131
+ logger_1.logger.error(` Error: ${errorMsg}`);
132
+ if (eventCount !== undefined) {
133
+ logger_1.logger.error(` Events not sent: ${eventCount} events`);
134
+ }
135
+ }
136
+ throw error;
137
+ }
138
+ }
139
+ /**
140
+ * Parses error response from API
141
+ */
142
+ async parseErrorResponse(response) {
143
+ try {
144
+ const errorData = await response.json();
145
+ return {
146
+ error: errorData.error || 'Unknown error',
147
+ message: errorData.message,
148
+ code: errorData.code,
149
+ status: response.status,
150
+ };
151
+ }
152
+ catch {
153
+ return {
154
+ error: constants_1.ERROR_MESSAGES.NETWORK_ERROR,
155
+ status: response.status,
156
+ };
157
+ }
158
+ }
159
+ /**
160
+ * Classifies an error into an ErrorType
161
+ */
162
+ classifyError(error) {
163
+ const { ErrorType } = require('../types');
164
+ // Network errors (no connection)
165
+ if (error.message?.includes('Network request failed') || error.message?.includes('fetch')) {
166
+ return ErrorType.NETWORK_ERROR;
167
+ }
168
+ // Timeout errors
169
+ if (error.message?.includes('timeout')) {
170
+ return ErrorType.TIMEOUT_ERROR;
171
+ }
172
+ // HTTP status-based classification
173
+ if (error.status) {
174
+ if (error.status >= 500) {
175
+ return ErrorType.SERVER_ERROR;
176
+ }
177
+ else if (error.status >= 400) {
178
+ return ErrorType.CLIENT_ERROR;
179
+ }
180
+ }
181
+ return ErrorType.UNKNOWN_ERROR;
182
+ }
183
+ }
184
+ exports.ApiClient = ApiClient;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Device Information Collector
3
+ *
4
+ * Uses the adapter pattern to automatically select the best device info implementation
5
+ * based on available modules (Native > Expo > Fallback)
6
+ */
7
+ import type { DeviceInfo as DeviceInfoType } from '../types';
8
+ declare class DeviceInfoCollector {
9
+ private adapter;
10
+ private cachedInfo;
11
+ /**
12
+ * Collects device information
13
+ * Uses cached value if available, otherwise collects fresh data
14
+ */
15
+ collect(): Promise<DeviceInfoType>;
16
+ /**
17
+ * Gets the cached device info without re-collecting
18
+ */
19
+ get(): DeviceInfoType | null;
20
+ /**
21
+ * Clears the cached device info
22
+ */
23
+ clearCache(): void;
24
+ }
25
+ export declare const deviceInfoCollector: DeviceInfoCollector;
26
+ export {};
27
+ //# sourceMappingURL=DeviceInfo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeviceInfo.d.ts","sourceRoot":"","sources":["../../src/core/DeviceInfo.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,UAAU,IAAI,cAAc,EAAE,MAAM,UAAU,CAAC;AAI7D,cAAM,mBAAmB;IACvB,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,UAAU,CAA+B;IAEjD;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,cAAc,CAAC;IA0CxC;;OAEG;IACH,GAAG,IAAI,cAAc,GAAG,IAAI;IAI5B;;OAEG;IACH,UAAU,IAAI,IAAI;CAGnB;AAED,eAAO,MAAM,mBAAmB,qBAA4B,CAAC"}
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ /**
3
+ * Device Information Collector
4
+ *
5
+ * Uses the adapter pattern to automatically select the best device info implementation
6
+ * based on available modules (Native > Expo > Fallback)
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.deviceInfoCollector = void 0;
10
+ const deviceInfo_1 = require("../adapters/deviceInfo");
11
+ const logger_1 = require("../utils/logger");
12
+ const Storage_1 = require("./Storage");
13
+ class DeviceInfoCollector {
14
+ constructor() {
15
+ this.adapter = (0, deviceInfo_1.getDeviceInfoAdapter)();
16
+ this.cachedInfo = null;
17
+ }
18
+ /**
19
+ * Collects device information
20
+ * Uses cached value if available, otherwise collects fresh data
21
+ */
22
+ async collect() {
23
+ // Return cached info if available
24
+ if (this.cachedInfo) {
25
+ return this.cachedInfo;
26
+ }
27
+ // Try to load from storage
28
+ const storedInfo = await Storage_1.storage.get('DEVICE_INFO');
29
+ if (storedInfo) {
30
+ this.cachedInfo = storedInfo;
31
+ return storedInfo;
32
+ }
33
+ // Collect fresh device info using adapter
34
+ logger_1.logger.debug('Collecting device information...');
35
+ try {
36
+ const deviceInfo = await this.adapter.collect();
37
+ // Cache and store the info
38
+ this.cachedInfo = deviceInfo;
39
+ await Storage_1.storage.set('DEVICE_INFO', deviceInfo);
40
+ logger_1.logger.debug('Device info collected');
41
+ return deviceInfo;
42
+ }
43
+ catch (error) {
44
+ logger_1.logger.error('Failed to collect device info:', error);
45
+ // Return fallback device info
46
+ const fallbackInfo = {
47
+ os_version: 'unknown',
48
+ device_model: 'unknown',
49
+ app_version: '1.0.0',
50
+ locale: 'en-US',
51
+ platform: 'android',
52
+ };
53
+ return fallbackInfo;
54
+ }
55
+ }
56
+ /**
57
+ * Gets the cached device info without re-collecting
58
+ */
59
+ get() {
60
+ return this.cachedInfo;
61
+ }
62
+ /**
63
+ * Clears the cached device info
64
+ */
65
+ clearCache() {
66
+ this.cachedInfo = null;
67
+ }
68
+ }
69
+ exports.deviceInfoCollector = new DeviceInfoCollector();
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Event Queue - Manages batching logic
3
+ */
4
+ import type { Event } from '../types';
5
+ export type FlushCallback = (events: Event[]) => Promise<void>;
6
+ export declare class EventQueue {
7
+ private queue;
8
+ private timer;
9
+ private readonly maxSize;
10
+ private readonly maxTime;
11
+ private readonly maxQueueSize;
12
+ private flushCallback;
13
+ constructor(maxSize: number, maxTime: number, maxQueueSize: number);
14
+ /**
15
+ * Sets the callback to be called when flush is triggered
16
+ */
17
+ setFlushCallback(callback: FlushCallback): void;
18
+ /**
19
+ * Adds an event to the queue
20
+ */
21
+ enqueue(event: Event): Promise<void>;
22
+ /**
23
+ * Removes and returns up to `count` events from the queue
24
+ */
25
+ dequeue(count: number): Event[];
26
+ /**
27
+ * Returns the current size of the queue
28
+ */
29
+ size(): number;
30
+ /**
31
+ * Returns all events in the queue without removing them
32
+ */
33
+ peek(): Event[];
34
+ /**
35
+ * Clears all events from the queue
36
+ */
37
+ clear(): Promise<void>;
38
+ /**
39
+ * Checks if the queue size has reached the threshold
40
+ */
41
+ private checkSizeThreshold;
42
+ /**
43
+ * Starts or restarts the flush timer
44
+ */
45
+ private startTimer;
46
+ /**
47
+ * Stops the flush timer
48
+ */
49
+ private stopTimer;
50
+ /**
51
+ * Flushes the queue by calling the flush callback
52
+ */
53
+ flush(): Promise<void>;
54
+ /**
55
+ * Validates UUID format (8-4-4-4-12 hex characters)
56
+ */
57
+ private isValidUUID;
58
+ /**
59
+ * Loads the queue from storage
60
+ */
61
+ loadFromStorage(): Promise<void>;
62
+ /**
63
+ * Saves the queue to storage
64
+ */
65
+ saveToStorage(): Promise<void>;
66
+ /**
67
+ * Cleanup method to stop timers
68
+ */
69
+ destroy(): void;
70
+ }
71
+ //# sourceMappingURL=EventQueue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventQueue.d.ts","sourceRoot":"","sources":["../../src/core/EventQueue.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAMtC,MAAM,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAE/D,qBAAa,UAAU;IACrB,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,aAAa,CAA8B;gBAEvC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;IAMlE;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IAI/C;;OAEG;IACG,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IA2B1C;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,EAAE;IAM/B;;OAEG;IACH,IAAI,IAAI,MAAM;IAId;;OAEG;IACH,IAAI,IAAI,KAAK,EAAE;IAIf;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B;;OAEG;YACW,kBAAkB;IAOhC;;OAEG;IACH,OAAO,CAAC,UAAU;IAgBlB;;OAEG;IACH,OAAO,CAAC,SAAS;IAOjB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA2C5B;;OAEG;IACH,OAAO,CAAC,WAAW;IAKnB;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAsCtC;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IASpC;;OAEG;IACH,OAAO,IAAI,IAAI;CAIhB"}
@@ -0,0 +1,216 @@
1
+ "use strict";
2
+ /**
3
+ * Event Queue - Manages batching logic
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.EventQueue = void 0;
7
+ const Storage_1 = require("./Storage");
8
+ const logger_1 = require("../utils/logger");
9
+ const constants_1 = require("../constants");
10
+ const uuid_1 = require("../utils/uuid");
11
+ class EventQueue {
12
+ constructor(maxSize, maxTime, maxQueueSize) {
13
+ this.queue = [];
14
+ this.timer = null;
15
+ this.flushCallback = null;
16
+ this.maxSize = maxSize;
17
+ this.maxTime = maxTime;
18
+ this.maxQueueSize = maxQueueSize;
19
+ }
20
+ /**
21
+ * Sets the callback to be called when flush is triggered
22
+ */
23
+ setFlushCallback(callback) {
24
+ this.flushCallback = callback;
25
+ }
26
+ /**
27
+ * Adds an event to the queue
28
+ */
29
+ async enqueue(event) {
30
+ const queueSizeBefore = this.queue.length;
31
+ // Check if queue is full
32
+ if (this.queue.length >= this.maxQueueSize) {
33
+ logger_1.logger.warn(constants_1.ERROR_MESSAGES.QUEUE_FULL);
34
+ logger_1.logger.warn(` Queue size: ${this.queue.length}/${this.maxQueueSize}`);
35
+ logger_1.logger.warn(` Removing oldest event: ${this.queue[0]?.name || 'unknown'}`);
36
+ // Remove oldest event
37
+ this.queue.shift();
38
+ }
39
+ this.queue.push(event);
40
+ logger_1.logger.info(`Event enqueued: ${event.name}`);
41
+ logger_1.logger.info(` Queue size: ${queueSizeBefore} -> ${this.queue.length}/${this.maxQueueSize}`);
42
+ // Persist to storage
43
+ await this.saveToStorage();
44
+ // Check if we should flush
45
+ await this.checkSizeThreshold();
46
+ // Start/restart the timer
47
+ this.startTimer();
48
+ }
49
+ /**
50
+ * Removes and returns up to `count` events from the queue
51
+ */
52
+ dequeue(count) {
53
+ const events = this.queue.splice(0, count);
54
+ // Removed verbose debug logging for production
55
+ return events;
56
+ }
57
+ /**
58
+ * Returns the current size of the queue
59
+ */
60
+ size() {
61
+ return this.queue.length;
62
+ }
63
+ /**
64
+ * Returns all events in the queue without removing them
65
+ */
66
+ peek() {
67
+ return [...this.queue];
68
+ }
69
+ /**
70
+ * Clears all events from the queue
71
+ */
72
+ async clear() {
73
+ this.queue = [];
74
+ this.stopTimer();
75
+ await this.saveToStorage();
76
+ // Removed verbose info logging for production
77
+ }
78
+ /**
79
+ * Checks if the queue size has reached the threshold
80
+ */
81
+ async checkSizeThreshold() {
82
+ if (this.queue.length >= this.maxSize) {
83
+ logger_1.logger.debug(`Queue size threshold reached (${this.queue.length}/${this.maxSize}), flushing...`);
84
+ await this.flush();
85
+ }
86
+ }
87
+ /**
88
+ * Starts or restarts the flush timer
89
+ */
90
+ startTimer() {
91
+ // Stop existing timer
92
+ this.stopTimer();
93
+ // Don't start timer if queue is empty
94
+ if (this.queue.length === 0) {
95
+ return;
96
+ }
97
+ // Start new timer
98
+ this.timer = setTimeout(async () => {
99
+ logger_1.logger.debug(`Queue timeout reached (${this.maxTime}ms), flushing...`);
100
+ await this.flush();
101
+ }, this.maxTime);
102
+ }
103
+ /**
104
+ * Stops the flush timer
105
+ */
106
+ stopTimer() {
107
+ if (this.timer) {
108
+ clearTimeout(this.timer);
109
+ this.timer = null;
110
+ }
111
+ }
112
+ /**
113
+ * Flushes the queue by calling the flush callback
114
+ */
115
+ async flush() {
116
+ if (this.queue.length === 0) {
117
+ logger_1.logger.debug('Queue is empty, nothing to flush');
118
+ return;
119
+ }
120
+ if (!this.flushCallback) {
121
+ logger_1.logger.warn('Flush callback not set, cannot flush queue');
122
+ return;
123
+ }
124
+ // Stop the timer during flush
125
+ this.stopTimer();
126
+ try {
127
+ // Get all events
128
+ const events = this.dequeue(this.queue.length);
129
+ logger_1.logger.info(`Flushing queue: ${events.length} events`);
130
+ const eventNames = events.map(e => e.name).join(', ');
131
+ logger_1.logger.info(` Events: [${eventNames}]`);
132
+ // Call the flush callback
133
+ await this.flushCallback(events);
134
+ // Save updated queue to storage
135
+ await this.saveToStorage();
136
+ logger_1.logger.info(`Flushed ${events.length} events successfully`);
137
+ logger_1.logger.info(` Remaining queue size: ${this.queue.length}`);
138
+ }
139
+ catch (error) {
140
+ logger_1.logger.error(`Failed to flush queue (${this.queue.length} events):`, error);
141
+ // Re-enqueue failed events
142
+ // Note: The BatchManager will handle this by storing failed batches
143
+ throw error;
144
+ }
145
+ finally {
146
+ // Restart timer if there are still events
147
+ if (this.queue.length > 0) {
148
+ this.startTimer();
149
+ }
150
+ }
151
+ }
152
+ /**
153
+ * Validates UUID format (8-4-4-4-12 hex characters)
154
+ */
155
+ isValidUUID(uuid) {
156
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
157
+ return uuidRegex.test(uuid);
158
+ }
159
+ /**
160
+ * Loads the queue from storage
161
+ */
162
+ async loadFromStorage() {
163
+ try {
164
+ const events = await Storage_1.storage.get('EVENT_QUEUE');
165
+ if (events && Array.isArray(events)) {
166
+ // Validate and fix event IDs
167
+ let fixedCount = 0;
168
+ this.queue = events.map((event) => {
169
+ // Fix invalid event IDs
170
+ if (!this.isValidUUID(event.id)) {
171
+ logger_1.logger.warn(`Invalid event ID detected: ${event.id}. Generating new ID.`);
172
+ fixedCount++;
173
+ return {
174
+ ...event,
175
+ id: (0, uuid_1.generateUUID)(),
176
+ };
177
+ }
178
+ return event;
179
+ });
180
+ if (fixedCount > 0) {
181
+ logger_1.logger.info(`Fixed ${fixedCount} invalid event IDs in queue`);
182
+ await this.saveToStorage();
183
+ }
184
+ logger_1.logger.info(`Loaded ${this.queue.length} events from storage`);
185
+ // Start timer if there are events
186
+ if (this.queue.length > 0) {
187
+ this.startTimer();
188
+ }
189
+ }
190
+ }
191
+ catch (error) {
192
+ logger_1.logger.error('Failed to load queue from storage:', error);
193
+ this.queue = [];
194
+ }
195
+ }
196
+ /**
197
+ * Saves the queue to storage
198
+ */
199
+ async saveToStorage() {
200
+ try {
201
+ await Storage_1.storage.set('EVENT_QUEUE', this.queue);
202
+ // Removed verbose debug logging for production
203
+ }
204
+ catch (error) {
205
+ logger_1.logger.error('Failed to save queue to storage:', error);
206
+ }
207
+ }
208
+ /**
209
+ * Cleanup method to stop timers
210
+ */
211
+ destroy() {
212
+ this.stopTimer();
213
+ // Removed verbose info logging for production
214
+ }
215
+ }
216
+ exports.EventQueue = EventQueue;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Storage Layer - AsyncStorage Wrapper
3
+ */
4
+ import type { StorageKey, StorageValue } from '../types/storage';
5
+ declare class Storage {
6
+ /**
7
+ * Sets a value in storage
8
+ */
9
+ set<K extends StorageKey>(key: K, value: StorageValue<K>): Promise<void>;
10
+ /**
11
+ * Gets a value from storage
12
+ */
13
+ get<K extends StorageKey>(key: K): Promise<StorageValue<K> | null>;
14
+ /**
15
+ * Removes a value from storage
16
+ */
17
+ remove(key: StorageKey): Promise<void>;
18
+ /**
19
+ * Clears all SDK-related storage
20
+ */
21
+ clear(): Promise<void>;
22
+ /**
23
+ * Checks if a key exists in storage
24
+ */
25
+ has(key: StorageKey): Promise<boolean>;
26
+ }
27
+ export declare const storage: Storage;
28
+ export {};
29
+ //# sourceMappingURL=Storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Storage.d.ts","sourceRoot":"","sources":["../../src/core/Storage.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGjE,cAAM,OAAO;IACX;;OAEG;IACG,GAAG,CAAC,CAAC,SAAS,UAAU,EAC5B,GAAG,EAAE,CAAC,EACN,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,GACrB,OAAO,CAAC,IAAI,CAAC;IAYhB;;OAEG;IACG,GAAG,CAAC,CAAC,SAAS,UAAU,EAC5B,GAAG,EAAE,CAAC,GACL,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAiBlC;;OAEG;IACG,MAAM,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAW5C;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAW5B;;OAEG;IACG,GAAG,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;CAQ7C;AAED,eAAO,MAAM,OAAO,SAAgB,CAAC"}